1 /** 2 * The Render Engine 3 * RevoluteJointComponent 4 * 5 * @fileoverview A revolute 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.RevoluteJoint", 37 "requires":[ 38 "R.components.physics.BaseMotorJoint", 39 "R.physics.Simulation", 40 "R.math.Point2D", 41 "R.math.Math2D", 42 "R.math.Vector2D" 43 ] 44 }); 45 46 /** 47 * @class A revolute joint which allows two bodies to revolve around a common 48 * anchor point in a {@link R.physics.Simulation}. 49 * 50 * @param name {String} Name of the component 51 * @param body1 {R.components.physics.BaseBody} The first body for the joint 52 * @param body2 {R.components.physics.BaseBody} The second body for the joint 53 * @param anchor {R.math.Point2D} A point, in world coordinates relative to the two 54 * bodies, to use as the joint's anchor point 55 * 56 * @extends R.components.physics.BaseMotorJoint 57 * @constructor 58 * @description Creates a revolute joint between two physical bodies. 59 */ 60 R.components.physics.RevoluteJoint = function () { 61 return R.components.physics.BaseMotorJoint.extend(/** @scope R.components.physics.RevoluteJoint.prototype */{ 62 63 anchor:null, 64 limits:null, 65 66 /** 67 * @private 68 */ 69 constructor:function (name, body1, body2, anchor) { 70 var jointDef = new Box2D.Dynamics.Joints.b2RevoluteJointDef(); 71 72 this.limits = []; 73 this.anchor = R.math.Point2D.create(anchor).div(R.physics.Simulation.WORLD_SIZE); 74 this.base(name || "RevoluteJoint", body1, body2, jointDef); 75 }, 76 77 /** 78 * When simulation starts offset the anchor point by the position of rigid body 1 (the "from" body). 79 * @private 80 */ 81 startSimulation:function () { 82 if (!this.getSimulation()) { 83 var anchor = new Box2D.Common.Math.b2Vec2(); 84 anchor.Set(this.anchor.x, this.anchor.y); 85 86 this.getJointDef().Initialize(this.getBody1().getBody(), this.getBody2().getBody(), anchor); 87 88 if (this.limits.length != 0) { 89 this.getJointDef().upperAngle = R.math.Math2D.degToRad(Math.max(this.limits[1], this.limits[0])); 90 this.getJointDef().lowerAngle = R.math.Math2D.degToRad(Math.min(this.limits[0], this.limits[1])); 91 this.getJointDef().enableLimit = true; 92 } 93 } 94 95 this.base(); 96 }, 97 98 /** 99 * Offset the joint's anchors by the given point 100 * @param pt {R.math.Point2D} The offset amount 101 */ 102 offset:function (pt) { 103 var ofs = R.clone(pt).div(R.physics.Simulation.WORLD_SIZE); 104 this.anchor.add(ofs); 105 ofs.destroy(); 106 }, 107 108 /** 109 * Clear the rotational limits. 110 */ 111 clearLimits:function () { 112 this.limits = []; 113 }, 114 115 /** 116 * Get the upper limiting angle, in degrees, through which the joint can rotate. 117 * @return {Number} The angle, or <code>undefined</code> 118 */ 119 getUpperLimitAngle:function () { 120 return this.limits.length != 0 ? R.math.Math2D.radToDeg(this.limits[1]) : undefined; 121 }, 122 123 /** 124 * Set the upper limiting angle through which the joint can rotate. Zero is the 125 * "top" of the rotation, with rotation moving positively in a counter-clockwise 126 * rotation. Negative numbers will move the rotation clockwise. 127 * 128 * @param angle {Number} An angle in degrees 129 */ 130 setUpperLimitAngle:function (angle) { 131 this.limits[1] = R.math.Math2D.degToRad(angle); 132 }, 133 134 /** 135 * Get the lower limiting angle, in degrees, through which the joint can rotate. 136 * @return {Number} The angle, or <code>undefined</code> 137 */ 138 getLowerLimitAngle:function () { 139 return this.limits.length != 0 ? R.math.Math2D.radToDeg(this.limits[0]) : undefined; 140 }, 141 142 /** 143 * Set the upper limiting angle through which the joint can rotate. Zero is the 144 * "top" of the rotation, with rotation moving positively in a counter-clockwise 145 * rotation. Negative numbers will move the rotation clockwise. 146 * 147 * @param angle {Number} An angle in degrees 148 */ 149 setLowerLimitAngle:function (angle) { 150 this.limits[0] = R.math.Math2D.degToRad(angle); 151 }, 152 153 /** 154 * During simulation, this returns the current angle of the joint 155 * in degrees. Outside of simulation it will always return zero. 156 * @return {Number} 157 */ 158 getJointAngle:function () { 159 if (this.simulation) { 160 return R.math.Math2D.radToDeg(this.getJoint().GetJointAngle()); 161 } else { 162 return 0; 163 } 164 } 165 166 }, { /** @scope R.components.physics.RevoluteJoint.prototype */ 167 168 /** 169 * Get the class name of this object 170 * 171 * @return {String} "R.components.physics.RevoluteJoint" 172 */ 173 getClassName:function () { 174 return "R.components.physics.RevoluteJoint"; 175 } 176 }); 177 };