topical media & game development
student-ar-org-papervision3d-core-controller-SkinController.ax
student-ar-org-papervision3d-core-controller-SkinController.ax
[swf]
flex
package org.papervision3d.core.controller
{
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.special.Skin3D;
public class @ax-student-ar-org-papervision3d-core-controller-SkinController implements IObjectController
{
public var poseMatrix:Matrix3D;
public var bindShapeMatrix:Matrix3D;
public var target:Skin3D;
public var joints:Array;
public var invBindMatrices:Array;
public var vertexWeights:Array;
Constructor.
@param target
public function @ax-student-ar-org-papervision3d-core-controller-SkinController(target:Skin3D)
{
this.target = target;
this.joints = new Array();
this.invBindMatrices = new Array();
this.vertexWeights = new Array();
}
Update.
public function update():void
{
if(!joints.length || !bindShapeMatrix)
return;
if(!_cached)
cacheVertices();
if(invBindMatrices.length != this.joints.length)
return;
var vertices:Array = target.geometry.vertices;
var i:int;
// reset mesh's vertices to 0
for(i = 0; i < vertices.length; i++)
vertices[i].x = vertices[i].y = vertices[i].z = 0;
// skin the mesh!
for(i = 0; i < joints.length; i++)
skinMesh(joints[i], this.vertexWeights[i], invBindMatrices[i], _cached, vertices);
}
Cache original vertices.
private function cacheVertices():void
{
this.target.transformVertices(this.bindShapeMatrix);
this.target.geometry.ready = true;
var vertices:Array = this.target.geometry.vertices;
_cached = new Array(vertices.length);
for(var i:int = 0; i < vertices.length; i++)
_cached[i] = new Number3D(vertices[i].x, vertices[i].y, vertices[i].z);
}
Skins a mesh.
@param joint
@param meshVerts
@param skinnedVerts
private function skinMesh(joint:DisplayObject3D, weights:Array, inverseBindMatrix:Matrix3D, meshVerts:Array, skinnedVerts:Array):void
{
var i:int;
var pos:Number3D = new Number3D();
var original:Number3D;
var skinned:Vertex3D;
var matrix:Matrix3D = Matrix3D.multiply(joint.world, inverseBindMatrix);
for( i = 0; i < weights.length; i++ )
{
var weight:Number = weights[i].weight;
var vertexIndex:int = weights[i].vertexIndex;
if( weight <= 0.0001 || weight >= 1.0001) continue;
original = meshVerts[ vertexIndex ];
skinned = skinnedVerts[ vertexIndex ];
pos.x = original.x;
pos.y = original.y;
pos.z = original.z;
// joint transform
Matrix3D.multiplyVector(matrix, pos);
//update the vertex
skinned.x += (pos.x * weight);
skinned.y += (pos.y * weight);
skinned.z += (pos.z * weight);
}
}
private var _cached:Array;
}
}
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.