Search in sources :

Example 1 with Buffer

use of java.nio.Buffer in project jmonkeyengine by jMonkeyEngine.

the class TangentBinormalGenerator method splitVertices.

//Don't remove splitmirorred boolean,It's not used right now, but i intend to
//make this method also split vertice with rotated tangent space and I'll
//add another splitRotated boolean 
private static List<VertexData> splitVertices(Mesh mesh, List<VertexData> vertexData, boolean splitMirorred) {
    int nbVertices = mesh.getBuffer(Type.Position).getNumElements();
    List<VertexData> newVertices = new ArrayList<VertexData>();
    Map<Integer, Integer> indiceMap = new HashMap<Integer, Integer>();
    FloatBuffer normalBuffer = mesh.getFloatBuffer(Type.Normal);
    for (int i = 0; i < vertexData.size(); i++) {
        ArrayList<TriangleData> triangles = vertexData.get(i).triangles;
        Vector3f givenNormal = new Vector3f();
        populateFromBuffer(givenNormal, normalBuffer, i);
        ArrayList<TriangleData> trianglesUp = new ArrayList<TriangleData>();
        ArrayList<TriangleData> trianglesDown = new ArrayList<TriangleData>();
        for (int j = 0; j < triangles.size(); j++) {
            TriangleData triangleData = triangles.get(j);
            if (parity(givenNormal, triangleData.normal) > 0) {
                trianglesUp.add(triangleData);
            } else {
                trianglesDown.add(triangleData);
            }
        }
        //if the vertex has triangles with opposite parity it has to be split
        if (!trianglesUp.isEmpty() && !trianglesDown.isEmpty()) {
            log.log(Level.FINE, "Splitting vertex {0}", i);
            //assigning triangle with the same parity to the original vertex
            vertexData.get(i).triangles.clear();
            vertexData.get(i).triangles.addAll(trianglesUp);
            //creating a new vertex
            VertexData newVert = new VertexData();
            //assigning triangles with opposite parity to it
            newVert.triangles.addAll(trianglesDown);
            newVertices.add(newVert);
            //keep vertex index to fix the index buffers later
            indiceMap.put(nbVertices, i);
            for (TriangleData tri : newVert.triangles) {
                for (int j = 0; j < tri.index.length; j++) {
                    if (tri.index[j] == i) {
                        tri.index[j] = nbVertices;
                    }
                }
            }
            nbVertices++;
        }
    }
    if (!newVertices.isEmpty()) {
        //we have new vertices, we need to update the mesh's buffers.
        for (Type type : VertexBuffer.Type.values()) {
            //skip tangent buffer as we're gonna overwrite it later
            if (type == Type.Tangent || type == Type.BindPoseTangent)
                continue;
            VertexBuffer vb = mesh.getBuffer(type);
            //They'll be initialized when Hardware Skinning is engaged
            if (vb == null || vb.getNumComponents() == 0)
                continue;
            Buffer buffer = vb.getData();
            //IndexBuffer has special treatement, only swapping the vertex indices is needed                
            if (type == Type.Index) {
                boolean isShortBuffer = vb.getFormat() == VertexBuffer.Format.UnsignedShort;
                for (VertexData vertex : newVertices) {
                    for (TriangleData tri : vertex.triangles) {
                        for (int i = 0; i < tri.index.length; i++) {
                            if (isShortBuffer) {
                                ((ShortBuffer) buffer).put(tri.triangleOffset + i, (short) tri.index[i]);
                            } else {
                                ((IntBuffer) buffer).put(tri.triangleOffset + i, tri.index[i]);
                            }
                        }
                    }
                }
                vb.setUpdateNeeded();
            } else {
                //copy the buffer in a bigger one and append nex vertices to the end
                Buffer newVerts = VertexBuffer.createBuffer(vb.getFormat(), vb.getNumComponents(), nbVertices);
                if (buffer != null) {
                    buffer.rewind();
                    bulkPut(vb.getFormat(), newVerts, buffer);
                    int index = vertexData.size();
                    newVerts.position(vertexData.size() * vb.getNumComponents());
                    for (int j = 0; j < newVertices.size(); j++) {
                        int oldInd = indiceMap.get(index);
                        for (int i = 0; i < vb.getNumComponents(); i++) {
                            putValue(vb.getFormat(), newVerts, buffer, oldInd * vb.getNumComponents() + i);
                        }
                        index++;
                    }
                    vb.updateData(newVerts);
                    //destroy previous buffer as it's no longer needed
                    destroyDirectBuffer(buffer);
                }
            }
        }
        vertexData.addAll(newVertices);
        mesh.updateCounts();
    }
    return vertexData;
}
Also used : FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) ByteBuffer(java.nio.ByteBuffer) IntBuffer(java.nio.IntBuffer) Buffer(java.nio.Buffer) DoubleBuffer(java.nio.DoubleBuffer) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) FloatBuffer(java.nio.FloatBuffer) Type(com.jme3.scene.VertexBuffer.Type) Vector3f(com.jme3.math.Vector3f) IntBuffer(java.nio.IntBuffer) ShortBuffer(java.nio.ShortBuffer)

Example 2 with Buffer

use of java.nio.Buffer 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 3 with Buffer

use of java.nio.Buffer 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 4 with Buffer

use of java.nio.Buffer 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 5 with Buffer

use of java.nio.Buffer in project jmonkeyengine by jMonkeyEngine.

the class ObjectHelper method flipMeshIfRequired.

/**
     * The method flips the mesh if the scale is mirroring it. Mirroring scale has either 1 or all 3 factors negative.
     * If two factors are negative then there is no mirroring because a rotation and translation can be found that will
     * lead to the same transform when all scales are positive.
     * 
     * @param geometry
     *            the geometry that is being flipped if necessary
     * @param scale
     *            the scale vector of the given geometry
     */
private void flipMeshIfRequired(Geometry geometry, Vector3f scale) {
    float s = scale.x * scale.y * scale.z;
    if (s < 0 && geometry.getMesh() != null) {
        // negative s means that the scale is mirroring the object
        FloatBuffer normals = geometry.getMesh().getFloatBuffer(Type.Normal);
        if (normals != null) {
            for (int i = 0; i < normals.limit(); i += 3) {
                if (scale.x < 0) {
                    normals.put(i, -normals.get(i));
                }
                if (scale.y < 0) {
                    normals.put(i + 1, -normals.get(i + 1));
                }
                if (scale.z < 0) {
                    normals.put(i + 2, -normals.get(i + 2));
                }
            }
        }
        if (geometry.getMesh().getMode() == Mode.Triangles) {
            // there is no need to flip the indexes for lines and points
            LOGGER.finer("Flipping index order in triangle mesh.");
            Buffer indexBuffer = geometry.getMesh().getBuffer(Type.Index).getData();
            for (int i = 0; i < indexBuffer.limit(); i += 3) {
                if (indexBuffer instanceof ShortBuffer) {
                    short index = ((ShortBuffer) indexBuffer).get(i + 1);
                    ((ShortBuffer) indexBuffer).put(i + 1, ((ShortBuffer) indexBuffer).get(i + 2));
                    ((ShortBuffer) indexBuffer).put(i + 2, index);
                } else {
                    int index = ((IntBuffer) indexBuffer).get(i + 1);
                    ((IntBuffer) indexBuffer).put(i + 1, ((IntBuffer) indexBuffer).get(i + 2));
                    ((IntBuffer) indexBuffer).put(i + 2, index);
                }
            }
        }
    }
}
Also used : FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer) IntBuffer(java.nio.IntBuffer) Buffer(java.nio.Buffer) IntBuffer(java.nio.IntBuffer) FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer) CullHint(com.jme3.scene.Spatial.CullHint)

Aggregations

Buffer (java.nio.Buffer)134 ByteBuffer (java.nio.ByteBuffer)121 IntBuffer (java.nio.IntBuffer)28 Test (org.junit.Test)21 FloatBuffer (java.nio.FloatBuffer)20 ShortBuffer (java.nio.ShortBuffer)18 CharBuffer (java.nio.CharBuffer)13 InvalidMarkException (java.nio.InvalidMarkException)12 IOException (java.io.IOException)10 DoubleBuffer (java.nio.DoubleBuffer)9 IndexBuffer (com.jme3.scene.mesh.IndexBuffer)7 LongBuffer (java.nio.LongBuffer)7 VertexBuffer (com.jme3.scene.VertexBuffer)4 HashMap (java.util.HashMap)4 ByteBufNIO (org.bson.ByteBufNIO)4 SocketChannel (java.nio.channels.SocketChannel)3 GenericRecord (org.apache.avro.generic.GenericRecord)3 DataBuffer (org.nd4j.linalg.api.buffer.DataBuffer)3 Type (com.jme3.scene.VertexBuffer.Type)2 BufferUnderflowException (java.nio.BufferUnderflowException)2