1 /**
  2  * The Render Engine
  3  * BaseJointComponent
  4  *
  5  * @fileoverview The base component type for all physical joints which can be used
  6  *               in a {@link Simulation}.
  7  *
  8  * @author: Brett Fattori (brettf@renderengine.com)
  9  *
 10  * @author: $Author: bfattori $
 11  * @version: $Revision: 1555 $
 12  *
 13  * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 14  *
 15  * Permission is hereby granted, free of charge, to any person obtaining a copy
 16  * of this software and associated documentation files (the "Software"), to deal
 17  * in the Software without restriction, including without limitation the rights
 18  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 19  * copies of the Software, and to permit persons to whom the Software is
 20  * furnished to do so, subject to the following conditions:
 21  *
 22  * The above copyright notice and this permission notice shall be included in
 23  * all copies or substantial portions of the Software.
 24  *
 25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 26  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 27  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 28  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 29  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 30  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 31  * THE SOFTWARE.
 32  *
 33  */
 34 
 35 // The class this file defines and its required classes
 36 R.Engine.define({
 37     "class":"R.components.physics.BaseJoint",
 38     "requires":[
 39         "R.components.Logic",
 40         "R.math.Math2D",
 41         "R.math.Vector2D",
 42         "R.math.Rectangle2D"
 43     ]
 44 });
 45 
 46 /**
 47  * @class The base component which initializes physical joints for use in a {@link R.physics.Simulation}.
 48  *
 49  * @param name {String} Name of the component
 50  * @param body1 {b2Body} The first body of the joint
 51  * @param body2 {b2Body} The second body of the joint
 52  * @param jointDef {b2JointDef} The joint definition.
 53  *
 54  * @extends R.components.Logic
 55  * @constructor
 56  * @description All physics joint components extend from this component type.
 57  */
 58 R.components.physics.BaseJoint = function () {
 59     return R.components.Logic.extend(/** @scope R.components.physics.BaseJoint.prototype */{
 60 
 61         jointDef:null,
 62         simulation:null,
 63         collideBodies:false,
 64         joint:null,
 65         body1:null,
 66         body2:null,
 67 
 68         /**
 69          * @private
 70          */
 71         constructor:function (name, body1, body2, jointDef) {
 72             Assert(body1 instanceof R.components.physics.BaseBody, "Body 1 for joint is not a R.components.BaseBody");
 73             Assert(body2 instanceof R.components.physics.BaseBody, "Body 2 for joint is not a R.components.BaseBody");
 74 
 75             this.base(name || "BaseJoint");
 76 
 77             this.jointDef = jointDef;
 78             this.simulation = null;
 79             this.body1 = body1;
 80             this.body2 = body2;
 81 
 82             this.collideBodies = false;
 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         },
 91 
 92         /**
 93          * Start simulating the joint.  If the joint isn't a part of the simulation,
 94          * it is added and simulation occurs.
 95          */
 96         startSimulation:function () {
 97             if (!this.simulation) {
 98                 this.simulation = this.getGameObject().getSimulation();
 99                 this.getJointDef().collideConnected = this.getCollideBodies();
100 
101                 this.joint = this.simulation.addJoint(this.getJointDef());
102             }
103         },
104 
105         /**
106          * Stop simulating the body.  If the body is a part of a simulation,
107          * it is removed and simulation stops.  The position and rotation of
108          * the body will not be updated.
109          */
110         stopSimulation:function () {
111             if (this.simulation) {
112                 this.simulation.removeJoint(this.getJoint());
113                 this.simulation = null;
114             }
115         },
116 
117         /**
118          * Get the simulation this joint is active within.
119          * @return {R.physics.Simuation}
120          */
121         getSimulation:function () {
122             return this.simulation;
123         },
124 
125         /**
126          * Get the Box2d joint definition object.
127          * @return {b2JointDef}
128          */
129         getJointDef:function () {
130             return this.jointDef;
131         },
132 
133         /**
134          * Get the Box2d joint object.
135          * @return {b2Joint}
136          */
137         getJoint:function () {
138             return this.joint;
139         },
140 
141         /**
142          * Get the component which corresponds to body 1 of the joint.
143          * @return {R.components.BaseBody}
144          */
145         getBody1:function () {
146             return this.body1;
147         },
148 
149         /**
150          * Get the component which corresponds to body 2 of the joint.
151          * @return {R.components.BaseBody}
152          */
153         getBody2:function () {
154             return this.body2;
155         },
156 
157         /**
158          * Set the first body of the joint. This should only be called when the
159          * joint is not being simulated.
160          * @param body {R.components.physics.BaseBody} The body component
161          */
162         setBody1:function (body) {
163             this.body1 = body;
164         },
165 
166         /**
167          * Set the second body of the joint. This should only be called when the
168          * joint is not being simulated.
169          * @param body {R.components.physics.BaseBody} The body component
170          */
171         setBody2:function (body) {
172             this.body2 = body;
173         },
174 
175         /**
176          * Returns <code>true</code> if the two bodies will check for collisions
177          * with eachother during the simulation.  The default is <code>false</code>.
178          * @return {Boolean}
179          */
180         getCollideBodies:function () {
181             return this.collideBodies;
182         },
183 
184         /**
185          * Set a flag which determines if the two bodies will collide with eachother
186          * during simulation.  After the simulation has started, you cannot change this
187          * flag without first stopping simulation on the bodies and joint.
188          *
189          * @param state {Boolean} Set to <code>true</code> to enable collisions between the two
190          *    bodies.  Default: <code>false</code>
191          */
192         setCollideBodies:function (state) {
193             this.collideBodies = state;
194         }
195 
196         /**
197          * Execute the joint component
198          * @private
199          */, execute:function (renderContext, time, dt) {
200             this.base(renderContext, time, dt);
201             /* pragma:DEBUG_START */
202             if (R.Engine.getDebugMode()) {
203                 renderContext.pushTransform();
204                 renderContext.setLineStyle("red");
205                 var b1p = R.math.Point2D.create(this.getBody1().getPosition());
206                 var b2p = R.math.Point2D.create(this.getBody2().getPosition());
207                 renderContext.drawLine(b1p, b2p);
208 
209                 //b1P = R.math.Point2D.create(this.)
210 
211                 b1p.destroy();
212                 b2p.destroy();
213                 renderContext.popTransform();
214             }
215             /* pragma:DEBUG_END */
216         }
217 
218     }, { /** @scope R.components.physics.BaseJoint.prototype */
219 
220         /**
221          * Get the class name of this object
222          *
223          * @return {String} "R.components.physics.BaseJoint"
224          */
225         getClassName:function () {
226             return "R.components.physics.BaseJoint";
227         }
228     });
229 }