mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-11-17 15:20:17 +01:00
Cleaning up maths: part 4.
More by ref args, cleaned up distance_to_flipper, ramp init.
This commit is contained in:
parent
fdf1f6c9f1
commit
2d2ca0ab2a
6 changed files with 153 additions and 177 deletions
|
@ -120,7 +120,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.Direction = ogRay->Direction;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance;
|
||||
srcRay.Origin = ogRay->Origin;
|
||||
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
||||
auto distance = maths::distance_to_flipper(srcRay, dstRay);
|
||||
if (distance == 0.0f)
|
||||
{
|
||||
NextBallPosition = dstRay.Origin;
|
||||
|
@ -166,14 +166,14 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09f)
|
||||
if (maths::distance_to_flipper(srcRay, dstRay) >= 1e+09f)
|
||||
{
|
||||
srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X;
|
||||
srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y;
|
||||
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)
|
||||
if (maths::distance_to_flipper(srcRay, dstRay) >= 1e+09f)
|
||||
{
|
||||
return 1e+09;
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.Origin.X = posX - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = posY - srcRay.Direction.Y * 5.0f;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09f)
|
||||
if (maths::distance_to_flipper(srcRay, dstRay) >= 1e+09f)
|
||||
{
|
||||
NextBallPosition.X = posX;
|
||||
NextBallPosition.Y = posY;
|
||||
|
@ -249,7 +249,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
||||
auto distance = maths::distance_to_flipper(srcRay, dstRay);
|
||||
CollisionDirection = dstRay.Direction;
|
||||
if (distance >= 1e+09f)
|
||||
{
|
||||
|
@ -265,7 +265,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.MinDistance = ogRay->MinDistance;
|
||||
srcRay.Origin = ogRay->Origin;
|
||||
srcRay.MaxDistance = rayMaxDistance;
|
||||
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
||||
auto distance = maths::distance_to_flipper(srcRay, dstRay);
|
||||
if (distance < 1e+09f)
|
||||
{
|
||||
NextBallPosition = dstRay.Origin;
|
||||
|
@ -389,7 +389,7 @@ void TFlipperEdge::place_in_grid()
|
|||
|
||||
void TFlipperEdge::set_control_points(float timeNow)
|
||||
{
|
||||
maths::SinCos(flipper_angle(timeNow), &flipper_sin_angle, &flipper_cos_angle);
|
||||
maths::SinCos(flipper_angle(timeNow), flipper_sin_angle, flipper_cos_angle);
|
||||
A1 = A1Src;
|
||||
A2 = A2Src;
|
||||
B1 = B1Src;
|
||||
|
@ -404,8 +404,8 @@ void TFlipperEdge::set_control_points(float timeNow)
|
|||
|
||||
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);
|
||||
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;
|
||||
|
|
|
@ -11,7 +11,7 @@ TLine::TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collis
|
|||
Y0 = y0;
|
||||
X1 = x1;
|
||||
Y1 = y1;
|
||||
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, const vector2& start,
|
||||
|
@ -21,7 +21,7 @@ TLine::TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collis
|
|||
Y0 = start.Y;
|
||||
X1 = end.X;
|
||||
Y1 = end.Y;
|
||||
maths::line_init(&Line, X0, Y0, X1, Y1);
|
||||
maths::line_init(Line, X0, Y0, X1, Y1);
|
||||
}
|
||||
|
||||
void TLine::Offset(float offset)
|
||||
|
@ -33,12 +33,12 @@ void TLine::Offset(float offset)
|
|||
Y0 += offY;
|
||||
X1 += offX;
|
||||
Y1 += offY;
|
||||
maths::line_init(&Line, X0, Y0, X1, Y1);
|
||||
maths::line_init(Line, X0, Y0, X1, Y1);
|
||||
}
|
||||
|
||||
float TLine::FindCollisionDistance(ray_type* ray)
|
||||
{
|
||||
return maths::ray_intersect_line(ray, &Line);
|
||||
return maths::ray_intersect_line(*ray, Line);
|
||||
}
|
||||
|
||||
void TLine::EdgeCollision(TBall* ball, float coef)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||
{
|
||||
visualStruct visual{};
|
||||
vector2 end{}, start{}, end2{}, start2{}, start3{}, end3{};
|
||||
vector2 wall1End{}, wall1Start{}, wall2Start{}, wall2End{};
|
||||
|
||||
MessageField = 0;
|
||||
UnusedBaseFlag = 1;
|
||||
|
@ -22,60 +22,51 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||
CollisionGroup = visual.CollisionGroup;
|
||||
|
||||
BallFieldMult = loader::query_float_attribute(groupIndex, 0, 701, 0.2f);
|
||||
RampFlag1 = static_cast<int>(loader::query_float_attribute(groupIndex, 0, 1305, 0));
|
||||
BallZOffsetFlag = static_cast<int>(loader::query_float_attribute(groupIndex, 0, 1305, 0));
|
||||
|
||||
auto floatArr3Plane = loader::query_float_attribute(groupIndex, 0, 1300);
|
||||
RampPlaneCount = static_cast<int>(floor(*floatArr3Plane));
|
||||
RampPlane = reinterpret_cast<ramp_plane_type*>(floatArr3Plane + 1);
|
||||
|
||||
auto floatArr4 = loader::query_float_attribute(groupIndex, 0, 1303);
|
||||
end.X = floatArr4[2];
|
||||
end.Y = floatArr4[3];
|
||||
start.X = floatArr4[4];
|
||||
start.Y = floatArr4[5];
|
||||
Line1 = new TLine(this, &ActiveFlag, 1 << static_cast<int>(floor(floatArr4[0])), start, end);
|
||||
auto wall0Arr = loader::query_float_attribute(groupIndex, 0, 1303);
|
||||
auto wall0CollisionGroup = 1 << static_cast<int>(floor(wall0Arr[0]));
|
||||
auto wall0Pts = reinterpret_cast<wall_point_type*>(wall0Arr + 2);
|
||||
Line1 = new TLine(this, &ActiveFlag, wall0CollisionGroup, wall0Pts->Pt1, wall0Pts->Pt0);
|
||||
Line1->WallValue = nullptr;
|
||||
Line1->place_in_grid();
|
||||
EdgeList.push_back(Line1);
|
||||
if (Line1)
|
||||
{
|
||||
Line1->WallValue = nullptr;
|
||||
Line1->place_in_grid();
|
||||
}
|
||||
|
||||
auto floatArr5WallPoint = loader::query_float_attribute(groupIndex, 0, 1301);
|
||||
Wall1PointFirst = 1 << static_cast<int>(floor(floatArr5WallPoint[0]));
|
||||
auto wallPt1_2 = static_cast<int>(floor(floatArr5WallPoint[1]));
|
||||
Wall1PointLast = floatArr5WallPoint[7];
|
||||
auto wall1Arr = loader::query_float_attribute(groupIndex, 0, 1301);
|
||||
Wall1CollisionGroup = 1 << static_cast<int>(floor(wall1Arr[0]));
|
||||
auto wall1Enabled = static_cast<int>(floor(wall1Arr[1]));
|
||||
Wall1BallOffset = wall1Arr[7];
|
||||
maths::find_closest_edge(
|
||||
RampPlane,
|
||||
RampPlaneCount,
|
||||
reinterpret_cast<wall_point_type*>(floatArr5WallPoint + 3),
|
||||
end2,
|
||||
start2);
|
||||
Line2 = new TLine(this, &ActiveFlag, CollisionGroup, start2, end2);
|
||||
reinterpret_cast<wall_point_type*>(wall1Arr + 3),
|
||||
wall1End,
|
||||
wall1Start);
|
||||
|
||||
Line2 = new TLine(this, &ActiveFlag, CollisionGroup, wall1Start, wall1End);
|
||||
Line2->WallValue = nullptr;
|
||||
Line2->place_in_grid();
|
||||
EdgeList.push_back(Line2);
|
||||
if (Line2)
|
||||
{
|
||||
Line2->WallValue = nullptr;
|
||||
Line2->place_in_grid();
|
||||
}
|
||||
|
||||
auto floatArr6WallPoint = loader::query_float_attribute(groupIndex, 0, 1302);
|
||||
auto wall2Pt1_2 = static_cast<int>(floor(floatArr6WallPoint[1]));
|
||||
Wall2PointFirst = 1 << static_cast<int>(floor(floatArr6WallPoint[0]));
|
||||
Wall2PointLast = floatArr6WallPoint[7];
|
||||
auto wall2Arr = loader::query_float_attribute(groupIndex, 0, 1302);
|
||||
Wall2CollisionGroup = 1 << static_cast<int>(floor(wall2Arr[0]));
|
||||
auto wall2Enabled = static_cast<int>(floor(wall2Arr[1]));
|
||||
Wall2BallOffset = wall2Arr[7];
|
||||
maths::find_closest_edge(
|
||||
RampPlane,
|
||||
RampPlaneCount,
|
||||
reinterpret_cast<wall_point_type*>(floatArr6WallPoint + 3),
|
||||
end3,
|
||||
start3);
|
||||
Line3 = new TLine(this, &ActiveFlag, CollisionGroup, start3, end3);
|
||||
reinterpret_cast<wall_point_type*>(wall2Arr + 3),
|
||||
wall2End,
|
||||
wall2Start);
|
||||
|
||||
Line3 = new TLine(this, &ActiveFlag, CollisionGroup, wall2Start, wall2End);
|
||||
Line3->WallValue = nullptr;
|
||||
Line3->place_in_grid();
|
||||
EdgeList.push_back(Line3);
|
||||
if (Line3)
|
||||
{
|
||||
Line3->WallValue = nullptr;
|
||||
Line3->place_in_grid();
|
||||
}
|
||||
|
||||
|
||||
auto xMin = 1000000000.0f;
|
||||
|
@ -96,30 +87,26 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||
{
|
||||
auto& point1 = *pointOrder[pt], point2 = *pointOrder[pt + 1];
|
||||
auto collisionGroup = 0;
|
||||
if (point1 != end2 || point2 != start2)
|
||||
|
||||
if (point1 == wall1End && point2 == wall1Start)
|
||||
{
|
||||
if (point1 != end3 || point2 != start3)
|
||||
{
|
||||
collisionGroup = visual.CollisionGroup;
|
||||
}
|
||||
else if (wall2Pt1_2)
|
||||
{
|
||||
collisionGroup = Wall2PointFirst;
|
||||
}
|
||||
if (wall1Enabled)
|
||||
collisionGroup = Wall1CollisionGroup;
|
||||
}
|
||||
else if (wallPt1_2)
|
||||
else if (point1 == wall2End && point2 == wall2Start)
|
||||
{
|
||||
collisionGroup = Wall1PointFirst;
|
||||
if (wall2Enabled)
|
||||
collisionGroup = Wall2CollisionGroup;
|
||||
}
|
||||
else
|
||||
collisionGroup = visual.CollisionGroup;
|
||||
|
||||
if (collisionGroup)
|
||||
{
|
||||
auto line = new TLine(this, &ActiveFlag, collisionGroup, point1, point2);
|
||||
line->WallValue = &plane;
|
||||
line->place_in_grid();
|
||||
EdgeList.push_back(line);
|
||||
if (line)
|
||||
{
|
||||
line->WallValue = &plane;
|
||||
line->place_in_grid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,17 +173,15 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
|
|||
ball->CollisionFlag = 0;
|
||||
if (edge == Line2)
|
||||
{
|
||||
ball->FieldFlag = Wall1PointFirst;
|
||||
if (!RampFlag1)
|
||||
return;
|
||||
ball->Position.Z = ball->Offset + Wall1PointLast;
|
||||
ball->FieldFlag = Wall1CollisionGroup;
|
||||
if (BallZOffsetFlag)
|
||||
ball->Position.Z = ball->Offset + Wall1BallOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
ball->FieldFlag = Wall2PointFirst;
|
||||
if (!RampFlag1)
|
||||
return;
|
||||
ball->Position.Z = ball->Offset + Wall2PointLast;
|
||||
ball->FieldFlag = Wall2CollisionGroup;
|
||||
if (BallZOffsetFlag)
|
||||
ball->Position.Z = ball->Offset + Wall2BallOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,15 +20,15 @@ public:
|
|||
int Scores[4]{};
|
||||
field_effect_type Field{};
|
||||
int CollisionGroup;
|
||||
int RampFlag1;
|
||||
bool BallZOffsetFlag;
|
||||
int RampPlaneCount;
|
||||
float BallFieldMult;
|
||||
ramp_plane_type* RampPlane;
|
||||
TEdgeSegment* Line2;
|
||||
TEdgeSegment* Line3;
|
||||
TEdgeSegment* Line1;
|
||||
int Wall1PointFirst;
|
||||
int Wall2PointFirst;
|
||||
float Wall1PointLast;
|
||||
float Wall2PointLast;
|
||||
int Wall1CollisionGroup;
|
||||
int Wall2CollisionGroup;
|
||||
float Wall1BallOffset;
|
||||
float Wall2BallOffset;
|
||||
};
|
||||
|
|
|
@ -129,37 +129,38 @@ 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)
|
||||
{
|
||||
line->Origin = { x0, y0 };
|
||||
line->Direction.X = x1 - x0;
|
||||
line->Direction.Y = y1 - y0;
|
||||
normalize_2d(line->Direction);
|
||||
line.Origin = { x0, y0 };
|
||||
line.Direction.X = x1 - x0;
|
||||
line.Direction.Y = y1 - y0;
|
||||
normalize_2d(line.Direction);
|
||||
|
||||
// Clockwise perpendicular to the line direction vector
|
||||
line->PerpendicularC = { line->Direction.Y, -line->Direction.X };
|
||||
line.PerpendicularC = { line.Direction.Y, -line.Direction.X };
|
||||
|
||||
auto lineStart = x0, lineEnd = x1;
|
||||
if (std::abs(line->Direction.X) < 0.000000001f)
|
||||
if (std::abs(line.Direction.X) < 0.000000001f)
|
||||
{
|
||||
line->Direction.X = 0.0;
|
||||
line.Direction.X = 0.0;
|
||||
lineStart = y0;
|
||||
lineEnd = y1;
|
||||
}
|
||||
|
||||
line->MinCoord = std::min(lineStart, lineEnd);
|
||||
line->MaxCoord = std::max(lineStart, lineEnd);
|
||||
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)
|
||||
// Stores ray-line intersection point in line.RayIntersect
|
||||
float maths::ray_intersect_line(const ray_type& ray, line_type& line)
|
||||
{
|
||||
// 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 };
|
||||
auto v1 = vector_sub(ray.Origin, line.Origin);
|
||||
auto v2 = line.Direction;
|
||||
auto v3 = vector2{ -ray.Direction.Y, ray.Direction.X };
|
||||
|
||||
// Project line on ray perpendicular, no intersection if ray is pointing away from the line
|
||||
auto v2DotV3 = DotProduct(v2, v3);
|
||||
|
@ -167,14 +168,14 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
|||
{
|
||||
// Distance to the intersect point: (V2 X V1) / (V2 dot V3)
|
||||
auto distance = cross(v2, v1) / v2DotV3;
|
||||
if (distance >= -ray->MinDistance && distance <= ray->MaxDistance)
|
||||
if (distance >= -ray.MinDistance && distance <= ray.MaxDistance)
|
||||
{
|
||||
line->RayIntersect.X = distance * ray->Direction.X + ray->Origin.X;
|
||||
line->RayIntersect.Y = distance * ray->Direction.Y + ray->Origin.Y;
|
||||
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)
|
||||
auto testPoint = line.Direction.X != 0.0f ? line.RayIntersect.X : line.RayIntersect.Y;
|
||||
if (testPoint >= line.MinCoord && testPoint <= line.MaxCoord)
|
||||
{
|
||||
return distance;
|
||||
}
|
||||
|
@ -223,7 +224,8 @@ float maths::basic_collision(TBall* ball, vector2* nextPosition, vector2* direct
|
|||
{
|
||||
ball->Position.X = nextPosition->X;
|
||||
ball->Position.Y = nextPosition->Y;
|
||||
float proj = -(direction->Y * ball->Acceleration.Y + direction->X * ball->Acceleration.X);
|
||||
|
||||
auto proj = -DotProduct(*direction, ball->Acceleration);
|
||||
if (proj < 0)
|
||||
{
|
||||
proj = -proj;
|
||||
|
@ -236,6 +238,7 @@ float maths::basic_collision(TBall* ball, vector2* nextPosition, vector2* direct
|
|||
ball->Acceleration.Y = (dy1 + ball->Acceleration.Y) * smoothness + dy1 * elasticity;
|
||||
normalize_2d(ball->Acceleration);
|
||||
}
|
||||
|
||||
float projSpeed = proj * ball->Speed;
|
||||
float newSpeed = ball->Speed - (1.0f - elasticity) * projSpeed;
|
||||
ball->Speed = newSpeed;
|
||||
|
@ -265,87 +268,75 @@ float maths::Distance(const vector2& vec1, const vector2& vec2)
|
|||
return sqrt(Distance_Squared(vec1, vec2));
|
||||
}
|
||||
|
||||
void maths::SinCos(float angle, float* sinOut, float* cosOut)
|
||||
void maths::SinCos(float angle, float& sinOut, float& cosOut)
|
||||
{
|
||||
*sinOut = sin(angle);
|
||||
*cosOut = cos(angle);
|
||||
sinOut = sin(angle);
|
||||
cosOut = cos(angle);
|
||||
}
|
||||
|
||||
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 xOffset = point.X - origin.X;
|
||||
auto yOffset = point.Y - origin.Y;
|
||||
point.X = xOffset * cos - yOffset * sin + origin.X;
|
||||
point.Y = xOffset * sin + yOffset * cos + origin.Y;
|
||||
}
|
||||
|
||||
float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2)
|
||||
// Return the distance from ray1 origin to the intersection point with the closest flipper feature.
|
||||
// Sets ray2 origin to intersection point, direction to collision direction
|
||||
float maths::distance_to_flipper(const ray_type& ray1, ray_type& ray2)
|
||||
{
|
||||
auto distance = 1000000000.0f;
|
||||
auto distanceType = -1;
|
||||
auto newDistance = ray_intersect_line(ray1, &TFlipperEdge::lineA);
|
||||
if (newDistance < 1000000000.0f)
|
||||
{
|
||||
distance = newDistance;
|
||||
distanceType = 0;
|
||||
}
|
||||
newDistance = ray_intersect_circle(*ray1, TFlipperEdge::circlebase);
|
||||
auto distanceType = FlipperIntersect::none;
|
||||
auto newDistance = ray_intersect_line(ray1, TFlipperEdge::lineA);
|
||||
if (newDistance < distance)
|
||||
{
|
||||
distance = newDistance;
|
||||
distanceType = 2;
|
||||
distanceType = FlipperIntersect::lineA;
|
||||
}
|
||||
newDistance = ray_intersect_circle(*ray1, TFlipperEdge::circleT1);
|
||||
newDistance = ray_intersect_circle(ray1, TFlipperEdge::circlebase);
|
||||
if (newDistance < distance)
|
||||
{
|
||||
distance = newDistance;
|
||||
distanceType = 3;
|
||||
distanceType = FlipperIntersect::circlebase;
|
||||
}
|
||||
newDistance = ray_intersect_line(ray1, &TFlipperEdge::lineB);
|
||||
newDistance = ray_intersect_circle(ray1, TFlipperEdge::circleT1);
|
||||
if (newDistance < distance)
|
||||
{
|
||||
distance = newDistance;
|
||||
distanceType = 1;
|
||||
distanceType = FlipperIntersect::circleT1;
|
||||
}
|
||||
newDistance = ray_intersect_line(ray1, TFlipperEdge::lineB);
|
||||
if (newDistance < distance)
|
||||
{
|
||||
distance = newDistance;
|
||||
distanceType = FlipperIntersect::lineB;
|
||||
}
|
||||
if (!ray2 || distance >= 1000000000.0f)
|
||||
return distance;
|
||||
|
||||
if (distanceType != -1)
|
||||
switch (distanceType)
|
||||
{
|
||||
vector2* nextOrigin;
|
||||
if (distanceType)
|
||||
{
|
||||
if (distanceType != 1)
|
||||
{
|
||||
float dirY;
|
||||
ray2->Origin.X = distance * ray1->Direction.X + ray1->Origin.X;
|
||||
ray2->Origin.Y = distance * ray1->Direction.Y + ray1->Origin.Y;
|
||||
if (distanceType == 2)
|
||||
{
|
||||
ray2->Direction.X = ray2->Origin.X - TFlipperEdge::circlebase.Center.X;
|
||||
dirY = ray2->Origin.Y - TFlipperEdge::circlebase.Center.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
ray2->Direction.X = ray2->Origin.X - TFlipperEdge::circleT1.Center.X;
|
||||
dirY = ray2->Origin.Y - TFlipperEdge::circleT1.Center.Y;
|
||||
}
|
||||
ray2->Direction.Y = dirY;
|
||||
normalize_2d(ray2->Direction);
|
||||
return distance;
|
||||
}
|
||||
ray2->Direction = TFlipperEdge::lineB.PerpendicularC;
|
||||
nextOrigin = &TFlipperEdge::lineB.RayIntersect;
|
||||
}
|
||||
else
|
||||
{
|
||||
ray2->Direction = TFlipperEdge::lineA.PerpendicularC;
|
||||
nextOrigin = &TFlipperEdge::lineA.RayIntersect;
|
||||
}
|
||||
ray2->Origin = *nextOrigin;
|
||||
return distance;
|
||||
case FlipperIntersect::lineA:
|
||||
ray2.Direction = TFlipperEdge::lineA.PerpendicularC;
|
||||
ray2.Origin = TFlipperEdge::lineA.RayIntersect;
|
||||
break;
|
||||
case FlipperIntersect::lineB:
|
||||
ray2.Direction = TFlipperEdge::lineB.PerpendicularC;
|
||||
ray2.Origin = TFlipperEdge::lineB.RayIntersect;
|
||||
break;
|
||||
case FlipperIntersect::circlebase:
|
||||
case FlipperIntersect::circleT1:
|
||||
ray2.Origin.X = distance * ray1.Direction.X + ray1.Origin.X;
|
||||
ray2.Origin.Y = distance * ray1.Direction.Y + ray1.Origin.Y;
|
||||
ray2.Direction = vector_sub(ray2.Origin, distanceType == FlipperIntersect::circlebase ?
|
||||
TFlipperEdge::circlebase.Center : TFlipperEdge::circleT1.Center);
|
||||
normalize_2d(ray2.Direction);
|
||||
break;
|
||||
case FlipperIntersect::none:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1000000000.0;
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
||||
void maths::RotateVector(vector2& vec, float angle)
|
||||
|
@ -365,14 +356,7 @@ void maths::RotateVector(vector2& vec, float angle)
|
|||
void maths::find_closest_edge(ramp_plane_type* planes, int planeCount, wall_point_type* wall, vector2& lineEnd,
|
||||
vector2& lineStart)
|
||||
{
|
||||
vector2 wallEnd{}, wallStart{};
|
||||
|
||||
wallStart.X = wall->X0;
|
||||
wallStart.Y = wall->Y0;
|
||||
wallEnd.Y = wall->Y1;
|
||||
wallEnd.X = wall->X1;
|
||||
|
||||
float maxDistance = 1000000000.0f;
|
||||
float distance = 1000000000.0f;
|
||||
for (auto index = 0; index < planeCount; index++)
|
||||
{
|
||||
auto& plane = planes[index];
|
||||
|
@ -382,10 +366,10 @@ void maths::find_closest_edge(ramp_plane_type* planes, int planeCount, wall_poin
|
|||
{
|
||||
auto& point1 = *pointOrder[pt], point2 = *pointOrder[pt + 1];
|
||||
|
||||
auto distance = Distance(wallStart, point1) + Distance(wallEnd, point2);
|
||||
if (distance < maxDistance)
|
||||
auto newDistance = Distance(wall->Pt0, point1) + Distance(wall->Pt1, point2);
|
||||
if (newDistance < distance)
|
||||
{
|
||||
maxDistance = distance;
|
||||
distance = newDistance;
|
||||
lineEnd = point1;
|
||||
lineStart = point2;
|
||||
}
|
||||
|
|
|
@ -59,10 +59,8 @@ struct line_type
|
|||
|
||||
struct wall_point_type
|
||||
{
|
||||
float X0;
|
||||
float Y0;
|
||||
float X1;
|
||||
float Y1;
|
||||
vector2 Pt0;
|
||||
vector2 Pt1;
|
||||
};
|
||||
|
||||
struct ramp_plane_type
|
||||
|
@ -76,6 +74,15 @@ struct ramp_plane_type
|
|||
vector2 FieldForce;
|
||||
};
|
||||
|
||||
enum class FlipperIntersect
|
||||
{
|
||||
none = -1,
|
||||
lineA = 0,
|
||||
lineB = 1,
|
||||
circlebase = 2,
|
||||
circleT1 = 3
|
||||
};
|
||||
|
||||
|
||||
class maths
|
||||
{
|
||||
|
@ -84,8 +91,8 @@ public:
|
|||
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 line_init(line_type& line, float x0, float y0, float x1, float y1);
|
||||
static float ray_intersect_line(const ray_type& ray, line_type& line);
|
||||
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);
|
||||
|
@ -97,9 +104,9 @@ public:
|
|||
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 SinCos(float angle, float& sinOut, float& cosOut);
|
||||
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(const 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);
|
||||
|
|
Loading…
Reference in a new issue