/**
* 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.terrain;
import static java.lang.Math.abs;
import org.openmali.vecmath2.TexCoord2f;
import org.openmali.vecmath2.Tuple3f;
import org.xith3d.scenegraph.Appearance;
import org.xith3d.scenegraph.GroupNode;
import org.xith3d.scenegraph.IndexedTriangleStripArray;
import org.xith3d.scenegraph.AbstractLODShape3D;
import org.xith3d.scenegraph.Node;
import org.xith3d.scenegraph.traversal.DetailedTraversalCallback;
/**
* @author Mathias 'cylab' Henze
* @since 1.0
*/
public class TerrainTile extends GroupNode
{
private GridTriangulator triangulator;
private GridSampler sampler;
private GridSurface shader;
private Appearance appearance;
private int surfaceDetail;
//private IndexedTriangleArray geometry;
private IndexedTriangleStripArray geometry;
public TerrainTile( GridSampler sampler,GridSurface surface, GridTriangulator triangulator ,int surfaceDetail )
{
float x1 = triangulator.getX1();
float z1 = triangulator.getZ1();
float x2 = triangulator.getX2();
float z2 = triangulator.getZ2();
float s1 = triangulator.getS1();
float t1 = triangulator.getT1();
float s2 = triangulator.getS2();
float t2 = triangulator.getT2();
this.triangulator = triangulator;
this.sampler = sampler;
this.shader = surface;
this.surfaceDetail = surfaceDetail;
this.appearance = surface.getAppearance();
//System.out.println("Number of vertices: " + triangulator.getSize() * triangulator.getSize());
Tuple3f[] coordinates = triangulator.getCoordinates();
//geometry = new IndexedTriangleArray(coordinates.length, GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2, index.length);
int[] index = triangulator.getIndex();
int units = surface.getTextureUnits();
geometry = new IndexedTriangleStripArray( coordinates.length, index.length );
geometry.setCoordinates( 0, coordinates );
geometry.setIndex( index );
geometry.setValidIndexCount( index.length );
geometry.setNormals(0, triangulator.getNormals() );
for ( int u = 0; u < units; u++ )
{
TexCoord2f[] texCoordinates = new TexCoord2f[ coordinates.length ];
for ( int i = 0; i < coordinates.length; i++ )
{
texCoordinates[ i ] = surface.map( s1 + ( coordinates[ i ].getX() - x1 ) / abs( x2 - x1 ) * abs( s2 - s1 ), t1 + ( coordinates[ i ].getZ() - z1 ) / abs( z2 - z1 ) * abs( t2 - t1 ), u );
}
geometry.setTextureCoordinates( u, 0, texCoordinates );
}
addChild( new TerrainShape() );
}
@Override
protected GroupNode newInstance()
{
return new TerrainTile( sampler, shader, triangulator ,surfaceDetail );
}
@Override
public boolean traverse( DetailedTraversalCallback callback )
{
if ( !callback.traversalOperationCommon( this ) )
return ( false );
if ( !callback.traversalOperation( this ) )
return ( false );
if ( callback.traversalCheckGroupCommon( this ) )
{
final int num = numChildren();
for ( int i = 0; i < num; i++ )
{
if ( !getChild( i ).traverse( callback ) )
return ( false );
}
}
return ( callback.traversalOperationCommonAfter( this ) && callback.traversalOperationAfter( this ) );
}
private class TerrainShape extends AbstractLODShape3D
{
int[][] lods = new int[ 8 ][ 0 ];
public TerrainShape()
{
super( geometry, appearance );
float tolerance = triangulator.getBaseTolerance();
// TODO cylab 2007-MAR-11: make this dependent of the view distance
float size = triangulator.getX2() - triangulator.getX1();
float step = size/4;
float normRange= triangulator.getS2() - triangulator.getS1();
for ( int i = 0; i < 8; i++ )
{
lods[ i ] = i == 0 ? triangulator.getIndex() : triangulator.getIndex( tolerance + normRange * i );
addLOD( size + step * i, i == 7 ? 1e20f : size+step * ( i + 1 ) );
}
}
@Override
protected void onLODChanged( int oldLOD, int newLOD, String name )
{
//if( newLOD < 2 )
//{
// System.out.println("LOD-Level: "+newLOD+" indicies: "+lods[newLOD].length);
//}
geometry.setIndex( lods[ newLOD ] );
geometry.setValidIndexCount( lods[ newLOD ].length );
geometry.setStripVertexCounts( new int[]
{
lods[ newLOD ].length
} );
}
@Override
protected TerrainShape newInstance()
{
boolean gib = Node.globalIgnoreBounds;
Node.globalIgnoreBounds = this.isIgnoreBounds();
TerrainShape newShape = new TerrainShape();
Node.globalIgnoreBounds = gib;
return ( newShape );
}
@Override
public boolean traverse( DetailedTraversalCallback callback )
{
return super.traverse( callback ); //To change body of overridden methods use File | Settings | File Templates.
}
}
}