| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="Asciidoctor 1.5.4"><meta name="keywords" content="documentation, physics, joint"><title>Physical Hinges and Joints</title><link rel="stylesheet" href="./asciidoctor.css">
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
- <link rel="stylesheet" href="./coderay-asciidoctor.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css"><link rel="stylesheet" href="/home/travis/build/jMonkeyEngine/wiki/build/asciidoc/html5/jme3/advanced/twemoji-awesome.css"></head><body class="article toc2 toc-left"><div id="header"><div id="toolbar"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/src/docs/asciidoc/jme3/advanced/hinges_and_joints.adoc"><i class="fa fa-pencil-square" aria-hidden="true"></i></a><a href="https://github.com/jMonkeyEngine/wiki/new/master/src/docs/asciidoc/jme3/advanced/"><i class="fa fa-plus-square" aria-hidden="true"></i></a><input dir="auto" style="position: relative; vertical-align: top;" spellcheck="false" autocomplete="off" class="searchbox__input aa-input" id="doc-search" name="search" placeholder="Search in the doc" required="required" type="search"></div><h1>Physical Hinges and Joints</h1><div class="details"><span class="author" id="author"></span><br><span id="revnumber">version ,</span> <span id="revdate">2016/03/17 20:48</span></div><div id="toc" class="toc2"><div id="toctitle">Table of Contents</div><ul class="sectlevel1"><li><a href="#sample-code">Sample Code</a></li><li><a href="#overview-of-this-physics-application">Overview of this Physics Application</a></li><li><a href="#creating-a-fixed-node">Creating a Fixed Node</a></li><li><a href="#creating-a-dynamic-node">Creating a Dynamic Node</a></li><li><a href="#understanding-dof-joints-and-hinges">Understanding DOF, Joints, and Hinges</a></li><li><a href="#creating-the-joint">Creating the Joint</a></li><li><a href="#apply-physical-forces">Apply Physical Forces</a></li></ul></div></div><div id="content"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>The jMonkeyEngine3 has built-in support for <a href="http://jbullet.advel.cz">jBullet physics</a> via the <code>com.jme3.bullet</code> package.</p></div>
- <div class="paragraph"><p>Game Physics are not only employed to calculate collisions, but they can also simulate hinges and joints. Think of pulley chains, shaky rope bridges, swinging pendulums, or (trap)door and chest hinges. Physics are a great addition to e.g. an action or puzzle game.</p></div>
- <div class="paragraph"><p>In this example, we will create a pendulum. The joint is the (invisible) connection between the pendulum body and the hook. You will see that you can use what you learn from the simple pendulum and apply it to other joint/hinge objects (rope bridges, etc).</p></div></div></div>
- <div class="sect1"><h2 id="sample-code">Sample Code</h2><div class="sectionbody"><div class="ulist"><ul><li><p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java">TestPhysicsHingeJoint.java</a></p></li></ul></div></div></div>
- <div class="sect1"><h2 id="overview-of-this-physics-application">Overview of this Physics Application</h2><div class="sectionbody"><div class="olist arabic"><ol class="arabic"><li><p>Create a SimpleApplication with a <a href="../../jme3/advanced/physics.html">BulletAppState</a></p><div class="ulist"><ul><li><p>This gives us a PhysicsSpace for PhysicsControls</p></li></ul></div></li><li><p>For the pendulum, we use a Spatial with a PhysicsControl, and we apply physical forces to them.</p><div class="ulist"><ul><li><p>The parts of the “pendulum are Physics Control’ed Spatials with Collision Shapes.</p></li><li><p>We create a fixed <code>hookNode</code> and a dynamic <code>pendulumNode</code>.</p></li></ul></div></li><li><p>We can “crank the handle and rotate the joint like a hinge, or we can let loose and expose the joints freely to gravity.</p><div class="ulist"><ul><li><p>For physical forces we will use the method <code>joint.enableMotor();</code></p></li></ul></div></li></ol></div></div></div>
- <div class="sect1"><h2 id="creating-a-fixed-node">Creating a Fixed Node</h2><div class="sectionbody"><div class="paragraph"><p>The hookNode is the fixed point from which the pendulum hangs. It has no mass.</p></div>
- <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">Node hookNode=PhysicsTestHelper.createPhysicsTestNode(
- assetManager, <span class="keyword">new</span> BoxCollisionShape(<span class="keyword">new</span> Vector3f( <span class="float">.1f</span>, <span class="float">.1f</span>, <span class="float">.1f</span>)),<span class="integer">0</span>);
- hookNode.getControl(RigidBodyControl.class).setPhysicsLocation(<span class="keyword">new</span> Vector3f(<span class="float">0f</span>,<span class="integer">0</span>,<span class="float">0f</span>));
- rootNode.attachChild(hookNode);
- getPhysicsSpace().add(hookNode);</code></pre></div></div>
- <div class="paragraph"><p>For a rope bridge, there would be two fixed nodes where the bridge is attached to the mountainside.</p></div></div></div>
- <div class="sect1"><h2 id="creating-a-dynamic-node">Creating a Dynamic Node</h2><div class="sectionbody"><div class="paragraph"><p>The pendulumNode is the dynamic part of the construction. It has a mass.</p></div>
- <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">Node pendulumNode=PhysicsTestHelper.createPhysicsTestNode(
- assetManager, <span class="keyword">new</span> BoxCollisionShape(<span class="keyword">new</span> Vector3f( <span class="float">.3f</span>, <span class="float">.3f</span>, <span class="float">.3f</span>)),<span class="integer">1</span>);
- pendulumNode.getControl(RigidBodyControl.class).setPhysicsLocation(<span class="keyword">new</span> Vector3f(<span class="float">0f</span>,-<span class="integer">1</span>,<span class="float">0f</span>));
- rootNode.attachChild(pendulumNode);
- getPhysicsSpace().add(pendulumNode);</code></pre></div></div>
- <div class="paragraph"><p>For a rope bridge, each set of planks would be one dynamic node.</p></div></div></div>
- <div class="sect1"><h2 id="understanding-dof-joints-and-hinges">Understanding DOF, Joints, and Hinges</h2><div class="sectionbody"><div class="paragraph"><p>A PhysicsHingeJoint is an invisible connection between two nodes – here between the pendulum body and the hook. Why are hinges and joints represented by the same class? Hinges and joints have something in common: They constrain the <em>mechanical degree of freedom</em> (DOF) of another object.</p></div>
- <div class="paragraph"><p>Consider a free falling, “unchained object in physical 3D space: It has 6 DOFs:</p></div>
- <div class="ulist"><ul><li><p>It translates along 3 axes</p></li><li><p>It rotates around 3 axes</p></li></ul></div>
- <div class="paragraph"><p>Now consider some examples of objects with joints:</p></div>
- <div class="ulist"><ul><li><p>An individual chain link is free to spin and move around, but joined into a chain, the link’s movement is restricted to stay with the surrounding links.</p></li><li><p>A person’s arm can rotate around some axes, but not around others. The shoulder joint allows one and restricts the other.</p></li><li><p>A door hinge is one of the most restricted types of joint: It can only rotate around one axis.</p></li></ul></div>
- <div class="paragraph"><p>You’ll understand that, when creating any type of joint, it is important to correctly specify the DOFs that the joint restricts, and the DOFs that the joint allows. For the typical DOF of a <a href="../../jme3/advanced/ragdoll.html">ragDoll</a> character’s limbs, jME even offers a special joint, <code>ConeJoint</code>.</p></div></div></div>
- <div class="sect1"><h2 id="creating-the-joint">Creating the Joint</h2><div class="sectionbody"><div class="paragraph"><p>You create the HingeJoint after you have created the nodes that are to be chained together. In the code snippet you see that the HingeJoint constructor requires the two node objects. You also have to specify axes and pivots – they are the degrees of freedom that you just heard about.</p></div>
- <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="directive">private</span> HingeJoint joint;
- ...
- public <span class="type">void</span> simpleInitApp() {
- ...
- <span class="comment">// hookNode and pendulumNode are created here...</span>
- ...
- joint=<span class="keyword">new</span> HingeJoint(hookNode.getControl(RigidBodyControl.class), <span class="comment">// A</span>
- pendulumNode.getControl(RigidBodyControl.class), <span class="comment">// B</span>
- <span class="keyword">new</span> Vector3f(<span class="float">0f</span>, <span class="float">0f</span>, <span class="float">0f</span>), <span class="comment">// pivot point local to A</span>
- <span class="keyword">new</span> Vector3f(<span class="float">0f</span>, <span class="float">1f</span>, <span class="float">0f</span>), <span class="comment">// pivot point local to B</span>
- Vector3f.UNIT_Z, <span class="comment">// DoF Axis of A (Z axis)</span>
- Vector3f.UNIT_Z ); <span class="comment">// DoF Axis of B (Z axis)</span></code></pre></div></div>
- <div class="paragraph"><p>The pivot point’s position will be at <code>(0,0,0)</code> in the global 3D space. In A’s local space that is at <code>(0,0,0)</code> and in B’s local space (remember B’s position was set to <code>(0,-1,0)</code>) that is at <code>(0,1,0)</code>.</p></div>
- <div class="paragraph"><p>Specify the following parameters for each joint:</p></div>
- <div class="ulist"><ul><li><p>PhysicsControl A and B – the two nodes that are to be joined</p></li><li><p>Vector3f pivot A and pivot B – coordinates of the attachment point relative to A and B</p><div class="ulist"><ul><li><p>The points typically lie on the surface of the PhysicsControl’s Spatials, rarely in the middle.</p></li></ul></div></li><li><p>Vector3f axisA and axisB – around which axes each node is allowed to spin.</p><div class="ulist"><ul><li><p>In our example, we constrain the pendulum to swing only along the Z axis.</p></li></ul></div></li></ul></div>
- <div class="paragraph"><p>Remember to add all joint objects to the physicsSpace, just like you would do with any physical objects.</p></div>
- <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">bulletAppState.getPhysicsSpace().add(joint);</code></pre></div></div>
- <div class="paragraph"><p><strong>Tip:</strong> If you want the joint to be visible, attach a geometry to the dynamic node, and translate it to its start position.</p></div></div></div>
- <div class="sect1"><h2 id="apply-physical-forces">Apply Physical Forces</h2><div class="sectionbody"><div class="paragraph"><p>You can apply forces to dynamic nodes (the ones that have a mass), and see how other joined (“chained) objects are dragged along.</p></div>
- <div class="paragraph"><p>Alternatively, you can also apply forces to the joint itself. In a game, you may want to spin an automatic revolving door, or slam a door closed in a spooky way, or dramatically open the lid of a treasure chest.</p></div>
- <div class="paragraph"><p>The method to call on the joint is <code>enableMotor()</code>.</p></div>
- <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">joint.enableMotor(<span class="predefined-constant">true</span>, <span class="integer">1</span>, <span class="float">.1f</span>);
- joint.enableMotor(<span class="predefined-constant">true</span>, -<span class="integer">1</span>, <span class="float">.1f</span>);</code></pre></div></div>
- <div class="olist arabic"><ol class="arabic"><li><p>Switch the motor on by supplying <code>true</code></p></li><li><p>Specify the velocity with which the joint should rotate around the specified axis.</p><div class="ulist"><ul><li><p>Use positive and negative numbers to change direction.</p></li></ul></div></li><li><p>Specify the impulse for this motor. Heavier masses need a bigger impulse to be moved.</p></li></ol></div>
- <div class="paragraph"><p>When you disable the motor, the chained nodes are exposed to gravity again:</p></div>
- <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">joint.enableMotor(<span class="predefined-constant">false</span>, <span class="integer">0</span>, <span class="integer">0</span>);</code></pre></div></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2019-12-20 23:30:51 +00:00</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
- apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
- indexName: 'jmonkeyengine',
- inputSelector: '#doc-search',
- debug: false // Set debug to true if you want to inspect the dropdown
- });</script></body></html>
|