You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
668 lines
23 KiB
668 lines
23 KiB
/*
|
|
* Copyright (c) 2009-2012 jMonkeyEngine
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
package com.jme3.bullet.objects;
|
|
|
|
import com.bulletphysics.collision.dispatch.CollisionFlags;
|
|
import com.bulletphysics.dynamics.RigidBody;
|
|
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
|
|
import com.bulletphysics.linearmath.Transform;
|
|
import com.jme3.bullet.PhysicsSpace;
|
|
import com.jme3.bullet.collision.PhysicsCollisionObject;
|
|
import com.jme3.bullet.collision.shapes.CollisionShape;
|
|
import com.jme3.bullet.collision.shapes.MeshCollisionShape;
|
|
import com.jme3.bullet.joints.PhysicsJoint;
|
|
import com.jme3.bullet.objects.infos.RigidBodyMotionState;
|
|
import com.jme3.bullet.util.Converter;
|
|
import com.jme3.export.InputCapsule;
|
|
import com.jme3.export.JmeExporter;
|
|
import com.jme3.export.JmeImporter;
|
|
import com.jme3.export.OutputCapsule;
|
|
import com.jme3.math.Matrix3f;
|
|
import com.jme3.math.Quaternion;
|
|
import com.jme3.math.Vector3f;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* <p>PhysicsRigidBody - Basic physics object</p>
|
|
* @author normenhansen
|
|
*/
|
|
public class PhysicsRigidBody extends PhysicsCollisionObject {
|
|
|
|
protected RigidBodyConstructionInfo constructionInfo;
|
|
protected RigidBody rBody;
|
|
protected RigidBodyMotionState motionState = new RigidBodyMotionState();
|
|
protected float mass = 1.0f;
|
|
protected boolean kinematic = false;
|
|
protected javax.vecmath.Vector3f tempVec = new javax.vecmath.Vector3f();
|
|
protected javax.vecmath.Vector3f tempVec2 = new javax.vecmath.Vector3f();
|
|
protected Transform tempTrans = new Transform(new javax.vecmath.Matrix3f());
|
|
protected javax.vecmath.Matrix3f tempMatrix = new javax.vecmath.Matrix3f();
|
|
//TEMP VARIABLES
|
|
protected javax.vecmath.Vector3f localInertia = new javax.vecmath.Vector3f();
|
|
protected ArrayList<PhysicsJoint> joints = new ArrayList<PhysicsJoint>();
|
|
|
|
public PhysicsRigidBody() {
|
|
}
|
|
|
|
/**
|
|
* Creates a new PhysicsRigidBody with the supplied collision shape
|
|
* @param shape
|
|
*/
|
|
public PhysicsRigidBody(CollisionShape shape) {
|
|
collisionShape = shape;
|
|
rebuildRigidBody();
|
|
}
|
|
|
|
public PhysicsRigidBody(CollisionShape shape, float mass) {
|
|
collisionShape = shape;
|
|
this.mass = mass;
|
|
rebuildRigidBody();
|
|
}
|
|
|
|
/**
|
|
* Builds/rebuilds the phyiscs body when parameters have changed
|
|
*/
|
|
protected void rebuildRigidBody() {
|
|
boolean removed = false;
|
|
if(collisionShape instanceof MeshCollisionShape && mass != 0){
|
|
throw new IllegalStateException("Dynamic rigidbody can not have mesh collision shape!");
|
|
}
|
|
if (rBody != null) {
|
|
if (rBody.isInWorld()) {
|
|
PhysicsSpace.getPhysicsSpace().remove(this);
|
|
removed = true;
|
|
}
|
|
rBody.destroy();
|
|
}
|
|
preRebuild();
|
|
rBody = new RigidBody(constructionInfo);
|
|
postRebuild();
|
|
if (removed) {
|
|
PhysicsSpace.getPhysicsSpace().add(this);
|
|
}
|
|
}
|
|
|
|
protected void preRebuild() {
|
|
collisionShape.calculateLocalInertia(mass, localInertia);
|
|
if (constructionInfo == null) {
|
|
constructionInfo = new RigidBodyConstructionInfo(mass, motionState, collisionShape.getCShape(), localInertia);
|
|
} else {
|
|
constructionInfo.mass = mass;
|
|
constructionInfo.collisionShape = collisionShape.getCShape();
|
|
constructionInfo.motionState = motionState;
|
|
}
|
|
}
|
|
|
|
protected void postRebuild() {
|
|
rBody.setUserPointer(this);
|
|
if (mass == 0.0f) {
|
|
rBody.setCollisionFlags(rBody.getCollisionFlags() | CollisionFlags.STATIC_OBJECT);
|
|
} else {
|
|
rBody.setCollisionFlags(rBody.getCollisionFlags() & ~CollisionFlags.STATIC_OBJECT);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return the motionState
|
|
*/
|
|
public RigidBodyMotionState getMotionState() {
|
|
return motionState;
|
|
}
|
|
|
|
/**
|
|
* Sets the physics object location
|
|
* @param location the location of the actual physics object
|
|
*/
|
|
public void setPhysicsLocation(Vector3f location) {
|
|
rBody.getCenterOfMassTransform(tempTrans);
|
|
Converter.convert(location, tempTrans.origin);
|
|
rBody.setCenterOfMassTransform(tempTrans);
|
|
motionState.setWorldTransform(tempTrans);
|
|
}
|
|
|
|
/**
|
|
* Sets the physics object rotation
|
|
* @param rotation the rotation of the actual physics object
|
|
*/
|
|
public void setPhysicsRotation(Matrix3f rotation) {
|
|
rBody.getCenterOfMassTransform(tempTrans);
|
|
Converter.convert(rotation, tempTrans.basis);
|
|
rBody.setCenterOfMassTransform(tempTrans);
|
|
motionState.setWorldTransform(tempTrans);
|
|
}
|
|
|
|
/**
|
|
* Sets the physics object rotation
|
|
* @param rotation the rotation of the actual physics object
|
|
*/
|
|
public void setPhysicsRotation(Quaternion rotation) {
|
|
rBody.getCenterOfMassTransform(tempTrans);
|
|
Converter.convert(rotation, tempTrans.basis);
|
|
rBody.setCenterOfMassTransform(tempTrans);
|
|
motionState.setWorldTransform(tempTrans);
|
|
}
|
|
|
|
/**
|
|
* Gets the physics object location, instantiates a new Vector3f object
|
|
*/
|
|
public Vector3f getPhysicsLocation() {
|
|
return getPhysicsLocation(null);
|
|
}
|
|
|
|
/**
|
|
* Gets the physics object rotation
|
|
*/
|
|
public Matrix3f getPhysicsRotationMatrix() {
|
|
return getPhysicsRotationMatrix(null);
|
|
}
|
|
|
|
/**
|
|
* Gets the physics object location, no object instantiation
|
|
* @param location the location of the actual physics object is stored in this Vector3f
|
|
*/
|
|
public Vector3f getPhysicsLocation(Vector3f location) {
|
|
if (location == null) {
|
|
location = new Vector3f();
|
|
}
|
|
rBody.getCenterOfMassTransform(tempTrans);
|
|
return Converter.convert(tempTrans.origin, location);
|
|
}
|
|
|
|
/**
|
|
* Gets the physics object rotation as a matrix, no conversions and no object instantiation
|
|
* @param rotation the rotation of the actual physics object is stored in this Matrix3f
|
|
*/
|
|
public Matrix3f getPhysicsRotationMatrix(Matrix3f rotation) {
|
|
if (rotation == null) {
|
|
rotation = new Matrix3f();
|
|
}
|
|
rBody.getCenterOfMassTransform(tempTrans);
|
|
return Converter.convert(tempTrans.basis, rotation);
|
|
}
|
|
|
|
/**
|
|
* Gets the physics object rotation as a quaternion, converts the bullet Matrix3f value,
|
|
* instantiates new object
|
|
*/
|
|
public Quaternion getPhysicsRotation(){
|
|
return getPhysicsRotation(null);
|
|
}
|
|
|
|
/**
|
|
* Gets the physics object rotation as a quaternion, converts the bullet Matrix3f value
|
|
* @param rotation the rotation of the actual physics object is stored in this Quaternion
|
|
*/
|
|
public Quaternion getPhysicsRotation(Quaternion rotation){
|
|
if (rotation == null) {
|
|
rotation = new Quaternion();
|
|
}
|
|
rBody.getCenterOfMassTransform(tempTrans);
|
|
return Converter.convert(tempTrans.basis, rotation);
|
|
}
|
|
|
|
/**
|
|
* Gets the physics object location
|
|
* @param location the location of the actual physics object is stored in this Vector3f
|
|
*/
|
|
public Vector3f getInterpolatedPhysicsLocation(Vector3f location) {
|
|
if (location == null) {
|
|
location = new Vector3f();
|
|
}
|
|
rBody.getInterpolationWorldTransform(tempTrans);
|
|
return Converter.convert(tempTrans.origin, location);
|
|
}
|
|
|
|
/**
|
|
* Gets the physics object rotation
|
|
* @param rotation the rotation of the actual physics object is stored in this Matrix3f
|
|
*/
|
|
public Matrix3f getInterpolatedPhysicsRotation(Matrix3f rotation) {
|
|
if (rotation == null) {
|
|
rotation = new Matrix3f();
|
|
}
|
|
rBody.getInterpolationWorldTransform(tempTrans);
|
|
return Converter.convert(tempTrans.basis, rotation);
|
|
}
|
|
|
|
/**
|
|
* Sets the node to kinematic mode. in this mode the node is not affected by physics
|
|
* but affects other physics objects. Its kinetic force is calculated by the amount
|
|
* of movement it is exposed to and its weight.
|
|
* @param kinematic
|
|
*/
|
|
public void setKinematic(boolean kinematic) {
|
|
this.kinematic = kinematic;
|
|
if (kinematic) {
|
|
rBody.setCollisionFlags(rBody.getCollisionFlags() | CollisionFlags.KINEMATIC_OBJECT);
|
|
rBody.setActivationState(com.bulletphysics.collision.dispatch.CollisionObject.DISABLE_DEACTIVATION);
|
|
} else {
|
|
rBody.setCollisionFlags(rBody.getCollisionFlags() & ~CollisionFlags.KINEMATIC_OBJECT);
|
|
rBody.setActivationState(com.bulletphysics.collision.dispatch.CollisionObject.ACTIVE_TAG);
|
|
}
|
|
}
|
|
|
|
public boolean isKinematic() {
|
|
return kinematic;
|
|
}
|
|
|
|
public void setCcdSweptSphereRadius(float radius) {
|
|
rBody.setCcdSweptSphereRadius(radius);
|
|
}
|
|
|
|
/**
|
|
* Sets the amount of motion that has to happen in one physics tick to trigger the continuous motion detection<br/>
|
|
* This avoids the problem of fast objects moving through other objects, set to zero to disable (default)
|
|
* @param threshold
|
|
*/
|
|
public void setCcdMotionThreshold(float threshold) {
|
|
rBody.setCcdMotionThreshold(threshold);
|
|
}
|
|
|
|
public float getCcdSweptSphereRadius() {
|
|
return rBody.getCcdSweptSphereRadius();
|
|
}
|
|
|
|
public float getCcdMotionThreshold() {
|
|
return rBody.getCcdMotionThreshold();
|
|
}
|
|
|
|
public float getCcdSquareMotionThreshold() {
|
|
return rBody.getCcdSquareMotionThreshold();
|
|
}
|
|
|
|
public float getMass() {
|
|
return mass;
|
|
}
|
|
|
|
/**
|
|
* Sets the mass of this PhysicsRigidBody, objects with mass=0 are static.
|
|
* @param mass
|
|
*/
|
|
public void setMass(float mass) {
|
|
this.mass = mass;
|
|
if(collisionShape instanceof MeshCollisionShape && mass != 0){
|
|
throw new IllegalStateException("Dynamic rigidbody can not have mesh collision shape!");
|
|
}
|
|
if (collisionShape != null) {
|
|
collisionShape.calculateLocalInertia(mass, localInertia);
|
|
}
|
|
if (rBody != null) {
|
|
rBody.setMassProps(mass, localInertia);
|
|
if (mass == 0.0f) {
|
|
rBody.setCollisionFlags(rBody.getCollisionFlags() | CollisionFlags.STATIC_OBJECT);
|
|
} else {
|
|
rBody.setCollisionFlags(rBody.getCollisionFlags() & ~CollisionFlags.STATIC_OBJECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Vector3f getGravity() {
|
|
return getGravity(null);
|
|
}
|
|
|
|
public Vector3f getGravity(Vector3f gravity) {
|
|
if (gravity == null) {
|
|
gravity = new Vector3f();
|
|
}
|
|
rBody.getGravity(tempVec);
|
|
return Converter.convert(tempVec, gravity);
|
|
}
|
|
|
|
/**
|
|
* Set the local gravity of this PhysicsRigidBody<br/>
|
|
* Set this after adding the node to the PhysicsSpace,
|
|
* the PhysicsSpace assigns its current gravity to the physics node when its added.
|
|
* @param gravity the gravity vector to set
|
|
*/
|
|
public void setGravity(Vector3f gravity) {
|
|
rBody.setGravity(Converter.convert(gravity, tempVec));
|
|
}
|
|
|
|
public float getFriction() {
|
|
return rBody.getFriction();
|
|
}
|
|
|
|
/**
|
|
* Sets the friction of this physics object
|
|
* @param friction the friction of this physics object
|
|
*/
|
|
public void setFriction(float friction) {
|
|
constructionInfo.friction = friction;
|
|
rBody.setFriction(friction);
|
|
}
|
|
|
|
public void setDamping(float linearDamping, float angularDamping) {
|
|
constructionInfo.linearDamping = linearDamping;
|
|
constructionInfo.angularDamping = angularDamping;
|
|
rBody.setDamping(linearDamping, angularDamping);
|
|
}
|
|
|
|
public void setLinearDamping(float linearDamping) {
|
|
constructionInfo.linearDamping = linearDamping;
|
|
rBody.setDamping(linearDamping, constructionInfo.angularDamping);
|
|
}
|
|
|
|
public void setAngularDamping(float angularDamping) {
|
|
constructionInfo.angularDamping = angularDamping;
|
|
rBody.setDamping(constructionInfo.linearDamping, angularDamping);
|
|
}
|
|
|
|
public float getLinearDamping() {
|
|
return constructionInfo.linearDamping;
|
|
}
|
|
|
|
public float getAngularDamping() {
|
|
return constructionInfo.angularDamping;
|
|
}
|
|
|
|
public float getRestitution() {
|
|
return rBody.getRestitution();
|
|
}
|
|
|
|
/**
|
|
* The "bouncyness" of the PhysicsRigidBody, best performance if restitution=0
|
|
* @param restitution
|
|
*/
|
|
public void setRestitution(float restitution) {
|
|
constructionInfo.restitution = restitution;
|
|
rBody.setRestitution(restitution);
|
|
}
|
|
|
|
/**
|
|
* Get the current angular velocity of this PhysicsRigidBody
|
|
* @return the current linear velocity
|
|
*/
|
|
public Vector3f getAngularVelocity() {
|
|
return Converter.convert(rBody.getAngularVelocity(tempVec));
|
|
}
|
|
|
|
/**
|
|
* Get the current angular velocity of this PhysicsRigidBody
|
|
* @param vec the vector to store the velocity in
|
|
*/
|
|
public void getAngularVelocity(Vector3f vec) {
|
|
Converter.convert(rBody.getAngularVelocity(tempVec), vec);
|
|
}
|
|
|
|
/**
|
|
* Sets the angular velocity of this PhysicsRigidBody
|
|
* @param vec the angular velocity of this PhysicsRigidBody
|
|
*/
|
|
public void setAngularVelocity(Vector3f vec) {
|
|
rBody.setAngularVelocity(Converter.convert(vec, tempVec));
|
|
rBody.activate();
|
|
}
|
|
|
|
/**
|
|
* Get the current linear velocity of this PhysicsRigidBody
|
|
* @return the current linear velocity
|
|
*/
|
|
public Vector3f getLinearVelocity() {
|
|
return Converter.convert(rBody.getLinearVelocity(tempVec));
|
|
}
|
|
|
|
/**
|
|
* Get the current linear velocity of this PhysicsRigidBody
|
|
* @param vec the vector to store the velocity in
|
|
*/
|
|
public void getLinearVelocity(Vector3f vec) {
|
|
Converter.convert(rBody.getLinearVelocity(tempVec), vec);
|
|
}
|
|
|
|
/**
|
|
* Sets the linear velocity of this PhysicsRigidBody
|
|
* @param vec the linear velocity of this PhysicsRigidBody
|
|
*/
|
|
public void setLinearVelocity(Vector3f vec) {
|
|
rBody.setLinearVelocity(Converter.convert(vec, tempVec));
|
|
rBody.activate();
|
|
}
|
|
|
|
/**
|
|
* Apply a force to the PhysicsRigidBody, only applies force if the next physics update call
|
|
* updates the physics space.<br>
|
|
* To apply an impulse, use applyImpulse, use applyContinuousForce to apply continuous force.
|
|
* @param force the force
|
|
* @param location the location of the force
|
|
*/
|
|
public void applyForce(final Vector3f force, final Vector3f location) {
|
|
rBody.applyForce(Converter.convert(force, tempVec), Converter.convert(location, tempVec2));
|
|
rBody.activate();
|
|
}
|
|
|
|
/**
|
|
* Apply a force to the PhysicsRigidBody, only applies force if the next physics update call
|
|
* updates the physics space.<br>
|
|
* To apply an impulse, use applyImpulse.
|
|
*
|
|
* @param force the force
|
|
*/
|
|
public void applyCentralForce(final Vector3f force) {
|
|
rBody.applyCentralForce(Converter.convert(force, tempVec));
|
|
rBody.activate();
|
|
}
|
|
|
|
/**
|
|
* Apply a force to the PhysicsRigidBody, only applies force if the next physics update call
|
|
* updates the physics space.<br>
|
|
* To apply an impulse, use applyImpulse.
|
|
*
|
|
* @param torque the torque
|
|
*/
|
|
public void applyTorque(final Vector3f torque) {
|
|
rBody.applyTorque(Converter.convert(torque, tempVec));
|
|
rBody.activate();
|
|
}
|
|
|
|
/**
|
|
* Apply an impulse to the PhysicsRigidBody in the next physics update.
|
|
* @param impulse applied impulse
|
|
* @param rel_pos location relative to object
|
|
*/
|
|
public void applyImpulse(final Vector3f impulse, final Vector3f rel_pos) {
|
|
rBody.applyImpulse(Converter.convert(impulse, tempVec), Converter.convert(rel_pos, tempVec2));
|
|
rBody.activate();
|
|
}
|
|
|
|
/**
|
|
* Apply a torque impulse to the PhysicsRigidBody in the next physics update.
|
|
* @param vec
|
|
*/
|
|
public void applyTorqueImpulse(final Vector3f vec) {
|
|
rBody.applyTorqueImpulse(Converter.convert(vec, tempVec));
|
|
rBody.activate();
|
|
}
|
|
|
|
/**
|
|
* Clear all forces from the PhysicsRigidBody
|
|
*
|
|
*/
|
|
public void clearForces() {
|
|
rBody.clearForces();
|
|
}
|
|
|
|
public void setCollisionShape(CollisionShape collisionShape) {
|
|
super.setCollisionShape(collisionShape);
|
|
if(collisionShape instanceof MeshCollisionShape && mass!=0){
|
|
throw new IllegalStateException("Dynamic rigidbody can not have mesh collision shape!");
|
|
}
|
|
if (rBody == null) {
|
|
rebuildRigidBody();
|
|
} else {
|
|
collisionShape.calculateLocalInertia(mass, localInertia);
|
|
constructionInfo.collisionShape = collisionShape.getCShape();
|
|
rBody.setCollisionShape(collisionShape.getCShape());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* reactivates this PhysicsRigidBody when it has been deactivated because it was not moving
|
|
*/
|
|
public void activate() {
|
|
rBody.activate();
|
|
}
|
|
|
|
public boolean isActive() {
|
|
return rBody.isActive();
|
|
}
|
|
|
|
/**
|
|
* sets the sleeping thresholds, these define when the object gets deactivated
|
|
* to save ressources. Low values keep the object active when it barely moves
|
|
* @param linear the linear sleeping threshold
|
|
* @param angular the angular sleeping threshold
|
|
*/
|
|
public void setSleepingThresholds(float linear, float angular) {
|
|
constructionInfo.linearSleepingThreshold = linear;
|
|
constructionInfo.angularSleepingThreshold = angular;
|
|
rBody.setSleepingThresholds(linear, angular);
|
|
}
|
|
|
|
public void setLinearSleepingThreshold(float linearSleepingThreshold) {
|
|
constructionInfo.linearSleepingThreshold = linearSleepingThreshold;
|
|
rBody.setSleepingThresholds(linearSleepingThreshold, constructionInfo.angularSleepingThreshold);
|
|
}
|
|
|
|
public void setAngularSleepingThreshold(float angularSleepingThreshold) {
|
|
constructionInfo.angularSleepingThreshold = angularSleepingThreshold;
|
|
rBody.setSleepingThresholds(constructionInfo.linearSleepingThreshold, angularSleepingThreshold);
|
|
}
|
|
|
|
public float getLinearSleepingThreshold() {
|
|
return constructionInfo.linearSleepingThreshold;
|
|
}
|
|
|
|
public float getAngularSleepingThreshold() {
|
|
return constructionInfo.angularSleepingThreshold;
|
|
}
|
|
|
|
public float getAngularFactor() {
|
|
return rBody.getAngularFactor();
|
|
}
|
|
|
|
public void setAngularFactor(float factor) {
|
|
rBody.setAngularFactor(factor);
|
|
}
|
|
|
|
/**
|
|
* do not use manually, joints are added automatically
|
|
*/
|
|
public void addJoint(PhysicsJoint joint) {
|
|
if (!joints.contains(joint)) {
|
|
joints.add(joint);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public void removeJoint(PhysicsJoint joint) {
|
|
joints.remove(joint);
|
|
}
|
|
|
|
/**
|
|
* Returns a list of connected joints. This list is only filled when
|
|
* the PhysicsRigidBody is actually added to the physics space or loaded from disk.
|
|
* @return list of active joints connected to this PhysicsRigidBody
|
|
*/
|
|
public List<PhysicsJoint> getJoints() {
|
|
return joints;
|
|
}
|
|
|
|
/**
|
|
* used internally
|
|
*/
|
|
public RigidBody getObjectId() {
|
|
return rBody;
|
|
}
|
|
|
|
/**
|
|
* destroys this PhysicsRigidBody and removes it from memory
|
|
*/
|
|
public void destroy() {
|
|
rBody.destroy();
|
|
}
|
|
|
|
@Override
|
|
public void write(JmeExporter e) throws IOException {
|
|
super.write(e);
|
|
OutputCapsule capsule = e.getCapsule(this);
|
|
|
|
capsule.write(getMass(), "mass", 1.0f);
|
|
|
|
capsule.write(getGravity(), "gravity", Vector3f.ZERO);
|
|
capsule.write(getFriction(), "friction", 0.5f);
|
|
capsule.write(getRestitution(), "restitution", 0);
|
|
capsule.write(getAngularFactor(), "angularFactor", 1);
|
|
capsule.write(kinematic, "kinematic", false);
|
|
|
|
capsule.write(constructionInfo.linearDamping, "linearDamping", 0);
|
|
capsule.write(constructionInfo.angularDamping, "angularDamping", 0);
|
|
capsule.write(constructionInfo.linearSleepingThreshold, "linearSleepingThreshold", 0.8f);
|
|
capsule.write(constructionInfo.angularSleepingThreshold, "angularSleepingThreshold", 1.0f);
|
|
|
|
capsule.write(getCcdMotionThreshold(), "ccdMotionThreshold", 0);
|
|
capsule.write(getCcdSweptSphereRadius(), "ccdSweptSphereRadius", 0);
|
|
|
|
capsule.write(getPhysicsLocation(new Vector3f()), "physicsLocation", new Vector3f());
|
|
capsule.write(getPhysicsRotationMatrix(new Matrix3f()), "physicsRotation", new Matrix3f());
|
|
|
|
capsule.writeSavableArrayList(joints, "joints", null);
|
|
}
|
|
|
|
@Override
|
|
public void read(JmeImporter e) throws IOException {
|
|
super.read(e);
|
|
|
|
InputCapsule capsule = e.getCapsule(this);
|
|
float mass = capsule.readFloat("mass", 1.0f);
|
|
this.mass = mass;
|
|
rebuildRigidBody();
|
|
setGravity((Vector3f) capsule.readSavable("gravity", Vector3f.ZERO.clone()));
|
|
setFriction(capsule.readFloat("friction", 0.5f));
|
|
setKinematic(capsule.readBoolean("kinematic", false));
|
|
|
|
setRestitution(capsule.readFloat("restitution", 0));
|
|
setAngularFactor(capsule.readFloat("angularFactor", 1));
|
|
setDamping(capsule.readFloat("linearDamping", 0), capsule.readFloat("angularDamping", 0));
|
|
setSleepingThresholds(capsule.readFloat("linearSleepingThreshold", 0.8f), capsule.readFloat("angularSleepingThreshold", 1.0f));
|
|
setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0));
|
|
setCcdSweptSphereRadius(capsule.readFloat("ccdSweptSphereRadius", 0));
|
|
|
|
setPhysicsLocation((Vector3f) capsule.readSavable("physicsLocation", new Vector3f()));
|
|
setPhysicsRotation((Matrix3f) capsule.readSavable("physicsRotation", new Matrix3f()));
|
|
|
|
joints = capsule.readSavableArrayList("joints", null);
|
|
}
|
|
}
|
|
|