我需要在场景中拥有多个相同的动画模型。如果可能的话,我希望他们有一个共享的几何和材料,但如果不可能,那么每个模型实例化它们就足够了。
不幸的是,我发现实现此结果的唯一方法是为每个模型实例通过JSONLoader。
SkinnedMesh确实有一个clone()方法,但似乎还没有完全实现。如果使用并且场景中存在原始网格和克隆网格,则只会出现一个,克隆一个将没有动画。
我试图将此示例用于共享骨架: https://github.com/mrdoob/three.js/pull/11666
......确实它有效,但我需要能够为每个模型实例播放不同的动画,让它们都玩相同的动画是不够的,遗憾的是。我希望我可以做类似的hax并插入我自己的骨架(由JSON文件中的骨骼制成),但它的表现非常类似于我只使用了SkinnedMesh中的clone()。
我正在使用此代码: https://github.com/arturitu/threejs-animation-workflow/blob/master/js/main.js
基本上我想要实现的是
var onLoad = function (geometry, materials) {
window.geometry = geometry;
character = new THREE.SkinnedMesh(
geometry,
new THREE.MeshFaceMaterial(materials)
);
character2 = character.someMagicalClone();
scene.add(character);
scene.add(character2);
(...)
我需要任何线索......当我等待帮助时,我忙着为SkinnedMesh和JSONLoader解构构造函数以获取线索;)
提前致谢!
答案 0 :(得分:0)
我在此拉取请求中找到了解决方案: https://github.com/mrdoob/three.js/pull/14494
简而言之,添加了两个功能:
function cloneAnimated( source ) {
var cloneLookup = new Map();
var clone = source.clone();
parallelTraverse( source, clone, function ( sourceNode, clonedNode ) {
cloneLookup.set( sourceNode, clonedNode );
} );
source.traverse( function ( sourceMesh ) {
if ( ! sourceMesh.isSkinnedMesh ) return;
var sourceBones = sourceMesh.skeleton.bones;
var clonedMesh = cloneLookup.get( sourceMesh );
clonedMesh.skeleton = sourceMesh.skeleton.clone();
clonedMesh.skeleton.bones = sourceBones.map( function ( sourceBone ) {
if ( ! cloneLookup.has( sourceBone ) ) {
throw new Error( 'THREE.AnimationUtils: Required bones are not descendants of the given object.' );
}
return cloneLookup.get( sourceBone );
} );
clonedMesh.bind( clonedMesh.skeleton, sourceMesh.bindMatrix );
} );
return clone;
}
function parallelTraverse( a, b, callback ) {
callback( a, b );
for ( var i = 0; i < a.children.length; i ++ ) {
parallelTraverse( a.children[ i ], b.children[ i ], callback );
}
}
据我了解,它会将克隆的骨架重新绑定到克隆的网格。 所以主题示例可能像这样:
var onLoad = function (geometry, materials) {
window.geometry = geometry;
character = new THREE.SkinnedMesh(
geometry,
new THREE.MeshFaceMaterial(materials)
);
character2 = cloneAnimated(character); // <-- used that new function
scene.add(character);
scene.add(character2);
(...)