Exemplo n.º 1
0
        void _determinePdeToConstrainEdge(Edge edge, float weight, ref PlaneDistanceError pde)
        {
            int vi0 = edge.v[0];
            int vi1 = edge.v[1];

            Vector3 v0    = mesh.vertices[vi0].coords;
            Vector3 vEdge = mesh.vertices[vi1].coords - v0;
            Vector3 edgeNormal;

            pde.Clear();
            float mag = vEdge.sqrMagnitude;

            for (int i = 0; i < edge.linkedFaces.Count; ++i)
            {
                edgeNormal = mesh.faces[edge.linkedFaces[i]].normal;

                Vector3 n = Vector3.Cross(vEdge, edgeNormal);                 // normal to edge and face
                UnityUtils.NormalizeSmallVector(ref n);

                float d = -Vector3.Dot(n, v0);
                pde2.Set(n.x, n.y, n.z, d, mag);
                // Multiply by face area (factor) for weighting
                pde2.OpMul(pde2.Factor() * weight * 0.5f);
                pde.OpAdd(pde2);
            }
        }
Exemplo n.º 2
0
        void _determinePdeForFace(int faceIndex, ref PlaneDistanceError pde)
        {
            KrablMesh.Face face = mesh.faces[faceIndex];
            Vector3        n    = mesh.CalculateFaceNormal(faceIndex);

            // Create error struct from the plane of the face (using face normal)
            float offset = -Vector3.Dot(n, mesh.vertices[face.v[0]].coords);

            pde.Set(n.x, n.y, n.z, offset, mesh.CalculateFaceArea(faceIndex));
            // Multiply by face area (factor) for weighting
            pde.OpMul(pde.Factor());
        }
Exemplo n.º 3
0
        void _calculateEdgeCost(int edgeIndex, CollapseInfo cinfo)
        {
            Edge   edge    = mesh.edges[edgeIndex];
            int    vindex0 = edge.v[0];
            int    vindex1 = edge.v[1];
            Vertex v0      = mesh.vertices[vindex0];
            Vertex v1      = mesh.vertices[vindex1];

            cinfo.vp = edge;

            PlaneDistanceError pde = pdePerVertex[edge.v[0]] + pdePerVertex[edge.v[1]];

            if (_parameters.recalculateVertexPositions)
            {
                if (mesh.IsEdgeBorder(edgeIndex) == false && pde.OptimalVertex(ref cinfo.targetPosition))
                {
                    cinfo.cost = (float)pde.CalculateError(cinfo.targetPosition);
                    //	Debug.Log(">optimal placement");
                }
                else if (pde.OptimalVertexLinear(ref cinfo.targetPosition, v0.coords, v1.coords))
                {
                    // the error term is not solvable
                    // Try to find a vert on the line going from v0 to v1
                    cinfo.cost = (float)pde.CalculateError(cinfo.targetPosition);
                    //	Debug.Log(">line placement");
                }
                else
                {
                    // Choose vert from the two endpoints and the midpoint
                    Vector3 tp     = 0.5f * (v0.coords + v1.coords);
                    double  error0 = pde.CalculateError(v0.coords);
                    double  error1 = pde.CalculateError(v1.coords);
                    double  error2 = pde.CalculateError(tp);
                    if (error0 < error1)
                    {
                        if (error0 < error2)
                        {
                            cinfo.targetPosition = v0.coords; cinfo.cost = (float)error0;
                        }
                        else
                        {
                            cinfo.targetPosition = tp; cinfo.cost = (float)error2;
                        }
                    }
                    else
                    {
                        if (error1 < error2)
                        {
                            cinfo.targetPosition = v1.coords; cinfo.cost = (float)error1;
                        }
                        else
                        {
                            cinfo.targetPosition = tp; cinfo.cost = (float)error2;
                        }
                    }
                }
            }
            else
            {
                double error0 = pde.CalculateError(v0.coords);
                double error1 = pde.CalculateError(v1.coords);
                if (error0 < error1)
                {
                    cinfo.targetPosition = v0.coords;
                    cinfo.cost           = (float)error0;
                }
                else
                {
                    cinfo.targetPosition = v1.coords;
                    cinfo.cost           = (float)error1;
                }
            }

            // Choose minimal error point -> bad for border edges which are underdefined
            if (localizeErrors)
            {
                cinfo.cost *= 1.0f / ((float)pde.Factor());
            }

            cinfo.positionCost = cinfo.cost;

            if (noPenalties == false)
            {
                _updateEdgePenalties(edgeIndex, cinfo, -1);
            }
        }