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

📄 propmanager.java

📁 java 3D
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

// PropManager.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th

/* The user supplies the name of a 3D object file to be loaded.
   Its bounding sphere is automatically scaled to have a radius 
   of 1 unit, and rotated -90 around x-axis if it is a 3ds model.

   A large range of different 3D object formats can be loaded
   since we are using the Portfolio loaders.

   Once loaded, the image can be moved and rotated along the
   X, Y, and Z axes, and scaled. The resulting position, 
   rotation, and scaling information can be stored in a 
   'coords' file (which has the same name as the 3D file
   + "Coords.txt").

   The rotation information is stored as a series of rotation
   *numbers* which must be executed in order to get to the curent
   overall rotation:
      1 = positive ROT_INCR around x-axis
      2 = negative ROT_INCR around x-axis

      3 = positive ROT_INCR around y-axis
      4 = negative ROT_INCR around y-axis

      5 = positive ROT_INCR around z-axis
      6 = negative ROT_INCR around z-axis

   This approach is used to try to avoid the problem that a mix of
   rotations about diffrent axes do not produce the same result if
   carried out in different orders.

   The coordinates information can be loaded along with the object
   by using:
		java Loader3D -c <3D filename>

   The loaded object is hung off several TGs, and the top one can be
   accessed by calling getTG().

   Changes:
   - removed use of j3d-fly VRML loader and starfire 3DS loader
*/

import java.util.*;
import java.io.*;
import java.text.DecimalFormat;

import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.loaders.*;

// Portfolio loader packages
import ncsa.j3d.*;
import ncsa.j3d.loaders.*;


public class PropManager
{
  // for specifying moves and rotations
  private static final int X_AXIS = 0;
  private static final int Y_AXIS = 1;
  private static final int Z_AXIS = 2;
  private static final int INCR = 0;
  private static final int DECR = 1;

  private static final double MOVE_INCR = 0.1;   // move increment for an object
  private static final double ROT_INCR = 10;     // rotation increment (in degrees)
  private static final double ROT_AMT = Math.toRadians(ROT_INCR);    // in radians


  // TGs which the loaded object (the prop) hangs off: 
  //       moveTG-->rotTG-->scaleTG-->objBoundsTG-->obj
  private TransformGroup moveTG, rotTG, scaleTG;    
  private Transform3D t3d;           // for accessing a TG's transform
  private Transform3D chgT3d;        // holds current change to the posn, rot, or scale

  private String filename;           // of loaded object
  private double xRot, yRot, zRot;   // total of rotation angles carried out
  private ArrayList rotInfo;         // stores the sequence of rotation numbers 
  private double scale;              // current object scaling

  private DecimalFormat df;    // for debugging


  public PropManager(String loadFnm, boolean hasCoordsInfo)
  {
    filename = loadFnm;
    xRot = 0.0; yRot = 0.0; zRot = 0.0;    // initial loaded object settings
    rotInfo = new ArrayList();
    scale = 1.0;

    t3d = new Transform3D();     // setup reusable Transform3D objects
    chgT3d = new Transform3D();

    df = new DecimalFormat("0.###");  // 3 dp

    loadFile(loadFnm);
    if (hasCoordsInfo)     // load in coords info also
      getFileCoords(loadFnm);
  }  // end of PropManager()



  private void loadFile(String fnm)
  /* The 3D object file is loaded using a Portfolio loader.

     The loaded object has 4 transform groups above it -- objBoundsTG is
     for adjusting the object's bounded sphere so it is centered at
     (0,0,0) and has unit radius. 

     The other TGs are for doing separate moves, rotations, and scaling
     of the object.
        moveTG-->rotTG-->scaleTG-->objBoundsTG-->object
  */
  { System.out.println("Loading object file: models/" + fnm);

	Scene s = null;
    ModelLoader modelLoader = new ModelLoader();
	try {
	  s = modelLoader.load("models/"+fnm);   // handles many types of file
	}
	catch (Exception e) {
	  System.err.println(e);
	  System.exit(1);
	}

    // get the branch group for the loaded object
    BranchGroup sceneGroup = s.getSceneGroup();

    // create a transform group for the object's bounding sphere
    TransformGroup objBoundsTG = new TransformGroup();
    objBoundsTG.addChild( sceneGroup );

    // resize loaded object's bounding sphere (and maybe rotate)
    String ext = getExtension(fnm);
    BoundingSphere objBounds = (BoundingSphere) sceneGroup.getBounds();
    setBSPosn(objBoundsTG, objBounds.getRadius(), ext);

    // create a transform group for scaling the object
    scaleTG = new TransformGroup();
    scaleTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    scaleTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    scaleTG.addChild( objBoundsTG );

    // create a transform group for rotating the object
    rotTG = new TransformGroup();
    rotTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    rotTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    rotTG.addChild( scaleTG );

    // create a transform group for moving the object
    moveTG = new TransformGroup();
    moveTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    moveTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    moveTG.addChild( rotTG );

  } // end of loadFile()


  private String getExtension(String fnm)
  // return the extension of fnm, or "(none)"
  {
    int dotposn = fnm.lastIndexOf(".");
    if (dotposn == -1)  // no extension
      return "(none)";
    else
      return fnm.substring(dotposn+1).toLowerCase();
  }


  private void setBSPosn(TransformGroup objBoundsTG, 
					double radius, String ext)
  // Scale the object to unit radius, and rotate -90 around x-axis if the
  // file contains a 3ds model
  {
    Transform3D objectTrans = new Transform3D();
    objBoundsTG.getTransform( objectTrans );

    // System.out.println("radius: " + df.format(radius));

    // scale the object so its bounds are within a 1 unit radius sphere
    Transform3D scaleTrans = new Transform3D();
    double scaleFactor = 1.0/radius;
    // System.out.println("scaleFactor: " + df.format(scaleFactor) );
    scaleTrans.setScale( scaleFactor );

    // final transform = [original] * [scale] (and possible *[rotate])
    objectTrans.mul(scaleTrans);
    
    if (ext.equals("3ds")) {   // the file is a 3ds model
      // System.out.println("Rotating -90 around x-axis");
      Transform3D rotTrans = new Transform3D();
      rotTrans.rotX( -Math.PI/2.0 );    // 3ds models are often on their face; fix that
      objectTrans.mul(rotTrans);
    }

    objBoundsTG.setTransform(objectTrans);
  } // end of setBSPosn()


  public TransformGroup getTG()
  // used by WrapLoader3D to add object to 3D world
  {  return moveTG; }


  // ----------------------------------------------------------------
  // obtain coords file info and apply it to the loaded object


  private void getFileCoords(String fnm)
  /* Obtain coords info from the coordinates file for fnm.
     The coords file has the format:
         <3D object fnm>
         [-p px py pz]
         [-r sequence of numbers]
         [-s scale]
  */
  { 
    String coordFile = "models/" + getName(fnm) + "Coords.txt";
    try {
      BufferedReader br = new BufferedReader( new FileReader(coordFile));
      br.readLine();    // skip fnm line (we know this already)
      String line;
      char ch;
      while((line = br.readLine()) != null) {
        ch = line.charAt(1);
        if (ch == 'p')
          setCurrentPosn(line);
        else if (ch == 'r')
          setCurrentRotation(line);
        else if (ch == 's')
          setCurrentScale(line);
        else
          System.out.println(coordFile + ": did not recognise line: " + line);
      }
      br.close();
      System.out.println("Read in coords file: " + coordFile);
    } 
    catch (IOException e) 
    { System.out.println("Error reading coords file: " + coordFile);
      System.exit(1);
    }
  }  // end of getFileCoords()



  private String getName(String fnm)
  // extract name before the final '.' suffix
  {
    int dotposn = fnm.lastIndexOf(".");
    if (dotposn == -1)  // no extension
      return fnm;
    else
      return fnm.substring(0, dotposn);
  }


  private void setCurrentPosn(String line)
  // extract the (x,y,z) position info from the coords file,
  // then apply it to the loaded object
  {
    double vals[] = new double[3];            // for the position data
    vals[0] = 0; vals[1] = 0; vals[2] = 0;    // represents (x,y,z)

    StringTokenizer tokens = new StringTokenizer(line);
    String token = tokens.nextToken();    // skip command label
    int count = 0;
    while (tokens.hasMoreTokens()) {
      token = tokens.nextToken();
      try {
        vals[count] = Double.parseDouble(token);
        count++;
      }
      catch (NumberFormatException ex){ 
        System.out.println("Incorrect format for position data in coords file"); 
        break;
      }

⌨️ 快捷键说明

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