gpt4 book ai didi

javascript - Three.JS - 使用相同的骨骼结构在 SkinnedMeshes 之间共享骨架

转载 作者:行者123 更新时间:2023-12-05 07:01:37 25 4
gpt4 key购买 nike

我一直在努力寻找一种方法来向现有骨架添加/移除衣服部分(衣服网格和 body 网格应该共享骨架)但我总是得到有趣/奇怪的结果。

我期待附加到共享骨架的所有衣服都已导出到具有相同骨架的 Blender,它们都共享相同的骨骼名称和结构,我认为是这样会让事情变得非常简单。

我在 Native iOS SceneKit 上使用了这些相同的 3D 文件,我实际上只是做了类似 clothing.skeleton = body.skeleton

但正如我所说,在 Three.JS 上似乎并不那么简单。

我试过类似的东西

clothingMesh.bind(bodySkeleton,clothingMesh.worldMatrix);

还试过:

clothingMesh.skeleton = bodySkeleton;
bodySkeleton.update();

但总是以奇怪的结果结束。我看过一些使用“ratargeting”函数的代码,但我相信这些仅在骨骼名称不匹配时使用,而我的情况并非如此。

JSFiddle Playground

我一直在通过 JSFiddle 研究它 https://jsfiddle.net/cabada/sxv4kbnm/ 那里有完整的代码,我正在尝试构建这个概念。

我修复骨架绑定(bind)方式的另一个目标是能够从其他来源复制骨架动画,这样我就可以即时下载它们并将它们动态应用到我的 Angular 色中。但是同样,得到奇怪的结果,动画骨架也共享与要设置动画的目标骨架相同的骨骼名称和结构。

我在网上找到的与该主题相关的资源和示例

https://raw.githack.com/funwithtriangles/three.js/dev/examples/webgl_animation_sharedskeleton.html

https://rawcdn.githack.com/mrdoob/three.js/r105/examples/webgl_loader_sea3d_bvh_retarget.html

https://jsfiddle.net/satori99/pay0oqcd/

https://github.com/mrdoob/three.js/pull/16608

Illustration

目标是能够在 body 上添加/删除衣服,使每个 Angular 色的所有网格都使用一个骨架(以实现良好的性能),并且能够添加/删除来自其他来源的动画。

最佳答案

您好,我遇到了同样的问题,我尝试使用下面编写的函数来解决您的问题,但没有成功。你能解决问题吗?

我尝试在更改 Angular 色的几何蒙皮网格后使用 bakeSkeleton(MyCharacterName)。该函数没有给我控制台错误,但显示变形为爆炸的 Angular 色?

    function bakeSkeleton ( target ) {
var v1 = new THREE.Vector3();

target.traverse( function ( object ) {
if ( !object.isSkinnedMesh ) return;
if ( object.geometry.isBufferGeometry !== true ) throw new Error( 'Only BufferGeometry supported.' );

var positionAttribute = object.geometry.getAttribute( 'position' );
var normalAttribute = object.geometry.getAttribute( 'normal' );

for ( var j = 0; j < positionAttribute.count; j ++ ) {
object.boneTransform( j, v1 );
positionAttribute.setXYZ( j, v1.x, v1.y, v1.z);

getBoneNormalTransform.call( object, j, v1 );
normalAttribute.setXYZ( j, v1.x, v1.y, v1.z );
}

positionAttribute.needsUpdate = true;
normalAttribute.needsUpdate = true;

object.skeleton.bones.forEach(bone => bone.rotation.set(0,0,0));
} );
}

const getBoneNormalTransform = (function () {

var baseNormal = new THREE.Vector3();

var skinIndex = new THREE.Vector4();
var skinWeight = new THREE.Vector4();

var vector = new THREE.Vector3();
var matrix = new THREE.Matrix4();
var matrix3 = new THREE.Matrix3();

return function ( index, target ) {

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 );

for ( var i = 0; i < 4; i ++ ) {

var weight = skinWeight.getComponent( i );

if ( weight !== 0 ) {

var boneIndex = skinIndex.getComponent( i );

matrix.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );

target.addScaledVector( vector.copy( baseNormal ).applyNormalMatrix( matrix3.getNormalMatrix(matrix) ), weight );

}

}

matrix3.getNormalMatrix(this.bindMatrixInverse);

return target.applyNormalMatrix( matrix3 );

};

}());

关于javascript - Three.JS - 使用相同的骨骼结构在 SkinnedMeshes 之间共享骨架,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63797734/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com