summaryrefslogtreecommitdiffstats
path: root/src/gleem/linalg/PlaneUV.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/gleem/linalg/PlaneUV.java')
-rw-r--r--src/gleem/linalg/PlaneUV.java203
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();
+ }
+}