|
|
|
@ -1,5 +1,5 @@ |
|
|
|
|
/* |
|
|
|
|
* Copyright (c) 2009-2018 jMonkeyEngine |
|
|
|
|
* Copyright (c) 2009-2019 jMonkeyEngine |
|
|
|
|
* All rights reserved. |
|
|
|
|
* |
|
|
|
|
* Redistribution and use in source and binary forms, with or without |
|
|
|
@ -32,7 +32,7 @@ |
|
|
|
|
package com.jme3.bullet; |
|
|
|
|
|
|
|
|
|
import com.jme3.app.Application; |
|
|
|
|
import com.jme3.app.state.AppState; |
|
|
|
|
import com.jme3.app.state.AbstractAppState; |
|
|
|
|
import com.jme3.app.state.AppStateManager; |
|
|
|
|
import com.jme3.bullet.PhysicsSpace.BroadphaseType; |
|
|
|
|
import com.jme3.bullet.debug.BulletDebugAppState; |
|
|
|
@ -49,27 +49,16 @@ import java.util.logging.Logger; |
|
|
|
|
* |
|
|
|
|
* @author normenhansen |
|
|
|
|
*/ |
|
|
|
|
public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
|
|
|
|
|
// FIXME: the bullet app state doesn't follow the proper AppState
|
|
|
|
|
// contract as it messes with its initialized state independently
|
|
|
|
|
// of when initialize()/cleanup() is actually called. This means
|
|
|
|
|
// that it's quite likely that the state manager will think the
|
|
|
|
|
// app state is initialized when it, itself, doesn't. This is
|
|
|
|
|
// a good example of why extending the abstract app state classes
|
|
|
|
|
// is better than implementing app state directly. If it wants
|
|
|
|
|
// to support a separate stated/not-started concept then that's
|
|
|
|
|
// separate from initialized/not-initialized but way more refactoring
|
|
|
|
|
// than I want to think about today. -pspeed:2019-09-15
|
|
|
|
|
public class BulletAppState |
|
|
|
|
extends AbstractAppState |
|
|
|
|
implements PhysicsTickListener { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* true if-and-only-if the physics simulation is running (started but not |
|
|
|
|
* yet stopped) |
|
|
|
|
*/ |
|
|
|
|
protected boolean initialized = false; |
|
|
|
|
protected volatile boolean isRunning = false; |
|
|
|
|
protected Application app; |
|
|
|
|
private String id; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* manager that manages this state, set during attach |
|
|
|
|
*/ |
|
|
|
@ -245,7 +234,7 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
* sooner, invoke this method. |
|
|
|
|
*/ |
|
|
|
|
public void startPhysics() { |
|
|
|
|
if (initialized) { |
|
|
|
|
if (isRunning) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -265,14 +254,14 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
throw new IllegalStateException(threadingType.toString()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
initialized = true; |
|
|
|
|
isRunning = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Stop physics after this state is detached. |
|
|
|
|
*/ |
|
|
|
|
public void stopPhysics() { |
|
|
|
|
if(!initialized){ |
|
|
|
|
if (!isRunning) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (executor != null) { |
|
|
|
@ -281,7 +270,7 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
} |
|
|
|
|
pSpace.removeTickListener(this); |
|
|
|
|
pSpace.destroy(); |
|
|
|
|
initialized = false; |
|
|
|
|
isRunning = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -291,54 +280,14 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
* @param stateManager the manager for this state (not null) |
|
|
|
|
* @param app the application which owns this state (not null) |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void initialize(AppStateManager stateManager, Application app) { |
|
|
|
|
super.initialize(stateManager, app); |
|
|
|
|
this.app = app; |
|
|
|
|
this.stateManager = stateManager; |
|
|
|
|
startPhysics(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Test whether the physics simulation is running (started but not yet |
|
|
|
|
* stopped). |
|
|
|
|
* |
|
|
|
|
* @return true if running, otherwise false |
|
|
|
|
*/ |
|
|
|
|
public boolean isInitialized() { |
|
|
|
|
return initialized; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Sets the unique ID of this app state. Note: that setting |
|
|
|
|
* this while an app state is attached to the state manager will |
|
|
|
|
* have no effect on ID-based lookups. |
|
|
|
|
*/ |
|
|
|
|
protected void setId( String id ) { |
|
|
|
|
this.id = id; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public String getId() { |
|
|
|
|
return id; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Enable or disable this state. |
|
|
|
|
* |
|
|
|
|
* @param enabled true → enable, false → disable |
|
|
|
|
*/ |
|
|
|
|
public void setEnabled(boolean enabled) { |
|
|
|
|
this.active = enabled; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Test whether this state is enabled. |
|
|
|
|
* |
|
|
|
|
* @return true if enabled, otherwise false |
|
|
|
|
*/ |
|
|
|
|
public boolean isEnabled() { |
|
|
|
|
return active; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Alter whether debug visualization is enabled. |
|
|
|
|
* |
|
|
|
@ -364,8 +313,10 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
* |
|
|
|
|
* @param stateManager (not null) |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void stateAttached(AppStateManager stateManager) { |
|
|
|
|
if (!initialized) { |
|
|
|
|
super.stateAttached(stateManager); |
|
|
|
|
if (!isRunning) { |
|
|
|
|
startPhysics(); |
|
|
|
|
} |
|
|
|
|
if (threadingType == ThreadingType.PARALLEL) { |
|
|
|
@ -377,15 +328,6 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Transition this state from running to terminating. Should be invoked only |
|
|
|
|
* by a subclass or by the AppStateManager. |
|
|
|
|
* |
|
|
|
|
* @param stateManager (not null) |
|
|
|
|
*/ |
|
|
|
|
public void stateDetached(AppStateManager stateManager) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Update this state prior to rendering. Should be invoked only by a |
|
|
|
|
* subclass or by the AppStateManager. Invoked once per frame, provided the |
|
|
|
@ -393,7 +335,9 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
* |
|
|
|
|
* @param tpf the time interval between frames (in seconds, ≥0) |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void update(float tpf) { |
|
|
|
|
super.update(tpf); |
|
|
|
|
if (debugEnabled && debugAppState == null && pSpace != null) { |
|
|
|
|
debugAppState = new BulletDebugAppState(pSpace); |
|
|
|
|
stateManager.attach(debugAppState); |
|
|
|
@ -415,7 +359,9 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
* |
|
|
|
|
* @param rm the render manager (not null) |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void render(RenderManager rm) { |
|
|
|
|
super.render(rm); |
|
|
|
|
if (!active) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -432,7 +378,9 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
* invoked only by a subclass or by the AppStateManager. Invoked once per |
|
|
|
|
* frame, provided the state is attached and enabled. |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void postRender() { |
|
|
|
|
super.postRender(); |
|
|
|
|
if (physicsFuture != null) { |
|
|
|
|
try { |
|
|
|
|
physicsFuture.get(); |
|
|
|
@ -451,12 +399,14 @@ public class BulletAppState implements AppState, PhysicsTickListener { |
|
|
|
|
* {@link #initialize(com.jme3.app.state.AppStateManager, com.jme3.app.Application)} |
|
|
|
|
* is invoked. |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public void cleanup() { |
|
|
|
|
if (debugAppState != null) { |
|
|
|
|
stateManager.detach(debugAppState); |
|
|
|
|
debugAppState = null; |
|
|
|
|
} |
|
|
|
|
stopPhysics(); |
|
|
|
|
super.cleanup(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|