📄 exhenge.java
字号:
//
// CLASS
// ExHenge - create a stone-henge like (vaguely) mysterious temple thing
//
// DESCRIPTION
// This example illustrates the use of a few of Java 3D's lighting
// types to create atmospheric lighting to make a structure look
// like it is glowing. In particular, we build a central emissive
// dome, unaffected by any lighting. Surrounding that dome are a
// series of arches that are lit by a one or more of a point
// light in the center, directional lights at front-left and
// back-right, and two ambient lights. Each of these lights can be
// turned on and off via menu items.
//
// SEE ALSO
// Arch
// ExAmbientLight
// ExDirectionalLight
// ExPointLight
//
// AUTHOR
// David R. Nadeau / San Diego Supercomputer Center
//
//
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.image.*;
public class ExHenge
extends Example
{
//--------------------------------------------------------------
// SCENE CONTENT
//--------------------------------------------------------------
//
// Nodes (updated via menu)
//
private AmbientLight ambient = null;
private AmbientLight brightAmbient = null;
private DirectionalLight redDirectional = null;
private DirectionalLight yellowDirectional = null;
private PointLight orangePoint = null;
//
// Build scene
//
public Group buildScene( )
{
// Turn off the example headlight
setHeadlightEnable( false );
// Default to walk navigation
setNavigationType( Walk );
//
// Preload the texture images
//
if ( debug ) System.err.println( " textures..." );
Texture groundTex = null;
Texture spurTex = null;
Texture domeTex = null;
TextureLoader texLoader = null;
ImageComponent image = null;
texLoader = new TextureLoader( "mud01.jpg", this );
image = texLoader.getImage( );
if ( image == null )
System.err.println( "Cannot load mud01.jpg texture" );
else
{
groundTex = texLoader.getTexture( );
groundTex.setBoundaryModeS( Texture.WRAP );
groundTex.setBoundaryModeT( Texture.WRAP );
groundTex.setMinFilter( Texture.NICEST );
groundTex.setMagFilter( Texture.NICEST );
groundTex.setMipMapMode( Texture.BASE_LEVEL );
groundTex.setEnable( true );
}
texLoader = new TextureLoader( "stonebrk2.jpg", this );
image = texLoader.getImage( );
if ( image == null )
System.err.println( "Cannot load stonebrk2.jpg texture" );
else
{
spurTex = texLoader.getTexture( );
spurTex.setBoundaryModeS( Texture.WRAP );
spurTex.setBoundaryModeT( Texture.WRAP );
spurTex.setMinFilter( Texture.NICEST );
spurTex.setMagFilter( Texture.NICEST );
spurTex.setMipMapMode( Texture.BASE_LEVEL );
spurTex.setEnable( true );
}
texLoader = new TextureLoader( "fire.jpg", this );
image = texLoader.getImage( );
if ( image == null )
System.err.println( "Cannot load fire.jpg texture" );
else
{
domeTex = texLoader.getTexture( );
domeTex.setBoundaryModeS( Texture.WRAP );
domeTex.setBoundaryModeT( Texture.WRAP );
domeTex.setMinFilter( Texture.NICEST );
domeTex.setMagFilter( Texture.NICEST );
domeTex.setMipMapMode( Texture.BASE_LEVEL );
domeTex.setEnable( true );
}
//
// Build some shapes we'll need
//
if ( debug ) System.err.println( " flying buttresses..." );
// Build three types of spurs (flying buttresses)
Appearance spurApp = new Appearance( );
Material spurMat = new Material( );
spurMat.setAmbientColor( 0.6f, 0.6f, 0.6f );
spurMat.setDiffuseColor( 1.0f, 1.0f, 1.0f );
spurMat.setSpecularColor( 0.0f, 0.0f, 0.0f );
spurApp.setMaterial( spurMat );
Transform3D tr = new Transform3D( );
tr.setIdentity( );
tr.setScale( new Vector3d( 1.0, 4.0, 1.0 ) );
TextureAttributes spurTexAtt = new TextureAttributes( );
spurTexAtt.setTextureMode( TextureAttributes.MODULATE );
spurTexAtt.setPerspectiveCorrectionMode(
TextureAttributes.NICEST );
spurTexAtt.setTextureTransform( tr );
spurApp.setTextureAttributes( spurTexAtt );
if ( spurTex != null )
spurApp.setTexture( spurTex );
Arch spur1 = new Arch(
0.0, // start Phi
1.571, // end Phi
9, // nPhi
-0.0982, // start Theta
0.0982, // end Theta (11.25 degrees)
2, // nTheta
2.5, // start radius
1.0, // end radius
0.05, // start phi thickness
0.025, // end phi thickness
spurApp ); // appearance
Arch spur2 = new Arch(
0.0, // start Phi
1.571, // end Phi
9, // nPhi
-0.0982, // start Theta
0.0982, // end Theta (11.25 degrees)
2, // nTheta
1.5, // start radius
2.0, // end radius
0.05, // start phi thickness
0.025, // end phi thickness
spurApp ); // appearance
Arch spur3 = new Arch(
0.0, // start Phi
1.571, // end Phi
9, // nPhi
-0.0982, // start Theta
0.0982, // end Theta (11.25 degrees)
2, // nTheta
1.5, // start radius
1.0, // end radius
0.05, // start phi thickness
0.025, // end phi thickness
spurApp ); // appearance
Arch spur4 = new Arch(
0.0, // start Phi
1.178, // end Phi
9, // nPhi
-0.0982, // start Theta
0.0982, // end Theta (11.25 degrees)
2, // nTheta
4.0, // start radius
4.0, // end radius
0.05, // start phi thickness
0.025, // end phi thickness
spurApp ); // appearance
// Put each spur into a shared group so we can instance
// the spurs multiple times
SharedGroup spur1Group = new SharedGroup( );
spur1Group.addChild( spur1 );
spur1Group.compile( );
SharedGroup spur2Group = new SharedGroup( );
spur2Group.addChild( spur2 );
spur2Group.compile( );
SharedGroup spur3Group = new SharedGroup( );
spur3Group.addChild( spur3 );
spur3Group.compile( );
SharedGroup spur4Group = new SharedGroup( );
spur4Group.addChild( spur4 );
spur4Group.compile( );
// Build a central dome
if ( debug ) System.err.println( " central dome..." );
Appearance domeApp = new Appearance( );
// No material needed - we want the dome to glow,
// so use a REPLACE mode texture only
TextureAttributes domeTexAtt = new TextureAttributes( );
domeTexAtt.setTextureMode( TextureAttributes.REPLACE );
domeTexAtt.setPerspectiveCorrectionMode(
TextureAttributes.NICEST );
domeApp.setTextureAttributes( domeTexAtt );
if ( domeTex != null )
domeApp.setTexture( domeTex );
Arch dome = new Arch(
0.0, // start Phi
1.571, // end Phi
5, // nPhi
0.0, // start Theta
2.0*Math.PI, // end Theta (360 degrees)
17, // nTheta
1.0, // start radius
1.0, // end radius
0.0, // start phi thickness
0.0, // end phi thickness
domeApp ); // appearance
// Build the ground. Use a trick to get better lighting
// effects by using an elevation grid. The idea is this:
// for interactive graphics systems, such as those
// controlled by Java3D, lighting effects are computed only
// at triangle vertexes. Imagine a big rectangular ground
// underneath a PointLight (added below). If the
// PointLight is above the center of the square, in the real
// world we'd expect a bright spot below it, fading to
// darkness at the edges of the square. Not so in
// interactive graphics. Since lighting is only computed
// at vertexes, and the square's vertexes are each
// equidistant from a centered PointLight, all four square
// coordinates get the same brightness. That brightness
// is interpolated across the square, giving a *constant*
// brightness for the entire square! There is no bright
// spot under the PointLight. So, here's the trick: use
// more triangles. Pretty simple. Split the ground under
// the PointLight into a grid of smaller squares. Each
// smaller square is shaded using light brightness computed
// at the square's vertexes. Squares directly under the
// PointLight get brighter lighting at their vertexes, and
// thus they are bright. This gives the desired bright
// spot under the PointLight. The more squares we use
// (a denser grid), the more accurate the bright spot and
// the smoother the lighting gradation from bright directly
// under the PointLight, to dark at the distant edges. Of
// course, with more squares, we also get more polygons to
// draw and a performance slow-down. So there is a
// tradeoff between lighting quality and drawing speed.
// For this example, we'll use a coarse mesh of triangles
// created using an ElevationGrid shape.
if ( debug ) System.err.println( " ground..." );
Appearance groundApp = new Appearance( );
Material groundMat = new Material( );
groundMat.setAmbientColor( 0.3f, 0.3f, 0.3f );
groundMat.setDiffuseColor( 0.7f, 0.7f, 0.7f );
groundMat.setSpecularColor( 0.0f, 0.0f, 0.0f );
groundApp.setMaterial( groundMat );
tr = new Transform3D( );
tr.setScale( new Vector3d( 8.0, 8.0, 1.0 ) );
TextureAttributes groundTexAtt = new TextureAttributes( );
groundTexAtt.setTextureMode( TextureAttributes.MODULATE );
groundTexAtt.setPerspectiveCorrectionMode(
TextureAttributes.NICEST );
groundTexAtt.setTextureTransform( tr );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -