Three.js-将骨架变换为几何体

Three.js-将骨架变换为几何体,three.js,3d,Three.js,3d,在不使用GPU的情况下,将矩阵应用于顶点以使实际几何体表示变换后的形状的正确方法是什么 我有一个要应用的角色模型,我想以不同姿势进行3D打印,因此我想使用导出3D可打印文件,但它只导出原始几何体 如果我能以正确的顺序覆盖每个骨骼矩阵,我应该能够在应用变换的情况下导出STL,对吗 var对象=[]; var三角形=0; 场景.遍历(函数(对象){ if(object.isMesh){ var geometry=object.geometry; if(geometry.isBufferGeometr

在不使用GPU的情况下,将矩阵应用于顶点以使实际几何体表示变换后的形状的正确方法是什么

我有一个要应用的角色模型,我想以不同姿势进行3D打印,因此我想使用导出3D可打印文件,但它只导出原始几何体

如果我能以正确的顺序覆盖每个骨骼矩阵,我应该能够在应用变换的情况下导出STL,对吗

var对象=[];
var三角形=0;
场景.遍历(函数(对象){
if(object.isMesh){
var geometry=object.geometry;
if(geometry.isBufferGeometry){
几何体=新的三个.geometry().fromBufferGeometry(几何体);
}
//TODO:应用骨架变换
if(geometry.isGeometry){
三角形+=geometry.faces.length;
对象。推送({
几何:几何,
matrixWorld:object.matrixWorld
} );
}
}
} );

查看此拉取请求:

特别是这一部分:

THREE.SkinnedMesh.prototype.boneTransform = 
...snip...
for ( var i = 0; i < 4; i ++ ) {
+
+           var skinWeight = skinWeights[ properties[ i ] ];
+
+           if ( skinWeight != 0 ) {
+
+               var boneIndex = skinIndices[ properties[ i ] ];
+               tempMatrix.multiplyMatrices( this.skeleton.bones[ boneIndex ].matrixWorld, this.skeleton.boneInverses[ boneIndex ] );
+               result.add( temp.copy( clone ).applyMatrix4( tempMatrix ).multiplyScalar( skinWeight ) );
+
+           }
+
+       }
THREE.skindmesh.prototype.boneTransform=
剪
对于(变量i=0;i<4;i++){
+
+var skinWeight=skinWeights[属性[i]];
+
+如果(皮肤重量!=0){
+
+var boneIndex=皮肤指数[属性[i]];
+多矩阵(this.skeleton.bones[boneIndex].matrixWorld,this.skeleton.boneiinverses[boneIndex]);
+结果.添加(临时复制(克隆).ApplyMatrix x4(临时矩阵).multiplyScalar(皮肤重量));
+
+           }
+
+       }
因此,要烘焙变形,必须执行以下步骤:

  • 检查所有顶点
  • 获取相应的
    皮肤指数
    皮肤权重
  • 获取每个顶点的关联骨骼及其权重
  • 检查所有骨骼
  • 获取骨骼的变换矩阵,并将其转换为
    几何体的坐标系
  • 通过相关的
    skinWeights[boneIdx]
  • 应用最终矩阵

  • 编辑:修复问题的导出器版本。()

    在场景中烘焙,保留法线,不导出到STL

    用法:

    bakeSkeleton(网格)

    转换将应用于提供的对象及其所有子对象
    GetBonnermalTransform
    SkindMesh
    上的内置
    BonetTransform
    生成,但适用于法线

    
    功能bakeSkeleton(目标){
    var v1=新向量3();
    遍历(函数(对象){
    如果(!object.isSkinnedMesh)返回;
    如果(object.geometry.isBufferGeometry!==true)抛出新错误(“仅支持BufferGeometry”);
    var positionAttribute=object.geometry.getAttribute('position');
    var normalAttribute=object.geometry.getAttribute('normal');
    对于(var j=0;jbone.rotation.set(0,0,0));
    } );
    }
    常量GetBonnerMaltTransform=(函数(){
    var baseNormal=newvector3();
    var skindex=新向量4();
    var skinWeight=新向量4();
    var向量=新向量3();
    var矩阵=新矩阵4();
    var matrix3=新的matrix3();
    返回函数(索引、目标){
    var skeleton=this.skeleton;
    var geometry=this.geometry;
    skinIndex.fromBufferAttribute(geometry.attributes.skinIndex,index);
    skinWeight.fromBufferAttribute(geometry.attributes.skinWeight,index);
    baseNormal.fromBufferAttribute(geometry.attributes.normal,index).applyNormalMatrix(matrix3.getNormalMatrix(this.bindMatrix));
    target.set(0,0,0);
    对于(变量i=0;i<4;i++){
    var-weight=皮肤重量。getComponent(i);
    如果(重量!==0){
    var boneIndex=skinIndex.getComponent(i);
    多矩阵(skeleton.bones[boneIndex].matrixWorld,skeleton.boneInverses[boneIndex]);
    target.addScaledVector(vector.copy(baseNormal).applyNormalMatrix(matrix3.getNormalMatrix(matrix)),权重);
    }
    }
    matrix3.getNormalMatrix(this.bindMatrixInverse);
    返回目标。applyNormalMatrix(matrix3);
    };
    }())
    
    欢迎来到堆栈溢出。谢谢你回答我的问题。看来我有一些工作要做,以适应该代码。谢谢你的解释@wizulus你已经设法将其纳入出口商。如果没有的话,我会在接下来的几周里尽我最大的努力,因为我现在遇到了和你上面描述的完全相同的问题。当前主控形状中的STL导出器只会忽略蒙皮网格顶点上的所有骨骼变换。这是一个旧版本的解决方案,但由于SkinIndex和skinWeights的存储方式不同,可能是由于新的动画系统,这不再起作用。我制作了一个版本的导出器,该导出器与当前主控器一起工作,并在SkindMesh对象上合并顶点骨骼变换。