Created
April 1, 2013 19:53
-
-
Save mattdesl/5287255 to your computer and use it in GitHub Desktop.
2D shadows in LibGDX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static Vector2 L = new Vector2(); | |
static Vector2 N = new Vector2(); | |
static Vector2 tmp = new Vector2(); | |
static Vector2[] points = new Vector2[] { | |
new Vector2(), new Vector2(), new Vector2(), new Vector2() | |
}; | |
static Vector2[] tmpBoundary = new Vector2[] { | |
new Vector2(), new Vector2() | |
}; | |
/** | |
* For the given light position (x, y with lower-left origin), determine the two | |
* "shadow boundary" points for the given rectangle (also uses lower-left origin). | |
* These points are the two that will need to be extended/projected from the light vector, | |
* in order to construct the shadow geometry. If the light is inside the rectangle, or could | |
* not find two shadow boundary points, null is returned. | |
* | |
* To reduce garbage, this method returns a static array | |
* with vectors shared across the various shadowBoundary methods. | |
* | |
* @param lightPos | |
* @param rect | |
* @return | |
*/ | |
public static Vector2[] shadowBoundary(Vector2 lightPos, Rectangle r) { | |
//corners, clockwise | |
points[0].set(r.x, r.y); | |
points[1].set(r.x + r.width, r.y); | |
points[2].set(r.x + r.width, r.y + r.height); | |
points[3].set(r.x, r.y + r.height); | |
int off = 0; | |
boolean lastFace = true; | |
//go through each point + 1 | |
for (int i=0; i<points.length + 1; i++) { | |
Vector2 p = points[i % points.length]; | |
Vector2 prev = points[i==0 ? points.length-1 : i-1]; | |
//line to point | |
//light to point vec, normalized | |
L.set(p).sub(lightPos).nor(); | |
//normalized direction of edge | |
N.set(p).sub(prev).nor(); | |
//dot product | |
float dot = N.dot(L); | |
boolean face = dot < 0; | |
//skip the first index, we'll come back to it later | |
if (i!=0) { | |
if (face != lastFace) { | |
if (off >= tmpBoundary.length) | |
return tmpBoundary; | |
tmpBoundary[off].set(p); | |
off++; | |
} | |
} | |
lastFace = face; | |
} | |
return off==0 ? null : tmpBoundary; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment