示例#1
0
  /**
   * Adds a series of polygons by rotating the points list (ps) steps times, and colouring them as
   * defined by the color array (stripes!).
   */
  public void lathePolygons(float[][] ps, Color[] color, int steps) {
    float _ps[][] = new float[ps.length][3];
    float stepAngle = (float) Math.PI * 2 / steps; // the angle of each step in radians
    int currColor = 0;
    float m[][];

    for (int step = 0; step < steps; step++) {
      // translate each point to it next step round
      m = Tools3d.rotateAboutZ(stepAngle);
      for (int i = 0; i < ps.length; i++) {
        Tools3d.applyTo(m, ps[i], _ps[i]);
      }

      // build the polygons
      for (int point = 0; point < ps.length - 1; point++) {
        this.addPolygon(
            new float[][] {_ps[point], ps[point], ps[point + 1], _ps[point + 1]}, color[currColor]);
      }

      // copy the translated array to the starting array read for the next iteration
      for (int i = 0; i < ps.length; i++) {
        ps[i][0] = _ps[i][0];
        ps[i][1] = _ps[i][1];
        ps[i][2] = _ps[i][2];
      }

      currColor++;
      if (currColor == color.length) {
        currColor = 0;
      }
    }
  }
示例#2
0
  /**
   * Uses the camera to map all points from model space, (x, y, z) to screen space (x_, y_, z_).
   * Remember that x_ represents the depth of the point and (y_, z_) maps to the screen (x, y)
   * co-ords of the point.
   *
   * @see CameraMan
   */
  public void transform() {
    final float[] f = modelViewer.cameraMan.getFocus();
    final float[][] m = modelViewer.cameraMan.getMatrix();
    final float d = modelViewer.cameraMan.getDistance();
    float[] a = new float[3];

    visible = false; // set true if any points are visble to the camera
    for (int i = 0; i < npoints * 3; i += 3) {
      a[0] = ps[i] - f[0];
      a[1] = ps[i + 1] - f[1];
      a[2] = ps[i + 2] - f[2];
      Tools3d.applyTo(m, a, a);
      visibles[i / 3] = Tools3d.projectYZ(a, a, d);
      ps_[i] = a[0];

      if (visibles[i / 3]) {
        modelViewer.cameraMan.scaleToScreen(a);
        ps_[i + 1] = a[1];
        ps_[i + 2] = a[2];
        visible = true;
      }

      // depth bounding box
      if (i == 0) {
        x_min = x_max = ps_[i];
      } else {
        if (ps_[i] < x_min) x_min = ps_[i];
        if (ps_[i] > x_max) x_max = ps_[i];
      }
    }
  }
示例#3
0
  /** Dumps the data of this 3d shape. */
  public String toString() {
    StringBuffer sb = new StringBuffer();

    // number of polygons
    sb.append(polygons.length + "\n");

    // loop - one line per polygon
    for (int i = 0; i < polygons.length; i++) {
      Polygon po = polygons[i];

      // todo: tidy up shadows - what a mess !
      boolean shadow = false;
      for (int j = 0; j < MAX_SHADOWS; j++) {
        if (shadowCasters[j] == i) {
          shadow = true;
          break;
        }
      }
      sb.append(shadow ? "t " : "f ");

      sb.append(po.doubleSided ? "t " : "f ");

      int rgb = po.c.getRGB();
      sb.append("\"" + Integer.toHexString(rgb & 0xFFFFFF) + "\" ");

      // loop - points in this polygon
      for (int j = 0; j < po.n; j++) {
        int index = po.points[j];
        sb.append(
            Tools3d.round(ps[index])
                + " "
                + Tools3d.round(ps[index + 1])
                + " "
                + Tools3d.round(ps[index + 2])
                + ", ");
      }

      // finished this polygon so end line
      sb.append("\n");
    }
    return new String(sb);
  }
示例#4
0
    /**
     * Creates the unit normal to the polygon by taking the cross product of the first two edges.
     * Call with 'nsides' set to two if the polygon is visible from both sides.
     */
    void setNormal() {
      // We need three points to define two edges.
      if (n < 3) return;
      if (normal == null) normal = new float[3];

      float[] p0 = {ps[points[0]], ps[points[0] + 1], ps[points[0] + 2]};
      float[] p1 = {ps[points[1]], ps[points[1] + 1], ps[points[1] + 2]};
      float[] p2 = {ps[points[2]], ps[points[2] + 1], ps[points[2] + 2]};

      float[] e1 = new float[3];
      float[] e2 = new float[3];

      Tools3d.subtract(p1, p0, e1);
      Tools3d.subtract(p2, p1, e2);

      Tools3d.cross(e1, e2, normal);
      Tools3d.makeUnit(normal);

      dirtyNormal = false;
    }
示例#5
0
    /**
     * Decides if this polygon is a 'back face'. A back face is a polygon that is facing away from
     * the camera and therefore should not be drawn. If this polygon is double sided then it can not
     * be a back face. In such a case this routine has the side effect of ensuring that the normal
     * points towards the camera eye rather than away from it.
     *
     * @see Obj3d#draw(Graphics)
     */
    boolean isBackFace(final float[] eye) {

      if (dirtyNormal) {
        setNormal();
      }

      p[0] = ps[points[0]];
      p[1] = ps[points[0] + 1];
      p[2] = ps[points[0] + 2];

      Tools3d.subtract(p, eye, ray);

      if (doubleSided) {
        // flip the normal if necessary so this is NOT a backface
        if (Tools3d.dot(normal, ray) >= 0) {
          Tools3d.scaleBy(normal, -1);
        }
        return false;
      } else {
        return (Tools3d.dot(normal, ray) >= 0);
      }
    }