summaryrefslogtreecommitdiffstats
path: root/src/classes/share/com/sun/j3d/internal
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/share/com/sun/j3d/internal')
-rwxr-xr-xsrc/classes/share/com/sun/j3d/internal/BufferWrapper.java186
-rwxr-xr-xsrc/classes/share/com/sun/j3d/internal/ByteBufferWrapper.java197
-rwxr-xr-xsrc/classes/share/com/sun/j3d/internal/ByteOrderWrapper.java101
-rw-r--r--src/classes/share/com/sun/j3d/internal/Distance.java1096
-rwxr-xr-xsrc/classes/share/com/sun/j3d/internal/DoubleBufferWrapper.java153
-rw-r--r--src/classes/share/com/sun/j3d/internal/FastVector.java143
-rwxr-xr-xsrc/classes/share/com/sun/j3d/internal/FloatBufferWrapper.java152
-rw-r--r--src/classes/share/com/sun/j3d/internal/J3dUtilsI18N.java63
-rw-r--r--src/classes/share/com/sun/j3d/internal/UtilFreelistManager.java98
-rw-r--r--src/classes/share/com/sun/j3d/internal/UtilMemoryFreelist.java292
10 files changed, 2481 insertions, 0 deletions
diff --git a/src/classes/share/com/sun/j3d/internal/BufferWrapper.java b/src/classes/share/com/sun/j3d/internal/BufferWrapper.java
new file mode 100755
index 0000000..40370bc
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/BufferWrapper.java
@@ -0,0 +1,186 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package com.sun.j3d.internal;
+
+import javax.media.j3d.J3DBuffer;
+import java.nio.Buffer;
+
+/**
+ * NIO Buffers are new in Java 1.4 but we need to run on 1.3
+ * as well, so this class was created to hide the NIO classes
+ * from non-1.4 Java 3D users.
+ *
+ * <p>
+ * NOTE: We no longer need to support JDK 1.3 as of the Java 3D 1.3.2
+ * community source release on java.net. We should be able to get rid
+ * of this class.
+ */
+
+public abstract class BufferWrapper {
+
+ /**
+ * Value returned from getBufferType(), this indicates
+ * that the BufferWrapper contains a null buffer.
+ */
+ public static final int TYPE_NULL = 0;
+
+ /**
+ * Value returned from getBufferType(), this indicates
+ * that the BufferWrapper does not hold data of type
+ * byte, float, or double.
+ */
+ public static final int TYPE_UNKNOWN = 1;
+
+ /**
+ * Value returned from getBufferType(), this indicates
+ * that the BufferWrapper contains a java.nio.ByteBuffer.
+ */
+ public static final int TYPE_BYTE = 2;
+
+ /**
+ * Value returned from getBufferType(), this indicates
+ * that the BufferWrapper contains a java.nio.FloatBuffer.
+ */
+ public static final int TYPE_FLOAT = 3;
+
+ /**
+ * Value returned from getBufferType(), this indicates
+ * that the BufferWrapper contains a java.nio.DoubleBuffer.
+ */
+ public static final int TYPE_DOUBLE = 4;
+
+ /**
+ * Never used - this class is abstract.
+ */
+ public BufferWrapper() {
+ }
+
+ /**
+ * Must be implemented by sublasses.
+ */
+ abstract Buffer getBuffer();
+
+ /**
+ * @return Buffer as object of type Object.
+ */
+ public Object getBufferAsObject() {
+ return getBuffer();
+ }
+
+ // Wrapper for all relevant Buffer methods.
+
+ /**
+ * @return This buffer's capacity (set at initialization in
+ * allocateDirect() ).
+ * @see ByteBufferWrapper#allocateDirect
+ */
+ public int capacity() {
+ return getBuffer().capacity();
+ }
+
+ /**
+ * @return This buffer's limit.
+ */
+ public int limit() {
+ return getBuffer().limit();
+ }
+
+ /**
+ * @return This buffer's position.
+ */
+ public int position() {
+ return getBuffer().position();
+ }
+
+ /**
+ * Sets this buffer's position.
+ * @return This buffer.
+ */
+ public BufferWrapper position(int newPosition){
+ getBuffer().position(newPosition);
+ return this;
+ }
+
+ /**
+ * Resets this buffer's position to the previously marked
+ * position.
+ * @return This buffer.
+ */
+ public BufferWrapper rewind() {
+ getBuffer().rewind();
+ return this;
+ }
+
+ /**
+ * @return An integer indicating the type of data held in
+ * this buffer.
+ * @see #TYPE_NULL
+ * @see #TYPE_BYTE
+ * @see #TYPE_FLOAT
+ * @see #TYPE_DOUBLE
+ * @see #TYPE_UNKNOWN
+ */
+ public static int getBufferType(J3DBuffer b) {
+ int bufferType;
+ Buffer buffer = b.getBuffer();
+
+ if (buffer == null) {
+ bufferType = TYPE_NULL;
+ }
+ else if (buffer instanceof java.nio.ByteBuffer) {
+ bufferType = TYPE_BYTE;
+ }
+ else if (buffer instanceof java.nio.FloatBuffer) {
+ bufferType = TYPE_FLOAT;
+ }
+ else if (buffer instanceof java.nio.DoubleBuffer) {
+ bufferType = TYPE_DOUBLE;
+ }
+ else {
+ bufferType = TYPE_UNKNOWN;
+ }
+ return bufferType;
+ }
+}
diff --git a/src/classes/share/com/sun/j3d/internal/ByteBufferWrapper.java b/src/classes/share/com/sun/j3d/internal/ByteBufferWrapper.java
new file mode 100755
index 0000000..61f2c58
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/ByteBufferWrapper.java
@@ -0,0 +1,197 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package com.sun.j3d.internal;
+
+import javax.media.j3d.J3DBuffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * NIO Buffers are new in Java 1.4 but we need to run on 1.3
+ * as well, so this class was created to hide the NIO classes
+ * from non-1.4 Java 3D users.
+ *
+ * <p>
+ * NOTE: We no longer need to support JDK 1.3 as of the Java 3D 1.3.2
+ * community source release on java.net. We should be able to get rid
+ * of this class.
+ */
+
+public class ByteBufferWrapper extends BufferWrapper {
+
+ private ByteBuffer buffer = null;
+
+ /**
+ * Constructor initializes buffer with a
+ * java.nio.ByteBuffer object.
+ */
+ public ByteBufferWrapper(ByteBuffer buffer) {
+ this.buffer = buffer;
+ }
+
+ /**
+ * Constructor initializes buffer with a
+ * javax.media.j3d.J3DBuffer object.
+ */
+ public ByteBufferWrapper(J3DBuffer b) {
+ buffer = (ByteBuffer)(b.getBuffer());
+ }
+
+ /**
+ * Allocate a direct ByteBuffer with the given capacity.
+ * @return New ByteBufferWrapper containing the
+ * new buffer.
+ */
+ public static ByteBufferWrapper allocateDirect(int capacity) {
+ ByteBuffer bb = ByteBuffer.allocateDirect(capacity);
+ return new ByteBufferWrapper(bb);
+ }
+
+ /**
+ * Returns the java.nio.Buffer contained within this
+ * ByteBufferWrapper.
+ */
+ public java.nio.Buffer getBuffer() {
+ return this.buffer;
+ }
+
+ // Wrapper for all relevant ByteBuffer methods.
+
+ /**
+ * @return A boolean indicating whether the java.nio.Buffer
+ * object contained within this ByteBuffer is direct or
+ * indirect.
+ */
+ public boolean isDirect() {
+ return buffer.isDirect();
+ }
+
+ /**
+ * Reads the byte at this buffer's current position,
+ * and then increments the position.
+ */
+ public byte get() {
+ return buffer.get();
+ }
+
+ /**
+ * Reads the byte at the given offset into the buffer.
+ */
+ public byte get(int index) {
+ return buffer.get(index);
+ }
+
+ /**
+ * Bulk <i>get</i> method. Transfers <code>dst.length</code>
+ * bytes from
+ * the buffer to the destination array and increments the
+ * buffer's position by <code>dst.length</code>.
+ */
+ public ByteBufferWrapper get(byte[] dst) {
+ buffer.get(dst);
+ return this;
+ }
+
+ /**
+ * Bulk <i>get</i> method. Transfers <i>length</i> bytes
+ * from the buffer starting at position <i>offset</i> into
+ * the destination array.
+ */
+ public ByteBufferWrapper get(byte[] dst, int offset, int length) {
+ buffer.get(dst, offset, length);
+ return this;
+ }
+
+ /**
+ * Returns the byte order of this buffer.
+ */
+ public ByteOrderWrapper order() {
+ if ( buffer.order()==ByteOrder.BIG_ENDIAN ) return ByteOrderWrapper.BIG_ENDIAN;
+ else return ByteOrderWrapper.LITTLE_ENDIAN;
+ }
+
+ /**
+ * Modifies this buffer's byte order.
+ */
+ public ByteBufferWrapper order(ByteOrderWrapper bo)
+ {
+ if ( bo == ByteOrderWrapper.BIG_ENDIAN ) buffer.order( ByteOrder.BIG_ENDIAN );
+ else buffer.order( ByteOrder.LITTLE_ENDIAN );
+ return this;
+ }
+
+ /**
+ * Creates a view of this ByteBufferWrapper as a
+ * FloatBufferWrapper. Uses the correct
+ */
+ public FloatBufferWrapper asFloatBuffer() {
+ return new FloatBufferWrapper( buffer.asFloatBuffer() );
+ }
+
+ /**
+ * Creates a view of this ByteBufferWrapper as a
+ * DoubleBufferWrapper.
+ */
+ public DoubleBufferWrapper asDoubleBuffer() {
+ return new DoubleBufferWrapper( buffer.asDoubleBuffer() );
+ }
+
+ /**
+ * Bulk <i>put</i> method. Transfers <code>src.length</code>
+ * bytes into the buffer at the current position.
+ */
+ public ByteBufferWrapper put(byte[] src) {
+ buffer.put(src);
+ return this;
+ }
+
+ /**
+ * Creates and returns a J3DBuffer object containing the
+ * buffer in this ByteBufferWrapper object.
+ */
+ public J3DBuffer getJ3DBuffer() {
+ return new J3DBuffer( buffer );
+ }
+}
diff --git a/src/classes/share/com/sun/j3d/internal/ByteOrderWrapper.java b/src/classes/share/com/sun/j3d/internal/ByteOrderWrapper.java
new file mode 100755
index 0000000..bfaa373
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/ByteOrderWrapper.java
@@ -0,0 +1,101 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package com.sun.j3d.internal;
+
+import javax.media.j3d.J3DBuffer;
+import java.nio.Buffer;
+import java.nio.ByteOrder;
+
+/**
+ * NIO Buffers are new in Java 1.4 but we need to run on 1.3
+ * as well, so this class was created to hide the NIO classes
+ * from non-1.4 Java 3D users.
+ *
+ * <p>
+ * Typesafe enum for byte orders.
+ *
+ * <p>
+ * NOTE: We no longer need to support JDK 1.3 as of the Java 3D 1.3.2
+ * community source release on java.net. We should be able to get rid
+ * of this class.
+ */
+
+public final class ByteOrderWrapper {
+
+ private final String enum_name;
+
+ /**
+ * Private constructor is only called from static initializers
+ * in this class.
+ */
+ private ByteOrderWrapper(String name) {
+ enum_name = name;
+ }
+
+ /**
+ * Static initializer creates object of this type.
+ */
+ public static final ByteOrderWrapper BIG_ENDIAN =
+ new ByteOrderWrapper("BIG_ENDIAN");
+
+ /**
+ * Static initializer creates object of this type.
+ */
+ public static final ByteOrderWrapper LITTLE_ENDIAN =
+ new ByteOrderWrapper("LITTLE_ENDIAN");
+
+ public String toString() {
+ return enum_name;
+ }
+
+ /**
+ * Returns the native byte order of the host system.
+ */
+ public static ByteOrderWrapper nativeOrder() {
+ if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
+ return ByteOrderWrapper.BIG_ENDIAN;
+ } else return ByteOrderWrapper.LITTLE_ENDIAN;
+ }
+}
diff --git a/src/classes/share/com/sun/j3d/internal/Distance.java b/src/classes/share/com/sun/j3d/internal/Distance.java
new file mode 100644
index 0000000..f49659f
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/Distance.java
@@ -0,0 +1,1096 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+// --------------------------------------------------
+//
+// Distance routines, ported from:
+//
+// Magic Software, Inc.
+// http://www.magic-software.com
+// http://www.wild-magic.com
+// Copyright (c) 2004. All Rights Reserved
+//
+// The Wild Magic Library (WML) source code is supplied under the terms of
+// the license agreement http://www.magic-software.com/License/WildMagic.pdf
+// and may not be copied or disclosed except in accordance with the terms of
+// that agreement.
+//
+// --------------------------------------------------
+
+package com.sun.j3d.internal;
+
+import javax.vecmath.*;
+
+/**
+ * Utility class used to calculate distance. Contains static methods
+ * used by picking method to determine intersections.
+ */
+
+public class Distance {
+ /* Threshold factor to determine if two lines are parallel */
+ static final double FUZZ = 1E-5;
+
+ /* Utility method, for easy switch between distance and squared distance */
+ private static final double DIST (double in) {
+ // return Math.sqrt (Math.abs (in));
+ return Math.abs (in);
+ }
+
+ /**
+ * Minimum ray to segment distance.
+ *
+ * @param rayorig Origin of the ray
+ * @param raydir Direction of the ray
+ * @param segstart Segment start point
+ * @param segend Segment end point
+ * @return the square of the minimum distance from the ray to the segment
+ */
+ static public double rayToSegment (Point3d rayorig,
+ Vector3d raydir,
+ Point3d segstart,
+ Point3d segend) {
+ return rayToSegment (rayorig, raydir, segstart, segend, null, null, null);
+ }
+
+ /**
+ * Minimum ray to segment distance. Returns the square of the distance.
+ *
+ * @param rayorig Origin of the ray
+ *
+ * @param raydir Direction of the ray
+ *
+ * @param segstart Segment start point
+ *
+ * @param segend Segment end point
+ *
+ * @param rayint If non-null, will be filled with the coordinates of
+ * the point corresponding to the minimum distance on the ray.
+ *
+ * @param segint If non-null, will be filled with the coordinates of
+ * the point corresponding to the minimum distance on the segment.
+ *
+ * @param param An array of two doubles, will be filled with the
+ * parametric factors used to find the point of shortest distance on
+ * each primitive (ray = O +sD, with O=origin and
+ * D=direction). param[0] will contain the parameter for the ray,
+ * and param[1] the parameter for the segment.
+ *
+ * @return the square of the minimum distance from the ray to the
+ * segment
+ */
+ static public double rayToSegment (Point3d rayorig,
+ Vector3d raydir,
+ Point3d segstart,
+ Point3d segend,
+ Point3d rayint,
+ Point3d segint,
+ double[] param) {
+ double s, t;
+
+ Vector3d diff = new Vector3d();
+ diff.sub (rayorig,segstart);
+ Vector3d segdir = new Vector3d();
+ segdir.sub (segend, segstart);
+ /*
+ System.out.println (rayorig + "\n" + raydir + "\n" + segstart + "\n" +
+ segdir);
+ */
+ double A = raydir.dot (raydir);//Dot(ray.m,ray.m);
+ double B = -raydir.dot (segdir);//-Dot(ray.m,seg.m);
+ double C = segdir.dot (segdir);//Dot(seg.m,seg.m);
+ double D = raydir.dot (diff);//Dot(ray.m,diff);
+ double E; // -Dot(seg.m,diff), defer until needed
+ double F = diff.dot (diff);//Dot(diff,diff);
+ double det = Math.abs(A*C-B*B); // A*C-B*B = |Cross(M0,M1)|^2 >= 0
+
+ double tmp;
+
+ if (det >= FUZZ) {
+ // ray and segment are not parallel
+ E = -segdir.dot (diff);//-Dot(seg.m,diff);
+ s = B*E-C*D;
+ t = B*D-A*E;
+
+ if (s >= 0) {
+ if (t >= 0) {
+ if (t <= det) { // region 0
+ // minimum at interior points of ray and segment
+ double invDet = 1.0f/det;
+ s *= invDet;
+ t *= invDet;
+ if (rayint!=null) rayint.scaleAdd (s, raydir, rayorig);
+ if (segint!=null) segint.scaleAdd (t, segdir, segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(s*(A*s+B*t+2*D)+t*(B*s+C*t+2*E)+F);
+ }
+ else { // region 1
+
+ t = 1;
+ if (D >= 0) {
+ s = 0;
+ if (rayint!=null) rayint.set (rayorig);
+ if (segint!=null) segint.set (segend);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ s = -D/A;
+ if (rayint!=null) rayint.scaleAdd (s, raydir, rayorig);
+ if (segint!=null) segint.set (segend);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST((D+2*B)*s+C+2*E+F);
+ }
+ }
+ }
+ else { // region 5
+ t = 0;
+ if (D >= 0) {
+ s = 0;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.set (segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else {
+ s = -D/A;
+ if (rayint != null) rayint.scaleAdd (s, raydir, rayorig);
+ if (segint != null) segint.set (segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ }
+ }
+ else {
+ if (t <= 0) { // region 4
+ if (D < 0) {
+ s = -D/A;
+ t = 0;
+ if (rayint != null) rayint.scaleAdd (s, raydir, rayorig);
+ if (segint != null) segint.set (segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ else {
+ s = 0;
+ if (E >= 0) {
+ t = 0;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.set (segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else if (-E >= C) {
+ t = 1;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.set (segend);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ t = -E/C;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.scaleAdd (t, segdir, segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(E*t+F);
+ }
+ }
+ }
+ else if (t <= det) { // region 3
+ s = 0;
+ if (E >= 0) {
+ t = 0;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.set (segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else if (-E >= C) {
+ t = 1;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.set (segend);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ t = -E/C;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.scaleAdd (t, segdir, segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(E*t+F);
+ }
+ }
+ else { // region 2
+ tmp = B+D;
+ if (tmp < 0) {
+ s = -tmp/A;
+ t = 1;
+ if (rayint != null) rayint.scaleAdd (s, raydir, rayorig);
+ if (segint != null) segint.set (segend);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(tmp*s+C+2*E+F);
+ }
+ else {
+ s = 0;
+ if (E >= 0) {
+ t = 0;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.set (segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else if (-E >= C) {
+ t = 1;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.set (segend);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ t = -E/C;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.scaleAdd (t, segdir, segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(E*t+F);
+ }
+ }
+ }
+ }
+ }
+ else {
+ // ray and segment are parallel
+ if (B > 0) {
+ // opposite direction vectors
+ t = 0;
+ if (D >= 0) {
+ s = 0;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.set (segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else {
+ s = -D/A;
+ if (rayint != null) rayint.scaleAdd (s, raydir, rayorig);
+ if (segint != null) segint.set (segstart);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ }
+ else {
+ // same direction vectors
+ E = segdir.dot (diff);//-Dot(seg.m,diff);
+ t = 1;
+ tmp = B+D;
+ if (tmp >= 0) {
+ s = 0;
+ if (rayint != null) rayint.set (rayorig);
+ if (segint != null) segint.set (segend);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ s = -tmp/A;
+ if (rayint != null) rayint.scaleAdd (s, raydir, rayorig);
+ if (segint != null) segint.set (segend);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(tmp*s+C+2*E+F);
+ }
+ }
+ }
+ }
+
+ /**
+ * Minimum ray to ray distance. Returns the square of the distance.
+ *
+ * @param ray0orig Origin of ray 0
+ * @param ray0dir Direction of ray 0
+ * @param ray1orig Origin of ray 1
+ * @param ray1dir Direction of ray 1
+ * @return the square of the minimum distance from the ray to the segment
+ */
+ static public double rayToRay (Point3d ray0orig,
+ Vector3d ray0dir,
+ Point3d ray1orig,
+ Vector3d ray1dir) {
+ return rayToRay (ray0orig, ray0dir, ray1orig, ray1dir, null, null, null);
+ }
+
+ /**
+ * Minimum ray to ray distance. Returns the square of the distance.
+ *
+ * @param ray0orig Origin of ray 0
+ *
+ * @param ray0dir Direction of ray 0
+ *
+ * @param ray1orig Origin of ray 1
+ *
+ * @param ray1dir Direction of ray 1
+ *
+ * @param ray0int If non-null, will be filled with the coordinates
+ * of the point corresponding to the minimum distance on ray 0.
+ *
+ * @param ray1int If non-null, will be filled with the coordinates
+ * of the point corresponding to the minimum distance on ray 1.
+ *
+ * @param param An array of two doubles, will be filled with the
+ * parametric factors used to find the point of shortest distance on
+ * each primitive (ray = O +sD, with O=origin and
+ * D=direction). param[0] will contain the parameter for ray0, and
+ * param[1] the parameter for ray1.
+ *
+ * @return the square of the minimum distance from the ray to the segment
+ */
+ static public double rayToRay (Point3d ray0orig,
+ Vector3d ray0dir,
+ Point3d ray1orig,
+ Vector3d ray1dir,
+ Point3d ray0int,
+ Point3d ray1int,
+ double[] param) {
+
+ double s, t;
+
+ Vector3d diff = new Vector3d();
+ diff.sub (ray0orig, ray1orig);
+
+ double A = ray0dir.dot (ray0dir); //Dot(ray0.m,ray0.m);
+ double B = -ray0dir.dot (ray1dir); //-Dot(ray0.m,ray1.m);
+ double C = ray1dir.dot (ray1dir); //Dot(ray1.m,ray1.m);
+ double D = ray0dir.dot (diff); //Dot(ray0.m,diff);
+ double E; // -Dot(ray1.m,diff), defer until needed
+ double F = diff.dot (diff); //Dot(diff,diff);
+ double det = Math.abs(A*C-B*B); // A*C-B*B = |Cross(M0,M1)|^2 >= 0
+ /*
+ System.out.println (ray0orig + "\n" + ray0dir + "\n" +
+ ray1orig + "\n" + ray1dir);
+ System.out.println (A + " " + B + " " + C + " " + D + " " + F + " " + det);
+ */
+ if (det >= FUZZ) {
+ // rays are not parallel
+ E = -ray1dir.dot (diff); //-Dot(ray1.m,diff);
+ s = B*E-C*D;
+ t = B*D-A*E;
+
+ if (s >= 0) {
+ if (t >= 0) { // region 0 (interior)
+ // minimum at two interior points of rays
+ double invDet = 1.0f/det;
+ s *= invDet;
+ t *= invDet;
+ if (ray0int != null) ray0int.scaleAdd (s, ray0dir, ray0orig);
+ if (ray1int != null) ray1int.scaleAdd (t, ray1dir, ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(s*(A*s+B*t+2*D)+t*(B*s+C*t+2*E)+F);
+ }
+ else { // region 3 (side)
+ t = 0;
+ if (D >= 0) {
+ s = 0;
+ if (ray0int != null) ray0int.set (ray0orig);
+ if (ray1int != null) ray1int.set (ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else {
+ s = -D/A;
+ if (ray0int != null) ray0int.scaleAdd (s, ray0dir, ray0orig);
+ if (ray1int != null) ray1int.set (ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ }
+ }
+ else {
+ if (t >= 0) { // region 1 (side)
+ s = 0;
+ if (E >= 0) {
+ t = 0;
+ if (ray0int != null) ray0int.set (ray0orig);
+ if (ray1int != null) ray1int.set (ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else {
+ t = -E/C;
+ if (ray0int != null) ray0int.set (ray0orig);
+ if (ray1int != null) ray1int.scaleAdd (t, ray1dir, ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(E*t+F);
+ }
+ }
+ else { // region 2 (corner)
+ if (D < 0) {
+ s = -D/A;
+ t = 0;
+ if (ray0int != null) ray0int.scaleAdd (s, ray0dir, ray0orig);
+ if (ray1int != null) ray1int.set (ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ else {
+ s = 0;
+ if (E >= 0) {
+ t = 0;
+ if (ray0int != null) ray0int.set (ray0orig);
+ if (ray1int != null) ray1int.set (ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else {
+ t = -E/C;
+ if (ray0int != null) ray0int.set (ray0orig);
+ if (ray1int != null) ray1int.scaleAdd (t, ray1dir, ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(E*t+F);
+ }
+ }
+ }
+ }
+ }
+ else {
+ // rays are parallel
+ if (B > 0) {
+ // opposite direction vectors
+ t = 0;
+ if (D >= 0) {
+ s = 0;
+ if (ray0int != null) ray0int.set (ray0orig);
+ if (ray1int != null) ray1int.set (ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else {
+ s = -D/A;
+ if (ray0int != null) ray0int.scaleAdd (s, ray0dir, ray0orig);
+ if (ray1int != null) ray1int.set (ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ }
+ else {
+ // same direction vectors
+ if (D >= 0) {
+ E = ray1dir.dot (diff); //-Dot(ray1.m,diff);
+ s = 0;
+ t = -E/C;
+ if (ray0int != null) ray0int.set (ray0orig);
+ if (ray1int != null) ray1int.scaleAdd (t, ray1dir, ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(E*t+F);
+ }
+ else {
+ s = -D/A;
+ t = 0;
+ if (ray0int != null) ray0int.scaleAdd (s, ray0dir, ray0orig);
+ if (ray1int != null) ray1int.set (ray1orig);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ }
+ }
+ }
+
+ /**
+ * Minimum pt to ray distance. Returns the square of the distance.
+ * @param pt The point
+ * @param rayorig Origin of the ray
+ * @param raydir Direction of the ray
+ * @return the square of the minimum distance between the point and the ray
+ */
+ static public double pointToRay (Point3d pt,
+ Point3d rayorig,
+ Vector3d raydir) {
+ return pointToRay (pt, rayorig, raydir, null, null);
+ }
+
+ /**
+ * Minimum pt to ray distance. Returns the square of the distance.
+ *
+ * @param pt The point
+ *
+ * @param rayorig Origin of the ray
+ *
+ * @param raydir Direction of the ray
+ *
+ * @param rayint If non-null, will be filled with the coordinates of
+ * the point corresponding to the minimum distance on the ray.
+ *
+ * @param param An array of one double, will be filled with the
+ * parametric factors used to find the point of shortest distance on
+ * the ray (ray = O +sD, with O=origin and D=direction). param[0]
+ * will contain the parameter for the ray.
+ *
+ * @return the square of the minimum distance between the point and the ray
+ */
+ static public double pointToRay (Point3d pt,
+ Point3d rayorig,
+ Vector3d raydir,
+ Point3d rayint,
+ double[] param) {
+
+ double t;
+
+ Vector3d diff = new Vector3d();
+ diff.sub (pt, rayorig);
+ t = raydir.dot (diff); //Dot(ray.m,diff);
+
+ if (t <= 0.0) {
+ t = 0.0; // behind start of ray
+ if (rayint != null) rayint.set (rayorig);
+ if (param != null) { param[0] = t; }
+ } else {
+ t /= raydir.dot (raydir); //Dot(ray.m,ray.m);
+ diff.scaleAdd (-t, raydir, diff); // diff = diff - t*ray.m;
+ if (rayint != null) rayint.scaleAdd (t, raydir, rayorig);
+ if (param != null) { param[0] = t; }
+ }
+ return diff.dot(diff);
+ }
+
+ /**
+ * Minimum pt to segment distance. Returns the square of the distance.
+ */
+ static public double pointToSegment (Point3d pt,
+ Point3d segstart,
+ Point3d segend) {
+ return pointToSegment (pt, segstart, segend, null, null);
+ }
+
+ /**
+ * Minimum pt to segment distance. Returns the square of the distance.
+ */
+ static public double pointToSegment (Point3d pt,
+ Point3d segstart,
+ Point3d segend,
+ Point3d segint,
+ double[] param) {
+
+ double t;
+ Vector3d segdir = new Vector3d ();
+ segdir.sub (segend, segstart);
+ Vector3d diff = new Vector3d();
+ diff.sub (pt,segstart);
+ t = segdir.dot (diff); //Dot(seg.m,diff);
+
+ if (t <= 0.0) {
+ t = 0.0f;
+ if (segint != null) segint.set (segstart);
+ if (param != null) { param[0] = t; }
+ }
+ else {
+ double mDotm = segdir.dot (segdir); //Dot(seg.m,seg.m);
+ if (t >= mDotm) {
+ t = 1.0f;
+ diff.sub (segdir);
+ if (segint != null) segint.set (segend);
+ if (param != null) { param[0] = t; }
+ }
+ else {
+ t /= mDotm;
+ diff.scaleAdd (-t, segdir, diff); //diff = diff - t*seg.m;
+ if (segint != null) segint.scaleAdd (t, segdir, segstart);
+ if (param != null) { param[0] = t; }
+ }
+ }
+ return diff.dot(diff); //DIST(diff);
+ }
+
+
+ /**
+ * Minimum segment to segment distance. Returns the square of the distance.
+ * @param seg0start the start of segment 0
+ * @param seg0end the end of segment 0
+ * @param seg1start the start of segment 1
+ * @param seg1end the end of segment 1
+ * @return the square of the minimum distance from segment to segment
+ */
+ static public double segmentToSegment (Point3d seg0start,
+ Point3d seg0end,
+ Point3d seg1start,
+ Point3d seg1end) {
+ return segmentToSegment (seg0start, seg0end, seg1start, seg1end,
+ null, null, null);
+ }
+
+ /**
+ * Minimum segment to segment distance. Returns the square of the distance.
+ *
+ * @param seg0start the start of segment 0
+ *
+ * @param seg0end the end of segment 0
+ *
+ * @param seg1start the start of segment 1
+ *
+ * @param seg1end the end of segment 1
+ *
+ * @param seg0int If non-null, will be filled with the coordinates
+ * of the point corresponding to the minimum distance on segment 0.
+ *
+ * @param seg1int If non-null, will be filled with the coordinates
+ * of the point corresponding to the minimum distance on segment 1.
+ *
+ * @param param An array of two doubles, will be filled with the
+ * parametric factors used to find the point of shortest distance on
+ * each primitive (segment = O +sD, with O=origin and
+ * D=direction). param[0] will contain the parameter for segment 0,
+ * and param[1] the parameter for segment 1.
+ *
+ * @return the square of the minimum distance from segment to segment
+ */
+ static public double segmentToSegment (Point3d seg0start,
+ Point3d seg0end,
+ Point3d seg1start,
+ Point3d seg1end,
+ Point3d seg0int,
+ Point3d seg1int,
+ double[] param) {
+ double s,t;
+
+ Vector3d diff = new Vector3d();
+ diff.sub (seg0start,seg1start);
+
+ Vector3d seg0dir = new Vector3d();
+ seg0dir.sub (seg0end, seg0start);
+ Vector3d seg1dir = new Vector3d();
+ seg1dir.sub (seg1end, seg1start);
+
+ double A = seg0dir.dot (seg0dir); //Dot(seg0dir,seg0dir);
+ double B = -seg0dir.dot (seg1dir); //-Dot(seg0dir,seg1dir);
+ double C = seg1dir.dot (seg1dir); //Dot(seg1dir,seg1dir);
+ double D = seg0dir.dot (diff); //Dot(seg0dir,diff);
+ double E; // -Dot(seg1dir,diff), defer until needed
+ double F = diff.dot (diff); //Dot(diff,diff);
+ double det = Math.abs(A*C-B*B); // A*C-B*B = |Cross(M0,M1)|^2 >= 0
+
+ double tmp;
+
+ if (det >= FUZZ) {
+ // line segments are not parallel
+ E = -seg1dir.dot (diff); //-Dot(seg1dir,diff);
+ s = B*E-C*D;
+ t = B*D-A*E;
+
+ if (s >= 0) {
+ if (s <= det) {
+ if (t >= 0) {
+ if (t <= det) { // region 0 (interior)
+ // minimum at two interior points of 3D lines
+ double invDet = 1.0f/det;
+ s *= invDet;
+ t *= invDet;
+ if (seg0int != null) seg0int.scaleAdd (s, seg0dir, seg0start);
+ if (seg1int != null) seg1int.scaleAdd (t, seg1dir, seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(s*(A*s+B*t+2*D)+t*(B*s+C*t+2*E)+F);
+ }
+ else { // region 3 (side)
+ t = 1;
+ tmp = B+D;
+ if (tmp >= 0) {
+ s = 0;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else if (-tmp >= A) {
+ s = 1;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+C+F+2*(E+tmp));
+ }
+ else {
+ s = -tmp/A;
+ if (seg0int != null) seg0int.scaleAdd (s, seg0dir, seg0start);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(tmp*s+C+2*E+F);
+ }
+ }
+ }
+ else { // region 7 (side)
+ t = 0;
+ if (D >= 0) {
+ s = 0;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else if (-D >= A) {
+ s = 1;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+2*D+F);
+ }
+ else {
+ s = -D/A;
+ if (seg0int != null) seg0int.scaleAdd (s, seg0dir, seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ }
+ }
+ else {
+ if (t >= 0) {
+ if (t <= det) { // region 1 (side)
+ s = 1;
+ tmp = B+E;
+ if (tmp >= 0) {
+ t = 0;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+2*D+F);
+ }
+ else if (-tmp >= C) {
+ t = 1;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+C+F+2*(D+tmp));
+ }
+ else {
+ t = -tmp/C;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.scaleAdd (t, seg1dir, seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(tmp*t+A+2*D+F);
+ }
+ }
+ else { // region 2 (corner)
+ tmp = B+D;
+ if (-tmp <= A) {
+ t = 1;
+ if (tmp >= 0) {
+ s = 0;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ s = -tmp/A;
+ if (seg0int!=null) seg0int.scaleAdd (s, seg0dir, seg0start);
+ if (seg1int!=null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(tmp*s+C+2*E+F);
+ }
+ }
+ else {
+ s = 1;
+ tmp = B+E;
+ if (tmp >= 0) {
+ t = 0;
+ if (seg0int!=null) seg0int.set (seg0end);
+ if (seg1int!=null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+2*D+F);
+ }
+ else if (-tmp >= C) {
+ t = 1;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+C+F+2*(D+tmp));
+ }
+ else {
+ t = -tmp/C;
+ if (seg0int!=null) seg0int.set (seg0end);
+ if (seg1int!=null) seg1int.scaleAdd (t, seg1dir, seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(tmp*t+A+2*D+F);
+ }
+ }
+ }
+ }
+ else { // region 8 (corner)
+ if (-D < A) {
+ t = 0;
+ if (D >= 0) {
+ s = 0;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else {
+ s = -D/A;
+ if (seg0int != null) seg0int.scaleAdd (s, seg0dir, seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ }
+ else {
+ s = 1;
+ tmp = B+E;
+ if (tmp >= 0) {
+ t = 0;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+2*D+F);
+ }
+ else if (-tmp >= C) {
+ t = 1;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+C+F+2*(D+tmp));
+ }
+ else {
+ t = -tmp/C;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.scaleAdd (t, seg1dir, seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(tmp*t+A+2*D+F);
+ }
+ }
+ }
+ }
+ }
+ else {
+ if (t >= 0) {
+ if (t <= det) { // region 5 (side)
+ s = 0;
+ if (E >= 0) {
+ t = 0;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else if (-E >= C) {
+ t = 1;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ t = -E/C;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.scaleAdd (t, seg1dir, seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(E*t+F);
+ }
+ }
+ else { // region 4 (corner)
+ tmp = B+D;
+ if (tmp < 0) {
+ t = 1;
+ if (-tmp >= A) {
+ s = 1;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+C+F+2*(E+tmp));
+ }
+ else {
+ s = -tmp/A;
+ if (seg0int != null) seg0int.scaleAdd (s, seg0dir, seg0start);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(tmp*s+C+2*E+F);
+ }
+ }
+ else {
+ s = 0;
+ if (E >= 0) {
+ t = 0;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else if (-E >= C) {
+ t = 1;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ t = -E/C;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.scaleAdd (t, seg1dir, seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(E*t+F);
+ }
+ }
+ }
+ }
+ else { // region 6 (corner)
+ if (D < 0) {
+ t = 0;
+ if (-D >= A) {
+ s = 1;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+2*D+F);
+ }
+ else {
+ s = -D/A;
+ if (seg0int != null) seg0int.scaleAdd (s, seg0dir, seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ }
+ else {
+ s = 0;
+ if (E >= 0) {
+ t = 0;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else if (-E >= C) {
+ t = 1;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ t = -E/C;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.scaleAdd (t, seg1dir, seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(E*t+F);
+ }
+ }
+ }
+ }
+ }
+ else {
+ // line segments are parallel
+ if (B > 0) {
+ // direction vectors form an obtuse angle
+ if (D >= 0) {
+ s = 0;
+ t = 0;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F);
+ }
+ else if (-D <= A) {
+ s = -D/A;
+ t = 0;
+ if (seg0int != null) seg0int.scaleAdd (s, seg0dir, seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ else {
+ E = -seg1dir.dot (diff); //-Dot(seg1dir,diff);
+ s = 1;
+ tmp = A+D;
+ if (-tmp >= B) {
+ t = 1;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+C+F+2*(B+D+E));
+ }
+ else {
+ t = -tmp/B;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.scaleAdd (t, seg1dir, seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+2*D+F+t*(C*t+2*(B+E)));
+ }
+ }
+ }
+ else {
+ // direction vectors form an acute angle
+ if (-D >= A) {
+ s = 1;
+ t = 0;
+ if (seg0int != null) seg0int.set (seg0end);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(A+2*D+F);
+ }
+ else if (D <= 0) {
+ s = -D/A;
+ t = 0;
+ if (seg0int != null) seg0int.scaleAdd (s, seg0dir, seg0start);
+ if (seg1int != null) seg1int.set (seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(D*s+F);
+ }
+ else {
+ E = -seg1dir.dot (diff); //-Dot(seg1dir,diff);
+ s = 0;
+ if (D >= -B) {
+ t = 1;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.set (seg1end);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(C+2*E+F);
+ }
+ else {
+ t = -D/B;
+ if (seg0int != null) seg0int.set (seg0start);
+ if (seg1int != null) seg1int.scaleAdd (t, seg1dir, seg1start);
+ if (param != null) { param[0] = s; param[1] = t; }
+ return DIST(F+t*(2*E+C*t));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+
diff --git a/src/classes/share/com/sun/j3d/internal/DoubleBufferWrapper.java b/src/classes/share/com/sun/j3d/internal/DoubleBufferWrapper.java
new file mode 100755
index 0000000..c6f011d
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/DoubleBufferWrapper.java
@@ -0,0 +1,153 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package com.sun.j3d.internal;
+
+import javax.media.j3d.J3DBuffer;
+import java.nio.DoubleBuffer;
+
+/**
+ * NIO Buffers are new in Java 1.4 but we need to run on 1.3
+ * as well, so this class was created to hide the NIO classes
+ * from non-1.4 Java 3D users.
+ *
+ * <p>
+ * NOTE: We no longer need to support JDK 1.3 as of the Java 3D 1.3.2
+ * community source release on java.net. We should be able to get rid
+ * of this class.
+ */
+
+public class DoubleBufferWrapper extends BufferWrapper {
+
+ private DoubleBuffer buffer = null;
+
+ /**
+ * Constructor initializes buffer with a
+ * java.nio.DoubleBuffer object.
+ */
+ public DoubleBufferWrapper(DoubleBuffer buffer) {
+ this.buffer = buffer;
+ }
+
+ /**
+ * Constructor initializes buffer with a
+ * javax.media.j3d.J3DBuffer object.
+ */
+ public DoubleBufferWrapper(J3DBuffer b) {
+ buffer = (DoubleBuffer)(b.getBuffer());
+ }
+
+ /**
+ * Returns the java.nio.Buffer contained within this
+ * DoubleBufferWrapper.
+ */
+ public java.nio.Buffer getBuffer() {
+ return this.buffer;
+ }
+
+ // Wrapper for all relevant DoubleBuffer methods.
+
+ /**
+ * @return A boolean indicating whether the java.nio.Buffer
+ * object contained within this DoubleBuffer is direct or
+ * indirect.
+ */
+ public boolean isDirect() {
+ return buffer.isDirect();
+ }
+
+ /**
+ * Reads the double at this buffer's current position,
+ * and then increments the position.
+ */
+ public double get() {
+ return buffer.get();
+ }
+
+ /**
+ * Reads the double at the given offset into the buffer.
+ */
+ public double get(int index) {
+ return buffer.get(index);
+ }
+
+ /**
+ * Bulk <i>get</i> method. Transfers <code>dst.length</code>
+ * doubles from
+ * the buffer to the destination array and increments the
+ * buffer's position by <code>dst.length</code>.
+ */
+ public DoubleBufferWrapper get(double[] dst) {
+ buffer.get(dst);
+ return this;
+ }
+
+ /**
+ * Bulk <i>get</i> method. Transfers <i>length</i> doubles
+ * from the buffer starting at position <i>offset</i> into
+ * the destination array.
+ */
+ public DoubleBufferWrapper get(double[] dst, int offset, int length){
+ buffer.get(dst, offset, length);
+ return this;
+ }
+
+ /**
+ * Bulk <i>put</i> method. Transfers <code>src.length</code>
+ * doubles into the buffer at the current position.
+ */
+ public DoubleBufferWrapper put(double[] src) {
+ buffer.put(src);
+ return this;
+ }
+
+ /**
+ * Creates and returns a J3DBuffer object containing the
+ * buffer in this DoubleBufferWrapper object.
+ */
+ public J3DBuffer getJ3DBuffer() {
+ return new J3DBuffer( buffer );
+ }
+
+}
diff --git a/src/classes/share/com/sun/j3d/internal/FastVector.java b/src/classes/share/com/sun/j3d/internal/FastVector.java
new file mode 100644
index 0000000..b3ed4c2
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/FastVector.java
@@ -0,0 +1,143 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package com.sun.j3d.internal;
+
+/**
+ * The FastVector object is a growable array of ints. It's much faster
+ * than the Java Vector class because it isn't synchronized. This class
+ * was created because it is needed in several places by graphics
+ * utilities.
+ */
+public class FastVector {
+
+ private int data[];
+ private int capacity;
+ private int increment;
+ private int size;
+
+ /**
+ * Add an element to the end of the array.
+ */
+ public void addElement(int element)
+ {
+ if (size >= capacity) {
+ capacity += (increment == 0) ? capacity : increment;
+ int newData[] = new int[capacity];
+ System.arraycopy(data, 0, newData, 0, size);
+ data = newData;
+ }
+ data[size++] = element;
+ } // End of addElement
+
+
+
+ /**
+ * Get number of ints currently stored in the array;
+ */
+ public int getSize()
+ {
+ return size;
+ } // End of getSize
+
+
+
+ /**
+ * Get access to array data
+ */
+ public int[] getData()
+ {
+ return data;
+ } // End of getData
+
+
+
+ /**
+ * Constructor.
+ * @param initialCapacity Number of ints the object can hold
+ * without reallocating the array.
+ * @param capacityIncrement Once the array has grown beyond
+ * its capacity, how much larger the reallocated array should be.
+ */
+ public FastVector(int initialCapacity, int capacityIncrement)
+ {
+ data = new int[initialCapacity];
+ capacity = initialCapacity;
+ increment = capacityIncrement;
+ size = 0;
+ } // End of FastVector(int, int)
+
+
+
+ /**
+ * Constructor.
+ * When the array runs out of space, its size is doubled.
+ * @param initialCapacity Number of ints the object can hold
+ * without reallocating the array.
+ */
+ public FastVector(int initialCapacity)
+ {
+ data = new int[initialCapacity];
+ capacity = initialCapacity;
+ increment = 0;
+ size = 0;
+ } // End of FastVector(int)
+
+
+
+ /**
+ * Constructor.
+ * The array is constructed with initial capacity of one integer.
+ * When the array runs out of space, its size is doubled.
+ */
+ public FastVector()
+ {
+ data = new int[1];
+ capacity = 1;
+ increment = 0;
+ size = 0;
+ } // End of FastVector()
+} // End of class FastVector
+
+// End of file FastVector.java
diff --git a/src/classes/share/com/sun/j3d/internal/FloatBufferWrapper.java b/src/classes/share/com/sun/j3d/internal/FloatBufferWrapper.java
new file mode 100755
index 0000000..8868901
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/FloatBufferWrapper.java
@@ -0,0 +1,152 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package com.sun.j3d.internal;
+
+import javax.media.j3d.J3DBuffer;
+import java.nio.FloatBuffer;
+
+/**
+ * NIO Buffers are new in Java 1.4 but we need to run on 1.3
+ * as well, so this class was created to hide the NIO classes
+ * from non-1.4 Java 3D users.
+ *
+ * <p>
+ * NOTE: We no longer need to support JDK 1.3 as of the Java 3D 1.3.2
+ * community source release on java.net. We should be able to get rid
+ * of this class.
+ */
+
+public class FloatBufferWrapper extends BufferWrapper {
+
+ private FloatBuffer buffer = null;
+
+ /**
+ * Constructor initializes buffer with a
+ * java.nio.FloatBuffer object.
+ */
+ public FloatBufferWrapper(FloatBuffer buffer) {
+ this.buffer = buffer;
+ }
+
+ /**
+ * Constructor initializes buffer with a
+ * javax.media.j3d.J3DBuffer object.
+ */
+ public FloatBufferWrapper(javax.media.j3d.J3DBuffer b) {
+ this.buffer = (FloatBuffer)(b.getBuffer());
+ }
+
+ /**
+ * Returns the java.nio.Buffer contained within this
+ * FloatBufferWrapper.
+ */
+ public java.nio.Buffer getBuffer() {
+ return this.buffer;
+ }
+
+ // Wrapper for all relevant FloatBuffer methods.
+
+ /**
+ * @return A boolean indicating whether the java.nio.Buffer
+ * object contained within this FloatBuffer is direct or
+ * indirect.
+ */
+ public boolean isDirect() {
+ return buffer.isDirect();
+ }
+
+ /**
+ * Reads the float at this buffer's current position,
+ * and then increments the position.
+ */
+ public float get() {
+ return buffer.get();
+ }
+
+ /**
+ * Reads the float at the given offset into the buffer.
+ */
+ public float get(int index) {
+ return buffer.get(index);
+ }
+
+ /**
+ * Bulk <i>get</i> method. Transfers <code>dst.length</code>
+ * floats from
+ * the buffer to the destination array and increments the
+ * buffer's position by <code>dst.length</code>.
+ */
+ public FloatBufferWrapper get(float[] dst) {
+ buffer.get(dst);
+ return this;
+ }
+
+ /**
+ * Bulk <i>get</i> method. Transfers <i>length</i> floats
+ * from the buffer starting at position <i>offset</i> into
+ * the destination array.
+ */
+ public FloatBufferWrapper get(float[] dst, int offset, int length){
+ buffer.get(dst, offset, length);
+ return this;
+ }
+
+ /**
+ * Bulk <i>put</i> method. Transfers <code>src.length</code>
+ * floats into the buffer at the current position.
+ */
+ public FloatBufferWrapper put(float[] src) {
+ buffer.put(src);
+ return this;
+ }
+
+ /**
+ * Creates and returns a J3DBuffer object containing the
+ * buffer in this FloatBufferWrapper object.
+ */
+ public J3DBuffer getJ3DBuffer() {
+ return new J3DBuffer( buffer );
+ }
+}
diff --git a/src/classes/share/com/sun/j3d/internal/J3dUtilsI18N.java b/src/classes/share/com/sun/j3d/internal/J3dUtilsI18N.java
new file mode 100644
index 0000000..a61c43a
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/J3dUtilsI18N.java
@@ -0,0 +1,63 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package com.sun.j3d.internal;
+
+import java.io.*;
+import java.util.*;
+
+
+public class J3dUtilsI18N {
+ static public String getString(String key) {
+ String s;
+ try {
+ s = (String) ResourceBundle.getBundle("com.sun.j3d.ExceptionStrings").getString(key);
+ }
+ catch (MissingResourceException e) {
+ System.err.println("J3dUtilsI18N: Error looking up: " + key);
+ s = key;
+ }
+ return s;
+ }
+}
diff --git a/src/classes/share/com/sun/j3d/internal/UtilFreelistManager.java b/src/classes/share/com/sun/j3d/internal/UtilFreelistManager.java
new file mode 100644
index 0000000..457968a
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/UtilFreelistManager.java
@@ -0,0 +1,98 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package com.sun.j3d.internal;
+
+
+public class UtilFreelistManager {
+
+ private static final boolean DEBUG = false;
+
+ // constants that represent the freelists managed by the Manager
+ public static final int VECTOR3D = 0;
+ public static final int POINT3D = 1;
+ public static final int PICKRESULT = 2;
+ public static final int MAXINT = 2;
+
+ // what list we are going to shrink next
+ private static int currlist = 0;
+
+ // the freelists managed by the manager
+ public static UtilMemoryFreelist vector3dFreelist = new UtilMemoryFreelist("javax.vecmath.Vector3d");
+ public static UtilMemoryFreelist point3dFreelist = new UtilMemoryFreelist("javax.vecmath.Point3d");
+ public static UtilMemoryFreelist pickResultFreelist = new UtilMemoryFreelist("com.sun.j3d.utils.picking.PickResult");
+
+
+// static MemoryFreeList[] freelist = new MemoryFreeList[MAXINT+1];
+
+// static void createFreeLists() {
+// freelist[VECTOR3D] = new MemoryFreeList("javax.vecmath.Vector3d");
+// freelist[POINT3D] = new MemoryFreeList("javax.vecmath.Point3d");
+// }
+
+
+// // see if the current list can be shrunk
+// static void manageLists() {
+// // System.out.println("manageLists");
+// if (freelist[currlist] != null) {
+// freelist[currlist].shrink();
+// }
+
+// currlist++;
+// if (currlist > MAXINT) currlist = 0;
+// }
+
+// // return the freelist specified by the list param
+// static MemoryFreeList getFreeList(int list) {
+// if (list < 0 || list > MAXINT) {
+// if (DEBUG) System.out.println("illegal list");
+// return null;
+// }
+// else {
+// return freelist[list];
+// }
+// }
+
+
+}
diff --git a/src/classes/share/com/sun/j3d/internal/UtilMemoryFreelist.java b/src/classes/share/com/sun/j3d/internal/UtilMemoryFreelist.java
new file mode 100644
index 0000000..3f559b7
--- /dev/null
+++ b/src/classes/share/com/sun/j3d/internal/UtilMemoryFreelist.java
@@ -0,0 +1,292 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package com.sun.j3d.internal;
+
+import java.util.*;
+
+// this class must be synchronized because different threads may try to access
+// the freelists
+public class UtilMemoryFreelist { // extends AbstractList {
+
+ // never go smaller than the initial capacity
+ ArrayList elementData = null;
+ int size = 0;
+ int currBlockSize = 10;
+ Object[] currBlock = null;
+ int currBlockIndex = 0;
+ int spaceUsed = 0;
+ int numBlocks = 0;
+ int capacity = 0;
+ int minBlockSize = 0;
+ boolean justShrunk = false;
+ int initcap = 10;
+
+ // the minimum size since the last shrink
+ int minSize = 0;
+
+ Class c = null;
+
+ public UtilMemoryFreelist(String className) {
+ this(className, 10);
+ }
+
+ public UtilMemoryFreelist(String className, int initialCapacity) {
+ if (initialCapacity < 0) {
+ throw new IllegalArgumentException ("Illegal Capacity: " +
+ initialCapacity);
+ }
+
+ try {
+ c = Class.forName(className);
+ }
+ catch (Exception e) {
+// System.out.println(e);
+ }
+
+ initcap = initialCapacity;
+ currBlockSize = initialCapacity;
+ minBlockSize = currBlockSize;
+ elementData = new ArrayList();
+ // add the first block of memory to the arraylist
+ currBlock = new Object[currBlockSize];
+ elementData.add(currBlock);
+ numBlocks++;
+ capacity += currBlockSize;
+ }
+
+ public UtilMemoryFreelist(String className, Collection collection) {
+ try {
+ c = Class.forName(className);
+ }
+ catch (Exception e) {
+// System.out.println(e);
+ }
+ size = collection.size();
+ initcap = size;
+ currBlockSize = size;
+ minBlockSize = currBlockSize;
+ elementData = new ArrayList();
+ currBlock = new Object[currBlockSize];
+ collection.toArray(currBlock);
+ elementData.add(currBlock);
+ numBlocks++;
+ capacity += currBlockSize;
+ spaceUsed = size;
+ }
+
+ public synchronized int size() {
+ return size;
+ }
+
+
+ public synchronized boolean add(Object o) {
+ if (justShrunk) {
+ // empty some space out in the current block instead of
+ // adding this message
+ if ((currBlockSize/2) < spaceUsed) {
+ size -= (spaceUsed - (currBlockSize/2));
+ spaceUsed = (currBlockSize/2);
+ Arrays.fill(currBlock, spaceUsed, currBlockSize-1, null);
+ }
+ justShrunk = false;
+ return false;
+ }
+ else {
+ ensureCapacity(size+1);
+
+ // check to see if the whole block is used and if so, reset the
+ // current block
+// System.out.println("spaceUsed = " + spaceUsed + " currBlockSize = " +
+// currBlockSize + " currBlockIndex = " +
+// currBlockIndex + " currBlock = " + currBlock);
+ if ((currBlockIndex == -1) || (spaceUsed >= currBlockSize)) {
+ currBlockIndex++;
+ currBlock = (Object[])elementData.get(currBlockIndex);
+ currBlockSize = currBlock.length;
+ spaceUsed = 0;
+ }
+ int index = spaceUsed++;
+ currBlock[index] = o;
+ size++;
+
+ return true;
+ }
+ }
+
+ private synchronized Object removeLastElement() {
+// System.out.println("removeLastElement: size = " + size);
+ int index = --spaceUsed;
+// System.out.println("index = " + index);
+ Object elm = currBlock[index];
+ currBlock[index] = null;
+ size--;
+
+ // see if this block is empty now, and if it is set the previous
+ // block to the current block
+ if (spaceUsed == 0) {
+ currBlockIndex--;
+ if (currBlockIndex < 0) {
+ currBlock = null;
+ currBlockSize = 0;
+ }
+ else {
+ currBlock = (Object[])elementData.get(currBlockIndex);
+ currBlockSize = currBlock.length;
+ }
+ spaceUsed = currBlockSize;
+ }
+
+ return elm;
+ }
+
+
+ public synchronized void shrink() {
+// System.out.println("shrink size = " + size + " minSize = " +
+// minSize);
+ if ((minSize > minBlockSize) && (numBlocks > 1)) {
+ justShrunk = true;
+
+// System.out.println("removing a block");
+// Runtime r = Runtime.getRuntime();
+// r.gc();
+// System.out.println("numBlocks = " + numBlocks + " size = " + size);
+// System.out.println("free memory before shrink: " + r.freeMemory());
+
+ // remove the last block
+ Object[] block = (Object[])elementData.remove(numBlocks-1);
+ numBlocks--;
+ capacity -= block.length;
+
+ // we only need to do this if the block removed was the current
+ // block. otherwise we just removed a null block.
+ if (numBlocks == currBlockIndex) {
+ size -= spaceUsed;
+ // set the current block to the last one
+ currBlockIndex = numBlocks-1;
+ currBlock = (Object[])elementData.get(currBlockIndex);
+ currBlockSize = currBlock.length;
+
+ spaceUsed = currBlockSize;
+
+ }
+
+// r.gc();
+// System.out.println("free memory after shrink: " + r.freeMemory());
+// System.out.println("numBlocks = " + numBlocks + " size = " + size);
+ }
+ else {
+ justShrunk = false;
+ }
+ minSize = size;
+ }
+
+ public synchronized void ensureCapacity(int minCapacity) {
+// System.out.println("ensureCapacity: size = " + size + " capacity: " +
+// elementData.length);
+// System.out.println("minCapacity = " + minCapacity + " capacity = "
+// + capacity);
+
+ if (minCapacity > capacity) {
+// System.out.println("adding a block: numBlocks = " + numBlocks);
+ int lastBlockSize =
+ ((Object[])elementData.get(numBlocks-1)).length;
+ int prevBlockSize = 0;
+ if (numBlocks > 1) {
+ prevBlockSize =
+ ((Object[])elementData.get(numBlocks-2)).length;
+ }
+ currBlockSize = lastBlockSize + prevBlockSize;
+ currBlock = new Object[currBlockSize];
+ elementData.add(currBlock);
+ numBlocks++;
+ currBlockIndex++;
+ capacity += currBlockSize;
+ // there is nothing used in this block yet
+ spaceUsed = 0;
+ }
+ }
+
+ synchronized void rangeCheck(int index) {
+ if (index >= size || index < 0) {
+ throw new IndexOutOfBoundsException("Index: " + index +
+ ", Size: " + size);
+ }
+ }
+
+ public synchronized void clear() {
+// System.out.println("clear");
+ elementData.clear();
+
+ // put an empty block in
+ currBlockSize = initcap;
+ minBlockSize = currBlockSize;
+ currBlock = new Object[currBlockSize];
+ elementData.add(currBlock);
+ numBlocks = 1;
+ capacity = currBlockSize;
+ spaceUsed = 0;
+ size = 0;
+ currBlockIndex = 0;
+ justShrunk = false;
+ }
+
+ public synchronized Object getObject() {
+ if (size > 0) {
+ return removeLastElement();
+ }
+ else {
+ try {
+ return c.newInstance();
+ }
+ catch (Exception e) {
+// System.out.println("caught exception");
+// System.out.print(e);
+ return null;
+ }
+ }
+ }
+
+}
+