Example #1
0
    public void finalizePatches()
    {
        computeVertexToPatchIndexes();
        patchTransforms_ = new PatchTransform_[nPatches_];

        //calculate transforms based on patch centers

        for (int ipatch = 0; ipatch < nPatches_; ++ipatch)
        {
            Patch_ patch = patches_[ipatch];

            //copy first vertex
            patchTransforms_[ipatch].position_ = vertices_[patch.startVertex_];
            patchTransforms_[ipatch].rotation_ = Quaternion.identity;

            for (uint ivert = patch.startVertex_ + 1; ivert < patch.startVertex_ + patch.nVertices_; ++ivert)
            {
                patchTransforms_[ipatch].position_ += vertices_[ivert];
                patchTransforms_[ipatch].position_ /= 2.0f;
            }

            //transform patches
            for (uint ivert = patch.startVertex_ + 0; ivert < patch.startVertex_ + patch.nVertices_; ++ivert)
            {
                vertices_[ivert] -= patchTransforms_[ipatch].position_;
            }
        }
    }
Example #2
0
    public void computeVertexToPatchIndexes()
    {
        vertexToPatchIndex_ = new int[numVertices_];

        for (int ipatch = 0; ipatch < nPatches_; ++ipatch)
        {
            Patch_ patch = patches_[ipatch];

            for (uint ivert = patch.startVertex_; ivert < patch.startVertex_ + patch.nVertices_; ++ivert)
            {
                vertexToPatchIndex_[ivert] = ipatch;
            }
        }
    }
Example #3
0
    static public OptimizedPatchedShape CreateOptimizedPatchedShapeFromPatchedShape(PatchedShape patchedShape)
    {
        uint idxRemapCapacity = 1024;

        uint[] idxRemap = new uint[idxRemapCapacity];

        OptimizedPatchedShape optimizedShape = new OptimizedPatchedShape();

        //allocate optimized shape
        optimizedShape.AllocateShape(patchedShape.numVertices_, patchedShape.numIndices_);
        optimizedShape.numIndices_ = 0; //we will be filling it from beginning

        optimizedShape.patches_  = new Patch_[patchedShape.nPatches_];
        optimizedShape.nPatches_ = patchedShape.nPatches_;

        uint nDstVertices = 0;

        for (uint ipatch = 0; ipatch < patchedShape.nPatches_; ++ipatch)
        {
            Patch_ patch = patchedShape.patches_[ipatch];
            //optimizedShape.patches_[ipatch] = new Patch_();

            if (patch.nVertices_ > idxRemapCapacity)
            {
                idxRemapCapacity = patch.nVertices_;
                idxRemap         = null;
                idxRemap         = new uint[idxRemapCapacity];
            }

            uint dstIndex = nDstVertices;
            uint srcIndex = patch.startVertex_;

            // copy first vertex
            optimizedShape.vertices_[dstIndex] = patchedShape.vertices_[srcIndex];
            optimizedShape.normals_[dstIndex]  = patchedShape.normals_[srcIndex];
            optimizedShape.uvs_[dstIndex]      = patchedShape.uvs_[srcIndex];

            uint nv = 1;
            idxRemap[0] = 0;

            Dictionary <PatchVertex_, uint> vmap = new Dictionary <PatchVertex_, uint>(new PatchVertexComparer_());
            PatchVertex_ v0 = new PatchVertex_(patchedShape.vertices_[srcIndex], patchedShape.normals_[srcIndex], patchedShape.uvs_[srcIndex]);

            vmap[v0] = 0;

            for (uint ivert = 1; ivert < patch.nVertices_; ++ivert)
            {
                PatchVertex_ v = new PatchVertex_(patchedShape.vertices_[srcIndex + ivert], patchedShape.normals_[srcIndex + ivert], patchedShape.uvs_[srcIndex + ivert]);

                uint val = 0;
                if (vmap.TryGetValue(v, out val))
                {
                    idxRemap[ivert] = val;
                }
                else
                {
                    // not found
                    //
                    optimizedShape.vertices_[dstIndex + nv] = patchedShape.vertices_[srcIndex + ivert];
                    optimizedShape.normals_[dstIndex + nv]  = patchedShape.normals_[srcIndex + ivert];
                    optimizedShape.uvs_[dstIndex + nv]      = patchedShape.uvs_[srcIndex + ivert];

                    idxRemap[ivert] = nv;
                    vmap[v]         = nv;

                    ++nv;
                }

                //mesh.vertexToPatchIndex_[ivert] = ipatch;
            }

            for (int i = 0; i < patch.nVertices_; ++i)
            {
                optimizedShape.indices_[optimizedShape.numIndices_] = (int)(idxRemap[i] + nDstVertices);
                optimizedShape.numIndices_++;
            }

            optimizedShape.patches_[ipatch].startVertex_ = nDstVertices;
            optimizedShape.patches_[ipatch].nVertices_   = nv;
            optimizedShape.patches_[ipatch].startIndex_  = patch.startVertex_;
            optimizedShape.patches_[ipatch].nIndices_    = patch.nVertices_;

            nDstVertices += nv;
        }

        idxRemap = null;

        optimizedShape.numVertices_ = (int)nDstVertices;

        return(optimizedShape);
    }
Example #4
0
    void _CreatePatchRecurse(Shape inputShape, ref int targetVerticesCount, ref int nTrianglesInThisPatch, int triangleIdx, bool[] triangleUsed, TriangleAdjacency_[] triAdjacency,
                             ref Patch_ curPatch, int srcTriangleIdx, ref uint dstTriangleIdx)
    {
        if (nTrianglesInThisPatch == 0)
        {
            return;
        }

        triangleUsed[triangleIdx] = true;

        int tri0 = inputShape.indices_[triangleIdx * 3 + 0];
        int tri1 = inputShape.indices_[triangleIdx * 3 + 1];
        int tri2 = inputShape.indices_[triangleIdx * 3 + 2];

        vertices_[targetVerticesCount + 0] = inputShape.vertices_[tri0];
        normals_[targetVerticesCount + 0]  = inputShape.normals_[tri0];
        uvs_[targetVerticesCount + 0]      = inputShape.uvs_[tri0];


        vertices_[targetVerticesCount + 1] = inputShape.vertices_[tri1];
        normals_[targetVerticesCount + 1]  = inputShape.normals_[tri1];
        uvs_[targetVerticesCount + 1]      = inputShape.uvs_[tri1];


        vertices_[targetVerticesCount + 2] = inputShape.vertices_[tri2];
        normals_[targetVerticesCount + 2]  = inputShape.normals_[tri2];
        uvs_[targetVerticesCount + 2]      = inputShape.uvs_[tri2];

        targetVerticesCount += 3;
        curPatch.nVertices_ += 3;
        ++dstTriangleIdx;

        // pick random edges
        //
        int randEdge0_0 = Random.Range(0, 2);
        int randEdge0_1 = wrap_inc(randEdge0_0, 0, 2);

        int randEdge1_0 = Random.Range(0, 2);

        if (randEdge1_0 == randEdge0_0)
        {
            randEdge1_0 = wrap_inc(randEdge1_0, 0, 2);
        }

        int randEdge1_1 = wrap_inc(randEdge1_0, 0, 2);

        int randEdge2_0 = 0;

        while (randEdge2_0 == randEdge0_0 || randEdge2_0 == randEdge1_0)
        {
            randEdge2_0++;
        }

        int randEdge2_1 = wrap_inc(randEdge2_0, 0, 2);

        int numRolledEdges = 3;

        //there's a 10% chance that there will be 2 edges
        //if (Random.Range(1, 10) == 1)
        //    numRolledEdges = 2;

        for (int iedge = 0; iedge < numRolledEdges; iedge++)
        {
            if (nTrianglesInThisPatch > 0)
            {
                int tmpEdge_0 = randEdge0_0;
                int tmpEdge_1 = randEdge0_1;
                if (iedge == 1)
                {
                    tmpEdge_0 = randEdge1_0;
                    tmpEdge_1 = randEdge1_1;
                }
                else if (iedge == 2)
                {
                    tmpEdge_0 = randEdge2_0;
                    tmpEdge_1 = randEdge2_1;
                }

                int randEdge_0 = inputShape.indices_[triangleIdx * 3 + tmpEdge_0];
                int randEdge_1 = inputShape.indices_[triangleIdx * 3 + tmpEdge_1];

                //PICO_ASSERT( randEdge_0 != randEdge_1 );

                // triangles adjacent to first vertex
                //
                TriangleAdjacency_ ta      = triAdjacency[randEdge_0];
                bool secondVertexTraversed = false;
                while (ta != null)
                {
                    uint iinner = ta.triangleIndex_;

                    if (!triangleUsed[iinner])
                    {
                        //int idx0 = inputShape.indices_[iinner * 3 + 0];
                        //int idx1 = inputShape.indices_[iinner * 3 + 1];
                        //int idx2 = inputShape.indices_[iinner * 3 + 2];

                        //if (((randEdge_0 == idx0) || (randEdge_0 == idx1) || (randEdge_0 == idx2))
                        //    && ((randEdge_1 == idx0) || (randEdge_1 == idx1) || (randEdge_1 == idx2))
                        //    )
                        {
                            triangleIdx            = (int)iinner;
                            nTrianglesInThisPatch -= 1;
                            if (nTrianglesInThisPatch > 0)
                            {
                                _CreatePatchRecurse(inputShape, ref targetVerticesCount, ref nTrianglesInThisPatch, triangleIdx, triangleUsed, triAdjacency, ref curPatch, srcTriangleIdx, ref dstTriangleIdx);
                                //    break;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    if (ta.nextTriangle_ != -1)
                    {
                        ta = triAdjacency[ta.nextTriangle_];
                    }
                    else
                    {
                        if (secondVertexTraversed)
                        {
                            ta = null;
                        }
                        else
                        {
                            ta = triAdjacency[randEdge_1];
                            secondVertexTraversed = true;
                        }
                    }
                }
            }
            else
            {
                break;
            }
        }
    }
    static public ExtrudedPatchedShape CreateExtrudedPatchedShapeFromOptimizedPatchedShape(OptimizedPatchedShape optimizedShape, float extrudeAmount)
    {
        //uint idxRemapCapacity = 1024;
        //uint[] idxRemap = new uint[idxRemapCapacity];

        ExtrudedPatchedShape extrudedShape = new ExtrudedPatchedShape();

        //allocate optimized shape
        extrudedShape.AllocateShape(optimizedShape.numVertices_ * 8, optimizedShape.numIndices_ * 12);
        extrudedShape.numIndices_ = 0; //we will be filling it from beginning

        extrudedShape.patches_  = new Patch_[optimizedShape.nPatches_];
        extrudedShape.nPatches_ = optimizedShape.nPatches_;

        uint nDstVertices        = 0;
        uint nDstIndices         = 0;
        int  numberOfNewVertices = 0;

        for (uint ipatch = 0; ipatch < optimizedShape.nPatches_; ++ipatch)
        {
            Patch_ patch = optimizedShape.patches_[ipatch];

            extrudedShape.patches_[ipatch].startVertex_ = nDstVertices;
            extrudedShape.patches_[ipatch].startIndex_  = nDstIndices;

            int lastNumberOfNewVertices = numberOfNewVertices;

            //copy all vertices original vertices
            for (uint ivert = patch.startVertex_; ivert < patch.startVertex_ + patch.nVertices_; ++ivert)
            {
                extrudedShape.vertices_[nDstVertices] = optimizedShape.vertices_[ivert];
                extrudedShape.normals_[nDstVertices]  = optimizedShape.normals_[ivert];
                extrudedShape.uvs_[nDstVertices]      = optimizedShape.uvs_[ivert];

                nDstVertices++;
            }
            //taking care of indices
            for (uint iidx = patch.startIndex_; iidx < patch.startIndex_ + patch.nIndices_; ++iidx)
            {
                extrudedShape.indices_[nDstIndices] = optimizedShape.indices_[iidx] + numberOfNewVertices;

                nDstIndices++;
            }

            //adding extruded vertices
            for (uint ivert = patch.startVertex_; ivert < patch.startVertex_ + patch.nVertices_; ++ivert)
            {
                extrudedShape.vertices_[nDstVertices] = optimizedShape.vertices_[ivert] - extrudeAmount * optimizedShape.normals_[ivert];
                extrudedShape.normals_[nDstVertices]  = -optimizedShape.normals_[ivert];
                extrudedShape.uvs_[nDstVertices]      = optimizedShape.uvs_[ivert];

                nDstVertices++;
                numberOfNewVertices++;
            }

            //adding indices in reverse order
            for (int iidx = (int)(patch.startIndex_ + patch.nIndices_) - 1; iidx >= patch.startIndex_; --iidx)
            {
                extrudedShape.indices_[nDstIndices] = optimizedShape.indices_[iidx] + numberOfNewVertices;

                nDstIndices++;
            }

            //taking care of edge vertices
            //first find all edges of a patch within just one triangle
            Dictionary <Edge_, uint> edges = new Dictionary <Edge_, uint>(new EdgeComparer_());

            for (uint tidx = patch.startIndex_; tidx < patch.startIndex_ + patch.nIndices_; tidx += 3)
            {
                Edge_ e1 = new Edge_(optimizedShape.indices_[tidx + 0], optimizedShape.indices_[tidx + 1]);
                Edge_ e2 = new Edge_(optimizedShape.indices_[tidx + 1], optimizedShape.indices_[tidx + 2]);
                Edge_ e3 = new Edge_(optimizedShape.indices_[tidx + 2], optimizedShape.indices_[tidx + 0]);

                uint val = 0;
                if (edges.TryGetValue(e1, out val))
                {
                    edges[e1] = val + 1;
                }
                else
                {
                    edges[e1] = 1;
                }

                if (edges.TryGetValue(e2, out val))
                {
                    edges[e2] = val + 1;
                }
                else
                {
                    edges[e2] = 1;
                }

                if (edges.TryGetValue(e3, out val))
                {
                    edges[e3] = val + 1;
                }
                else
                {
                    edges[e3] = 1;
                }
            }

            foreach (KeyValuePair <Edge_, uint> entry in edges)
            {
                if (entry.Value == 1)
                {
                    //add this edge to extruded geometry

                    //we need to duplicate 4 vertices because of new normals
                    //these are:
                    int v1 = entry.Key.v1_ + lastNumberOfNewVertices;
                    int v2 = entry.Key.v2_ + lastNumberOfNewVertices;
                    int v3 = entry.Key.v1_ + (int)patch.nVertices_ + lastNumberOfNewVertices;
                    int v4 = entry.Key.v2_ + (int)patch.nVertices_ + lastNumberOfNewVertices;

                    Vector3 p1 = extrudedShape.vertices_[v1];
                    Vector3 p2 = extrudedShape.vertices_[v2];
                    Vector3 p3 = extrudedShape.vertices_[v3];
                    Vector3 p4 = extrudedShape.vertices_[v4];

                    //v1
                    extrudedShape.vertices_[nDstVertices] = extrudedShape.vertices_[v1];
                    extrudedShape.normals_[nDstVertices]  = Vector3.Cross(p1 - p3, p1 - p2);
                    extrudedShape.uvs_[nDstVertices]      = extrudedShape.uvs_[v1];
                    int newV1index = (int)nDstVertices;
                    nDstVertices++;
                    numberOfNewVertices++;

                    //v2
                    extrudedShape.vertices_[nDstVertices] = extrudedShape.vertices_[v2];
                    extrudedShape.normals_[nDstVertices]  = Vector3.Cross(p2 - p1, p2 - p4);
                    extrudedShape.uvs_[nDstVertices]      = extrudedShape.uvs_[v2];
                    int newV2index = (int)nDstVertices;
                    nDstVertices++;
                    numberOfNewVertices++;

                    //v3
                    extrudedShape.vertices_[nDstVertices] = extrudedShape.vertices_[v3];
                    extrudedShape.normals_[nDstVertices]  = Vector3.Cross(p3 - p4, p3 - p1);
                    extrudedShape.uvs_[nDstVertices]      = extrudedShape.uvs_[v3];
                    int newV3index = (int)nDstVertices;
                    nDstVertices++;
                    numberOfNewVertices++;

                    //v4
                    extrudedShape.vertices_[nDstVertices] = extrudedShape.vertices_[v4];
                    extrudedShape.normals_[nDstVertices]  = Vector3.Cross(p4 - p2, p4 - p3);
                    extrudedShape.uvs_[nDstVertices]      = extrudedShape.uvs_[v3];
                    int newV4index = (int)nDstVertices;
                    nDstVertices++;
                    numberOfNewVertices++;

                    extrudedShape.indices_[nDstIndices++] = newV1index;
                    extrudedShape.indices_[nDstIndices++] = newV3index;
                    extrudedShape.indices_[nDstIndices++] = newV2index;

                    extrudedShape.indices_[nDstIndices++] = newV2index;
                    extrudedShape.indices_[nDstIndices++] = newV3index;
                    extrudedShape.indices_[nDstIndices++] = newV4index;
                }
            }

            extrudedShape.patches_[ipatch].nVertices_ = nDstVertices - extrudedShape.patches_[ipatch].startVertex_;
            extrudedShape.patches_[ipatch].nIndices_  = nDstIndices - extrudedShape.patches_[ipatch].startIndex_;
        }

        extrudedShape.numVertices_ = (int)nDstVertices;
        extrudedShape.numIndices_  = (int)nDstIndices;

        //resize final array
        Array.Resize <Vector3>(ref extrudedShape.vertices_, extrudedShape.numVertices_);
        Array.Resize <Vector3>(ref extrudedShape.normals_, extrudedShape.numVertices_);
        Array.Resize <Vector2>(ref extrudedShape.uvs_, extrudedShape.numVertices_);

        Array.Resize <int>(ref extrudedShape.indices_, extrudedShape.numIndices_);

        extrudedShape.finalizePatches();

        return(extrudedShape);
    }