我有一组大约二十条线,形成一个形状(“小鸟”)。我目前正在“镜子”顶部绕 y 轴(“上”轴)旋转它。这是屏幕截图:
[ ] 我想要做的是将旋转形状投影到“镜子”(黄色平面)的 xy 平面上,只需忽略 z 分量,这样您就只会看到形状从其角度看时的二维投影侧面。
目前,我的攻击计划如下:
- 保持原始形状为 3 维形式,以便正确旋转。我认为如果此时将其减少到二维,旋转将不正确。
- 绕 y 轴旋转 3D 原型(prototype),但还不显示它。这是我当前使用的代码:
var m = new THREE.Matrix4();
var mat = m.makeRotationY(base.ONE_DEGREE * 0.2);
birdyGroupClone.applyMatrix(mat);
- 通过子数组遍历组中的各个线,然后转到 Geometry.vertices 并将 z 分量设置为零。
- 最后,将这些二维线(作为一组)渲染到 xy 平面上。
我陷入了第 3 点,因为当我将组中的行乘以矩阵时,我无法在层次结构中的任何位置找到中间旋转结果。顶点本身不受影响——它们仍然包含规范的“根”值。
以下是从 Chrome 浏览器调试 session 中获取的组的对象层次结构的相关部分:
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
这是旋转之后的结果。中间的变换后顶点在哪里,我可以将其用于我的变换“管道”(以进行二维投影)。它们仅反射(reflect)在浏览器 Canvas 中吗?
所以我的问题是:
- 我的攻击计划听起来正确吗?或者有更好的方法吗?
- 如果是,我如何访问中间转换的结果,以便应用处理“管道”?
非常感谢。
最佳答案
根据 WestLangley 的输入,我找到了解决方案。现在我已经完成了,我意识到描述我的问题的更好方法是说我想将 3-d 对象的阴影投影到平面上。
我基本上必须单独对每个线条几何图形进行变换,而不是对组进行变换。通过这种方式,线的顶点被更新,然后我可以按照前面所述继续执行计划的其余部分。
这是我的代码:
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);
也许这不是最漂亮的方法,但它确实有效。
这是显示结果的屏幕截图。注意,它是如何完全存在于平面上并且没有“深度”的:
关于three.js - 如何在 Three.js 中将 3D 对象投影到 2D 平面上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32153295/