From 2d6f2c14e5992b9ae1e31bfab8ae6adbb061deee Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Wed, 28 Dec 2022 08:47:44 +0300 Subject: [PATCH] FT collision part1: AABB. --- SpaceCadetPinball/DebugOverlay.cpp | 21 +++++ SpaceCadetPinball/DebugOverlay.h | 1 + SpaceCadetPinball/TCircle.cpp | 11 ++- SpaceCadetPinball/TCircle.h | 2 +- SpaceCadetPinball/TCollisionComponent.cpp | 1 + SpaceCadetPinball/TCollisionComponent.h | 2 + SpaceCadetPinball/TEdgeSegment.cpp | 47 ++++-------- SpaceCadetPinball/TEdgeSegment.h | 3 +- SpaceCadetPinball/TFlagSpinner.cpp | 4 +- SpaceCadetPinball/TFlipper.cpp | 1 + SpaceCadetPinball/TFlipperEdge.cpp | 93 ++++++++--------------- SpaceCadetPinball/TFlipperEdge.h | 2 +- SpaceCadetPinball/THole.cpp | 2 +- SpaceCadetPinball/TKickout.cpp | 2 +- SpaceCadetPinball/TLine.cpp | 10 ++- SpaceCadetPinball/TLine.h | 2 +- SpaceCadetPinball/TOneway.cpp | 4 +- SpaceCadetPinball/TRamp.cpp | 8 +- SpaceCadetPinball/TTableLayer.cpp | 2 +- SpaceCadetPinball/maths.cpp | 8 ++ SpaceCadetPinball/maths.h | 2 + SpaceCadetPinball/options.cpp | 2 + SpaceCadetPinball/options.h | 1 + SpaceCadetPinball/pb.cpp | 9 ++- SpaceCadetPinball/pb.h | 3 +- SpaceCadetPinball/winmain.cpp | 2 + 26 files changed, 132 insertions(+), 113 deletions(-) diff --git a/SpaceCadetPinball/DebugOverlay.cpp b/SpaceCadetPinball/DebugOverlay.cpp index a3d1ff3..7621462 100644 --- a/SpaceCadetPinball/DebugOverlay.cpp +++ b/SpaceCadetPinball/DebugOverlay.cpp @@ -123,6 +123,10 @@ void DebugOverlay::DrawOverlay() if (options::Options.DebugOverlayBallDepthGrid) DrawBallDepthSteps(); + // Draw AABB of collision components + if (options::Options.DebugOverlayAabb) + DrawComponentAabb(); + // Restore render target SDL_SetRenderTarget(winmain::Renderer, initialRenderTarget); SDL_SetRenderDrawColor(winmain::Renderer, @@ -271,6 +275,23 @@ void DebugOverlay::DrawBallDepthSteps() } } +void DebugOverlay::DrawComponentAabb() +{ + SDL_SetRenderDrawColor(winmain::Renderer, 0, 50, 200, 255); + for (auto cmp : pb::MainTable->ComponentList) + { + auto collCmp = dynamic_cast(cmp); + if (collCmp) + { + const auto& aabb = collCmp->AABB; + auto pt1 = proj::xform_to_2d(vector2{ aabb.XMax, aabb.YMax }); + auto pt2 = proj::xform_to_2d(vector2{ aabb.XMin, aabb.YMin }); + SDL_Rect rect{ pt2.X,pt2.Y, pt1.X - pt2.X , pt1.Y - pt2.Y }; + SDL_RenderDrawRect(winmain::Renderer, &rect); + } + } +} + void DebugOverlay::DrawCicleType(circle_type& circle) { vector2 linePt{ circle.Center.X + sqrt(circle.RadiusSq), circle.Center.Y }; diff --git a/SpaceCadetPinball/DebugOverlay.h b/SpaceCadetPinball/DebugOverlay.h index 3c95d52..af01689 100644 --- a/SpaceCadetPinball/DebugOverlay.h +++ b/SpaceCadetPinball/DebugOverlay.h @@ -22,4 +22,5 @@ private: static void DrawAllSprites(); static void DrawSoundPositions(); static void DrawBallDepthSteps(); + static void DrawComponentAabb(); }; \ No newline at end of file diff --git a/SpaceCadetPinball/TCircle.cpp b/SpaceCadetPinball/TCircle.cpp index 485346b..a3bd49a 100644 --- a/SpaceCadetPinball/TCircle.cpp +++ b/SpaceCadetPinball/TCircle.cpp @@ -29,7 +29,16 @@ void TCircle::EdgeCollision(TBall* ball, float distance) CollisionComponent->Collision(ball, &nextPosition, &direction, distance, this); } -void TCircle::place_in_grid() +void TCircle::place_in_grid(RectF* aabb) { + if(aabb) + { + const auto radius = sqrt(Circle.RadiusSq); + aabb->Merge({ + Circle.Center.X + radius, Circle.Center.Y + radius, + Circle.Center.X - radius, Circle.Center.Y - radius + }); + } + TTableLayer::edges_insert_circle(&Circle, this, nullptr); } diff --git a/SpaceCadetPinball/TCircle.h b/SpaceCadetPinball/TCircle.h index 2ba6b35..7cac2e4 100644 --- a/SpaceCadetPinball/TCircle.h +++ b/SpaceCadetPinball/TCircle.h @@ -12,5 +12,5 @@ public: float radius); float FindCollisionDistance(ray_type* ray) override; void EdgeCollision(TBall* ball, float distance) override; - void place_in_grid() override; + void place_in_grid(RectF* aabb) override; }; diff --git a/SpaceCadetPinball/TCollisionComponent.cpp b/SpaceCadetPinball/TCollisionComponent.cpp index 5e7cfb2..822bee1 100644 --- a/SpaceCadetPinball/TCollisionComponent.cpp +++ b/SpaceCadetPinball/TCollisionComponent.cpp @@ -13,6 +13,7 @@ TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, b visualStruct visual{}; ActiveFlag = 1; + AABB = { -10000, -10000, 10000, 10000 }; if (GroupName != nullptr) UnusedBaseFlag = 1; if (groupIndex <= 0) diff --git a/SpaceCadetPinball/TCollisionComponent.h b/SpaceCadetPinball/TCollisionComponent.h index e0d727c..01d35f5 100644 --- a/SpaceCadetPinball/TCollisionComponent.h +++ b/SpaceCadetPinball/TCollisionComponent.h @@ -1,4 +1,5 @@ #pragma once +#include "maths.h" #include "TPinballComponent.h" struct vector2; @@ -15,6 +16,7 @@ public: float Threshold; int SoftHitSoundId; int HardHitSoundId; + RectF AABB; TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall); ~TCollisionComponent() override; diff --git a/SpaceCadetPinball/TEdgeSegment.cpp b/SpaceCadetPinball/TEdgeSegment.cpp index 3ffff0d..2d78f8b 100644 --- a/SpaceCadetPinball/TEdgeSegment.cpp +++ b/SpaceCadetPinball/TEdgeSegment.cpp @@ -33,15 +33,10 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c center.Y = floatArr[2]; auto radius = offset + floatArr[3]; auto circle = new TCircle(collComp, activeFlagPtr, collisionGroup, ¢er, radius); - edge = circle; - - if (circle) - { - circle->WallValue = reinterpret_cast(wallValue); - circle->place_in_grid(); - } - + circle->WallValue = reinterpret_cast(wallValue); + circle->place_in_grid(&collComp->AABB); collComp->EdgeList.push_back(circle); + edge = circle; break; } case wall_type::Line: @@ -51,15 +46,11 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c end.X = floatArr[3]; end.Y = floatArr[4]; auto line = new TLine(collComp, activeFlagPtr, collisionGroup, start, end); + line->WallValue = reinterpret_cast(wallValue); + line->Offset(offset); + line->place_in_grid(&collComp->AABB); + collComp->EdgeList.push_back(line); edge = line; - - if (line) - { - line->WallValue = reinterpret_cast(wallValue); - line->Offset(offset); - line->place_in_grid(); - collComp->EdgeList.push_back(line); - } break; } default: @@ -99,13 +90,9 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c { float radius = offset * 1.001f; auto circle = new TCircle(collComp, activeFlagPtr, collisionGroup, ¢er, radius); - - if (circle) - { - circle->WallValue = reinterpret_cast(wallValue); - circle->place_in_grid(); - collComp->EdgeList.push_back(circle); - } + circle->WallValue = reinterpret_cast(wallValue); + circle->place_in_grid(&collComp->AABB); + collComp->EdgeList.push_back(circle); } } @@ -114,16 +101,12 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c end.X = floatArrPtr[2]; end.Y = floatArrPtr[3]; auto line = new TLine(collComp, activeFlagPtr, collisionGroup, start, end); + line->WallValue = reinterpret_cast(wallValue); + line->Offset(offset); + line->place_in_grid(&collComp->AABB); + collComp->EdgeList.push_back(line); + edge = line; - - if (line) - { - line->WallValue = reinterpret_cast(wallValue); - line->Offset(offset); - line->place_in_grid(); - collComp->EdgeList.push_back(line); - } - prevCenter = center; } } diff --git a/SpaceCadetPinball/TEdgeSegment.h b/SpaceCadetPinball/TEdgeSegment.h index 6ea257b..28e75aa 100644 --- a/SpaceCadetPinball/TEdgeSegment.h +++ b/SpaceCadetPinball/TEdgeSegment.h @@ -3,6 +3,7 @@ class TBall; class TCollisionComponent; struct ray_type; +struct RectF; enum class wall_type : int { @@ -24,7 +25,7 @@ public: virtual void EdgeCollision(TBall* ball, float distance) = 0; virtual void port_draw(); - virtual void place_in_grid() = 0; + virtual void place_in_grid(RectF* aabb) = 0; virtual float FindCollisionDistance(ray_type* ray) = 0; static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* activeFlagPtr, diff --git a/SpaceCadetPinball/TFlagSpinner.cpp b/SpaceCadetPinball/TFlagSpinner.cpp index 9e3c384..751d6a1 100644 --- a/SpaceCadetPinball/TFlagSpinner.cpp +++ b/SpaceCadetPinball/TFlagSpinner.cpp @@ -24,7 +24,7 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom auto line = new TLine(this, &ActiveFlag, visual.CollisionGroup, start, end); if (line) { - line->place_in_grid(); + line->place_in_grid(&AABB); EdgeList.push_back(line); } @@ -32,7 +32,7 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom PrevCollider = line; if (line) { - line->place_in_grid(); + line->place_in_grid(&AABB); EdgeList.push_back(line); } diff --git a/SpaceCadetPinball/TFlipper.cpp b/SpaceCadetPinball/TFlipper.cpp index c7fb28c..300c356 100644 --- a/SpaceCadetPinball/TFlipper.cpp +++ b/SpaceCadetPinball/TFlipper.cpp @@ -39,6 +39,7 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t collMult, Elasticity, Smoothness); + flipperEdge->place_in_grid(&AABB); FlipperEdge = flipperEdge; BmpIndex = 0; diff --git a/SpaceCadetPinball/TFlipperEdge.cpp b/SpaceCadetPinball/TFlipperEdge.cpp index f53799a..c0602e2 100644 --- a/SpaceCadetPinball/TFlipperEdge.cpp +++ b/SpaceCadetPinball/TFlipperEdge.cpp @@ -12,7 +12,7 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi vector3* origin, vector3* vecT1, vector3* vecT2, float extendTime, float retractTime, float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, activeFlag, collisionGroup) { - vector3 crossProd{}, vecDir1{}, vecDir2{}; + vector3 crossProd{}, vecOriginT1{}, vecOriginT2{}; Elasticity = elasticity; Smoothness = smoothness; @@ -31,20 +31,21 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi CircleT1RadiusMSq = CircleT1Radius * 1.01f * (CircleT1Radius * 1.01f); CircleT1RadiusSq = CircleT1Radius * CircleT1Radius; - vecDir1.X = vecT1->X - origin->X; - vecDir1.Y = vecT1->Y - origin->Y; - vecDir1.Z = 0.0; - maths::normalize_2d(vecDir1); + vecOriginT1.X = vecT1->X - origin->X; + vecOriginT1.Y = vecT1->Y - origin->Y; + vecOriginT1.Z = 0.0; + maths::normalize_2d(vecOriginT1); - vecDir2.X = vecT2->X - origin->X; - vecDir2.Y = vecT2->Y - origin->Y; - vecDir2.Z = 0.0; - maths::normalize_2d(vecDir2); + vecOriginT2.X = vecT2->X - origin->X; + vecOriginT2.Y = vecT2->Y - origin->Y; + vecOriginT2.Z = 0.0; + maths::normalize_2d(vecOriginT2); - AngleMax = acos(maths::DotProduct(vecDir1, vecDir2)); - maths::cross(vecDir1, vecDir2, crossProd); + AngleMax = acos(maths::DotProduct(vecOriginT1, vecOriginT2)); + maths::cross(vecOriginT1, vecOriginT2, crossProd); if (crossProd.Z < 0.0f) AngleMax = -AngleMax; + FlipperFlag = MessageCode::TFlipperNull; AngleDst = 0.0; @@ -60,19 +61,17 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi ExtendTime = extendTime; RetractTime = retractTime; - auto dirX1 = vecDir1.X; - auto dirY1 = -vecDir1.Y; - A2Src.X = dirY1 * CirclebaseRadius + origin->X; - A2Src.Y = dirX1 * CirclebaseRadius + origin->Y; - A1Src.X = dirY1 * CircleT1Radius + vecT1->X; - A1Src.Y = dirX1 * CircleT1Radius + vecT1->Y; + const vector2 perpOriginT1Cc = { -vecOriginT1.Y , vecOriginT1.X }; + A2Src.X = perpOriginT1Cc.X * CirclebaseRadius + origin->X; + A2Src.Y = perpOriginT1Cc.Y * CirclebaseRadius + origin->Y; + A1Src.X = perpOriginT1Cc.X * CircleT1Radius + vecT1->X; + A1Src.Y = perpOriginT1Cc.Y * CircleT1Radius + vecT1->Y; - dirX1 = -dirX1; - dirY1 = -dirY1; - B1Src.X = dirY1 * CirclebaseRadius + origin->X; - B1Src.Y = dirX1 * CirclebaseRadius + origin->Y; - B2Src.X = dirY1 * CircleT1Radius + vecT1->X; - B2Src.Y = dirX1 * CircleT1Radius + vecT1->Y; + const vector2 perpOriginT1C = { vecOriginT1.Y , -vecOriginT1.X }; + B1Src.X = perpOriginT1C.X * CirclebaseRadius + origin->X; + B1Src.Y = perpOriginT1C.Y * CirclebaseRadius + origin->Y; + B2Src.X = perpOriginT1C.X * CircleT1Radius + vecT1->X; + B2Src.Y = perpOriginT1C.Y * CircleT1Radius + vecT1->Y; if (AngleMax < 0.0f) { @@ -89,7 +88,6 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi auto distance = maths::Distance(*vecT1, *vecT2); CollisionTimeAdvance = minMoveTime / (distance / CircleT1Radius + distance / CircleT1Radius); - TFlipperEdge::place_in_grid(); EdgeCollisionFlag = 0; InputTime = 0.0; CollisionFlag1 = 0; @@ -349,46 +347,19 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float distance) maths::basic_collision(ball, &NextBallPosition, &CollisionDirection, elasticity, Smoothness, 1000000000.0, 0.0); } -void TFlipperEdge::place_in_grid() +void TFlipperEdge::place_in_grid(RectF* aabb) { - float x0 = RotOrigin.X - CirclebaseRadius; - float y0 = RotOrigin.Y - CirclebaseRadius; - float x1 = RotOrigin.X + CirclebaseRadius; - float y1 = RotOrigin.Y + CirclebaseRadius; + auto xMax = std::max(std::max(T2Src.X + CircleT1Radius, T1Src.X + CircleT1Radius), RotOrigin.X + CirclebaseRadius); + auto yMax = std::max(std::max(T2Src.Y + CircleT1Radius, T1Src.Y + CircleT1Radius), RotOrigin.Y + CirclebaseRadius); + auto xMin = std::min(std::min(T2Src.X - CircleT1Radius, T1Src.X - CircleT1Radius), RotOrigin.X - CirclebaseRadius); + auto yMin = std::min(std::min(T2Src.Y - CircleT1Radius, T1Src.Y - CircleT1Radius), RotOrigin.Y - CirclebaseRadius); - float v2 = T1Src.X - CircleT1Radius; - if (v2 < x0) - x0 = v2; + if (aabb) + { + aabb->Merge({xMax, yMax, xMin, yMin}); + } - float v3 = T1Src.Y - CircleT1Radius; - if (v3 < y0) - y0 = v3; - - float v4 = T1Src.X + CircleT1Radius; - if (v4 > x1) - x1 = v4; - - float v5 = T1Src.Y + CircleT1Radius; - if (v5 > y1) - y1 = v5; - - float v6 = T2Src.X - CircleT1Radius; - if (v6 < x0) - x0 = v6; - - float v7 = T2Src.Y - CircleT1Radius; - if (v7 < y0) - y0 = v7; - - float v8 = T2Src.X + CircleT1Radius; - if (v8 > x1) - x1 = v8; - - float v9 = T2Src.Y + CircleT1Radius; - if (v9 > y1) - y1 = v9; - - TTableLayer::edges_insert_square(y0, x0, y1, x1, this, nullptr); + TTableLayer::edges_insert_square(yMin, xMin, yMax, xMax, this, nullptr); } void TFlipperEdge::set_control_points(float timeNow) diff --git a/SpaceCadetPinball/TFlipperEdge.h b/SpaceCadetPinball/TFlipperEdge.h index 4d567f7..d0f4653 100644 --- a/SpaceCadetPinball/TFlipperEdge.h +++ b/SpaceCadetPinball/TFlipperEdge.h @@ -14,7 +14,7 @@ public: void port_draw() override; float FindCollisionDistance(ray_type* ray) override; void EdgeCollision(TBall* ball, float distance) override; - void place_in_grid() override; + void place_in_grid(RectF* aabb) override; void set_control_points(float timeNow); float flipper_angle(float timeNow); int is_ball_inside(float x, float y); diff --git a/SpaceCadetPinball/THole.cpp b/SpaceCadetPinball/THole.cpp index 0dab6fd..6aaef00 100644 --- a/SpaceCadetPinball/THole.cpp +++ b/SpaceCadetPinball/THole.cpp @@ -35,7 +35,7 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table, Circle.RadiusSq); if (tCircle) { - tCircle->place_in_grid(); + tCircle->place_in_grid(&AABB); EdgeList.push_back(tCircle); } diff --git a/SpaceCadetPinball/TKickout.cpp b/SpaceCadetPinball/TKickout.cpp index 69db464..90591c8 100644 --- a/SpaceCadetPinball/TKickout.cpp +++ b/SpaceCadetPinball/TKickout.cpp @@ -39,7 +39,7 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis reinterpret_cast(visual.FloatArr), Circle.RadiusSq); if (tCircle) { - tCircle->place_in_grid(); + tCircle->place_in_grid(&AABB); EdgeList.push_back(tCircle); } diff --git a/SpaceCadetPinball/TLine.cpp b/SpaceCadetPinball/TLine.cpp index 625b28f..3d95fb3 100644 --- a/SpaceCadetPinball/TLine.cpp +++ b/SpaceCadetPinball/TLine.cpp @@ -51,8 +51,16 @@ void TLine::EdgeCollision(TBall* ball, float distance) this); } -void TLine::place_in_grid() +void TLine::place_in_grid(RectF* aabb) { + if (aabb) + { + aabb->Merge({ + std::max(X0, X1), std::max(Y0, Y1), + std::min(X0, X1), std::min(Y0, Y1) + }); + } + auto edgeMan = TTableLayer::edge_manager; auto xBox0 = edgeMan->box_x(X0); auto yBox0 = edgeMan->box_y(Y0); diff --git a/SpaceCadetPinball/TLine.h b/SpaceCadetPinball/TLine.h index 1bb8894..9a05508 100644 --- a/SpaceCadetPinball/TLine.h +++ b/SpaceCadetPinball/TLine.h @@ -13,5 +13,5 @@ public: void Offset(float offset); float FindCollisionDistance(ray_type* ray) override; void EdgeCollision(TBall* ball, float distance) override; - void place_in_grid() override; + void place_in_grid(RectF* aabb) override; }; diff --git a/SpaceCadetPinball/TOneway.cpp b/SpaceCadetPinball/TOneway.cpp index 8751b84..27a4cfa 100644 --- a/SpaceCadetPinball/TOneway.cpp +++ b/SpaceCadetPinball/TOneway.cpp @@ -25,7 +25,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab if (line) { line->Offset(table->CollisionCompOffset); - line->place_in_grid(); + line->place_in_grid(&AABB); EdgeList.push_back(line); } @@ -34,7 +34,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab if (line) { line->Offset(-table->CollisionCompOffset * 0.8f); - Line->place_in_grid(); + Line->place_in_grid(&AABB); EdgeList.push_back(Line); } } diff --git a/SpaceCadetPinball/TRamp.cpp b/SpaceCadetPinball/TRamp.cpp index 185175a..fc5adad 100644 --- a/SpaceCadetPinball/TRamp.cpp +++ b/SpaceCadetPinball/TRamp.cpp @@ -33,7 +33,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, auto wall0Pts = reinterpret_cast(wall0Arr + 2); Line1 = new TLine(this, &ActiveFlag, wall0CollisionGroup, wall0Pts->Pt1, wall0Pts->Pt0); Line1->WallValue = nullptr; - Line1->place_in_grid(); + Line1->place_in_grid(&AABB); EdgeList.push_back(Line1); auto wall1Arr = loader::query_float_attribute(groupIndex, 0, 1301); @@ -49,7 +49,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, Line2 = new TLine(this, &ActiveFlag, CollisionGroup, wall1Start, wall1End); Line2->WallValue = nullptr; - Line2->place_in_grid(); + Line2->place_in_grid(&AABB); EdgeList.push_back(Line2); auto wall2Arr = loader::query_float_attribute(groupIndex, 0, 1302); @@ -65,7 +65,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, Line3 = new TLine(this, &ActiveFlag, CollisionGroup, wall2Start, wall2End); Line3->WallValue = nullptr; - Line3->place_in_grid(); + Line3->place_in_grid(&AABB); EdgeList.push_back(Line3); @@ -105,7 +105,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, { auto line = new TLine(this, &ActiveFlag, collisionGroup, point1, point2); line->WallValue = &plane; - line->place_in_grid(); + line->place_in_grid(&AABB); EdgeList.push_back(line); } } diff --git a/SpaceCadetPinball/TTableLayer.cpp b/SpaceCadetPinball/TTableLayer.cpp index c1d3932..311a2e0 100644 --- a/SpaceCadetPinball/TTableLayer.cpp +++ b/SpaceCadetPinball/TTableLayer.cpp @@ -91,7 +91,7 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f edgePoints[i + 1].Y, edgePoints[i].X, edgePoints[i].Y); - line->place_in_grid(); + line->place_in_grid(&AABB); EdgeList.push_back(line); } diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp index d8b51b4..382aab2 100644 --- a/SpaceCadetPinball/maths.cpp +++ b/SpaceCadetPinball/maths.cpp @@ -5,6 +5,14 @@ #include "TFlipperEdge.h" +void RectF::Merge(RectF aabb) +{ + XMax = std::max(XMax, aabb.XMax); + YMax = std::max(YMax, aabb.YMax); + XMin = std::min(XMin, aabb.XMin); + YMin = std::min(YMin, aabb.YMin); +} + // Performs AABB merge, creating rect that is just large enough to contain both source rects. void maths::enclosing_box(const rectangle_type& rect1, const rectangle_type& rect2, rectangle_type& dstRect) { diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h index 49dfc19..6ba3c32 100644 --- a/SpaceCadetPinball/maths.h +++ b/SpaceCadetPinball/maths.h @@ -88,6 +88,8 @@ struct ramp_plane_type struct RectF { float XMax, YMax, XMin, YMin; + + void Merge(RectF aabb); }; enum class FlipperIntersect diff --git a/SpaceCadetPinball/options.cpp b/SpaceCadetPinball/options.cpp index 269963e..e759506 100644 --- a/SpaceCadetPinball/options.cpp +++ b/SpaceCadetPinball/options.cpp @@ -118,6 +118,7 @@ void options::InitPrimary() translations::SetCurrentLanguage(get_string("Language", translations::GetCurrentLanguage()->ShortName).c_str()); Options.FontFileName = get_string("FontFileName", ""); Options.DebugOverlayBallDepthGrid = get_int("Debug Overlay Ball Depth Grid", true); + Options.DebugOverlayAabb = get_int("Debug Overlay AABB", true); } void options::InitSecondary() @@ -169,6 +170,7 @@ void options::uninit() set_string("Language", translations::GetCurrentLanguage()->ShortName); set_string("FontFileName", Options.FontFileName.c_str()); set_int("Debug Overlay Ball Depth Grid", Options.DebugOverlayBallDepthGrid); + set_int("Debug Overlay AABB", Options.DebugOverlayAabb); } diff --git a/SpaceCadetPinball/options.h b/SpaceCadetPinball/options.h index 4157959..9e01f00 100644 --- a/SpaceCadetPinball/options.h +++ b/SpaceCadetPinball/options.h @@ -93,6 +93,7 @@ struct optionsStruct bool DebugOverlaySprites; bool DebugOverlaySounds; bool DebugOverlayBallDepthGrid; + bool DebugOverlayAabb; std::string FontFileName; }; diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index c4a93ae..6c45be3 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -32,7 +32,8 @@ TPinballTable* pb::MainTable = nullptr; DatFile* pb::record_table = nullptr; int pb::time_ticks = 0; GameModes pb::game_mode = GameModes::GameOver; -float pb::time_now = 0, pb::time_next = 0, pb::ball_speed_limit, pb::time_ticks_remainder = 0; +float pb::time_now = 0, pb::time_next = 0, pb::time_ticks_remainder = 0; +float pb::ball_speed_limit, pb::ball_min_smth, pb::ball_inv_smth, pb::ball_collision_dist; bool pb::FullTiltMode = false, pb::FullTiltDemoMode = false, pb::cheat_mode = false, pb::demo_mode = false; std::string pb::DatFileName, pb::BasePath; ImU32 pb::TextBoxColor; @@ -102,7 +103,11 @@ int pb::init() MainTable = new TPinballTable(); high_score::read(); - ball_speed_limit = MainTable->BallList.at(0)->Offset * 200.0f; + auto ball = MainTable->BallList.at(0); + ball_speed_limit = ball->Offset * 200.0f; + ball_min_smth = ball->Offset * 0.5f; + ball_inv_smth = 1.0f / ball_min_smth; + ball_collision_dist = (ball->Offset + ball_min_smth) * 2.0f; int red = 255, green = 255, blue = 255; auto fontColor = get_rc_string(Msg::TextBoxColor); diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index 9f8e185..88e0fe3 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -42,7 +42,8 @@ class pb { public: static int time_ticks; - static float ball_speed_limit, time_now, time_next, time_ticks_remainder; + static float time_now, time_next, time_ticks_remainder; + static float ball_speed_limit, ball_min_smth, ball_inv_smth, ball_collision_dist; static GameModes game_mode; static bool cheat_mode; static DatFile* record_table; diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 44c5f96..f282a93 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -732,6 +732,8 @@ void winmain::RenderUi() Options.DebugOverlaySprites ^= true; if (ImGui::MenuItem("All Edges", nullptr, Options.DebugOverlayAllEdges)) Options.DebugOverlayAllEdges ^= true; + if (ImGui::MenuItem("Component AABB", nullptr, Options.DebugOverlayAabb)) + Options.DebugOverlayAabb ^= true; if (ImGui::MenuItem("Ball Position", nullptr, Options.DebugOverlayBallPosition)) Options.DebugOverlayBallPosition ^= true; if (ImGui::MenuItem("Ball Box Edges", nullptr, Options.DebugOverlayBallEdges))