package com.uwsoft.editor.renderer.systems.render; import box2dLight.RayHandler; import com.badlogic.ashley.core.ComponentMapper; import com.badlogic.ashley.core.Entity; import com.badlogic.ashley.core.Family; import com.badlogic.ashley.systems.IteratingSystem; import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.math.Affine2; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.physics.box2d.World; import com.uwsoft.editor.renderer.commons.IExternalItemType; import com.uwsoft.editor.renderer.components.*; import com.uwsoft.editor.renderer.physics.PhysicsBodyLoader; import com.uwsoft.editor.renderer.systems.render.logic.DrawableLogicMapper; import com.uwsoft.editor.renderer.utils.ComponentRetriever; public class Overlap2dRenderer extends IteratingSystem { private final float TIME_STEP = 1f/60; private ComponentMapper<ViewPortComponent> viewPortMapper = ComponentMapper.getFor(ViewPortComponent.class); private ComponentMapper<CompositeTransformComponent> compositeTransformMapper = ComponentMapper.getFor(CompositeTransformComponent.class); private ComponentMapper<NodeComponent> nodeMapper = ComponentMapper.getFor(NodeComponent.class); private ComponentMapper<ParentNodeComponent> parentNodeMapper = ComponentMapper.getFor(ParentNodeComponent.class); private ComponentMapper<TransformComponent> transformMapper = ComponentMapper.getFor(TransformComponent.class); private ComponentMapper<MainItemComponent> mainItemComponentMapper = ComponentMapper.getFor(MainItemComponent.class); private ComponentMapper<ShaderComponent> shaderComponentComponentMapper = ComponentMapper.getFor(ShaderComponent.class); private DrawableLogicMapper drawableLogicMapper; private RayHandler rayHandler; // private World world; //private Box2DDebugRenderer debugRenderer = new Box2DDebugRenderer(); public static float timeRunning = 0; public Batch batch; public Overlap2dRenderer(Batch batch) { super(Family.all(ViewPortComponent.class).get()); this.batch = batch; drawableLogicMapper = new DrawableLogicMapper(); } public void addDrawableType(IExternalItemType itemType) { drawableLogicMapper.addDrawableToMap(itemType.getTypeId(), itemType.getDrawable()); } @Override public void processEntity(Entity entity, float deltaTime) { timeRunning+=deltaTime; ViewPortComponent ViewPortComponent = viewPortMapper.get(entity); Camera camera = ViewPortComponent.viewPort.getCamera(); camera.update(); batch.setProjectionMatrix(camera.combined); batch.begin(); drawRecursively(entity, 1f); batch.end(); //TODO kinda not cool (this should be done in separate lights renderer maybe? if (rayHandler != null) { rayHandler.setCulling(false); OrthographicCamera orthoCamera = (OrthographicCamera) camera; camera.combined.scl(1f / PhysicsBodyLoader.getScale()); rayHandler.setCombinedMatrix(orthoCamera); rayHandler.updateAndRender(); } //debugRenderer.render(world, camera.combined); //TODO Spine rendere thing } private void drawRecursively(Entity rootEntity, float parentAlpha) { //currentComposite = rootEntity; CompositeTransformComponent curCompositeTransformComponent = compositeTransformMapper.get(rootEntity); TransformComponent transform = transformMapper.get(rootEntity); ShaderComponent shaderComponent = shaderComponentComponentMapper.get(rootEntity); boolean shaderExist = shaderComponent!=null && shaderComponent.getShader()!=null; if(shaderExist){ batch.setShader(shaderComponent.getShader()); } if (curCompositeTransformComponent.transform || transform.rotation != 0 || transform.scaleX !=1 || transform.scaleY !=1){ MainItemComponent childMainItemComponent = mainItemComponentMapper.get(rootEntity); //System.out.println(" Name " +childMainItemComponent.itemIdentifier); //System.out.println(curCompositeTransformComponent.computedTransform.toString()); computeTransform(rootEntity); //System.out.println(curCompositeTransformComponent.computedTransform.toString()); applyTransform(rootEntity, batch); } TintComponent tintComponent = ComponentRetriever.get(rootEntity, TintComponent.class); parentAlpha *= tintComponent.color.a; drawChildren(rootEntity, batch, curCompositeTransformComponent, parentAlpha); if (curCompositeTransformComponent.transform || transform.rotation != 0 || transform.scaleX !=1 || transform.scaleY !=1) resetTransform(rootEntity, batch); if(shaderExist){ batch.setShader(null); } } private void drawChildren(Entity rootEntity, Batch batch, CompositeTransformComponent curCompositeTransformComponent, float parentAlpha) { NodeComponent nodeComponent = nodeMapper.get(rootEntity); Entity[] children = nodeComponent.children.begin(); TransformComponent transform = transformMapper.get(rootEntity); if (curCompositeTransformComponent.transform || transform.rotation != 0 || transform.scaleX !=1 || transform.scaleY !=1) { for (int i = 0, n = nodeComponent.children.size; i < n; i++) { Entity child = children[i]; LayerMapComponent rootLayers = ComponentRetriever.get(rootEntity, LayerMapComponent.class); ZIndexComponent childZIndexComponent = ComponentRetriever.get(child, ZIndexComponent.class); if(!rootLayers.isVisible(childZIndexComponent.layerName)) { continue; } MainItemComponent childMainItemComponent = mainItemComponentMapper.get(child); if(!childMainItemComponent.visible){ continue; } int entityType = childMainItemComponent.entityType; NodeComponent childNodeComponent = nodeMapper.get(child); if(childNodeComponent ==null){ //Find logic from the mapper and draw it drawableLogicMapper.getDrawable(entityType).draw(batch, child, parentAlpha); }else{ //Step into Composite drawRecursively(child, parentAlpha); } } } else { // No transform for this group, offset each child. TransformComponent compositeTransform = transformMapper.get(rootEntity); float offsetX = compositeTransform.x, offsetY = compositeTransform.y; if(viewPortMapper.has(rootEntity)){ offsetX = 0; offsetY = 0; } for (int i = 0, n = nodeComponent.children.size; i < n; i++) { Entity child = children[i]; LayerMapComponent rootLayers = ComponentRetriever.get(rootEntity, LayerMapComponent.class); ZIndexComponent childZIndexComponent = ComponentRetriever.get(child, ZIndexComponent.class); if(!rootLayers.isVisible(childZIndexComponent.layerName)) { continue; } MainItemComponent childMainItemComponent = mainItemComponentMapper.get(child); if(!childMainItemComponent.visible){ continue; } TransformComponent childTransformComponent = transformMapper.get(child); float cx = childTransformComponent.x, cy = childTransformComponent.y; childTransformComponent.x = cx + offsetX; childTransformComponent.y = cy + offsetY; NodeComponent childNodeComponent = nodeMapper.get(child); int entityType = mainItemComponentMapper.get(child).entityType; if(childNodeComponent ==null){ //Find the logic from mapper and draw it drawableLogicMapper.getDrawable(entityType).draw(batch, child, parentAlpha); }else{ //Step into Composite drawRecursively(child, parentAlpha); } childTransformComponent.x = cx; childTransformComponent.y = cy; } } nodeComponent.children.end(); } /** Returns the transform for this group's coordinate system. * @param rootEntity */ protected Matrix4 computeTransform (Entity rootEntity) { CompositeTransformComponent curCompositeTransformComponent = compositeTransformMapper.get(rootEntity); //NodeComponent nodeComponent = nodeMapper.get(rootEntity); ParentNodeComponent parentNodeComponent = parentNodeMapper.get(rootEntity); TransformComponent curTransform = transformMapper.get(rootEntity); Affine2 worldTransform = curCompositeTransformComponent.worldTransform; //TODO origin thing float originX = 0; float originY = 0; float x = curTransform.x; float y = curTransform.y; float rotation = curTransform.rotation; float scaleX = curTransform.scaleX; float scaleY = curTransform.scaleY; worldTransform.setToTrnRotScl(x + originX, y + originY, rotation, scaleX, scaleY); if (originX != 0 || originY != 0) worldTransform.translate(-originX, -originY); // Find the first parent that transforms. CompositeTransformComponent parentTransformComponent = null; //NodeComponent parentNodeComponent; Entity parentEntity = null; if(parentNodeComponent != null){ parentEntity = parentNodeComponent.parentEntity; } // if (parentEntity != null){ // // } // while (parentEntity != null) { // parentNodeComponent = nodeMapper.get(parentEntity); // if (parentTransformComponent.transform) break; // System.out.println("Gand"); // parentEntity = parentNodeComponent.parentEntity; // parentTransformComponent = compositeTransformMapper.get(parentEntity); // // } if (parentEntity != null){ parentTransformComponent = compositeTransformMapper.get(parentEntity); TransformComponent transform = transformMapper.get(parentEntity); if(curCompositeTransformComponent.transform || transform.rotation != 0 || transform.scaleX !=1 || transform.scaleY !=1) worldTransform.preMul(parentTransformComponent.worldTransform); //MainItemComponent main = parentEntity.getComponent(MainItemComponent.class); //System.out.println("NAME " + main.itemIdentifier); } curCompositeTransformComponent.computedTransform.set(worldTransform); return curCompositeTransformComponent.computedTransform; } protected void applyTransform (Entity rootEntity, Batch batch) { CompositeTransformComponent curCompositeTransformComponent = compositeTransformMapper.get(rootEntity); curCompositeTransformComponent.oldTransform.set(batch.getTransformMatrix()); batch.setTransformMatrix(curCompositeTransformComponent.computedTransform); } protected void resetTransform (Entity rootEntity, Batch batch) { CompositeTransformComponent curCompositeTransformComponent = compositeTransformMapper.get(rootEntity); batch.setTransformMatrix(curCompositeTransformComponent.oldTransform); } public void setRayHandler(RayHandler rayHandler){ this.rayHandler = rayHandler; } // public void setBox2dWorld(World world) { // this.world = world; // } //this method has been left to avoid any compatibility issue //setPhysicsOn has been moved in PhysicsSystem class //Physics is now totally decoupled from rendering @Deprecated public void setPhysicsOn(boolean isPhysicsOn) { //empty } public Batch getBatch() { return batch; } }