Javascript Three.js-蒙皮骨骼网格实例、动画和混合
我正在开发一个小型多人游戏,它有一个单一皮肤的玩家网格,许多玩家都在使用它。一些背景:我尝试过通过maya和blender collada导出加载。两者似乎都引用了某种形式的动画数据,但我无法让它工作。我试过maya JSON导出器,它只使用一条材质线就可以导出小1k文件。最后,搅拌机工作了。对于那些也尝试加载蒙皮网格的用户,我发现这非常有用: 现在我有了一个来自JSON加载程序的Javascript Three.js-蒙皮骨骼网格实例、动画和混合,javascript,animation,opengl-es,three.js,skeletal-mesh,Javascript,Animation,Opengl Es,Three.js,Skeletal Mesh,我正在开发一个小型多人游戏,它有一个单一皮肤的玩家网格,许多玩家都在使用它。一些背景:我尝试过通过maya和blender collada导出加载。两者似乎都引用了某种形式的动画数据,但我无法让它工作。我试过maya JSON导出器,它只使用一条材质线就可以导出小1k文件。最后,搅拌机工作了。对于那些也尝试加载蒙皮网格的用户,我发现这非常有用: 现在我有了一个来自JSON加载程序的几何体对象和材质数组 我可以在材质上设置skinning=true,创建THREE.skindmesh,将其添加到场
几何体
对象和材质
数组
我可以在材质上设置skinning=true
,创建THREE.skindmesh
,将其添加到场景中,通过THREE.AnimationHandler.add添加动画(我不清楚AnimationHandler
实际做什么),创建THREE.Animation
,调用play()
和更新(dt)
。最后,我在场景中播放了一个网格和一个动画
现在我想要的是这些
多个实例-我希望在我的场景中运行多个播放器模型
- 我不希望多次加载相同的网格和动画数据
- 动画时间应该是每个实例的时间(因此它们不会同步动画)
我应该为同一个模型创建多个THREE.skindmesh
和THREE.Animation
?THREE.AnimationHandler
从哪里来
许多动画-我希望空闲/运行周期能够单独播放
好吧,这里只有一个动画关键帧的时间轴。Three.js是如何为我进行分区的,还是我必须手动进行分区
动画混合-当角色停止运行并静止不动时,我不希望从一个动画到另一个动画的瞬间捕捉。我想暂停跑步动画并将该状态混合回空闲动画
对于蒙皮网格(而不是变形目标),当前是否可以这样做?有关于这方面的例子或文档吗
任何信息都将不胜感激,哪怕只是朝着正确的方向轻推一下。我还没有读完完整的教程,我想了解一些关于这些特性的更高层次的信息
我可以很高兴地实现2和3,但我想了解一些关于threejs蒙皮和动画框架的信息/描述性文档,以帮助我入门。比如说,这并没有什么可谈的
[编辑]
谢谢,@NishchitDhanani,这个页面很好,但没有提到多个动画或混合骨骼动画:
本页说,多个动画仍然是当前的问题,但不是更多(在评论中讨论了一些):
目前的答案是
使用许多THREE.skindmesh
,但仍然不能确定THREE.AnimationHandler
不知道。也许有一种方法可以在THREE.Animation
中手动修改开始/结束关键帧
还没有完全实现。我可能会尝试创建一个自定义着色器,可以使用两个3.Animation
s并在它们之间进行插值
我已经能够同时部署四个不同的动画模型,使用Blender创建并导出为JSON文件,方法是使用JSON加载程序的单独定制功能为每个模型创建单独的蒙皮网格。我的四个模型中的每一个都有不同的网格、动画、纹理和关键帧数
var loader = new THREE.JSONLoader();
loader.load("model_1.js", createSkinnedMeshforModel_1);
loader.load("model_2.js", createSkinnedMeshforModel_2);
loader.load("model_3.js", createSkinnedMeshforModel_3);
...
var animations = [];
function createSkinnedMeshforModel_1( geometry, materials )
{
var myModel1, animation;
THREE.AnimationHandler.add( geometry.animation );
myModel1 = new THREE.SkinnedMesh(geometry, new THREE.MeshFaceMaterial(materials));
enableSkinning( myModel1 );
scene.add( myModel1 );
animation = new THREE.Animation(myModel1, Model1_Animation_title, THREE.AnimationHandler.CATMULLROM);
animations.push( animation );
for( var i = 0; i < animations.length; i ++ )
{
animations[ i ].play();
}
}
function createSkinnedMeshforModel_2( geometry, materials )
{
var myModel2, animation;
THREE.AnimationHandler.add( geometry.animation );
myModel2 = new THREE.SkinnedMesh(geometry, new THREE.MeshFaceMaterial(materials));
enableSkinning( myModel2 );
scene.add( myModel2 );
animation = new THREE.Animation(myModel2, Model2_Animation_title, THREE.AnimationHandler.CATMULLROM);
animations.push( animation );
for( var i = 0; i < animations.length; i ++ )
{
animations[ i ].play();
}
}
function createSkinnedMeshforModel_3( geometry, materials )
{
var myModel3, animation;
THREE.AnimationHandler.add( geometry.animation );
myModel3 = new THREE.SkinnedMesh(geometry, new THREE.MeshFaceMaterial(materials));
enableSkinning( myModel3 );
scene.add( myModel3 );
animation = new THREE.Animation(myModel3, Model3_Animation_title, THREE.AnimationHandler.CATMULLROM);
animations.push( animation );
for( var i = 0; i < animations.length; i ++ )
{
animations[ i ].play();
}
}
也许这种方法为问题1提供了某种解决方案,也可能为问题2提供了某种解决方案
关于问题2,Three.js版本r62更新了Blender exporter以允许“导出多个操作”。虽然我还没有尝试过,但这可能允许加载给定模型的两个或多个副本,同时为不同的动作指定动画标题。当需要执行不同的操作时,可以在视图中交换模型
如果可行,那么问题3的一个可能解决方案可能是在Blender中创建一个额外的动画动作,将模型从活动状态混合到空闲状态。自第67版(2014年4月)起,支持骨骼动画混合和多个动画。您仍然需要为每个模型创建一个skindmesh
。AnimationHandler
负责每帧更新(勾选)动画,因此您应该在该帧上调用update,而不是在每个动画上手动调用update
请参阅新添加的示例:webgl\u animation\u skining\u blending.html,或者在此处查看我自己的几个示例:
@Xealgo:有一个新的Maya导出器,它也可以处理骨骼和动画。几个月前,在我被迫使用Blender工作流之前,我很想拥有它。:)
这里有一个链接:任何人对必须从MAYA 2013导出场景的人有任何建议,都没有其他选项。除了将其导入不同的programs@RyanBlevins我正在使用collada制作我的水平网格+灯光等。这只是骨骼动画,我无法工作。collada加载程序为您提供一个具有.scene
的对象。您可以添加整个对象,也可以从其子对象中拾取和选择。它必须具有蒙皮骨骼动画。在站点上的任何位置都看不到webgl动画蒙皮混合示例,并且,导出具有多个动画的混合器模型并加载三个版本66会引发错误未捕获的TypeError:无法读取未定义的“任何想法”的属性“名称”?是的,它位于当前的“开发”分支上,尚未进入版本发布。啊,好吧!我应该意识到:p谢谢。
animations[ i ].pause();
... (random delay) ...
animations[ i ].play();