Search for Spatial in the SimEtherial Example project led to the following files:
HudLabelState.java
Main.java
ModelViewState.java
PlayerMovementState.java
SiliconDioxideState.java
SkyState.java
##Tips in ModelViewState.java (code snippets) :
1. private Map<EntityId, Spatial> modelIndex = new HashMap<>();
2. public Spatial getModel( EntityId id ) {
return modelIndex.get(id);
}
3. @Override
protected void onEnable() {
mobs = new MobContainer(ed);
models = new ModelContainer(ed);
mobs.start();
models.start();
((Main)getApplication()).getRootNode().attachChild(modelRoot);
}
4. @Override
protected void onDisable() {
modelRoot.removeFromParent();
models.stop();
mobs.stop();
mobs = null;
models = null;
}
5. @Override
public void update( float tpf ) {
// Grab a consistent time for this frame
long time = timeState.getTime();
// Update all of the models
models.update();
mobs.update();
for( Mob mob : mobs.getArray() ) {
mob.updateSpatial(time);
}
}
6. protected Spatial createShip( Entity entity ) {
AssetManager assetManager = getApplication().getAssetManager();
Spatial ship = assetManager.loadModel("Models/fighter.j3o");
// THIS ONE IS NEW TO ME. Spatial.center() -> Centers the spatial in the origin of the world bound.
ship.center();
Texture texture = assetManager.loadTexture("Textures/ship1.png");
//Material mat = GuiGlobals.getInstance().createMaterial(texture, false).getMaterial();
Material mat = new Material(getApplication().getAssetManager(), "MatDefs/FogUnshaded.j3md");
mat.setTexture("ColorMap", texture);
mat.setColor("FogColor", new ColorRGBA(0, 0, 0.1f, 1));
mat.setFloat("FogDepth", 64);
ship.setMaterial(mat);
// HERE THE NODE NAME INCLUDES THE ENTITY ID NUMBER.
Node result = new Node("ship:" + entity.getId());
result.attachChild(ship);
result.setUserData("entityId", entity.getId().getId());
return result;
}
7. protected Spatial createModel( Entity entity ) {
// Check to see if one already exists
Spatial result = modelIndex.get(entity.getId());
if( result != null ) {
return result;
}
// Else figure out what type to create...
ObjectType type = entity.get(ObjectType.class);
String typeName = type.getTypeName(ed);
switch( typeName ) {
case ObjectTypes.SHIP:
result = createShip(entity);
break;
case ObjectTypes.GRAV_SPHERE:
result = createGravSphere(entity);
break;
default:
throw new RuntimeException("Unknown spatial type:" + typeName);
}
// Add it to the index
modelIndex.put(entity.getId(), result);
modelRoot.attachChild(result);
return result;
}
8. protected void updateModel( Spatial spatial, Entity entity, boolean updatePosition ) {
if( updatePosition ) {
Position pos = entity.get(Position.class);
// I like to move it... move it...
spatial.setLocalTranslation(pos.getLocation().toVector3f());
spatial.setLocalRotation(pos.getFacing().toQuaternion());
}
}
9. protected void removeModel( Spatial spatial, Entity entity ) {
modelIndex.remove(entity.getId());
spatial.removeFromParent();
}
See also ModelViewState.Mob class. This does model position interpolation between packets received from the network.
Question: What does Mob stand for?
See also ModelViewState.MobContainer class. It is an EntityContainer of type Mob.
Seems like it keeps a collection of ObjectType, Positions and entities of the above
mentioned Mob class. This is probably to do object position interpolations.
See also inner class ModelContainer, which extends EntityContainer
Seems to be another collection of spatials, positions and entities for position interpolation.
Takes precidence over MobContainer.
##Tips from PlayerMovementState.java (code snippets):
-
A client network session is setup from this line:
This is probably a SpiderMonkey messageTransmission channel to the server.
// Grab the game session
session = getState(ConnectionState.class).getService(GameSessionClientService.class);
.
-
Player commands are issued to the server in the update() method with this line:
session.move(rot, thrust);
.
3. PlayerMovementState extends BaseAppState implements AnalogFunctionListener, StateFunctionListener
There are obviously method calls in the code that refer to these. getState() is one.
Conclusions … or more correctly …
Gleenings from code studied:
-
EntityData is a one-way trip over the wire. From server to client only.
-
Spatials to EntityId hashmaps are set up on the client.
-
Client commands are sent directly to the server via a
MessageListener
when appropriately setup for this purpose.