Search in sources :

Example 1 with Matrix4f

use of com.jme3.math.Matrix4f 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 Matrix4f

use of com.jme3.math.Matrix4f 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 Matrix4f

use of com.jme3.math.Matrix4f in project jmonkeyengine by jMonkeyEngine.

the class GeometryBatchFactory method mergeGeometries.

/**
     * Merges all geometries in the collection into
     * the output mesh. Creates a new material using the TextureAtlas.
     * 
     * @param geometries
     * @param outMesh
     */
public static void mergeGeometries(Collection<Geometry> geometries, Mesh outMesh) {
    int[] compsForBuf = new int[VertexBuffer.Type.values().length];
    Format[] formatForBuf = new Format[compsForBuf.length];
    boolean[] normForBuf = new boolean[VertexBuffer.Type.values().length];
    int totalVerts = 0;
    int totalTris = 0;
    int totalLodLevels = 0;
    int maxWeights = -1;
    Mode mode = null;
    for (Geometry geom : geometries) {
        totalVerts += geom.getVertexCount();
        totalTris += geom.getTriangleCount();
        totalLodLevels = Math.min(totalLodLevels, geom.getMesh().getNumLodLevels());
        Mode listMode;
        int components;
        switch(geom.getMesh().getMode()) {
            case Points:
                listMode = Mode.Points;
                components = 0;
                break;
            case LineLoop:
            case LineStrip:
            case Lines:
                listMode = Mode.Lines;
                components = 2;
                break;
            case TriangleFan:
            case TriangleStrip:
            case Triangles:
                listMode = Mode.Triangles;
                components = 3;
                break;
            default:
                throw new UnsupportedOperationException();
        }
        for (VertexBuffer vb : geom.getMesh().getBufferList().getArray()) {
            int currentCompsForBuf = compsForBuf[vb.getBufferType().ordinal()];
            if (vb.getBufferType() != Type.Index && currentCompsForBuf != 0 && currentCompsForBuf != vb.getNumComponents()) {
                throw new UnsupportedOperationException("The geometry " + geom + " buffer " + vb.getBufferType() + " has different number of components than the rest of the meshes " + "(this: " + vb.getNumComponents() + ", expected: " + currentCompsForBuf + ")");
            }
            compsForBuf[vb.getBufferType().ordinal()] = vb.getNumComponents();
            formatForBuf[vb.getBufferType().ordinal()] = vb.getFormat();
            normForBuf[vb.getBufferType().ordinal()] = vb.isNormalized();
        }
        maxWeights = Math.max(maxWeights, geom.getMesh().getMaxNumWeights());
        if (mode != null && mode != listMode) {
            throw new UnsupportedOperationException("Cannot combine different" + " primitive types: " + mode + " != " + listMode);
        }
        mode = listMode;
        compsForBuf[Type.Index.ordinal()] = components;
    }
    outMesh.setMaxNumWeights(maxWeights);
    outMesh.setMode(mode);
    if (totalVerts >= 65536) {
        // make sure we create an UnsignedInt buffer so
        // we can fit all of the meshes
        formatForBuf[Type.Index.ordinal()] = Format.UnsignedInt;
    } else {
        formatForBuf[Type.Index.ordinal()] = Format.UnsignedShort;
    }
    // generate output buffers based on retrieved info
    for (int i = 0; i < compsForBuf.length; i++) {
        if (compsForBuf[i] == 0) {
            continue;
        }
        Buffer data;
        if (i == Type.Index.ordinal()) {
            data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalTris);
        } else {
            data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalVerts);
        }
        VertexBuffer vb = new VertexBuffer(Type.values()[i]);
        vb.setupData(Usage.Static, compsForBuf[i], formatForBuf[i], data);
        vb.setNormalized(normForBuf[i]);
        outMesh.setBuffer(vb);
    }
    int globalVertIndex = 0;
    int globalTriIndex = 0;
    for (Geometry geom : geometries) {
        Mesh inMesh = geom.getMesh();
        geom.computeWorldMatrix();
        Matrix4f worldMatrix = geom.getWorldMatrix();
        int geomVertCount = inMesh.getVertexCount();
        int geomTriCount = inMesh.getTriangleCount();
        for (int bufType = 0; bufType < compsForBuf.length; bufType++) {
            VertexBuffer inBuf = inMesh.getBuffer(Type.values()[bufType]);
            VertexBuffer outBuf = outMesh.getBuffer(Type.values()[bufType]);
            if (inBuf == null || outBuf == null) {
                continue;
            }
            if (Type.Index.ordinal() == bufType) {
                int components = compsForBuf[bufType];
                IndexBuffer inIdx = inMesh.getIndicesAsList();
                IndexBuffer outIdx = outMesh.getIndexBuffer();
                for (int tri = 0; tri < geomTriCount; tri++) {
                    for (int comp = 0; comp < components; comp++) {
                        int idx = inIdx.get(tri * components + comp) + globalVertIndex;
                        outIdx.put((globalTriIndex + tri) * components + comp, idx);
                    }
                }
            } else if (Type.Position.ordinal() == bufType) {
                FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
                FloatBuffer outPos = (FloatBuffer) outBuf.getData();
                doTransformVerts(inPos, globalVertIndex, outPos, worldMatrix);
            } else if (Type.Normal.ordinal() == bufType) {
                FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
                FloatBuffer outPos = (FloatBuffer) outBuf.getData();
                doTransformNorms(inPos, globalVertIndex, outPos, worldMatrix);
            } else if (Type.Tangent.ordinal() == bufType) {
                FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
                FloatBuffer outPos = (FloatBuffer) outBuf.getData();
                int components = inBuf.getNumComponents();
                doTransformTangents(inPos, globalVertIndex, components, outPos, worldMatrix);
            } else {
                inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount);
            }
        }
        globalVertIndex += geomVertCount;
        globalTriIndex += geomTriCount;
    }
}
Also used : FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IntBuffer(java.nio.IntBuffer) Buffer(java.nio.Buffer) Mode(com.jme3.scene.Mesh.Mode) FloatBuffer(java.nio.FloatBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) Matrix4f(com.jme3.math.Matrix4f) Format(com.jme3.scene.VertexBuffer.Format)

Example 4 with Matrix4f

use of com.jme3.math.Matrix4f in project jmonkeyengine by jMonkeyEngine.

the class FbxBindPose method fromElement.

@Override
public void fromElement(FbxElement element) {
    super.fromElement(element);
    for (FbxElement child : element.children) {
        if (!child.id.equals("PoseNode")) {
            continue;
        }
        FbxId node = null;
        float[] matData = null;
        for (FbxElement e : child.children) {
            if (e.id.equals("Node")) {
                node = FbxId.create(e.properties.get(0));
            } else if (e.id.equals("Matrix")) {
                double[] matDataDoubles = (double[]) e.properties.get(0);
                if (matDataDoubles.length != 16) {
                    // corrupt
                    throw new UnsupportedOperationException("Bind pose matrix " + "must have 16 doubles, but it has " + matDataDoubles.length + ". Data is corrupt");
                }
                matData = new float[16];
                for (int i = 0; i < matDataDoubles.length; i++) {
                    matData[i] = (float) matDataDoubles[i];
                }
            }
        }
        if (node != null && matData != null) {
            Matrix4f matrix = new Matrix4f(matData);
            bindPose.put(node, matrix);
        }
    }
}
Also used : FbxElement(com.jme3.scene.plugins.fbx.file.FbxElement) Matrix4f(com.jme3.math.Matrix4f) FbxId(com.jme3.scene.plugins.fbx.file.FbxId)

Example 5 with Matrix4f

use of com.jme3.math.Matrix4f in project jmonkeyengine by jMonkeyEngine.

the class ObjectHelper method getTransformation.

/**
     * This method calculates local transformation for the object. Parentage is
     * taken under consideration.
     * 
     * @param objectStructure
     *            the object's structure
     * @return objects transformation relative to its parent
     */
public Transform getTransformation(Structure objectStructure, BlenderContext blenderContext) {
    TempVars tempVars = TempVars.get();
    Matrix4f parentInv = tempVars.tempMat4;
    Pointer pParent = (Pointer) objectStructure.getFieldValue("parent");
    if (pParent.isNotNull()) {
        Structure parentObjectStructure = (Structure) blenderContext.getLoadedFeature(pParent.getOldMemoryAddress(), LoadedDataType.STRUCTURE);
        this.getMatrix(parentObjectStructure, "obmat", fixUpAxis, parentInv).invertLocal();
    } else {
        parentInv.loadIdentity();
    }
    Matrix4f globalMatrix = this.getMatrix(objectStructure, "obmat", fixUpAxis, tempVars.tempMat42);
    Matrix4f localMatrix = parentInv.multLocal(globalMatrix);
    this.getSizeSignums(objectStructure, tempVars.vect1);
    localMatrix.toTranslationVector(tempVars.vect2);
    localMatrix.toRotationQuat(tempVars.quat1);
    localMatrix.toScaleVector(tempVars.vect3);
    Transform t = new Transform(tempVars.vect2, tempVars.quat1.normalizeLocal(), tempVars.vect3.multLocal(tempVars.vect1));
    tempVars.release();
    return t;
}
Also used : Matrix4f(com.jme3.math.Matrix4f) Pointer(com.jme3.scene.plugins.blender.file.Pointer) TempVars(com.jme3.util.TempVars) Structure(com.jme3.scene.plugins.blender.file.Structure) Transform(com.jme3.math.Transform)

Aggregations

Matrix4f (com.jme3.math.Matrix4f)36 TempVars (com.jme3.util.TempVars)24 Vector3f (com.jme3.math.Vector3f)15 FloatBuffer (java.nio.FloatBuffer)7 BoundingBox (com.jme3.bounding.BoundingBox)6 Transform (com.jme3.math.Transform)6 Bone (com.jme3.animation.Bone)4 CollisionResult (com.jme3.collision.CollisionResult)3 Spatial (com.jme3.scene.Spatial)3 BoundingVolume (com.jme3.bounding.BoundingVolume)2 Material (com.jme3.material.Material)2 Quaternion (com.jme3.math.Quaternion)2 Geometry (com.jme3.scene.Geometry)2 BoneContext (com.jme3.scene.plugins.blender.animations.BoneContext)2 Structure (com.jme3.scene.plugins.blender.file.Structure)2 FbxId (com.jme3.scene.plugins.fbx.file.FbxId)2 FrameBuffer (com.jme3.texture.FrameBuffer)2 Texture2D (com.jme3.texture.Texture2D)2 Picture (com.jme3.ui.Picture)2 ByteBuffer (java.nio.ByteBuffer)2