RigidBodyControl.java 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * To change this template, choose Tools | Templates
  3. * and open the template in the editor.
  4. */
  5. package com.jme3.bullet.control;
  6. import com.jme3.bullet.PhysicsSpace;
  7. import com.jme3.bullet.collision.shapes.BoxCollisionShape;
  8. import com.jme3.bullet.collision.shapes.CollisionShape;
  9. import com.jme3.bullet.collision.shapes.SphereCollisionShape;
  10. import com.jme3.bullet.objects.PhysicsRigidBody;
  11. import com.jme3.bullet.util.CollisionShapeFactory;
  12. import com.jme3.export.InputCapsule;
  13. import com.jme3.export.JmeExporter;
  14. import com.jme3.export.JmeImporter;
  15. import com.jme3.export.OutputCapsule;
  16. import com.jme3.math.Quaternion;
  17. import com.jme3.math.Vector3f;
  18. import com.jme3.renderer.RenderManager;
  19. import com.jme3.renderer.ViewPort;
  20. import com.jme3.scene.Geometry;
  21. import com.jme3.scene.Mesh;
  22. import com.jme3.scene.Node;
  23. import com.jme3.scene.Spatial;
  24. import com.jme3.scene.control.Control;
  25. import com.jme3.scene.shape.Box;
  26. import com.jme3.scene.shape.Sphere;
  27. import java.io.IOException;
  28. /**
  29. *
  30. * @author normenhansen
  31. */
  32. public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl {
  33. protected Spatial spatial;
  34. protected boolean enabled = true;
  35. protected boolean added = false;
  36. protected PhysicsSpace space = null;
  37. protected boolean kinematicSpatial = true;
  38. public RigidBodyControl() {
  39. }
  40. /**
  41. * When using this constructor, the CollisionShape for the RigidBody is generated
  42. * automatically when the Control is added to a Spatial.
  43. * @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.
  44. */
  45. public RigidBodyControl(float mass) {
  46. this.mass = mass;
  47. }
  48. /**
  49. * Creates a new PhysicsNode with the supplied collision shape
  50. * @param child
  51. * @param shape
  52. */
  53. public RigidBodyControl(CollisionShape shape) {
  54. super(shape);
  55. }
  56. public RigidBodyControl(CollisionShape shape, float mass) {
  57. super(shape, mass);
  58. }
  59. public Control cloneForSpatial(Spatial spatial) {
  60. RigidBodyControl control = new RigidBodyControl(collisionShape, mass);
  61. control.setAngularFactor(getAngularFactor());
  62. control.setAngularSleepingThreshold(getAngularSleepingThreshold());
  63. control.setCcdMotionThreshold(getCcdMotionThreshold());
  64. control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
  65. control.setCollideWithGroups(getCollideWithGroups());
  66. control.setCollisionGroup(getCollisionGroup());
  67. control.setDamping(getLinearDamping(), getAngularDamping());
  68. control.setFriction(getFriction());
  69. control.setGravity(getGravity());
  70. control.setKinematic(isKinematic());
  71. control.setKinematicSpatial(isKinematicSpatial());
  72. control.setLinearSleepingThreshold(getLinearSleepingThreshold());
  73. control.setPhysicsLocation(getPhysicsLocation(null));
  74. control.setPhysicsRotation(getPhysicsRotationMatrix(null));
  75. control.setRestitution(getRestitution());
  76. if (mass > 0) {
  77. control.setAngularVelocity(getAngularVelocity());
  78. control.setLinearVelocity(getLinearVelocity());
  79. }
  80. control.setApplyPhysicsLocal(isApplyPhysicsLocal());
  81. control.setSpatial(spatial);
  82. return control;
  83. }
  84. public void setSpatial(Spatial spatial) {
  85. if (getUserObject() == null || getUserObject() == this.spatial) {
  86. setUserObject(spatial);
  87. }
  88. this.spatial = spatial;
  89. if (spatial == null) {
  90. if (getUserObject() == spatial) {
  91. setUserObject(null);
  92. }
  93. spatial = null;
  94. collisionShape = null;
  95. return;
  96. }
  97. if (collisionShape == null) {
  98. createCollisionShape();
  99. rebuildRigidBody();
  100. }
  101. setPhysicsLocation(getSpatialTranslation());
  102. setPhysicsRotation(getSpatialRotation());
  103. }
  104. protected void createCollisionShape() {
  105. if (spatial == null) {
  106. return;
  107. }
  108. if (spatial instanceof Geometry) {
  109. Geometry geom = (Geometry) spatial;
  110. Mesh mesh = geom.getMesh();
  111. if (mesh instanceof Sphere) {
  112. collisionShape = new SphereCollisionShape(((Sphere) mesh).getRadius());
  113. return;
  114. } else if (mesh instanceof Box) {
  115. collisionShape = new BoxCollisionShape(new Vector3f(((Box) mesh).getXExtent(), ((Box) mesh).getYExtent(), ((Box) mesh).getZExtent()));
  116. return;
  117. }
  118. }
  119. if (mass > 0) {
  120. collisionShape = CollisionShapeFactory.createDynamicMeshShape(spatial);
  121. } else {
  122. collisionShape = CollisionShapeFactory.createMeshShape(spatial);
  123. }
  124. }
  125. public void setEnabled(boolean enabled) {
  126. this.enabled = enabled;
  127. if (space != null) {
  128. if (enabled && !added) {
  129. if (spatial != null) {
  130. setPhysicsLocation(getSpatialTranslation());
  131. setPhysicsRotation(getSpatialRotation());
  132. }
  133. space.addCollisionObject(this);
  134. added = true;
  135. } else if (!enabled && added) {
  136. space.removeCollisionObject(this);
  137. added = false;
  138. }
  139. }
  140. }
  141. public boolean isEnabled() {
  142. return enabled;
  143. }
  144. /**
  145. * Checks if this control is in kinematic spatial mode.
  146. * @return true if the spatial location is applied to this kinematic rigidbody
  147. */
  148. public boolean isKinematicSpatial() {
  149. return kinematicSpatial;
  150. }
  151. /**
  152. * Sets this control to kinematic spatial mode so that the spatials transform will
  153. * be applied to the rigidbody in kinematic mode, defaults to true.
  154. * @param kinematicSpatial
  155. */
  156. public void setKinematicSpatial(boolean kinematicSpatial) {
  157. this.kinematicSpatial = kinematicSpatial;
  158. }
  159. public boolean isApplyPhysicsLocal() {
  160. return motionState.isApplyPhysicsLocal();
  161. }
  162. /**
  163. * When set to true, the physics coordinates will be applied to the local
  164. * translation of the Spatial
  165. * @param applyPhysicsLocal
  166. */
  167. public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
  168. motionState.setApplyPhysicsLocal(applyPhysicsLocal);
  169. }
  170. private Vector3f getSpatialTranslation(){
  171. if(motionState.isApplyPhysicsLocal()){
  172. return spatial.getLocalTranslation();
  173. }
  174. return spatial.getWorldTranslation();
  175. }
  176. private Quaternion getSpatialRotation(){
  177. if(motionState.isApplyPhysicsLocal()){
  178. return spatial.getLocalRotation();
  179. }
  180. return spatial.getWorldRotation();
  181. }
  182. public void update(float tpf) {
  183. if (enabled && spatial != null) {
  184. if (isKinematic() && kinematicSpatial) {
  185. super.setPhysicsLocation(getSpatialTranslation());
  186. super.setPhysicsRotation(getSpatialRotation());
  187. } else {
  188. getMotionState().applyTransform(spatial);
  189. }
  190. }
  191. }
  192. public void render(RenderManager rm, ViewPort vp) {
  193. if (enabled && space != null && space.getDebugManager() != null) {
  194. if (debugShape == null) {
  195. attachDebugShape(space.getDebugManager());
  196. }
  197. //TODO: using spatial traslation/rotation..
  198. debugShape.setLocalTranslation(spatial.getWorldTranslation());
  199. debugShape.setLocalRotation(spatial.getWorldRotation());
  200. debugShape.updateLogicalState(0);
  201. debugShape.updateGeometricState();
  202. rm.renderScene(debugShape, vp);
  203. }
  204. }
  205. public void setPhysicsSpace(PhysicsSpace space) {
  206. if (space == null) {
  207. if (this.space != null) {
  208. this.space.removeCollisionObject(this);
  209. added = false;
  210. }
  211. } else {
  212. if(this.space==space) return;
  213. space.addCollisionObject(this);
  214. added = true;
  215. }
  216. this.space = space;
  217. }
  218. public PhysicsSpace getPhysicsSpace() {
  219. return space;
  220. }
  221. @Override
  222. public void write(JmeExporter ex) throws IOException {
  223. super.write(ex);
  224. OutputCapsule oc = ex.getCapsule(this);
  225. oc.write(enabled, "enabled", true);
  226. oc.write(motionState.isApplyPhysicsLocal(), "applyLocalPhysics", false);
  227. oc.write(kinematicSpatial, "kinematicSpatial", true);
  228. oc.write(spatial, "spatial", null);
  229. }
  230. @Override
  231. public void read(JmeImporter im) throws IOException {
  232. super.read(im);
  233. InputCapsule ic = im.getCapsule(this);
  234. enabled = ic.readBoolean("enabled", true);
  235. kinematicSpatial = ic.readBoolean("kinematicSpatial", true);
  236. spatial = (Spatial) ic.readSavable("spatial", null);
  237. motionState.setApplyPhysicsLocal(ic.readBoolean("applyLocalPhysics", false));
  238. setUserObject(spatial);
  239. }
  240. }