1 /** 2 * The Render Engine 3 * DistanceJointComponent 4 * 5 * @fileoverview A distance 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.DistanceJoint", 37 "requires":[ 38 "R.components.physics.BaseJoint", 39 "R.physics.Simulation", 40 "R.math.Math2D" 41 ] 42 }); 43 44 /** 45 * @class A distance joint which maintains constant distance between two bodies 46 * in a {@link R.physics.Simulation}. You can picture this as a massless 47 * rigid rod anchored at the two anchor points. 48 * 49 * @param name {String} Name of the component 50 * @param body1 {R.components.physics.BaseBody} The first body for the joint 51 * @param body2 {R.components.physics.BaseBody} The second body for the joint 52 * @param anchor1 {R.math.Vector2D} The anchor on body 1, or <code>null</code> 53 * @param anchor2 {R.math.Vector2D} The anchor on body 2, or <code>null</code> 54 * 55 * @extends R.components.physics.BaseJoint 56 * @constructor 57 * @description Creates a distance joint between two physical bodies. The distance can 58 * be softened by adjusting the frequency and the damping ratio of the joint. 59 * Rotation is not limited by this joint. If you do not specify anchor 1 or 60 * anchor 2, the joint will use the position of each body offset by its physical 61 * origin. 62 */ 63 R.components.physics.DistanceJoint = function () { 64 return R.components.physics.BaseJoint.extend(/** @scope R.components.physics.DistanceJoint.prototype */{ 65 66 anchor1:null, 67 anchor2:null, 68 69 /** 70 * @private 71 */ 72 constructor:function (name, body1, body2, anchor1, anchor2) { 73 var jointDef = new Box2D.Dynamics.Joints.b2DistanceJointDef(); 74 75 if (anchor1) { 76 this.anchor1 = R.math.Point2D.create(anchor1).div(R.physics.Simulation.WORLD_SIZE); 77 } 78 79 if (anchor2) { 80 this.anchor2 = R.math.Point2D.create(anchor2).div(R.physics.Simulation.WORLD_SIZE); 81 } 82 83 this.base(name || "DistanceJoint", body1, body2, jointDef); 84 }, 85 86 /** 87 * Offset the joint's anchors by the given point 88 * @param pt {R.math.Point2D} The offset amount 89 */ 90 offset:function (pt) { 91 var ofs = R.clone(pt).div(R.physics.Simulation.WORLD_SIZE); 92 93 if (this.anchor1) { 94 this.anchor1.add(ofs); 95 } 96 97 if (this.anchor2) { 98 this.anchor2.add(ofs); 99 } 100 101 ofs.destroy(); 102 }, 103 104 /** 105 * When simulation starts set the anchor points to the position of each rigid body. 106 * @private 107 */ 108 startSimulation:function () { 109 if (!this.getSimulation()) { 110 111 var anchor1 = new Box2D.Common.Math.b2Vec2(), anchor2 = new Box2D.Common.Math.b2Vec2(), 112 a1 = this.anchor1, a2 = this.anchor2; 113 114 // If a1 or a2 were not specified, use the position of each body 115 if (!a1) { 116 a1 = R.math.Point2D.create(this.getBody1().getPosition()); 117 a1.add(this.getBody1().getLocalOrigin()).div(R.physics.Simulation.WORLD_SIZE); 118 } 119 120 if (!a2) { 121 a2 = R.math.Point2D.create(this.getBody2().getPosition()); 122 a2.add(this.getBody2().getLocalOrigin()).div(R.physics.Simulation.WORLD_SIZE); 123 } 124 125 // Translate the anchor positions into B2 vectors 126 anchor1.Set(a1.x, a1.y); 127 anchor2.Set(a2.x, a2.y); 128 129 // Initialize the joint 130 this.getJointDef().Initialize(this.getBody1().getBody(), this.getBody2().getBody(), 131 anchor1, anchor2); 132 } 133 134 this.base(); 135 }, 136 137 /** 138 * Set the frequency which is used to determine joint softness. According to 139 * Box2d documentation the frequency should be less than half of the time step 140 * used for the simulation. In the engine, the frequency of the time step is 141 * the frame rate. 142 * 143 * @param hz {Number} The frequency in Hertz. 144 */ 145 setFrequency:function (hz) { 146 this.getJointDef().frequencyHz = hz; 147 }, 148 149 /** 150 * Get the frequency from the joint definition. 151 * @return {Number} 152 */ 153 getFrequency:function () { 154 return this.getJointDef().frequencyHz; 155 }, 156 157 /** 158 * Set the damping ratio which is used to determine joint softness. The value 159 * should be between 0.0 and 1.0, with 1.0 being extremely rigid. 160 * 161 * @param dampingRatio {Number} A value between 0.0 and 1.0 162 */ 163 setDampingRatio:function (dampingRatio) { 164 this.getJointDef().dampingRatio = dampingRatio; 165 }, 166 167 /** 168 * Get the damping ratio from the joint definition. 169 * @return {Number} 170 */ 171 getDampingRatio:function () { 172 return this.getJointDef().dampingRatio; 173 } 174 175 }, { /** @scope R.components.physics.DistanceJoint.prototype */ 176 177 /** 178 * Get the class name of this object 179 * 180 * @return {String} "R.components.physics.DistanceJoint" 181 */ 182 getClassName:function () { 183 return "R.components.physics.DistanceJoint"; 184 } 185 }); 186 }