OSDN Git Service

Add AndroidTGALoader
[mikumikustudio/MikuMikuStudio.git] / engine / src / bullet / com / jme3 / bullet / objects / PhysicsRigidBody.java
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  */
32 package com.jme3.bullet.objects;
33
34 import com.jme3.math.Vector3f;
35 import com.jme3.scene.Spatial;
36 import com.jme3.bullet.PhysicsSpace;
37 import com.jme3.bullet.collision.PhysicsCollisionObject;
38 import com.jme3.bullet.collision.shapes.CollisionShape;
39 import com.jme3.bullet.collision.shapes.MeshCollisionShape;
40 import com.jme3.bullet.joints.PhysicsJoint;
41 import com.jme3.bullet.objects.infos.RigidBodyMotionState;
42 import com.jme3.export.InputCapsule;
43 import com.jme3.export.JmeExporter;
44 import com.jme3.export.JmeImporter;
45 import com.jme3.export.OutputCapsule;
46 import com.jme3.math.Matrix3f;
47 import com.jme3.math.Quaternion;
48 import com.jme3.scene.Geometry;
49 import com.jme3.scene.Node;
50 import com.jme3.scene.debug.Arrow;
51 import java.io.IOException;
52 import java.util.ArrayList;
53 import java.util.Iterator;
54 import java.util.List;
55 import java.util.logging.Level;
56 import java.util.logging.Logger;
57
58 /**
59  * <p>PhysicsRigidBody - Basic physics object</p>
60  * @author normenhansen
61  */
62 public class PhysicsRigidBody extends PhysicsCollisionObject {
63
64     protected RigidBodyMotionState motionState = new RigidBodyMotionState();
65     protected float mass = 1.0f;
66     protected boolean kinematic = false;
67     protected ArrayList<PhysicsJoint> joints = new ArrayList<PhysicsJoint>();
68
69     public PhysicsRigidBody() {
70     }
71
72     /**
73      * Creates a new PhysicsRigidBody with the supplied collision shape
74      * @param child
75      * @param shape
76      */
77     public PhysicsRigidBody(CollisionShape shape) {
78         collisionShape = shape;
79         rebuildRigidBody();
80     }
81
82     public PhysicsRigidBody(CollisionShape shape, float mass) {
83         collisionShape = shape;
84         this.mass = mass;
85         rebuildRigidBody();
86     }
87
88     /**
89      * Builds/rebuilds the phyiscs body when parameters have changed
90      */
91     protected void rebuildRigidBody() {
92         boolean removed = false;
93         if (collisionShape instanceof MeshCollisionShape && mass != 0) {
94             throw new IllegalStateException("Dynamic rigidbody can not have mesh collision shape!");
95         }
96         if (objectId != 0) {
97             if (isInWorld(objectId)) {
98                 PhysicsSpace.getPhysicsSpace().remove(this);
99                 removed = true;
100             }
101             Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Clearing RigidBody {0}", Long.toHexString(objectId));
102             finalizeNative(objectId);
103         }
104         preRebuild();
105         objectId = createRigidBody(mass, motionState.getObjectId(), collisionShape.getObjectId());
106         Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Created RigidBody {0}", Long.toHexString(objectId));
107         postRebuild();
108         if (removed) {
109             PhysicsSpace.getPhysicsSpace().add(this);
110         }
111     }
112
113     protected void preRebuild() {
114     }
115
116     private native long createRigidBody(float mass, long motionStateId, long collisionShapeId);
117
118     protected void postRebuild() {
119         if (mass == 0.0f) {
120             setStatic(objectId, true);
121         } else {
122             setStatic(objectId, false);
123         }
124         initUserPointer();
125     }
126
127     /**
128      * @return the motionState
129      */
130     public RigidBodyMotionState getMotionState() {
131         return motionState;
132     }
133
134     public boolean isInWorld() {
135         return isInWorld(objectId);
136     }
137
138     private native boolean isInWorld(long objectId);
139
140     /**
141      * Sets the physics object location
142      * @param location the location of the actual physics object
143      */
144     public void setPhysicsLocation(Vector3f location) {
145         setPhysicsLocation(objectId, location);
146     }
147
148     private native void setPhysicsLocation(long objectId, Vector3f location);
149
150     /**
151      * Sets the physics object rotation
152      * @param rotation the rotation of the actual physics object
153      */
154     public void setPhysicsRotation(Matrix3f rotation) {
155         setPhysicsRotation(objectId, rotation);
156     }
157
158     private native void setPhysicsRotation(long objectId, Matrix3f rotation);
159
160     /**
161      * Sets the physics object rotation
162      * @param rotation the rotation of the actual physics object
163      */
164     public void setPhysicsRotation(Quaternion rotation) {
165         setPhysicsRotation(objectId, rotation);
166     }
167
168     private native void setPhysicsRotation(long objectId, Quaternion rotation);
169
170     /**
171      * @return the physicsLocation
172      */
173     public Vector3f getPhysicsLocation(Vector3f trans) {
174         if (trans == null) {
175             trans = new Vector3f();
176         }
177         getPhysicsLocation(objectId, trans);
178         return trans;
179     }
180
181     private native void getPhysicsLocation(long objectId, Vector3f vector);
182
183     /**
184      * @return the physicsLocation
185      */
186     public Quaternion getPhysicsRotation(Quaternion rot) {
187         if (rot == null) {
188             rot = new Quaternion();
189         }
190         getPhysicsRotation(objectId, rot);
191         return rot;
192     }
193
194     private native void getPhysicsRotation(long objectId, Quaternion rot);
195
196     /**
197      * @return the physicsLocation
198      */
199     public Matrix3f getPhysicsRotationMatrix(Matrix3f rot) {
200         if (rot == null) {
201             rot = new Matrix3f();
202         }
203         getPhysicsRotationMatrix(objectId, rot);
204         return rot;
205     }
206
207     private native void getPhysicsRotationMatrix(long objectId, Matrix3f rot);
208
209     /**
210      * @return the physicsLocation
211      */
212     public Vector3f getPhysicsLocation() {
213         Vector3f vec = new Vector3f();
214         getPhysicsLocation(objectId, vec);
215         return vec;
216     }
217
218     /**
219      * @return the physicsLocation
220      */
221     public Quaternion getPhysicsRotation() {
222         Quaternion quat = new Quaternion();
223         getPhysicsRotation(objectId, quat);
224         return quat;
225     }
226
227     public Matrix3f getPhysicsRotationMatrix() {
228         Matrix3f mtx = new Matrix3f();
229         getPhysicsRotationMatrix(objectId, mtx);
230         return mtx;
231     }
232
233 //    /**
234 //     * Gets the physics object location
235 //     * @param location the location of the actual physics object is stored in this Vector3f
236 //     */
237 //    public Vector3f getInterpolatedPhysicsLocation(Vector3f location) {
238 //        if (location == null) {
239 //            location = new Vector3f();
240 //        }
241 //        rBody.getInterpolationWorldTransform(tempTrans);
242 //        return Converter.convert(tempTrans.origin, location);
243 //    }
244 //
245 //    /**
246 //     * Gets the physics object rotation
247 //     * @param rotation the rotation of the actual physics object is stored in this Matrix3f
248 //     */
249 //    public Matrix3f getInterpolatedPhysicsRotation(Matrix3f rotation) {
250 //        if (rotation == null) {
251 //            rotation = new Matrix3f();
252 //        }
253 //        rBody.getInterpolationWorldTransform(tempTrans);
254 //        return Converter.convert(tempTrans.basis, rotation);
255 //    }
256     /**
257      * Sets the node to kinematic mode. in this mode the node is not affected by physics
258      * but affects other physics objects. Iits kinetic force is calculated by the amount
259      * of movement it is exposed to and its weight.
260      * @param kinematic
261      */
262     public void setKinematic(boolean kinematic) {
263         this.kinematic = kinematic;
264         setKinematic(objectId, kinematic);
265     }
266
267     private native void setKinematic(long objectId, boolean kinematic);
268
269     public boolean isKinematic() {
270         return kinematic;
271     }
272
273     public void setCcdSweptSphereRadius(float radius) {
274         setCcdSweptSphereRadius(objectId, radius);
275     }
276
277     private native void setCcdSweptSphereRadius(long objectId, float radius);
278
279     /**
280      * Sets the amount of motion that has to happen in one physics tick to trigger the continuous motion detection<br/>
281      * This avoids the problem of fast objects moving through other objects, set to zero to disable (default)
282      * @param threshold
283      */
284     public void setCcdMotionThreshold(float threshold) {
285         setCcdMotionThreshold(objectId, threshold);
286     }
287
288     private native void setCcdMotionThreshold(long objectId, float threshold);
289
290     public float getCcdSweptSphereRadius() {
291         return getCcdSweptSphereRadius(objectId);
292     }
293
294     private native float getCcdSweptSphereRadius(long objectId);
295
296     public float getCcdMotionThreshold() {
297         return getCcdMotionThreshold(objectId);
298     }
299
300     private native float getCcdMotionThreshold(long objectId);
301
302     public float getCcdSquareMotionThreshold() {
303         return getCcdSquareMotionThreshold(objectId);
304     }
305
306     private native float getCcdSquareMotionThreshold(long objectId);
307
308     public float getMass() {
309         return mass;
310     }
311
312     /**
313      * Sets the mass of this PhysicsRigidBody, objects with mass=0 are static.
314      * @param mass
315      */
316     public void setMass(float mass) {
317         this.mass = mass;
318         if (collisionShape instanceof MeshCollisionShape && mass != 0) {
319             throw new IllegalStateException("Dynamic rigidbody can not have mesh collision shape!");
320         }
321         if (objectId != 0) {
322             if (collisionShape != null) {
323                 updateMassProps(objectId, collisionShape.getObjectId(), mass);
324             }
325             if (mass == 0.0f) {
326                 setStatic(objectId, true);
327             } else {
328                 setStatic(objectId, false);
329             }
330         }
331     }
332
333     private native void setStatic(long objectId, boolean state);
334
335     private native long updateMassProps(long objectId, long collisionShapeId, float mass);
336
337     public Vector3f getGravity() {
338         return getGravity(null);
339     }
340
341     public Vector3f getGravity(Vector3f gravity) {
342         if (gravity == null) {
343             gravity = new Vector3f();
344         }
345         getGravity(objectId, gravity);
346         return gravity;
347     }
348
349     private native void getGravity(long objectId, Vector3f gravity);
350
351     /**
352      * Set the local gravity of this PhysicsRigidBody<br/>
353      * Set this after adding the node to the PhysicsSpace,
354      * the PhysicsSpace assigns its current gravity to the physics node when its added.
355      * @param gravity the gravity vector to set
356      */
357     public void setGravity(Vector3f gravity) {
358         setGravity(objectId, gravity);
359     }
360
361     private native void setGravity(long objectId, Vector3f gravity);
362
363     public float getFriction() {
364         return getFriction(objectId);
365     }
366
367     private native float getFriction(long objectId);
368
369     /**
370      * Sets the friction of this physics object
371      * @param friction the friction of this physics object
372      */
373     public void setFriction(float friction) {
374         setFriction(objectId, friction);
375     }
376
377     private native void setFriction(long objectId, float friction);
378
379     public void setDamping(float linearDamping, float angularDamping) {
380         setDamping(objectId, linearDamping, angularDamping);
381     }
382
383     private native void setDamping(long objectId, float linearDamping, float angularDamping);
384
385 //    private native void setRestitution(long objectId, float factor);
386 //
387 //    public void setLinearDamping(float linearDamping) {
388 //        constructionInfo.linearDamping = linearDamping;
389 //        rBody.setDamping(linearDamping, constructionInfo.angularDamping);
390 //    }
391 //
392 //    private native void setRestitution(long objectId, float factor);
393 //
394 //    public void setAngularDamping(float angularDamping) {
395 ////        constructionInfo.angularDamping = angularDamping;
396 ////        rBody.setDamping(constructionInfo.linearDamping, angularDamping);
397 //        
398 //    }
399     private native void setAngularDamping(long objectId, float factor);
400
401     public float getLinearDamping() {
402         return getLinearDamping(objectId);
403     }
404
405     private native float getLinearDamping(long objectId);
406
407     public float getAngularDamping() {
408         return getAngularDamping(objectId);
409     }
410
411     private native float getAngularDamping(long objectId);
412
413     public float getRestitution() {
414         return getRestitution(objectId);
415     }
416
417     private native float getRestitution(long objectId);
418
419     /**
420      * The "bouncyness" of the PhysicsRigidBody, best performance if restitution=0
421      * @param restitution
422      */
423     public void setRestitution(float restitution) {
424         setRestitution(objectId, restitution);
425     }
426
427     private native void setRestitution(long objectId, float factor);
428
429     /**
430      * Get the current angular velocity of this PhysicsRigidBody
431      * @return the current linear velocity
432      */
433     public Vector3f getAngularVelocity() {
434         Vector3f vec = new Vector3f();
435         getAngularVelocity(objectId, vec);
436         return vec;
437     }
438
439     private native void getAngularVelocity(long objectId, Vector3f vec);
440
441     /**
442      * Get the current angular velocity of this PhysicsRigidBody
443      * @param vec the vector to store the velocity in
444      */
445     public void getAngularVelocity(Vector3f vec) {
446         getAngularVelocity(objectId, vec);
447     }
448
449     /**
450      * Sets the angular velocity of this PhysicsRigidBody
451      * @param vec the angular velocity of this PhysicsRigidBody
452      */
453     public void setAngularVelocity(Vector3f vec) {
454         setAngularVelocity(objectId, vec);
455         activate();
456     }
457
458     private native void setAngularVelocity(long objectId, Vector3f vec);
459
460     /**
461      * Get the current linear velocity of this PhysicsRigidBody
462      * @return the current linear velocity
463      */
464     public Vector3f getLinearVelocity() {
465         Vector3f vec = new Vector3f();
466         getLinearVelocity(objectId, vec);
467         return vec;
468     }
469
470     private native void getLinearVelocity(long objectId, Vector3f vec);
471
472     /**
473      * Get the current linear velocity of this PhysicsRigidBody
474      * @param vec the vector to store the velocity in
475      */
476     public void getLinearVelocity(Vector3f vec) {
477         getLinearVelocity(objectId, vec);
478     }
479
480     /**
481      * Sets the linear velocity of this PhysicsRigidBody
482      * @param vec the linear velocity of this PhysicsRigidBody
483      */
484     public void setLinearVelocity(Vector3f vec) {
485         setLinearVelocity(objectId, vec);
486         activate();
487     }
488
489     private native void setLinearVelocity(long objectId, Vector3f vec);
490
491     /**
492      * Apply a force to the PhysicsRigidBody, only applies force if the next physics update call
493      * updates the physics space.<br>
494      * To apply an impulse, use applyImpulse, use applyContinuousForce to apply continuous force.
495      * @param force the force
496      * @param location the location of the force
497      */
498     public void applyForce(Vector3f force, Vector3f location) {
499         applyForce(objectId, force, location);
500         activate();
501     }
502
503     private native void applyForce(long objectId, Vector3f force, Vector3f location);
504
505     /**
506      * Apply a force to the PhysicsRigidBody, only applies force if the next physics update call
507      * updates the physics space.<br>
508      * To apply an impulse, use applyImpulse.
509      * 
510      * @param force the force
511      */
512     public void applyCentralForce(Vector3f force) {
513         applyCentralForce(objectId, force);
514         activate();
515     }
516
517     private native void applyCentralForce(long objectId, Vector3f force);
518
519     /**
520      * Apply a force to the PhysicsRigidBody, only applies force if the next physics update call
521      * updates the physics space.<br>
522      * To apply an impulse, use applyImpulse.
523      * 
524      * @param torque the torque
525      */
526     public void applyTorque(Vector3f torque) {
527         applyTorque(objectId, torque);
528         activate();
529     }
530
531     private native void applyTorque(long objectId, Vector3f vec);
532
533     /**
534      * Apply an impulse to the PhysicsRigidBody in the next physics update.
535      * @param impulse applied impulse
536      * @param rel_pos location relative to object
537      */
538     public void applyImpulse(Vector3f impulse, Vector3f rel_pos) {
539         applyImpulse(objectId, impulse, rel_pos);
540         activate();
541     }
542
543     private native void applyImpulse(long objectId, Vector3f impulse, Vector3f rel_pos);
544
545     /**
546      * Apply a torque impulse to the PhysicsRigidBody in the next physics update.
547      * @param vec
548      */
549     public void applyTorqueImpulse(Vector3f vec) {
550         applyTorqueImpulse(objectId, vec);
551         activate();
552     }
553
554     private native void applyTorqueImpulse(long objectId, Vector3f vec);
555
556     /**
557      * Clear all forces from the PhysicsRigidBody
558      * 
559      */
560     public void clearForces() {
561         clearForces(objectId);
562     }
563
564     private native void clearForces(long objectId);
565
566     public void setCollisionShape(CollisionShape collisionShape) {
567         super.setCollisionShape(collisionShape);
568         if (collisionShape instanceof MeshCollisionShape && mass != 0) {
569             throw new IllegalStateException("Dynamic rigidbody can not have mesh collision shape!");
570         }
571         if (objectId == 0) {
572             rebuildRigidBody();
573         } else {
574             setCollisionShape(objectId, collisionShape.getObjectId());
575             updateMassProps(objectId, collisionShape.getObjectId(), mass);
576         }
577     }
578
579     private native void setCollisionShape(long objectId, long collisionShapeId);
580
581     /**
582      * reactivates this PhysicsRigidBody when it has been deactivated because it was not moving
583      */
584     public void activate() {
585         activate(objectId);
586     }
587
588     private native void activate(long objectId);
589
590     public boolean isActive() {
591         return isActive(objectId);
592     }
593
594     private native boolean isActive(long objectId);
595
596     /**
597      * sets the sleeping thresholds, these define when the object gets deactivated
598      * to save ressources. Low values keep the object active when it barely moves
599      * @param linear the linear sleeping threshold
600      * @param angular the angular sleeping threshold
601      */
602     public void setSleepingThresholds(float linear, float angular) {
603         setSleepingThresholds(objectId, linear, angular);
604     }
605
606     private native void setSleepingThresholds(long objectId, float linear, float angular);
607
608     public void setLinearSleepingThreshold(float linearSleepingThreshold) {
609         setLinearSleepingThreshold(objectId, linearSleepingThreshold);
610     }
611
612     private native void setLinearSleepingThreshold(long objectId, float linearSleepingThreshold);
613
614     public void setAngularSleepingThreshold(float angularSleepingThreshold) {
615         setAngularSleepingThreshold(objectId, angularSleepingThreshold);
616     }
617
618     private native void setAngularSleepingThreshold(long objectId, float angularSleepingThreshold);
619
620     public float getLinearSleepingThreshold() {
621         return getLinearSleepingThreshold(objectId);
622     }
623
624     private native float getLinearSleepingThreshold(long objectId);
625
626     public float getAngularSleepingThreshold() {
627         return getAngularSleepingThreshold(objectId);
628     }
629
630     private native float getAngularSleepingThreshold(long objectId);
631
632     public float getAngularFactor() {
633         return getAngularFactor(objectId);
634     }
635
636     private native float getAngularFactor(long objectId);
637
638     public void setAngularFactor(float factor) {
639         setAngularFactor(objectId, factor);
640     }
641
642     private native void setAngularFactor(long objectId, float factor);
643
644     /**
645      * do not use manually, joints are added automatically
646      */
647     public void addJoint(PhysicsJoint joint) {
648         if (!joints.contains(joint)) {
649             joints.add(joint);
650         }
651         updateDebugShape();
652     }
653
654     /**
655      * 
656      */
657     public void removeJoint(PhysicsJoint joint) {
658         joints.remove(joint);
659     }
660
661     /**
662      * Returns a list of connected joints. This list is only filled when
663      * the PhysicsRigidBody is actually added to the physics space or loaded from disk.
664      * @return list of active joints connected to this PhysicsRigidBody
665      */
666     public List<PhysicsJoint> getJoints() {
667         return joints;
668     }
669
670     @Override
671     protected Spatial getDebugShape() {
672         //add joints
673         Spatial shape = super.getDebugShape();
674         Node node = null;
675         if (shape instanceof Node) {
676             node = (Node) shape;
677         } else {
678             node = new Node("DebugShapeNode");
679             node.attachChild(shape);
680         }
681         int i = 0;
682         for (Iterator<PhysicsJoint> it = joints.iterator(); it.hasNext();) {
683             PhysicsJoint physicsJoint = it.next();
684             Vector3f pivot = null;
685             if (physicsJoint.getBodyA() == this) {
686                 pivot = physicsJoint.getPivotA();
687             } else {
688                 pivot = physicsJoint.getPivotB();
689             }
690             Arrow arrow = new Arrow(pivot);
691             Geometry geom = new Geometry("DebugBone" + i, arrow);
692             geom.setMaterial(debugMaterialGreen);
693             node.attachChild(geom);
694             i++;
695         }
696         return node;
697     }
698
699     @Override
700     public void write(JmeExporter e) throws IOException {
701         super.write(e);
702         OutputCapsule capsule = e.getCapsule(this);
703
704         capsule.write(getMass(), "mass", 1.0f);
705
706         capsule.write(getGravity(), "gravity", Vector3f.ZERO);
707         capsule.write(getFriction(), "friction", 0.5f);
708         capsule.write(getRestitution(), "restitution", 0);
709         capsule.write(getAngularFactor(), "angularFactor", 1);
710         capsule.write(kinematic, "kinematic", false);
711
712         capsule.write(getLinearDamping(), "linearDamping", 0);
713         capsule.write(getAngularDamping(), "angularDamping", 0);
714         capsule.write(getLinearSleepingThreshold(), "linearSleepingThreshold", 0.8f);
715         capsule.write(getAngularSleepingThreshold(), "angularSleepingThreshold", 1.0f);
716
717         capsule.write(getCcdMotionThreshold(), "ccdMotionThreshold", 0);
718         capsule.write(getCcdSweptSphereRadius(), "ccdSweptSphereRadius", 0);
719
720         capsule.write(getPhysicsLocation(new Vector3f()), "physicsLocation", new Vector3f());
721         capsule.write(getPhysicsRotationMatrix(new Matrix3f()), "physicsRotation", new Matrix3f());
722
723         capsule.writeSavableArrayList(joints, "joints", null);
724     }
725
726     @Override
727     public void read(JmeImporter e) throws IOException {
728         super.read(e);
729
730         InputCapsule capsule = e.getCapsule(this);
731         float mass = capsule.readFloat("mass", 1.0f);
732         this.mass = mass;
733         rebuildRigidBody();
734         setGravity((Vector3f) capsule.readSavable("gravity", Vector3f.ZERO.clone()));
735         setFriction(capsule.readFloat("friction", 0.5f));
736         setKinematic(capsule.readBoolean("kinematic", false));
737
738         setRestitution(capsule.readFloat("restitution", 0));
739         setAngularFactor(capsule.readFloat("angularFactor", 1));
740         setDamping(capsule.readFloat("linearDamping", 0), capsule.readFloat("angularDamping", 0));
741         setSleepingThresholds(capsule.readFloat("linearSleepingThreshold", 0.8f), capsule.readFloat("angularSleepingThreshold", 1.0f));
742         setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0));
743         setCcdSweptSphereRadius(capsule.readFloat("ccdSweptSphereRadius", 0));
744
745         setPhysicsLocation((Vector3f) capsule.readSavable("physicsLocation", new Vector3f()));
746         setPhysicsRotation((Matrix3f) capsule.readSavable("physicsRotation", new Matrix3f()));
747
748         joints = capsule.readSavableArrayList("joints", null);
749     }
750 }