1 /**
  2  * The Render Engine
  3  * PrismaticJointComponent
  4  *
  5  * @fileoverview A prismatic joint which can be used in a {@link Simulation}.
  6  *
  7  * @author: Brett Fattori (brettf@renderengine.com)
  8  *
  9  * @author: $Author: bfattori $
 10  * @version: $Revision: 1555 $
 11  *
 12  * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 13  *
 14  * Permission is hereby granted, free of charge, to any person obtaining a copy
 15  * of this software and associated documentation files (the "Software"), to deal
 16  * in the Software without restriction, including without limitation the rights
 17  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 18  * copies of the Software, and to permit persons to whom the Software is
 19  * furnished to do so, subject to the following conditions:
 20  *
 21  * The above copyright notice and this permission notice shall be included in
 22  * all copies or substantial portions of the Software.
 23  *
 24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 26  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 27  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 28  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 29  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 30  * THE SOFTWARE.
 31  *
 32  */
 33 
 34 // The class this file defines and its required classes
 35 R.Engine.define({
 36     "class":"R.components.physics.PrismaticJoint",
 37     "requires":[
 38         "R.components.physics.BaseMotorJoint",
 39         "R.physics.Simulation",
 40         "R.math.Math2D"
 41     ]
 42 });
 43 
 44 /**
 45  * @class A prismatic joint which allows movement in one degree of freedom: translation along
 46  *        an axis anchored in the first body.  The joint limits relative rotations.
 47  *
 48  * @param name {String} Name of the component
 49  * @param body1 {R.components.physics.BaseBody} The first body for the joint
 50  * @param body2 {R.components.physics.BaseBody} The second body for the joint
 51  * @param anchor {R.math.Point2D} A point, in world coordinates relative to the two
 52  *    bodies, to use as the joint's anchor point
 53  * @param [axis] {R.math.Vector2D} The axis of translation.  If <code>null</code> the
 54  *        "up" vector is applied.
 55  *
 56  * @extends R.components.physics.BaseMotorJoint
 57  * @constructor
 58  * @description Creates a prismatic joint between two physical bodies.
 59  */
 60 R.components.physics.PrismaticJoint = function () {
 61     return R.components.physics.BaseMotorJoint.extend(/** @scope R.components.physics.RevoluteJoint.prototype */{
 62 
 63         anchor:null,
 64         limits:null,
 65         axis:null,
 66 
 67         /**
 68          * @private
 69          */
 70         constructor:function (name, body1, body2, anchor, axis) {
 71             var jointDef = new Box2D.Dynamics.Joints.b2PrismaticJointDef();
 72 
 73             this.limits = [];
 74             this.anchor = R.math.Point2D.create(anchor).div(R.physics.Simulation.WORLD_SIZE);
 75 
 76             if (axis) {
 77                 this.axis = R.math.Vector2D.create(axis);
 78             } else {
 79                 this.axis = R.clone(R.math.Vector2D.UP);
 80             }
 81 
 82             this.base(name || "PrismaticJoint", body1, body2, jointDef);
 83         },
 84 
 85         /**
 86          * Offset the joint's anchors by the given point
 87          * @param pt {R.math.Point2D} The offset amount
 88          */
 89         offset:function (pt) {
 90             var ofs = R.clone(pt).div(R.physics.Simulation.WORLD_SIZE);
 91             this.anchor.add(ofs);
 92             ofs.destroy();
 93         },
 94 
 95         /**
 96          * When simulation starts offset the anchor point by the position of rigid body 1 (the "from" body).
 97          * @private
 98          */
 99         startSimulation:function () {
100             if (!this.getSimulation()) {
101                 var anchor = new Box2D.Common.Math.b2Vec2(), axis = new Box2D.Common.Math.b2Vec2();
102                 anchor.Set(this.anchor.x, this.anchor.y);
103                 axis.Set(this.axis.x, this.axis.y);
104 
105                 this.getJointDef().Initialize(this.getBody1().getBody(), this.getBody2().getBody(), anchor, axis);
106 
107                 if (this.limits.length != 0) {
108                     this.getJointDef().upperTranslation = this.limits[1];
109                     this.getJointDef().lowerTranslation = this.limits[0];
110                     this.getJointDef().enableLimit = true;
111                 }
112             }
113 
114             this.base();
115         },
116 
117         /**
118          * Clear the translation limits.
119          */
120         clearLimits:function () {
121             this.limits = [];
122         },
123 
124         /**
125          * Get the upper limit of translation, in meters, through which the joint can travel.
126          * @return {Number}
127          */
128         getUpperLimit:function () {
129             return this.limits[1];
130         },
131 
132         /**
133          * Set the upper limit of translation through which the joint can travel.
134          *
135          * @param limit {Number} The limit, in meters
136          */
137         setUpperLimit:function (limit) {
138             this.limits[1] = limit;
139         },
140 
141         /**
142          * Get the lower limit of translation, in meters, through which the joint can travel.
143          * @return {Number}
144          */
145         getLowerLimit:function () {
146             return this.limits[0];
147         },
148 
149         /**
150          * Set the lower limit of translation through which the joint can travel.
151          *
152          * @param limit {Number} The limit, in meters
153          */
154         setLowerLimit:function (limit) {
155             this.limits[0] = limit;
156         }
157 
158     }, { /** @scope R.components.physics.PrismaticJoint.prototype */
159 
160         /**
161          * Get the class name of this object
162          *
163          * @return {String} "R.components.physics.PrismaticJoint"
164          */
165         getClassName:function () {
166             return "R.components.physics.PrismaticJoint";
167         }
168     });
169 };