THREE.js - 将THREE.SkinnedMesh添加到自定义骨架结构

时间:2016-06-01 01:57:48

标签: javascript three.js

我尝试使用THREE.BoneTHREE.SkeletonTHREE.SkinnedMesh类在THREE.js中定义人体模型。

我定义了一个由12个正文部分组成的自定义骨架结构,每个部分都是THREE.Bone个实例,并使用.add()方法定义它们之间的父/子关系。最后,我创建了一个标准THREE.Object3D作为完整骨架父体的体根。

仅发布结构的一部分以简洁:

// create person object
var body_root = new THREE.Object3D()

// create torso
var torso  = new THREE.Bone();
torso.id   = 1;
torso.name = "torso";
x_t = 0;
y_t = 0;
z_t = 0;
torso.position.set(x_t,y_t,z_t);
x_alpha = 0 * Math.PI;
y_alpha = 0 * Math.PI;
z_alpha = 0 * Math.PI;
torso.rotation.set(x_alpha,y_alpha,z_alpha);

// create right arm
var right_arm = new THREE.Bone();
right_arm.id   = 2;
right_arm.name = "right_arm";
x_t = -TORSO_WIDTH / 2;
y_t = TORSO_HEIGHT;
z_t = 0;
right_arm.position.set(x_t,y_t,z_t);
x_alpha = 0 * Math.PI;
y_alpha = 0 * Math.PI;
z_alpha = 0 * Math.PI;
right_arm.rotation.set(x_alpha,y_alpha,z_alpha);

// add right_arm as child of torso
torso.add( right_arm );

这很好用,加载页面后我可以访问模型并通过控制台正确遍历它。

然而,当我尝试在场景中渲染骨架时,事情变得棘手。

1。如何为自定义骨架结构添加THREE.SkinnedMesh

documentation(查看源代码)中,为所有骨骼共同创建CylinderGeometrySkinnedMesh

var geometry = new THREE.CylinderGeometry( 5, 5, 5, 5, 15, 5, 30 );
var mesh = THREE.SkinnedMesh( geometry, material );

然后骨骼结构绑定:

// See example from THREE.Skeleton for the armSkeleton
var rootBone = armSkeleton.bones[ 0 ];
mesh.add( rootBone );
// Bind the skeleton to the mesh
mesh.bind( armSkeleton );

这非常适用于文档中的简单示例(下一个的每个父节点共有5个骨骼),但是如何将此示例调整为更复杂的结构,其中一些骨骼有多个子节点?我如何实现具有不同几何形状的骨骼?例如,我想实现像肩膀和肘关节这样的关节,我只能用不同基底半径的圆柱来改变旋转和身体部位,如手臂和前臂。

是否可以单独为每个关节定义SkinnedMesh,并且结构比示例中的更复杂?如果是这样,你怎么把它们连在一起呢?

2。我是否可以在不定义蒙皮网格的情况下向场景添加THREE.SkeletonHelper但仅使用骨骼?

由于我不知道问题1的答案,所以我决定简单地尝试渲染骨架结构。通过创建THREE.SkeletonHelper实例并将其添加到场景中,可以在其他示例(例如this one)中完成此操作。

我尝试将body_root变量(而不是SkinnedMesh)传递给构造函数,并创建了帮助程序,但未呈现。

helper = new THREE.SkeletonHelper( body_root );
helper.material.linewidth = 3;
scene.add( helper );

为了可视化帮助器,它需要绑定到网格物体,即使网格没有直接添加到场景中,即添加线mesh.bind(armSkeleton)也可以看到骨架帮助器。

这是否可以在不定义网格的情况下可视化骨架帮助器?如果是这样的话?

关于问题2的注释:

我相信这应该是可能的,因为THREE.SkeletonHelper类在内部定义了自己的几何和材质,所以应该可以渲染它而不需要骨架的网格:

THREE.SkeletonHelper = function ( object ) {

    this.bones = this.getBoneList( object );

    var geometry = new THREE.Geometry();

    for ( var i = 0; i < this.bones.length; i ++ ) {

        var bone = this.bones[ i ];

        if ( bone.parent instanceof THREE.Bone ) {

            geometry.vertices.push( new THREE.Vector3() );
            geometry.vertices.push( new THREE.Vector3() );
            geometry.colors.push( new THREE.Color( 0, 0, 1 ) );
            geometry.colors.push( new THREE.Color( 0, 1, 0 ) );

        }

    }

    geometry.dynamic = true;

    var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors, depthTest: false, depthWrite: false, transparent: true } );

    THREE.LineSegments.call( this, geometry, material );

    this.root = object;

    this.matrix = object.matrixWorld;
    this.matrixAutoUpdate = false;

    this.update();

};

0 个答案:

没有答案