1 /**
  2  * The Render Engine
  3  * BaseMotorJointComponent
  4  *
  5  * @fileoverview Base motor joint is used as the class from which motor joints originate.
  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.BaseMotorJoint",
 37     "requires":[
 38         "R.components.physics.BaseJoint",
 39         "R.physics.Simulation",
 40         "R.math.Math2D"
 41     ]
 42 });
 43 
 44 /**
 45  * @class The base motor joint for all joints which can be driven by a motor.
 46  *
 47  * @param name {String} Name of the component
 48  * @param body1 {R.components.physics.BaseBody} The first body for the joint
 49  * @param body2 {R.components.physics.BaseBody} The second body for the joint
 50  * @param anchor {R.math.Point2D} A point, in world coordinates relative to the two
 51  *    bodies, to use as the joint's anchor point
 52  *
 53  * @extends R.components.physics.BaseJoint
 54  * @constructor
 55  * @description Creates a revolute joint between two physical bodies.
 56  */
 57 R.components.physics.BaseMotorJoint = function () {
 58     return R.components.physics.BaseJoint.extend(/** @scope R.components.physics.BaseMotorJoint.prototype */{
 59 
 60         mForce:null,
 61         mSpeed:null,
 62 
 63         /**
 64          * @private
 65          */
 66         constructor:function (name, body1, body2, jointDef) {
 67             this.mForce = null;
 68             this.mSpeed = 0;
 69             this.base(name || "BaseMotorJoint", body1, body2, jointDef);
 70         },
 71 
 72         /**
 73          * When simulation starts offset the anchor point by the position of rigid body 1 (the "from" body).
 74          * @private
 75          */
 76         startSimulation:function () {
 77             if (!this.getSimulation()) {
 78                 if (this.mForce != null) {
 79                     if (this.getJointDef().type == Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint)
 80                         this.getJointDef().maxMotorTorque = this.mForce;
 81                     else
 82                         this.getJointDef().maxMotorForce = this.mForce;
 83 
 84                     this.getJointDef().motorSpeed = this.mSpeed;
 85                     this.getJointDef().enableMotor = true;
 86                 }
 87             }
 88 
 89             this.base();
 90         },
 91 
 92         /**
 93          * Clear the motor force.
 94          */
 95         clearForce:function () {
 96             this.mForce = null;
 97         },
 98 
 99         /**
100          * Get the force which will be applied when the joint is used as a motor.
101          * @return {Number}
102          */
103         getMotorForce:function () {
104             if (this.simulation) {
105                 return this.getJoint().GetMotorTorque(1 / R.Engine.getFPS());
106             } else {
107                 return this.mTorque;
108             }
109         },
110 
111         /**
112          * Set the force which is applied via the motor, or to resist forces applied to it.  You can
113          * use this value to simulate joint friction by setting the motor speed to zero
114          * and applying a small amount of force.  During simulation, the force is applied directly
115          * to the joint.  In joints where torque is used, the force is applied to the torque instead.
116          *
117          * @param force {Number} The amount of force to apply
118          */
119         setMotorForce:function (force) {
120             if (this.simulation) {
121                 // Apply directly to the joint
122                 if (this.getJointDef().type == Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint)
123                     this.getJoint().SetMotorTorque(force);
124                 else
125                     this.getJoint().SetMotorForce(force);
126             } else {
127                 // Apply to the joint definition
128                 this.mForce = force;
129             }
130         },
131 
132         /**
133          * Get the speed of the motor.  During simulation, the value returned is the
134          * joint's speed, not the speed set for the motor.
135          * @return {Number}
136          */
137         getMotorSpeed:function () {
138             if (this.simulation) {
139                 return this.getJoint().GetJointSpeed();
140             } else {
141                 return this.mSpeed;
142             }
143         },
144 
145         /**
146          * Set the speed of the motor applied to the joint.
147          *
148          * @param speed {Number} The speed of the motor
149          */
150         setMotorSpeed:function (speed) {
151             if (this.simulation) {
152                 this.getJoint().SetMotorSpeed(speed);
153             } else {
154                 this.mSpeed = speed;
155             }
156         },
157 
158         /**
159          * During simulation, get the reaction force vector of the joint.  Outside
160          * of simulation, the vector will be zero.
161          * @return {R.math.Vector2D}
162          */
163         getReactionForce:function () {
164             if (this.simulation) {
165                 var vec = this.getJoint().GetReactionForce(1 / R.Engine.getFPS());
166                 return R.math.Vector2D.create(vec.x, vec.y);
167             } else {
168                 return R.math.Vector2D.ZERO;
169             }
170         },
171 
172         /**
173          * During simulation, get the reaction torque.  Outside of simulation, the
174          * torque is zero.
175          * @return {Number}
176          */
177         getReactionTorque:function () {
178             if (this.simulation) {
179                 return this.getJoint().GetReactionTorque(1 / R.Engine.getFPS());
180             } else {
181                 return 0;
182             }
183         }
184 
185     }, { /** @scope R.components.physics.BaseMotorJoint.prototype */
186 
187         /**
188          * Get the class name of this object
189          *
190          * @return {String} "R.components.physics.BaseMotorJoint"
191          */
192         getClassName:function () {
193             return "R.components.physics.BaseMotorJoint";
194         }
195     });
196 };