// // CLASS // ExPointLight - illustrate use of point lights // // LESSON // Add a PointLight node to illuminate a scene. // // SEE ALSO // ExAmbientLight // ExDirectionalLight // ExSpotLight // // AUTHOR // David R. Nadeau / San Diego Supercomputer Center // import java.awt.*; import java.awt.event.*; import javax.media.j3d.*; import javax.vecmath.*; public class ExPointLight extends Example { //-------------------------------------------------------------- // SCENE CONTENT //-------------------------------------------------------------- // // Nodes (updated via menu) // private PointLight light = null; // // Build scene // public Group buildScene( ) { // Get the current color, position, and attenuation Color3f color = (Color3f)colors[currentColor].value; Point3f pos = (Point3f)positions[currentPosition].value; Point3f atten = (Point3f)attenuations[currentAttenuation].value; // Turn off the example headlight setHeadlightEnable( false ); // Build the scene root Group scene = new Group( ); // BEGIN EXAMPLE TOPIC // Create influencing bounds BoundingSphere worldBounds = new BoundingSphere( new Point3d( 0.0, 0.0, 0.0 ), // Center 1000.0 ); // Extent // Set the light color and its influencing bounds light = new PointLight( ); light.setEnable( lightOnOff ); light.setColor( color ); light.setPosition( pos ); light.setAttenuation( atten ); light.setCapability( PointLight.ALLOW_STATE_WRITE ); light.setCapability( PointLight.ALLOW_COLOR_WRITE ); light.setCapability( PointLight.ALLOW_POSITION_WRITE); light.setCapability( PointLight.ALLOW_ATTENUATION_WRITE); light.setInfluencingBounds( worldBounds ); scene.addChild( light ); // END EXAMPLE TOPIC // Build foreground geometry scene.addChild( new SphereGroup( ) ); // Add arrows in a fan to show light ray directions scene.addChild( buildArrows( ) ); return scene; } //-------------------------------------------------------------- // FOREGROUND AND ANNOTATION CONTENT //-------------------------------------------------------------- // // Create a fan of annotation arrows aiming in all directions, // but in the XY plane. Next, build an array of Transform3D's, // one for each of the light positions shown on the positions // menu. Save these Transform3Ds and a top-level TransformGroup // surrounding the arrows. Later, when the user selects a new // light position, we poke the corresponding Transform3D into // the TransformGroup to cause the arrows to move to a new // position. // private Transform3D[] arrowPositionTransforms = null; private TransformGroup arrowPositionTransformGroup = null; private Group buildArrows( ) { // Create a transform group surrounding the arrows. // Enable writing of its transform. arrowPositionTransformGroup = new TransformGroup( ); arrowPositionTransformGroup.setCapability( TransformGroup.ALLOW_TRANSFORM_WRITE ); // Create a group of arrows in a fan and add that group // to the transform group. AnnotationArrowFan af = new AnnotationArrowFan( 0.0f, 0.0f, 0.0f, // center position 2.5f, // arrow length 0.0f, // start angle (float)(Math.PI*2.0*7.0/8.0),// end angle 8 ); // number of arrows arrowPositionTransformGroup.addChild( af ); // Create a set of Transform3Ds for the different // arrow positions. arrowPositionTransforms = new Transform3D[positions.length]; Point3f pos; Vector3f v = new Vector3f( ); for ( int i = 0; i < positions.length; i++ ) { // Create a Transform3D, setting its translation. arrowPositionTransforms[i] = new Transform3D( ); pos = (Point3f)positions[i].value; v.set( pos ); arrowPositionTransforms[i].setTranslation( v ); } // Set the initial transform to be the current position arrowPositionTransformGroup.setTransform( arrowPositionTransforms[currentPosition] ); return arrowPositionTransformGroup; } //-------------------------------------------------------------- // USER INTERFACE //-------------------------------------------------------------- // // Main // public static void main( String[] args ) { ExPointLight ex = new ExPointLight( ); ex.initialize( args ); ex.buildUniverse( ); ex.showFrame( ); } // On/off choices private boolean lightOnOff = true; private CheckboxMenuItem lightOnOffMenu; // Color menu choices private NameValue[] colors = { new NameValue( "White", White ), new NameValue( "Gray", Gray ), new NameValue( "Black", Black ), new NameValue( "Red", Red ), new NameValue( "Yellow", Yellow ), new NameValue( "Green", Green ), new NameValue( "Cyan", Cyan ), new NameValue( "Blue", Blue ), new NameValue( "Magenta", Magenta ), }; private int currentColor = 0; private CheckboxMenu colorMenu = null; // Position menu choices private NameValue[] positions = { new NameValue( "Origin", Origin ), new NameValue( "+X", PlusX ), new NameValue( "-X", MinusX ), new NameValue( "+Y", PlusY ), new NameValue( "-Y", MinusY ), new NameValue( "+Z", PlusZ ), new NameValue( "-Z", MinusZ ), }; private int currentPosition = 0; private CheckboxMenu positionMenu = null; // Attenuation menu choices private NameValue[] attenuations = { new NameValue( "Constant", new Point3f( 1.0f, 0.0f, 0.0f ) ), new NameValue( "Linear", new Point3f( 0.0f, 1.0f, 0.0f ) ), new NameValue( "Quadratic", new Point3f( 0.0f, 0.0f, 1.0f ) ), }; private int currentAttenuation = 0; private CheckboxMenu attenuationMenu = null; // // Initialize the GUI (application and applet) // public void initialize( String[] args ) { // Initialize the window, menubar, etc. super.initialize( args ); exampleFrame.setTitle( "Java 3D Point Light Example" ); // // Add a menubar menu to change node parameters // Light on/off // Color --> // Position --> // Attenuation --> // Menu m = new Menu( "PointLight" ); lightOnOffMenu = new CheckboxMenuItem( "Light on/off", lightOnOff ); lightOnOffMenu.addItemListener( this ); m.add( lightOnOffMenu ); colorMenu = new CheckboxMenu( "Color", colors, currentColor, this ); m.add( colorMenu ); positionMenu = new CheckboxMenu( "Position", positions, currentPosition, this ); m.add( positionMenu ); attenuationMenu = new CheckboxMenu( "Attenuation", attenuations, currentAttenuation, this ); m.add( attenuationMenu ); exampleMenuBar.add( m ); } // // Handle checkboxes and menu choices // public void checkboxChanged( CheckboxMenu menu, int check ) { if ( menu == colorMenu ) { // Change the light color currentColor = check; Color3f color = (Color3f)colors[check].value; light.setColor( color ); return; } if ( menu == positionMenu ) { // Change the light position currentPosition = check; Point3f pos = (Point3f)positions[check].value; light.setPosition( pos ); // Change the arrow group position arrowPositionTransformGroup.setTransform( arrowPositionTransforms[check] ); return; } if ( menu == attenuationMenu ) { // Change the light attenuation currentAttenuation = check; Point3f atten = (Point3f)attenuations[check].value; light.setAttenuation( atten ); return; } // Handle all other checkboxes super.checkboxChanged( menu, check ); } public void itemStateChanged( ItemEvent event ) { Object src = event.getSource( ); if ( src == lightOnOffMenu ) { // Turn the light on or off lightOnOff = lightOnOffMenu.getState( ); light.setEnable( lightOnOff ); return; } // Handle all other checkboxes super.itemStateChanged( event ); } }