three.js-bone

Three.js学习笔记 本篇介绍bone的创建和绑定。完成简单的骨骼动画。

初始化数据、创建骨骼

这里我们使用Cylinder来创建一段几何图形模拟具有骨骼的物体。
你可以比作人的身体而我们创建的bones骨骼以及skeleton骨架就相当于人的脊椎。

    
    //每段高度,这里指骨骼长度
    var segmentHeight = 6;
    
    //分段数量,这里指骨骼数量
    var segmentCount = 1;
    
    //骨架总高度 `6`
    var height = segmentHeight * segmentCount;
    
    //骨架一半的高度 `3`
    var halfHeight = height * 0.5;
    var sizing = {
                    segmentHeight: segmentHeight,
                    segmentCount: segmentCount,
                    height: height,
                    halfHeight: halfHeight
                };

    
    function createGeometry(sizing) {
                var geometry = new THREE.CylinderGeometry(
                    0.5, //圆柱头部半径
                    0.5, //圆柱底部半径
                    sizing.height,   // 骨架高度`6` 
                    32,
                    sizing.segmentCount * 6, // 骨骼数`6`
                    true 
                );
                
                //遍历几何图形上的所有顶点
                for (var i = 0; i < geometry.vertices.length; i++) {
                
                    var vertex = geometry.vertices[i];
                    
                    
                /*  计算顶点索引值 `skinIndex` (受那个骨骼影响)
                 *  先将原来 `vertice `顶点的 `y `坐标加上骨架的一半高度,
                 *  相当于将原来在骨架顶部的 `y `轴坐标原点上移到骨骼 `y `轴的中心处
                 *   |                                          |
                 *   |                                          |
                 *   |                +  sizing.halfHeight =    |. `y`坐标原点   
                 *   |                                          |
                 *   |                                          |
                 *   |. `y`坐标原点                                                                               |
                 *
                 *  然后除以骨骼数,然后向下取整便可取到索引值
                 *
                 * */                   
                    
                    
                    var y = (vertex.y + sizing.halfHeight);
                    var skinIndex = Math.floor(y / sizing.segmentHeight);
                    
                    
                /*  计算权重`skinWeight`受骨骼影响的比重
                 *   
                 *  y % sizing.segmentHeight (这里的y是偏移过的也就是加了`sizing.halfHeight`)
                 * 
                 *  这里取余可以求出相对一根骨骼底部的偏移量(因为索引值上面已经求出来了)
                 *  再除以骨架的高度,便可以求出相对于权重
                 * 
                 * */                   
                 
                    var skinWeight = (y % sizing.segmentHeight) / sizing.segmentHeight;
                    
                    //放入相应的`geometry`属性中
                    geometry.skinIndices.push(new THREE.Vector4(skinIndex, skinIndex + 1, 0, 0));
                    geometry.skinWeights.push(new THREE.Vector4(1 - skinWeight, skinWeight, 0, 0));
                }
                return geometry;
            };
    

创建骨架和蒙皮


    function createMesh(geometry, bones) {
                
                //创建骨骼材质
                var material = new THREE.MeshPhongMaterial({
                    skinning: true,
                    color:0xff0000
                });
                
                //创建蒙皮对象
                var mesh = new THREE.SkinnedMesh(geometry, material);
                
                //通过已有的骨骼创建骨架
                var skeleton = new THREE.Skeleton(bones);
                
                //从蒙皮,将蒙皮对象和骨架绑定
                mesh.add(bones[0]);
                mesh.bind(skeleton);
                
                return mesh;
            };

SkinnedMesh

蒙皮对象。

Constructor

    var mesh = THREE.SkinnedMesh( geometry, material );
Main Properties
  • geometry :一种几个图形,需要设置Geometry.skinIndices(索引值)和 Geometry.skinWeights(权重)
  • material :材质,需要设置skinning: true

Skeleton

创建身体


    var geometry = createGeometry(sizing);
    var bones = createBones(sizing);
                
    mesh = createMesh(geometry, bones);
    
    scene.add(mesh);

活动身体

现在只需要在render()里面操作骨骼就可以产生简单的骨骼动画了。

    function render() {
    
            requestAnimationFrame(render);
            renderer.render(scene, camera);
            
            //操作第二个骨骼进行旋转
            mesh.skeleton.bones[1].rotation.x = Math.PI / 180 * 30;
            mesh.skeleton.bones[1].rotation.z = Math.PI / 180 * 30;
            }

outPut

转载于:https://www.cnblogs.com/chenjy1225/p/9640500.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值