Search in sources :

Example 11 with IndexBuffer

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

the class CurvesTemporalMesh method loadNurbSurface.

/**
     * This method loads the NURBS curve or surface.
     * @param nurb
     *            the NURBS data structure
     * @throws BlenderFileException
     *             an exception is thrown when problems with reading occur
     */
@SuppressWarnings("unchecked")
private void loadNurbSurface(Structure nurb, int materialIndex) throws BlenderFileException {
    // loading the knots
    List<Float>[] knots = new List[2];
    Pointer[] pKnots = new Pointer[] { (Pointer) nurb.getFieldValue("knotsu"), (Pointer) nurb.getFieldValue("knotsv") };
    for (int i = 0; i < knots.length; ++i) {
        if (pKnots[i].isNotNull()) {
            FileBlockHeader fileBlockHeader = blenderContext.getFileBlock(pKnots[i].getOldMemoryAddress());
            BlenderInputStream blenderInputStream = blenderContext.getInputStream();
            blenderInputStream.setPosition(fileBlockHeader.getBlockPosition());
            int knotsAmount = fileBlockHeader.getCount() * fileBlockHeader.getSize() / 4;
            knots[i] = new ArrayList<Float>(knotsAmount);
            for (int j = 0; j < knotsAmount; ++j) {
                knots[i].add(Float.valueOf(blenderInputStream.readFloat()));
            }
        }
    }
    // loading the flags and orders (basis functions degrees)
    int flag = ((Number) nurb.getFieldValue("flag")).intValue();
    boolean smooth = (flag & FLAG_SMOOTH) != 0;
    int flagU = ((Number) nurb.getFieldValue("flagu")).intValue();
    int flagV = ((Number) nurb.getFieldValue("flagv")).intValue();
    int orderU = ((Number) nurb.getFieldValue("orderu")).intValue();
    int orderV = ((Number) nurb.getFieldValue("orderv")).intValue();
    // loading control points and their weights
    int pntsU = ((Number) nurb.getFieldValue("pntsu")).intValue();
    int pntsV = ((Number) nurb.getFieldValue("pntsv")).intValue();
    List<Structure> bPoints = ((Pointer) nurb.getFieldValue("bp")).fetchData();
    List<List<Vector4f>> controlPoints = new ArrayList<List<Vector4f>>(pntsV);
    for (int i = 0; i < pntsV; ++i) {
        List<Vector4f> uControlPoints = new ArrayList<Vector4f>(pntsU);
        for (int j = 0; j < pntsU; ++j) {
            DynamicArray<Float> vec = (DynamicArray<Float>) bPoints.get(j + i * pntsU).getFieldValue("vec");
            if (blenderContext.getBlenderKey().isFixUpAxis()) {
                uControlPoints.add(new Vector4f(vec.get(0).floatValue(), vec.get(2).floatValue(), -vec.get(1).floatValue(), vec.get(3).floatValue()));
            } else {
                uControlPoints.add(new Vector4f(vec.get(0).floatValue(), vec.get(1).floatValue(), vec.get(2).floatValue(), vec.get(3).floatValue()));
            }
        }
        if ((flagU & 0x01) != 0) {
            for (int k = 0; k < orderU - 1; ++k) {
                uControlPoints.add(uControlPoints.get(k));
            }
        }
        controlPoints.add(uControlPoints);
    }
    if ((flagV & 0x01) != 0) {
        for (int k = 0; k < orderV - 1; ++k) {
            controlPoints.add(controlPoints.get(k));
        }
    }
    int originalVerticesAmount = vertices.size();
    int resolu = ((Number) nurb.getFieldValue("resolu")).intValue();
    if (knots[1] == null) {
        // creating the NURB curve
        Curve curve = new Curve(new Spline(controlPoints.get(0), knots[0]), resolu);
        FloatBuffer vertsBuffer = (FloatBuffer) curve.getBuffer(Type.Position).getData();
        beziers.add(new BezierLine(BufferUtils.getVector3Array(vertsBuffer), materialIndex, smooth, false));
    } else {
        // creating the NURB surface
        int resolv = ((Number) nurb.getFieldValue("resolv")).intValue();
        int uSegments = resolu * controlPoints.get(0).size() - 1;
        int vSegments = resolv * controlPoints.size() - 1;
        Surface nurbSurface = Surface.createNurbsSurface(controlPoints, knots, uSegments, vSegments, orderU, orderV, smooth);
        FloatBuffer vertsBuffer = (FloatBuffer) nurbSurface.getBuffer(Type.Position).getData();
        vertices.addAll(Arrays.asList(BufferUtils.getVector3Array(vertsBuffer)));
        FloatBuffer normalsBuffer = (FloatBuffer) nurbSurface.getBuffer(Type.Normal).getData();
        normals.addAll(Arrays.asList(BufferUtils.getVector3Array(normalsBuffer)));
        IndexBuffer indexBuffer = nurbSurface.getIndexBuffer();
        for (int i = 0; i < indexBuffer.size(); i += 3) {
            int index1 = indexBuffer.get(i) + originalVerticesAmount;
            int index2 = indexBuffer.get(i + 1) + originalVerticesAmount;
            int index3 = indexBuffer.get(i + 2) + originalVerticesAmount;
            faces.add(new Face(new Integer[] { index1, index2, index3 }, smooth, materialIndex, null, null, this));
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Pointer(com.jme3.scene.plugins.blender.file.Pointer) FloatBuffer(java.nio.FloatBuffer) Spline(com.jme3.math.Spline) Surface(com.jme3.scene.shape.Surface) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) Vector4f(com.jme3.math.Vector4f) ArrayList(java.util.ArrayList) List(java.util.List) BlenderInputStream(com.jme3.scene.plugins.blender.file.BlenderInputStream) Structure(com.jme3.scene.plugins.blender.file.Structure) Face(com.jme3.scene.plugins.blender.meshes.Face) FileBlockHeader(com.jme3.scene.plugins.blender.file.FileBlockHeader) Curve(com.jme3.scene.shape.Curve) DynamicArray(com.jme3.scene.plugins.blender.file.DynamicArray)

Example 12 with IndexBuffer

use of com.jme3.scene.mesh.IndexBuffer 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 13 with IndexBuffer

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

the class TangentBinormalGenerator method processTriangleFan.

private static List<VertexData> processTriangleFan(Mesh mesh, int[] index, Vector3f[] v, Vector2f[] t) {
    IndexBuffer indexBuffer = mesh.getIndexBuffer();
    FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
    FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData();
    List<VertexData> vertices = initVertexData(vertexBuffer.limit() / 3);
    index[0] = indexBuffer.get(0);
    index[1] = indexBuffer.get(1);
    populateFromBuffer(v[0], vertexBuffer, index[0]);
    populateFromBuffer(v[1], vertexBuffer, index[1]);
    populateFromBuffer(t[0], textureBuffer, index[0]);
    populateFromBuffer(t[1], textureBuffer, index[1]);
    for (int i = 2; i < vertexBuffer.limit() / 3; i++) {
        index[2] = indexBuffer.get(i);
        populateFromBuffer(v[2], vertexBuffer, index[2]);
        populateFromBuffer(t[2], textureBuffer, index[2]);
        TriangleData triData = processTriangle(index, v, t);
        vertices.get(index[0]).triangles.add(triData);
        vertices.get(index[1]).triangles.add(triData);
        vertices.get(index[2]).triangles.add(triData);
        Vector3f vTemp = v[1];
        v[1] = v[2];
        v[2] = vTemp;
        Vector2f tTemp = t[1];
        t[1] = t[2];
        t[2] = tTemp;
        index[1] = index[2];
    }
    return vertices;
}
Also used : IndexBuffer(com.jme3.scene.mesh.IndexBuffer) Vector2f(com.jme3.math.Vector2f) Vector3f(com.jme3.math.Vector3f) FloatBuffer(java.nio.FloatBuffer)

Example 14 with IndexBuffer

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

the class OBJLoader method constructMesh.

protected Mesh constructMesh(ArrayList<Face> faceList) {
    Mesh m = new Mesh();
    m.setMode(Mode.Triangles);
    boolean hasTexCoord = false;
    boolean hasNormals = false;
    ArrayList<Face> newFaces = new ArrayList<Face>(faceList.size());
    for (int i = 0; i < faceList.size(); i++) {
        Face f = faceList.get(i);
        for (Vertex v : f.verticies) {
            findVertexIndex(v);
            if (!hasTexCoord && v.vt != null)
                hasTexCoord = true;
            if (!hasNormals && v.vn != null)
                hasNormals = true;
        }
        if (f.verticies.length == 4) {
            Face[] t = quadToTriangle(f);
            newFaces.add(t[0]);
            newFaces.add(t[1]);
        } else {
            newFaces.add(f);
        }
    }
    FloatBuffer posBuf = BufferUtils.createFloatBuffer(vertIndexMap.size() * 3);
    FloatBuffer normBuf = null;
    FloatBuffer tcBuf = null;
    if (hasNormals) {
        normBuf = BufferUtils.createFloatBuffer(vertIndexMap.size() * 3);
        m.setBuffer(VertexBuffer.Type.Normal, 3, normBuf);
    }
    if (hasTexCoord) {
        tcBuf = BufferUtils.createFloatBuffer(vertIndexMap.size() * 2);
        m.setBuffer(VertexBuffer.Type.TexCoord, 2, tcBuf);
    }
    IndexBuffer indexBuf = null;
    if (vertIndexMap.size() >= 65536) {
        // too many verticies: use intbuffer instead of shortbuffer
        IntBuffer ib = BufferUtils.createIntBuffer(newFaces.size() * 3);
        m.setBuffer(VertexBuffer.Type.Index, 3, ib);
        indexBuf = new IndexIntBuffer(ib);
    } else {
        ShortBuffer sb = BufferUtils.createShortBuffer(newFaces.size() * 3);
        m.setBuffer(VertexBuffer.Type.Index, 3, sb);
        indexBuf = new IndexShortBuffer(sb);
    }
    int numFaces = newFaces.size();
    for (int i = 0; i < numFaces; i++) {
        Face f = newFaces.get(i);
        if (f.verticies.length != 3)
            continue;
        Vertex v0 = f.verticies[0];
        Vertex v1 = f.verticies[1];
        Vertex v2 = f.verticies[2];
        posBuf.position(v0.index * 3);
        posBuf.put(v0.v.x).put(v0.v.y).put(v0.v.z);
        posBuf.position(v1.index * 3);
        posBuf.put(v1.v.x).put(v1.v.y).put(v1.v.z);
        posBuf.position(v2.index * 3);
        posBuf.put(v2.v.x).put(v2.v.y).put(v2.v.z);
        if (normBuf != null) {
            if (v0.vn != null) {
                normBuf.position(v0.index * 3);
                normBuf.put(v0.vn.x).put(v0.vn.y).put(v0.vn.z);
                normBuf.position(v1.index * 3);
                normBuf.put(v1.vn.x).put(v1.vn.y).put(v1.vn.z);
                normBuf.position(v2.index * 3);
                normBuf.put(v2.vn.x).put(v2.vn.y).put(v2.vn.z);
            }
        }
        if (tcBuf != null) {
            if (v0.vt != null) {
                tcBuf.position(v0.index * 2);
                tcBuf.put(v0.vt.x).put(v0.vt.y);
                tcBuf.position(v1.index * 2);
                tcBuf.put(v1.vt.x).put(v1.vt.y);
                tcBuf.position(v2.index * 2);
                tcBuf.put(v2.vt.x).put(v2.vt.y);
            }
        }
        // current face * 3 = current index
        int index = i * 3;
        indexBuf.put(index, v0.index);
        indexBuf.put(index + 1, v1.index);
        indexBuf.put(index + 2, v2.index);
    }
    m.setBuffer(VertexBuffer.Type.Position, 3, posBuf);
    // index buffer and others were set on creation
    m.setStatic();
    m.updateBound();
    m.updateCounts();
    //m.setInterleaved();
    // clear data generated face statements
    // to prepare for next mesh
    vertIndexMap.clear();
    indexVertMap.clear();
    curIndex = 0;
    return m;
}
Also used : FloatBuffer(java.nio.FloatBuffer) 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)

Example 15 with IndexBuffer

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

the class LodGenerator method gatherIndexData.

private void gatherIndexData(Mesh mesh, List<Vertex> vertexLookup) {
    VertexBuffer indexBuffer = mesh.getBuffer(VertexBuffer.Type.Index);
    indexCount = indexBuffer.getNumElements() * 3;
    Buffer b = indexBuffer.getDataReadOnly();
    b.rewind();
    while (b.remaining() != 0) {
        Triangle tri = new Triangle();
        tri.isRemoved = false;
        triangleList.add(tri);
        for (int i = 0; i < 3; i++) {
            if (b instanceof IntBuffer) {
                tri.vertexId[i] = ((IntBuffer) b).get();
            } else {
                //bit shift to avoid negative values due to conversion form short to int.
                //we need an unsigned int here.
                tri.vertexId[i] = ((ShortBuffer) b).get() & 0xffff;
            }
            // assert (tri.vertexId[i] < vertexLookup.size());
            tri.vertex[i] = vertexLookup.get(tri.vertexId[i]);
            //debug only;
            tri.vertex[i].index = tri.vertexId[i];
        }
        if (tri.isMalformed()) {
            if (!tri.isRemoved) {
                logger.log(Level.FINE, "malformed triangle found with ID:{0}\n{1} It will be excluded from Lod level calculations.", new Object[] { triangleList.indexOf(tri), tri.toString() });
                tri.isRemoved = true;
                indexCount -= 3;
            }
        } else {
            tri.computeNormal();
            addTriangleToEdges(tri);
        }
    }
    b.rewind();
}
Also used : VertexBuffer(com.jme3.scene.VertexBuffer) FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer) IntBuffer(java.nio.IntBuffer) Buffer(java.nio.Buffer) VertexBuffer(com.jme3.scene.VertexBuffer) IntBuffer(java.nio.IntBuffer) 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