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.

Revisions

  1. @invalid-email-address Anonymous created this gist Aug 23, 2015.
    91 changes: 91 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,91 @@
    // 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);
    }