⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 landscape.java

📁 java3D game engine design of the source [three-dimensionalvirtualrealitynetworkprogram] - "virtual
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

// Landscape.java
// Andrew Davison, August 2003, dandrew@ratree.psu.ac.th

/* Landscape loads a landscape made up of a mesh and a texture.
   If the user supplied the filename, fname, then Landscape looks
   in models/fname.obj for the mesh, and models/fname.jpg for the
   texture.

   The resulting BranchGroup, landBG, is added to the scene (sceneBG).

   The Landscape may contain two kinds of scenery:

     * full 3D shapes, loaded with PropManager.
       Intended for irregular objects which the user can move around,
       and perhaps enter (e.g. a castle).

     * ground cover, which are 2D images that rotate to always face
       the user. Intended for simple, symmetrical objects that
       'decorate' the scene, such as trees, bushes.

       Since many copies will be required, a SharedGroup node is
       used for each unique piece of ground cover.
       Ground cover is managed by a GroundCover object.

    The Landscape is surrounded by four walls which are covered
    in a mountain range image.
*/

import java.io.*;
import java.util.*;

import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.image.*;

import com.sun.j3d.loaders.objectfile.ObjectFile;
import com.sun.j3d.loaders.*;

import com.sun.j3d.utils.picking.*;



public class Landscape
{
  private static final double LAND_LEN = 60.0;  
           // length of landscape in world coordinates
  private static final String WALL_PIC = "models/mountain2Sq.jpg";
           // texture used for the four walls around the landscape

  private BranchGroup sceneBG;
  private BranchGroup landBG = null;   // holding the landscape parts
  private Shape3D landShape3D = null;  // holding the landscape mesh

  // various mesh dimensions, set in getLandDimensions()
  private double landLength, minHeight, maxHeight;
  private double scaleLen;

  private Vector3d originVec = null;   
       // where the user starts in the landscape (in world coordinates)


  public Landscape(BranchGroup sceneBG, String fname)
  {
    this.sceneBG = sceneBG;
    loadMesh(fname);        // initialize landBG
    getLandShape(landBG);   // initialize landShape3D

    // set the picking capabilities so that intersection
    // coords can be extracted after the shape is picked
    PickTool.setCapabilities(landShape3D, PickTool.INTERSECT_COORD);
 
    getLandDimensions(landShape3D);   // extracts sizes from landShape3D

    makeScenery(landBG, fname);   // add any scenery
    addWalls();                   // walls around the landscape

    GroundCover gc = new GroundCover(fname);
    landBG.addChild( gc.getCoverBG() );    // add any ground cover

    addLandtoScene(landBG);
    addLandTexture(landShape3D, fname);
  }  // end Landscape()



  private void loadMesh(String fname)
  /* Load the terrain mesh from models/fname.obj.
     We use Java 3D's OBJ loader. Then assign its BranchGroup to
     landBG.
  */
  {
    FileWriter ofw = null;
    String fn = new String("models/" + fname + ".obj");   // assume OBJ file in models/
    System.out.println( "Loading terrain mesh from: " + fn + " ..." );
    try {
      ObjectFile f = new ObjectFile();    // ObjectFile.STRIPIFY
      Scene loadedScene = f.load(fn);

      if(loadedScene == null ) {
        System.out.println("Scene not found in: " + fn);
        System.exit(0);
      }
 
      landBG = loadedScene.getSceneGroup();    // the land's BG
      if(landBG == null ) {
        System.out.println("No land branch group found");
        System.exit(0);
      }
    }
    catch( IOException ioe )
    { System.err.println("Terrain mesh load error: " + fn); 
      System.exit(0);
    }
  } // end of loadMesh()



  private void getLandShape(BranchGroup landBG)
  /* Check that landBG (the mesh's BranchGroup) contains a
     single Shape3D, and assign it to landShape3D for later.
     Also check that the shape holds a single GeometryArray.

     landShape3D is later used for picking, and its dimensions
     are extracted. 
  */
  {
    if (landBG.numChildren() > 1)
      System.out.println("More than one child in land branch group");

    Node node = landBG.getChild(0);
    if (!(node instanceof Shape3D)) {
      System.out.println("No Shape3D found in land branch group");
      System.exit(0);
    }
    landShape3D = (Shape3D) node;
  
    if (landShape3D == null) {
      System.out.println("Land Shape3D has no value");
      System.exit(0);
    }

    if (landShape3D.numGeometries() > 1)
      System.out.println("More than 1 geometry in land branch group");

    Geometry g = landShape3D.getGeometry();
    if (!(g instanceof GeometryArray)) {
      System.out.println("No Geometry Array found in land Shape3D");
      System.exit(0);
    }
  }  // end of getLandShape()



  private void getLandDimensions(Shape3D landShape3D)
  /* If we reach this point, then landShape3D contains a single
     GeometryArray of points representing the landscape's mesh.
     
     We can get the dimensions of the mesh by using a BoundingBox.

     Check if the XY plane is the 'floor' of the landscape, which
     is how the TerraGen mesh should have been exported. The X and
     Y lengths should be the same, and start at (0,0).

     Set the following vars:
       * landLength     // length of the X (and Y) side
       * scaleLen       // the scaling necessary to fit landLength
                        // into LAND_LEN units in the world
       * minHeight and maxHeight   // along the Z axis
  */
  {
    // get the bounds of the shape
    BoundingBox boundBox = new BoundingBox( landShape3D.getBounds() );
    Point3d lower = new Point3d();
    Point3d upper = new Point3d();
    boundBox.getLower(lower); boundBox.getUpper(upper);
    System.out.println("lower: " + lower + "\nupper: " + upper );

   if ((lower.y == 0) && (upper.x == upper.y)) {
     // System.out.println("XY being used as the floor");
   }
   else if ((lower.z == 0) && (upper.x == upper.z)) {
     System.out.println("Error: XZ set as the floor; change to XY in Terragen");
     System.exit(0);
   }
   else {
     System.out.println("Cannot determine floor axes");
     System.out.println("Y range should == X range, and start at 0");
     System.exit(0);
   }

   landLength = upper.x;
   scaleLen = LAND_LEN/landLength;
   System.out.println("scaleLen: " + scaleLen );
   minHeight = lower.z;  
   maxHeight = upper.z;
  }  // end of getLandDimensions()


  private void addLandtoScene(BranchGroup landBG)
  /* The floor of the landscape is the XY plane, starting at (0,0),
     with sides of landLength units.

     The landscape (landBG) is rotated to lie on the XZ plane, scaled
     to have floor sides of length LAND_LEN (scaleLen = LAND_LEN/landLength),
     then translated so that the center of the landscape is at (0,0).
  */
  {
     // rotate and scale land
     Transform3D t3d = new Transform3D();
     t3d.rotX( -Math.PI/2.0 );    // so land's XY is resting on the XZ plane
     t3d.setScale( new Vector3d(scaleLen, scaleLen, scaleLen) );  // scale
     TransformGroup sTG = new TransformGroup(t3d);
     sTG.addChild(landBG);

     // center the land, which starts at (0,0) on the XZ plane,
     // so move it left and forward
     Transform3D t3d1 = new Transform3D();
     t3d1.set( new Vector3d(-LAND_LEN/2, 0, LAND_LEN/2));  // translate
     TransformGroup posTG = new TransformGroup(t3d1);
     posTG.addChild( sTG ); 

     sceneBG.addChild(posTG);
  }  // end of addLandtoScene()



  // ----------------------- add texture to the land ------------------


  private void addLandTexture(Shape3D shape, String fname)
  /* The land texture (in models/fname.jpg) shows the landscape from
     above, and is used to colour the mesh loaded from the OBJ file.

     To save memory, the shape is one-sided.
     The texture is blended with a white material so that lighting 
     effects can be shown.
  */
  {  Appearance app = shape.getAppearance();

    // generate texture coords that 'stretch' the texture over the mesh
    app.setTexCoordGeneration( stampTexCoords(shape) );

    // combine texture with colour and lighting of underlying surface
    TextureAttributes ta = new TextureAttributes();
    ta.setTextureMode( TextureAttributes.MODULATE );
    app.setTextureAttributes( ta );

    // apply texture to shape
    Texture2D tex = loadLandTexture(fname);
    if (tex != null) {
      app.setTexture(tex);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -