- /**
- * @class PlaneShape
- * @param orientation {Number} index of axis which is the plane's normal ( 0 = X, 1 = Y, 2 = Z )
- * @param half_width {Number} half width of the plane
- * @param half_length {Number} half height of the plane
- * @constructor
- */
- Goblin.PlaneShape = function( orientation, half_width, half_length ) {
- /**
- * index of axis which is the plane's normal ( 0 = X, 1 = Y, 2 = Z )
- * when 0, width is Y and length is Z
- * when 1, width is X and length is Z
- * when 2, width is X and length is Y
- *
- * @property half_width
- * @type {Number}
- */
- this.orientation = orientation;
-
- /**
- * half width of the plane
- *
- * @property half_height
- * @type {Number}
- */
- this.half_width = half_width;
-
- /**
- * half length of the plane
- *
- * @property half_length
- * @type {Number}
- */
- this.half_length = half_length;
-
- this.aabb = new Goblin.AABB();
- this.calculateLocalAABB( this.aabb );
-
-
- if ( this.orientation === 0 ) {
- this._half_width = 0;
- this._half_height = this.half_width;
- this._half_depth = this.half_length;
- } else if ( this.orientation === 1 ) {
- this._half_width = this.half_width;
- this._half_height = 0;
- this._half_depth = this.half_length;
- } else {
- this._half_width = this.half_width;
- this._half_height = this.half_length;
- this._half_depth = 0;
- }
- };
-
- /**
- * Calculates this shape's local AABB and stores it in the passed AABB object
- *
- * @method calculateLocalAABB
- * @param aabb {AABB}
- */
- Goblin.PlaneShape.prototype.calculateLocalAABB = function( aabb ) {
- if ( this.orientation === 0 ) {
- this._half_width = 0;
- this._half_height = this.half_width;
- this._half_depth = this.half_length;
-
- aabb.min.x = 0;
- aabb.min.y = -this.half_width;
- aabb.min.z = -this.half_length;
-
- aabb.max.x = 0;
- aabb.max.y = this.half_width;
- aabb.max.z = this.half_length;
- } else if ( this.orientation === 1 ) {
- this._half_width = this.half_width;
- this._half_height = 0;
- this._half_depth = this.half_length;
-
- aabb.min.x = -this.half_width;
- aabb.min.y = 0;
- aabb.min.z = -this.half_length;
-
- aabb.max.x = this.half_width;
- aabb.max.y = 0;
- aabb.max.z = this.half_length;
- } else {
- this._half_width = this.half_width;
- this._half_height = this.half_length;
- this._half_depth = 0;
-
- aabb.min.x = -this.half_width;
- aabb.min.y = -this.half_length;
- aabb.min.z = 0;
-
- aabb.max.x = this.half_width;
- aabb.max.y = this.half_length;
- aabb.max.z = 0;
- }
- };
-
- Goblin.PlaneShape.prototype.getInertiaTensor = function( mass ) {
- var width_squared = this.half_width * this.half_width * 4,
- length_squared = this.half_length * this.half_length * 4,
- element = 0.0833 * mass,
-
- x = element * length_squared,
- y = element * ( width_squared + length_squared ),
- z = element * width_squared;
-
- if ( this.orientation === 0 ) {
- return new Goblin.Matrix3(
- y, 0, 0,
- 0, x, 0,
- 0, 0, z
- );
- } else if ( this.orientation === 1 ) {
- return new Goblin.Matrix3(
- x, 0, 0,
- 0, y, 0,
- 0, 0, z
- );
- } else {
- return new Goblin.Matrix3(
- y, 0, 0,
- 0, z, 0,
- 0, 0, x
- );
- }
- };
-
- /**
- * Given `direction`, find the point in this body which is the most extreme in that direction.
- * This support point is calculated in world coordinates and stored in the second parameter `support_point`
- *
- * @method findSupportPoint
- * @param direction {vec3} direction to use in finding the support point
- * @param support_point {vec3} vec3 variable which will contain the supporting point after calling this method
- */
- Goblin.PlaneShape.prototype.findSupportPoint = function( direction, support_point ) {
- /*
- support_point = [
- sign( direction.x ) * _half_width,
- sign( direction.y ) * _half_height,
- sign( direction.z ) * _half_depth
- ]
- */
-
- // Calculate the support point in the local frame
- if ( direction.x < 0 ) {
- support_point.x = -this._half_width;
- } else {
- support_point.x = this._half_width;
- }
-
- if ( direction.y < 0 ) {
- support_point.y = -this._half_height;
- } else {
- support_point.y = this._half_height;
- }
-
- if ( direction.z < 0 ) {
- support_point.z = -this._half_depth;
- } else {
- support_point.z = this._half_depth;
- }
- };
-
- /**
- * Checks if a ray segment intersects with the shape
- *
- * @method rayIntersect
- * @property start {vec3} start point of the segment
- * @property end {vec3{ end point of the segment
- * @return {RayIntersection|null} if the segment intersects, a RayIntersection is returned, else `null`
- */
- Goblin.PlaneShape.prototype.rayIntersect = (function(){
- var normal = new Goblin.Vector3(),
- ab = new Goblin.Vector3(),
- point = new Goblin.Vector3(),
- t;
-
- return function( start, end ) {
- if ( this.orientation === 0 ) {
- normal.x = 1;
- normal.y = normal.z = 0;
- } else if ( this.orientation === 1 ) {
- normal.y = 1;
- normal.x = normal.z = 0;
- } else {
- normal.z = 1;
- normal.x = normal.y = 0;
- }
-
- ab.subtractVectors( end, start );
- t = -normal.dot( start ) / normal.dot( ab );
-
- if ( t < 0 || t > 1 ) {
- return null;
- }
-
- point.scaleVector( ab, t );
- point.add( start );
-
- if ( point.x < -this._half_width || point.x > this._half_width ) {
- return null;
- }
-
- if ( point.y < -this._half_height || point.y > this._half_height ) {
- return null;
- }
-
- if ( point.z < -this._half_depth || point.z > this._half_depth ) {
- return null;
- }
-
- var intersection = Goblin.ObjectPool.getObject( 'RayIntersection' );
- intersection.object = this;
- intersection.t = t * ab.length();
- intersection.point.copy( point );
- intersection.normal.copy( normal );
-
- return intersection;
- };
- })();
-