From fdf1f6c9f18dce51ee8894d37314c76f1aafe95d Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Fri, 13 May 2022 11:15:30 +0300 Subject: [PATCH] Cleaning up maths: part 3. Demangled methods, vectors args by ref, added comments, more accurate ray_intersect_line. --- SpaceCadetPinball/NatvisFile.natvis | 3 + SpaceCadetPinball/TBall.cpp | 2 +- SpaceCadetPinball/TCircle.cpp | 4 +- SpaceCadetPinball/TEdgeManager.cpp | 2 +- SpaceCadetPinball/TEdgeSegment.cpp | 6 +- SpaceCadetPinball/TFlagSpinner.cpp | 4 +- SpaceCadetPinball/TFlipperEdge.cpp | 62 ++-- SpaceCadetPinball/THole.cpp | 2 +- SpaceCadetPinball/TKickout.cpp | 2 +- SpaceCadetPinball/TLine.cpp | 18 +- SpaceCadetPinball/TLine.h | 2 +- SpaceCadetPinball/TOneway.cpp | 4 +- SpaceCadetPinball/TPinballComponent.cpp | 2 +- SpaceCadetPinball/TRamp.cpp | 37 +-- SpaceCadetPinball/TTableLayer.cpp | 16 +- SpaceCadetPinball/maths.cpp | 411 ++++++++++-------------- SpaceCadetPinball/maths.h | 49 +-- SpaceCadetPinball/nudge.cpp | 4 +- SpaceCadetPinball/pb.cpp | 8 +- SpaceCadetPinball/proj.cpp | 2 +- SpaceCadetPinball/render.cpp | 12 +- 21 files changed, 296 insertions(+), 356 deletions(-) diff --git a/SpaceCadetPinball/NatvisFile.natvis b/SpaceCadetPinball/NatvisFile.natvis index cc64cd6..b1b1551 100644 --- a/SpaceCadetPinball/NatvisFile.natvis +++ b/SpaceCadetPinball/NatvisFile.natvis @@ -10,4 +10,7 @@ Color + + {{ X={X} Y={Y} Z={Z} }} + \ No newline at end of file diff --git a/SpaceCadetPinball/TBall.cpp b/SpaceCadetPinball/TBall.cpp index 5de74b5..f19bcad 100644 --- a/SpaceCadetPinball/TBall.cpp +++ b/SpaceCadetPinball/TBall.cpp @@ -135,7 +135,7 @@ void TBall::throw_ball(TBall* ball, vector3* acceleration, float angleMult, floa ball->Acceleration = *acceleration; float rnd = RandFloat(); float angle = (1.0f - (rnd + rnd)) * angleMult; - maths::RotateVector(&ball->Acceleration, angle); + maths::RotateVector(ball->Acceleration, angle); rnd = RandFloat(); ball->Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1; } diff --git a/SpaceCadetPinball/TCircle.cpp b/SpaceCadetPinball/TCircle.cpp index 4cf9d79..b61ccfd 100644 --- a/SpaceCadetPinball/TCircle.cpp +++ b/SpaceCadetPinball/TCircle.cpp @@ -14,7 +14,7 @@ TCircle::TCircle(TCollisionComponent* collComp, char* activeFlag, unsigned colli 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) @@ -25,7 +25,7 @@ void TCircle::EdgeCollision(TBall* ball, float coef) nextPosition.Y = coef * ball->Acceleration.Y + ball->Position.Y; direction.X = nextPosition.X - Circle.Center.X; direction.Y = nextPosition.Y - Circle.Center.Y; - maths::normalize_2d(&direction); + maths::normalize_2d(direction); CollisionComponent->Collision(ball, &nextPosition, &direction, coef, this); } diff --git a/SpaceCadetPinball/TEdgeManager.cpp b/SpaceCadetPinball/TEdgeManager.cpp index 0fba12e..745ff23 100644 --- a/SpaceCadetPinball/TEdgeManager.cpp +++ b/SpaceCadetPinball/TEdgeManager.cpp @@ -100,7 +100,7 @@ void TEdgeManager::FieldEffects(TBall* ball, vector2* dstVec) { if (field->CollisionComp->FieldEffect(ball, &vec)) { - maths::vector_add(dstVec, &vec); + maths::vector_add(*dstVec, vec); } } } diff --git a/SpaceCadetPinball/TEdgeSegment.cpp b/SpaceCadetPinball/TEdgeSegment.cpp index 6aa0c74..3ffff0d 100644 --- a/SpaceCadetPinball/TEdgeSegment.cpp +++ b/SpaceCadetPinball/TEdgeSegment.cpp @@ -50,7 +50,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c start.Y = floatArr[2]; end.X = floatArr[3]; end.Y = floatArr[4]; - auto line = new TLine(collComp, activeFlagPtr, collisionGroup, &start, &end); + auto line = new TLine(collComp, activeFlagPtr, collisionGroup, start, end); edge = line; if (line) @@ -93,7 +93,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c vec1.Y = center.Y - prevCenter.Y; vec2.X = centerX2 - centerX1; vec2.Y = centerY2 - center.Y; - maths::cross(&vec1, &vec2, &dstVec); + maths::cross(vec1, vec2, dstVec); if ((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]; end.X = floatArrPtr[2]; end.Y = floatArrPtr[3]; - auto line = new TLine(collComp, activeFlagPtr, collisionGroup, &start, &end); + auto line = new TLine(collComp, activeFlagPtr, collisionGroup, start, end); edge = line; if (line) diff --git a/SpaceCadetPinball/TFlagSpinner.cpp b/SpaceCadetPinball/TFlagSpinner.cpp index ea2e77c..86b1bf5 100644 --- a/SpaceCadetPinball/TFlagSpinner.cpp +++ b/SpaceCadetPinball/TFlagSpinner.cpp @@ -21,14 +21,14 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom end.Y = visual.FloatArr[1]; start.X = visual.FloatArr[2]; 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) { line->place_in_grid(); EdgeList.push_back(line); } - line = new TLine(this, &ActiveFlag, visual.CollisionGroup, &end, &start); + line = new TLine(this, &ActiveFlag, visual.CollisionGroup, end, start); PrevCollider = line; if (line) { diff --git a/SpaceCadetPinball/TFlipperEdge.cpp b/SpaceCadetPinball/TFlipperEdge.cpp index b6637fd..82dfef2 100644 --- a/SpaceCadetPinball/TFlipperEdge.cpp +++ b/SpaceCadetPinball/TFlipperEdge.cpp @@ -23,8 +23,8 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi RetractTime = retractTime; CollisionMult = collMult; - T1Src = *vecT1; - T2Src = *vecT2; + T1Src = static_cast(*vecT1); + T2Src = static_cast(*vecT2); RotOrigin.X = origin->X; RotOrigin.Y = origin->Y; @@ -39,15 +39,15 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi vecDir1.X = vecT1->X - origin->X; vecDir1.Y = vecT1->Y - origin->Y; vecDir1.Z = 0.0; - maths::normalize_2d(&vecDir1); + maths::normalize_2d(vecDir1); vecDir2.X = vecT2->X - origin->X; vecDir2.Y = vecT2->Y - origin->Y; vecDir2.Z = 0.0; - maths::normalize_2d(&vecDir2); + maths::normalize_2d(vecDir2); - AngleMax = acos(maths::DotProduct(&vecDir1, &vecDir2)); - maths::cross(&vecDir1, &vecDir2, &crossProd); + AngleMax = acos(maths::DotProduct(vecDir1, vecDir2)); + maths::cross(vecDir1, vecDir2, crossProd); if (crossProd.Z < 0.0f) AngleMax = -AngleMax; FlipperFlag = 0; @@ -69,8 +69,8 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi if (AngleMax < 0.0f) { - maths::vswap(&A1Src, &B1Src); - maths::vswap(&A2Src, &B2Src); + std::swap(A1Src, B1Src); + std::swap(A2Src, B2Src); } auto dx = vecT1->X - RotOrigin.X; @@ -79,7 +79,7 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi DistanceDivSq = distance1 * distance1; float minMoveTime = std::min(ExtendTime, RetractTime); - auto distance = maths::Distance(vecT1, vecT2); + auto distance = maths::Distance(*vecT1, *vecT2); CollisionTimeAdvance = minMoveTime / (distance / CircleT1Radius + distance / CircleT1Radius); TFlipperEdge::place_in_grid(); @@ -139,12 +139,12 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray) { if (maths::Distance_Squared(ogRay->Origin, T1) >= CircleT1RadiusMSq) { - srcRay.Direction.Y = lineB.PerpendicularL.Y; - srcRay.Direction.X = lineB.PerpendicularL.X; + srcRay.Direction.Y = lineB.PerpendicularC.Y; + srcRay.Direction.X = lineB.PerpendicularC.X; if (ballInside == 4) { - srcRay.Direction.Y = lineA.PerpendicularL.Y; - srcRay.Direction.X = lineA.PerpendicularL.X; + srcRay.Direction.Y = lineA.PerpendicularC.Y; + srcRay.Direction.X = lineA.PerpendicularC.X; } srcRay.Direction.X = -srcRay.Direction.X; 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.Y = T1.Y - ogRay->Origin.Y; - maths::normalize_2d(&srcRay.Direction); + maths::normalize_2d(srcRay.Direction); } } else { srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X; 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; @@ -170,7 +170,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray) { srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X; 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.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f; if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09f) @@ -203,9 +203,9 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray) vector2* linePtr; if (FlipperFlag == 1 && ballInside != 5) { - linePtr = &lineA.PerpendicularL; - srcRay.Direction.Y = lineA.PerpendicularL.Y; - srcRay.Direction.X = lineA.PerpendicularL.X; + linePtr = &lineA.PerpendicularC; + srcRay.Direction.Y = lineA.PerpendicularC.Y; + srcRay.Direction.X = lineA.PerpendicularC.X; } else { @@ -215,7 +215,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray) CollisionFlag2 = 1; srcRay.Direction.X = RotOrigin.X - posX; 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.Y = posY - srcRay.Direction.Y * 5.0f; @@ -235,9 +235,9 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray) NextBallPosition.Y -= srcRay.Direction.Y * 1e-05f; return 0.0; } - linePtr = &lineB.PerpendicularL; - srcRay.Direction.Y = lineB.PerpendicularL.Y; - srcRay.Direction.X = lineB.PerpendicularL.X; + linePtr = &lineB.PerpendicularC; + srcRay.Direction.Y = lineB.PerpendicularC.Y; + srcRay.Direction.X = lineB.PerpendicularC.X; } CollisionLinePerp = *linePtr; @@ -274,13 +274,13 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray) vector2* linePtr; if (FlipperFlag == 2) { - linePtr = &lineB.PerpendicularL; + linePtr = &lineB.PerpendicularC; CollisionFlag1 = AngleMax <= 0.0f; } else { CollisionFlag1 = AngleMax > 0.0f; - linePtr = &lineA.PerpendicularL; + linePtr = &lineA.PerpendicularC; } CollisionLinePerp = *linePtr; CollisionDirection = dstRay.Direction; @@ -313,7 +313,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef) { float v11; float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult); - float dot1 = maths::DotProduct(&CollisionLinePerp, &CollisionDirection); + float dot1 = maths::DotProduct(CollisionLinePerp, CollisionDirection); if (dot1 >= 0.0f) v11 = dot1 * v20; else @@ -395,11 +395,11 @@ void TFlipperEdge::set_control_points(float timeNow) B1 = B1Src; B2 = B2Src; T1 = T1Src; - maths::RotatePt(&A1, 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(&B1, flipper_sin_angle, flipper_cos_angle, &RotOrigin); - maths::RotatePt(&B2, 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(T1, 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); } void TFlipperEdge::build_edges_in_motion() diff --git a/SpaceCadetPinball/THole.cpp b/SpaceCadetPinball/THole.cpp index 428852f..265bc7b 100644 --- a/SpaceCadetPinball/THole.cpp +++ b/SpaceCadetPinball/THole.cpp @@ -127,7 +127,7 @@ int THole::FieldEffect(TBall* ball, vector2* vecDst) direction.Y = Circle.Center.Y - ball->Position.Y; 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->Y = direction.Y * GravityPull - ball->Acceleration.Y * ball->Speed; result = 1; diff --git a/SpaceCadetPinball/TKickout.cpp b/SpaceCadetPinball/TKickout.cpp index 156184c..c321a3f 100644 --- a/SpaceCadetPinball/TKickout.cpp +++ b/SpaceCadetPinball/TKickout.cpp @@ -138,7 +138,7 @@ int TKickout::FieldEffect(TBall* ball, vector2* dstVec) direction.Y = Circle.Center.Y - ball->Position.Y; if (direction.Y * direction.Y + direction.X * direction.X > Circle.RadiusSq) return 0; - maths::normalize_2d(&direction); + maths::normalize_2d(direction); dstVec->X = direction.X * FieldMult - ball->Acceleration.X * ball->Speed; dstVec->Y = direction.Y * FieldMult - ball->Acceleration.Y * ball->Speed; return 1; diff --git a/SpaceCadetPinball/TLine.cpp b/SpaceCadetPinball/TLine.cpp index fd1d1e2..5f47c54 100644 --- a/SpaceCadetPinball/TLine.cpp +++ b/SpaceCadetPinball/TLine.cpp @@ -14,20 +14,20 @@ TLine::TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collis maths::line_init(&Line, x0, y0, x1, y1); } -TLine::TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, struct vector2* start, - struct vector2* end) : TEdgeSegment(collCmp, activeFlag, collisionGroup) +TLine::TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, const vector2& start, + const vector2& end) : TEdgeSegment(collCmp, activeFlag, collisionGroup) { - X0 = start->X; - Y0 = start->Y; - X1 = end->X; - Y1 = end->Y; + X0 = start.X; + Y0 = start.Y; + X1 = end.X; + Y1 = end.Y; maths::line_init(&Line, X0, Y0, X1, Y1); } void TLine::Offset(float offset) { - float offX = offset * Line.PerpendicularL.X; - float offY = offset * Line.PerpendicularL.Y; + float offX = offset * Line.PerpendicularC.X; + float offY = offset * Line.PerpendicularC.Y; X0 += offX; Y0 += offY; @@ -46,7 +46,7 @@ void TLine::EdgeCollision(TBall* ball, float coef) CollisionComponent->Collision( ball, &Line.RayIntersect, - &Line.PerpendicularL, + &Line.PerpendicularC, coef, this); } diff --git a/SpaceCadetPinball/TLine.h b/SpaceCadetPinball/TLine.h index f494f4f..1009c40 100644 --- a/SpaceCadetPinball/TLine.h +++ b/SpaceCadetPinball/TLine.h @@ -9,7 +9,7 @@ public: line_type Line{}; 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, vector2* start, vector2* end); + 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; diff --git a/SpaceCadetPinball/TOneway.cpp b/SpaceCadetPinball/TOneway.cpp index d16d536..227f77c 100644 --- a/SpaceCadetPinball/TOneway.cpp +++ b/SpaceCadetPinball/TOneway.cpp @@ -21,7 +21,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab linePt1.X = visual.FloatArr[2]; 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) { line->Offset(table->CollisionCompOffset); @@ -29,7 +29,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab EdgeList.push_back(line); } - line = new TLine(this, &ActiveFlag, visual.CollisionGroup, &linePt1, &linePt2); + line = new TLine(this, &ActiveFlag, visual.CollisionGroup, linePt1, linePt2); Line = line; if (line) { diff --git a/SpaceCadetPinball/TPinballComponent.cpp b/SpaceCadetPinball/TPinballComponent.cpp index 16ee2c9..e72d6c3 100644 --- a/SpaceCadetPinball/TPinballComponent.cpp +++ b/SpaceCadetPinball/TPinballComponent.cpp @@ -59,7 +59,7 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool tmpRect.YPosition = bmp->YPosition - table->YOffset; tmpRect.Width = bmp->Width; tmpRect.Height = bmp->Height; - maths::enclosing_box(&bmp1Rect, &tmpRect, &bmp1Rect); + maths::enclosing_box(bmp1Rect, tmpRect, bmp1Rect); } RenderSprite = render::create_sprite( diff --git a/SpaceCadetPinball/TRamp.cpp b/SpaceCadetPinball/TRamp.cpp index 7a29af1..75da0ac 100644 --- a/SpaceCadetPinball/TRamp.cpp +++ b/SpaceCadetPinball/TRamp.cpp @@ -14,7 +14,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) { visualStruct visual{}; - vector2 end{}, start{}, *end2, *start2, *start3, *end3; + vector2 end{}, start{}, end2{}, start2{}, start3{}, end3{}; MessageField = 0; UnusedBaseFlag = 1; @@ -33,7 +33,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, end.Y = floatArr4[3]; start.X = floatArr4[4]; start.Y = floatArr4[5]; - Line1 = new TLine(this, &ActiveFlag, 1 << static_cast(floor(floatArr4[0])), &start, &end); + Line1 = new TLine(this, &ActiveFlag, 1 << static_cast(floor(floatArr4[0])), start, end); EdgeList.push_back(Line1); if (Line1) { @@ -49,8 +49,8 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, RampPlane, RampPlaneCount, reinterpret_cast(floatArr5WallPoint + 3), - &end2, - &start2); + end2, + start2); Line2 = new TLine(this, &ActiveFlag, CollisionGroup, start2, end2); EdgeList.push_back(Line2); if (Line2) @@ -67,8 +67,8 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, RampPlane, RampPlaneCount, reinterpret_cast(floatArr6WallPoint + 3), - &end3, - &start3); + end3, + start3); Line3 = new TLine(this, &ActiveFlag, CollisionGroup, start3, end3); EdgeList.push_back(Line3); if (Line3) @@ -84,20 +84,17 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, auto xMax = -1000000000.0f; for (auto index = 0; index < RampPlaneCount; index++) { - auto plane = &RampPlane[index]; - auto pVec1 = &plane->V1; - auto pVec2 = &plane->V2; - auto pVec3 = &plane->V3; + auto& plane = RampPlane[index]; + vector2* pointOrder[4] = { &plane.V1, &plane.V2, &plane.V3, &plane.V1 }; - 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 - 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); - - vector2* pointOrder[4] = {pVec1, pVec2, pVec3, pVec1}; + 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 + 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); + 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; if (point1 != end2 || point2 != start2) { @@ -120,15 +117,15 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, EdgeList.push_back(line); if (line) { - line->WallValue = plane; + line->WallValue = &plane; line->place_in_grid(); } } } - plane->FieldForce.X = cos(plane->GravityAngle2) * sin(plane->GravityAngle1) * + plane.FieldForce.X = cos(plane.GravityAngle2) * sin(plane.GravityAngle1) * PinballTable->GravityDirVectMult; - plane->FieldForce.Y = sin(plane->GravityAngle2) * sin(plane->GravityAngle1) * + plane.FieldForce.Y = sin(plane.GravityAngle2) * sin(plane.GravityAngle1) * PinballTable->GravityDirVectMult; } diff --git a/SpaceCadetPinball/TTableLayer.cpp b/SpaceCadetPinball/TTableLayer.cpp index 710a019..0dfc914 100644 --- a/SpaceCadetPinball/TTableLayer.cpp +++ b/SpaceCadetPinball/TTableLayer.cpp @@ -220,45 +220,45 @@ void TTableLayer::edges_insert_circle(circle_type* circle, TEdgeSegment* edge, f ray.Direction.X = 1.0; ray.Direction.Y = 0.0; ray.MaxDistance = edge_manager->AdvanceX; - if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f) + if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f) break; ray.Direction.X = -1.0; 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; ray.Direction.X = 0.0; ray.Direction.Y = 1.0; ray.MaxDistance = edge_manager->AdvanceY; - if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f) + if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f) break; ray.Direction.Y = -1.0; 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; ray.Direction.Y = 0.0; ray.Direction.X = -1.0; ray.MaxDistance = edge_manager->AdvanceX; - if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f) + if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f) break; ray.Direction.X = 1.0; 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; ray.Direction.X = 0.0; ray.Direction.Y = -1.0; ray.MaxDistance = edge_manager->AdvanceY; - if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f) + if (maths::ray_intersect_circle(ray, *circle) < 1000000000.0f) break; ray.Direction.Y = 1.0; 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; collision = false; diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp index b9ab866..c9035e5 100644 --- a/SpaceCadetPinball/maths.cpp +++ b/SpaceCadetPinball/maths.cpp @@ -5,163 +5,125 @@ #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; - int yPos1 = rect1->YPosition; - 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) + auto xPos = rect1.XPosition, width = rect1.Width; + if (rect2.XPosition < rect1.XPosition) { - width1 += xPos1 - xPos2; - xPos1 = xPos2; + xPos = rect2.XPosition; + width += rect1.XPosition - rect2.XPosition; } - if (yPos2 < yPos1) + + auto yPos = rect1.YPosition, height = rect1.Height; + if (rect2.YPosition < rect1.YPosition) { - height1 += yPos1 - yPos2; - yPos1 = yPos2; + yPos = rect2.YPosition; + height += rect1.YPosition - rect2.YPosition; } - if (width2 + xPos2 > xPos1 + width1) - width1 = xPos2_2 + width2 - xPos1; - int height1_2 = height1; - if (height2 + yPos2 > height1 + yPos1) - height1_2 = yPos2 + height2 - yPos1; - dstRect->YPosition = yPos1; - dstRect->Height = height1_2; - dstRect->XPosition = xPos1; - dstRect->Width = width1; + + auto xEnd2 = rect2.XPosition + rect2.Width; + if (xEnd2 > xPos + width) + width = xEnd2 - xPos; + + auto yEnd2 = rect2.YPosition + rect2.Height; + if (yEnd2 > yPos + height) + height = yEnd2 - yPos; + + dstRect.XPosition = xPos; + dstRect.YPosition = yPos; + dstRect.Width = width; + dstRect.Height = height; } - -int maths::rectangle_clip(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect) +// Creates rect that represents an intersection of rect1 and rect2. +// Return true when intersection exists. +bool maths::rectangle_clip(const rectangle_type& rect1, const rectangle_type& rect2, rectangle_type* dstRect) { - int xPos1 = rect1->XPosition; - int yPos1 = rect1->YPosition; - 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) + auto xEnd2 = rect2.XPosition + rect2.Width; + if (rect2.XPosition >= rect1.XPosition + rect1.Width || rect1.XPosition >= xEnd2) return 0; - if (xPos1 >= xRight2) + + auto yEnd2 = rect2.YPosition + rect2.Height; + if (rect2.YPosition >= rect1.YPosition + rect1.Height || rect1.YPosition >= yEnd2) return 0; - int yPos2 = yPos1; - if (yPos1 + height1 < rect2->YPosition || yPos1 >= yRight2) - return 0; - if (xPos1 < rect2->XPosition) + + auto xPos = rect1.XPosition, width = rect1.Width; + if (rect1.XPosition < rect2.XPosition) { - width1 += xPos1 - rect2->XPosition; - xPos1 = rect2->XPosition; + xPos = rect2.XPosition; + width += rect1.XPosition - rect2.XPosition; } - if (xPos1 + width1 > xRight2) - width1 = xRight2 - xPos1; - int height2 = height1; - if (yPos1 < rect2->YPosition) + + auto yPos = rect1.YPosition, height = rect1.Height; + if (rect1.YPosition < rect2.YPosition) { - height2 = yPos1 - rect2->YPosition + height1; - yPos2 = rect2->YPosition; + yPos = rect2.YPosition; + height += rect1.YPosition - rect2.YPosition; } - if (height2 + yPos2 > yRight2) - height2 = yRight2 - yPos2; - if (!width1 || !height2) - return 0; + + if (xPos + width > xEnd2) + width = xEnd2 - xPos; + if (yPos + height > yEnd2) + height = yEnd2 - yPos; + + if (width == 0 || height == 0) + return false; + if (dstRect) { - dstRect->XPosition = xPos1; - dstRect->YPosition = yPos2; - dstRect->Width = width1; - dstRect->Height = height2; + dstRect->XPosition = xPos; + dstRect->YPosition = yPos; + dstRect->Width = width; + dstRect->Height = height; } - return 1; + return true; } - -int maths::overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect) -{ - 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) +// Returns the distance from ray origin to the first ray-circle intersection point. +float maths::ray_intersect_circle(const ray_type& ray, const circle_type& circle) { // O - ray origin // D - ray direction // C - circle center // R - circle radius // L, C - O, vector between O and C - float Lx = circle->Center.X - ray->Origin.X; - float Ly = circle->Center.Y - ray->Origin.Y; + auto L = vector_sub(circle.Center, ray.Origin); // 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 return 1000000000.0f; // 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 - // T0 = Tca - Sqrt(rad^2 - d^2). d = sqrt(L dot L - Tca dot Tca) - if (LMagSq < circle->RadiusSq) - return Tca - sqrt(circle->RadiusSq - LMagSq + Tca * Tca); - - // Thc^2 = rad^2 - d = rad^2 - L dot L + Tca dot Tca - float ThcSq = circle->RadiusSq - LMagSq + Tca * Tca; - if (ThcSq < 0.0f) // No intersection if Thc is negative - return 1000000000.0f; + // Thc^2 = rad^2 - d^2; d = sqrt(L dot L - Tca * Tca) + float ThcSq = circle.RadiusSq - LMagSq + Tca * Tca; // 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); - if (T0 < 0.0f || T0 > ray->MaxDistance) + if (T0 < 0.0f || T0 > ray.MaxDistance) return 1000000000.0f; 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) { - vec->X = 1.0f / mag * vec->X; - vec->Y = 1.0f / mag * vec->Y; + vec.X /= mag; + vec.Y /= 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) { - float v9; - bool lineDirection; - float v11; - + line->Origin = { x0, y0 }; line->Direction.X = x1 - x0; line->Direction.Y = y1 - y0; - normalize_2d(&line->Direction); - line->PerpendicularL.X = line->Direction.Y; - line->PerpendicularL.Y = -line->Direction.X; - line->PreComp1 = -(line->Direction.Y * x0) + line->Direction.X * y0; - if (line->Direction.X >= 0.000000001f || line->Direction.X <= -0.000000001f) - { - v9 = x1; - lineDirection = x0 >= x1; - v11 = x0; - } - else + normalize_2d(line->Direction); + + // Clockwise perpendicular to the line direction vector + line->PerpendicularC = { line->Direction.Y, -line->Direction.X }; + + auto lineStart = x0, lineEnd = x1; + if (std::abs(line->Direction.X) < 0.000000001f) { line->Direction.X = 0.0; - v9 = y1; - lineDirection = y0 >= y1; - v11 = y0; - } - if (lineDirection) - { - line->OriginX = v9; - line->OriginY = v11; - } - else - { - line->OriginY = v9; - line->OriginX = v11; + lineStart = y0; + lineEnd = y1; } + + 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) { - bool v5; - bool v6; + // V1 vector between ray origin and line origin + // 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; - if (perpDot < 0.0f) + // Project line on ray perpendicular, no intersection if ray is pointing away from the line + auto v2DotV3 = DotProduct(v2, v3); + if (v2DotV3 < 0.0f) { - float result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line-> - PreComp1) - / perpDot); - if (result >= -ray->MinDistance && result <= ray->MaxDistance) + // Distance to the intersect point: (V2 X V1) / (V2 dot V3) + auto distance = cross(v2, v1) / v2DotV3; + if (distance >= -ray->MinDistance && distance <= ray->MaxDistance) { - line->RayIntersect.X = result * ray->Direction.X + ray->Origin.X; - float v4 = result * ray->Direction.Y + ray->Origin.Y; - line->RayIntersect.Y = v4; - if (line->Direction.X == 0.0f) + line->RayIntersect.X = distance * ray->Direction.X + ray->Origin.X; + line->RayIntersect.Y = distance * ray->Direction.Y + ray->Origin.Y; + + // 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) - { - 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 distance; } } } + 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->Y = vec2->X * vec1->Z - vec1->X * vec2->Z; - dstVec->Z = vec1->X * vec2->Y - vec2->X * vec1->Y; + dstVec.X = vec2.Z * vec1.Y - vec2.Y * vec1.Z; + dstVec.Y = vec2.X * vec1.Z - vec1.X * vec2.Z; + dstVec.Z = vec1.X * vec2.Y - vec2.X * vec1.Y; } -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; - 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) result = 0.0; else @@ -263,10 +207,15 @@ float maths::magnitude(vector3* vec) return result; } -void maths::vector_add(vector2* vec1Dst, vector2* vec2) +void maths::vector_add(vector2& vec1Dst, const vector2& vec2) { - vec1Dst->X += vec2->X; - vec1Dst->Y += vec2->Y; + vec1Dst.X += vec2.X; + 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, @@ -285,7 +234,7 @@ float maths::basic_collision(TBall* ball, vector2* nextPosition, vector2* direct 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); + normalize_2d(ball->Acceleration); } float projSpeed = proj * ball->Speed; 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.Y = newSpeed * ball->Acceleration.Y + direction->Y * boost; - ball->Speed = normalize_2d(&ball->Acceleration); + ball->Speed = normalize_2d(ball->Acceleration); } 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; - *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); + return sqrt(Distance_Squared(vec1, vec2)); } 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); } -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 dirY = point->Y - origin->Y; - point->X = dirX * cos - dirY * sin + origin->X; - point->Y = dirX * sin + dirY * cos + origin->Y; + auto dirX = point.X - origin.X; + auto dirY = point.Y - origin.Y; + point.X = dirX * cos - dirY * sin + origin.X; + point.Y = dirX * sin + dirY * cos + origin.Y; } 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; distanceType = 0; } - newDistance = ray_intersect_circle(ray1, &TFlipperEdge::circlebase); + newDistance = ray_intersect_circle(*ray1, TFlipperEdge::circlebase); if (newDistance < distance) { distance = newDistance; distanceType = 2; } - newDistance = ray_intersect_circle(ray1, &TFlipperEdge::circleT1); + newDistance = ray_intersect_circle(*ray1, TFlipperEdge::circleT1); if (newDistance < distance) { 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; } ray2->Direction.Y = dirY; - normalize_2d(&ray2->Direction); + normalize_2d(ray2->Direction); return distance; } - ray2->Direction = TFlipperEdge::lineB.PerpendicularL; + ray2->Direction = TFlipperEdge::lineB.PerpendicularC; nextOrigin = &TFlipperEdge::lineB.RayIntersect; } else { - ray2->Direction = TFlipperEdge::lineA.PerpendicularL; + ray2->Direction = TFlipperEdge::lineA.PerpendicularC; nextOrigin = &TFlipperEdge::lineA.RayIntersect; } ray2->Origin = *nextOrigin; @@ -406,20 +348,22 @@ float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2) return 1000000000.0; } -void maths::RotateVector(vector2* vec, float angle) +void maths::RotateVector(vector2& vec, float angle) { float s = sin(angle), c = cos(angle); - vec->X = c * vec->X - s * vec->Y; - vec->Y = s * vec->X + c * vec->Y; + vec.X = c * vec.X - s * vec.Y; + vec.Y = s * vec.X + c * vec.Y; /* Error in the original, should be: - * tmp = c * vec->X - s * vec->Y; - * vec->Y = s * vec->X + c * vec->Y; - * vec->X = tmp + * auto newX = c * vec.X - s * vec.Y; + * vec.Y = s * vec.X + c * vec.Y; + * 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, - vector2** lineStart) +void maths::find_closest_edge(ramp_plane_type* planes, int planeCount, wall_point_type* wall, vector2& lineEnd, + vector2& lineStart) { vector2 wallEnd{}, wallStart{}; @@ -429,35 +373,22 @@ void maths::find_closest_edge(ramp_plane_type* plane, int planeCount, wall_point wallEnd.X = wall->X1; float maxDistance = 1000000000.0f; - ramp_plane_type* planePtr = plane; for (auto index = 0; index < planeCount; index++) { - auto vec1 = &planePtr->V1, - vec2 = &planePtr->V2, - vec3 = &planePtr->V3; - auto distance = Distance(&wallStart, vec1) + Distance(&wallEnd, vec2); - if (distance < maxDistance) - { - maxDistance = distance; - *lineEnd = vec1; - *lineStart = vec2; - } + auto& plane = planes[index]; + vector2* pointOrder[4] = { &plane.V1, &plane.V2, &plane.V3, &plane.V1 }; - distance = Distance(&wallStart, vec2) + Distance(&wallEnd, vec3); - if (distance < maxDistance) + for (auto pt = 0; pt < 3; pt++) { - maxDistance = distance; - *lineEnd = vec2; - *lineStart = vec3; - } + auto& point1 = *pointOrder[pt], point2 = *pointOrder[pt + 1]; - distance = Distance(&wallStart, vec3) + Distance(&wallEnd, vec1); - if (distance < maxDistance) - { - maxDistance = distance; - *lineEnd = vec3; - *lineStart = vec1; + auto distance = Distance(wallStart, point1) + Distance(wallEnd, point2); + if (distance < maxDistance) + { + maxDistance = distance; + lineEnd = point1; + lineStart = point2; + } } - ++planePtr; } } diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h index 87ed98a..b9a85d8 100644 --- a/SpaceCadetPinball/maths.h +++ b/SpaceCadetPinball/maths.h @@ -6,6 +6,15 @@ struct vector2 { float X; 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 @@ -40,11 +49,11 @@ struct ray_type struct line_type { - vector2 PerpendicularL; + vector2 PerpendicularC; vector2 Direction; - float PreComp1; - float OriginX; - float OriginY; + vector2 Origin; + float MinCoord; + float MaxCoord; vector2 RayIntersect; }; @@ -71,27 +80,27 @@ struct ramp_plane_type class maths { public: - static void enclosing_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect); - static int rectangle_clip(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect); - static int overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect); - static float ray_intersect_circle(ray_type* ray, circle_type* circle); - static float normalize_2d(vector2* vec); + static void enclosing_box(const rectangle_type& rect1, const rectangle_type& rect2, rectangle_type& dstRect); + static bool rectangle_clip(const rectangle_type& rect1, const rectangle_type& rect2, rectangle_type* dstRect); + static float ray_intersect_circle(const ray_type& ray, const circle_type& circle); + static float normalize_2d(vector2& vec); static void line_init(line_type* line, float x0, float y0, float x1, float y1); static float ray_intersect_line(ray_type* ray, line_type* line); - static void cross(vector3* vec1, vector3* vec2, vector3* dstVec); - static float magnitude(vector3* vec); - static void vector_add(vector2* vec1Dst, vector2* vec2); + static void cross(const vector3& vec1, const vector3& vec2, vector3& dstVec); + static float cross(const vector2& vec1, const 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, float smoothness, float threshold, float boost); - static float Distance_Squared(vector2& vec1, vector2& vec2); - static float DotProduct(vector2* vec1, vector2* vec2); - static void vswap(vector2* vec1, vector2* vec2); - static float Distance(vector2* vec1, vector2* vec2); + static float Distance_Squared(const vector2& vec1, const vector2& vec2); + static float DotProduct(const vector2& vec1, const vector2& vec2); + static float Distance(const vector2& vec1, const vector2& vec2); 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 void RotateVector(vector2* vec, float angle); - static void find_closest_edge(ramp_plane_type* plane, int planeCount, wall_point_type* wall, vector2** lineEnd, - vector2** lineStart); + static void RotateVector(vector2& vec, float angle); + static void find_closest_edge(ramp_plane_type* plane, int planeCount, wall_point_type* wall, vector2& lineEnd, + vector2& lineStart); }; diff --git a/SpaceCadetPinball/nudge.cpp b/SpaceCadetPinball/nudge.cpp index 7a69eed..9c5a456 100644 --- a/SpaceCadetPinball/nudge.cpp +++ b/SpaceCadetPinball/nudge.cpp @@ -75,8 +75,8 @@ void nudge::_nudge(float xDiff, float yDiff) { 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); + maths::vector_add(ball->Acceleration, accelMod); + ball->Speed = maths::normalize_2d(ball->Acceleration); if (ball->Acceleration.X == 0.0f) invAccelX = 1000000000.0; else diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index e5a73ac..839b9c2 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -243,7 +243,7 @@ void pb::ballset(float dx, float dy) TBall* ball = MainTable->BallList.at(0); ball->Acceleration.X = dx * 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) @@ -313,8 +313,8 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls) 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); + 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; } @@ -623,7 +623,7 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball) ball->RayMaxDistance = maxDistance; positionMod.X = maxDistance * ball->Acceleration.X; positionMod.Y = maxDistance * ball->Acceleration.Y; - maths::vector_add(&ball->Position, &positionMod); + maths::vector_add(ball->Position, positionMod); } else { diff --git a/SpaceCadetPinball/proj.cpp b/SpaceCadetPinball/proj.cpp index ec73fda..c53ddc7 100644 --- a/SpaceCadetPinball/proj.cpp +++ b/SpaceCadetPinball/proj.cpp @@ -38,7 +38,7 @@ float proj::z_distance(vector3* vec) { vector3 dstVec{}; matrix_vector_multiply(&matrix, vec, &dstVec); - return maths::magnitude(&dstVec); + return maths::magnitude(dstVec); } void proj::xform_to_2d(vector3* vec, int* dst) diff --git a/SpaceCadetPinball/render.cpp b/SpaceCadetPinball/render.cpp index 432576f..78c94b5 100644 --- a/SpaceCadetPinball/render.cpp +++ b/SpaceCadetPinball/render.cpp @@ -76,15 +76,15 @@ void render::update() { case VisualTypes::Sprite: 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; else curSprite->DirtyRect.Width = -1; break; 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; else curSprite->DirtyRect.Width = -1; @@ -291,7 +291,7 @@ void render::repaint(struct render_sprite_type_struct* sprite) { 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( clipRect.Width, clipRect.Height, @@ -334,7 +334,7 @@ void render::paint_balls() { auto ball = ball_list[index]; 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 yPos = dirty->YPosition; @@ -407,7 +407,7 @@ void render::build_occlude_list() { if (!refSprite->UnknownFlag && refSprite->BoundingRect.Width != -1 - && maths::rectangle_clip(&mainSprite->BoundingRect, &refSprite->BoundingRect, nullptr) + && maths::rectangle_clip(mainSprite->BoundingRect, refSprite->BoundingRect, nullptr) && spriteArr) { spriteArr->push_back(refSprite);