From 6b748a88a6f4f81cee8b2bd7e0e0d812680ff081 Mon Sep 17 00:00:00 2001 From: rinold Date: Thu, 5 Feb 2015 20:22:43 +0300 Subject: [PATCH] Draft EdgeShape support for dynamic shadows + minor re-factoring for #40 --- src/box2dLight/Light.java | 8 ---- src/box2dLight/LightData.java | 15 ++++++ src/box2dLight/PointLight.java | 87 ++++++++++++++++++---------------- 3 files changed, 62 insertions(+), 48 deletions(-) diff --git a/src/box2dLight/Light.java b/src/box2dLight/Light.java index 1b9f6f7..e9b5861 100644 --- a/src/box2dLight/Light.java +++ b/src/box2dLight/Light.java @@ -457,13 +457,5 @@ static public void setContactFilter(short categoryBits, short groupIndex, filterA.groupIndex = groupIndex; filterA.maskBits = maskBits; } - - /** Returns the distance between the given line and point. Note the specified line is not a line segment. */ - public static float sqDistanceLinePoint (float startX, float startY, float endX, float endY, float pointX, float pointY) { - float tmp1 = (endX - startX); - float tmp2 = (endY - startY); - float normalLength2 = tmp1 * tmp1 + tmp2 * tmp2; - return ((pointX - startX) * tmp2 - (pointY - startY) * tmp1) / normalLength2; - } } diff --git a/src/box2dLight/LightData.java b/src/box2dLight/LightData.java index a8dfb27..4625db3 100644 --- a/src/box2dLight/LightData.java +++ b/src/box2dLight/LightData.java @@ -10,4 +10,19 @@ public LightData(float h) { height = h; } + public float getLimit(float distance, float lightHeight, float lightRange) { + float l = 0f; + if (lightHeight > height) { + l = lightRange * height / (lightHeight - height); + float diff = lightRange - distance; + if (l > diff) l = diff; + } else if (lightHeight == 0f) { + l = lightRange; + } else { + l = lightRange - distance; + } + if (l < 0) l = 0f; + return l; + } + } diff --git a/src/box2dLight/PointLight.java b/src/box2dLight/PointLight.java index d6cde32..2c13814 100644 --- a/src/box2dLight/PointLight.java +++ b/src/box2dLight/PointLight.java @@ -11,6 +11,7 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.physics.box2d.ChainShape; import com.badlogic.gdx.physics.box2d.CircleShape; +import com.badlogic.gdx.physics.box2d.EdgeShape; import com.badlogic.gdx.physics.box2d.Fixture; import com.badlogic.gdx.physics.box2d.PolygonShape; import com.badlogic.gdx.physics.box2d.Shape; @@ -105,11 +106,12 @@ protected void updateDynamicShadowMeshes() { float colBits = rayHandler.ambientLight.toFloatBits(); for (Fixture fixture : affectedFixtures) { LightData data = (LightData)fixture.getUserData(); - if (data == null) continue; + if (data == null || fixture.isSensor()) continue; Shape fixtureShape = fixture.getShape(); Type type = fixtureShape.getType(); center.set(fixture.getBody().getWorldCenter()); + int size = 0; float l = 0f; float f = 1f / data.shadowsDropped; if (type == Type.Polygon || type == Type.Chain) { @@ -121,7 +123,6 @@ protected void updateDynamicShadowMeshes() { int vertexCount = isPolygon ? pShape.getVertexCount() : cShape.getVertexCount(); - int size = 0; int minN = -1; int maxN = -1; int minDstN = -1; @@ -181,16 +182,7 @@ protected void updateDynamicShadowMeshes() { tmpVec.set(tmpVerts.get(n)); float dst = tmpVec.dst(start); - if (height > data.height) { - l = dst * data.height / (height - data.height); - float diff = distance - dst; - if (l > diff) l = diff; - } else if (height == 0f) { - l = distance; - } else { - l = distance - dst; - } - if (l < 0) l = 0f; + l = data.getLimit(dst, height, distance); tmpEnd.set(tmpVec).sub(start).limit(l).add(tmpVec); @@ -204,31 +196,12 @@ protected void updateDynamicShadowMeshes() { dynamicSegments[size++] = colBits; dynamicSegments[size++] = f; } - - - Mesh mesh = new Mesh( - VertexDataType.VertexArray, staticLight, 2 * ind.size, 0, - new VertexAttribute(Usage.Position, 2, "vertex_positions"), - new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"), - new VertexAttribute(Usage.Generic, 1, "s")); - mesh.setVertices(dynamicSegments, 0, size); - dynamicShadowMeshes.add(mesh); } else if (type == Type.Circle) { CircleShape shape = (CircleShape)fixtureShape; - int size = 0; float r = shape.getRadius(); float dst = tmpVec.set(center).dst(start); float a = (float)Math.acos(r/dst) * MathUtils.radDeg; - if (height > data.height) { - l = dst * data.height / (height - data.height); - float diff = distance - dst; - if (l > diff) l = diff; - } else if (height == 0f) { - l = distance; - } else { - l = distance - dst; - } - if (l < 0) l = 0f; + l = data.getLimit(dst, height, distance); tmpVec.set(start).sub(center).clamp(r, r).rotate(a); tmpStart.set(center).add(tmpVec); @@ -255,15 +228,49 @@ protected void updateDynamicShadowMeshes() { dynamicSegments[size++] = tmpEnd.y; dynamicSegments[size++] = colBits; dynamicSegments[size++] = f; + } else if (type == Type.Edge) { + EdgeShape shape = (EdgeShape)fixtureShape; + + shape.getVertex1(tmpVec); + tmpVec.set(fixture.getBody().getWorldPoint(tmpVec)); + float dst = tmpVec.dst(start); + l = data.getLimit(dst, height, distance); + + dynamicSegments[size++] = tmpVec.x; + dynamicSegments[size++] = tmpVec.y; + dynamicSegments[size++] = colBits; + dynamicSegments[size++] = f; + + tmpEnd.set(tmpVec).sub(start).limit(l).add(tmpVec); + dynamicSegments[size++] = tmpEnd.x; + dynamicSegments[size++] = tmpEnd.y; + dynamicSegments[size++] = colBits; + dynamicSegments[size++] = f; + + shape.getVertex2(tmpVec); + tmpVec.set(fixture.getBody().getWorldPoint(tmpVec)); + dst = tmpVec.dst(start); + l = data.getLimit(dst, height, distance); + + dynamicSegments[size++] = tmpVec.x; + dynamicSegments[size++] = tmpVec.y; + dynamicSegments[size++] = colBits; + dynamicSegments[size++] = f; - Mesh mesh = new Mesh( - VertexDataType.VertexArray, staticLight, size / 4, 0, - new VertexAttribute(Usage.Position, 2, "vertex_positions"), - new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"), - new VertexAttribute(Usage.Generic, 1, "s")); - mesh.setVertices(dynamicSegments, 0, size); - dynamicShadowMeshes.add(mesh); - } + tmpEnd.set(tmpVec).sub(start).limit(l).add(tmpVec); + dynamicSegments[size++] = tmpEnd.x; + dynamicSegments[size++] = tmpEnd.y; + dynamicSegments[size++] = colBits; + dynamicSegments[size++] = f; + } + + Mesh mesh = new Mesh( + VertexDataType.VertexArray, staticLight, size / 4, 0, + new VertexAttribute(Usage.Position, 2, "vertex_positions"), + new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"), + new VertexAttribute(Usage.Generic, 1, "s")); + mesh.setVertices(dynamicSegments, 0, size); + dynamicShadowMeshes.add(mesh); } }