Search in sources :

Example 1 with Triangle

use of com.jme3.math.Triangle in project jmonkeyengine by jMonkeyEngine.

the class MikktspaceTangentGenerator method generateTSpaces.

static boolean generateTSpaces(TSpace[] psTspace, final TriInfo[] pTriInfos, final Group[] pGroups, final int iNrActiveGroups, final int[] piTriListIn, final float fThresCos, final MikkTSpaceContext mikkTSpace) {
    TSpace[] pSubGroupTspace;
    SubGroup[] pUniSubGroups;
    int[] pTmpMembers;
    int iMaxNrFaces = 0, iUniqueTspaces = 0, g = 0, i = 0;
    for (g = 0; g < iNrActiveGroups; g++) {
        if (iMaxNrFaces < pGroups[g].nrFaces) {
            iMaxNrFaces = pGroups[g].nrFaces;
        }
    }
    if (iMaxNrFaces == 0) {
        return true;
    }
    // make initial allocations
    pSubGroupTspace = new TSpace[iMaxNrFaces];
    pUniSubGroups = new SubGroup[iMaxNrFaces];
    pTmpMembers = new int[iMaxNrFaces];
    iUniqueTspaces = 0;
    for (g = 0; g < iNrActiveGroups; g++) {
        final Group pGroup = pGroups[g];
        int iUniqueSubGroups = 0, s = 0;
        for (// triangles
        i = 0; // triangles
        i < pGroup.nrFaces; // triangles
        i++) {
            // triangle number
            final int f = pGroup.faceIndices.get(i);
            int index = -1, iVertIndex = -1, iOF_1 = -1, iMembers = 0, j = 0, l = 0;
            SubGroup tmp_group = new SubGroup();
            boolean bFound;
            Vector3f n, vOs, vOt;
            if (pTriInfos[f].assignedGroup[0] == pGroup) {
                index = 0;
            } else if (pTriInfos[f].assignedGroup[1] == pGroup) {
                index = 1;
            } else if (pTriInfos[f].assignedGroup[2] == pGroup) {
                index = 2;
            }
            assert (index >= 0 && index < 3);
            iVertIndex = piTriListIn[f * 3 + index];
            assert (iVertIndex == pGroup.vertexRepresentitive);
            // is normalized already
            n = getNormal(mikkTSpace, iVertIndex);
            // project
            vOs = pTriInfos[f].os.subtract(n.mult(n.dot(pTriInfos[f].os)));
            vOt = pTriInfos[f].ot.subtract(n.mult(n.dot(pTriInfos[f].ot)));
            vOs.normalizeLocal();
            vOt.normalizeLocal();
            // original face number
            iOF_1 = pTriInfos[f].orgFaceNumber;
            iMembers = 0;
            for (j = 0; j < pGroup.nrFaces; j++) {
                // triangle number
                final int t = pGroup.faceIndices.get(j);
                final int iOF_2 = pTriInfos[t].orgFaceNumber;
                // project
                Vector3f vOs2 = pTriInfos[t].os.subtract(n.mult(n.dot(pTriInfos[t].os)));
                Vector3f vOt2 = pTriInfos[t].ot.subtract(n.mult(n.dot(pTriInfos[t].ot)));
                vOs2.normalizeLocal();
                vOt2.normalizeLocal();
                {
                    final boolean bAny = ((pTriInfos[f].flag | pTriInfos[t].flag) & GROUP_WITH_ANY) != 0;
                    // make sure triangles which belong to the same quad are joined.
                    final boolean bSameOrgFace = iOF_1 == iOF_2;
                    final float fCosS = vOs.dot(vOs2);
                    final float fCosT = vOt.dot(vOt2);
                    // sanity check
                    assert (f != t || bSameOrgFace);
                    if (bAny || bSameOrgFace || (fCosS > fThresCos && fCosT > fThresCos)) {
                        pTmpMembers[iMembers++] = t;
                    }
                }
            }
            // sort pTmpMembers
            tmp_group.nrFaces = iMembers;
            tmp_group.triMembers = pTmpMembers;
            if (iMembers > 1) {
                quickSort(pTmpMembers, 0, iMembers - 1, INTERNAL_RND_SORT_SEED);
            }
            // look for an existing match
            bFound = false;
            l = 0;
            while (l < iUniqueSubGroups && !bFound) {
                bFound = compareSubGroups(tmp_group, pUniSubGroups[l]);
                if (!bFound) {
                    ++l;
                }
            }
            // assign tangent space index
            assert (bFound || l == iUniqueSubGroups);
            // if no match was found we allocate a new subgroup
            if (!bFound) {
                // insert new subgroup
                int[] pIndices = new int[iMembers];
                pUniSubGroups[iUniqueSubGroups] = new SubGroup();
                pUniSubGroups[iUniqueSubGroups].nrFaces = iMembers;
                pUniSubGroups[iUniqueSubGroups].triMembers = pIndices;
                System.arraycopy(tmp_group.triMembers, 0, pIndices, 0, iMembers);
                //memcpy(pIndices, tmp_group.pTriMembers, iMembers*sizeof(int));
                pSubGroupTspace[iUniqueSubGroups] = evalTspace(tmp_group.triMembers, iMembers, piTriListIn, pTriInfos, mikkTSpace, pGroup.vertexRepresentitive);
                ++iUniqueSubGroups;
            }
            // output tspace
            {
                final int iOffs = pTriInfos[f].tSpacesOffs;
                final int iVert = pTriInfos[f].vertNum[index];
                TSpace pTS_out = psTspace[iOffs + iVert];
                assert (pTS_out.counter < 2);
                assert (((pTriInfos[f].flag & ORIENT_PRESERVING) != 0) == pGroup.orientPreservering);
                if (pTS_out.counter == 1) {
                    pTS_out.set(avgTSpace(pTS_out, pSubGroupTspace[l]));
                    // update counter
                    pTS_out.counter = 2;
                    pTS_out.orient = pGroup.orientPreservering;
                } else {
                    assert (pTS_out.counter == 0);
                    pTS_out.set(pSubGroupTspace[l]);
                    // update counter
                    pTS_out.counter = 1;
                    pTS_out.orient = pGroup.orientPreservering;
                }
            }
        }
        iUniqueTspaces += iUniqueSubGroups;
    }
    return true;
}
Also used : Vector3f(com.jme3.math.Vector3f)

Example 2 with Triangle

use of com.jme3.math.Triangle in project jmonkeyengine by jMonkeyEngine.

the class MikktspaceTangentGenerator method initTriInfo.

static void initTriInfo(TriInfo[] pTriInfos, final int[] piTriListIn, final MikkTSpaceContext mikkTSpace, final int iNrTrianglesIn) {
    // generate neighbor info list
    for (int f = 0; f < iNrTrianglesIn; f++) {
        for (int i = 0; i < 3; i++) {
            pTriInfos[f].faceNeighbors[i] = -1;
            pTriInfos[f].assignedGroup[i] = null;
            pTriInfos[f].os.x = 0.0f;
            pTriInfos[f].os.y = 0.0f;
            pTriInfos[f].os.z = 0.0f;
            pTriInfos[f].ot.x = 0.0f;
            pTriInfos[f].ot.y = 0.0f;
            pTriInfos[f].ot.z = 0.0f;
            pTriInfos[f].magS = 0;
            pTriInfos[f].magT = 0;
            // assumed bad
            pTriInfos[f].flag |= GROUP_WITH_ANY;
        }
    }
    // evaluate first order derivatives
    for (int f = 0; f < iNrTrianglesIn; f++) {
        // initial values
        final Vector3f v1 = getPosition(mikkTSpace, piTriListIn[f * 3 + 0]);
        final Vector3f v2 = getPosition(mikkTSpace, piTriListIn[f * 3 + 1]);
        final Vector3f v3 = getPosition(mikkTSpace, piTriListIn[f * 3 + 2]);
        final Vector3f t1 = getTexCoord(mikkTSpace, piTriListIn[f * 3 + 0]);
        final Vector3f t2 = getTexCoord(mikkTSpace, piTriListIn[f * 3 + 1]);
        final Vector3f t3 = getTexCoord(mikkTSpace, piTriListIn[f * 3 + 2]);
        final float t21x = t2.x - t1.x;
        final float t21y = t2.y - t1.y;
        final float t31x = t3.x - t1.x;
        final float t31y = t3.y - t1.y;
        final Vector3f d1 = v2.subtract(v1);
        final Vector3f d2 = v3.subtract(v1);
        final float fSignedAreaSTx2 = t21x * t31y - t21y * t31x;
        //assert(fSignedAreaSTx2!=0);
        // eq 18
        Vector3f vOs = d1.mult(t31y).subtract(d2.mult(t21y));
        // eq 19
        Vector3f vOt = d1.mult(-t31x).add(d2.mult(t21x));
        pTriInfos[f].flag |= (fSignedAreaSTx2 > 0 ? ORIENT_PRESERVING : 0);
        if (isNotZero(fSignedAreaSTx2)) {
            final float fAbsArea = Math.abs(fSignedAreaSTx2);
            final float fLenOs = vOs.length();
            final float fLenOt = vOt.length();
            final float fS = (pTriInfos[f].flag & ORIENT_PRESERVING) == 0 ? (-1.0f) : 1.0f;
            if (isNotZero(fLenOs)) {
                pTriInfos[f].os = vOs.multLocal(fS / fLenOs);
            }
            if (isNotZero(fLenOt)) {
                pTriInfos[f].ot = vOt.multLocal(fS / fLenOt);
            }
            // evaluate magnitudes prior to normalization of vOs and vOt
            pTriInfos[f].magS = fLenOs / fAbsArea;
            pTriInfos[f].magT = fLenOt / fAbsArea;
            // if this is a good triangle
            if (isNotZero(pTriInfos[f].magS) && isNotZero(pTriInfos[f].magT)) {
                pTriInfos[f].flag &= (~GROUP_WITH_ANY);
            }
        }
    }
    // force otherwise healthy quads to a fixed orientation
    int t = 0;
    while (t < (iNrTrianglesIn - 1)) {
        final int iFO_a = pTriInfos[t].orgFaceNumber;
        final int iFO_b = pTriInfos[t + 1].orgFaceNumber;
        if (iFO_a == iFO_b) {
            // this is a quad
            final boolean bIsDeg_a = (pTriInfos[t].flag & MARK_DEGENERATE) != 0;
            final boolean bIsDeg_b = (pTriInfos[t + 1].flag & MARK_DEGENERATE) != 0;
            // DegenPrologue(), but just in case check bIsDeg_a and bIsDeg_a are false
            if ((bIsDeg_a || bIsDeg_b) == false) {
                final boolean bOrientA = (pTriInfos[t].flag & ORIENT_PRESERVING) != 0;
                final boolean bOrientB = (pTriInfos[t + 1].flag & ORIENT_PRESERVING) != 0;
                // if this happens the quad has extremely bad mapping!!
                if (bOrientA != bOrientB) {
                    //printf("found quad with bad mapping\n");
                    boolean bChooseOrientFirstTri = false;
                    if ((pTriInfos[t + 1].flag & GROUP_WITH_ANY) != 0) {
                        bChooseOrientFirstTri = true;
                    } else if (calcTexArea(mikkTSpace, Arrays.copyOfRange(piTriListIn, t * 3 + 0, t * 3 + 3)) >= calcTexArea(mikkTSpace, Arrays.copyOfRange(piTriListIn, (t + 1) * 3 + 0, (t + 1) * 3 + 3))) {
                        bChooseOrientFirstTri = true;
                    }
                    // force match
                    {
                        final int t0 = bChooseOrientFirstTri ? t : (t + 1);
                        final int t1 = bChooseOrientFirstTri ? (t + 1) : t;
                        // clear first
                        pTriInfos[t1].flag &= (~ORIENT_PRESERVING);
                        // copy bit
                        pTriInfos[t1].flag |= (pTriInfos[t0].flag & ORIENT_PRESERVING);
                    }
                }
            }
            t += 2;
        } else {
            ++t;
        }
    }
    // match up edge pairs
    {
        //Edge * pEdges = (Edge *) malloc(sizeof(Edge)*iNrTrianglesIn*3);
        Edge[] pEdges = new Edge[iNrTrianglesIn * 3];
        //TODO nehon weird... original algorithm check if pEdges is null but it's just been allocated... weirder, it does soemthing different if the edges are null...
        //    if (pEdges==null)
        //      BuildNeighborsSlow(pTriInfos, piTriListIn, iNrTrianglesIn);
        //    else
        //    {
        buildNeighborsFast(pTriInfos, pEdges, piTriListIn, iNrTrianglesIn);
    //    }
    }
}
Also used : Vector3f(com.jme3.math.Vector3f)

Example 3 with Triangle

use of com.jme3.math.Triangle in project jmonkeyengine by jMonkeyEngine.

the class MikktspaceTangentGenerator method DegenEpilogue.

static void DegenEpilogue(TSpace[] psTspace, TriInfo[] pTriInfos, int[] piTriListIn, final MikkTSpaceContext mikkTSpace, final int iNrTrianglesIn, final int iTotTris) {
    // punishment for degenerate triangles is O(N^2)
    for (int t = iNrTrianglesIn; t < iTotTris; t++) {
        // degenerate triangles on a quad with one good triangle are skipped
        // here but processed in the next loop
        final boolean bSkip = (pTriInfos[t].flag & QUAD_ONE_DEGEN_TRI) != 0;
        if (!bSkip) {
            for (int i = 0; i < 3; i++) {
                final int index1 = piTriListIn[t * 3 + i];
                // search through the good triangles
                boolean bNotFound = true;
                int j = 0;
                while (bNotFound && j < (3 * iNrTrianglesIn)) {
                    final int index2 = piTriListIn[j];
                    if (index1 == index2) {
                        bNotFound = false;
                    } else {
                        ++j;
                    }
                }
                if (!bNotFound) {
                    final int iTri = j / 3;
                    final int iVert = j % 3;
                    final int iSrcVert = pTriInfos[iTri].vertNum[iVert];
                    final int iSrcOffs = pTriInfos[iTri].tSpacesOffs;
                    final int iDstVert = pTriInfos[t].vertNum[i];
                    final int iDstOffs = pTriInfos[t].tSpacesOffs;
                    // copy tspace
                    psTspace[iDstOffs + iDstVert] = psTspace[iSrcOffs + iSrcVert];
                }
            }
        }
    }
    // deal with degenerate quads with one good triangle
    for (int t = 0; t < iNrTrianglesIn; t++) {
        // other triangle is degenerate
        if ((pTriInfos[t].flag & QUAD_ONE_DEGEN_TRI) != 0) {
            byte[] pV = pTriInfos[t].vertNum;
            int iFlag = (1 << pV[0]) | (1 << pV[1]) | (1 << pV[2]);
            int iMissingIndex = 0;
            if ((iFlag & 2) == 0) {
                iMissingIndex = 1;
            } else if ((iFlag & 4) == 0) {
                iMissingIndex = 2;
            } else if ((iFlag & 8) == 0) {
                iMissingIndex = 3;
            }
            int iOrgF = pTriInfos[t].orgFaceNumber;
            Vector3f vDstP = getPosition(mikkTSpace, makeIndex(iOrgF, iMissingIndex));
            boolean bNotFound = true;
            int i = 0;
            while (bNotFound && i < 3) {
                final int iVert = pV[i];
                final Vector3f vSrcP = getPosition(mikkTSpace, makeIndex(iOrgF, iVert));
                if (vSrcP.equals(vDstP)) {
                    final int iOffs = pTriInfos[t].tSpacesOffs;
                    psTspace[iOffs + iMissingIndex] = psTspace[iOffs + iVert];
                    bNotFound = false;
                } else {
                    ++i;
                }
            }
            assert (!bNotFound);
        }
    }
}
Also used : Vector3f(com.jme3.math.Vector3f)

Example 4 with Triangle

use of com.jme3.math.Triangle in project jmonkeyengine by jMonkeyEngine.

the class TangentBinormalGenerator method processTriangleData.

private static void processTriangleData(Mesh mesh, List<VertexData> vertices, boolean approxTangent, boolean splitMirrored) {
    ArrayList<VertexInfo> vertexMap = linkVertices(mesh, splitMirrored);
    FloatBuffer tangents = BufferUtils.createFloatBuffer(vertices.size() * 4);
    ColorRGBA[] cols = null;
    if (debug) {
        cols = new ColorRGBA[vertices.size()];
    }
    Vector3f tangent = new Vector3f();
    Vector3f binormal = new Vector3f();
    //Vector3f normal = new Vector3f();
    Vector3f givenNormal = new Vector3f();
    Vector3f tangentUnit = new Vector3f();
    Vector3f binormalUnit = new Vector3f();
    for (int k = 0; k < vertexMap.size(); k++) {
        float wCoord = -1;
        VertexInfo vertexInfo = vertexMap.get(k);
        givenNormal.set(vertexInfo.normal);
        givenNormal.normalizeLocal();
        TriangleData firstTriangle = vertices.get(vertexInfo.indices.get(0)).triangles.get(0);
        // check tangent and binormal consistency
        tangent.set(firstTriangle.tangent);
        tangent.normalizeLocal();
        binormal.set(firstTriangle.binormal);
        binormal.normalizeLocal();
        for (int i : vertexInfo.indices) {
            ArrayList<TriangleData> triangles = vertices.get(i).triangles;
            for (int j = 0; j < triangles.size(); j++) {
                TriangleData triangleData = triangles.get(j);
                tangentUnit.set(triangleData.tangent);
                tangentUnit.normalizeLocal();
                if (tangent.dot(tangentUnit) < toleranceDot) {
                    log.log(Level.WARNING, "Angle between tangents exceeds tolerance " + "for vertex {0}.", i);
                    break;
                }
                if (!approxTangent) {
                    binormalUnit.set(triangleData.binormal);
                    binormalUnit.normalizeLocal();
                    if (binormal.dot(binormalUnit) < toleranceDot) {
                        log.log(Level.WARNING, "Angle between binormals exceeds tolerance " + "for vertex {0}.", i);
                        break;
                    }
                }
            }
        }
        // find average tangent
        tangent.set(0, 0, 0);
        binormal.set(0, 0, 0);
        int triangleCount = 0;
        for (int i : vertexInfo.indices) {
            ArrayList<TriangleData> triangles = vertices.get(i).triangles;
            triangleCount += triangles.size();
            if (debug) {
                cols[i] = ColorRGBA.White;
            }
            for (int j = 0; j < triangles.size(); j++) {
                TriangleData triangleData = triangles.get(j);
                tangent.addLocal(triangleData.tangent);
                binormal.addLocal(triangleData.binormal);
            }
        }
        int blameVertex = vertexInfo.indices.get(0);
        if (tangent.length() < ZERO_TOLERANCE) {
            log.log(Level.WARNING, "Shared tangent is zero for vertex {0}.", blameVertex);
            // attempt to fix from binormal
            if (binormal.length() >= ZERO_TOLERANCE) {
                binormal.cross(givenNormal, tangent);
                tangent.normalizeLocal();
            } else // if all fails use the tangent from the first triangle
            {
                tangent.set(firstTriangle.tangent);
            }
        } else {
            tangent.divideLocal(triangleCount);
        }
        tangentUnit.set(tangent);
        tangentUnit.normalizeLocal();
        if (Math.abs(Math.abs(tangentUnit.dot(givenNormal)) - 1) < ZERO_TOLERANCE) {
            log.log(Level.WARNING, "Normal and tangent are parallel for vertex {0}.", blameVertex);
        }
        if (!approxTangent) {
            if (binormal.length() < ZERO_TOLERANCE) {
                log.log(Level.WARNING, "Shared binormal is zero for vertex {0}.", blameVertex);
                // attempt to fix from tangent
                if (tangent.length() >= ZERO_TOLERANCE) {
                    givenNormal.cross(tangent, binormal);
                    binormal.normalizeLocal();
                } else // if all fails use the binormal from the first triangle
                {
                    binormal.set(firstTriangle.binormal);
                }
            } else {
                binormal.divideLocal(triangleCount);
            }
            binormalUnit.set(binormal);
            binormalUnit.normalizeLocal();
            if (Math.abs(Math.abs(binormalUnit.dot(givenNormal)) - 1) < ZERO_TOLERANCE) {
                log.log(Level.WARNING, "Normal and binormal are parallel for vertex {0}.", blameVertex);
            }
            if (Math.abs(Math.abs(binormalUnit.dot(tangentUnit)) - 1) < ZERO_TOLERANCE) {
                log.log(Level.WARNING, "Tangent and binormal are parallel for vertex {0}.", blameVertex);
            }
        }
        Vector3f finalTangent = new Vector3f();
        Vector3f tmp = new Vector3f();
        for (int i : vertexInfo.indices) {
            if (approxTangent) {
                // Gram-Schmidt orthogonalize
                finalTangent.set(tangent).subtractLocal(tmp.set(givenNormal).multLocal(givenNormal.dot(tangent)));
                finalTangent.normalizeLocal();
                wCoord = tmp.set(givenNormal).crossLocal(tangent).dot(binormal) < 0f ? -1f : 1f;
                tangents.put((i * 4), finalTangent.x);
                tangents.put((i * 4) + 1, finalTangent.y);
                tangents.put((i * 4) + 2, finalTangent.z);
                tangents.put((i * 4) + 3, wCoord);
            } else {
                tangents.put((i * 4), tangent.x);
                tangents.put((i * 4) + 1, tangent.y);
                tangents.put((i * 4) + 2, tangent.z);
                tangents.put((i * 4) + 3, wCoord);
            //setInBuffer(binormal, binormals, i);
            }
        }
    }
    tangents.limit(tangents.capacity());
    // If the model already had a tangent buffer, replace it with the regenerated one
    mesh.clearBuffer(Type.Tangent);
    mesh.setBuffer(Type.Tangent, 4, tangents);
    if (mesh.isAnimated()) {
        mesh.clearBuffer(Type.BindPoseNormal);
        mesh.clearBuffer(Type.BindPosePosition);
        mesh.clearBuffer(Type.BindPoseTangent);
        mesh.generateBindPose(true);
    }
    if (debug) {
        writeColorBuffer(vertices, cols, mesh);
    }
    mesh.updateBound();
    mesh.updateCounts();
}
Also used : ColorRGBA(com.jme3.math.ColorRGBA) Vector3f(com.jme3.math.Vector3f) FloatBuffer(java.nio.FloatBuffer)

Example 5 with Triangle

use of com.jme3.math.Triangle 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)

Aggregations

Vector3f (com.jme3.math.Vector3f)19 Triangle (com.jme3.math.Triangle)9 FloatBuffer (java.nio.FloatBuffer)7 TempVars (com.jme3.util.TempVars)6 CollisionResult (com.jme3.collision.CollisionResult)5 Vector2f (com.jme3.math.Vector2f)5 ShortBuffer (java.nio.ShortBuffer)5 VertexBuffer (com.jme3.scene.VertexBuffer)4 Buffer (java.nio.Buffer)4 IntBuffer (java.nio.IntBuffer)4 ArrayList (java.util.ArrayList)4 Geometry (com.jme3.scene.Geometry)3 BoundingBox (com.jme3.bounding.BoundingBox)2 UnsupportedCollisionException (com.jme3.collision.UnsupportedCollisionException)2 Mesh (com.jme3.scene.Mesh)2 Spatial (com.jme3.scene.Spatial)2 Quad (com.jme3.scene.shape.Quad)2 ByteBuffer (java.nio.ByteBuffer)2 List (java.util.List)2 Test (org.junit.Test)2