TPlunger ready. TEdgeManager v1.
This commit is contained in:
@@ -1,16 +1,274 @@
|
||||
#include "pch.h"
|
||||
#include "TEdgeManager.h"
|
||||
|
||||
int TEdgeManager::FieldEffects(TBall* ball, vector_type* vecDst)
|
||||
#include "TEdgeBox.h"
|
||||
#include "TTableLayer.h"
|
||||
|
||||
TEdgeManager::TEdgeManager(float posX, float posY, float width, float height)
|
||||
{
|
||||
return 0;
|
||||
X = posX;
|
||||
Y = posY;
|
||||
MaxBoxX = 10;
|
||||
MaxBoxY = 15;
|
||||
AdvanceX = width / 10.0f;
|
||||
AdvanceY = height / 15.0f;
|
||||
AdvanceXInv = 1.0f / AdvanceX;
|
||||
AdvanceYInv = 1.0f / AdvanceY;
|
||||
BoxArray = new TEdgeBox[150];
|
||||
}
|
||||
|
||||
void TEdgeManager::edges_insert_square(float a1, float a2, float a3, float a4, TEdgeSegment* a5, field_effect_type* a6)
|
||||
TEdgeManager::~TEdgeManager()
|
||||
{
|
||||
delete[] BoxArray;
|
||||
}
|
||||
|
||||
int TEdgeManager::box_x(float x)
|
||||
{
|
||||
return static_cast<int>((max(0, min(floor((x - X) * AdvanceXInv), (MaxBoxX - 1)))));
|
||||
}
|
||||
|
||||
int TEdgeManager::box_y(float y)
|
||||
{
|
||||
return static_cast<int>((max(0, min(floor((y - Y) * AdvanceYInv), (MaxBoxY - 1)))));
|
||||
}
|
||||
|
||||
int TEdgeManager::increment_box_x(int x)
|
||||
{
|
||||
return min(x + 1, MaxBoxX - 1);
|
||||
}
|
||||
|
||||
int TEdgeManager::increment_box_y(int y)
|
||||
{
|
||||
return min(y + 1, MaxBoxY - 1);
|
||||
}
|
||||
|
||||
void TEdgeManager::add_edge_to_box(int x, int y, TEdgeSegment* edge)
|
||||
{
|
||||
BoxArray[x + y * MaxBoxX].EdgeList->Add(edge);
|
||||
}
|
||||
|
||||
void TEdgeManager::add_field_to_box(int x, int y, field_effect_type* field)
|
||||
{
|
||||
BoxArray[x + y * MaxBoxX].FieldList->Add(field);
|
||||
}
|
||||
|
||||
int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeDst, ray_type* ray, TBall* ball,
|
||||
int edgeIndex)
|
||||
{
|
||||
if (x >= 0 && x < 10 && y >= 0 && y < 15)
|
||||
{
|
||||
TEdgeBox* edgeBox = &BoxArray[x + y * MaxBoxX];
|
||||
TEdgeSegment** edgePtr = &EdgeArray[edgeIndex];
|
||||
for (auto index = edgeBox->EdgeList->Count() - 1; index >= 0; --index)
|
||||
{
|
||||
auto edge = static_cast<TEdgeSegment*>(edgeBox->EdgeList->Get(index));
|
||||
if (!edge->ProcessedFlag && *edge->PinbCompFlag2Ptr && (edge->VisualFlag & ray->FieldFlag))
|
||||
{
|
||||
if (!ball->already_hit(edge))
|
||||
{
|
||||
++edgeIndex;
|
||||
*edgePtr = edge;
|
||||
++edgePtr;
|
||||
edge->ProcessedFlag = 1;
|
||||
auto dist = edge->FindCollisionDistance(ray);
|
||||
if (dist < *distPtr)
|
||||
{
|
||||
*distPtr = dist;
|
||||
*edgeDst = edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return edgeIndex;
|
||||
}
|
||||
|
||||
void TEdgeManager::FieldEffects(TBall* ball, vector_type* dstVec)
|
||||
{
|
||||
vector_type vec{};
|
||||
TEdgeBox* edgeBox = &BoxArray[box_x(ball->Position.X) + box_y(ball->Position.Y) *
|
||||
MaxBoxX];
|
||||
|
||||
for (int index = edgeBox->FieldList->Count() - 1; index >= 0; --index)
|
||||
{
|
||||
auto field = static_cast<field_effect_type*>(edgeBox->FieldList->Get(index));
|
||||
if (*field->Flag2Ptr && ball->FieldFlag & field->Mask)
|
||||
{
|
||||
if (field->CollisionComp->FieldEffect(ball, &vec))
|
||||
{
|
||||
maths::vector_add(dstVec, &vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float TEdgeManager::FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegment** edge)
|
||||
{
|
||||
return 1000000000.0;
|
||||
auto distance = 1000000000.0f;
|
||||
auto edgeIndex = 0;
|
||||
|
||||
auto rayX = ray->Origin.X;
|
||||
auto rayY = ray->Origin.Y;
|
||||
auto rayBoxX = box_x(rayX);
|
||||
auto rayBoxY = box_y(rayY);
|
||||
|
||||
auto rayEndX = ray->Direction.X * ray->MaxDistance + ray->Origin.X;
|
||||
auto rayEndY = ray->Direction.Y * ray->MaxDistance + ray->Origin.Y;
|
||||
auto rayEndBoxX = box_x(rayEndX);
|
||||
auto rayEndBoxY = box_y(rayEndY);
|
||||
|
||||
auto rayDirX = rayX >= rayEndX ? -1 : 1;
|
||||
auto rayDirY = rayY >= rayEndY ? -1 : 1;
|
||||
|
||||
if (rayBoxY == rayEndBoxY)
|
||||
{
|
||||
if (rayDirX == 1)
|
||||
{
|
||||
for (auto indexX = rayBoxX; indexX <= rayEndBoxX; indexX++)
|
||||
{
|
||||
edgeIndex = TestGridBox(indexX, rayBoxY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto indexX = rayBoxX; indexX >= rayEndBoxX; indexX--)
|
||||
{
|
||||
edgeIndex = TestGridBox(indexX, rayBoxY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rayBoxX == rayEndBoxX)
|
||||
{
|
||||
if (rayDirY == 1)
|
||||
{
|
||||
for (auto indexY = rayBoxY; indexY <= rayEndBoxY; indexY++)
|
||||
{
|
||||
edgeIndex = TestGridBox(rayBoxX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto indexY = rayBoxY; indexY >= rayEndBoxY; indexY--)
|
||||
{
|
||||
edgeIndex = TestGridBox(rayBoxX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rayDyDX = (rayY - rayEndY) / (rayX - rayEndX);
|
||||
auto indexX = rayBoxX;
|
||||
auto indexY = rayBoxY;
|
||||
auto bresIndexX = rayBoxX + 1;
|
||||
auto bresIndexY = rayBoxY + 1;
|
||||
auto bresXAdd = rayY - rayDyDX * rayX;
|
||||
edgeIndex = TestGridBox(rayBoxX, rayBoxY, &distance, edge, ray, ball, 0);
|
||||
if (rayDirX == 1)
|
||||
{
|
||||
if (rayDirY == 1)
|
||||
{
|
||||
do
|
||||
{
|
||||
auto yCoord = bresIndexY * AdvanceY + Y;
|
||||
auto xCoord = (bresIndexX * AdvanceX + X) * rayDyDX + bresXAdd;
|
||||
if (xCoord >= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
{
|
||||
++indexX;
|
||||
++bresIndexX;
|
||||
}
|
||||
++indexY;
|
||||
++bresIndexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
++indexX;
|
||||
++bresIndexX;
|
||||
}
|
||||
edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
while (indexX < rayEndBoxX || indexY < rayEndBoxY);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
auto yCoord = indexY * AdvanceY + Y;
|
||||
auto xCoord = (bresIndexX * AdvanceX + X) * rayDyDX + bresXAdd;
|
||||
if (xCoord <= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
{
|
||||
++indexX;
|
||||
++bresIndexX;
|
||||
}
|
||||
--indexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
++indexX;
|
||||
++bresIndexX;
|
||||
}
|
||||
edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
while (indexX < rayEndBoxX || indexY > rayEndBoxY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rayDirY == 1)
|
||||
{
|
||||
do
|
||||
{
|
||||
auto yCoord = bresIndexY * AdvanceY + Y;
|
||||
auto xCoord = (indexX * AdvanceX + X) * rayDyDX + bresXAdd;
|
||||
if (xCoord >= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
--indexX;
|
||||
++indexY;
|
||||
++bresIndexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
--indexX;
|
||||
}
|
||||
edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
while (indexX > rayEndBoxX || indexY < rayEndBoxY);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
auto yCoord = indexY * AdvanceY + Y;
|
||||
auto xCoord = (indexX * AdvanceX + X) * rayDyDX + bresXAdd;
|
||||
if (xCoord <= yCoord)
|
||||
{
|
||||
if (xCoord == yCoord)
|
||||
--indexX;
|
||||
--indexY;
|
||||
}
|
||||
else
|
||||
{
|
||||
--indexX;
|
||||
}
|
||||
edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex);
|
||||
}
|
||||
while (indexX > rayEndBoxX || indexY > rayEndBoxY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (auto edgePtr = EdgeArray; edgeIndex > 0; --edgeIndex, ++edgePtr)
|
||||
{
|
||||
(*edgePtr)->ProcessedFlag = 0;
|
||||
}
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user