>
> The basic issue is a fundamental one with the way that Java3D works.
> When you ask for the view frustum projection matrix from Java3D it gives
> you the value used on the previous frame, not the current one. At a
> minimum, you need one frame to be rendered before the ROAM code can do
> anything useful. From your description, it sounds like you aren't
> setting up the view with the canvas before there is data available and
> thus, if you don't get anything to drive a second frame render then
> nothing will happen. Ie The event from the navigation will force a
> second frame render, as will the resize of the window etc.

I am not sure, if I understood you correctly. Are you saying that, I don't
see anything at first because I had no objects or whatever in the view,
which I could have seen? Now I added a Box somewhere near the terrain.
So starting the application gives me the view of the box, but I still get
the terrain only by clicking into the panel (See RoamTest3).

>
> Note also that we have one or two outstanding bugs with dynamically
> tiled terrain currently. We're not quite sure what they are yet but know
> they exist.

Could you bee a bit more specific on that? What kind of bugs?

While playing with your code I stumbled over
AbstractStaticTerrainData method getGridDepth() it was returning
gridWidth, I guess it should be gridDepth? But this class has nothing to
do with the tiling.

Thanks for your help

Desiree

> --
> Justin Couch                         http://www.vlc.com.au/~justin/
> Java Architect & Bit Twiddler              http://www.yumetech.com/
> Author, Java 3D FAQ Maintainer                  http://www.j3d.org/
> -------------------------------------------------------------------
> "Humanism is dead. Animals think, feel; so do machines now.
> Neither man nor woman is the measure of all things. Every organism
> processes data according to its domain, its environment; you, with
> all your brains, would be useless in a mouse's universe..."
>                                                - Greg Bear, Slant
> -------------------------------------------------------------------
>
> ===========================================================================
> To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
> of the message "signoff JAVA3D-INTEREST".  For general help, send email to
> [EMAIL PROTECTED] and include in the body of the message "help".
>
/*****************************************************************************
 *                        J3D.org Copyright (c) 2000
 *                               Java Source
 *
 * This source is licensed under the GNU LGPL v2.1
 * Please read http://www.gnu.org/copyleft/lgpl.html for more information
 *
 * This software comes with the standard NO WARRANTY disclaimer for any
 * purpose. Use it at your own risk. If there's a problem you get to fix it.
 *
 ****************************************************************************/

// Standard imports
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.j3d.*;
import javax.vecmath.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;

// Application Specific imports
import org.j3d.geom.Box;

import org.j3d.loaders.HeightMapTerrainData;
import org.j3d.loaders.SimpleTiledTerrainData;
import org.j3d.loaders.vterrain.BTHeader;
import org.j3d.loaders.vterrain.BTParser;

import org.j3d.terrain.AbstractStaticTerrainData;
import org.j3d.terrain.AppearanceGenerator;
import org.j3d.terrain.Landscape;
import org.j3d.terrain.TerrainData;
import org.j3d.terrain.roam.SplitMergeLandscape;

import org.j3d.texture.TextureCache;
import org.j3d.texture.TextureCacheFactory;

import org.j3d.ui.navigation.MouseViewHandler;
import org.j3d.ui.navigation.NavigationStateManager;
import org.j3d.ui.navigation.NavigationState;

import org.j3d.util.interpolator.ColorInterpolator;
import org.j3d.util.frustum.ViewFrustum;

/**
 * Demonstration of the ROAM code.
 *
 *
 * @author Justin Couch
 * @version $Revision: 1.5 $
 */
public class RoamTest3 extends DemoFrameDesTest
    implements ItemListener, AppearanceGenerator
    //    public class RoamTest2 extends DemoFrameDesTest
    //implements AppearanceGenerator
{
    // Achtung front und back hardcodiert
    private static final double BACK_CLIP_DISTANCE = 3000.0;
    private static final double FRONT_CLIP_DISTANCE = 1;

    /** The main canvas that we are navigating on */
    private Canvas3D navCanvas;

    /** The canvas that provides a birds-eye view of the scene */
    private Canvas3D topDownCanvas;

    /** Global material instance to use */
    private Material material;

    /** Global polygon attributes to use */
    private PolygonAttributes polyAttr;

    private MouseViewHandler groundNav;
    private MouseViewHandler topDownNav;

    /** The view frustum for the ground canvas */
    private ViewFrustum viewFrustum;

    /** The landscape we are navigating around */
    private Landscape landscape;

    /** The branchgroup to add our terrain to */
    private BranchGroup terrainGroup;

    /** TG that holds the user view position. Used when new terrain set */
    private TransformGroup gndViewTransform;

    /** TG that holds the top-down user view position. Used when new terrain set */
    private TransformGroup topViewTransform;

    private HashMap terrainFilesMap;
    private HashMap textureFilesMap;

    /** Mapping of the button to the polygon mode value */
    private HashMap polyModeMap;

    /** The color interpolator for doing height interpolations with */
    private ColorInterpolator heightRamp;

    /**
     * Construct a new demo with no geometry currently showing, but the
     * default type is set to quads.
     */
    public RoamTest3()
    {
        super("Terrain Culling Demo");

        navCanvas = createCanvas();

        terrainFilesMap = new HashMap();
        textureFilesMap = new HashMap();

        Panel p0 = new Panel(new GridLayout(1, 2));
        p0.add(navCanvas);
        //p0.add(topDownCanvas);

        add(p0, BorderLayout.CENTER);

        JPanel p1 = new JPanel(new FlowLayout());

        // Crater Lake Beispiel funktioniert
        ButtonGroup grp = new ButtonGroup();
        JRadioButton button = new JRadioButton("Crater Lake");
        button.addItemListener(this);
        grp.add(button);
        p1.add(button);

        terrainFilesMap.put(button, "crater_0513.bt");
        textureFilesMap.put(button, null);

        // Listener fuer MouseNavigation?
        groundNav = new MouseViewHandler();
        groundNav.setCanvas(navCanvas);
        groundNav.setButtonNavigation(MouseEvent.BUTTON1_MASK,
                                      NavigationState.FLY_STATE);
        groundNav.setButtonNavigation(MouseEvent.BUTTON2_MASK,
                                      NavigationState.TILT_STATE);
        groundNav.setButtonNavigation(MouseEvent.BUTTON3_MASK,
                                      NavigationState.PAN_STATE);

        buildScene();

        viewFrustum = new ViewFrustum(navCanvas);

        // Now set up the material and appearance handling for the generator
        material = new Material();
        material.setLightingEnable(true);

        polyAttr = new PolygonAttributes();
        polyAttr.setCapability(PolygonAttributes.ALLOW_MODE_WRITE);
        polyAttr.setCullFace(PolygonAttributes.CULL_NONE);
        polyAttr.setBackFaceNormalFlip(true);
        polyAttr.setPolygonMode(PolygonAttributes.POLYGON_FILL);

        heightRamp = new ColorInterpolator(ColorInterpolator.HSV_SPACE);
        heightRamp.addRGBKeyFrame(-20,  0,    0,    1,     0);
        heightRamp.addRGBKeyFrame(0,    0,    0.7f, 0.95f, 0);
        heightRamp.addRGBKeyFrame(5,    1,    1,    0,     0);
        heightRamp.addRGBKeyFrame(10,   0,    0.6f, 0,     0);
        heightRamp.addRGBKeyFrame(100,  0,    1,    0,     0);
        heightRamp.addRGBKeyFrame(1000, 0.6f, 0.7f, 0,     0);
        heightRamp.addRGBKeyFrame(1500, 0.5f, 0.5f, 0.3f,  0);
        heightRamp.addRGBKeyFrame(2500, 1,    1,    1,     0);

        //setSize(600, 400);
        //setVisible(true);
        loadTerrain(new String(),new String());
    }

    //----------------------------------------------------------
    // Methods required by ItemListener
    //----------------------------------------------------------

    /**
     * Process the change of state request from the colour selector panel.
     *
     * @param evt The event that caused this method to be called
     */
    // ??????????????????
    public void itemStateChanged(ItemEvent evt)
    {
        System.out.println("itemStateChanged");
        if(evt.getStateChange() != ItemEvent.SELECTED)
            return;

        Object src = evt.getSource();

        if(textureFilesMap.containsKey(src))
        {
            // map change request
            String terrain = (String)terrainFilesMap.get(src);
            String texture = (String)textureFilesMap.get(src);

            loadTerrain(terrain, texture);
        }
    }

    //----------------------------------------------------------
    // Methods required by AppearanceGenerator
    //----------------------------------------------------------

    /**
     * Create a new appearance instance. We set them all up with different
     * appearance instances, but share the material information.
     * 
     * Wieso Appearance neu aber Material teilen ????????????
     *
     * @return The new appearance instance to use
     */
    public Appearance createAppearance()
    {
        Appearance app = new Appearance();
        app.setMaterial(material);
        app.setPolygonAttributes(polyAttr);

        return app;
    }

    //----------------------------------------------------------
    // Internal convenience methods
    //----------------------------------------------------------

    /**
     * Build the scenegraph for the canvas
     */
    private void buildScene()
    {
        Color3f ambientBlue = new Color3f(0.0f, 0.02f, 0.5f);
        Color3f white = new Color3f(1, 1, 1);
        Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
        Color3f blue = new Color3f(0.00f, 0.20f, 0.80f);
        Color3f specular = new Color3f(0.7f, 0.7f, 0.7f);

        VirtualUniverse universe = new VirtualUniverse();
        Locale locale = new Locale(universe);

        BranchGroup view_group = new BranchGroup();
        BranchGroup world_object_group = new BranchGroup();

        PhysicalBody body = new PhysicalBody();
        PhysicalEnvironment env = new PhysicalEnvironment();

        Point3d origin = new Point3d(0, 0, 0);
        BoundingSphere light_bounds =
            new BoundingSphere(origin, BACK_CLIP_DISTANCE);
        DirectionalLight headlight = new DirectionalLight();
        headlight.setColor(white);
        headlight.setInfluencingBounds(light_bounds);
        headlight.setEnable(true);

        //
        // View group for the ground navigation system that the
        // roam code will apply to.
        //

        // Das ist die ViewPlatform von der aus bestimmt wird was im 
        // Blickfeld ist und geladen werden muss ??????????

        // linker Canvas der Demo

        ViewPlatform gnd_camera = new ViewPlatform();

        Transform3D angle = new Transform3D();

        gndViewTransform = new TransformGroup();
        gndViewTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        gndViewTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

        gndViewTransform.addChild(gnd_camera);
        gndViewTransform.addChild(headlight);   
        gndViewTransform.addChild(new Box(10, 10, 10));

        View gnd_view = new View();
        gnd_view.setBackClipDistance(BACK_CLIP_DISTANCE);
        gnd_view.setFrontClipDistance(FRONT_CLIP_DISTANCE);
        gnd_view.setPhysicalBody(body);
        gnd_view.setPhysicalEnvironment(env);
        gnd_view.addCanvas3D(navCanvas);
        gnd_view.attachViewPlatform(gnd_camera);

        //System.out.println("front clip dist "+gnd_view.getFrontClipDistance());
        //System.out.println("back clip dist "+gnd_view.getBackClipDistance());

        groundNav.setViewInfo(gnd_view, gndViewTransform);
        groundNav.setNavigationSpeed(50.0f);

        view_group.addChild(gndViewTransform);
        view_group.addChild(groundNav.getTimerBehavior());       

        // Create a new branchgroup that is for the geometry. Initially starts
        // with a null child at position zero so that we only need to write the
        // child and not extend. One less capability to set is good.
        terrainGroup = new BranchGroup();
        terrainGroup.setCapability(Group.ALLOW_CHILDREN_WRITE);
        terrainGroup.setCapability(Group.ALLOW_CHILDREN_EXTEND);

        TransformGroup testBoxTG = new TransformGroup();
        Transform3D testBoxT3d = new Transform3D();
        testBoxT3d.setTranslation(new Vector3f(50,3510,-50));
        testBoxTG.setTransform(testBoxT3d);
        testBoxTG.addChild(new Box(10, 10, 10));
        //world_object_group.addChild(new Box(100, 100, 100));
        world_object_group.addChild(testBoxTG);
        world_object_group.addChild(terrainGroup);

        // Add everything to the locale
        locale.addBranchGraph(view_group);
        locale.addBranchGraph(world_object_group);
    }

    /**
     * Load the terrain and get it read to roll. If the texture file is not
     * specified then no texture will be loaded and colour information is
     * used instead.
     *
     * @param filename The name of the terrain file
     * @param textureName The name of the texture file, or null
     */
    private void loadTerrain(String filename, String textureName)
    //private void loadTerrain()
    {
        // Variante 25 5*5
        double eastValues[] = new double[25];
        eastValues[0]=3445800.0;
        eastValues[1]=3445800.0;
        eastValues[2]=3445800.0;
        eastValues[3]=3445800.0;
        eastValues[4]=3445800.0;
        eastValues[5]=3445850.0;
        eastValues[6]=3445850.0;
        eastValues[7]=3445850.0;
        eastValues[8]=3445850.0;
        eastValues[9]=3445850.0;
        eastValues[10]=3445900.0;
        eastValues[11]=3445900.0;
        eastValues[12]=3445900.0;
        eastValues[13]=3445900.0;
        eastValues[14]=3445900.0;
        eastValues[15]=3445950.0;
        eastValues[16]=3445950.0;
        eastValues[17]=3445950.0;
        eastValues[18]=3445950.0;
        eastValues[19]=3445950.0;
        eastValues[20]=3446000.0;
        eastValues[21]=3446000.0;
        eastValues[22]=3446000.0;
        eastValues[23]=3446000.0;
        eastValues[24]=3446000.0;

        double northValues[] = new double[25];
        northValues[0]=5408515.20967;
        northValues[1]=5408565.20967;
        northValues[2]=5408615.20967;
        northValues[3]=5408665.20967;
        northValues[4]=5408715.20967;
        northValues[5]=5408515.20967;
        northValues[6]=5408565.20967;
        northValues[7]=5408615.20967;
        northValues[8]=5408665.20967;
        northValues[9]=5408715.20967;
        northValues[10]=5408515.20967;
        northValues[11]=5408565.20967;
        northValues[12]=5408615.20967;
        northValues[13]=5408665.20967;
        northValues[14]=5408715.20967;
        northValues[15]=5408515.20967;
        northValues[16]=5408565.20967;
        northValues[17]=5408615.20967;
        northValues[18]=5408665.20967;
        northValues[19]=5408715.20967;
        northValues[20]=5408515.20967;
        northValues[21]=5408565.20967;
        northValues[22]=5408615.20967;
        northValues[23]=5408665.20967;
        northValues[24]=5408715.20967;

        double heightValues[] = new double[25];
        heightValues[0]=3500.0;
        heightValues[1]=3500.0;
        heightValues[2]=3500.0;
        heightValues[3]=3500.0;
        heightValues[4]=3550.0;
        heightValues[5]=3550.0;
        heightValues[6]=3500.0;
        heightValues[7]=3500.0;
        heightValues[8]=3500.0;
        heightValues[9]=3500.0;
        heightValues[10]=3550.0;
        heightValues[11]=3500.0;
        heightValues[12]=3500.0;
        heightValues[13]=3500.0;
        heightValues[14]=3500.0;
        heightValues[15]=3500.0;
        heightValues[16]=3500.0;
        heightValues[17]=3500.0;
        heightValues[18]=3500.0;
        heightValues[19]=3500.0;
        heightValues[20]=3550.0;
        heightValues[21]=3500.0;
        heightValues[22]=3500.0;
        heightValues[23]=3500.0;
        heightValues[24]=3500.0;
        // Ende Daten Variante 25

        View v = navCanvas.getView();
        v.stopView();

        if(landscape != null) {
            landscape.setAppearanceGenerator(null);
            landscape.detach();
            landscape = null;
        }
        
        System.gc();
        
        System.out.println("Loading terrain file. Please wait");
        
        TerrainData terrain = null;       

        // Datenzuweisung Variante 25 5*5
        // funkt
        float data[][] = new float[5][5];
        for (int i=0;i<5;i++) {
            data[i][0]=(float) heightValues[i*2];
            data[i][1]=(float) heightValues[(i*2)+1];
            data[i][2]=(float) heightValues[(i*2)+2];
            data[i][3]=(float) heightValues[(i*2)+3];
            data[i][4]=(float) heightValues[(i*2)+4];
        }

        System.out.println("data.length "+data.length);
        for (int j=0;j<data.length;j++) {
            for (int k=0;k<data[0].length;k++) {
                System.out.println("data["+j+"]["+k+"] "+data[j][k]);
            }
        }
        
        // Keine Kopie anfertigen
        boolean mustCopy = false;
        
        // 50m in x und y Richtung
        Point2d stepDetails = new Point2d(50,50);
        
        SimpleTiledTerrainData simpleTerrain = new 
SimpleTiledTerrainData(data,mustCopy,stepDetails);
        terrain = simpleTerrain;
                
        System.out.println("Building landscape");
        
        // SplitMergeLandscape implementiert eigentlichen
        // ROAM Algorithmus
        
        landscape = new SplitMergeLandscape(viewFrustum, terrain);

        Point3d p3dmin = new Point3d();
        Point3d p3dmax = new Point3d();
        //viewFrustum.getBounds(p3dmin,p3dmax);
        //System.out.println("p3dmin "+p3dmin+" p3dmax "+p3dmax);

        landscape.setCapability(BranchGroup.ALLOW_DETACH);
        landscape.setAppearanceGenerator(this);
        
        float[] origin = new float[3];
        terrain.getCoordinate(origin, 1, 1);
        System.out.println("origin[] "+origin[0]+" "+origin[1]+" "+origin[2]);
        
        Transform3D angle = new Transform3D();
        
        // Anfangsposition des View definieren, funkt fuer crater aber
        // nicht fuer alien
        
        // setup the top view by just raising it some amount and we want
        Vector3f pos = new Vector3f();
        pos.x = origin[0];
        pos.y = origin[1];
        pos.z = origin[2]+100;
        //pos.z += 5000;
        //pos.x = origin[0];
        //pos.y = origin[2];
        angle.setTranslation(pos);
        gndViewTransform.setTransform(angle);

        // Force a single render so that the view transform is updated
        // and the projection matrix is correct for the view frustum.
        v.renderOnce();
        
        //viewFrustum.getBounds(p3dmin,p3dmax);
        //System.out.println("0! p3dmin "+p3dmin+" p3dmax "+p3dmax);
        viewFrustum.viewingPlatformMoved();
        //viewFrustum.getBounds(p3dmin,p3dmax);
        //System.out.println("1! p3dmin "+p3dmin+" p3dmax "+p3dmax);
        
        Matrix3f mtx = new Matrix3f();
        Vector3f orient = new Vector3f(0, 0, -1);
        
        angle.get(mtx, pos);
        mtx.transform(orient);
        
        //System.out.println("pos "+pos);
        //System.out.println("orient "+orient);
        landscape.initialize(pos, orient);

        //viewFrustum.getBounds(p3dmin,p3dmax);
        //System.out.println("2! p3dmin "+p3dmin+" p3dmax "+p3dmax);
        
        groundNav.setFrameUpdateListener(landscape);
        
        terrainGroup.removeAllChildren();
        terrainGroup.addChild(landscape);

        //viewFrustum.getBounds(p3dmin,p3dmax);
        //System.out.println("3! p3dmin "+p3dmin+" p3dmax "+p3dmax);
        
        // Set the nav speed to be one grid square per second
        groundNav.setNavigationSpeed((float)terrain.getGridXStep());
        
        
        v.startView();
            
        System.out.println("Ready for rendering");      
    }

    public static void main(String[] argv)
    {
        RoamTest3 demo = new RoamTest3();
        demo.setSize(600, 400);
        demo.setVisible(true);
    }
}
/*****************************************************************************
 *                        J3D.org Copyright (c) 2000
 *                               Java Source
 *
 * This source is licensed under the GNU LGPL v2.1
 * Please read http://www.gnu.org/copyleft/lgpl.html for more information
 *
 * This software comes with the standard NO WARRANTY disclaimer for any
 * purpose. Use it at your own risk. If there's a problem you get to fix it.
 *
 ****************************************************************************/

// Standard imports
import java.awt.*;
import java.awt.event.*;

import javax.media.j3d.Canvas3D;
import javax.media.j3d.GraphicsConfigTemplate3D;

// Application Specific imports
// none

/**
 * Demonstration of a mouse navigation in a world.
 *
 * @author Justin Couch
 * @version $Revision: 1.1 $
 */
public class DemoFrameDesTest extends Frame implements WindowListener
{
    public DemoFrameDesTest(String title)
    {
        super(title);

        setLocation(30, 10);
        addWindowListener(this);
    }

    /**
     * Creates a new canvas each time this is called.
     *
     * @return A new canvas instance
     */
    protected Canvas3D createCanvas()
    {
        Canvas3D canvas;

        GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
        template.setDoubleBuffer(template.REQUIRED);
        GraphicsEnvironment env =
            GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice dev = env.getDefaultScreenDevice();
        //System.out.println("env "+env.toString());
        //System.out.println("dev "+dev.toString());
        //System.out.println("template "+template.toString());

        canvas = new Canvas3D(dev.getBestConfiguration(template));
        canvas.setStereoEnable(false);
        canvas.setDoubleBufferEnable(true);
        //canvas.setDoubleBufferEnable(false);

        System.out.println("Canvas "+canvas);
        return canvas;
    }

    /**
     * Ignored
     */
    public void windowActivated(WindowEvent evt)
    {
    }

    /**
     * Ignored
     */
    public void windowClosed(WindowEvent evt)
    {
    }

    /**
     * Exit the application
     *
     * @param evt The event that caused this method to be called.
     */
    public void windowClosing(WindowEvent evt)
    {
        System.exit(0);
    }

    /**
     * Ignored
     */
    public void windowDeactivated(WindowEvent evt)
    {
    }

    /**
     * Ignored
     */
    public void windowDeiconified(WindowEvent evt)
    {
    }

    /**
     * Ignored
     */
    public void windowIconified(WindowEvent evt)
    {
    }

    /**
     * Ignored
     */
    public void windowOpened(WindowEvent evt)
    {
    }
}

Reply via email to