org.hakkit.bounding.Ray.java Source code

Java tutorial

Introduction

Here is the source code for org.hakkit.bounding.Ray.java

Source

/*
 * Hakkit - A Minecraft plugin API and server extension.
 *
 * Copyright (C) Hakkit Development Team
 *
 * This file is part of Hakkit.
 *
 * Hakkit is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Hakkit is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Hakkit.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.hakkit.bounding;

import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.hakkit.entity.player.Player;

/**
 * I ignorantly disregarded the Bounding______ naming (i.e. BoundingRay) because
 * it seems a bit off to call this a "bounding" object. It really just intersects.
 * Maybe I'll rename Bounding to something more reasonable later on.
 */
public class Ray extends Bounding {
    private Vector3D origin;
    private Vector3D direction;
    private double minimum;
    private double maximum;

    public Ray(Vector3D origin, Vector3D direction, double minimum, double maximum) {
        this.origin = origin;
        this.direction = direction;
        this.minimum = maximum;
        this.maximum = Math.max(minimum, maximum); //Ensure that maximum >= minimum
    }

    public Ray(Vector3D origin, Vector3D direction, double maximum) {
        this(origin, direction, 0d, maximum);
    }

    public Ray(Vector3D origin, Vector3D direction) {
        this(origin, direction, Double.MAX_VALUE);
    }

    public Vector3D getOrigin() {
        return origin;
    }

    public Vector3D getDirection() {
        return direction;
    }

    @Override
    public boolean intersect(BoundingBox b) {
        double tmin, tmax, tymin, tymax, tzmin, tzmax;

        if (getDirection().getX() >= 0) {
            tmin = (b.getStart().getX() - getOrigin().getX()) / getDirection().getX();
            tmax = (b.getEnd().getX() - getOrigin().getX()) / getDirection().getX();
        } else {
            tmin = (b.getEnd().getX() - getOrigin().getX()) / getDirection().getX();
            tmax = (b.getStart().getX() - getOrigin().getX()) / getDirection().getX();
        }

        if (getDirection().getY() >= 0) {
            tymin = (b.getStart().getY() - getOrigin().getY()) / getDirection().getY();
            tymax = (b.getEnd().getY() - getOrigin().getY()) / getDirection().getY();
        } else {
            tymin = (b.getEnd().getY() - getOrigin().getY()) / getDirection().getY();
            tymax = (b.getStart().getY() - getOrigin().getY()) / getDirection().getY();
        }

        if ((tmin > tymax) || (tymin > tmax))
            return false;

        if (tymin > tmin)
            tmin = tymin;

        if (tymax < tmax)
            tmax = tymax;

        if (getDirection().getZ() >= 0) {
            tzmin = (b.getStart().getZ() - getOrigin().getZ()) / getDirection().getZ();
            tzmax = (b.getEnd().getZ() - getOrigin().getZ()) / getDirection().getZ();
        } else {
            tzmin = (b.getEnd().getZ() - getOrigin().getZ()) / getDirection().getZ();
            tzmax = (b.getStart().getZ() - getOrigin().getZ()) / getDirection().getZ();
        }

        if ((tmin > tzmax) || (tzmin > tmax))
            return false;

        if (tzmin > tmin)
            tmin = tzmin;
        if (tzmax < tmax)
            tmax = tzmax;

        return ((tmin < maximum) && (tmax > minimum));
    }

    @Override
    public boolean intersect(BoundingSphere b) {
        double radiusSquared = b.getRadius() * b.getRadius();

        Vector3D L = b.getCenter().subtract(getOrigin());
        double tca = L.dotProduct(getDirection());
        if (tca < 0)
            return false; //Very bad.

        double d2 = L.dotProduct(L) - tca * tca;
        if (d2 > radiusSquared)
            return false;

        double thc = Math.sqrt(radiusSquared - d2); //Distance from the origin to the center of the intersections
        double t0 = tca - thc; //Distance from ray origin to the intersection point
        double t1 = tca + thc; //Distance from the ray origin to the second intersection point

        //Ensure the first intersection is within our value range.
        if (t0 > maximum || t0 < minimum)
            return false;

        //It must be within range, and an intersection must have occurred.
        return true;
    }

    /**
     * Creates a ray from a player instance, using its reach distance as the maximum distance the ray may travel.
     * @param player Player to instantiate a new ray from.
     * @return Ray.
     */
    public static final Ray fromPlayer(Player player) {
        return null; //TODO: Fix this.
        //return fromPlayer(player, 0, player.g());
    }

    /**
     * Creates a ray from a player instance.
     * @param player Player to instantiate a new ray from.
     * @param maximum Maximum length (or distance) of the ray.
     * @return Ray.
     */
    public static final Ray fromPlayer(Player player, double maximum) {
        return fromPlayer(player, 0, maximum);
    }

    /**
     * Creates a ray from a player instance using its location and look vectors.
     * @param player Player to instantiate a new ray from.
     * @param minimum Minimum length (or distance) of the ray.
     * @param maximum Maximum length (or distance) of the ray.
     * @return Ray.
     */
    public static final Ray fromPlayer(Player player, double minimum, double maximum) {
        return new Ray(player.getPosition().getLocation(), player.getLookDirection(), minimum, maximum);
    }
}