Search in sources :

Example 1 with BIHTree

use of com.jme3.collision.bih.BIHTree in project jmonkeyengine by jMonkeyEngine.

the class BIHNode method intersectWhere.

public final int intersectWhere(Ray r, Matrix4f worldMatrix, BIHTree tree, float sceneMin, float sceneMax, CollisionResults results) {
    TempVars vars = TempVars.get();
    ArrayList<BIHStackData> stack = vars.bihStack;
    stack.clear();
    //        float tHit = Float.POSITIVE_INFINITY;
    Vector3f o = vars.vect1.set(r.getOrigin());
    Vector3f d = vars.vect2.set(r.getDirection());
    Matrix4f inv = vars.tempMat4.set(worldMatrix).invertLocal();
    inv.mult(r.getOrigin(), r.getOrigin());
    // Fixes rotation collision bug
    inv.multNormal(r.getDirection(), r.getDirection());
    //        inv.multNormalAcross(r.getDirection(), r.getDirection());
    float[] origins = { r.getOrigin().x, r.getOrigin().y, r.getOrigin().z };
    float[] invDirections = { 1f / r.getDirection().x, 1f / r.getDirection().y, 1f / r.getDirection().z };
    r.getDirection().normalizeLocal();
    Vector3f v1 = vars.vect3, v2 = vars.vect4, v3 = vars.vect5;
    int cols = 0;
    stack.add(new BIHStackData(this, sceneMin, sceneMax));
    stackloop: while (stack.size() > 0) {
        BIHStackData data = stack.remove(stack.size() - 1);
        BIHNode node = data.node;
        float tMin = data.min, tMax = data.max;
        if (tMax < tMin) {
            continue;
        }
        leafloop: while (node.axis != 3) {
            // while node is not a leaf
            int a = node.axis;
            // find the origin and direction value for the given axis
            float origin = origins[a];
            float invDirection = invDirections[a];
            float tNearSplit, tFarSplit;
            BIHNode nearNode, farNode;
            tNearSplit = (node.leftPlane - origin) * invDirection;
            tFarSplit = (node.rightPlane - origin) * invDirection;
            nearNode = node.left;
            farNode = node.right;
            if (invDirection < 0) {
                float tmpSplit = tNearSplit;
                tNearSplit = tFarSplit;
                tFarSplit = tmpSplit;
                BIHNode tmpNode = nearNode;
                nearNode = farNode;
                farNode = tmpNode;
            }
            if (tMin > tNearSplit && tMax < tFarSplit) {
                continue stackloop;
            }
            if (tMin > tNearSplit) {
                tMin = max(tMin, tFarSplit);
                node = farNode;
            } else if (tMax < tFarSplit) {
                tMax = min(tMax, tNearSplit);
                node = nearNode;
            } else {
                stack.add(new BIHStackData(farNode, max(tMin, tFarSplit), tMax));
                tMax = min(tMax, tNearSplit);
                node = nearNode;
            }
        }
        // a leaf
        for (int i = node.leftIndex; i <= node.rightIndex; i++) {
            tree.getTriangle(i, v1, v2, v3);
            float t = r.intersects(v1, v2, v3);
            if (!Float.isInfinite(t)) {
                if (worldMatrix != null) {
                    worldMatrix.mult(v1, v1);
                    worldMatrix.mult(v2, v2);
                    worldMatrix.mult(v3, v3);
                    float t_world = new Ray(o, d).intersects(v1, v2, v3);
                    t = t_world;
                }
                Vector3f contactNormal = Triangle.computeTriangleNormal(v1, v2, v3, null);
                Vector3f contactPoint = new Vector3f(d).multLocal(t).addLocal(o);
                float worldSpaceDist = o.distance(contactPoint);
                CollisionResult cr = new CollisionResult(contactPoint, worldSpaceDist);
                cr.setContactNormal(contactNormal);
                cr.setTriangleIndex(tree.getTriangleIndex(i));
                results.addCollision(cr);
                cols++;
            }
        }
    }
    vars.release();
    r.setOrigin(o);
    r.setDirection(d);
    return cols;
}
Also used : CollisionResult(com.jme3.collision.CollisionResult) Matrix4f(com.jme3.math.Matrix4f) Vector3f(com.jme3.math.Vector3f) TempVars(com.jme3.util.TempVars) Ray(com.jme3.math.Ray)

Example 2 with BIHTree

use of com.jme3.collision.bih.BIHTree in project jmonkeyengine by jMonkeyEngine.

the class BIHNode method intersectBrute.

public final int intersectBrute(Ray r, Matrix4f worldMatrix, BIHTree tree, float sceneMin, float sceneMax, CollisionResults results) {
    float tHit = Float.POSITIVE_INFINITY;
    TempVars vars = TempVars.get();
    Vector3f v1 = vars.vect1, v2 = vars.vect2, v3 = vars.vect3;
    int cols = 0;
    ArrayList<BIHStackData> stack = vars.bihStack;
    stack.clear();
    stack.add(new BIHStackData(this, 0, 0));
    stackloop: while (stack.size() > 0) {
        BIHStackData data = stack.remove(stack.size() - 1);
        BIHNode node = data.node;
        leafloop: while (node.axis != 3) {
            // while node is not a leaf
            BIHNode nearNode, farNode;
            nearNode = node.left;
            farNode = node.right;
            stack.add(new BIHStackData(farNode, 0, 0));
            node = nearNode;
        }
        // a leaf
        for (int i = node.leftIndex; i <= node.rightIndex; i++) {
            tree.getTriangle(i, v1, v2, v3);
            if (worldMatrix != null) {
                worldMatrix.mult(v1, v1);
                worldMatrix.mult(v2, v2);
                worldMatrix.mult(v3, v3);
            }
            float t = r.intersects(v1, v2, v3);
            if (t < tHit) {
                tHit = t;
                Vector3f contactPoint = new Vector3f(r.direction).multLocal(tHit).addLocal(r.origin);
                CollisionResult cr = new CollisionResult(contactPoint, tHit);
                cr.setTriangleIndex(tree.getTriangleIndex(i));
                results.addCollision(cr);
                cols++;
            }
        }
    }
    vars.release();
    return cols;
}
Also used : CollisionResult(com.jme3.collision.CollisionResult) Vector3f(com.jme3.math.Vector3f) TempVars(com.jme3.util.TempVars)

Example 3 with BIHTree

use of com.jme3.collision.bih.BIHTree in project jmonkeyengine by jMonkeyEngine.

the class Mesh method createCollisionData.

/**
     * Generates a collision tree for the mesh.
     * Called automatically by {@link #collideWith(com.jme3.collision.Collidable,
     * com.jme3.math.Matrix4f,
     * com.jme3.bounding.BoundingVolume,
     * com.jme3.collision.CollisionResults) }.
     */
public void createCollisionData() {
    BIHTree tree = new BIHTree(this);
    tree.construct();
    collisionTree = tree;
}
Also used : BIHTree(com.jme3.collision.bih.BIHTree)

Example 4 with BIHTree

use of com.jme3.collision.bih.BIHTree in project jmonkeyengine by jMonkeyEngine.

the class BIHNode method intersectWhere.

public final int intersectWhere(Collidable col, BoundingBox box, Matrix4f worldMatrix, BIHTree tree, CollisionResults results) {
    TempVars vars = TempVars.get();
    ArrayList<BIHStackData> stack = vars.bihStack;
    stack.clear();
    float[] minExts = { box.getCenter().x - box.getXExtent(), box.getCenter().y - box.getYExtent(), box.getCenter().z - box.getZExtent() };
    float[] maxExts = { box.getCenter().x + box.getXExtent(), box.getCenter().y + box.getYExtent(), box.getCenter().z + box.getZExtent() };
    stack.add(new BIHStackData(this, 0, 0));
    Triangle t = new Triangle();
    int cols = 0;
    stackloop: while (stack.size() > 0) {
        BIHNode node = stack.remove(stack.size() - 1).node;
        while (node.axis != 3) {
            int a = node.axis;
            float maxExt = maxExts[a];
            float minExt = minExts[a];
            if (node.leftPlane < node.rightPlane) {
                // if the box is in that gap, we stop there
                if (minExt > node.leftPlane && maxExt < node.rightPlane) {
                    continue stackloop;
                }
            }
            if (maxExt < node.rightPlane) {
                node = node.left;
            } else if (minExt > node.leftPlane) {
                node = node.right;
            } else {
                stack.add(new BIHStackData(node.right, 0, 0));
                node = node.left;
            }
        //                if (maxExt < node.leftPlane
        //                 && maxExt < node.rightPlane){
        //                    node = node.left;
        //                }else if (minExt > node.leftPlane
        //                       && minExt > node.rightPlane){
        //                    node = node.right;
        //                }else{
        //                }
        }
        for (int i = node.leftIndex; i <= node.rightIndex; i++) {
            tree.getTriangle(i, t.get1(), t.get2(), t.get3());
            if (worldMatrix != null) {
                worldMatrix.mult(t.get1(), t.get1());
                worldMatrix.mult(t.get2(), t.get2());
                worldMatrix.mult(t.get3(), t.get3());
            }
            int added = col.collideWith(t, results);
            if (added > 0) {
                int index = tree.getTriangleIndex(i);
                int start = results.size() - added;
                for (int j = start; j < results.size(); j++) {
                    CollisionResult cr = results.getCollisionDirect(j);
                    cr.setTriangleIndex(index);
                }
                cols += added;
            }
        }
    }
    vars.release();
    return cols;
}
Also used : CollisionResult(com.jme3.collision.CollisionResult) Triangle(com.jme3.math.Triangle) TempVars(com.jme3.util.TempVars)

Aggregations

CollisionResult (com.jme3.collision.CollisionResult)3 TempVars (com.jme3.util.TempVars)3 Vector3f (com.jme3.math.Vector3f)2 BIHTree (com.jme3.collision.bih.BIHTree)1 Matrix4f (com.jme3.math.Matrix4f)1 Ray (com.jme3.math.Ray)1 Triangle (com.jme3.math.Triangle)1