topical media & game development

talk show tell print

mobile-query-three-plugins-cannonjs-vendor-cannon.js-src-objects-Compound.js / js



  /*global CANNON:true */
  
  
@class CANNON.Compound @extends CANNON.Shape @brief A shape made of several other shapes.
author: schteppe

  
  CANNON.Compound = function(){
      CANNON.Shape.call(this);
      this.type = CANNON.Shape.types.COMPOUND;
      this.childShapes = [];
      this.childOffsets = [];
      this.childOrientations = [];
  };
  CANNON.Compound.prototype = new CANNON.Shape();
  CANNON.Compound.prototype.constructor = CANNON.Compound;
  
  
@method addChild @memberof CANNON.Compound @brief Add a child shape.
parameter: CANNON.Shape shape
parameter: CANNON.Vec3 offset
parameter: CANNON.Quaternion orientation

  
  CANNON.Compound.prototype.addChild = function(shape,offset,orientation){
      offset = offset || new CANNON.Vec3();
      orientation = orientation || new CANNON.Quaternion();
      this.childShapes.push(shape);
      this.childOffsets.push(offset);
      this.childOrientations.push(orientation);
  };
  
  CANNON.Compound.prototype.volume = function(){
      var r = 0.0;
      for(var i = 0; i<this.childShapes.length; i++)
          r += this.childShapes[i].volume();
      return r;
  };
  
  CANNON.Compound.prototype.calculateLocalInertia = function(mass,target){
      target = target || new CANNON.Vec3();
  
      // Calculate the total volume, we will spread out this objects' mass on the sub shapes
      var V = this.volume();
  
      for(var i = 0; i<this.childShapes.length; i++){
          // Get child information
          var b = this.childShapes[i];
          var o = this.childOffsets[i];
          var q = this.childOrientations[i];
          var m = b.volume() / V * mass;
  
          // Get the child inertia, transformed relative to local frame
          var inertia = b.calculateTransformedInertia(m,q);
  
          // Add its inertia using the parallel axis theorem, i.e.
          // I += I_child;    
          // I += m_child * r^2
  
          target.vadd(inertia,target);
          var mr2 = new CANNON.Vec3(m*o.x*o.x,
                                    m*o.y*o.y,
                                    m*o.z*o.z);
          target.vadd(mr2,target);
      }
      return target;
  };
  
  CANNON.Compound.prototype.boundingSphereRadius = function(){
      var r = 0.0;
      for(var i = 0; i<this.childShapes.length; i++){
          var candidate = this.childOffsets[i].norm() + this.childShapes[i].boundingSphereRadius();
          if(r < candidate)
              r = candidate;
      }
      return r;
  };
  
  var aabbmaxTemp = new CANNON.Vec3();
  var aabbminTemp = new CANNON.Vec3();
  var childPosTemp = new CANNON.Vec3();
  var childQuatTemp = new CANNON.Vec3();
  CANNON.Compound.prototype.calculateWorldAABB = function(pos,quat,min,max){
      var N=this.childShapes.length;
      min.set(Infinity,Infinity,Infinity);
      max.set(-Infinity,-Infinity,-Infinity);
      // Get each axis max
      for(var i=0; i<N; i++){
  
          // Accumulate transformation to child
          this.childOffsets[i].copy(childPosTemp);
          quat.vmult(childPosTemp,childPosTemp);
          pos.vadd(childPosTemp,childPosTemp);
          //quat.mult(this.childOrientations[i],childQuatTemp);
  
          // Get child AABB
          this.childShapes[i].calculateWorldAABB(childPosTemp,
                                                 this.childOrientations[i],
                                                 aabbminTemp,
                                                 aabbmaxTemp);
  
          if(aabbminTemp.x < min.x) min.x = aabbminTemp.x;
          if(aabbminTemp.y < min.y) min.y = aabbminTemp.y;
          if(aabbminTemp.z < min.z) min.z = aabbminTemp.z;
          
          if(aabbmaxTemp.x > max.x) max.x = aabbmaxTemp.x;
          if(aabbmaxTemp.y > max.y) max.y = aabbmaxTemp.y;
          if(aabbmaxTemp.z > max.z) max.z = aabbmaxTemp.z;
      }
  };


(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.