Search in sources :

Example 6 with IndexBuffer

use of com.jme3.scene.mesh.IndexBuffer in project jmonkeyengine by jMonkeyEngine.

the class TerrainPatch method generateLodEntropies.

/**
     * This calculation is slow, so don't use it often.
     */
public void generateLodEntropies() {
    float[] entropies = new float[getMaxLod() + 1];
    for (int i = 0; i <= getMaxLod(); i++) {
        int curLod = (int) Math.pow(2, i);
        IndexBuffer idxB = geomap.writeIndexArrayLodDiff(curLod, false, false, false, false, totalSize);
        Buffer ib;
        if (idxB.getBuffer() instanceof IntBuffer)
            ib = (IntBuffer) idxB.getBuffer();
        else
            ib = (ShortBuffer) idxB.getBuffer();
        entropies[i] = EntropyComputeUtil.computeLodEntropy(mesh, ib);
    }
    lodEntropy = entropies;
}
Also used : FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IntBuffer(java.nio.IntBuffer) Buffer(java.nio.Buffer) VertexBuffer(com.jme3.scene.VertexBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IntBuffer(java.nio.IntBuffer) ShortBuffer(java.nio.ShortBuffer)

Example 7 with IndexBuffer

use of com.jme3.scene.mesh.IndexBuffer in project jmonkeyengine by jMonkeyEngine.

the class LODGeomap method writeIndexArrayLodVariable.

public IndexBuffer writeIndexArrayLodVariable(int lod, int rightLod, int topLod, int leftLod, int bottomLod, int totalSize) {
    int numIndexes = calculateNumIndexesLodDiff(lod);
    IndexBuffer ib = IndexBuffer.createIndexBuffer(numIndexes, numIndexes);
    VerboseBuffer buffer = new VerboseBuffer(ib);
    //System.out.println("	for (z="+lod+"; z<"+(getWidth()-(1*lod))+"; z+="+lod+")");
    for (int r = lod; r < getWidth() - (2 * lod); r += lod) {
        // row
        int rowIdx = r * getWidth();
        int nextRowIdx = (r + 1 * lod) * getWidth();
        for (int c = lod; c < getWidth() - (1 * lod); c += lod) {
            // column
            int idx = rowIdx + c;
            buffer.put(idx);
            idx = nextRowIdx + c;
            buffer.put(idx);
        }
        // add degenerate triangles
        if (r < getWidth() - (3 * lod)) {
            int idx = nextRowIdx + getWidth() - (1 * lod) - 1;
            buffer.put(idx);
            // inset by 1
            idx = nextRowIdx + (1 * lod);
            buffer.put(idx);
        //System.out.println("");
        }
    }
    //System.out.println("\nright:");
    //int runningBufferCount = buffer.getCount();
    //System.out.println("buffer start: "+runningBufferCount);
    // right
    int br = getWidth() * (getWidth() - lod) - 1 - lod;
    // bottom right -1
    buffer.put(br);
    int corner = getWidth() * getWidth() - 1;
    // bottom right corner
    buffer.put(corner);
    if (rightLod > lod) {
        // if lower LOD
        int idx = corner;
        // iterations
        int it = (getWidth() - 1) / rightLod;
        int lodDiff = rightLod / lod;
        for (int i = it; i > 0; i--) {
            // for each lod level of the neighbour
            idx = getWidth() * (i * rightLod + 1) - 1;
            for (int j = 1; j <= lodDiff; j++) {
                // for each section in that lod level
                int idxB = idx - (getWidth() * (j * lod)) - lod;
                if (j == lodDiff && i == 1) {
                    // the last one
                    buffer.put(getWidth() - 1);
                } else if (j == lodDiff) {
                    buffer.put(idxB);
                    buffer.put(idxB + lod);
                } else {
                    buffer.put(idxB);
                    buffer.put(idx);
                }
            }
        }
        // reset winding order
        // top-right +1row
        buffer.put(getWidth() * (lod + 1) - lod - 1);
        // top-right
        buffer.put(getWidth() - 1);
    } else {
        //br+1);//degenerate to flip winding order
        buffer.put(corner);
        for (int row = getWidth() - lod; row > lod; row -= lod) {
            // mult to get row
            int idx = row * getWidth() - 1;
            buffer.put(idx);
            buffer.put(idx - lod);
        }
        buffer.put(getWidth() - 1);
    }
    // top 			(the order gets reversed here so the diagonals line up)
    if (topLod > lod) {
        // if lower LOD
        if (rightLod > lod) {
            // need to flip winding order
            buffer.put(getWidth() - 1);
            buffer.put(getWidth() * lod - 1);
            buffer.put(getWidth() - 1);
        }
        int idx = getWidth() - 1;
        // iterations
        int it = (getWidth() - 1) / topLod;
        int lodDiff = topLod / lod;
        for (int i = it; i > 0; i--) {
            // for each lod level of the neighbour
            idx = (i * topLod);
            for (int j = 1; j <= lodDiff; j++) {
                // for each section in that lod level
                int idxB = lod * getWidth() + (i * topLod) - (j * lod);
                if (j == lodDiff && i == 1) {
                    // the last one
                    buffer.put(0);
                } else if (j == lodDiff) {
                    buffer.put(idxB);
                    buffer.put(idx - topLod);
                } else {
                    buffer.put(idxB);
                    buffer.put(idx);
                }
            }
        }
    } else {
        if (rightLod > lod) {
            buffer.put(getWidth() - 1);
        }
        for (int col = getWidth() - 1 - lod; col > 0; col -= lod) {
            int idx = col + (lod * getWidth());
            buffer.put(idx);
            idx = col;
            buffer.put(idx);
        }
        buffer.put(0);
    }
    buffer.put(0);
    // left
    if (leftLod > lod) {
        // if lower LOD
        int idx = 0;
        // iterations
        int it = (getWidth() - 1) / leftLod;
        int lodDiff = leftLod / lod;
        for (int i = 0; i < it; i++) {
            // for each lod level of the neighbour
            idx = getWidth() * (i * leftLod);
            for (int j = 1; j <= lodDiff; j++) {
                // for each section in that lod level
                int idxB = idx + (getWidth() * (j * lod)) + lod;
                if (j == lodDiff && i == it - 1) {
                    // the last one
                    buffer.put(getWidth() * getWidth() - getWidth());
                } else if (j == lodDiff) {
                    buffer.put(idxB);
                    buffer.put(idxB - lod);
                } else {
                    buffer.put(idxB);
                    buffer.put(idx);
                }
            }
        }
    } else {
        buffer.put(0);
        buffer.put(getWidth() * lod + lod);
        buffer.put(0);
        for (int row = lod; row < getWidth() - lod; row += lod) {
            int idx = row * getWidth();
            buffer.put(idx);
            idx = row * getWidth() + lod;
            buffer.put(idx);
        }
        buffer.put(getWidth() * (getWidth() - 1));
    }
    // bottom
    if (bottomLod > lod) {
        // if lower LOD
        if (leftLod > lod) {
            buffer.put(getWidth() * (getWidth() - 1));
            buffer.put(getWidth() * (getWidth() - lod));
            buffer.put(getWidth() * (getWidth() - 1));
        }
        int idx = getWidth() * getWidth() - getWidth();
        // iterations
        int it = (getWidth() - 1) / bottomLod;
        int lodDiff = bottomLod / lod;
        for (int i = 0; i < it; i++) {
            // for each lod level of the neighbour
            idx = getWidth() * getWidth() - getWidth() + (i * bottomLod);
            for (int j = 1; j <= lodDiff; j++) {
                // for each section in that lod level
                int idxB = idx - (getWidth() * lod) + j * lod;
                if (j == lodDiff && i == it - 1) {
                    // the last one
                    buffer.put(getWidth() * getWidth() - 1);
                } else if (j == lodDiff) {
                    buffer.put(idxB);
                    buffer.put(idx + bottomLod);
                } else {
                    buffer.put(idxB);
                    buffer.put(idx);
                }
            }
        }
    } else {
        if (leftLod > lod) {
            buffer.put(getWidth() * (getWidth() - 1));
            buffer.put(getWidth() * getWidth() - (getWidth() * lod) + lod);
            buffer.put(getWidth() * (getWidth() - 1));
        }
        for (int col = lod; col < getWidth() - lod; col += lod) {
            // up
            int idx = getWidth() * (getWidth() - 1 - lod) + col;
            buffer.put(idx);
            // down
            idx = getWidth() * (getWidth() - 1) + col;
            buffer.put(idx);
        }
    //buffer.put(getWidth()*getWidth()-1-lod); // <-- THIS caused holes at the end!
    }
    buffer.put(getWidth() * getWidth() - 1);
    // fill in the rest of the buffer with degenerates, there should only be a couple
    for (int i = buffer.getCount(); i < numIndexes; i++) {
        buffer.put(getWidth() * getWidth() - 1);
    }
    return buffer.delegate;
}
Also used : IndexBuffer(com.jme3.scene.mesh.IndexBuffer)

Example 8 with IndexBuffer

use of com.jme3.scene.mesh.IndexBuffer in project jmonkeyengine by jMonkeyEngine.

the class LODGeomap method createMesh.

public Mesh createMesh(Vector3f scale, Vector2f tcScale, Vector2f tcOffset, float offsetAmount, int totalSize, boolean center, int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod) {
    FloatBuffer pb = writeVertexArray(null, scale, center);
    FloatBuffer texb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize);
    FloatBuffer nb = writeNormalArray(null, scale);
    Buffer ib;
    IndexBuffer idxB = writeIndexArrayLodDiff(lod, rightLod, topLod, leftLod, bottomLod, totalSize);
    if (idxB.getBuffer() instanceof IntBuffer)
        ib = (IntBuffer) idxB.getBuffer();
    else
        ib = (ShortBuffer) idxB.getBuffer();
    FloatBuffer bb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
    FloatBuffer tanb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
    writeTangentArray(nb, tanb, bb, texb, scale);
    Mesh m = new Mesh();
    m.setMode(Mode.TriangleStrip);
    m.setBuffer(Type.Position, 3, pb);
    m.setBuffer(Type.Normal, 3, nb);
    m.setBuffer(Type.Tangent, 3, tanb);
    m.setBuffer(Type.Binormal, 3, bb);
    m.setBuffer(Type.TexCoord, 2, texb);
    if (ib instanceof IntBuffer)
        m.setBuffer(Type.Index, 3, (IntBuffer) ib);
    else if (ib instanceof ShortBuffer)
        m.setBuffer(Type.Index, 3, (ShortBuffer) ib);
    m.setStatic();
    m.updateBound();
    return m;
}
Also used : FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IntBuffer(java.nio.IntBuffer) Buffer(java.nio.Buffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IntBuffer(java.nio.IntBuffer) Mesh(com.jme3.scene.Mesh) FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer)

Example 9 with IndexBuffer

use of com.jme3.scene.mesh.IndexBuffer in project jmonkeyengine by jMonkeyEngine.

the class BatchNode method mergeGeometries.

/**
     * Merges all geometries in the collection into
     * the output mesh. Does not take into account materials.
     *
     * @param geometries
     * @param outMesh
     */
private void mergeGeometries(Mesh outMesh, List<Geometry> geometries) {
    int[] compsForBuf = new int[VertexBuffer.Type.values().length];
    VertexBuffer.Format[] formatForBuf = new VertexBuffer.Format[compsForBuf.length];
    boolean[] normForBuf = new boolean[VertexBuffer.Type.values().length];
    int totalVerts = 0;
    int totalTris = 0;
    int totalLodLevels = 0;
    int maxWeights = -1;
    Mesh.Mode mode = null;
    float lineWidth = 1f;
    for (Geometry geom : geometries) {
        totalVerts += geom.getVertexCount();
        totalTris += geom.getTriangleCount();
        totalLodLevels = Math.min(totalLodLevels, geom.getMesh().getNumLodLevels());
        if (maxVertCount < geom.getVertexCount()) {
            maxVertCount = geom.getVertexCount();
        }
        Mesh.Mode listMode;
        //float listLineWidth = 1f;
        int components;
        switch(geom.getMesh().getMode()) {
            case Points:
                listMode = Mesh.Mode.Points;
                components = 1;
                break;
            case LineLoop:
            case LineStrip:
            case Lines:
                listMode = Mesh.Mode.Lines;
                //listLineWidth = geom.getMesh().getLineWidth();
                components = 2;
                break;
            case TriangleFan:
            case TriangleStrip:
            case Triangles:
                listMode = Mesh.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() != VertexBuffer.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;
        //Not needed anymore as lineWidth is now in RenderState and will be taken into account when merging according to the material
        //            if (mode == Mesh.Mode.Lines) {
        //                if (lineWidth != 1f && listLineWidth != lineWidth) {
        //                    throw new UnsupportedOperationException("When using Mesh Line mode, cannot combine meshes with different line width "
        //                            + lineWidth + " != " + listLineWidth);
        //                }
        //                lineWidth = listLineWidth;
        //            }
        compsForBuf[VertexBuffer.Type.Index.ordinal()] = components;
    }
    outMesh.setMaxNumWeights(maxWeights);
    outMesh.setMode(mode);
    //outMesh.setLineWidth(lineWidth);
    if (totalVerts >= 65536) {
        // make sure we create an UnsignedInt buffer so we can fit all of the meshes
        formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedInt;
    } else {
        formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.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 == VertexBuffer.Type.Index.ordinal()) {
            data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalTris);
        } else {
            data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalVerts);
        }
        VertexBuffer vb = new VertexBuffer(VertexBuffer.Type.values()[i]);
        vb.setupData(VertexBuffer.Usage.Dynamic, 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();
        if (!isBatch(geom)) {
            geom.associateWithGroupNode(this, globalVertIndex);
        }
        int geomVertCount = inMesh.getVertexCount();
        int geomTriCount = inMesh.getTriangleCount();
        for (int bufType = 0; bufType < compsForBuf.length; bufType++) {
            VertexBuffer inBuf = inMesh.getBuffer(VertexBuffer.Type.values()[bufType]);
            VertexBuffer outBuf = outMesh.getBuffer(VertexBuffer.Type.values()[bufType]);
            if (outBuf == null) {
                continue;
            }
            if (VertexBuffer.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 (VertexBuffer.Type.Position.ordinal() == bufType) {
                FloatBuffer inPos = (FloatBuffer) inBuf.getData();
                FloatBuffer outPos = (FloatBuffer) outBuf.getData();
                doCopyBuffer(inPos, globalVertIndex, outPos, 3);
            } else if (VertexBuffer.Type.Normal.ordinal() == bufType || VertexBuffer.Type.Tangent.ordinal() == bufType) {
                FloatBuffer inPos = (FloatBuffer) inBuf.getData();
                FloatBuffer outPos = (FloatBuffer) outBuf.getData();
                doCopyBuffer(inPos, globalVertIndex, outPos, compsForBuf[bufType]);
                if (VertexBuffer.Type.Tangent.ordinal() == bufType) {
                    useTangents = true;
                }
            } else {
                if (inBuf == null) {
                    throw new IllegalArgumentException("Geometry " + geom.getName() + " has no " + outBuf.getBufferType() + " buffer whereas other geoms have. all geometries should have the same types of buffers.\n Try to use GeometryBatchFactory.alignBuffer() on the BatchNode before batching");
                } else if (outBuf == null) {
                    throw new IllegalArgumentException("Geometry " + geom.getName() + " has a " + outBuf.getBufferType() + " buffer whereas other geoms don't. all geometries should have the same types of buffers.\n Try to use GeometryBatchFactory.alignBuffer() on the BatchNode before batching");
                } else {
                    inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount);
                }
            }
        }
        globalVertIndex += geomVertCount;
        globalTriIndex += geomTriCount;
    }
}
Also used : FloatBuffer(java.nio.FloatBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) Buffer(java.nio.Buffer) FloatBuffer(java.nio.FloatBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer)

Example 10 with IndexBuffer

use of com.jme3.scene.mesh.IndexBuffer in project jmonkeyengine by jMonkeyEngine.

the class IrUtils method convertIrMeshToJmeMesh.

/**
     * Convert IrMesh to jME3 mesh.
     */
public static Mesh convertIrMeshToJmeMesh(IrMesh mesh) {
    Map<IrVertex, Integer> vertexToVertexIndex = new HashMap<IrVertex, Integer>();
    List<IrVertex> vertices = new ArrayList<IrVertex>();
    List<Integer> indexes = new ArrayList<Integer>();
    int vertexIndex = 0;
    for (IrPolygon polygon : mesh.polygons) {
        if (polygon.vertices.length != 3) {
            throw new UnsupportedOperationException("IrMesh must be triangulated first");
        }
        for (IrVertex vertex : polygon.vertices) {
            // Is this vertex already indexed?
            Integer existingIndex = vertexToVertexIndex.get(vertex);
            if (existingIndex == null) {
                // Not indexed yet, allocate index.
                indexes.add(vertexIndex);
                vertexToVertexIndex.put(vertex, vertexIndex);
                vertices.add(vertex);
                vertexIndex++;
            } else {
                // Index already allocated for this vertex, reuse it.
                indexes.add(existingIndex);
            }
        }
    }
    Mesh jmeMesh = new Mesh();
    jmeMesh.setMode(Mesh.Mode.Triangles);
    FloatBuffer posBuf = null;
    FloatBuffer normBuf = null;
    FloatBuffer tangBuf = null;
    FloatBuffer uv0Buf = null;
    FloatBuffer uv1Buf = null;
    ByteBuffer colorBuf = null;
    ByteBuffer boneIndices = null;
    FloatBuffer boneWeights = null;
    IndexBuffer indexBuf = null;
    IrVertex inspectionVertex = vertices.get(0);
    if (inspectionVertex.pos != null) {
        posBuf = BufferUtils.createVector3Buffer(vertices.size());
        jmeMesh.setBuffer(VertexBuffer.Type.Position, 3, posBuf);
    }
    if (inspectionVertex.norm != null) {
        normBuf = BufferUtils.createVector3Buffer(vertices.size());
        jmeMesh.setBuffer(VertexBuffer.Type.Normal, 3, normBuf);
    }
    if (inspectionVertex.tang4d != null) {
        tangBuf = BufferUtils.createFloatBuffer(vertices.size() * 4);
        jmeMesh.setBuffer(VertexBuffer.Type.Tangent, 4, tangBuf);
    }
    if (inspectionVertex.tang != null || inspectionVertex.bitang != null) {
        throw new IllegalStateException("Mesh is using 3D tangents, must be converted to 4D tangents first.");
    }
    if (inspectionVertex.uv0 != null) {
        uv0Buf = BufferUtils.createVector2Buffer(vertices.size());
        jmeMesh.setBuffer(VertexBuffer.Type.TexCoord, 2, uv0Buf);
    }
    if (inspectionVertex.uv1 != null) {
        uv1Buf = BufferUtils.createVector2Buffer(vertices.size());
        jmeMesh.setBuffer(VertexBuffer.Type.TexCoord2, 2, uv1Buf);
    }
    if (inspectionVertex.color != null) {
        colorBuf = BufferUtils.createByteBuffer(vertices.size() * 4);
        jmeMesh.setBuffer(VertexBuffer.Type.Color, 4, colorBuf);
        jmeMesh.getBuffer(VertexBuffer.Type.Color).setNormalized(true);
    }
    if (inspectionVertex.boneWeightsIndices != null) {
        boneIndices = BufferUtils.createByteBuffer(vertices.size() * 4);
        boneWeights = BufferUtils.createFloatBuffer(vertices.size() * 4);
        jmeMesh.setBuffer(VertexBuffer.Type.BoneIndex, 4, boneIndices);
        jmeMesh.setBuffer(VertexBuffer.Type.BoneWeight, 4, boneWeights);
        //creating empty buffers for HW skinning 
        //the buffers will be setup if ever used.
        VertexBuffer weightsHW = new VertexBuffer(VertexBuffer.Type.HWBoneWeight);
        VertexBuffer indicesHW = new VertexBuffer(VertexBuffer.Type.HWBoneIndex);
        //setting usage to cpuOnly so that the buffer is not send empty to the GPU
        indicesHW.setUsage(VertexBuffer.Usage.CpuOnly);
        weightsHW.setUsage(VertexBuffer.Usage.CpuOnly);
        jmeMesh.setBuffer(weightsHW);
        jmeMesh.setBuffer(indicesHW);
    }
    if (vertices.size() >= 65536) {
        // too many verticies: use intbuffer instead of shortbuffer
        IntBuffer ib = BufferUtils.createIntBuffer(indexes.size());
        jmeMesh.setBuffer(VertexBuffer.Type.Index, 3, ib);
        indexBuf = new IndexIntBuffer(ib);
    } else {
        ShortBuffer sb = BufferUtils.createShortBuffer(indexes.size());
        jmeMesh.setBuffer(VertexBuffer.Type.Index, 3, sb);
        indexBuf = new IndexShortBuffer(sb);
    }
    jmeMesh.setStatic();
    int maxBonesPerVertex = -1;
    for (IrVertex vertex : vertices) {
        if (posBuf != null) {
            posBuf.put(vertex.pos.x).put(vertex.pos.y).put(vertex.pos.z);
        }
        if (normBuf != null) {
            normBuf.put(vertex.norm.x).put(vertex.norm.y).put(vertex.norm.z);
        }
        if (tangBuf != null) {
            tangBuf.put(vertex.tang4d.x).put(vertex.tang4d.y).put(vertex.tang4d.z).put(vertex.tang4d.w);
        }
        if (uv0Buf != null) {
            uv0Buf.put(vertex.uv0.x).put(vertex.uv0.y);
        }
        if (uv1Buf != null) {
            uv1Buf.put(vertex.uv1.x).put(vertex.uv1.y);
        }
        if (colorBuf != null) {
            colorBuf.putInt(vertex.color.asIntABGR());
        }
        if (boneIndices != null) {
            if (vertex.boneWeightsIndices != null) {
                if (vertex.boneWeightsIndices.length > 4) {
                    throw new UnsupportedOperationException("Mesh uses more than 4 weights per bone. " + "Call trimBoneWeights() to allieviate this");
                }
                for (int i = 0; i < vertex.boneWeightsIndices.length; i++) {
                    boneIndices.put((byte) (vertex.boneWeightsIndices[i].boneIndex & 0xFF));
                    boneWeights.put(vertex.boneWeightsIndices[i].boneWeight);
                }
                for (int i = 0; i < 4 - vertex.boneWeightsIndices.length; i++) {
                    boneIndices.put((byte) 0);
                    boneWeights.put(0f);
                }
            } else {
                boneIndices.putInt(0);
                boneWeights.put(0f).put(0f).put(0f).put(0f);
            }
            maxBonesPerVertex = Math.max(maxBonesPerVertex, vertex.boneWeightsIndices.length);
        }
    }
    for (int i = 0; i < indexes.size(); i++) {
        indexBuf.put(i, indexes.get(i));
    }
    jmeMesh.updateCounts();
    jmeMesh.updateBound();
    if (boneIndices != null) {
        jmeMesh.setMaxNumWeights(maxBonesPerVertex);
        jmeMesh.prepareForAnim(true);
        jmeMesh.generateBindPose(true);
    }
    return jmeMesh;
}
Also used : HashMap(java.util.HashMap) VertexBuffer(com.jme3.scene.VertexBuffer) ArrayList(java.util.ArrayList) Mesh(com.jme3.scene.Mesh) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IndexShortBuffer(com.jme3.scene.mesh.IndexShortBuffer) IndexIntBuffer(com.jme3.scene.mesh.IndexIntBuffer) IndexIntBuffer(com.jme3.scene.mesh.IndexIntBuffer) IntBuffer(java.nio.IntBuffer) IndexShortBuffer(com.jme3.scene.mesh.IndexShortBuffer) ShortBuffer(java.nio.ShortBuffer)

Aggregations

IndexBuffer (com.jme3.scene.mesh.IndexBuffer)21 FloatBuffer (java.nio.FloatBuffer)21 IntBuffer (java.nio.IntBuffer)10 ShortBuffer (java.nio.ShortBuffer)10 Buffer (java.nio.Buffer)9 VertexBuffer (com.jme3.scene.VertexBuffer)5 Vector3f (com.jme3.math.Vector3f)4 Mesh (com.jme3.scene.Mesh)3 ByteBuffer (java.nio.ByteBuffer)3 ArrayList (java.util.ArrayList)3 IndexedMesh (com.bulletphysics.collision.shapes.IndexedMesh)2 Vector2f (com.jme3.math.Vector2f)2 IndexIntBuffer (com.jme3.scene.mesh.IndexIntBuffer)2 IndexShortBuffer (com.jme3.scene.mesh.IndexShortBuffer)2 HashMap (java.util.HashMap)2 Matrix4f (com.jme3.math.Matrix4f)1 Spline (com.jme3.math.Spline)1 Vector4f (com.jme3.math.Vector4f)1 Mode (com.jme3.scene.Mesh.Mode)1 CullHint (com.jme3.scene.Spatial.CullHint)1