diff -r 4cb233cbad35 -r 1221cace448b javafx-ui-common/src/javafx/scene/shape/Box.java --- a/javafx-ui-common/src/javafx/scene/shape/Box.java Thu Apr 04 17:09:33 2013 -0700 +++ b/javafx-ui-common/src/javafx/scene/shape/Box.java Fri Apr 12 19:22:35 2013 -0700 @@ -387,8 +387,7 @@ 0, 0, 1, 1, 4, 2, 4, 2, 1, 1, 5, 3, 2, 0, 6, 2, 3, 1, 3, 1, 6, 2, 7, 3, 0, 0, 4, 1, 2, 2, 2, 2, 4, 1, 6, 3, 1, 0, 3, 1, 5, 2, 5, 2, 3, 1, 7, 3,}; - TriangleMesh mesh = new TriangleMesh(points, texCoords, faces); - mesh.setFaceSmoothingGroups(faceSmoothingGroups); + TriangleMesh mesh = new TriangleMesh(points, texCoords, faces, faceSmoothingGroups); return mesh; } diff -r 4cb233cbad35 -r 1221cace448b javafx-ui-common/src/javafx/scene/shape/Cylinder.java --- a/javafx-ui-common/src/javafx/scene/shape/Cylinder.java Thu Apr 04 17:09:33 2013 -0700 +++ b/javafx-ui-common/src/javafx/scene/shape/Cylinder.java Fri Apr 12 19:22:35 2013 -0700 @@ -489,8 +489,7 @@ smoothing[i] = 2; } - TriangleMesh m = new TriangleMesh(points, tPoints, faces); - m.setFaceSmoothingGroups(smoothing); + TriangleMesh m = new TriangleMesh(points, tPoints, faces, smoothing); return m; } diff -r 4cb233cbad35 -r 1221cace448b javafx-ui-common/src/javafx/scene/shape/FloatArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javafx-ui-common/src/javafx/scene/shape/FloatArray.java Fri Apr 12 19:22:35 2013 -0700 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javafx.scene.shape; + + +/** + * + * @author akouznet + */ +public class FloatArray extends ObservableArray { + + private float[] array; + + final float[] getArray() { + return array; + } + + public FloatArray(int COMPONENTS_PER_ELEMENT) { + super(COMPONENTS_PER_ELEMENT); + } + + /** + * Sets the array of this {@code TriangleMesh} + * + * @param array source array of components_per_element * n values containing n new array. + */ + public final void setArray(float[] array) { + checkLength(array.length); + + if ((this.array == null) || (this.array.length < array.length)) { + this.array = new float[array.length]; + } + System.arraycopy(array, 0, this.array, 0, array.length); + // Store the valid elements count. + // Note this.array.length can be bigger than array.length. + setSize(array.length / COMPONENTS_PER_ELEMENT); + + setDirty(true); + } + + /** + * Sets the array associated with this {@code FloatArray} + * starting at the specified {@code index} using data in {@code array} + * starting at index {@code start} for {@code length} number of array. + * + * @param index the starting destination index in this TriangleMesh's array array + * @param array source array of floats containing the new array + * @param start starting source index in the array array. + * @param length number of point elements to be copied. + */ + public final void setArray(int index, float[] array, + int start, int length) { + + if (index < 0 || start < 0 || length < 0) { + throw new IllegalArgumentException("index, start and length can't be negative"); + } + int startOffset = start * COMPONENTS_PER_ELEMENT; + int lengthInFloatUnit = length * COMPONENTS_PER_ELEMENT; + if ((startOffset >= array.length) || ((startOffset + lengthInFloatUnit) > array.length)) { + throw new IllegalArgumentException("start or (start + length) is out of range for input array"); + } + int indexOffset = index * COMPONENTS_PER_ELEMENT; + int pointCountInFloatUnit = size() * COMPONENTS_PER_ELEMENT; + if ((indexOffset >= pointCountInFloatUnit) || + ((indexOffset + lengthInFloatUnit) > pointCountInFloatUnit)) { + throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's array"); + } + System.arraycopy(array, startOffset, this.array, indexOffset, lengthInFloatUnit); + + addDirtyRange(index, length); + } + + /** + * Gets the array of this {@code TriangleMesh} + * + * @param array a float array that will receive the array + * if it not null and has sufficient capacity. + * @return a float array of array + */ + public final float[] getArray(float[] array) { + if (this.array == null) { + return null; + } + int pointCountInFloatUnit = size() * COMPONENTS_PER_ELEMENT; + if ((array == null) || (pointCountInFloatUnit > array.length)) { + array = new float[pointCountInFloatUnit]; + } + System.arraycopy(this.array, 0, array, 0, pointCountInFloatUnit); + return array; + } + + public final float get(int index) { + return array[index]; + } + + /** + * Gets the array associated with this {@code TriangleMesh} starting at the + * specified {@code index} for {@code length} number of array. + * + * @param index starting source array index in this {@code TriangleMesh} + * @param array destination array that will receive this {@code TriangleMesh}'s array data + * @param length number of point elements to be copied + * @return a float array of array + */ + public final float[] getArray(int index, float[] array, int length) { + if (index < 0 || length < 0) { + throw new IllegalArgumentException("index and length have to be non-zero"); + } + + int lengthInFloatUnit = length * COMPONENTS_PER_ELEMENT; + if (lengthInFloatUnit > array.length) { + throw new IllegalArgumentException("length is out of range for input array"); + } + int indexOffset = index * COMPONENTS_PER_ELEMENT; + int pointCountInFloatUnit = size() * COMPONENTS_PER_ELEMENT; + if ((indexOffset >= pointCountInFloatUnit) || + ((indexOffset + lengthInFloatUnit) > pointCountInFloatUnit)) { + throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's array"); + } + + if (this.array == null) { + return null; + } + System.arraycopy(this.array, indexOffset, array, 0, lengthInFloatUnit); + return array; + } + + private void checkLength(int length) throws IllegalArgumentException { + // Check that array.length is divisible by components_per_element + if ((length % COMPONENTS_PER_ELEMENT) != 0) { + throw new IllegalArgumentException("array.length has to be divisible by " + COMPONENTS_PER_ELEMENT + "."); + } + } +} \ No newline at end of file diff -r 4cb233cbad35 -r 1221cace448b javafx-ui-common/src/javafx/scene/shape/IntegerArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javafx-ui-common/src/javafx/scene/shape/IntegerArray.java Fri Apr 12 19:22:35 2013 -0700 @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javafx.scene.shape; + +/** + * + * @author akouznet + */ +public class IntegerArray extends ObservableArray { + + private int[] array; + + final int[] getArray() { + return array; + } + + public IntegerArray() { + super(1); + } + + public IntegerArray(int COMPONENTS_PER_ELEMENT) { + super(COMPONENTS_PER_ELEMENT); + } + + /** + * Sets the array, indices into the points and texCoords arrays, + * associated with this {@code TriangleMesh}. + * + * @param array source array of components_per_element * n indices + * (3 point indices and 3 texCood indices) containing n new array + */ + public final void setArray(int[] array) { + // Check that array.length is divisible by components_per_element + if ((array.length % COMPONENTS_PER_ELEMENT) != 0) { + throw new IllegalArgumentException("array.length has to be divisible by components_per_element (" + COMPONENTS_PER_ELEMENT + ")."); + } + + if ((this.array == null) || (this.array.length < array.length)) { + this.array = new int[array.length]; + } + System.arraycopy(array, 0, this.array, 0, array.length); + // Store the valid face count. + // Note this.array.length can be bigger than array.length. + setSize(array.length / COMPONENTS_PER_ELEMENT); + + setDirty(true); + } + + /** + * Sets the array, indices into the points and texCoords arrays, + * associated with this {@code TriangleMesh} + * starting at the specified{@code index} using data in {@code array} + * starting at index {@code start} for {@code length} number of array. + * + * @param index the starting destination index in this TriangleMesh's array array + * @param array an int array containing the new interleaved vertices + * @param start starting source index in the array array. + * @param length number of interleaved vertex elements to be copied + */ + public final void setArray(int index, int[] array, int start, int length) { + if (index < 0 || start < 0 || length < 0) { + throw new IllegalArgumentException("index, start and length have to be non-zero"); + } + int startOffset = start * COMPONENTS_PER_ELEMENT; + int lengthInIntUnit = length * COMPONENTS_PER_ELEMENT; + if ((startOffset >= array.length) || ((startOffset + lengthInIntUnit) > array.length)) { + throw new IllegalArgumentException("start or (start + length) is out of range for input array"); + } + int indexOffset = index * COMPONENTS_PER_ELEMENT; + int sizeInIntUnit = size() * COMPONENTS_PER_ELEMENT; + if ((indexOffset >= sizeInIntUnit) || + ((indexOffset + lengthInIntUnit) > sizeInIntUnit)) { + throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's array"); + } + System.arraycopy(array, startOffset, this.array, indexOffset, lengthInIntUnit); + + addDirtyRange(index, length); + } + + /** + * Gets the array, indices into the points and texCoords arrays, of this + * {@code TriangleMesh} + * + * @param array an int array that will receive the array if it not null and + * has sufficient capacity. + * @return an int array of array + * + */ + public final int[] getArray(int[] array) { + if (this.array == null) { + return null; + } + + int sizeInIntUnit = size() * COMPONENTS_PER_ELEMENT; + if ((array == null) || (sizeInIntUnit > array.length)) { + array = new int[sizeInIntUnit]; + } + System.arraycopy(this.array, 0, array, 0, sizeInIntUnit); + return array; + } + + public int get(int index) { + return array[index]; + } + + /** + * Gets the array, indices into the points and texCoords arrays, + * associated with this {@code TriangleMesh} starting at the specified + * {@code index} for {@code length} number of array. + * + * @param index starting source array index in this {@code TriangleMesh} + * @param array destination array that will receive this {@code TriangleMesh}'s array data + * @param length number of face elements to be copied + * @return an int array of array + */ + public final int[] getArray(int index, int[] array, int length) { + if (index < 0 || length < 0) { + throw new IllegalArgumentException("index and length have to be non-zero"); + } + + int lengthInIntUnit = length * COMPONENTS_PER_ELEMENT; + if (lengthInIntUnit > array.length) { + throw new IllegalArgumentException("length is out of range for input array"); + } + int indexOffset = index * COMPONENTS_PER_ELEMENT; + int sizeInIntUnit = size() * COMPONENTS_PER_ELEMENT; + if ((indexOffset >= sizeInIntUnit) || + ((indexOffset + lengthInIntUnit) > sizeInIntUnit)) { + throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's array"); + } + + if (this.array == null) { + return null; + } + System.arraycopy(this.array, indexOffset, array, 0, lengthInIntUnit); + return array; + } +} diff -r 4cb233cbad35 -r 1221cace448b javafx-ui-common/src/javafx/scene/shape/ObservableArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javafx-ui-common/src/javafx/scene/shape/ObservableArray.java Fri Apr 12 19:22:35 2013 -0700 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javafx.scene.shape; + + +import javafx.beans.property.ReadOnlyIntegerProperty; +import javafx.beans.property.ReadOnlyIntegerWrapper; + + +/** + * + * @author akouznet + */ +public class ObservableArray { + + protected final int COMPONENTS_PER_ELEMENT; + protected boolean dirty; + protected boolean dirtyInFull; + protected int dirtyRangeFrom; + protected int dirtyRangeLength; + + public ObservableArray(int COMPONENTS_PER_ELEMENT) { + this.COMPONENTS_PER_ELEMENT = COMPONENTS_PER_ELEMENT; + } + + final int getDirtyRangeLength() { + return dirtyRangeLength; + } + + final int getDirtyRangeFrom() { + return dirtyRangeFrom; + } + + public final boolean isDirty() { + return dirty; + } + + public boolean isDirtyInFull() { + return dirtyInFull; + } + + final void setDirty(boolean dirty) { + this.dirty = this.dirtyInFull = dirty; + dirtyRangeLength = 0; + } + + final void addDirtyRange(int from, int length) { + if (!dirtyInFull) { + dirty = true; + if (dirtyRangeLength == 0) { + dirtyRangeFrom = from; + dirtyRangeLength = length; + } else { + int fromIndex = Math.min(dirtyRangeFrom, from); + int toIndex = Math.max(dirtyRangeFrom + dirtyRangeLength, from + length); + dirtyRangeFrom = fromIndex; + dirtyRangeLength = toIndex - fromIndex; + } + } + } + + /** + * The total number of elements of this {@code ObservableArray} + * This is {@code array.length / COMPONENTS_PER_ELEMENT}. + */ + protected ReadOnlyIntegerWrapper size = new ReadOnlyIntegerWrapper(this, "size"); + + final void setSize(int value) { + sizePropertyImpl().set(value); + } + + /** + * Retrieve total number of elements of this {@code FloatArray} + * + * @return the total number of elements + */ + public final int size() { + return size.get(); + } + + public ReadOnlyIntegerProperty sizeProperty() { + return sizePropertyImpl().getReadOnlyProperty(); + } + + protected ReadOnlyIntegerWrapper sizePropertyImpl() { + return size; + } +} diff -r 4cb233cbad35 -r 1221cace448b javafx-ui-common/src/javafx/scene/shape/Sphere.java --- a/javafx-ui-common/src/javafx/scene/shape/Sphere.java Thu Apr 04 17:09:33 2013 -0700 +++ b/javafx-ui-common/src/javafx/scene/shape/Sphere.java Fri Apr 12 19:22:35 2013 -0700 @@ -402,8 +402,7 @@ smoothing[i] = 1; } - TriangleMesh m = new TriangleMesh(points, tPoints, faces); - m.setFaceSmoothingGroups(smoothing); + TriangleMesh m = new TriangleMesh(points, tPoints, faces, smoothing); return m; } diff -r 4cb233cbad35 -r 1221cace448b javafx-ui-common/src/javafx/scene/shape/TriangleMesh.java --- a/javafx-ui-common/src/javafx/scene/shape/TriangleMesh.java Thu Apr 04 17:09:33 2013 -0700 +++ b/javafx-ui-common/src/javafx/scene/shape/TriangleMesh.java Fri Apr 12 19:22:35 2013 -0700 @@ -32,8 +32,6 @@ import com.sun.javafx.scene.input.PickResultChooser; import com.sun.javafx.sg.PGTriangleMesh; import com.sun.javafx.tk.Toolkit; -import javafx.beans.property.ReadOnlyIntegerProperty; -import javafx.beans.property.ReadOnlyIntegerWrapper; import javafx.geometry.Point2D; import javafx.geometry.Point3D; import javafx.scene.Node; @@ -84,29 +82,12 @@ public static final int NUM_COMPONENTS_PER_TEXCOORD = 2; public static final int NUM_COMPONENTS_PER_FACE = 6; - private float[] points; - private float[] texCoords; - private int[] faces; - private int[] faceSmoothingGroups; + private FloatArray points = new FloatArray(NUM_COMPONENTS_PER_POINT); + private FloatArray texCoords = new FloatArray(NUM_COMPONENTS_PER_TEXCOORD); + private IntegerArray faces = new IntegerArray(NUM_COMPONENTS_PER_FACE); + private IntegerArray faceSmoothingGroups = new IntegerArray(); - private boolean pointsDirty = true; - private boolean texCoordsDirty = true; - private boolean facesDirty = true; - private boolean fsgDirty = true; - - // Partial Update constants and variables - private static final int RANGE_INDEX = 0; - private static final int RANGE_LENGTH = 1; - private static final int MAX_RANGE_SIZE = 2; private int refCount = 1; - private boolean pointUpdateRange = false; - private int[] pointRangeInfos; - private boolean texCoordUpdateRange = false; - private int[] texCoordRangeInfos; - private boolean faceUpdateRange = false; - private int[] faceRangeInfos; - private boolean fsgUpdateRange = false; - private int[] fsgRangeInfos; private BaseBounds cachedBounds; @@ -127,629 +108,40 @@ * by NUM_COMPONENTS_PER_FACE) */ public TriangleMesh(float[] points, float[] texCoords, int[] faces) { - setPoints(points); - setTexCoords(texCoords); - setFaces(faces); + this.points.setArray(points); + this.texCoords.setArray(texCoords); + this.faces.setArray(faces); + } + /** + * Creates a new instance of {@code TriangleMesh} class. + * TODO: 3D - doc. follows array semantic + * + * @param points points array (points.length must be divisible by NUM_COMPONENTS_PER_POINT) + * @param texCoords texCoords array (texCoords.length must be divisible by + * NUM_COMPONENTS_PER_TEXCOORD) + * @param faces faces (or triangles) array (faces.length must be divisible + * by NUM_COMPONENTS_PER_FACE) + */ + public TriangleMesh(float[] points, float[] texCoords, int[] faces, int[] faceSmoothingGroups) { + this.points.setArray(points); + this.texCoords.setArray(texCoords); + this.faces.setArray(faces); + this.faceSmoothingGroups.setArray(faceSmoothingGroups); } - /** - * The total number of points of this {@code TriangleMesh} - */ - private ReadOnlyIntegerWrapper pointCount; - - final void setPointCount(int value) { - pointCountPropertyImpl().set(value); - } - - /** - * Retrieve total number of points of this {@code TriangleMesh} - * - * @return the total number of points - */ - public final int getPointCount() { - return pointCount == null ? 0 : pointCount.get(); - } - - public ReadOnlyIntegerProperty pointCountProperty() { - return pointCountPropertyImpl().getReadOnlyProperty(); - } - - private ReadOnlyIntegerWrapper pointCountPropertyImpl() { - if (pointCount == null) { - pointCount = new ReadOnlyIntegerWrapper(this, "pointCount"); - } - return pointCount; - } - - /** - * The total number of texture coordinates of this {@code TriangleMesh} - */ - private ReadOnlyIntegerWrapper texCoordCount; - - final void setTexCoordCount(int value) { - texCoordCountPropertyImpl().set(value); - } - - /** - * Retrieve total number of texture coordinates of this {@code TriangleMesh} - * - * @return the total number of texture coordinates - */ - public final int getTexCoordCount() { - return texCoordCount == null ? 0 : texCoordCount.get(); - } - - public ReadOnlyIntegerProperty texCoordCountProperty() { - return texCoordCountPropertyImpl().getReadOnlyProperty(); - } - - private ReadOnlyIntegerWrapper texCoordCountPropertyImpl() { - if (texCoordCount == null) { - texCoordCount = new ReadOnlyIntegerWrapper(this, "texCoordCount"); - } - return texCoordCount; - } - - /** - * The total number of faces of this {@code TriangleMesh} - */ - private ReadOnlyIntegerWrapper faceCount; - - final void setFaceCount(int value) { - faceCountPropertyImpl().set(value); - } - - /** - * Retrieve total number of faces of this {@code TriangleMesh} - * - * @return the total number of faces - */ - public final int getFaceCount() { - return faceCount == null ? 0 : faceCount.get(); - } - - public ReadOnlyIntegerProperty faceCountProperty() { - return faceCountPropertyImpl().getReadOnlyProperty(); - } - - private ReadOnlyIntegerWrapper faceCountPropertyImpl() { - if (faceCount == null) { - faceCount = new ReadOnlyIntegerWrapper(this, "faceCount"); - } - return faceCount; - } - - /** - * The total number of faceSmoothingGroups of this {@code TriangleMesh} - */ - private ReadOnlyIntegerWrapper faceSmoothingGroupCount; - - final void setFaceSmoothingGroupCount(int value) { - faceSmoothingGroupCountPropertyImpl().set(value); - } - - /** - * Retrieve total number of faceSmoothingGroups of this {@code TriangleMesh} - * - * @return the total number of faceSmoothingGroups - */ - public final int getFaceSmoothingGroupCount() { - return faceSmoothingGroupCount == null ? 0 : faceSmoothingGroupCount.get(); - } - - public ReadOnlyIntegerProperty faceSmoothingGroupCountProperty() { - return faceSmoothingGroupCountPropertyImpl().getReadOnlyProperty(); - } - - private ReadOnlyIntegerWrapper faceSmoothingGroupCountPropertyImpl() { - if (faceSmoothingGroupCount == null) { - faceSmoothingGroupCount = new ReadOnlyIntegerWrapper(this, "faceSmoothingGroupCount"); - } - return faceSmoothingGroupCount; - } - - /** - * Sets the points of this {@code TriangleMesh} - * - * @param points source array of NUM_COMPONENTS_PER_POINT * n values containing n new points. - */ - public final void setPoints(float[] points) { - // Check that points.length is divisible by NUM_COMPONENTS_PER_POINT - if ((points.length % NUM_COMPONENTS_PER_POINT) != 0) { - throw new IllegalArgumentException("points.length has to be divisible by NUM_COMPONENTS_PER_POINT." - + " It is to store multiple x, y, and z coordinates of this mesh"); - } - - if ((this.points == null) || (this.points.length < points.length)) { - this.points = new float[points.length]; - } - System.arraycopy(points, 0, this.points, 0, points.length); - // Store the valid point count. - // Note this.points.length can be bigger than points.length. - setPointCount(points.length / NUM_COMPONENTS_PER_POINT); - - pointsDirty = true; - setDirty(true); - } - - /** - * Sets the points associated with this {@code TriangleMesh} - * starting at the specified {@code index} using data in {@code points} - * starting at index {@code start} for {@code length} number of points. - * - * @param index the starting destination index in this TriangleMesh's points array - * @param points source array of floats containing the new points - * @param start starting source index in the points array. - * @param length number of point elements to be copied. - */ - public final void setPoints(int index, float[] points, - int start, int length) { - - if (index < 0 || start < 0 || length < 0) { - throw new IllegalArgumentException("index, start and length have to be non-zero"); - } - int startOffset = start * NUM_COMPONENTS_PER_POINT; - int lengthInFloatUnit = length * NUM_COMPONENTS_PER_POINT; - if ((startOffset >= points.length) || ((startOffset + lengthInFloatUnit) > points.length)) { - throw new IllegalArgumentException("start or (start + length) is out of range for input points"); - } - int indexOffset = index * NUM_COMPONENTS_PER_POINT; - int pointCountInFloatUnit = getPointCount() * NUM_COMPONENTS_PER_POINT; - if ((indexOffset >= pointCountInFloatUnit) || - ((indexOffset + lengthInFloatUnit) > pointCountInFloatUnit)) { - throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's points"); - } - System.arraycopy(points, startOffset, this.points, indexOffset, lengthInFloatUnit); - - if (pointRangeInfos == null) { - pointRangeInfos = new int[MAX_RANGE_SIZE]; - } - - if (!pointUpdateRange) { - pointsDirty = pointUpdateRange = true; - pointRangeInfos[RANGE_INDEX] = index; - pointRangeInfos[RANGE_LENGTH] = length; - } else { - pointsDirty = true; - int fromIndex = Math.min(pointRangeInfos[RANGE_INDEX], index); - int toIndex = Math.max(pointRangeInfos[RANGE_INDEX] + pointRangeInfos[RANGE_LENGTH], index + length); - pointRangeInfos[RANGE_INDEX] = fromIndex; - pointRangeInfos[RANGE_LENGTH] = toIndex - fromIndex; - } - - setDirty(true); - } - - /** - * Gets the points of this {@code TriangleMesh} - * - * @param points a float array that will receive the points - * if it not null and has sufficient capacity. - * @return a float array of points - */ - public final float[] getPoints(float[] points) { - if (this.points == null) { - return null; - } - int pointCountInFloatUnit = getPointCount() * NUM_COMPONENTS_PER_POINT; - if ((points == null) || (pointCountInFloatUnit > points.length)) { - points = new float[pointCountInFloatUnit]; - } - System.arraycopy(this.points, 0, points, 0, pointCountInFloatUnit); + public FloatArray getPoints() { return points; } - /** - * Gets the points associated with this {@code TriangleMesh} starting at the - * specified {@code index} for {@code length} number of points. - * - * @param index starting source points index in this {@code TriangleMesh} - * @param points destination array that will receive this {@code TriangleMesh}'s points data - * @param length number of point elements to be copied - * @return a float array of points - */ - public final float[] getPoints(int index, float[] points, int length) { - if (index < 0 || length < 0) { - throw new IllegalArgumentException("index and length have to be non-zero"); - } - - int lengthInFloatUnit = length * NUM_COMPONENTS_PER_POINT; - if (lengthInFloatUnit > points.length) { - throw new IllegalArgumentException("length is out of range for input points"); - } - int indexOffset = index * NUM_COMPONENTS_PER_POINT; - int pointCountInFloatUnit = getPointCount() * NUM_COMPONENTS_PER_POINT; - if ((indexOffset >= pointCountInFloatUnit) || - ((indexOffset + lengthInFloatUnit) > pointCountInFloatUnit)) { - throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's points"); - } - - if (this.points == null) { - return null; - } - System.arraycopy(this.points, indexOffset, points, 0, lengthInFloatUnit); - return points; + public FloatArray getTexCoords() { + return texCoords; } - /** - * Sets the texture coordinates of this {@code TriangleMesh}. - * - * @param texCoords source array of NUM_COMPONENTS_PER_TEXCOORD * n values containing n new texCoords. - */ - public final void setTexCoords(float[] texCoords) { - // Check that texCoords.length is divisible by NUM_COMPONENTS_PER_TEXCOORD - if ((texCoords.length % NUM_COMPONENTS_PER_TEXCOORD) != 0) { - throw new IllegalArgumentException("texCoords.length has to be divisible by NUM_COMPONENTS_PER_TEXCOORD." - +" It is to store multiple u and v texture coordinates of this mesh"); - } - - if ((this.texCoords == null) || (this.texCoords.length < texCoords.length)) { - this.texCoords = new float[texCoords.length]; - } - System.arraycopy(texCoords, 0, this.texCoords, 0, texCoords.length); - // Store the valid texCoords count. - // Note this.texCoords.length can be bigger than texCoords.length. - setTexCoordCount(texCoords.length / NUM_COMPONENTS_PER_TEXCOORD); - - texCoordsDirty = true; - setDirty(true); - } - - /** - * Sets the texture coordinates associated with this {@code TriangleMesh} - * starting at the specified {@code index} using data in {@code texCoords} - * starting at index {@code start} for {@code length} number of texCoords. - * - * @param index the starting destination index in this TriangleMesh's texCoords array - * @param texCoords an float array containing the new texture coordinates - * @param start starting source index in the texture coordinates array - * @param length number of texCoord elements to be copied. - */ - public final void setTexCoords(int index, float[] texCoords, int start, - int length) { - if (index < 0 || start < 0 || length < 0) { - throw new IllegalArgumentException("index, start and length have to be non-zero"); - } - int startOffset = start * NUM_COMPONENTS_PER_TEXCOORD; - int lengthInFloatUnit = length * NUM_COMPONENTS_PER_TEXCOORD; - if ((startOffset >= texCoords.length) || ((startOffset + lengthInFloatUnit) > texCoords.length)) { - throw new IllegalArgumentException("start or (start + length) is out of range for input texCoords"); - } - int indexOffset = index * NUM_COMPONENTS_PER_TEXCOORD; - int texCoordCountInFloatUnit = getTexCoordCount() * NUM_COMPONENTS_PER_TEXCOORD; - if ((indexOffset >= texCoordCountInFloatUnit) || - ((indexOffset + lengthInFloatUnit) > texCoordCountInFloatUnit)) { - throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's texCoords"); - } - System.arraycopy(texCoords, startOffset, this.texCoords, indexOffset, lengthInFloatUnit); - - if (texCoordRangeInfos == null) { - texCoordRangeInfos = new int[MAX_RANGE_SIZE]; - } - if (!texCoordUpdateRange) { - texCoordsDirty = texCoordUpdateRange = true; - texCoordRangeInfos[RANGE_INDEX] = index; - texCoordRangeInfos[RANGE_LENGTH] = length; - } else { - texCoordsDirty = true; - int fromIndex = Math.min(texCoordRangeInfos[RANGE_INDEX], index); - int toIndex = Math.max(texCoordRangeInfos[RANGE_INDEX] + texCoordRangeInfos[RANGE_LENGTH], index + length); - texCoordRangeInfos[RANGE_INDEX] = fromIndex; - texCoordRangeInfos[RANGE_LENGTH] = toIndex - fromIndex; - } - setDirty(true); - } - - /** - * Gets the texture coordinates of this {@code TriangleMesh}. - * - * @param texCoords a float array that will receive the texture coordinates - * if it not null and has sufficient capacity - * @return a float array of texture coordinates - */ - public final float[] getTexCoords(float[] texCoords) { - if (this.texCoords == null) { - return null; - } - - int texCoordCountInFloatUnit = getTexCoordCount() * NUM_COMPONENTS_PER_TEXCOORD; - if ((texCoords == null) || (texCoordCountInFloatUnit > texCoords.length)) { - texCoords = new float[texCoordCountInFloatUnit]; - } - System.arraycopy(this.texCoords, 0, texCoords, 0, texCoordCountInFloatUnit); - return texCoords; - } - - /** - * Gets the texture coordinates associated with this {@code TriangleMesh} - * starting at the specified {@code index} for {@code length} number of - * texCoords. - * - * @param index starting source texCoords index in this {@code TriangleMesh} - * @param texCoords destination array that will receive this {@code TriangleMesh}'s texCoords data - * @param length number of texCoord elements to be copied - * @return a float array of texture coordinates - */ - public final float[] getTexCoords(int index, float[] texCoords, int length) { - if (index < 0 || length < 0) { - throw new IllegalArgumentException("index and length have to be non-zero"); - } - - int lengthInFloatUnit = length * NUM_COMPONENTS_PER_TEXCOORD; - if (lengthInFloatUnit > texCoords.length) { - throw new IllegalArgumentException("length is out of range for input texCoords"); - } - int indexOffset = index * NUM_COMPONENTS_PER_TEXCOORD; - int texCoordCountInFloatUnit = getTexCoordCount() * NUM_COMPONENTS_PER_TEXCOORD; - if ((indexOffset >= texCoordCountInFloatUnit) || - ((indexOffset + lengthInFloatUnit) > texCoordCountInFloatUnit)) { - throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's texCoords"); - } - - if (this.texCoords == null) { - return null; - } - System.arraycopy(this.texCoords, indexOffset, texCoords, 0, lengthInFloatUnit); - return texCoords; - } - - /** - * Sets the faces, indices into the points and texCoords arrays, - * associated with this {@code TriangleMesh}. - * - * @param faces source array of NUM_COMPONENTS_PER_FACE * n indices - * (3 point indices and 3 texCood indices) containing n new faces - */ - public final void setFaces(int[] faces) { - // Check that faces.length is divisible by NUM_COMPONENTS_PER_FACE - if ((faces.length % NUM_COMPONENTS_PER_FACE) != 0) { - throw new IllegalArgumentException("faces.length has to be divisible by NUM_COMPONENTS_PER_FACE."); - } - - if ((this.faces == null) || (this.faces.length < faces.length)) { - this.faces = new int[faces.length]; - } - System.arraycopy(faces, 0, this.faces, 0, faces.length); - // Store the valid face count. - // Note this.faces.length can be bigger than faces.length. - setFaceCount(faces.length / NUM_COMPONENTS_PER_FACE); - - facesDirty = true; - setDirty(true); - } - - /** - * Sets the faces, indices into the points and texCoords arrays, - * associated with this {@code TriangleMesh} - * starting at the specified{@code index} using data in {@code faces} - * starting at index {@code start} for {@code length} number of faces. - * - * @param index the starting destination index in this TriangleMesh's faces array - * @param faces an int array containing the new interleaved vertices - * @param start starting source index in the faces array. - * @param length number of interleaved vertex elements to be copied - */ - public final void setFaces(int index, int[] faces, int start, int length) { - if (index < 0 || start < 0 || length < 0) { - throw new IllegalArgumentException("index, start and length have to be non-zero"); - } - int startOffset = start * NUM_COMPONENTS_PER_FACE; - int lengthInIntUnit = length * NUM_COMPONENTS_PER_FACE; - if ((startOffset >= faces.length) || ((startOffset + lengthInIntUnit) > faces.length)) { - throw new IllegalArgumentException("start or (start + length) is out of range for input faces"); - } - int indexOffset = index * NUM_COMPONENTS_PER_FACE; - int faceCountInIntUnit = getFaceCount() * NUM_COMPONENTS_PER_FACE; - if ((indexOffset >= faceCountInIntUnit) || - ((indexOffset + lengthInIntUnit) > faceCountInIntUnit)) { - throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's faces"); - } - System.arraycopy(faces, startOffset, this.faces, indexOffset, lengthInIntUnit); - - if (faceRangeInfos == null) { - faceRangeInfos = new int[MAX_RANGE_SIZE]; - } - if (!faceUpdateRange) { - facesDirty = faceUpdateRange = true; - faceRangeInfos[RANGE_INDEX] = index; - faceRangeInfos[RANGE_LENGTH] = length; - } else { - facesDirty = true; - int fromIndex = Math.min(faceRangeInfos[RANGE_INDEX], index); - int toIndex = Math.max(faceRangeInfos[RANGE_INDEX] + faceRangeInfos[RANGE_LENGTH], index + length); - faceRangeInfos[RANGE_INDEX] = fromIndex; - faceRangeInfos[RANGE_LENGTH] = toIndex - fromIndex; - } - setDirty(true); - } - - /** - * Gets the faces, indices into the points and texCoords arrays, of this - * {@code TriangleMesh} - * - * @param faces an int array that will receive the faces if it not null and - * has sufficient capacity. - * @return an int array of faces - * - */ - public final int[] getFaces(int[] faces) { - if (this.faces == null) { - return null; - } - - int faceCountInIntUnit = getFaceCount() * NUM_COMPONENTS_PER_FACE; - if ((faces == null) || (faceCountInIntUnit > faces.length)) { - faces = new int[faceCountInIntUnit]; - } - System.arraycopy(this.faces, 0, faces, 0, faceCountInIntUnit); + public IntegerArray getFaces() { return faces; } - /** - * Gets the faces, indices into the points and texCoords arrays, - * associated with this {@code TriangleMesh} starting at the specified - * {@code index} for {@code length} number of faces. - * - * @param index starting source faces index in this {@code TriangleMesh} - * @param faces destination array that will receive this {@code TriangleMesh}'s faces data - * @param length number of face elements to be copied - * @return an int array of faces - */ - public final int[] getFaces(int index, int[] faces, int length) { - if (index < 0 || length < 0) { - throw new IllegalArgumentException("index and length have to be non-zero"); - } - - int lengthInIntUnit = length * NUM_COMPONENTS_PER_FACE; - if (lengthInIntUnit > faces.length) { - throw new IllegalArgumentException("length is out of range for input faces"); - } - int indexOffset = index * NUM_COMPONENTS_PER_FACE; - int faceCountInIntUnit = getFaceCount() * NUM_COMPONENTS_PER_FACE; - if ((indexOffset >= faceCountInIntUnit) || - ((indexOffset + lengthInIntUnit) > faceCountInIntUnit)) { - throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's faces"); - } - - if (this.faces == null) { - return null; - } - System.arraycopy(this.faces, indexOffset, faces, 0, lengthInIntUnit); - return faces; - } - - /** - * Sets the face smoothing group for each face in this {@code TriangleMesh} - * - * TODO: 3D - if faceSmoothingGroups is null (default) --> smooth faces - * Note: faceSmoothingGroups.length must be equal to faces.length/NUM_COMPONENTS_PER_FACE. - * Error: Throw exception? - */ - public final void setFaceSmoothingGroups(int[] faceSmoothingGroups) { - // Check that faceSmoothingGroups.length is 1/NUM_COMPONENTS_PER_FACE of faces.length - if (faceSmoothingGroups.length != (faces.length / NUM_COMPONENTS_PER_FACE)) { - throw new IllegalArgumentException("faceSmoothingGroups.length has to be equal to (faces.length / NUM_COMPONENTS_PER_FACE)."); - } - - // NOTE: The face smoothing group value is currently restricted from 0 to 31. - for (int i = 0; i < faceSmoothingGroups.length; i++) { - if (faceSmoothingGroups[i] < 0 || faceSmoothingGroups[i] > 31) { - throw new IllegalArgumentException("The face smoothing group value should be from 0 to 31 inclusive."); - } - } - - if ((this.faceSmoothingGroups == null) || - (this.faceSmoothingGroups.length < faceSmoothingGroups.length)) { - this.faceSmoothingGroups = new int[faceSmoothingGroups.length]; - } - System.arraycopy(faceSmoothingGroups, 0, this.faceSmoothingGroups, 0, faceSmoothingGroups.length); - // Store the valid faceSmoothingGroup count. - // Note this.faceSmoothingGroups.length can be bigger than faceSmoothingGroups.length. - setFaceSmoothingGroupCount(faceSmoothingGroups.length); - - fsgDirty = true; - setDirty(true); - } - - /** - * Sets the faceSmoothingGroups associated with this {@code TriangleMesh} - * starting at the specified {@code index} using data in {@code faceSmoothingGroups} - * starting at index {@code start} for {@code length} number of faceSmoothingGroups. - * - * @param index the starting destination index in this TriangleMesh's faceSmoothingGroups array - * @param points source array of floats containing the new faceSmoothingGroups - * @param start starting source index in the faceSmoothingGroups array. - * @param length number of faceSmoothingGroup elements to be copied. - */ - public final void setFaceSmoothingGroups(int index, int[] faceSmoothingGroups, - int start, int length) { - - if (index < 0 || start < 0 || length < 0) { - throw new IllegalArgumentException("index, start and length have to be non-zero"); - } - - if ((start >= faceSmoothingGroups.length) || ((start + length) > faceSmoothingGroups.length)) { - throw new IllegalArgumentException("start or (start + length) is out of range for input faceSmoothingGroups"); - } - int fsgCount = getFaceSmoothingGroupCount(); - if ((index >= fsgCount) || - ((index + length) > fsgCount)) { - throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's faceSmoothingGroups"); - } - - // NOTE: The face smoothing group value is currently restricted from 0 to 31. - for (int i = start; i < length; i++) { - if (faceSmoothingGroups[i] < 0 || faceSmoothingGroups[i] > 31) { - throw new IllegalArgumentException("The face smoothing group value should be from 0 to 31 inclusive."); - } - } - - System.arraycopy(faceSmoothingGroups, start, this.faceSmoothingGroups, index, length); - - if (fsgRangeInfos == null) { - fsgRangeInfos = new int[MAX_RANGE_SIZE]; - } - if (!fsgUpdateRange) { - fsgDirty = fsgUpdateRange = true; - fsgRangeInfos[RANGE_INDEX] = index; - fsgRangeInfos[RANGE_LENGTH] = length; - } else { - fsgDirty = true; - int fromIndex = Math.min(fsgRangeInfos[RANGE_INDEX], index); - int toIndex = Math.max(fsgRangeInfos[RANGE_INDEX] + fsgRangeInfos[RANGE_LENGTH], index + length); - fsgRangeInfos[RANGE_INDEX] = fromIndex; - fsgRangeInfos[RANGE_LENGTH] = toIndex - fromIndex; - } - setDirty(true); - } - - /** - * Gets the face smoothing group for each face in this {@code TriangleMesh} - * @return an int array to smoothing group bits for each face - */ - public final int[] getFaceSmoothingGroups(int[] faceSmoothingGroups) { - if (this.faceSmoothingGroups == null) { - return null; - } - - int fsgCount = getFaceSmoothingGroupCount(); - if ((faceSmoothingGroups == null) || - (fsgCount > faceSmoothingGroups.length)) { - faceSmoothingGroups = new int[fsgCount]; - } - System.arraycopy(this.faceSmoothingGroups, 0, faceSmoothingGroups, 0, fsgCount); - return faceSmoothingGroups; - } - - /** - * Gets the face smoothing group for each face in this {@code TriangleMesh} - * starting at the specified {@code index} for {@code length} number of face - * smoothing groups. - * - * @param index starting source face smoothing groups index in this {@code TriangleMesh} - * @param faceSmoothingGroups destination array that will receive this - * {@code TriangleMesh}'s faceSmoothingGroups data - * @param length number of faceSmoothingGroup elements to be copied - * @return an int array of faceSmoothingGroups - */ - public final int[] getFaceSmoothingGroups(int index, int[] faceSmoothingGroups, int length) { - if (index < 0 || length < 0) { - throw new IllegalArgumentException("index and length have to be non-zero"); - } - - if (length > faceSmoothingGroups.length) { - throw new IllegalArgumentException("length is out of range for input faceSmoothingGroups"); - } - - int fsgCount = getFaceSmoothingGroupCount(); - if ((index >= fsgCount) || ((index + length) > fsgCount)) { - throw new IllegalArgumentException("index or (index + length) is out of range for this triangle mesh's faceSmoothingGroups"); - } - - if (this.faceSmoothingGroups == null) { - return null; - } - System.arraycopy(this.faceSmoothingGroups, index, faceSmoothingGroups, 0, length); + public IntegerArray getFaceSmoothingGroups() { return faceSmoothingGroups; } @@ -757,16 +149,10 @@ void setDirty(boolean value) { super.setDirty(value); if (!value) { // false - pointsDirty = false; - texCoordsDirty = false; - facesDirty = false; - fsgDirty = false; - pointUpdateRange = false; - texCoordUpdateRange = false; - faceUpdateRange = false; - fsgUpdateRange = false; - // We don't clear up XXXPartialUpdateInfos array since we will - // overwrite every element when we update the array. + points.setDirty(false); + texCoords.setDirty(false); + faces.setDirty(false); + faceSmoothingGroups.setDirty(false); } } @@ -822,39 +208,39 @@ PGTriangleMesh pgTriMesh = impl_getPGTriangleMesh(); // sync points - if (pointsDirty) { - if (pointUpdateRange) { - pgTriMesh.setPoints(points, pointRangeInfos[RANGE_INDEX], - pointRangeInfos[RANGE_LENGTH]); + if (points.isDirty()) { + if (points.isDirtyInFull()) { + pgTriMesh.setPoints(points.getArray()); } else { - pgTriMesh.setPoints(points); + pgTriMesh.setPoints(points.getArray(), points.getDirtyRangeFrom(), + points.getDirtyRangeLength()); } } // sync texCoords - if (texCoordsDirty) { - if (texCoordUpdateRange) { - pgTriMesh.setTexCoords(texCoords, texCoordRangeInfos[RANGE_INDEX], - texCoordRangeInfos[RANGE_LENGTH]); + if (texCoords.isDirty()) { + if (texCoords.isDirtyInFull()) { + pgTriMesh.setTexCoords(texCoords.getArray()); } else { - pgTriMesh.setTexCoords(texCoords); + pgTriMesh.setTexCoords(texCoords.getArray(), texCoords.getDirtyRangeFrom(), + texCoords.getDirtyRangeLength()); } } // sync faces - if (facesDirty) { - if (faceUpdateRange) { - pgTriMesh.setFaces(faces, faceRangeInfos[RANGE_INDEX], - faceRangeInfos[RANGE_LENGTH]); + if (faces.isDirty()) { + if (faces.isDirtyInFull()) { + pgTriMesh.setFaces(faces.getArray()); } else { - pgTriMesh.setFaces(faces); + pgTriMesh.setFaces(faces.getArray(), faces.getDirtyRangeFrom(), + faces.getDirtyRangeLength()); } } // sync faceSmoothingGroups - if (fsgDirty) { - if (fsgUpdateRange) { - pgTriMesh.setFaceSmoothingGroups(faceSmoothingGroups, fsgRangeInfos[RANGE_INDEX], - fsgRangeInfos[RANGE_LENGTH]); + if (faceSmoothingGroups.isDirty()) { + if (faceSmoothingGroups.isDirtyInFull()) { + pgTriMesh.setFaceSmoothingGroups(faceSmoothingGroups.getArray()); } else { - pgTriMesh.setFaceSmoothingGroups(faceSmoothingGroups); + pgTriMesh.setFaceSmoothingGroups(faceSmoothingGroups.getArray(), faceSmoothingGroups.getDirtyRangeFrom(), + faceSmoothingGroups.getDirtyRangeLength()); } } @@ -866,9 +252,9 @@ if (isDirty() || cachedBounds == null) { cachedBounds = new BoxBounds(); - final double len = points.length; - for (int i = 0; i < len; i += 3) { - cachedBounds.add(points[i], points[i + 1], points[i + 2]); + final double len = points.size() * NUM_COMPONENTS_PER_POINT; + for (int i = 0; i < len; i += NUM_COMPONENTS_PER_POINT) { + cachedBounds.add(points.get(i), points.get(i + 1), points.get(i + 2)); } } return bounds.deriveWithNewBounds(cachedBounds); @@ -925,13 +311,13 @@ PickRay pickRay, Point3D origin, Point3D dir, int faceIndex, CullFace cullFace, Node candidate, boolean reportFace, PickResultChooser result) { - final int v0Idx = faces[faceIndex] * 3; - final int v1Idx = faces[faceIndex + 2] * 3; - final int v2Idx = faces[faceIndex + 4] * 3; + final int v0Idx = faces.get(faceIndex) * 3; + final int v1Idx = faces.get(faceIndex + 2) * 3; + final int v2Idx = faces.get(faceIndex + 4) * 3; - final Point3D v0 = new Point3D(points[v0Idx], points[v0Idx + 1], points[v0Idx + 2]); - final Point3D v1 = new Point3D(points[v1Idx], points[v1Idx + 1], points[v1Idx + 2]); - final Point3D v2 = new Point3D(points[v2Idx], points[v2Idx + 1], points[v2Idx + 2]); + final Point3D v0 = new Point3D(points.get(v0Idx), points.get(v0Idx + 1), points.get(v0Idx + 2)); + final Point3D v1 = new Point3D(points.get(v1Idx), points.get(v1Idx + 1), points.get(v1Idx + 2)); + final Point3D v2 = new Point3D(points.get(v2Idx), points.get(v2Idx + 1), points.get(v2Idx + 2)); final Point3D e1 = v1.subtract(v0); final Point3D e2 = v2.subtract(v0); @@ -1019,13 +405,13 @@ // Obtain the texture triangle - final int t0Idx = faces[faceIndex + 1] * 2; - final int t1Idx = faces[faceIndex + 3] * 2; - final int t2Idx = faces[faceIndex + 5] * 2; + final int t0Idx = faces.get(faceIndex + 1) * 2; + final int t1Idx = faces.get(faceIndex + 3) * 2; + final int t2Idx = faces.get(faceIndex + 5) * 2; - final Point2D u0 = new Point2D(texCoords[t0Idx], texCoords[t0Idx + 1]); - final Point2D u1 = new Point2D(texCoords[t1Idx], texCoords[t1Idx + 1]); - final Point2D u2 = new Point2D(texCoords[t2Idx], texCoords[t2Idx + 1]); + final Point2D u0 = new Point2D(texCoords.get(t0Idx), texCoords.get(t0Idx + 1)); + final Point2D u1 = new Point2D(texCoords.get(t1Idx), texCoords.get(t1Idx + 1)); + final Point2D u2 = new Point2D(texCoords.get(t2Idx), texCoords.get(t2Idx + 1)); final Point2D txCentroid = computeCentroid(u0, u1, u2); @@ -1073,7 +459,7 @@ Node candidate, CullFace cullFace, boolean reportFace) { boolean found = false; - final int size = faces.length; + final int size = faces.size(); final Vec3d o = pickRay.getOriginNoClone(); final Point3D origin = new Point3D(o.x, o.y, o.z);