Search in sources :

Example 76 with TempVars

use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.

the class SpatialTrack method setTime.

/**
     * 
     * Modify the spatial which this track modifies.
     * 
     * @param time
     *            the current time of the animation
     */
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
    Spatial spatial = control.getSpatial();
    Vector3f tempV = vars.vect1;
    Vector3f tempS = vars.vect2;
    Quaternion tempQ = vars.quat1;
    Vector3f tempV2 = vars.vect3;
    Vector3f tempS2 = vars.vect4;
    Quaternion tempQ2 = vars.quat2;
    int lastFrame = times.length - 1;
    if (time < 0 || lastFrame == 0) {
        if (rotations != null)
            rotations.get(0, tempQ);
        if (translations != null)
            translations.get(0, tempV);
        if (scales != null) {
            scales.get(0, tempS);
        }
    } else if (time >= times[lastFrame]) {
        if (rotations != null)
            rotations.get(lastFrame, tempQ);
        if (translations != null)
            translations.get(lastFrame, tempV);
        if (scales != null) {
            scales.get(lastFrame, tempS);
        }
    } else {
        int startFrame = 0;
        int endFrame = 1;
        // use lastFrame so we never overflow the array
        for (int i = 0; i < lastFrame && times[i] < time; ++i) {
            startFrame = i;
            endFrame = i + 1;
        }
        float blend = (time - times[startFrame]) / (times[endFrame] - times[startFrame]);
        if (rotations != null)
            rotations.get(startFrame, tempQ);
        if (translations != null)
            translations.get(startFrame, tempV);
        if (scales != null) {
            scales.get(startFrame, tempS);
        }
        if (rotations != null)
            rotations.get(endFrame, tempQ2);
        if (translations != null)
            translations.get(endFrame, tempV2);
        if (scales != null) {
            scales.get(endFrame, tempS2);
        }
        tempQ.nlerp(tempQ2, blend);
        tempV.interpolateLocal(tempV2, blend);
        tempS.interpolateLocal(tempS2, blend);
    }
    if (translations != null)
        spatial.setLocalTranslation(tempV);
    if (rotations != null)
        spatial.setLocalRotation(tempQ);
    if (scales != null) {
        spatial.setLocalScale(tempS);
    }
}
Also used : Spatial(com.jme3.scene.Spatial) Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f)

Example 77 with TempVars

use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.

the class ChaseCameraAppState method rotateCamera.

/**
     * rotate the camera around the target
     */
protected void rotateCamera() {
    verticalRotation = FastMath.clamp(verticalRotation, minVerticalRotation, maxVerticalRotation);
    TempVars vars = TempVars.get();
    Quaternion rot = vars.quat1;
    Quaternion rot2 = vars.quat2;
    rot.fromAngleNormalAxis(verticalRotation, leftVector);
    rot2.fromAngleNormalAxis(horizontalRotation, upVector);
    rot2.multLocal(rot);
    target.setLocalRotation(rot2);
    vars.release();
}
Also used : Quaternion(com.jme3.math.Quaternion) TempVars(com.jme3.util.TempVars)

Example 78 with TempVars

use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.

the class Skeleton method computeSkinningMatrices.

/**
     * Compute the skining matrices for each bone of the skeleton that would be used to transform vertices of associated meshes
     * @return 
     */
public Matrix4f[] computeSkinningMatrices() {
    TempVars vars = TempVars.get();
    for (int i = 0; i < boneList.length; i++) {
        boneList[i].getOffsetTransform(skinningMatrixes[i], vars.quat1, vars.vect1, vars.vect2, vars.tempMat3);
    }
    vars.release();
    return skinningMatrixes;
}
Also used : TempVars(com.jme3.util.TempVars)

Example 79 with TempVars

use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.

the class SkeletonControl method applySkinning.

/**
     * Method to apply skinning transforms to a mesh's buffers
     *
     * @param mesh the mesh
     * @param offsetMatrices the offset matices to apply
     */
private void applySkinning(Mesh mesh, Matrix4f[] offsetMatrices) {
    int maxWeightsPerVert = mesh.getMaxNumWeights();
    if (maxWeightsPerVert <= 0) {
        throw new IllegalStateException("Max weights per vert is incorrectly set!");
    }
    int fourMinusMaxWeights = 4 - maxWeightsPerVert;
    // NOTE: This code assumes the vertex buffer is in bind pose
    // resetToBind() has been called this frame
    VertexBuffer vb = mesh.getBuffer(Type.Position);
    FloatBuffer fvb = (FloatBuffer) vb.getData();
    fvb.rewind();
    VertexBuffer nb = mesh.getBuffer(Type.Normal);
    FloatBuffer fnb = (FloatBuffer) nb.getData();
    fnb.rewind();
    // get boneIndexes and weights for mesh
    ByteBuffer ib = (ByteBuffer) mesh.getBuffer(Type.BoneIndex).getData();
    FloatBuffer wb = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();
    ib.rewind();
    wb.rewind();
    float[] weights = wb.array();
    byte[] indices = ib.array();
    int idxWeights = 0;
    TempVars vars = TempVars.get();
    float[] posBuf = vars.skinPositions;
    float[] normBuf = vars.skinNormals;
    int iterations = (int) FastMath.ceil(fvb.limit() / ((float) posBuf.length));
    int bufLength = posBuf.length;
    for (int i = iterations - 1; i >= 0; i--) {
        // read next set of positions and normals from native buffer
        bufLength = Math.min(posBuf.length, fvb.remaining());
        fvb.get(posBuf, 0, bufLength);
        fnb.get(normBuf, 0, bufLength);
        int verts = bufLength / 3;
        int idxPositions = 0;
        // iterate vertices and apply skinning transform for each effecting bone
        for (int vert = verts - 1; vert >= 0; vert--) {
            // Skip this vertex if the first weight is zero.
            if (weights[idxWeights] == 0) {
                idxPositions += 3;
                idxWeights += 4;
                continue;
            }
            float nmx = normBuf[idxPositions];
            float vtx = posBuf[idxPositions++];
            float nmy = normBuf[idxPositions];
            float vty = posBuf[idxPositions++];
            float nmz = normBuf[idxPositions];
            float vtz = posBuf[idxPositions++];
            float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0;
            for (int w = maxWeightsPerVert - 1; w >= 0; w--) {
                float weight = weights[idxWeights];
                Matrix4f mat = offsetMatrices[indices[idxWeights++] & 0xff];
                rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight;
                ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight;
                rz += (mat.m20 * vtx + mat.m21 * vty + mat.m22 * vtz + mat.m23) * weight;
                rnx += (nmx * mat.m00 + nmy * mat.m01 + nmz * mat.m02) * weight;
                rny += (nmx * mat.m10 + nmy * mat.m11 + nmz * mat.m12) * weight;
                rnz += (nmx * mat.m20 + nmy * mat.m21 + nmz * mat.m22) * weight;
            }
            idxWeights += fourMinusMaxWeights;
            idxPositions -= 3;
            normBuf[idxPositions] = rnx;
            posBuf[idxPositions++] = rx;
            normBuf[idxPositions] = rny;
            posBuf[idxPositions++] = ry;
            normBuf[idxPositions] = rnz;
            posBuf[idxPositions++] = rz;
        }
        fvb.position(fvb.position() - bufLength);
        fvb.put(posBuf, 0, bufLength);
        fnb.position(fnb.position() - bufLength);
        fnb.put(normBuf, 0, bufLength);
    }
    vars.release();
    vb.updateData(fvb);
    nb.updateData(fnb);
}
Also used : Matrix4f(com.jme3.math.Matrix4f) FloatBuffer(java.nio.FloatBuffer) TempVars(com.jme3.util.TempVars) ByteBuffer(java.nio.ByteBuffer)

Example 80 with TempVars

use of com.jme3.util.TempVars in project jmonkeyengine by jMonkeyEngine.

the class SkeletonControl method applySkinningTangents.

/**
     * Specific method for skinning with tangents to avoid cluttering the
     * classic skinning calculation with null checks that would slow down the
     * process even if tangents don't have to be computed. Also the iteration
     * has additional indexes since tangent has 4 components instead of 3 for
     * pos and norm
     *
     * @param maxWeightsPerVert maximum number of weights per vertex
     * @param mesh the mesh
     * @param offsetMatrices the offsetMaytrices to apply
     * @param tb the tangent vertexBuffer
     */
private void applySkinningTangents(Mesh mesh, Matrix4f[] offsetMatrices, VertexBuffer tb) {
    int maxWeightsPerVert = mesh.getMaxNumWeights();
    if (maxWeightsPerVert <= 0) {
        throw new IllegalStateException("Max weights per vert is incorrectly set!");
    }
    int fourMinusMaxWeights = 4 - maxWeightsPerVert;
    // NOTE: This code assumes the vertex buffer is in bind pose
    // resetToBind() has been called this frame
    VertexBuffer vb = mesh.getBuffer(Type.Position);
    FloatBuffer fvb = (FloatBuffer) vb.getData();
    fvb.rewind();
    VertexBuffer nb = mesh.getBuffer(Type.Normal);
    FloatBuffer fnb = (FloatBuffer) nb.getData();
    fnb.rewind();
    FloatBuffer ftb = (FloatBuffer) tb.getData();
    ftb.rewind();
    // get boneIndexes and weights for mesh
    ByteBuffer ib = (ByteBuffer) mesh.getBuffer(Type.BoneIndex).getData();
    FloatBuffer wb = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();
    ib.rewind();
    wb.rewind();
    float[] weights = wb.array();
    byte[] indices = ib.array();
    int idxWeights = 0;
    TempVars vars = TempVars.get();
    float[] posBuf = vars.skinPositions;
    float[] normBuf = vars.skinNormals;
    float[] tanBuf = vars.skinTangents;
    int iterations = (int) FastMath.ceil(fvb.limit() / ((float) posBuf.length));
    int bufLength = 0;
    int tanLength = 0;
    for (int i = iterations - 1; i >= 0; i--) {
        // read next set of positions and normals from native buffer
        bufLength = Math.min(posBuf.length, fvb.remaining());
        tanLength = Math.min(tanBuf.length, ftb.remaining());
        fvb.get(posBuf, 0, bufLength);
        fnb.get(normBuf, 0, bufLength);
        ftb.get(tanBuf, 0, tanLength);
        int verts = bufLength / 3;
        int idxPositions = 0;
        //tangents has their own index because of the 4 components
        int idxTangents = 0;
        // iterate vertices and apply skinning transform for each effecting bone
        for (int vert = verts - 1; vert >= 0; vert--) {
            // Skip this vertex if the first weight is zero.
            if (weights[idxWeights] == 0) {
                idxTangents += 4;
                idxPositions += 3;
                idxWeights += 4;
                continue;
            }
            float nmx = normBuf[idxPositions];
            float vtx = posBuf[idxPositions++];
            float nmy = normBuf[idxPositions];
            float vty = posBuf[idxPositions++];
            float nmz = normBuf[idxPositions];
            float vtz = posBuf[idxPositions++];
            float tnx = tanBuf[idxTangents++];
            float tny = tanBuf[idxTangents++];
            float tnz = tanBuf[idxTangents++];
            // skipping the 4th component of the tangent since it doesn't have to be transformed
            idxTangents++;
            float rx = 0, ry = 0, rz = 0, rnx = 0, rny = 0, rnz = 0, rtx = 0, rty = 0, rtz = 0;
            for (int w = maxWeightsPerVert - 1; w >= 0; w--) {
                float weight = weights[idxWeights];
                Matrix4f mat = offsetMatrices[indices[idxWeights++] & 0xff];
                rx += (mat.m00 * vtx + mat.m01 * vty + mat.m02 * vtz + mat.m03) * weight;
                ry += (mat.m10 * vtx + mat.m11 * vty + mat.m12 * vtz + mat.m13) * weight;
                rz += (mat.m20 * vtx + mat.m21 * vty + mat.m22 * vtz + mat.m23) * weight;
                rnx += (nmx * mat.m00 + nmy * mat.m01 + nmz * mat.m02) * weight;
                rny += (nmx * mat.m10 + nmy * mat.m11 + nmz * mat.m12) * weight;
                rnz += (nmx * mat.m20 + nmy * mat.m21 + nmz * mat.m22) * weight;
                rtx += (tnx * mat.m00 + tny * mat.m01 + tnz * mat.m02) * weight;
                rty += (tnx * mat.m10 + tny * mat.m11 + tnz * mat.m12) * weight;
                rtz += (tnx * mat.m20 + tny * mat.m21 + tnz * mat.m22) * weight;
            }
            idxWeights += fourMinusMaxWeights;
            idxPositions -= 3;
            normBuf[idxPositions] = rnx;
            posBuf[idxPositions++] = rx;
            normBuf[idxPositions] = rny;
            posBuf[idxPositions++] = ry;
            normBuf[idxPositions] = rnz;
            posBuf[idxPositions++] = rz;
            idxTangents -= 4;
            tanBuf[idxTangents++] = rtx;
            tanBuf[idxTangents++] = rty;
            tanBuf[idxTangents++] = rtz;
            //once again skipping the 4th component of the tangent
            idxTangents++;
        }
        fvb.position(fvb.position() - bufLength);
        fvb.put(posBuf, 0, bufLength);
        fnb.position(fnb.position() - bufLength);
        fnb.put(normBuf, 0, bufLength);
        ftb.position(ftb.position() - tanLength);
        ftb.put(tanBuf, 0, tanLength);
    }
    vars.release();
    vb.updateData(fvb);
    nb.updateData(fnb);
    tb.updateData(ftb);
}
Also used : Matrix4f(com.jme3.math.Matrix4f) FloatBuffer(java.nio.FloatBuffer) TempVars(com.jme3.util.TempVars) ByteBuffer(java.nio.ByteBuffer)

Aggregations

TempVars (com.jme3.util.TempVars)103 Vector3f (com.jme3.math.Vector3f)50 Quaternion (com.jme3.math.Quaternion)13 Matrix4f (com.jme3.math.Matrix4f)12 BoundingBox (com.jme3.bounding.BoundingBox)10 Bone (com.jme3.animation.Bone)8 Spatial (com.jme3.scene.Spatial)7 CollisionResult (com.jme3.collision.CollisionResult)6 Vector2f (com.jme3.math.Vector2f)6 FloatBuffer (java.nio.FloatBuffer)6 BoundingSphere (com.jme3.bounding.BoundingSphere)5 BoundingVolume (com.jme3.bounding.BoundingVolume)5 Transform (com.jme3.math.Transform)5 DirectionalLight (com.jme3.light.DirectionalLight)4 PointLight (com.jme3.light.PointLight)4 Geometry (com.jme3.scene.Geometry)4 SpotLight (com.jme3.light.SpotLight)3 ColorRGBA (com.jme3.math.ColorRGBA)3 Matrix3f (com.jme3.math.Matrix3f)3 Vector4f (com.jme3.math.Vector4f)3