mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-12-18 20:02:40 -05:00
TEdgeSegment v1.
This commit is contained in:
parent
dbb69d8976
commit
0258363287
12 changed files with 340 additions and 2 deletions
|
@ -172,9 +172,12 @@
|
|||
<ClInclude Include="TBall.h" />
|
||||
<ClInclude Include="TBlocker.h" />
|
||||
<ClInclude Include="TBumper.h" />
|
||||
<ClInclude Include="TCircle.h" />
|
||||
<ClInclude Include="TCollisionComponent.h" />
|
||||
<ClInclude Include="TComponentGroup.h" />
|
||||
<ClInclude Include="TDemo.h" />
|
||||
<ClInclude Include="TDrain.h" />
|
||||
<ClInclude Include="TEdgeSegment.h" />
|
||||
<ClInclude Include="TFlagSpinner.h" />
|
||||
<ClInclude Include="TFlipper.h" />
|
||||
<ClInclude Include="TGate.h" />
|
||||
|
@ -185,6 +188,7 @@
|
|||
<ClInclude Include="TLightBargraph.h" />
|
||||
<ClInclude Include="TLightGroup.h" />
|
||||
<ClInclude Include="TLightRollover.h" />
|
||||
<ClInclude Include="TLine.h" />
|
||||
<ClInclude Include="TOneway.h" />
|
||||
<ClInclude Include="TPinballComponent.h" />
|
||||
<ClInclude Include="TPinballTable.h" />
|
||||
|
@ -228,9 +232,12 @@
|
|||
<ClCompile Include="TBall.cpp" />
|
||||
<ClCompile Include="TBlocker.cpp" />
|
||||
<ClCompile Include="TBumper.cpp" />
|
||||
<ClCompile Include="TCircle.cpp" />
|
||||
<ClCompile Include="TCollisionComponent.cpp" />
|
||||
<ClCompile Include="TComponentGroup.cpp" />
|
||||
<ClCompile Include="TDemo.cpp" />
|
||||
<ClCompile Include="TDrain.cpp" />
|
||||
<ClCompile Include="TEdgeSegment.cpp" />
|
||||
<ClCompile Include="TFlagSpinner.cpp" />
|
||||
<ClCompile Include="TFlipper.cpp" />
|
||||
<ClCompile Include="TGate.cpp" />
|
||||
|
@ -241,6 +248,7 @@
|
|||
<ClCompile Include="TLightBargraph.cpp" />
|
||||
<ClCompile Include="TLightGroup.cpp" />
|
||||
<ClCompile Include="TLightRollover.cpp" />
|
||||
<ClCompile Include="TLine.cpp" />
|
||||
<ClCompile Include="TOneway.cpp" />
|
||||
<ClCompile Include="TPinballComponent.cpp" />
|
||||
<ClCompile Include="TPinballTable.cpp" />
|
||||
|
|
|
@ -19,6 +19,18 @@
|
|||
<Filter Include="Source Files\PinballComponents">
|
||||
<UniqueIdentifier>{33813da8-81ac-449c-b19a-9756272519b9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\TEdgeSegment">
|
||||
<UniqueIdentifier>{0aa40751-a44a-400e-8809-ee817161e8e0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\TEdgeSegment">
|
||||
<UniqueIdentifier>{d70e7fca-2294-41a4-9cf8-78052bdb9aa4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\TCollisionComponent">
|
||||
<UniqueIdentifier>{01aed326-d2ec-457a-b99f-08ef32ed97fa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\TCollisionComponent">
|
||||
<UniqueIdentifier>{7ed2796a-da4b-4edd-8783-53e45d8d1c88}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h">
|
||||
|
@ -168,6 +180,18 @@
|
|||
<ClInclude Include="zdrv.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TEdgeSegment.h">
|
||||
<Filter>Header Files\TEdgeSegment</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TCollisionComponent.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TCircle.h">
|
||||
<Filter>Header Files\TEdgeSegment</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TLine.h">
|
||||
<Filter>Header Files\TEdgeSegment</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
|
@ -314,6 +338,18 @@
|
|||
<ClCompile Include="zdrv.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TEdgeSegment.cpp">
|
||||
<Filter>Source Files\TEdgeSegment</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TCollisionComponent.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TCircle.cpp">
|
||||
<Filter>Source Files\TEdgeSegment</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TLine.cpp">
|
||||
<Filter>Source Files\TEdgeSegment</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="NatvisFile.natvis" />
|
||||
|
|
16
SpaceCadetPinball/TCircle.cpp
Normal file
16
SpaceCadetPinball/TCircle.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include "pch.h"
|
||||
#include "TCircle.h"
|
||||
|
||||
TCircle::TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned visualFlag, float* floatArr,
|
||||
float radius): TEdgeSegment(collComp, someFlagPtr, visualFlag)
|
||||
{
|
||||
Circle.RadiusSq = radius * radius;
|
||||
Circle.X = *floatArr;
|
||||
Circle.Y = floatArr[1];
|
||||
Circle.Unknown2 = floatArr[2];
|
||||
}
|
||||
|
||||
double TCircle::FindCollisionDistance(ray_type* ray)
|
||||
{
|
||||
return maths::ray_intersect_circle(ray, &Circle);
|
||||
}
|
12
SpaceCadetPinball/TCircle.h
Normal file
12
SpaceCadetPinball/TCircle.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
#include "maths.h"
|
||||
#include "TEdgeSegment.h"
|
||||
|
||||
class TCircle :
|
||||
public TEdgeSegment
|
||||
{
|
||||
circle_type Circle;
|
||||
|
||||
TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned int visualFlag, float* floatArr, float radius);
|
||||
double FindCollisionDistance(ray_type* ray) override;
|
||||
};
|
2
SpaceCadetPinball/TCollisionComponent.cpp
Normal file
2
SpaceCadetPinball/TCollisionComponent.cpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include "pch.h"
|
||||
#include "TCollisionComponent.h"
|
5
SpaceCadetPinball/TCollisionComponent.h
Normal file
5
SpaceCadetPinball/TCollisionComponent.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
class TCollisionComponent
|
||||
{
|
||||
};
|
||||
|
10
SpaceCadetPinball/TEdgeSegment.cpp
Normal file
10
SpaceCadetPinball/TEdgeSegment.cpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "pch.h"
|
||||
#include "TEdgeSegment.h"
|
||||
|
||||
TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned visualFlag)
|
||||
{
|
||||
this->CollisionComponent = collComp;
|
||||
this->PinbCompFlag2Ptr = someFlag;
|
||||
this->VisualFlag = visualFlag;
|
||||
this->Unknown3_0 = 0;
|
||||
}
|
23
SpaceCadetPinball/TEdgeSegment.h
Normal file
23
SpaceCadetPinball/TEdgeSegment.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include "TCollisionComponent.h"
|
||||
#include "maths.h"
|
||||
#include "TBall.h"
|
||||
|
||||
class TEdgeSegment
|
||||
{
|
||||
public:
|
||||
TCollisionComponent* CollisionComponent;
|
||||
char* PinbCompFlag2Ptr;
|
||||
char Unknown3_0;
|
||||
char Unknown3_1;
|
||||
char Unknown3_2;
|
||||
char Unknown3_3;
|
||||
char Unknown4;
|
||||
int VisualFlag;
|
||||
|
||||
TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag);
|
||||
//virtual ~TEdgeSegment() = 0;
|
||||
virtual void place_in_grid() = 0;
|
||||
virtual double FindCollisionDistance(ray_type* ray) = 0;
|
||||
virtual void EdgeCollision(TBall* ball, float coef) = 0;
|
||||
};
|
38
SpaceCadetPinball/TLine.cpp
Normal file
38
SpaceCadetPinball/TLine.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include "pch.h"
|
||||
#include "TLine.h"
|
||||
|
||||
|
||||
TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, float x0, float y0, float x1,
|
||||
float y1): TEdgeSegment(collCmp, flagPtr, visualFlag)
|
||||
{
|
||||
Start.X = x0;
|
||||
Start.Y = y0;
|
||||
End.X = x1;
|
||||
End.Y = y1;
|
||||
maths::line_init(&Line, x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start,
|
||||
struct vector_type* end) : TEdgeSegment(collCmp, flagPtr, visualFlag)
|
||||
{
|
||||
Start = *start;
|
||||
End = *end;
|
||||
maths::line_init(&Line, Start.X, Start.Y, End.X, End.Y);
|
||||
}
|
||||
|
||||
void TLine::Offset(float offset)
|
||||
{
|
||||
float offX = offset * Line.PerpendicularL.X;
|
||||
float offY = offset * Line.PerpendicularL.Y;
|
||||
|
||||
Start.X += offX;
|
||||
Start.Y += offY;
|
||||
End.X += offX;
|
||||
End.Y += offY;
|
||||
maths::line_init(&Line, Start.X, Start.Y, End.X, End.Y);
|
||||
}
|
||||
|
||||
double TLine::FindCollisionDistance(ray_type* ray)
|
||||
{
|
||||
return maths::ray_intersect_line(ray, &Line);
|
||||
}
|
17
SpaceCadetPinball/TLine.h
Normal file
17
SpaceCadetPinball/TLine.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include "maths.h"
|
||||
#include "TEdgeSegment.h"
|
||||
|
||||
class TLine :
|
||||
public TEdgeSegment
|
||||
{
|
||||
public:
|
||||
line_type Line;
|
||||
vector_type Start;
|
||||
vector_type End;
|
||||
TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, float x0, float y0, float x1, float y1);
|
||||
TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start,
|
||||
struct vector_type* end);
|
||||
void Offset(float offset);
|
||||
double FindCollisionDistance(ray_type* ray) override;
|
||||
};
|
|
@ -83,7 +83,6 @@ int maths::overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectang
|
|||
{
|
||||
int v3; // esi
|
||||
int v4; // edi
|
||||
int v5; // esi
|
||||
int v6; // esi
|
||||
int v7; // edi
|
||||
|
||||
|
@ -100,7 +99,7 @@ int maths::overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectang
|
|||
v4 = rect2->XPosition;
|
||||
}
|
||||
dstRect->Width = v3 + v4 + 1;
|
||||
v5 = rect1->YPosition;
|
||||
int v5 = rect1->YPosition;
|
||||
if (v5 >= rect2->YPosition)
|
||||
{
|
||||
dstRect->YPosition = rect2->YPosition;
|
||||
|
@ -116,3 +115,133 @@ int maths::overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectang
|
|||
dstRect->Height = v6 + v7 + 1;
|
||||
return dstRect->Width <= rect2->Width + rect1->Width && dstRect->Height <= rect2->Height + rect1->Height;
|
||||
}
|
||||
|
||||
float maths::ray_intersect_circle(ray_type* ray, circle_type* circle)
|
||||
{
|
||||
// O - ray origin
|
||||
// D - ray direction
|
||||
// C - circle center
|
||||
// R - circle radius
|
||||
// L, C - O, vector between O and C
|
||||
float Lx = circle->X - ray->Origin.X;
|
||||
float Ly = circle->Y - ray->Origin.Y;
|
||||
|
||||
// Tca, L dot D, projection of L on D
|
||||
float Tca = Ly * ray->Direction.Y + Lx * ray->Direction.X;
|
||||
if (Tca < 0.0) // No intersection if Tca is negative
|
||||
return 1000000000.0f;
|
||||
|
||||
// L dot L, distance from ray origin to circle center
|
||||
float LMagSq = Ly * Ly + Lx * Lx;
|
||||
|
||||
// If ray origin is inside of the circle
|
||||
// T0 = Tca - Sqrt(rad^2 - d^2). d = sqrt(L dot L - Tca dot Tca)
|
||||
if (LMagSq < circle->RadiusSq)
|
||||
return Tca - sqrt(circle->RadiusSq - LMagSq + Tca * Tca);
|
||||
|
||||
// Thc^2 = rad^2 - d = rad^2 - L dot L + Tca dot Tca
|
||||
float ThcSq = circle->RadiusSq - LMagSq + Tca * Tca;
|
||||
if (ThcSq < 0.0) // No intersection if Thc is negative
|
||||
return 1000000000.0f;
|
||||
|
||||
// T0 = Tca - Thc, distance from origin to first intersection
|
||||
float T0 = Tca - sqrt(ThcSq);
|
||||
if (T0 < 0.0 || T0 > ray->MaxDistance)
|
||||
return 1000000000.0f;
|
||||
return T0;
|
||||
}
|
||||
|
||||
|
||||
float maths::normalize_2d(vector_type* vec)
|
||||
{
|
||||
float mag = sqrt(vec->X * vec->X + vec->Y * vec->Y);
|
||||
if (0.0 != mag)
|
||||
{
|
||||
vec->X = 1.0f / mag * vec->X;
|
||||
vec->Y = 1.0f / mag * vec->Y;
|
||||
}
|
||||
return mag;
|
||||
}
|
||||
|
||||
|
||||
void maths::line_init(line_type* line, float x0, float y0, float x1, float y1)
|
||||
{
|
||||
float v9; // st7
|
||||
bool lineDirection; // pf
|
||||
float v11; // eax
|
||||
|
||||
line->Direction.X = x1 - x0;
|
||||
line->Direction.Y = y1 - y0;
|
||||
normalize_2d(&line->Direction);
|
||||
line->PerpendicularL.X = line->Direction.Y;
|
||||
line->PerpendicularL.Y = -line->Direction.X;
|
||||
line->PreComp1 = -(line->Direction.Y * x0) + (line->Direction.X * y0);
|
||||
if (line->Direction.X >= 0.000000001 || line->Direction.X <= -0.000000001)
|
||||
{
|
||||
v9 = x1;
|
||||
lineDirection = x0 >= x1;
|
||||
v11 = x0;
|
||||
}
|
||||
else
|
||||
{
|
||||
line->Direction.X = 0.0;
|
||||
v9 = y1;
|
||||
lineDirection = y0 >= y1;
|
||||
v11 = y0;
|
||||
}
|
||||
if (lineDirection)
|
||||
{
|
||||
line->Origin.X = v9;
|
||||
line->Origin.Y = v11;
|
||||
}
|
||||
else
|
||||
{
|
||||
line->Origin.Y = v9;
|
||||
line->Origin.X = v11;
|
||||
}
|
||||
}
|
||||
|
||||
float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
||||
{
|
||||
// Similar to https://rootllama.wordpress.com/2014/06/20/ray-line-segment-intersection-test-in-2d/
|
||||
float perpDot; // st7
|
||||
float result; // st7
|
||||
float v4; // st6
|
||||
bool v5; // c0
|
||||
bool v6; // c3
|
||||
float v7; // st6
|
||||
|
||||
perpDot = line->PerpendicularL.Y * ray->Direction.Y + ray->Direction.X * line->PerpendicularL.X;
|
||||
if (perpDot < 0.0)
|
||||
{
|
||||
result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line->PreComp1)
|
||||
/ perpDot);
|
||||
if (result >= -ray->Unknown7 && result <= ray->MaxDistance)
|
||||
{
|
||||
line->Unknown9 = result * ray->Direction.X + ray->Origin.X;
|
||||
v4 = result * ray->Direction.Y + ray->Origin.Y;
|
||||
line->Unknown10 = v4;
|
||||
if (0.0 == line->Direction.X)
|
||||
{
|
||||
if (v4 >= line->Origin.X)
|
||||
{
|
||||
v5 = v4 < line->Origin.Y;
|
||||
v6 = v4 == line->Origin.Y;
|
||||
if (v5 || v6)
|
||||
return result;
|
||||
return 1000000000.0;
|
||||
}
|
||||
}
|
||||
else if (line->Origin.X <= line->Unknown9)
|
||||
{
|
||||
v7 = line->Unknown9;
|
||||
v5 = v7 < line->Origin.Y;
|
||||
v6 = v7 == line->Origin.Y;
|
||||
if (v5 || v6)
|
||||
return result;
|
||||
return 1000000000.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1000000000.0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
struct vector_type
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
};
|
||||
|
||||
|
||||
struct __declspec(align(4)) rectangle_type
|
||||
{
|
||||
|
@ -9,10 +15,46 @@ struct __declspec(align(4)) rectangle_type
|
|||
int Height;
|
||||
};
|
||||
|
||||
struct circle_type
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Unknown2;
|
||||
float RadiusSq;
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) ray_type
|
||||
{
|
||||
vector_type Origin;
|
||||
float Unknown2;
|
||||
vector_type Direction;
|
||||
float Unknown5;
|
||||
float MaxDistance;
|
||||
float Unknown7;
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) line_type
|
||||
{
|
||||
vector_type PerpendicularL;
|
||||
float Unknown2;
|
||||
vector_type Direction;
|
||||
float Unknown5;
|
||||
float PreComp1;
|
||||
vector_type Origin;
|
||||
float Unknown9;
|
||||
float Unknown10;
|
||||
float Unknown11;
|
||||
};
|
||||
|
||||
|
||||
class maths
|
||||
{
|
||||
public:
|
||||
static void enclosing_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect);
|
||||
static int rectangle_clip(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect);
|
||||
static int overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect);
|
||||
static float ray_intersect_circle(ray_type* ray, circle_type* circle);
|
||||
static float normalize_2d(vector_type* vec);
|
||||
static void line_init(line_type* line, float x0, float y0, float x1, float y1);
|
||||
static float ray_intersect_line(ray_type* ray, line_type* line);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue