/**
* Copyright 2012 Jason Sorensen (sorensenj@smert.net)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package net.smert.frameworkgl.math;
import net.smert.frameworkgl.utils.ThreadLocalVars;
/**
*
* @author Jason Sorensen <sorensenj@smert.net>
*/
public class AABBUtilities {
private AABBUtilities() {
}
public static boolean DoesAabb0IntersectAabb1(AABB aabb0, AABB aabb1) {
return ((aabb0.min.getX() <= aabb1.max.getX()) && (aabb1.min.getX() <= aabb0.max.getX())
&& (aabb0.min.getZ() <= aabb1.max.getZ()) && (aabb1.min.getZ() <= aabb0.max.getZ())
&& (aabb0.min.getY() <= aabb1.max.getY()) && (aabb1.min.getY() <= aabb0.max.getY()));
}
public static boolean IsAabb0ContainedInAabb1(AABB aabb0, AABB aabb1) {
return ((aabb0.min.getX() >= aabb1.min.getX()) && (aabb0.max.getX() <= aabb1.max.getX())
&& (aabb0.min.getZ() >= aabb1.min.getZ()) && (aabb0.max.getZ() <= aabb1.max.getZ())
&& (aabb0.min.getY() >= aabb1.min.getY()) && (aabb0.max.getY() <= aabb1.max.getY()));
}
public static float ManhattanDistance(AABB aabb0, AABB aabb1) {
// Temp vars from thread local storage
ThreadLocalVars vars = ThreadLocalVars.Get();
Vector3f posA = vars.v3f0;
Vector3f posB = vars.v3f1;
// Calculate position
posA.set(aabb0.min).add(aabb0.max).multiply(.5f);
posB.set(aabb1.min).add(aabb1.max).multiply(.5f);
// Absolute vector between both positions
posA.subtract(posB).abs();
float dist = posA.getX() + posA.getY() + posA.getZ();
// Release vars instance
vars.release();
return dist;
}
public static void Swap(AABB aabb0, AABB aabb1) {
// Temp vars from thread local storage
ThreadLocalVars vars = ThreadLocalVars.Get();
Vector3f swap = vars.v3f0;
// Swap AABBs
swap.set(aabb0.min);
aabb0.min.set(aabb1.min);
aabb1.min.set(swap);
swap.set(aabb0.max);
aabb0.max.set(aabb1.max);
aabb1.max.set(swap);
// Release vars instance
vars.release();
}
public static void Transform(AABB localAabb, Transform4f worldTransform, AABB worldAabb) {
// Temp vars from thread local storage
ThreadLocalVars vars = ThreadLocalVars.Get();
Matrix3f rotationAbsolute = vars.m3f0;
Vector3f localExtent = vars.v3f0;
Vector3f localPosition = vars.v3f1;
Vector3f worldExtent = vars.v3f2;
Vector3f worldPosition = vars.v3f3;
localPosition.set(localAabb.min).add(localAabb.max).multiply(.5f);
worldTransform.multiplyOut(localPosition, worldPosition);
localExtent.set(localAabb.max).subtract(localAabb.min).multiply(.5f);
rotationAbsolute.set(worldTransform.getRotation()).absolute();
worldExtent.set(
rotationAbsolute.dotRow(0, localExtent),
rotationAbsolute.dotRow(1, localExtent),
rotationAbsolute.dotRow(2, localExtent));
worldAabb.max.set(worldPosition).add(worldExtent);
worldAabb.min.set(worldPosition).subtract(worldExtent);
// Release vars instance
vars.release();
}
public static void Transform(AABB localAabb, float margin, Transform4f worldTransform, AABB worldAabb) {
// Temp vars from thread local storage
ThreadLocalVars vars = ThreadLocalVars.Get();
Matrix3f rotationAbsolute = vars.m3f0;
Vector3f localExtent = vars.v3f0;
Vector3f localPosition = vars.v3f1;
Vector3f margins = vars.v3f2;
Vector3f worldExtent = vars.v3f3;
Vector3f worldPosition = vars.v3f4;
localPosition.set(localAabb.min).add(localAabb.max).multiply(.5f);
worldTransform.multiplyOut(localPosition, worldPosition);
margins.set(margin, margin, margin);
localExtent.set(localAabb.max).subtract(localAabb.min).multiply(.5f).add(margins);
rotationAbsolute.set(worldTransform.getRotation()).absolute();
worldExtent.set(
rotationAbsolute.dotRow(0, localExtent),
rotationAbsolute.dotRow(1, localExtent),
rotationAbsolute.dotRow(2, localExtent));
worldAabb.max.set(worldPosition).add(worldExtent);
worldAabb.min.set(worldPosition).subtract(worldExtent);
// Release vars instance
vars.release();
}
}