| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
- package com.jme3.bullet.control;
- import com.jme3.bullet.PhysicsSpace;
- import com.jme3.bullet.collision.shapes.BoxCollisionShape;
- import com.jme3.bullet.collision.shapes.CollisionShape;
- import com.jme3.bullet.collision.shapes.SphereCollisionShape;
- import com.jme3.bullet.objects.PhysicsRigidBody;
- import com.jme3.bullet.util.CollisionShapeFactory;
- import com.jme3.export.InputCapsule;
- import com.jme3.export.JmeExporter;
- import com.jme3.export.JmeImporter;
- import com.jme3.export.OutputCapsule;
- import com.jme3.math.Quaternion;
- import com.jme3.math.Vector3f;
- import com.jme3.renderer.RenderManager;
- import com.jme3.renderer.ViewPort;
- import com.jme3.scene.Geometry;
- import com.jme3.scene.Mesh;
- import com.jme3.scene.Node;
- import com.jme3.scene.Spatial;
- import com.jme3.scene.control.Control;
- import com.jme3.scene.shape.Box;
- import com.jme3.scene.shape.Sphere;
- import java.io.IOException;
- /**
- *
- * @author normenhansen
- */
- public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl {
- protected Spatial spatial;
- protected boolean enabled = true;
- protected boolean added = false;
- protected PhysicsSpace space = null;
- protected boolean kinematicSpatial = true;
- public RigidBodyControl() {
- }
- /**
- * When using this constructor, the CollisionShape for the RigidBody is generated
- * automatically when the Control is added to a Spatial.
- * @param mass When not 0, a HullCollisionShape is generated, otherwise a MeshCollisionShape is used. For geometries with box or sphere meshes the proper box or sphere collision shape is used.
- */
- public RigidBodyControl(float mass) {
- this.mass = mass;
- }
- /**
- * Creates a new PhysicsNode with the supplied collision shape
- * @param child
- * @param shape
- */
- public RigidBodyControl(CollisionShape shape) {
- super(shape);
- }
- public RigidBodyControl(CollisionShape shape, float mass) {
- super(shape, mass);
- }
- public Control cloneForSpatial(Spatial spatial) {
- RigidBodyControl control = new RigidBodyControl(collisionShape, mass);
- control.setAngularFactor(getAngularFactor());
- control.setAngularSleepingThreshold(getAngularSleepingThreshold());
- control.setCcdMotionThreshold(getCcdMotionThreshold());
- control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
- control.setCollideWithGroups(getCollideWithGroups());
- control.setCollisionGroup(getCollisionGroup());
- control.setDamping(getLinearDamping(), getAngularDamping());
- control.setFriction(getFriction());
- control.setGravity(getGravity());
- control.setKinematic(isKinematic());
- control.setKinematicSpatial(isKinematicSpatial());
- control.setLinearSleepingThreshold(getLinearSleepingThreshold());
- control.setPhysicsLocation(getPhysicsLocation(null));
- control.setPhysicsRotation(getPhysicsRotationMatrix(null));
- control.setRestitution(getRestitution());
- if (mass > 0) {
- control.setAngularVelocity(getAngularVelocity());
- control.setLinearVelocity(getLinearVelocity());
- }
- control.setApplyPhysicsLocal(isApplyPhysicsLocal());
- control.setSpatial(spatial);
- return control;
- }
- public void setSpatial(Spatial spatial) {
- if (getUserObject() == null || getUserObject() == this.spatial) {
- setUserObject(spatial);
- }
- this.spatial = spatial;
- if (spatial == null) {
- if (getUserObject() == spatial) {
- setUserObject(null);
- }
- spatial = null;
- collisionShape = null;
- return;
- }
- if (collisionShape == null) {
- createCollisionShape();
- rebuildRigidBody();
- }
- setPhysicsLocation(getSpatialTranslation());
- setPhysicsRotation(getSpatialRotation());
- }
- protected void createCollisionShape() {
- if (spatial == null) {
- return;
- }
- if (spatial instanceof Geometry) {
- Geometry geom = (Geometry) spatial;
- Mesh mesh = geom.getMesh();
- if (mesh instanceof Sphere) {
- collisionShape = new SphereCollisionShape(((Sphere) mesh).getRadius());
- return;
- } else if (mesh instanceof Box) {
- collisionShape = new BoxCollisionShape(new Vector3f(((Box) mesh).getXExtent(), ((Box) mesh).getYExtent(), ((Box) mesh).getZExtent()));
- return;
- }
- }
- if (mass > 0) {
- collisionShape = CollisionShapeFactory.createDynamicMeshShape(spatial);
- } else {
- collisionShape = CollisionShapeFactory.createMeshShape(spatial);
- }
- }
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- if (space != null) {
- if (enabled && !added) {
- if (spatial != null) {
- setPhysicsLocation(getSpatialTranslation());
- setPhysicsRotation(getSpatialRotation());
- }
- space.addCollisionObject(this);
- added = true;
- } else if (!enabled && added) {
- space.removeCollisionObject(this);
- added = false;
- }
- }
- }
- public boolean isEnabled() {
- return enabled;
- }
- /**
- * Checks if this control is in kinematic spatial mode.
- * @return true if the spatial location is applied to this kinematic rigidbody
- */
- public boolean isKinematicSpatial() {
- return kinematicSpatial;
- }
- /**
- * Sets this control to kinematic spatial mode so that the spatials transform will
- * be applied to the rigidbody in kinematic mode, defaults to true.
- * @param kinematicSpatial
- */
- public void setKinematicSpatial(boolean kinematicSpatial) {
- this.kinematicSpatial = kinematicSpatial;
- }
- public boolean isApplyPhysicsLocal() {
- return motionState.isApplyPhysicsLocal();
- }
- /**
- * When set to true, the physics coordinates will be applied to the local
- * translation of the Spatial
- * @param applyPhysicsLocal
- */
- public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
- motionState.setApplyPhysicsLocal(applyPhysicsLocal);
- }
- private Vector3f getSpatialTranslation(){
- if(motionState.isApplyPhysicsLocal()){
- return spatial.getLocalTranslation();
- }
- return spatial.getWorldTranslation();
- }
- private Quaternion getSpatialRotation(){
- if(motionState.isApplyPhysicsLocal()){
- return spatial.getLocalRotation();
- }
- return spatial.getWorldRotation();
- }
- public void update(float tpf) {
- if (enabled && spatial != null) {
- if (isKinematic() && kinematicSpatial) {
- super.setPhysicsLocation(getSpatialTranslation());
- super.setPhysicsRotation(getSpatialRotation());
- } else {
- getMotionState().applyTransform(spatial);
- }
- }
- }
- public void render(RenderManager rm, ViewPort vp) {
- if (enabled && space != null && space.getDebugManager() != null) {
- if (debugShape == null) {
- attachDebugShape(space.getDebugManager());
- }
- //TODO: using spatial traslation/rotation..
- debugShape.setLocalTranslation(spatial.getWorldTranslation());
- debugShape.setLocalRotation(spatial.getWorldRotation());
- debugShape.updateLogicalState(0);
- debugShape.updateGeometricState();
- rm.renderScene(debugShape, vp);
- }
- }
- public void setPhysicsSpace(PhysicsSpace space) {
- if (space == null) {
- if (this.space != null) {
- this.space.removeCollisionObject(this);
- added = false;
- }
- } else {
- if(this.space==space) return;
- space.addCollisionObject(this);
- added = true;
- }
- this.space = space;
- }
- public PhysicsSpace getPhysicsSpace() {
- return space;
- }
- @Override
- public void write(JmeExporter ex) throws IOException {
- super.write(ex);
- OutputCapsule oc = ex.getCapsule(this);
- oc.write(enabled, "enabled", true);
- oc.write(motionState.isApplyPhysicsLocal(), "applyLocalPhysics", false);
- oc.write(kinematicSpatial, "kinematicSpatial", true);
- oc.write(spatial, "spatial", null);
- }
- @Override
- public void read(JmeImporter im) throws IOException {
- super.read(im);
- InputCapsule ic = im.getCapsule(this);
- enabled = ic.readBoolean("enabled", true);
- kinematicSpatial = ic.readBoolean("kinematicSpatial", true);
- spatial = (Spatial) ic.readSavable("spatial", null);
- motionState.setApplyPhysicsLocal(ic.readBoolean("applyLocalPhysics", false));
- setUserObject(spatial);
- }
- }
|