Ejemplo n.º 1
0
        //void generateLookups(List<Vector3> vertices, List<Face3> faces, List<MetaVertex> metaVertices, List<Edge> edges ) {
        void generateLookups(List <Vector3> vertices, List <Face3> faces, MetaVertex[] metaVertices, Dictionary <string, Edge> edges)
        {
            Face3 face, edge;

            for (int i = 0, il = vertices.Count; i < il; i++)
            {
                //metaVertices[ i ] = { edges: [] };
                metaVertices[i] = new MetaVertex();
            }

            for (int i = 0, il = faces.Count; i < il; i++)
            {
                face = faces[i];

                processEdge(face.a, face.b, vertices, edges, face, metaVertices);
                processEdge(face.b, face.c, vertices, edges, face, metaVertices);
                processEdge(face.c, face.a, vertices, edges, face, metaVertices);
            }
        }
Ejemplo n.º 2
0
        /////////////////////////////

        // Performs one iteration of Subdivision
        void smooth(Geometry geometry)
        {
            Vector3 tmp = new Vector3();

            List <Vector3> oldVertices;
            List <Face3>   oldFaces;
            List <Vector3> newVertices;
            List <Face3>   newFaces;          // newUVs = [];

            int n, l;
            //List<Edge> sourceEdges;
            Dictionary <string, Edge> sourceEdges;

            //var metaVertices, sourceEdges;

            // new stuff.
            //var newSourceVertices;

            oldVertices = geometry.vertices;       // { x, y, z}
            oldFaces    = geometry.faces;          // { a: oldVertex1, b: oldVertex2, c: oldVertex3 }

            /******************************************************
             *
             * Step 0: Preprocess Geometry to Generate edges Lookup
             *
             *******************************************************/

            MetaVertex[] metaVertices = new MetaVertex[oldVertices.Count];
            //sourceEdges = {}; // Edge => { oldVertex1, oldVertex2, faces[]  }
            //sourceEdges = new List<Edge>();
            sourceEdges = new Dictionary <string, Edge>();

            generateLookups(oldVertices, oldFaces, metaVertices, sourceEdges);


            /******************************************************
             *
             *	Step 1.
             *	For each edge, create a new Edge Vertex,
             *	then position it.
             *
             *******************************************************/

            List <Vector3> newEdgeVertices = new List <Vector3>();
            Vector3        other           = new Vector3();
            //Edge currentEdge;
            Vector3 newEdge;
            Face3   face;
            float   edgeVertexWeight;
            float   adjacentVertexWeight;
            int     connectedFaces;

            //for ( i in sourceEdges ) {
            foreach (Edge currentEdge in sourceEdges.Values)
            {
                //currentEdge = sourceEdges[ i ];
                newEdge = new Vector3();

                edgeVertexWeight     = 3.0f / 8;
                adjacentVertexWeight = 1.0f / 8;

                connectedFaces = currentEdge.faces.Count;

                // check how many linked faces. 2 should be correct.
                if (connectedFaces != 2)
                {
                    // if length is not 2, handle condition
                    edgeVertexWeight     = 0.5f;
                    adjacentVertexWeight = 0;

                    if (connectedFaces != 1)
                    {
                        if (WARNINGS)
                        {
                            Debug.Log("Subdivision Modifier: Number of connected faces != 2, is: " + connectedFaces + " / " + currentEdge);
                        }
                    }
                }

                //newEdge.addVectors( currentEdge.a, currentEdge.b ).multiplyScalar( edgeVertexWeight );
                newEdge = (currentEdge.a + currentEdge.b) * (edgeVertexWeight);

                //tmp.set( 0, 0, 0 );
                tmp = new Vector3(0, 0, 0);

                for (int j = 0; j < connectedFaces; j++)
                {
                    face = currentEdge.faces[j];

                    for (int k = 0; k < 3; k++)
                    {
                        //other = oldVertices[ face[ ABC[k] ] ];
                        int index;
                        if (k == 0)
                        {
                            index = face.a;
                        }
                        else if (k == 1)
                        {
                            index = face.b;
                        }
                        else
                        {
                            index = face.c;
                        }
                        other = oldVertices[index];

                        if (other != currentEdge.a && other != currentEdge.b)
                        {
                            break;
                        }
                    }
                    tmp += (other);
                }

                tmp     *= (adjacentVertexWeight);
                newEdge += (tmp);

                currentEdge.newEdge = newEdgeVertices.Count;
                newEdgeVertices.Add(newEdge);
                // console.log(currentEdge, newEdge);
            }

            /******************************************************
             *
             *	Step 2.
             *	Reposition each source vertices.
             *
             *******************************************************/
            float          beta = 0.0f;
            float          sourceVertexWeight;
            float          connectingVertexWeight;
            Edge           connectingEdge;
            List <Edge>    connectingEdges;
            Vector3        oldVertex;
            Vector3        newSourceVertex;
            List <Vector3> newSourceVertices = new List <Vector3>();

            for (int i = 0, il = oldVertices.Count; i < il; i++)
            {
                oldVertex = oldVertices[i];

                // find all connecting edges (using lookupTable)
                connectingEdges = metaVertices[i].edges;
                n = connectingEdges.Count;
                //beta;

                if (n == 3)
                {
                    beta = 3.0f / 16;
                }
                else if (n > 3)
                {
                    beta = 3.0f / (8 * n);                       // Warren's modified formula
                }

                // Loop's original beta formula
                // beta = 1 / n * ( 5/8 - Math.pow( 3/8 + 1/4 * Math.cos( 2 * Math. PI / n ), 2) );

                sourceVertexWeight     = 1 - n * beta;
                connectingVertexWeight = beta;

                if (n <= 2)
                {
                    // crease and boundary rules
                    // console.warn('crease and boundary rules');

                    if (n == 2)
                    {
                        if (WARNINGS)
                        {
                            Debug.LogWarning("2 connecting edges" + connectingEdges);
                        }
                        sourceVertexWeight     = 3.0f / 4;
                        connectingVertexWeight = 1.0f / 8;

                        // sourceVertexWeight = 1;
                        // connectingVertexWeight = 0;
                    }
                    else if (n == 1)
                    {
                        if (WARNINGS)
                        {
                            Debug.LogWarning("only 1 connecting edge");
                        }
                    }
                    else if (n == 0)
                    {
                        if (WARNINGS)
                        {
                            Debug.LogWarning("0 connecting edges");
                        }
                    }
                }

                //newSourceVertex = oldVertex.clone().multiplyScalar( sourceVertexWeight );
                newSourceVertex = oldVertex * (sourceVertexWeight);

                tmp = Vector3.zero;

                for (int j = 0; j < n; j++)
                {
                    connectingEdge = connectingEdges[j];
                    other          = connectingEdge.a != oldVertex ? connectingEdge.a : connectingEdge.b;
                    tmp           += (other);
                }

                tmp             *= (connectingVertexWeight);
                newSourceVertex += (tmp);

                newSourceVertices.Add(newSourceVertex);
            }


            /******************************************************
             *
             *	Step 3.
             *	Generate Faces between source vertecies
             *	and edge vertices.
             *
             *******************************************************/

            //newVertices = newSourceVertices.concat( newEdgeVertices );
            Debug.LogWarning("TODO: CHECK");
            //newVertices = newSourceVertices;
            newVertices = new List <Vector3>();
            newVertices.AddRange(newSourceVertices);
            newVertices.AddRange(newEdgeVertices);

            int sl = newSourceVertices.Count;
            int edge1, edge2, edge3;

            newFaces = new List <Face3>();

            for (int i = 0, il = oldFaces.Count; i < il; i++)
            {
                face = oldFaces[i];

                // find the 3 new edges vertex of each old face

                edge1 = getEdge(face.a, face.b, sourceEdges).newEdge + sl;
                edge2 = getEdge(face.b, face.c, sourceEdges).newEdge + sl;
                edge3 = getEdge(face.c, face.a, sourceEdges).newEdge + sl;

                // create 4 faces.

                newFace(newFaces, edge1, edge2, edge3);
                newFace(newFaces, face.a, edge1, edge3);
                newFace(newFaces, face.b, edge2, edge1);
                newFace(newFaces, face.c, edge3, edge2);
            }

            // Overwrite old arrays
            geometry.vertices = newVertices;
            geometry.faces    = newFaces;

            // console.log('done');
        }