Search in sources :

Example 36 with VertexBuffer

use of com.jme3.scene.VertexBuffer 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)

Example 37 with VertexBuffer

use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.

the class VertexBuffer method clone.

/**
     * Creates a deep clone of this VertexBuffer but overrides the
     * {@link Type}.
     * 
     * @param overrideType The type of the cloned VertexBuffer
     * @return A deep clone of the buffer
     */
public VertexBuffer clone(Type overrideType) {
    VertexBuffer vb = new VertexBuffer(overrideType);
    vb.components = components;
    vb.componentsLength = componentsLength;
    // Make sure to pass a read-only buffer to clone so that
    // the position information doesn't get clobbered by another
    // reading thread during cloning (and vice versa) since this is
    // a purely read-only operation.
    vb.data = BufferUtils.clone(getDataReadOnly());
    vb.format = format;
    vb.handleRef = new Object();
    vb.id = -1;
    vb.normalized = normalized;
    vb.instanceSpan = instanceSpan;
    vb.offset = offset;
    vb.stride = stride;
    vb.updateNeeded = true;
    vb.usage = usage;
    return vb;
}
Also used : NativeObject(com.jme3.util.NativeObject)

Example 38 with VertexBuffer

use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.

the class GLRenderer method renderMeshDefault.

private void renderMeshDefault(Mesh mesh, int lod, int count, VertexBuffer[] instanceData) {
    // Here while count is still passed in.  Can be removed when/if
    // the method is collapsed again.  -pspeed        
    count = Math.max(mesh.getInstanceCount(), count);
    VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
    if (interleavedData != null && interleavedData.isUpdateNeeded()) {
        updateBufferData(interleavedData);
    }
    VertexBuffer indices;
    if (mesh.getNumLodLevels() > 0) {
        indices = mesh.getLodLevel(lod);
    } else {
        indices = mesh.getBuffer(Type.Index);
    }
    if (instanceData != null) {
        for (VertexBuffer vb : instanceData) {
            setVertexAttrib(vb, null);
        }
    }
    for (VertexBuffer vb : mesh.getBufferList().getArray()) {
        if (vb.getBufferType() == Type.InterleavedData || // ignore cpu-only buffers
        vb.getUsage() == Usage.CpuOnly || vb.getBufferType() == Type.Index) {
            continue;
        }
        if (vb.getStride() == 0) {
            // not interleaved
            setVertexAttrib(vb);
        } else {
            // interleaved
            setVertexAttrib(vb, interleavedData);
        }
    }
    clearVertexAttribs();
    if (indices != null) {
        drawTriangleList(indices, mesh, count);
    } else {
        drawTriangleArray(mesh.getMode(), count, mesh.getVertexCount());
    }
}
Also used : VertexBuffer(com.jme3.scene.VertexBuffer)

Example 39 with VertexBuffer

use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.

the class GLRenderer method renderMeshVertexArray.

private void renderMeshVertexArray(Mesh mesh, int lod, int count, VertexBuffer instanceData) {
    if (mesh.getId() == -1) {
        updateVertexArray(mesh, instanceData);
    } else {
    // TODO: Check if it was updated
    }
    if (context.boundVertexArray != mesh.getId()) {
        gl3.glBindVertexArray(mesh.getId());
        context.boundVertexArray = mesh.getId();
    }
    //        IntMap<VertexBuffer> buffers = mesh.getBuffers();
    VertexBuffer indices;
    if (mesh.getNumLodLevels() > 0) {
        indices = mesh.getLodLevel(lod);
    } else {
        indices = mesh.getBuffer(Type.Index);
    }
    if (indices != null) {
        drawTriangleList(indices, mesh, count);
    } else {
        drawTriangleArray(mesh.getMode(), count, mesh.getVertexCount());
    }
    clearVertexAttribs();
}
Also used : VertexBuffer(com.jme3.scene.VertexBuffer)

Example 40 with VertexBuffer

use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.

the class TangentBinormalGenerator method processTriangles.

private static List<VertexData> processTriangles(Mesh mesh, int[] index, Vector3f[] v, Vector2f[] t, boolean splitMirrored) {
    IndexBuffer indexBuffer = mesh.getIndexBuffer();
    FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
    if (mesh.getBuffer(Type.TexCoord) == null) {
        throw new IllegalArgumentException("Can only generate tangents for " + "meshes with texture coordinates");
    }
    FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData();
    List<VertexData> vertices = initVertexData(vertexBuffer.limit() / 3);
    for (int i = 0; i < indexBuffer.size() / 3; i++) {
        for (int j = 0; j < 3; j++) {
            index[j] = indexBuffer.get(i * 3 + j);
            populateFromBuffer(v[j], vertexBuffer, index[j]);
            populateFromBuffer(t[j], textureBuffer, index[j]);
        }
        TriangleData triData = processTriangle(index, v, t);
        if (splitMirrored) {
            triData.setIndex(index);
            triData.triangleOffset = i * 3;
        }
        vertices.get(index[0]).triangles.add(triData);
        vertices.get(index[1]).triangles.add(triData);
        vertices.get(index[2]).triangles.add(triData);
    }
    return vertices;
}
Also used : IndexBuffer(com.jme3.scene.mesh.IndexBuffer) FloatBuffer(java.nio.FloatBuffer)

Aggregations

FloatBuffer (java.nio.FloatBuffer)42 VertexBuffer (com.jme3.scene.VertexBuffer)40 Vector3f (com.jme3.math.Vector3f)17 ByteBuffer (java.nio.ByteBuffer)12 IndexBuffer (com.jme3.scene.mesh.IndexBuffer)9 ShortBuffer (java.nio.ShortBuffer)9 IntBuffer (java.nio.IntBuffer)8 Buffer (java.nio.Buffer)6 Geometry (com.jme3.scene.Geometry)5 Mesh (com.jme3.scene.Mesh)5 Bone (com.jme3.animation.Bone)4 Matrix4f (com.jme3.math.Matrix4f)4 Vector2f (com.jme3.math.Vector2f)4 ArrayList (java.util.ArrayList)4 Material (com.jme3.material.Material)3 ColorRGBA (com.jme3.math.ColorRGBA)3 Type (com.jme3.scene.VertexBuffer.Type)3 TempVars (com.jme3.util.TempVars)3 HashMap (java.util.HashMap)3 BoundingBox (com.jme3.bounding.BoundingBox)2