Ejemplo n.º 1
0
  /**
   * intersect checks for collisions between this collision tree and a provided Ray. Any collisions
   * are stored in a provided list as primitive index values. The ray is assumed to have a
   * normalized direction for accurate calculations.
   *
   * @param ray the ray to test for intersections.
   * @param store a list to fill with the index values of the primitive hit. if null, a new List is
   *     created.
   * @return the list.
   */
  public List<PrimitiveKey> intersect(final Ray3 ray, final List<PrimitiveKey> store) {
    List<PrimitiveKey> result = store;
    if (result == null) {
      result = new ArrayList<PrimitiveKey>();
    }

    // if our ray doesn't hit the bounds, then it must not hit a primitive.
    if (!_worldBounds.intersects(ray)) {
      return result;
    }

    // This is not a leaf node, therefore, check each child (left/right) for intersection with the
    // ray.
    if (_left != null) {
      _left._worldBounds =
          _left._bounds.transform(getMesh().getWorldTransform(), _left._worldBounds);
      _left.intersect(ray, result);
    }

    if (_right != null) {
      _right._worldBounds =
          _right._bounds.transform(getMesh().getWorldTransform(), _right._worldBounds);
      _right.intersect(ray, result);
    } else if (_left == null) {
      // This is a leaf node. We can therefore check each primitive this node contains. If an
      // intersection occurs,
      // place it in the list.

      final MeshData data = getMesh().getMeshData();
      final ReadOnlyTransform transform = getMesh().getWorldTransform();

      Vector3[] points = null;
      for (int i = _start; i < _end; i++) {
        points = data.getPrimitiveVertices(_primitiveIndices[i], _section, points);
        for (int t = 0; t < points.length; t++) {
          transform.applyForward(points[t]);
        }
        if (ray.intersects(points, null)) {
          result.add(new PrimitiveKey(_primitiveIndices[i], _section));
        }
      }
    }
    return result;
  }
Ejemplo n.º 2
0
  public static void findTrianglePick(
      final Mesh mesh, final Ray3 toTest, final List<PrimitiveKey> results) {
    if (mesh.getWorldBound() == null
        || !mesh.getSceneHints().isPickingHintEnabled(PickingHint.Pickable)) {
      return;
    }

    if (mesh.getWorldBound().intersects(toTest)) {
      final CollisionTree ct = CollisionTreeManager.getInstance().getCollisionTree(mesh);
      if (ct != null) {
        ct.getBounds().transform(mesh.getWorldTransform(), ct.getWorldBounds());
        ct.intersect(toTest, results);
      }
    }
  }
Ejemplo n.º 3
0
  /**
   * This function checks for intersection between this mesh and the given one. On the first
   * intersection, true is returned.
   *
   * @param toCheck The intersection testing mesh.
   * @return True if they intersect.
   */
  public static boolean hasTriangleCollision(final Mesh testMesh, final Mesh toCheck) {
    if (!testMesh.getSceneHints().isPickingHintEnabled(PickingHint.Collidable)
        || !toCheck.getSceneHints().isPickingHintEnabled(PickingHint.Collidable)) {
      return false;
    }

    final CollisionTree thisCT = CollisionTreeManager.getInstance().getCollisionTree(testMesh);
    final CollisionTree checkCT = CollisionTreeManager.getInstance().getCollisionTree(toCheck);

    if (thisCT == null || checkCT == null) {
      return false;
    }

    final ReadOnlyTransform worldTransform = testMesh.getWorldTransform();
    thisCT.getBounds().transform(worldTransform, thisCT.getWorldBounds());
    return thisCT.intersect(checkCT);
  }
Ejemplo n.º 4
0
  /**
   * This function finds all intersections between this mesh and the checking one. The intersections
   * are stored as Integer objects of Triangle indexes in each of the parameters.
   *
   * @param toCheck The Mesh to check.
   * @param testIndex The array of triangle indexes intersecting in this mesh.
   * @param otherIndex The array of triangle indexes intersecting in the given mesh.
   */
  public static void findPrimitiveCollision(
      final Mesh testMesh,
      final Mesh toCheck,
      final List<PrimitiveKey> testIndex,
      final List<PrimitiveKey> otherIndex) {
    if (!testMesh.getSceneHints().isPickingHintEnabled(PickingHint.Collidable)
        || !toCheck.getSceneHints().isPickingHintEnabled(PickingHint.Collidable)) {
      return;
    }

    final CollisionTree myTree = CollisionTreeManager.getInstance().getCollisionTree(testMesh);
    final CollisionTree otherTree = CollisionTreeManager.getInstance().getCollisionTree(toCheck);

    if (myTree == null || otherTree == null) {
      return;
    }

    myTree.getBounds().transform(testMesh.getWorldTransform(), myTree.getWorldBounds());

    myTree.intersect(otherTree, testIndex, otherIndex);
  }
Ejemplo n.º 5
0
  /**
   * Determines if this Collision Tree intersects the given CollisionTree. If a collision occurs,
   * true is returned, otherwise false is returned. If the provided collisionTree is invalid, false
   * is returned. All collisions that occur are stored in lists as an integer index into the mesh's
   * triangle buffer. where aList is the primitives for this mesh and bList is the primitives for
   * the test tree.
   *
   * @param collisionTree The Tree to test.
   * @param aList a list to contain the colliding primitives of this mesh.
   * @param bList a list to contain the colliding primitives of the testing mesh.
   * @return True if they intersect, false otherwise.
   */
  public boolean intersect(
      final CollisionTree collisionTree,
      final List<PrimitiveKey> aList,
      final List<PrimitiveKey> bList) {

    if (collisionTree == null) {
      return false;
    }

    collisionTree._worldBounds =
        collisionTree._bounds.transform(
            collisionTree.getMesh().getWorldTransform(), collisionTree._worldBounds);

    // our two collision bounds do not intersect, therefore, our primitives
    // must not intersect. Return false.
    if (!intersectsBounding(collisionTree._worldBounds)) {
      return false;
    }

    // if our node is not a leaf send the children (both left and right) to
    // the test tree.
    if (_left != null) { // This is not a leaf
      boolean test = collisionTree.intersect(_left, bList, aList);
      test = collisionTree.intersect(_right, bList, aList) || test;
      return test;
    }

    // This node is a leaf, but the testing tree node is not. Therefore,
    // continue processing the testing tree until we find its leaves.
    if (collisionTree._left != null) {
      boolean test = intersect(collisionTree._left, aList, bList);
      test = intersect(collisionTree._right, aList, bList) || test;
      return test;
    }

    // both this node and the testing node are leaves. Therefore, we can
    // switch to checking the contained primitives with each other. Any
    // that are found to intersect are placed in the appropriate list.
    final ReadOnlyTransform transformA = getMesh().getWorldTransform();
    final ReadOnlyTransform transformB = collisionTree.getMesh().getWorldTransform();

    final MeshData dataA = getMesh().getMeshData();
    final MeshData dataB = collisionTree.getMesh().getMeshData();

    Vector3[] storeA = null;
    Vector3[] storeB = null;

    boolean test = false;

    for (int i = _start; i < _end; i++) {
      storeA = dataA.getPrimitiveVertices(_primitiveIndices[i], _section, storeA);
      // to world space
      for (int t = 0; t < storeA.length; t++) {
        transformA.applyForward(storeA[t]);
      }
      for (int j = collisionTree._start; j < collisionTree._end; j++) {
        storeB =
            dataB.getPrimitiveVertices(
                collisionTree._primitiveIndices[j], collisionTree._section, storeB);
        // to world space
        for (int t = 0; t < storeB.length; t++) {
          transformB.applyForward(storeB[t]);
        }
        if (Intersection.intersection(storeA, storeB)) {
          test = true;
          aList.add(new PrimitiveKey(_primitiveIndices[i], _section));
          bList.add(new PrimitiveKey(collisionTree._primitiveIndices[j], collisionTree._section));
        }
      }
    }

    return test;
  }
Ejemplo n.º 6
0
  /**
   * Determines if this Collision Tree intersects the given CollisionTree. If a collision occurs,
   * true is returned, otherwise false is returned. If the provided collisionTree is invalid, false
   * is returned.
   *
   * @param collisionTree The Tree to test.
   * @return True if they intersect, false otherwise.
   */
  public boolean intersect(final CollisionTree collisionTree) {
    if (collisionTree == null) {
      return false;
    }

    collisionTree._worldBounds =
        collisionTree._bounds.transform(
            collisionTree.getMesh().getWorldTransform(), collisionTree._worldBounds);

    // our two collision bounds do not intersect, therefore, our primitives
    // must not intersect. Return false.
    if (!intersectsBounding(collisionTree._worldBounds)) {
      return false;
    }

    // check children
    if (_left != null) { // This is not a leaf
      if (collisionTree.intersect(_left)) {
        return true;
      }
      if (collisionTree.intersect(_right)) {
        return true;
      }
      return false;
    }

    // This is a leaf
    if (collisionTree._left != null) {
      // but collision isn't
      if (intersect(collisionTree._left)) {
        return true;
      }
      if (intersect(collisionTree._right)) {
        return true;
      }
      return false;
    }

    // both are leaves
    final ReadOnlyTransform transformA = getMesh().getWorldTransform();
    final ReadOnlyTransform transformB = collisionTree.getMesh().getWorldTransform();

    final MeshData dataA = getMesh().getMeshData();
    final MeshData dataB = collisionTree.getMesh().getMeshData();

    Vector3[] storeA = null;
    Vector3[] storeB = null;

    // for every primitive to compare, put them into world space and check for intersections
    for (int i = _start; i < _end; i++) {
      storeA = dataA.getPrimitiveVertices(_primitiveIndices[i], _section, storeA);
      // to world space
      for (int t = 0; t < storeA.length; t++) {
        transformA.applyForward(storeA[t]);
      }
      for (int j = collisionTree._start; j < collisionTree._end; j++) {
        storeB =
            dataB.getPrimitiveVertices(
                collisionTree._primitiveIndices[j], collisionTree._section, storeB);
        // to world space
        for (int t = 0; t < storeB.length; t++) {
          transformB.applyForward(storeB[t]);
        }
        if (Intersection.intersection(storeA, storeB)) {
          return true;
        }
      }
    }

    return false;
  }