예제 #1
0
  /**
   * Calculates the minimum bounding sphere of 4 points. Used in welzl's algorithm.
   *
   * @param O The 1st point inside the sphere.
   * @param A The 2nd point inside the sphere.
   * @param B The 3rd point inside the sphere.
   * @param C The 4th point inside the sphere.
   * @see #calcWelzl(java.nio.FloatBuffer)
   */
  private void setSphere(final Vector3 O, final Vector3 A, final Vector3 B, final Vector3 C) {
    final Vector3 a = A.subtract(O, null);
    final Vector3 b = B.subtract(O, null);
    final Vector3 c = C.subtract(O, null);

    final double Denominator =
        2.0
            * (a.getX() * (b.getY() * c.getZ() - c.getY() * b.getZ())
                - b.getX() * (a.getY() * c.getZ() - c.getY() * a.getZ())
                + c.getX() * (a.getY() * b.getZ() - b.getY() * a.getZ()));
    if (Denominator == 0) {
      _center.set(0, 0, 0);
      setRadius(0);
    } else {
      final Vector3 o =
          a.cross(b, null)
              .multiplyLocal(c.lengthSquared())
              .addLocal(c.cross(a, null).multiplyLocal(b.lengthSquared()))
              .addLocal(b.cross(c, null).multiplyLocal(a.lengthSquared()))
              .divideLocal(Denominator);

      setRadius(o.length() * radiusEpsilon);
      O.add(o, _center);
    }
  }
예제 #2
0
  @Override
  public void startWalk(final Ray3 walkRay) {
    // store ray
    _walkRay.set(walkRay);

    // simplify access to direction
    final ReadOnlyVector3 direction = _walkRay.getDirection();

    // Move start point to grid space
    final Vector3 start = _walkRay.getOrigin().subtract(_gridOrigin, null);

    _gridLocation[0] = (int) MathUtils.floor(start.getX() / _gridSpacing.getX());
    _gridLocation[1] = (int) MathUtils.floor(start.getY() / _gridSpacing.getY());

    final double invDirX = 1.0 / direction.getX();
    final double invDirY = 1.0 / direction.getY();

    // Check which direction on the X world axis we are moving.
    if (direction.getX() > BresenhamZUpGridTracer.TOLERANCE) {
      _distToNextXIntersection =
          ((_gridLocation[0] + 1) * _gridSpacing.getX() - start.getX()) * invDirX;
      _distBetweenXIntersections = _gridSpacing.getX() * invDirX;
      _stepXDirection = 1;
    } else if (direction.getX() < -BresenhamZUpGridTracer.TOLERANCE) {
      _distToNextXIntersection =
          (start.getX() - _gridLocation[0] * _gridSpacing.getX()) * -direction.getX();
      _distBetweenXIntersections = -_gridSpacing.getX() * invDirX;
      _stepXDirection = -1;
    } else {
      _distToNextXIntersection = Double.MAX_VALUE;
      _distBetweenXIntersections = Double.MAX_VALUE;
      _stepXDirection = 0;
    }

    // Check which direction on the Y world axis we are moving.
    if (direction.getY() > BresenhamZUpGridTracer.TOLERANCE) {
      _distToNextYIntersection =
          ((_gridLocation[1] + 1) * _gridSpacing.getY() - start.getY()) * invDirY;
      _distBetweenYIntersections = _gridSpacing.getY() * invDirY;
      _stepYDirection = 1;
    } else if (direction.getY() < -BresenhamZUpGridTracer.TOLERANCE) {
      _distToNextYIntersection =
          (start.getY() - _gridLocation[1] * _gridSpacing.getY()) * -direction.getY();
      _distBetweenYIntersections = -_gridSpacing.getY() * invDirY;
      _stepYDirection = -1;
    } else {
      _distToNextYIntersection = Double.MAX_VALUE;
      _distBetweenYIntersections = Double.MAX_VALUE;
      _stepYDirection = 0;
    }

    // Reset some variables
    _rayLocation.set(start);
    _totalTravel = 0.0;
    _stepDirection = Direction.None;
  }
예제 #3
0
  @Override
  public void applyFilter(final InteractManager manager) {
    final SpatialState state = manager.getSpatialState();
    final ReadOnlyVector3 scale = state.getTransform().getScale();
    final double x = MathUtils.clamp(scale.getX(), _minScale.getX(), _maxScale.getX());
    final double y = MathUtils.clamp(scale.getY(), _minScale.getY(), _maxScale.getY());
    final double z = MathUtils.clamp(scale.getZ(), _minScale.getZ(), _maxScale.getZ());

    state.getTransform().setScale(x, y, z);
  }
예제 #4
0
 /**
  * Calculates the minimum bounding sphere of 2 points. Used in welzl's algorithm.
  *
  * @param O The 1st point inside the sphere.
  * @param A The 2nd point inside the sphere.
  * @see #calcWelzl(java.nio.FloatBuffer)
  */
 private void setSphere(final Vector3 O, final Vector3 A) {
   setRadius(
       Math.sqrt(
               ((A.getX() - O.getX()) * (A.getX() - O.getX())
                       + (A.getY() - O.getY()) * (A.getY() - O.getY())
                       + (A.getZ() - O.getZ()) * (A.getZ() - O.getZ()))
                   / 4f)
           + radiusEpsilon
           - 1);
   Vector3.lerp(O, A, .5, _center);
 }
예제 #5
0
  /** Defines the normals of each face of the pyramid. */
  protected void setNormalData() {

    Vector3 normal = new Vector3();
    Vector3 work = new Vector3();

    FloatBuffer norms = BufferUtils.createVector3Buffer(12);

    // side 1
    MathUtil.createNormal(normal, vert0, vert1, peak, work);
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());

    // side 2
    MathUtil.createNormal(normal, vert1, vert2, peak, work);
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());

    // side 3
    MathUtil.createNormal(normal, vert2, vert3, peak, work);
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());

    // side 4
    MathUtil.createNormal(normal, vert3, vert0, peak, work);
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());
    norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ());

    norms.rewind();
    sides.getMeshData().setNormalBuffer(norms);
  }
예제 #6
0
파일: Grid.java 프로젝트: nasa/DERT
 @Override
 public void setLocation(double x, double y, double z, boolean doEdit) {
   super.setLocation(x - offset.getX(), y - offset.getY(), z - offset.getZ(), doEdit);
 }
예제 #7
0
파일: Particle.java 프로젝트: krka/Ardor3D
  /**
   * Update the vertices for this particle, taking size, spin and viewer into consideration. In the
   * case of particle type ParticleType.GeomMesh, the original triangle normal is maintained rather
   * than rotating it to face the camera or parent vectors.
   *
   * @param cam Camera to use in determining viewer aspect. If null, or if parent is not set to
   *     camera facing, parent's left and up vectors are used.
   */
  public void updateVerts(final Camera cam) {
    final double orient = parent.getParticleOrientation() + values[VAL_CURRENT_SPIN];
    final double currSize = values[VAL_CURRENT_SIZE];

    if (type == ParticleSystem.ParticleType.GeomMesh
        || type == ParticleSystem.ParticleType.Point) {; // nothing to do
    } else if (cam != null && parent.isCameraFacing()) {
      final ReadOnlyVector3 camUp = cam.getUp();
      final ReadOnlyVector3 camLeft = cam.getLeft();
      final ReadOnlyVector3 camDir = cam.getDirection();
      if (parent.isVelocityAligned()) {
        bbX.set(_velocity).normalizeLocal().multiplyLocal(currSize);
        camDir.cross(bbX, bbY).normalizeLocal().multiplyLocal(currSize);
      } else if (orient == 0) {
        bbX.set(camLeft).multiplyLocal(currSize);
        bbY.set(camUp).multiplyLocal(currSize);
      } else {
        final double cA = MathUtils.cos(orient) * currSize;
        final double sA = MathUtils.sin(orient) * currSize;
        bbX.set(camLeft)
            .multiplyLocal(cA)
            .addLocal(camUp.getX() * sA, camUp.getY() * sA, camUp.getZ() * sA);
        bbY.set(camLeft)
            .multiplyLocal(-sA)
            .addLocal(camUp.getX() * cA, camUp.getY() * cA, camUp.getZ() * cA);
      }
    } else {
      bbX.set(parent.getLeftVector()).multiplyLocal(0);
      bbY.set(parent.getUpVector()).multiplyLocal(0);
    }

    final Vector3 tempVec3 = Vector3.fetchTempInstance();
    final FloatBuffer vertexBuffer = parent.getParticleGeometry().getMeshData().getVertexBuffer();
    switch (type) {
      case Quad:
        {
          _position.subtract(bbX, tempVec3).subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 0);

          _position.subtract(bbX, tempVec3).addLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1);

          _position.add(bbX, tempVec3).addLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 2);

          _position.add(bbX, tempVec3).subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 3);
          break;
        }
      case GeomMesh:
        {
          final Quaternion tempQuat = Quaternion.fetchTempInstance();
          final ReadOnlyVector3 norm = triModel.getNormal();
          if (orient != 0) {
            tempQuat.fromAngleNormalAxis(orient, norm);
          }

          for (int x = 0; x < 3; x++) {
            if (orient != 0) {
              tempQuat.apply(triModel.get(x), tempVec3);
            } else {
              tempVec3.set(triModel.get(x));
            }
            tempVec3.multiplyLocal(currSize).addLocal(_position);
            BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + x);
          }
          Quaternion.releaseTempInstance(tempQuat);
          break;
        }
      case Triangle:
        {
          _position
              .subtract(3 * bbX.getX(), 3 * bbX.getY(), 3 * bbX.getZ(), tempVec3)
              .subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 0);

          _position.add(bbX, tempVec3).addLocal(3 * bbY.getX(), 3 * bbY.getY(), 3 * bbY.getZ());
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1);

          _position.add(bbX, tempVec3).subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 2);
          break;
        }
      case Line:
        {
          _position.subtract(bbX, tempVec3);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex);

          _position.add(bbX, tempVec3);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1);
          break;
        }
      case Point:
        {
          BufferUtils.setInBuffer(_position, vertexBuffer, startIndex);
          break;
        }
    }
    Vector3.releaseTempInstance(tempVec3);
  }
예제 #8
0
  /**
   * Sets the vertices that make the pyramid. Where the center of the box is the origin and the base
   * and height are set during construction.
   */
  protected void setVertexData() {
    peak = new Vector3(0, 0, 0);
    vert0 = new Vector3(-width / 2, -height / 2, -length);
    vert1 = new Vector3(width / 2, -height / 2, -length);
    vert2 = new Vector3(width / 2, height / 2, -length);
    vert3 = new Vector3(-width / 2, height / 2, -length);

    FloatBuffer verts = BufferUtils.createVector3Buffer(12);

    // side 1
    verts.put((float) vert0.getX()).put((float) vert0.getY()).put((float) vert0.getZ());
    verts.put((float) vert1.getX()).put((float) vert1.getY()).put((float) vert1.getZ());
    verts.put((float) peak.getX()).put((float) peak.getY()).put((float) peak.getZ());

    // side 2
    verts.put((float) vert1.getX()).put((float) vert1.getY()).put((float) vert1.getZ());
    verts.put((float) vert2.getX()).put((float) vert2.getY()).put((float) vert2.getZ());
    verts.put((float) peak.getX()).put((float) peak.getY()).put((float) peak.getZ());

    // side 3
    verts.put((float) vert2.getX()).put((float) vert2.getY()).put((float) vert2.getZ());
    verts.put((float) vert3.getX()).put((float) vert3.getY()).put((float) vert3.getZ());
    verts.put((float) peak.getX()).put((float) peak.getY()).put((float) peak.getZ());

    // side 4
    verts.put((float) vert3.getX()).put((float) vert3.getY()).put((float) vert3.getZ());
    verts.put((float) vert0.getX()).put((float) vert0.getY()).put((float) vert0.getZ());
    verts.put((float) peak.getX()).put((float) peak.getY()).put((float) peak.getZ());

    verts.rewind();
    sides.getMeshData().setVertexBuffer(verts);
  }