Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将Three.js场景导出到STL以保持动画完整_Javascript_Three.js_Export - Fatal编程技术网

Javascript 将Three.js场景导出到STL以保持动画完整

Javascript 将Three.js场景导出到STL以保持动画完整,javascript,three.js,export,Javascript,Three.js,Export,我渲染了一个Three.js场景,我想导出它在动画渲染后的外观。例如,在动画已过100帧后,用户点击导出,场景应导出为STL,就像此时一样 根据我的尝试(即使用),它似乎只使用初始位置导出模型 如果已经有办法做到这一点,或者有一个简单的解决办法,我希望能朝这个方向推动一下 更新:在对内部进行了一点深入研究之后,我已经找到了(至少表面上)STLExporter无法工作的原因。STLExporter查找所有对象,并要求它们提供几何体对象的顶点和面。我的模型有一堆剥皮的骨头。在动画步骤中,骨骼会得到更

我渲染了一个Three.js场景,我想导出它在动画渲染后的外观。例如,在动画已过100帧后,用户点击导出,场景应导出为STL,就像此时一样

根据我的尝试(即使用),它似乎只使用初始位置导出模型

如果已经有办法做到这一点,或者有一个简单的解决办法,我希望能朝这个方向推动一下

更新:在对内部进行了一点深入研究之后,我已经找到了(至少表面上)STLExporter无法工作的原因。STLExporter查找所有对象,并要求它们提供
几何体
对象的顶点和面。我的模型有一堆剥皮的骨头。在动画步骤中,骨骼会得到更新,但这些更新不会传播到原始
几何体
对象。我知道这些变换的顶点正在被计算,并且存在于某个地方(它们会显示在画布上)

问题是这些变换的顶点和面存储在哪里,我可以访问它们以将其导出为STL吗

问题是这些变换的顶点和面存储在哪里,我可以访问它们以将其导出为STL吗

不幸的是,这个问题的答案是没有答案的。这些都是在GPU上通过调用WebGL函数通过传入几个大数组来计算的

为了解释如何计算,让我们首先回顾一下动画是如何工作的,以供参考。 除其他外,该对象包含一个骨架(由多个顶点组成)和一组顶点。他们一开始被安排在一个被称为。每个顶点都绑定到0-4个骨骼,如果这些骨骼移动,顶点将移动,从而创建动画

如果以我们的骑士为例,在摇摆中暂停动画,然后尝试,生成的STL文件将正好是这个姿势,而不是动画姿势。为什么?因为它只是查看mesh.geometry.vertex,而在动画期间,这些顶点不会从原始绑定姿势更改。只有骨骼会发生变化,GPU会进行一些数学运算来移动对应于每个骨骼的顶点

移动每个顶点的数学方法非常简单——将绑定姿势顶点位置变换到骨骼空间,然后在导出之前从骨骼空间变换到全局空间。
修改源代码后,我们将其添加到原始导出器:

vector.copy( vertices[ vertexIndex ] );
boneIndices = [];   //which bones we need
boneIndices[0] = mesh.geometry.skinIndices[vertexIndex].x;
boneIndices[1] = mesh.geometry.skinIndices[vertexIndex].y;
boneIndices[2] = mesh.geometry.skinIndices[vertexIndex].z;
boneIndices[3] = mesh.geometry.skinIndices[vertexIndex].w;

weights = [];   //some bones impact the vertex more than others
weights[0] = mesh.geometry.skinWeights[vertexIndex].x;
weights[1] = mesh.geometry.skinWeights[vertexIndex].y;
weights[2] = mesh.geometry.skinWeights[vertexIndex].z;
weights[3] = mesh.geometry.skinWeights[vertexIndex].w;

inverses = [];  //boneInverses are the transform from bind-pose to some "bone space"
inverses[0] = mesh.skeleton.boneInverses[ boneIndices[0] ];
inverses[1] = mesh.skeleton.boneInverses[ boneIndices[1] ];
inverses[2] = mesh.skeleton.boneInverses[ boneIndices[2] ];
inverses[3] = mesh.skeleton.boneInverses[ boneIndices[3] ];

skinMatrices = [];  //each bone's matrix world is the transform from "bone space" to the "global space"
skinMatrices[0] = mesh.skeleton.bones[ boneIndices[0] ].matrixWorld;
skinMatrices[1] = mesh.skeleton.bones[ boneIndices[1] ].matrixWorld;
skinMatrices[2] = mesh.skeleton.bones[ boneIndices[2] ].matrixWorld;
skinMatrices[3] = mesh.skeleton.bones[ boneIndices[3] ].matrixWorld;

var finalVector = new THREE.Vector4();
for(var k = 0; k<4; k++) {
    var tempVector = new THREE.Vector4(vector.x, vector.y, vector.z);
    //weight the transformation
    tempVector.multiplyScalar(weights[k]);
    //the inverse takes the vector into local bone space
    tempVector.applyMatrix4(inverses[k])
    //which is then transformed to the appropriate world space
    .applyMatrix4(skinMatrices[k]);
    finalVector.add(tempVector);
}

output += '\t\t\tvertex ' + finalVector.x + ' ' + finalVector.y + ' ' + finalVector.z + '\n';
vector.copy(顶点[vertexIndex]);
骨指数=[]//我们需要哪些骨头
boneIndices[0]=mesh.geometry.SkinIndex[vertexIndex].x;
boneIndices[1]=mesh.geometry.SkinIndex[vertexIndex].y;
boneIndices[2]=mesh.geometry.SkinIndex[vertexIndex].z;
boneIndices[3]=mesh.geometry.SkinIndex[vertexIndex].w;
权重=[]//某些骨骼对顶点的影响比其他骨骼更大
权重[0]=mesh.geometry.skinWeights[vertexIndex].x;
权重[1]=mesh.geometry.skinWeights[vertexIndex].y;
权重[2]=mesh.geometry.skinWeights[vertexIndex].z;
权重[3]=mesh.geometry.skinWeights[vertexIndex].w;
倒数=[]//骨骼反转是从绑定姿势到某些“骨骼空间”的变换
反转[0]=mesh.skeleton.boneInverses[boneIndices[0]];
反转[1]=mesh.skeleton.boneInverses[boneIndices[1]];
反转[2]=mesh.skeleton.boneInverses[boneIndices[2]];
反转[3]=网格.骨架.骨骼反转[3];
皮肤基质=[]//每个骨骼的矩阵世界都是从“骨骼空间”到“全局空间”的变换
SkinMatrix[0]=mesh.skeleton.bones[BoneIndicates[0]].matrixWorld;
SkinMatrix[1]=mesh.skeleton.bones[BoneIndicates[1]].matrixWorld;
SkinMatrix[2]=mesh.skeleton.bones[BoneIndicates[2]].matrixWorld;
SkinMatrix[3]=mesh.skeleton.bones[BoneIndicates[3]].matrixWorld;
var finalVector=new THREE.Vector4();

对于(var k=0;k在一周的努力之后,我设法修改了代码,将morphTarget数据包含在最终的stl文件中


不是我们喜欢的语言,它不漂亮,但是它管理得很好。希望有人能在我之外得到一些有用的东西。

见问题解释不同类型的3D矩阵。STL标签用于C++标准模板库,是你的意图吗?不。现在就修改标签。我还修改了Objuturn。与bufferGeometry一起工作的er脚本功能类似。您如何对进行相同的更改?自从我得到一个空文件后,该导出器似乎不再工作。知道如何处理新的动画吗?我尝试复制代码,但几何体结构不同,我没有足够的知识来适应它