summaryrefslogtreecommitdiffstats
path: root/src/net/java/joglutils/msg
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2007-03-18 11:58:01 +0000
committerKenneth Russel <[email protected]>2007-03-18 11:58:01 +0000
commite1f4a731f55ab29e3f23f87102af1b11c67cb0da (patch)
tree244171ec6562416e3c44341c13f903a29ad44c69 /src/net/java/joglutils/msg
parent208b84ae11288b4edd190364528289240303cb5d (diff)
Initial checkin of the Minimal Scene Graph (MSG) library, intentended
for experimentation with both 3D and 2D/3D interaction. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/joglutils/trunk@44 83d24430-9974-4f80-8418-2cc3294053b9
Diffstat (limited to 'src/net/java/joglutils/msg')
-rw-r--r--src/net/java/joglutils/msg/actions/Action.java83
-rw-r--r--src/net/java/joglutils/msg/actions/GLRenderAction.java230
-rw-r--r--src/net/java/joglutils/msg/actions/package.html8
-rw-r--r--src/net/java/joglutils/msg/collections/Vec2fCollection.java155
-rw-r--r--src/net/java/joglutils/msg/collections/Vec3fCollection.java157
-rw-r--r--src/net/java/joglutils/msg/collections/Vec4fCollection.java159
-rw-r--r--src/net/java/joglutils/msg/collections/package.html9
-rw-r--r--src/net/java/joglutils/msg/elements/BlendElement.java139
-rw-r--r--src/net/java/joglutils/msg/elements/ColorElement.java93
-rw-r--r--src/net/java/joglutils/msg/elements/CoordinateElement.java88
-rw-r--r--src/net/java/joglutils/msg/elements/Element.java103
-rw-r--r--src/net/java/joglutils/msg/elements/GLBlendElement.java138
-rw-r--r--src/net/java/joglutils/msg/elements/GLColorElement.java102
-rw-r--r--src/net/java/joglutils/msg/elements/GLCoordinateElement.java99
-rw-r--r--src/net/java/joglutils/msg/elements/GLModelMatrixElement.java97
-rw-r--r--src/net/java/joglutils/msg/elements/GLProjectionMatrixElement.java75
-rw-r--r--src/net/java/joglutils/msg/elements/GLTextureCoordinateElement.java104
-rw-r--r--src/net/java/joglutils/msg/elements/GLTextureElement.java96
-rw-r--r--src/net/java/joglutils/msg/elements/GLViewingMatrixElement.java81
-rw-r--r--src/net/java/joglutils/msg/elements/ModelMatrixElement.java105
-rw-r--r--src/net/java/joglutils/msg/elements/ProjectionMatrixElement.java93
-rw-r--r--src/net/java/joglutils/msg/elements/TextureCoordinateElement.java88
-rw-r--r--src/net/java/joglutils/msg/elements/TextureElement.java101
-rw-r--r--src/net/java/joglutils/msg/elements/ViewingMatrixElement.java93
-rw-r--r--src/net/java/joglutils/msg/elements/package.html18
-rw-r--r--src/net/java/joglutils/msg/impl/BufferFactory.java139
-rw-r--r--src/net/java/joglutils/msg/math/Box3f.java82
-rw-r--r--src/net/java/joglutils/msg/math/DimensionMismatchException.java51
-rw-r--r--src/net/java/joglutils/msg/math/IntersectionPoint.java61
-rw-r--r--src/net/java/joglutils/msg/math/Line.java150
-rw-r--r--src/net/java/joglutils/msg/math/Mat2f.java167
-rw-r--r--src/net/java/joglutils/msg/math/Mat3f.java191
-rw-r--r--src/net/java/joglutils/msg/math/Mat4f.java574
-rw-r--r--src/net/java/joglutils/msg/math/Matf.java166
-rw-r--r--src/net/java/joglutils/msg/math/MathUtil.java88
-rw-r--r--src/net/java/joglutils/msg/math/NonSquareMatrixException.java51
-rw-r--r--src/net/java/joglutils/msg/math/Plane.java119
-rw-r--r--src/net/java/joglutils/msg/math/PlaneUV.java201
-rw-r--r--src/net/java/joglutils/msg/math/Rotf.java309
-rw-r--r--src/net/java/joglutils/msg/math/SingularMatrixException.java51
-rw-r--r--src/net/java/joglutils/msg/math/Sphere.java183
-rw-r--r--src/net/java/joglutils/msg/math/Vec2f.java184
-rw-r--r--src/net/java/joglutils/msg/math/Vec3d.java206
-rw-r--r--src/net/java/joglutils/msg/math/Vec3f.java230
-rw-r--r--src/net/java/joglutils/msg/math/Vec4f.java214
-rw-r--r--src/net/java/joglutils/msg/math/Vecf.java94
-rw-r--r--src/net/java/joglutils/msg/math/Veci.java94
-rw-r--r--src/net/java/joglutils/msg/math/package.html8
-rw-r--r--src/net/java/joglutils/msg/misc/State.java220
-rw-r--r--src/net/java/joglutils/msg/misc/StateIndex.java56
-rw-r--r--src/net/java/joglutils/msg/misc/SystemTime.java108
-rw-r--r--src/net/java/joglutils/msg/misc/Time.java50
-rw-r--r--src/net/java/joglutils/msg/misc/package.html10
-rw-r--r--src/net/java/joglutils/msg/nodes/Blend.java168
-rw-r--r--src/net/java/joglutils/msg/nodes/Camera.java126
-rw-r--r--src/net/java/joglutils/msg/nodes/Color4.java95
-rw-r--r--src/net/java/joglutils/msg/nodes/Coordinate3.java62
-rw-r--r--src/net/java/joglutils/msg/nodes/Group.java124
-rw-r--r--src/net/java/joglutils/msg/nodes/IndexedTriangleSet.java67
-rw-r--r--src/net/java/joglutils/msg/nodes/Node.java52
-rw-r--r--src/net/java/joglutils/msg/nodes/PerspectiveCamera.java97
-rw-r--r--src/net/java/joglutils/msg/nodes/Separator.java52
-rw-r--r--src/net/java/joglutils/msg/nodes/Texture2.java139
-rw-r--r--src/net/java/joglutils/msg/nodes/TextureCoordinate2.java62
-rw-r--r--src/net/java/joglutils/msg/nodes/Transform.java66
-rw-r--r--src/net/java/joglutils/msg/nodes/TriangleSet.java62
-rw-r--r--src/net/java/joglutils/msg/nodes/package.html8
-rw-r--r--src/net/java/joglutils/msg/overview.html50
-rw-r--r--src/net/java/joglutils/msg/test/DisplayShelf.java433
-rw-r--r--src/net/java/joglutils/msg/test/Test.java150
-rw-r--r--src/net/java/joglutils/msg/test/package.html8
71 files changed, 8392 insertions, 0 deletions
diff --git a/src/net/java/joglutils/msg/actions/Action.java b/src/net/java/joglutils/msg/actions/Action.java
new file mode 100644
index 0000000..21ca2bc
--- /dev/null
+++ b/src/net/java/joglutils/msg/actions/Action.java
@@ -0,0 +1,83 @@
+/*
+ * 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.actions;
+
+import net.java.joglutils.msg.misc.*;
+import net.java.joglutils.msg.nodes.*;
+
+/** The base class of all actions, which are applied to nodes in the
+ scene graph to implement operations such as rendering. <P>
+
+ Subclasses of Action should define, by convention, a public static
+ method <CODE>getDefaultState</CODE>, returning a {@link
+ net.java.joglutils.msg.misc.State State} object, which is used to
+ enable the elements in the state which should be updated by the
+ action's traversal of nodes. Each Action instance maintains a
+ State object internally which is initialized from this
+ default. Note that different actions may enable different elements
+ of the global state.
+*/
+
+public abstract class Action {
+
+ /** Applies this Action to a particular node. This is how operations
+ such as rendering are initiated. */
+ public void apply(Node node) {
+ node.doAction(this);
+ }
+
+ /** Returns the global state this action encompasses, which is
+ altered by the nodes the action traverses. */
+ public abstract State getState();
+
+ // Visitor methods, one per node class
+
+ // FIXME: should rethink this mechanism and make it extensible as
+ // per the original Open Inventor
+ public abstract void visit (Blend blend);
+ public abstract void visit (Color4 colors);
+ public abstract void visit (Coordinate3 coords);
+ public abstract void visit (IndexedTriangleSet tris);
+ public abstract void visit (PerspectiveCamera camera);
+ public abstract void visitPre (Separator sep);
+ public abstract void visitPost(Separator sep);
+ public abstract void visit (Texture2 texture);
+ public abstract void visit (TextureCoordinate2 texCoords);
+ public abstract void visit (Transform transform);
+ public abstract void visit (TriangleSet tris);
+}
diff --git a/src/net/java/joglutils/msg/actions/GLRenderAction.java b/src/net/java/joglutils/msg/actions/GLRenderAction.java
new file mode 100644
index 0000000..2274af1
--- /dev/null
+++ b/src/net/java/joglutils/msg/actions/GLRenderAction.java
@@ -0,0 +1,230 @@
+/*
+ * 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.actions;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import com.sun.opengl.util.texture.*;
+
+import net.java.joglutils.msg.elements.*;
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+import net.java.joglutils.msg.nodes.*;
+
+/** An action which performs rendering of a scene graph via OpenGL. <P>
+
+ When applied to the root of the scene graph, this action does not
+ perform any clearing of the color or depth buffer; this is the
+ responsibility of the caller. The render action pushes, pops, and
+ initializes enough OpenGL state to isolate itself, at least in
+ theory, from any surrounding OpenGL state that the application may
+ have set up. There should in theory be no user-visible OpenGL side
+ effects as a result of rendering with this action.
+*/
+
+public class GLRenderAction extends Action {
+ // Boilerplate
+ private static State defaults = new State();
+ /** Returns the default state all instances of this class are initialized with. */
+ public static State getDefaultState() {
+ return defaults;
+ }
+
+ private State state = new State(defaults);
+ public State getState() {
+ return state;
+ }
+
+ static {
+ // FIXME: may need to rethink when and where these elements are enabled
+
+ // In Open Inventor, this is folded into the node's initialization
+ // (i.e., the node needs to know which elements it might affect).
+ // That in theory allows for fewer elements to be enabled, but it
+ // isn't clear that this makes a difference, or that it results in
+ // correct code elsewhere where certain elements implicitly expect
+ // others to be enabled.
+ GLBlendElement .enable(getDefaultState());
+ GLColorElement .enable(getDefaultState());
+ GLCoordinateElement .enable(getDefaultState());
+ GLModelMatrixElement .enable(getDefaultState());
+ GLProjectionMatrixElement .enable(getDefaultState());
+ GLViewingMatrixElement .enable(getDefaultState());
+ GLTextureCoordinateElement.enable(getDefaultState());
+ GLTextureElement .enable(getDefaultState());
+ }
+
+ // For automatically setting the aspect ratios of cameras we encounter
+ private float curAspectRatio = 1.0f;
+
+ private int applyDepth = 0;
+
+ public void apply(Node node) {
+ GL gl = GLU.getCurrentGL();
+ int depth = applyDepth++;
+ try {
+ if (depth == 0) {
+ // Applying to the root of the scene graph
+ // Push necessary GL state
+ // FIXME: add in additional bits as we add more capabilities
+ gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_CURRENT_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_TRANSFORM_BIT);
+ gl.glEnable(GL.GL_DEPTH_TEST);
+ gl.glColor4f(1, 1, 1, 1);
+ gl.glMatrixMode(GL.GL_TEXTURE);
+ gl.glLoadIdentity();
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glPushClientAttrib(GL.GL_CLIENT_VERTEX_ARRAY_BIT);
+ // Figure out the aspect ratio of the current viewport
+ int[] viewport = new int[4];
+ gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
+ curAspectRatio = (float) viewport[2] / (float) viewport[3];
+ }
+ super.apply(node);
+ } finally {
+ if (depth == 0) {
+ gl.glPopClientAttrib();
+ gl.glPopAttrib();
+ }
+ --applyDepth;
+ }
+ }
+
+ public void visit(Blend blend) {
+ GLBlendElement.set(state,
+ blend.getEnabled(),
+ blend.getBlendColor(),
+ blend.getSourceFunc(),
+ blend.getDestFunc(),
+ blend.getBlendEquation());
+ }
+
+ public void visit(Color4 colors) {
+ GLColorElement.set(state, colors.getData().getData());
+ }
+
+ public void visit(Coordinate3 coords) {
+ GLCoordinateElement.set(state, coords.getData().getData());
+ }
+
+ public void visit(IndexedTriangleSet tris) {
+ throw new RuntimeException("Not yet implemented");
+ }
+
+ public void visit(PerspectiveCamera camera) {
+ // FIXME: unclear whether we should be doing this, or whether we
+ // should have a mechanism which doesn't require mutation of the
+ // camera
+ camera.setAspectRatio(curAspectRatio);
+
+ GLViewingMatrixElement.set(state, camera.getViewingMatrix());
+ GLProjectionMatrixElement.set(state, camera.getProjectionMatrix());
+ }
+
+ public void visitPre(Separator sep) {
+ state.push();
+ }
+
+ public void visitPost(Separator sep) {
+ state.pop();
+ }
+
+ public void visit(Texture2 texture) {
+ GLTextureElement.set(state, texture.getTexture(), texture.getTexEnvMode());
+ }
+
+ public void visit(TextureCoordinate2 texCoords) {
+ GLTextureCoordinateElement.set(state, texCoords.getData().getData());
+ }
+
+ public void visit(Transform transform) {
+ GLModelMatrixElement.mult(state, transform.getTransform());
+ }
+
+ public void visit(TriangleSet tris) {
+ if (CoordinateElement.get(state) != null) {
+ // OK, we have coordinates to send down, at least
+
+ GL gl = GLU.getCurrentGL();
+
+ Texture tex = GLTextureElement.get(state);
+ boolean haveTexCoords = (GLTextureCoordinateElement.get(state) != null);
+
+ if (tex != null) {
+ // Set up the texture matrix to uniformly map [0..1] to the used
+ // portion of the texture image
+ gl.glMatrixMode(GL.GL_TEXTURE);
+ gl.glPushMatrix();
+ gl.glLoadTransposeMatrixf(getTextureMatrix(tex).getRowMajorData(), 0);
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ } else if (haveTexCoords) {
+ // Want to turn off the use of texture coordinates to avoid errors
+ // FIXME: not 100% sure whether we need to do this, but think we should
+ gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+ }
+
+ // For now, assume the triangle set and the number of available
+ // coordinates match -- may want to add debugging information
+ // for this later
+ gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3 * tris.getNumTriangles());
+
+ if (tex != null) {
+ gl.glMatrixMode(GL.GL_TEXTURE);
+ gl.glPopMatrix();
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ } else if (haveTexCoords) {
+ // Might want this the next time we render a shape
+ gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+ }
+
+ private Mat4f textureMatrix = new Mat4f();
+ private Mat4f getTextureMatrix(Texture texture) {
+ textureMatrix.makeIdent();
+ TextureCoords coords = texture.getImageTexCoords();
+ // Horizontal scale
+ textureMatrix.set(0, 0, coords.right() - coords.left());
+ // Vertical scale (may be negative if texture needs to be flipped vertically)
+ float vertScale = coords.top() - coords.bottom();
+ textureMatrix.set(1, 1, vertScale);
+ textureMatrix.set(0, 3, coords.left());
+ textureMatrix.set(1, 3, coords.bottom());
+ return textureMatrix;
+ }
+}
diff --git a/src/net/java/joglutils/msg/actions/package.html b/src/net/java/joglutils/msg/actions/package.html
new file mode 100644
index 0000000..a07291e
--- /dev/null
+++ b/src/net/java/joglutils/msg/actions/package.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<body>
+
+Actions which are applied to nodes to implement operations such as rendering.
+
+</body>
+</html>
diff --git a/src/net/java/joglutils/msg/collections/Vec2fCollection.java b/src/net/java/joglutils/msg/collections/Vec2fCollection.java
new file mode 100644
index 0000000..a5ad3d3
--- /dev/null
+++ b/src/net/java/joglutils/msg/collections/Vec2fCollection.java
@@ -0,0 +1,155 @@
+/*
+ * 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.collections;
+
+import java.nio.*;
+
+import com.sun.opengl.util.*;
+
+import net.java.joglutils.msg.impl.*;
+import net.java.joglutils.msg.math.*;
+
+/** Provides the abstraction of a collection of Vec2f objects while
+ allowing access to the backing store in the form of a direct
+ FloatBuffer to make it easy to pass down to OpenGL. */
+
+public class Vec2fCollection {
+ // Data is stored as a direct FloatBuffer
+ private FloatBuffer data;
+
+ private static final int ELEMENT_SIZE = 2;
+
+ /** Creates an empty Vec2fCollection. */
+ public Vec2fCollection() {
+ // Assume you'll probably want at least four vertices
+ this(4);
+ }
+
+ /** Creates an empty Vec2fCollection with the backing store sized to
+ hold roughly the given number of vectors. */
+ public Vec2fCollection(int estimatedSize) {
+ data = BufferFactory.newFloatBuffer(ELEMENT_SIZE * estimatedSize);
+ data.limit(0);
+ }
+
+ /** Returns the number of Vec2fs currently in this collection. */
+ public int size() {
+ return data.limit() / ELEMENT_SIZE;
+ }
+
+ /** Stores the given Vec2f at the given index. If the collection has
+ not grown to the given size, throws an exception. */
+ public void set(int index, Vec2f value) throws IndexOutOfBoundsException {
+ if (index >= size()) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + size());
+ }
+ int base = index * ELEMENT_SIZE;
+ FloatBuffer buf = data;
+ buf.put(base, value.x());
+ buf.put(base + 1, value.y());
+ }
+
+ /** Fetches the Vec2f at the given index. If the collection has not
+ grown to the given size, throws an exception. */
+ public Vec2f get(int index) throws IndexOutOfBoundsException {
+ if (index >= size()) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + size());
+ }
+ int base = index * ELEMENT_SIZE;
+ // Note: could use a small pool of Vec2fs here if allocation rate
+ // is an issue. However, escape analysis should eventually take
+ // care of this.
+ FloatBuffer buf = data;
+ return new Vec2f(buf.get(base), buf.get(base + 1));
+ }
+
+ /** Adds the given Vec2f to this collection, expanding it if
+ necessary. */
+ public void add(Vec2f value) {
+ FloatBuffer buf = data;
+ if (buf.limit() == buf.capacity()) {
+ FloatBuffer newBuf = BufferUtil.newFloatBuffer(Math.max(buf.capacity() + ELEMENT_SIZE,
+ round((int) (buf.capacity() * 1.5f))));
+ newBuf.put(buf);
+ newBuf.limit(buf.limit());
+ data = newBuf;
+ buf = newBuf;
+ }
+ int pos = buf.limit();
+ buf.limit(pos + ELEMENT_SIZE);
+ buf.put(pos, value.x());
+ buf.put(pos + 1, value.y());
+ }
+
+ /** Removes the given Vec2f from this collection. Moves all Vec2fs
+ above it down one slot. */
+ public Vec2f remove(int index) throws IndexOutOfBoundsException {
+ if (index >= size()) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + size());
+ }
+ FloatBuffer buf = data;
+ int pos = index * ELEMENT_SIZE;
+ Vec2f res = new Vec2f(buf.get(pos), buf.get(pos + 1));
+ if (index == size() - 1) {
+ // Simply lower the limit
+ buf.limit(buf.limit() - ELEMENT_SIZE);
+ } else {
+ buf.position(pos + 1);
+ FloatBuffer rest = buf.slice();
+ buf.position(pos);
+ buf.put(rest);
+ buf.limit(buf.limit() - ELEMENT_SIZE);
+ }
+ return res;
+ }
+
+ /** Returns the backing buffer of this collection. */
+ public FloatBuffer getData() {
+ FloatBuffer buf = data;
+ buf.position(0);
+ return buf.slice();
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static int round(int size) {
+ return size - (size % ELEMENT_SIZE);
+ }
+}
diff --git a/src/net/java/joglutils/msg/collections/Vec3fCollection.java b/src/net/java/joglutils/msg/collections/Vec3fCollection.java
new file mode 100644
index 0000000..698017d
--- /dev/null
+++ b/src/net/java/joglutils/msg/collections/Vec3fCollection.java
@@ -0,0 +1,157 @@
+/*
+ * 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.collections;
+
+import java.nio.*;
+
+import com.sun.opengl.util.*;
+
+import net.java.joglutils.msg.impl.*;
+import net.java.joglutils.msg.math.*;
+
+/** Provides the abstraction of a collection of Vec3f objects while
+ allowing access to the backing store in the form of a direct
+ FloatBuffer to make it easy to pass down to OpenGL. */
+
+public class Vec3fCollection {
+ // Data is stored as a direct FloatBuffer
+ private FloatBuffer data;
+
+ private static final int ELEMENT_SIZE = 3;
+
+ /** Creates an empty Vec3fCollection. */
+ public Vec3fCollection() {
+ // Assume you'll probably want at least four vertices
+ this(4);
+ }
+
+ /** Creates an empty Vec3fCollection with the backing store sized to
+ hold roughly the given number of vectors. */
+ public Vec3fCollection(int estimatedSize) {
+ data = BufferFactory.newFloatBuffer(ELEMENT_SIZE * estimatedSize);
+ data.limit(0);
+ }
+
+ /** Returns the number of Vec3fs currently in this collection. */
+ public int size() {
+ return data.limit() / ELEMENT_SIZE;
+ }
+
+ /** Stores the given Vec3f at the given index. If the collection has
+ not grown to the given size, throws an exception. */
+ public void set(int index, Vec3f value) throws IndexOutOfBoundsException {
+ if (index >= size()) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + size());
+ }
+ int base = index * ELEMENT_SIZE;
+ FloatBuffer buf = data;
+ buf.put(base, value.x());
+ buf.put(base + 1, value.y());
+ buf.put(base + 2, value.z());
+ }
+
+ /** Fetches the Vec3f at the given index. If the collection has not
+ grown to the given size, throws an exception. */
+ public Vec3f get(int index) throws IndexOutOfBoundsException {
+ if (index >= size()) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + size());
+ }
+ int base = index * ELEMENT_SIZE;
+ // Note: could use a small pool of Vec3fs here if allocation rate
+ // is an issue. However, escape analysis should eventually take
+ // care of this.
+ FloatBuffer buf = data;
+ return new Vec3f(buf.get(base), buf.get(base + 1), buf.get(base + 2));
+ }
+
+ /** Adds the given Vec3f to this collection, expanding it if
+ necessary. */
+ public void add(Vec3f value) {
+ FloatBuffer buf = data;
+ if (buf.limit() == buf.capacity()) {
+ FloatBuffer newBuf = BufferUtil.newFloatBuffer(Math.max(buf.capacity() + ELEMENT_SIZE,
+ round((int) (buf.capacity() * 1.5f))));
+ newBuf.put(buf);
+ newBuf.limit(buf.limit());
+ data = newBuf;
+ buf = newBuf;
+ }
+ int pos = buf.limit();
+ buf.limit(pos + ELEMENT_SIZE);
+ buf.put(pos, value.x());
+ buf.put(pos + 1, value.y());
+ buf.put(pos + 2, value.z());
+ }
+
+ /** Removes the given Vec3f from this collection. Moves all Vec3fs
+ above it down one slot. */
+ public Vec3f remove(int index) throws IndexOutOfBoundsException {
+ if (index >= size()) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + size());
+ }
+ FloatBuffer buf = data;
+ int pos = index * ELEMENT_SIZE;
+ Vec3f res = new Vec3f(buf.get(pos), buf.get(pos + 1), buf.get(pos + 2));
+ if (index == size() - 1) {
+ // Simply lower the limit
+ buf.limit(buf.limit() - ELEMENT_SIZE);
+ } else {
+ buf.position(pos + 1);
+ FloatBuffer rest = buf.slice();
+ buf.position(pos);
+ buf.put(rest);
+ buf.limit(buf.limit() - ELEMENT_SIZE);
+ }
+ return res;
+ }
+
+ /** Returns the backing buffer of this collection. */
+ public FloatBuffer getData() {
+ FloatBuffer buf = data;
+ buf.position(0);
+ return buf.slice();
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static int round(int size) {
+ return size - (size % ELEMENT_SIZE);
+ }
+}
diff --git a/src/net/java/joglutils/msg/collections/Vec4fCollection.java b/src/net/java/joglutils/msg/collections/Vec4fCollection.java
new file mode 100644
index 0000000..a1d1e86
--- /dev/null
+++ b/src/net/java/joglutils/msg/collections/Vec4fCollection.java
@@ -0,0 +1,159 @@
+/*
+ * 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.collections;
+
+import java.nio.*;
+
+import com.sun.opengl.util.*;
+
+import net.java.joglutils.msg.impl.*;
+import net.java.joglutils.msg.math.*;
+
+/** Provides the abstraction of a collection of Vec4f objects while
+ allowing access to the backing store in the form of a direct
+ FloatBuffer to make it easy to pass down to OpenGL. */
+
+public class Vec4fCollection {
+ // Data is stored as a direct FloatBuffer
+ private FloatBuffer data;
+
+ private static final int ELEMENT_SIZE = 4;
+
+ /** Creates an empty Vec4fCollection. */
+ public Vec4fCollection() {
+ // Assume you'll probably want at least four vertices
+ this(4);
+ }
+
+ /** Creates an empty Vec4fCollection with the backing store sized to
+ hold roughly the given number of vectors. */
+ public Vec4fCollection(int estimatedSize) {
+ data = BufferFactory.newFloatBuffer(ELEMENT_SIZE * estimatedSize);
+ data.limit(0);
+ }
+
+ /** Returns the number of Vec4fs currently in this collection. */
+ public int size() {
+ return data.limit() / ELEMENT_SIZE;
+ }
+
+ /** Stores the given Vec4f at the given index. If the collection has
+ not grown to the given size, throws an exception. */
+ public void set(int index, Vec4f value) throws IndexOutOfBoundsException {
+ if (index >= size()) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + size());
+ }
+ int base = index * ELEMENT_SIZE;
+ FloatBuffer buf = data;
+ buf.put(base, value.x());
+ buf.put(base + 1, value.y());
+ buf.put(base + 2, value.z());
+ buf.put(base + 3, value.w());
+ }
+
+ /** Fetches the Vec4f at the given index. If the collection has not
+ grown to the given size, throws an exception. */
+ public Vec4f get(int index) throws IndexOutOfBoundsException {
+ if (index >= size()) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + size());
+ }
+ int base = index * ELEMENT_SIZE;
+ // Note: could use a small pool of Vec4fs here if allocation rate
+ // is an issue. However, escape analysis should eventually take
+ // care of this.
+ FloatBuffer buf = data;
+ return new Vec4f(buf.get(base), buf.get(base + 1), buf.get(base + 2), buf.get(base + 3));
+ }
+
+ /** Adds the given Vec4f to this collection, expanding it if
+ necessary. */
+ public void add(Vec4f value) {
+ FloatBuffer buf = data;
+ if (buf.limit() == buf.capacity()) {
+ FloatBuffer newBuf = BufferUtil.newFloatBuffer(Math.max(buf.capacity() + ELEMENT_SIZE,
+ round((int) (buf.capacity() * 1.5f))));
+ newBuf.put(buf);
+ newBuf.limit(buf.limit());
+ data = newBuf;
+ buf = newBuf;
+ }
+ int pos = buf.limit();
+ buf.limit(pos + ELEMENT_SIZE);
+ buf.put(pos, value.x());
+ buf.put(pos + 1, value.y());
+ buf.put(pos + 2, value.z());
+ buf.put(pos + 3, value.w());
+ }
+
+ /** Removes the given Vec4f from this collection. Moves all Vec4fs
+ above it down one slot. */
+ public Vec4f remove(int index) throws IndexOutOfBoundsException {
+ if (index >= size()) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + size());
+ }
+ FloatBuffer buf = data;
+ int pos = index * ELEMENT_SIZE;
+ Vec4f res = new Vec4f(buf.get(pos), buf.get(pos + 1), buf.get(pos + 2), buf.get(pos + 3));
+ if (index == size() - 1) {
+ // Simply lower the limit
+ buf.limit(buf.limit() - ELEMENT_SIZE);
+ } else {
+ buf.position(pos + 1);
+ FloatBuffer rest = buf.slice();
+ buf.position(pos);
+ buf.put(rest);
+ buf.limit(buf.limit() - ELEMENT_SIZE);
+ }
+ return res;
+ }
+
+ /** Returns the backing buffer of this collection. */
+ public FloatBuffer getData() {
+ FloatBuffer buf = data;
+ buf.position(0);
+ return buf.slice();
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static int round(int size) {
+ return size - (size % ELEMENT_SIZE);
+ }
+}
diff --git a/src/net/java/joglutils/msg/collections/package.html b/src/net/java/joglutils/msg/collections/package.html
new file mode 100644
index 0000000..e917f3d
--- /dev/null
+++ b/src/net/java/joglutils/msg/collections/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<body>
+
+Collection classes for storing vector data in formats which can be
+quickly sent down to OpenGL.
+
+</body>
+</html>
diff --git a/src/net/java/joglutils/msg/elements/BlendElement.java b/src/net/java/joglutils/msg/elements/BlendElement.java
new file mode 100644
index 0000000..2a0d488
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/BlendElement.java
@@ -0,0 +1,139 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+import net.java.joglutils.msg.nodes.*;
+
+/** Represents the blending state of the OpenGL fixed-function pipeline. */
+
+public class BlendElement extends Element {
+ // Boilerplate
+ private static StateIndex index = State.registerElementType();
+ public StateIndex getStateIndex() { return index; }
+ public Element newInstance() {
+ return new BlendElement();
+ }
+ /** Returns the instance of this element in the passed State. */
+ public static BlendElement getInstance(State state) {
+ return (BlendElement) state.getElement(index);
+ }
+ /** Enables this element in the passed state, which should be the
+ default for a given action. */
+ public static void enable(State defaultState) {
+ BlendElement tmp = new BlendElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // These defaults match those in the Blend node -- is there a better way of factoring them out?
+
+ // Whether blending is enabled
+ protected boolean enabled;
+ protected Vec4f blendColor = new Vec4f();
+ protected int srcFunc = Blend.ONE;
+ protected int destFunc = Blend.ZERO;
+ protected int blendEquation = Blend.FUNC_ADD;
+
+ /** Sets all of the portions of the blending state in the passed State object. */
+ public static void set(State state,
+ boolean enabled,
+ Vec4f blendColor,
+ int srcFunc,
+ int destFunc,
+ int blendEquation) {
+ getInstance(state).setElt(enabled,
+ blendColor,
+ srcFunc,
+ destFunc,
+ blendEquation);
+ }
+
+ /** Returns whether blending is enabled. */
+ public static boolean getEnabled(State state) {
+ return getInstance(state).enabled;
+ }
+
+ /** Returns the blending color. */
+ public static Vec4f getBlendColor(State state) {
+ return getInstance(state).blendColor;
+ }
+
+ /** Returns the source function for blending. */
+ public static int getSourceFunc(State state) {
+ return getInstance(state).srcFunc;
+ }
+
+ /** Returns the destination function for blending. */
+ public static int getDestFunc(State state) {
+ return getInstance(state).destFunc;
+ }
+
+ /** Returns the blending equation. */
+ public static int getBlendEquation(State state) {
+ return getInstance(state).blendEquation;
+ }
+
+ public void push(State state) {
+ BlendElement prev = (BlendElement) getNextInStack();
+ if (prev != null) {
+ // Pull down the data from the previous element
+ enabled = prev.enabled;
+ blendColor.set(prev.blendColor);
+ srcFunc = prev.srcFunc;
+ destFunc = prev.destFunc;
+ blendEquation = prev.blendEquation;
+ }
+ }
+
+ /** Sets all of the portions of the blending state in this element. */
+ public void setElt(boolean enabled,
+ Vec4f blendColor,
+ int srcFunc,
+ int destFunc,
+ int blendEquation) {
+ this.enabled = enabled;
+ this.blendColor.set(blendColor);
+ this.srcFunc = srcFunc;
+ this.destFunc = destFunc;
+ this.blendEquation = blendEquation;
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/ColorElement.java b/src/net/java/joglutils/msg/elements/ColorElement.java
new file mode 100644
index 0000000..a725d61
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/ColorElement.java
@@ -0,0 +1,93 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the current set of colors, which are applied on a
+ per-vertex basis to any drawn geometry. */
+
+public class ColorElement extends Element {
+ // Boilerplate
+ private static StateIndex index = State.registerElementType();
+ public StateIndex getStateIndex() { return index; }
+ public Element newInstance() {
+ return new ColorElement();
+ }
+ /** Returns the instance of this element in the passed State. */
+ public static ColorElement getInstance(State state) {
+ return (ColorElement) state.getElement(index);
+ }
+ /** Enables this element in the passed state, which should be the
+ default for a given action. */
+ public static void enable(State defaultState) {
+ ColorElement tmp = new ColorElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // The actual color data
+ protected FloatBuffer colors;
+ // The color binding to material parameter (not yet implemented)
+ protected int colorBinding;
+
+ /** Sets the color data in the passed state. */
+ public static void set(State state, FloatBuffer colors) {
+ getInstance(state).setElt(colors);
+ }
+
+ /** Returns the color data in the passed state. */
+ public static FloatBuffer get(State state) {
+ return getInstance(state).colors;
+ }
+
+ public void push(State state) {
+ ColorElement prev = (ColorElement) getNextInStack();
+ if (prev != null) {
+ // Pull down the data from the previous element
+ colors = prev.colors;
+ }
+ }
+
+ /** Sets the color data in this element. */
+ public void setElt(FloatBuffer colors) {
+ this.colors = colors;
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/CoordinateElement.java b/src/net/java/joglutils/msg/elements/CoordinateElement.java
new file mode 100644
index 0000000..34b16bc
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/CoordinateElement.java
@@ -0,0 +1,88 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the current set of coordinates, which are assembled to
+ draw geometry. */
+
+public class CoordinateElement extends Element {
+ // Boilerplate
+ private static StateIndex index = State.registerElementType();
+ public StateIndex getStateIndex() { return index; }
+ public Element newInstance() {
+ return new CoordinateElement();
+ }
+ public static CoordinateElement getInstance(State state) {
+ return (CoordinateElement) state.getElement(index);
+ }
+ public static void enable(State defaultState) {
+ CoordinateElement tmp = new CoordinateElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // The actual coordinate data
+ protected FloatBuffer coords;
+
+ /** Sets the coordinate data in the passed state. */
+ public static void set(State state, FloatBuffer coords) {
+ getInstance(state).setElt(coords);
+ }
+
+ /** Returns the coordinate data in the passed state. */
+ public static FloatBuffer get(State state) {
+ return getInstance(state).coords;
+ }
+
+ public void push(State state) {
+ CoordinateElement prev = (CoordinateElement) getNextInStack();
+ if (prev != null) {
+ // Pull down the data from the previous element
+ coords = prev.coords;
+ }
+ }
+
+ /** Sets the coordinate data in this element. */
+ public void setElt(FloatBuffer coords) {
+ this.coords = coords;
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/Element.java b/src/net/java/joglutils/msg/elements/Element.java
new file mode 100644
index 0000000..5937b65
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/Element.java
@@ -0,0 +1,103 @@
+/*
+ * 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.elements;
+
+import net.java.joglutils.msg.misc.*;
+
+/** Represents an element in the global {@link
+ net.java.joglutils.msg.misc.State state}, such as the current 3D
+ coordinates or texture to be applied. The organization of the
+ global state into elements is one of the key mechanisms for
+ extendability of the library which was pioneered by Open Inventor.
+*/
+
+public abstract class Element {
+ // Elements are organized into stacks. When we descend past (for
+ // example) a Separator node, we need to push all of the state
+ // elements, traverse the children, and then pop the state elements
+ // so afterward we restore the original state. This is implemented
+ // in the State class using a linked list of Elements, where the
+ // State keeps track of the top of each element stack.
+ private Element nextInStack;
+
+ // Additionally we maintain a linked list through all Element
+ // instances pushed and popped in the State, so that we don't have
+ // to traverse all Element slots when performing a state pop.
+ private Element next;
+
+ // Elements need to keep track of their depth in the stack in order
+ // for the State to maintain itself
+ private int depth;
+
+ protected Element() {}
+
+ /** Creates a new instance initialized to the default values for the
+ state element. All concrete Element subclasses must implement
+ this operation. */
+ public abstract Element newInstance();
+
+ /** Returns the next element in the stack. */
+ public Element getNextInStack() { return nextInStack; }
+ /** Sets the next element in the stack. */
+ public void setNextInStack(Element nextInStack) { this.nextInStack = nextInStack; }
+
+ /** Returns the next element in the linked list of elements which
+ were modified since the last state push. */
+ public Element getNext() { return next; }
+ /** Sets the next element in the linked list of elements which were
+ modified since the last state push. */
+ public void setNext(Element next) { this.next = next; }
+
+ /** Returns the depth of this element in its stack, used to implement lazy state pushing. */
+ public int getDepth() { return depth; }
+ /** Sets the depth of this element in its stack, used to implement lazy state pushing. */
+ public void setDepth(int depth) { this.depth = depth; }
+
+ /** Pushes the element, allowing for side effects to occur. Default method does nothing. */
+ public void push(State state) {}
+ /** Pops the element, allowing for side effects to occur. Default
+ method does nothing. NOTE that it is not legal to call
+ State.getElement() in the implementation of this method, which
+ is why the previous top element is provided as an argument. */
+ public void pop (State state, Element previousTopElement) {}
+
+ /** All concrete element subclasses must register themselves with
+ the State in order to reserve a slot, or index, in the
+ state. This method must be overridden to return this slot. */
+ public abstract StateIndex getStateIndex();
+}
diff --git a/src/net/java/joglutils/msg/elements/GLBlendElement.java b/src/net/java/joglutils/msg/elements/GLBlendElement.java
new file mode 100644
index 0000000..7955533
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/GLBlendElement.java
@@ -0,0 +1,138 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+import net.java.joglutils.msg.nodes.*;
+
+/** Represents the blending state of the OpenGL fixed-function
+ pipeline and causes side-effects in OpenGL for rendering. */
+
+public class GLBlendElement extends BlendElement {
+ // Boilerplate for concrete element subclasses
+ public Element newInstance() {
+ return new GLBlendElement();
+ }
+ public static GLBlendElement getInstance(State state) {
+ return (GLBlendElement) BlendElement.getInstance(state);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new GLBlendElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ public void pop(State state, Element previousTopElement) {
+ send();
+ }
+
+ public void setElt(boolean enabled,
+ Vec4f blendColor,
+ int srcFunc,
+ int destFunc,
+ int blendEquation) {
+ super.setElt(enabled, blendColor, srcFunc, destFunc, blendEquation);
+ send();
+ }
+
+ private static int oglBlendFunc(int func) {
+ switch (func) {
+ case Blend.ZERO: return GL.GL_ZERO;
+ case Blend.ONE: return GL.GL_ONE;
+ case Blend.SRC_COLOR: return GL.GL_SRC_COLOR;
+ case Blend.ONE_MINUS_SRC_COLOR: return GL.GL_ONE_MINUS_SRC_COLOR;
+ case Blend.DST_COLOR: return GL.GL_DST_COLOR;
+ case Blend.ONE_MINUS_DST_COLOR: return GL.GL_ONE_MINUS_DST_COLOR;
+ case Blend.SRC_ALPHA: return GL.GL_SRC_ALPHA;
+ case Blend.ONE_MINUS_SRC_ALPHA: return GL.GL_ONE_MINUS_SRC_ALPHA;
+ case Blend.DST_ALPHA: return GL.GL_DST_ALPHA;
+ case Blend.ONE_MINUS_DST_ALPHA: return GL.GL_ONE_MINUS_DST_ALPHA;
+ case Blend.SRC_ALPHA_SATURATE: return GL.GL_SRC_ALPHA_SATURATE;
+ case Blend.CONSTANT_COLOR: return GL.GL_CONSTANT_COLOR;
+ case Blend.ONE_MINUS_CONSTANT_COLOR: return GL.GL_ONE_MINUS_CONSTANT_COLOR;
+ case Blend.CONSTANT_ALPHA: return GL.GL_CONSTANT_ALPHA;
+ case Blend.ONE_MINUS_CONSTANT_ALPHA: return GL.GL_ONE_MINUS_CONSTANT_ALPHA;
+ }
+ throw new InternalError("Illegal blend function " + func);
+ }
+
+ private int oglBlendEquation(int equation) {
+ switch (equation) {
+ case Blend.FUNC_ADD: return GL.GL_FUNC_ADD;
+ case Blend.FUNC_SUBTRACT: return GL.GL_FUNC_SUBTRACT;
+ case Blend.FUNC_REVERSE_SUBTRACT: return GL.GL_FUNC_REVERSE_SUBTRACT;
+ case Blend.MIN: return GL.GL_MIN;
+ case Blend.MAX: return GL.GL_MAX;
+ }
+ throw new InternalError("Illegal blend equation " + equation);
+ }
+
+ private static void validateFunc(GL gl, int func) {
+ if (func == GL.GL_CONSTANT_COLOR ||
+ func == GL.GL_ONE_MINUS_CONSTANT_COLOR ||
+ func == GL.GL_CONSTANT_ALPHA ||
+ func == GL.GL_ONE_MINUS_CONSTANT_ALPHA) {
+ if (!gl.isExtensionAvailable("GL_ARB_imaging")) {
+ throw new RuntimeException("Blend function requires GL_ARB_imaging extension");
+ }
+ }
+ }
+
+ private void send() {
+ GL gl = GLU.getCurrentGL();
+ // Don't try to optimize what we send to OpenGL at this point -- too complicated
+ if (enabled) {
+ gl.glEnable(GL.GL_BLEND);
+ int oglSrcFunc = oglBlendFunc(srcFunc);
+ int oglDestFunc = oglBlendFunc(destFunc);
+ validateFunc(gl, oglSrcFunc);
+ validateFunc(gl, oglDestFunc);
+ gl.glBlendFunc(oglSrcFunc, oglDestFunc);
+ if (gl.isExtensionAvailable("GL_ARB_imaging")) {
+ gl.glBlendEquation(oglBlendEquation(blendEquation));
+ gl.glBlendColor(blendColor.x(), blendColor.y(), blendColor.z(), blendColor.w());
+ }
+ } else {
+ gl.glDisable(GL.GL_BLEND);
+ }
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/GLColorElement.java b/src/net/java/joglutils/msg/elements/GLColorElement.java
new file mode 100644
index 0000000..732ee98
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/GLColorElement.java
@@ -0,0 +1,102 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the current set of colors, which are applied on a
+ per-vertex basis to any drawn geometry, and causes side-effects in
+ OpenGL for rendering. */
+
+public class GLColorElement extends ColorElement {
+ // Boilerplate for concrete element subclasses
+ public Element newInstance() {
+ return new GLColorElement();
+ }
+ public static GLColorElement getInstance(State state) {
+ return (GLColorElement) ColorElement.getInstance(state);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new GLColorElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // Whether the OpenGL state is currently enabled
+ private boolean enabled;
+
+ public void push(State state) {
+ super.push(state);
+ // Copy enabled state from previous element if any
+ GLColorElement prev = (GLColorElement) getNextInStack();
+ if (prev != null) {
+ enabled = prev.enabled;
+ }
+ }
+
+ public void pop(State state, Element previousTopElement) {
+ GLColorElement prev = (GLColorElement) previousTopElement;
+ boolean shouldBeEnabled = enabled;
+ enabled = prev.enabled;
+ // Put things back the way they were
+ setEnabled(shouldBeEnabled);
+ }
+
+ public void setElt(FloatBuffer colors) {
+ super.setElt(colors);
+ setEnabled(colors != null);
+ }
+
+ private void setEnabled(boolean enabled) {
+ if (this.enabled == enabled)
+ return; // No OpenGL work to do
+ this.enabled = enabled;
+ GL gl = GLU.getCurrentGL();
+ if (enabled) {
+ gl.glColorPointer(4, GL.GL_FLOAT, 0, colors);
+ gl.glEnableClientState(GL.GL_COLOR_ARRAY);
+ } else {
+ gl.glDisableClientState(GL.GL_COLOR_ARRAY);
+ // Assume we have to reset the current color to the default
+ gl.glColor4f(1, 1, 1, 1);
+ }
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/GLCoordinateElement.java b/src/net/java/joglutils/msg/elements/GLCoordinateElement.java
new file mode 100644
index 0000000..d33e4ec
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/GLCoordinateElement.java
@@ -0,0 +1,99 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the current set of coordinates, which are assembled to
+ draw geometry, and causes side-effects in OpenGL. */
+
+public class GLCoordinateElement extends CoordinateElement {
+ // Boilerplate for concrete element subclasses
+ public Element newInstance() {
+ return new GLCoordinateElement();
+ }
+ public static GLCoordinateElement getInstance(State state) {
+ return (GLCoordinateElement) CoordinateElement.getInstance(state);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new GLCoordinateElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // Whether the OpenGL state is currently enabled
+ private boolean enabled;
+
+ public void push(State state) {
+ super.push(state);
+ // Copy enabled state from previous element if any
+ GLCoordinateElement prev = (GLCoordinateElement) getNextInStack();
+ if (prev != null) {
+ enabled = prev.enabled;
+ }
+ }
+
+ public void pop(State state, Element previousTopElement) {
+ GLCoordinateElement prev = (GLCoordinateElement) previousTopElement;
+ boolean shouldBeEnabled = enabled;
+ enabled = prev.enabled;
+ // Put things back the way they were
+ setEnabled(shouldBeEnabled);
+ }
+
+ public void setElt(FloatBuffer coords) {
+ super.setElt(coords);
+ setEnabled(coords != null);
+ }
+
+ private void setEnabled(boolean enabled) {
+ if (this.enabled == enabled)
+ return; // No OpenGL work to do
+ this.enabled = enabled;
+ GL gl = GLU.getCurrentGL();
+ if (enabled) {
+ gl.glVertexPointer(3, GL.GL_FLOAT, 0, coords);
+ gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
+ } else {
+ gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
+ }
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/GLModelMatrixElement.java b/src/net/java/joglutils/msg/elements/GLModelMatrixElement.java
new file mode 100644
index 0000000..24097bc
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/GLModelMatrixElement.java
@@ -0,0 +1,97 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the model matrix, which is the transformation applied
+ to objects in the scene, and causes side-effects in OpenGL. */
+
+public class GLModelMatrixElement extends ModelMatrixElement {
+ // Boilerplate for concrete element subclasses
+ public Element newInstance() {
+ return new GLModelMatrixElement();
+ }
+ public static GLModelMatrixElement getInstance(State state) {
+ return (GLModelMatrixElement) ModelMatrixElement.getInstance(state);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new GLModelMatrixElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // State which we need in order to reset the modelview matrix
+ private State state;
+
+ public void push(State state) {
+ super.push(state);
+ this.state = state;
+
+ // Cause side-effects in OpenGL
+ GL gl = GLU.getCurrentGL();
+ gl.glPushMatrix();
+ }
+
+ public void pop(State state, Element previousTopElement) {
+ super.pop(state, previousTopElement);
+
+ // Cause side-effects in OpenGL
+ GL gl = GLU.getCurrentGL();
+ gl.glPopMatrix();
+ }
+
+ public void makeEltIdent() {
+ super.makeEltIdent();
+ // Cause side-effects in OpenGL
+ // Recompute the complete modelview matrix
+ Mat4f mat = ViewingMatrixElement.getInstance(state).getMatrix();
+ GL gl = GLU.getCurrentGL();
+ gl.glLoadTransposeMatrixf(mat.getRowMajorData(), 0);
+ }
+
+ public void multElt(Mat4f matrix) {
+ super.multElt(matrix);
+ GL gl = GLU.getCurrentGL();
+ gl.glMultTransposeMatrixf(matrix.getRowMajorData(), 0);
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/GLProjectionMatrixElement.java b/src/net/java/joglutils/msg/elements/GLProjectionMatrixElement.java
new file mode 100644
index 0000000..6c8d7d2
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/GLProjectionMatrixElement.java
@@ -0,0 +1,75 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the projection matrix, which transforms view-space
+ coordinates into screen-space coordinates, and performs
+ side-effects in OpenGL. */
+
+public class GLProjectionMatrixElement extends ProjectionMatrixElement {
+ // Boilerplate for concrete element subclasses
+ public Element newInstance() {
+ return new GLProjectionMatrixElement();
+ }
+ public static GLProjectionMatrixElement getInstance(State state) {
+ return (GLProjectionMatrixElement) ProjectionMatrixElement.getInstance(state);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new GLProjectionMatrixElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ public void push(State state) {
+ super.push(state);
+ }
+
+ public void setElt(Mat4f matrix) {
+ super.setElt(matrix);
+ GL gl = GLU.getCurrentGL();
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glLoadTransposeMatrixf(matrix.getRowMajorData(), 0);
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/GLTextureCoordinateElement.java b/src/net/java/joglutils/msg/elements/GLTextureCoordinateElement.java
new file mode 100644
index 0000000..111d0a9
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/GLTextureCoordinateElement.java
@@ -0,0 +1,104 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the current set of texture coordinates, which are
+ applied on a per-vertex basis to any drawn geometry, and performs
+ side-effects in OpenGL. */
+
+public class GLTextureCoordinateElement extends TextureCoordinateElement {
+ // Boilerplate for concrete element subclasses
+ public Element newInstance() {
+ return new GLTextureCoordinateElement();
+ }
+ public static GLTextureCoordinateElement getInstance(State state) {
+ return (GLTextureCoordinateElement) TextureCoordinateElement.getInstance(state);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new GLTextureCoordinateElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // Whether the OpenGL state is currently enabled
+ private boolean enabled;
+
+ public void push(State state) {
+ super.push(state);
+ // Copy enabled state from previous element if any
+ GLTextureCoordinateElement prev = (GLTextureCoordinateElement) getNextInStack();
+ if (prev != null) {
+ enabled = prev.enabled;
+ }
+ }
+
+ public void pop(State state, Element previousTopElement) {
+ GLTextureCoordinateElement prev = (GLTextureCoordinateElement) previousTopElement;
+ boolean shouldBeEnabled = enabled;
+ enabled = prev.enabled;
+ // Put things back the way they were
+ setEnabled(shouldBeEnabled);
+ }
+
+ public void setElt(FloatBuffer coords) {
+ super.setElt(coords);
+ setEnabled(coords != null);
+ }
+
+ private void setEnabled(boolean enabled) {
+ if (this.enabled == enabled)
+ return; // No OpenGL work to do
+ this.enabled = enabled;
+ GL gl = GLU.getCurrentGL();
+ if (enabled) {
+ // FIXME: may want to link this up with the GLTextureElement so
+ // that we only enable the texture coordinate array if we both
+ // have a TextureCoordinateElement and a TextureElement active
+ // (a little error checking for the application)
+ gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, coords);
+ gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+ } else {
+ gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/GLTextureElement.java b/src/net/java/joglutils/msg/elements/GLTextureElement.java
new file mode 100644
index 0000000..5241b09
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/GLTextureElement.java
@@ -0,0 +1,96 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import com.sun.opengl.util.texture.*;
+
+import net.java.joglutils.msg.misc.*;
+import net.java.joglutils.msg.nodes.*;
+
+/** Represents the current texture, which is applied to any drawn
+ geometry if texture coordinates are also supplied, and performs
+ side-effects in OpenGL. */
+
+public class GLTextureElement extends TextureElement {
+ // Boilerplate for concrete element subclasses
+ public Element newInstance() {
+ return new GLTextureElement();
+ }
+ public static GLTextureElement getInstance(State state) {
+ return (GLTextureElement) TextureElement.getInstance(state);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new GLTextureElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ public void pop(State state, Element previousTopElement) {
+ // Put things back the way they were
+ switchTextures(((GLTextureElement) previousTopElement).texture, texture, texEnvMode);
+ }
+
+ public void setElt(Texture texture, int texEnvMode) {
+ Texture prev = this.texture;
+ super.setElt(texture, texEnvMode);
+ switchTextures(prev, texture, texEnvMode);
+ }
+
+ private void switchTextures(Texture prev, Texture texture, int texEnvMode) {
+ GL gl = GLU.getCurrentGL();
+ // FIXME: should be smarter about this; if the target is the same
+ // for the previous and current textures, just bind the new one
+ if (prev != null) {
+ prev.disable();
+ }
+ if (texture != null) {
+ texture.enable();
+ texture.bind();
+ int glEnvMode = 0;
+ switch (texEnvMode) {
+ case Texture2.MODULATE: glEnvMode = GL.GL_MODULATE; break;
+ case Texture2.DECAL: glEnvMode = GL.GL_DECAL; break;
+ case Texture2.BLEND: glEnvMode = GL.GL_BLEND; break;
+ case Texture2.REPLACE: glEnvMode = GL.GL_REPLACE; break;
+ }
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, glEnvMode);
+ }
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/GLViewingMatrixElement.java b/src/net/java/joglutils/msg/elements/GLViewingMatrixElement.java
new file mode 100644
index 0000000..5848413
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/GLViewingMatrixElement.java
@@ -0,0 +1,81 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the viewing matrix, which contains the transformation
+ between the camera and the model, and performs side-effects in
+ OpenGL. */
+
+public class GLViewingMatrixElement extends ViewingMatrixElement {
+ // Boilerplate for concrete element subclasses
+ public Element newInstance() {
+ return new GLViewingMatrixElement();
+ }
+ public static GLViewingMatrixElement getInstance(State state) {
+ return (GLViewingMatrixElement) ViewingMatrixElement.getInstance(state);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new GLViewingMatrixElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // State which we need in order to reset the modelview matrix
+ private State state;
+ protected Mat4f temp = new Mat4f();
+
+ public void push(State state) {
+ super.push(state);
+ this.state = state;
+ }
+
+ public void setElt(Mat4f matrix) {
+ super.setElt(matrix);
+ // Must push the combined viewing and modelview matrices down to OpenGL
+ Mat4f mdl = ModelMatrixElement.getInstance(state).getMatrix();
+ temp.mul(matrix, mdl);
+ GL gl = GLU.getCurrentGL();
+ gl.glLoadTransposeMatrixf(temp.getRowMajorData(), 0);
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/ModelMatrixElement.java b/src/net/java/joglutils/msg/elements/ModelMatrixElement.java
new file mode 100644
index 0000000..cfe726e
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/ModelMatrixElement.java
@@ -0,0 +1,105 @@
+/*
+ * 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.elements;
+
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the model matrix, which is the transformation applied
+ to objects in the scene. */
+
+public class ModelMatrixElement extends Element {
+ // Boilerplate
+ private static StateIndex index = State.registerElementType();
+ public StateIndex getStateIndex() { return index; }
+ public Element newInstance() {
+ return new ModelMatrixElement();
+ }
+ public static ModelMatrixElement getInstance(State state) {
+ return (ModelMatrixElement) state.getElement(index);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new ModelMatrixElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // The matrix data
+ protected Mat4f matrix;
+ protected Mat4f temp = new Mat4f();
+
+ public ModelMatrixElement() {
+ matrix = new Mat4f();
+ matrix.makeIdent();
+ }
+
+ public void push(State state) {
+ ModelMatrixElement prev = (ModelMatrixElement) getNextInStack();
+ if (prev != null) {
+ matrix.set(prev.matrix);
+ }
+ }
+
+ /** Returns the current model matrix; callers should not mutate this
+ directly but instead use the accessor methods to change it. */
+ public Mat4f getMatrix() {
+ return matrix;
+ }
+
+ /** Sets the current element to the identity matrix. */
+ public static void makeIdent(State state) {
+ ModelMatrixElement elt = getInstance(state);
+ elt.makeEltIdent();
+ }
+
+ /** Sets this element to the identity matrix. */
+ public void makeEltIdent() {
+ matrix.makeIdent();
+ }
+
+ /** Multiplies the current element by the given matrix. */
+ public static void mult(State state, Mat4f matrix) {
+ ModelMatrixElement elt = getInstance(state);
+ elt.multElt(matrix);
+ }
+
+ /** Multiplies this element by the given matrix. */
+ public void multElt(Mat4f matrix) {
+ temp.set(this.matrix);
+ this.matrix.mul(temp, matrix);
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/ProjectionMatrixElement.java b/src/net/java/joglutils/msg/elements/ProjectionMatrixElement.java
new file mode 100644
index 0000000..dd70ca3
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/ProjectionMatrixElement.java
@@ -0,0 +1,93 @@
+/*
+ * 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.elements;
+
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the projection matrix, which transforms view-space
+ coordinates into screen-space coordinates. */
+
+public class ProjectionMatrixElement extends Element {
+ // Boilerplate
+ private static StateIndex index = State.registerElementType();
+ public StateIndex getStateIndex() { return index; }
+ public Element newInstance() {
+ return new ProjectionMatrixElement();
+ }
+ public static ProjectionMatrixElement getInstance(State state) {
+ return (ProjectionMatrixElement) state.getElement(index);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new ProjectionMatrixElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // The matrix data
+ protected Mat4f matrix;
+
+ public ProjectionMatrixElement() {
+ matrix = new Mat4f();
+ matrix.makeIdent();
+ }
+
+ /** Returns the current projection matrix; callers should not mutate
+ this directly but instead use the accessor methods to change
+ it. */
+ public Mat4f getMatrix() {
+ return matrix;
+ }
+
+ public void push(State state) {
+ ProjectionMatrixElement prev = (ProjectionMatrixElement) getNextInStack();
+ if (prev != null) {
+ matrix.set(prev.matrix);
+ }
+ }
+
+ /** Sets the projection matrix in the given state to the given one. */
+ public static void set(State state, Mat4f matrix) {
+ ProjectionMatrixElement elt = getInstance(state);
+ elt.setElt(matrix);
+ }
+
+ /** Sets the projection matrix in this element to the given one. */
+ public void setElt(Mat4f matrix) {
+ this.matrix.set(matrix);
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/TextureCoordinateElement.java b/src/net/java/joglutils/msg/elements/TextureCoordinateElement.java
new file mode 100644
index 0000000..6d36c6c
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/TextureCoordinateElement.java
@@ -0,0 +1,88 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the current set of texture coordinates, which are
+ applied on a per-vertex basis to any drawn geometry. */
+
+public class TextureCoordinateElement extends Element {
+ // Boilerplate
+ private static StateIndex index = State.registerElementType();
+ public StateIndex getStateIndex() { return index; }
+ public Element newInstance() {
+ return new TextureCoordinateElement();
+ }
+ public static TextureCoordinateElement getInstance(State state) {
+ return (TextureCoordinateElement) state.getElement(index);
+ }
+ public static void enable(State defaultState) {
+ TextureCoordinateElement tmp = new TextureCoordinateElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // The actual coordinate data
+ protected FloatBuffer coords;
+
+ /** Sets the texture coordinate data in the passed state. */
+ public static void set(State state, FloatBuffer coords) {
+ getInstance(state).setElt(coords);
+ }
+
+ /** Returns the texture coordinate data in the passed state. */
+ public static FloatBuffer get(State state) {
+ return getInstance(state).coords;
+ }
+
+ public void push(State state) {
+ TextureCoordinateElement prev = (TextureCoordinateElement) getNextInStack();
+ if (prev != null) {
+ // Pull down the data from the previous element
+ coords = prev.coords;
+ }
+ }
+
+ /** Sets the texture coordinate data in this element. */
+ public void setElt(FloatBuffer coords) {
+ this.coords = coords;
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/TextureElement.java b/src/net/java/joglutils/msg/elements/TextureElement.java
new file mode 100644
index 0000000..90a9ebc
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/TextureElement.java
@@ -0,0 +1,101 @@
+/*
+ * 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.elements;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import com.sun.opengl.util.texture.*;
+
+import net.java.joglutils.msg.misc.*;
+
+// FIXME: the TextureElement / GLTextureElement distinction doesn't
+// make much sense here, because the Texture object the TextureElement
+// contains already implicitly relies on OpenGL
+
+/** Represents the current texture, which is applied to any drawn
+ geometry if texture coordinates are also supplied. */
+
+public class TextureElement extends Element {
+ // Boilerplate
+ private static StateIndex index = State.registerElementType();
+ public StateIndex getStateIndex() { return index; }
+ public Element newInstance() {
+ return new TextureElement();
+ }
+ public static TextureElement getInstance(State state) {
+ return (TextureElement) state.getElement(index);
+ }
+ public static void enable(State defaultState) {
+ TextureElement tmp = new TextureElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // The actual Texture object
+ protected Texture texture;
+ // The texture environment mode
+ protected int texEnvMode;
+
+ /** Sets the texture and environment mode in the given state. */
+ public static void set(State state, Texture texture, int texEnvMode) {
+ getInstance(state).setElt(texture, texEnvMode);
+ }
+
+ /** Returns the current texture in the state. */
+ public static Texture get(State state) {
+ return getInstance(state).texture;
+ }
+
+ /** Returns the texture environment mode in the state. */
+ public static int getEnvMode(State state) {
+ return getInstance(state).texEnvMode;
+ }
+
+ public void push(State state) {
+ TextureElement prev = (TextureElement) getNextInStack();
+ if (prev != null) {
+ // Pull down the texture from the previous element
+ texture = prev.texture;
+ }
+ }
+
+ /** Sets the texture and environment mode in this element. */
+ public void setElt(Texture texture, int texEnvMode) {
+ this.texture = texture;
+ this.texEnvMode = texEnvMode;
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/ViewingMatrixElement.java b/src/net/java/joglutils/msg/elements/ViewingMatrixElement.java
new file mode 100644
index 0000000..5142678
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/ViewingMatrixElement.java
@@ -0,0 +1,93 @@
+/*
+ * 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.elements;
+
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+
+/** Represents the viewing matrix, which contains the transformation
+ between the camera and the model. */
+
+public class ViewingMatrixElement extends Element {
+ // Boilerplate
+ private static StateIndex index = State.registerElementType();
+ public StateIndex getStateIndex() { return index; }
+ public Element newInstance() {
+ return new ViewingMatrixElement();
+ }
+ public static ViewingMatrixElement getInstance(State state) {
+ return (ViewingMatrixElement) state.getElement(index);
+ }
+ public static void enable(State defaultState) {
+ Element tmp = new ViewingMatrixElement();
+ defaultState.setElement(tmp.getStateIndex(), tmp);
+ }
+
+ // The matrix data
+ protected Mat4f matrix;
+
+ public ViewingMatrixElement() {
+ matrix = new Mat4f();
+ matrix.makeIdent();
+ }
+
+ /** Returns the current viewing matrix; callers should not mutate
+ this directly but instead use the accessor methods to change
+ it. */
+ public Mat4f getMatrix() {
+ return matrix;
+ }
+
+ public void push(State state) {
+ ViewingMatrixElement prev = (ViewingMatrixElement) getNextInStack();
+ if (prev != null) {
+ matrix.set(prev.matrix);
+ }
+ }
+
+ /** Sets the viewing matrix in the given state to the given one. */
+ public static void set(State state, Mat4f matrix) {
+ ViewingMatrixElement elt = getInstance(state);
+ elt.setElt(matrix);
+ }
+
+ /** Sets the viewing matrix in this element to the given one. */
+ public void setElt(Mat4f matrix) {
+ this.matrix.set(matrix);
+ }
+}
diff --git a/src/net/java/joglutils/msg/elements/package.html b/src/net/java/joglutils/msg/elements/package.html
new file mode 100644
index 0000000..870e605
--- /dev/null
+++ b/src/net/java/joglutils/msg/elements/package.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<body>
+
+Elements of the global state affected by actions' traversal of
+nodes. Only developers of the library will typically have to interact
+with the classes in this package.
+
+<P>
+
+In similar fashion to Open Inventor, each element in this package is
+typically partitioned into two classes, one which holds the storage
+for the element and one which implements the OpenGL side-effects. This
+organization allows certain actions to traverse the scene graph
+without requiring an OpenGL context to be current.
+
+</body>
+</html>
diff --git a/src/net/java/joglutils/msg/impl/BufferFactory.java b/src/net/java/joglutils/msg/impl/BufferFactory.java
new file mode 100644
index 0000000..191c5c7
--- /dev/null
+++ b/src/net/java/joglutils/msg/impl/BufferFactory.java
@@ -0,0 +1,139 @@
+/*
+ * 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.impl;
+
+import java.nio.*;
+import java.util.*;
+import com.sun.opengl.util.*;
+
+/** Assists in allocation of direct Buffers. On some platforms when a
+ small direct Buffer is allocated there is a large amount of
+ rounding up which occurs. This BufferFactory allocates direct
+ Buffers in chunks and hands out slices of those chunks to
+ clients. */
+
+public class BufferFactory {
+ private static ByteBuffer curByteBuf;
+ private static ShortBuffer curShortBuf;
+ private static IntBuffer curIntBuf;
+ private static FloatBuffer curFloatBuf;
+ private static DoubleBuffer curDoubleBuf;
+
+ // I believe the rounding-up size of direct Buffers on Unix platforms is 8K
+ private static final int CHUNK_SIZE = 8 * 1024;
+
+ public static synchronized ByteBuffer newByteBuffer(int numElements) {
+ int sz = numElements * BufferUtil.SIZEOF_BYTE;
+ if (sz > CHUNK_SIZE) {
+ // Just allocate a fresh ByteBuffer and don't worry about
+ // rounding up its allocation size and re-using the end portion
+ return BufferUtil.newByteBuffer(numElements);
+ }
+ if (curByteBuf == null || curByteBuf.remaining() < numElements) {
+ curByteBuf = BufferUtil.newByteBuffer(CHUNK_SIZE / BufferUtil.SIZEOF_BYTE);
+ }
+ curByteBuf.limit(curByteBuf.position() + numElements);
+ ByteBuffer res = curByteBuf.slice();
+ curByteBuf.position(curByteBuf.limit());
+ return res;
+ }
+
+ public static synchronized ShortBuffer newShortBuffer(int numElements) {
+ int sz = numElements * BufferUtil.SIZEOF_SHORT;
+ if (sz > CHUNK_SIZE) {
+ // Just allocate a fresh ShortBuffer and don't worry about
+ // rounding up its allocation size and re-using the end portion
+ return BufferUtil.newShortBuffer(numElements);
+ }
+ if (curShortBuf == null || curShortBuf.remaining() < numElements) {
+ curShortBuf = BufferUtil.newShortBuffer(CHUNK_SIZE / BufferUtil.SIZEOF_SHORT);
+ }
+ curShortBuf.limit(curShortBuf.position() + numElements);
+ ShortBuffer res = curShortBuf.slice();
+ curShortBuf.position(curShortBuf.limit());
+ return res;
+ }
+
+ public static synchronized IntBuffer newIntBuffer(int numElements) {
+ int sz = numElements * BufferUtil.SIZEOF_INT;
+ if (sz > CHUNK_SIZE) {
+ // Just allocate a fresh IntBuffer and don't worry about
+ // rounding up its allocation size and re-using the end portion
+ return BufferUtil.newIntBuffer(numElements);
+ }
+ if (curIntBuf == null || curIntBuf.remaining() < numElements) {
+ curIntBuf = BufferUtil.newIntBuffer(CHUNK_SIZE / BufferUtil.SIZEOF_INT);
+ }
+ curIntBuf.limit(curIntBuf.position() + numElements);
+ IntBuffer res = curIntBuf.slice();
+ curIntBuf.position(curIntBuf.limit());
+ return res;
+ }
+
+ public static synchronized FloatBuffer newFloatBuffer(int numElements) {
+ int sz = numElements * BufferUtil.SIZEOF_FLOAT;
+ if (sz > CHUNK_SIZE) {
+ // Just allocate a fresh FloatBuffer and don't worry about
+ // rounding up its allocation size and re-using the end portion
+ return BufferUtil.newFloatBuffer(numElements);
+ }
+ if (curFloatBuf == null || curFloatBuf.remaining() < numElements) {
+ curFloatBuf = BufferUtil.newFloatBuffer(CHUNK_SIZE / BufferUtil.SIZEOF_FLOAT);
+ }
+ curFloatBuf.limit(curFloatBuf.position() + numElements);
+ FloatBuffer res = curFloatBuf.slice();
+ curFloatBuf.position(curFloatBuf.limit());
+ return res;
+ }
+
+ public static synchronized DoubleBuffer newDoubleBuffer(int numElements) {
+ int sz = numElements * BufferUtil.SIZEOF_DOUBLE;
+ if (sz > CHUNK_SIZE) {
+ // Just allocate a fresh DoubleBuffer and don't worry about
+ // rounding up its allocation size and re-using the end portion
+ return BufferUtil.newDoubleBuffer(numElements);
+ }
+ if (curDoubleBuf == null || curDoubleBuf.remaining() < numElements) {
+ curDoubleBuf = BufferUtil.newDoubleBuffer(CHUNK_SIZE / BufferUtil.SIZEOF_DOUBLE);
+ }
+ curDoubleBuf.limit(curDoubleBuf.position() + numElements);
+ DoubleBuffer res = curDoubleBuf.slice();
+ curDoubleBuf.position(curDoubleBuf.limit());
+ return res;
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Box3f.java b/src/net/java/joglutils/msg/math/Box3f.java
new file mode 100644
index 0000000..1dafd7c
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Box3f.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+/** Represents an axis-aligned box in 3D space. */
+
+public class Box3f {
+ private Vec3f min = new Vec3f();
+ private Vec3f max = new Vec3f();
+
+ public Box3f() {}
+
+ public Box3f(Vec3f min, Vec3f max) {
+ setMin(min);
+ setMax(max);
+ }
+
+ public void setMin(Vec3f min) { this.min.set(min); }
+ public Vec3f getMin() { return min; }
+
+ public void setMax(Vec3f max) { this.max.set(max); }
+ public Vec3f getMax() { return max; }
+
+ public Vec3f getCenter() {
+ return new Vec3f(0.5f * (min.x() + max.x()),
+ 0.5f * (min.y() + max.y()),
+ 0.5f * (min.z() + max.z()));
+ }
+
+ public void extendBy(Vec3f point) {
+ if (point.x() < min.x()) min.setX(point.x());
+ if (point.y() < min.y()) min.setY(point.y());
+ if (point.z() < min.z()) min.setZ(point.z());
+ if (point.x() > max.x()) max.setX(point.x());
+ if (point.y() > max.y()) max.setY(point.y());
+ if (point.z() > max.z()) max.setZ(point.z());
+ }
+
+ public void extendBy(Box3f box) {
+ if (box.min.x() < min.x()) min.setX(box.min.x());
+ if (box.min.y() < min.y()) min.setY(box.min.y());
+ if (box.min.z() < min.z()) min.setZ(box.min.z());
+ if (box.max.x() > max.x()) max.setX(box.max.x());
+ if (box.max.y() > max.y()) max.setY(box.max.y());
+ if (box.max.z() > max.z()) max.setZ(box.max.z());
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/DimensionMismatchException.java b/src/net/java/joglutils/msg/math/DimensionMismatchException.java
new file mode 100644
index 0000000..a29c6c9
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/DimensionMismatchException.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+/** Thrown to indicate a mismatch of dimensionality of a matrix or
+ vector. */
+
+public class DimensionMismatchException extends RuntimeException {
+ public DimensionMismatchException() {
+ super();
+ }
+
+ public DimensionMismatchException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/IntersectionPoint.java b/src/net/java/joglutils/msg/math/IntersectionPoint.java
new file mode 100644
index 0000000..5a76312
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/IntersectionPoint.java
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+/** Wraps a 3D point and parametric time value. */
+
+public class IntersectionPoint {
+ private Vec3f intPt = new Vec3f();
+ private float t;
+
+ public Vec3f getIntersectionPoint() {
+ return intPt;
+ }
+
+ public void setIntersectionPoint(Vec3f newPt) {
+ intPt.set(newPt);
+ }
+
+ public float getT() {
+ return t;
+ }
+
+ public void setT(float t) {
+ this.t = t;
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Line.java b/src/net/java/joglutils/msg/math/Line.java
new file mode 100644
index 0000000..2004c08
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Line.java
@@ -0,0 +1,150 @@
+/*
+ * 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;
+
+/** Represents a line in 3D space. */
+
+public class Line {
+ private Vec3f point;
+ /** Normalized */
+ private Vec3f direction;
+ /** For computing projections along line */
+ private Vec3f alongVec;
+
+ /** Default constructor initializes line to point (0, 0, 0) and
+ direction (1, 0, 0) */
+ public Line() {
+ point = new Vec3f(0, 0, 0);
+ direction = new Vec3f(1, 0, 0);
+ alongVec = new Vec3f();
+ recalc();
+ }
+
+ /** Line goes in direction <b>direction</b> through the point
+ <b>point</b>. <b>direction</b> does not need to be normalized but must
+ not be the zero vector. */
+ public Line(Vec3f direction, Vec3f point) {
+ direction = new Vec3f(direction);
+ direction.normalize();
+ point = new Vec3f(point);
+ alongVec = new Vec3f();
+ recalc();
+ }
+
+ /** Setter does some work to maintain internal caches.
+ <b>direction</b> does not need to be normalized but must not be
+ the zero vector. */
+ public void setDirection(Vec3f direction) {
+ this.direction.set(direction);
+ this.direction.normalize();
+ recalc();
+ }
+
+ /** Direction is normalized internally, so <b>direction</b> is not
+ necessarily equal to <code>plane.setDirection(direction);
+ plane.getDirection();</code> */
+ public Vec3f getDirection() {
+ return direction;
+ }
+
+ /** Setter does some work to maintain internal caches. */
+ public void setPoint(Vec3f point) {
+ this.point.set(point);
+ recalc();
+ }
+
+ public Vec3f getPoint() {
+ return point;
+ }
+
+ /** Project a point onto the line */
+ public void projectPoint(Vec3f pt,
+ Vec3f projPt) {
+ float dotp = direction.dot(pt);
+ projPt.set(direction);
+ projPt.scale(dotp);
+ projPt.add(alongVec);
+ }
+
+ /** Find closest point on this line to the given ray, specified by
+ start point and direction. If ray is parallel to this line,
+ returns false and closestPoint is not modified. */
+ public boolean closestPointToRay(Vec3f rayStart,
+ Vec3f rayDirection,
+ Vec3f closestPoint) {
+ // Line 1 is this one. Line 2 is the incoming one.
+ Mat2f A = new Mat2f();
+ A.set(0, 0, -direction.lengthSquared());
+ A.set(1, 1, -rayDirection.lengthSquared());
+ A.set(0, 1, direction.dot(rayDirection));
+ A.set(1, 0, A.get(0, 1));
+ if (Math.abs(A.determinant()) == 0.0f) {
+ return false;
+ }
+ if (!A.invert()) {
+ return false;
+ }
+ Vec2f b = new Vec2f();
+ b.setX(point.dot(direction) - rayStart.dot(direction));
+ b.setY(rayStart.dot(rayDirection) - point.dot(rayDirection));
+ Vec2f x = new Vec2f();
+ A.xformVec(b, x);
+ if (x.y() < 0) {
+ // Means that ray start is closest point to this line
+ closestPoint.set(rayStart);
+ } else {
+ closestPoint.set(direction);
+ closestPoint.scale(x.x());
+ closestPoint.add(point);
+ }
+ return true;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void recalc() {
+ float denom = direction.lengthSquared();
+ if (denom == 0.0f) {
+ throw new RuntimeException("Line.recalc: ERROR: direction was the zero vector " +
+ "(not allowed)");
+ }
+ alongVec.set(point.minus(direction.times(point.dot(direction))));
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Mat2f.java b/src/net/java/joglutils/msg/math/Mat2f.java
new file mode 100644
index 0000000..80e8131
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Mat2f.java
@@ -0,0 +1,167 @@
+/*
+ * 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;
+
+/** 2x2 matrix class useful for simple linear algebra. Representation
+ is (as Mat4f) in row major order and assumes multiplication by
+ column vectors on the right. */
+
+public class Mat2f {
+ private float[] data;
+
+ /** Creates new matrix initialized to the zero matrix */
+ public Mat2f() {
+ data = new float[4];
+ }
+
+ /** Initialize to the identity matrix. */
+ public void makeIdent() {
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 2; j++) {
+ if (i == j) {
+ set(i, j, 1.0f);
+ } else {
+ set(i, j, 0.0f);
+ }
+ }
+ }
+ }
+
+ /** Gets the (i,j)th element of this matrix, where i is the row
+ index and j is the column index */
+ public float get(int i, int j) {
+ return data[2 * i + j];
+ }
+
+ /** Sets the (i,j)th element of this matrix, where i is the row
+ index and j is the column index */
+ public void set(int i, int j, float val) {
+ data[2 * i + j] = val;
+ }
+
+ /** Set column i (i=[0..1]) to vector v. */
+ public void setCol(int i, Vec2f v) {
+ set(0, i, v.x());
+ set(1, i, v.y());
+ }
+
+ /** Set row i (i=[0..1]) to vector v. */
+ public void setRow(int i, Vec2f v) {
+ set(i, 0, v.x());
+ set(i, 1, v.y());
+ }
+
+ /** Transpose this matrix in place. */
+ public void transpose() {
+ float t = get(0, 1);
+ set(0, 1, get(1, 0));
+ set(1, 0, t);
+ }
+
+ /** Return the determinant. */
+ public float determinant() {
+ return (get(0, 0) * get(1, 1) - get(1, 0) * get(0, 1));
+ }
+
+ /** Full matrix inversion in place. If matrix is singular, returns
+ false and matrix contents are untouched. If you know the matrix
+ is orthonormal, you can call transpose() instead. */
+ public boolean invert() {
+ float det = determinant();
+ if (det == 0.0f)
+ return false;
+
+ // Create transpose of cofactor matrix in place
+ float t = get(0, 0);
+ set(0, 0, get(1, 1));
+ set(1, 1, t);
+ set(0, 1, -get(0, 1));
+ set(1, 0, -get(1, 0));
+
+ // Now divide by determinant
+ for (int i = 0; i < 4; i++) {
+ data[i] /= det;
+ }
+ return true;
+ }
+
+ /** Multiply a 2D vector by this matrix. NOTE: src and dest must be
+ different vectors. */
+ public void xformVec(Vec2f src, Vec2f dest) {
+ dest.set(get(0, 0) * src.x() +
+ get(0, 1) * src.y(),
+
+ get(1, 0) * src.x() +
+ get(1, 1) * src.y());
+ }
+
+ /** Returns this * b; creates new matrix */
+ public Mat2f mul(Mat2f b) {
+ Mat2f tmp = new Mat2f();
+ tmp.mul(this, b);
+ return tmp;
+ }
+
+ /** this = a * b */
+ public void mul(Mat2f a, Mat2f b) {
+ for (int rc = 0; rc < 2; rc++)
+ for (int cc = 0; cc < 2; cc++) {
+ float tmp = 0.0f;
+ for (int i = 0; i < 2; i++)
+ tmp += a.get(rc, i) * b.get(i, cc);
+ set(rc, cc, tmp);
+ }
+ }
+
+ public Matf toMatf() {
+ Matf out = new Matf(2, 2);
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 2; j++) {
+ out.set(i, j, get(i, j));
+ }
+ }
+ return out;
+ }
+
+ public String toString() {
+ String endl = System.getProperty("line.separator");
+ return "(" +
+ get(0, 0) + ", " + get(0, 1) + endl +
+ get(1, 0) + ", " + get(1, 1) + ")";
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Mat3f.java b/src/net/java/joglutils/msg/math/Mat3f.java
new file mode 100644
index 0000000..976699f
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Mat3f.java
@@ -0,0 +1,191 @@
+/*
+ * 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;
+
+/** 3x3 matrix class useful for simple linear algebra. Representation
+ is (as Mat4f) in row major order and assumes multiplication by
+ column vectors on the right. */
+
+public class Mat3f {
+ private float[] data;
+
+ /** Creates new matrix initialized to the zero matrix */
+ public Mat3f() {
+ data = new float[9];
+ }
+
+ /** Initialize to the identity matrix. */
+ public void makeIdent() {
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ if (i == j) {
+ set(i, j, 1.0f);
+ } else {
+ set(i, j, 0.0f);
+ }
+ }
+ }
+ }
+
+ /** Gets the (i,j)th element of this matrix, where i is the row
+ index and j is the column index */
+ public float get(int i, int j) {
+ return data[3 * i + j];
+ }
+
+ /** Sets the (i,j)th element of this matrix, where i is the row
+ index and j is the column index */
+ public void set(int i, int j, float val) {
+ data[3 * i + j] = val;
+ }
+
+ /** Set column i (i=[0..2]) to vector v. */
+ public void setCol(int i, Vec3f v) {
+ set(0, i, v.x());
+ set(1, i, v.y());
+ set(2, i, v.z());
+ }
+
+ /** Set row i (i=[0..2]) to vector v. */
+ public void setRow(int i, Vec3f v) {
+ set(i, 0, v.x());
+ set(i, 1, v.y());
+ set(i, 2, v.z());
+ }
+
+ /** Transpose this matrix in place. */
+ public void transpose() {
+ float t;
+ t = get(0, 1);
+ set(0, 1, get(1, 0));
+ set(1, 0, t);
+
+ t = get(0, 2);
+ set(0, 2, get(2, 0));
+ set(2, 0, t);
+
+ t = get(1, 2);
+ set(1, 2, get(2, 1));
+ set(2, 1, t);
+ }
+
+ /** Return the determinant. Computed across the zeroth row. */
+ public float determinant() {
+ return (get(0, 0) * (get(1, 1) * get(2, 2) - get(2, 1) * get(1, 2)) +
+ get(0, 1) * (get(2, 0) * get(1, 2) - get(1, 0) * get(2, 2)) +
+ get(0, 2) * (get(1, 0) * get(2, 1) - get(2, 0) * get(1, 1)));
+ }
+
+ /** Full matrix inversion in place. If matrix is singular, throws
+ SingularMatrixException. If you know the matrix is orthonormal,
+ you can call transpose() instead. */
+ public void invert() throws SingularMatrixException {
+ float det = determinant();
+ if (det == 0.0f)
+ throw new SingularMatrixException();
+
+ // Form cofactor matrix
+ Mat3f cf = new Mat3f();
+ cf.set(0, 0, get(1, 1) * get(2, 2) - get(2, 1) * get(1, 2));
+ cf.set(0, 1, get(2, 0) * get(1, 2) - get(1, 0) * get(2, 2));
+ cf.set(0, 2, get(1, 0) * get(2, 1) - get(2, 0) * get(1, 1));
+ cf.set(1, 0, get(2, 1) * get(0, 2) - get(0, 1) * get(2, 2));
+ cf.set(1, 1, get(0, 0) * get(2, 2) - get(2, 0) * get(0, 2));
+ cf.set(1, 2, get(2, 0) * get(0, 1) - get(0, 0) * get(2, 1));
+ cf.set(2, 0, get(0, 1) * get(1, 2) - get(1, 1) * get(0, 2));
+ cf.set(2, 1, get(1, 0) * get(0, 2) - get(0, 0) * get(1, 2));
+ cf.set(2, 2, get(0, 0) * get(1, 1) - get(1, 0) * get(0, 1));
+
+ // Now copy back transposed
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ set(i, j, cf.get(j, i) / det);
+ }
+
+ /** Multiply a 3D vector by this matrix. NOTE: src and dest must be
+ different vectors. */
+ public void xformVec(Vec3f src, Vec3f dest) {
+ dest.set(get(0, 0) * src.x() +
+ get(0, 1) * src.y() +
+ get(0, 2) * src.z(),
+
+ get(1, 0) * src.x() +
+ get(1, 1) * src.y() +
+ get(1, 2) * src.z(),
+
+ get(2, 0) * src.x() +
+ get(2, 1) * src.y() +
+ get(2, 2) * src.z());
+ }
+
+ /** Returns this * b; creates new matrix */
+ public Mat3f mul(Mat3f b) {
+ Mat3f tmp = new Mat3f();
+ tmp.mul(this, b);
+ return tmp;
+ }
+
+ /** this = a * b */
+ public void mul(Mat3f a, Mat3f b) {
+ for (int rc = 0; rc < 3; rc++)
+ for (int cc = 0; cc < 3; cc++) {
+ float tmp = 0.0f;
+ for (int i = 0; i < 3; i++)
+ tmp += a.get(rc, i) * b.get(i, cc);
+ set(rc, cc, tmp);
+ }
+ }
+
+ public Matf toMatf() {
+ Matf out = new Matf(3, 3);
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ out.set(i, j, get(i, j));
+ }
+ }
+ return out;
+ }
+
+ public String toString() {
+ String endl = System.getProperty("line.separator");
+ return "(" +
+ get(0, 0) + ", " + get(0, 1) + ", " + get(0, 2) + endl +
+ get(1, 0) + ", " + get(1, 1) + ", " + get(1, 2) + endl +
+ get(2, 0) + ", " + get(2, 1) + ", " + get(2, 2) + ")";
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Mat4f.java b/src/net/java/joglutils/msg/math/Mat4f.java
new file mode 100644
index 0000000..b0cc67e
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Mat4f.java
@@ -0,0 +1,574 @@
+/*
+ * 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;
+
+/** A (very incomplete) 4x4 matrix class. Representation assumes
+ row-major order and multiplication by column vectors on the
+ right. */
+
+public class Mat4f {
+ private float[] data;
+
+ /** Creates new matrix initialized to the zero matrix */
+ public Mat4f() {
+ data = new float[16];
+ }
+
+ /** Creates new matrix initialized to argument's contents */
+ public Mat4f(Mat4f arg) {
+ this();
+ set(arg);
+ }
+
+ /** Sets this matrix to the identity matrix */
+ public void makeIdent() {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ if (i == j) {
+ set(i, j, 1.0f);
+ } else {
+ set(i, j, 0.0f);
+ }
+ }
+ }
+ }
+
+ /** Sets this matrix to be equivalent to the given one */
+ public void set(Mat4f arg) {
+ float[] mine = data;
+ float[] yours = arg.data;
+ for (int i = 0; i < mine.length; i++) {
+ mine[i] = yours[i];
+ }
+ }
+
+ /** Gets the (i,j)th element of this matrix, where i is the row
+ index and j is the column index */
+ public float get(int i, int j) {
+ return data[4 * i + j];
+ }
+
+ /** Sets the (i,j)th element of this matrix, where i is the row
+ index and j is the column index */
+ public void set(int i, int j, float val) {
+ data[4 * i + j] = val;
+ }
+
+ /** Sets the translation component of this matrix (i.e., the three
+ top elements of the third column) without touching any of the
+ other parts of the matrix */
+ public void setTranslation(Vec3f trans) {
+ set(0, 3, trans.x());
+ set(1, 3, trans.y());
+ set(2, 3, trans.z());
+ }
+
+ /** Sets the rotation component of this matrix (i.e., the upper left
+ 3x3) without touching any of the other parts of the matrix */
+ public void setRotation(Rotf rot) {
+ rot.toMatrix(this);
+ }
+
+ /** Sets the upper-left 3x3 of this matrix assuming that the given
+ x, y, and z vectors form an orthonormal basis */
+ public void setRotation(Vec3f x, Vec3f y, Vec3f z) {
+ set(0, 0, x.x());
+ set(1, 0, x.y());
+ set(2, 0, x.z());
+
+ set(0, 1, y.x());
+ set(1, 1, y.y());
+ set(2, 1, y.z());
+
+ set(0, 2, z.x());
+ set(1, 2, z.y());
+ set(2, 2, z.z());
+ }
+
+ /** Gets the upper left 3x3 of this matrix as a rotation. Currently
+ does not work if there are scales. Ignores translation
+ component. */
+ public void getRotation(Rotf rot) {
+ rot.fromMatrix(this);
+ }
+
+ /** Sets the elements (0, 0), (1, 1), and (2, 2) with the
+ appropriate elements of the given three-dimensional scale
+ vector. Does not perform a full multiplication of the upper-left
+ 3x3; use this with an identity matrix in conjunction with
+ <code>mul</code> for that. */
+ public void setScale(Vec3f scale) {
+ set(0, 0, scale.x());
+ set(1, 1, scale.y());
+ set(2, 2, scale.z());
+ }
+
+ /** Inverts this matrix assuming that it represents a rigid
+ transform (i.e., some combination of rotations and
+ translations). Assumes column vectors. Algorithm: transposes
+ upper left 3x3; negates translation in rightmost column and
+ transforms by inverted rotation. */
+ public void invertRigid() {
+ float t;
+ // Transpose upper left 3x3
+ t = get(0, 1);
+ set(0, 1, get(1, 0));
+ set(1, 0, t);
+ t = get(0, 2);
+ set(0, 2, get(2, 0));
+ set(2, 0, t);
+ t = get(1, 2);
+ set(1, 2, get(2, 1));
+ set(2, 1, t);
+ // Transform negative translation by this
+ Vec3f negTrans = new Vec3f(-get(0, 3), -get(1, 3), -get(2, 3));
+ Vec3f trans = new Vec3f();
+ xformDir(negTrans, trans);
+ set(0, 3, trans.x());
+ set(1, 3, trans.y());
+ set(2, 3, trans.z());
+ }
+
+ /** Performs general 4x4 matrix inversion.
+ @throws SingularMatrixException if this matrix is singular (i.e., non-invertible)
+ */
+ public void invert() throws SingularMatrixException {
+ invertGeneral(this);
+ }
+
+ /** Returns this * b; creates new matrix */
+ public Mat4f mul(Mat4f b) {
+ Mat4f tmp = new Mat4f();
+ tmp.mul(this, b);
+ return tmp;
+ }
+
+ /** this = a * b */
+ public void mul(Mat4f a, Mat4f b) {
+ for (int rc = 0; rc < 4; rc++)
+ for (int cc = 0; cc < 4; cc++) {
+ float tmp = 0.0f;
+ for (int i = 0; i < 4; i++)
+ tmp += a.get(rc, i) * b.get(i, cc);
+ set(rc, cc, tmp);
+ }
+ }
+
+ /** Transpose this matrix in place. */
+ public void transpose() {
+ float t;
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < i; j++) {
+ t = get(i, j);
+ set(i, j, get(j, i));
+ set(j, i, t);
+ }
+ }
+ }
+
+ /** Multiply a 4D vector by this matrix. NOTE: src and dest must be
+ different vectors. */
+ public void xformVec(Vec4f src, Vec4f dest) {
+ for (int rc = 0; rc < 4; rc++) {
+ float tmp = 0.0f;
+ for (int cc = 0; cc < 4; cc++) {
+ tmp += get(rc, cc) * src.get(cc);
+ }
+ dest.set(rc, tmp);
+ }
+ }
+
+ /** Transforms a 3D vector as though it had a homogeneous coordinate
+ and assuming that this matrix represents only rigid
+ transformations; i.e., is not a full transformation. NOTE: src
+ and dest must be different vectors. */
+ public void xformPt(Vec3f src, Vec3f dest) {
+ for (int rc = 0; rc < 3; rc++) {
+ float tmp = 0.0f;
+ for (int cc = 0; cc < 3; cc++) {
+ tmp += get(rc, cc) * src.get(cc);
+ }
+ tmp += get(rc, 3);
+ dest.set(rc, tmp);
+ }
+ }
+
+ /** Transforms src using only the upper left 3x3. NOTE: src and dest
+ must be different vectors. */
+ public void xformDir(Vec3f src, Vec3f dest) {
+ for (int rc = 0; rc < 3; rc++) {
+ float tmp = 0.0f;
+ for (int cc = 0; cc < 3; cc++) {
+ tmp += get(rc, cc) * src.get(cc);
+ }
+ dest.set(rc, tmp);
+ }
+ }
+
+ /** Copies data in column-major (OpenGL format) order into passed
+ float array, which must have length 16 or greater. */
+ public void getColumnMajorData(float[] out) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ out[4 * j + i] = get(i, j);
+ }
+ }
+ }
+
+ /** Returns the matrix data in row-major format, which is the
+ opposite of OpenGL's convention. */
+ public float[] getRowMajorData() {
+ return data;
+ }
+
+ public Matf toMatf() {
+ Matf out = new Matf(4, 4);
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ out.set(i, j, get(i, j));
+ }
+ }
+ return out;
+ }
+
+ public String toString() {
+ String endl = System.getProperty("line.separator");
+ return "(" +
+ get(0, 0) + ", " + get(0, 1) + ", " + get(0, 2) + ", " + get(0, 3) + endl +
+ get(1, 0) + ", " + get(1, 1) + ", " + get(1, 2) + ", " + get(1, 3) + endl +
+ get(2, 0) + ", " + get(2, 1) + ", " + get(2, 2) + ", " + get(2, 3) + endl +
+ get(3, 0) + ", " + get(3, 1) + ", " + get(3, 2) + ", " + get(3, 3) + ")";
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // The following code was borrowed from Java 3D's vecmath implementation
+
+ private void invertGeneral(Mat4f m1) {
+ double temp[] = new double[16];
+ double result[] = new double[16];
+ int row_perm[] = new int[4];
+ int i, r, c;
+
+ // Use LU decomposition and backsubstitution code specifically
+ // for floating-point 4x4 matrices.
+
+ // Copy source matrix to t1tmp
+ temp[0] = m1.get(0, 0);
+ temp[1] = m1.get(0, 1);
+ temp[2] = m1.get(0, 2);
+ temp[3] = m1.get(0, 3);
+
+ temp[4] = m1.get(1, 0);
+ temp[5] = m1.get(1, 1);
+ temp[6] = m1.get(1, 2);
+ temp[7] = m1.get(1, 3);
+
+ temp[8] = m1.get(2, 0);
+ temp[9] = m1.get(2, 1);
+ temp[10] = m1.get(2, 2);
+ temp[11] = m1.get(2, 3);
+
+ temp[12] = m1.get(3, 0);
+ temp[13] = m1.get(3, 1);
+ temp[14] = m1.get(3, 2);
+ temp[15] = m1.get(3, 3);
+
+ // Calculate LU decomposition: Is the matrix singular?
+ if (!luDecomposition(temp, row_perm)) {
+ // Matrix has no inverse
+ throw new SingularMatrixException();
+ }
+
+ // Perform back substitution on the identity matrix
+ for(i=0;i<16;i++) result[i] = 0.0;
+ result[0] = 1.0; result[5] = 1.0; result[10] = 1.0; result[15] = 1.0;
+ luBacksubstitution(temp, row_perm, result);
+
+ set(0, 0, (float)result[0]);
+ set(0, 1, (float)result[1]);
+ set(0, 2, (float)result[2]);
+ set(0, 3, (float)result[3]);
+
+ set(1, 0, (float)result[4]);
+ set(1, 1, (float)result[5]);
+ set(1, 2, (float)result[6]);
+ set(1, 3, (float)result[7]);
+
+ set(2, 0, (float)result[8]);
+ set(2, 1, (float)result[9]);
+ set(2, 2, (float)result[10]);
+ set(2, 3, (float)result[11]);
+
+ set(3, 0, (float)result[12]);
+ set(3, 1, (float)result[13]);
+ set(3, 2, (float)result[14]);
+ set(3, 3, (float)result[15]);
+ }
+
+ /**
+ * Given a 4x4 array "matrix0", this function replaces it with the
+ * LU decomposition of a row-wise permutation of itself. The input
+ * parameters are "matrix0" and "dimen". The array "matrix0" is also
+ * an output parameter. The vector "row_perm[4]" is an output
+ * parameter that contains the row permutations resulting from partial
+ * pivoting. The output parameter "even_row_xchg" is 1 when the
+ * number of row exchanges is even, or -1 otherwise. Assumes data
+ * type is always double.
+ *
+ * This function is similar to luDecomposition, except that it
+ * is tuned specifically for 4x4 matrices.
+ *
+ * @return true if the matrix is nonsingular, or false otherwise.
+ */
+ //
+ // Reference: Press, Flannery, Teukolsky, Vetterling,
+ // _Numerical_Recipes_in_C_, Cambridge University Press,
+ // 1988, pp 40-45.
+ //
+ static boolean luDecomposition(double[] matrix0,
+ int[] row_perm) {
+
+ double row_scale[] = new double[4];
+
+ // Determine implicit scaling information by looping over rows
+ {
+ int i, j;
+ int ptr, rs;
+ double big, temp;
+
+ ptr = 0;
+ rs = 0;
+
+ // For each row ...
+ i = 4;
+ while (i-- != 0) {
+ big = 0.0;
+
+ // For each column, find the largest element in the row
+ j = 4;
+ while (j-- != 0) {
+ temp = matrix0[ptr++];
+ temp = Math.abs(temp);
+ if (temp > big) {
+ big = temp;
+ }
+ }
+
+ // Is the matrix singular?
+ if (big == 0.0) {
+ return false;
+ }
+ row_scale[rs++] = 1.0 / big;
+ }
+ }
+
+ {
+ int j;
+ int mtx;
+
+ mtx = 0;
+
+ // For all columns, execute Crout's method
+ for (j = 0; j < 4; j++) {
+ int i, imax, k;
+ int target, p1, p2;
+ double sum, big, temp;
+
+ // Determine elements of upper diagonal matrix U
+ for (i = 0; i < j; i++) {
+ target = mtx + (4*i) + j;
+ sum = matrix0[target];
+ k = i;
+ p1 = mtx + (4*i);
+ p2 = mtx + j;
+ while (k-- != 0) {
+ sum -= matrix0[p1] * matrix0[p2];
+ p1++;
+ p2 += 4;
+ }
+ matrix0[target] = sum;
+ }
+
+ // Search for largest pivot element and calculate
+ // intermediate elements of lower diagonal matrix L.
+ big = 0.0;
+ imax = -1;
+ for (i = j; i < 4; i++) {
+ target = mtx + (4*i) + j;
+ sum = matrix0[target];
+ k = j;
+ p1 = mtx + (4*i);
+ p2 = mtx + j;
+ while (k-- != 0) {
+ sum -= matrix0[p1] * matrix0[p2];
+ p1++;
+ p2 += 4;
+ }
+ matrix0[target] = sum;
+
+ // Is this the best pivot so far?
+ if ((temp = row_scale[i] * Math.abs(sum)) >= big) {
+ big = temp;
+ imax = i;
+ }
+ }
+
+ if (imax < 0) {
+ throw new RuntimeException("Logic error: imax < 0");
+ }
+
+ // Is a row exchange necessary?
+ if (j != imax) {
+ // Yes: exchange rows
+ k = 4;
+ p1 = mtx + (4*imax);
+ p2 = mtx + (4*j);
+ while (k-- != 0) {
+ temp = matrix0[p1];
+ matrix0[p1++] = matrix0[p2];
+ matrix0[p2++] = temp;
+ }
+
+ // Record change in scale factor
+ row_scale[imax] = row_scale[j];
+ }
+
+ // Record row permutation
+ row_perm[j] = imax;
+
+ // Is the matrix singular
+ if (matrix0[(mtx + (4*j) + j)] == 0.0) {
+ return false;
+ }
+
+ // Divide elements of lower diagonal matrix L by pivot
+ if (j != (4-1)) {
+ temp = 1.0 / (matrix0[(mtx + (4*j) + j)]);
+ target = mtx + (4*(j+1)) + j;
+ i = 3 - j;
+ while (i-- != 0) {
+ matrix0[target] *= temp;
+ target += 4;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Solves a set of linear equations. The input parameters "matrix1",
+ * and "row_perm" come from luDecompostionD4x4 and do not change
+ * here. The parameter "matrix2" is a set of column vectors assembled
+ * into a 4x4 matrix of floating-point values. The procedure takes each
+ * column of "matrix2" in turn and treats it as the right-hand side of the
+ * matrix equation Ax = LUx = b. The solution vector replaces the
+ * original column of the matrix.
+ *
+ * If "matrix2" is the identity matrix, the procedure replaces its contents
+ * with the inverse of the matrix from which "matrix1" was originally
+ * derived.
+ */
+ //
+ // Reference: Press, Flannery, Teukolsky, Vetterling,
+ // _Numerical_Recipes_in_C_, Cambridge University Press,
+ // 1988, pp 44-45.
+ //
+ static void luBacksubstitution(double[] matrix1,
+ int[] row_perm,
+ double[] matrix2) {
+
+ int i, ii, ip, j, k;
+ int rp;
+ int cv, rv;
+
+ // rp = row_perm;
+ rp = 0;
+
+ // For each column vector of matrix2 ...
+ for (k = 0; k < 4; k++) {
+ // cv = &(matrix2[0][k]);
+ cv = k;
+ ii = -1;
+
+ // Forward substitution
+ for (i = 0; i < 4; i++) {
+ double sum;
+
+ ip = row_perm[rp+i];
+ sum = matrix2[cv+4*ip];
+ matrix2[cv+4*ip] = matrix2[cv+4*i];
+ if (ii >= 0) {
+ // rv = &(matrix1[i][0]);
+ rv = i*4;
+ for (j = ii; j <= i-1; j++) {
+ sum -= matrix1[rv+j] * matrix2[cv+4*j];
+ }
+ }
+ else if (sum != 0.0) {
+ ii = i;
+ }
+ matrix2[cv+4*i] = sum;
+ }
+
+ // Backsubstitution
+ // rv = &(matrix1[3][0]);
+ rv = 3*4;
+ matrix2[cv+4*3] /= matrix1[rv+3];
+
+ rv -= 4;
+ matrix2[cv+4*2] = (matrix2[cv+4*2] -
+ matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+2];
+
+ rv -= 4;
+ matrix2[cv+4*1] = (matrix2[cv+4*1] -
+ matrix1[rv+2] * matrix2[cv+4*2] -
+ matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+1];
+
+ rv -= 4;
+ matrix2[cv+4*0] = (matrix2[cv+4*0] -
+ matrix1[rv+1] * matrix2[cv+4*1] -
+ matrix1[rv+2] * matrix2[cv+4*2] -
+ matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+0];
+ }
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Matf.java b/src/net/java/joglutils/msg/math/Matf.java
new file mode 100644
index 0000000..483e246
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Matf.java
@@ -0,0 +1,166 @@
+/*
+ * 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;
+
+/** Arbitrary-size single-precision matrix class. Currently very
+ simple and only supports a few needed operations. */
+
+public class Matf {
+ private float[] data;
+ private int nCol; // number of columns
+ private int nRow; // number of columns
+
+ public Matf(int nRow, int nCol) {
+ data = new float[nRow * nCol];
+ this.nCol = nCol;
+ this.nRow = nRow;
+ }
+
+ public Matf(Matf arg) {
+ nRow = arg.nRow;
+ nCol = arg.nCol;
+ data = new float[nRow * nCol];
+ System.arraycopy(arg.data, 0, data, 0, data.length);
+ }
+
+ public int nRow() {
+ return nRow;
+ }
+
+ public int nCol() {
+ return nCol;
+ }
+
+ /** Gets the (i,j)th element of this matrix, where i is the row
+ index and j is the column index */
+ public float get(int i, int j) {
+ return data[nCol * i + j];
+ }
+
+ /** Sets the (i,j)th element of this matrix, where i is the row
+ index and j is the column index */
+ public void set(int i, int j, float val) {
+ data[nCol * i + j] = val;
+ }
+
+ /** Returns transpose of this matrix; creates new matrix */
+ public Matf transpose() {
+ Matf tmp = new Matf(nCol, nRow);
+ for (int i = 0; i < nRow; i++) {
+ for (int j = 0; j < nCol; j++) {
+ tmp.set(j, i, get(i, j));
+ }
+ }
+ return tmp;
+ }
+
+ /** Returns this * b; creates new matrix */
+ public Matf mul(Matf b) throws DimensionMismatchException {
+ if (nCol() != b.nRow())
+ throw new DimensionMismatchException();
+ Matf tmp = new Matf(nRow(), b.nCol());
+ for (int i = 0; i < nRow(); i++) {
+ for (int j = 0; j < b.nCol(); j++) {
+ float val = 0;
+ for (int t = 0; t < nCol(); t++) {
+ val += get(i, t) * b.get(t, j);
+ }
+ tmp.set(i, j, val);
+ }
+ }
+ return tmp;
+ }
+
+ /** Returns this * v, assuming v is a column vector. */
+ public Vecf mul(Vecf v) throws DimensionMismatchException {
+ if (nCol() != v.length()) {
+ throw new DimensionMismatchException();
+ }
+ Vecf out = new Vecf(nRow());
+ for (int i = 0; i < nRow(); i++) {
+ float tmp = 0;
+ for (int j = 0; j < nCol(); j++) {
+ tmp += get(i, j) * v.get(j);
+ }
+ out.set(i, tmp);
+ }
+ return out;
+ }
+
+ /** If this is a 2x2 matrix, returns it as a Mat2f. */
+ public Mat2f toMat2f() throws DimensionMismatchException {
+ if (nRow() != 2 || nCol() != 2) {
+ throw new DimensionMismatchException();
+ }
+ Mat2f tmp = new Mat2f();
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 2; j++) {
+ tmp.set(i, j, get(i, j));
+ }
+ }
+ return tmp;
+ }
+
+ /** If this is a 3x3 matrix, returns it as a Mat3f. */
+ public Mat3f toMat3f() throws DimensionMismatchException {
+ if (nRow() != 3 || nCol() != 3) {
+ throw new DimensionMismatchException();
+ }
+ Mat3f tmp = new Mat3f();
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ tmp.set(i, j, get(i, j));
+ }
+ }
+ return tmp;
+ }
+
+ /** If this is a 4x4 matrix, returns it as a Mat4f. */
+ public Mat4f toMat4f() throws DimensionMismatchException {
+ if (nRow() != 4 || nCol() != 4) {
+ throw new DimensionMismatchException();
+ }
+ Mat4f tmp = new Mat4f();
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ tmp.set(i, j, get(i, j));
+ }
+ }
+ return tmp;
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/MathUtil.java b/src/net/java/joglutils/msg/math/MathUtil.java
new file mode 100644
index 0000000..db115d2
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/MathUtil.java
@@ -0,0 +1,88 @@
+/*
+ * 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;
+
+/** Utility math routines. */
+
+public class MathUtil {
+ /** Makes an arbitrary vector perpendicular to <B>src</B> and
+ inserts it into <B>dest</B>. Returns false if the source vector
+ was equal to (0, 0, 0). */
+ public static boolean makePerpendicular(Vec3f src,
+ Vec3f dest) {
+ if ((src.x() == 0.0f) && (src.y() == 0.0f) && (src.z() == 0.0f)) {
+ return false;
+ }
+
+ if (src.x() != 0.0f) {
+ if (src.y() != 0.0f) {
+ dest.set(-src.y(), src.x(), 0.0f);
+ } else {
+ dest.set(-src.z(), 0.0f, src.x());
+ }
+ } else {
+ dest.set(1.0f, 0.0f, 0.0f);
+ }
+ return true;
+ }
+
+ /** Returns 1 if the sign of the given argument is positive; -1 if
+ negative; 0 if 0. */
+ public static int sgn(float f) {
+ if (f > 0) {
+ return 1;
+ } else if (f < 0) {
+ return -1;
+ }
+ return 0;
+ }
+
+ /** Clamps argument between min and max values. */
+ public static float clamp(float val, float min, float max) {
+ if (val < min) return min;
+ if (val > max) return max;
+ return val;
+ }
+
+ /** Clamps argument between min and max values. */
+ public static int clamp(int val, int min, int max) {
+ if (val < min) return min;
+ if (val > max) return max;
+ return val;
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/NonSquareMatrixException.java b/src/net/java/joglutils/msg/math/NonSquareMatrixException.java
new file mode 100644
index 0000000..52a37af
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/NonSquareMatrixException.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+/** Thrown to indicate a non-square matrix during an operation
+ requiring one. */
+
+public class NonSquareMatrixException extends RuntimeException {
+ public NonSquareMatrixException() {
+ super();
+ }
+
+ public NonSquareMatrixException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Plane.java b/src/net/java/joglutils/msg/math/Plane.java
new file mode 100644
index 0000000..7c34636
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Plane.java
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+/** Represents a plane in 3D space. */
+
+public class Plane {
+ /** Normalized */
+ private Vec3f normal;
+ private Vec3f point;
+ /** Constant for faster projection and intersection */
+ float c;
+
+ /** Default constructor initializes normal to (0, 1, 0) and point to
+ (0, 0, 0) */
+ public Plane() {
+ normal = new Vec3f(0, 1, 0);
+ point = new Vec3f(0, 0, 0);
+ recalc();
+ }
+
+ /** Sets all parameters of plane. Plane has normal <b>normal</b> and
+ goes through the point <b>point</b>. Normal does not need to be
+ unit length but must not be the zero vector. */
+ public Plane(Vec3f normal, Vec3f point) {
+ this.normal = new Vec3f(normal);
+ this.normal.normalize();
+ this.point = new Vec3f(point);
+ recalc();
+ }
+
+ /** Setter does some work to maintain internal caches. Normal does
+ not need to be unit length but must not be the zero vector. */
+ public void setNormal(Vec3f normal) {
+ this.normal.set(normal);
+ this.normal.normalize();
+ recalc();
+ }
+
+ /** Normal is normalized internally, so <b>normal</b> is not
+ necessarily equal to <code>plane.setNormal(normal);
+ plane.getNormal();</code> */
+ public Vec3f getNormal() {
+ return normal;
+ }
+
+ /** Setter does some work to maintain internal caches */
+ public void setPoint(Vec3f point) {
+ this.point.set(point);
+ recalc();
+ }
+
+ public Vec3f getPoint() {
+ return point;
+ }
+
+ /** Project a point onto the plane */
+ public void projectPoint(Vec3f pt,
+ Vec3f projPt) {
+ float scale = normal.dot(pt) - c;
+ projPt.set(pt.minus(normal.times(normal.dot(point) - c)));
+ }
+
+ /** Intersect a ray with the plane. Returns true if intersection occurred, false
+ otherwise. This is a two-sided ray cast. */
+ public boolean intersectRay(Vec3f rayStart,
+ Vec3f rayDirection,
+ IntersectionPoint intPt) {
+ float denom = normal.dot(rayDirection);
+ if (denom == 0)
+ return false;
+ intPt.setT((c - normal.dot(rayStart)) / denom);
+ intPt.setIntersectionPoint(rayStart.plus(rayDirection.times(intPt.getT())));
+ return true;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void recalc() {
+ c = normal.dot(point);
+ }
+}
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();
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Rotf.java b/src/net/java/joglutils/msg/math/Rotf.java
new file mode 100644
index 0000000..ed14a19
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Rotf.java
@@ -0,0 +1,309 @@
+/*
+ * 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;
+
+/** Represents a rotation in 3D space with single-precision
+ components. Uses a quaternion as the internal representation. */
+
+public class Rotf {
+ private static float EPSILON = 1.0e-7f;
+
+ // Representation is a quaternion. Element 0 is the scalar part (=
+ // cos(theta/2)), elements 1..3 the imaginary/"vector" part (=
+ // sin(theta/2) * axis).
+ private float q0;
+ private float q1;
+ private float q2;
+ private float q3;
+
+ /** Default constructor initializes to the identity quaternion */
+ public Rotf() {
+ init();
+ }
+
+ public Rotf(Rotf arg) {
+ set(arg);
+ }
+
+ /** Axis does not need to be normalized but must not be the zero
+ vector. Angle is in radians. */
+ public Rotf(Vec3f axis, float angle) {
+ set(axis, angle);
+ }
+
+ /** Creates a rotation which will rotate vector "from" into vector
+ "to". */
+ public Rotf(Vec3f from, Vec3f to) {
+ set(from, to);
+ }
+
+ /** Re-initialize this quaternion to be the identity quaternion "e"
+ (i.e., no rotation) */
+ public void init() {
+ q0 = 1;
+ q1 = q2 = q3 = 0;
+ }
+
+ /** Test for "approximate equality" -- performs componentwise test
+ to see whether difference between all components is less than
+ epsilon. */
+ public boolean withinEpsilon(Rotf arg, float epsilon) {
+ return ((Math.abs(q0 - arg.q0) < epsilon) &&
+ (Math.abs(q1 - arg.q1) < epsilon) &&
+ (Math.abs(q2 - arg.q2) < epsilon) &&
+ (Math.abs(q3 - arg.q3) < epsilon));
+ }
+
+ /** Axis does not need to be normalized but must not be the zero
+ vector. Angle is in radians. */
+ public void set(Vec3f axis, float angle) {
+ float halfTheta = angle / 2.0f;
+ q0 = (float) Math.cos(halfTheta);
+ float sinHalfTheta = (float) Math.sin(halfTheta);
+ Vec3f realAxis = new Vec3f(axis);
+ realAxis.normalize();
+ q1 = realAxis.x() * sinHalfTheta;
+ q2 = realAxis.y() * sinHalfTheta;
+ q3 = realAxis.z() * sinHalfTheta;
+ }
+
+ /** Sets this rotation to the contents of the passed one. */
+ public void set(Rotf arg) {
+ q0 = arg.q0;
+ q1 = arg.q1;
+ q2 = arg.q2;
+ q3 = arg.q3;
+ }
+
+ /** Sets this rotation to that which will rotate vector "from" into
+ vector "to". from and to do not have to be the same length. */
+ public void set(Vec3f from, Vec3f to) {
+ Vec3f axis = from.cross(to);
+ if (axis.lengthSquared() < EPSILON) {
+ init();
+ return;
+ }
+ float dotp = from.dot(to);
+ float denom = from.length() * to.length();
+ if (denom < EPSILON) {
+ init();
+ return;
+ }
+ dotp /= denom;
+ set(axis, (float) Math.acos(dotp));
+ }
+
+ /** Returns angle (in radians) and mutates the given vector to be
+ the axis. */
+ public float get(Vec3f axis) {
+ // FIXME: Is this numerically stable? Is there a better way to
+ // extract the angle from a quaternion?
+ // NOTE: remove (float) to illustrate compiler bug
+ float retval = (float) (2.0f * Math.acos(q0));
+ axis.set(q1, q2, q3);
+ float len = axis.length();
+ if (len == 0.0f) {
+ axis.set(0, 0, 1);
+ } else {
+ axis.scale(1.0f / len);
+ }
+ return retval;
+ }
+
+ /** Returns inverse of this rotation; creates a new rotation. */
+ public Rotf inverse() {
+ Rotf tmp = new Rotf(this);
+ tmp.invert();
+ return tmp;
+ }
+
+ /** Mutate this quaternion to be its inverse. This is equivalent to
+ the conjugate of the quaternion. */
+ public void invert() {
+ q1 = -q1;
+ q2 = -q2;
+ q3 = -q3;
+ }
+
+ /** Returns the length of this quaternion in four-space. */
+ public float length() {
+ return (float) Math.sqrt(lengthSquared());
+ }
+
+ /** This dotted with this */
+ public float lengthSquared() {
+ return (q0 * q0 +
+ q1 * q1 +
+ q2 * q2 +
+ q3 * q3);
+ }
+
+ /** Make this quaternion a unit quaternion again. If you are
+ composing dozens of quaternions you probably should call this
+ periodically to ensure that you have a valid rotation. */
+ public void normalize() {
+ float len = length();
+ q0 /= len;
+ q1 /= len;
+ q2 /= len;
+ q3 /= len;
+ }
+
+ /** Returns this * b, in that order; creates new rotation */
+ public Rotf times(Rotf b) {
+ Rotf tmp = new Rotf();
+ tmp.mul(this, b);
+ return tmp;
+ }
+
+ /** Compose two rotations: this = A * B in that order. NOTE that
+ because we assume a column vector representation that this
+ implies that a vector rotated by the cumulative rotation will be
+ rotated first by B, then A. NOTE: "this" must be different than
+ both a and b. */
+ public void mul(Rotf a, Rotf b) {
+ q0 = (a.q0 * b.q0 - a.q1 * b.q1 -
+ a.q2 * b.q2 - a.q3 * b.q3);
+ q1 = (a.q0 * b.q1 + a.q1 * b.q0 +
+ a.q2 * b.q3 - a.q3 * b.q2);
+ q2 = (a.q0 * b.q2 + a.q2 * b.q0 -
+ a.q1 * b.q3 + a.q3 * b.q1);
+ q3 = (a.q0 * b.q3 + a.q3 * b.q0 +
+ a.q1 * b.q2 - a.q2 * b.q1);
+ }
+
+ /** Turns this rotation into a 3x3 rotation matrix. NOTE: only
+ mutates the upper-left 3x3 of the passed Mat4f. Implementation
+ from B. K. P. Horn's <u>Robot Vision</u> textbook. */
+ public void toMatrix(Mat4f mat) {
+ float q00 = q0 * q0;
+ float q11 = q1 * q1;
+ float q22 = q2 * q2;
+ float q33 = q3 * q3;
+ // Diagonal elements
+ mat.set(0, 0, q00 + q11 - q22 - q33);
+ mat.set(1, 1, q00 - q11 + q22 - q33);
+ mat.set(2, 2, q00 - q11 - q22 + q33);
+ // 0,1 and 1,0 elements
+ float q03 = q0 * q3;
+ float q12 = q1 * q2;
+ mat.set(0, 1, 2.0f * (q12 - q03));
+ mat.set(1, 0, 2.0f * (q03 + q12));
+ // 0,2 and 2,0 elements
+ float q02 = q0 * q2;
+ float q13 = q1 * q3;
+ mat.set(0, 2, 2.0f * (q02 + q13));
+ mat.set(2, 0, 2.0f * (q13 - q02));
+ // 1,2 and 2,1 elements
+ float q01 = q0 * q1;
+ float q23 = q2 * q3;
+ mat.set(1, 2, 2.0f * (q23 - q01));
+ mat.set(2, 1, 2.0f * (q01 + q23));
+ }
+
+ /** Turns the upper left 3x3 of the passed matrix into a rotation.
+ Implementation from Watt and Watt, <u>Advanced Animation and
+ Rendering Techniques</u>.
+ @see Mat4f#getRotation */
+ public void fromMatrix(Mat4f mat) {
+ // FIXME: Should reimplement to follow Horn's advice of using
+ // eigenvector decomposition to handle roundoff error in given
+ // matrix.
+
+ float tr, s;
+ int i, j, k;
+
+ tr = mat.get(0, 0) + mat.get(1, 1) + mat.get(2, 2);
+ if (tr > 0.0) {
+ s = (float) Math.sqrt(tr + 1.0f);
+ q0 = s * 0.5f;
+ s = 0.5f / s;
+ q1 = (mat.get(2, 1) - mat.get(1, 2)) * s;
+ q2 = (mat.get(0, 2) - mat.get(2, 0)) * s;
+ q3 = (mat.get(1, 0) - mat.get(0, 1)) * s;
+ } else {
+ i = 0;
+ if (mat.get(1, 1) > mat.get(0, 0))
+ i = 1;
+ if (mat.get(2, 2) > mat.get(i, i))
+ i = 2;
+ j = (i+1)%3;
+ k = (j+1)%3;
+ s = (float) Math.sqrt( (mat.get(i, i) - (mat.get(j, j) + mat.get(k, k))) + 1.0f);
+ setQ(i+1, s * 0.5f);
+ s = 0.5f / s;
+ q0 = (mat.get(k, j) - mat.get(j, k)) * s;
+ setQ(j+1, (mat.get(j, i) + mat.get(i, j)) * s);
+ setQ(k+1, (mat.get(k, i) + mat.get(i, k)) * s);
+ }
+ }
+
+ /** Rotate a vector by this quaternion. Implementation is from
+ Horn's <u>Robot Vision</u>. NOTE: src and dest must be different
+ vectors. */
+ public void rotateVector(Vec3f src, Vec3f dest) {
+ Vec3f qVec = new Vec3f(q1, q2, q3);
+ Vec3f qCrossX = qVec.cross(src);
+ Vec3f qCrossXCrossQ = qCrossX.cross(qVec);
+ qCrossX.scale(2.0f * q0);
+ qCrossXCrossQ.scale(-2.0f);
+ dest.add(src, qCrossX);
+ dest.add(dest, qCrossXCrossQ);
+ }
+
+ /** Rotate a vector by this quaternion, returning newly-allocated result. */
+ public Vec3f rotateVector(Vec3f src) {
+ Vec3f tmp = new Vec3f();
+ rotateVector(src, tmp);
+ return tmp;
+ }
+
+ public String toString() {
+ return "(" + q0 + ", " + q1 + ", " + q2 + ", " + q3 + ")";
+ }
+
+ private void setQ(int i, float val) {
+ switch (i) {
+ case 0: q0 = val; break;
+ case 1: q1 = val; break;
+ case 2: q2 = val; break;
+ case 3: q3 = val; break;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/SingularMatrixException.java b/src/net/java/joglutils/msg/math/SingularMatrixException.java
new file mode 100644
index 0000000..8fefb80
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/SingularMatrixException.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+/** Thrown to indicate a singular matrix during an inversion or
+ related operation. */
+
+public class SingularMatrixException extends RuntimeException {
+ public SingularMatrixException() {
+ super();
+ }
+
+ public SingularMatrixException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Sphere.java b/src/net/java/joglutils/msg/math/Sphere.java
new file mode 100644
index 0000000..232d81b
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Sphere.java
@@ -0,0 +1,183 @@
+/*
+ * 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;
+
+/** Represents a sphere. */
+
+public class Sphere {
+ private Vec3f center = new Vec3f();
+ private float radius;
+ private float radSq;
+
+ /** Default constructor creates a sphere with center (0, 0, 0) and
+ radius 0 */
+ public Sphere() {
+ makeEmpty();
+ }
+
+ public Sphere(Vec3f center, float radius) {
+ set(center, radius);
+ }
+
+ public Sphere(Sphere other) {
+ set(other);
+ }
+
+ public Sphere(Box3f box) {
+ set(box);
+ }
+
+ /** Re-initialize this sphere to center (0, 0, 0) and radius 0 */
+ public void makeEmpty() {
+ center.set(0, 0, 0);
+ radius = radSq = 0;
+ }
+
+ public void setCenter(Vec3f center) { this.center.set(center); }
+ public Vec3f getCenter() { return center; }
+
+ public void setRadius(float radius) { this.radius = radius;
+ radSq = radius * radius; }
+ public float getRadius() { return radius; }
+
+ public void set(Vec3f center, float radius) {
+ setCenter(center); setRadius(radius);
+ }
+ /** Returns radius and mutates passed "center" vector */
+ float get(Vec3f center) {
+ center.set(this.center); return radius;
+ }
+
+ /** Sets the parameters of this sphere to those of the given one */
+ public void set(Sphere other) {
+ set(other.center, other.radius);
+ }
+
+ /** Sets this sphere to encompass the given box */
+ public void set(Box3f box) {
+ Vec3f max = box.getMax();
+ Vec3f ctr = box.getCenter();
+ Vec3f diff = max.minus(ctr);
+ set(ctr, diff.length());
+ }
+
+ /** Mutate this sphere to encompass both itself and the argument.
+ Ignores zero-size arguments. */
+ public void extendBy(Sphere arg) {
+ if ((radius == 0.0f) || (arg.radius == 0.0f))
+ return;
+ // FIXME: This algorithm is a quick hack -- minimum bounding
+ // sphere of a set of other spheres is a well studied problem, but
+ // not by me
+ Vec3f diff = arg.center.minus(center);
+ if (diff.lengthSquared() == 0.0f) {
+ setRadius(Math.max(radius, arg.radius));
+ return;
+ }
+ IntersectionPoint[] intPt = new IntersectionPoint[4];
+ for (int i = 0; i < intPt.length; i++) {
+ intPt[i] = new IntersectionPoint();
+ }
+ int numIntersections;
+ numIntersections = intersectRay(center, diff, intPt[0], intPt[1]);
+ assert numIntersections == 2;
+ numIntersections = intersectRay(center, diff, intPt[2], intPt[3]);
+ assert numIntersections == 2;
+ IntersectionPoint minIntPt = intPt[0];
+ IntersectionPoint maxIntPt = intPt[0];
+ // Find minimum and maximum t values, take associated intersection
+ // points, find midpoint and half length of line segment -->
+ // center and radius.
+ for (int i = 0; i < 4; i++) {
+ if (intPt[i].getT() < minIntPt.getT()) {
+ minIntPt = intPt[i];
+ } else if (intPt[i].getT() > maxIntPt.getT()) {
+ maxIntPt = intPt[i];
+ }
+ }
+ // Compute the average -- this is the new center
+ center.add(minIntPt.getIntersectionPoint(),
+ maxIntPt.getIntersectionPoint());
+ center.scale(0.5f);
+ // Compute half the length -- this is the radius
+ setRadius(
+ 0.5f *
+ minIntPt.getIntersectionPoint().
+ minus(maxIntPt.getIntersectionPoint()).
+ length()
+ );
+ }
+
+ /** Intersect a ray with the sphere. This is a one-sided ray
+ cast. Mutates one or both of intPt0 and intPt1. Returns number
+ of intersections which occurred. */
+ int intersectRay(Vec3f rayStart,
+ Vec3f rayDirection,
+ IntersectionPoint intPt0,
+ IntersectionPoint intPt1) {
+ // Solve quadratic equation
+ float a = rayDirection.lengthSquared();
+ if (a == 0.0)
+ return 0;
+ float b = 2.0f * (rayStart.dot(rayDirection) - rayDirection.dot(center));
+ Vec3f tempDiff = center.minus(rayStart);
+ float c = tempDiff.lengthSquared() - radSq;
+ float disc = b * b - 4 * a * c;
+ if (disc < 0.0f)
+ return 0;
+ int numIntersections;
+ if (disc == 0.0f)
+ numIntersections = 1;
+ else
+ numIntersections = 2;
+ intPt0.setT((0.5f * (-1.0f * b + (float) Math.sqrt(disc))) / a);
+ if (numIntersections == 2)
+ intPt1.setT((0.5f * (-1.0f * b - (float) Math.sqrt(disc))) / a);
+ Vec3f tmp = new Vec3f(rayDirection);
+ tmp.scale(intPt0.getT());
+ tmp.add(tmp, rayStart);
+ intPt0.setIntersectionPoint(tmp);
+ if (numIntersections == 2) {
+ tmp.set(rayDirection);
+ tmp.scale(intPt1.getT());
+ tmp.add(tmp, rayStart);
+ intPt1.setIntersectionPoint(tmp);
+ }
+ return numIntersections;
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Vec2f.java b/src/net/java/joglutils/msg/math/Vec2f.java
new file mode 100644
index 0000000..a50338d
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Vec2f.java
@@ -0,0 +1,184 @@
+/*
+ * 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;
+
+/** 2-element single-precision vector */
+
+public class Vec2f {
+ private float x;
+ private float y;
+
+ public Vec2f() {}
+
+ public Vec2f(Vec2f arg) {
+ this(arg.x, arg.y);
+ }
+
+ public Vec2f(float x, float y) {
+ set(x, y);
+ }
+
+ public Vec2f copy() {
+ return new Vec2f(this);
+ }
+
+ public void set(Vec2f arg) {
+ set(arg.x, arg.y);
+ }
+
+ public void set(float x, float y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ /** Sets the ith component, 0 <= i < 2 */
+ public void set(int i, float val) {
+ switch (i) {
+ case 0: x = val; break;
+ case 1: y = val; break;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /** Gets the ith component, 0 <= i < 2 */
+ public float get(int i) {
+ switch (i) {
+ case 0: return x;
+ case 1: return y;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public float x() { return x; }
+ public float y() { return y; }
+
+ public void setX(float x) { this.x = x; }
+ public void setY(float y) { this.y = y; }
+
+ public float dot(Vec2f arg) {
+ return x * arg.x + y * arg.y;
+ }
+
+ public float length() {
+ return (float) Math.sqrt(lengthSquared());
+ }
+
+ public float lengthSquared() {
+ return this.dot(this);
+ }
+
+ public void normalize() {
+ float len = length();
+ if (len == 0.0f) return;
+ scale(1.0f / len);
+ }
+
+ /** Returns this * val; creates new vector */
+ public Vec2f times(float val) {
+ Vec2f tmp = new Vec2f(this);
+ tmp.scale(val);
+ return tmp;
+ }
+
+ /** this = this * val */
+ public void scale(float val) {
+ x *= val;
+ y *= val;
+ }
+
+ /** Returns this + arg; creates new vector */
+ public Vec2f plus(Vec2f arg) {
+ Vec2f tmp = new Vec2f();
+ tmp.add(this, arg);
+ return tmp;
+ }
+
+ /** this = this + b */
+ public void add(Vec2f b) {
+ add(this, b);
+ }
+
+ /** this = a + b */
+ public void add(Vec2f a, Vec2f b) {
+ x = a.x + b.x;
+ y = a.y + b.y;
+ }
+
+ /** Returns this + s * arg; creates new vector */
+ public Vec2f addScaled(float s, Vec2f arg) {
+ Vec2f tmp = new Vec2f();
+ tmp.addScaled(this, s, arg);
+ return tmp;
+ }
+
+ /** this = a + s * b */
+ public void addScaled(Vec2f a, float s, Vec2f b) {
+ x = a.x + s * b.x;
+ y = a.y + s * b.y;
+ }
+
+ /** Returns this - arg; creates new vector */
+ public Vec2f minus(Vec2f arg) {
+ Vec2f tmp = new Vec2f();
+ tmp.sub(this, arg);
+ return tmp;
+ }
+
+ /** this = this - b */
+ public void sub(Vec2f b) {
+ sub(this, b);
+ }
+
+ /** this = a - b */
+ public void sub(Vec2f a, Vec2f b) {
+ x = a.x - b.x;
+ y = a.y - b.y;
+ }
+
+ public Vecf toVecf() {
+ Vecf out = new Vecf(2);
+ for (int i = 0; i < 2; i++) {
+ out.set(i, get(i));
+ }
+ return out;
+ }
+
+ public String toString() {
+ return "(" + x + ", " + y + ")";
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Vec3d.java b/src/net/java/joglutils/msg/math/Vec3d.java
new file mode 100644
index 0000000..aa3f4b8
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Vec3d.java
@@ -0,0 +1,206 @@
+/*
+ * 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;
+
+/** 3-element double-precision vector */
+
+public class Vec3d {
+ private double x;
+ private double y;
+ private double z;
+
+ public Vec3d() {}
+
+ public Vec3d(Vec3d arg) {
+ set(arg);
+ }
+
+ public Vec3d(double x, double y, double z) {
+ set(x, y, z);
+ }
+
+ public Vec3d copy() {
+ return new Vec3d(this);
+ }
+
+ /** Convert to single-precision */
+ public Vec3f toFloat() {
+ return new Vec3f((float) x, (float) y, (float) z);
+ }
+
+ public void set(Vec3d arg) {
+ set(arg.x, arg.y, arg.z);
+ }
+
+ public void set(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ /** Sets the ith component, 0 <= i < 3 */
+ public void set(int i, double val) {
+ switch (i) {
+ case 0: x = val; break;
+ case 1: y = val; break;
+ case 2: z = val; break;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /** Gets the ith component, 0 <= i < 3 */
+ public double get(int i) {
+ switch (i) {
+ case 0: return x;
+ case 1: return y;
+ case 2: return z;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public double x() { return x; }
+ public double y() { return y; }
+ public double z() { return z; }
+
+ public void setX(double x) { this.x = x; }
+ public void setY(double y) { this.y = y; }
+ public void setZ(double z) { this.z = z; }
+
+ public double dot(Vec3d arg) {
+ return x * arg.x + y * arg.y + z * arg.z;
+ }
+
+ public double length() {
+ return Math.sqrt(lengthSquared());
+ }
+
+ public double lengthSquared() {
+ return this.dot(this);
+ }
+
+ public void normalize() {
+ double len = length();
+ if (len == 0.0) return;
+ scale(1.0f / len);
+ }
+
+ /** Returns this * val; creates new vector */
+ public Vec3d times(double val) {
+ Vec3d tmp = new Vec3d(this);
+ tmp.scale(val);
+ return tmp;
+ }
+
+ /** this = this * val */
+ public void scale(double val) {
+ x *= val;
+ y *= val;
+ z *= val;
+ }
+
+ /** Returns this + arg; creates new vector */
+ public Vec3d plus(Vec3d arg) {
+ Vec3d tmp = new Vec3d();
+ tmp.add(this, arg);
+ return tmp;
+ }
+
+ /** this = this + b */
+ public void add(Vec3d b) {
+ add(this, b);
+ }
+
+ /** this = a + b */
+ public void add(Vec3d a, Vec3d b) {
+ x = a.x + b.x;
+ y = a.y + b.y;
+ z = a.z + b.z;
+ }
+
+ /** Returns this + s * arg; creates new vector */
+ public Vec3d addScaled(double s, Vec3d arg) {
+ Vec3d tmp = new Vec3d();
+ tmp.addScaled(this, s, arg);
+ return tmp;
+ }
+
+ /** this = a + s * b */
+ public void addScaled(Vec3d a, double s, Vec3d b) {
+ x = a.x + s * b.x;
+ y = a.y + s * b.y;
+ z = a.z + s * b.z;
+ }
+
+ /** Returns this - arg; creates new vector */
+ public Vec3d minus(Vec3d arg) {
+ Vec3d tmp = new Vec3d();
+ tmp.sub(this, arg);
+ return tmp;
+ }
+
+ /** this = this - b */
+ public void sub(Vec3d b) {
+ sub(this, b);
+ }
+
+ /** this = a - b */
+ public void sub(Vec3d a, Vec3d b) {
+ x = a.x - b.x;
+ y = a.y - b.y;
+ z = a.z - b.z;
+ }
+
+ /** Returns this cross arg; creates new vector */
+ public Vec3d cross(Vec3d arg) {
+ Vec3d tmp = new Vec3d();
+ tmp.cross(this, arg);
+ return tmp;
+ }
+
+ /** this = a cross b. NOTE: "this" must be a different vector than
+ both a and b. */
+ public void cross(Vec3d a, Vec3d b) {
+ x = a.y * b.z - a.z * b.y;
+ y = a.z * b.x - a.x * b.z;
+ z = a.x * b.y - a.y * b.x;
+ }
+
+ public String toString() {
+ return "(" + x + ", " + y + ", " + z + ")";
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Vec3f.java b/src/net/java/joglutils/msg/math/Vec3f.java
new file mode 100644
index 0000000..7e18d9c
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Vec3f.java
@@ -0,0 +1,230 @@
+/*
+ * 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;
+
+/** 3-element single-precision vector */
+
+public class Vec3f {
+ public static final Vec3f X_AXIS = new Vec3f( 1, 0, 0);
+ public static final Vec3f Y_AXIS = new Vec3f( 0, 1, 0);
+ public static final Vec3f Z_AXIS = new Vec3f( 0, 0, 1);
+ public static final Vec3f NEG_X_AXIS = new Vec3f(-1, 0, 0);
+ public static final Vec3f NEG_Y_AXIS = new Vec3f( 0, -1, 0);
+ public static final Vec3f NEG_Z_AXIS = new Vec3f( 0, 0, -1);
+
+ private float x;
+ private float y;
+ private float z;
+
+ public Vec3f() {}
+
+ public Vec3f(Vec3f arg) {
+ set(arg);
+ }
+
+ public Vec3f(float x, float y, float z) {
+ set(x, y, z);
+ }
+
+ public Vec3f copy() {
+ return new Vec3f(this);
+ }
+
+ /** Convert to double-precision */
+ public Vec3d toDouble() {
+ return new Vec3d(x, y, z);
+ }
+
+ public void set(Vec3f arg) {
+ set(arg.x, arg.y, arg.z);
+ }
+
+ public void set(float x, float y, float z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ /** Sets the ith component, 0 <= i < 3 */
+ public void set(int i, float val) {
+ switch (i) {
+ case 0: x = val; break;
+ case 1: y = val; break;
+ case 2: z = val; break;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /** Gets the ith component, 0 <= i < 3 */
+ public float get(int i) {
+ switch (i) {
+ case 0: return x;
+ case 1: return y;
+ case 2: return z;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public float x() { return x; }
+ public float y() { return y; }
+ public float z() { return z; }
+
+ public void setX(float x) { this.x = x; }
+ public void setY(float y) { this.y = y; }
+ public void setZ(float z) { this.z = z; }
+
+ public float dot(Vec3f arg) {
+ return x * arg.x + y * arg.y + z * arg.z;
+ }
+
+ public float length() {
+ return (float) Math.sqrt(lengthSquared());
+ }
+
+ public float lengthSquared() {
+ return this.dot(this);
+ }
+
+ public void normalize() {
+ float len = length();
+ if (len == 0.0f) return;
+ scale(1.0f / len);
+ }
+
+ /** Returns this * val; creates new vector */
+ public Vec3f times(float val) {
+ Vec3f tmp = new Vec3f(this);
+ tmp.scale(val);
+ return tmp;
+ }
+
+ /** this = this * val */
+ public void scale(float val) {
+ x *= val;
+ y *= val;
+ z *= val;
+ }
+
+ /** Returns this + arg; creates new vector */
+ public Vec3f plus(Vec3f arg) {
+ Vec3f tmp = new Vec3f();
+ tmp.add(this, arg);
+ return tmp;
+ }
+
+ /** this = this + b */
+ public void add(Vec3f b) {
+ add(this, b);
+ }
+
+ /** this = a + b */
+ public void add(Vec3f a, Vec3f b) {
+ x = a.x + b.x;
+ y = a.y + b.y;
+ z = a.z + b.z;
+ }
+
+ /** Returns this + s * arg; creates new vector */
+ public Vec3f addScaled(float s, Vec3f arg) {
+ Vec3f tmp = new Vec3f();
+ tmp.addScaled(this, s, arg);
+ return tmp;
+ }
+
+ /** this = a + s * b */
+ public void addScaled(Vec3f a, float s, Vec3f b) {
+ x = a.x + s * b.x;
+ y = a.y + s * b.y;
+ z = a.z + s * b.z;
+ }
+
+ /** Returns this - arg; creates new vector */
+ public Vec3f minus(Vec3f arg) {
+ Vec3f tmp = new Vec3f();
+ tmp.sub(this, arg);
+ return tmp;
+ }
+
+ /** this = this - b */
+ public void sub(Vec3f b) {
+ sub(this, b);
+ }
+
+ /** this = a - b */
+ public void sub(Vec3f a, Vec3f b) {
+ x = a.x - b.x;
+ y = a.y - b.y;
+ z = a.z - b.z;
+ }
+
+ /** Returns this cross arg; creates new vector */
+ public Vec3f cross(Vec3f arg) {
+ Vec3f tmp = new Vec3f();
+ tmp.cross(this, arg);
+ return tmp;
+ }
+
+ /** this = a cross b. NOTE: "this" must be a different vector than
+ both a and b. */
+ public void cross(Vec3f a, Vec3f b) {
+ x = a.y * b.z - a.z * b.y;
+ y = a.z * b.x - a.x * b.z;
+ z = a.x * b.y - a.y * b.x;
+ }
+
+ /** Sets each component of this vector to the product of the
+ component with the corresponding component of the argument
+ vector. */
+ public void componentMul(Vec3f arg) {
+ x *= arg.x;
+ y *= arg.y;
+ z *= arg.z;
+ }
+
+ public Vecf toVecf() {
+ Vecf out = new Vecf(3);
+ for (int i = 0; i < 3; i++) {
+ out.set(i, get(i));
+ }
+ return out;
+ }
+
+ public String toString() {
+ return "(" + x + ", " + y + ", " + z + ")";
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Vec4f.java b/src/net/java/joglutils/msg/math/Vec4f.java
new file mode 100644
index 0000000..8b120e0
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Vec4f.java
@@ -0,0 +1,214 @@
+/*
+ * 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;
+
+/** 4-element single-precision vector */
+
+public class Vec4f {
+ private float x;
+ private float y;
+ private float z;
+ private float w;
+
+ public Vec4f() {}
+
+ public Vec4f(Vec4f arg) {
+ set(arg);
+ }
+
+ public Vec4f(float x, float y, float z, float w) {
+ set(x, y, z, w);
+ }
+
+ public Vec4f copy() {
+ return new Vec4f(this);
+ }
+
+ public void set(Vec4f arg) {
+ set(arg.x, arg.y, arg.z, arg.w);
+ }
+
+ public void set(float x, float y, float z, float w) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ }
+
+ /** Sets the ith component, 0 <= i < 4 */
+ public void set(int i, float val) {
+ switch (i) {
+ case 0: x = val; break;
+ case 1: y = val; break;
+ case 2: z = val; break;
+ case 3: w = val; break;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /** Gets the ith component, 0 <= i < 4 */
+ public float get(int i) {
+ switch (i) {
+ case 0: return x;
+ case 1: return y;
+ case 2: return z;
+ case 3: return w;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public float x() { return x; }
+ public float y() { return y; }
+ public float z() { return z; }
+ public float w() { return w; }
+
+ public void setX(float x) { this.x = x; }
+ public void setY(float y) { this.y = y; }
+ public void setZ(float z) { this.z = z; }
+ public void setW(float w) { this.w = w; }
+
+ public float dot(Vec4f arg) {
+ return x * arg.x + y * arg.y + z * arg.z + w * arg.w;
+ }
+
+ public float length() {
+ return (float) Math.sqrt(lengthSquared());
+ }
+
+ public float lengthSquared() {
+ return this.dot(this);
+ }
+
+ public void normalize() {
+ float len = length();
+ if (len == 0.0f) return;
+ scale(1.0f / len);
+ }
+
+ /** Returns this * val; creates new vector */
+ public Vec4f times(float val) {
+ Vec4f tmp = new Vec4f(this);
+ tmp.scale(val);
+ return tmp;
+ }
+
+ /** this = this * val */
+ public void scale(float val) {
+ x *= val;
+ y *= val;
+ z *= val;
+ w *= val;
+ }
+
+ /** Returns this + arg; creates new vector */
+ public Vec4f plus(Vec4f arg) {
+ Vec4f tmp = new Vec4f();
+ tmp.add(this, arg);
+ return tmp;
+ }
+
+ /** this = this + b */
+ public void add(Vec4f b) {
+ add(this, b);
+ }
+
+ /** this = a + b */
+ public void add(Vec4f a, Vec4f b) {
+ x = a.x + b.x;
+ y = a.y + b.y;
+ z = a.z + b.z;
+ w = a.w + b.w;
+ }
+
+ /** Returns this + s * arg; creates new vector */
+ public Vec4f addScaled(float s, Vec4f arg) {
+ Vec4f tmp = new Vec4f();
+ tmp.addScaled(this, s, arg);
+ return tmp;
+ }
+
+ /** this = a + s * b */
+ public void addScaled(Vec4f a, float s, Vec4f b) {
+ x = a.x + s * b.x;
+ y = a.y + s * b.y;
+ z = a.z + s * b.z;
+ w = a.w + s * b.w;
+ }
+
+ /** Returns this - arg; creates new vector */
+ public Vec4f minus(Vec4f arg) {
+ Vec4f tmp = new Vec4f();
+ tmp.sub(this, arg);
+ return tmp;
+ }
+
+ /** this = this - b */
+ public void sub(Vec4f b) {
+ sub(this, b);
+ }
+
+ /** this = a - b */
+ public void sub(Vec4f a, Vec4f b) {
+ x = a.x - b.x;
+ y = a.y - b.y;
+ z = a.z - b.z;
+ w = a.w - b.w;
+ }
+
+ /** Sets each component of this vector to the product of the
+ component with the corresponding component of the argument
+ vector. */
+ public void componentMul(Vec4f arg) {
+ x *= arg.x;
+ y *= arg.y;
+ z *= arg.z;
+ w *= arg.w;
+ }
+
+ public Vecf toVecf() {
+ Vecf out = new Vecf(4);
+ for (int i = 0; i < 4; i++) {
+ out.set(i, get(i));
+ }
+ return out;
+ }
+
+ public String toString() {
+ return "(" + x + ", " + y + ", " + z + ")";
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Vecf.java b/src/net/java/joglutils/msg/math/Vecf.java
new file mode 100644
index 0000000..070bfab
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Vecf.java
@@ -0,0 +1,94 @@
+/*
+ * 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;
+
+/** Arbitrary-length single-precision vector class. Currently very
+ simple and only supports a few needed operations. */
+
+public class Vecf {
+ private float[] data;
+
+ public Vecf(int n) {
+ data = new float[n];
+ }
+
+ public Vecf(Vecf arg) {
+ data = new float[arg.data.length];
+ System.arraycopy(arg.data, 0, data, 0, data.length);
+ }
+
+ public int length() {
+ return data.length;
+ }
+
+ public float get(int i) {
+ return data[i];
+ }
+
+ public void set(int i, float val) {
+ data[i] = val;
+ }
+
+ public Vec2f toVec2f() throws DimensionMismatchException {
+ if (length() != 2)
+ throw new DimensionMismatchException();
+ Vec2f out = new Vec2f();
+ for (int i = 0; i < 2; i++) {
+ out.set(i, get(i));
+ }
+ return out;
+ }
+
+ public Vec3f toVec3f() throws DimensionMismatchException {
+ if (length() != 3)
+ throw new DimensionMismatchException();
+ Vec3f out = new Vec3f();
+ for (int i = 0; i < 3; i++) {
+ out.set(i, get(i));
+ }
+ return out;
+ }
+
+ public Veci toInt() {
+ Veci out = new Veci(length());
+ for (int i = 0; i < length(); i++) {
+ out.set(i, (int) get(i));
+ }
+ return out;
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/Veci.java b/src/net/java/joglutils/msg/math/Veci.java
new file mode 100644
index 0000000..00302e9
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/Veci.java
@@ -0,0 +1,94 @@
+/*
+ * 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;
+
+/** Arbitrary-length integer vector class. Currently very simple and
+ only supports a few needed operations. */
+
+public class Veci {
+ private int[] data;
+
+ public Veci(int n) {
+ data = new int[n];
+ }
+
+ public Veci(Veci arg) {
+ data = new int[arg.data.length];
+ System.arraycopy(arg.data, 0, data, 0, data.length);
+ }
+
+ public int length() {
+ return data.length;
+ }
+
+ public int get(int i) {
+ return data[i];
+ }
+
+ public void set(int i, int val) {
+ data[i] = val;
+ }
+
+ public Vec2f toVec2f() throws DimensionMismatchException {
+ if (length() != 2)
+ throw new DimensionMismatchException();
+ Vec2f out = new Vec2f();
+ for (int i = 0; i < 2; i++) {
+ out.set(i, get(i));
+ }
+ return out;
+ }
+
+ public Vec3f toVec3f() throws DimensionMismatchException {
+ if (length() != 3)
+ throw new DimensionMismatchException();
+ Vec3f out = new Vec3f();
+ for (int i = 0; i < 3; i++) {
+ out.set(i, get(i));
+ }
+ return out;
+ }
+
+ public Vecf toVecf() {
+ Vecf out = new Vecf(length());
+ for (int i = 0; i < length(); i++) {
+ out.set(i, get(i));
+ }
+ return out;
+ }
+}
diff --git a/src/net/java/joglutils/msg/math/package.html b/src/net/java/joglutils/msg/math/package.html
new file mode 100644
index 0000000..be2d23c
--- /dev/null
+++ b/src/net/java/joglutils/msg/math/package.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<body>
+
+Linear algebra and classes implementing basic 3D operations.
+
+</body>
+</html>
diff --git a/src/net/java/joglutils/msg/misc/State.java b/src/net/java/joglutils/msg/misc/State.java
new file mode 100644
index 0000000..c718f71
--- /dev/null
+++ b/src/net/java/joglutils/msg/misc/State.java
@@ -0,0 +1,220 @@
+/*
+ * 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.misc;
+
+import java.util.*;
+
+import net.java.joglutils.msg.elements.*;
+
+/** Represents a collection of state elements, which are updated by
+ actions during scene graph traversal. */
+
+public class State {
+ // Provides each concrete Element subclass a unique slot in the State.
+ // Note that subclasses of concrete Element subclasses share the
+ // slot with their parent class. Which one is used for a given
+ // Action is decided by which elements are enabled for that action.
+ private static int curStateIndex = 0;
+
+ // The representation of the State.
+ private List<Element> elements = new ArrayList<Element>();
+
+ // The default enabled elements for this State. The State instances
+ // created by each Action instance point to the default enabled
+ // elements; this is where the individual Action's State is
+ // initialized from.
+ // Note that this mechanism is needed because different actions
+ // install different Element subclasses (i.e., ModelMatrixElement
+ // vs. GLModelMatrixElement) into the same element slot.
+ private State defaults;
+
+ // A linked list of elements touched since the last push, used to
+ // reduce the number of elements that need to be accessed during a
+ // pop() operation.
+ private Element topElement;
+
+ // The depth at which we are operating, to implement lazy pushing
+ // and popping of state elements
+ private int depth;
+
+ /** This constructor should only be used for the default State for a
+ given Action subclass. */
+ public State() {
+ }
+
+ /** This constructor should be used to create the concrete State
+ instances for each Action instance. The default State given
+ should be that for the particular Action class. */
+ public State(State defaults) {
+ this.defaults = defaults;
+ // Do a push() to ensure that we always have a non-null and
+ // pristine entry at the top of each stack
+ push();
+ }
+
+ /** Gets the state element at the given index. */
+ public Element getElement(StateIndex index) {
+ // The comments in the Open Inventor implementation indicate that
+ // a bug that was found and fixed was that this method must not be
+ // called in the process of popping the state. This assert
+ // attempts to guard against that happening.
+ assert depth >= ((topElement == null) ? 0 : topElement.getDepth()) :
+ "Elements must not be changed while the state is being popped (element being changed: " +
+ elements.get(index.getIndex()).getClass().getName() + ").";
+
+ int idx = index.getIndex();
+
+ if (defaults == null) {
+ // This State contains the defaults for a particular Action
+ // class. Don't do anything fancy -- just return the element at
+ // the particular index.
+ if (idx >= elements.size()) {
+ return null;
+ }
+ return elements.get(idx);
+ }
+
+ if (idx >= elements.size()) {
+ // Expand list to the needed size
+ while (idx >= elements.size()) {
+ elements.add(null);
+ }
+ }
+
+ Element elt = elements.get(idx);
+ if (elt == null) {
+ // Lazily create a copy of the default and put it in place
+ elt = defaults.getElement(index);
+ if (elt == null) {
+ throw new RuntimeException("Error in initialization of default element for state index " + idx);
+ }
+ elt = elt.newInstance();
+ elt.setDepth(0);
+ elements.set(idx, elt);
+ }
+
+ // If element is not at current depth, we have to push a new
+ // element on the stack
+ if (elt.getDepth() < depth) {
+ // FIXME: consider doubly-linked-list scheme as in Inventor to
+ // avoid excessive object creation during scene graph traversal
+ Element newElt = elt.newInstance();
+ newElt.setNextInStack(elt);
+ newElt.setDepth(depth);
+ // Add newly-created element to the all-element stack
+ newElt.setNext(topElement);
+ topElement = newElt;
+ elements.set(idx, newElt);
+ // Call push on new element in case it has side effects
+ newElt.push(this);
+ // Return new element
+ elt = newElt;
+ }
+
+ return elt;
+ }
+
+ /** Sets the element at the given state index. This should only be
+ used by Action, Element and Node subclasses to initialize the
+ default state for a given Action class. */
+ public void setElement(StateIndex index, Element element) {
+ if (defaults != null) {
+ throw new RuntimeException("Misuse of setElement(); should only be used to initialize default State for an Action");
+ }
+ int idx = index.getIndex();
+ if (idx >= elements.size()) {
+ while (idx >= elements.size()) {
+ elements.add(null);
+ }
+ }
+ elements.set(idx, element);
+ }
+
+ /** Pushes (saves) the current state until a pop() restores it. The
+ push is done lazily: this just increments the depth in the
+ state. When an element is accessed with getElement() and its
+ depth is less than the current depth, it is then pushed
+ individually. */
+ public void push() {
+ ++depth;
+ }
+
+ /** Pops the state, restoring the state to just before the last push(). */
+ public void pop() {
+ --depth;
+
+ Element poppedElt = null;
+ Element nextInStack = null;
+
+ // As in Open Inventor, the popping is done in two passes. This is
+ // apparently needed if Open Inventor-style caching is added in
+ // the future. The first pass calls pop() on all of the elements
+ // that will be popped; the second pass actually removes the
+ // elements from their respective stacks.
+ for (poppedElt = topElement;
+ poppedElt != null && poppedElt.getDepth() > depth;
+ poppedElt = poppedElt.getNext()) {
+
+ // Find the next element in the same stack as the element being
+ // popped. This element will become the new top of that stack.
+ nextInStack = poppedElt.getNextInStack();
+
+ // Give the new top element in the stack a chance to update
+ // things. Pass old element instance just in case.
+ poppedElt.getNextInStack().pop(this, poppedElt);
+ }
+
+ // Remove all such elements from their respective stacks
+ while (topElement != null && topElement.getDepth() > depth) {
+ poppedElt = topElement;
+
+ // Remove from main element list
+ topElement = topElement.getNext();
+
+ // Remove from element stack
+ elements.set(poppedElt.getStateIndex().getIndex(), poppedElt.getNextInStack());
+ }
+ }
+
+ /** Should be called by Element subclasses to register themselves
+ with the State class. This provides them a StateIndex with which
+ they can index into the State. */
+ public static synchronized StateIndex registerElementType() {
+ return new StateIndex(curStateIndex++);
+ }
+}
diff --git a/src/net/java/joglutils/msg/misc/StateIndex.java b/src/net/java/joglutils/msg/misc/StateIndex.java
new file mode 100644
index 0000000..982a4c7
--- /dev/null
+++ b/src/net/java/joglutils/msg/misc/StateIndex.java
@@ -0,0 +1,56 @@
+/*
+ * 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.misc;
+
+/** Represents an index into the global state managed by the State
+ class. This class is an opaque data type that is created by
+ calling {@link State#registerElementType
+ State.registerElementType()}. */
+
+public class StateIndex {
+ private int index;
+
+ /** Constructor is package-private to avoid leakage of representation */
+ StateIndex(int index) {
+ this.index = index;
+ }
+
+ int getIndex() {
+ return index;
+ }
+}
diff --git a/src/net/java/joglutils/msg/misc/SystemTime.java b/src/net/java/joglutils/msg/misc/SystemTime.java
new file mode 100644
index 0000000..6342d58
--- /dev/null
+++ b/src/net/java/joglutils/msg/misc/SystemTime.java
@@ -0,0 +1,108 @@
+/*
+ * 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.misc;
+
+/** Implementation of {@link Time Time} interface based on {@link
+ java.lang.System#currentTimeMillis System.currentTimeMillis}.
+ Performs smoothing internally to avoid effects of poor granularity
+ of currentTimeMillis on Windows platform in particular. */
+
+public class SystemTime implements Time {
+ private static final int DEFAULT_NUM_SMOOTHING_SAMPLES = 10;
+ private long[] samples = new long[DEFAULT_NUM_SMOOTHING_SAMPLES];
+ private int numSmoothingSamples;
+ private int curSmoothingSample; // Index of current sample to be replaced
+ private long baseTime = System.currentTimeMillis();
+ private boolean hasCurTime;
+ private double curTime;
+ private double deltaT;
+
+ /** Sets number of smoothing samples. Defaults to 10. Note that
+ there may be a discontinuity in the reported time after a call
+ to this method. */
+ public void setNumSmoothingSamples(int num) {
+ samples = new long[num];
+ numSmoothingSamples = 0;
+ curSmoothingSample = 0;
+ hasCurTime = false;
+ }
+
+ /** Returns number of smoothing samples; default is 10. */
+ public int getNumSmoothingSamples() {
+ return samples.length;
+ }
+
+ /** Rebases this timer. After very long periods of time the
+ resolution of this timer may decrease; the application can call
+ this to restore higher resolution. Note that there may be a
+ discontinuity in the reported time after a call to this
+ method. */
+ public void rebase() {
+ baseTime = System.currentTimeMillis();
+ setNumSmoothingSamples(samples.length);
+ }
+
+ public void update() {
+ long tmpTime = System.currentTimeMillis();
+ long diffSinceBase = tmpTime - baseTime;
+ samples[curSmoothingSample] = diffSinceBase;
+ curSmoothingSample = (curSmoothingSample + 1) % samples.length;
+ numSmoothingSamples = Math.min(1 + numSmoothingSamples, samples.length);
+ // Average of samples is current time
+ double newCurTime = 0.0;
+ for (int i = 0; i < numSmoothingSamples; i++) {
+ newCurTime += samples[i];
+ }
+ newCurTime /= (1000.0f * numSmoothingSamples);
+ double lastTime = curTime;
+ if (!hasCurTime) {
+ lastTime = newCurTime;
+ hasCurTime = true;
+ }
+ deltaT = newCurTime - lastTime;
+ curTime = newCurTime;
+ }
+
+ public double time() {
+ return curTime;
+ }
+
+ public double deltaT() {
+ return deltaT;
+ }
+}
diff --git a/src/net/java/joglutils/msg/misc/Time.java b/src/net/java/joglutils/msg/misc/Time.java
new file mode 100644
index 0000000..a0428c3
--- /dev/null
+++ b/src/net/java/joglutils/msg/misc/Time.java
@@ -0,0 +1,50 @@
+/*
+ * 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.misc;
+
+/** Interface abstracting concept of time from applications. */
+
+public interface Time {
+ /** Updates this Time object. Call update() each frame before
+ calling the accessor routines. */
+ public void update();
+ /** Time in seconds since beginning of application. */
+ public double time();
+ /** Time in seconds since last update. */
+ public double deltaT();
+}
diff --git a/src/net/java/joglutils/msg/misc/package.html b/src/net/java/joglutils/msg/misc/package.html
new file mode 100644
index 0000000..56976d3
--- /dev/null
+++ b/src/net/java/joglutils/msg/misc/package.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<body>
+
+Defines miscellaneous classes most users will not need to interact
+with. Includes the State class which encapsulates Elements and is used
+by Actions.
+
+</body>
+</html>
diff --git a/src/net/java/joglutils/msg/nodes/Blend.java b/src/net/java/joglutils/msg/nodes/Blend.java
new file mode 100644
index 0000000..18cd5a6
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/Blend.java
@@ -0,0 +1,168 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.actions.*;
+import net.java.joglutils.msg.math.*;
+
+/** Provides control over OpenGL blending modes. */
+
+public class Blend extends Node {
+ private boolean enabled;
+ private Vec4f blendColor = new Vec4f();
+ private int srcFunc = ONE;
+ private int destFunc = ZERO;
+ private int blendEquation = FUNC_ADD;
+
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int ZERO = 1;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int ONE = 2;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int SRC_COLOR = 3;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int ONE_MINUS_SRC_COLOR = 4;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int DST_COLOR = 5;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int ONE_MINUS_DST_COLOR = 6;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int SRC_ALPHA = 7;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int ONE_MINUS_SRC_ALPHA = 8;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int DST_ALPHA = 9;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int ONE_MINUS_DST_ALPHA = 10;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int SRC_ALPHA_SATURATE = 11;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int CONSTANT_COLOR = 12;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int ONE_MINUS_CONSTANT_COLOR = 13;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int CONSTANT_ALPHA = 14;
+ /** One of the blend functions. See the OpenGL documentation for glBlendFunc for more details. */
+ public static final int ONE_MINUS_CONSTANT_ALPHA = 15;
+
+ /** One of the blend equations. See the OpenGL documentation for glBlendEquation for more details. */
+ public static final int FUNC_ADD = 1;
+ /** One of the blend equations. See the OpenGL documentation for glBlendEquation for more details. */
+ public static final int FUNC_SUBTRACT = 2;
+ /** One of the blend equations. See the OpenGL documentation for glBlendEquation for more details. */
+ public static final int FUNC_REVERSE_SUBTRACT = 3;
+ /** One of the blend equations. See the OpenGL documentation for glBlendEquation for more details. */
+ public static final int MIN = 4;
+ /** One of the blend equations. See the OpenGL documentation for glBlendEquation for more details. */
+ public static final int MAX = 5;
+
+ /** Sets whether blending is enabled. Defaults to false. */
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ /** Returns whether blending is enabled. Defaults to false. */
+ public boolean getEnabled() {
+ return enabled;
+ }
+
+ /** Sets the source blending function to one of ZERO, ONE,
+ SRC_COLOR, ONE_MINUS_SRC_COLOR, DST_COLOR, ONE_MINUS_DST_COLOR,
+ SRC_ALPHA, ONE_MINUS_SRC_ALPHA, DST_ALPHA, ONE_MINUS_DST_ALPHA,
+ SRC_ALPHA_SATURATE, CONSTANT_COLOR, ONE_MINUS_CONSTANT_COLOR,
+ CONSTANT_ALPHA, or ONE_MINUS_CONSTANT_ALPHA. The default is ONE. */
+ public void setSourceFunc(int func) {
+ if (func < ZERO || func > ONE_MINUS_CONSTANT_ALPHA) {
+ throw new IllegalArgumentException("Illegal source blending function " + func);
+ }
+ srcFunc = func;
+ }
+
+ /** Returns the source blending function. The default is ONE. */
+ public int getSourceFunc() {
+ return srcFunc;
+ }
+
+ /** Sets the destination blending function to one of ZERO, ONE,
+ SRC_COLOR, ONE_MINUS_SRC_COLOR, DST_COLOR, ONE_MINUS_DST_COLOR,
+ SRC_ALPHA, ONE_MINUS_SRC_ALPHA, DST_ALPHA, ONE_MINUS_DST_ALPHA,
+ SRC_ALPHA_SATURATE, CONSTANT_COLOR, ONE_MINUS_CONSTANT_COLOR,
+ CONSTANT_ALPHA, or ONE_MINUS_CONSTANT_ALPHA. The default is
+ ZERO. */
+ public void setDestFunc(int func) {
+ if (func < ZERO || func > ONE_MINUS_CONSTANT_ALPHA) {
+ throw new IllegalArgumentException("Illegal destination blending function " + func);
+ }
+ destFunc = func;
+ }
+
+ /** Returns the destination blending function. The default is ZERO. */
+ public int getDestFunc() {
+ return destFunc;
+ }
+
+ /** Sets the blending equation to one of FUNC_ADD, FUNC_SUBTRACT,
+ FUNC_REVERSE_SUBTRACT, MIN, or MAX. Defaults to FUNC_ADD. */
+ public void setBlendEquation(int equation) {
+ if (equation < FUNC_ADD || equation > MAX) {
+ throw new IllegalArgumentException("Illegal blending equation " + equation);
+ }
+ this.blendEquation = equation;
+ }
+
+ /** Returns the blending equation. Defaults to FUNC_ADD. */
+ public int getBlendEquation() {
+ return blendEquation;
+ }
+
+ /** Sets the blending color; see the documentation for glBlendColor
+ for more details. Defaults to [0, 0, 0, 0]. */
+ public void setBlendColor(Vec4f color) {
+ blendColor.set(color);
+ }
+
+ /** Gets the blending color; see the documentation for glBlendColor
+ for more details. Defaults to [0, 0, 0, 0]. */
+ public Vec4f getBlendColor() {
+ return blendColor;
+ }
+
+ public void doAction(Action action) {
+ action.visit(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/Camera.java b/src/net/java/joglutils/msg/nodes/Camera.java
new file mode 100644
index 0000000..9d1f965
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/Camera.java
@@ -0,0 +1,126 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.math.*;
+
+/** Represents a camera which is used to view the scene. The camera
+ should be added to the scene graph before the geometry it is
+ intended to view. <P>
+
+ The camera's default parameters are a position at (0, 0, 1),
+ facing down the negative Z axis with the Y axis up, an aspect
+ ratio of 1.0, a near distance of 1.0, a far distance of 100.0, and
+ a focal distance of 10.0.
+*/
+
+public abstract class Camera extends Node {
+ private Vec3f position;
+ private Rotf orientation;
+ private float aspectRatio = 1.0f;
+ private float nearDistance = 1.0f;
+ private float farDistance = 100.0f;
+ private float focalDistance = 10.0f;
+
+ protected boolean projDirty;
+ protected boolean viewDirty;
+ protected Mat4f projMatrix;
+ protected Mat4f viewMatrix;
+
+ public Camera() {
+ position = new Vec3f(0, 0, 1);
+ orientation = new Rotf();
+ // orientation = new Rotf(new Vec3f(0, 1, 0), (float) (Math.PI));
+
+ projMatrix = new Mat4f();
+ viewMatrix = new Mat4f();
+ projDirty = true;
+ viewDirty = true;
+ }
+
+ /** Sets the position of the camera. */
+ public void setPosition(Vec3f position) { this.position.set(position); viewDirty = true; }
+ /** Returns the position of the camera. */
+ public Vec3f getPosition() { return position; }
+
+ /** Sets the orientation of the camera. */
+ public void setOrientation(Rotf orientation) { this.orientation.set(orientation); viewDirty = true; }
+ /** Returns the orientation of the camera. */
+ public Rotf getOrientation() { return orientation; }
+
+ /** Sets the aspect ratio of the camera. */
+ public void setAspectRatio(float aspectRatio) { this.aspectRatio = aspectRatio; projDirty = true; }
+ /** Returns the aspect ratio of the camera. */
+ public float getAspectRatio() { return aspectRatio; }
+
+ /** Sets the distance from the eye point to the near clipping plane. */
+ public void setNearDistance(float nearDistance) { this.nearDistance = nearDistance; projDirty = true; }
+ /** Returns the distance from the eye point to the near clipping plane. */
+ public float getNearDistance() { return nearDistance; }
+
+ /** Sets the distance from the eye point to the far clipping plane. */
+ public void setFarDistance(float farDistance) { this.farDistance = farDistance; projDirty = true; }
+ /** Returns the distance from the eye point to the far clipping plane. */
+ public float getFarDistance() { return farDistance; }
+
+ /** Sets the distance from the eye point to the focal point of the
+ scene. This is only used for mouse-based interaction with the
+ scene and is not factored in to the rendering process. */
+ public void setFocalDistance(float focalDistance) { this.focalDistance = focalDistance; projDirty = true; }
+ /** Returns the distance from the eye point to the focal point of
+ the scene. This is only used for mouse-based interaction with
+ the scene and is not factored in to the rendering process. */
+ public float getFocalDistance() { return focalDistance; }
+
+ /** Returns the viewing matrix associated with this camera's parameters. */
+ public Mat4f getViewingMatrix() {
+ if (viewDirty) {
+ viewMatrix.makeIdent();
+ viewDirty = false;
+
+ viewMatrix.setRotation(getOrientation());
+ viewMatrix.setTranslation(getPosition());
+ viewMatrix.invertRigid();
+ }
+
+ return viewMatrix;
+ }
+
+ /** Returns the projection matrix associated with this camera's parameters. */
+ public abstract Mat4f getProjectionMatrix();
+}
diff --git a/src/net/java/joglutils/msg/nodes/Color4.java b/src/net/java/joglutils/msg/nodes/Color4.java
new file mode 100644
index 0000000..d6568e3
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/Color4.java
@@ -0,0 +1,95 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.actions.*;
+import net.java.joglutils.msg.collections.*;
+
+/** Represents a set of 4-valued colors which are applied on a
+ per-vertex basis to any drawn polygons. Currently the color can
+ only be bound to one material parameter of the fixed-function
+ OpenGL pipeline, defaulting to "ambient and diffuse". <P>
+
+ For correct rendering results, the colors stored in this node
+ should have their alpha premultiplied; in other words, the red,
+ green, and blue (x, y, and z components of the stored vectors)
+ should be multiplied by the alpha value (the w component) before
+ storing them in this node.
+*/
+
+public class Color4 extends Node {
+ private Vec4fCollection data;
+
+ // private int colorBinding = AMBIENT_AND_DIFFUSE;
+
+ /******
+
+ * Note: these aren't needed until we have lighting
+
+ // FIXME: factor this out into a separate ColorBinding node
+ public static final int EMISSION = 1;
+ public static final int AMBIENT = 2;
+ public static final int DIFFUSE = 3;
+ public static final int SPECULAR = 4;
+ public static final int AMBIENT_AND_DIFFUSE = 5;
+
+ public void setColorBinding(int colorBinding) {
+ if (binding < EMISSION || binding > AMBIENT_AND_DIFFUSE) {
+ throw new IllegalArgumentException("Illegal color binding " + binding);
+ }
+ this.colorBinding = colorBinding;
+ }
+
+ public int getColorBinding() {
+ return colorBinding;
+ }
+
+ */
+
+ public void setData(Vec4fCollection data) {
+ this.data = data;
+ }
+
+ public Vec4fCollection getData() {
+ return data;
+ }
+
+ public void doAction(Action action) {
+ action.visit(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/Coordinate3.java b/src/net/java/joglutils/msg/nodes/Coordinate3.java
new file mode 100644
index 0000000..4e2b94b
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/Coordinate3.java
@@ -0,0 +1,62 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.actions.*;
+import net.java.joglutils.msg.collections.*;
+
+/** Represents a set of 3-dimensional vertices which can be assembled
+ into shapes. */
+
+public class Coordinate3 extends Node {
+ private Vec3fCollection data;
+
+ /** Sets the coordinate data in this node. */
+ public void setData(Vec3fCollection data) {
+ this.data = data;
+ }
+
+ /** Returns the coordinate data in this node. */
+ public Vec3fCollection getData() {
+ return data;
+ }
+
+ public void doAction(Action action) {
+ action.visit(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/Group.java b/src/net/java/joglutils/msg/nodes/Group.java
new file mode 100644
index 0000000..f9a961b
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/Group.java
@@ -0,0 +1,124 @@
+/*
+ * 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.nodes;
+
+import java.util.*;
+
+import net.java.joglutils.msg.actions.*;
+
+/** A node which manages other Node instances. */
+
+public class Group extends Node {
+ private List<Node> children = new ArrayList<Node>();
+
+ /** Append a child node to the list of children nodes this group node is managing. */
+ public void addChild(Node child) {
+ children.add(child);
+ }
+
+ /** Adds a child so that it becomes the one with the given index. */
+ public void insertChild(Node child, int index) {
+ children.add(index, child);
+ }
+
+ /** Returns the child node with the given index. */
+ public Node getChild(int index) {
+ return children.get(index);
+ }
+
+ /** Finds the index of given child within the group. Returns -1 if not found. */
+ public int findChild(Node node) {
+ return children.indexOf(node);
+ }
+
+ /** Returns number of children. */
+ public int getNumChildren() {
+ return children.size();
+ }
+
+ /** Removes the child with given index from the group.
+
+ @throws IndexOutOfBoundsException if the index is less than 0 or
+ greater than the number of children
+ */
+ public void removeChild(int index) throws IndexOutOfBoundsException {
+ children.remove(index);
+ }
+
+ /** Removes the given child from the group. This is a convenience
+ method equivalent to calling {@link #findChild findChild} and,
+ if the node is found, passing the index to {@link #removeChild
+ removeChild}.
+ */
+ public void removeChild(Node node) {
+ int idx = findChild(node);
+ if (idx >= 0)
+ removeChild(idx);
+ }
+
+ /** Removes all children from this Group node. */
+ public void removeAllChildren() {
+ children.clear();
+ }
+
+ /** Replaces the child at the given index with the new child.
+
+ @throws IndexOutOfBoundsException if the index is less than 0 or
+ greater than the number of children
+ */
+ public void replaceChild(int index, Node newChild) throws IndexOutOfBoundsException {
+ removeChild(index);
+ insertChild(newChild, index);
+ }
+
+ /** Replaces the old child with the new child. This is a convenience
+ method. It will simply call {@link #findChild findChild} with
+ oldChild as argument, and call replaceChild(int, SoNode*) if the
+ child is found. */
+ public void replaceChild(Node oldChild, Node newChild) {
+ int idx = findChild(oldChild);
+ if (idx >= 0)
+ replaceChild(idx, newChild);
+ }
+
+ public void doAction(Action action) {
+ for (int i = 0; i < getNumChildren(); i++) {
+ action.apply(getChild(i));
+ }
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/IndexedTriangleSet.java b/src/net/java/joglutils/msg/nodes/IndexedTriangleSet.java
new file mode 100644
index 0000000..d2932c8
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/IndexedTriangleSet.java
@@ -0,0 +1,67 @@
+/*
+ * 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.nodes;
+
+import java.nio.*;
+
+import net.java.joglutils.msg.actions.*;
+
+/** An IndexedTriangleSet assembles the coordinates specified by a
+ Coordinate3 node, and any auxiliary nodes such as a
+ TextureCoordinate2 node, into a set of triangles by indexing into
+ the pools of coordinates set up by these other nodes. (NOTE:
+ (FIXME) rendering support for this node is not yet
+ implemented.) */
+
+public class IndexedTriangleSet extends Node {
+ private IntBuffer indices;
+
+ /** Sets the indices this node uses to group vertices into triangles. */
+ public void setIndices(IntBuffer indices) {
+ this.indices = indices;
+ }
+
+ /** Returns the indices this node uses to group vertices into triangles. */
+ public IntBuffer getIndices() {
+ return indices;
+ }
+
+ public void doAction(Action action) {
+ action.visit(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/Node.java b/src/net/java/joglutils/msg/nodes/Node.java
new file mode 100644
index 0000000..6fc4eb9
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/Node.java
@@ -0,0 +1,52 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.actions.*;
+
+/** The base class for all nodes in the scene graph. */
+
+public class Node {
+
+ /** This is an internal API not intended for public use. To apply an
+ action to the scene graph or a portion of the scene graph, use
+ {@link net.java.joglutils.msg.actions.Action#apply
+ Action.apply}. */
+ public void doAction(Action action) {
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/PerspectiveCamera.java b/src/net/java/joglutils/msg/nodes/PerspectiveCamera.java
new file mode 100644
index 0000000..b72507a
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/PerspectiveCamera.java
@@ -0,0 +1,97 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.actions.*;
+import net.java.joglutils.msg.math.*;
+
+/** Represents a camera utilizing a perspective projection. <P>
+
+ The default height angle is Math.PI / 4 radians (45 degrees),
+ meaning that the camera has a total vertical field of view of 90
+ degrees.
+*/
+
+public class PerspectiveCamera extends Camera {
+ private static final float DEFAULT_HEIGHT_ANGLE = (float) (Math.PI / 4);
+ // Amount the most recently set height angle differed from the default
+ private float vertFOVScale = 1.0f;
+
+ public Mat4f getProjectionMatrix() {
+ if (projDirty) {
+ projMatrix.makeIdent();
+ projDirty = false;
+
+ // Recompute matrix based on current parameters
+ float zNear = getNearDistance();
+ float zFar = getFarDistance();
+ float deltaZ = zFar - zNear;
+ float aspect = getAspectRatio();
+ float radians = vertFOVScale * DEFAULT_HEIGHT_ANGLE;
+ float sine = (float) Math.sin(radians);
+ if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
+ return projMatrix;
+ }
+
+ float cotangent = (float) Math.cos(radians) / sine;
+ projMatrix.set(0, 0, cotangent / aspect);
+ projMatrix.set(1, 1, cotangent);
+ projMatrix.set(2, 2, -(zFar + zNear) / deltaZ);
+ projMatrix.set(3, 2, -1);
+ projMatrix.set(2, 3, -2 * zNear * zFar / deltaZ);
+ projMatrix.set(3, 3, 0);
+ }
+
+ return projMatrix;
+ }
+
+ /** Sets the height angle of this perspective camera. */
+ public void setHeightAngle(float heightAngle) {
+ vertFOVScale = heightAngle / DEFAULT_HEIGHT_ANGLE;
+ projDirty = true;
+ }
+
+ /** Returns the height angle of this perspective camera. */
+ public float getHeightAngle() {
+ return vertFOVScale * DEFAULT_HEIGHT_ANGLE;
+ }
+
+ public void doAction(Action action) {
+ action.visit(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/Separator.java b/src/net/java/joglutils/msg/nodes/Separator.java
new file mode 100644
index 0000000..c60ba45
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/Separator.java
@@ -0,0 +1,52 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.actions.*;
+
+/** Represents a push / pop of OpenGL state, "separating" the
+ sub-graph below this separator from the nodes which follow it in
+ the graph. */
+
+public class Separator extends Group {
+ public void doAction(Action action) {
+ action.visitPre(this);
+ super.doAction(action);
+ action.visitPost(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/Texture2.java b/src/net/java/joglutils/msg/nodes/Texture2.java
new file mode 100644
index 0000000..441c2f5
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/Texture2.java
@@ -0,0 +1,139 @@
+/*
+ * 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.nodes;
+
+import java.awt.image.*;
+import java.io.*;
+import java.net.*;
+
+import javax.media.opengl.*;
+import com.sun.opengl.util.texture.*;
+
+import net.java.joglutils.msg.actions.*;
+
+/** Represents a two-dimensional texture. */
+
+public class Texture2 extends Node {
+ private TextureData data;
+ private Texture texture;
+ private int texEnvMode = MODULATE;
+ private boolean dirty;
+
+ /** Represents the OpenGL MODULATE texture environment mode. */
+ public static final int MODULATE = 1;
+ /** Represents the OpenGL DECAL texture environment mode. */
+ public static final int DECAL = 2;
+ /** Represents the OpenGL BLEND texture environment mode. */
+ public static final int BLEND = 3;
+ /** Represents the OpenGL REPLACE texture environment mode. */
+ public static final int REPLACE = 4;
+
+ /** Initializes this texture from the given file. No OpenGL work is
+ done during this call; it is done lazily when the Texture is
+ fetched. */
+ public void setTexture(File file, boolean mipmap, String fileSuffix) throws IOException {
+ data = TextureIO.newTextureData(file, mipmap, fileSuffix);
+ dirty = true;
+ }
+
+ /** Initializes this texture from the given InputStream. No OpenGL
+ work is done during this call; it is done lazily when the
+ Texture is fetched. */
+ public void setTexture(InputStream stream, boolean mipmap, String fileSuffix) throws IOException {
+ data = TextureIO.newTextureData(stream, mipmap, fileSuffix);
+ dirty = true;
+ }
+
+ /** Initializes this texture from the given URL. No OpenGL work is
+ done during this call; it is done lazily when the Texture is
+ fetched. */
+ public void setTexture(URL url, boolean mipmap, String fileSuffix) throws IOException {
+ data = TextureIO.newTextureData(url, mipmap, fileSuffix);
+ dirty = true;
+ }
+
+ /** Initializes this texture from the given BufferedImage. No OpenGL
+ work is done during this call; it is done lazily when the
+ Texture is fetched. */
+ public void setTexture(BufferedImage image, boolean mipmap) {
+ data = TextureIO.newTextureData(image, mipmap);
+ dirty = true;
+ }
+
+ /** Initializes this texture from the given TextureData. No OpenGL
+ work is done during this call; it is done lazily when the
+ Texture is fetched. */
+ public void setTexture(TextureData data) {
+ this.data = data;
+ dirty = true;
+ }
+
+ /** Fetches the Texture object associated with this Texture2 node.
+ An OpenGL context must be current at the time this method is
+ called or a GLException will be thrown. */
+ public Texture getTexture() throws GLException {
+ if (dirty) {
+ if (texture != null) {
+ texture.dispose();
+ texture = null;
+ }
+ texture = TextureIO.newTexture(data);
+ data = null;
+ dirty = false;
+ }
+ return texture;
+ }
+
+ /** Sets the texture environment mode. Default is MODULATE. */
+ public void setTexEnvMode(int mode) {
+ if (mode < MODULATE || mode > REPLACE) {
+ throw new IllegalArgumentException("Illegal texture environment mode");
+ }
+ this.texEnvMode = mode;
+ }
+
+ /** Returns the texture environment mode: one of MODULATE, DECAL,
+ BLEND, or REPLACE. */
+ public int getTexEnvMode() {
+ return texEnvMode;
+ }
+
+ public void doAction(Action action) {
+ action.visit(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/TextureCoordinate2.java b/src/net/java/joglutils/msg/nodes/TextureCoordinate2.java
new file mode 100644
index 0000000..ed4ecf8
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/TextureCoordinate2.java
@@ -0,0 +1,62 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.actions.*;
+import net.java.joglutils.msg.collections.*;
+
+/** Represents a set of 2-dimensional texture coordinates which can be
+ used to texture geometric shapes. */
+
+public class TextureCoordinate2 extends Node {
+ private Vec2fCollection data;
+
+ /** Sets the texture coordinate data in this node. */
+ public void setData(Vec2fCollection data) {
+ this.data = data;
+ }
+
+ /** Returns the texture coordinate data in this node. */
+ public Vec2fCollection getData() {
+ return data;
+ }
+
+ public void doAction(Action action) {
+ action.visit(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/Transform.java b/src/net/java/joglutils/msg/nodes/Transform.java
new file mode 100644
index 0000000..0faf8e6
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/Transform.java
@@ -0,0 +1,66 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.actions.*;
+import net.java.joglutils.msg.math.*;
+
+/** Represents a generalized 4x4 matrix transformation. */
+
+public class Transform extends Node {
+ private Mat4f transform;
+
+ public Transform() {
+ transform = new Mat4f();
+ transform.makeIdent();
+ }
+
+ /** Sets the transformation in thie node. */
+ public void setTransform(Mat4f transform) {
+ this.transform.set(transform);
+ }
+
+ /** Returns the transformation in thie node. */
+ public Mat4f getTransform() {
+ return transform;
+ }
+
+ public void doAction(Action action) {
+ action.visit(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/TriangleSet.java b/src/net/java/joglutils/msg/nodes/TriangleSet.java
new file mode 100644
index 0000000..775c622
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/TriangleSet.java
@@ -0,0 +1,62 @@
+/*
+ * 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.nodes;
+
+import net.java.joglutils.msg.actions.*;
+
+/** A TriangleSet assembles the coordinates specified by a Coordinate3
+ node, and any auxiliary nodes such as a TextureCoordinate2 node,
+ into a set of triangles. */
+
+public class TriangleSet extends Node {
+ private int numTriangles;
+
+ /** Sets the number of triangles this TriangleSet references. */
+ public void setNumTriangles(int numTriangles) {
+ this.numTriangles = numTriangles;
+ }
+
+ /** Returns the number of triangles this TriangleSet references. */
+ public int getNumTriangles() {
+ return numTriangles;
+ }
+
+ public void doAction(Action action) {
+ action.visit(this);
+ }
+}
diff --git a/src/net/java/joglutils/msg/nodes/package.html b/src/net/java/joglutils/msg/nodes/package.html
new file mode 100644
index 0000000..a7ce71e
--- /dev/null
+++ b/src/net/java/joglutils/msg/nodes/package.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<body>
+
+The primary package of the MSG library, defining the node types in the scene graph.
+
+</body>
+</html>
diff --git a/src/net/java/joglutils/msg/overview.html b/src/net/java/joglutils/msg/overview.html
new file mode 100644
index 0000000..828dc12
--- /dev/null
+++ b/src/net/java/joglutils/msg/overview.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title>The Minimal Scene Graph (MSG)</title>
+</head>
+<body>
+<h2>Overview</h2>
+
+<P>
+
+The Minimal Scene Graph (MSG) is a small, lightweight 3D scene graph
+library layered on top of the <a href="http://jogl.dev.java.net">Java(tm)
+Binding to the OpenGL(r) API</a> (JOGL). MSG is heavily inspired by
+the Open Inventor(tm) library developed by Silicon Graphics, Inc. and
+derives most of its concepts and internal structure from this library,
+which was released in open-source form in 2000. Many implementation
+decisions were informed by studying the Open Inventor source code.
+
+</P>
+<P>
+
+MSG is more free-form in style than many contemporary scene graphs.
+The traversal order of the scene graph is significant, and occurs in
+top-down, left-to-right order. Nodes placed in the scene graph affect
+the global state when they are traversed. When geometry is rendered,
+it acquires its visual characteristics from the current settings in
+the global state. Actions are applied to nodes to cause operations
+such as rendering.
+
+</P>
+<P>
+
+Group nodes collect children nodes underneath them, but have no effect
+on the global state, which propagates both upward and downward through
+them. Separator nodes, which are a subclass of Group, prevent state
+changes underneath them from propagating out and affecting nodes which
+follow them in the graph. This allows them to be used as an effective
+means of collecting reusable pieces of scene graph structure. Global
+state propagates downward through Separators.
+
+</P>
+<P>
+
+The current set of nodes is minimal (as indicated by the name of the
+library) and the current set of actions is incomplete.
+
+</P>
+
+</body>
+</html>
diff --git a/src/net/java/joglutils/msg/test/DisplayShelf.java b/src/net/java/joglutils/msg/test/DisplayShelf.java
new file mode 100644
index 0000000..73a63de
--- /dev/null
+++ b/src/net/java/joglutils/msg/test/DisplayShelf.java
@@ -0,0 +1,433 @@
+/*
+ * 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.test;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.DisplayMode;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.event.*;
+import java.awt.image.*;
+import java.net.*;
+import java.util.*;
+import javax.imageio.*;
+import javax.swing.*;
+import javax.swing.event.*;
+
+import javax.media.opengl.*;
+
+import net.java.joglutils.msg.actions.*;
+import net.java.joglutils.msg.collections.*;
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.misc.*;
+import net.java.joglutils.msg.nodes.*;
+
+/** A test implementing a 3D display shelf component. */
+
+public class DisplayShelf extends Container {
+ private GLCanvas canvas;
+
+ private float DEFAULT_ASPECT_RATIO = 0.665f;
+ // This also affects the spacing
+ private float DEFAULT_HEIGHT = 1.5f;
+
+ // The camera
+ private PerspectiveCamera camera;
+
+ static class TitleGraph {
+ String url;
+ Transform xform = new Transform();
+ Texture2 texture = new Texture2();
+ Coordinate3 coords = new Coordinate3();
+
+ TitleGraph(String url) {
+ this.url = url;
+ }
+ }
+
+ private Group root;
+ private String[] images;
+ private List<TitleGraph> titles = new ArrayList<TitleGraph>();
+ private int targetIndex;
+ // This encodes both the current position and the animation alpha
+ private float currentIndex;
+ // If the difference between the current index and target index is >
+ // EPSILON, then we will continue repainting
+ private static final float EPSILON = 1.0e-3f;
+ private SystemTime time;
+ private boolean animating;
+ // A scale factor for the animation speed
+ private static final float ANIM_SCALE_FACTOR = 3.0f;
+ // The rotation angle of the titles
+ private static final float ROT_ANGLE = (float) Math.toRadians(60);
+ // Constant rotations
+ private static final Rotf POS_ANGLE = new Rotf(Vec3f.Y_AXIS, ROT_ANGLE);
+ private static final Rotf NEG_ANGLE = new Rotf(Vec3f.Y_AXIS, -ROT_ANGLE);
+
+ private void computeCoords(Coordinate3 coordNode, float aspectRatio) {
+ Vec3fCollection coords = coordNode.getData();
+ if (coords == null) {
+ coords = new Vec3fCollection();
+ Vec3f zero = new Vec3f();
+ for (int i = 0; i < 6; i++) {
+ coords.add(zero);
+ }
+ coordNode.setData(coords);
+ }
+ // Now compute the actual values
+ Vec3f lowerLeft = new Vec3f(-0.5f * DEFAULT_HEIGHT * aspectRatio, 0, 0);
+ Vec3f lowerRight = new Vec3f( 0.5f * DEFAULT_HEIGHT * aspectRatio, 0, 0);
+ Vec3f upperLeft = new Vec3f(-0.5f * DEFAULT_HEIGHT * aspectRatio, DEFAULT_HEIGHT, 0);
+ Vec3f upperRight = new Vec3f( 0.5f * DEFAULT_HEIGHT * aspectRatio, DEFAULT_HEIGHT, 0);
+ // First triangle
+ coords.set(0, upperRight);
+ coords.set(1, upperLeft);
+ coords.set(2, lowerLeft);
+ // Second triangle
+ coords.set(3, upperRight);
+ coords.set(4, lowerLeft);
+ coords.set(5, lowerRight);
+ }
+
+ private void startLoading() {
+ final List<TitleGraph> queuedGraphs = new ArrayList<TitleGraph>();
+ queuedGraphs.addAll(titles);
+
+ new Thread(new Runnable() {
+ public void run() {
+ while (queuedGraphs.size() > 0) {
+ TitleGraph graph = queuedGraphs.remove(0);
+ BufferedImage img = null;
+ try {
+ img = ImageIO.read(new URL(graph.url));
+ } catch (Exception e) {
+ System.out.println("Exception loading " + graph.url + ":");
+ e.printStackTrace();
+ }
+ if (img != null) {
+ graph.texture.setTexture(img, false);
+ // Figure out the new aspect ratio based on the image's width and height
+ float aspectRatio = (float) img.getWidth() / (float) img.getHeight();
+ // Compute new coordinates
+ computeCoords(graph.coords, aspectRatio);
+ // Schedule a repaint
+ canvas.repaint();
+ }
+ }
+ }
+ }).start();
+ }
+
+ private void setTargetIndex(int index) {
+ this.targetIndex = index;
+ if (!animating) {
+ time.rebase();
+ }
+ canvas.repaint();
+ }
+
+ private boolean recompute(boolean force) {
+ if (!force) {
+ if (Math.abs(targetIndex - currentIndex) < EPSILON)
+ return false;
+ }
+
+ time.update();
+ float deltaT = (float) time.deltaT();
+
+ // Make the animation speed independent of frame rate
+ currentIndex = currentIndex + (targetIndex - currentIndex) * deltaT * ANIM_SCALE_FACTOR;
+
+ // Now recompute the position of the camera
+ camera.setPosition(new Vec3f(currentIndex, 0.5f * DEFAULT_HEIGHT, DEFAULT_HEIGHT));
+
+ // Now recompute the orientations of each title
+ int firstIndex = (int) Math.floor(currentIndex);
+ int secondIndex = (int) Math.ceil(currentIndex);
+
+ float alpha = currentIndex - firstIndex;
+
+ int idx = 0;
+ for (TitleGraph graph : titles) {
+ if (idx < firstIndex) {
+ graph.xform.getTransform().setRotation(POS_ANGLE);
+ graph.xform.getTransform().setTranslation(new Vec3f(idx, 0, 0));
+ } else if (idx > secondIndex) {
+ graph.xform.getTransform().setRotation(NEG_ANGLE);
+ graph.xform.getTransform().setTranslation(new Vec3f(idx, 0, 0));
+ } else if (idx == firstIndex) {
+ // Interpolate
+ graph.xform.getTransform().setRotation(new Rotf(Vec3f.Y_AXIS, alpha * ROT_ANGLE));
+ graph.xform.getTransform().setTranslation(new Vec3f(idx, 0, (1.0f - alpha) * 0.4f * DEFAULT_HEIGHT));
+ } else {
+ // Interpolate
+ graph.xform.getTransform().setRotation(new Rotf(Vec3f.Y_AXIS, (1.0f - alpha) * -ROT_ANGLE));
+ graph.xform.getTransform().setTranslation(new Vec3f(idx, 0, alpha * 0.4f * DEFAULT_HEIGHT));
+ }
+
+ ++idx;
+ }
+
+ return true;
+ }
+
+ public DisplayShelf(Group root, String[] images) {
+ this.images = images;
+ this.root = root;
+ time = new SystemTime();
+ time.rebase();
+ setLayout(new BorderLayout());
+ camera = new PerspectiveCamera();
+ camera.setNearDistance(0.1f);
+ camera.setFarDistance(20.0f);
+ canvas = new GLCanvas();
+ canvas.addGLEventListener(new Listener());
+ add(canvas, BorderLayout.CENTER);
+ final JSlider slider = new JSlider(0, images.length - 1, 0);
+ slider.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ setTargetIndex(slider.getValue());
+ }
+ });
+ add(slider, BorderLayout.SOUTH);
+ }
+
+ class Listener implements GLEventListener {
+ private GLRenderAction ra = new GLRenderAction();
+
+ public void init(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+
+ // Build the scene graph
+ root.removeAllChildren();
+
+ // The images
+ Separator imageRoot = new Separator();
+
+ // The mirrored images, under the floor
+ Separator mirrorRoot = new Separator();
+
+ Transform mirrorXform = new Transform();
+ // Mirror vertically
+ mirrorXform.getTransform().set(1, 1, -1.0f);
+ mirrorRoot.addChild(mirrorXform);
+ // Assume we know what we're doing here with setting per-vertex
+ // colors for each piece of geometry in one shot
+ Color4 colorNode = new Color4();
+ Vec4fCollection colors = new Vec4fCollection();
+ Vec4f fadeTop = new Vec4f(0.75f, 0.75f, 0.75f, 0.75f);
+ Vec4f fadeBot = new Vec4f(0.25f, 0.25f, 0.25f, 0.25f);
+ // First triangle
+ colors.add(fadeTop);
+ colors.add(fadeTop);
+ colors.add(fadeBot);
+ // Second triangle
+ colors.add(fadeTop);
+ colors.add(fadeBot);
+ colors.add(fadeBot);
+ colorNode.setData(colors);
+ mirrorRoot.addChild(colorNode);
+
+ TriangleSet tris = new TriangleSet();
+ tris.setNumTriangles(2);
+
+ int i = 0;
+ for (String image : images) {
+ TitleGraph graph = new TitleGraph(image);
+ titles.add(graph);
+ computeCoords(graph.coords, DEFAULT_ASPECT_RATIO);
+ graph.xform.getTransform().setTranslation(new Vec3f(i, 0, 0));
+ Separator sep = new Separator();
+ sep.addChild(graph.xform);
+ sep.addChild(graph.coords);
+ sep.addChild(graph.texture);
+ TextureCoordinate2 texCoordNode = new TextureCoordinate2();
+ Vec2fCollection texCoords = new Vec2fCollection();
+ // Texture coordinates for two triangles
+ // First triangle
+ texCoords.add(new Vec2f( 1, 1));
+ texCoords.add(new Vec2f( 0, 1));
+ texCoords.add(new Vec2f( 0, 0));
+ // Second triangle
+ texCoords.add(new Vec2f( 1, 1));
+ texCoords.add(new Vec2f( 0, 0));
+ texCoords.add(new Vec2f( 1, 0));
+ texCoordNode.setData(texCoords);
+ sep.addChild(texCoordNode);
+
+ sep.addChild(tris);
+
+ // Add this to each rendering root
+ imageRoot.addChild(sep);
+ mirrorRoot.addChild(sep);
+
+ ++i;
+ }
+
+ // Now produce the floor geometry
+ float minx = -i;
+ float maxx = 2 * i;
+ // Furthest back from the camera
+ float minz = -2 * DEFAULT_HEIGHT;
+ // Assume this will be close enough to cover all of the mirrored geometry
+ float maxz = DEFAULT_HEIGHT;
+ Separator floorRoot = new Separator();
+ Blend blend = new Blend();
+ blend.setEnabled(true);
+ blend.setSourceFunc(Blend.ONE);
+ blend.setDestFunc(Blend.ONE_MINUS_SRC_ALPHA);
+ floorRoot.addChild(blend);
+ Coordinate3 floorCoords = new Coordinate3();
+ floorCoords.setData(new Vec3fCollection());
+ // First triangle
+ floorCoords.getData().add(new Vec3f(maxx, 0, minz));
+ floorCoords.getData().add(new Vec3f(minx, 0, minz));
+ floorCoords.getData().add(new Vec3f(minx, 0, maxz));
+ // Second triangle
+ floorCoords.getData().add(new Vec3f(maxx, 0, minz));
+ floorCoords.getData().add(new Vec3f(minx, 0, maxz));
+ floorCoords.getData().add(new Vec3f(maxx, 0, maxz));
+ floorRoot.addChild(floorCoords);
+ // Colors
+ Vec4f gray = new Vec4f(0.4f, 0.4f, 0.4f, 0.4f);
+ Vec4f clearGray = new Vec4f(0.0f, 0.0f, 0.0f, 0.0f);
+ Color4 floorColors = new Color4();
+ floorColors.setData(new Vec4fCollection());
+ // First triangle
+ floorColors.getData().add(gray);
+ floorColors.getData().add(gray);
+ floorColors.getData().add(clearGray);
+ // Second triangle
+ floorColors.getData().add(gray);
+ floorColors.getData().add(clearGray);
+ floorColors.getData().add(clearGray);
+ floorRoot.addChild(floorColors);
+
+ floorRoot.addChild(tris);
+
+ // Now set up the overall scene graph
+ root.addChild(camera);
+ root.addChild(imageRoot);
+ root.addChild(mirrorRoot);
+ root.addChild(floorRoot);
+
+ startLoading();
+ recompute(true);
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ // Recompute position of camera and orientation of images
+ boolean repaintAgain = recompute(false);
+
+ // Redraw
+ GL gl = drawable.getGL();
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ ra.apply(root);
+
+ if (repaintAgain) {
+ animating = true;
+ canvas.repaint();
+ } else {
+ animating = false;
+ }
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
+ }
+
+ public static void main(String[] args) {
+ Frame f = new Frame("Display Shelf test");
+ f.setLayout(new BorderLayout());
+ f.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ new Thread(new Runnable() {
+ public void run() {
+ System.exit(0);
+ }
+ }).start();
+ }
+ });
+
+ // The images to configure the shelf with
+ String[] images = {
+ "http://a1.phobos.apple.com/r10/Music/05/7d/c3/dj.umbuvrfe.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/cb/9a/b3/mzi.krksguze.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/94/8d/83/dj.jionwnuf.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/26/43/02/dj.dgnjindw.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/69/2a/63/mzi.wpfmtfzp.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/17/e1/88/dj.gcajwhco.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/21/f6/32/dj.glzycglj.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/d1/6b/3b/mzi.pajmxsmk.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/f6/a7/b2/dj.lamcsbwx.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/84/a5/4f/dj.nqvsikaq.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/7d/c3/23/dj.elyzoipc.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/80/a5/8c/dj.oidpsvzg.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/d1/b2/cf/dj.moyzjiht.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/49/a3/59/mzi.ssjpuxwt.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/9b/8f/7c/dj.qizpbris.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/b1/4f/c8/dj.uadqyjbr.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/d4/31/df/mzi.pqzeferc.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/4b/88/a7/dj.jhotijvb.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/a8/a9/36/dj.asztraij.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/d6/6b/c4/mzi.dricykdh.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Features/d4/81/a3/dj.tpysowpf.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/4f/2c/a6/dj.cawuddxy.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/d8/9c/8a/mzi.vmajyyha.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/00/5c/31/mzi.tuyoxwib.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/da/c8/e2/mzi.sanzeosx.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/43/cc/0e/dj.zfqfgoas.200x200-75.jpg",
+ "http://a1.phobos.apple.com/r10/Music/73/70/13/mzi.uswlslxx.200x200-75.jpg"
+ };
+
+ Separator root = new Separator();
+
+ DisplayShelf shelf = new DisplayShelf(root, images);
+ f.add(shelf);
+ GraphicsDevice dev = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+ DisplayMode curMode = dev.getDisplayMode();
+ int height = (int) (0.5f * curMode.getWidth());
+ f.setSize(curMode.getWidth(), height);
+ f.setLocation(0, (curMode.getHeight() - height) / 2);
+ f.setVisible(true);
+ }
+}
diff --git a/src/net/java/joglutils/msg/test/Test.java b/src/net/java/joglutils/msg/test/Test.java
new file mode 100644
index 0000000..a782e3e
--- /dev/null
+++ b/src/net/java/joglutils/msg/test/Test.java
@@ -0,0 +1,150 @@
+/*
+ * 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.test;
+
+import java.awt.Frame;
+import java.awt.event.*;
+import java.io.*;
+
+import javax.media.opengl.*;
+import com.sun.opengl.util.texture.*;
+
+import net.java.joglutils.msg.actions.*;
+import net.java.joglutils.msg.collections.*;
+import net.java.joglutils.msg.math.*;
+import net.java.joglutils.msg.nodes.*;
+
+/** A very basic test of the Minimal Scene Graph library. */
+
+public class Test {
+ public static void main(String[] args) {
+ Frame frame = new Frame("Minimal Scene Graph (MSG) Test");
+ GLCanvas canvas = new GLCanvas();
+ canvas.addGLEventListener(new Listener());
+ frame.add(canvas);
+ frame.setSize(512, 512);
+ frame.setVisible(true);
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ new Thread(new Runnable() {
+ public void run() {
+ System.exit(0);
+ }
+ }).start();
+ }
+ });
+ }
+
+ static class Listener implements GLEventListener {
+ private Separator root;
+ private GLRenderAction renderAction;
+
+ public void init(GLAutoDrawable drawable) {
+ root = new Separator();
+ PerspectiveCamera cam = new PerspectiveCamera();
+ cam.setPosition(new Vec3f(0, 0, 2));
+ root.addChild(cam);
+ Coordinate3 coordNode = new Coordinate3();
+ Vec3fCollection coords = new Vec3fCollection();
+ // First triangle
+ coords.add(new Vec3f( 1, 1, 0));
+ coords.add(new Vec3f(-1, 1, 0));
+ coords.add(new Vec3f(-1, -1, 0));
+ // Second triangle
+ coords.add(new Vec3f( 1, 1, 0));
+ coords.add(new Vec3f(-1, -1, 0));
+ coords.add(new Vec3f( 1, -1, 0));
+ coordNode.setData(coords);
+ root.addChild(coordNode);
+
+ // Texture coordinates
+ TextureCoordinate2 texCoordNode = new TextureCoordinate2();
+ Vec2fCollection texCoords = new Vec2fCollection();
+ // First triangle
+ texCoords.add(new Vec2f( 1, 1));
+ texCoords.add(new Vec2f( 0, 1));
+ texCoords.add(new Vec2f( 0, 0));
+ // Second triangle
+ texCoords.add(new Vec2f( 1, 1));
+ texCoords.add(new Vec2f( 0, 0));
+ texCoords.add(new Vec2f( 1, 0));
+ texCoordNode.setData(texCoords);
+ root.addChild(texCoordNode);
+
+ // Colors
+ Color4 colorNode = new Color4();
+ Vec4fCollection colors = new Vec4fCollection();
+ // First triangle
+ colors.add(new Vec4f(1.0f, 1.0f, 1.0f, 1.0f));
+ colors.add(new Vec4f(1.0f, 1.0f, 1.0f, 1.0f));
+ colors.add(new Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
+ // Second triangle
+ colors.add(new Vec4f(1.0f, 1.0f, 1.0f, 1.0f));
+ colors.add(new Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
+ colors.add(new Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
+ colorNode.setData(colors);
+ root.addChild(colorNode);
+
+ TriangleSet tris = new TriangleSet();
+ tris.setNumTriangles(2);
+ root.addChild(tris);
+
+ // Testing transforms
+ Transform xform = new Transform();
+ xform.getTransform().setTranslation(new Vec3f(2, -2, 0));
+ // xform.getTransform().setRotation(new Rotf(new Vec3f(0, 1, 0), (float) (-Math.PI / 4)));
+ root.addChild(xform);
+
+ root.addChild(tris);
+
+ GL gl = drawable.getGL();
+ gl.glEnable(GL.GL_DEPTH_TEST);
+
+ renderAction = new GLRenderAction();
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ renderAction.apply(root);
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {}
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
+ }
+}
diff --git a/src/net/java/joglutils/msg/test/package.html b/src/net/java/joglutils/msg/test/package.html
new file mode 100644
index 0000000..8697264
--- /dev/null
+++ b/src/net/java/joglutils/msg/test/package.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<body>
+
+Test programs.
+
+</body>
+</html>