📄 elevationgrid.java
字号:
//
// CLASS
// ElevationGrid - a 3D terrain grid built from a list of heights
//
// DESCRIPTION
// This class creates a 3D terrain on a grid whose X and Z dimensions,
// and row/column spacing are parameters, along with a list of heights
// (elevations), one per grid row/column pair.
//
package Java3DApplet;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;
class ElevationGrid
extends Primitive
{
// Parameters
protected int xDimension = 0, zDimension = 0;
protected double xSpacing = 0.0, zSpacing = 0.0;
protected double[] heights = null;
// 3D nodes
private Appearance mainAppearance = null;
private Shape3D shape = null;
private IndexedTriangleStripArray tristrip = null;
//
// Construct an elevation grid
//
public ElevationGrid( )
{
xDimension = 2;
zDimension = 2;
xSpacing = 1.0;
zSpacing = 1.0;
mainAppearance = null;
zeroHeights( );
rebuild( );
try {
jbInit();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
public ElevationGrid( int xDim, int zDim )
{
xDimension = xDim;
zDimension = zDim;
xSpacing = 1.0;
zSpacing = 1.0;
mainAppearance = null;
zeroHeights( );
rebuild( );
}
public ElevationGrid( int xDim, int zDim,
Appearance app )
{
xDimension = xDim;
zDimension = zDim;
xSpacing = 1.0;
zSpacing = 1.0;
mainAppearance = app;
zeroHeights( );
rebuild( );
}
public ElevationGrid( int xDim, int zDim,
double xSpace, double zSpace )
{
xDimension = xDim;
zDimension = zDim;
xSpacing = xSpace;
zSpacing = zSpace;
mainAppearance = null;
zeroHeights( );
rebuild( );
}
public ElevationGrid( int xDim, int zDim,
double xSpace, double zSpace,
Appearance app )
{
xDimension = xDim;
zDimension = zDim;
xSpacing = xSpace;
zSpacing = zSpace;
mainAppearance = app;
zeroHeights( );
rebuild( );
}
public ElevationGrid( int xDim, int zDim,
double[] h )
{
this( xDim, zDim, 1.0, 1.0, h, null );
}
public ElevationGrid( int xDim, int zDim,
double[] h,
Appearance app )
{
this( xDim, zDim, 1.0, 1.0, h, app );
}
public ElevationGrid( int xDim, int zDim,
double xSpace, double zSpace,
double[] h )
{
this( xDim, zDim, xSpace, zSpace, h, null );
}
public ElevationGrid( int xDim, int zDim,
double xSpace, double zSpace,
double[] h,
Appearance app )
{
xDimension = xDim;
zDimension = zDim;
xSpacing = xSpace;
zSpacing = zSpace;
mainAppearance = app;
if ( h == null )
zeroHeights( );
else
{
heights = new double[h.length];
for ( int i = 0; i < h.length; i++ )
heights[i] = h[i];
}
rebuild( );
}
private void zeroHeights( )
{
int n = xDimension * zDimension;
heights = new double[n];
for ( int i = 0; i < n; i++ )
heights[i] = 0.0;
}
private void rebuild( )
{
// Build a shape
if ( shape == null )
{
shape = new Shape3D( );
shape.setCapability( Shape3D.ALLOW_APPEARANCE_WRITE );
shape.setCapability( Shape3D.ALLOW_GEOMETRY_WRITE );
shape.setAppearance( mainAppearance );
addChild( shape );
}
else
{
shape.setAppearance( mainAppearance );
}
if ( xDimension < 2 || zDimension < 2 ||
heights == null || heights.length < 4 )
{
tristrip = null;
shape.setGeometry( null );
return;
}
// Create a list of coordinates, one per grid row/column
double[] coordinates = new double[xDimension*zDimension*3];
double x, z;
int n = 0, k = 0;
z = ((double)(zDimension-1)) * zSpacing / 2.0; // start at front edge
for ( int i = 0; i < zDimension; i++ )
{
x = -((double)(xDimension-1)) * xSpacing / 2.0;// start at left edge
for ( int j = 0; j < xDimension; j++ )
{
coordinates[n++] = x;
coordinates[n++] = heights[k++];
coordinates[n++] = z;
x += xSpacing;
}
z -= zSpacing;
}
// Create a list of normals, one per grid row/column
float[] normals = new float[xDimension*zDimension*3];
Vector3f one = new Vector3f( 0.0f, 0.0f, 0.0f );
Vector3f two = new Vector3f( 0.0f, 0.0f, 0.0f );
Vector3f norm = new Vector3f( 0.0f, 0.0f, 0.0f );
n = 0;
k = 0;
for ( int i = 0; i < zDimension-1; i++ )
{
for ( int j = 0; j < xDimension-1; j++ )
{
// Vector to right in X
one.set( (float)xSpacing, (float)(heights[k+1] - heights[k]), 0.0f );
// Vector back in Z
two.set( 0.0f, (float)(heights[k+xDimension] - heights[k]), (float)-zSpacing );
// Cross them to get the normal
norm.cross( one, two );
normals[n++] = norm.x;
normals[n++] = norm.y;
normals[n++] = norm.z;
k++;
}
// Last normal in row is a copy of the previous one
normals[n] = normals[n-3]; // X
normals[n+1] = normals[n-2]; // Y
normals[n+2] = normals[n-1]; // Z
n += 3;
k++;
}
// Last row of normals is a copy of the previous row
for ( int j = 0; j < xDimension; j++ )
{
normals[n] = normals[n-xDimension*3]; // X
normals[n+1] = normals[n-xDimension*3+1]; // Y
normals[n+2] = normals[n-xDimension*3+2]; // Z
n += 3;
}
// Create a list of texture coordinates, one per grid row/column
float[] texcoordinates = new float[xDimension*zDimension*2];
float deltaS = 1.0f / (float)(xDimension-1);
float deltaT = 1.0f / (float)(zDimension-1);
float s = 0.0f;
float t = 0.0f;
n = 0;
for ( int i = 0; i < zDimension; i++ )
{
s = 0.0f;
for ( int j = 0; j < xDimension; j++ )
{
texcoordinates[n++] = s;
texcoordinates[n++] = t;
s += deltaS;
}
t += deltaT;
}
// Create a list of triangle strip indexes. Each strip goes
// down one row (X direction) of the elevation grid.
int[] indexes = new int[xDimension*(zDimension-1)*2];
int[] stripCounts = new int[zDimension-1];
n = 0;
k = 0;
for ( int i = 0; i < zDimension-1; i++ )
{
stripCounts[i] = xDimension*2;
for ( int j = 0; j < xDimension; j++ )
{
indexes[n++] = k+xDimension;
indexes[n++] = k;
k++;
}
}
// Create geometry for collection of triangle strips, one
// strip per row of the elevation grid
tristrip = new IndexedTriangleStripArray(
coordinates.length,
GeometryArray.COORDINATES |
GeometryArray.NORMALS |
GeometryArray.TEXTURE_COORDINATE_2,
indexes.length,
stripCounts );
tristrip.setCoordinates( 0, coordinates );
tristrip.setNormals( 0, normals );
tristrip.setTextureCoordinates( 0, texcoordinates );
tristrip.setCoordinateIndices( 0, indexes );
tristrip.setNormalIndices( 0, indexes );
tristrip.setTextureCoordinateIndices( 0, indexes );
// Set the geometry for the shape
shape.setGeometry( tristrip );
}
//
// Control the appearance
//
public void setAppearance( Appearance app )
{
mainAppearance = app;
if ( shape != null )
shape.setAppearance( mainAppearance );
}
//
// Control grid parameters
//
public void setHeights( double[] h )
{
if ( h == null )
zeroHeights( );
else
{
heights = new double[h.length];
for ( int i = 0; i < h.length; i++ )
heights[i] = h[i];
}
rebuild( );
}
public double[] getHeights( )
{
return heights;
}
public void setXDimension( int xDim )
{
xDimension = xDim;
rebuild( );
}
public int getXDimension( )
{
return xDimension;
}
public void setZDimension( int zDim )
{
zDimension = zDim;
rebuild( );
}
public int getZDimension( )
{
return zDimension;
}
public void setXSpacing( double xSpace )
{
xSpacing = xSpace;
rebuild( );
}
public double getXSpacing( )
{
return xSpacing;
}
public void setZSpacing( double zSpace )
{
zSpacing = zSpace;
rebuild( );
}
public double getZSpacing( )
{
return zSpacing;
}
//
// Provide info on the shape and geometry
//
public Shape3D getShape( int partid )
{
return shape;
}
public int getNumTriangles( )
{
return xDimension * zDimension * 2;
}
public int getNumVertices( )
{
return xDimension * zDimension;
}
public Appearance getAppearance(int partId)
{
return getShape(0).getAppearance();
}
private void jbInit() throws Exception {
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -