BowlerKernel
PhysicsCore.java
Go to the documentation of this file.
1 package com.neuronrobotics.bowlerstudio.physics;
2 
3 import java.util.ArrayList;
4 
5 import javax.vecmath.Matrix4f;
6 import javax.vecmath.Quat4f;
7 import javax.vecmath.Vector3f;
8 
9 import com.bulletphysics.collision.broadphase.BroadphaseInterface;
10 import com.bulletphysics.collision.broadphase.DbvtBroadphase;
11 import com.bulletphysics.collision.dispatch.CollisionDispatcher;
12 import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
13 import com.bulletphysics.collision.shapes.CollisionShape;
14 import com.bulletphysics.collision.shapes.StaticPlaneShape;
15 import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
16 import com.bulletphysics.dynamics.RigidBody;
17 import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
18 import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
19 import com.bulletphysics.linearmath.DefaultMotionState;
20 import com.bulletphysics.linearmath.Transform;
21 import com.neuronrobotics.bowlerstudio.IssueReportingExceptionHandler;
22 import com.neuronrobotics.sdk.util.ThreadUtil;
23 
24 import eu.mihosoft.vrl.v3d.CSG;
25 
26 import javafx.application.Platform;
27 
28 public class PhysicsCore {
29 
30  private BroadphaseInterface broadphase = new DbvtBroadphase();
31  private DefaultCollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
32  private CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);
33 
34  private SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
35 
36  private DiscreteDynamicsWorld dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, broadphase,
37  solver,
39  // setup our collision shapes
40  private CollisionShape groundShape = null;
41 
42  private ArrayList<IPhysicsManager> objects = new ArrayList<>();
43  private RigidBody groundRigidBody;
44 
45  private boolean runEngine = false;
46  private int msTime = 16;
47 
48  private Thread physicsThread = null;
49  private int simulationSubSteps = 5;
50  private float lin_damping;
51  private float ang_damping;
52  private float linearSleepThreshhold;
53  private float angularSleepThreshhold;
54  private float deactivationTime;
55 
56  public PhysicsCore() throws Exception {
57  // set the gravity of our world
58  getDynamicsWorld().setGravity(
59  new Vector3f(0, 0, (float) -98 * MobileBasePhysicsManager.PhysicsGravityScalar));
60 
61  setGroundShape(new StaticPlaneShape(new Vector3f(0, 0, 10), 1));
62  }
63 
64  public BroadphaseInterface getBroadphase() {
65  return broadphase;
66  }
67 
68  public void setBroadphase(BroadphaseInterface broadphase) {
69  this.broadphase = broadphase;
70  }
71 
72  public DefaultCollisionConfiguration getCollisionConfiguration() {
74  }
75 
76  public void setCollisionConfiguration(DefaultCollisionConfiguration collisionConfiguration) {
77  this.collisionConfiguration = collisionConfiguration;
78  }
79 
80  public CollisionDispatcher getDispatcher() {
81  return dispatcher;
82  }
83 
84  public void setDispatcher(CollisionDispatcher dispatcher) {
85  this.dispatcher = dispatcher;
86  }
87 
88  public SequentialImpulseConstraintSolver getSolver() {
89  return solver;
90  }
91 
92  public void setSolver(SequentialImpulseConstraintSolver solver) {
93  this.solver = solver;
94  }
95 
96  public DiscreteDynamicsWorld getDynamicsWorld() {
97  return dynamicsWorld;
98  }
99 
100  public void setDynamicsWorld(DiscreteDynamicsWorld dynamicsWorld) {
101  this.dynamicsWorld = dynamicsWorld;
102  }
103 
104  public CollisionShape getGroundShape() {
105  return groundShape;
106  }
107 
108  public void setGroundShape(CollisionShape cs) {
109  if (groundRigidBody != null) {
110  getDynamicsWorld().removeRigidBody(groundRigidBody); // add our
111  // ground to
112  // the
113  }
114  this.groundShape = cs;
115  // setup the motion state
116  DefaultMotionState groundMotionState = new DefaultMotionState(
117  new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, 0, 0), 1.0f)));
118 
119  RigidBodyConstructionInfo groundRigidBodyCI = new RigidBodyConstructionInfo(0,
120  groundMotionState, groundShape,
121  new Vector3f(0, 0, 0));
122  groundRigidBody = new RigidBody(groundRigidBodyCI);
123  dynamicsWorld.addRigidBody(groundRigidBody); // add our ground to the
124  }
125 
126  public ArrayList<IPhysicsManager> getPhysicsObjects() {
127  return objects;
128  }
129 
130  public void setDamping(float lin_damping, float ang_damping) {
131  this.lin_damping = (lin_damping);
132  this.ang_damping = (ang_damping);
133  for (IPhysicsManager m : getPhysicsObjects()) {
134  m.getFallRigidBody().setDamping(lin_damping, ang_damping);
135  }
136  }
137 
139  this.linearSleepThreshhold = (linearSleepThreshhold);
140  this.angularSleepThreshhold = (angularSleepThreshhold);
141  for (IPhysicsManager m : getPhysicsObjects()) {
142  m.getFallRigidBody().setSleepingThresholds(linearSleepThreshhold, angularSleepThreshhold);
143  }
144  }
145 
147  this.deactivationTime = deactivationTime;
148  for (IPhysicsManager m : getPhysicsObjects()) {
149  m.getFallRigidBody().setDeactivationTime(deactivationTime);
150  }
151  }
152 
153  public void setObjects(ArrayList<IPhysicsManager> objects) {
154  this.objects = objects;
155  }
156 
157  public void startPhysicsThread(int ms) {
158  msTime = ms;
159  if (physicsThread == null) {
160  runEngine = true;
161  physicsThread = new Thread(() -> {
162  Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
163 
164  while (runEngine) {
165  try {
166  long start = System.currentTimeMillis();
167  stepMs(msTime);
168  long took = (System.currentTimeMillis() - start);
169  if (took < msTime) {
170  ThreadUtil.wait((int) (msTime - took));
171  } else {
172  System.out.println("Real time physics broken: " + took);
173  }
174  } catch (Exception E) {
175  E.printStackTrace();
176  }
177  }
178  });
179  physicsThread.start();
180  }
181  }
182 
183  public ArrayList<CSG> getCsgFromEngine() {
184  ArrayList<CSG> csg = new ArrayList<>();
185  for (IPhysicsManager o : getPhysicsObjects()) {
186  for (CSG c : o.getBaseCSG()) {
187  csg.add(c);
188  }
189  }
190  return csg;
191  }
192 
193  public void stopPhysicsThread() {
194  physicsThread = null;
195  runEngine = false;
196  }
197 
198  public void step(float timeStep) {
199  long startTime = System.currentTimeMillis();
200 
201  getDynamicsWorld().stepSimulation(timeStep, getSimulationSubSteps());
202  if ((((float) (System.currentTimeMillis() - startTime)) / 1000.0f) > timeStep) {
203  // System.out.println(" Compute took too long "+timeStep);
204  }
205  for (IPhysicsManager o : getPhysicsObjects()) {
206  o.update(timeStep);
207  }
208 
209  Platform.runLater(() -> {
210  for (IPhysicsManager o : getPhysicsObjects()) {
211  try {
212  TransformFactory.bulletToAffine(o.getRigidBodyLocation(), o.getUpdateTransform());
213  } catch (Exception e) {
214 
215  }
216  }
217  });
218  }
219 
220  public void stepMs(double timeStep) {
221  step((float) (timeStep / 1000.0));
222  }
223 
224  public void add(IPhysicsManager manager) {
225  if (!getPhysicsObjects().contains(manager)) {
226  getPhysicsObjects().add(manager);
227  if (!WheelCSGPhysicsManager.class.isInstance(manager)
228  && !VehicleCSGPhysicsManager.class.isInstance(manager)) {
229  getDynamicsWorld().addRigidBody(manager.getFallRigidBody());
230  }
231  if (HingeCSGPhysicsManager.class.isInstance(manager)) {
232  if (((HingeCSGPhysicsManager) manager).getConstraint() != null) {
234  .addConstraint(((HingeCSGPhysicsManager) manager).getConstraint(), true);
235  }
236  }
237  if (VehicleCSGPhysicsManager.class.isInstance(manager)) {
238  getDynamicsWorld().addVehicle(((VehicleCSGPhysicsManager) manager).getVehicle());
239  }
240 
241  }
242  }
243 
244  public void remove(IPhysicsManager manager) {
245  if (getPhysicsObjects().contains(manager)) {
246  getPhysicsObjects().remove(manager);
247  if (!WheelCSGPhysicsManager.class.isInstance(manager)
248  && !VehicleCSGPhysicsManager.class.isInstance(manager)) {
249 
250  getDynamicsWorld().removeRigidBody(manager.getFallRigidBody());
251  }
252  if (HingeCSGPhysicsManager.class.isInstance(manager)) {
253  if (((HingeCSGPhysicsManager) manager).getConstraint() != null) {
254  getDynamicsWorld().removeConstraint(((HingeCSGPhysicsManager) manager).getConstraint());
255  }
256  }
257  if (VehicleCSGPhysicsManager.class.isInstance(manager)) {
258  getDynamicsWorld().removeVehicle(((VehicleCSGPhysicsManager) manager).getVehicle());
259  }
260 
261  }
262  }
263 
264  public void clear() {
266  ThreadUtil.wait((int) (msTime * 2));
267  for (IPhysicsManager manager : getPhysicsObjects()) {
268  if (!WheelCSGPhysicsManager.class.isInstance(manager)
269  && !VehicleCSGPhysicsManager.class.isInstance(manager)) {
270  getDynamicsWorld().removeRigidBody(manager.getFallRigidBody());
271  }
272  if (HingeCSGPhysicsManager.class.isInstance(manager)) {
273  if (((HingeCSGPhysicsManager) manager).getConstraint() != null) {
274  getDynamicsWorld().removeConstraint(((HingeCSGPhysicsManager) manager).getConstraint());
275  }
276  }
277  if (VehicleCSGPhysicsManager.class.isInstance(manager)) {
278  getDynamicsWorld().removeVehicle(((VehicleCSGPhysicsManager) manager).getVehicle());
279  }
280 
281  }
282  getPhysicsObjects().clear();
283 
284  }
285 
286  public int getSimulationSubSteps() {
287  return simulationSubSteps;
288  }
289 
290  public float getDeactivationTime() {
291  return deactivationTime;
292  }
293 
294  public void setSimulationSubSteps(int simpulationSubSteps) {
295  this.simulationSubSteps = simpulationSubSteps;
296  }
297 
298  public float getLin_damping() {
299  return lin_damping;
300  }
301 
302  public float getAng_damping() {
303  return ang_damping;
304  }
305 
306  public float getLinearSleepThreshhold() {
307  return linearSleepThreshhold;
308  }
309 
310  public float getAngularSleepThreshhold() {
311  return angularSleepThreshhold;
312  }
313 
314 }
DefaultCollisionConfiguration collisionConfiguration
void setDispatcher(CollisionDispatcher dispatcher)
void setSleepingThresholds(float linearSleepThreshhold, float angularSleepThreshhold)
void setSimulationSubSteps(int simpulationSubSteps)
ArrayList< IPhysicsManager > getPhysicsObjects()
SequentialImpulseConstraintSolver solver
void setBroadphase(BroadphaseInterface broadphase)
SequentialImpulseConstraintSolver getSolver()
void setSolver(SequentialImpulseConstraintSolver solver)
void setCollisionConfiguration(DefaultCollisionConfiguration collisionConfiguration)
void setObjects(ArrayList< IPhysicsManager > objects)
void setDamping(float lin_damping, float ang_damping)
DefaultCollisionConfiguration getCollisionConfiguration()
void setDynamicsWorld(DiscreteDynamicsWorld dynamicsWorld)
static void bulletToAffine(Affine affine, com.bulletphysics.linearmath.Transform bullet)