/**
* Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions 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 the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package org.xith3d.scenegraph;
import java.util.List;
import org.jagatoo.opengl.enums.GeometryArrayType;
import org.openmali.spatial.VertexContainer;
import org.openmali.spatial.WriteableTriangleContainer;
import org.openmali.spatial.bounds.Bounds;
import org.openmali.spatial.polygons.Triangle;
import org.openmali.vecmath2.Colorf;
import org.openmali.vecmath2.TexCoordf;
import org.openmali.vecmath2.Tuple3f;
import org.openmali.vecmath2.TupleNf;
import org.openmali.vecmath2.Vector3f;
import org.openmali.vecmath2.Vertex3f;
import org.xith3d.picking.PickPool;
import org.xith3d.render.CanvasPeer;
import org.xith3d.render.SceneGraphOpenGLReferences;
/**
* A Geometry contains mesh data. Usually a Appearance is associated to it, both
* composing a Shape3D
*
* @author David Yazel
* @author Marvin Froehlich (aka Qudus)
*/
public abstract class Geometry extends NodeComponent implements VertexContainer
{
public enum Optimization
{
/**
* Use this, if a Shape is highly dynamic (Appearance and Geometry).
*/
NONE,
/**
* The Renderer tries to find the best suitable optimization.
*/
AUTO,
/**
* Use this, if a Geometry and texture coordinates are absolutely
* static.<br>
* Changes will be expensive.
*/
USE_DISPLAY_LISTS,
/**
* Use this, if a Geometry and texture coordinates are absolutely
* static.<br>
* Changes will be expensive.
*/
USE_VBOS,
/**
* Use this, if the vertices are absolutely static.<br>
* Changes will be expensive.
*/
USE_VBO_FOR_VERTEX_DATA,
/**
* Use this, if a the texture coordinates are absolutely static.<br>
* Changes will be expensive.
*/
USE_VBO_FOR_TEXTURE_COORDINATES;
public final boolean isNone()
{
return ( this == NONE );
}
public final boolean isAuto()
{
return ( this == AUTO );
}
public final boolean dl()
{
return ( this == USE_DISPLAY_LISTS );
}
public final boolean vboForVertices()
{
return ( ( this == USE_VBOS ) || ( this == USE_VBO_FOR_VERTEX_DATA ) );
}
public final boolean vboForTexCoords()
{
return ( ( this == USE_VBOS ) || ( this == USE_VBO_FOR_TEXTURE_COORDINATES ) );
}
public final boolean vbo()
{
return ( ( this == USE_VBOS ) || ( this == USE_VBO_FOR_VERTEX_DATA ) || ( this == USE_VBO_FOR_TEXTURE_COORDINATES ) );
}
public final boolean optForVertices()
{
return ( vboForVertices() );
}
public final boolean optForTexCoords()
{
return ( vboForTexCoords() );
}
}
public static final int COORDINATES = GeometryDataContainer.COORDINATES;
public static final int NORMALS = GeometryDataContainer.NORMALS;
public static final int COLORS = GeometryDataContainer.COLORS;
public static final int TEXTURE_COORDINATES = GeometryDataContainer.TEXTURE_COORDINATES;
public static final int VERTEX_ATTRIBUTES = GeometryDataContainer.VERTEX_ATTRIBUTES;
public static final int BY_REFERENCE = GeometryDataContainer.BY_REFERENCE;
public static final int INTERLEAVED = GeometryDataContainer.INTERLEAVED;
/*
public static final int USE_NIO_BUFFER = 2048;
public static final int USE_COORD_INDEX_ONLY = 4096;
*/
protected final GeometryDataContainer dataContainer;
private final SceneGraphOpenGLReferences openGLReferences_texCoords = new SceneGraphOpenGLReferences( 1 );
private final SceneGraphOpenGLReferences openGLReferences_geomData = new SceneGraphOpenGLReferences( 1 );
private final SceneGraphOpenGLReferences openGLReferences = new SceneGraphOpenGLReferences( 1 );
private Optimization optimization = Optimization.AUTO;
private Bounds cachedBounds = null;
/**
* @return this Geometry's basic type (used by OpenGL).
*/
public final GeometryArrayType getType()
{
return ( dataContainer.getType() );
}
/**
* @return <code>true</code>, if this Geometry is a Strip
*/
public final boolean isStrip()
{
return ( dataContainer.isStrip() );
}
/**
* @return the number of vertices per face (3 for triangles).
*/
public final int getFaceSize()
{
return ( dataContainer.getFaceSize() );
}
/**
* @return <code>true</code>, if this Geometry is built of triangles or can at least be interpreted as triangles.
*/
public abstract boolean isTriangulatable();
/**
* @return <code>true</code>, if this Geometry is built of triangles.
*/
public abstract boolean isTriangulated();
/**
* @return the maximum number of vertices, this geometry can hold.
*/
public final int getMaxVertexCount()
{
return ( dataContainer.getMaxVertexCount() );
}
/**
* {@inheritDoc}
*/
public int getVertexCount()
{
return ( dataContainer.getVertexCount() );
}
/**
* {@inheritDoc}
*/
public boolean getVertex( int i, Tuple3f pos )
{
return ( dataContainer.getVertex( i, pos ) );
}
/**
* @return the format of the vertices in this object.
*/
public final int getVertexFormat()
{
return ( dataContainer.getVertexFormat() );
}
/**
* @return <code>true</code>, if this Geometry is constructed by interleaved data
* (one ByteBuffer for all data except index).
*/
public final boolean isInterleaved()
{
return ( dataContainer.isInterleaved() );
}
/**
* @return <code>true</code>, if this Geometry has an Index.
*/
public final boolean hasIndex()
{
return ( dataContainer.hasIndex() );
}
/**
* @return <code>true</code>, if this geometry's color component has an alpha channel.
*/
public final boolean hasColorAlpha()
{
return ( dataContainer.hasColorAlpha() );
}
/**
* @return <code>true</code>, if this Geometry has the queried feature(s).
*/
public final boolean hasFeature( int flag )
{
return ( dataContainer.hasFeature( flag ) );
}
/**
* Sets this Geometry's Optimization to be used.
*
* @param opt
*/
public void setOptimization( Optimization opt )
{
if ( opt == null )
throw new NullPointerException( "Optimization must not be null" );
this.optimization = opt;
}
/**
* @return this Geometry's Optimization level.
*/
public final Optimization getOptimization()
{
return ( optimization );
}
/**
* Marks this Geometry's bounds dirty. This will cause a bounds update
* when the Geometry is next rendered.
*/
public void setBoundsDirty()
{
this.cachedBounds = null;
}
/**
* @return <code>true</code>, if a bounds update is requested.
*/
public final boolean isBoundsDirty()
{
return ( cachedBounds == null );
}
void setCachedBounds( Bounds b )
{
this.cachedBounds = b;
}
final Bounds getCachedBounds()
{
return ( cachedBounds );
}
/**
* This method calculates face normals (each orthogonal to its face).
*
* @see #calculateFaceNormals()
*
* @param apply if <code>true</code>, the normals are applied back to the Geometry
* @param faceNormals must be of size getTrianglesCount(), or <code>null</code>.
* It is filled with the face normals, if not <code>null</code>.
* @param vertexNormals must be of size getVertexCount(), or <code>null</code>.
* It is filled with the new vertex normals, if not <code>null</code>.
*/
public void calculateFaceNormals( boolean apply, Vector3f[] faceNormals, Vector3f[] vertexNormals )
{
if ( !( this instanceof WriteableTriangleContainer ) )
throw new Error( "Not an instance of WriteableTriangleContainer" );
WriteableTriangleContainer wtc = (WriteableTriangleContainer)this;
Triangle triangle = PickPool.allocateTriangle();
triangle.setFeatures( Vertex3f.COORDINATES | Vertex3f.NORMALS );
Vector3f faceNormal = Vector3f.fromPool();
final int numTrangles = wtc.getTriangleCount();
for ( int i = 0; i < numTrangles; i++ )
{
wtc.getTriangle( i, triangle );
triangle.getFaceNormal( faceNormal );
if ( apply )
{
triangle.setVertexNormalA( faceNormal );
triangle.setVertexNormalB( faceNormal );
triangle.setVertexNormalC( faceNormal );
this.setTriangle( triangle );
}
if ( faceNormals != null )
{
if ( faceNormals[ i ] != null )
faceNormals[ i ].set( faceNormal );
else
faceNormals[ i ] = new Vector3f( faceNormal );
}
if ( vertexNormals != null )
{
if ( vertexNormals[ triangle.getVertexIndexA() ] != null )
vertexNormals[ triangle.getVertexIndexA() ].set( faceNormal );
else
vertexNormals[ triangle.getVertexIndexA() ] = new Vector3f( faceNormal );
if ( vertexNormals[ triangle.getVertexIndexB() ] != null )
vertexNormals[ triangle.getVertexIndexB() ].set( faceNormal );
else
vertexNormals[ triangle.getVertexIndexB() ] = new Vector3f( faceNormal );
if ( vertexNormals[ triangle.getVertexIndexC() ] != null )
vertexNormals[ triangle.getVertexIndexC() ].set( faceNormal );
else
vertexNormals[ triangle.getVertexIndexC() ] = new Vector3f( faceNormal );
}
}
Vector3f.toPool( faceNormal );
}
/**
* This method calculates face normals and applies them to the Geometry.
*
* @see #calculateFaceNormals(boolean, Vector3f[], Vector3f[])
*/
public void calculateFaceNormals()
{
calculateFaceNormals( true, null, null );
}
/**
* Inverts all the normals in place.
*/
public void invertNormals()
{
if ( !hasNormals() )
return;
Vector3f normal = Vector3f.fromPool();
for ( int i = 0; i < getVertexCount(); i++ )
{
getNormal( i, normal );
normal.negate();
setNormal( i, normal );
}
Vector3f.toPool( normal );
}
/**
* Super fast method add a bunch of data right into the data elements.
*/
public final void addData( float[] coordData, float[] texCoordData, float[] normalData, float[] colorData )
{
dataContainer.addData( coordData, texCoordData, normalData, colorData );
}
/**
* Super fast method for moving a bunch of data into the data elements. The
* Positions are all translated according to the tuple passed in.
*/
public final void addData( Tuple3f translate, int numVertices, float[] coordData, float[] texCoordData, float[] normalData, float[] colorData )
{
dataContainer.addData( translate.getX(), translate.getY(), translate.getZ(), numVertices, coordData, texCoordData, normalData, colorData );
}
/**
* Super fast method for moving a bunch of data into the data elements. The
* Positions are all translated according to the tuple passed in. The color
* for all the vertices are set the specified value
*/
public void addData( Tuple3f translate, int numVertices, float[] coordData, float[] texCoordData, float[] normalData, float alpha )
{
dataContainer.addData( translate.getX(), translate.getY(), translate.getZ(), numVertices, coordData, texCoordData, normalData, alpha );
}
/**
* Directly sets the coordinates data buffer.
*
* @param data
*/
public final void setCoordinateData( GeomNioFloatData data )
{
dataContainer.setCoordinateData( data );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* @return the data buffer for coordinate data.
*/
public final GeomNioFloatData getCoordinatesData()
{
return ( (GeomNioFloatData)dataContainer.getCoordinatesData() );
}
/**
* @return 3 for 3D-coordinates, etc.
*/
public final int getCoordinatesSize()
{
return ( dataContainer.getCoordinatesSize() );
}
/**
* @return the offset in the data buffer, if this is interleaved data.
*/
public final long getCoordinatesOffset()
{
return ( dataContainer.getCoordinatesOffset() );
}
/**
* Directly sets the normals data buffer.
*
* @param data
*/
public void setNormalData( GeomNioFloatData data )
{
dataContainer.setNormalData( data );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* @return the data buffer for normal data.
*/
public final GeomNioFloatData getNormalsData()
{
return ( (GeomNioFloatData)dataContainer.getNormalsData() );
}
/**
* @return this size of normals (always 3).
*/
public final int getNormalsSize()
{
return ( dataContainer.getNormalsSize() );
}
/**
* @return the offset in the data buffer, if this is interleaved data.
*/
public final long getNormalsOffset()
{
return ( dataContainer.getNormalsOffset() );
}
/**
* Directly sets the color data buffer.
*
* @param data
*/
public void setColorData( GeomNioFloatData data )
{
dataContainer.setColorData( data );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* @return the data buffer for color data.
*/
public final GeomNioFloatData getColorData()
{
return ( (GeomNioFloatData)dataContainer.getColorData() );
}
/**
* @return this size of colors (always 3 or 4, no alpha / alpha).
*/
public final int getColorsSize()
{
return ( dataContainer.getColorsSize() );
}
/**
* @return the offset in the data buffer, if this is interleaved data.
*/
public final long getColorsOffset()
{
return ( dataContainer.getColorsOffset() );
}
/**
* Directly sets the tex-coords data buffer for the guven texture-unit.
*
* @param unit
* @param data
*/
public void setTexCoordData( int unit, GeomNioFloatData data )
{
dataContainer.setTexCoordData( unit, data );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* @return the data buffer for tex-coord data for the given texture-unit.
*
* @param unit
*/
public final GeomNioFloatData getTexCoordsData( int unit )
{
return ( (GeomNioFloatData)dataContainer.getTexCoordsData( unit ) );
}
/**
* @return the size of the texture coordinates of texture unit 'unit'.
* This is always (1, 2, 3 or 4).
*/
public final int getTexCoordSize( int unit )
{
return ( dataContainer.getTexCoordSize( unit ) );
}
/**
* @return the number of texture units used in this Geometry.
*/
public final int getNumTextureUnits()
{
return ( dataContainer.getNumTextureUnits() );
}
/**
* @deprecated replaced by {@link #getNumTextureUnits()}
*/
@Deprecated
public final int getTexCoordSetCount()
{
return ( getNumTextureUnits() );
}
/**
* @return The map for texture coordinates to texture units. (for internal use only!)
*/
public final int[] getTexCoordSetMap()
{
return ( dataContainer.getTexCoordSetMap() );
}
/**
* Gets the map for texture coordinates to texture units. (for internal use only!)
*
* @param intArray
*/
public final void getTexCoordSetMap( int[] intArray )
{
dataContainer.getTexCoordSetMap( intArray );
}
/**
* @return the offset in the data buffer, if this is interleaved data.
*/
public final long getTexCoordsOffset( int unit )
{
return ( dataContainer.getTexCoordsOffset( unit ) );
}
/**
* @return the data buffer for vertex-attributes data.
*
* @param index
*/
public final GeomNioFloatData getVertexAttribData( int index )
{
return ( (GeomNioFloatData)dataContainer.getVertexAttribData( index ) );
}
/**
* @return the size of the queried vertex attributes.
*
* @param index
*/
public final int getVertexAttribSize( int index )
{
return ( dataContainer.getVertexAttribSize( index ) );
}
/**
* @return the offset in the data buffer, if this is interleaved data.
*/
public final long getVertexAttribsOffset( int index )
{
return ( dataContainer.getVertexAttribsOffset( index ) );
}
/**
* @return the data buffer for interleaved data. If this Geometry is not
* interleaved, an error is thrown.
*/
public final GeomNioFloatData getInterleavedData()
{
return ( (GeomNioFloatData)dataContainer.getInterleavedData() );
}
/**
* Sets the index of the first vertex which will be rendered from this
* geometry array. The extact vertices which will be rendered is from
* InitialVertexIndex to InitialVertexIndex + ValidVertexCount-1.
*
* @param initialVertex
*/
public final void setInitialVertexIndex( int initialVertex )
{
dataContainer.setInitialIndex( initialVertex );
}
/**
* @return the index of the first vertex which will be rendered from this
* geometry array. The extact vertices which will be rendered is
* from InitialVertexIndex to InitialVertexIndex +
* ValidVertexCount-1.
*/
public final int getInitialVertexIndex()
{
return ( dataContainer.getInitialIndex() );
}
/**
* Sets the number of vertices which will be rendered from this geometry
* array. The extact vertices which will be rendered is from
* InitialVertexIndex to InitialVertexIndex + ValidVertexCount-1.
*
* @param count
*/
public void setValidVertexCount( int count )
{
dataContainer.setValidVertexCount( count );
setChanged( true );
setBoundsDirty();
}
/**
* @return the number of vertices which will be rendered from this geometry
* array. The extact vertices which will be rendered is from
* InitialVertexIndex to InitialVertexIndex + ValidVertexCount-1.
*/
public final int getValidVertexCount()
{
return ( dataContainer.getValidVertexCount() );
}
/**
* Sets the coordinates of the specified vertex. The coordinates should
* occupy the first three indices of the given array.
*/
public final void setCoordinate( int vertexIndex, float[] floatArray )
{
dataContainer.setCoordinate( vertexIndex, floatArray );
setBoundsDirty();
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the coordinates of the vertices starting at the specified index.
*
* @param vertexIndex The index of the first vertex to be modified.
* @param floatArray The new coordinates. The size of the array must be a
* multiple of 3.
* @param startIndex The index of the first coordinate in the given array.
* The first read item of the array will be startIndex*3.
* @param length The number of vertices to copy
*/
public final void setCoordinates( int vertexIndex, float[] floatArray, int startIndex, int length )
{
dataContainer.setCoordinates( vertexIndex, floatArray, startIndex, length );
setBoundsDirty();
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the coordinates of the vertices starting at the specified index.
*
* @param vertexIndex The index of the first vertex to modify
* @param floatArray The new coordinates. The size of the array must be a
* multiple of 3.
*/
public final void setCoordinates( int vertexIndex, float[] floatArray )
{
dataContainer.setCoordinates( vertexIndex, floatArray );
setBoundsDirty();
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the coordinates of the vertex at the given index
*
* @param vertexIndex The index of the vertex to modify
* @param point3f The new coordinates
*/
public final void setCoordinate( int vertexIndex, Tuple3f point3f )
{
dataContainer.setCoordinate( vertexIndex, point3f );
setBoundsDirty();
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the coordinates of the vertex at the given index
*
* @param vertexIndex The index of the vertex to modify
* @param x The new coordinates
* @param y The new coordinates
* @param z The new coordinates
*/
public final void setCoordinate( int vertexIndex, float x, float y, float z )
{
dataContainer.setCoordinate( vertexIndex, x, y, z );
setBoundsDirty();
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the coordinates of the vertices starting at the specified index.
*
* @param vertexIndex The index of the first vertex to modify
* @param point3fArray The new coordinates.
*/
public final void setCoordinates( int vertexIndex, Tuple3f[] point3fArray )
{
dataContainer.setCoordinates( vertexIndex, point3fArray );
setBoundsDirty();
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the coordinates of the vertices starting at the specified index
*
* @param vertexIndex The index of the first vertex to be modified.
* @param point3fArray The new coordinates
* @param startIndex The index of the first coordinate in the given array
* @param length The number of coordinates to copy
*/
public final void setCoordinates( int vertexIndex, Tuple3f[] point3fArray, int startIndex, int length )
{
dataContainer.setCoordinates( vertexIndex, point3fArray, startIndex, length );
setBoundsDirty();
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
public final void setCoordinates( int vertexIndex, List<Tuple3f> point3fList )
{
dataContainer.setCoordinates( vertexIndex, point3fList );
setBoundsDirty();
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
public final <T extends Tuple3f> T getCoordinate( int index, T point )
{
dataContainer.getCoordinate( index, point );
return ( point );
}
public final void getCoordinate( int vertexIndex, float[] floatArray )
{
dataContainer.getCoordinate( vertexIndex, floatArray );
}
public final void getCoordinates( int vertexIndex, Tuple3f[] point3fArray )
{
dataContainer.getCoordinates( vertexIndex, point3fArray );
}
public final void getCoordinates( int vertexIndex, float[] floatArray )
{
dataContainer.getCoordinates( vertexIndex, floatArray );
}
/**
* @return <code>true</code>, if this geometry contains normal data.
*/
public final boolean hasNormals()
{
return ( dataContainer.hasNormals() );
}
/**
* Sets the normal of the vertex at the given index.
*
* @param vertexIndex The index of the vertex to modify
* @param floatArray The new normal data. Its size must be a multiple of 3.
*/
public final void setNormal( int vertexIndex, float[] floatArray )
{
dataContainer.setNormal( vertexIndex, floatArray );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the normals of the vertices starting at the specified index.
*
* @param vertexIndex The index of the first vertex to modify
* @param floatArray The new normals. Its size must be a multiple of 3.
*/
public final void setNormals( int vertexIndex, float[] floatArray )
{
dataContainer.setNormals( vertexIndex, floatArray );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the normals of the vertices starting at the specified index.
*
* @param vertexIndex The index of the first vertex to modify
* @param floatArray The new normal data. Its size must be a multiple of 3.
* @param startIndex The first coordinate to use in the given array. The
* first element of the array to be used will be startIndex*3.
* @param length The number of vertices to modify
*/
public final void setNormals( int vertexIndex, float[] floatArray, int startIndex, int length )
{
dataContainer.setNormals( vertexIndex, floatArray, startIndex, length );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the normal of the vertex at the given index.
*
* @param vertexIndex THe index of the vertex to modify
* @param vector3f The new normal
*/
public final void setNormal( int vertexIndex, Vector3f vector3f )
{
dataContainer.setNormal( vertexIndex, vector3f );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the normal of the vertex at the given index.
*
* @param vertexIndex THe index of the vertex to modify
* @param x The new normal
* @param y The new normal
* @param z The new normal
*/
public final void setNormal( int vertexIndex, float x, float y, float z )
{
dataContainer.setNormal( vertexIndex, x, y, z );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the normals of the vertices at the specified index.
*
* @param vertexIndex The index of the first vertex to modify
* @param vector3fArray The new normals
*/
public final void setNormals( int vertexIndex, Vector3f[] vector3fArray )
{
dataContainer.setNormals( vertexIndex, vector3fArray );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the normals of the vertices starting at the specified index.
*
* @param vertexIndex The index of the first vertex to modify
* @param vector3fArray The new normals
* @param startIndex The index of the first coordinate to use in the given
* array.
* @param length The number of vertices to modify
*/
public final void setNormals( int vertexIndex, Vector3f[] vector3fArray, int startIndex, int length )
{
dataContainer.setNormals( vertexIndex, vector3fArray, startIndex, length );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
public final Vector3f getNormal( int index, Vector3f normal )
{
return ( dataContainer.getNormal( index, normal ) );
}
public final void getNormal( int vertexIndex, float[] floatArray )
{
dataContainer.getNormal( vertexIndex, floatArray );
}
public final void getNormals( int vertexIndex, float[] floatArray )
{
dataContainer.getNormals( vertexIndex, floatArray );
}
public final void getNormals( int index0, Vector3f[] vector3fArray )
{
dataContainer.getNormals( index0, vector3fArray );
}
/**
* Flips (inverts, negates) all the normals of this Geometry.
*
* @throws Error, if this Geometry doesn't currently have normals.
*/
public void flipNormals()
{
if ( !this.hasNormals() )
throw new Error( "This Geometry doesn't have normals!" );
Vector3f normal = Vector3f.fromPool();
for ( int i = 0; i < getVertexCount(); i++ )
{
getNormal( i, normal );
normal.negate();
setNormal( i, normal );
}
Vector3f.toPool( normal );
}
/**
* @return <code>true</code>, if this Geometry contains color data.
*/
public final boolean hasColors()
{
return ( dataContainer.hasColors() );
}
/**
* Sets the color of the vertex at the specified index.
*
* @param vertexIndex The index of the vertex to modify
* @param floatArray The new color data. The first {@link #colorSize}
* elements will be used.
*/
public final void setColor( int vertexIndex, float[] floatArray )
{
dataContainer.setColor( vertexIndex, floatArray );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the colors of the vertices starting at the specified index.
*
* @param vertexIndex The index of the first vertex to modify
* @param colorSize
* @param floatArray The new color value. Its size must be a multiple of
* {@link #colorSize}.
*/
public final void setColors( int vertexIndex, int colorSize, float[] floatArray )
{
dataContainer.setColors( vertexIndex, colorSize, floatArray );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the colors of the vertices starting at the specified index.
*
* @param vertexIndex The index of the first vertex to be modified.
* @param floatArray The new color data. The size of the array must be a
* multiple of {@link #colorSize}.
* @param colorSize
* @param startIndex The index of the first color in the given array. The
* first read item of the array will be startIndex*colorSize.
* @param length The number of colors to copy
*/
public final void setColors( int vertexIndex, int colorSize, float[] floatArray, int startIndex, int length )
{
dataContainer.setColors( vertexIndex, colorSize, floatArray, startIndex, length );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the color of the vertex at the specified index.
*
* @param vertexIndex The index of the vertex to modify
* @param colorf The new color.
*/
public final void setColor( int vertexIndex, Colorf colorf )
{
dataContainer.setColor( vertexIndex, colorf );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the color of the vertex at the specified index.
*
* @param vertexIndex The index of the vertex to modify
* @param r
* @param g
* @param b
*/
public final void setColor( int vertexIndex, float r, float g, float b )
{
dataContainer.setColor( vertexIndex, r, g, b );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the color of the vertex at the specified index.
*
* @param vertexIndex The index of the vertex to modify
* @param r
* @param g
* @param b
* @param a
*/
public final void setColor( int vertexIndex, float r, float g, float b, float a )
{
dataContainer.setColor( vertexIndex, r, g, b, a );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the colors of the vertices starting at the specified index.
*
* @param vertexIndex The index of the first vertex to modify.
* @param colorfArray The new color values.
*/
public final void setColors( int vertexIndex, Colorf[] colorfArray )
{
dataContainer.setColors( vertexIndex, colorfArray );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the colors of the vertices starting at the given index.
*
* @param vertexIndex The index of the first vertex to modify
* @param colorfArray The new color data.
* @param startIndex The index of the first color in the given array
* @param length The number of vertices to modify.
*/
public final void setColors( int vertexIndex, Colorf[] colorfArray, int startIndex, int length )
{
dataContainer.setColors( vertexIndex, colorfArray, startIndex, length );
openGLReferences_geomData.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Gets the color of the vertex at the specified index.
*
* @param vertexIndex The index of the vertex to modify
* @param colorf The new color.
*/
public final Colorf getColor( int vertexIndex, Colorf colorf )
{
return ( dataContainer.getColor( vertexIndex, colorf ) );
}
/**
* Gets the color of the vertex at the specified index.
*
* @param vertexIndex The index of the vertex to modify
* @param floatArray
*/
public final void getColor( int vertexIndex, float[] floatArray )
{
dataContainer.getColor( vertexIndex, floatArray );
}
/**
* Gets the color of the vertex at the specified index.
*
* @param vertexIndex The index of the vertex to modify
* @param colorf The new color.
*/
public final void getColors( int vertexIndex, float[] floatArray )
{
dataContainer.getColors( vertexIndex, floatArray );
}
/**
* @return <code>true</code>, if this Geometry contains texture-coordinate data (for any texture-unit).
*/
public final boolean hasTextureCoordinates()
{
return ( dataContainer.hasTextureCoordinates() );
}
/**
* @return <code>true</code>, if this Geometry contains texture-coordinate data (for the given texture-unit).
*/
public final boolean hasTextureCoordinates( int unit )
{
return ( dataContainer.hasTextureCoordinates( unit ) );
}
/**
* Sets the texture coordinate of the vertex at the specified index for the
* specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the vertex to modify
* @param floatArray The new texture coordinate data. Its size must be 2, 3 or 4.
*/
public final void setTextureCoordinate( int unit, int vertexIndex, float[] floatArray )
{
dataContainer.setTextureCoordinate( unit, vertexIndex, floatArray );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the texture coordinate of the vertex starting at the specified index
* for the specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the first vertex to modify
* @param texCoordSize 1, 2, 3 or 4
* @param floatArray The new coordinate data. Its size must be a multiple of
* 2, 3 or 4 depending on texCoordSet format.
*/
public final void setTextureCoordinates( int unit, int vertexIndex, int texCoordSize, float[] floatArray )
{
dataContainer.setTextureCoordinates( unit, vertexIndex, texCoordSize, floatArray );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the texture coordinate of the vertex starting at the specified index
* for the specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the first vertex to modify
* @param texCoordSize
* @param floatArray The new coordinate data. Its size must be a multiple of 2.
* @param startIndex
* @param length
*/
public final void setTextureCoordinates( int unit, int vertexIndex, int texCoordSize, float[] floatArray, int startIndex, int length )
{
dataContainer.setTextureCoordinates( unit, vertexIndex, texCoordSize, floatArray, startIndex, length );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the texture coordinate of the vertex at the specified index for the
* specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the vertex to modify
* @param s
*/
public final void setTextureCoordinate( int unit, int vertexIndex, float s )
{
dataContainer.setTextureCoordinate( unit, vertexIndex, s );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the texture coordinate of the vertex at the specified index for the
* specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the vertex to modify
* @param s
* @param t
*/
public final void setTextureCoordinate( int unit, int vertexIndex, float s, float t )
{
dataContainer.setTextureCoordinate( unit, vertexIndex, s, t );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the texture coordinate of the vertex at the specified index for the
* specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the vertex to modify
* @param s
* @param t
* @param r
*/
public final void setTextureCoordinate( int unit, int vertexIndex, float s, float t, float r )
{
dataContainer.setTextureCoordinate( unit, vertexIndex, s, t, r );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the texture coordinate of the vertex at the specified index for the
* specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the vertex to modify
* @param s
* @param t
* @param r
* @param q
*/
public final void setTextureCoordinate( int unit, int vertexIndex, float s, float t, float r, float q )
{
dataContainer.setTextureCoordinate( unit, vertexIndex, s, t, r, q );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the texture coordinate of the vertex at the specified index for the
* specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the vertex to modify
* @param texCoord
*/
public final void setTextureCoordinate( int unit, int vertexIndex, TexCoordf<?> texCoord )
{
dataContainer.setTextureCoordinate( unit, vertexIndex, texCoord );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the texture coordinate of the vertex starting at the specified index
* for the specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the first vertex to modify
* @param texCoordArray
*/
public final void setTextureCoordinates( int unit, int vertexIndex, TexCoordf<?>[] texCoordArray )
{
dataContainer.setTextureCoordinates( unit, vertexIndex, texCoordArray );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Sets the texture coordinate of the vertex starting at the specified index
* for the specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the first vertex to modify
* @param texCoordArray
* @param startIndex
* @param length
*/
public final void setTextureCoordinates( int unit, int vertexIndex, TexCoordf<?>[] texCoordArray, int startIndex, int length )
{
dataContainer.setTextureCoordinates( unit, vertexIndex, texCoordArray, startIndex, length );
openGLReferences_texCoords.invalidateNames();
openGLReferences.invalidateNames();
}
/**
* Gets the texture coordinate of the vertex at the specified index for the
* specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the vertex to modify
* @param floatArray The new texture coordinate data. Its size must be 2, 3 or 4.
*/
public final void getTextureCoordinate( int unit, int vertexIndex, float[] floatArray )
{
dataContainer.getTextureCoordinate( unit, vertexIndex, floatArray );
}
public final void getTextureCoordinates( int unit, int vertexIndex, float[] floatArray )
{
dataContainer.getTextureCoordinates( unit, vertexIndex, floatArray );
}
/**
* Gets the texture coordinate of the vertex at the specified index for the
* specified coordinates set.
*
* @param unit The coordinates set.
* @param vertexIndex The index of the vertex to modify
* @param texCoord
*/
public final <T extends TexCoordf<?>> T getTextureCoordinate( int unit, int vertexIndex, T texCoord )
{
return ( dataContainer.getTextureCoordinate( unit, vertexIndex, texCoord ) );
}
/**
* @return <code>true</code>, if this Geometry contains vertex-attribute data.
*/
public final boolean hasVertexAttributes()
{
return ( dataContainer.hasVertexAttributes() );
}
/**
* @return <code>true</code>, if this Geometry contains vertex-attribute data at the given index.
*
* @param attribIndex
*/
public final boolean hasVertexAttributes( int attribIndex )
{
return ( dataContainer.hasVertexAttributes( attribIndex ) );
}
/**
* @return the number of vertex attributes in the Geometry.
*/
public final int getVertexAttributesCount()
{
return ( dataContainer.getVertexAttributesCount() );
}
/**
* Sets the vertex attribute of the vertex at the specified index for the
* specified attribute.
*
* @param attribIndex The attributes set.
* @param vertexIndex The index of the vertex to modify
* @param floatArray The new attribute data. Its size must be 1, 2, 3 or 4.
*/
public final void setVertexAttribute( int attribIndex, int vertexIndex, float[] floatArray )
{
dataContainer.setVertexAttribute( attribIndex, vertexIndex, floatArray );
}
/**
* Sets the vertex attributes.
*
* @param attribIndex The attributes set.
* @param vertexIndex The index of the first vertex to modify
* @param values The new attribute data.
* @param attribSize the size of each attribute element (1, 2, 3, 4)
*/
public final void setVertexAttributes( int attribIndex, int vertexIndex, float[] values, int attribSize )
{
dataContainer.setVertexAttributes( attribIndex, vertexIndex, values, attribSize );
}
/**
* Sets the vertex attributes.
*
* @param attribIndex The attributes set.
* @param vertexIndex The index of the first vertex to modify
* @param values The new attribute data.
* @param attribsSize (1, 2, 3, 4)
* @param startIndex
* @param length
*/
public final void setVertexAttributes( int attribIndex, int vertexIndex, float[] values, int attribsSize, int startIndex, int length )
{
dataContainer.setVertexAttributes( attribIndex, vertexIndex, values, attribsSize, startIndex, length );
}
/**
* Sets the vertex attribute of the vertex at the specified index for the
* specified attribute.
*
* @param attribIndex The attributes set.
* @param vertexIndex The index of the vertex to modify
* @param value The new attribute data.
*/
public final void setVertexAttribute( int attribIndex, int vertexIndex, float value )
{
dataContainer.setVertexAttribute( attribIndex, vertexIndex, value );
}
/**
* Sets the vertex attribute of the vertex at the specified index for the
* specified attribute.
*
* @param attribIndex The attributes set.
* @param vertexIndex The index of the vertex to modify
* @param value The new attribute data.
*/
public final void setVertexAttribute( int attribIndex, int vertexIndex, TupleNf<?> value )
{
dataContainer.setVertexAttribute( attribIndex, vertexIndex, value );
}
/**
* Sets the vertex attributes.
*
* @param attribIndex The attributes set.
* @param vertexIndex The index of the first vertex to modify
* @param values The new attribute data.
*/
public final void setVertexAttributes( int attribIndex, int vertexIndex, TupleNf<?>[] values )
{
dataContainer.setVertexAttributes( attribIndex, vertexIndex, values );
}
/**
* Sets the vertex attributes.
*
* @param attribIndex The attributes set.
* @param vertexIndex The index of the first vertex to modify
* @param values The new attribute data.
* @param startIndex
* @param length
*/
public final void setVertexAttributes( int attribIndex, int vertexIndex, TupleNf<?>[] values, int startIndex, int length )
{
dataContainer.setVertexAttributes( attribIndex, vertexIndex, values, startIndex, length );
}
public final void getVertexAttribute( int attribIndex, int vertexIndex, float[] floatArray )
{
dataContainer.getVertexAttribute( attribIndex, vertexIndex, floatArray );
}
public final void getVertexAttributes( int attribIndex, int vertexIndex, float[] floatArray )
{
dataContainer.getVertexAttributes( attribIndex, vertexIndex, floatArray );
}
/**
* Gets the vertex attribute of the vertex at the specified index for the
* specified attribute.
*
* @param attribIndex The attributes set.
* @param vertexIndex The index of the vertex to modify
*/
public final float getVertexAttribute( int attribIndex, int vertexIndex )
{
return ( dataContainer.getVertexAttribute( attribIndex, vertexIndex ) );
}
/**
* Gets the vertex attribute of the vertex at the specified index for the
* specified attribute.
*
* @param attribIndex The attributes set.
* @param vertexIndex The index of the vertex to modify
* @param value The buffer for the attribute data.
*/
public final void getVertexAttribute( int attribIndex, int vertexIndex, TupleNf<?> value )
{
dataContainer.getVertexAttribute( attribIndex, vertexIndex, value );
}
/**
* Applies the the n-th Triangle to the GeometryArray.
* This method must be overridden by concrete classes to fix the vertex-index (e.g. for an IndexedTriangleArray)
*
* @param i0 the first triangle's vertex-index
* @param i1 the second triangle's vertex-index
* @param i2 the third triangle's vertex-index
* @param triangle
*
* @return true, if the triangle could be applied
*/
public final boolean setTriangle( int i0, int i1, int i2, Triangle triangle )
{
return ( setTriangle( i0, i1, i2, triangle ) );
}
/**
* Applies the the n-th Triangle to the GeometryArray.
* This method must be overridden by concrete classes to fix the vertex-index (e.g. for an IndexedTriangleArray)
*
* @param triangle
*
* @return true, if the triangle could be applied
*/
public final boolean setTriangle( Triangle triangle )
{
return ( dataContainer.setTriangle( triangle ) );
}
/**
* Retrieves the the n-th Triangle from the GeometryArray.
* This method must be overridden by concrete classes to fix the vertex-index (e.g. for an IndexedTriangleArray)
*
* @param i0 the first triangle's vertex-index
* @param i1 the second triangle's vertex-index
* @param i2 the third triangle's vertex-index
* @param triangle
*
* @return true, if the triangle could be retrieved
*/
public final boolean getTriangle( int i0, int i1, int i2, Triangle triangle )
{
return ( dataContainer.getTriangle( i0, i1, i2, triangle ) );
}
public final float[] getCoordRefFloat()
{
return ( dataContainer.getCoordRefFloat() );
}
public final float[] getColorRefFloat()
{
return ( dataContainer.getColorRefFloat() );
}
public final float[] getNormalRefFloat()
{
return ( dataContainer.getNormalRefFloat() );
}
public final float[] getTexCoordRefFloat( int unit )
{
return ( dataContainer.getTexCoordRefFloat( unit ) );
}
public final SceneGraphOpenGLReferences getOpenGLReference_DL_GeomData()
{
return ( openGLReferences_geomData );
}
public final SceneGraphOpenGLReferences getOpenGLReference_DL_TexCoords()
{
return ( openGLReferences_texCoords );
}
public final SceneGraphOpenGLReferences getOpenGLReference_DL()
{
return ( openGLReferences );
}
/**
* {@inheritDoc}
*/
@Override
protected void finalize()
{
openGLReferences_geomData.prepareObjectForDestroy();
openGLReferences_texCoords.prepareObjectForDestroy();
openGLReferences.prepareObjectForDestroy();
}
/**
* {@inheritDoc}
*/
@Override
public void freeOpenGLResources( CanvasPeer canvasPeer )
{
if ( getCoordinatesData() != null )
getCoordinatesData().freeOpenGLResources( canvasPeer );
if ( getNormalsData() != null )
getNormalsData().freeOpenGLResources( canvasPeer );
if ( getColorData() != null )
getColorData().freeOpenGLResources( canvasPeer );
if ( hasTextureCoordinates() )
{
int[] tcsm = getTexCoordSetMap();
for ( int i = 0; i < tcsm.length; i++ )
{
getTexCoordsData( tcsm[i] ).freeOpenGLResources( canvasPeer );
}
}
if ( hasVertexAttributes() )
{
GeomNioFloatData d;
for ( int i = 0; i < 16; i++ )
{
if ( ( d = getVertexAttribData( i ) ) != null )
d.freeOpenGLResources( canvasPeer );
}
}
if ( openGLReferences_geomData.referenceExists( canvasPeer ) )
openGLReferences_geomData.prepareObjectForDestroy( canvasPeer );
if ( openGLReferences_texCoords.referenceExists( canvasPeer ) )
openGLReferences_texCoords.prepareObjectForDestroy( canvasPeer );
if ( openGLReferences.referenceExists( canvasPeer ) )
openGLReferences.prepareObjectForDestroy( canvasPeer );
}
/**
* {@inheritDoc}
*/
@Override
protected void duplicateNodeComponent( NodeComponent original, boolean forceDuplicate )
{
super.duplicateNodeComponent( original, forceDuplicate );
Geometry o = (Geometry)original;
this.dataContainer.copyFrom( o.dataContainer, forceDuplicate );
this.optimization = o.optimization;
this.setBoundsDirty();
}
/**
* Sets up the Geometry to be stored in a single NIO buffer for interleaved geometry.
*
* @param features
* @param colorAlpha
* @param tuSizes the sizes of the texture-units (may be null, if not contained in the features mask)
* @param vaSizes the sizes of the vertex-arrays (may be null, if not contained in the features mask)
*/
public final void makeInterleaved( int features, boolean colorAlpha, int[] tuSizes, int[] vaSizes )
{
dataContainer.makeInterleaved( features, colorAlpha, tuSizes, vaSizes );
}
/**
* Sets up the Geometry to be stored in a single NIO buffer for interleaved geometry.
*/
public final void makeInterleaved()
{
dataContainer.makeInterleaved();
}
/**
* {@inheritDoc}
*/
@Override
public abstract Geometry cloneNodeComponent( boolean forceDuplicate );
public Geometry( GeometryArrayType type, boolean hasIndex, int coordsSize, int vertexCount, int[] stripVertexCounts, int indexCount )
{
super( false );
this.dataContainer = new GeometryDataContainer( type, hasIndex, coordsSize, vertexCount, stripVertexCounts, indexCount );
}
}