public static void Stop(Profiler profiler) { if (Active) { profiler?.Stop(); } }
private void Sound() { Profiler.Start(); try { var viewer = Game.RenderProcess.Viewer; if (viewer == null) { return; } OpenAL.Listenerf(OpenAL.AL_GAIN, Simulator.Instance.GamePaused ? 0 : (float)Game.Settings.SoundVolumePercent / 100f); // Update activity sounds if (viewer.Simulator.SoundNotify != TrainEvent.None) { if (viewer.World.GameSounds != null) { viewer.World.GameSounds.HandleEvent(viewer.Simulator.SoundNotify); } viewer.Simulator.SoundNotify = TrainEvent.None; } // Update all sound in our list //float UpdateInterrupts = 0; StartUpdateTime = viewer.RealTime; int RetryUpdate = 0; int restartIndex = -1; while (RetryUpdate >= 0) { bool updateInterrupted = false; lock (SoundSources) { UpdateCounter++; UpdateCounter %= FULLUPDATECYCLE; var removals = new List <KeyValuePair <object, SoundSourceBase> >(); #if DEBUG_SOURCE_SOURCES SoundSrcBaseCount += SoundSources.Count; #endif foreach (var sources in SoundSources) { restartIndex++; #if DEBUG_SOURCE_SOURCES SoundSrcCount += sources.Value.Count; if (sources.Value.Count < 1) { NullSoundSrcBaseCount++; //Trace.TraceInformation("Null SoundSourceBase {0}", sources.Key.ToString()); } #endif if (restartIndex >= RetryUpdate) { for (int i = 0; i < sources.Value.Count; i++) { if (!sources.Value[i].NeedsFrequentUpdate && UpdateCounter > 0) { continue; } if (!sources.Value[i].Update()) { removals.Add(new KeyValuePair <object, SoundSourceBase>(sources.Key, sources.Value[i])); } } } // Check if Add or Remove Sound Sources is waiting to get in - allow it if so. // Update can be a (relatively) long process. if (ASyncUpdatePending > 0) { updateInterrupted = true; RetryUpdate = restartIndex; //Trace.TraceInformation("Sound Source Updates Interrupted: {0}, Restart Index:{1}", UpdateInterrupts, restartIndex); break; } } if (!updateInterrupted) { RetryUpdate = -1; } #if DEBUG_SOURCE_SOURCES Trace.TraceInformation("SoundProcess: sound source self-removal on " + Thread.CurrentThread.Name); #endif // Remove Sound Sources for train no longer active. This doesn't seem to be necessary - // cleanup when a train is removed seems to do it anyway with hardly any delay. foreach (var removal in removals) { // If either of the key or value no longer exist, we can't remove them - so skip over them. if (SoundSources.ContainsKey(removal.Key) && SoundSources[removal.Key].Contains(removal.Value)) { removal.Value.Uninitialize(); SoundSources[removal.Key].Remove(removal.Value); if (SoundSources[removal.Key].Count == 0) { SoundSources.Remove(removal.Key); } } } } //Update check for activity sounds if (ORTSActSoundSourceList != null) { ORTSActSoundSourceList.Update(); } } //if (UpdateInterrupts > 1) // Trace.TraceInformation("Sound Source Update Interrupted more than once: {0}", UpdateInterrupts); // <CSComment> the block below could provide better sound response but is more demanding in terms of CPU time, especially for slow CPUs /* int resptime = (int)((viewer.RealTime - StartUpdateTime) * 1000); * SleepTime = 50 - resptime; * if (SleepTime < 5) * SleepTime = 5;*/ #if DEBUG_SOURCE_SOURCES SoundTime += (int)((viewer.RealTime - StartUpdateTime) * 1000); if (viewer.RealTime - ConsoleWriteTime >= 15f) { Trace.WriteLine("SoundSourceBases (Null): {0} ({1}), SoundSources: {2}, Time: {3}ms", (int)(SoundSrcBaseCount / UpdateCounter), (int)(NullSoundSrcBaseCount / UpdateCounter), (int)(SoundSrcCount / UpdateCounter), (int)(SoundTime / UpdateCounter)); ConsoleWriteTime = viewer.RealTime; SoundTime = 0; UpdateCounter = 0; SoundSrcCount = 0; SoundSrcBaseCount = 0; NullSoundSrcBaseCount = 0; } #endif } finally { Profiler.Stop(); } }
public override void Update(GameTime gameTime) { // <T> --> Toggle between bird's-eye view and camera view. if (InputService.IsPressed(Keys.T, true)) { _topViewEnabled = !_topViewEnabled; if (_topViewEnabled) GraphicsScreen.CameraNode = _topDownCameraNode; else GraphicsScreen.CameraNode = _sceneCameraNode; } // <C> --> Enable or disable frustum culling. if (InputService.IsPressed(Keys.C, true)) _cullingEnabled = !_cullingEnabled; // Elapsed time since the last frame: float timeStep = (float)gameTime.ElapsedGameTime.TotalSeconds; // We update the camera movement target all 10 seconds. const float cameraTargetUpdateInterval = 10; // Get the current camera position. var currentPosition = _sceneCameraNode.PoseWorld.Position; var currentOrientation = _sceneCameraNode.PoseWorld.Orientation; // Update the camera movement. We move a fraction of the targetMovement / targetRotation. _sceneCameraNode.PoseWorld = new Pose( currentPosition + _cameraTargetMovement * timeStep / cameraTargetUpdateInterval, Matrix.CreateRotationY(_cameraTargetRotation * timeStep / cameraTargetUpdateInterval) * currentOrientation); // When the cameraTargetUpdateInterval has passed, we choose a new random movement // vector and rotation angle. _cameraTargetUpdateTime += timeStep; if (_cameraTargetUpdateTime > cameraTargetUpdateInterval) { _cameraTargetUpdateTime = 0; // Get random rotation angle. _cameraTargetRotation = RandomHelper.Random.NextFloat(-ConstantsF.TwoPi, ConstantsF.TwoPi); // Get a random movement vector. We get random vector until we have a movement vector // that does not move the camera outside of the level boundaries. do { _cameraTargetMovement = RandomHelper.Random.NextVector3(-LevelSize, LevelSize); _cameraTargetMovement.Y = 0; } while (Math.Abs(_sceneCameraNode.PoseWorld.Position.X + _cameraTargetMovement.X) > LevelSize / 2 || Math.Abs(_sceneCameraNode.PoseWorld.Position.Z + _cameraTargetMovement.Z) > LevelSize / 2); } // Update collision domain. if (_cullingEnabled) _domain.Update((float)gameTime.ElapsedGameTime.TotalSeconds); // Render objects. var debugRenderer = GraphicsScreen.DebugRenderer; debugRenderer.Clear(); debugRenderer.DrawText("\n\nCulling " + (_cullingEnabled ? "Enabled" : "Disabled")); // Draw frustum. debugRenderer.DrawObject(_sceneCameraNode, Color.Red, true, false); if (!_cullingEnabled) { Profiler.Start("NoCull"); // Simply render all objects. // Frustum culling is not used, so we render ALL objects. Most of them will not // be visible in the _sceneCamera and a lot of rendering time is wasted. foreach (var collisionObject in _domain.CollisionObjects) { var geometricObject = collisionObject.GeometricObject; debugRenderer.DrawObject(geometricObject, Color.Red, false, false); } Profiler.Stop("NoCull"); } else { if (_topViewEnabled) { // Render all objects just for debugging. foreach (var collisionObject in _domain.CollisionObjects) { var geometricObject = collisionObject.GeometricObject; debugRenderer.DrawObject(geometricObject, Color.White, false, false); } } // Use frustum culling: Profiler.Start("WithCull"); // Get the combined WorldViewProjection matrix of the camera. Matrix worldViewProjection = _sceneCameraNode.Camera.Projection.ToMatrix() * _sceneCameraNode.PoseWorld.Inverse; // Extract the frustum planes of the camera. _planes.Clear(); GeometryHelper.ExtractPlanes(worldViewProjection, _planes, false); // Get the broad phase partition. var partition = (DualPartition<CollisionObject>)_domain.BroadPhase; // ----- Frustum Culling: // Use the broad phase partition to get all objects where the axis-aligned // bounding box (AABB) overlaps the volume defined by the frustum planes. // We draw these objects and can ignore all other objects. foreach (var collisionObject in partition.GetOverlaps(_planes)) { var geometricObject = collisionObject.GeometricObject; debugRenderer.DrawObject(geometricObject, Color.Red, false, false); } Profiler.Stop("WithCull"); } }
protected override void OnAppearing() { Device.BeginInvokeOnMainThread(() => Profiler.Stop(_name + " Appearing")); }
protected override void OnResume() { base.OnResume(); Profiler.Stop("OnResume"); }
protected void Application_EndRequest(object src, EventArgs e) { Profiler.Stop(); }
public List <PathFinderNode> FindPath(IVec3 start, IVec3 end) { Profiler.Start("Pathfinder.FindPath"); HighResolutionTime.Start(); PathFinderNode parentNode; bool found = false; int gridX = mGrid.GetGridWidth(); int gridY = mGrid.GetGridHeight(); mStop = false; mStopped = false; mOpen.Clear(); mClose.Clear(); #if DEBUGON if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(0, 0, start.x, start.y, PathFinderNodeType.Start, -1, -1); } if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(0, 0, end.x, end.y, PathFinderNodeType.End, -1, -1); } #endif sbyte[,] direction; if (mDiagonals) { direction = new sbyte[8, 2] { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 } } } ; else { direction = new sbyte[4, 2] { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } } }; parentNode.G = 0; parentNode.H = mHEstimate; parentNode.F = parentNode.G + parentNode.H; parentNode.X = start.x; parentNode.Y = start.y; parentNode.Z = start.z; parentNode.PX = parentNode.X; parentNode.PY = parentNode.Y; parentNode.PZ = parentNode.Z; mOpen.Push(parentNode); while (mOpen.Count > 0 && !mStop) { parentNode = mOpen.Pop(); #if DEBUGON if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(0, 0, parentNode.X, parentNode.Y, PathFinderNodeType.Current, -1, -1); } #endif if (parentNode.X == end.x && parentNode.Y == end.y) { mClose.Add(parentNode); found = true; break; } if (mClose.Count > mSearchLimit) { mStopped = true; Profiler.Stop("Pathfinder.FindPath"); return(null); } if (mPunishChangeDirection) { mHoriz = (parentNode.X - parentNode.PX); } //Lets calculate each successors for (int i = 0; i < (mDiagonals ? 8 : 4); i++) { PathFinderNode newNode = new PathFinderNode(); newNode.X = parentNode.X + direction[i, 0]; newNode.Y = parentNode.Y + direction[i, 1]; newNode.Z = 0; //### FIX FOR PATHFINDING TO WORK IN Z if (newNode.X < 0 || newNode.Y < 0 || newNode.X >= gridX || newNode.Y >= gridY) { continue; } int newG; if (mHeavyDiagonals && i > 3) { newG = parentNode.G + (int)(mGrid.GetBlockedValue(newNode) * 2.41); } else { newG = parentNode.G + mGrid.GetBlockedValue(newNode); } if (newG == parentNode.G) { //Unbrekeable continue; } if (mPunishChangeDirection) { if ((newNode.X - parentNode.X) != 0) { if (mHoriz == 0) { newG += 20; } } if ((newNode.Y - parentNode.Y) != 0) { if (mHoriz != 0) { newG += 20; } } } int foundInOpenIndex = -1; for (int j = 0; j < mOpen.Count; j++) { if (mOpen[j].X == newNode.X && mOpen[j].Y == newNode.Y) { foundInOpenIndex = j; break; } } if (foundInOpenIndex != -1 && mOpen[foundInOpenIndex].G <= newG) { continue; } int foundInCloseIndex = -1; for (int j = 0; j < mClose.Count; j++) { if (mClose[j].X == newNode.X && mClose[j].Y == newNode.Y) { foundInCloseIndex = j; break; } } if (foundInCloseIndex != -1 && mClose[foundInCloseIndex].G <= newG) { continue; } newNode.PX = parentNode.X; newNode.PY = parentNode.Y; newNode.PZ = parentNode.Z; newNode.G = newG; switch (mFormula) { default: case HeuristicFormula.Manhattan: newNode.H = mHEstimate * (Math.Abs(newNode.X - end.x) + Math.Abs(newNode.Y - end.y)); break; case HeuristicFormula.MaxDXDY: newNode.H = mHEstimate * (Math.Max(Math.Abs(newNode.X - end.x), Math.Abs(newNode.Y - end.y))); break; case HeuristicFormula.DiagonalShortCut: int h_diagonal = Math.Min(Math.Abs(newNode.X - end.x), Math.Abs(newNode.Y - end.y)); int h_straight = (Math.Abs(newNode.X - end.x) + Math.Abs(newNode.Y - end.y)); newNode.H = (mHEstimate * 2) * h_diagonal + mHEstimate * (h_straight - 2 * h_diagonal); break; case HeuristicFormula.Euclidean: newNode.H = (int)(mHEstimate * Math.Sqrt(Math.Pow((newNode.X - end.x), 2) + Math.Pow((newNode.Y - end.y), 2))); break; case HeuristicFormula.EuclideanNoSQR: newNode.H = (int)(mHEstimate * (Math.Pow((newNode.X - end.x), 2) + Math.Pow((newNode.Y - end.y), 2))); break; case HeuristicFormula.Custom1: IVec3 dxy = new IVec3(); dxy.Set(Math.Abs(end.x - newNode.X), Math.Abs(end.y - newNode.Y), 0); //### fix z int Orthogonal = Math.Abs(dxy.x - dxy.y); int Diagonal = Math.Abs(((dxy.x + dxy.y) - Orthogonal) / 2); newNode.H = mHEstimate * (Diagonal + Orthogonal + dxy.x + dxy.y); break; } if (mTieBreaker) { int dx1 = parentNode.X - end.x; int dy1 = parentNode.Y - end.y; int dx2 = start.x - end.x; int dy2 = start.y - end.y; int cross = Math.Abs(dx1 * dy2 - dx2 * dy1); newNode.H = (int)(newNode.H + cross * 0.001); } newNode.F = newNode.G + newNode.H; #if DEBUGON if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(parentNode.X, parentNode.Y, newNode.X, newNode.Y, PathFinderNodeType.Open, newNode.F, newNode.G); } #endif //It is faster if we leave the open node in the priority queue //When it is removed, all nodes around will be closed, it will be ignored automatically //if (foundInOpenIndex != -1) // mOpen.RemoveAt(foundInOpenIndex); //if (foundInOpenIndex == -1) mOpen.Push(newNode); } mClose.Add(parentNode); #if DEBUGON if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(0, 0, parentNode.X, parentNode.Y, PathFinderNodeType.Close, parentNode.F, parentNode.G); } #endif } mCompletedTime = HighResolutionTime.GetTime(); if (found) { PathFinderNode fNode = mClose[mClose.Count - 1]; for (int i = mClose.Count - 1; i >= 0; i--) { if (fNode.PX == mClose[i].X && fNode.PY == mClose[i].Y || i == mClose.Count - 1) { #if DEBUGON if (mDebugFoundPath && PathFinderDebug != null) { PathFinderDebug(fNode.X, fNode.Y, mClose[i].X, mClose[i].Y, PathFinderNodeType.Path, mClose[i].F, mClose[i].G); } #endif fNode = mClose[i]; } else { mClose.RemoveAt(i); } } mStopped = true; mClose.RemoveAt(0); // we have duplicate path information PathFinderNode endPFN = new PathFinderNode(); endPFN.PX = end.x; endPFN.PY = end.y; mClose.Add(endPFN); Profiler.Stop("Pathfinder.FindPath"); return(mClose); } mStopped = true; Profiler.Stop("Pathfinder.FindPath"); return(null); }
protected override void OnRender(RenderContext context) { if (ActiveCameraNode == null) { return; } context.Scene = Scene; context.CameraNode = ActiveCameraNode; context.LodCameraNode = ActiveCameraNode; // Copy all scene nodes into a list. CopyNodesToList(Scene, _sceneNodes); // ----- Occlusion Culling // Usually, we would make a scene query to get all scene nodes within the // viewing frustum. But in this example we will use the new OcclusionBuffer. if (EnableCulling) { // Render all occluders into the occlusion buffer. // - "_sceneNodes" is a list of all scene nodes. The OcclusionBuffer will // go through the list and render all occluders. // - "LightNode" is the main directional light that casts a cascaded shadow. // Passing the light node to the OcclusionBuffer activates shadow caster // culling. // - A custom scene node renderer can be passed to the OcclusionBuffer. In // this example, the ground mesh "Gravel/Gravel.fbx" has a material with an // "Occluder" render pass. When we pass the "MeshRenderer" to the OcclusionBuffer // the ground mesh will be rendered directly into the occlusion buffer. Profiler.Start("Occlusion.Render"); context.RenderPass = "******"; OcclusionBuffer.Render(_sceneNodes, LightNode, MeshRenderer, context); context.RenderPass = null; Profiler.Stop("Occlusion.Render"); // Perform occlusion culling on the specified list of scene nodes. // - The scene nodes will be tested against the occluders. If a scene node // is hidden, it will be replaced with a null entry in the list. // - When shadow caster culling is active, shadow casting scene nodes will // also be tested against the occluders. If the shadow is not visible, // the shadow caster will internally be marked as occluded. The ShadowMapRenderer // will automatically skip occluded scene nodes. Profiler.Start("Occlusion.Query"); OcclusionBuffer.Query(_sceneNodes, context); Profiler.Stop("Occlusion.Query"); } // The base DeferredGraphicsScreen expects a CustomSceneQuery. // --> Copy the occlusion culling results to a CustomSceneQuery. _sceneQuery.Set(ActiveCameraNode, _sceneNodes, context); var renderTargetPool = GraphicsService.RenderTargetPool; var graphicsDevice = GraphicsService.GraphicsDevice; var originalRenderTarget = context.RenderTarget; var fullViewport = context.Viewport; RenderTarget2D topDownRenderTarget = null; const int topDownViewSize = 384; if (ShowTopDownView) { // Render top-down scene into an offscreen render target. var format = new RenderTargetFormat(context.RenderTarget) { Width = topDownViewSize, Height = topDownViewSize, }; topDownRenderTarget = renderTargetPool.Obtain2D(format); context.Scene = Scene; context.CameraNode = _topDownCameraNode; context.Viewport = new Viewport(0, 0, topDownViewSize, topDownViewSize); context.RenderTarget = topDownRenderTarget; RenderScene(_sceneQuery, context, true, false, false, false); _debugRenderer.Clear(); _debugRenderer.DrawObject(ActiveCameraNode, Color.Red, true, true); _debugRenderer.Render(context); context.RenderTarget = originalRenderTarget; context.Viewport = fullViewport; } // Render regular 3D scene. context.Scene = Scene; context.CameraNode = ActiveCameraNode; RenderScene(_sceneQuery, context, true, false, true, false); // Render debug visualization on top of scene. bool renderObject = false; switch (DebugVisualization) { case DebugVisualization.CameraHzb: OcclusionBuffer.VisualizeCameraBuffer(DebugLevel, context); break; case DebugVisualization.LightHzb: OcclusionBuffer.VisualizeLightBuffer(DebugLevel, context); break; case DebugVisualization.Object: OcclusionBuffer.VisualizeObject(DebugObject, context); renderObject = true; break; case DebugVisualization.ShadowCaster: OcclusionBuffer.VisualizeShadowCaster(DebugObject, context); break; case DebugVisualization.ShadowVolume: OcclusionBuffer.VisualizeShadowVolume(DebugObject, context); renderObject = true; break; } if (renderObject) { _debugRenderer.Clear(); _debugRenderer.DrawObject(DebugObject, Color.Yellow, true, true); _debugRenderer.Render(context); } if (ShowTopDownView) { // Copy offscreen buffer to screen. context.Viewport = fullViewport; graphicsDevice.Viewport = fullViewport; SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullNone); SpriteBatch.Draw( topDownRenderTarget, new Rectangle(fullViewport.Width - topDownViewSize, fullViewport.Height - topDownViewSize, topDownViewSize, topDownViewSize), Color.White); SpriteBatch.End(); renderTargetPool.Recycle(topDownRenderTarget); } // Clean-up _sceneNodes.Clear(); _sceneQuery.Reset(); context.Scene = null; context.CameraNode = null; context.LodCameraNode = null; }
/// <summary> /// Builds the voxel buffer without locking the chunk data. /// </summary> /// <param name="needToSetCurrentChunk">True if we need to set this chunk as the current chunk for the terrain, false if not.</param> private void BuildVoxelBufferNoLockData(bool needToSetCurrentChunk) { Profiler.Start("Voxel Buffer Building"); lock ( _chunkBuilder ) { _chunkBuilder.Reset(); // get the terrain var terrain = Terrain.Instance; if (needToSetCurrentChunk) { terrain.SetCurrentChunk(this); } // go through for each terrain block var temp = new Block(); var tempBounds = new BoundingBox(); var blockCenter = new Vector3(); var useSmoothLighting = Game.Instance.Settings.SmoothLighting; for (int x = 0; x < ChunkData.SizeXZ; ++x) { for (int z = 0; z < ChunkData.SizeXZ; ++z) { var lighting = new BlockFaceLighting(Block.MaximumLighting); for (int y = ChunkData.SizeY - 1; y >= 0; --y) { // get block info var block = _data[x, y, z]; var exposed = false; if (block.TypeInfo.IsEmpty) { continue; } // get the block's and center Position.LocalToWorld(_data.Index, x, y, z, out blockCenter); // get surrounding block light level // TODO : We don't need to get a lot of these if smooth lighting is disabled var right = GetLightFromBlock(terrain, x + 1, y, z); var rightTop = GetLightFromBlock(terrain, x + 1, y + 1, z); var rightBottom = GetLightFromBlock(terrain, x + 1, y - 1, z); var left = GetLightFromBlock(terrain, x - 1, y, z); var leftTop = GetLightFromBlock(terrain, x - 1, y + 1, z); var leftBottom = GetLightFromBlock(terrain, x - 1, y - 1, z); var back = GetLightFromBlock(terrain, x, y, z + 1); var backLeft = GetLightFromBlock(terrain, x - 1, y, z + 1); var backRight = GetLightFromBlock(terrain, x + 1, y, z + 1); var backTop = GetLightFromBlock(terrain, x, y + 1, z + 1); var backTopLeft = GetLightFromBlock(terrain, x - 1, y + 1, z + 1); var backTopRight = GetLightFromBlock(terrain, x + 1, y + 1, z + 1); var backBottom = GetLightFromBlock(terrain, x, y - 1, z + 1); var backBottomLeft = GetLightFromBlock(terrain, x - 1, y - 1, z + 1); var backBottomRight = GetLightFromBlock(terrain, x + 1, y - 1, z + 1); var front = GetLightFromBlock(terrain, x, y, z - 1); var frontLeft = GetLightFromBlock(terrain, x - 1, y, z - 1); var frontRight = GetLightFromBlock(terrain, x + 1, y, z - 1); var frontTop = GetLightFromBlock(terrain, x, y + 1, z - 1); var frontTopLeft = GetLightFromBlock(terrain, x - 1, y + 1, z - 1); var frontTopRight = GetLightFromBlock(terrain, x + 1, y + 1, z - 1); var frontBottom = GetLightFromBlock(terrain, x, y - 1, z - 1); var frontBottomLeft = GetLightFromBlock(terrain, x - 1, y - 1, z - 1); var frontBottomRight = GetLightFromBlock(terrain, x + 1, y - 1, z - 1); var top = GetLightFromBlock(terrain, x, y + 1, z); var bottom = GetLightFromBlock(terrain, x, y - 1, z); // check to the right temp.Type = terrain.Query(x + 1, y, z); if (temp.TypeInfo.IsEmpty) { lighting = new BlockFaceLighting(right); // calculate smooth lighting if (useSmoothLighting) { lighting.LowerLeft = 0.25f * (right + rightBottom + frontBottomRight + frontRight); lighting.LowerRight = 0.25f * (right + rightBottom + backBottomRight + backRight); lighting.UpperRight = 0.25f * (right + rightTop + backTopRight + backRight); lighting.UpperLeft = 0.25f * (right + rightTop + frontTopRight + frontRight); } _chunkBuilder.AddFaceData(blockCenter, BlockFace.Right, block.Type, lighting); exposed = true; } // check to the left temp.Type = terrain.Query(x - 1, y, z); if (temp.TypeInfo.IsEmpty) { lighting = new BlockFaceLighting(left); // calculate smooth lighting if (useSmoothLighting) { lighting.LowerLeft = 0.25f * (left + leftBottom + backBottomLeft + backLeft); lighting.LowerRight = 0.25f * (left + leftBottom + frontBottomLeft + frontLeft); lighting.UpperRight = 0.25f * (left + leftTop + frontTopLeft + frontLeft); lighting.UpperLeft = 0.25f * (left + leftTop + backTopLeft + backLeft); } _chunkBuilder.AddFaceData(blockCenter, BlockFace.Left, block.Type, lighting); exposed = true; } // check in back temp.Type = terrain.Query(x, y, z + 1); if (temp.TypeInfo.IsEmpty) { lighting = new BlockFaceLighting(back); // calculate smooth lighting if (useSmoothLighting) { lighting.LowerLeft = 0.25f * (back + backBottom + backBottomRight + backRight); lighting.LowerRight = 0.25f * (back + backBottom + backBottomLeft + backLeft); lighting.UpperRight = 0.25f * (back + backTop + backTopLeft + backLeft); lighting.UpperLeft = 0.25f * (back + backTop + backTopRight + backRight); } _chunkBuilder.AddFaceData(blockCenter, BlockFace.Back, block.Type, lighting); exposed = true; } // check in front temp.Type = terrain.Query(x, y, z - 1); if (temp.TypeInfo.IsEmpty) { lighting = new BlockFaceLighting(front); // calculate smooth lighting if (useSmoothLighting) { lighting.LowerLeft = 0.25f * (front + frontBottom + frontBottomLeft + frontLeft); lighting.LowerRight = 0.25f * (front + frontBottom + frontBottomRight + frontRight); lighting.UpperRight = 0.25f * (front + frontTop + frontTopRight + frontRight); lighting.UpperLeft = 0.25f * (front + frontTop + frontTopLeft + frontLeft); } _chunkBuilder.AddFaceData(blockCenter, BlockFace.Front, block.Type, lighting); exposed = true; } // check above temp.Type = terrain.Query(x, y + 1, z); if (temp.TypeInfo.IsEmpty) { lighting = new BlockFaceLighting(top); // calculate smooth lighting if (useSmoothLighting) { lighting.LowerLeft = 0.25f * (top + frontTop + frontTopLeft + leftTop); lighting.LowerRight = 0.25f * (top + frontTop + frontTopRight + rightTop); lighting.UpperRight = 0.25f * (top + backTop + backTopRight + rightTop); lighting.UpperLeft = 0.25f * (top + backTop + backTopLeft + leftTop); } _chunkBuilder.AddFaceData(blockCenter, BlockFace.Top, block.Type, lighting); exposed = true; } // check below temp.Type = terrain.Query(x, y - 1, z); if (temp.TypeInfo.IsEmpty) { lighting = new BlockFaceLighting(bottom); // calculate smooth lighting if (useSmoothLighting) { lighting.LowerLeft = 0.25f * (bottom + backBottom + backBottomLeft + leftBottom); lighting.LowerRight = 0.25f * (bottom + backBottom + backBottomRight + rightBottom); lighting.UpperRight = 0.25f * (bottom + frontBottom + frontBottomRight + rightBottom); lighting.UpperLeft = 0.25f * (bottom + frontBottom + frontBottomLeft + leftBottom); } _chunkBuilder.AddFaceData(blockCenter, BlockFace.Bottom, block.Type, lighting); exposed = true; } // add the block's bounds to the octree if it's exposed if (exposed) { CreateBlockBounds(x, y, z, ref tempBounds); _octree.Add(tempBounds); } } } } // now build the terrain lock ( _terrain ) { _chunkBuilder.PopulateBuffer(_terrain); } } Profiler.Stop("Voxel Buffer Building"); }
protected void Application_EndRequest(object sender, EventArgs e) { Console.WriteLine("Application_EndRequest"); Profiler.Stop(); }
private void ProfilerForm_Closing(object sender, System.ComponentModel.CancelEventArgs e) { _p.Stop(); }
protected override void Draw(GameTime Time) { Performance.Draw(Time); GraphicsDevice.Clear(Color.CornflowerBlue); Profiler.Start("Game Draw"); switch (State) { #region MainMenu case States.MainMenu: Globe.Batches[0].Draw(Textures.Get("cog"), Screen.ViewportBounds); break; #endregion #region MapEditor case States.MapEditor: Globe.Batches[0].Begin(SpriteSortMode.BackToFront, Camera.View); Map.Draw(); Globe.Batches[0].End(); Globe.Batches[0].DrawRectangle(new Rectangle(16, (int)((Screen.ViewportHeight / 2f) - (11 * Tile.Height)), 52, (22 * Tile.Height)), (Color.Gray * .75f), (Color.Black * .75f)); Vector2 UIPos = new Vector2(32, 0); for (int i = -10; i <= 20; i++) { float Opacity = (1 - (Math.Abs(i) * .05f)); UIPos.Y = ((Screen.ViewportHeight / 2f) + (i * (Tile.Height + 5))); ushort ID = (ushort)Math.Max(0, Math.Min(ushort.MaxValue, (EditorForeTile + i))); if ((ID > 0) && (ID <= Mod.Fore.Values.Count)) { if (Textures.Exists("Tiles.Fore." + ID)) { Textures.Draw(("Tiles.Fore." + ID), UIPos, null, (Color.White * Opacity), 0, Origin.Center, 1); } if (Mod.Fore[ID].Frames > 0) { if (Mod.Fore[ID].Animation == null) { Mod.Fore[ID].Animation = new Animation(("Tiles.Fore." + ID + "-"), Mod.Fore[ID].Frames, true, Mod.Fore[ID].Speed); } else { Mod.Fore[ID].Animation.Update(Time); } Textures.Draw(Mod.Fore[ID].Animation.Texture(), UIPos, null, (Color.White * Opacity), 0, Origin.Center, 1); } } } UIPos = new Vector2(52, 0); for (int i = -10; i <= 20; i++) { float Opacity = (1 - (Math.Abs(i) * .05f)); UIPos.Y = ((Screen.ViewportHeight / 2f) + (i * (Tile.Height + 5))); ushort ID = (ushort)Math.Max(0, Math.Min(ushort.MaxValue, (EditorBackTile + i))); if ((ID > 0) && (ID <= Mod.Back.Values.Count)) { if (Textures.Exists("Tiles.Back." + ID)) { Textures.Draw(("Tiles.Back." + ID), UIPos, null, (Color.White * Opacity), 0, Origin.Center, 1); } if (Mod.Back[ID].Frames > 0) { if (Mod.Back[ID].Animation == null) { Mod.Back[ID].Animation = new Animation(("Tiles.Back." + ID + "-"), Mod.Back[ID].Frames, true, Mod.Back[ID].Speed); } else { Mod.Back[ID].Animation.Update(Time); } Textures.Draw(Mod.Back[ID].Animation.Texture(), UIPos, null, (Color.White * Opacity), 0, Origin.Center, 1); } } } break; #endregion #region Game case States.Game: Globe.Batches[0].Begin(SpriteSortMode.BackToFront, Camera.View); Map.Draw(); for (byte i = 0; i < Players.Length; i++) { if (Players[i] != null) { Players[i].Draw(); } } Globe.Batches[0].End(); break; #endregion } Profiler.Stop("Game Draw"); //Performance.Draw(Fonts.Get("Default/ExtraSmall"), new Vector2(5, (Screen.ViewportHeight - 35)), Origin.None, Color.White, Color.Black); //Profiler.Draw(430); Batch.EndAll(); base.Draw(Time); }
protected override void Update(GameTime Time) { Mouse.Update(); Keyboard.Update(Time); XboxPad.Update(Time); Timers.Update(Time); Performance.Update(Time); Globe.Active = IsActive; if (XboxPad.Pressed(XboxPad.Buttons.Back) || Keyboard.Pressed(Keyboard.Keys.Escape)) { Exit(); } Profiler.Start("Game Update"); switch (State) { #region MainMenu case States.MainMenu: if (Globe.Active) { if (Keyboard.Pressed(Keyboard.Keys.F1)) { CreateLobby("Server"); State = States.Game; } else if (Keyboard.Pressed(Keyboard.Keys.F2)) { if (Keyboard.Holding(Keyboard.Keys.LeftShift) || Keyboard.Holding(Keyboard.Keys.RightShift)) { MultiPlayer.Connect("Game", "127.0.0.1", 6121, Globe.Version, MpName); } else { MultiPlayer.Connect("Game", "71.3.34.68", 6121, Globe.Version, MpName); } } else if (Keyboard.Pressed(Keyboard.Keys.F3)) { CreateLobby("Server"); Camera.Position = new Vector2((Map.Width / 2f), (Map.Height / 2f)); State = States.MapEditor; } } break; #endregion case States.RequestMap: if (MultiPlayer.Type() == MultiPlayer.Types.Client) { MultiPlayer.Send(MultiPlayer.Construct(Packets.RequestMap)); State = States.SyncingMap; } break; #region MapEditor case States.MapEditor: Map.Update(Time); Point MousePoint = new Point((int)(Mouse.CameraPosition.X / Tile.Width), (int)(Mouse.CameraPosition.Y / Tile.Height)); if (Globe.Active) { #region Camera Movement if (Keyboard.Holding(Keyboard.Keys.W)) { Camera.Position.Y -= (float)(Map.Speed.Y * Time.ElapsedGameTime.TotalSeconds); } if (Keyboard.Holding(Keyboard.Keys.S)) { Camera.Position.Y += (float)(Map.Speed.Y * Time.ElapsedGameTime.TotalSeconds); } if (Keyboard.Holding(Keyboard.Keys.A)) { Camera.Position.X -= (float)(Map.Speed.X * Time.ElapsedGameTime.TotalSeconds); } if (Keyboard.Holding(Keyboard.Keys.D)) { Camera.Position.X += (float)(Map.Speed.X * Time.ElapsedGameTime.TotalSeconds); } #endregion bool BackPlace = (Keyboard.Holding(Keyboard.Keys.LeftShift) || Keyboard.Holding(Keyboard.Keys.RightShift)); if (Mouse.ScrolledUp()) { if (!BackPlace) { if (EditorForeTile > 1) { EditorForeTile--; } } else { if (EditorBackTile > 1) { EditorBackTile--; } } } if (Mouse.ScrolledDown()) { if (!BackPlace) { if (EditorForeTile < Mod.Fore.Values.Count) { EditorForeTile++; } } else { if (EditorBackTile < Mod.Back.Values.Count) { EditorBackTile++; } } } if (Mouse.Holding(Mouse.Buttons.Left)) { if (!BackPlace) { Map.PlaceFore(EditorForeTile, MousePoint.X, MousePoint.Y, null, true); } else { Map.PlaceBack(EditorBackTile, MousePoint.X, MousePoint.Y, true); } } if (Mouse.Holding(Mouse.Buttons.Right)) { if (!BackPlace) { Map.ClearFore(MousePoint.X, MousePoint.Y, true); } else { Map.ClearBack(MousePoint.X, MousePoint.Y, true); } } } break; #endregion #region Game case States.Game: Map.Update(Time); for (byte i = 0; i < Players.Length; i++) { if (Players[i] != null) { Players[i].Update(Time); } } if (MultiPlayer.Type("Game") == MultiPlayer.Types.Server) { if (Timers.Tick("Positions")) { foreach (var Player1 in Players) { if (Player1 != null && (Player1.Connection != null)) { var O = MultiPlayer.Construct("Game", Packets.Position); foreach (var Player2 in Players) { if ((Player2 != Player1) && (Player2 != null) && !Player2.Dead) { O.Write(Player2.Slot); O.Write(Player2.Position); O.Write(Player2.Angle); } } MultiPlayer.SendTo("Game", O, Player1.Connection, NetDeliveryMethod.UnreliableSequenced, 1); } } } if (GameType == GameTypes.TeamStandard) { if (!RoundEnded) { if (RoundEndWait > 0) { RoundEndWait -= Time.ElapsedGameTime.TotalSeconds; } else if ((TeamCount(1) > 0) && (TeamCount(2) > 0)) { if ((DeadCount(1) == TeamCount(1)) && (DeadCount(2) == TeamCount(2))) { EndRound(VictoryStates.Draw, 0, 0); } else if (DeadCount(1) == TeamCount(1)) { EndRound(VictoryStates.Team, 2, 0); } else if (DeadCount(2) == TeamCount(2)) { EndRound(VictoryStates.Team, 1, 0); } } } else { if (RoundTimer > 0) { RoundTimer -= Time.ElapsedGameTime.TotalSeconds; } else { NewRound(); } } } } break; #endregion } Profiler.Stop("Game Update"); #region Networking MultiPlayer.Flush("Game"); NetIncomingMessage I; while ((I = MultiPlayer.Read("Game")) != null) { var Break = false; switch (I.MessageType) { case NetIncomingMessageType.ConnectionApproval: Read(Packets.Connection, I); break; case NetIncomingMessageType.Data: Read((Packets)I.ReadByte(), I); break; case NetIncomingMessageType.StatusChanged: var Status = ((MultiPlayer.Type("Game") == MultiPlayer.Types.Client) ? (NetConnectionStatus)I.ReadByte() : ((MultiPlayer.Type("Game") == MultiPlayer.Types.Server) ? I.SenderConnection.Status : NetConnectionStatus.None)); switch (Status) { case NetConnectionStatus.Connected: if (MultiPlayer.Type("Game") == MultiPlayer.Types.Client) { var Hail = I.SenderConnection.RemoteHailMessage; Read((Packets)Hail.ReadByte(), Hail); } break; case NetConnectionStatus.Disconnected: if ((MultiPlayer.Type("Game") == MultiPlayer.Types.Client) && (I.SenderConnection.Status == NetConnectionStatus.Disconnected)) { QuitLobby(); Break = true; } else { Read(Packets.Disconnection, I); } break; } break; } if (Break) { break; } } #endregion base.Update(Time); }
protected override void Update(GameTime time) { Performance.UpdateFPS.Record(1 / time.ElapsedGameTime.TotalSeconds); Timers.Update(time); Globe.IsActive = IsActive; Mouse.Update(); Keyboard.Update(time); XboxPad.Update(time); if (XboxPad.Pressed(XboxPad.Buttons.Back) || Keyboard.Pressed(Keyboard.Keys.Escape) || Quit) { Exit(); } if (Keyboard.Pressed(Keyboard.Keys.F3)) { Profiler.Enabled = !Profiler.Enabled; } Profiler.Start("Game Update"); #region Menu/Connecting if (Frame == Frames.Menu) { UpdateMenuWorld(time); if (MenuState == MenuStates.UsernameEntry) { if (IsActive) { BlinkTimer -= time.ElapsedGameTime.TotalSeconds; if (BlinkTimer <= 0) { BlinkTimer += .6; } var name = Settings.Get("Name").AcceptInput(String.InputFlags.NoLeadingSpaces | String.InputFlags.NoRepeatingSpaces, 20); Settings.Set("Name", name); if (Keyboard.Pressed(Keyboard.Keys.Enter) && !name.IsNullOrEmpty()) { MenuState = MenuStates.HostConnect; } } } else if (MenuState == MenuStates.HostConnect) { if (Mouse.Press(Mouse.Buttons.Left)) { Vector2 scale = Scale * .75f, size = _orbisFont.MeasureString("Host") * scale; var button = new Rectangle((int)(Screen.BackBufferWidth / 2f - size.X / 2f), (int)(Screen.BackBufferHeight / 2f - size.Y), (int)size.X, (int)size.Y); if (new Rectangle(Mouse.X, Mouse.Y, 1, 1).Intersects(button)) { Multiplayer.CreateLobby(Settings.Get("Name")); GenStarted = false; Frame = Frames.LoadGame; } scale = Scale * .75f; size = _orbisFont.MeasureString("Connect") * scale; button = new Rectangle((int)(Screen.BackBufferWidth / 2f - size.X / 2f), (int)(Screen.BackBufferHeight / 2f + size.Y * .25f), (int)size.X, (int)size.Y); if (new Rectangle(Mouse.X, Mouse.Y, 1, 1).Intersects(button)) { MenuState = MenuStates.IPEntry; } } } else if (MenuState == MenuStates.IPEntry) { if (IsActive) { BlinkTimer -= time.ElapsedGameTime.TotalSeconds; if (BlinkTimer <= 0) { BlinkTimer += .6; } var ip = Settings.Get("IP").AcceptInput( String.InputFlags.NoLeadingPeriods | String.InputFlags.NoLetters | String.InputFlags.NoSpecalCharacters | String.InputFlags.NoSpaces | String.InputFlags.AllowPeriods | String.InputFlags.NoRepeatingPeriods | String.InputFlags.AllowColons | String.InputFlags.NoRepeatingColons | String.InputFlags.NoLeadingPeriods, 21); Settings.Set("IP", ip); if (Keyboard.Pressed(Keyboard.Keys.Enter) && !ip.IsNullOrEmpty()) { Network.Connect(Settings.Get("IP").Split(':')[0], Settings.Get("IP").Contains(":") ? Convert.ToInt32(Settings.Get("IP").Split(':')[1]) : Multiplayer.Port, new Network.Packet(null, Settings.Get("Name"))); Frame = Frames.Connecting; } else if (Keyboard.Pressed(Keyboard.Keys.Tab)) { MenuState = MenuStates.HostConnect; } } } Network.Update(); } else if (Frame == Frames.Connecting) { UpdateMenuWorld(time); BlinkTimer -= time.ElapsedGameTime.TotalSeconds; if (BlinkTimer <= 0) { BlinkTimer += 1; } Network.Update(); } #endregion #region LoadGame/Game else if (Frame == Frames.LoadGame) { UpdateMenuWorld(time); BlinkTimer -= time.ElapsedGameTime.TotalSeconds; if (BlinkTimer <= 0) { BlinkTimer += 1; } if (Network.IsNullOrServer) { if (!GenStarted) { LoadingText = null; GenDone = false; var thread = new Thread(() => { GameWorld = World.Generate(8400, 2400); }) { IsBackground = true }; thread.Start(); GenStarted = true; } if (GenDone) { BufferedStrings = new OrderedDictionary(); if (MenuMusicChannel.HasValue) { Sound.Terminate(MenuMusicChannel.Value); MenuMusicChannel = null; } LoadItems(); Self.Spawn(GameWorld.Spawn); GameWorld.Position = Self.WorldPosition; Frame = Frames.Game; } } Network.Update(); } else if (Frame == Frames.Game) { MouseTileX = (int)Math.Floor(Mouse.CameraPosition.X / Tile.Size); MouseTileY = (int)Math.Floor(Mouse.CameraPosition.Y / Tile.Size); Self.SelfUpdate(time); foreach (var t in Players) { t?.Update(time); } GameWorld.Position = Self.WorldPosition; if (Settings.IsDebugMode) { if (Keyboard.Pressed(Keyboard.Keys.L)) { GameWorld.Light = !GameWorld.Light; } if (Mouse.ScrolledUp()) { GameWorld.Zoom = MathHelper.Min(8, (float)Math.Round(GameWorld.Zoom + ZoomRate, 2)); } if (Mouse.ScrolledDown()) { GameWorld.Zoom = MathHelper.Max(.5f, (float)Math.Round(GameWorld.Zoom - ZoomRate, 2)); } if (Keyboard.Pressed(Keyboard.Keys.D1)) { Self.AddItem(Items["Dirt"].Clone(Keyboard.HoldingShift() ? 30 : 3)); } if (Keyboard.Pressed(Keyboard.Keys.D2)) { Self.AddItem(Items["Stone"].Clone(Keyboard.HoldingShift() ? 30 : 3)); } } for (var i = (BufferedStrings.Count - 1); i >= 0; i--) { var bString = (BufferedStrings[i] as BufferedString); bString.CalculateRectangle(_orbisFont, new Vector2(Self.WorldPosition.X, (Self.WorldPosition.Y - BufferedString.PlayerYOffset))); if (i < (BufferedStrings.Count - 1)) { if (bString.Rectangle.Intersects((BufferedStrings[i + 1] as BufferedString).Rectangle)) { bString.Offset -= (20 * (float)time.ElapsedGameTime.TotalSeconds); } else { bString.Offset += (20 * (float)time.ElapsedGameTime.TotalSeconds); } } else { bString.Offset = MathHelper.Min(0, (bString.Offset + (20 * (float)time.ElapsedGameTime.TotalSeconds))); } bString.Life -= (float)time.ElapsedGameTime.TotalSeconds; if (bString.Life <= 0) { BufferedStrings.RemoveAt(i); i--; } } Network.Update(); } #endregion Profiler.Stop("Game Update"); Textures.Dispose(); Sound.AutoTerminate(); base.Update(time); }
public void TestIsolatedRecursion() { var a = new Profiler(); a.Start("op"); a.Start("a"); a.Start("b"); a.Start("wrapper [isolate]"); ; a.Start("a"); a.Start("b"); a.Stop("b"); a.Stop("a"); a.Stop("wrapper [isolate]"); a.Stop("b"); a.Stop("a"); a.Start("c"); a.Start("a"); a.Stop("a"); a.Stop("c"); a.Start("d"); a.Start("d", true); a.Stop("d"); a.Stop("d"); a.Start("d [drop]"); a.Start("d", true); a.Stop("d"); a.Stop("d [drop]"); a.Stop("op"); var result = a.RootNode.ToProfilingResultNode(); var r = new ProfilingResultNode[] { result }; var depthList = string.Join(",", r.Traverse(false).Select(n => n.First().SegmentName)); Assert.Equal("op,a,b,wrapper,a,b,c,a,d,d", depthList); var breadthList = string.Join(",", r.Traverse(true).Select(n => n.First().SegmentName)); Assert.Equal("op,a,c,d,b,a,d,wrapper,a,b", breadthList); }
protected override void Draw(GameTime time) { Performance.DrawFPS.Record(1 / time.ElapsedGameTime.TotalSeconds); GraphicsDevice.Clear(Color.Black); Profiler.Start("Game Draw"); #region Menu/Connecting if (Frame == Frames.Menu) { MenuWorld.Draw(); Screen.Cease(); MenuWorld.DrawLightMap(); Screen.Setup(SpriteSortMode.Deferred, SamplerState.PointClamp); Screen.Draw(_orbisLogo, new Vector2(Screen.BackBufferWidth / 2f, 160 * Scale.Y), (float)(.1f * Math.Cos(time.TotalGameTime.TotalSeconds)), Textures.Origin.Center, ((float)(1 + (.2f * Math.Sin(time.TotalGameTime.TotalSeconds))) * Scale)); Screen.DrawString("Developed by Dcrew & Pyroglyph", _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight - Screen.BackBufferHeight / 8f), Color.Gray * .5f, Textures.Origin.Center, Scale * .5f); if (MenuState == MenuStates.UsernameEntry) { Screen.DrawString("Enter your name!", _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight / 2f - 35 * Scale.Y), Color.Gray * .75f, new Textures.Origin(.5f, 1, true), Scale * .75f); Screen.DrawString(Settings.Get("Name") + ((BlinkTimer <= .3f) && IsActive ? "|" : string.Empty), _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight / 2f - 30 * Scale.Y), Color.Black * .75f, new Textures.Origin(.5f, 0, true), Scale * .75f); Screen.DrawString("Press 'enter' to proceed!", _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight / 2f + 35 * Scale.Y), Color.DimGray * .5f, new Textures.Origin(.5f, 1, true), Scale * .5f); } else if (MenuState == MenuStates.HostConnect) { var scale = Scale * .5f; var size = _orbisFont.MeasureString("Welcome, ") * scale; Screen.DrawString("Welcome, ", _orbisFont, new Vector2(Screen.BackBufferWidth / 2f - _orbisFont.MeasureString("Welcome, " + Settings.Get("Name") + "!").X *scale.X / 2f, Screen.BackBufferHeight / 2f - size.Y * 3), Color.Gray * .75f, null, 0, new Textures.Origin(0, .5f, true), scale); Screen.DrawString(Settings.Get("Name"), _orbisFont, new Vector2(Screen.BackBufferWidth / 2f - _orbisFont.MeasureString("Welcome, " + Settings.Get("Name") + "!").X *scale.X / 2f + _orbisFont.MeasureString("Welcome, ").X *scale.X, Screen.BackBufferHeight / 2f - size.Y * 3), Color.Green * .75f, new Textures.Origin(0, .5f, true), scale); Screen.DrawString("!", _orbisFont, new Vector2(Screen.BackBufferWidth / 2f - _orbisFont.MeasureString("Welcome, " + Settings.Get("Name") + "!").X *scale.X / 2f + _orbisFont.MeasureString("Welcome, " + Settings.Get("Name")).X *scale.X, Screen.BackBufferHeight / 2f - size.Y * 3), Color.Gray * .75f, new Textures.Origin(0, .5f, true), scale); var mouse = new Rectangle(Mouse.X, Mouse.Y, 1, 1); scale = Scale * .75f; size = _orbisFont.MeasureString("Host") * scale; var button = new Rectangle((int)(Screen.BackBufferWidth / 2f - size.X / 2f), (int)(Screen.BackBufferHeight / 2f - size.Y), (int)size.X, (int)size.Y); var color = Color.Silver; if (mouse.Intersects(button)) { scale += new Vector2(.35f); color = Color.White; } Screen.DrawString("Host", _orbisFont, new Vector2(button.X + button.Width / 2f, button.Y + button.Height / 2f), color, Color.Black * .5f, Textures.Origin.Center, scale); scale = Scale * .75f; size = _orbisFont.MeasureString("Connect") * scale; button = new Rectangle((int)(Screen.BackBufferWidth / 2f - size.X / 2f), (int)(Screen.BackBufferHeight / 2f + size.Y * .25f), (int)size.X, (int)size.Y); color = Color.Silver; if (mouse.Intersects(button)) { scale += new Vector2(.35f); color = Color.White; } Screen.DrawString("Connect", _orbisFont, new Vector2(button.X + button.Width / 2f, button.Y + button.Height / 2f), color, Color.Black * .5f, Textures.Origin.Center, scale); } else if (MenuState == MenuStates.IPEntry) { Screen.DrawString("Server IP:", _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight / 2f - 35 * Scale.Y), Color.Gray * .75f, new Textures.Origin(.5f, 1, true), Scale * .75f); Screen.DrawString(Settings.Get("IP") + ((BlinkTimer <= .3f) && IsActive ? "|" : string.Empty), _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight / 2f - 30 * Scale.Y), Color.Black * .75f, new Textures.Origin(.5f, 0, true), Scale * .75f); Screen.DrawString("Press 'enter' to proceed!", _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight / 2f + 130 * Scale.Y), Color.DimGray * .5f, new Textures.Origin(.5f, 1, true), Scale * .5f); Screen.DrawString("Press 'tab' to go back!", _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight / 2f + 190 * Scale.Y), Color.DimGray * .5f, new Textures.Origin(.5f, 1, true), Scale * .5f); } Screen.Cease(); } else if (Frame == Frames.Connecting) { MenuWorld.Draw(); Screen.Cease(); MenuWorld.DrawLightMap(); Screen.Setup(); Screen.DrawString("Connecting to " + Settings.Get("IP") + new string('.', 4 - (int)Math.Ceiling(BlinkTimer * 4)), _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight / 2f), Color.White, Textures.Origin.Center, Scale * .5f); Screen.Cease(); } #endregion #region LoadGame/Game else if (Frame == Frames.LoadGame) { MenuWorld.Draw(); Screen.Cease(); MenuWorld.DrawLightMap(); Screen.Setup(); if (!string.IsNullOrEmpty(LoadingText)) { Screen.DrawString((LoadingText + new string('.', 4 - (int)Math.Ceiling(BlinkTimer * 4)) + " " + Math.Round(LoadingPercentage) + "%"), _orbisFont, new Vector2(Screen.BackBufferWidth / 2f, Screen.BackBufferHeight / 2f), Color.White, Textures.Origin.Center, Scale * .5f); } Screen.Cease(); } else if (Frame == Frames.Game) { GameWorld.Draw(); foreach (var t in Players) { t?.Draw(); } Screen.Draw(World._tilesTexture, new Rectangle(MouseTileX * Tile.Size, MouseTileY * Tile.Size, Tile.Size, Tile.Size), Tile.Source(1, 1), Color.White * (float)(.3f + (.25f * Math.Sin(time.TotalGameTime.TotalSeconds * 5)))); Screen.Cease(); GameWorld.DrawLightMap(); var invSlot = Textures.Load("Inventory Slot.png"); Screen.Setup(); const int itemsPerRow = 7; var invScale = 1f; var invPos = new Vector2((Screen.BackBufferWidth - (((invSlot.Width * invScale) * itemsPerRow) + (itemsPerRow - 1)) - 5), 5); Self.DrawInventory(invPos, itemsPerRow, invScale); if (Settings.IsDebugMode) { var rows = (int)Math.Ceiling(Inventory.PlayerInvSize / (float)itemsPerRow); invPos.Y += (rows * (invSlot.Height * invScale)) + 5; invScale = .5f; invPos.X = (Screen.BackBufferWidth - (((invSlot.Width * invScale) * itemsPerRow) + (itemsPerRow - 1)) - 5); foreach (var t in Players.Where(player => !player.Matches(null, Self))) { t.DrawInventory(invPos, itemsPerRow, invScale); invPos.Y += (rows * (invSlot.Height * invScale)) + 10; } } Screen.Cease(); if (Settings.IsDebugMode) { Screen.Setup(); Screen.DrawString(("Zoom: " + GameWorld.Zoom + " - Direction: " + Self.Direction + " - Inputs: " + Self.LastInput), Font.Load("Orbis"), new Vector2(2), Color.White, Color.Black, new Vector2(DebugTextScale)); Screen.DrawString(("IsFalling: " + Self.IsFalling + " - IsOnGround: " + Self.IsOnGround), Font.Load("Orbis"), new Vector2(2, (2 + ((DebugTextScale * 100) * 1))), Color.White, Color.Black, new Vector2(DebugTextScale)); Screen.DrawString(("TilePos: " + Self.TileX + "," + Self.TileY + " - MoveSpeed: " + Self.MovementSpeed + " - MoveResistance: " + Self.MovementResistance + " - Velocity: " + Math.Round(Self.Velocity.X, 1) + "," + Math.Round(Self.Velocity.Y, 1)), Font.Load("Orbis"), new Vector2(2, (2 + ((DebugTextScale * 100) * 2))), Color.White, Color.Black, new Vector2(DebugTextScale)); Screen.Cease(); } if (BufferedStrings.Count > 0) { Screen.Setup(GameWorld.Matrix); foreach (var v in BufferedStrings.Values) { var bString = (v as BufferedString); Screen.DrawString(bString.Text, _orbisFont, new Vector2(Self.WorldPosition.X, (Self.WorldPosition.Y - BufferedString.PlayerYOffset + bString.Offset)), (Color.White * MathHelper.Clamp((float)bString.Life, 0, 1)), Textures.Origin.Center, new Vector2(BufferedString.Scale)); } Screen.Cease(); } } #endregion Profiler.Stop("Game Draw"); Profiler.Start("Profiler"); if (Profiler.Enabled) { Profiler.Draw(430); } Profiler.Stop("Profiler"); base.Draw(time); }
public void CreateChunk() { profiler.Start(); // Direction swapper used for correctiong UV-coordinates int directionSwapper = 0; int vertexIndex = 0; int count = size - 1; for (int z = 0; z < count; ++z) { for (int y = 0; y < count; ++y) { for (int x = 0; x < count; ++x) { // Index of base points, and also adjacent points on cube. float[] basePoints = GetPoints(x, y, z); // Store scalars corresponding to vertices. float[] storedScalars = new float[basePoints.Length]; for (int j = 0; j < basePoints.Length; ++j) { storedScalars[j] = voxels[(int)basePoints[j]].Value; } // Initialize cubeindex int cubeIndex = 0; // First part of the algorithm uses a table which maps the vertices under the isosurface to the // intersecting edges. An 8 bit index is formed where each bit corresponds to a vertex. for (int j = 0; j < storedScalars.Length; ++j) { cubeIndex |= storedScalars[j] < isolevel ? resolutions[j] : 0; } int bits = Terrain3DTables.EdgeTable[cubeIndex]; // If no edges are crossed, continue to the next iteration. if (bits == 0) { continue; } float alpha = 0.5f; int resValue = 1; // Check which edges are crossed and estimate the point location with a weighted average of scalar values at edge endpoints. // Cases 1 - 8 Horizontal edges at bottom of the cube // Cases 16 - 128 Horizontal edges at top of the cube // Cases 256 - 2048 Vertical edges of the cubes for (int index = 0; index < 12; ++index) { if ((bits & resValue) != 0) { alpha = (isolevel - storedScalars[vertPoint[index].value[0]]) / (storedScalars[vertPoint[index].value[1]] - storedScalars[vertPoint[index].value[2]]); vertexList[index] = Vector3.Lerp(voxels[(int)basePoints[vertPoint[index].value[3]]].position, voxels[(int)basePoints[vertPoint[index].value[4]]].position, alpha); } resValue = resValue * 2; } cubeIndex <<= 4; int i = 0; while (Terrain3DTables.TriTable[cubeIndex + i] != -1) { int index1 = Terrain3DTables.TriTable[cubeIndex + i]; int index2 = Terrain3DTables.TriTable[cubeIndex + i + 1]; int index3 = Terrain3DTables.TriTable[cubeIndex + i + 2]; vertices.Add(vertexList[index1]); vertices.Add(vertexList[index2]); vertices.Add(vertexList[index3]); triangles.Add(vertexIndex); triangles.Add(vertexIndex + 1); triangles.Add(vertexIndex + 2); directionSwapper = 1 - directionSwapper; if (directionSwapper == 0) { uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(0, 1)); uvs.Add(new Vector2(1, 1)); } else { uvs.Add(new Vector2(1, 0)); uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(1, 1)); } vertexIndex += 3; i += 3; } } } } // Build the Mesh: mesh.Clear(); mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); mesh.uv = uvs.ToArray(); mesh.RecalculateNormals(); GetComponent <MeshCollider>().sharedMesh = mesh; vertices.Clear(); uvs.Clear(); triangles.Clear(); profiler.Stop(); }
/// <summary> /// Creates a cache poller /// </summary> /// <typeparam name="T">Type of item in the cache</typeparam> /// <param name="owner">The PollNode owner of this Cache</param> /// <param name="description">Description of the operation, used purely for profiling</param> /// <param name="cacheDuration">The length of time to cache data for</param> /// <param name="getData">The operation used to actually get data, e.g. <code>using (var conn = GetConnectionAsync()) { return getFromConnection(conn); }</code></param> /// <param name="timeoutMs">The timeout in milliseconds for this poll to complete before aborting.</param> /// <param name="logExceptions">Whether to log any exceptions to the log</param> /// <param name="addExceptionData">Optionally add exception data, e.g. <code>e => e.AddLoggedData("Server", Name)</code></param> /// <param name="afterPoll">An optional action to run after polling has completed successfully</param> /// <param name="memberName"></param> /// <param name="sourceFilePath"></param> /// <param name="sourceLineNumber"></param> /// <returns>A cache update action, used when creating a <see cref="Cache"/>.</returns> public Cache(PollNode owner, string description, TimeSpan cacheDuration, Func <Task <T> > getData, int?timeoutMs = null, bool?logExceptions = null, Action <Exception> addExceptionData = null, Action <Cache <T> > afterPoll = null, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) : base(cacheDuration, memberName, sourceFilePath, sourceLineNumber) { MiniProfilerDescription = "Poll: " + description; // concatenate once logExceptions = logExceptions ?? LogExceptions; _updateFunc = async() => { var success = true; PollStatus = "UpdateCacheItem"; if (EnableProfiling) { Profiler = _profilerOptions.StartProfiler(MiniProfilerDescription); Profiler.Id = UniqueId; } using (MiniProfiler.Current.Step(description)) { try { PollStatus = "Fetching"; using (MiniProfiler.Current.Step("Data Fetch")) { var task = getData(); if (timeoutMs.HasValue) { if (await Task.WhenAny(task, Task.Delay(timeoutMs.Value)).ConfigureAwait(false) == task) { // Re-await for throws. Data = await task; } else { // This means the .WhenAny returned the timeout first...boom. throw new TimeoutException($"Fetch timed out after {timeoutMs} ms."); } } else { Data = await task; } } PollStatus = "Fetch Complete"; SetSuccess(); afterPoll?.Invoke(this); } catch (Exception e) { success = false; if (logExceptions.Value) { addExceptionData?.Invoke(e); Current.LogException(e); } var errorMessage = StringBuilderCache.Get() .Append("Unable to fetch from ") .Append(owner.NodeType) .Append(": ") .Append(e.Message); #if DEBUG errorMessage.Append(" @ ").Append(e.StackTrace); #endif if (e.InnerException != null) { errorMessage.AppendLine().Append(e.InnerException.Message); } PollStatus = "Fetch Failed"; SetFail(e, errorMessage.ToStringRecycle()); } owner.PollComplete(this, success); } if (EnableProfiling) { Profiler.Stop(); } PollStatus = "UpdateCacheItem Complete"; return(Data); }; }
public void Update() { try { long ProcessingTime = 0L; while (ThreadManager.RunChunkManagerThread) { ProcessingTime = (long)DateTime.UtcNow.TimeOfDay.TotalMilliseconds; Profiler.Start("Chunk Manager Update", Color.MediumPurple); #region Legacy Infinite Terrain Code //Update the tick counters //Handle loading and unloading //First unload all bad chunks //Bad being they are too far away //Also keep them in a temporary Vector3Int array representing chunk positions of loaded chunks #region Block Updates //Sync block updates lock (updates) { lock (LoadedChunkPositions) { Logger.info(-1, "Update Count: " + updates.Count); updatedBlocks = !(updates.Count == 0); for (int i = 0; i < updates.Count; i++) { int targetX = int.MinValue, targetY = int.MinValue, targetZ = int.MinValue; #region Chunk Hedging if (updates[i].X == 0) { targetX = updates[i].ChunkPos.X - 1; targetY = targetY == int.MinValue ? updates[i].ChunkPos.Y : targetY; targetZ = targetZ == int.MinValue ? updates[i].ChunkPos.Z : targetZ; } if (updates[i].X == Chunk.CHUNK_SIZE - 1) { targetX = updates[i].ChunkPos.X + 1; targetY = targetY == int.MinValue ? updates[i].ChunkPos.Y : targetY; targetZ = targetZ == int.MinValue ? updates[i].ChunkPos.Z : targetZ; } if (updates[i].Y == 0) { targetX = targetX == int.MinValue ? updates[i].ChunkPos.X : targetX; targetY = updates[i].ChunkPos.Y - 1; targetZ = targetZ == int.MinValue ? updates[i].ChunkPos.Z : targetZ; } if (updates[i].Y == Chunk.CHUNK_SIZE - 1) { targetX = targetX == int.MinValue ? updates[i].ChunkPos.X : targetX; targetY = updates[i].ChunkPos.Y + 1; targetZ = targetZ == int.MinValue ? updates[i].ChunkPos.Z : targetZ; } if (updates[i].Z == 0) { targetX = targetX == int.MinValue ? updates[i].ChunkPos.X : targetX; targetY = targetY == int.MinValue ? updates[i].ChunkPos.Y : targetY; targetZ = updates[i].ChunkPos.Z - 1; } if (updates[i].Z == Chunk.CHUNK_SIZE - 1) { targetX = targetX == int.MinValue ? updates[i].ChunkPos.X : targetX; targetY = targetY == int.MinValue ? updates[i].ChunkPos.Y : targetY; targetZ = updates[i].ChunkPos.Z + 1; } #endregion Vector3Int targetPosX = new Vector3Int(targetX, updates[i].ChunkPos.Y, updates[i].ChunkPos.Z); Vector3Int targetPosY = new Vector3Int(updates[i].ChunkPos.X, targetY, updates[i].ChunkPos.Z); Vector3Int targetPosZ = new Vector3Int(updates[i].ChunkPos.X, updates[i].ChunkPos.Y, targetZ); if (LoadedChunkPositions.Contains(updates[i].ChunkPos)) { if (chunks[ChunkIndexMapping[updates[i].ChunkPos]].isLoaded && chunks.Count <= ChunkIndexMapping[updates[i].ChunkPos]) { chunks[ChunkIndexMapping[updates[i].ChunkPos]].SetBlock(updates[i].BlockID, updates[i].X, updates[i].Y, updates[i].Z, updates[i].Reason); } } if (LoadedChunkPositions.Contains(targetPosX)) { if (chunks[ChunkIndexMapping[targetPosX]].isLoaded && chunks.Count <= ChunkIndexMapping[targetPosX]) { chunks[ChunkIndexMapping[targetPosX]].UpdateNeeded = true; } } if (LoadedChunkPositions.Contains(targetPosY)) { if (chunks[ChunkIndexMapping[targetPosY]].isLoaded && chunks.Count <= ChunkIndexMapping[targetPosY]) { chunks[ChunkIndexMapping[targetPosY]].UpdateNeeded = true; } } if (LoadedChunkPositions.Contains(targetPosZ)) { if (chunks[ChunkIndexMapping[targetPosZ]].isLoaded && chunks.Count <= ChunkIndexMapping[targetPosZ]) { chunks[ChunkIndexMapping[targetPosZ]].UpdateNeeded = true; } } } updates.Clear(); } } #endregion #region Unloading lock (LoadedChunkPositions) { for (int i = 0; i < chunks.Count; i++) { if (chunks[i].isLoaded) { if (previousPlayerChunk != playerChunk) { Profiler.Start("Chunk Unload", Color.Red); //Calculate distance in the form of a cube Vector3Int chunkPos = new Vector3Int(chunks[i].posX, chunks[i].posY, chunks[i].posZ); //GameClient.LOGGER.info(0, "Currently dealing with chunk (" + chunkPos.X + " " + chunkPos.Y + " " + chunkPos.Z + ")!"); if (LoadedChunkPositions.Contains(chunkPos) && chunkPos.X > playerChunk.X + SimulationDistance || chunkPos.X < playerChunk.X - SimulationDistance - 1 || chunkPos.Y > playerChunk.Y + SimulationDistance || chunkPos.Y < playerChunk.Y - SimulationDistance - 1 || chunkPos.Z > playerChunk.Z + SimulationDistance || chunkPos.Z < playerChunk.Z - SimulationDistance - 1 //Max world bounds || chunkPos.X > WorldWidth || chunkPos.X < -WorldWidth - 1 || chunkPos.Y > MaxChunksY || chunkPos.Y < 0 || chunkPos.Z > WorldWidth || chunkPos.Z < -WorldWidth - 1) { UnloadChunk(chunks[i].posX, chunks[i].posY, chunks[i].posZ); } else { //Add to LoadedChunkPositions if (!LoadedChunkPositions.Contains(chunkPos)) { LoadedChunkPositions.Add(chunkPos); } } Profiler.Stop("Chunk Unload"); Profiler.Start("Chunk Manager Update", Color.MediumPurple); //Update the chunk chunks[i].Update(); } } } #endregion #region Loading //Now that we've unloaded all chunks, we can see which chunks we need to load byte numberOfChunksLoadedThisFrame = 0; //This algorithm loads all chunks on the z axis, then the x axis and lastly the y axis //It only load 1 z layer every frame (a layer is anything from 1 chunk to RENDER_DISTANCE chunks if (numberOfChunksLoaded < SimulationArea + 1) { for (int i = 0; i < LoadDistance; i++) { Profiler.Start("Chunk Load Math", Color.DarkOliveGreen); //Calculate the bounds of chunks that can be loaded int minX = MathHelper.Clamp(playerChunk.X - i, playerChunk.X - SimulationDistance, playerChunk.X + SimulationDistance); int minY = MathHelper.Clamp(playerChunk.Y - i, playerChunk.Y - SimulationDistance, playerChunk.Y + SimulationDistance); int minZ = MathHelper.Clamp(playerChunk.Z - i, playerChunk.Z - SimulationDistance, playerChunk.Z + SimulationDistance); int maxX = MathHelper.Clamp(playerChunk.X + i, playerChunk.X - SimulationDistance, playerChunk.X + SimulationDistance); int maxY = MathHelper.Clamp(playerChunk.Y + i, playerChunk.Y - SimulationDistance, playerChunk.Y + SimulationDistance); int maxZ = MathHelper.Clamp(playerChunk.Z + i, playerChunk.Z - SimulationDistance, playerChunk.Z + SimulationDistance); //World boundaries. Chunks cant be loaded outside these boundaries minX = MathHelper.Clamp(minX, -WorldWidth, WorldWidth); minY = MathHelper.Clamp(minY, 0, MaxChunksY); minZ = MathHelper.Clamp(minZ, -WorldWidth, WorldWidth); maxX = MathHelper.Clamp(maxX, -WorldWidth, WorldWidth); maxY = MathHelper.Clamp(maxY, 0, MaxChunksY); maxZ = MathHelper.Clamp(maxZ, -WorldWidth, WorldWidth); Profiler.Stop("Chunk Load Math"); for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { for (int z = minZ; z < maxZ; z++) { Profiler.Start("Chunk Load", Color.Ivory); Vector3Int chunkPos = new Vector3Int(x, y, z); //Check if we should load this chunk (if its within simulation distance & isn't inside LoadedChunkPositions>) if (!LoadedChunkPositions.Contains(chunkPos) && chunkPos.X < playerChunk.X + SimulationDistance && chunkPos.X > playerChunk.X - SimulationDistance && chunkPos.Y < playerChunk.Y + SimulationDistance && chunkPos.Y > playerChunk.Y - SimulationDistance && chunkPos.Z < playerChunk.Z + SimulationDistance && chunkPos.Z > playerChunk.Z - SimulationDistance //Max world bounds && chunkPos.X < WorldWidth && chunkPos.X > -WorldWidth && chunkPos.Y < MaxChunksY && chunkPos.Y > -1 && chunkPos.Z < WorldWidth && chunkPos.Z > -WorldWidth) { Profiler.Stop("Chunk Load"); //Chunk is unloaded. So load it Profiler.Start("Chunk Generation", Color.DeepPink); //Chunk NextChunkToLoad = SolidChunk.Generate(chunkPos.X, chunkPos.Y, chunkPos.Z, 1); Chunk NextChunkToLoad = FetchChunk(chunkPos.X, chunkPos.Y, chunkPos.Z); RegisterChunk(NextChunkToLoad); Profiler.Stop("Chunk Generation"); Profiler.Start("Chunk Load", Color.Ivory); //RegisterChunk(FetchChunk(chunkPos.X, chunkPos.Y, chunkPos.Z)); numberOfChunksLoaded++; numberOfChunksLoadedThisFrame++; Profiler.Stop("Chunk Load"); //If we loaded more than the maximum number of chunks, stop loading chunks this frame to keep a playable framerate if (numberOfChunksLoadedThisFrame > MaximumChunksToLoadPerFrame) { break; } } else { Profiler.Stop("Chunk Load"); } } //If we loaded more than the maximum number of chunks, stop loading chunks this frame to keep a playable framerate if (numberOfChunksLoadedThisFrame > MaximumChunksToLoadPerFrame) { break; } } //Break the loop if we loaded a single chunk if (numberOfChunksLoadedThisFrame > 0) { break; } } //Break the loop if we loaded a single chunk if (numberOfChunksLoadedThisFrame > 0) { break; } } if (numberOfChunksLoadedThisFrame < 1) { LoadDistance++; } if (LoadDistance > SimulationDistance) { LoadDistance = 2; } } } previousPlayerChunk = playerChunk; #endregion #endregion #region Fixed Terrain Code /*byte numberOfChunksLoadedThisFrame = 0; * * //This algorithm loads all chunks on the z axis, then the x axis and lastly the y axis * //It only load 1 z layer every frame (a layer is anything from 1 chunk to RENDER_DISTANCE chunks * if (numberOfChunksLoaded <= SimulationArea) * { * Profiler.Start("Chunk Load Loop"); * * for (int i = 0; i < LoadDistance; i++) * { * Profiler.Start("Chunk Load Math", Color.DarkOliveGreen); * * //Calculate the bounds of chunks that can be loaded * int minX = playerChunk.X - i; * int minY = playerChunk.Y - i; * int minZ = playerChunk.Z - i; * * int maxX = playerChunk.X + i; * int maxY = playerChunk.Y + i; * int maxZ = playerChunk.Z + i; * * //World boundaries. Chunks cant be loaded outside these boundaries * minX = MathHelper.Clamp(minX, -8, 8); * minY = MathHelper.Clamp(minY, 0, 16); * minZ = MathHelper.Clamp(minZ, -8, 8); * * maxX = MathHelper.Clamp(maxX, -8, 8); * maxY = MathHelper.Clamp(maxY, 0, 16); * maxZ = MathHelper.Clamp(maxZ, -8, 8); * * Profiler.Stop("Chunk Load Math"); * * for (int y = minY; y < maxY; y++) * { * for (int x = minX; x < maxX; x++) * { * for (int z = minZ; z < maxZ; z++) * { * Profiler.Start("Chunk Load", Color.Ivory); * * Vector3Int chunkPos = new Vector3Int(x, y, z); * * //Check if we should load this chunk (if its within simulation distance & isn't inside LoadedChunkPositions>) * if (!LoadedChunkPositions.Contains(chunkPos) && * chunkPos.X < playerChunk.X + SimulationDistance && chunkPos.X > playerChunk.X - SimulationDistance * && chunkPos.Y < playerChunk.Y + SimulationDistance && chunkPos.Y > playerChunk.Y - SimulationDistance * && chunkPos.Z < playerChunk.Z + SimulationDistance && chunkPos.Z > playerChunk.Z - SimulationDistance * * //Max world bounds * && chunkPos.X < WorldWidth && chunkPos.X > -WorldWidth * && chunkPos.Y < MaxChunksY && chunkPos.Y > -1 * && chunkPos.Z < WorldWidth && chunkPos.Z > -WorldWidth) * { * //Chunk is unloaded. So load it * Profiler.Start("Chunk Generation", Color.DeepPink); * Chunk NextChunkToLoad = SolidChunk.Generate(chunkPos.X, chunkPos.Y, chunkPos.Z, 1); * RegisterChunk(NextChunkToLoad); * Profiler.Stop("Chunk Generation"); * * //RegisterChunk(FetchChunk(chunkPos.X, chunkPos.Y, chunkPos.Z)); * * numberOfChunksLoaded++; * numberOfChunksLoadedThisFrame++; * * Profiler.Stop("Chunk Load"); * * //If we loaded more than the maximum number of chunks, stop loading chunks this frame to keep a playable framerate * if (numberOfChunksLoadedThisFrame > MaximumChunksToLoadPerFrame) * { * break; * } * } * else * { * Profiler.Stop("Chunk Load"); * } * } * * //If we loaded more than the maximum number of chunks, stop loading chunks this frame to keep a playable framerate * if (numberOfChunksLoadedThisFrame > MaximumChunksToLoadPerFrame) * { * break; * } * } * * //Break the loop if we loaded a single chunk * if (numberOfChunksLoadedThisFrame > 0) * { * break; * } * } * * //Break the loop if we loaded a single chunk * if (numberOfChunksLoadedThisFrame > 0) * { * break; * } * } * * if (numberOfChunksLoadedThisFrame < 1) * { * LoadDistance++; * } * if (LoadDistance > SimulationDistance) * { * LoadDistance = 2; * } * }*/ #endregion SyncCache(); Profiler.Stop("Chunk Manager Update"); ProcessingTime = (long)DateTime.UtcNow.TimeOfDay.TotalMilliseconds - ProcessingTime; //Wait 1/60 - the time elapsed, clamped between 0 and int.max Thread.Sleep(FastMath.FastClamp((int)(50 - ProcessingTime), 50, int.MaxValue)); } } catch (ThreadAbortException ex) { //Thread aborting! Logger.fatal(-1, "Thread \"" + Thread.CurrentThread.Name + "\" aborted! This is usually normal!"); } }
public void TestJsonProfilingStorage() { slf4net.LoggerFactory.SetFactoryResolver(new SimpleFactoryResolver(item => Console.WriteLine(item.Message))); var target = new JsonProfilingStorage(ProfilingStorageBase.Inline); // save empty result should not throw exception target.SaveResult(null); var name = "test"; var stepName = "step1"; var profiler = new Profiler(name, target, new [] { "test", "test2" }) as IProfiler; var mockParameter = new Mock<IDataParameter>(); mockParameter.Setup(p => p.ParameterName).Returns("p1"); mockParameter.Setup(p => p.Value).Returns(1); mockParameter.Setup(p => p.Direction).Returns(ParameterDirection.Input); var mockParameterDBNull = new Mock<IDbDataParameter>(); mockParameterDBNull.Setup(p => p.DbType).Returns(DbType.Binary); mockParameterDBNull.Setup(p => p.Value).Returns(DBNull.Value); mockParameterDBNull.Setup(p => p.Direction).Returns(ParameterDirection.Input); var mockParameterBinary = new Mock<IDataParameter>(); mockParameterBinary.Setup(p => p.DbType).Returns(DbType.Binary); mockParameterBinary.Setup(p => p.Value).Returns(new byte[100]); mockParameterBinary.Setup(p => p.Direction).Returns(ParameterDirection.Input); var mockParameterBinaryTooBig = new Mock<IDbDataParameter>(); mockParameterBinaryTooBig.Setup(p => p.DbType).Returns(DbType.Binary); mockParameterBinaryTooBig.Setup(p => p.Value).Returns(new byte[0x200 + 1]); mockParameterBinaryTooBig.Setup(p => p.Direction).Returns(ParameterDirection.Input); var mockParameterDateTime = new Mock<IDbDataParameter>(); mockParameterDateTime.Setup(p => p.DbType).Returns(DbType.DateTime); mockParameterDateTime.Setup(p => p.Value).Returns(DateTime.Now); mockParameterDateTime.Setup(p => p.Direction).Returns(ParameterDirection.Input); var mockParameterEnum = new Mock<IDbDataParameter>(); mockParameterEnum.Setup(p => p.DbType).Returns(DbType.Int32); mockParameterEnum.Setup(p => p.Value).Returns(DbType.Boolean); mockParameterEnum.Setup(p => p.Direction).Returns(ParameterDirection.Input); var mockParameterXml = new Mock<IDbDataParameter>(); mockParameterXml.Setup(p => p.DbType).Returns(DbType.Xml); mockParameterXml.Setup(p => p.Value).Returns("<xml />"); mockParameterXml.Setup(p => p.Direction).Returns(ParameterDirection.Input); var mockParameterCollection = new Mock<IDataParameterCollection>(); mockParameterCollection.Setup(collections => collections.GetEnumerator()).Returns(new IDataParameter[] { mockParameter.Object, mockParameterDBNull.Object, mockParameterBinary.Object, mockParameterBinaryTooBig.Object, mockParameterDateTime.Object, mockParameterEnum.Object, mockParameterXml.Object }.GetEnumerator()); mockParameterCollection.Setup(collection => collection.Count).Returns(1); var mockCommand = new Mock<IDbCommand>(); mockCommand.Setup(cmd => cmd.CommandText).Returns("test sql"); mockCommand.Setup(cmd => cmd.Parameters).Returns(mockParameterCollection.Object); var dbTiming = new DbTiming( profiler, DbExecuteType.Reader, mockCommand.Object); using (profiler.Step(stepName, null, null)) { profiler.AddCustomTiming(dbTiming); profiler.AddCustomTiming(new CustomTiming(profiler, "custom", "custom")); } profiler.Stop(); // save normal result should not throw exception target.SaveResult(profiler); slf4net.LoggerFactory.Reset(); }
public void ConstructMesh(object param) //For metadata { try { //check if the param is a chunk if (param == null || !(param is Chunk)) { return; } //convert the param to usable data Chunk baseChunk = (Chunk)param; Profiler.Start("Mesh Building", Color.Blue); //Force other worker threads to wait lock (vertices) { if (vertices.Count == 0) { //isGenerated = false; //just incase } Color topShadowBase = new Color(0xE5E5E5); //229 Color bottomShadowBase = new Color(0x999999); //153 Color nsShadowBase = new Color(0xAFAFAF); //175 Color ewShadowBase = new Color(0xC4C4C4); //196 //tmp //Vector3Int position = new Vector3Int(posX, posY, posZ); //Vector3Int size = new Vector3Int(16); //Construct Quad Vertices List <VertexPositionColorTexture> finalVerts = new List <VertexPositionColorTexture>(); List <VertexPositionColorTexture> vertTmp = new List <VertexPositionColorTexture>(); int i = 0; for (int y = 0; y < Chunk.CHUNK_SIZE; y++) { for (int z = 0; z < Chunk.CHUNK_SIZE; z++) { for (int x = 0; x < Chunk.CHUNK_SIZE; x++) { Block currentBlock = BlockManager.GetBlock(baseChunk.chunk_blockdata[x, y, z]); if (currentBlock.IsTransparent == false) { //GameClient.LOGGER.info("X: " + x + ", Y: " + y + ", Z: " + z); i++; #region Mesh Building //TODO: Build according to model /* * Color topShadowBase = new Color(0xE5E5E5); //229 * Color bottomShadowBase = new Color(0x999999); //153 * Color nsShadowBase = new Color(0xAFAFAF); //175 * Color ewShadowBase = new Color(0xC4C4C4); //196*/ Vector3Int position = new Vector3Int(x + 1, y + 1, z + 1); Vector3 size = new Vector3(0.5f, 0.5f, 0.5f); //GameClient.LOGGER.info("pos: " + position + " size: " + size); //List<VertexPositionColorTexture> vertTmp = new List<VertexPositionColorTexture>(); if (CheckBlockVisible((sbyte)(x + 1), (sbyte)y, (sbyte)z)) { //North vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y - size.Y, position.Z + size.Z), nsShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.north.X, currentBlock.BlockModel.voxels[0].textures.north.W))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y + size.Y, position.Z - size.Z), nsShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.north.Z, currentBlock.BlockModel.voxels[0].textures.north.Y))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y - size.Y, position.Z - size.Z), nsShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.north.Z, currentBlock.BlockModel.voxels[0].textures.north.W))); vertTmp.Add(vertTmp[0]); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y + size.Y, position.Z + size.Z), nsShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.north.X, currentBlock.BlockModel.voxels[0].textures.north.Y))); vertTmp.Add(vertTmp[1]); finalVerts.AddRange(vertTmp); vertTmp.Clear(); } if (CheckBlockVisible((sbyte)(x - 1), (sbyte)y, (sbyte)z)) { //South vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y - size.Y, position.Z - size.Z), nsShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.south.X, currentBlock.BlockModel.voxels[0].textures.south.W))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y + size.Y, position.Z - size.Z), nsShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.south.X, currentBlock.BlockModel.voxels[0].textures.south.Y))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y - size.Y, position.Z + size.Z), nsShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.south.Z, currentBlock.BlockModel.voxels[0].textures.south.W))); vertTmp.Add(vertTmp[1]); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y + size.Y, position.Z + size.Z), nsShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.south.Z, currentBlock.BlockModel.voxels[0].textures.south.Y))); vertTmp.Add(vertTmp[2]); finalVerts.AddRange(vertTmp); vertTmp.Clear(); } if (CheckBlockVisible((sbyte)x, (sbyte)(y + 1), (sbyte)z)) { //Top vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y + size.Y, position.Z - size.Z), topShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.up.Z, currentBlock.BlockModel.voxels[0].textures.up.Y))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y + size.Y, position.Z + size.Z), topShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.up.X, currentBlock.BlockModel.voxels[0].textures.up.W))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y + size.Y, position.Z - size.Z), topShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.up.X, currentBlock.BlockModel.voxels[0].textures.up.Y))); vertTmp.Add(vertTmp[0]); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y + size.Y, position.Z + size.Z), topShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.up.Z, currentBlock.BlockModel.voxels[0].textures.up.W))); vertTmp.Add(vertTmp[1]); finalVerts.AddRange(vertTmp); vertTmp.Clear(); } if (CheckBlockVisible((sbyte)x, (sbyte)(y - 1), (sbyte)z)) { //Bottom vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y - size.Y, position.Z - size.Z), bottomShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.down.X, currentBlock.BlockModel.voxels[0].textures.down.Y))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y - size.Y, position.Z + size.Z), bottomShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.down.X, currentBlock.BlockModel.voxels[0].textures.down.W))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y - size.Y, position.Z - size.Z), bottomShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.down.Z, currentBlock.BlockModel.voxels[0].textures.down.Y))); vertTmp.Add(vertTmp[1]); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y - size.Y, position.Z + size.Z), bottomShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.down.Z, currentBlock.BlockModel.voxels[0].textures.down.W))); vertTmp.Add(vertTmp[2]); finalVerts.AddRange(vertTmp); vertTmp.Clear(); } if (CheckBlockVisible((sbyte)x, (sbyte)y, (sbyte)(z + 1))) { //West vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y - size.Y, position.Z + size.Z), ewShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.west.X, currentBlock.BlockModel.voxels[0].textures.west.W))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y + size.Y, position.Z + size.Z), ewShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.west.X, currentBlock.BlockModel.voxels[0].textures.west.Y))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y - size.Y, position.Z + size.Z), ewShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.west.Z, currentBlock.BlockModel.voxels[0].textures.west.W))); vertTmp.Add(vertTmp[1]); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y + size.Y, position.Z + size.Z), ewShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.west.Z, currentBlock.BlockModel.voxels[0].textures.west.Y))); vertTmp.Add(vertTmp[2]); finalVerts.AddRange(vertTmp); vertTmp.Clear(); } if (CheckBlockVisible((sbyte)x, (sbyte)y, (sbyte)(z - 1))) { //East vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y - size.Y, position.Z - size.Z), ewShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.east.X, currentBlock.BlockModel.voxels[0].textures.east.W))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y + size.Y, position.Z - size.Z), ewShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.east.Z, currentBlock.BlockModel.voxels[0].textures.east.Y))); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X - size.X, position.Y - size.Y, position.Z - size.Z), ewShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.east.Z, currentBlock.BlockModel.voxels[0].textures.east.W))); vertTmp.Add(vertTmp[0]); vertTmp.Add(new VertexPositionColorTexture(new Vector3(position.X + size.X, position.Y + size.Y, position.Z - size.Z), ewShadowBase, new Vector2(currentBlock.BlockModel.voxels[0].textures.east.X, currentBlock.BlockModel.voxels[0].textures.east.Y))); vertTmp.Add(vertTmp[1]); finalVerts.AddRange(vertTmp); vertTmp.Clear(); } #endregion } else { //TODO: Handle transparent meshes } } } } //GameClient.LOGGER.info(i + " blocks found!"); //vertices.Clear(); vertices = finalVerts; if (vertices.Count != 0 && VoxelClient.Graphics.GraphicsDevice != null) { vertexBuffer = new VertexBuffer(VoxelClient.Graphics.GraphicsDevice, typeof(VertexPositionColorTexture), vertices.Count, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices.ToArray()); indexBuffer = new IndexBuffer(VoxelClient.Graphics.GraphicsDevice, typeof(int), indices.Count, BufferUsage.WriteOnly); indexBuffer.SetData(indices.ToArray()); } lock (verts) { verts = vertices.ToArray(); } isGenerated = true; } Profiler.Stop("Mesh Building"); //Kill this thread Util.Managers.ThreadManager.RemoveThreadClean(Thread.CurrentThread.Name); } catch (ThreadAbortException ex) { Logger.fatal(-1, "Thread \"" + Thread.CurrentThread.Name + "\" aborted! This is usually normal!"); } }