1
0
Fork 0
mirror of https://github.com/k4zmu2a/SpaceCadetPinball.git synced 2024-11-22 17:00:18 +01:00

vector_type is 3 x float, TCollisionComponent v1.

This commit is contained in:
oz 2020-11-28 14:39:12 +03:00
parent 0258363287
commit a1678120f8
15 changed files with 270 additions and 60 deletions

View file

@ -1,13 +1,11 @@
#include "pch.h" #include "pch.h"
#include "TCircle.h" #include "TCircle.h"
TCircle::TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned visualFlag, float* floatArr, TCircle::TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned visualFlag, vector_type* center,
float radius): TEdgeSegment(collComp, someFlagPtr, visualFlag) float radius): TEdgeSegment(collComp, someFlagPtr, visualFlag)
{ {
Circle.RadiusSq = radius * radius; Circle.RadiusSq = radius * radius;
Circle.X = *floatArr; Circle.Center = *center;
Circle.Y = floatArr[1];
Circle.Unknown2 = floatArr[2];
} }
double TCircle::FindCollisionDistance(ray_type* ray) double TCircle::FindCollisionDistance(ray_type* ray)

View file

@ -5,8 +5,18 @@
class TCircle : class TCircle :
public TEdgeSegment public TEdgeSegment
{ {
public:
circle_type Circle; circle_type Circle;
TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned int visualFlag, float* floatArr, float radius); TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned int visualFlag, vector_type* center,
float radius);
double FindCollisionDistance(ray_type* ray) override; double FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float coef) override
{
}
void place_in_grid() override
{
}
}; };

View file

@ -1,2 +1,50 @@
#include "pch.h" #include "pch.h"
#include "TCollisionComponent.h" #include "TCollisionComponent.h"
#include "loader.h"
#include "TEdgeSegment.h"
#include "TPinballTable.h"
TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, int someFlag) : TPinballComponent(
table, groupIndex, true)
{
visualStruct visual{};
EdgeList = new objlist_class(4, 4);
UnknownBaseFlag2 = 1;
if (GroupName != nullptr)
UnknownBaseFlag1 = 1;
if (groupIndex <= 0)
{
loader::default_vsi(&visual);
}
else
{
loader::query_visual(groupIndex, 0, &visual);
if (someFlag)
{
float offset = table->UnknownP61F;
float* floatArr = loader::query_float_attribute(groupIndex, 0, 600);
TEdgeSegment::install_wall(floatArr, this, &UnknownBaseFlag2, visual.Flag, offset, 0);
}
}
UnknownC7F = visual.Kicker.Unknown1F;
UnknownC4F = visual.Unknown2F;
UnknownC5F = visual.Unknown1F;
UnknownC6F = visual.Kicker.Unknown2F;
SoundIndex1 = visual.Kicker.SoundIndex;
SoundIndex2 = visual.SoundIndex2;
GroupIndex = groupIndex;
}
TCollisionComponent::~TCollisionComponent()
{
for (TEdgeSegment* edge; EdgeList->Count() > 0;)
{
edge = static_cast<TEdgeSegment*>(EdgeList->Get(0));
EdgeList->Delete(edge);
delete edge;
}
delete this->EdgeList;
}

View file

@ -1,5 +1,20 @@
#pragma once #pragma once
class TCollisionComponent #include "objlist_class.h"
{ #include "TPinballComponent.h"
};
class TCollisionComponent : public TPinballComponent
{
public:
objlist_class* EdgeList;
__int16 UnknownC2;
__int16 UnknownC3;
float UnknownC4F;
float UnknownC5F;
float UnknownC6F;
float UnknownC7F;
int SoundIndex2;
int SoundIndex1;
TCollisionComponent(TPinballTable* table, int groupIndex, int someFlag);
~TCollisionComponent();
};

View file

@ -1,5 +1,7 @@
#include "pch.h" #include "pch.h"
#include "TEdgeSegment.h" #include "TEdgeSegment.h"
#include "TCircle.h"
#include "TLine.h"
TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned visualFlag) TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned visualFlag)
{ {
@ -8,3 +10,116 @@ TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsign
this->VisualFlag = visualFlag; this->VisualFlag = visualFlag;
this->Unknown3_0 = 0; this->Unknown3_0 = 0;
} }
TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* collComp, char* flagPtr,
unsigned int visual_flag,
float offset, int someValue)
{
vector_type center{}, start{}, end{}, prevCenter{}, vec1{}, vec2{}, dstVec{};
TEdgeSegment* edge1;
wall_type wallType = static_cast<wall_type>(static_cast<int>(floor(*floatArr) - 1.0));
switch (wallType)
{
case wall_type::Circle:
{
center.X = floatArr[1];
center.Y = floatArr[2];
auto radius = offset + floatArr[3];
auto circle = new TCircle(collComp, flagPtr, visual_flag, &center, radius);
if (circle)
{
circle->WallValue = someValue;
circle->place_in_grid();
}
collComp->EdgeList->Add(circle);
return circle;
}
case wall_type::Line:
{
start.X = floatArr[1];
start.Y = floatArr[2];
end.X = floatArr[3];
end.Y = floatArr[4];
auto line = new TLine(collComp, flagPtr, visual_flag, &start, &end);
if (line)
{
line->WallValue = someValue;
line->Offset(offset);
line->place_in_grid();
collComp->EdgeList->Add(line);
}
return line;
}
default:
{
int wallTypeI = static_cast<int>(wallType);
auto floatArrPtr = floatArr + 1;
prevCenter.X = floatArr[2 * wallTypeI - 1];
prevCenter.Y = floatArr[2 * wallTypeI];
for (int index = 0; index < wallTypeI; index++, floatArrPtr += 2)
{
float centerX2, centerY2;
if (index >= wallTypeI - 1)
{
centerX2 = floatArr[1];
centerY2 = floatArr[2];
}
else
{
centerX2 = floatArrPtr[2];
centerY2 = floatArrPtr[3];
}
auto centerX1 = floatArrPtr[0];
auto centerY1 = floatArrPtr[1];
center.X = centerX1;
center.Y = centerY1;
if (offset != 0.0)
{
vec1.X = centerX1 - prevCenter.X;
vec1.Y = center.Y - prevCenter.Y;
vec2.X = centerX2 - centerX1;
vec2.Y = centerY2 - center.Y;
maths::cross(&vec1, &vec2, &dstVec);
if (dstVec.Z > 0.0 && offset > 0.0 ||
dstVec.Z < 0.0 && offset < 0.0)
{
auto radius = offset * 1.001;
auto circle = new TCircle(collComp, flagPtr, visual_flag, &center, radius);
if (circle)
{
circle->WallValue = someValue;
circle->place_in_grid();
collComp->EdgeList->Add(circle);
}
}
}
start.X = floatArrPtr[0];
start.Y = floatArrPtr[1];
end.X = floatArrPtr[2];
end.Y = floatArrPtr[3];
auto line = new TLine(collComp, flagPtr, visual_flag, &start, &end);
if (line)
{
line->WallValue = someValue;
line->Offset(offset);
line->place_in_grid();
collComp->EdgeList->Add(line);
}
prevCenter = center;
}
}
}
return nullptr;
}

View file

@ -3,21 +3,30 @@
#include "maths.h" #include "maths.h"
#include "TBall.h" #include "TBall.h"
enum class wall_type
{
Circle = 0,
Line = 1,
};
class TEdgeSegment class TEdgeSegment
{ {
public: public:
TCollisionComponent* CollisionComponent; TCollisionComponent* CollisionComponent;
char* PinbCompFlag2Ptr; char* PinbCompFlag2Ptr;
char Unknown3_0; char Unknown3_0;
char Unknown3_1; int WallValue;
char Unknown3_2;
char Unknown3_3;
char Unknown4;
int VisualFlag; int VisualFlag;
TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag); TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag);
//virtual ~TEdgeSegment() = 0;
virtual ~TEdgeSegment()
{
}
virtual void place_in_grid() = 0; virtual void place_in_grid() = 0;
virtual double FindCollisionDistance(ray_type* ray) = 0; virtual double FindCollisionDistance(ray_type* ray) = 0;
virtual void EdgeCollision(TBall* ball, float coef) = 0; virtual void EdgeCollision(TBall* ball, float coef) = 0;
static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* flagPtr,
unsigned int visual_flag, float offset, int someValue);
}; };

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "TPinballComponent.h" #include "TPinballComponent.h"
class TFlipper : class TFlipper :
public TPinballComponent public TPinballComponent
{ {

View file

@ -5,19 +5,21 @@
TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, float x0, float y0, float x1, TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, float x0, float y0, float x1,
float y1): TEdgeSegment(collCmp, flagPtr, visualFlag) float y1): TEdgeSegment(collCmp, flagPtr, visualFlag)
{ {
Start.X = x0; this->X0 = x0;
Start.Y = y0; this->Y0 = y0;
End.X = x1; this->X1 = x1;
End.Y = y1; this->Y1 = y1;
maths::line_init(&Line, x0, y0, x1, y1); maths::line_init(&Line, x0, y0, x1, y1);
} }
TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start, TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start,
struct vector_type* end) : TEdgeSegment(collCmp, flagPtr, visualFlag) struct vector_type* end) : TEdgeSegment(collCmp, flagPtr, visualFlag)
{ {
Start = *start; this->X0 = start->X;
End = *end; this->Y0 = start->Y;
maths::line_init(&Line, Start.X, Start.Y, End.X, End.Y); this->X1 = end->X;
this->Y1 = end->Y;
maths::line_init(&Line, X0, Y0, X1, Y1);
} }
void TLine::Offset(float offset) void TLine::Offset(float offset)
@ -25,14 +27,14 @@ void TLine::Offset(float offset)
float offX = offset * Line.PerpendicularL.X; float offX = offset * Line.PerpendicularL.X;
float offY = offset * Line.PerpendicularL.Y; float offY = offset * Line.PerpendicularL.Y;
Start.X += offX; X0 += offX;
Start.Y += offY; Y0 += offY;
End.X += offX; X1 += offX;
End.Y += offY; Y1 += offY;
maths::line_init(&Line, Start.X, Start.Y, End.X, End.Y); maths::line_init(&Line, X0, Y0, X1, Y1);
} }
double TLine::FindCollisionDistance(ray_type* ray) double TLine::FindCollisionDistance(ray_type* ray)
{ {
return maths::ray_intersect_line(ray, &Line); return maths::ray_intersect_line(ray, &Line);
} }

View file

@ -7,11 +7,18 @@ class TLine :
{ {
public: public:
line_type Line; line_type Line;
vector_type Start; float X0, Y0, X1, Y1;
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, float x0, float y0, float x1, float y1);
TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start, TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start,
struct vector_type* end); struct vector_type* end);
void Offset(float offset); void Offset(float offset);
double FindCollisionDistance(ray_type* ray) override; double FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float coef) override
{
}
void place_in_grid() override
{
}
}; };

View file

@ -2,11 +2,12 @@
#include "render.h" #include "render.h"
#include "TZmapList.h" #include "TZmapList.h"
class TPinballTable;
class TPinballComponent class TPinballComponent
{ {
public: public:
TPinballComponent(class TPinballTable* table, int groupIndex, bool loadVisuals); TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals);
virtual ~TPinballComponent(); virtual ~TPinballComponent();
virtual int Message(int message1, float message2); virtual int Message(int message1, float message2);
virtual void put_scoring(int score1, int score2); virtual void put_scoring(int score1, int score2);

View file

@ -73,7 +73,7 @@ public:
int UnknownP58; int UnknownP58;
int UnknownP59; int UnknownP59;
int UnknownP60; int UnknownP60;
int UnknownP61; float UnknownP61F;
int UnknownP62; int UnknownP62;
int UnknownP63; int UnknownP63;
int UnknownP64; int UnknownP64;

View file

@ -83,7 +83,7 @@ int loader::error(int errorCode, int captionCode)
void loader::default_vsi(visualStruct* visual) void loader::default_vsi(visualStruct* visual)
{ {
visual->Unknown14Flag = 0; visual->Flag = 0;
visual->Kicker.Unknown1F = 8.9999999e10f; visual->Kicker.Unknown1F = 8.9999999e10f;
visual->Kicker.SoundIndex = 0; visual->Kicker.SoundIndex = 0;
visual->Unknown1F = 0.94999999f; visual->Unknown1F = 0.94999999f;
@ -509,7 +509,7 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi
shortValSub602 = shortVal - 602; shortValSub602 = shortVal - 602;
if (!shortValSub602) if (!shortValSub602)
{ {
visual2->Unknown14Flag |= 1 << *nextShortVal; visual2->Flag |= 1 << *nextShortVal;
goto LABEL_31; goto LABEL_31;
} }
shortValSub1100 = shortValSub602 - 498; shortValSub1100 = shortValSub602 - 498;
@ -537,8 +537,8 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi
} }
} }
LABEL_33: LABEL_33:
if (!visual2->Unknown14Flag) if (!visual2->Flag)
visual2->Unknown14Flag = 1; visual2->Flag = 1;
floatArr = (float*)partman::field(loader_table, groupIndexSum3, datFieldTypes::FloatArray); floatArr = (float*)partman::field(loader_table, groupIndexSum3, datFieldTypes::FloatArray);
if (!floatArr) if (!floatArr)
return 0; return 0;

View file

@ -41,7 +41,7 @@ struct __declspec(align(4)) visualStruct
float* FloatArr; float* FloatArr;
int SoundIndex2; int SoundIndex2;
visualKickerStruct Kicker; visualKickerStruct Kicker;
int Unknown14Flag; int Flag;
int SoundIndex4; int SoundIndex4;
int SoundIndex3; int SoundIndex3;
gdrv_bitmap8* Bitmap; gdrv_bitmap8* Bitmap;

View file

@ -123,8 +123,8 @@ float maths::ray_intersect_circle(ray_type* ray, circle_type* circle)
// C - circle center // C - circle center
// R - circle radius // R - circle radius
// L, C - O, vector between O and C // L, C - O, vector between O and C
float Lx = circle->X - ray->Origin.X; float Lx = circle->Center.X - ray->Origin.X;
float Ly = circle->Y - ray->Origin.Y; float Ly = circle->Center.Y - ray->Origin.Y;
// Tca, L dot D, projection of L on D // Tca, L dot D, projection of L on D
float Tca = Ly * ray->Direction.Y + Lx * ray->Direction.X; float Tca = Ly * ray->Direction.Y + Lx * ray->Direction.X;
@ -191,13 +191,13 @@ void maths::line_init(line_type* line, float x0, float y0, float x1, float y1)
} }
if (lineDirection) if (lineDirection)
{ {
line->Origin.X = v9; line->OriginX = v9;
line->Origin.Y = v11; line->OriginY = v11;
} }
else else
{ {
line->Origin.Y = v9; line->OriginY = v9;
line->Origin.X = v11; line->OriginX = v11;
} }
} }
@ -216,27 +216,27 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
{ {
result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line->PreComp1) result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line->PreComp1)
/ perpDot); / perpDot);
if (result >= -ray->Unknown7 && result <= ray->MaxDistance) if (result >= -ray->MinDistance && result <= ray->MaxDistance)
{ {
line->Unknown9 = result * ray->Direction.X + ray->Origin.X; line->CompTmp1 = result * ray->Direction.X + ray->Origin.X;
v4 = result * ray->Direction.Y + ray->Origin.Y; v4 = result * ray->Direction.Y + ray->Origin.Y;
line->Unknown10 = v4; line->Unknown10 = v4;
if (0.0 == line->Direction.X) if (0.0 == line->Direction.X)
{ {
if (v4 >= line->Origin.X) if (v4 >= line->OriginX)
{ {
v5 = v4 < line->Origin.Y; v5 = v4 < line->OriginY;
v6 = v4 == line->Origin.Y; v6 = v4 == line->OriginY;
if (v5 || v6) if (v5 || v6)
return result; return result;
return 1000000000.0; return 1000000000.0;
} }
} }
else if (line->Origin.X <= line->Unknown9) else if (line->OriginX <= line->CompTmp1)
{ {
v7 = line->Unknown9; v7 = line->CompTmp1;
v5 = v7 < line->Origin.Y; v5 = v7 < line->OriginY;
v6 = v7 == line->Origin.Y; v6 = v7 == line->OriginY;
if (v5 || v6) if (v5 || v6)
return result; return result;
return 1000000000.0; return 1000000000.0;
@ -245,3 +245,10 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
} }
return 1000000000.0; return 1000000000.0;
} }
void maths::cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec)
{
dstVec->X = vec2->Z * vec1->Y - vec2->Y * vec1->Z;
dstVec->Y = vec2->X * vec1->Z - vec1->X * vec2->Z;
dstVec->Z = vec1->X * vec2->Y - vec2->X * vec1->Y;
}

View file

@ -4,6 +4,7 @@ struct vector_type
{ {
float X; float X;
float Y; float Y;
float Z;
}; };
@ -17,31 +18,26 @@ struct __declspec(align(4)) rectangle_type
struct circle_type struct circle_type
{ {
float X; vector_type Center;
float Y;
float Unknown2;
float RadiusSq; float RadiusSq;
}; };
struct __declspec(align(4)) ray_type struct __declspec(align(4)) ray_type
{ {
vector_type Origin; vector_type Origin;
float Unknown2;
vector_type Direction; vector_type Direction;
float Unknown5;
float MaxDistance; float MaxDistance;
float Unknown7; float MinDistance;
}; };
struct __declspec(align(4)) line_type struct __declspec(align(4)) line_type
{ {
vector_type PerpendicularL; vector_type PerpendicularL;
float Unknown2;
vector_type Direction; vector_type Direction;
float Unknown5;
float PreComp1; float PreComp1;
vector_type Origin; float OriginX;
float Unknown9; float OriginY;
float CompTmp1;
float Unknown10; float Unknown10;
float Unknown11; float Unknown11;
}; };
@ -57,4 +53,5 @@ public:
static float normalize_2d(vector_type* vec); static float normalize_2d(vector_type* vec);
static void line_init(line_type* line, float x0, float y0, float x1, float y1); 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); static float ray_intersect_line(ray_type* ray, line_type* line);
static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec);
}; };