예제 #1
0
 private void ModifyVertex(CharacterData characterData, ref UIVertex uiVertex)
 {
     for (int i = 0; i < vertexModifiers.Length; i++)
     {
         VertexModifier vertexModifier = vertexModifiers[i];
         vertexModifier.Apply(characterData, ref uiVertex);
     }
 }
예제 #2
0
        public void ForEachVertex(VertexModifier modifier)
        {
            int count = Vertices.Count;

            for (int i = 0; i < count; ++i)
            {
                Vector3 vertex = Vertices[i];
                Vector2 uv     = UVs[i];

                modifier(ref vertex, ref uv);

                Vertices[i] = vertex;
                UVs[i]      = uv;
            }
        }
        static void Build14(int gridSize, out VertexModifier vertexModifier, out Dictionary<string, MeshRebuilder> rebuilders)
        {
            List<Vector3B> vertices = new List<Vector3B>();

            for (int y = 0; y < gridSize; ++y)
                for (int x = 0; x < gridSize; ++x)
                    vertices.Add(new Vector3B(2 * x, 0, 2 * y));

            List<int> triangles = new List<int>();

            for (int y = 0; y < gridSize - 1; ++y)
                for (int x = 0; x < gridSize - 1; ++x)
                {
                    triangles.Add(gridSize * (y) + (x));
                    triangles.Add(gridSize * (y) + (x + 1));
                    triangles.Add(gridSize * (y + 1) + (x + 1));

                    triangles.Add(gridSize * (y) + (x));
                    triangles.Add(gridSize * (y + 1) + (x + 1));
                    triangles.Add(gridSize * (y + 1) + (x));
                }

            var physicsMesh = new BEPUphysics.BroadPhaseEntries.StaticMesh(vertices.ToArray(), triangles.ToArray(), BEPUutilities.AffineTransform.Identity);

            vertexModifier = (Random random) =>
            {
                for (int vertexIndex = 0; vertexIndex < physicsMesh.Mesh.Data.Vertices.Length; ++vertexIndex)
                    physicsMesh.Mesh.Data.Vertices[vertexIndex].Y = (float)random.NextDouble() * 2;
            };

            rebuilders = new Dictionary<string, MeshRebuilder>();
            rebuilders.Add("v1.4.0 Reconstruct", (i) =>
            {
                physicsMesh.Mesh.Tree.Reconstruct();
                physicsMesh.UpdateBoundingBox();
            });
            rebuilders.Add("v1.4.0 Refit", (i) =>
            {
                physicsMesh.Mesh.Tree.Refit();
                physicsMesh.UpdateBoundingBox();
            });
        }
예제 #4
0
        /// <summary>
        /// Iterates over the vertices in the height map and modifies them according to the provided modifier.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="radius"></param>
        /// <param name="magnitude"></param>
        /// <param name="modifyVertex"></param>
        private void ModifyVertices(Vector2 position, float radius, float magnitude, int numPasses, VertexModifier modifyVertex)
        {
            if (NewAction)
            {
                NewAction = false;

                BackupVertices();
                mUndoStack.Push(mCurrentAction);
                mCurrentAction = null;
                mCurrentAction = new ModifyAction();
                mRedoStack.Clear();
            }

            float radiusSquared = radius * radius;

            // Normalize origin of modification to [0,mHeight), [0, mWidth).
            position.X = position.X / Utils.WorldScale.X + mWidth / 2;
            position.Y = position.Y / Utils.WorldScale.Z + mHeight / 2;

            int minZ = (int)Math.Max(0, position.Y - radius), maxZ = (int)Math.Min(mHeight - 1, position.Y + radius);
            int minX = (int)Math.Max(0, position.X - radius), maxX = (int)Math.Min(mWidth - 1, position.X + radius);

            for (int pass = 0; pass < numPasses; ++pass)
            {
                for (int zIndex = minZ; zIndex <= maxZ; ++zIndex)
                {
                    for (int xIndex = minX; xIndex <= maxX; ++xIndex)
                    {
                        Vector2 displacement = new Vector2(xIndex, zIndex) - position;

                        if (mIsBlock || displacement.LengthSquared() < radiusSquared)
                        {
                            float featherScale = mIsFeathered ? mIsBlock ? Math.Max(0.0f, (float)Math.Log(radius * 2.0f - displacement.Length())) / radius : Math.Max(0.0f, (float)Math.Log(radius - displacement.Length())) / radius : 1.0f;
                            modifyVertex(xIndex, zIndex, magnitude * featherScale, pass);

                            WriteDirtyBit(xIndex, zIndex);
                        }
                    }
                }
            }

            UpdateNormalVectors(minZ, maxZ, minX, maxX);
            UpdateVertexBuffers();
        }
 void Start()
 {
     _modifier = GetComponent <VertexModifier>();
     StartCoroutine(Shrink());
 }
        static void Test(VertexModifier vertexModifier, MeshRebuilder rebuilder, CostMetricMeasurer costMeasurer, string testName, int iterations)
        {
            Random random = new Random(5);
            double sum = 0;
            double fastest = double.MaxValue;
            double slowest = 0;
            for (int iterationIndex = 0; iterationIndex < iterations; ++iterationIndex)
            {
                vertexModifier(random);

                var start = Stopwatch.GetTimestamp();
                rebuilder(iterationIndex);
                var end = Stopwatch.GetTimestamp();

                var time = (end - start) / (double)Stopwatch.Frequency;

                if (time < fastest) fastest = time;
                if (time > slowest) slowest = time;

                sum += time;
            }
            Console.WriteLine($"{testName}:");
            Console.WriteLine($"Average: {sum / iterations}");
            Console.WriteLine($"Fastest: {fastest}");
            Console.WriteLine($"Slowest: {slowest}");
            if (costMeasurer != null)
                Console.WriteLine($"Cost Metric: {costMeasurer()}");
        }
        static void Build2(int gridSize, out VertexModifier vertexModifier, out Dictionary<string, MeshRebuilder> rebuilders, out CostMetricMeasurer costMeasurer, out MeshDisposer disposer)
        {
            List<Vector3> vertices = new List<Vector3>();

            for (int y = 0; y < gridSize; ++y)
                for (int x = 0; x < gridSize; ++x)
                    vertices.Add(new Vector3(2 * x, 0, 2 * y));

            List<int> triangles = new List<int>();

            for (int y = 0; y < gridSize - 1; ++y)
                for (int x = 0; x < gridSize - 1; ++x)
                {
                    triangles.Add(gridSize * (y) + (x));
                    triangles.Add(gridSize * (y) + (x + 1));
                    triangles.Add(gridSize * (y + 1) + (x + 1));

                    triangles.Add(gridSize * (y) + (x));
                    triangles.Add(gridSize * (y + 1) + (x + 1));
                    triangles.Add(gridSize * (y + 1) + (x));
                }

            var physicsMesh = new Mesh(vertices.ToArray(), triangles.ToArray());

            vertexModifier = (Random random) =>
            {
                for (int vertexIndex = 0; vertexIndex < physicsMesh.Vertices.Length; ++vertexIndex)
                    physicsMesh.Vertices[vertexIndex].Y = (float)random.NextDouble() * 2;
            };

            rebuilders = new Dictionary<string, MeshRebuilder>();
            //Note incremental first, sweep second. Starts the refine off with a better tree to begin with so it doesn't to do an unrealistic amount of optimization to begin with.
            rebuilders.Add("v2 Reconstruct Incremental", (i) => physicsMesh.RebuildIncremental());
            rebuilders.Add("v2 Reconstruct Sweep", (i) => physicsMesh.RebuildSweep());
            rebuilders.Add("v2 Refit And Refine", (i) => physicsMesh.RefitWithIncrementalRefine(i));
            rebuilders.Add("v2 Refit", (i) => physicsMesh.Refit());

            disposer = () => { physicsMesh.Tree.Dispose(); };

            costMeasurer = () => { return physicsMesh.Tree.MeasureCostMetric(); };
        }
예제 #8
0
        private void IterateOverTerrainVertices(IEnumerable<Vector3> selectedBlocks, Vector3 center, float radius, VertexModifier modifier, float deltaHeight)
        {
            Vector2 centerVertexSpace = new Vector2(center.X / BLOCK_SIZE * HeightMapMesh.NUM_SIDE_VERTICES, center.Z / BLOCK_SIZE * HeightMapMesh.NUM_SIDE_VERTICES);

            float radiusVertexSpace = radius / BLOCK_SIZE * (float)Math.Sqrt(2 * HeightMapMesh.NUM_SIDE_VERTICES * HeightMapMesh.NUM_SIDE_VERTICES);
            float radiusSquared = radiusVertexSpace * radiusVertexSpace;

            int minX = (int)Math.Floor(centerVertexSpace.X - radiusVertexSpace), maxX = (int)Math.Ceiling(centerVertexSpace.X + radiusVertexSpace);
            int minZ = (int)Math.Floor(centerVertexSpace.Y - radiusVertexSpace), maxZ = (int)Math.Ceiling(centerVertexSpace.Y + radiusVertexSpace);

            for (int z = minZ; z <= maxZ; z++)
            {
                for (int x = minX; x <= maxX; x++)
                {
                    Vector2 positionVertexSpace = new Vector2(x, z);
                    if ((positionVertexSpace - centerVertexSpace).LengthSquared() <= radiusSquared)
                    {
                        modifier(selectedBlocks, positionVertexSpace, deltaHeight);
                    }
                }
            }

            Vector3 radiusOffset = new Vector3(radius, 0, radius);
            Vector3 minCoordinate = CoordinateFromPosition(center - radiusOffset) + new Vector3(-1, 0, -1);
            Vector3 maxCoordinate = CoordinateFromPosition(center + radiusOffset) + new Vector3(1, 0, 1);

            List<Tuple<Vector3, List<Direction>>> blocksToConnectNormals = new List<Tuple<Vector3,List<Direction>>>();
            for (int blockZ = (int)minCoordinate.Z; blockZ <= (int)maxCoordinate.Z; ++blockZ)
            {
                for (int blockX = (int)minCoordinate.X; blockX <= (int)maxCoordinate.X; ++blockX)
                {
                    Vector3 coordinate = new Vector3(blockX, minCoordinate.Y, blockZ);
                    if (!mBlocks.ContainsKey(coordinate))
                    {
                        continue;
                    }

                    List<Direction> neighbors = new List<Direction>();
                    if (blockZ == (int)minCoordinate.Z)
                    {
                        neighbors.Add(Direction.NORTH);
                    }
                    neighbors.Add(Direction.SOUTH);

                    if (blockX == (int)minCoordinate.X)
                    {
                        neighbors.Add(Direction.WEST);
                    }
                    neighbors.Add(Direction.EAST);

                    UpdateMesh(coordinate, neighbors);

                    blocksToConnectNormals.Add(new Tuple<Vector3,List<Direction>>(coordinate, neighbors));

                    mSpace.Remove(mBlocks[coordinate].HeightMap.StaticCollidable);
                    mBlocks[coordinate].HeightMap.UpdateStaticCollidable();
                    mSpace.Add(mBlocks[coordinate].HeightMap.StaticCollidable);
                }
            }

            foreach (Tuple<Vector3, List<Direction>> neighbor in blocksToConnectNormals)
            {
                AttachNeighborNormals(neighbor.Item1, neighbor.Item2);
            }
        }