three.js 源码注释(六十二)objects/SkinnedMesh.js

102 篇文章 12 订阅
100 篇文章 3 订阅

商域无疆 (http://blog.csdn.net/omni360/)

本文遵循“署名-非商业用途-保持一致”创作公用协议

转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化、GOLANG、Html5、WEBGL、THREE.JS否则,出自本博客的文章拒绝转载或再转载,谢谢合作。


俺也是刚开始学,好多地儿肯定不对还请见谅.

以下代码是THREE.JS 源码文件中objects/SkinnedMesh.js文件的注释.

更多更新在 : https://github.com/omni360/three.js.sourcecode


/**
 * @author mikael emtinger / http://gomo.se/
 * @author alteredq / http://alteredqualia.com/
 * @author ikerr / http://verold.com
 */
/*
///SkinnedMesh对象,蒙皮网格对象,蒙皮网格用于渲染人物。人物动画使用的骨骼,而且每个骨骼影响网格的一部分.
*/
///<summary>SkinnedMesh</summary>
///<param name ="geometry" type="THREE.Geometry">Geometry对象(灯笼的框架)</param>
///<param name ="material" type="THREE.Material">Material对象(材质对象)</param>
///<param name ="useVertexTexture" type="boolean">true 或者 false,是否使用顶点纹理,对象构建后,该属性不能修改.</param>
///<returns type="SkinnedMesh">返回SkinnedMesh对象</returns>
THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) {

	THREE.Mesh.call( this, geometry, material );	//调用Mesh对象的call方法,将原本属于Mesh的方法交给当前对象SkinnedMesh来使用.

	this.bindMode = "attached";		//绑定模式
	this.bindMatrix = new THREE.Matrix4();		//绑定矩阵
	this.bindMatrixInverse = new THREE.Matrix4();	//绑定矩阵的逆矩阵

	// init bones 初始化骨骼

	// TODO: remove bone creation as there is no reason (other than
	// convenience) for THREE.SkinnedMesh to do this.

	var bones = [];	//存储骨骼的数组,这个属性在构造函数中设置.

	if ( this.geometry && this.geometry.bones !== undefined ) {	

		var bone, gbone, p, q, s;

		for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++b ) {

			gbone = this.geometry.bones[ b ];

			p = gbone.pos;
			q = gbone.rotq;
			s = gbone.scl;

			bone = new THREE.Bone( this );
			bones.push( bone );

			bone.name = gbone.name;
			bone.position.set( p[ 0 ], p[ 1 ], p[ 2 ] );	//位置属性
			bone.quaternion.set( q[ 0 ], q[ 1 ], q[ 2 ], q[ 3 ] );	//四元数属性

			if ( s !== undefined ) {

				bone.scale.set( s[ 0 ], s[ 1 ], s[ 2 ] );	//缩放属性

			} else {

				bone.scale.set( 1, 1, 1 );	

			}

		}

		for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++b ) {

			gbone = this.geometry.bones[ b ];

			if ( gbone.parent !== - 1 ) {

				bones[ gbone.parent ].add( bones[ b ] );

			} else {

				this.add( bones[ b ] );

			}

		}

	}

	this.normalizeSkinWeights();	//构造SkinnedMesh对象时调用normalizeSkinWeights方法,确保skinWeights的各元素是归一化的.

	this.updateMatrixWorld( true );		//对当前对象及其子对象的matrix属性应用全局位移,旋转,缩放变换.
	this.bind( new THREE.Skeleton( bones, undefined, useVertexTexture ) );	//调用bind方法,绑定骨骼对象.

};

/*************************************************
****下面是SkinnedMesh对象的方法属性定义,继承自Mesh
**************************************************/
THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype );
/*
///bind方法将蒙皮网格对象根据绑定矩阵绑定骨架.
*/
///<summary>bind</summary>
///<param name ="skeleton" type="SkinnedMesh">骨骼数组</param>
///<param name ="bindMatrix" type="Matrix4">可选参数,绑定矩阵</param>
///<returns type="SkinnedMesh">蒙皮网格对象</returns>
THREE.SkinnedMesh.prototype.bind = function( skeleton, bindMatrix ) {

	this.skeleton = skeleton;

	if ( bindMatrix === undefined ) {	//如果没有指定绑定矩阵

		this.updateMatrixWorld( true );

		bindMatrix = this.matrixWorld;	//使用蒙皮网格对象的世界坐标矩阵.

	}

	this.bindMatrix.copy( bindMatrix );
	this.bindMatrixInverse.getInverse( bindMatrix );

};

/*pose方法
///pose方法重新计算蒙皮网格对象的骨架的计算本地矩阵,位置,旋转缩放属性
*/
///<summary>pose</summary>
///<returns type="Skeleton">返回包含新属性的蒙皮网格对象.</returns>	
THREE.SkinnedMesh.prototype.pose = function () {

	this.skeleton.pose();	//调用骨架对象的pose方法.

};

/*normalizeSkinWeights方法
///normalizeSkinWeights方法归一化蒙皮网格对象的蒙皮权重.
*/
///<summary>calculateInverses</summary>
///<returns type="Skeleton">返回新权重的蒙皮网格对象.</returns>	
THREE.SkinnedMesh.prototype.normalizeSkinWeights = function () {

	if ( this.geometry instanceof THREE.Geometry ) {

		for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {		//遍历蒙皮指数数组.

			var sw = this.geometry.skinWeights[ i ];		//蒙皮权重数组

			var scale = 1.0 / sw.lengthManhattan();		//求和sw的x,y,z分量

			if ( scale !== Infinity ) {		//scale不等于正无穷大

				sw.multiplyScalar( scale );		//sw的每个分量乘以scale

			} else {

				sw.set( 1 ); // this will be normalized by the shader anyway	//sw将被着色器归一化??????搞不明白.

			}

		}

	} else {

		// skinning weights assumed to be normalized for THREE.BufferGeometry
		// 蒙皮权重确保是归一化的 ,供THREE.BufferGeometry使用.

	}

};

/*
///updateMatrixWorld方法对当前对象及其子对象的matrix属性应用全局位移,旋转,缩放变换.
///NOTE: 在updateMatrixWorld方法中如果参数force为true,将对其子对象应用同样的全局变换.
*/
///<summary>updateMatrixWorld</summary>
///<param name ="force" type="Boolean">true或者false</param>
///<returns type="Object3D">返回新的SkinnedMesh对象</returns>		
THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) {

	THREE.Mesh.prototype.updateMatrixWorld.call( this, true );

	if ( this.bindMode === "attached" ) {	//当bindmode为attached

		this.bindMatrixInverse.getInverse( this.matrixWorld );

	} else if ( this.bindMode === "detached" ) {

		this.bindMatrixInverse.getInverse( this.bindMatrix );

	} else {

		console.warn( 'THREE.SkinnedMesh unreckognized bindMode: ' + this.bindMode );

	}

};

/*clone方法
///clone方法克隆一个SkinnedMesh蒙皮网格对象.
*/
///<summary>clone</summary>
///<param name ="object" type="SkinnedMesh">接收克隆的SkinnedMesh对象</param>
///<param name ="recursive" type="boolean">是否对子对象一一进行克隆</param>
///<returns type="Ray">返回SkinnedMesh蒙皮网格网格对象.</returns>	
THREE.SkinnedMesh.prototype.clone = function( object ) {

	if ( object === undefined ) {

		object = new THREE.SkinnedMesh( this.geometry, this.material, this.useVertexTexture );

	}

	THREE.Mesh.prototype.clone.call( this, object );	//继承Mesh的clone方法

	return object;	//返回SkinnedMesh蒙皮网格网格对象

};


商域无疆 (http://blog.csdn.net/omni360/)

本文遵循“署名-非商业用途-保持一致”创作公用协议

转载请保留此句:商域无疆 -  本博客专注于 敏捷开发及移动和物联设备研究:数据可视化、GOLANG、Html5、WEBGL、THREE.JS否则,出自本博客的文章拒绝转载或再转载,谢谢合作。


以下代码是THREE.JS 源码文件中objects/SkinnedMesh.js文件的注释.

更多更新在 : https://github.com/omni360/three.js.sourcecode

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值