diff options
Diffstat (limited to 'src/net/java/joglutils/msg/math/PlaneUV.java')
-rw-r--r-- | src/net/java/joglutils/msg/math/PlaneUV.java | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/src/net/java/joglutils/msg/math/PlaneUV.java b/src/net/java/joglutils/msg/math/PlaneUV.java new file mode 100644 index 0000000..5d3a8a2 --- /dev/null +++ b/src/net/java/joglutils/msg/math/PlaneUV.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + */ + +package net.java.joglutils.msg.math; + +/** This differs from the Plane class in that it maintains an origin + and orthonormal U, V axes in the plane so that it can project a 3D + point to a 2D one. U cross V = normal. U and V coordinates are + computed with respect to the origin. */ + +public class PlaneUV { + private Vec3f origin = new Vec3f(); + /** Normalized */ + private Vec3f normal = new Vec3f(); + private Vec3f uAxis = new Vec3f(); + private Vec3f vAxis = new Vec3f(); + + /** Default constructor initializes normal to (0, 1, 0), origin to + (0, 0, 0), U axis to (1, 0, 0) and V axis to (0, 0, -1). */ + public PlaneUV() { + setEverything(new Vec3f(0, 1, 0), + new Vec3f(0, 0, 0), + new Vec3f(1, 0, 0), + new Vec3f(0, 0, -1)); + } + + /** Takes normal vector and a point which the plane goes through + (which becomes the plane's "origin"). Normal does NOT have to be + normalized, but may not be zero vector. U and V axes are + initialized to arbitrary values. */ + public PlaneUV(Vec3f normal, Vec3f origin) { + setOrigin(origin); + setNormal(normal); + } + + /** Takes normal vector, point which plane goes through, and the "u" + axis in the plane. Computes the "v" axis by taking the cross + product of the normal and the u axis. Axis must be perpendicular + to normal. Normal and uAxis do NOT have to be normalized, but + neither may be the zero vector. */ + public PlaneUV(Vec3f normal, + Vec3f origin, + Vec3f uAxis) { + setOrigin(origin); + setNormalAndU(normal, uAxis); + } + + /** Takes normal vector, point which plane goes through, and both + the u and v axes. u axis cross v axis = normal. Normal, uAxis, and + vAxis do NOT have to be normalized, but none may be the zero + vector. */ + public PlaneUV(Vec3f normal, + Vec3f origin, + Vec3f uAxis, + Vec3f vAxis) { + setEverything(normal, origin, uAxis, vAxis); + } + + /** Set the origin, through which this plane goes and with respect + to which U and V coordinates are computed */ + public void setOrigin(Vec3f origin) { + this.origin.set(origin); + } + + public Vec3f getOrigin() { + return new Vec3f(origin); + } + + /** Normal, U and V axes must be orthogonal and satisfy U cross V = + normal, do not need to be unit length but must not be the zero + vector. */ + public void setNormalAndUV(Vec3f normal, + Vec3f uAxis, + Vec3f vAxis) { + setEverything(normal, origin, uAxis, vAxis); + } + + /** This version sets the normal vector and generates new U and V + axes. */ + public void setNormal(Vec3f normal) { + Vec3f uAxis = new Vec3f(); + MathUtil.makePerpendicular(normal, uAxis); + Vec3f vAxis = normal.cross(uAxis); + setEverything(normal, origin, uAxis, vAxis); + } + + /** This version computes the V axis from (normal cross U). */ + public void setNormalAndU(Vec3f normal, + Vec3f uAxis) { + Vec3f vAxis = normal.cross(uAxis); + setEverything(normal, origin, uAxis, vAxis); + } + + /** Normal, U and V axes are normalized internally, so, for example, + <b>normal</b> is not necessarily equal to + <code>plane.setNormal(normal); plane.getNormal();</code> */ + public Vec3f getNormal() { + return normal; + } + + public Vec3f getUAxis() { + return uAxis; + } + + public Vec3f getVAxis() { + return vAxis; + } + + /** Project a point onto the plane */ + public void projectPoint(Vec3f point, + Vec3f projPt, + Vec2f uvCoords) { + // Using projPt as a temporary + projPt.sub(point, origin); + float dotp = normal.dot(projPt); + // Component perpendicular to plane + Vec3f tmpDir = new Vec3f(); + tmpDir.set(normal); + tmpDir.scale(dotp); + projPt.sub(projPt, tmpDir); + // Take dot products with basis vectors + uvCoords.set(projPt.dot(uAxis), + projPt.dot(vAxis)); + // Add on center to intersection point + projPt.add(origin); + } + + /** Intersect a ray with this plane, outputting not only the 3D + intersection point but also the U, V coordinates of the + intersection. Returns true if intersection occurred, false + otherwise. This is a two-sided ray cast. */ + public boolean intersectRay(Vec3f rayStart, + Vec3f rayDirection, + IntersectionPoint intPt, + Vec2f uvCoords) { + float denom = rayDirection.dot(normal); + if (denom == 0.0f) + return false; + Vec3f tmpDir = new Vec3f(); + tmpDir.sub(origin, rayStart); + float t = tmpDir.dot(normal) / denom; + // Find intersection point + Vec3f tmpPt = new Vec3f(); + tmpPt.set(rayDirection); + tmpPt.scale(t); + tmpPt.add(rayStart); + intPt.setIntersectionPoint(tmpPt); + intPt.setT(t); + // Find UV coords + tmpDir.sub(intPt.getIntersectionPoint(), origin); + uvCoords.set(tmpDir.dot(uAxis), tmpDir.dot(vAxis)); + return true; + } + + private void setEverything(Vec3f normal, + Vec3f origin, + Vec3f uAxis, + Vec3f vAxis) { + this.normal.set(normal); + this.origin.set(origin); + this.uAxis.set(uAxis); + this.vAxis.set(vAxis); + this.normal.normalize(); + this.uAxis.normalize(); + this.vAxis.normalize(); + } +} |