From e5d9a1bcf6d752f14f3b301e06f0abf5519765a7 Mon Sep 17 00:00:00 2001 From: Gabriele Giuseppini Date: Sun, 2 Dec 2018 15:54:31 +0100 Subject: [PATCH] Finalized collisions; added render stats to extended status text --- FloatingSandbox TODO.txt | 19 ++++++++----------- GameLib/GameController.cpp | 3 ++- GameLib/GameParameters.h | 7 +++++++ GameLib/RenderContext.cpp | 6 ++++++ GameLib/RenderContext.h | 16 +++++++++++++++- GameLib/RenderCore.h | 28 ++++++++++++++++++++++++++++ GameLib/Ship.cpp | 29 ++++++++++++++++------------- GameLib/ShipRenderContext.cpp | 17 +++++++++++++++++ GameLib/ShipRenderContext.h | 31 +++++++++++++++++-------------- GameLib/TextLayer.cpp | 14 +++++++++++++- GameLib/TextLayer.h | 5 +++-- 11 files changed, 132 insertions(+), 43 deletions(-) diff --git a/FloatingSandbox TODO.txt b/FloatingSandbox TODO.txt index 3982d2903..8f7a49667 100644 --- a/FloatingSandbox TODO.txt +++ b/FloatingSandbox TODO.txt @@ -153,22 +153,19 @@ Render: + 100: OK,but not really "draggy" + 10,000: awesome - = Adjust restitution coefficient at collisions - - Try again with normal, but displacement being delta P instead of delta Y - - Recheck L'n'F' for current collision handling - Recheck L'n'F' for strength - - Extended status: take stats from RenderContext - - RenderContext::Stats: - - LastRenderedShipSprings - - LastRenderedShipTriangles - - LastRenderedGenericTextureTriangles - - LastRenderedConnectedComponents + = Extended status: take stats from RenderContext + + RenderContext::Stats: + + LastRenderedShipSprings + + LastRenderedShipTriangles + + LastRenderedGenericTextureTriangles + + LastRenderedConnectedComponents ---- - - Reset stats at each RenderContext::RenderStart() + + Reset stats at each RenderContext::RenderStart() - = Redo full perf analysis + + Redo full perf analysis - 1.8.0 - Libsimdpp spring relaxation (*) diff --git a/GameLib/GameController.cpp b/GameLib/GameController.cpp index a4338bf44..2751c27ec 100644 --- a/GameLib/GameController.cpp +++ b/GameLib/GameController.cpp @@ -578,5 +578,6 @@ void GameController::PublishStats(std::chrono::steady_clock::time_point nowReal) mIsPaused, mRenderContext->GetZoom(), totalURRatio, - lastURRatio); + lastURRatio, + mRenderContext->GetStatistics()); } \ No newline at end of file diff --git a/GameLib/GameParameters.h b/GameLib/GameParameters.h index c245f8c64..88255d1e9 100644 --- a/GameLib/GameParameters.h +++ b/GameLib/GameParameters.h @@ -24,6 +24,13 @@ struct GameParameters template static constexpr T SimulationStepTimeDuration = 0.02f; + template + inline T MechanicalSimulationStepTimeDuration() const + { + return SimulationStepTimeDuration + / NumMechanicalDynamicsIterations(); + } + // // Physical Constants diff --git a/GameLib/RenderContext.cpp b/GameLib/RenderContext.cpp index 410188b02..24ea6dcc6 100644 --- a/GameLib/RenderContext.cpp +++ b/GameLib/RenderContext.cpp @@ -63,6 +63,8 @@ RenderContext::RenderContext( , mVectorFieldLengthMultiplier(1.0f) , mShowStressedSprings(false) , mWireframeMode(false) + // Statistics + , mRenderStatistics() { static constexpr float GenericTextureProgressSteps = 10.0f; static constexpr float CloudTextureProgressSteps = 4.0f; @@ -408,6 +410,7 @@ void RenderContext::AddShip( *mShaderManager, mGenericTextureAtlasOpenGLHandle, *mGenericTextureAtlasMetadata, + mRenderStatistics, mOrthoMatrix, mVisibleWorldHeight, mVisibleWorldWidth, @@ -444,6 +447,9 @@ void RenderContext::RenderStart() // Communicate start to child contextes mTextRenderContext->RenderStart(); + + // Reset stats + mRenderStatistics.Reset(); } void RenderContext::UploadStarsStart(size_t starCount) diff --git a/GameLib/RenderContext.h b/GameLib/RenderContext.h index bfe33cb02..6c42a76f8 100644 --- a/GameLib/RenderContext.h +++ b/GameLib/RenderContext.h @@ -263,6 +263,15 @@ class RenderContext - screenOffset.y / static_cast(mCanvasHeight) * mVisibleWorldHeight); } + // + // Statistics + // + + RenderStatistics const & GetStatistics() const + { + return mRenderStatistics; + } + public: void Reset(); @@ -809,7 +818,6 @@ class RenderContext void RenderEnd(); - private: void RenderCrossesOfLight(); @@ -1018,6 +1026,12 @@ class RenderContext float mVectorFieldLengthMultiplier; bool mShowStressedSprings; bool mWireframeMode; + + // + // Statistics + // + + RenderStatistics mRenderStatistics; }; } \ No newline at end of file diff --git a/GameLib/RenderCore.h b/GameLib/RenderCore.h index ee7652cd7..44ab38b2f 100644 --- a/GameLib/RenderCore.h +++ b/GameLib/RenderCore.h @@ -152,4 +152,32 @@ struct TextQuadVertex }; #pragma pack(pop) + +// +// Statistics +// + +struct RenderStatistics +{ + std::uint64_t LastRenderedShipSprings; + std::uint64_t LastRenderedShipTriangles; + std::uint64_t LastRenderedShipConnectedComponents; + std::uint64_t LastRenderedGenericTextures; + std::uint64_t LastRenderedEphemeralPoints; + + RenderStatistics() + { + Reset(); + } + + void Reset() + { + LastRenderedShipSprings = 0; + LastRenderedShipTriangles = 0; + LastRenderedShipConnectedComponents = 0; + LastRenderedGenericTextures = 0; + LastRenderedEphemeralPoints = 0; + } +}; + } diff --git a/GameLib/Ship.cpp b/GameLib/Ship.cpp index 66bb58d14..9127ac8c5 100644 --- a/GameLib/Ship.cpp +++ b/GameLib/Ship.cpp @@ -635,6 +635,7 @@ void Ship::UpdatePointForces(GameParameters const & gameParameters) if (mPoints.GetPosition(pointIndex).y < waterHeightAtThisPoint) { + // Drag force = -C*V^2*Vn mPoints.GetForce(pointIndex) += mPoints.GetVelocity(pointIndex).square() * (-waterDragCoefficient); @@ -693,9 +694,7 @@ void Ship::UpdateSpringForces(GameParameters const & /*gameParameters*/) void Ship::IntegrateAndResetPointForces(GameParameters const & gameParameters) { - float const dt = - GameParameters::SimulationStepTimeDuration - / gameParameters.NumMechanicalDynamicsIterations(); + float const dt = gameParameters.MechanicalSimulationStepTimeDuration(); // Global damp - lowers velocity uniformly, damping oscillations originating between gravity and buoyancy // @@ -746,18 +745,22 @@ void Ship::HandleCollisionsWithSeaFloor(GameParameters const & gameParameters) { // // We handle collisions really simplistically: we move back points to where they were - // at the last update, when they were NOT under the ocean floor. + // at the last update, when they were NOT under the ocean floor, and fully bounce velocity back. // - // Ideally we would have to find the mid-point - between the position at t-1 and t - at which - // we really entered the sea floor, and then move the point there. We could find the midpoint - // with successive approximations, but this might not work when the floor is really rugged. + // Regarding calculating the post-collision position: ideally we would have to find the + // mid-point - between the position at t-1 and t - at which we really entered the sea floor, + // and then move the point there. We could find the midpoint with successive approximations, + // but this might not work when the floor is really rugged. + // + // Regarding calculating the post-collision velocity: ideally we would mirror velocity around + // the sea floor normal, but if we did this together with moving the point at the previous position, + // that point would start oscillating up and down, as the new position would allow it to gather + // momentum and come crashing down again. // // Hence we're gonna stick with this simple algorithm. // - float const dt = - GameParameters::SimulationStepTimeDuration - / gameParameters.NumMechanicalDynamicsIterations(); + float const dt = gameParameters.MechanicalSimulationStepTimeDuration(); for (auto pointIndex : mPoints) { @@ -765,11 +768,11 @@ void Ship::HandleCollisionsWithSeaFloor(GameParameters const & gameParameters) float const floorheight = mParentWorld.GetOceanFloorHeightAt(mPoints.GetPosition(pointIndex).x); if (mPoints.GetPosition(pointIndex).y < floorheight) { - // Move point back where it was + // Move point back to where it was mPoints.GetPosition(pointIndex) -= mPoints.GetVelocity(pointIndex) * dt; - // Simulate a perfectly elastic collision - mPoints.GetVelocity(pointIndex) *= -1.0f; + // Bounce velocity (naively) + mPoints.GetVelocity(pointIndex) = -mPoints.GetVelocity(pointIndex); } } } diff --git a/GameLib/ShipRenderContext.cpp b/GameLib/ShipRenderContext.cpp index e854c450f..3d9c65b4e 100644 --- a/GameLib/ShipRenderContext.cpp +++ b/GameLib/ShipRenderContext.cpp @@ -18,6 +18,7 @@ ShipRenderContext::ShipRenderContext( ShaderManager & shaderManager, GameOpenGLTexture & textureAtlasOpenGLHandle, TextureAtlasMetadata const & textureAtlasMetadata, + RenderStatistics & renderStatistics, float const(&orthoMatrix)[4][4], float visibleWorldHeight, float visibleWorldWidth, @@ -30,6 +31,7 @@ ShipRenderContext::ShipRenderContext( bool showStressedSprings, bool wireframeMode) : mShaderManager(shaderManager) + , mRenderStatistics(renderStatistics) // Parameters - all set at the end of the constructor , mCanvasToVisibleWorldHeightRatio(0) , mAmbientLightIntensity(0.0f) @@ -802,6 +804,9 @@ void ShipRenderContext::RenderEnd() } } + // Update stats + mRenderStatistics.LastRenderedShipConnectedComponents += mConnectedComponents.size(); + // // Render ephemeral points @@ -867,6 +872,9 @@ void ShipRenderContext::RenderSpringElements( // Draw glDrawElements(GL_LINES, static_cast(2 * connectedComponent.springElementCount), GL_UNSIGNED_INT, 0); + + // Update stats + mRenderStatistics.LastRenderedShipSprings += connectedComponent.springElementCount; } void ShipRenderContext::RenderRopeElements(ConnectedComponentData const & connectedComponent) @@ -916,6 +924,9 @@ void ShipRenderContext::RenderTriangleElements( // Draw glDrawElements(GL_TRIANGLES, static_cast(3 * connectedComponent.triangleElementCount), GL_UNSIGNED_INT, 0); + + // Update stats + mRenderStatistics.LastRenderedShipTriangles += connectedComponent.triangleElementCount; } void ShipRenderContext::RenderStressedSpringElements(ConnectedComponentData const & connectedComponent) @@ -977,6 +988,9 @@ void ShipRenderContext::RenderGenericTextures(GenericTextureConnectedComponentDa // Draw polygons glDrawArrays(GL_TRIANGLES, 0, static_cast(connectedComponent.VertexBuffer.size())); + + // Update stats + mRenderStatistics.LastRenderedGenericTextures += connectedComponent.VertexBuffer.size() / 6; } } @@ -996,6 +1010,9 @@ void ShipRenderContext::RenderEphemeralPoints() // Draw glDrawElements(GL_POINTS, static_cast(mEphemeralPoints.size()), GL_UNSIGNED_INT, 0); + + // Update stats + mRenderStatistics.LastRenderedEphemeralPoints += mEphemeralPoints.size(); } } diff --git a/GameLib/ShipRenderContext.h b/GameLib/ShipRenderContext.h index 7c811b2ca..e689658c4 100644 --- a/GameLib/ShipRenderContext.h +++ b/GameLib/ShipRenderContext.h @@ -32,6 +32,7 @@ class ShipRenderContext ShaderManager & shaderManager, GameOpenGLTexture & textureAtlasOpenGLHandle, TextureAtlasMetadata const & textureAtlasMetadata, + RenderStatistics & renderStatistics, float const(&orthoMatrix)[4][4], float visibleWorldHeight, float visibleWorldWidth, @@ -43,7 +44,7 @@ class ShipRenderContext VectorFieldRenderMode vectorFieldRenderMode, bool showStressedSprings, bool wireframeMode); - + ~ShipRenderContext(); public: @@ -171,7 +172,7 @@ class ShipRenderContext } void UploadElementsEnd(); - + void UploadElementStressedSpringsStart(); inline void UploadElementStressedSpring( @@ -240,7 +241,7 @@ class ShipRenderContext float alpha) { size_t const connectedComponentIndex = connectedComponentId - 1; - + assert(connectedComponentIndex < mGenericTextureConnectedComponents.size()); // Get this connected component's vertex buffer @@ -249,7 +250,7 @@ class ShipRenderContext // // Populate the texture quad // - + TextureAtlasFrameMetadata const & frame = mTextureAtlasMetadata.GetFrameMetadata(textureFrameId); float const leftX = -frame.FrameMetadata.AnchorWorldX; @@ -267,7 +268,7 @@ class ShipRenderContext // Top-left vertexBuffer.emplace_back( position, - vec2f(leftX, topY), + vec2f(leftX, topY), vec2f(frame.TextureCoordinatesBottomLeft.x, frame.TextureCoordinatesTopRight.y), scale, angle, @@ -331,7 +332,7 @@ class ShipRenderContext } - // + // // Ephemeral points // @@ -357,12 +358,12 @@ class ShipRenderContext vec2f const * restrict position, vec2f const * restrict vector, float lengthAdjustment, - vec4f const & color); + vec4f const & color); void RenderEnd(); private: - + struct ConnectedComponentData; struct GenericTextureConnectedComponentData; @@ -378,7 +379,7 @@ class ShipRenderContext ConnectedComponentData const & connectedComponent, bool withTexture); - void RenderStressedSpringElements(ConnectedComponentData const & connectedComponent); + void RenderStressedSpringElements(ConnectedComponentData const & connectedComponent); void RenderGenericTextures(GenericTextureConnectedComponentData const & connectedComponent); @@ -405,6 +406,8 @@ class ShipRenderContext ShaderManager & mShaderManager; + RenderStatistics & mRenderStatistics; + // // Ship textures @@ -416,7 +419,7 @@ class ShipRenderContext // // Points // - + size_t const mPointCount; GameOpenGLVBO mPointPositionVBO; @@ -424,7 +427,7 @@ class ShipRenderContext GameOpenGLVBO mPointWaterVBO; GameOpenGLVBO mPointColorVBO; GameOpenGLVBO mPointElementTextureCoordinatesVBO; - + // // Generic Textures // @@ -438,7 +441,7 @@ struct TextureRenderPolygonVertex vec2f centerPosition; vec2f vertexOffset; vec2f textureCoordinate; - + float scale; float angle; float alpha; @@ -473,7 +476,7 @@ struct TextureRenderPolygonVertex size_t mGenericTextureAllocatedVertexBufferSize; GameOpenGLVBO mGenericTextureRenderPolygonVertexVBO; - + // @@ -522,7 +525,7 @@ struct TextureRenderPolygonVertex }; #pragma pack(pop) - + // // All the data that belongs to a single connected component // diff --git a/GameLib/TextLayer.cpp b/GameLib/TextLayer.cpp index 900324b60..1342e1640 100644 --- a/GameLib/TextLayer.cpp +++ b/GameLib/TextLayer.cpp @@ -37,7 +37,8 @@ void TextLayer::SetStatusText( bool isPaused, float zoom, float totalUpdateToRenderDurationRatio, - float lastUpdateToRenderDurationRatio) + float lastUpdateToRenderDurationRatio, + Render::RenderStatistics const & renderStatistics) { int elapsedSecondsGameInt = static_cast(roundf(elapsedGameSeconds.count())); int minutesGame = elapsedSecondsGameInt / 60; @@ -76,6 +77,17 @@ void TextLayer::SetStatusText( << " ZOOM:" << zoom; mStatusTextLines.emplace_back(ss.str()); + + ss.str(""); + + ss + << "SPR:" << renderStatistics.LastRenderedShipSprings + << " TRI:" << renderStatistics.LastRenderedShipTriangles + << " CC:" << renderStatistics.LastRenderedShipConnectedComponents + << " GENTEX:" << renderStatistics.LastRenderedGenericTextures + << " EPH:" << renderStatistics.LastRenderedEphemeralPoints; + + mStatusTextLines.emplace_back(ss.str()); } mIsStatusTextDirty = true; diff --git a/GameLib/TextLayer.h b/GameLib/TextLayer.h index 4d4fd572f..b51d64ee4 100644 --- a/GameLib/TextLayer.h +++ b/GameLib/TextLayer.h @@ -26,12 +26,13 @@ class TextLayer void SetStatusText( float immediateFps, - float averageFps, + float averageFps, std::chrono::duration elapsedGameSeconds, bool isPaused, float zoom, float totalUpdateToRenderDurationRatio, - float lastUpdateToRenderDurationRatio); + float lastUpdateToRenderDurationRatio, + Render::RenderStatistics const & renderStatistics); void Update();