// 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> raycasts = new ArrayList<>(360/45 + 1); //Arraylist of the points for all the lightsources ArrayList 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 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); }