dommstyle.txt

来自「Simple DOOM style navigation of a 3D sce」· 文本 代码 · 共 1,957 行 · 第 1/4 页

TXT
1,957
字号
  private void moveLeft() {
    doMove(new Vector3d(-getMovementRate(), 0.0, 0.0));
  }

  private void moveRight() {
    doMove(new Vector3d(getMovementRate(), 0.0, 0.0));
  }

  private void moveUp() {
    doMove(new Vector3d(0.0, getMovementRate(), 0.0));
  }

  private void moveDown() {
    doMove(new Vector3d(0.0, -getMovementRate(), 0.0));
  }

  protected void rotRight() {
    doRotateY(getRotateRightAmount());
  }

  protected void rotUp() {
    doRotateX(getRotateUpAmount());
  }

  protected void rotLeft() {
    doRotateY(getRotateLeftAmount());
  }

  protected void rotDown() {
    doRotateX(getRotateDownAmount());
  }

  protected void rollLeft() {
    doRotateZ(getRollLeftAmount());
  }

  protected void rollRight() {
    doRotateZ(getRollRightAmount());
  }

  protected void updateTransform() {
    transformGroup.setTransform(transform3D);
  }

  protected void doRotateY(double radians) {
    transformGroup.getTransform(transform3D);
    Transform3D toMove = new Transform3D();
    toMove.rotY(radians);
    transform3D.mul(toMove);
    updateTransform();
  }

  protected void doRotateX(double radians) {
    transformGroup.getTransform(transform3D);
    Transform3D toMove = new Transform3D();
    toMove.rotX(radians);
    transform3D.mul(toMove);
    updateTransform();
  }

  protected void doRotateZ(double radians) {
    transformGroup.getTransform(transform3D);
    Transform3D toMove = new Transform3D();
    toMove.rotZ(radians);
    transform3D.mul(toMove);
    updateTransform();
  }

  protected void doMove(Vector3d theMove) {
    transformGroup.getTransform(transform3D);
    Transform3D toMove = new Transform3D();
    toMove.setTranslation(theMove);
    transform3D.mul(toMove);
    updateTransform();
  }

  protected double getMovementRate() {
    return moveRate * speed;
  }

  protected double getRollLeftAmount() {
    return rotateZAmount * speed;
  }

  protected double getRollRightAmount() {
    return -rotateZAmount * speed;
  }

  protected double getRotateUpAmount() {
    return rotateYAmount * speed;
  }

  protected double getRotateDownAmount() {
    return -rotateYAmount * speed;
  }

  protected double getRotateLeftAmount() {
    return rotateYAmount * speed;
  }

  protected double getRotateRightAmount() {
    return -rotateYAmount * speed;
  }

  public void setRotateXAmount(double radians) {
    rotateXAmount = radians;
  }

  public void setRotateYAmount(double radians) {
    rotateYAmount = radians;
  }

  public void setRotateZAmount(double radians) {
    rotateZAmount = radians;
  }

  public void setMovementRate(double meters) {
    moveRate = meters; // Travel rate in meters/frame
  }

  public void setForwardKey(int key) {
    forwardKey = key;
  }

  public void setBackKey(int key) {
    backKey = key;
  }

  public void setLeftKey(int key) {
    leftKey = key;
  }
}

//creates a 2x2x2 cuboid with its base at y=0

class Cuboid extends ComplexObject {
  public Cuboid(Component comp, Group g, int nFlags) {
    super(comp, g, nFlags);
  }

  protected Group createGeometryGroup(Appearance app, Vector3d position,
      Vector3d scale, String szTextureFile, String szSoundFile) {
    int nFlags = GeometryArray.COORDINATES | GeometryArray.NORMALS;

    if ((m_nFlags & TEXTURE) == TEXTURE)
      nFlags |= GeometryArray.TEXTURE_COORDINATE_2;

    QuadArray quadArray = new QuadArray(24, nFlags);

    quadArray.setCoordinates(0, verts, 0, 24);

    for (int n = 0; n < 24; n++)
      quadArray.setNormal(n, normals[n / 4]);

    if ((m_nFlags & TEXTURE) == TEXTURE) {
      quadArray.setTextureCoordinates(0, 0, tcoords, 0, 24);
      setTexture(app, szTextureFile);
    }

    Shape3D shape = new Shape3D(quadArray, app);

    BranchGroup bg = new BranchGroup();
    bg.addChild(shape);
    return bg;
  }

  private static final float[] verts = {
  // front face
      1.0f, 0.0f, 1.0f, 1.0f, 2.0f, 1.0f, -1.0f, 2.0f, 1.0f, -1.0f, 0.0f,
      1.0f,
      // back face
      -1.0f, 0.0f, -1.0f, -1.0f, 2.0f, -1.0f, 1.0f, 2.0f, -1.0f, 1.0f,
      0.0f, -1.0f,
      // right face
      1.0f, 0.0f, -1.0f, 1.0f, 2.0f, -1.0f, 1.0f, 2.0f, 1.0f, 1.0f, 0.0f,
      1.0f,
      // left face
      -1.0f, 0.0f, 1.0f, -1.0f, 2.0f, 1.0f, -1.0f, 2.0f, -1.0f, -1.0f,
      0.0f, -1.0f,
      // top face
      1.0f, 2.0f, 1.0f, 1.0f, 2.0f, -1.0f, -1.0f, 2.0f, -1.0f, -1.0f,
      2.0f, 1.0f,
      // bottom face
      -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f,
      0.0f, 1.0f, };

  private static final float[] tcoords = {
  // front
      1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
      // back
      1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
      //right
      1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
      // left
      1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
      // top
      1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
      // bottom
      0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f };

  private static final Vector3f[] normals = { new Vector3f(0.0f, 0.0f, 1.0f), // front
      // face
      new Vector3f(0.0f, 0.0f, -1.0f), // back face
      new Vector3f(1.0f, 0.0f, 0.0f), // right face
      new Vector3f(-1.0f, 0.0f, 0.0f), // left face
      new Vector3f(0.0f, 1.0f, 0.0f), // top face
      new Vector3f(0.0f, -1.0f, 0.0f), // bottom face
  };
}

//*****************************************************************************
/**
 * Utils
 * 
 * @author Daniel Selman
 * @version 1.0
 */
//*****************************************************************************

class Utils {
  // convert an angular rotation about an axis to a Quaternion
  static Quat4f createQuaternionFromAxisAndAngle(Vector3d axis, double angle) {
    double sin_a = Math.sin(angle / 2);
    double cos_a = Math.cos(angle / 2);

    // use a vector so we can call normalize
    Vector4f q = new Vector4f();

    q.x = (float) (axis.x * sin_a);
    q.y = (float) (axis.y * sin_a);
    q.z = (float) (axis.z * sin_a);
    q.w = (float) cos_a;

    // It is necessary to normalise the quaternion
    // in case any values are very close to zero.
    q.normalize();

    // convert to a Quat4f and return
    return new Quat4f(q);
  }

  // convert three rotations about the Euler axes to a Quaternion
  static Quat4f createQuaternionFromEuler(double angleX, double angleY,
      double angleZ) {
    // simply call createQuaternionFromAxisAndAngle
    // for each axis and multiply the results
    Quat4f qx = createQuaternionFromAxisAndAngle(new Vector3d(1, 0, 0),
        angleX);
    Quat4f qy = createQuaternionFromAxisAndAngle(new Vector3d(0, 1, 0),
        angleY);
    Quat4f qz = createQuaternionFromAxisAndAngle(new Vector3d(0, 0, 1),
        angleZ);

    // qx = qx * qy
    qx.mul(qy);

    // qx = qx * qz
    qx.mul(qz);

    return qx;
  }

  static public double getRandomNumber(double basis, double random) {
    return basis + ((float) Math.random() * random * 2f) - (random);
  }

  static public double getRandomNumber(double basis, double random,
      double scale) {
    double value = basis + ((float) Math.random() * random * 2f) - (random);
    return value * scale;
  }

  static public StringBuffer readFile(URL urlFile) {
    /*   allocate a temporary buffer to store the input file*/
    StringBuffer szBufferData = new StringBuffer();
    Vector keyFramesVector = new Vector();

    try {
      InputStream inputStream = urlFile.openStream();

      int nChar = 0;

      // read the entire file into the StringBuffer
      while (true) {
        nChar = inputStream.read();

        /* if we have not hit the end of file
         add the character to the StringBuffer
*/
        if (nChar != -1)
          szBufferData.append((char) nChar);
        else
          // EOF
          break;
      }

      inputStream.close();
    } catch (Exception e) {
      System.err.println(e.toString());
      return null;
    }

    return szBufferData;
  }

  static public RotPosScaleTCBSplinePathInterpolator createSplinePathInterpolator(
      Alpha alpha, TransformGroup tg, Transform3D axis, URL urlKeyframes) {
    TCBKeyFrame[] keyFrames = readKeyFrames(urlKeyframes);

    if (keyFrames != null)
      return new RotPosScaleTCBSplinePathInterpolator(alpha, tg, axis,
          keyFrames);

    return null;
  }

  static public TCBKeyFrame[] readKeyFrames(URL urlKeyframes) {
    StringBuffer szBufferData = readFile(urlKeyframes);

    if (szBufferData == null)
      return null;

    Vector keyFramesVector = new Vector();

    // create a tokenizer to tokenize the input file at whitespace
    java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(
        szBufferData.toString());

    // each keyframe is defined as follows
    // - knot (0 >= k <= 1)
    // - position (x,y,z)
    // - rotation (rx,ry,rz)
    // - scale (x,y,z)

    // - tension (-1 >= t <= 1)
    // - continuity (-1 >= c <= 1)
    // - bias (-1 >= b <= 1)
    // - linear (int - 0 or 1)

    while (true) {
      try {
        float knot = Float.parseFloat(tokenizer.nextToken());

        float posX = Float.parseFloat(tokenizer.nextToken());
        float posY = Float.parseFloat(tokenizer.nextToken());
        float posZ = Float.parseFloat(tokenizer.nextToken());

        float rotX = Float.parseFloat(tokenizer.nextToken());
        float rotY = Float.parseFloat(tokenizer.nextToken());
        float rotZ = Float.parseFloat(tokenizer.nextToken());

        float scaleX = Float.parseFloat(tokenizer.nextToken());
        float scaleY = Float.parseFloat(tokenizer.nextToken());
        float scaleZ = Float.parseFloat(tokenizer.nextToken());

        float tension = Float.parseFloat(tokenizer.nextToken());
        float continuity = Float.parseFloat(tokenizer.nextToken());
        float bias = Float.parseFloat(tokenizer.nextToken());

        int linear = Integer.parseInt(tokenizer.nextToken());

        TCBKeyFrame keyframe = new TCBKeyFrame(knot, linear,
            new Point3f(posX, posY, posZ),
            createQuaternionFromEuler(rotX, rotY, rotZ),
            new Point3f(scaleX, scaleY, scaleZ), tension,
            continuity, bias);

        keyFramesVector.add(keyframe);
      } catch (Exception e) {
        break;
      }
    }

    // create the return structure and populate
    TCBKeyFrame[] keysReturn = new TCBKeyFrame[keyFramesVector.size()];

    for (int n = 0; n < keysReturn.length; n++)
      keysReturn[n] = (TCBKeyFrame) keyFramesVector.get(n);

    // return the array
    return keysReturn;
  }
}

class Land extends ComplexObject {
  public static final float WIDTH = 1.0f;

  public static final float LENGTH = 1.0f;

  public static final float HEIGHT = 0.0f;

  public Land(Component comp, Group g, int nFlags) {
    super(comp, g, nFlags);
  }

  protected Group createGeometryGroup(Appearance app, Vector3d position,
      Vector3d scale, String szTextureFile, String szSoundFile) {
    int nFlags = GeometryArray.COORDINATES | GeometryArray.NORMALS;

    if ((m_nFlags & TEXTURE) == TEXTURE)
      nFlags |= GeometryArray.TEXTURE_COORDINATE_2;

    QuadArray quadArray = new QuadArray(4, nFlags);

    float[] coordArray = { -WIDTH, HEIGHT, LENGTH, WIDTH, HEIGHT, LENGTH,
        WIDTH, HEIGHT, -LENGTH, -WIDTH, HEIGHT, -LENGTH };

    quadArray.setCoordinates(0, coordArray, 0, coordArray.length / 3);

    for (int n = 0; n < coordArray.length / 3; n++)
      quadArray.setNormal(n, new Vector3f(0, 1, 0));

    if ((m_nFlags & TEXTURE) == TEXTURE) {
      float[] texArray = { 0, 0, 1, 0, 1, 1, 0, 1 };

      quadArray.setTextureCoordinates(0, 0, texArray, 0,
          coordArray.length / 3);
      setTexture(app, szTextureFile);
    }

    BranchGroup bg = new BranchGroup();
    Shape3D shape = new Shape3D(quadArray, app);
    bg.addChild(shape);

    return bg;
  }
}

/**
 * This class is a simple behavior that invokes the KeyNavigator to modify the
 * view platform transform.
 */

class CollisionBehavior extends Behavior {
  private WakeupOnCollisionEntry wakeupOne = null;

  private WakeupOnCollisionExit wakeupTwo = null;

  private WakeupCriterion[] wakeupArray = new WakeupCriterion[2];

  private WakeupCondition wakeupCondition = null;

  private ComplexObject m_Owner = null;

  public CollisionBehavior(Node node, ComplexObject owner) {
    wakeupOne = new WakeupOnCollisionEntry(node,
        WakeupOnCollisionEntry.USE_GEOMETRY);
    wakeupTwo = new WakeupOnCollisionExit(node,
        WakeupOnCollisionExit.USE_GEOMETRY);

    wakeupArray[0] = wakeupOne;
    wakeupArray[1] = wakeupTwo;

    wakeupCondition = new WakeupOr(wakeupArray);

    m_Owner = owner;
  }

  /**
   * Override Behavior's initialize method to setup wakeup criteria.
   */
  public void initialize() {
    // Establish initial wakeup criteria
    wakeupOn(wakeupCondition);
  }

  /**
   * Override Behavior's stimulus method to handle the event.
   */
  public void processStimulus(Enumeration criteria) {
    WakeupCriterion genericEvt;

    while (criteria.hasMoreElements()) {
      genericEvt = (WakeupCriterion) criteria.nextElement();

      if (genericEvt instanceof WakeupOnCollisionEntry) {
        m_Owner.onCollide(true);
      } else if (genericEvt instanceof WakeupOnCollisionExit) {
        m_Owner.onCollide(false);
      }
    }

    // Set wakeup criteria for next time
    wakeupOn(wakeupCondition);
  }
}

⌨️ 快捷键说明

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