Renamed some collision variables.

This commit is contained in:
Muzychenko Andrey 2022-05-20 11:51:00 +03:00
parent 5461483bb5
commit 97aea20586
57 changed files with 162 additions and 173 deletions

View File

@ -19,7 +19,7 @@
gdrv_bitmap8* DebugOverlay::dbScreen = nullptr;
int SDL_RenderDrawCircle(SDL_Renderer* renderer, int x, int y, int radius)
static int SDL_RenderDrawCircle(SDL_Renderer* renderer, int x, int y, int radius)
{
int offsetx, offsety, d;
int status;
@ -184,7 +184,7 @@ void DebugOverlay::DrawBallInfo()
SDL_RenderDrawCircle(winmain::Renderer, pt1.X, pt1.Y, 10);
auto nextPos = ballPosition;
maths::vector_add(nextPos, maths::vector_mul(ball->Acceleration, ball->Speed / 10.0f));
maths::vector_add(nextPos, maths::vector_mul(ball->Direction, ball->Speed / 10.0f));
auto pt2 = proj::xform_to_2d(nextPos);
SDL_RenderDrawLine(winmain::Renderer, pt1.X, pt1.Y, pt2.X, pt2.Y);
}
@ -223,7 +223,7 @@ void DebugOverlay::DrawEdge(TEdgeSegment* edge)
break;
}
}
if (refBall != nullptr && (refBall->FieldFlag & edge->CollisionGroup) == 0)
if (refBall != nullptr && (refBall->CollisionMask & edge->CollisionGroup) == 0)
return;
}

View File

@ -21,13 +21,11 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
CollisionComp = nullptr;
EdgeCollisionCount = 0;
TimeDelta = 0.0;
FieldFlag = 1;
CollisionMask = 1;
CollisionFlag = 0;
Speed = 0.0;
Acceleration.Y = 0.0;
Acceleration.X = 0.0;
InvAcceleration.Y = 1000000000.0;
InvAcceleration.X = 1000000000.0;
Direction.Y = 0.0;
Direction.X = 0.0;
Position.X = 0.0;
Position.Y = 0.0;
@ -117,23 +115,23 @@ int TBall::Message(int code, float value)
Position.Y = 0.0;
ActiveFlag = 0;
CollisionFlag = 0;
FieldFlag = 1;
Acceleration.Y = 0.0;
CollisionMask = 1;
Direction.Y = 0.0;
Position.Z = Offset;
Acceleration.X = 0.0;
Direction.X = 0.0;
Speed = 0.0;
RayMaxDistance = 0.0;
}
return 0;
}
void TBall::throw_ball(TBall* ball, vector3* acceleration, float angleMult, float speedMult1, float speedMult2)
void TBall::throw_ball(TBall* ball, vector3* direction, float angleMult, float speedMult1, float speedMult2)
{
ball->CollisionComp = nullptr;
ball->Acceleration = *acceleration;
ball->Direction = *direction;
float rnd = RandFloat();
float angle = (1.0f - (rnd + rnd)) * angleMult;
maths::RotateVector(ball->Acceleration, angle);
maths::RotateVector(ball->Direction, angle);
rnd = RandFloat();
ball->Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1;
}

View File

@ -14,19 +14,18 @@ public :
bool already_hit(TEdgeSegment* edge);
int Message(int code, float value) override;
static void throw_ball(TBall* ball, vector3* acceleration, float angleMult, float speedMult1,
static void throw_ball(TBall* ball, vector3* direction, float angleMult, float speedMult1,
float speedMult2);
vector3 Position{};
vector3 Acceleration{};
vector3 Direction{};
float Speed;
float RayMaxDistance;
float TimeDelta;
float TimeNow;
vector2 InvAcceleration{};
vector2 RampFieldForce{};
TCollisionComponent* CollisionComp;
int FieldFlag;
int CollisionMask;
TEdgeSegment* Collisions[5]{};
int EdgeCollisionCount;
vector3 CollisionOffset{};

View File

@ -100,7 +100,7 @@ int TBumper::Message(int code, float value)
return 0;
}
void TBumper::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TBumper::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
if (DefaultCollision(ball, nextPosition, direction))
{

View File

@ -14,7 +14,7 @@ public:
TBumper(TPinballTable* table, int groupIndex);
~TBumper() override = default;
int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
void put_scoring(int index, int score) override;
int get_scoring(int index) override;

View File

@ -17,16 +17,16 @@ float TCircle::FindCollisionDistance(ray_type* ray)
return maths::ray_intersect_circle(*ray, Circle);
}
void TCircle::EdgeCollision(TBall* ball, float coef)
void TCircle::EdgeCollision(TBall* ball, float distance)
{
vector2 direction{}, nextPosition{};
nextPosition.X = coef * ball->Acceleration.X + ball->Position.X;
nextPosition.Y = coef * ball->Acceleration.Y + ball->Position.Y;
nextPosition.X = distance * ball->Direction.X + ball->Position.X;
nextPosition.Y = distance * ball->Direction.Y + ball->Position.Y;
direction.X = nextPosition.X - Circle.Center.X;
direction.Y = nextPosition.Y - Circle.Center.Y;
maths::normalize_2d(direction);
CollisionComponent->Collision(ball, &nextPosition, &direction, coef, this);
CollisionComponent->Collision(ball, &nextPosition, &direction, distance, this);
}
void TCircle::place_in_grid()

View File

@ -11,6 +11,6 @@ public:
TCircle(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, vector2* center,
float radius);
float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float coef) override;
void EdgeCollision(TBall* ball, float distance) override;
void place_in_grid() override;
};

View File

@ -74,7 +74,7 @@ int TCollisionComponent::DefaultCollision(TBall* ball, vector2* nextPosition, ve
}
void TCollisionComponent::Collision(TBall* ball, vector2* nextPosition, vector2* direction,
float coef, TEdgeSegment* edge)
float distance, TEdgeSegment* edge)
{
int soundIndex;

View File

@ -19,7 +19,7 @@ public:
TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall);
~TCollisionComponent() override;
void port_draw() override;
virtual void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
virtual void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge);
virtual int FieldEffect(TBall* ball, vector2* vecDst);
int DefaultCollision(TBall* ball, vector2* nextPosition, vector2* direction);

View File

@ -93,12 +93,12 @@ int TDemo::Message(int code, float value)
return 0;
}
void TDemo::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TDemo::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
ball->not_again(edge);
ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef;
ball->RayMaxDistance -= distance;
switch (reinterpret_cast<size_t>(edge->WallValue))
{

View File

@ -7,7 +7,7 @@ class TDemo :
public:
TDemo(TPinballTable* table, int groupIndex);
int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
static void PlungerRelease(int timerId, void* caller);

View File

@ -28,7 +28,7 @@ int TDrain::Message(int code, float value)
return 0;
}
void TDrain::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TDrain::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
ball->Message(1024, 0.0);
PinballTable->BallInSink = 1;

View File

@ -7,7 +7,7 @@ class TDrain :
public:
TDrain(TPinballTable* table, int groupIndex);
int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
static void TimerCallback(int timerId, void* caller);

View File

@ -74,7 +74,7 @@ int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeD
for (auto it = edgeBox->EdgeList.rbegin(); it != edgeBox->EdgeList.rend(); ++it)
{
auto edge = *it;
if (!edge->ProcessedFlag && *edge->ActiveFlag && (edge->CollisionGroup & ray->FieldFlag))
if (!edge->ProcessedFlag && *edge->ActiveFlag && (edge->CollisionGroup & ray->CollisionMask))
{
if (!ball->already_hit(edge))
{
@ -104,7 +104,7 @@ void TEdgeManager::FieldEffects(TBall* ball, vector2* dstVec)
for (auto it = edgeBox->FieldList.rbegin(); it != edgeBox->FieldList.rend(); ++it)
{
auto field = *it;
if (*field->Flag2Ptr && ball->FieldFlag & field->Mask)
if (*field->ActiveFlag && ball->CollisionMask & field->CollisionGroup)
{
if (field->CollisionComp->FieldEffect(ball, &vec))
{

View File

@ -6,8 +6,8 @@ class TEdgeBox;
struct field_effect_type
{
char* Flag2Ptr;
int Mask;
char* ActiveFlag;
int CollisionGroup;
TCollisionComponent* CollisionComp;
};

View File

@ -22,7 +22,7 @@ public:
TEdgeSegment(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup);
virtual ~TEdgeSegment() = default;
virtual void EdgeCollision(TBall* ball, float coef) = 0;
virtual void EdgeCollision(TBall* ball, float distance) = 0;
virtual void port_draw();
virtual void place_in_grid() = 0;
virtual float FindCollisionDistance(ray_type* ray) = 0;

View File

@ -72,12 +72,12 @@ int TFlagSpinner::Message(int code, float value)
return 0;
}
void TFlagSpinner::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void TFlagSpinner::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge)
{
ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance = ball->RayMaxDistance - coef;
ball->RayMaxDistance = ball->RayMaxDistance - distance;
ball->not_again(edge);
SpinDirection = 2 * (PrevCollider != edge) - 1;

View File

@ -7,7 +7,7 @@ class TFlagSpinner :
public:
TFlagSpinner(TPinballTable* table, int groupIndex);
int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
void put_scoring(int index, int score) override;
int get_scoring(int index) override;

View File

@ -128,7 +128,7 @@ void TFlipper::port_draw()
FlipperEdge->port_draw();
}
void TFlipper::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TFlipper::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
}

View File

@ -11,7 +11,7 @@ public:
~TFlipper() override;
int Message(int code, float value) override;
void port_draw() override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller);

View File

@ -298,7 +298,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
return 1e+09;
}
void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
void TFlipperEdge::EdgeCollision(TBall* ball, float distance)
{
EdgeCollisionFlag = 1;
if (!FlipperFlag || !CollisionFlag2 || CollisionFlag1)
@ -308,11 +308,11 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
{
float dx = NextBallPosition.X - RotOrigin.X;
float dy = NextBallPosition.Y - RotOrigin.Y;
float distance = dy * dy + dx * dx;
if (circlebase.RadiusSq * 1.01f < distance)
float distanceSq = dy * dy + dx * dx;
if (circlebase.RadiusSq * 1.01f < distanceSq)
{
float v11;
float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult);
float v20 = sqrt(distanceSq / DistanceDivSq) * (fabs(AngleMax) / AngleMult);
float dot1 = maths::DotProduct(CollisionLinePerp, CollisionDirection);
if (dot1 >= 0.0f)
v11 = dot1 * v20;
@ -337,9 +337,9 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
float elasticity;
float dx = NextBallPosition.X - RotOrigin.X;
float dy = NextBallPosition.Y - RotOrigin.Y;
float distance = dy * dy + dx * dx;
if (circlebase.RadiusSq * 1.01f < distance)
elasticity = (1.0f - sqrt(distance / DistanceDivSq)) * Elasticity;
float distanceSq = dy * dy + dx * dx;
if (circlebase.RadiusSq * 1.01f < distanceSq)
elasticity = (1.0f - sqrt(distanceSq / DistanceDivSq)) * Elasticity;
else
elasticity = Elasticity;
maths::basic_collision(ball, &NextBallPosition, &CollisionDirection, elasticity, Smoothness, 1000000000.0, 0.0);

View File

@ -12,7 +12,7 @@ public:
float elasticity, float smoothness);
void port_draw() override;
float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float coef) override;
void EdgeCollision(TBall* ball, float distance) override;
void place_in_grid() override;
void set_control_points(float timeNow);
void build_edges_in_motion();

View File

@ -40,20 +40,20 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
}
ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2];
FieldFlag = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304)));
CollisionMask = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304)));
/*Full tilt hack - FieldFlag should be on*/
// Full tilt hack - CollisionMask should be 1
if (pb::FullTiltMode)
FieldFlag = 1;
CollisionMask = 1;
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];
circle.RadiusSq = Circle.RadiusSq;
circle.Center.X = Circle.Center.X;
circle.Center.Y = Circle.Center.Y;
Field.Flag2Ptr = &ActiveFlag;
Field.ActiveFlag = &ActiveFlag;
Field.CollisionComp = this;
Field.Mask = visual.CollisionGroup;
Field.CollisionGroup = visual.CollisionGroup;
TTableLayer::edges_insert_circle(&circle, nullptr, &Field);
}
@ -69,7 +69,7 @@ int THole::Message(int code, float value)
return 0;
}
void THole::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void THole::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
if (!BallCapturedFlag)
{
@ -79,7 +79,7 @@ void THole::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
ball->CollisionComp = this;
ball->Position.X = Circle.Center.X;
ball->Position.Y = Circle.Center.Y;
ball->Acceleration.Z = 0.0;
ball->Direction.Z = 0.0;
// Ramp hole has no delay in FT.
auto captureTime = pb::FullTiltMode ? 0 : 0.5f;
@ -102,18 +102,18 @@ int THole::FieldEffect(TBall* ball, vector2* vecDst)
{
if (BallCapturedSecondStage)
{
ball->Acceleration.Z -= PinballTable->GravityDirVectMult * ball->TimeDelta * GravityMult;
ball->Position.Z += ball->Acceleration.Z;
ball->Direction.Z -= PinballTable->GravityDirVectMult * ball->TimeDelta * GravityMult;
ball->Position.Z += ball->Direction.Z;
if (ball->Position.Z <= ZSetValue)
{
BallCapturedFlag = 0;
BallCapturedSecondStage = 0;
ball->Position.Z = ZSetValue;
ball->Acceleration.Z = 0.0;
ball->FieldFlag = FieldFlag;
ball->Acceleration.Y = 0.0;
ball->Direction.Z = 0.0;
ball->CollisionMask = CollisionMask;
ball->Direction.Y = 0.0;
ball->CollisionComp = nullptr;
ball->Acceleration.X = 0.0;
ball->Direction.X = 0.0;
ball->Speed = 0.0;
loader::play_sound(SoftHitSoundId);
control::handler(58, this);
@ -128,8 +128,8 @@ int THole::FieldEffect(TBall* ball, vector2* vecDst)
if (direction.X * direction.X + direction.Y * direction.Y <= Circle.RadiusSq)
{
maths::normalize_2d(direction);
vecDst->X = direction.X * GravityPull - ball->Acceleration.X * ball->Speed;
vecDst->Y = direction.Y * GravityPull - ball->Acceleration.Y * ball->Speed;
vecDst->X = direction.X * GravityPull - ball->Direction.X * ball->Speed;
vecDst->Y = direction.Y * GravityPull - ball->Direction.Y * ball->Speed;
result = 1;
}
else

View File

@ -9,7 +9,7 @@ class THole :
public:
THole(TPinballTable* table, int groupIndex);
int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
int FieldEffect(TBall* ball, vector2* vecDst) override;
@ -22,7 +22,7 @@ public:
float Unknown4;
float GravityMult;
float ZSetValue;
int FieldFlag;
int CollisionMask;
float GravityPull;
circle_type Circle{};
field_effect_type Field{};

View File

@ -33,7 +33,7 @@ int TKickback::Message(int code, float value)
return 0;
}
void TKickback::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void TKickback::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge)
{
if (PinballTable->TiltLockFlag)

View File

@ -7,7 +7,7 @@ class TKickback :
public:
TKickback(TPinballTable* table, int groupIndex);
int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller);

View File

@ -47,16 +47,16 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis
auto zAttr = loader::query_float_attribute(groupIndex, 0, 408);
CollisionBallSetZ = pb::FullTiltMode && !pb::FullTiltDemoMode ? zAttr[3] : zAttr[2];
ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f;
BallAcceleration = visual.Kicker.ThrowBallAcceleration;
BallThrowDirection = visual.Kicker.ThrowBallDirection;
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
ThrowSpeedMult1 = visual.Kicker.Boost;
circle.RadiusSq = Circle.RadiusSq;
circle.Center.X = Circle.Center.X;
circle.Center.Y = Circle.Center.Y;
Field.Flag2Ptr = &ActiveFlag;
Field.ActiveFlag = &ActiveFlag;
Field.CollisionComp = this;
Field.Mask = visual.CollisionGroup;
Field.CollisionGroup = visual.CollisionGroup;
TTableLayer::edges_insert_circle(&circle, nullptr, &Field);
}
@ -104,7 +104,7 @@ int TKickout::get_scoring(int index)
return index < 5 ? Scores[index] : 0;
}
void TKickout::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TKickout::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
if (!KickFlag1)
{
@ -139,8 +139,8 @@ int TKickout::FieldEffect(TBall* ball, vector2* dstVec)
if (direction.Y * direction.Y + direction.X * direction.X > Circle.RadiusSq)
return 0;
maths::normalize_2d(direction);
dstVec->X = direction.X * FieldMult - ball->Acceleration.X * ball->Speed;
dstVec->Y = direction.Y * FieldMult - ball->Acceleration.Y * ball->Speed;
dstVec->X = direction.X * FieldMult - ball->Direction.X * ball->Speed;
dstVec->Y = direction.Y * FieldMult - ball->Direction.Y * ball->Speed;
return 1;
}
@ -154,7 +154,7 @@ void TKickout::TimerExpired(int timerId, void* caller)
if (kick->Ball)
{
kick->Ball->Position.Z = kick->OriginalBallZ;
TBall::throw_ball(kick->Ball, &kick->BallAcceleration, kick->ThrowAngleMult, kick->ThrowSpeedMult1,
TBall::throw_ball(kick->Ball, &kick->BallThrowDirection, kick->ThrowAngleMult, kick->ThrowSpeedMult1,
kick->ThrowSpeedMult2);
kick->ActiveFlag = 0;
kick->Ball = nullptr;

View File

@ -11,7 +11,7 @@ public:
int Message(int code, float value) override;
void put_scoring(int index, int score) override;
int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
int FieldEffect(TBall* ball, vector2* vecDst) override;
@ -28,7 +28,7 @@ public:
float FieldMult;
circle_type Circle{};
float OriginalBallZ{};
vector3 BallAcceleration{};
vector3 BallThrowDirection{};
float ThrowAngleMult;
float ThrowSpeedMult1;
float ThrowSpeedMult2;

View File

@ -34,12 +34,12 @@ int TLightRollover::Message(int code, float value)
return 0;
}
void TLightRollover::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void TLightRollover::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge)
{
ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef;
ball->RayMaxDistance -= distance;
ball->not_again(edge);
if (!PinballTable->TiltLockFlag)
{

View File

@ -8,7 +8,7 @@ public:
TLightRollover(TPinballTable* table, int groupIndex);
~TLightRollover() override = default;
int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
static void delay_expired(int timerId, void* caller);

View File

@ -41,13 +41,13 @@ float TLine::FindCollisionDistance(ray_type* ray)
return maths::ray_intersect_line(*ray, Line);
}
void TLine::EdgeCollision(TBall* ball, float coef)
void TLine::EdgeCollision(TBall* ball, float distance)
{
CollisionComponent->Collision(
ball,
&Line.RayIntersect,
&Line.PerpendicularC,
coef,
distance,
this);
}

View File

@ -12,6 +12,6 @@ public:
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, const vector2& start, const vector2& end);
void Offset(float offset);
float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float coef) override;
void EdgeCollision(TBall* ball, float distance) override;
void place_in_grid() override;
};

View File

@ -40,14 +40,14 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab
}
}
void TOneway::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TOneway::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
if (edge == Line)
{
ball->not_again(edge);
ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef;
ball->RayMaxDistance -= distance;
if (!PinballTable->TiltLockFlag)
{
if (HardHitSoundId)

View File

@ -8,7 +8,7 @@ class TOneway : public TCollisionComponent
public:
TOneway(TPinballTable* table, int groupIndex);
~TOneway() override = default;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
void put_scoring(int index, int score) override;
int get_scoring(int index) override;

View File

@ -33,12 +33,12 @@ TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(t
table->PlungerPositionY = floatArr[1];
}
void TPlunger::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TPlunger::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
if (PinballTable->TiltLockFlag)
Message(1017, 0.0);
coef = RandFloat() * Boost * 0.1f + Boost; // it is intended that the passed in coef is never used!
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, coef);
auto boost = RandFloat() * Boost * 0.1f + Boost;
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, boost);
}
int TPlunger::Message(int code, float value)

View File

@ -7,7 +7,7 @@ class TPlunger :
public:
TPlunger(TPinballTable* table, int groupIndex);
~TPlunger() override = default;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
int Message(int code, float value) override;

View File

@ -62,7 +62,7 @@ int TPopupTarget::get_scoring(int index)
return index < 3 ? Scores[index] : 0;
}
void TPopupTarget::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void TPopupTarget::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge)
{
if (this->PinballTable->TiltLockFlag)

View File

@ -9,7 +9,7 @@ public:
int Message(int code, float value) override;
void put_scoring(int index, int score) override;
int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller);

View File

@ -116,9 +116,9 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
PinballTable->GravityDirVectMult;
}
Field.Flag2Ptr = &ActiveFlag;
Field.ActiveFlag = &ActiveFlag;
Field.CollisionComp = this;
Field.Mask = visual.CollisionGroup;
Field.CollisionGroup = visual.CollisionGroup;
auto x1 = xMax;
auto y1 = yMax;
@ -138,12 +138,12 @@ int TRamp::get_scoring(int index)
return index < 4 ? Scores[index] : 0;
}
void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
ball->not_again(edge);
ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef;
ball->RayMaxDistance -= distance;
auto plane = static_cast<ramp_plane_type*>(edge->WallValue);
if (plane)
@ -156,7 +156,7 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
ball->RampFieldForce.Y = plane->FieldForce.Y;
ball->Position.Z = ball->Position.X * ball->CollisionOffset.X + ball->Position.Y * ball->CollisionOffset.Y +
ball->Offset + ball->CollisionOffset.Z;
ball->FieldFlag = CollisionGroup;
ball->CollisionMask = CollisionGroup;
return;
}
@ -173,13 +173,13 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
ball->CollisionFlag = 0;
if (edge == Line2)
{
ball->FieldFlag = Wall1CollisionGroup;
ball->CollisionMask = Wall1CollisionGroup;
if (BallZOffsetFlag)
ball->Position.Z = ball->Offset + Wall1BallOffset;
}
else
{
ball->FieldFlag = Wall2CollisionGroup;
ball->CollisionMask = Wall2CollisionGroup;
if (BallZOffsetFlag)
ball->Position.Z = ball->Offset + Wall2BallOffset;
}
@ -188,8 +188,8 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
int TRamp::FieldEffect(TBall* ball, vector2* vecDst)
{
vecDst->X = ball->RampFieldForce.X - ball->Acceleration.X * ball->Speed * BallFieldMult;
vecDst->Y = ball->RampFieldForce.Y - ball->Acceleration.Y * ball->Speed * BallFieldMult;
vecDst->X = ball->RampFieldForce.X - ball->Direction.X * ball->Speed * BallFieldMult;
vecDst->Y = ball->RampFieldForce.Y - ball->Direction.Y * ball->Speed * BallFieldMult;
return 1;
}

View File

@ -12,7 +12,7 @@ public:
TRamp(TPinballTable* table, int groupIndex);
void put_scoring(int index, int score) override;
int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
int FieldEffect(TBall* ball, vector2* vecDst) override;
void port_draw() override;

View File

@ -37,12 +37,12 @@ int TRollover::Message(int code, float value)
return 0;
}
void TRollover::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void TRollover::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge)
{
ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef;
ball->RayMaxDistance -= distance;
ball->not_again(edge);
gdrv_bitmap8* bmp = nullptr;
if (!PinballTable->TiltLockFlag)

View File

@ -10,7 +10,7 @@ public:
TRollover(TPinballTable* table, int groupIndex);
~TRollover() override = default;
int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
void put_scoring(int index, int score) override;
int get_scoring(int index) override;

View File

@ -16,7 +16,7 @@ TSink::TSink(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
MessageField = 0;
Timer = 0;
loader::query_visual(groupIndex, 0, &visual);
BallAcceleration = visual.Kicker.ThrowBallAcceleration;
BallThrowDirection = visual.Kicker.ThrowBallDirection;
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
ThrowSpeedMult1 = visual.Kicker.Boost;
ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f;
@ -75,7 +75,7 @@ int TSink::get_scoring(int index)
return index < 3 ? Scores[index] : 0;
}
void TSink::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TSink::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
Timer = 0;
if (PinballTable->TiltLockFlag)
@ -99,7 +99,7 @@ void TSink::TimerExpired(int timerId, void* caller)
ball->ActiveFlag = 1;
ball->Position.X = sink->BallPosition.X;
ball->Position.Y = sink->BallPosition.Y;
TBall::throw_ball(ball, &sink->BallAcceleration, sink->ThrowAngleMult, sink->ThrowSpeedMult1,
TBall::throw_ball(ball, &sink->BallThrowDirection, sink->ThrowAngleMult, sink->ThrowSpeedMult1,
sink->ThrowSpeedMult2);
if (sink->SoundIndex3)
loader::play_sound(sink->SoundIndex3);

View File

@ -10,7 +10,7 @@ public:
int Message(int code, float value) override;
void put_scoring(int index, int score) override;
int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller);
@ -18,7 +18,7 @@ public:
int Timer;
float TimerTime;
vector2 BallPosition{};
vector3 BallAcceleration{};
vector3 BallThrowDirection{};
float ThrowAngleMult;
float ThrowSpeedMult1;
float ThrowSpeedMult2;

View File

@ -64,7 +64,7 @@ int TSoloTarget::get_scoring(int index)
return index < 1 ? Scores[index] : 0;
}
void TSoloTarget::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void TSoloTarget::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge)
{
if (DefaultCollision(ball, nextPosition, direction))

View File

@ -9,7 +9,7 @@ public:
int Message(int code, float value) override;
void put_scoring(int index, int score) override;
int get_scoring(int index) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
static void TimerExpired(int timerId, void* caller);

View File

@ -98,8 +98,8 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
visArrPtr += 2;
}
Field.Mask = -1;
Field.Flag2Ptr = &ActiveFlag;
Field.CollisionGroup = -1;
Field.ActiveFlag = &ActiveFlag;
Field.CollisionComp = this;
edges_insert_square(Unknown2F, Unknown1F, Unknown4F, Unknown3F, nullptr,
&Field);
@ -113,9 +113,9 @@ TTableLayer::~TTableLayer()
int TTableLayer::FieldEffect(TBall* ball, vector2* vecDst)
{
vecDst->X = GraityDirX - (0.5f - RandFloat() + ball->Acceleration.X) *
vecDst->X = GraityDirX - (0.5f - RandFloat() + ball->Direction.X) *
ball->Speed * GraityMult;
vecDst->Y = GraityDirY - ball->Acceleration.Y * ball->Speed * GraityMult;
vecDst->Y = GraityDirY - ball->Direction.Y * ball->Speed * GraityMult;
return 1;
}

View File

@ -10,12 +10,12 @@ TTripwire::TTripwire(TPinballTable* table, int groupIndex) : TRollover(table, gr
{
}
void TTripwire::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void TTripwire::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge)
{
ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y;
ball->RayMaxDistance -= coef;
ball->RayMaxDistance -= distance;
ball->not_again(edge);
if (!PinballTable->TiltLockFlag)
{

View File

@ -7,6 +7,6 @@ class TTripwire :
public:
TTripwire(TPinballTable* table, int groupIndex);
~TTripwire() override = default;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
};

View File

@ -24,7 +24,7 @@ int TWall::Message(int code, float value)
return 0;
}
void TWall::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef, TEdgeSegment* edge)
void TWall::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
{
if (DefaultCollision(ball, nextPosition, direction))
{

View File

@ -10,7 +10,7 @@ class TWall :
public:
TWall(TPinballTable* table, int groupIndex);
int Message(int code, float value) override;
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float coef,
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge) override;
void put_scoring(int index, int score) override;
int get_scoring(int index) override;

View File

@ -390,7 +390,7 @@ int loader::kicker(int groupIndex, visualKickerStruct* kicker)
kicker->ThrowBallMult = *floatArr;
break;
case 404:
kicker->ThrowBallAcceleration = *reinterpret_cast<vector3*>(floatArr);
kicker->ThrowBallDirection = *reinterpret_cast<vector3*>(floatArr);
floatArr += 3;
index += 4;
break;

View File

@ -25,7 +25,7 @@ struct visualKickerStruct
float Threshold;
float Boost;
float ThrowBallMult;
vector3 ThrowBallAcceleration;
vector3 ThrowBallDirection;
float ThrowBallAngleMult;
int HardHitSoundId;
};

View File

@ -231,30 +231,35 @@ float maths::basic_collision(TBall* ball, vector2* nextPosition, vector2* direct
ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y;
auto proj = -DotProduct(*direction, ball->Acceleration);
if (proj < 0)
// Project ball direction on collision rebound direction
auto reboundProj = -DotProduct(*direction, ball->Direction);
if (reboundProj < 0)
{
proj = -proj;
// Negative projection means no rebound, both direction vectors point the same way.
reboundProj = -reboundProj;
}
else
{
float dx1 = proj * direction->X;
float dy1 = proj * direction->Y;
ball->Acceleration.X = (dx1 + ball->Acceleration.X) * smoothness + dx1 * elasticity;
ball->Acceleration.Y = (dy1 + ball->Acceleration.Y) * smoothness + dy1 * elasticity;
normalize_2d(ball->Acceleration);
// Apply rebound to ball direction
float dx1 = reboundProj * direction->X;
float dy1 = reboundProj * direction->Y;
ball->Direction.X = (dx1 + ball->Direction.X) * smoothness + dx1 * elasticity;
ball->Direction.Y = (dy1 + ball->Direction.Y) * smoothness + dy1 * elasticity;
normalize_2d(ball->Direction);
}
float projSpeed = proj * ball->Speed;
float newSpeed = ball->Speed - (1.0f - elasticity) * projSpeed;
ball->Speed = newSpeed;
if (projSpeed >= threshold)
// Apply rebound to ball speed
float reboundSpeed = reboundProj * ball->Speed;
ball->Speed -= (1.0f - elasticity) * reboundSpeed;
if (reboundSpeed >= threshold)
{
ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * boost;
ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * boost;
ball->Speed = normalize_2d(ball->Acceleration);
// Change ball direction if rebound speed is above threshold
ball->Direction.X = ball->Speed * ball->Direction.X + direction->X * boost;
ball->Direction.Y = ball->Speed * ball->Direction.Y + direction->Y * boost;
ball->Speed = normalize_2d(ball->Direction);
}
return projSpeed;
return reboundSpeed;
}
float maths::Distance_Squared(const vector2& vec1, const vector2& vec2)

View File

@ -53,7 +53,7 @@ struct ray_type
float MinDistance;
float TimeNow;
float TimeDelta;
int FieldFlag;
int CollisionMask;
};
struct line_type

View File

@ -65,7 +65,6 @@ void nudge::nudge_up()
void nudge::_nudge(float xDiff, float yDiff)
{
vector2 accelMod;
float invAccelX, invAccelY;
accelMod.X = xDiff * 0.5f;
accelMod.Y = yDiff * 0.5f;
@ -73,20 +72,10 @@ void nudge::_nudge(float xDiff, float yDiff)
{
if (ball->ActiveFlag && !ball->CollisionComp)
{
ball->Acceleration.X = ball->Acceleration.X * ball->Speed;
ball->Acceleration.Y = ball->Acceleration.Y * ball->Speed;
maths::vector_add(ball->Acceleration, accelMod);
ball->Speed = maths::normalize_2d(ball->Acceleration);
if (ball->Acceleration.X == 0.0f)
invAccelX = 1000000000.0;
else
invAccelX = 1.0f / ball->Acceleration.X;
ball->InvAcceleration.X = invAccelX;
if (ball->Acceleration.Y == 0.0f)
invAccelY = 1000000000.0;
else
invAccelY = 1.0f / ball->Acceleration.Y;
ball->InvAcceleration.Y = invAccelY;
ball->Direction.X = ball->Direction.X * ball->Speed;
ball->Direction.Y = ball->Direction.Y * ball->Speed;
maths::vector_add(ball->Direction, accelMod);
ball->Speed = maths::normalize_2d(ball->Direction);
}
}

View File

@ -241,9 +241,9 @@ void pb::ballset(float dx, float dy)
// dx and dy are normalized to window, ideally in [-1, 1]
static constexpr float sensitivity = 7000;
TBall* ball = MainTable->BallList.at(0);
ball->Acceleration.X = dx * sensitivity;
ball->Acceleration.Y = dy * sensitivity;
ball->Speed = maths::normalize_2d(ball->Acceleration);
ball->Direction.X = dx * sensitivity;
ball->Direction.Y = dy * sensitivity;
ball->Speed = maths::normalize_2d(ball->Direction);
}
void pb::frame(float dtMilliSec)
@ -311,12 +311,10 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
TTableLayer::edge_manager->FieldEffects(ball, &vec2);
vec2.X = vec2.X * timeDelta;
vec2.Y = vec2.Y * timeDelta;
ball->Acceleration.X = ball->Speed * ball->Acceleration.X;
ball->Acceleration.Y = ball->Speed * ball->Acceleration.Y;
maths::vector_add(ball->Acceleration, vec2);
ball->Speed = maths::normalize_2d(ball->Acceleration);
ball->InvAcceleration.X = ball->Acceleration.X == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.X;
ball->InvAcceleration.Y = ball->Acceleration.Y == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.Y;
ball->Direction.X = ball->Speed * ball->Direction.X;
ball->Direction.Y = ball->Speed * ball->Direction.Y;
maths::vector_add(ball->Direction, vec2);
ball->Speed = maths::normalize_2d(ball->Direction);
}
auto timeDelta2 = timeDelta;
@ -489,9 +487,9 @@ void pb::InputDown(GameInput input)
ball->Position.X = 1.0;
ball->Position.Z = ball->Offset;
ball->Position.Y = 1.0;
ball->Acceleration.Z = 0.0;
ball->Acceleration.Y = 0.0;
ball->Acceleration.X = 0.0;
ball->Direction.Z = 0.0;
ball->Direction.Y = 0.0;
ball->Direction.X = 0.0;
break;
case 'h':
{
@ -607,9 +605,9 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball)
ball->TimeNow = timeNow;
ray.Origin = ball->Position;
ray.Direction = ball->Acceleration;
ray.Direction = ball->Direction;
ray.MaxDistance = maxDistance;
ray.FieldFlag = ball->FieldFlag;
ray.CollisionMask = ball->CollisionMask;
ray.TimeNow = timeNow;
ray.TimeDelta = timeDelta;
ray.MinDistance = 0.0020000001f;
@ -621,8 +619,8 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball)
{
maxDistance = timeDelta * ball->Speed;
ball->RayMaxDistance = maxDistance;
positionMod.X = maxDistance * ball->Acceleration.X;
positionMod.Y = maxDistance * ball->Acceleration.Y;
positionMod.X = maxDistance * ball->Direction.X;
positionMod.Y = maxDistance * ball->Direction.Y;
maths::vector_add(ball->Position, positionMod);
}
else