public boolean validate(float x1, float z1, float x2, float z2, Spatial spatial) { // generate the start and destination points Vector3f start = new Vector3f(x1, EStats.SnowballHeight.getValue(), z1); Vector3f destination = new Vector3f(x2, EStats.SnowballHeight.getValue(), z2); // convert points to world coordinate system spatial.localToWorld(start, start); spatial.localToWorld(destination, destination); // generate Ray for intersection detection Vector3f direction = destination.subtract(start).normalizeLocal(); Ray moveRay = new Ray(start, direction); // calculate the intersection between the move ray and the spatial Vector3f hitPoint = getIntersection(moveRay, spatial, null, false); // if there is no hit point, it is a valid throw if (hitPoint == null) return true; // if there is a hit point, compare the distances. float distance1 = start.distanceSquared(destination); float distance2 = start.distanceSquared(hitPoint); if (distance1 <= distance2) return true; else return false; }
public Vector3f getDestination(float x1, float z1, float x2, float z2, Spatial spatial) { // generate the start and destination points Vector3f start = new Vector3f(x1, EStats.SnowmanHeight.getValue() / 2.0f, z1); Vector3f destination = new Vector3f(x2, EStats.SnowmanHeight.getValue() / 2.0f, z2); // convert points to world coordinate system spatial.localToWorld(start, start); spatial.localToWorld(destination, destination); // generate Ray for intersection detection Vector3f direction = destination.subtract(start).normalizeLocal(); Ray moveRay = new Ray(start, direction); // calculate the intersection between the move ray and the spatial Vector3f hitPoint = getIntersection(moveRay, spatial, null, false); // if there are no obstacles, return the destination directly if (hitPoint == null) { spatial.worldToLocal(destination, destination); return destination; } else { float originalDistance = destination.distance(start); float newDistance = hitPoint.distance(start); if (originalDistance > newDistance - EStats.BackoffDistance.getValue()) { // we are either trying to go through a hit point // or got too close to one direction.multLocal(EStats.BackoffDistance.getValue()); Vector3f newDestination = hitPoint.subtractLocal(direction); spatial.worldToLocal(newDestination, newDestination); return newDestination; } else { // destination is not close to any hit points so // we can just return it directly spatial.worldToLocal(destination, destination); return destination; } } }