topical media & game development

talk show tell print

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.