private MeshQuery.Result ModifyVertices(MeshQuery query, List <int> indecies)
        {
            var upMode           = query.ForceDirection.y > 0;
            var modified         = 0;
            var scannedTriangles = 0;

            // modify vertices
            for (int j = 0; j < indecies.Count; j++)
            {
                int outerIndex = indecies[j] * 3;
                for (var k = 0; k < 3; k++)
                {
                    var index    = outerIndex + k;
                    var vertex   = query.Vertices[index];
                    var distance = Vector3.Distance(vertex, query.Epicenter);
                    if (distance < query.Radius)
                    {
                        float heightDiff = query.GetForceChange(distance);
                        query.Vertices[index] = new Vector3(
                            vertex.x,
                            vertex.y + (upMode ? heightDiff : -heightDiff),
                            vertex.z);
                        modified++;
                    }
                }
                scannedTriangles++;
            }

            return(new MeshQuery.Result(query.Vertices)
            {
                ModifiedVertices = modified,
                ScannedTriangles = scannedTriangles
            });
        }
Example #2
0
        /// <summary> Modifies mesh plane based on it's equation parameters. </summary>
        protected MeshQuery.Result Modify(MeshQuery query, int startIndex, int endIndex,
                                          Vector3 n, float magnitude, float d)
        {
            var halfVertexCount = query.Vertices.Length / 2;
            var vertices        = query.Vertices;
            int modified        = 0;
            var destroyed       = 0;

            for (int j = startIndex; j < endIndex; j += 3)
            {
                // triangle is already collapsed
                if (vertices[j] == vertices[j + 1])
                {
                    continue;
                }

                for (int i = j; i < j + 3; i++)
                {
                    var v        = vertices[i];
                    var distance = Vector3.Distance(v, query.Epicenter);
                    if (distance < query.Radius)
                    {
                        var distanceToWall = (v.x * n.x + v.y * n.y + v.z * n.z - d) / magnitude;
                        var forceChange    = query.GetForceChange(distance);
                        // NOTE whole traingle should be removed as one of the vertices is
                        // moved more than threshold allows
                        if (Math.Abs(distanceToWall + forceChange) > query.OffsetThreshold)
                        {
                            // collapse triangle into point
                            var firstVertIndex = i - i % 3;
                            vertices[firstVertIndex + 1] = vertices[firstVertIndex];
                            vertices[firstVertIndex + 2] = vertices[firstVertIndex];

                            var backSideIndex = halfVertexCount + firstVertIndex;
                            vertices[backSideIndex + 1] = vertices[backSideIndex];
                            vertices[backSideIndex + 2] = vertices[backSideIndex];
                            destroyed += 3;
                            break;
                        }
                        vertices[i] = v + forceChange * query.ForceDirection;
                        vertices[halfVertexCount + i] = vertices[i];
                        modified++;
                    }
                }
            }
            return(new MeshQuery.Result(query.Vertices)
            {
                DestroyedVertices = destroyed,
                ModifiedVertices = modified,
                ScannedTriangles = -1
            });
        }
        /// <inheritdoc />
        public MeshQuery.Result Modify(MeshQuery query)
        {
            var vertices  = query.Vertices;
            int modified  = 0;
            var destroyed = 0;

            for (int j = 0; j < vertices.Length; j += 3)
            {
                // triangle is already collapsed
                if (vertices[j] == vertices[j + 1])
                {
                    continue;
                }

                for (int i = j; i < j + 3; i++)
                {
                    var v        = vertices[i];
                    var distance = Vector3.Distance(v, query.Epicenter);
                    if (distance < query.Radius)
                    {
                        var forceChange      = query.GetForceChange(distance);
                        var distanceToCenter = Vector3.Distance(v, _center);
                        if (Math.Abs(_radius - distanceToCenter + forceChange) > query.OffsetThreshold)
                        {
                            // collapse triangle into point
                            var firstVertIndex = i - i % 3;
                            vertices[firstVertIndex + 1] = vertices[firstVertIndex];
                            vertices[firstVertIndex + 2] = vertices[firstVertIndex];
                            destroyed += 3;
                            break;
                        }
                        var forceDirection = (_center - v).normalized;
                        vertices[i] = v + forceChange * forceDirection;
                        modified++;
                    }
                }
            }

            return(new MeshQuery.Result(vertices)
            {
                DestroyedVertices = destroyed,
                ModifiedVertices = modified
            });
        }