Skip to content

Instantly share code, notes, and snippets.

Created August 23, 2015 18:20
Show Gist options
  • Save anonymous/81621a5f65de59a93a67 to your computer and use it in GitHub Desktop.
Save anonymous/81621a5f65de59a93a67 to your computer and use it in GitHub Desktop.
// Code which is run at the top most level, or the render method
//'lightsource' interchangable with 'point in which the rays come out of'
float jitter = 0.02f;
//Arraylist for multiple 'lightsources'; The 360/45 is so I can have 8 lightsources in a circle around the center lightsource
ArrayList<ArrayList<Vec2f>> raycasts = new ArrayList<>(360/45 + 1);
//Arraylist of the points for all the lightsources
ArrayList<Vec2f> castPoints = new ArrayList<>();
//Loop to make the 8 surrounding lightsources
for(int i = 0; i < 8; ++i){
raycasts.add(new ArrayList<>());
castPoints.add(castPoint.add((float)Math.cos(i * Math.toRadians(360/8)) * 10, (float)Math.sin(i * Math.toRadians(360/8)) * 10));
Collections.addAll(raycasts.get(i), castAll(castPoints.get(i), 400, boxVertices.toArray(new Vec2f[0]), jitter, collisions));
}
//Adding the center light source
raycasts.add(new ArrayList<>());
castPoints.add(castPoint);
Collections.addAll(raycasts.get(raycasts.size()-1), RaycastEngine.castAll(castPoint, 400, boxVertices.toArray(new Vec2f[0]), jitter, collisions));
//Raycasting methods
public static Vec2f[] castAll(Vec2f castPoint, float cutoff, Vec2f[] points, float jitter, CollisionRule... collidables) {
//Arraylist to contain the angles for the rays going towards each vertice
ArrayList<Double> angles = new ArrayList<>(points.length * 3 + defaultAngles.size());
//The defaultAngles var is an ArrayList containing angles going at 45, 135, 225, 315 (angles going diagonal)
angles.addAll(defaultAngles);
//Converting all the vertices into angles
for (Vec2f point : points) {
double angle = angleBetweenVectors(castPoint, point); //Math.atan2(point.y - castPoint.y, point.x - castPoint.x)
//Converting negative values to positive so it is sorted and ordered correctly
if(angle < 0) angle += Math.PI*2;
angles.add(angle);
//Adding jitter to catch any walls behind the vertice if the ray hits the vertice
angles.add(angle + jitter/4);
angles.add(angle - jitter/4);
angles.add(angle + jitter);
angles.add(angle - jitter);
}
//More raycasting code which takes an array of angles instead of an array of vertices
return castAll(castPoint, cutoff, doubleArrayListToPrim(angles), collidables);
}
public static Vec2f[] castAll(Vec2f castPoint, float cutoff, double[] angles, CollisionRule... collidables){
//1 point of ray contact for each angle of ray
Vec2f[] results = new Vec2f[angles.length];
angles = sortAngles(angles); //Arrays.sort(double[])
for(int i = 0; i < results.length; ++i){
//Cast a ray at the angles and return a point of contact
results[i] = castRay(castPoint, angles[i], cutoff, collidables);
}
return results;
}
public static Vec2f castRay(Vec2f center, double radians, float cutoff, CollisionRule... collidables){
//Step amount (2px)
Vec2f rayStep = new Vec2f((float) (Math.cos(radians)) * 2.0f, (float) (Math.sin(radians)) * 2.0f);
float stepDistance = rayStep.length(); // Math.sqrt(x*x + y*y)
//How far the ray has gone
float accumulatedDistance = 0.0f;
//Clone of the center so we don't actually change its original values of the original variable
//Also the starting point of the ray and the current position of the ray
Vec2f rayPoint = new Vec2f(center);
while(accumulatedDistance < cutoff){
accumulatedDistance += stepDistance;
//Add step to the current position of ray
rayPoint.addLocal(rayStep);
for(CollisionRule collisionRule : collidables){
if(collisionRule.collision(rayPoint)){ //Basically a simple AABB collision detection
return rayPoint;
}
}
}
//No collision so add the point of contact at the edge of the lightsource
return center.add((float) Math.cos(radians) * cutoff, (float) Math.sin(radians) * cutoff);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment