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 "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)
{
Circle.RadiusSq = radius * radius;
Circle.X = *floatArr;
Circle.Y = floatArr[1];
Circle.Unknown2 = floatArr[2];
Circle.Center = *center;
}
double TCircle::FindCollisionDistance(ray_type* ray)

View File

@ -5,8 +5,18 @@
class TCircle :
public TEdgeSegment
{
public:
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;
void EdgeCollision(TBall* ball, float coef) override
{
}
void place_in_grid() override
{
}
};

View File

@ -1,2 +1,50 @@
#include "pch.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
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 "TEdgeSegment.h"
#include "TCircle.h"
#include "TLine.h"
TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned visualFlag)
{
@ -8,3 +10,116 @@ TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsign
this->VisualFlag = visualFlag;
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 "TBall.h"
enum class wall_type
{
Circle = 0,
Line = 1,
};
class TEdgeSegment
{
public:
TCollisionComponent* CollisionComponent;
char* PinbCompFlag2Ptr;
char Unknown3_0;
char Unknown3_1;
char Unknown3_2;
char Unknown3_3;
char Unknown4;
int WallValue;
int VisualFlag;
TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag);
//virtual ~TEdgeSegment() = 0;
virtual ~TEdgeSegment()
{
}
virtual void place_in_grid() = 0;
virtual double FindCollisionDistance(ray_type* ray) = 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
#include "TPinballComponent.h"
class TFlipper :
public TPinballComponent
{

View File

@ -5,19 +5,21 @@
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;
this->X0 = x0;
this->Y0 = y0;
this->X1 = x1;
this->Y1 = 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);
this->X0 = start->X;
this->Y0 = start->Y;
this->X1 = end->X;
this->Y1 = end->Y;
maths::line_init(&Line, X0, Y0, X1, Y1);
}
void TLine::Offset(float offset)
@ -25,14 +27,14 @@ 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);
X0 += offX;
Y0 += offY;
X1 += offX;
Y1 += offY;
maths::line_init(&Line, X0, Y0, X1, Y1);
}
double TLine::FindCollisionDistance(ray_type* ray)
{
return maths::ray_intersect_line(ray, &Line);
}
}

View File

@ -7,11 +7,18 @@ class TLine :
{
public:
line_type Line;
vector_type Start;
vector_type End;
float X0, Y0, X1, 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,
struct vector_type* end);
void Offset(float offset);
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 "TZmapList.h"
class TPinballTable;
class TPinballComponent
{
public:
TPinballComponent(class TPinballTable* table, int groupIndex, bool loadVisuals);
TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals);
virtual ~TPinballComponent();
virtual int Message(int message1, float message2);
virtual void put_scoring(int score1, int score2);

View File

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

View File

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

View File

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

View File

@ -123,8 +123,8 @@ float maths::ray_intersect_circle(ray_type* ray, circle_type* circle)
// 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;
float Lx = circle->Center.X - ray->Origin.X;
float Ly = circle->Center.Y - ray->Origin.Y;
// Tca, L dot D, projection of L on D
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)
{
line->Origin.X = v9;
line->Origin.Y = v11;
line->OriginX = v9;
line->OriginY = v11;
}
else
{
line->Origin.Y = v9;
line->Origin.X = v11;
line->OriginY = v9;
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)
/ 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;
line->Unknown10 = v4;
if (0.0 == line->Direction.X)
{
if (v4 >= line->Origin.X)
if (v4 >= line->OriginX)
{
v5 = v4 < line->Origin.Y;
v6 = v4 == line->Origin.Y;
v5 = v4 < line->OriginY;
v6 = v4 == line->OriginY;
if (v5 || v6)
return result;
return 1000000000.0;
}
}
else if (line->Origin.X <= line->Unknown9)
else if (line->OriginX <= line->CompTmp1)
{
v7 = line->Unknown9;
v5 = v7 < line->Origin.Y;
v6 = v7 == line->Origin.Y;
v7 = line->CompTmp1;
v5 = v7 < line->OriginY;
v6 = v7 == line->OriginY;
if (v5 || v6)
return result;
return 1000000000.0;
@ -245,3 +245,10 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
}
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 Y;
float Z;
};
@ -17,31 +18,26 @@ struct __declspec(align(4)) rectangle_type
struct circle_type
{
float X;
float Y;
float Unknown2;
vector_type Center;
float RadiusSq;
};
struct __declspec(align(4)) ray_type
{
vector_type Origin;
float Unknown2;
vector_type Direction;
float Unknown5;
float MaxDistance;
float Unknown7;
float MinDistance;
};
struct __declspec(align(4)) line_type
{
vector_type PerpendicularL;
float Unknown2;
vector_type Direction;
float Unknown5;
float PreComp1;
vector_type Origin;
float Unknown9;
float OriginX;
float OriginY;
float CompTmp1;
float Unknown10;
float Unknown11;
};
@ -57,4 +53,5 @@ public:
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);
static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec);
};