Java Code Examples for com.jme3.scene.mesh.IndexBuffer#wrapIndexBuffer()

The following examples show how to use com.jme3.scene.mesh.IndexBuffer#wrapIndexBuffer() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SkeletonControl.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * 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
    IndexBuffer ib = IndexBuffer.wrapIndexBuffer(mesh.getBuffer(Type.BoneIndex).getData());
    FloatBuffer wb = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();

    wb.rewind();

    float[] weights = wb.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[ib.get(idxWeights++)];

                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);

}
 
Example 2
Source File: SkinningControl.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * 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
    IndexBuffer ib = IndexBuffer.wrapIndexBuffer(mesh.getBuffer(Type.BoneIndex).getData());
    FloatBuffer wb = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData();

    wb.rewind();

    float[] weights = wb.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[ib.get(idxWeights++)];

                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);

}