如何将Three.js场景中的几何体导出为已修改的OBJ?

时间:2016-05-06 16:09:00

标签: javascript three.js geometry export

每次从Three.js场景导出并保存模型(SkinnedMesh)时,都会保存原始导入的模型。即使我通过旋转骨骼并更改变形目标的值来修改模型,也会发生这种情况。

我已在控制台窗口中检查了几何体数据的更改,并显示骨骼和变形目标信息已更新。但出于某种原因,当我导出并保存时,不会保存更新的模型。

这是我的render()函数,其中模型被导出并保存为OBJ。

function render() {

    cube.rotation.x += guiControls.rotationX;
    cube.rotation.y += guiControls.rotationY;
    cube.rotation.z += guiControls.rotationZ;

    spotLight.position.x = guiControls.lightX;
    spotLight.position.y = guiControls.lightY;
    spotLight.position.z = guiControls.lightZ;

    camera.lookAt(lookAtPos);

        scene.traverse(function(child){
        if (child instanceof THREE.SkinnedMesh){  

            child.skeleton.bones[13].rotation.y = guiControls.Shoulder;
            child.scale.x = guiControls.ScaleX;
            child.scale.y = guiControls.ScaleY;
            child.scale.z = guiControls.ScaleZ;
            child.position.x = guiControls.PositionX;
            child.position.y = guiControls.PositionY;
            child.position.z = guiControls.PositionZ;

            child.geometry.dynamic = true;
            child.geometry.verticesNeedUpdate = true;
            child.geometry.elementsNeedUpdate = true;
            child.updateProjectionMatrix = true;

            if(save){
              var exporter = new THREE.OBJExporter();
              var result = exporter.parse(child);

              var saveData = (function () {
                var a = document.createElement("a");
                document.body.appendChild(a);
                a.style = "display: none";
                return function (data, fileName) {
                      var obj = data,
                      blob = new Blob([obj], {type: "octet/stream"}),
                      url = window.URL.createObjectURL(blob);
                  a.href = url;
                  a.download = fileName;
                  a.click();
                  window.URL.revokeObjectURL(url);
                };
              }());

              saveData(result, "ModelOBJExport.obj");

              save = false;
            }

        }
        else if  (child instanceof THREE.SkeletonHelper){
            child.update();
        }
    });

} 

这是一个包含我所有代码的JSFiddle - https://jsfiddle.net/markskelton/ord9gL1a/。我不确定如何上传我的模型,以便人们可以将其用于我的代码。

1 个答案:

答案 0 :(得分:0)

我不知道你的情况中是否有一些是多余的但这是在我的保存过程中。设置尺寸,位置和旋转后,请尝试:

    child.updateMatrix();
    child.geometry.applyMatrix(child.matrix);
    child.matrixAutoUpdate = true;
    //reset the matrix to identity if you want to be double sure the matrix is now actually ready for export.
    child.matrix.identity();

出于某种原因,这对人们不起作用。我正在添加我完整运行的功能,评论和所有。我不能说为什么其他人不能让这个工作。这对我来说很好。我会建议人们是否有问题,在新问题中显示代码和示例问题。

objSaver.prototype.modifyMeshToRhinoObj = function (mesh) {
        var exporter = new THREE.OBJExporter();
        //we do no save the original extrusion geometry. We clone it, match it's axis and scale to external settings, usually found in Rhino (non adjusted obj up), and save the clone.
        //This is so on re-import it is treated as if it came from any mesh tool.
        var polygonGeometry = new THREE.Geometry().fromBufferGeometry(mesh.geometry._bufferGeometry);
        var volumeClone = new THREE.Mesh(polygonGeometry, [
                new THREE.MeshBasicMaterial({ color: 16711680 }),
                new THREE.MeshBasicMaterial({ color: 16711680 })
        ]);
        volumeClone.scale.set(1, 1, mesh.scale.z);
        volumeClone.rotation.x = de2ra(180);
        volumeClone.rotation.z = de2ra(-90);
        volumeClone.updateMatrix();
        volumeClone.geometry.applyMatrix(volumeClone.matrix);
        volumeClone.matrixAutoUpdate = true;
        volumeClone.matrix.identity();
        volumeClone.geometry.verticesNeedUpdate = true;
        mesh.userData.cloned = true;
        mesh.userData.baseline = mesh.userData.buildingHeight;
        return exporter.parse(volumeClone);
};