如何将三维物体投射到三维飞机的二维飞机上?

时间:2015-08-22 06:52:47

标签: three.js

我有一组二十个左右的线条形成一个形状(#34;小鸟")。我正在围绕y轴("向上"轴)旋转它在"镜像"顶部。这是一个屏幕截图:

[complex shape rotating on yellow mirror] 我想要做的是将旋转形状投影到"镜像"的xy平面上。 (黄色平面)只是忽略z分量,所以你只能从侧面看到形状的二维投影。

目前,我的攻击计划如下:

  1. 保持原始形状为三维形状,以便旋转正常。我想如果我此时将其减少到2-d,那么轮换就不对了。
  2. 围绕y轴旋转三维原型,但尚未显示。以下是我目前正在使用的代码:
  3. var m = new THREE.Matrix4();
    var mat = m.makeRotationY(base.ONE_DEGREE * 0.2);
    birdyGroupClone.applyMatrix(mat);
    
    1. 通过children数组遍历组中的各个行,然后转到geometry.vertices并将z组件设置为零。
    2. 最后,将这些2-d线(作为一组)渲染到xy平面上。
    3. 我被困在第3点,因为当我将组中的线乘以矩阵时,我无法在层次结构中的任何位置找到中间旋转结果。顶点本身不受影响 - 它们仍然包含规范的" root"值。

      以下是从Chrome浏览器调试会话中获取的对象层次结构的相关部分:

      birdyGroupClone: THREE.Object3D
          __webglActive: true
          __webglInit: true
          _listeners: Object
          _modelViewMatrix: THREE.Matrix4
          _normalMatrix: THREE.Matrix3
          castShadow: false
          children: Array[30]
              0: THREE.Line
              1: THREE.Line
              2: THREE.Line
              3: THREE.Line
              4: THREE.Line
              __webglActive: true
              __webglInit: true
              _listeners: Object
              _modelViewMatrix: THREE.Matrix4
              _normalMatrix: THREE.Matrix3
              castShadow: false
              children: Array[0]
              eulerOrder: (...)
              frustumCulled: true
              geometry: THREE.Geometry
                  __colorArray: Float32Array[6]
                  __lineDistanceArray: Float32Array[2]
                  __vertexArray: Float32Array[6]
                  __webglColorBuffer: WebGLBuffer
                  __webglInit: true
                  __webglLineCount: 2
                  __webglLineDistanceBuffer: WebGLBuffer
                  __webglVertexBuffer: WebGLBuffer
                  _listeners: Object
                  boundingBox: null
                  boundingSphere: THREE.Sphere
                  colors: Array[0]
                  colorsNeedUpdate: false
                  dynamic: true
                  elementsNeedUpdate: false
                  faceVertexUvs: Array[1]
                  faces: Array[0]
                  groupsNeedUpdate: false
                  hasTangents: false
                  id: 160
                  lineDistances: Array[0]
                  lineDistancesNeedUpdate: false
                  morphColors: Array[0]
                  morphNormals: Array[0]
                  morphTargets: Array[0]
                  name: ""
                  normalsNeedUpdate: false
                  skinIndices: Array[0]
                  skinWeights: Array[0]
                  tangentsNeedUpdate: false
                  type: "Geometry"
                  uuid: "55EE9F6D-0DD1-4581-817A-9E324EC5225D"
                  uvsNeedUpdate: false
                  vertices: Array[2]
                      0: THREE.Vector3  <-- These are unaffected by the rotation
                          x: -0.616     <--  Where are the transformed coordinates?
                          y: 0
                          z: -0.68
                          __proto__: THREE.Vector3
                      1: THREE.Vector3
                          x: -0.5
                          y: 0
                          z: -1
                          __proto__: THREE.Vector3
                      length: 2
      

      这是在轮换之后。中间变换后顶点在哪里,我可以用于转换&#34;管道&#34; (采取2-d投影)。它们只反映在浏览器画布中吗?

      所以我的问题是:

      1. 我的攻击计划是否正确,或者有更好的方法吗?
      2. 如果是,我如何访问中间转换的结果,以便我可以应用&#34;管道&#34;处理?
      3. 非常感谢。

1 个答案:

答案 0 :(得分:0)

根据WestLangley的意见,我找到了一个解决方案。现在我已经完成了,我意识到更好的描述我的问题的方法就是说我想将三维物体的阴影投影到一个平面上。

我基本上必须单独对每个线几何进行变换,而不是在组上进行变换。这样做,行的顶点被更新,然后我可以继续我的计划的其余部分,如前所述。

以下是我的代码:

 var m = new THREE.Matrix4();
 var mat = m.makeRotationY(base.ONE_DEGREE * 0.2);

 // loop over each line and transform individually
 // I had to do in a try catch block, but you shouldn't have to
 try {
   for (var i=0; i< birdyGroupClone.children.length; i++) {
     birdyGroupClone.children[i].geometry.applyMatrix(mat);
   }
 }
 catch(e){
   console.log('caught error=' + e);
   return false;
 }

 // Create a new Shadow group on each render
 // make sure to remove the old one, otherwise your frame rate will bog down
 // I had trouble with simply cloning birdyGroupClone because it doesn't
 // deep copy all the way down (?), so I create anew each time.
 factory.xyProjectionMesh.remove(birdyGroupShadow);
 birdyGroupShadow = new THREE.Object3D();

 //remove z-component from birdyGroupClone vertices
 for (var i=0; i< birdyGroupClone.children.length; i++) {
   var line, lineGeometry, vertex;

   lineGeometry = new THREE.Geometry();

   vertex = birdyGroupClone.children[i].geometry.vertices[0];
   lineGeometry.vertices.push(new THREE.Vector3(vertex.x, vertex.y, 0));
   vertex = birdyGroupClone.children[i].geometry.vertices[1];
   lineGeometry.vertices.push(new THREE.Vector3(vertex.x, vertex.y, 0));

   line = new THREE.Line(lineGeometry, birdyGroupClone.children[i].material);

   birdyGroupShadow.add(line);
 };

 birdyGroupShadow.position.set(0,0,0);
 this.xyProjectionMesh.add(birdyGroupShadow);

也许这不是最漂亮的方式,但它确实有效。

这是显示结果的屏幕截图。请注意,它如何完全存在于飞机上并且没有“深度”:

enter image description here