1/*
2 * Copyright (c) 2009-2010 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32package com.jme3.bullet.joints;
33
34import com.jme3.bullet.objects.PhysicsRigidBody;
35import com.jme3.export.*;
36import com.jme3.math.Vector3f;
37import java.io.IOException;
38import java.util.logging.Level;
39import java.util.logging.Logger;
40
41/**
42 * <p>PhysicsJoint - Basic Phyiscs Joint</p>
43 * @author normenhansen
44 */
45public abstract class PhysicsJoint implements Savable {
46
47    protected long objectId = 0;
48    protected PhysicsRigidBody nodeA;
49    protected PhysicsRigidBody nodeB;
50    protected Vector3f pivotA;
51    protected Vector3f pivotB;
52    protected boolean collisionBetweenLinkedBodys = true;
53
54    public PhysicsJoint() {
55    }
56
57    /**
58     * @param pivotA local translation of the joint connection point in node A
59     * @param pivotB local translation of the joint connection point in node B
60     */
61    public PhysicsJoint(PhysicsRigidBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB) {
62        this.nodeA = nodeA;
63        this.nodeB = nodeB;
64        this.pivotA = pivotA;
65        this.pivotB = pivotB;
66        nodeA.addJoint(this);
67        nodeB.addJoint(this);
68    }
69
70    public float getAppliedImpulse() {
71        return getAppliedImpulse(objectId);
72    }
73
74    private native float getAppliedImpulse(long objectId);
75
76    /**
77     * @return the constraint
78     */
79    public long getObjectId() {
80        return objectId;
81    }
82
83    /**
84     * @return the collisionBetweenLinkedBodys
85     */
86    public boolean isCollisionBetweenLinkedBodys() {
87        return collisionBetweenLinkedBodys;
88    }
89
90    /**
91     * toggles collisions between linked bodys<br>
92     * joint has to be removed from and added to PhyiscsSpace to apply this.
93     * @param collisionBetweenLinkedBodys set to false to have no collisions between linked bodys
94     */
95    public void setCollisionBetweenLinkedBodys(boolean collisionBetweenLinkedBodys) {
96        this.collisionBetweenLinkedBodys = collisionBetweenLinkedBodys;
97    }
98
99    public PhysicsRigidBody getBodyA() {
100        return nodeA;
101    }
102
103    public PhysicsRigidBody getBodyB() {
104        return nodeB;
105    }
106
107    public Vector3f getPivotA() {
108        return pivotA;
109    }
110
111    public Vector3f getPivotB() {
112        return pivotB;
113    }
114
115    /**
116     * destroys this joint and removes it from its connected PhysicsRigidBodys joint lists
117     */
118    public void destroy() {
119        getBodyA().removeJoint(this);
120        getBodyB().removeJoint(this);
121    }
122
123    public void write(JmeExporter ex) throws IOException {
124        OutputCapsule capsule = ex.getCapsule(this);
125        capsule.write(nodeA, "nodeA", null);
126        capsule.write(nodeB, "nodeB", null);
127        capsule.write(pivotA, "pivotA", null);
128        capsule.write(pivotB, "pivotB", null);
129    }
130
131    public void read(JmeImporter im) throws IOException {
132        InputCapsule capsule = im.getCapsule(this);
133        this.nodeA = ((PhysicsRigidBody) capsule.readSavable("nodeA", new PhysicsRigidBody()));
134        this.nodeB = (PhysicsRigidBody) capsule.readSavable("nodeB", new PhysicsRigidBody());
135        this.pivotA = (Vector3f) capsule.readSavable("pivotA", new Vector3f());
136        this.pivotB = (Vector3f) capsule.readSavable("pivotB", new Vector3f());
137    }
138
139    @Override
140    protected void finalize() throws Throwable {
141        super.finalize();
142        Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing Joint {0}", Long.toHexString(objectId));
143        finalizeNative(objectId);
144    }
145
146    private native void finalizeNative(long objectId);
147}
148