FT collision part1: AABB.

This commit is contained in:
Muzychenko Andrey 2022-12-28 08:47:44 +03:00
parent 17f11bd428
commit 2d6f2c14e5
26 changed files with 132 additions and 113 deletions

View File

@ -123,6 +123,10 @@ void DebugOverlay::DrawOverlay()
if (options::Options.DebugOverlayBallDepthGrid) if (options::Options.DebugOverlayBallDepthGrid)
DrawBallDepthSteps(); DrawBallDepthSteps();
// Draw AABB of collision components
if (options::Options.DebugOverlayAabb)
DrawComponentAabb();
// Restore render target // Restore render target
SDL_SetRenderTarget(winmain::Renderer, initialRenderTarget); SDL_SetRenderTarget(winmain::Renderer, initialRenderTarget);
SDL_SetRenderDrawColor(winmain::Renderer, 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<TCollisionComponent*>(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) void DebugOverlay::DrawCicleType(circle_type& circle)
{ {
vector2 linePt{ circle.Center.X + sqrt(circle.RadiusSq), circle.Center.Y }; vector2 linePt{ circle.Center.X + sqrt(circle.RadiusSq), circle.Center.Y };

View File

@ -22,4 +22,5 @@ private:
static void DrawAllSprites(); static void DrawAllSprites();
static void DrawSoundPositions(); static void DrawSoundPositions();
static void DrawBallDepthSteps(); static void DrawBallDepthSteps();
static void DrawComponentAabb();
}; };

View File

@ -29,7 +29,16 @@ void TCircle::EdgeCollision(TBall* ball, float distance)
CollisionComponent->Collision(ball, &nextPosition, &direction, distance, this); 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); TTableLayer::edges_insert_circle(&Circle, this, nullptr);
} }

View File

@ -12,5 +12,5 @@ public:
float radius); float radius);
float FindCollisionDistance(ray_type* ray) override; float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float distance) override; void EdgeCollision(TBall* ball, float distance) override;
void place_in_grid() override; void place_in_grid(RectF* aabb) override;
}; };

View File

@ -13,6 +13,7 @@ TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, b
visualStruct visual{}; visualStruct visual{};
ActiveFlag = 1; ActiveFlag = 1;
AABB = { -10000, -10000, 10000, 10000 };
if (GroupName != nullptr) if (GroupName != nullptr)
UnusedBaseFlag = 1; UnusedBaseFlag = 1;
if (groupIndex <= 0) if (groupIndex <= 0)

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "maths.h"
#include "TPinballComponent.h" #include "TPinballComponent.h"
struct vector2; struct vector2;
@ -15,6 +16,7 @@ public:
float Threshold; float Threshold;
int SoftHitSoundId; int SoftHitSoundId;
int HardHitSoundId; int HardHitSoundId;
RectF AABB;
TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall); TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall);
~TCollisionComponent() override; ~TCollisionComponent() override;

View File

@ -33,15 +33,10 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
center.Y = floatArr[2]; center.Y = floatArr[2];
auto radius = offset + floatArr[3]; auto radius = offset + floatArr[3];
auto circle = new TCircle(collComp, activeFlagPtr, collisionGroup, &center, radius); auto circle = new TCircle(collComp, activeFlagPtr, collisionGroup, &center, radius);
edge = circle; circle->WallValue = reinterpret_cast<void*>(wallValue);
circle->place_in_grid(&collComp->AABB);
if (circle)
{
circle->WallValue = reinterpret_cast<void*>(wallValue);
circle->place_in_grid();
}
collComp->EdgeList.push_back(circle); collComp->EdgeList.push_back(circle);
edge = circle;
break; break;
} }
case wall_type::Line: case wall_type::Line:
@ -51,15 +46,11 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
end.X = floatArr[3]; end.X = floatArr[3];
end.Y = floatArr[4]; end.Y = floatArr[4];
auto line = new TLine(collComp, activeFlagPtr, collisionGroup, start, end); auto line = new TLine(collComp, activeFlagPtr, collisionGroup, start, end);
line->WallValue = reinterpret_cast<void*>(wallValue);
line->Offset(offset);
line->place_in_grid(&collComp->AABB);
collComp->EdgeList.push_back(line);
edge = line; edge = line;
if (line)
{
line->WallValue = reinterpret_cast<void*>(wallValue);
line->Offset(offset);
line->place_in_grid();
collComp->EdgeList.push_back(line);
}
break; break;
} }
default: default:
@ -99,13 +90,9 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
{ {
float radius = offset * 1.001f; float radius = offset * 1.001f;
auto circle = new TCircle(collComp, activeFlagPtr, collisionGroup, &center, radius); auto circle = new TCircle(collComp, activeFlagPtr, collisionGroup, &center, radius);
circle->WallValue = reinterpret_cast<void*>(wallValue);
if (circle) circle->place_in_grid(&collComp->AABB);
{ collComp->EdgeList.push_back(circle);
circle->WallValue = reinterpret_cast<void*>(wallValue);
circle->place_in_grid();
collComp->EdgeList.push_back(circle);
}
} }
} }
@ -114,16 +101,12 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
end.X = floatArrPtr[2]; end.X = floatArrPtr[2];
end.Y = floatArrPtr[3]; end.Y = floatArrPtr[3];
auto line = new TLine(collComp, activeFlagPtr, collisionGroup, start, end); auto line = new TLine(collComp, activeFlagPtr, collisionGroup, start, end);
line->WallValue = reinterpret_cast<void*>(wallValue);
line->Offset(offset);
line->place_in_grid(&collComp->AABB);
collComp->EdgeList.push_back(line);
edge = line; edge = line;
if (line)
{
line->WallValue = reinterpret_cast<void*>(wallValue);
line->Offset(offset);
line->place_in_grid();
collComp->EdgeList.push_back(line);
}
prevCenter = center; prevCenter = center;
} }
} }

View File

@ -3,6 +3,7 @@
class TBall; class TBall;
class TCollisionComponent; class TCollisionComponent;
struct ray_type; struct ray_type;
struct RectF;
enum class wall_type : int enum class wall_type : int
{ {
@ -24,7 +25,7 @@ public:
virtual void EdgeCollision(TBall* ball, float distance) = 0; virtual void EdgeCollision(TBall* ball, float distance) = 0;
virtual void port_draw(); 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; virtual float FindCollisionDistance(ray_type* ray) = 0;
static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* activeFlagPtr, static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* activeFlagPtr,

View File

@ -24,7 +24,7 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom
auto line = new TLine(this, &ActiveFlag, visual.CollisionGroup, start, end); auto line = new TLine(this, &ActiveFlag, visual.CollisionGroup, start, end);
if (line) if (line)
{ {
line->place_in_grid(); line->place_in_grid(&AABB);
EdgeList.push_back(line); EdgeList.push_back(line);
} }
@ -32,7 +32,7 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom
PrevCollider = line; PrevCollider = line;
if (line) if (line)
{ {
line->place_in_grid(); line->place_in_grid(&AABB);
EdgeList.push_back(line); EdgeList.push_back(line);
} }

View File

@ -39,6 +39,7 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
collMult, collMult,
Elasticity, Elasticity,
Smoothness); Smoothness);
flipperEdge->place_in_grid(&AABB);
FlipperEdge = flipperEdge; FlipperEdge = flipperEdge;
BmpIndex = 0; BmpIndex = 0;

View File

@ -12,7 +12,7 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
vector3* origin, vector3* vecT1, vector3* vecT2, float extendTime, float retractTime, vector3* origin, vector3* vecT1, vector3* vecT2, float extendTime, float retractTime,
float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, activeFlag, collisionGroup) float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, activeFlag, collisionGroup)
{ {
vector3 crossProd{}, vecDir1{}, vecDir2{}; vector3 crossProd{}, vecOriginT1{}, vecOriginT2{};
Elasticity = elasticity; Elasticity = elasticity;
Smoothness = smoothness; Smoothness = smoothness;
@ -31,20 +31,21 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
CircleT1RadiusMSq = CircleT1Radius * 1.01f * (CircleT1Radius * 1.01f); CircleT1RadiusMSq = CircleT1Radius * 1.01f * (CircleT1Radius * 1.01f);
CircleT1RadiusSq = CircleT1Radius * CircleT1Radius; CircleT1RadiusSq = CircleT1Radius * CircleT1Radius;
vecDir1.X = vecT1->X - origin->X; vecOriginT1.X = vecT1->X - origin->X;
vecDir1.Y = vecT1->Y - origin->Y; vecOriginT1.Y = vecT1->Y - origin->Y;
vecDir1.Z = 0.0; vecOriginT1.Z = 0.0;
maths::normalize_2d(vecDir1); maths::normalize_2d(vecOriginT1);
vecDir2.X = vecT2->X - origin->X; vecOriginT2.X = vecT2->X - origin->X;
vecDir2.Y = vecT2->Y - origin->Y; vecOriginT2.Y = vecT2->Y - origin->Y;
vecDir2.Z = 0.0; vecOriginT2.Z = 0.0;
maths::normalize_2d(vecDir2); maths::normalize_2d(vecOriginT2);
AngleMax = acos(maths::DotProduct(vecDir1, vecDir2)); AngleMax = acos(maths::DotProduct(vecOriginT1, vecOriginT2));
maths::cross(vecDir1, vecDir2, crossProd); maths::cross(vecOriginT1, vecOriginT2, crossProd);
if (crossProd.Z < 0.0f) if (crossProd.Z < 0.0f)
AngleMax = -AngleMax; AngleMax = -AngleMax;
FlipperFlag = MessageCode::TFlipperNull; FlipperFlag = MessageCode::TFlipperNull;
AngleDst = 0.0; AngleDst = 0.0;
@ -60,19 +61,17 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
ExtendTime = extendTime; ExtendTime = extendTime;
RetractTime = retractTime; RetractTime = retractTime;
auto dirX1 = vecDir1.X; const vector2 perpOriginT1Cc = { -vecOriginT1.Y , vecOriginT1.X };
auto dirY1 = -vecDir1.Y; A2Src.X = perpOriginT1Cc.X * CirclebaseRadius + origin->X;
A2Src.X = dirY1 * CirclebaseRadius + origin->X; A2Src.Y = perpOriginT1Cc.Y * CirclebaseRadius + origin->Y;
A2Src.Y = dirX1 * CirclebaseRadius + origin->Y; A1Src.X = perpOriginT1Cc.X * CircleT1Radius + vecT1->X;
A1Src.X = dirY1 * CircleT1Radius + vecT1->X; A1Src.Y = perpOriginT1Cc.Y * CircleT1Radius + vecT1->Y;
A1Src.Y = dirX1 * CircleT1Radius + vecT1->Y;
dirX1 = -dirX1; const vector2 perpOriginT1C = { vecOriginT1.Y , -vecOriginT1.X };
dirY1 = -dirY1; B1Src.X = perpOriginT1C.X * CirclebaseRadius + origin->X;
B1Src.X = dirY1 * CirclebaseRadius + origin->X; B1Src.Y = perpOriginT1C.Y * CirclebaseRadius + origin->Y;
B1Src.Y = dirX1 * CirclebaseRadius + origin->Y; B2Src.X = perpOriginT1C.X * CircleT1Radius + vecT1->X;
B2Src.X = dirY1 * CircleT1Radius + vecT1->X; B2Src.Y = perpOriginT1C.Y * CircleT1Radius + vecT1->Y;
B2Src.Y = dirX1 * CircleT1Radius + vecT1->Y;
if (AngleMax < 0.0f) if (AngleMax < 0.0f)
{ {
@ -89,7 +88,6 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
auto distance = maths::Distance(*vecT1, *vecT2); auto distance = maths::Distance(*vecT1, *vecT2);
CollisionTimeAdvance = minMoveTime / (distance / CircleT1Radius + distance / CircleT1Radius); CollisionTimeAdvance = minMoveTime / (distance / CircleT1Radius + distance / CircleT1Radius);
TFlipperEdge::place_in_grid();
EdgeCollisionFlag = 0; EdgeCollisionFlag = 0;
InputTime = 0.0; InputTime = 0.0;
CollisionFlag1 = 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); 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; auto xMax = std::max(std::max(T2Src.X + CircleT1Radius, T1Src.X + CircleT1Radius), RotOrigin.X + CirclebaseRadius);
float y0 = RotOrigin.Y - CirclebaseRadius; auto yMax = std::max(std::max(T2Src.Y + CircleT1Radius, T1Src.Y + CircleT1Radius), RotOrigin.Y + CirclebaseRadius);
float x1 = RotOrigin.X + CirclebaseRadius; auto xMin = std::min(std::min(T2Src.X - CircleT1Radius, T1Src.X - CircleT1Radius), RotOrigin.X - CirclebaseRadius);
float y1 = RotOrigin.Y + CirclebaseRadius; auto yMin = std::min(std::min(T2Src.Y - CircleT1Radius, T1Src.Y - CircleT1Radius), RotOrigin.Y - CirclebaseRadius);
float v2 = T1Src.X - CircleT1Radius; if (aabb)
if (v2 < x0) {
x0 = v2; aabb->Merge({xMax, yMax, xMin, yMin});
}
float v3 = T1Src.Y - CircleT1Radius; TTableLayer::edges_insert_square(yMin, xMin, yMax, xMax, this, nullptr);
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);
} }
void TFlipperEdge::set_control_points(float timeNow) void TFlipperEdge::set_control_points(float timeNow)

View File

@ -14,7 +14,7 @@ public:
void port_draw() override; void port_draw() override;
float FindCollisionDistance(ray_type* ray) override; float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float distance) 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); void set_control_points(float timeNow);
float flipper_angle(float timeNow); float flipper_angle(float timeNow);
int is_ball_inside(float x, float y); int is_ball_inside(float x, float y);

View File

@ -35,7 +35,7 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
Circle.RadiusSq); Circle.RadiusSq);
if (tCircle) if (tCircle)
{ {
tCircle->place_in_grid(); tCircle->place_in_grid(&AABB);
EdgeList.push_back(tCircle); EdgeList.push_back(tCircle);
} }

View File

@ -39,7 +39,7 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis
reinterpret_cast<vector3*>(visual.FloatArr), Circle.RadiusSq); reinterpret_cast<vector3*>(visual.FloatArr), Circle.RadiusSq);
if (tCircle) if (tCircle)
{ {
tCircle->place_in_grid(); tCircle->place_in_grid(&AABB);
EdgeList.push_back(tCircle); EdgeList.push_back(tCircle);
} }

View File

@ -51,8 +51,16 @@ void TLine::EdgeCollision(TBall* ball, float distance)
this); 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 edgeMan = TTableLayer::edge_manager;
auto xBox0 = edgeMan->box_x(X0); auto xBox0 = edgeMan->box_x(X0);
auto yBox0 = edgeMan->box_y(Y0); auto yBox0 = edgeMan->box_y(Y0);

View File

@ -13,5 +13,5 @@ public:
void Offset(float offset); void Offset(float offset);
float FindCollisionDistance(ray_type* ray) override; float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float distance) override; void EdgeCollision(TBall* ball, float distance) override;
void place_in_grid() override; void place_in_grid(RectF* aabb) override;
}; };

View File

@ -25,7 +25,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab
if (line) if (line)
{ {
line->Offset(table->CollisionCompOffset); line->Offset(table->CollisionCompOffset);
line->place_in_grid(); line->place_in_grid(&AABB);
EdgeList.push_back(line); EdgeList.push_back(line);
} }
@ -34,7 +34,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab
if (line) if (line)
{ {
line->Offset(-table->CollisionCompOffset * 0.8f); line->Offset(-table->CollisionCompOffset * 0.8f);
Line->place_in_grid(); Line->place_in_grid(&AABB);
EdgeList.push_back(Line); EdgeList.push_back(Line);
} }
} }

View File

@ -33,7 +33,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
auto wall0Pts = reinterpret_cast<wall_point_type*>(wall0Arr + 2); auto wall0Pts = reinterpret_cast<wall_point_type*>(wall0Arr + 2);
Line1 = new TLine(this, &ActiveFlag, wall0CollisionGroup, wall0Pts->Pt1, wall0Pts->Pt0); Line1 = new TLine(this, &ActiveFlag, wall0CollisionGroup, wall0Pts->Pt1, wall0Pts->Pt0);
Line1->WallValue = nullptr; Line1->WallValue = nullptr;
Line1->place_in_grid(); Line1->place_in_grid(&AABB);
EdgeList.push_back(Line1); EdgeList.push_back(Line1);
auto wall1Arr = loader::query_float_attribute(groupIndex, 0, 1301); 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 = new TLine(this, &ActiveFlag, CollisionGroup, wall1Start, wall1End);
Line2->WallValue = nullptr; Line2->WallValue = nullptr;
Line2->place_in_grid(); Line2->place_in_grid(&AABB);
EdgeList.push_back(Line2); EdgeList.push_back(Line2);
auto wall2Arr = loader::query_float_attribute(groupIndex, 0, 1302); 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 = new TLine(this, &ActiveFlag, CollisionGroup, wall2Start, wall2End);
Line3->WallValue = nullptr; Line3->WallValue = nullptr;
Line3->place_in_grid(); Line3->place_in_grid(&AABB);
EdgeList.push_back(Line3); 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); auto line = new TLine(this, &ActiveFlag, collisionGroup, point1, point2);
line->WallValue = &plane; line->WallValue = &plane;
line->place_in_grid(); line->place_in_grid(&AABB);
EdgeList.push_back(line); EdgeList.push_back(line);
} }
} }

View File

@ -91,7 +91,7 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
edgePoints[i + 1].Y, edgePoints[i + 1].Y,
edgePoints[i].X, edgePoints[i].X,
edgePoints[i].Y); edgePoints[i].Y);
line->place_in_grid(); line->place_in_grid(&AABB);
EdgeList.push_back(line); EdgeList.push_back(line);
} }

View File

@ -5,6 +5,14 @@
#include "TFlipperEdge.h" #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. // 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) void maths::enclosing_box(const rectangle_type& rect1, const rectangle_type& rect2, rectangle_type& dstRect)
{ {

View File

@ -88,6 +88,8 @@ struct ramp_plane_type
struct RectF struct RectF
{ {
float XMax, YMax, XMin, YMin; float XMax, YMax, XMin, YMin;
void Merge(RectF aabb);
}; };
enum class FlipperIntersect enum class FlipperIntersect

View File

@ -118,6 +118,7 @@ void options::InitPrimary()
translations::SetCurrentLanguage(get_string("Language", translations::GetCurrentLanguage()->ShortName).c_str()); translations::SetCurrentLanguage(get_string("Language", translations::GetCurrentLanguage()->ShortName).c_str());
Options.FontFileName = get_string("FontFileName", ""); Options.FontFileName = get_string("FontFileName", "");
Options.DebugOverlayBallDepthGrid = get_int("Debug Overlay Ball Depth Grid", true); Options.DebugOverlayBallDepthGrid = get_int("Debug Overlay Ball Depth Grid", true);
Options.DebugOverlayAabb = get_int("Debug Overlay AABB", true);
} }
void options::InitSecondary() void options::InitSecondary()
@ -169,6 +170,7 @@ void options::uninit()
set_string("Language", translations::GetCurrentLanguage()->ShortName); set_string("Language", translations::GetCurrentLanguage()->ShortName);
set_string("FontFileName", Options.FontFileName.c_str()); set_string("FontFileName", Options.FontFileName.c_str());
set_int("Debug Overlay Ball Depth Grid", Options.DebugOverlayBallDepthGrid); set_int("Debug Overlay Ball Depth Grid", Options.DebugOverlayBallDepthGrid);
set_int("Debug Overlay AABB", Options.DebugOverlayAabb);
} }

View File

@ -93,6 +93,7 @@ struct optionsStruct
bool DebugOverlaySprites; bool DebugOverlaySprites;
bool DebugOverlaySounds; bool DebugOverlaySounds;
bool DebugOverlayBallDepthGrid; bool DebugOverlayBallDepthGrid;
bool DebugOverlayAabb;
std::string FontFileName; std::string FontFileName;
}; };

View File

@ -32,7 +32,8 @@ TPinballTable* pb::MainTable = nullptr;
DatFile* pb::record_table = nullptr; DatFile* pb::record_table = nullptr;
int pb::time_ticks = 0; int pb::time_ticks = 0;
GameModes pb::game_mode = GameModes::GameOver; 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; bool pb::FullTiltMode = false, pb::FullTiltDemoMode = false, pb::cheat_mode = false, pb::demo_mode = false;
std::string pb::DatFileName, pb::BasePath; std::string pb::DatFileName, pb::BasePath;
ImU32 pb::TextBoxColor; ImU32 pb::TextBoxColor;
@ -102,7 +103,11 @@ int pb::init()
MainTable = new TPinballTable(); MainTable = new TPinballTable();
high_score::read(); 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; int red = 255, green = 255, blue = 255;
auto fontColor = get_rc_string(Msg::TextBoxColor); auto fontColor = get_rc_string(Msg::TextBoxColor);

View File

@ -42,7 +42,8 @@ class pb
{ {
public: public:
static int time_ticks; 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 GameModes game_mode;
static bool cheat_mode; static bool cheat_mode;
static DatFile* record_table; static DatFile* record_table;

View File

@ -732,6 +732,8 @@ void winmain::RenderUi()
Options.DebugOverlaySprites ^= true; Options.DebugOverlaySprites ^= true;
if (ImGui::MenuItem("All Edges", nullptr, Options.DebugOverlayAllEdges)) if (ImGui::MenuItem("All Edges", nullptr, Options.DebugOverlayAllEdges))
Options.DebugOverlayAllEdges ^= true; Options.DebugOverlayAllEdges ^= true;
if (ImGui::MenuItem("Component AABB", nullptr, Options.DebugOverlayAabb))
Options.DebugOverlayAabb ^= true;
if (ImGui::MenuItem("Ball Position", nullptr, Options.DebugOverlayBallPosition)) if (ImGui::MenuItem("Ball Position", nullptr, Options.DebugOverlayBallPosition))
Options.DebugOverlayBallPosition ^= true; Options.DebugOverlayBallPosition ^= true;
if (ImGui::MenuItem("Ball Box Edges", nullptr, Options.DebugOverlayBallEdges)) if (ImGui::MenuItem("Ball Box Edges", nullptr, Options.DebugOverlayBallEdges))