package gameEngine.simulator.interfaces; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import gameEngine.entites.*; import gameEngine.entites.gameComponents.*; import gameEngine.scenes.Scene; import gameEngine.views.Sprite; import models.algebra.Expression; import models.algebra.Term; import models.algebra.Constant; import models.dataConstraintModel.JsonTerm; import models.dataConstraintModel.MapTerm; import models.dataFlowModel.DataTransferChannel; import simulator.Event; import simulator.Resource; import simulator.Simulator; import simulator.SystemState; import simulator.interfaces.INativeInitializer; import simulator.interfaces.INativeReceiver; public class GameEnginePresenter implements INativeReceiver, INativeInitializer { public final String sceneUpdateChannelName = "SceneUpdate"; public final String cameraPositionUpdateChannelName = "CameraPositionUpdate"; public final String cameraRotationUpdateChannelName = "CameraRotationUpdate"; public final String cameraScaleUpdateChannelName = "CameraScaleUpdate"; public final String cameraProjectionUpdateChannelName = "CameraProjectionUpdate"; public final String entityPositionUpdateChannelName = "EntityPositionUpdate"; public final String entityRotationUpdateChannelName = "EntityRotationUpdate"; public final String entityScaleUpdateChannelName = "EntityScaleUpdate"; public final String spriteUpdateChannelName = "SpriteUpdate"; public final String sceneUpdateEventChannelName = "SceneUpdateEvent"; public final String keyEventChannelName = "KeyEvent"; protected Scene scene; protected Simulator simulator; protected DataTransferChannel sceneUpdateChannel; protected DataTransferChannel cameraPositionUpdateChannel; protected DataTransferChannel cameraRotationUpdateChannel; protected DataTransferChannel cameraScaleUpdateChannel; protected DataTransferChannel cameraProjectionUpdateChannel; protected DataTransferChannel entityPositionUpdateChannel; protected DataTransferChannel entityRotationUpdateChannel; protected DataTransferChannel entityScaleUpdateChannel; protected DataTransferChannel spriteUpdateChannel; protected DataTransferChannel sceneUpdateEventChannel; protected DataTransferChannel keyEventChannel; protected Map<DataTransferChannel, Map<String, Resource>> channelAndResourcesForEntityReceiving = new HashMap<>(); protected Map<DataTransferChannel, Resource> channelAndResourcesForCameraReceiving = new HashMap<>(); public GameEnginePresenter(Scene scene, Simulator simulator) { this.scene = scene; this.simulator = simulator; sceneUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(sceneUpdateChannelName); cameraPositionUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(cameraPositionUpdateChannelName); cameraRotationUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(cameraRotationUpdateChannelName); cameraScaleUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(cameraScaleUpdateChannelName); cameraProjectionUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(cameraProjectionUpdateChannelName); entityPositionUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(entityPositionUpdateChannelName); entityRotationUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(entityRotationUpdateChannelName); entityScaleUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(entityScaleUpdateChannelName); spriteUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(spriteUpdateChannelName); sceneUpdateEventChannel = (DataTransferChannel) simulator.getModel().getInputChannel(sceneUpdateEventChannelName); keyEventChannel = (DataTransferChannel) simulator.getModel().getInputChannel(keyEventChannelName); simulator.addNativeReceiver(this, sceneUpdateChannel); simulator.addSystemInitializer(this); } @Override public void onInitFromModel(SystemState initialSystemState) { Resource sceneResource = initialSystemState.getResource("scene"); if (sceneResource != null) { Resource entitiesResource = sceneResource.getChildrenMap().get("entities"); if (entitiesResource != null) { for (Map.Entry<String, Resource> entity: entitiesResource.getChildrenMap().entrySet()) { String eId = entity.getKey(); Resource entityResource = entity.getValue(); Resource transformResource = entityResource.getChildrenMap().get("transform"); Resource meshResource = entityResource.getChildrenMap().get("mesh"); Resource positionResource = transformResource.getChildrenMap().get("position"); Resource rotationResource = transformResource.getChildrenMap().get("rotation"); Resource scaleResource = transformResource.getChildrenMap().get("scale"); if (meshResource != null && positionResource != null && rotationResource != null && scaleResource != null) { // Add a game entity to scene. String px = positionResource.getChildrenMap().get("x").getState().getValue().toString(); String py = positionResource.getChildrenMap().get("y").getState().getValue().toString(); String pz = positionResource.getChildrenMap().get("z").getState().getValue().toString(); String rx = rotationResource.getChildrenMap().get("x").getState().getValue().toString(); String ry = rotationResource.getChildrenMap().get("y").getState().getValue().toString(); String rz = rotationResource.getChildrenMap().get("z").getState().getValue().toString(); String sx = scaleResource.getChildrenMap().get("x").getState().getValue().toString(); String sy = scaleResource.getChildrenMap().get("y").getState().getValue().toString(); String sz = scaleResource.getChildrenMap().get("z").getState().getValue().toString(); String type = (String) ((Constant) meshResource.getChildrenMap().get("type").getState().getValue()).getValue(); String texturePath = (String) ((Constant) meshResource.getChildrenMap().get("sprite").getState().getValue()).getValue(); GameObject gameObj = addGameObjectToScene(eId, meshResource, px, py, pz, rx, ry, rz, sx, sy, sz, type, texturePath); // Connect game entity and model. connectGameEntiotyAndModel(eId, gameObj, positionResource, rotationResource, scaleResource); } } } } } @Override public void onReceiveFromModel(Event event, SystemState nextSystemState) { Expression message = event.getMessage(); if (message instanceof Term && ((Term) message).getChildren().size() >= 2) { Expression curScExp = ((Term) message).getChild(0); Expression nextScExp = ((Term) message).getChild(1); if (curScExp instanceof JsonTerm && nextScExp instanceof JsonTerm) { JsonTerm curSc = (JsonTerm) curScExp; JsonTerm nextSc = (JsonTerm) nextScExp; Resource sceneResource = nextSystemState.getResource(event.getInputResource().getResourceIdentifier()); Expression cameraExp = nextSc.get("camera"); if (cameraExp != null && cameraExp instanceof JsonTerm) { // Connect camera and model. JsonTerm camera = (JsonTerm) cameraExp; Resource cameraResource = sceneResource.getChildrenMap().get("camera"); Camera cameraObj = scene.getCamera(); Resource cameraTransformResource = cameraResource.getChildrenMap().get("transform"); Resource cameraProjectionResource = cameraResource.getChildrenMap().get("projection"); Resource cameraPositionResource = cameraTransformResource.getChildrenMap().get("position"); Resource cameraRotationResource = cameraTransformResource.getChildrenMap().get("rotation"); Resource cameraScaleResource = cameraTransformResource.getChildrenMap().get("scale"); if (channelAndResourcesForCameraReceiving.get(cameraPositionUpdateChannel) == null) { CameraPositionReceiver nativePositionReceiver = new CameraPositionReceiver(cameraObj); simulator.addNativeReceiver(nativePositionReceiver, cameraPositionUpdateChannel, cameraPositionResource); channelAndResourcesForCameraReceiving.put(cameraPositionUpdateChannel, cameraPositionResource); } if (channelAndResourcesForCameraReceiving.get(cameraRotationUpdateChannel) == null) { CameraRotationReceiver nativeRotationReceiver = new CameraRotationReceiver(cameraObj); simulator.addNativeReceiver(nativeRotationReceiver, cameraRotationUpdateChannel, cameraRotationResource); channelAndResourcesForCameraReceiving.put(cameraRotationUpdateChannel, cameraRotationResource); } if (channelAndResourcesForCameraReceiving.get(cameraScaleUpdateChannel) == null) { CameraScaleReceiver nativeScaleReceiver = new CameraScaleReceiver(cameraObj); simulator.addNativeReceiver(nativeScaleReceiver, cameraScaleUpdateChannel, cameraScaleResource); channelAndResourcesForCameraReceiving.put(cameraScaleUpdateChannel, cameraScaleResource); } if (channelAndResourcesForCameraReceiving.get(cameraProjectionUpdateChannel) == null) { CameraProjectionReceiver nativeProjectionReceiver = new CameraProjectionReceiver(cameraObj); simulator.addNativeReceiver(nativeProjectionReceiver, cameraProjectionUpdateChannel, cameraProjectionResource); channelAndResourcesForCameraReceiving.put(cameraProjectionUpdateChannel, cameraProjectionResource); } } Expression oldEntities = curSc.get("entities"); Expression newEntities = nextSc.get("entities"); Set<String> oldEidSet = new HashSet<>(((MapTerm) oldEntities).keySet()); Set<String> newEidSet = new HashSet<>(((MapTerm) newEntities).keySet()); oldEidSet.removeAll(((MapTerm) newEntities).keySet()); newEidSet.removeAll(((MapTerm) oldEntities).keySet()); if (!oldEidSet.isEmpty() || !newEidSet.isEmpty()) { // If the set of scene entities is changed. // Remove old entities and their native receivers. for (String oldEid: oldEidSet) { scene.removeEntity(oldEid); } for (DataTransferChannel channel: channelAndResourcesForEntityReceiving.keySet()) { Map<String, Resource> widToResource = channelAndResourcesForEntityReceiving.get(channel); for (String oldEid: oldEidSet) { Resource resource = widToResource.remove(oldEid); if (resource != null) { simulator.removeNativeReceiver(channel, resource); } } } // Add new entities. Resource entitiesResource = sceneResource.getChildrenMap().get("entities"); for (String newEid: newEidSet) { Expression entityExp = ((MapTerm) newEntities).get(newEid); if (entityExp instanceof JsonTerm) { JsonTerm entity = (JsonTerm) entityExp; Resource entityResource = entitiesResource.getChildrenMap().get(newEid); Expression transformExp = entity.get("transform"); Expression meshExp = entity.get("mesh"); if (transformExp instanceof JsonTerm && meshExp instanceof JsonTerm) { JsonTerm transform = (JsonTerm) transformExp; JsonTerm mesh = (JsonTerm) meshExp; Resource transformResource = entityResource.getChildrenMap().get("transform"); Resource meshResource = entityResource.getChildrenMap().get("mesh"); Expression positionExp = transform.get("position"); Expression rotationExp = transform.get("rotation"); Expression scaleExp = transform.get("scale"); Resource positionResource = transformResource.getChildrenMap().get("position"); Resource rotationResource = transformResource.getChildrenMap().get("rotation"); Resource scaleResource = transformResource.getChildrenMap().get("scale"); if (positionExp instanceof JsonTerm && rotationExp instanceof JsonTerm && scaleExp instanceof JsonTerm) { // Add a game entity to scene. JsonTerm position = (JsonTerm) positionExp; JsonTerm rotation = (JsonTerm) rotationExp; JsonTerm scale = (JsonTerm) scaleExp; String px = position.get("x").toString(); String py = position.get("y").toString(); String pz = position.get("z").toString(); String rx = rotation.get("x").toString(); String ry = rotation.get("y").toString(); String rz = rotation.get("z").toString(); String sx = scale.get("x").toString(); String sy = scale.get("y").toString(); String sz = scale.get("z").toString(); String type = (String) ((Constant) mesh.get("type")).getValue(); String texturePath = (String) ((Constant) mesh.get("sprite")).getValue(); GameObject gameObj = addGameObjectToScene(newEid, meshResource, px, py, pz, rx, ry, rz, sx, sy, sz, type, texturePath); // Connect game entity and model. connectGameEntiotyAndModel(newEid, gameObj, positionResource, rotationResource, scaleResource); } } } } } } } } private GameObject addGameObjectToScene(String eId, Resource meshResource, String px, String py, String pz, String rx, String ry, String rz, String sx, String sy, String sz, String type, String texturePath) { GameObject gameObj = new GameObject(eId);//新しいIDが必要あり gameObj.transform.setPosition(Float.parseFloat(px), Float.parseFloat(py), Float.parseFloat(pz)); gameObj.transform.setRotation(Float.parseFloat(rx), Float.parseFloat(ry), Float.parseFloat(rz)); gameObj.transform.setScale(Float.parseFloat(sx), Float.parseFloat(sy), Float.parseFloat(sz)); if (type.equals("sprite")) { Mesh meshObj = new Mesh(gameObj, Mesh.MeshType.SPRITE, texturePath); gameObj.addComponent(meshObj); SpriteReceiver nativeSpriteReceiver = new SpriteReceiver(meshObj); simulator.addNativeReceiver(nativeSpriteReceiver, spriteUpdateChannel, meshResource); Map<String, Resource> resources = channelAndResourcesForEntityReceiving.get(spriteUpdateChannel); if (resources == null) { resources = new HashMap<>(); channelAndResourcesForEntityReceiving.put(spriteUpdateChannel, resources); } resources.put(eId, meshResource); } scene.addEntity(eId, gameObj); return gameObj; } private void connectGameEntiotyAndModel(String eId, GameObject gameObj, Resource positionResource, Resource rotationResource, Resource scaleResource) { EntityPositionReceiver nativePositionReceiver = new EntityPositionReceiver(gameObj); simulator.addNativeReceiver(nativePositionReceiver, entityPositionUpdateChannel, positionResource); Map<String, Resource> resources = channelAndResourcesForEntityReceiving.get(entityPositionUpdateChannel); if (resources == null) { resources = new HashMap<>(); channelAndResourcesForEntityReceiving.put(entityPositionUpdateChannel, resources); } resources.put(eId, positionResource); EntityRotationReceiver nativeRotationReceiver = new EntityRotationReceiver(gameObj); simulator.addNativeReceiver(nativeRotationReceiver, entityRotationUpdateChannel, rotationResource); resources = channelAndResourcesForEntityReceiving.get(entityRotationUpdateChannel); if (resources == null) { resources = new HashMap<>(); channelAndResourcesForEntityReceiving.put(entityRotationUpdateChannel, resources); } resources.put(eId, rotationResource); EntityScaleReceiver nativeScaleReceiver = new EntityScaleReceiver(gameObj); simulator.addNativeReceiver(nativeScaleReceiver, entityScaleUpdateChannel, scaleResource); resources = channelAndResourcesForEntityReceiving.get(entityScaleUpdateChannel); if (resources == null) { resources = new HashMap<>(); channelAndResourcesForEntityReceiving.put(entityScaleUpdateChannel, resources); } resources.put(eId, scaleResource); } }