private bool DealWithSpecialCases(OutputMesh builder, int facesIndex,
                                          CPNPolygon polygon)
        {
            CPNSideEdge[] polylines = polygon.sideEdges;
            /*---- SPECIAL CASES  ----*/
            if (MV == 1 && MH != 1)
            {
                NetPolylineIndicesArray array1 = new NetPolylineIndicesArray(polylines[0], builder);
                NetPolylineIndicesArray array2 = new NetPolylineIndicesArray(polylines[2], builder, true);
                MeshStructures.CreateSideTriangles(builder, array2, array1, facesIndex);
                return(true);
            }

            if (MV != 1 && MH == 1)
            {
                NetPolylineIndicesArray array1 = new NetPolylineIndicesArray(polylines[1], builder);
                NetPolylineIndicesArray array2 = new NetPolylineIndicesArray(polylines[3], builder, true);
                MeshStructures.CreateSideTriangles(builder, array2, array1, facesIndex);
                return(true);
            }

            if (MV == 1 && MH == 1)
            {
                builder.WriteQuad(facesIndex, polylines[0].GetFirstVertex(), polylines[1].GetFirstVertex(),
                                  polylines[2].GetFirstVertex(), polylines[3].GetFirstVertex());
                return(true);
            }
            return(false);
        }
        public void EvaluatePolyline(CurvedPolygonsNet net, OutputMesh mesh, CPNGuide guide)
        {
            bool uvAvailable = net.GetUv() != null && net.GetUv().Length != 0 && mesh.DoUseUVs();
            int  countP      = mesh.CountProperties();

            //bool tgAvailable = net.GetTangents() != null && net.GetTangents().Length != 0;

            short[] tessellationDegrees = CPNGuide_loqs;

            guide.vBuffer = CreateBufferWithIndices(guide.vBuffer, net.GetVertices(), guide.GetIndices());
            guide.nBuffer = CreateBufferWithIndices(guide.vBuffer, net.GetNormals(), guide.GetIndices());
            if (uvAvailable)
            {
                guide.uvsBuffer = CreateBufferWithIndices(guide.uvsBuffer, net.GetUv(), guide.GetIndices());
            }
            if (countP > 0)
            {
                guide.PreparePropertiesBuffers(countP);
                for (int k = 0; k < countP; k++)
                {
                    guide.propertiesBuffer[k] = CreateBufferWithIndices(guide.propertiesBuffer[k],
                                                                        net.GetProperties3()[k], guide.GetIndices());
                }
            }
        }
        public void CreateQuadTessellation(OutputMesh builder, int internalsIndex, int facesIndex,
                                           CPNPolygon polygon)
        {
            /*---- SPECIAL CASES  ----*/
            if (DealWithSpecialCases(builder, facesIndex, polygon))
            {
                return;
            }

            CPNSideEdge[] polylines             = polygon.sideEdges;
            int           trPosition            = facesIndex;
            int           innerVerticesPosition = internalsIndex;

            //Internal Quads -- Pretty Straightforward
            for (int i = 0; i < MV - 2; i++)
            {
                int rowPosition1 = innerVerticesPosition + (i) * (MH - 1);
                int rowPosition2 = innerVerticesPosition + (i + 1) * (MH - 1);

                for (int j = 0; j < MH - 2; j++)
                {
                    trPosition = builder.WriteQuad(trPosition, rowPosition1 + j, rowPosition1 + j + 1,
                                                   rowPosition2 + j + 1, rowPosition2 + j);
                }
            }

            UpdateSides(builder, polygon, trPosition, innerVerticesPosition);
        }
        public void BuildModel(GameObject gameObject)
        {
            CurvedPolygonsNet cpnet = GetPolylinesCPNet(asset.GetCPN());

            short[] loqs = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };

            CPNTessellationProcess tessellationProcess = ProcessesKeeper.GetTessellationProcess();

            TessellationOutput output = tessellationProcess.InitProcess(cpnet, loqs, this);

            //Debug.Log("cpnet.GetGeometriesCount() " + cpnet.GetGeometriesCount());

            tessellationProcess.BuildProfile();

            int[] builtTrianglesCount = output.GetBuiltTrianglesSize();
            int   builtVerticesCount  = output.GetBuiltVerticesSize();

            Vector2[] uvs_      = new Vector2[builtVerticesCount];
            Vector3[] vertices_ = new Vector3[builtVerticesCount];
            Vector3[] normals_  = new Vector3[builtVerticesCount];
            int[][]   indices_  = new int[builtTrianglesCount.Length][];
            //Debug.Log("indices_ " + indices_.Length);
            for (int i = 0; i < builtTrianglesCount.Length; i++)
            {
                indices_[i] = new int[builtTrianglesCount[i] * 3];
                //Debug.Log("indices_[" + i + "] " + indices_[i].Length);
            }

            OutputMesh mesh = null;

            mesh = new OutputMesh(vertices_, uvs_, normals_, indices_);
            tessellationProcess.WriteMesh(mesh);

            MeshAssigner.AssignMesh(gameObject, vertices_, normals_, uvs_, indices_);
        }
 public NetPolylineIndicesArray(CPNSideEdge guide, OutputMesh builder)
 {
     this.guide    = guide;
     this.builder  = builder;
     this.position = 0;
     this.back     = false;
 }
Beispiel #6
0
        // Retrieves meshes from last generate result and creates according Unity meshes
        void GetMeshes(Material[] materials, Transform loc2WorldTrafo, out OutputMesh[] meshes)
        {
            int numMeshes = Prt4Unity.GetMeshCount(ctx);

            meshes = new OutputMesh[numMeshes];
            for (int i = 0; i < numMeshes; i++)
            {
                IntPtr name, pVertices, pNormals, pTexcoords;
                int    numVertices;
                Prt4Unity.GetMesh(ctx, i, out name, out numVertices, out pVertices, out pNormals, out pTexcoords);
                OutputMesh outputMesh = new OutputMesh();
                meshes[i]            = outputMesh;
                outputMesh.mesh      = new Mesh();
                outputMesh.mesh.name = Marshal.PtrToStringUni(name);
                float[] floats = new float[numVertices * 3];
                Marshal.Copy(pVertices, floats, 0, numVertices * 3);
                Vector3[] vertices = new Vector3[numVertices];
                Vector3   preScale = loc2WorldTrafo.localScale;
                for (int v = 0; v < numVertices; v++)
                {
                    vertices[v]    = new Vector3(floats[3 * v + 0], floats[3 * v + 1], floats[3 * v + 2]);
                    vertices[v]    = loc2WorldTrafo.InverseTransformPoint(vertices[v]);
                    vertices[v].x *= preScale.x;
                    vertices[v].y *= preScale.y;
                    vertices[v].z *= preScale.z;
                }
                outputMesh.mesh.vertices = vertices;
                Marshal.Copy(pNormals, floats, 0, numVertices * 3);
                Vector3[] normals = new Vector3[numVertices];
                for (int v = 0; v < numVertices; v++)
                {
                    normals[v] = new Vector3(floats[3 * v + 0], floats[3 * v + 1], floats[3 * v + 2]);
                }
                outputMesh.mesh.normals = normals;
                if (pTexcoords != IntPtr.Zero)
                {
                    Marshal.Copy(pTexcoords, floats, 0, numVertices * 2);
                    Vector2[] texcoords = new Vector2[numVertices];
                    for (int v = 0; v < numVertices; v++)
                    {
                        texcoords[v] = new Vector2(floats[2 * v + 0], floats[2 * v + 1]);
                    }
                    outputMesh.mesh.uv = texcoords;
                }

                int numSubMeshes = Prt4Unity.GetSubMeshCount(ctx, i);
                outputMesh.mesh.subMeshCount = (int)numSubMeshes;
                outputMesh.materials         = new Material[numSubMeshes];
                for (int s = 0; s < numSubMeshes; s++)
                {
                    IntPtr pIndices;
                    int    numIndices, materialIndex;
                    Prt4Unity.GetSubMesh(ctx, i, s, out pIndices, out numIndices, out materialIndex);
                    int[] indices = new int[numIndices];
                    Marshal.Copy(pIndices, indices, 0, numIndices);
                    outputMesh.mesh.SetTriangles(indices, (int)s);
                    outputMesh.materials[s] = materials[materialIndex];
                }
            }
        }
        public void writeWithGuideBack(CPNSideEdge guide, int N, float step, OutputMesh mesh,
                                       CPNGuideEvaluator evaluator)
        {
            this.step = step;
            requestSize(N + 1);

            //We should have only one thickness on multisided edge, you know?
            this.thickness = 1;

            for (int i = 0; i <= N; i++)
            {
                //This is the eval-back
                evaluator.EvalAt(1.0f - i * step, guide);
                Vector3 dev = evaluator.EvalDev(guide);
                vertices[i] = evaluator.EvalVertex(guide);
                if (i == 0)
                {
                    devFirst = dev;
                }
                if (i == N)
                {
                    devLast = dev;
                }
                evaluator.EvalAt(i * step + DELTA, guide);
                verticesDplus[i] = evaluator.EvalVertex(guide);
                evaluator.EvalAt(i * step - DELTA, guide);
                verticesDminus[i] = evaluator.EvalVertex(guide);
                normals[i]        = evaluator.EvalNormal(guide, dev).normalized;
                uvs[i]            = evaluator.EvalUV(guide);
                for (int k = 0; k < countP; k++)
                {
                    properties[k][i] = evaluator.EvalProperty(guide, k);
                }
            }
        }
Beispiel #8
0
        private void WriteMesh(Mesh storedMesh, OutputMesh output /*,bool useUnityNormals*/)
        {
            if (output.GetVertices().Length > CPNTessellationProcess.MAX_VERTICES_SIZE)
            {
                return;
            }

            storedMesh.Clear();
            storedMesh.vertices = output.GetVertices();
            storedMesh.uv       = output.GetUVs();
            storedMesh.normals  = output.GetNormals();

            int[][] triangles = output.GetTriangles();
            if (triangles.Length == 0)
            {
                storedMesh.SetTriangles(new int[0], 0);
            }
            else
            {
                storedMesh.subMeshCount = triangles.Length;
                for (int i = 0; i < triangles.Length; i++)
                {
                    storedMesh.SetTriangles(triangles[i], i);
                }
            }
        }
Beispiel #9
0
        public void Execute()
        {
            CurvedPolygonsNet cpnet = asset.GetCPN();

            short[] loqs = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };

            CPNTessellationProcess tessellationProcess = ProcessesKeeper.GetTessellationProcess();

            TessellationOutput output = tessellationProcess.InitProcess(cpnet, loqs);

            tessellationProcess.BuildProfile();

            int[] builtTrianglesCount = output.GetBuiltTrianglesSize();
            int   builtVerticesCount  = output.GetBuiltVerticesSize();

            uvs_      = new Vector2[builtVerticesCount];
            vertices_ = new Vector3[builtVerticesCount];
            normals_  = new Vector3[builtVerticesCount];
            indices_  = new int[builtTrianglesCount.Length][];
            for (int i = 0; i < builtTrianglesCount.Length; i++)
            {
                indices_[i] = new int[builtTrianglesCount[i] * 3];
            }

            OutputMesh mesh = null;

            mesh = new OutputMesh(vertices_, uvs_, normals_, indices_);
            tessellationProcess.WriteMesh(mesh);
        }
 public LinearMeshIndicesArray(int first, int move, int count, OutputMesh builder)
 {
     this.first    = first;
     this.move_    = move;
     this.count_   = count;
     this.source   = builder;
     this.position = 0;
 }
        public int UpdateSides(OutputMesh builder, CPNPolygon polygon, int trPosition,
                               int innerVerticesPosition)
        {
            CPNSideEdge[] polylines = polygon.sideEdges;

            first[0] = innerVerticesPosition;
            first[1] = innerVerticesPosition + (MH - 2);
            first[2] = innerVerticesPosition + (MV - 1) * (MH - 1) - 1;
            first[3] = innerVerticesPosition + (MV - 2) * (MH - 1);

            move[0] = 1;
            move[1] = (MH - 1);
            move[2] = -1;
            move[3] = -(MH - 1);

            count[0] = MH - 1;
            count[1] = MV - 1;
            count[2] = MH - 1;
            count[3] = MV - 1;

            for (int i = 0; i < 4; i++)
            {
                if (polylines[i].GetN() > 1)
                {
                    LinearMeshIndicesArray          lmi = new LinearMeshIndicesArray(first[i], move[i], count[i], builder);
                    NetPolylineInternalIndicesArray npi = new NetPolylineInternalIndicesArray(polylines[i], builder);
                    trPosition = MeshStructures.CreateSideTriangles(builder, lmi, npi, trPosition);
                }
                else
                {
                    LinearMeshIndicesArray  lmi = new LinearMeshIndicesArray(first[i], move[i], count[i], builder);
                    NetPolylineIndicesArray npi = new NetPolylineIndicesArray(polylines[i], builder);
                    trPosition = MeshStructures.CreateSideTriangles(builder, lmi, npi, trPosition);
                }

                int prev = i == 0 ? 3 : i - 1;
                if (polylines[i].GetN() > 1 && polylines[prev].GetN() > 1)
                {
                    trPosition = builder.WriteQuad(trPosition, polylines[i].GetIndex(0), polylines[i].GetIndex(1), first[i],
                                                   polylines[prev].GetBackIndex(1));
                }
                else if (polylines[i].GetN() > 1)
                {
                    trPosition = builder.WriteTriangle(trPosition, polylines[i].GetIndex(0), polylines[i].GetIndex(1),
                                                       first[i]);
                }
                else if (polylines[prev].GetN() > 1)
                {
                    trPosition = builder.WriteTriangle(trPosition, polylines[i].GetIndex(0), first[i],
                                                       polylines[prev].GetBackIndex(1));
                }

                // System.err.println("trPosition on sides " + trPosition);
            }

            return(trPosition);
        }
 public void Setup(int first, int move, int count, int last, OutputMesh builder, int layer)
 {
     this.first = first;
     this.move_ = move;
     this.count_ = count;
     this.last = last;
     this.source = builder;
     this.layer = layer;
     position = 0;
 }
Beispiel #13
0
        public void WriteMesh(OutputMesh mesh)
        {
            int position = WriteVertices(mesh);

            position = WriteEdges(mesh, position);

            WriteEdgesNormals(mesh);

            position = WritePolygons(mesh, position);
        }
        public NGonsMeshIndicesArray(int first, int move, int count, int last, OutputMesh builder, int layer)
        {

            this.first = first;
            this.move_ = move;
            this.count_ = count;
            this.last = last;
            this.source = builder;
            this.layer = layer;
            position = 0;
        }
 public void Setup(int first, int move, int deltaMove, int count, OutputMesh builder, int layer)
 {
     this.deltaMove = deltaMove;
     this.basemove  = move;
     this.move_     = move + deltaMove;
     this.count_    = count;
     this.builder   = builder;
     this.layer     = layer;
     index          = first;
     next           = first + this.move_;
     this.first     = first;
 }
Beispiel #16
0
        int WritePolygons(OutputMesh mesh, int position)
        {
            int geometriesCount = this.curvedPolygonsNet.GetGeometriesCount();

            CPNPolygon[][] polygons                = tessellationOutput.GetPolygons();
            int[][]        polygonsProfile         = tessellationOutput.GetPolygonsProfile();
            int[][]        polygonsVerticesProfile = tessellationOutput.GetPolygonsVerticesProfile();

            for (int k = 0; k < geometriesCount; k++)
            {
                mesh.SetGeometry(k);
                CPNGeometry geometry = this.curvedPolygonsNet.GetGeometries()[k];

                int geomPolygonsCount = subSet == null?geometry.GetPolygonsCount() : subSet.polygons[k].Length;

                for (int i = 0; i < geomPolygonsCount; i++)
                {
                    int        index = subSet == null ? i : subSet.polygons[k][i];
                    int        countEffectiveSize = polygons[k][index].sideEdges.Length;
                    CPNPolygon polygonData        = polygons[k][index];

                    if (countEffectiveSize > 2 && countEffectiveSize < TESSELLATION_PROCESS_NET_INTERPOLATORS &&
                        !polygonData.skip)
                    {
                        polygonData.computeSideEdgesSizes();
                        ICPNetInterpolator netInterpolator = manager.GetSchema(polygonData.schemaIndex).
                                                             interpolators[countEffectiveSize];

                        netInterpolator.UdpdateContent(mesh, polygonData, polygonsVerticesProfile[k][index],
                                                       polygonsProfile[k][index]);
                    }
                }
                position += polygonsVerticesProfile[k][geometry.GetPolygonsCount()];

                int     triangleIndex  = polygonsProfile[k][geometry.GetPolygonsCount()];
                int     trianglesCount = geometry.GetTrianglesCount();
                short[] triangles      = geometry.GetTriangles();
                for (int i = 0; i < trianglesCount; i++)
                {
                    mesh.WriteTriangle(triangleIndex, triangles[3 * i], triangles[3 * i + 1], triangles[3 * i + 2]);
                    triangleIndex++;
                }
                int     quadsCount = geometry.GetQuadsCount();
                short[] quads      = geometry.GetQuads();
                for (int i = 0; i < quadsCount; i++)
                {
                    mesh.WriteQuad(triangleIndex, quads[3 * i], quads[3 * i + 1], quads[3 * i + 2], quads[3 * i + 3]);
                    triangleIndex += 2;
                }
            }

            return(position);
        }
Beispiel #17
0
        public void Execute()
        {
            CurvedPolygonsNet cpnet = asset.GetCPN();

            CurvedPolyVariants cpnVariants = new CurvedPolyVariants();

            cpnVariants.SetCPN(cpnet);

            short[] loqs = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };

            CPNTessellationProcess tessellationProcess = ProcessesKeeper.GetTessellationProcess();

            TessellationOutput output = tessellationProcess.InitProcess(cpnet, loqs);

            //Debug.Log("cpnet.GetGeometriesCount() " + cpnet.GetGeometriesCount());

            tessellationProcess.BuildProfile();

            int[] builtTrianglesCount = output.GetBuiltTrianglesSize();
            int   builtVerticesCount  = output.GetBuiltVerticesSize();

            uvs_      = new Vector2[builtVerticesCount];
            vertices_ = new Vector3[builtVerticesCount];
            normals_  = new Vector3[builtVerticesCount];
            indices_  = new int[builtTrianglesCount.Length][];
            for (int i = 0; i < builtTrianglesCount.Length; i++)
            {
                indices_[i] = new int[builtTrianglesCount[i] * 3];
            }

            OutputMesh mesh = null;

            mesh = new OutputMesh(vertices_, uvs_, normals_, indices_);
            tessellationProcess.WriteMesh(mesh);

            //here
            int id = cpnVariants.GetFreeTessellationRecordId();

            cpnVariants.SetRecord(id, new OutputMesh(vertices_, uvs_, normals_, indices_), output);

            //this.outMesh = cpnVariants.GetMeshOutput(id).GetNewCloneVariant();

            CPNSubset subsSet = new CPNSubset();

            TessellationOutput output2 = tessellationProcess.InitProcess(cpnet, loqs, subsSet);

            this.mesh2 = new OutputMesh(outMesh.GetVertices(), outMesh.GetUVs(),
                                        outMesh.GetNormals(), outMesh.GetTriangles());
            tessellationProcess.WriteMesh(mesh2);
        }
Beispiel #18
0
        void WriteEdgesNormals(OutputMesh mesh)
        {
            IGuideModel guideEvaluator = GetGuideModel();

            CPNGuide[] guides    = this.tessellationOutput.GetGuides();
            int        edgesSize = subSet == null?curvedPolygonsNet.GetEdgesCount() : subSet.edges.Length;

            for (int i = 0; i < edgesSize; i++)
            {
                int index = subSet == null ? i : subSet.edges[i];
                if (guides[index].GetN() > 0)
                {
                    guideEvaluator.EvaluateNormals(mesh, guides[index]);
                }
            }
        }
        Vector3 EvalVertex(OutputMesh builder, CPNPolygon polylines, float innerX, float innerY, out Vector3 uv)
        {
            updateVals(innerX, innerY);

            for (int k = 0; k < sides; k++)
            {
                int kprev = k == 0 ? sides - 1 : k - 1;

                float dx = (innerX * cos_[k] - innerY * sin_[k]) - 1;
                float dy = (innerX * sin_[k] + innerY * cos_[k]);

                float U = cornerCoordsMatrix[0] * dx + cornerCoordsMatrix[2] * dy;
                float V = cornerCoordsMatrix[1] * dx + cornerCoordsMatrix[3] * dy;

                int indexU = (int)((U + 0.0001f) * totalInterpolationStep);
                int indexV = (int)((V + 0.0001f) * totalInterpolationStep);

                if (indexU > interpolationSteps)
                {
                    indexU = interpolationSteps;
                }
                if (indexV > interpolationSteps)
                {
                    indexV = interpolationSteps;
                }

                tmpInterpolations[k]   = evalVertex(polylines.sideEdges[k], polylines.sideEdges[kprev], U, V);
                tmpInterpolationsUV[k] = evalUV(polylines.sideEdges[k], polylines.sideEdges[kprev], U, V);
            }

            Vector3 vertex = val[0] * tmpInterpolations[0];

            uv = val[0] * tmpInterpolationsUV[0];

            for (int k = 1; k < sides; k++)
            {
                vertex = vertex + tmpInterpolations[k] * val[k];
                uv     = uv + tmpInterpolationsUV[k] * val[k];
            }

            return(vertex);
        }
Beispiel #20
0
        int WriteEdges(OutputMesh mesh, int position)
        {
            IGuideModel guideEvaluator = GetGuideModel();
            int         edgesSize      = subSet == null?curvedPolygonsNet.GetEdgesCount() : subSet.edges.Length;

            CPNGuide[] guides       = this.tessellationOutput.GetGuides();
            int[]      edgesProfile = this.tessellationOutput.GetEdgesProfile();

            for (int i = 0; i < edgesSize; i++)
            {
                int      index    = subSet == null ? i : subSet.edges[i];
                CPNGuide polyline = guides[index];
                if (polyline.GetN() > 0)
                {
                    short[] edge        = curvedPolygonsNet.GetEdges(/* i */);
                    int     edgeLength  = curvedPolygonsNet.GetEdgeLength(index);
                    float[] edgeWeights = curvedPolygonsNet.GetEdgeWeights(/* i */);
                    short[] edgeHints   = curvedPolygonsNet.GetEdgeHints(/* i */);

                    int edgePosition = curvedPolygonsNet.GetEdgePosition(index);

                    guideEvaluator.EvaluateEdge(curvedPolygonsNet, mesh, polyline, (short)edgeLength, edge, edgePosition,
                                                edgeHints, edgeWeights,
                                                edgesProfile, index);
                    position += polyline.GetN() - 1;
                }
            }

            edgesSize = curvedPolygonsNet.GetEdgesCount();
            int polylinesSize = subSet == null?curvedPolygonsNet.GetPolylinesCount() : subSet.polylines.Length;

            //No need to compute polylines
            for (int i = 0; i < polylinesSize; i++)
            {
                int index = subSet == null ? i : subSet.edges[i];
                index += edgesSize;
                CPNGuide polyline = guides[index];
                guideEvaluator.EvaluatePolyline(curvedPolygonsNet, mesh, polyline);
            }
            return(position);
        }
        private void prepareMemory(int M, CPNSideEdge[] guides, OutputMesh mesh)
        {
            int triangleSize = ((M)*(M + 1)) >> 1;
            int totalSize    = (triangleSize) * sides + 1;

            memory.requestSize(totalSize);

            for (int i = 0; i < sides; i++)
            {
                int relativePosition = triangleSize * (sides - 1 - i);

                bufferTemp.requestSize(M + 1);
                bufferTemp.writeWithGuideBack(guides[i], M, mesh, evaluator);

                for (int j = 0; j < M; j++)
                {
                    memory.vertices[relativePosition + j] = bufferTemp.vertices[j];
                    memory.uv[relativePosition + j]       = bufferTemp.uvs[j];
                }
            }
        }
        public void EvaluateNormals(OutputMesh mesh, CPNGuide guide)
        {
            int N = guide.GetN();

            if (N <= 0)
            {
                return;
            }

            bool doTangents = mesh.DoUseTangents();
            bool doNormals  = mesh.DoNormals();

            if (doNormals)
            {
                float step = 1.0f / N;
                for (int j = 1; j < N; j++)
                {
                    EvalAt(j * step, guide);
                    Vector3 dev;
                    Vector3 normal = EvalNormal(guide, out dev);
                    int     index  = guide.GetIndex(j);
                    mesh.SetNormal(index, normal.normalized);
                    if (doTangents)
                    {
                        mesh.SetTangent(index, GetTangent(guide, dev, normal).normalized);
                    }
                }
                if (doTangents)
                {
                    for (int j = 0; j <= N; j += N)
                    {
                        EvalAt(j * step, guide);
                        Vector3 dev    = EvalDev(guide);
                        int     index  = guide.GetIndex(j);
                        Vector3 normal = mesh.GetNormal(index);
                        mesh.SetTangent(index, GetTangent(guide, dev, normal).normalized);
                    }
                }
            }
        }
        public void writeWithGuide(CPNSideEdge guide, int N, float step, OutputMesh mesh,
                                   CPNGuideEvaluator evaluator)
        {
            this.step = step;
            requestSize(N + 1);

            //We should have only one thickness on multisided edge, you know?
            this.thickness = 1;

            for (int i = 0; i <= N; i++)
            {
                ts[i] = evaluator.EvalAt(i * step, guide);
                Vector3 dev = evaluator.EvalDev(guide);
                vertices[i] = evaluator.EvalVertex(guide);
                uvs[i]      = evaluator.EvalUV(guide);
                normals[i]  = evaluator.EvalNormal(guide, dev).normalized;
                for (int k = 0; k < countP; k++)
                {
                    properties[k][i] = evaluator.EvalProperty(guide, k);
                }
            }
        }
Beispiel #24
0
        int WriteVertices(OutputMesh mesh)
        {
            int numberOfVertices = subSet == null?curvedPolygonsNet.GetNumberOfVertices() :
                                       subSet.vertices.Length;

            Vector3[]   vertices        = curvedPolygonsNet.GetVertices();
            Vector3[]   normals         = curvedPolygonsNet.GetNormals();
            Vector3[]   uvs             = curvedPolygonsNet.GetUv();
            Vector3[][] properties      = curvedPolygonsNet.GetProperties3();
            int         countProperties = mesh.CountProperties();
            //Vector3[] tangents = curvedPolygonsNet.GetTangents();
            //bool doTangents = tangents != null;
            bool doUvs     = uvs != null && mesh.DoUseUVs();
            bool doNormals = normals != null && mesh.DoNormals();

            for (int i = 0; i < numberOfVertices; i++)
            {
                int index = subSet == null ? i : subSet.vertices[i];
                mesh.SetVertex(index, vertices[index]);
                if (doUvs)
                {
                    mesh.SetUV(index, uvs[index]);
                }
                if (doNormals)
                {
                    mesh.SetNormal(index, normals[index]);
                }
                for (int k = 0; k < countProperties; k++)
                {
                    mesh.SetProperty3(index, k, properties[k][index]);
                }
            }


            return(numberOfVertices);
        }
Beispiel #25
0
        public void UdpdateContent(OutputMesh mesh, CPNPolygon polygon, int internalsIndex,
                                   int facesIndex, bool doUpdateStructure = true)
        {
            triangleStructure.RetrieveInfos(polygon);

            int   M    = triangleStructure.GetM();
            float step = 1.0f / M;

            CPNSideEdge[] polylines = polygon.sideEdges;
            buffer0.writeWithGuide(polylines[0], M, mesh, evaluator);
            buffer1.writeWithGuide(polylines[1], M, mesh, evaluator);
            buffer2.writeWithGuide(polylines[2], M, mesh, evaluator);

            corner0.Set(buffer0, buffer2);
            corner1.Set(buffer1, buffer0);
            corner2.Set(buffer2, buffer1);

            prepareMemory(M);

            for (int i = 1; i < M - 1; i++)
            {
                for (int j = 1; j < M - 1 - (i - 1); j++)
                {
                    int wIndex = M - i - j;

                    Vector3 V1   = corner0.evalVertex(j, i);
                    Vector3 V1uv = corner0.evalUV(j, i);

                    Vector3 V2   = corner1.evalVertex(i, wIndex);
                    Vector3 V2uv = corner1.evalUV(i, wIndex);

                    Vector3 V3   = corner2.evalVertex(wIndex, j);
                    Vector3 V3uv = corner2.evalUV(wIndex, j);

                    float U = j * step;
                    float V = i * step;
                    float W = 1 - U - V;

                    float a1 = W * W;
                    float a2 = U * U;
                    float a3 = V * V;
#if DEBUG
                    if (interpolationCorner != 0)
                    {
                        switch (interpolationCorner)
                        {
                        case 1: a1 = 1; a2 = 0; a3 = 0; break;

                        case 2: a1 = 0; a2 = 1; a3 = 0; break;

                        case 3: a1 = 0; a2 = 0; a3 = 1; break;
                        }
                    }
#endif

                    float rec = 1.0f / (a1 + a2 + a3);
                    a1 *= rec;
                    a2 *= rec;
                    a3 *= rec;

                    Vector3 vertex = V1 * a1 + V2 * a2 + V3 * a3;
                    Vector3 uv     = V1uv * a1 + V2uv * a2 + V3uv * a3;

                    int memoryIndex = j + i * (M + 1) - (((i) * (i - 1)) >> 1);
                    memory.vertices[memoryIndex] = vertex;
                    memory.uv[memoryIndex]       = uv;
                }
            }

            int position = internalsIndex;

            for (int i = 1; i < M - 1; i++)
            {
                for (int j = 1; j < M - 1 - (i - 1); j++)
                {
                    int rowIndex     = i * (M + 1) - (((i) * (i - 1)) >> 1);
                    int rowIndexPrev = (i - 1) * (M + 1) - (((i - 1) * (i - 2)) >> 1);
                    int rowIndexNext = (i + 1) * (M + 1) - (((i + 1) * (i)) >> 1);

                    int     memoryIndex = j + rowIndex;
                    Vector3 vertex      = memory.vertices[memoryIndex];
                    Vector3 uv          = memory.uv[memoryIndex];

                    //Normal (S is the vertices, the surface)
                    Vector3 dSdu   = memory.vertices[memoryIndex + 1] - memory.vertices[memoryIndex - 1];
                    Vector3 dSdv   = memory.vertices[rowIndexNext + j] - memory.vertices[rowIndexPrev + j];
                    Vector3 normal = Vector3.Cross(dSdu, dSdv).normalized;

                    //Tangent
                    Vector3 dTxdu   = memory.uv[memoryIndex + 1] - memory.uv[memoryIndex - 1];
                    Vector3 dTxdv   = memory.uv[rowIndexNext + j] - memory.uv[rowIndexPrev + j];
                    Vector3 tangent = getTangent(dSdu, dSdv, dTxdu, dTxdv);

                    mesh.SetPNUV(position, vertex, normal, uv, tangent);

                    position++;
                }
            }

            if (doUpdateStructure)
            {
                triangleStructure.CreateTriangleTessellation(mesh, internalsIndex, facesIndex, polygon);
            }
        }
        public void UdpdateContent(OutputMesh mesh, CPNPolygon polygon, int internalsIndex,
                                   int facesIndex, bool doUpdateStructure = true)
        {
            triangleStructure.RetrieveInfos(polygon);

            bool useUV           = mesh.DoUseUVs();
            bool useNormals      = mesh.DoNormals();
            bool useTangents     = mesh.DoUseUVs();
            int  countProperties = mesh.CountProperties();

            buffer0.requestProperties(countProperties);
            buffer1.requestProperties(countProperties);
            buffer2.requestProperties(countProperties);

            int   M    = triangleStructure.GetM();
            float step = 1.0f / M;

            CPNSideEdge[] polylines = polygon.sideEdges;
            buffer0.writeWithGuide(polylines[0], M, mesh, evaluator);
            buffer1.writeWithGuide(polylines[1], M, mesh, evaluator);
            buffer2.writeWithGuide(polylines[2], M, mesh, evaluator);

            edgeSurface0.Set(buffer0, buffer2, buffer1);
            edgeSurface1.Set(buffer1, buffer0, buffer2);
            edgeSurface2.Set(buffer2, buffer1, buffer0);

            computeCorners();

            float l1 = ks[0] * ks[1] * ks[0] * ks[1];
            float l2 = ks[1] * ks[2] * ks[1] * ks[2];
            float l3 = ks[2] * ks[0] * ks[2] * ks[0];

            prepareMemory(M, countProperties);

            int position = internalsIndex;

            for (int i = 1; i < M - 1; i++)
            {
                for (int j = 1; j < M - 1 - (i - 1); j++)
                {
                    int k = M - i - j;

                    float U = j * step;
                    float V = i * step;
                    float W = 1 - U - V;

                    float a1 = U * U * W * W * l1 /** buffer0.thickness*/;
                    float a2 = V * V * U * U * l2 /** buffer1.thickness*/;
                    float a3 = W * W * V * V * l3 /** buffer2.thickness*/;

                    //float a1 = W * W;
                    //float a2 = U * U;
                    //float a3 = V * V;

                    if (TriangleInterpolator4.interpolationCorner != 0)
                    {
                        switch (TriangleInterpolator4.interpolationCorner)
                        {
                        case 1: a1 = 1; a2 = 0; a3 = 0; break;

                        case 2: a1 = 0; a2 = 1; a3 = 0; break;

                        case 3: a1 = 0; a2 = 0; a3 = 1; break;
                        }
                    }

                    float rec = 1.0f / (a1 + a2 + a3);
                    a1 *= rec;
                    a2 *= rec;
                    a3 *= rec;


                    Vector3 V1     = edgeSurface0.evalVertex(/*j,*/ i, polylines[0], U / (1 - V));
                    Vector3 V2     = edgeSurface1.evalVertex(/*i,*/ k, polylines[1], V / (1 - W));
                    Vector3 V3     = edgeSurface2.evalVertex(/*k,*/ j, polylines[2], W / (1 - U));
                    Vector3 vertex = V1 * a1 + V2 * a2 + V3 * a3;

                    int memoryIndex = j + i * (M + 1) - (((i) * (i - 1)) >> 1);
                    memory.vertices[memoryIndex] = vertex;

                    if (useUV)
                    {
                        Vector3 V1uv = edgeSurface0.evalUV(/*j,*/ i, polylines[0], U / (1 - V));
                        Vector3 V2uv = edgeSurface1.evalUV(/*i,*/ k, polylines[1], V / (1 - W));
                        Vector3 V3uv = edgeSurface2.evalUV(/*k,*/ j, polylines[2], W / (1 - U));
                        Vector3 uv   = V1uv * a1 + V2uv * a2 + V3uv * a3;
                        //Vector3 vertex = V3;
                        //Vector3 uv = V3uv;

                        memory.uv[memoryIndex] = uv;
                    }

                    for (int pIndex = 0; pIndex < countProperties; pIndex++)
                    {
                        Vector3 V1prop = edgeSurface0.evalProperty(pIndex, i, polylines[0], U / (1 - V));
                        Vector3 V2prop = edgeSurface1.evalProperty(pIndex, k, polylines[1], V / (1 - W));
                        Vector3 V3prop = edgeSurface2.evalProperty(pIndex, j, polylines[2], W / (1 - U));
                        Vector3 prop   = V1prop * a1 + V2prop * a2 + V3prop * a3;
                        mesh.SetProperty3(position, pIndex, prop);
                    }

                    position++;
                }
            }

            position = internalsIndex;

            for (int i = 1; i < M - 1; i++)
            {
                for (int j = 1; j < M - 1 - (i - 1); j++)
                {
                    int rowIndex     = i * (M + 1) - (((i) * (i - 1)) >> 1);
                    int rowIndexPrev = (i - 1) * (M + 1) - (((i - 1) * (i - 2)) >> 1);
                    int rowIndexNext = (i + 1) * (M + 1) - (((i + 1) * (i)) >> 1);

                    int     memoryIndex = j + rowIndex;
                    Vector3 vertex      = memory.vertices[memoryIndex];
                    Vector3 uv          = memory.uv[memoryIndex];

                    Vector3 normal  = Vector3.zero;
                    Vector3 tangent = Vector3.zero;

                    if (useNormals)
                    {
                        //Normal (S is the vertices, the surface)
                        Vector3 dSdu = memory.vertices[memoryIndex + 1] - memory.vertices[memoryIndex - 1];
                        Vector3 dSdv = memory.vertices[rowIndexNext + j] - memory.vertices[rowIndexPrev + j];
                        normal = Vector3.Cross(dSdu, dSdv).normalized;

                        if (useTangents)
                        {
                            //Tangent
                            Vector3 dTxdu = memory.uv[memoryIndex + 1] - memory.uv[memoryIndex - 1];
                            Vector3 dTxdv = memory.uv[rowIndexNext + j] - memory.uv[rowIndexPrev + j];
                            tangent = getTangent(dSdu, dSdv, dTxdu, dTxdv);
                        }
                    }

                    mesh.SetPNUV(position, vertex, normal, uv, tangent);

                    position++;
                }
            }

            if (doUpdateStructure)
            {
                triangleStructure.CreateTriangleTessellation(mesh, internalsIndex, facesIndex, polygon);
            }
        }
Beispiel #27
0
        public static int CreateSideTriangles2(OutputMesh builder,
                                               IMeshIndicesArray inside, IMeshIndicesArray outside,
                                               int intTrIndex)
        {
            Vector3[] vs = builder.GetVertices();

            int   outerEdgeLength = outside.Count();
            int   innerEdgeLength = inside.Count();
            int   outerIndex      = 0;
            int   innerIndex      = 0;
            float dtInner         = innerEdgeLength > 1 ? 1.0f / (innerEdgeLength - 1) : 1;
            float dtOuter         = outerEdgeLength > 1 ? 1.0f / (outerEdgeLength - 1) : 1;

            float kIn  = 0;
            float kOut = 1;

            if (outerEdgeLength > 1 && innerEdgeLength > 1)
            {
                Vector3 A = vs[outside.GetIndex()];
                Vector3 B = vs[outside.GetNext()];
                Vector3 C = vs[inside.GetIndex()];
                Vector3 D = vs[outside.GetAtIndex(outerEdgeLength - 2)];
                Vector3 E = vs[outside.GetAtIndex(outerEdgeLength - 1)];
                Vector3 F = vs[inside.GetAtIndex(innerEdgeLength - 1)];

                kIn  = Vector3.Dot(C - A, B - A) / Vector3.Dot(B - A, B - A);
                kOut = Vector3.Dot(F - D, E - D) / Vector3.Dot(E - D, E - D);

                float rect = 1.0f / (outerEdgeLength - 1);
                kIn  = kIn * rect;
                kOut = 1 - (1 - kOut) * rect;
            }

            while (innerIndex < innerEdgeLength - 1 || outerIndex < outerEdgeLength - 1)
            {
                if (innerIndex < innerEdgeLength - 1)
                {
                    if (outerIndex < outerEdgeLength - 1)
                    {
                        int id1 = outside.GetIndex();
                        int id2 = inside.GetIndex();
                        int id3 = outside.GetNext();
                        int id4 = inside.GetNext();

                        float tOuter = dtOuter * (outerIndex);
                        float tInner = dtInner * (innerIndex) * (kOut - kIn) + kIn;

                        if (tInner <= tOuter)
                        {
                            intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2);
                            innerIndex++;
                            inside.Move();
                        }
                        else
                        {
                            intTrIndex = builder.WriteTriangle(intTrIndex, id1, id3, id2);
                            outerIndex++;
                            outside.Move();
                        }
                    }
                    else
                    {
                        int id1 = outside.GetIndex();
                        int id2 = inside.GetIndex();
                        int id4 = inside.GetNext();

                        intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2);
                        innerIndex++;
                        inside.Move();
                    }
                }
                else
                {
                    int id1 = outside.GetIndex();
                    int id2 = inside.GetIndex();
                    int id3 = outside.GetNext();
                    intTrIndex = builder.WriteTriangle(
                        intTrIndex, id1, id3, id2);
                    outerIndex++;
                    outside.Move();
                }
            }
            return(intTrIndex);
        }
Beispiel #28
0
        public static int CreateSideTriangles(OutputMesh builder,
                                              IMeshIndicesArray inside, IMeshIndicesArray outside,
                                              int intTrIndex)
        {
            /*Vector3[] vs = builder.GetVertices();
             * int outerEdgeLength = outside.Count();
             * int innerEdgeLength = inside.Count();
             * int outerIndex = 0;
             * int innerIndex = 0;
             *
             * while (innerIndex < innerEdgeLength - 1 || outerIndex < outerEdgeLength - 1)
             * {
             *  if (innerIndex < innerEdgeLength - 1)
             *  {
             *      if (outerIndex < outerEdgeLength - 1)
             *      {
             *          int id1 = outerIndex;
             *          int id2 = innerIndex;
             *          int id3 = outside.GetNext();
             *          int id4 = inside.GetNext();
             *
             *          Vector3 P1 = vs[id1];
             *          Vector3 P2 = vs[id2];
             *          Vector3 P3 = vs[id3];
             *          Vector3 P4 = vs[id4];
             *
             *          float dInner = (P4 - P1).sqrMagnitude;
             *          float dOuter = (P3 - P2).sqrMagnitude;
             *
             *          if (dInner < dOuter) {
             *              intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2);
             *              innerIndex++;
             *              inside.Move();
             *          } else {
             *              intTrIndex = builder.WriteTriangle(intTrIndex, id1, id3, id2);
             *              outerIndex++;
             *              outside.Move();
             *
             *          }
             *      }
             *      else
             *      {
             *
             *          int id1 = outerIndex;
             *          int id2 = innerIndex;
             *          int id4 = inside.GetNext();
             *
             *          intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2);
             *          innerIndex++;
             *          inside.Move();
             *      }
             *  }
             *  else
             *  {
             *      int id1 = outerIndex;
             *      int id2 = innerIndex;
             *      int id3 = outside.GetNext();
             *      intTrIndex = builder.WriteTriangle(
             *          intTrIndex, id1, id3, id2);
             *      outerIndex++;
             *      outside.Move();
             *  }
             * }
             *
             * return intTrIndex;*/


            Vector3[] vs = builder.GetVertices();

            int outerEdgeLength = outside.Count();
            int innerEdgeLength = inside.Count();
            int outerIndex      = 0;
            int innerIndex      = 0;

            while (innerIndex < innerEdgeLength - 1 || outerIndex < outerEdgeLength - 1)
            {
                if (innerIndex < innerEdgeLength - 1)
                {
                    if (outerIndex < outerEdgeLength - 1)
                    {
                        int id1 = outside.GetIndex();
                        int id2 = inside.GetIndex();
                        int id3 = outside.GetNext();
                        int id4 = inside.GetNext();

                        Vector3 P1 = vs[id1];
                        Vector3 P2 = vs[id2];
                        Vector3 P3 = vs[id3];
                        Vector3 P4 = vs[id4];

                        float dInner = (P4 - P1).sqrMagnitude;
                        float dOuter = (P3 - P2).sqrMagnitude;

                        if (dInner <= dOuter)
                        {
                            intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2);
                            innerIndex++;
                            inside.Move();
                        }
                        else
                        {
                            intTrIndex = builder.WriteTriangle(intTrIndex, id1, id3, id2);
                            outerIndex++;
                            outside.Move();
                        }
                    }
                    else
                    {
                        int id1 = outside.GetIndex();
                        int id2 = inside.GetIndex();
                        int id4 = inside.GetNext();

                        intTrIndex = builder.WriteTriangle(intTrIndex, id1, id4, id2);
                        innerIndex++;
                        inside.Move();
                    }
                }
                else
                {
                    int id1 = outside.GetIndex();
                    int id2 = inside.GetIndex();
                    int id3 = outside.GetNext();
                    intTrIndex = builder.WriteTriangle(
                        intTrIndex, id1, id3, id2);
                    outerIndex++;
                    outside.Move();
                }
            }
            return(intTrIndex);
        }
Beispiel #29
0
 public bool Generate(Mesh startShape, Transform loc2WorldTrafo, Shader shader, out OutputMesh[] meshes, string specialMaterial)
 {
     Vector3[] vertices = new Vector3[startShape.vertices.Length];
     for (int i = 0; i < vertices.Length; i++)  
         vertices[i] = loc2WorldTrafo.TransformPoint(startShape.vertices[i]);
     
     if(!Prt4Unity.Generate(ctx, vertices, vertices.Length, startShape.triangles, startShape.triangles.Length, specialMaterial))
     {
         meshes = null;
         return false;
     }
     Material[] materials = GetMaterials(shader);
     GetMeshes(materials, loc2WorldTrafo, out meshes);
     Prt4Unity.ReleaseMeshesAndMaterials(ctx);
     return true;
 }
 public void Free()
 {
     used = false;
     tessellationOutput = null;
     outputMesh         = null;
 }
 public NetPolylineInternalIndicesArray(CPNSideEdge sideEdge, OutputMesh builder)
 {
     this.sideEdge = sideEdge;
     this.builder  = builder;
     this.position = 0;
 }
Beispiel #32
0
        // Retrieves meshes from last generate result and creates according Unity meshes
        void GetMeshes(Material[] materials, Transform loc2WorldTrafo, out OutputMesh[] meshes)
        {
            int numMeshes = Prt4Unity.GetMeshCount(ctx);
            meshes = new OutputMesh[numMeshes];
            for(int i = 0; i < numMeshes; i++)
            {
                IntPtr name, pVertices, pNormals, pTexcoords;
                int numVertices;
                Prt4Unity.GetMesh(ctx, i, out name, out numVertices, out pVertices, out pNormals, out pTexcoords);
                OutputMesh outputMesh = new OutputMesh();
                meshes[i] = outputMesh;
                outputMesh.mesh = new Mesh();
                outputMesh.mesh.name = Marshal.PtrToStringUni(name);
                float[] floats = new float[numVertices * 3];
                Marshal.Copy(pVertices, floats, 0, numVertices * 3);
                Vector3[] vertices = new Vector3[numVertices];
                Vector3 preScale = loc2WorldTrafo.localScale;
                for (int v = 0; v < numVertices; v++) {
                    vertices[v] = new Vector3(floats[3 * v + 0], floats[3 * v + 1], floats[3 * v + 2]);
                    vertices[v] = loc2WorldTrafo.InverseTransformPoint(vertices[v]);
                    vertices[v].x *= preScale.x;
					vertices[v].y *= preScale.y;
					vertices[v].z *= preScale.z;
                }
                outputMesh.mesh.vertices = vertices;
                Marshal.Copy(pNormals, floats, 0, numVertices * 3);
                Vector3[] normals = new Vector3[numVertices];
                for(int v = 0; v < numVertices; v++)
                    normals[v] = new Vector3(floats[3 * v + 0], floats[3 * v + 1], floats[3 * v + 2]);
                outputMesh.mesh.normals = normals;
                if(pTexcoords != IntPtr.Zero)
                {
                    Marshal.Copy(pTexcoords, floats, 0, numVertices * 2);
                    Vector2[] texcoords = new Vector2[numVertices];
                    for(int v = 0; v < numVertices; v++)
                        texcoords[v] = new Vector2(floats[2 * v + 0], floats[2 * v + 1]);
                    outputMesh.mesh.uv = texcoords;
                }

                int numSubMeshes = Prt4Unity.GetSubMeshCount(ctx, i);
                outputMesh.mesh.subMeshCount = (int)numSubMeshes;
                outputMesh.materials = new Material[numSubMeshes];
                for(int s = 0; s < numSubMeshes; s++)
                {
                    IntPtr pIndices;
                    int numIndices, materialIndex;
                    Prt4Unity.GetSubMesh(ctx, i, s, out pIndices, out numIndices, out materialIndex);
                    int[] indices = new int[numIndices];
                    Marshal.Copy(pIndices, indices, 0, numIndices);
                    outputMesh.mesh.SetTriangles(indices, (int)s);
                    outputMesh.materials[s] = materials[materialIndex];
                }
            }
        }
Beispiel #33
0
 public bool Generate(Mesh startShape, Transform loc2WorldTrafo, Shader shader, out OutputMesh[] meshes)
 {
     ctx.SetAttributes(attributes);
     return ctx.Generate(startShape, loc2WorldTrafo, shader, out meshes, collisionMaterial);
 }