如何用随机粒子填充已加载的STL网格(非简单形状像CUBE ETC),并使用Three.js中绑定的此几何体进行动画处理

时间:2018-10-25 20:01:44

标签: three.js points

我如何用随机粒子填充已加载的STL网格(如suzane NOT SIMPLE SHAPES LIKE CUBE等),并使用three.js在此几何范围内对其进行动画处理?

我看到了很多示例,但所有示例都针对具有几何边界(例如立方体或球体)的简单形状,并受中心坐标限制

https://threejs.org/examples/?q=points#webgl_custom_attributes_points3

TNX

2 个答案:

答案 0 :(得分:1)

使用射线的概念,它计算射线与网格物体的面的交点,如果数字为奇数,则意味着该点位于网格物体内部:

Codepen

  function fillWithPoints(geometry, count) {

    var ray = new THREE.Ray()

    var size = new THREE.Vector3();
    geometry.computeBoundingBox();
    let bbox = geometry.boundingBox;

    let points = [];

    var dir = new THREE.Vector3(1, 1, 1).normalize();
    for (let i = 0; i < count; i++) {
      let p = setRandomVector(bbox.min, bbox.max);
      points.push(p);
    }

    function setRandomVector(min, max){
      let v = new THREE.Vector3(
        THREE.Math.randFloat(min.x, max.x),
        THREE.Math.randFloat(min.y, max.y),
        THREE.Math.randFloat(min.z, max.z)
      );
      if (!isInside(v)){return setRandomVector(min, max);}
      return v;
    }

    function isInside(v){

      ray.set(v, dir);
      let counter = 0;

      let pos = geometry.attributes.position;
      let faces = pos.count / 3;
      let vA = new THREE.Vector3(), vB = new THREE.Vector3(), vC = new THREE.Vector3();

      for(let i = 0; i < faces; i++){
        vA.fromBufferAttribute(pos, i * 3 + 0);
        vB.fromBufferAttribute(pos, i * 3 + 1);
        vC.fromBufferAttribute(pos, i * 3 + 2);
        if (ray.intersectTriangle(vA, vB, vC)) counter++;
      }

      return counter % 2 == 1;
    }

    return new THREE.BufferGeometry().setFromPoints(points);
  }

答案 1 :(得分:0)

上一个答案中的概念很好,但是有一些性能限制:

  • 用每条射线测试整个几何
  • 外部点的递归会导致堆栈溢出

此外,它与索引几何不兼容。

可以通过创建空间哈希图来存储几何三角形并将交集测试限制为仅网格的一部分来进行改进。

Demonstration

enter image description here