Exemplo n.º 1
0
        // Triangulate Bone Samplers.  todo: Burst it.
        internal static void TriangulateSamplers(Vector2[] samplers, List <Vector2> triVertices, List <int> triIndices)
        {
            foreach (var v in samplers)
            {
                var vertexCount = triVertices.Count;

                for (int i = 0; i < triIndices.Count / 3; ++i)
                {
                    int    i1     = triIndices[0 + (i * 3)];
                    int    i2     = triIndices[1 + (i * 3)];
                    int    i3     = triIndices[2 + (i * 3)];
                    float2 v1     = triVertices[i1];
                    float2 v2     = triVertices[i2];
                    float2 v3     = triVertices[i3];
                    var    inside = ModuleHandle.IsInsideTriangle(v, v1, v2, v3);
                    if (inside)
                    {
                        triVertices.Add(v);
                        triIndices.Add(i1); triIndices.Add(i2); triIndices.Add(vertexCount);
                        triIndices.Add(i2); triIndices.Add(i3); triIndices.Add(vertexCount);
                        triIndices.Add(i3); triIndices.Add(i1); triIndices.Add(vertexCount);
                        break;
                    }
                }
            }
        }
Exemplo n.º 2
0
 private static bool SubdivideSafe(NativeArray <float2> points, NativeArray <int2> edges, ref NativeArray <float2> outVertices, ref int outVertexCount, ref NativeArray <int> outIndices, ref int outIndexCount, ref NativeArray <int2> outEdges, ref int outEdgeCount, float areaFactor, float areaThreshold, int refineIterations, int smoothenIterations)
 {
     try
     {
         ModuleHandle.Subdivide(Allocator.Persistent, points, edges, ref outVertices, ref outVertexCount, ref outIndices, ref outIndexCount, ref outEdges, ref outEdgeCount, areaFactor, areaThreshold, refineIterations, smoothenIterations);
     }
     catch (Exception)
     {
         return(false);
     }
     return(true);
 }
Exemplo n.º 3
0
 private static bool TessellateSafe(NativeArray <float2> points, NativeArray <int2> edges, ref NativeArray <float2> outVertices, ref int outVertexCount, ref NativeArray <int> outIndices, ref int outIndexCount, ref NativeArray <int2> outEdges, ref int outEdgeCount)
 {
     try
     {
         ModuleHandle.Tessellate(Allocator.Persistent, points, edges, ref outVertices, ref outVertexCount, ref outIndices, ref outIndexCount, ref outEdges, ref outEdgeCount);
     }
     catch (Exception)
     {
         return(false);
     }
     return(true);
 }
Exemplo n.º 4
0
        private static unsafe void TessellateBurst(Allocator allocator, float2 *points, int pointCount, int2 *edges, int edgeCount, float2 *outVertices, int *outIndices, int2 *outEdges, int arrayCount, int3 *result)
        {
            NativeArray <int2> _edges = new NativeArray <int2>(edgeCount, allocator);

            for (int i = 0; i < _edges.Length; ++i)
            {
                _edges[i] = edges[i];
            }

            NativeArray <float2> _points = new NativeArray <float2>(pointCount, allocator);

            for (int i = 0; i < _points.Length; ++i)
            {
                _points[i] = points[i];
            }

            NativeArray <int>    _outIndices  = new NativeArray <int>(arrayCount, allocator);
            NativeArray <int2>   _outEdges    = new NativeArray <int2>(arrayCount, allocator);
            NativeArray <float2> _outVertices = new NativeArray <float2>(arrayCount, allocator);

            int outEdgeCount   = 0;
            int outIndexCount  = 0;
            int outVertexCount = 0;

            ModuleHandle.Tessellate(allocator, _points, _edges, ref _outVertices, ref outVertexCount, ref _outIndices, ref outIndexCount, ref _outEdges, ref outEdgeCount);

            for (int i = 0; i < outEdgeCount; ++i)
            {
                outEdges[i] = _outEdges[i];
            }
            for (int i = 0; i < outIndexCount; ++i)
            {
                outIndices[i] = _outIndices[i];
            }
            for (int i = 0; i < outVertexCount; ++i)
            {
                outVertices[i] = _outVertices[i];
            }

            result->x = outVertexCount;
            result->y = outIndexCount;
            result->z = outEdgeCount;

            _outVertices.Dispose();
            _outEdges.Dispose();
            _outIndices.Dispose();
            _points.Dispose();
            _edges.Dispose();
        }
Exemplo n.º 5
0
        private static unsafe void SubdivideBurst(Allocator allocator, float2 *points, int pointCount, int2 *edges, int edgeCount, float2 *outVertices, int *outIndices, int2 *outEdges, int arrayCount, float areaFactor, float areaThreshold, int refineIterations, int smoothenIterations, int3 *result)
        {
            NativeArray <int2> _edges = new NativeArray <int2>(edgeCount, allocator);

            for (int i = 0; i < _edges.Length; ++i)
            {
                _edges[i] = edges[i];
            }

            NativeArray <float2> _points = new NativeArray <float2>(pointCount, allocator);

            for (int i = 0; i < _points.Length; ++i)
            {
                _points[i] = points[i];
            }

            NativeArray <int>    _outIndices  = new NativeArray <int>(arrayCount, allocator);
            NativeArray <int2>   _outEdges    = new NativeArray <int2>(arrayCount, allocator);
            NativeArray <float2> _outVertices = new NativeArray <float2>(arrayCount, allocator);
            int outEdgeCount   = 0;
            int outIndexCount  = 0;
            int outVertexCount = 0;

            ModuleHandle.Subdivide(allocator, _points, _edges, ref _outVertices, ref outVertexCount, ref _outIndices, ref outIndexCount, ref _outEdges, ref outEdgeCount, areaFactor, areaThreshold, refineIterations, smoothenIterations);

            for (int i = 0; i < outEdgeCount; ++i)
            {
                outEdges[i] = _outEdges[i];
            }
            for (int i = 0; i < outIndexCount; ++i)
            {
                outIndices[i] = _outIndices[i];
            }
            for (int i = 0; i < outVertexCount; ++i)
            {
                outVertices[i] = _outVertices[i];
            }

            result->x = outVertexCount;
            result->y = outIndexCount;
            result->z = outEdgeCount;

            _outVertices.Dispose();
            _outEdges.Dispose();
            _outIndices.Dispose();
            _points.Dispose();
            _edges.Dispose();
        }
Exemplo n.º 6
0
        // Find Target Area to Subdivide for BBW. todo: Burst it.
        internal static float FindTargetAreaForWeightMesh(List <Vector2> triVertices, List <int> triIndices, float meshAreaFactor, float largestTriangleFactor)
        {
            float totalArea = 0, largestArea = 0, targetArea = 0;

            for (int i = 0; i < triIndices.Count / 3; ++i)
            {
                int    i1   = triIndices[0 + (i * 3)];
                int    i2   = triIndices[1 + (i * 3)];
                int    i3   = triIndices[2 + (i * 3)];
                float2 v1   = triVertices[i1];
                float2 v2   = triVertices[i2];
                float2 v3   = triVertices[i3];
                float  area = ModuleHandle.TriangleArea(v1, v2, v3);
                totalArea   = totalArea + area;
                largestArea = largestArea > area ? largestArea : area;
            }

            targetArea = Mathf.Max(meshAreaFactor * totalArea, largestTriangleFactor * largestArea);
            return(targetArea);
        }
Exemplo n.º 7
0
 // Triangulate Skipped Original Points. These points are discarded during PlanarGrapg cleanup. But bbw only cares if these are part of any geometry. So just insert them. todo: Burst it.
 internal static void TriangulateInternal(int[] internalIndices, List <Vector2> triVertices, List <int> triIndices)
 {
     foreach (var index in internalIndices)
     {
         var v             = triVertices[index];
         var triangleCount = triIndices.Count / 3;
         for (int i = 0; i < triangleCount; ++i)
         {
             int    i1 = triIndices[0 + (i * 3)];
             int    i2 = triIndices[1 + (i * 3)];
             int    i3 = triIndices[2 + (i * 3)];
             float2 v1 = triVertices[i1];
             float2 v2 = triVertices[i2];
             float2 v3 = triVertices[i3];
             var    c1 = (float)Math.Round(ModuleHandle.OrientFast(v1, v2, v), 2);
             if (c1 == 0)
             {
                 triIndices[0 + (i * 3)] = i1; triIndices[1 + (i * 3)] = index; triIndices[2 + (i * 3)] = i3;
                 triIndices.Add(index); triIndices.Add(i2); triIndices.Add(i3);
             }
             else
             {
                 var c2 = (float)Math.Round(ModuleHandle.OrientFast(v2, v3, v), 2);
                 if (c2 == 0)
                 {
                     triIndices[0 + (i * 3)] = i2; triIndices[1 + (i * 3)] = index; triIndices[2 + (i * 3)] = i1;
                     triIndices.Add(index); triIndices.Add(i3); triIndices.Add(i1);
                 }
                 else
                 {
                     var c3 = (float)Math.Round(ModuleHandle.OrientFast(v3, v1, v), 2);
                     if (c3 == 0)
                     {
                         triIndices[0 + (i * 3)] = i3; triIndices[1 + (i * 3)] = index; triIndices[2 + (i * 3)] = i2;
                         triIndices.Add(index); triIndices.Add(i1); triIndices.Add(i2);
                     }
                 }
             }
         }
     }
 }
Exemplo n.º 8
0
        internal BoneWeight[] CalculateInternal(string name, Vector2[] vertices, int[] indices, Edge[] edges, Vector2[] controlPoints, Edge[] bones, int[] pins, int numSamples, bool subdivide, ref bool done)
        {
            done = false;
            var weights = new BoneWeight[vertices.Length];

            for (var i = 0; i < weights.Length; ++i)
            {
                weights[i] = defaultWeight;
            }
            if (vertices.Length < 3)
            {
                return(weights);
            }

            var boneSamples  = SampleBones(controlPoints, bones, numSamples);
            var verticesList = new List <Vector2>(vertices.Length + controlPoints.Length + boneSamples.Length);

            Round(vertices);
            Round(controlPoints);
            Round(boneSamples);
            verticesList.AddRange(vertices);
            verticesList.AddRange(controlPoints);
            verticesList.AddRange(boneSamples);

            var utEdges    = new List <Edge>(edges);
            var utIndices  = new List <int>();
            var utVertices = new List <Vector2>(vertices);

            // Input Vertices are well refined and smoothed, just triangulate with bones and cages.
            bool ok = TriangulationUtility.TriangulateSafe(utVertices, utEdges, utIndices);

            if (!ok || utIndices.Count == 0)
            {
                utIndices.AddRange(indices);
                utVertices.AddRange(vertices);
            }
            else if (subdivide)
            {
                var targetArea = TriangulationUtility.FindTargetAreaForWeightMesh(utVertices, utIndices, kMeshAreaFactor, kLargestTriangleAreaFactor);
                TriangulationUtility.TessellateSafe(0, 0, 0, 0, targetArea, 1, 0, utVertices, utEdges, utIndices);
            }
            if (utIndices.Count == 0)
            {
                return(weights);
            }

            // Copy Original Indices.
            var coIndices = new List <int>(utIndices);

            utIndices.Clear();
            for (int i = 0; i < coIndices.Count / 3; ++i)
            {
                int    i1 = coIndices[0 + (i * 3)];
                int    i2 = coIndices[1 + (i * 3)];
                int    i3 = coIndices[2 + (i * 3)];
                float2 v1 = utVertices[i1];
                float2 v2 = utVertices[i2];
                float2 v3 = utVertices[i3];
                var    rt = (float)Math.Round(ModuleHandle.OrientFast(v1, v2, v3), 2);
                if (rt != 0)
                {
                    utIndices.Add(i1);
                    utIndices.Add(i2);
                    utIndices.Add(i3);
                }
            }

            // Insert Samplers.
            var internalPoints = new List <int>();

            for (int i = 0; i < utVertices.Count; ++i)
            {
                if (utIndices.Count(x => x == i) == 0)
                {
                    internalPoints.Add(i);
                }
            }

            TriangulationUtility.TriangulateInternal(internalPoints.ToArray(), utVertices, utIndices);
            TriangulationUtility.TriangulateSamplers(boneSamples, utVertices, utIndices);
            TriangulationUtility.TriangulateSamplers(controlPoints, utVertices, utIndices);
            var tessellatedIndices  = utIndices.ToArray();
            var tessellatedVertices = utVertices.ToArray();

            GCHandle verticesHandle      = GCHandle.Alloc(tessellatedVertices, GCHandleType.Pinned);
            GCHandle indicesHandle       = GCHandle.Alloc(tessellatedIndices, GCHandleType.Pinned);
            GCHandle controlPointsHandle = GCHandle.Alloc(controlPoints, GCHandleType.Pinned);
            GCHandle bonesHandle         = GCHandle.Alloc(bones, GCHandleType.Pinned);
            GCHandle pinsHandle          = GCHandle.Alloc(pins, GCHandleType.Pinned);
            GCHandle weightsHandle       = GCHandle.Alloc(weights, GCHandleType.Pinned);

            int result = Bbw(kNumIterations,
                             verticesHandle.AddrOfPinnedObject(), tessellatedVertices.Length, vertices.Length,
                             indicesHandle.AddrOfPinnedObject(), tessellatedIndices.Length,
                             controlPointsHandle.AddrOfPinnedObject(), controlPoints.Length,
                             bonesHandle.AddrOfPinnedObject(), bones.Length,
                             pinsHandle.AddrOfPinnedObject(), pins.Length,
                             weightsHandle.AddrOfPinnedObject());

            switch (result)
            {
            case 1:
            case 2:
                Debug.LogWarning($"Weight generation failure due to unexpected mesh input. Re-generate the mesh with a different Outline Detail value to resolve the issue. Error Code: {result}");
                break;

            case 3:
                if (!PlayerSettings.suppressCommonWarnings)
                {
                    Debug.LogWarning($"Internal weight generation error. Error Code: {result}");
                }
                break;
            }

            verticesHandle.Free();
            indicesHandle.Free();
            controlPointsHandle.Free();
            bonesHandle.Free();
            pinsHandle.Free();
            weightsHandle.Free();

            // OhmDebugger.WriteStatisticsText(verticesList.ToArray(), edges, bones, boneSamples, weights, tessellatedVertices, tessellatedIndices, vertices.Length, controlPoints.Length, boneSamples.Length, "UTess", 1000);

            for (var i = 0; i < weights.Length; ++i)
            {
                var weight = weights[i];

                if (weight.Sum() == 0f)
                {
                    weights[i] = defaultWeight;
                }
                else if (!done)
                {
                    done = (weight.boneIndex0 != 0 || weight.boneIndex1 != 0 || weight.boneIndex2 != 0 || weight.boneIndex3 != 0);
                }
            }

            return(weights);
        }