AbstractPhysicsControl.java 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * Copyright (c) 2009-2012 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.control;
  33. import com.jme3.bullet.PhysicsSpace;
  34. import com.jme3.export.InputCapsule;
  35. import com.jme3.export.JmeExporter;
  36. import com.jme3.export.JmeImporter;
  37. import com.jme3.export.OutputCapsule;
  38. import com.jme3.math.Quaternion;
  39. import com.jme3.math.Vector3f;
  40. import com.jme3.renderer.RenderManager;
  41. import com.jme3.renderer.ViewPort;
  42. import com.jme3.scene.Spatial;
  43. import java.io.IOException;
  44. /**
  45. * AbstractPhysicsControl manages the lifecycle of a physics object that is
  46. * attached to a spatial in the SceneGraph.
  47. *
  48. * @author normenhansen
  49. */
  50. public abstract class AbstractPhysicsControl implements PhysicsControl {
  51. private final Quaternion tmp_inverseWorldRotation = new Quaternion();
  52. protected Spatial spatial;
  53. protected boolean enabled = true;
  54. protected boolean added = false;
  55. protected PhysicsSpace space = null;
  56. protected boolean applyLocal = false;
  57. /**
  58. * Called when the control is added to a new spatial, create any
  59. * spatial-dependent data here.
  60. *
  61. * @param spat The new spatial, guaranteed not to be null
  62. */
  63. protected abstract void createSpatialData(Spatial spat);
  64. /**
  65. * Called when the control is removed from a spatial, remove any
  66. * spatial-dependent data here.
  67. *
  68. * @param spat The old spatial, guaranteed not to be null
  69. */
  70. protected abstract void removeSpatialData(Spatial spat);
  71. /**
  72. * Called when the physics object is supposed to move to the spatial
  73. * position.
  74. *
  75. * @param vec
  76. */
  77. protected abstract void setPhysicsLocation(Vector3f vec);
  78. /**
  79. * Called when the physics object is supposed to move to the spatial
  80. * rotation.
  81. *
  82. * @param quat
  83. */
  84. protected abstract void setPhysicsRotation(Quaternion quat);
  85. /**
  86. * Called when the physics object is supposed to add all objects it needs to
  87. * manage to the physics space.
  88. *
  89. * @param space
  90. */
  91. protected abstract void addPhysics(PhysicsSpace space);
  92. /**
  93. * Called when the physics object is supposed to remove all objects added to
  94. * the physics space.
  95. *
  96. * @param space
  97. */
  98. protected abstract void removePhysics(PhysicsSpace space);
  99. public boolean isApplyPhysicsLocal() {
  100. return applyLocal;
  101. }
  102. /**
  103. * When set to true, the physics coordinates will be applied to the local
  104. * translation of the Spatial
  105. *
  106. * @param applyPhysicsLocal
  107. */
  108. public void setApplyPhysicsLocal(boolean applyPhysicsLocal) {
  109. applyLocal = applyPhysicsLocal;
  110. }
  111. protected Vector3f getSpatialTranslation() {
  112. if (applyLocal) {
  113. return spatial.getLocalTranslation();
  114. }
  115. return spatial.getWorldTranslation();
  116. }
  117. protected Quaternion getSpatialRotation() {
  118. if (applyLocal) {
  119. return spatial.getLocalRotation();
  120. }
  121. return spatial.getWorldRotation();
  122. }
  123. /**
  124. * Applies a physics transform to the spatial
  125. *
  126. * @param worldLocation
  127. * @param worldRotation
  128. */
  129. protected void applyPhysicsTransform(Vector3f worldLocation, Quaternion worldRotation) {
  130. if (enabled && spatial != null) {
  131. Vector3f localLocation = spatial.getLocalTranslation();
  132. Quaternion localRotationQuat = spatial.getLocalRotation();
  133. if (!applyLocal && spatial.getParent() != null) {
  134. localLocation.set(worldLocation).subtractLocal(spatial.getParent().getWorldTranslation());
  135. localLocation.divideLocal(spatial.getParent().getWorldScale());
  136. tmp_inverseWorldRotation.set(spatial.getParent().getWorldRotation()).inverseLocal().multLocal(localLocation);
  137. localRotationQuat.set(worldRotation);
  138. tmp_inverseWorldRotation.set(spatial.getParent().getWorldRotation()).inverseLocal().mult(localRotationQuat, localRotationQuat);
  139. spatial.setLocalTranslation(localLocation);
  140. spatial.setLocalRotation(localRotationQuat);
  141. } else {
  142. spatial.setLocalTranslation(worldLocation);
  143. spatial.setLocalRotation(worldRotation);
  144. }
  145. }
  146. }
  147. public void setSpatial(Spatial spatial) {
  148. if (this.spatial != null && this.spatial != spatial) {
  149. removeSpatialData(this.spatial);
  150. }
  151. else if (this.spatial == spatial) {
  152. return;
  153. }
  154. this.spatial = spatial;
  155. if (spatial == null) {
  156. return;
  157. }
  158. createSpatialData(this.spatial);
  159. setPhysicsLocation(getSpatialTranslation());
  160. setPhysicsRotation(getSpatialRotation());
  161. }
  162. public void setEnabled(boolean enabled) {
  163. this.enabled = enabled;
  164. if (space != null) {
  165. if (enabled && !added) {
  166. if (spatial != null) {
  167. setPhysicsLocation(getSpatialTranslation());
  168. setPhysicsRotation(getSpatialRotation());
  169. }
  170. addPhysics(space);
  171. added = true;
  172. } else if (!enabled && added) {
  173. removePhysics(space);
  174. added = false;
  175. }
  176. }
  177. }
  178. public boolean isEnabled() {
  179. return enabled;
  180. }
  181. public void update(float tpf) {
  182. }
  183. public void render(RenderManager rm, ViewPort vp) {
  184. }
  185. public void setPhysicsSpace(PhysicsSpace space) {
  186. if (space == null) {
  187. if (this.space != null) {
  188. removePhysics(space);
  189. added = false;
  190. }
  191. } else {
  192. if (this.space == space) {
  193. return;
  194. }
  195. addPhysics(space);
  196. added = true;
  197. }
  198. this.space = space;
  199. }
  200. public PhysicsSpace getPhysicsSpace() {
  201. return space;
  202. }
  203. @Override
  204. public void write(JmeExporter ex) throws IOException {
  205. OutputCapsule oc = ex.getCapsule(this);
  206. oc.write(enabled, "enabled", true);
  207. oc.write(applyLocal, "applyLocalPhysics", false);
  208. oc.write(spatial, "spatial", null);
  209. }
  210. @Override
  211. public void read(JmeImporter im) throws IOException {
  212. InputCapsule ic = im.getCapsule(this);
  213. enabled = ic.readBoolean("enabled", true);
  214. spatial = (Spatial) ic.readSavable("spatial", null);
  215. applyLocal = ic.readBoolean("applyLocalPhysics", false);
  216. }
  217. }