Search in sources :

Example 21 with Edge

use of com.jme3.scene.plugins.blender.meshes.Edge in project jmonkeyengine by jMonkeyEngine.

the class LodGenerator method computeEdgeCollapseCost.

float computeEdgeCollapseCost(Vertex src, Edge dstEdge) {
    // This is based on Ogre's collapse cost calculation algorithm.
    Vertex dest = dstEdge.destination;
    // then this would destroy the shape, so don't do this
    if (src.triangles.size() == 1 && dest.triangles.size() == 1) {
        return NEVER_COLLAPSE_COST;
    }
    // Look for a face normal changing by > 90 degrees
    for (Triangle triangle : src.triangles) {
        // Ignore the deleted faces (those including src & dest)
        if (!triangle.hasVertex(dest)) {
            // Test the new face normal
            Vertex pv0, pv1, pv2;
            // Replace src with dest wherever it is
            pv0 = (triangle.vertex[0] == src) ? dest : triangle.vertex[0];
            pv1 = (triangle.vertex[1] == src) ? dest : triangle.vertex[1];
            pv2 = (triangle.vertex[2] == src) ? dest : triangle.vertex[2];
            // Cross-product 2 edges
            tmpV1.set(pv1.position).subtractLocal(pv0.position);
            tmpV2.set(pv2.position).subtractLocal(pv1.position);
            //computing the normal
            Vector3f newNormal = tmpV1.crossLocal(tmpV2);
            newNormal.normalizeLocal();
            // If < 0 then more than 90 degree difference
            if (newNormal.dot(triangle.normal) < 0.0f) {
                // Don't do it!
                return NEVER_COLLAPSE_COST;
            }
        }
    }
    float cost;
    // If we're looking at a border vertex
    if (isBorderVertex(src)) {
        if (dstEdge.refCount > 1) {
            // src is on a border, but the src-dest edge has more than one tri on it
            // So it must be collapsing inwards
            // Mark as very high-value cost
            // curvature = 1.0f;
            cost = 1.0f;
        } else {
            // Collapsing ALONG a border
            // We can't use curvature to measure the effect on the model
            // Instead, see what effect it has on 'pulling' the other border edges
            // The more colinear, the less effect it will have
            // So measure the 'kinkiness' (for want of a better term)
            // Find the only triangle using this edge.
            // PMTriangle* triangle = findSideTriangle(src, dst);
            cost = 0.0f;
            Vector3f collapseEdge = tmpV1.set(src.position).subtractLocal(dest.position);
            collapseEdge.normalizeLocal();
            for (Edge edge : src.edges) {
                Vertex neighbor = edge.destination;
                //reference check intended
                if (neighbor != dest && edge.refCount == 1) {
                    Vector3f otherBorderEdge = tmpV2.set(src.position).subtractLocal(neighbor.position);
                    otherBorderEdge.normalizeLocal();
                    // This time, the nearer the dot is to -1, the better, because that means
                    // the edges are opposite each other, therefore less kinkiness
                    // Scale into [0..1]
                    float kinkiness = (otherBorderEdge.dot(collapseEdge) + 1.002f) * 0.5f;
                    cost = Math.max(cost, kinkiness);
                }
            }
        }
    } else {
        // not a border
        // Standard inner vertex
        // Calculate curvature
        // use the triangle facing most away from the sides
        // to determine our curvature term
        // Iterate over src's faces again
        cost = 0.001f;
        for (Triangle triangle : src.triangles) {
            // curve for face i and closer side to it
            float mincurv = 1.0f;
            for (Triangle triangle2 : src.triangles) {
                if (triangle2.hasVertex(dest)) {
                    // Dot product of face normal gives a good delta angle
                    float dotprod = triangle.normal.dot(triangle2.normal);
                    // NB we do (1-..) to invert curvature where 1 is high curvature [0..1]
                    // Whilst dot product is high when angle difference is low
                    mincurv = Math.min(mincurv, (1.002f - dotprod) * 0.5f);
                }
            }
            cost = Math.max(cost, mincurv);
        }
    }
    // check for texture seam ripping
    if (src.isSeam) {
        if (!dest.isSeam) {
            cost += meshBoundingSphereRadius;
        } else {
            cost += meshBoundingSphereRadius * 0.5;
        }
    }
    return cost * src.position.distanceSquared(dest.position);
}
Also used : Vector3f(com.jme3.math.Vector3f)

Example 22 with Edge

use of com.jme3.scene.plugins.blender.meshes.Edge in project jmonkeyengine by jMonkeyEngine.

the class BoundingCollisionTest method testBoxBoxCollision.

@Test
public void testBoxBoxCollision() {
    BoundingBox box1 = new BoundingBox(Vector3f.ZERO, 1, 1, 1);
    BoundingBox box2 = new BoundingBox(Vector3f.ZERO, 1, 1, 1);
    checkCollision(box1, box2, 1);
    // Put it at the very edge - should still intersect.
    box2.setCenter(new Vector3f(2f, 0f, 0f));
    checkCollision(box1, box2, 1);
    // Put it a wee bit farther - no intersection expected
    box2.setCenter(new Vector3f(2f + FastMath.ZERO_TOLERANCE, 0, 0));
    checkCollision(box1, box2, 0);
    // Check the corners.
    box2.setCenter(new Vector3f(2f, 2f, 2f));
    checkCollision(box1, box2, 1);
    box2.setCenter(new Vector3f(2f, 2f, 2f + FastMath.ZERO_TOLERANCE));
    checkCollision(box1, box2, 0);
}
Also used : BoundingBox(com.jme3.bounding.BoundingBox) Vector3f(com.jme3.math.Vector3f) Test(org.junit.Test)

Example 23 with Edge

use of com.jme3.scene.plugins.blender.meshes.Edge in project jmonkeyengine by jMonkeyEngine.

the class LightFilterTest method testPointFiltering.

@Test
public void testPointFiltering() {
    PointLight pl = new PointLight(Vector3f.ZERO);
    geom.addLight(pl);
    // Infinite point lights must never be filtered
    checkFilteredLights(1);
    // Light at origin does not intersect geom which is at Z=10
    pl.setRadius(1);
    checkFilteredLights(0);
    // Put it closer to geom, the very edge of the sphere touches the box.
    // Still not considered an intersection though.
    pl.setPosition(new Vector3f(0, 0, 8f));
    checkFilteredLights(0);
    // And more close - now its an intersection.
    pl.setPosition(new Vector3f(0, 0, 8f + FastMath.ZERO_TOLERANCE));
    checkFilteredLights(1);
    // Move the geometry away
    geom.move(0, 0, FastMath.ZERO_TOLERANCE);
    checkFilteredLights(0);
    // Test if the algorithm converts the sphere 
    // to a box before testing the collision (incorrect)
    float sqrt3 = FastMath.sqrt(3);
    pl.setPosition(new Vector3f(2, 2, 8));
    pl.setRadius(sqrt3);
    checkFilteredLights(0);
    // Make it a wee bit larger.
    pl.setRadius(sqrt3 + FastMath.ZERO_TOLERANCE);
    checkFilteredLights(1);
    // Rotate the camera so it is up, light is outside frustum.
    cam.lookAtDirection(Vector3f.UNIT_Y, Vector3f.UNIT_Y);
    checkFilteredLights(0);
    // ==================================
    // Tests for bounding Sphere
    geom.setModelBound(new BoundingSphere(1f, Vector3f.ZERO));
    geom.setLocalTranslation(0, 0, 2);
    pl.setPosition(new Vector3f(0, 0, 2f));
    // Infinite point lights must never be filtered
    pl.setRadius(0);
    checkFilteredLights(1);
    pl.setRadius(1f);
    // Put the light at the very close to the geom,
    // the very edge of the sphere touches the other bounding sphere
    // Still not considered an intersection though.
    pl.setPosition(new Vector3f(0, 0, 0));
    checkFilteredLights(0);
    // And more close - now its an intersection.
    pl.setPosition(new Vector3f(0, 0, 0f + FastMath.ZERO_TOLERANCE));
    checkFilteredLights(1);
    geom.setLocalTranslation(0, 0, 0);
    // In this case its an intersection for pointLight v. box
    // But not for pointLight v. sphere
    // Vector3f(0, 0.5f, 0.5f).normalize().mult(2) ~ >= (0.0, 1.4142135, 1.4142135)
    //pl.setPosition(new Vector3f(0, 0.5f, 0.5f).normalizeLocal().multLocal(2 + FastMath.ZERO_TOLERANCE));
    pl.setPosition(new Vector3f(0f, 1.4142135f, 1.4142135f).multLocal(1 + FastMath.ZERO_TOLERANCE));
    checkFilteredLights(0);
    // Make the distance a wee bit closer, now its an intersection
    //pl.setPosition(new Vector3f(0, 0.5f, 0.5f).normalizeLocal().multLocal(2 - FastMath.ZERO_TOLERANCE));
    pl.setPosition(new Vector3f(0f, 1.4142135f, 1.4142135f).multLocal(1 - FastMath.ZERO_TOLERANCE));
    checkFilteredLights(1);
    // it's a point light, also test for the other corner
    pl.setPosition(new Vector3f(0f, -1.4142135f, -1.4142135f).multLocal(1 - FastMath.ZERO_TOLERANCE));
    checkFilteredLights(0);
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) Vector3f(com.jme3.math.Vector3f) Test(org.junit.Test)

Example 24 with Edge

use of com.jme3.scene.plugins.blender.meshes.Edge in project jmonkeyengine by jMonkeyEngine.

the class BoundingSphere method merge.

//    /**
//     * Merges this sphere with the given OBB.
//     *
//     * @param volume
//     *            The OBB to merge.
//     * @return This sphere, after merging.
//     */
//    private BoundingSphere mergeOBB(OrientedBoundingBox volume) {
//        // compute edge points from the obb
//        if (!volume.correctCorners)
//            volume.computeCorners();
//        _mergeBuf.rewind();
//        for (int i = 0; i < 8; i++) {
//            _mergeBuf.put(volume.vectorStore[i].x);
//            _mergeBuf.put(volume.vectorStore[i].y);
//            _mergeBuf.put(volume.vectorStore[i].z);
//        }
//
//        // remember old radius and center
//        float oldRadius = radius;
//        Vector3f oldCenter = _compVect2.set( center );
//
//        // compute new radius and center from obb points
//        computeFromPoints(_mergeBuf);
//        Vector3f newCenter = _compVect3.set( center );
//        float newRadius = radius;
//
//        // restore old center and radius
//        center.set( oldCenter );
//        radius = oldRadius;
//
//        //merge obb points result
//        merge( newRadius, newCenter, this );
//
//        return this;
//    }
private BoundingVolume merge(float temp_radius, Vector3f temp_center, BoundingSphere rVal) {
    TempVars vars = TempVars.get();
    Vector3f diff = temp_center.subtract(center, vars.vect1);
    float lengthSquared = diff.lengthSquared();
    float radiusDiff = temp_radius - radius;
    float fRDiffSqr = radiusDiff * radiusDiff;
    if (fRDiffSqr >= lengthSquared) {
        if (radiusDiff <= 0.0f) {
            vars.release();
            return this;
        }
        Vector3f rCenter = rVal.center;
        if (rCenter == null) {
            rVal.setCenter(rCenter = new Vector3f());
        }
        rCenter.set(temp_center);
        rVal.setRadius(temp_radius);
        vars.release();
        return rVal;
    }
    float length = (float) Math.sqrt(lengthSquared);
    Vector3f rCenter = rVal.center;
    if (rCenter == null) {
        rVal.setCenter(rCenter = new Vector3f());
    }
    if (length > RADIUS_EPSILON) {
        float coeff = (length + radiusDiff) / (2.0f * length);
        rCenter.set(center.addLocal(diff.multLocal(coeff)));
    } else {
        rCenter.set(center);
    }
    rVal.setRadius(0.5f * (length + radius + temp_radius));
    vars.release();
    return rVal;
}
Also used : TempVars(com.jme3.util.TempVars)

Aggregations

Vector3f (com.jme3.math.Vector3f)17 ArrayList (java.util.ArrayList)7 Edge (com.jme3.scene.plugins.blender.meshes.Edge)5 Face (com.jme3.scene.plugins.blender.meshes.Face)5 Test (org.junit.Test)5 BoundingBox (com.jme3.bounding.BoundingBox)3 BoundingSphere (com.jme3.bounding.BoundingSphere)3 Structure (com.jme3.scene.plugins.blender.file.Structure)3 TempVars (com.jme3.util.TempVars)3 Node (com.jme3.scene.Node)2 BlenderFileException (com.jme3.scene.plugins.blender.file.BlenderFileException)2 Pointer (com.jme3.scene.plugins.blender.file.Pointer)2 HashSet (java.util.HashSet)2 LinkedHashSet (java.util.LinkedHashSet)2 List (java.util.List)2 CollisionResult (com.jme3.collision.CollisionResult)1 DirectionalLight (com.jme3.light.DirectionalLight)1 PointLight (com.jme3.light.PointLight)1 SpotLight (com.jme3.light.SpotLight)1 Plane (com.jme3.math.Plane)1