All Downloads are FREE. Search and download functionalities are using the official Maven repository.

box2dLight.DirectionalLight Maven / Gradle / Ivy

There is a newer version: 1.5
Show newest version

package box2dLight;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.Mesh.VertexDataType;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;

/**
 * Light which source is at infinite distance
 * 
 * 

Extends {@link Light} * * @author kalle_h */ public class DirectionalLight extends Light { protected final Vector2 start[]; protected final Vector2 end[]; protected float sin; protected float cos; /** * Creates directional light which source is at infinite distance, * direction and intensity is same everywhere * *

-90 direction is straight from up * * @param rayHandler * not {@code null} instance of RayHandler * @param rays * number of rays - more rays make light to look more realistic * but will decrease performance, can't be less than MIN_RAYS * @param color * color, set to {@code null} to use the default color * @param directionDegree * direction in degrees */ public DirectionalLight(RayHandler rayHandler, int rays, Color color, float directionDegree) { super(rayHandler, rays, color, Float.POSITIVE_INFINITY, directionDegree); vertexNum = (vertexNum - 1) * 2; start = new Vector2[rayNum]; end = new Vector2[rayNum]; for (int i = 0; i < rayNum; i++) { start[i] = new Vector2(); end[i] = new Vector2(); } lightMesh = new Mesh( VertexDataType.VertexArray, staticLight, vertexNum, 0, new VertexAttribute(Usage.Position, 2, "vertex_positions"), new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"), new VertexAttribute(Usage.Generic, 1, "s")); softShadowMesh = new Mesh( VertexDataType.VertexArray, staticLight, vertexNum, 0, new VertexAttribute(Usage.Position, 2, "vertex_positions"), new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"), new VertexAttribute(Usage.Generic, 1, "s")); update(); } @Override public void setDirection (float direction) { this.direction = direction; sin = MathUtils.sinDeg(direction); cos = MathUtils.cosDeg(direction); if (staticLight) dirty = true; } @Override void update () { if (staticLight && !dirty) return; dirty = false; final float width = (rayHandler.x2 - rayHandler.x1); final float height = (rayHandler.y2 - rayHandler.y1); final float sizeOfScreen = width > height ? width : height; float xAxelOffSet = sizeOfScreen * cos; float yAxelOffSet = sizeOfScreen * sin; // preventing length <0 assertion error on box2d. if ((xAxelOffSet * xAxelOffSet < 0.1f) && (yAxelOffSet * yAxelOffSet < 0.1f)) { xAxelOffSet = 1; yAxelOffSet = 1; } final float widthOffSet = sizeOfScreen * -sin; final float heightOffSet = sizeOfScreen * cos; float x = (rayHandler.x1 + rayHandler.x2) * 0.5f - widthOffSet; float y = (rayHandler.y1 + rayHandler.y2) * 0.5f - heightOffSet; final float portionX = 2f * widthOffSet / (rayNum - 1); x = (MathUtils.floor(x / (portionX * 2))) * portionX * 2; final float portionY = 2f * heightOffSet / (rayNum - 1); y = (MathUtils.ceil(y / (portionY * 2))) * portionY * 2; for (int i = 0; i < rayNum; i++) { final float steppedX = i * portionX + x; final float steppedY = i * portionY + y; m_index = i; start[i].x = steppedX - xAxelOffSet; start[i].y = steppedY - yAxelOffSet; mx[i] = end[i].x = steppedX + xAxelOffSet; my[i] = end[i].y = steppedY + yAxelOffSet; if (rayHandler.world != null && !xray) { rayHandler.world.rayCast(ray, start[i], end[i]); } } // update light mesh // ray starting point int size = 0; final int arraySize = rayNum; for (int i = 0; i < arraySize; i++) { segments[size++] = start[i].x; segments[size++] = start[i].y; segments[size++] = colorF; segments[size++] = 1f; segments[size++] = mx[i]; segments[size++] = my[i]; segments[size++] = colorF; segments[size++] = 1f; } lightMesh.setVertices(segments, 0, size); if (!soft || xray) return; size = 0; for (int i = 0; i < arraySize; i++) { segments[size++] = mx[i]; segments[size++] = my[i]; segments[size++] = colorF; segments[size++] = 1f; segments[size++] = mx[i] + softShadowLength * cos; segments[size++] = my[i] + softShadowLength * sin; segments[size++] = zeroColorBits; segments[size++] = 1f; } softShadowMesh.setVertices(segments, 0, size); } @Override void render () { rayHandler.lightRenderedLastFrame++; lightMesh.render( rayHandler.lightShader, GL20.GL_TRIANGLE_STRIP, 0, vertexNum); if (soft && !xray) { softShadowMesh.render( rayHandler.lightShader, GL20.GL_TRIANGLE_STRIP, 0, vertexNum); } } @Override public boolean contains (float x, float y) { boolean oddNodes = false; float x2 = mx[rayNum] = start[0].x; float y2 = my[rayNum] = start[0].y; float x1, y1; for (int i = 0; i <= rayNum; x2 = x1, y2 = y1, ++i) { x1 = mx[i]; y1 = my[i]; if (((y1 < y) && (y2 >= y)) || (y1 >= y) && (y2 < y)) { if ((y - y1) / (y2 - y1) * (x2 - x1) < (x - x1)) oddNodes = !oddNodes; } } for (int i = 0; i < rayNum; x2 = x1, y2 = y1, ++i) { x1 = start[i].x; y1 = start[i].y; if (((y1 < y) && (y2 >= y)) || (y1 >= y) && (y2 < y)) { if ((y - y1) / (y2 - y1) * (x2 - x1) < (x - x1)) oddNodes = !oddNodes; } } return oddNodes; } /** Not applicable for this light type **/ @Deprecated @Override public void attachToBody (Body body) { } /** Not applicable for this light type **/ @Deprecated @Override public void setPosition (float x, float y) { } /** Not applicable for this light type *

Always return {@code null} **/ @Deprecated @Override public Body getBody () { return null; } /** Not applicable for this light type *

Always return {@code 0} **/ @Deprecated @Override public float getX () { return 0; } /** Not applicable for this light type *

Always return {@code 0} **/ @Deprecated @Override public float getY () { return 0; } /** Not applicable for this light type **/ @Deprecated @Override public void setPosition (Vector2 position) { } /** Not applicable for this light type **/ @Deprecated @Override public void setDistance(float dist) { } /** Not applicable for this light type **/ @Deprecated @Override public void setIgnoreAttachedBody(boolean flag) { } /** Not applicable for this light type *

Always return {@code false} **/ @Deprecated @Override public boolean getIgnoreAttachedBody() { return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy