mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2023-12-30 21:52:56 +00:00
Cleaning up maths: part 3.
Demangled methods, vectors args by ref, added comments, more accurate ray_intersect_line.
This commit is contained in:
parent
2d0da712e3
commit
fdf1f6c9f1
@ -10,4 +10,7 @@
|
|||||||
<Item Name="[Color]" ExcludeView="simple">Color</Item>
|
<Item Name="[Color]" ExcludeView="simple">Color</Item>
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
|
<Type Name="vector3">
|
||||||
|
<DisplayString>{{ X={X} Y={Y} Z={Z} }}</DisplayString>
|
||||||
|
</Type>
|
||||||
</AutoVisualizer>
|
</AutoVisualizer>
|
@ -135,7 +135,7 @@ void TBall::throw_ball(TBall* ball, vector3* acceleration, float angleMult, floa
|
|||||||
ball->Acceleration = *acceleration;
|
ball->Acceleration = *acceleration;
|
||||||
float rnd = RandFloat();
|
float rnd = RandFloat();
|
||||||
float angle = (1.0f - (rnd + rnd)) * angleMult;
|
float angle = (1.0f - (rnd + rnd)) * angleMult;
|
||||||
maths::RotateVector(&ball->Acceleration, angle);
|
maths::RotateVector(ball->Acceleration, angle);
|
||||||
rnd = RandFloat();
|
rnd = RandFloat();
|
||||||
ball->Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1;
|
ball->Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ TCircle::TCircle(TCollisionComponent* collComp, char* activeFlag, unsigned colli
|
|||||||
|
|
||||||
float TCircle::FindCollisionDistance(ray_type* ray)
|
float TCircle::FindCollisionDistance(ray_type* ray)
|
||||||
{
|
{
|
||||||
return maths::ray_intersect_circle(ray, &Circle);
|
return maths::ray_intersect_circle(*ray, Circle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCircle::EdgeCollision(TBall* ball, float coef)
|
void TCircle::EdgeCollision(TBall* ball, float coef)
|
||||||
@ -25,7 +25,7 @@ void TCircle::EdgeCollision(TBall* ball, float coef)
|
|||||||
nextPosition.Y = coef * ball->Acceleration.Y + ball->Position.Y;
|
nextPosition.Y = coef * ball->Acceleration.Y + ball->Position.Y;
|
||||||
direction.X = nextPosition.X - Circle.Center.X;
|
direction.X = nextPosition.X - Circle.Center.X;
|
||||||
direction.Y = nextPosition.Y - Circle.Center.Y;
|
direction.Y = nextPosition.Y - Circle.Center.Y;
|
||||||
maths::normalize_2d(&direction);
|
maths::normalize_2d(direction);
|
||||||
CollisionComponent->Collision(ball, &nextPosition, &direction, coef, this);
|
CollisionComponent->Collision(ball, &nextPosition, &direction, coef, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ void TEdgeManager::FieldEffects(TBall* ball, vector2* dstVec)
|
|||||||
{
|
{
|
||||||
if (field->CollisionComp->FieldEffect(ball, &vec))
|
if (field->CollisionComp->FieldEffect(ball, &vec))
|
||||||
{
|
{
|
||||||
maths::vector_add(dstVec, &vec);
|
maths::vector_add(*dstVec, vec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
|
|||||||
start.Y = floatArr[2];
|
start.Y = floatArr[2];
|
||||||
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);
|
||||||
edge = line;
|
edge = line;
|
||||||
|
|
||||||
if (line)
|
if (line)
|
||||||
@ -93,7 +93,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
|
|||||||
vec1.Y = center.Y - prevCenter.Y;
|
vec1.Y = center.Y - prevCenter.Y;
|
||||||
vec2.X = centerX2 - centerX1;
|
vec2.X = centerX2 - centerX1;
|
||||||
vec2.Y = centerY2 - center.Y;
|
vec2.Y = centerY2 - center.Y;
|
||||||
maths::cross(&vec1, &vec2, &dstVec);
|
maths::cross(vec1, vec2, dstVec);
|
||||||
if ((dstVec.Z > 0.0f && offset > 0.0f) ||
|
if ((dstVec.Z > 0.0f && offset > 0.0f) ||
|
||||||
(dstVec.Z < 0.0f && offset < 0.0f))
|
(dstVec.Z < 0.0f && offset < 0.0f))
|
||||||
{
|
{
|
||||||
@ -113,7 +113,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
|
|||||||
start.Y = floatArrPtr[1];
|
start.Y = floatArrPtr[1];
|
||||||
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);
|
||||||
edge = line;
|
edge = line;
|
||||||
|
|
||||||
if (line)
|
if (line)
|
||||||
|
@ -21,14 +21,14 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom
|
|||||||
end.Y = visual.FloatArr[1];
|
end.Y = visual.FloatArr[1];
|
||||||
start.X = visual.FloatArr[2];
|
start.X = visual.FloatArr[2];
|
||||||
start.Y = visual.FloatArr[3];
|
start.Y = visual.FloatArr[3];
|
||||||
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();
|
||||||
EdgeList.push_back(line);
|
EdgeList.push_back(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
line = new TLine(this, &ActiveFlag, visual.CollisionGroup, &end, &start);
|
line = new TLine(this, &ActiveFlag, visual.CollisionGroup, end, start);
|
||||||
PrevCollider = line;
|
PrevCollider = line;
|
||||||
if (line)
|
if (line)
|
||||||
{
|
{
|
||||||
|
@ -23,8 +23,8 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||||||
RetractTime = retractTime;
|
RetractTime = retractTime;
|
||||||
CollisionMult = collMult;
|
CollisionMult = collMult;
|
||||||
|
|
||||||
T1Src = *vecT1;
|
T1Src = static_cast<vector2>(*vecT1);
|
||||||
T2Src = *vecT2;
|
T2Src = static_cast<vector2>(*vecT2);
|
||||||
RotOrigin.X = origin->X;
|
RotOrigin.X = origin->X;
|
||||||
RotOrigin.Y = origin->Y;
|
RotOrigin.Y = origin->Y;
|
||||||
|
|
||||||
@ -39,15 +39,15 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||||||
vecDir1.X = vecT1->X - origin->X;
|
vecDir1.X = vecT1->X - origin->X;
|
||||||
vecDir1.Y = vecT1->Y - origin->Y;
|
vecDir1.Y = vecT1->Y - origin->Y;
|
||||||
vecDir1.Z = 0.0;
|
vecDir1.Z = 0.0;
|
||||||
maths::normalize_2d(&vecDir1);
|
maths::normalize_2d(vecDir1);
|
||||||
|
|
||||||
vecDir2.X = vecT2->X - origin->X;
|
vecDir2.X = vecT2->X - origin->X;
|
||||||
vecDir2.Y = vecT2->Y - origin->Y;
|
vecDir2.Y = vecT2->Y - origin->Y;
|
||||||
vecDir2.Z = 0.0;
|
vecDir2.Z = 0.0;
|
||||||
maths::normalize_2d(&vecDir2);
|
maths::normalize_2d(vecDir2);
|
||||||
|
|
||||||
AngleMax = acos(maths::DotProduct(&vecDir1, &vecDir2));
|
AngleMax = acos(maths::DotProduct(vecDir1, vecDir2));
|
||||||
maths::cross(&vecDir1, &vecDir2, &crossProd);
|
maths::cross(vecDir1, vecDir2, crossProd);
|
||||||
if (crossProd.Z < 0.0f)
|
if (crossProd.Z < 0.0f)
|
||||||
AngleMax = -AngleMax;
|
AngleMax = -AngleMax;
|
||||||
FlipperFlag = 0;
|
FlipperFlag = 0;
|
||||||
@ -69,8 +69,8 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||||||
|
|
||||||
if (AngleMax < 0.0f)
|
if (AngleMax < 0.0f)
|
||||||
{
|
{
|
||||||
maths::vswap(&A1Src, &B1Src);
|
std::swap(A1Src, B1Src);
|
||||||
maths::vswap(&A2Src, &B2Src);
|
std::swap(A2Src, B2Src);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dx = vecT1->X - RotOrigin.X;
|
auto dx = vecT1->X - RotOrigin.X;
|
||||||
@ -79,7 +79,7 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||||||
DistanceDivSq = distance1 * distance1;
|
DistanceDivSq = distance1 * distance1;
|
||||||
|
|
||||||
float minMoveTime = std::min(ExtendTime, RetractTime);
|
float minMoveTime = std::min(ExtendTime, RetractTime);
|
||||||
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();
|
TFlipperEdge::place_in_grid();
|
||||||
@ -139,12 +139,12 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
{
|
{
|
||||||
if (maths::Distance_Squared(ogRay->Origin, T1) >= CircleT1RadiusMSq)
|
if (maths::Distance_Squared(ogRay->Origin, T1) >= CircleT1RadiusMSq)
|
||||||
{
|
{
|
||||||
srcRay.Direction.Y = lineB.PerpendicularL.Y;
|
srcRay.Direction.Y = lineB.PerpendicularC.Y;
|
||||||
srcRay.Direction.X = lineB.PerpendicularL.X;
|
srcRay.Direction.X = lineB.PerpendicularC.X;
|
||||||
if (ballInside == 4)
|
if (ballInside == 4)
|
||||||
{
|
{
|
||||||
srcRay.Direction.Y = lineA.PerpendicularL.Y;
|
srcRay.Direction.Y = lineA.PerpendicularC.Y;
|
||||||
srcRay.Direction.X = lineA.PerpendicularL.X;
|
srcRay.Direction.X = lineA.PerpendicularC.X;
|
||||||
}
|
}
|
||||||
srcRay.Direction.X = -srcRay.Direction.X;
|
srcRay.Direction.X = -srcRay.Direction.X;
|
||||||
srcRay.Direction.Y = -srcRay.Direction.Y;
|
srcRay.Direction.Y = -srcRay.Direction.Y;
|
||||||
@ -153,14 +153,14 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
{
|
{
|
||||||
srcRay.Direction.X = T1.X - ogRay->Origin.X;
|
srcRay.Direction.X = T1.X - ogRay->Origin.X;
|
||||||
srcRay.Direction.Y = T1.Y - ogRay->Origin.Y;
|
srcRay.Direction.Y = T1.Y - ogRay->Origin.Y;
|
||||||
maths::normalize_2d(&srcRay.Direction);
|
maths::normalize_2d(srcRay.Direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X;
|
srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X;
|
||||||
srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y;
|
srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y;
|
||||||
maths::normalize_2d(&srcRay.Direction);
|
maths::normalize_2d(srcRay.Direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||||
@ -170,7 +170,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
{
|
{
|
||||||
srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X;
|
srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X;
|
||||||
srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y;
|
srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y;
|
||||||
maths::normalize_2d(&srcRay.Direction);
|
maths::normalize_2d(srcRay.Direction);
|
||||||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
||||||
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09f)
|
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09f)
|
||||||
@ -203,9 +203,9 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
vector2* linePtr;
|
vector2* linePtr;
|
||||||
if (FlipperFlag == 1 && ballInside != 5)
|
if (FlipperFlag == 1 && ballInside != 5)
|
||||||
{
|
{
|
||||||
linePtr = &lineA.PerpendicularL;
|
linePtr = &lineA.PerpendicularC;
|
||||||
srcRay.Direction.Y = lineA.PerpendicularL.Y;
|
srcRay.Direction.Y = lineA.PerpendicularC.Y;
|
||||||
srcRay.Direction.X = lineA.PerpendicularL.X;
|
srcRay.Direction.X = lineA.PerpendicularC.X;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -215,7 +215,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
CollisionFlag2 = 1;
|
CollisionFlag2 = 1;
|
||||||
srcRay.Direction.X = RotOrigin.X - posX;
|
srcRay.Direction.X = RotOrigin.X - posX;
|
||||||
srcRay.Direction.Y = RotOrigin.Y - posY;
|
srcRay.Direction.Y = RotOrigin.Y - posY;
|
||||||
maths::normalize_2d(&srcRay.Direction);
|
maths::normalize_2d(srcRay.Direction);
|
||||||
|
|
||||||
srcRay.Origin.X = posX - srcRay.Direction.X * 5.0f;
|
srcRay.Origin.X = posX - srcRay.Direction.X * 5.0f;
|
||||||
srcRay.Origin.Y = posY - srcRay.Direction.Y * 5.0f;
|
srcRay.Origin.Y = posY - srcRay.Direction.Y * 5.0f;
|
||||||
@ -235,9 +235,9 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
NextBallPosition.Y -= srcRay.Direction.Y * 1e-05f;
|
NextBallPosition.Y -= srcRay.Direction.Y * 1e-05f;
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
linePtr = &lineB.PerpendicularL;
|
linePtr = &lineB.PerpendicularC;
|
||||||
srcRay.Direction.Y = lineB.PerpendicularL.Y;
|
srcRay.Direction.Y = lineB.PerpendicularC.Y;
|
||||||
srcRay.Direction.X = lineB.PerpendicularL.X;
|
srcRay.Direction.X = lineB.PerpendicularC.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollisionLinePerp = *linePtr;
|
CollisionLinePerp = *linePtr;
|
||||||
@ -274,13 +274,13 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
vector2* linePtr;
|
vector2* linePtr;
|
||||||
if (FlipperFlag == 2)
|
if (FlipperFlag == 2)
|
||||||
{
|
{
|
||||||
linePtr = &lineB.PerpendicularL;
|
linePtr = &lineB.PerpendicularC;
|
||||||
CollisionFlag1 = AngleMax <= 0.0f;
|
CollisionFlag1 = AngleMax <= 0.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CollisionFlag1 = AngleMax > 0.0f;
|
CollisionFlag1 = AngleMax > 0.0f;
|
||||||
linePtr = &lineA.PerpendicularL;
|
linePtr = &lineA.PerpendicularC;
|
||||||
}
|
}
|
||||||
CollisionLinePerp = *linePtr;
|
CollisionLinePerp = *linePtr;
|
||||||
CollisionDirection = dstRay.Direction;
|
CollisionDirection = dstRay.Direction;
|
||||||
@ -313,7 +313,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
|
|||||||
{
|
{
|
||||||
float v11;
|
float v11;
|
||||||
float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult);
|
float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult);
|
||||||
float dot1 = maths::DotProduct(&CollisionLinePerp, &CollisionDirection);
|
float dot1 = maths::DotProduct(CollisionLinePerp, CollisionDirection);
|
||||||
if (dot1 >= 0.0f)
|
if (dot1 >= 0.0f)
|
||||||
v11 = dot1 * v20;
|
v11 = dot1 * v20;
|
||||||
else
|
else
|
||||||
@ -395,11 +395,11 @@ void TFlipperEdge::set_control_points(float timeNow)
|
|||||||
B1 = B1Src;
|
B1 = B1Src;
|
||||||
B2 = B2Src;
|
B2 = B2Src;
|
||||||
T1 = T1Src;
|
T1 = T1Src;
|
||||||
maths::RotatePt(&A1, flipper_sin_angle, flipper_cos_angle, &RotOrigin);
|
maths::RotatePt(A1, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||||
maths::RotatePt(&A2, flipper_sin_angle, flipper_cos_angle, &RotOrigin);
|
maths::RotatePt(A2, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||||
maths::RotatePt(&T1, flipper_sin_angle, flipper_cos_angle, &RotOrigin);
|
maths::RotatePt(T1, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||||
maths::RotatePt(&B1, flipper_sin_angle, flipper_cos_angle, &RotOrigin);
|
maths::RotatePt(B1, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||||
maths::RotatePt(&B2, flipper_sin_angle, flipper_cos_angle, &RotOrigin);
|
maths::RotatePt(B2, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TFlipperEdge::build_edges_in_motion()
|
void TFlipperEdge::build_edges_in_motion()
|
||||||
|
@ -127,7 +127,7 @@ int THole::FieldEffect(TBall* ball, vector2* vecDst)
|
|||||||
direction.Y = Circle.Center.Y - ball->Position.Y;
|
direction.Y = Circle.Center.Y - ball->Position.Y;
|
||||||
if (direction.X * direction.X + direction.Y * direction.Y <= Circle.RadiusSq)
|
if (direction.X * direction.X + direction.Y * direction.Y <= Circle.RadiusSq)
|
||||||
{
|
{
|
||||||
maths::normalize_2d(&direction);
|
maths::normalize_2d(direction);
|
||||||
vecDst->X = direction.X * GravityPull - ball->Acceleration.X * ball->Speed;
|
vecDst->X = direction.X * GravityPull - ball->Acceleration.X * ball->Speed;
|
||||||
vecDst->Y = direction.Y * GravityPull - ball->Acceleration.Y * ball->Speed;
|
vecDst->Y = direction.Y * GravityPull - ball->Acceleration.Y * ball->Speed;
|
||||||
result = 1;
|
result = 1;
|
||||||
|
@ -138,7 +138,7 @@ int TKickout::FieldEffect(TBall* ball, vector2* dstVec)
|
|||||||
direction.Y = Circle.Center.Y - ball->Position.Y;
|
direction.Y = Circle.Center.Y - ball->Position.Y;
|
||||||
if (direction.Y * direction.Y + direction.X * direction.X > Circle.RadiusSq)
|
if (direction.Y * direction.Y + direction.X * direction.X > Circle.RadiusSq)
|
||||||
return 0;
|
return 0;
|
||||||
maths::normalize_2d(&direction);
|
maths::normalize_2d(direction);
|
||||||
dstVec->X = direction.X * FieldMult - ball->Acceleration.X * ball->Speed;
|
dstVec->X = direction.X * FieldMult - ball->Acceleration.X * ball->Speed;
|
||||||
dstVec->Y = direction.Y * FieldMult - ball->Acceleration.Y * ball->Speed;
|
dstVec->Y = direction.Y * FieldMult - ball->Acceleration.Y * ball->Speed;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -14,20 +14,20 @@ TLine::TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collis
|
|||||||
maths::line_init(&Line, x0, y0, x1, y1);
|
maths::line_init(&Line, x0, y0, x1, y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TLine::TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, struct vector2* start,
|
TLine::TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, const vector2& start,
|
||||||
struct vector2* end) : TEdgeSegment(collCmp, activeFlag, collisionGroup)
|
const vector2& end) : TEdgeSegment(collCmp, activeFlag, collisionGroup)
|
||||||
{
|
{
|
||||||
X0 = start->X;
|
X0 = start.X;
|
||||||
Y0 = start->Y;
|
Y0 = start.Y;
|
||||||
X1 = end->X;
|
X1 = end.X;
|
||||||
Y1 = end->Y;
|
Y1 = end.Y;
|
||||||
maths::line_init(&Line, X0, Y0, X1, Y1);
|
maths::line_init(&Line, X0, Y0, X1, Y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLine::Offset(float offset)
|
void TLine::Offset(float offset)
|
||||||
{
|
{
|
||||||
float offX = offset * Line.PerpendicularL.X;
|
float offX = offset * Line.PerpendicularC.X;
|
||||||
float offY = offset * Line.PerpendicularL.Y;
|
float offY = offset * Line.PerpendicularC.Y;
|
||||||
|
|
||||||
X0 += offX;
|
X0 += offX;
|
||||||
Y0 += offY;
|
Y0 += offY;
|
||||||
@ -46,7 +46,7 @@ void TLine::EdgeCollision(TBall* ball, float coef)
|
|||||||
CollisionComponent->Collision(
|
CollisionComponent->Collision(
|
||||||
ball,
|
ball,
|
||||||
&Line.RayIntersect,
|
&Line.RayIntersect,
|
||||||
&Line.PerpendicularL,
|
&Line.PerpendicularC,
|
||||||
coef,
|
coef,
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ public:
|
|||||||
line_type Line{};
|
line_type Line{};
|
||||||
float X0, Y0, X1, Y1;
|
float X0, Y0, X1, Y1;
|
||||||
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, float x0, float y0, float x1, float y1);
|
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, float x0, float y0, float x1, float y1);
|
||||||
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, vector2* start, vector2* end);
|
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, const vector2& start, const vector2& end);
|
||||||
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 coef) override;
|
void EdgeCollision(TBall* ball, float coef) override;
|
||||||
|
@ -21,7 +21,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab
|
|||||||
linePt1.X = visual.FloatArr[2];
|
linePt1.X = visual.FloatArr[2];
|
||||||
linePt1.Y = visual.FloatArr[3];
|
linePt1.Y = visual.FloatArr[3];
|
||||||
|
|
||||||
auto line = new TLine(this, &ActiveFlag, visual.CollisionGroup, &linePt2, &linePt1);
|
auto line = new TLine(this, &ActiveFlag, visual.CollisionGroup, linePt2, linePt1);
|
||||||
if (line)
|
if (line)
|
||||||
{
|
{
|
||||||
line->Offset(table->CollisionCompOffset);
|
line->Offset(table->CollisionCompOffset);
|
||||||
@ -29,7 +29,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab
|
|||||||
EdgeList.push_back(line);
|
EdgeList.push_back(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
line = new TLine(this, &ActiveFlag, visual.CollisionGroup, &linePt1, &linePt2);
|
line = new TLine(this, &ActiveFlag, visual.CollisionGroup, linePt1, linePt2);
|
||||||
Line = line;
|
Line = line;
|
||||||
if (line)
|
if (line)
|
||||||
{
|
{
|
||||||
|
@ -59,7 +59,7 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
|||||||
tmpRect.YPosition = bmp->YPosition - table->YOffset;
|
tmpRect.YPosition = bmp->YPosition - table->YOffset;
|
||||||
tmpRect.Width = bmp->Width;
|
tmpRect.Width = bmp->Width;
|
||||||
tmpRect.Height = bmp->Height;
|
tmpRect.Height = bmp->Height;
|
||||||
maths::enclosing_box(&bmp1Rect, &tmpRect, &bmp1Rect);
|
maths::enclosing_box(bmp1Rect, tmpRect, bmp1Rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderSprite = render::create_sprite(
|
RenderSprite = render::create_sprite(
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||||
{
|
{
|
||||||
visualStruct visual{};
|
visualStruct visual{};
|
||||||
vector2 end{}, start{}, *end2, *start2, *start3, *end3;
|
vector2 end{}, start{}, end2{}, start2{}, start3{}, end3{};
|
||||||
|
|
||||||
MessageField = 0;
|
MessageField = 0;
|
||||||
UnusedBaseFlag = 1;
|
UnusedBaseFlag = 1;
|
||||||
@ -33,7 +33,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||||||
end.Y = floatArr4[3];
|
end.Y = floatArr4[3];
|
||||||
start.X = floatArr4[4];
|
start.X = floatArr4[4];
|
||||||
start.Y = floatArr4[5];
|
start.Y = floatArr4[5];
|
||||||
Line1 = new TLine(this, &ActiveFlag, 1 << static_cast<int>(floor(floatArr4[0])), &start, &end);
|
Line1 = new TLine(this, &ActiveFlag, 1 << static_cast<int>(floor(floatArr4[0])), start, end);
|
||||||
EdgeList.push_back(Line1);
|
EdgeList.push_back(Line1);
|
||||||
if (Line1)
|
if (Line1)
|
||||||
{
|
{
|
||||||
@ -49,8 +49,8 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||||||
RampPlane,
|
RampPlane,
|
||||||
RampPlaneCount,
|
RampPlaneCount,
|
||||||
reinterpret_cast<wall_point_type*>(floatArr5WallPoint + 3),
|
reinterpret_cast<wall_point_type*>(floatArr5WallPoint + 3),
|
||||||
&end2,
|
end2,
|
||||||
&start2);
|
start2);
|
||||||
Line2 = new TLine(this, &ActiveFlag, CollisionGroup, start2, end2);
|
Line2 = new TLine(this, &ActiveFlag, CollisionGroup, start2, end2);
|
||||||
EdgeList.push_back(Line2);
|
EdgeList.push_back(Line2);
|
||||||
if (Line2)
|
if (Line2)
|
||||||
@ -67,8 +67,8 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||||||
RampPlane,
|
RampPlane,
|
||||||
RampPlaneCount,
|
RampPlaneCount,
|
||||||
reinterpret_cast<wall_point_type*>(floatArr6WallPoint + 3),
|
reinterpret_cast<wall_point_type*>(floatArr6WallPoint + 3),
|
||||||
&end3,
|
end3,
|
||||||
&start3);
|
start3);
|
||||||
Line3 = new TLine(this, &ActiveFlag, CollisionGroup, start3, end3);
|
Line3 = new TLine(this, &ActiveFlag, CollisionGroup, start3, end3);
|
||||||
EdgeList.push_back(Line3);
|
EdgeList.push_back(Line3);
|
||||||
if (Line3)
|
if (Line3)
|
||||||
@ -84,20 +84,17 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||||||
auto xMax = -1000000000.0f;
|
auto xMax = -1000000000.0f;
|
||||||
for (auto index = 0; index < RampPlaneCount; index++)
|
for (auto index = 0; index < RampPlaneCount; index++)
|
||||||
{
|
{
|
||||||
auto plane = &RampPlane[index];
|
auto& plane = RampPlane[index];
|
||||||
auto pVec1 = &plane->V1;
|
vector2* pointOrder[4] = { &plane.V1, &plane.V2, &plane.V3, &plane.V1 };
|
||||||
auto pVec2 = &plane->V2;
|
|
||||||
auto pVec3 = &plane->V3;
|
|
||||||
|
|
||||||
xMin = std::min(std::min(std::min(plane->V3.X, plane->V1.X), plane->V2.X), xMin);
|
xMin = std::min(std::min(std::min(plane.V3.X, plane.V1.X), plane.V2.X), xMin);
|
||||||
yMin = std::min(std::min(std::min(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin); // Sic
|
yMin = std::min(std::min(std::min(plane.V3.Y, plane.V1.Y), plane.V2.Y), xMin); // Sic
|
||||||
xMax = std::max(std::max(std::max(plane->V3.X, plane->V1.X), plane->V2.X), xMin);
|
xMax = std::max(std::max(std::max(plane.V3.X, plane.V1.X), plane.V2.X), xMin);
|
||||||
yMax = std::max(std::max(std::max(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin);
|
yMax = std::max(std::max(std::max(plane.V3.Y, plane.V1.Y), plane.V2.Y), xMin);
|
||||||
|
|
||||||
vector2* pointOrder[4] = {pVec1, pVec2, pVec3, pVec1};
|
|
||||||
for (auto pt = 0; pt < 3; pt++)
|
for (auto pt = 0; pt < 3; pt++)
|
||||||
{
|
{
|
||||||
auto point1 = pointOrder[pt], point2 = pointOrder[pt + 1];
|
auto& point1 = *pointOrder[pt], point2 = *pointOrder[pt + 1];
|
||||||
auto collisionGroup = 0;
|
auto collisionGroup = 0;
|
||||||
if (point1 != end2 || point2 != start2)
|
if (point1 != end2 || point2 != start2)
|
||||||
{
|
{
|
||||||
@ -120,15 +117,15 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||||||
EdgeList.push_back(line);
|
EdgeList.push_back(line);
|
||||||
if (line)
|
if (line)
|
||||||
{
|
{
|
||||||
line->WallValue = plane;
|
line->WallValue = &plane;
|
||||||
line->place_in_grid();
|
line->place_in_grid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plane->FieldForce.X = cos(plane->GravityAngle2) * sin(plane->GravityAngle1) *
|
plane.FieldForce.X = cos(plane.GravityAngle2) * sin(plane.GravityAngle1) *
|
||||||
PinballTable->GravityDirVectMult;
|
PinballTable->GravityDirVectMult;
|
||||||
plane->FieldForce.Y = sin(plane->GravityAngle2) * sin(plane->GravityAngle1) *
|
plane.FieldForce.Y = sin(plane.GravityAngle2) * sin(plane.GravityAngle1) *
|
||||||
PinballTable->GravityDirVectMult;
|
PinballTable->GravityDirVectMult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,45 +220,45 @@ void TTableLayer::edges_insert_circle(circle_type* circle, TEdgeSegment* edge, f
|
|||||||
ray.Direction.X = 1.0;
|
ray.Direction.X = 1.0;
|
||||||
ray.Direction.Y = 0.0;
|
ray.Direction.Y = 0.0;
|
||||||
ray.MaxDistance = edge_manager->AdvanceX;
|
ray.MaxDistance = edge_manager->AdvanceX;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.X = -1.0;
|
ray.Direction.X = -1.0;
|
||||||
ray.Origin.X = ray.Origin.X + edge_manager->AdvanceX;
|
ray.Origin.X = ray.Origin.X + edge_manager->AdvanceX;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.X = 0.0;
|
ray.Direction.X = 0.0;
|
||||||
ray.Direction.Y = 1.0;
|
ray.Direction.Y = 1.0;
|
||||||
ray.MaxDistance = edge_manager->AdvanceY;
|
ray.MaxDistance = edge_manager->AdvanceY;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.Y = -1.0;
|
ray.Direction.Y = -1.0;
|
||||||
ray.Origin.Y = ray.Origin.Y + edge_manager->AdvanceY;
|
ray.Origin.Y = ray.Origin.Y + edge_manager->AdvanceY;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.Y = 0.0;
|
ray.Direction.Y = 0.0;
|
||||||
ray.Direction.X = -1.0;
|
ray.Direction.X = -1.0;
|
||||||
ray.MaxDistance = edge_manager->AdvanceX;
|
ray.MaxDistance = edge_manager->AdvanceX;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.X = 1.0;
|
ray.Direction.X = 1.0;
|
||||||
ray.Origin.X = ray.Origin.X - edge_manager->AdvanceX;
|
ray.Origin.X = ray.Origin.X - edge_manager->AdvanceX;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.X = 0.0;
|
ray.Direction.X = 0.0;
|
||||||
ray.Direction.Y = -1.0;
|
ray.Direction.Y = -1.0;
|
||||||
ray.MaxDistance = edge_manager->AdvanceY;
|
ray.MaxDistance = edge_manager->AdvanceY;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.Y = 1.0;
|
ray.Direction.Y = 1.0;
|
||||||
ray.Origin.Y = ray.Origin.Y - edge_manager->AdvanceY;
|
ray.Origin.Y = ray.Origin.Y - edge_manager->AdvanceY;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
collision = false;
|
collision = false;
|
||||||
|
@ -5,163 +5,125 @@
|
|||||||
#include "TFlipperEdge.h"
|
#include "TFlipperEdge.h"
|
||||||
|
|
||||||
|
|
||||||
void maths::enclosing_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect)
|
// 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)
|
||||||
{
|
{
|
||||||
int xPos1 = rect1->XPosition;
|
auto xPos = rect1.XPosition, width = rect1.Width;
|
||||||
int yPos1 = rect1->YPosition;
|
if (rect2.XPosition < rect1.XPosition)
|
||||||
int width1 = rect1->Width;
|
|
||||||
int height1 = rect1->Height;
|
|
||||||
int xPos2 = rect2->XPosition;
|
|
||||||
bool rect2XPosLessRect1 = rect2->XPosition < rect1->XPosition;
|
|
||||||
int yPos2 = rect2->YPosition;
|
|
||||||
int width2 = rect2->Width;
|
|
||||||
int height2 = rect2->Height;
|
|
||||||
int xPos2_2 = rect2->XPosition;
|
|
||||||
if (rect2XPosLessRect1)
|
|
||||||
{
|
{
|
||||||
width1 += xPos1 - xPos2;
|
xPos = rect2.XPosition;
|
||||||
xPos1 = xPos2;
|
width += rect1.XPosition - rect2.XPosition;
|
||||||
}
|
}
|
||||||
if (yPos2 < yPos1)
|
|
||||||
|
auto yPos = rect1.YPosition, height = rect1.Height;
|
||||||
|
if (rect2.YPosition < rect1.YPosition)
|
||||||
{
|
{
|
||||||
height1 += yPos1 - yPos2;
|
yPos = rect2.YPosition;
|
||||||
yPos1 = yPos2;
|
height += rect1.YPosition - rect2.YPosition;
|
||||||
}
|
}
|
||||||
if (width2 + xPos2 > xPos1 + width1)
|
|
||||||
width1 = xPos2_2 + width2 - xPos1;
|
auto xEnd2 = rect2.XPosition + rect2.Width;
|
||||||
int height1_2 = height1;
|
if (xEnd2 > xPos + width)
|
||||||
if (height2 + yPos2 > height1 + yPos1)
|
width = xEnd2 - xPos;
|
||||||
height1_2 = yPos2 + height2 - yPos1;
|
|
||||||
dstRect->YPosition = yPos1;
|
auto yEnd2 = rect2.YPosition + rect2.Height;
|
||||||
dstRect->Height = height1_2;
|
if (yEnd2 > yPos + height)
|
||||||
dstRect->XPosition = xPos1;
|
height = yEnd2 - yPos;
|
||||||
dstRect->Width = width1;
|
|
||||||
|
dstRect.XPosition = xPos;
|
||||||
|
dstRect.YPosition = yPos;
|
||||||
|
dstRect.Width = width;
|
||||||
|
dstRect.Height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates rect that represents an intersection of rect1 and rect2.
|
||||||
int maths::rectangle_clip(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect)
|
// Return true when intersection exists.
|
||||||
|
bool maths::rectangle_clip(const rectangle_type& rect1, const rectangle_type& rect2, rectangle_type* dstRect)
|
||||||
{
|
{
|
||||||
int xPos1 = rect1->XPosition;
|
auto xEnd2 = rect2.XPosition + rect2.Width;
|
||||||
int yPos1 = rect1->YPosition;
|
if (rect2.XPosition >= rect1.XPosition + rect1.Width || rect1.XPosition >= xEnd2)
|
||||||
int height1 = rect1->Height;
|
|
||||||
int xRight2 = rect2->XPosition + rect2->Width;
|
|
||||||
int width1 = rect1->Width;
|
|
||||||
int yRight2 = rect2->YPosition + rect2->Height;
|
|
||||||
if (xPos1 + width1 < rect2->XPosition)
|
|
||||||
return 0;
|
return 0;
|
||||||
if (xPos1 >= xRight2)
|
|
||||||
|
auto yEnd2 = rect2.YPosition + rect2.Height;
|
||||||
|
if (rect2.YPosition >= rect1.YPosition + rect1.Height || rect1.YPosition >= yEnd2)
|
||||||
return 0;
|
return 0;
|
||||||
int yPos2 = yPos1;
|
|
||||||
if (yPos1 + height1 < rect2->YPosition || yPos1 >= yRight2)
|
auto xPos = rect1.XPosition, width = rect1.Width;
|
||||||
return 0;
|
if (rect1.XPosition < rect2.XPosition)
|
||||||
if (xPos1 < rect2->XPosition)
|
|
||||||
{
|
{
|
||||||
width1 += xPos1 - rect2->XPosition;
|
xPos = rect2.XPosition;
|
||||||
xPos1 = rect2->XPosition;
|
width += rect1.XPosition - rect2.XPosition;
|
||||||
}
|
}
|
||||||
if (xPos1 + width1 > xRight2)
|
|
||||||
width1 = xRight2 - xPos1;
|
auto yPos = rect1.YPosition, height = rect1.Height;
|
||||||
int height2 = height1;
|
if (rect1.YPosition < rect2.YPosition)
|
||||||
if (yPos1 < rect2->YPosition)
|
|
||||||
{
|
{
|
||||||
height2 = yPos1 - rect2->YPosition + height1;
|
yPos = rect2.YPosition;
|
||||||
yPos2 = rect2->YPosition;
|
height += rect1.YPosition - rect2.YPosition;
|
||||||
}
|
}
|
||||||
if (height2 + yPos2 > yRight2)
|
|
||||||
height2 = yRight2 - yPos2;
|
if (xPos + width > xEnd2)
|
||||||
if (!width1 || !height2)
|
width = xEnd2 - xPos;
|
||||||
return 0;
|
if (yPos + height > yEnd2)
|
||||||
|
height = yEnd2 - yPos;
|
||||||
|
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (dstRect)
|
if (dstRect)
|
||||||
{
|
{
|
||||||
dstRect->XPosition = xPos1;
|
dstRect->XPosition = xPos;
|
||||||
dstRect->YPosition = yPos2;
|
dstRect->YPosition = yPos;
|
||||||
dstRect->Width = width1;
|
dstRect->Width = width;
|
||||||
dstRect->Height = height2;
|
dstRect->Height = height;
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the distance from ray origin to the first ray-circle intersection point.
|
||||||
int maths::overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect)
|
float maths::ray_intersect_circle(const ray_type& ray, const circle_type& circle)
|
||||||
{
|
|
||||||
int v3;
|
|
||||||
int v4;
|
|
||||||
int v6;
|
|
||||||
int v7;
|
|
||||||
|
|
||||||
if (rect1->XPosition >= rect2->XPosition)
|
|
||||||
{
|
|
||||||
dstRect->XPosition = rect2->XPosition;
|
|
||||||
v3 = rect1->Width - rect2->XPosition;
|
|
||||||
v4 = rect1->XPosition;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dstRect->XPosition = rect1->XPosition;
|
|
||||||
v3 = rect2->Width - rect1->XPosition;
|
|
||||||
v4 = rect2->XPosition;
|
|
||||||
}
|
|
||||||
dstRect->Width = v3 + v4 + 1;
|
|
||||||
int v5 = rect1->YPosition;
|
|
||||||
if (v5 >= rect2->YPosition)
|
|
||||||
{
|
|
||||||
dstRect->YPosition = rect2->YPosition;
|
|
||||||
v6 = rect1->Height - rect2->YPosition;
|
|
||||||
v7 = rect1->YPosition;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dstRect->YPosition = v5;
|
|
||||||
v6 = rect2->Height - rect1->YPosition;
|
|
||||||
v7 = rect2->YPosition;
|
|
||||||
}
|
|
||||||
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
|
// O - ray origin
|
||||||
// D - ray direction
|
// D - ray direction
|
||||||
// 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->Center.X - ray->Origin.X;
|
auto L = vector_sub(circle.Center, ray.Origin);
|
||||||
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 = DotProduct(L, ray.Direction);
|
||||||
if (Tca < 0.0f) // No intersection if Tca is negative
|
if (Tca < 0.0f) // No intersection if Tca is negative
|
||||||
return 1000000000.0f;
|
return 1000000000.0f;
|
||||||
|
|
||||||
// L dot L, distance from ray origin to circle center
|
// L dot L, distance from ray origin to circle center
|
||||||
float LMagSq = Ly * Ly + Lx * Lx;
|
float LMagSq = DotProduct(L, L);
|
||||||
|
|
||||||
// If ray origin is inside of the circle
|
// Thc^2 = rad^2 - d^2; d = sqrt(L dot L - Tca * Tca)
|
||||||
// T0 = Tca - Sqrt(rad^2 - d^2). d = sqrt(L dot L - Tca dot Tca)
|
float ThcSq = circle.RadiusSq - LMagSq + Tca * 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.0f) // No intersection if Thc is negative
|
|
||||||
return 1000000000.0f;
|
|
||||||
|
|
||||||
// T0 = Tca - Thc, distance from origin to first intersection
|
// T0 = Tca - Thc, distance from origin to first intersection
|
||||||
|
// If ray origin is inside of the circle, then T0 is negative
|
||||||
|
if (LMagSq < circle.RadiusSq)
|
||||||
|
return Tca - sqrt(ThcSq);
|
||||||
|
|
||||||
|
// No intersection if ThcSq is negative, that is if d > rad
|
||||||
|
if (ThcSq < 0.0f)
|
||||||
|
return 1000000000.0f;
|
||||||
|
|
||||||
|
// T0 should be positive and less that max ray distance
|
||||||
float T0 = Tca - sqrt(ThcSq);
|
float T0 = Tca - sqrt(ThcSq);
|
||||||
if (T0 < 0.0f || T0 > ray->MaxDistance)
|
if (T0 < 0.0f || T0 > ray.MaxDistance)
|
||||||
return 1000000000.0f;
|
return 1000000000.0f;
|
||||||
return T0;
|
return T0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float maths::normalize_2d(vector2& vec)
|
||||||
float maths::normalize_2d(vector2* vec)
|
|
||||||
{
|
{
|
||||||
float mag = sqrt(vec->X * vec->X + vec->Y * vec->Y);
|
float mag = sqrt(vec.X * vec.X + vec.Y * vec.Y);
|
||||||
if (mag != 0.0f)
|
if (mag != 0.0f)
|
||||||
{
|
{
|
||||||
vec->X = 1.0f / mag * vec->X;
|
vec.X /= mag;
|
||||||
vec->Y = 1.0f / mag * vec->Y;
|
vec.Y /= mag;
|
||||||
}
|
}
|
||||||
return mag;
|
return mag;
|
||||||
}
|
}
|
||||||
@ -169,93 +131,75 @@ float maths::normalize_2d(vector2* vec)
|
|||||||
|
|
||||||
void maths::line_init(line_type* line, float x0, float y0, float x1, float y1)
|
void maths::line_init(line_type* line, float x0, float y0, float x1, float y1)
|
||||||
{
|
{
|
||||||
float v9;
|
line->Origin = { x0, y0 };
|
||||||
bool lineDirection;
|
|
||||||
float v11;
|
|
||||||
|
|
||||||
line->Direction.X = x1 - x0;
|
line->Direction.X = x1 - x0;
|
||||||
line->Direction.Y = y1 - y0;
|
line->Direction.Y = y1 - y0;
|
||||||
normalize_2d(&line->Direction);
|
normalize_2d(line->Direction);
|
||||||
line->PerpendicularL.X = line->Direction.Y;
|
|
||||||
line->PerpendicularL.Y = -line->Direction.X;
|
// Clockwise perpendicular to the line direction vector
|
||||||
line->PreComp1 = -(line->Direction.Y * x0) + line->Direction.X * y0;
|
line->PerpendicularC = { line->Direction.Y, -line->Direction.X };
|
||||||
if (line->Direction.X >= 0.000000001f || line->Direction.X <= -0.000000001f)
|
|
||||||
{
|
auto lineStart = x0, lineEnd = x1;
|
||||||
v9 = x1;
|
if (std::abs(line->Direction.X) < 0.000000001f)
|
||||||
lineDirection = x0 >= x1;
|
|
||||||
v11 = x0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
line->Direction.X = 0.0;
|
line->Direction.X = 0.0;
|
||||||
v9 = y1;
|
lineStart = y0;
|
||||||
lineDirection = y0 >= y1;
|
lineEnd = y1;
|
||||||
v11 = y0;
|
|
||||||
}
|
|
||||||
if (lineDirection)
|
|
||||||
{
|
|
||||||
line->OriginX = v9;
|
|
||||||
line->OriginY = v11;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
line->OriginY = v9;
|
|
||||||
line->OriginX = v11;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
line->MinCoord = std::min(lineStart, lineEnd);
|
||||||
|
line->MaxCoord = std::max(lineStart, lineEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the distance from ray origin to the ray-line segment intersection point.
|
||||||
float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
||||||
{
|
{
|
||||||
bool v5;
|
// V1 vector between ray origin and line origin
|
||||||
bool v6;
|
// V2 ray direction
|
||||||
|
// V3 line perpendicular clockwise
|
||||||
|
auto v1 = vector_sub(ray->Origin, line->Origin);
|
||||||
|
auto v2 = line->Direction;
|
||||||
|
auto v3 = vector2{ -ray->Direction.Y, ray->Direction.X };
|
||||||
|
|
||||||
float perpDot = line->PerpendicularL.Y * ray->Direction.Y + ray->Direction.X * line->PerpendicularL.X;
|
// Project line on ray perpendicular, no intersection if ray is pointing away from the line
|
||||||
if (perpDot < 0.0f)
|
auto v2DotV3 = DotProduct(v2, v3);
|
||||||
|
if (v2DotV3 < 0.0f)
|
||||||
{
|
{
|
||||||
float result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line->
|
// Distance to the intersect point: (V2 X V1) / (V2 dot V3)
|
||||||
PreComp1)
|
auto distance = cross(v2, v1) / v2DotV3;
|
||||||
/ perpDot);
|
if (distance >= -ray->MinDistance && distance <= ray->MaxDistance)
|
||||||
if (result >= -ray->MinDistance && result <= ray->MaxDistance)
|
|
||||||
{
|
{
|
||||||
line->RayIntersect.X = result * ray->Direction.X + ray->Origin.X;
|
line->RayIntersect.X = distance * ray->Direction.X + ray->Origin.X;
|
||||||
float v4 = result * ray->Direction.Y + ray->Origin.Y;
|
line->RayIntersect.Y = distance * ray->Direction.Y + ray->Origin.Y;
|
||||||
line->RayIntersect.Y = v4;
|
|
||||||
if (line->Direction.X == 0.0f)
|
// Check if intersection point is inside line segment
|
||||||
|
auto testPoint = line->Direction.X != 0.0f ? line->RayIntersect.X : line->RayIntersect.Y;
|
||||||
|
if (testPoint >= line->MinCoord && testPoint <= line->MaxCoord)
|
||||||
{
|
{
|
||||||
if (v4 >= line->OriginX)
|
return distance;
|
||||||
{
|
|
||||||
v5 = v4 < line->OriginY;
|
|
||||||
v6 = v4 == line->OriginY;
|
|
||||||
if (v5 || v6)
|
|
||||||
return result;
|
|
||||||
return 1000000000.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (line->OriginX <= line->RayIntersect.X)
|
|
||||||
{
|
|
||||||
float v7 = line->RayIntersect.X;
|
|
||||||
v5 = v7 < line->OriginY;
|
|
||||||
v6 = v7 == line->OriginY;
|
|
||||||
if (v5 || v6)
|
|
||||||
return result;
|
|
||||||
return 1000000000.0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1000000000.0;
|
return 1000000000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void maths::cross(vector3* vec1, vector3* vec2, vector3* dstVec)
|
void maths::cross(const vector3& vec1, const vector3& vec2, vector3& dstVec)
|
||||||
{
|
{
|
||||||
dstVec->X = vec2->Z * vec1->Y - vec2->Y * vec1->Z;
|
dstVec.X = vec2.Z * vec1.Y - vec2.Y * vec1.Z;
|
||||||
dstVec->Y = vec2->X * vec1->Z - vec1->X * vec2->Z;
|
dstVec.Y = vec2.X * vec1.Z - vec1.X * vec2.Z;
|
||||||
dstVec->Z = vec1->X * vec2->Y - vec2->X * vec1->Y;
|
dstVec.Z = vec1.X * vec2.Y - vec2.X * vec1.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
float maths::magnitude(vector3* vec)
|
float maths::cross(const vector2& vec1, const vector2& vec2)
|
||||||
|
{
|
||||||
|
return vec1.X * vec2.Y - vec1.Y * vec2.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
float maths::magnitude(const vector3& vec)
|
||||||
{
|
{
|
||||||
float result;
|
float result;
|
||||||
auto magSq = vec->X * vec->X + vec->Y * vec->Y + vec->Z * vec->Z;
|
auto magSq = vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z;
|
||||||
if (magSq == 0.0f)
|
if (magSq == 0.0f)
|
||||||
result = 0.0;
|
result = 0.0;
|
||||||
else
|
else
|
||||||
@ -263,10 +207,15 @@ float maths::magnitude(vector3* vec)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void maths::vector_add(vector2* vec1Dst, vector2* vec2)
|
void maths::vector_add(vector2& vec1Dst, const vector2& vec2)
|
||||||
{
|
{
|
||||||
vec1Dst->X += vec2->X;
|
vec1Dst.X += vec2.X;
|
||||||
vec1Dst->Y += vec2->Y;
|
vec1Dst.Y += vec2.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector2 maths::vector_sub(const vector2& vec1, const vector2& vec2)
|
||||||
|
{
|
||||||
|
return { vec1.X - vec2.X, vec1.Y - vec2.Y };
|
||||||
}
|
}
|
||||||
|
|
||||||
float maths::basic_collision(TBall* ball, vector2* nextPosition, vector2* direction, float elasticity, float smoothness,
|
float maths::basic_collision(TBall* ball, vector2* nextPosition, vector2* direction, float elasticity, float smoothness,
|
||||||
@ -285,7 +234,7 @@ float maths::basic_collision(TBall* ball, vector2* nextPosition, vector2* direct
|
|||||||
float dy1 = proj * direction->Y;
|
float dy1 = proj * direction->Y;
|
||||||
ball->Acceleration.X = (dx1 + ball->Acceleration.X) * smoothness + dx1 * elasticity;
|
ball->Acceleration.X = (dx1 + ball->Acceleration.X) * smoothness + dx1 * elasticity;
|
||||||
ball->Acceleration.Y = (dy1 + ball->Acceleration.Y) * smoothness + dy1 * elasticity;
|
ball->Acceleration.Y = (dy1 + ball->Acceleration.Y) * smoothness + dy1 * elasticity;
|
||||||
normalize_2d(&ball->Acceleration);
|
normalize_2d(ball->Acceleration);
|
||||||
}
|
}
|
||||||
float projSpeed = proj * ball->Speed;
|
float projSpeed = proj * ball->Speed;
|
||||||
float newSpeed = ball->Speed - (1.0f - elasticity) * projSpeed;
|
float newSpeed = ball->Speed - (1.0f - elasticity) * projSpeed;
|
||||||
@ -294,33 +243,26 @@ float maths::basic_collision(TBall* ball, vector2* nextPosition, vector2* direct
|
|||||||
{
|
{
|
||||||
ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * boost;
|
ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * boost;
|
||||||
ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * boost;
|
ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * boost;
|
||||||
ball->Speed = normalize_2d(&ball->Acceleration);
|
ball->Speed = normalize_2d(ball->Acceleration);
|
||||||
}
|
}
|
||||||
return projSpeed;
|
return projSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
float maths::Distance_Squared(vector2& vec1, vector2& vec2)
|
float maths::Distance_Squared(const vector2& vec1, const vector2& vec2)
|
||||||
{
|
{
|
||||||
return (vec1.Y - vec2.Y) * (vec1.Y - vec2.Y) + (vec1.X - vec2.X) * (vec1.X - vec2.X);
|
auto dx = vec1.X - vec2.X;
|
||||||
|
auto dy = vec1.Y - vec2.Y;
|
||||||
|
return dy * dy + dx * dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
float maths::DotProduct(vector2* vec1, vector2* vec2)
|
float maths::DotProduct(const vector2& vec1, const vector2& vec2)
|
||||||
{
|
{
|
||||||
return vec1->Y * vec2->Y + vec1->X * vec2->X;
|
return vec1.X * vec2.X + vec1.Y * vec2.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void maths::vswap(vector2* vec1, vector2* vec2)
|
float maths::Distance(const vector2& vec1, const vector2& vec2)
|
||||||
{
|
{
|
||||||
vector2 tmp = *vec1;
|
return sqrt(Distance_Squared(vec1, vec2));
|
||||||
*vec1 = *vec2;
|
|
||||||
*vec2 = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
float maths::Distance(vector2* vec1, vector2* vec2)
|
|
||||||
{
|
|
||||||
auto dx = vec1->X - vec2->X;
|
|
||||||
auto dy = vec1->Y - vec2->Y;
|
|
||||||
return sqrt(dy * dy + dx * dx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void maths::SinCos(float angle, float* sinOut, float* cosOut)
|
void maths::SinCos(float angle, float* sinOut, float* cosOut)
|
||||||
@ -329,12 +271,12 @@ void maths::SinCos(float angle, float* sinOut, float* cosOut)
|
|||||||
*cosOut = cos(angle);
|
*cosOut = cos(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void maths::RotatePt(vector2* point, float sin, float cos, vector2* origin)
|
void maths::RotatePt(vector2& point, float sin, float cos, const vector2& origin)
|
||||||
{
|
{
|
||||||
auto dirX = point->X - origin->X;
|
auto dirX = point.X - origin.X;
|
||||||
auto dirY = point->Y - origin->Y;
|
auto dirY = point.Y - origin.Y;
|
||||||
point->X = dirX * cos - dirY * sin + origin->X;
|
point.X = dirX * cos - dirY * sin + origin.X;
|
||||||
point->Y = dirX * sin + dirY * cos + origin->Y;
|
point.Y = dirX * sin + dirY * cos + origin.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2)
|
float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2)
|
||||||
@ -347,13 +289,13 @@ float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2)
|
|||||||
distance = newDistance;
|
distance = newDistance;
|
||||||
distanceType = 0;
|
distanceType = 0;
|
||||||
}
|
}
|
||||||
newDistance = ray_intersect_circle(ray1, &TFlipperEdge::circlebase);
|
newDistance = ray_intersect_circle(*ray1, TFlipperEdge::circlebase);
|
||||||
if (newDistance < distance)
|
if (newDistance < distance)
|
||||||
{
|
{
|
||||||
distance = newDistance;
|
distance = newDistance;
|
||||||
distanceType = 2;
|
distanceType = 2;
|
||||||
}
|
}
|
||||||
newDistance = ray_intersect_circle(ray1, &TFlipperEdge::circleT1);
|
newDistance = ray_intersect_circle(*ray1, TFlipperEdge::circleT1);
|
||||||
if (newDistance < distance)
|
if (newDistance < distance)
|
||||||
{
|
{
|
||||||
distance = newDistance;
|
distance = newDistance;
|
||||||
@ -389,15 +331,15 @@ float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2)
|
|||||||
dirY = ray2->Origin.Y - TFlipperEdge::circleT1.Center.Y;
|
dirY = ray2->Origin.Y - TFlipperEdge::circleT1.Center.Y;
|
||||||
}
|
}
|
||||||
ray2->Direction.Y = dirY;
|
ray2->Direction.Y = dirY;
|
||||||
normalize_2d(&ray2->Direction);
|
normalize_2d(ray2->Direction);
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
ray2->Direction = TFlipperEdge::lineB.PerpendicularL;
|
ray2->Direction = TFlipperEdge::lineB.PerpendicularC;
|
||||||
nextOrigin = &TFlipperEdge::lineB.RayIntersect;
|
nextOrigin = &TFlipperEdge::lineB.RayIntersect;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ray2->Direction = TFlipperEdge::lineA.PerpendicularL;
|
ray2->Direction = TFlipperEdge::lineA.PerpendicularC;
|
||||||
nextOrigin = &TFlipperEdge::lineA.RayIntersect;
|
nextOrigin = &TFlipperEdge::lineA.RayIntersect;
|
||||||
}
|
}
|
||||||
ray2->Origin = *nextOrigin;
|
ray2->Origin = *nextOrigin;
|
||||||
@ -406,20 +348,22 @@ float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2)
|
|||||||
return 1000000000.0;
|
return 1000000000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void maths::RotateVector(vector2* vec, float angle)
|
void maths::RotateVector(vector2& vec, float angle)
|
||||||
{
|
{
|
||||||
float s = sin(angle), c = cos(angle);
|
float s = sin(angle), c = cos(angle);
|
||||||
vec->X = c * vec->X - s * vec->Y;
|
vec.X = c * vec.X - s * vec.Y;
|
||||||
vec->Y = s * vec->X + c * vec->Y;
|
vec.Y = s * vec.X + c * vec.Y;
|
||||||
/* Error in the original, should be:
|
/* Error in the original, should be:
|
||||||
* tmp = c * vec->X - s * vec->Y;
|
* auto newX = c * vec.X - s * vec.Y;
|
||||||
* vec->Y = s * vec->X + c * vec->Y;
|
* vec.Y = s * vec.X + c * vec.Y;
|
||||||
* vec->X = tmp
|
* vec.X = newX;
|
||||||
*/
|
*/
|
||||||
|
// Original code rotates the point on a figure eight curve.
|
||||||
|
// Luckily, it is never used with angle always set to 0.
|
||||||
}
|
}
|
||||||
|
|
||||||
void maths::find_closest_edge(ramp_plane_type* plane, int planeCount, wall_point_type* wall, vector2** lineEnd,
|
void maths::find_closest_edge(ramp_plane_type* planes, int planeCount, wall_point_type* wall, vector2& lineEnd,
|
||||||
vector2** lineStart)
|
vector2& lineStart)
|
||||||
{
|
{
|
||||||
vector2 wallEnd{}, wallStart{};
|
vector2 wallEnd{}, wallStart{};
|
||||||
|
|
||||||
@ -429,35 +373,22 @@ void maths::find_closest_edge(ramp_plane_type* plane, int planeCount, wall_point
|
|||||||
wallEnd.X = wall->X1;
|
wallEnd.X = wall->X1;
|
||||||
|
|
||||||
float maxDistance = 1000000000.0f;
|
float maxDistance = 1000000000.0f;
|
||||||
ramp_plane_type* planePtr = plane;
|
|
||||||
for (auto index = 0; index < planeCount; index++)
|
for (auto index = 0; index < planeCount; index++)
|
||||||
{
|
{
|
||||||
auto vec1 = &planePtr->V1,
|
auto& plane = planes[index];
|
||||||
vec2 = &planePtr->V2,
|
vector2* pointOrder[4] = { &plane.V1, &plane.V2, &plane.V3, &plane.V1 };
|
||||||
vec3 = &planePtr->V3;
|
|
||||||
auto distance = Distance(&wallStart, vec1) + Distance(&wallEnd, vec2);
|
|
||||||
if (distance < maxDistance)
|
|
||||||
{
|
|
||||||
maxDistance = distance;
|
|
||||||
*lineEnd = vec1;
|
|
||||||
*lineStart = vec2;
|
|
||||||
}
|
|
||||||
|
|
||||||
distance = Distance(&wallStart, vec2) + Distance(&wallEnd, vec3);
|
for (auto pt = 0; pt < 3; pt++)
|
||||||
if (distance < maxDistance)
|
|
||||||
{
|
{
|
||||||
maxDistance = distance;
|
auto& point1 = *pointOrder[pt], point2 = *pointOrder[pt + 1];
|
||||||
*lineEnd = vec2;
|
|
||||||
*lineStart = vec3;
|
|
||||||
}
|
|
||||||
|
|
||||||
distance = Distance(&wallStart, vec3) + Distance(&wallEnd, vec1);
|
auto distance = Distance(wallStart, point1) + Distance(wallEnd, point2);
|
||||||
if (distance < maxDistance)
|
if (distance < maxDistance)
|
||||||
{
|
{
|
||||||
maxDistance = distance;
|
maxDistance = distance;
|
||||||
*lineEnd = vec3;
|
lineEnd = point1;
|
||||||
*lineStart = vec1;
|
lineStart = point2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++planePtr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,15 @@ struct vector2
|
|||||||
{
|
{
|
||||||
float X;
|
float X;
|
||||||
float Y;
|
float Y;
|
||||||
|
|
||||||
|
bool operator==(const vector2& vec)
|
||||||
|
{
|
||||||
|
return X == vec.X && Y == vec.Y;
|
||||||
|
}
|
||||||
|
bool operator!=(const vector2& vec)
|
||||||
|
{
|
||||||
|
return X != vec.X || Y != vec.Y;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vector3 :vector2
|
struct vector3 :vector2
|
||||||
@ -40,11 +49,11 @@ struct ray_type
|
|||||||
|
|
||||||
struct line_type
|
struct line_type
|
||||||
{
|
{
|
||||||
vector2 PerpendicularL;
|
vector2 PerpendicularC;
|
||||||
vector2 Direction;
|
vector2 Direction;
|
||||||
float PreComp1;
|
vector2 Origin;
|
||||||
float OriginX;
|
float MinCoord;
|
||||||
float OriginY;
|
float MaxCoord;
|
||||||
vector2 RayIntersect;
|
vector2 RayIntersect;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,27 +80,27 @@ struct ramp_plane_type
|
|||||||
class maths
|
class maths
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void enclosing_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect);
|
static void enclosing_box(const rectangle_type& rect1, const rectangle_type& rect2, rectangle_type& dstRect);
|
||||||
static int rectangle_clip(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect);
|
static bool rectangle_clip(const rectangle_type& rect1, const rectangle_type& rect2, rectangle_type* dstRect);
|
||||||
static int overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect);
|
static float ray_intersect_circle(const ray_type& ray, const circle_type& circle);
|
||||||
static float ray_intersect_circle(ray_type* ray, circle_type* circle);
|
static float normalize_2d(vector2& vec);
|
||||||
static float normalize_2d(vector2* 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(vector3* vec1, vector3* vec2, vector3* dstVec);
|
static void cross(const vector3& vec1, const vector3& vec2, vector3& dstVec);
|
||||||
static float magnitude(vector3* vec);
|
static float cross(const vector2& vec1, const vector2& vec2);
|
||||||
static void vector_add(vector2* vec1Dst, vector2* vec2);
|
static float magnitude(const vector3& vec);
|
||||||
|
static void vector_add(vector2& vec1Dst, const vector2& vec2);
|
||||||
|
static vector2 vector_sub(const vector2& vec1, const vector2& vec2);
|
||||||
static float basic_collision(TBall* ball, vector2* nextPosition, vector2* direction, float elasticity,
|
static float basic_collision(TBall* ball, vector2* nextPosition, vector2* direction, float elasticity,
|
||||||
float smoothness,
|
float smoothness,
|
||||||
float threshold, float boost);
|
float threshold, float boost);
|
||||||
static float Distance_Squared(vector2& vec1, vector2& vec2);
|
static float Distance_Squared(const vector2& vec1, const vector2& vec2);
|
||||||
static float DotProduct(vector2* vec1, vector2* vec2);
|
static float DotProduct(const vector2& vec1, const vector2& vec2);
|
||||||
static void vswap(vector2* vec1, vector2* vec2);
|
static float Distance(const vector2& vec1, const vector2& vec2);
|
||||||
static float Distance(vector2* vec1, vector2* vec2);
|
|
||||||
static void SinCos(float angle, float* sinOut, float* cosOut);
|
static void SinCos(float angle, float* sinOut, float* cosOut);
|
||||||
static void RotatePt(vector2* point, float sin, float cos, vector2* origin);
|
static void RotatePt(vector2& point, float sin, float cos, const vector2& origin);
|
||||||
static float distance_to_flipper(ray_type* ray1, ray_type* ray2);
|
static float distance_to_flipper(ray_type* ray1, ray_type* ray2);
|
||||||
static void RotateVector(vector2* vec, float angle);
|
static void RotateVector(vector2& vec, float angle);
|
||||||
static void find_closest_edge(ramp_plane_type* plane, int planeCount, wall_point_type* wall, vector2** lineEnd,
|
static void find_closest_edge(ramp_plane_type* plane, int planeCount, wall_point_type* wall, vector2& lineEnd,
|
||||||
vector2** lineStart);
|
vector2& lineStart);
|
||||||
};
|
};
|
||||||
|
@ -75,8 +75,8 @@ void nudge::_nudge(float xDiff, float yDiff)
|
|||||||
{
|
{
|
||||||
ball->Acceleration.X = ball->Acceleration.X * ball->Speed;
|
ball->Acceleration.X = ball->Acceleration.X * ball->Speed;
|
||||||
ball->Acceleration.Y = ball->Acceleration.Y * ball->Speed;
|
ball->Acceleration.Y = ball->Acceleration.Y * ball->Speed;
|
||||||
maths::vector_add(&ball->Acceleration, &accelMod);
|
maths::vector_add(ball->Acceleration, accelMod);
|
||||||
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
ball->Speed = maths::normalize_2d(ball->Acceleration);
|
||||||
if (ball->Acceleration.X == 0.0f)
|
if (ball->Acceleration.X == 0.0f)
|
||||||
invAccelX = 1000000000.0;
|
invAccelX = 1000000000.0;
|
||||||
else
|
else
|
||||||
|
@ -243,7 +243,7 @@ void pb::ballset(float dx, float dy)
|
|||||||
TBall* ball = MainTable->BallList.at(0);
|
TBall* ball = MainTable->BallList.at(0);
|
||||||
ball->Acceleration.X = dx * sensitivity;
|
ball->Acceleration.X = dx * sensitivity;
|
||||||
ball->Acceleration.Y = dy * sensitivity;
|
ball->Acceleration.Y = dy * sensitivity;
|
||||||
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
ball->Speed = maths::normalize_2d(ball->Acceleration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb::frame(float dtMilliSec)
|
void pb::frame(float dtMilliSec)
|
||||||
@ -313,8 +313,8 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
|||||||
vec2.Y = vec2.Y * timeDelta;
|
vec2.Y = vec2.Y * timeDelta;
|
||||||
ball->Acceleration.X = ball->Speed * ball->Acceleration.X;
|
ball->Acceleration.X = ball->Speed * ball->Acceleration.X;
|
||||||
ball->Acceleration.Y = ball->Speed * ball->Acceleration.Y;
|
ball->Acceleration.Y = ball->Speed * ball->Acceleration.Y;
|
||||||
maths::vector_add(&ball->Acceleration, &vec2);
|
maths::vector_add(ball->Acceleration, vec2);
|
||||||
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
ball->Speed = maths::normalize_2d(ball->Acceleration);
|
||||||
ball->InvAcceleration.X = ball->Acceleration.X == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.X;
|
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->InvAcceleration.Y = ball->Acceleration.Y == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.Y;
|
||||||
}
|
}
|
||||||
@ -623,7 +623,7 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball)
|
|||||||
ball->RayMaxDistance = maxDistance;
|
ball->RayMaxDistance = maxDistance;
|
||||||
positionMod.X = maxDistance * ball->Acceleration.X;
|
positionMod.X = maxDistance * ball->Acceleration.X;
|
||||||
positionMod.Y = maxDistance * ball->Acceleration.Y;
|
positionMod.Y = maxDistance * ball->Acceleration.Y;
|
||||||
maths::vector_add(&ball->Position, &positionMod);
|
maths::vector_add(ball->Position, positionMod);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,7 @@ float proj::z_distance(vector3* vec)
|
|||||||
{
|
{
|
||||||
vector3 dstVec{};
|
vector3 dstVec{};
|
||||||
matrix_vector_multiply(&matrix, vec, &dstVec);
|
matrix_vector_multiply(&matrix, vec, &dstVec);
|
||||||
return maths::magnitude(&dstVec);
|
return maths::magnitude(dstVec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proj::xform_to_2d(vector3* vec, int* dst)
|
void proj::xform_to_2d(vector3* vec, int* dst)
|
||||||
|
@ -76,15 +76,15 @@ void render::update()
|
|||||||
{
|
{
|
||||||
case VisualTypes::Sprite:
|
case VisualTypes::Sprite:
|
||||||
if (curSprite->DirtyRectPrev.Width > 0)
|
if (curSprite->DirtyRectPrev.Width > 0)
|
||||||
maths::enclosing_box(&curSprite->DirtyRectPrev, &curSprite->BmpRect, &curSprite->DirtyRect);
|
maths::enclosing_box(curSprite->DirtyRectPrev, curSprite->BmpRect, curSprite->DirtyRect);
|
||||||
|
|
||||||
if (maths::rectangle_clip(&curSprite->DirtyRect, &vscreen_rect, &curSprite->DirtyRect))
|
if (maths::rectangle_clip(curSprite->DirtyRect, vscreen_rect, &curSprite->DirtyRect))
|
||||||
clearSprite = true;
|
clearSprite = true;
|
||||||
else
|
else
|
||||||
curSprite->DirtyRect.Width = -1;
|
curSprite->DirtyRect.Width = -1;
|
||||||
break;
|
break;
|
||||||
case VisualTypes::None:
|
case VisualTypes::None:
|
||||||
if (maths::rectangle_clip(&curSprite->BmpRect, &vscreen_rect, &curSprite->DirtyRect))
|
if (maths::rectangle_clip(curSprite->BmpRect, vscreen_rect, &curSprite->DirtyRect))
|
||||||
clearSprite = !curSprite->Bmp;
|
clearSprite = !curSprite->Bmp;
|
||||||
else
|
else
|
||||||
curSprite->DirtyRect.Width = -1;
|
curSprite->DirtyRect.Width = -1;
|
||||||
@ -291,7 +291,7 @@ void render::repaint(struct render_sprite_type_struct* sprite)
|
|||||||
{
|
{
|
||||||
if (!refSprite->UnknownFlag && refSprite->Bmp)
|
if (!refSprite->UnknownFlag && refSprite->Bmp)
|
||||||
{
|
{
|
||||||
if (maths::rectangle_clip(&refSprite->BmpRect, &sprite->DirtyRect, &clipRect))
|
if (maths::rectangle_clip(refSprite->BmpRect, sprite->DirtyRect, &clipRect))
|
||||||
zdrv::paint(
|
zdrv::paint(
|
||||||
clipRect.Width,
|
clipRect.Width,
|
||||||
clipRect.Height,
|
clipRect.Height,
|
||||||
@ -334,7 +334,7 @@ void render::paint_balls()
|
|||||||
{
|
{
|
||||||
auto ball = ball_list[index];
|
auto ball = ball_list[index];
|
||||||
auto dirty = &ball->DirtyRect;
|
auto dirty = &ball->DirtyRect;
|
||||||
if (ball->Bmp && maths::rectangle_clip(&ball->BmpRect, &vscreen_rect, &ball->DirtyRect))
|
if (ball->Bmp && maths::rectangle_clip(ball->BmpRect, vscreen_rect, &ball->DirtyRect))
|
||||||
{
|
{
|
||||||
int xPos = dirty->XPosition;
|
int xPos = dirty->XPosition;
|
||||||
int yPos = dirty->YPosition;
|
int yPos = dirty->YPosition;
|
||||||
@ -407,7 +407,7 @@ void render::build_occlude_list()
|
|||||||
{
|
{
|
||||||
if (!refSprite->UnknownFlag
|
if (!refSprite->UnknownFlag
|
||||||
&& refSprite->BoundingRect.Width != -1
|
&& refSprite->BoundingRect.Width != -1
|
||||||
&& maths::rectangle_clip(&mainSprite->BoundingRect, &refSprite->BoundingRect, nullptr)
|
&& maths::rectangle_clip(mainSprite->BoundingRect, refSprite->BoundingRect, nullptr)
|
||||||
&& spriteArr)
|
&& spriteArr)
|
||||||
{
|
{
|
||||||
spriteArr->push_back(refSprite);
|
spriteArr->push_back(refSprite);
|
||||||
|
Loading…
Reference in New Issue
Block a user