diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index bd26638..5aa3f46 100644 Binary files a/Doc/FuncStats.xlsx and b/Doc/FuncStats.xlsx differ diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj b/SpaceCadetPinball/SpaceCadetPinball.vcxproj index 91c58c3..87e3db8 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj @@ -189,6 +189,7 @@ + @@ -258,6 +259,7 @@ + diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters index 57f0cf1..8a4faae 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters @@ -219,6 +219,9 @@ Header Files\TPinballComponent + + Header Files + @@ -404,6 +407,9 @@ Source Files\TPinballComponent + + Source Files + diff --git a/SpaceCadetPinball/TFlipperEdge.cpp b/SpaceCadetPinball/TFlipperEdge.cpp new file mode 100644 index 0000000..a32f9d9 --- /dev/null +++ b/SpaceCadetPinball/TFlipperEdge.cpp @@ -0,0 +1,512 @@ +#include "pch.h" +#include "TFlipperEdge.h" + + +#include "TLine.h" +#include "TPinballTable.h" +#include "TTableLayer.h" + +float TFlipperEdge::flipper_sin_angle, TFlipperEdge::flipper_cos_angle; +vector_type TFlipperEdge::A1, TFlipperEdge::A2, TFlipperEdge::B1, TFlipperEdge::B2, TFlipperEdge::T1; +line_type TFlipperEdge::lineA, TFlipperEdge::lineB; +circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1; + +TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag, TPinballTable* table, + vector_type* origin, vector_type* vecT, vector_type* vec3, float bmpCoef1, float bmpCoef2, + float a11, float c4F, float c5F): TEdgeSegment(collComp, someFlag, visualFlag) +{ + vector_type crossProd{}, vecDir1{}, vecDir2{}; + + CollisionC4F = c4F; + CollisionC5F = c5F; + BmpCoef1 = bmpCoef1; + BmpCoef2 = bmpCoef2; + Unknown32F = a11; + + T1Src = *vecT; + Unknown36V = *vec3; + RotOrigin.X = origin->X; + RotOrigin.Y = origin->Y; + + CirclebaseRadius = origin->Z + table->CollisionCompOffset; + CirclebaseRadiusMSq = CirclebaseRadius * 1.01f * (CirclebaseRadius * 1.01f); + CirclebaseRadiusSq = CirclebaseRadius * CirclebaseRadius; + + CircleT1Radius = vecT->Z + table->CollisionCompOffset; + CircleT1RadiusMSq = CircleT1Radius * 1.01f * (CircleT1Radius * 1.01f); + CircleT1RadiusSq = CircleT1Radius * CircleT1Radius; + + vecDir1.X = vecT->X - origin->X; + vecDir1.Y = vecT->Y - origin->Y; + vecDir1.Z = 0.0; + maths::normalize_2d(&vecDir1); + + vecDir2.X = vec3->X - origin->X; + vecDir2.Y = vec3->Y - origin->Y; + vecDir2.Z = 0.0; + maths::normalize_2d(&vecDir2); + + AngleMax = acos(maths::DotProduct(&vecDir1, &vecDir2)); + maths::cross(&vecDir1, &vecDir2, &crossProd); + if (crossProd.Z < 0.0) + AngleMax = -AngleMax; + FlipperFlag = 0; + Angle1 = 0.0; + + auto dirX1 = vecDir1.X; + auto dirY1 = -vecDir1.Y; + A2Src.X = dirY1 * CirclebaseRadius + origin->X; + A2Src.Y = dirX1 * CirclebaseRadius + origin->Y; + A1Src.X = dirY1 * CircleT1Radius + vecT->X; + A1Src.Y = dirX1 * CircleT1Radius + vecT->Y; + + dirX1 = -dirX1; + dirY1 = -dirY1; + B1Src.X = dirY1 * CirclebaseRadius + origin->X; + B1Src.Y = dirX1 * CirclebaseRadius + origin->Y; + B2Src.X = dirY1 * CircleT1Radius + vecT->X; + B2Src.Y = dirX1 * CircleT1Radius + vecT->Y; + + if (AngleMax < 0.0) + { + maths::vswap(&A1Src, &B1Src); + maths::vswap(&A2Src, &B2Src); + } + + auto dx = vecT->X - RotOrigin.X; + auto dy = vecT->Y - RotOrigin.Y; + auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT->Z; + DistanceDivSq = distance1 * distance1; + + float bmpCoef = min(BmpCoef1, BmpCoef2); + auto distance = maths::Distance(vecT, vec3); + Unknown40F = bmpCoef / (distance / CircleT1Radius + distance / CircleT1Radius); + + TFlipperEdge::place_in_grid(); + Unknown44 = 0; + TimeAngle = 0.0; + Unknown15 = 0; + Unknown46F = 0.0; + AngleMult = 0.0; +} + +void TFlipperEdge::port_draw() +{ + set_control_points(TimeAngle); + build_edges_in_motion(); +} + +float TFlipperEdge::FindCollisionDistance(ray_type* ray) +{ + auto ogRay = ray; + + + float* pfVar2; + short uVar3; + int iVar4; + int uVar5; + vector_type* prVar6; + vector_type* plVar6; + vector_type* pvVar7; + float fVar8; + ray_type ray2; + ray_type ray1; + float local_1c; + float local_18; + float local_14; + float local_10; + float local_c; + float local_8; + + if (ogRay->TimeNow > this->Unknown46F) { + this->FlipperFlag = 0; + } + if (this->Unknown44 == 0) { + if (this->FlipperFlag == 0) { + this->Unknown44 = 0; + this->Unknown15 = 0; + this->Unknown16 = 0; + set_control_points( ogRay->TimeNow); + build_edges_in_motion(); + iVar4 = is_ball_inside( (ogRay->Origin).X, (ogRay->Origin).Y); + ray1.MinDistance = ogRay->MinDistance; + if (iVar4 == 0) { + ray1.Direction.X = (ogRay->Direction).X; + ray1.Direction.Y = (ogRay->Direction).Y; + ray1.Direction.Z = (ogRay->Direction).Z; + ray1.MaxDistance = ogRay->MaxDistance; + ray1.Origin.X = (ogRay->Origin).X; + ray1.Origin.Y = (ogRay->Origin).Y; + ray1.Origin.Z = (ogRay->Origin).Z; + fVar8 = maths::distance_to_flipper(&ray1, &ray2); + plVar6 = &ray2.Origin; + if (fVar8 == 0.0) { + pvVar7 = &this->NextBallPosition; + pvVar7->X = ray2.Origin.X; + (this->NextBallPosition).Y = ray2.Origin.Y; + (this->NextBallPosition).Z = ray2.Origin.Z; + pvVar7->X = pvVar7->X - ray1.Direction.X * 1e-05f; + pfVar2 = &(this->NextBallPosition).Y; + *pfVar2 = *pfVar2 - ray1.Direction.Y * 1e-05f; + } + else { + pvVar7 = &this->NextBallPosition; + LAB_0101bab7: + pvVar7->X = (plVar6)->X; + pvVar7->Y = (plVar6)->Y; + pvVar7->Z = (plVar6)->Z; + } + (this->CollisionDirection).X = ray2.Direction.X; + (this->CollisionDirection).Y = ray2.Direction.Y; + (this->CollisionDirection).Z = ray2.Direction.Z; + return fVar8; + } + fVar8 = maths::Distance_Squared(ogRay->Origin, this->RotOrigin); + if (this->CirclebaseRadiusMSq <= fVar8) { + fVar8 = maths::Distance_Squared(ogRay->Origin, T1); + if (this->CircleT1RadiusMSq <= fVar8) { + ray1.Direction.Y = lineB.PerpendicularL.Y; + ray1.Direction.X = lineB.PerpendicularL.X; + if (iVar4 == 4) { + ray1.Direction.Y = lineA.PerpendicularL.Y; + ray1.Direction.X = lineA.PerpendicularL.X; + } + ray1.Direction.X = -ray1.Direction.X; + ray1.Direction.Y = -ray1.Direction.Y; + } + else { + ray1.Direction.X = T1.X - (ogRay->Origin).X; + ray1.Direction.Y = T1.Y - (ogRay->Origin).Y; + maths::normalize_2d(&ray1.Direction); + } + } + else { + ray1.Direction.X = (this->RotOrigin).X - (ogRay->Origin).X; + ray1.Direction.Y = (this->RotOrigin).Y - (ogRay->Origin).Y; + maths::normalize_2d(&ray1.Direction); + } + ray1.Origin.X = (ogRay->Origin).X - ray1.Direction.X * 5.0f; + ray1.Origin.Y = (ogRay->Origin).Y - ray1.Direction.Y * 5.0f; + ray1.MaxDistance = ogRay->MaxDistance + 10.0f; + fVar8 = maths::distance_to_flipper(&ray1, &ray2); + if (1e+09 <= fVar8) { + ray1.Direction.X = (this->RotOrigin).X - (ogRay->Origin).X; + ray1.Direction.Y = (this->RotOrigin).Y - (ogRay->Origin).Y; + maths::normalize_2d(&ray1.Direction); + ray1.Origin.X = (ogRay->Origin).X - ray1.Direction.X * 5.0f; + ray1.Origin.Y = (ogRay->Origin).Y - ray1.Direction.Y * 5.0f; + fVar8 = maths::distance_to_flipper(&ray1, &ray2); + if (1e+09 <= fVar8) { + return 1e+09; + } + } + LAB_0101ba1a: + (this->NextBallPosition).X = ray2.Origin.X; + (this->NextBallPosition).Y = ray2.Origin.Y; + (this->NextBallPosition).Z = ray2.Origin.Z; + pvVar7 = &this->CollisionDirection; + prVar6 = &ray2.Direction; + LAB_0101bc82: + pvVar7->X = prVar6->X; + pvVar7->Y = prVar6->Y; + pvVar7->Z = prVar6->Z; + (this->NextBallPosition).X = (this->NextBallPosition).X - ray1.Direction.X * 1e-05; + pfVar2 = &(this->NextBallPosition).Y; + *pfVar2 = *pfVar2 - ray1.Direction.Y * 1e-05; + return 0.0; + } + local_8 = (ogRay->Origin).X; + local_14 = this->Unknown40F * ogRay->MaxDistance; + local_c = (ogRay->Origin).Y; + local_10 = ogRay->TimeNow; + local_18 = this->Unknown40F * (ogRay->Direction).X; + local_1c = (ogRay->Direction).Y * this->Unknown40F; + fVar8 = ogRay->TimeDelta + ogRay->TimeNow; + uVar3 = fVar8 <= local_10;// fp flag shift + while (uVar3 == 0) { + set_control_points( local_10); + build_edges_in_motion(); + iVar4 = is_ball_inside( local_8, local_c); + if (iVar4 != 0) { + if ((this->FlipperFlag == 1) && (iVar4 != 5)) { + plVar6 = &lineA.PerpendicularL; + ray1.Direction.Y = lineA.PerpendicularL.Y; + ray1.Direction.X = lineA.PerpendicularL.X; + } + else { + if ((this->FlipperFlag != 2) || (iVar4 == 4)) { + ray1.Direction.X = (this->RotOrigin).X - local_8; + this->Unknown15 = 0; + this->Unknown16 = 1; + ray1.Direction.Y = (this->RotOrigin).Y - local_c; + maths::normalize_2d(&ray1.Direction); + ray1.Origin.X = local_8 - ray1.Direction.X * 5.0f; + ray1.Origin.Y = local_c - ray1.Direction.Y * 5.0f; + ray1.MaxDistance = ogRay->MaxDistance + 10.0f; + fVar8 = maths::distance_to_flipper(&ray1, &ray2); + if (1e+09 <= fVar8) { + (this->NextBallPosition).X = local_8; + (this->CollisionDirection).X = -ray1.Direction.X; + (this->NextBallPosition).Y = local_c; + (this->CollisionDirection).Y = -ray1.Direction.Y; + return 0.0; + } + goto LAB_0101ba1a; + } + plVar6 = &lineB.PerpendicularL; + ray1.Direction.Y = lineB.PerpendicularL.Y; + ray1.Direction.X = lineB.PerpendicularL.X; + } + ray1.Direction.X = -ray1.Direction.X; + ray1.Direction.Y = -ray1.Direction.Y; + (this->Unknown17V).X = plVar6->X; + (this->Unknown17V).Y = plVar6->Y; + (this->Unknown17V).Z = plVar6->Z; + this->Unknown16 = 0; + this->Unknown15 = 1; + ray1.MinDistance = 0.002; + ray1.Origin.X = (ogRay->Origin).X - ray1.Direction.X * 5.0f; + ray1.Origin.Y = (ogRay->Origin).Y - ray1.Direction.Y * 5.0f; + ray1.MaxDistance = ogRay->MaxDistance + 10.0f; + fVar8 = maths::distance_to_flipper(&ray1, &ray2); + (this->CollisionDirection).X = ray2.Direction.X; + (this->CollisionDirection).Y = ray2.Direction.Y; + (this->CollisionDirection).Z = ray2.Direction.Z; + if (1e+09 <= fVar8) { + return 1e+09; + } + pvVar7 = &this->NextBallPosition; + prVar6 = &ray2.Origin; + goto LAB_0101bc82; + } + ray1.Direction.X = (ogRay->Direction).X; + ray1.Direction.Y = (ogRay->Direction).Y; + ray1.Direction.Z = (ogRay->Direction).Z; + ray1.MinDistance = ogRay->MinDistance; + ray1.Origin.X = (ogRay->Origin).X; + ray1.Origin.Y = (ogRay->Origin).Y; + ray1.Origin.Z = (ogRay->Origin).Z; + ray1.MaxDistance = local_14; + fVar8 = maths::distance_to_flipper(&ray1, &ray2); + if (fVar8 < 1e+09) { + pvVar7 = &this->NextBallPosition; + pvVar7->X = ray2.Origin.X; + (this->NextBallPosition).Y = ray2.Origin.Y; + (this->NextBallPosition).Z = ray2.Origin.Z; + pvVar7->X = pvVar7->X - ray1.Direction.X * 1e-05f; + pfVar2 = &(this->NextBallPosition).Y; + *pfVar2 = *pfVar2 - ray1.Direction.Y * 1e-05f; + uVar5 = this->AngleMax > 0.0; + pvVar7 = &this->Unknown17V; + if (this->FlipperFlag == 2) { + plVar6 = &lineB.PerpendicularL; + this->Unknown15 = (uVar5 == 0); + } + else { + this->Unknown15 = uVar5; + plVar6 = &lineA.PerpendicularL; + } + goto LAB_0101bab7; + } + local_10 = local_10 + this->Unknown40F; + local_8 = local_8 + local_18; + local_c = local_c + local_1c; + fVar8 = ogRay->TimeDelta + ogRay->TimeNow; + uVar3 = fVar8 <= local_10; + } + } + else { + this->Unknown44 = 0; + } + return 1e+09; +} + +void TFlipperEdge::EdgeCollision(TBall* ball, float coef) +{ + Unknown44 = 1; + if (!FlipperFlag || !Unknown16 || Unknown15) + { + float collMult = 0.0; + if (Unknown15) + { + float dx = NextBallPosition.X - RotOrigin.X; + float dy = NextBallPosition.Y - RotOrigin.Y; + float distance = dy * dy + dx * dx; + if (circlebase.RadiusSq * 1.01 < distance) + { + float v11; + float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult); + float dot1 = maths::DotProduct(&Unknown17V, &CollisionDirection); + if (dot1 >= 0.0) + v11 = dot1 * v20; + else + v11 = 0.0; + collMult = v11 * Unknown32F; + } + } + + float maxSpeed = collMult <= 0.0 ? 1000000000.0f : -1.0f; + maths::basic_collision( + ball, + &NextBallPosition, + &CollisionDirection, + CollisionC4F, + CollisionC5F, + maxSpeed, + collMult); + return; + } + + float c4F; + float dx = NextBallPosition.X - RotOrigin.X; + float dy = NextBallPosition.Y - RotOrigin.Y; + float distance = dy * dy + dx * dx; + if (circlebase.RadiusSq * 1.01 < distance) + c4F = (1.0f - sqrt(distance / DistanceDivSq)) * CollisionC4F; + else + c4F = CollisionC4F; + maths::basic_collision(ball, &NextBallPosition, &CollisionDirection, c4F, CollisionC5F, 1000000000.0, 0.0); +} + +void TFlipperEdge::place_in_grid() +{ + float x0 = RotOrigin.X - CirclebaseRadius; + float y0 = RotOrigin.Y - CirclebaseRadius; + float x1 = CirclebaseRadius + RotOrigin.X; + + float v1 = RotOrigin.Y + CirclebaseRadius; + float v2 = T1Src.X - CircleT1Radius; + if (v2 < x0) + x0 = v2; + + float v3 = T1Src.Y - CircleT1Radius; + if (v3 < y0) + y0 = v3; + + float v4 = CircleT1Radius + T1Src.X; + if (v4 > x1) + x1 = v4; + + float v5 = T1Src.Y + CircleT1Radius; + if (v5 > v1) + v1 = v5; + + float v6 = Unknown36V.X - CircleT1Radius; + if (v6 < x0) + x0 = v6; + + float v7 = Unknown36V.Y - CircleT1Radius; + if (v7 < y0) + y0 = v7; + + float v8 = Unknown36V.X + CircleT1Radius; + if (v8 > x1) + x1 = v8; + + float v9 = CircleT1Radius + Unknown36V.Y; + if (v9 > v1) + v1 = v9; + + float y1 = v1; + TTableLayer::edges_insert_square(y0, x0, y1, x1, this, nullptr); +} + +void TFlipperEdge::set_control_points(float timeNow) +{ + maths::SinCos(flipper_angle(timeNow), &flipper_sin_angle, &flipper_cos_angle); + A1 = A1Src; + A2 = A2Src; + 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); +} + +void TFlipperEdge::build_edges_in_motion() +{ + maths::line_init(&lineA, A1.X, A1.Y, A2.X, A2.Y); + maths::line_init(&lineB, B1.X, B1.Y, B2.X, B2.Y); + circlebase.RadiusSq = CirclebaseRadiusSq; + circlebase.Center.X = RotOrigin.X; + circlebase.Center.Y = RotOrigin.Y; + circleT1.RadiusSq = CircleT1RadiusSq; + circleT1.Center.X = T1.X; + circleT1.Center.Y = T1.Y; +} + +float TFlipperEdge::flipper_angle(float timeNow) +{ + if (!FlipperFlag) + return Angle1; + float angle = (Angle1 - Angle2) / AngleMax * AngleMult; + if (angle < 0.0) + angle = -angle; + + if (angle >= 0.0000001) + angle = (timeNow - TimeAngle) / angle; + else + angle = 1.0; + + angle = min(1, max(angle, 0)); + if (FlipperFlag == 2) + angle = 1.0f - angle; + return angle * AngleMax; +} + +int TFlipperEdge::is_ball_inside(float x, float y) +{ + vector_type ptTest{}; + float dx = RotOrigin.X - x; + float dy = RotOrigin.Y - y; + if ((A2.X - A1.X) * (y - A1.Y) - (A2.Y - A1.Y) * (x - A1.X) >= 0.0 && + (B1.X - A2.X) * (y - A2.Y) - (B1.Y - A2.Y) * (x - A2.X) >= 0.0 && + (B2.X - B1.X) * (y - B1.Y) - (B2.Y - B1.Y) * (x - B1.X) >= 0.0 && + (A1.X - B2.X) * (y - B2.Y) - (A1.Y - B2.Y) * (x - B2.X) >= 0.0 || + dy * dy + dx * dx <= CirclebaseRadiusSq || + (T1.Y - y) * (T1.Y - y) + (T1.X - x) * (T1.X - x) < CircleT1RadiusSq) + { + if (FlipperFlag == 1) + ptTest = AngleMax < 0.0 ? B1 : B2; + else if (FlipperFlag == 2) + ptTest = AngleMax < 0.0 ? A2 : A1; + else + ptTest = T1; + + if ((y - ptTest.Y) * (RotOrigin.X - ptTest.X) - + (x - ptTest.X) * (RotOrigin.Y - ptTest.Y) >= 0.0f) + return 4; + return 5; + } + return 0; +} + +void TFlipperEdge::SetMotion(int code, float value) +{ + switch (code) + { + case 1: + this->Angle2 = flipper_angle(value); + this->Angle1 = this->AngleMax; + this->AngleMult = this->BmpCoef1; + break; + case 2: + this->Angle2 = flipper_angle(value); + this->Angle1 = 0.0; + this->AngleMult = this->BmpCoef2; + break; + case 1024: + this->FlipperFlag = 0; + this->Angle1 = 0.0; + return; + default: break; + } + + if (!this->FlipperFlag) + this->TimeAngle = value; + this->FlipperFlag = code; + this->Unknown46F = this->AngleMult + this->TimeAngle; +} diff --git a/SpaceCadetPinball/TFlipperEdge.h b/SpaceCadetPinball/TFlipperEdge.h new file mode 100644 index 0000000..c19f366 --- /dev/null +++ b/SpaceCadetPinball/TFlipperEdge.h @@ -0,0 +1,61 @@ +#pragma once +#include "maths.h" +#include "TEdgeSegment.h" + +class TPinballTable; + +class TFlipperEdge : public TEdgeSegment +{ +public: + TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag, TPinballTable* table, + vector_type* origin, vector_type* vecT, vector_type* vec3, float bmpCoef1, float bmpCoef2, float a11, + float c4F, float c5F); + void port_draw() override; + float FindCollisionDistance(ray_type* ray) override; + void EdgeCollision(TBall* ball, float coef) override; + void place_in_grid() override; + void set_control_points(float timeNow); + void build_edges_in_motion(); + float flipper_angle(float timeNow); + int is_ball_inside(float x, float y); + void SetMotion(int code, float value); + + int FlipperFlag; + float CollisionC4F; + float CollisionC5F; + vector_type RotOrigin; + float CirclebaseRadius; + float CircleT1Radius; + float CirclebaseRadiusSq; + float CircleT1RadiusSq; + float CirclebaseRadiusMSq; + float CircleT1RadiusMSq; + float AngleMax; + float Angle2; + float Angle1; + int Unknown15; + int Unknown16; + vector_type Unknown17V; + vector_type A1Src; + vector_type A2Src; + vector_type B1Src; + vector_type B2Src; + float Unknown32F; + vector_type T1Src; + vector_type Unknown36V; + float DistanceDivSq; + float Unknown40F; + vector_type CollisionDirection; + int Unknown44; + float TimeAngle; + float Unknown46F; + float AngleMult; + float BmpCoef1; + float BmpCoef2; + vector_type NextBallPosition; + + static float flipper_sin_angle, flipper_cos_angle; + static vector_type A1, A2, B1, B2, T1; + static line_type lineA, lineB; + static circle_type circlebase, circleT1; +}; diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp index 3591832..0623913 100644 --- a/SpaceCadetPinball/maths.cpp +++ b/SpaceCadetPinball/maths.cpp @@ -268,7 +268,8 @@ void maths::vector_add(vector_type* vec1Dst, vector_type* vec2) vec1Dst->Y += vec2->Y; } -float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float a4, float a5, float maxSpeed, +float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float a4, float a5, + float maxSpeed, float multiplier) { ball->Position.X = nextPosition->X; @@ -304,3 +305,41 @@ float maths::Distance_Squared(vector_type vec1, vector_type vec2) { return (vec1.Y - vec2.Y) * (vec1.Y - vec2.Y) + (vec1.X - vec2.X) * (vec1.X - vec2.X); } + +float maths::DotProduct(vector_type* vec1, vector_type* vec2) +{ + return vec1->Y * vec2->Y + vec1->X * vec2->X; +} + +void maths::vswap(vector_type* vec1, vector_type* vec2) +{ + vector_type tmp = *vec1; + *vec1 = *vec2; + *vec2 = tmp; +} + +float maths::Distance(vector_type* vec1, vector_type* 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) +{ + *sinOut = sin(angle); + *cosOut = cos(angle); +} + +void maths::RotatePt(vector_type* point, float sin, float cos, vector_type* 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; +} + +float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2) +{ + return 0; +} diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h index a1fd4a1..092cfdd 100644 --- a/SpaceCadetPinball/maths.h +++ b/SpaceCadetPinball/maths.h @@ -62,4 +62,10 @@ public: static float basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float a4, float a5, float maxSpeed, float multiplier); static float Distance_Squared(vector_type vec1, vector_type vec2); + static float DotProduct(vector_type* vec1, vector_type* vec2); + static void vswap(vector_type* vec1, vector_type* vec2); + static float Distance(vector_type* vec1, vector_type* vec2); + static void SinCos(float angle, float* sinOut, float* cosOut); + static void RotatePt(vector_type* point, float sin, float cos, vector_type* origin); + static float distance_to_flipper(ray_type* ray1, ray_type* ray2); };