diff options
Diffstat (limited to 'src/gleem/linalg/PlaneUV.java')
-rw-r--r-- | src/gleem/linalg/PlaneUV.java | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/src/gleem/linalg/PlaneUV.java b/src/gleem/linalg/PlaneUV.java new file mode 100644 index 0000000..ff1baad --- /dev/null +++ b/src/gleem/linalg/PlaneUV.java @@ -0,0 +1,203 @@ +/* + * gleem -- OpenGL Extremely Easy-To-Use Manipulators. + * Copyright (C) 1998-2003 Kenneth B. Russell ([email protected]) + * + * Copying, distribution and use of this software in source and binary + * forms, with or without modification, is permitted provided that the + * following conditions are met: + * + * Distributions of source code must reproduce the copyright notice, + * this list of conditions and the following disclaimer in the source + * code header files; and Distributions of binary code must reproduce + * the copyright notice, this list of conditions and the following + * disclaimer in the documentation, Read me file, license file and/or + * other materials provided with the software distribution. + * + * The names of Sun Microsystems, Inc. ("Sun") and/or the copyright + * holder may not 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, NON-INTERFERENCE, ACCURACY OF + * INFORMATIONAL CONTENT OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. THE + * COPYRIGHT HOLDER, SUN AND SUN'S 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 THE + * COPYRIGHT HOLDER, SUN OR SUN'S 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 ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGES. YOU ACKNOWLEDGE THAT THIS SOFTWARE IS NOT + * DESIGNED, LICENSED OR INTENDED FOR USE IN THE DESIGN, CONSTRUCTION, + * OPERATION OR MAINTENANCE OF ANY NUCLEAR FACILITY. THE COPYRIGHT + * HOLDER, SUN AND SUN'S LICENSORS DISCLAIM ANY EXPRESS OR IMPLIED + * WARRANTY OF FITNESS FOR SUCH USES. + */ + +package gleem.linalg; + +/** 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(); + } +} |