1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/raycastlib.git synced 2024-11-23 20:49:57 +01:00

Finish DDA

This commit is contained in:
Miloslav Číž 2018-09-24 18:33:40 +02:00
parent e9e50a2d41
commit 980be935d0
2 changed files with 98 additions and 155 deletions

View file

@ -460,7 +460,6 @@ RCL_Unit *_RCL_floorPixelDistances = 0;
uint32_t profile_RCL_dist = 0; uint32_t profile_RCL_dist = 0;
uint32_t profile_RCL_len = 0; uint32_t profile_RCL_len = 0;
uint32_t profile_RCL_pointIfLeftOfRay = 0; uint32_t profile_RCL_pointIfLeftOfRay = 0;
uint32_t profile_RCL_castRaySquare = 0;
uint32_t profile_RCL_castRayMultiHit = 0; uint32_t profile_RCL_castRayMultiHit = 0;
uint32_t profile_RCL_castRay = 0; uint32_t profile_RCL_castRay = 0;
uint32_t profile_RCL_absVal = 0; uint32_t profile_RCL_absVal = 0;
@ -480,7 +479,6 @@ RCL_Unit *_RCL_floorPixelDistances = 0;
printf(" RCL_dist: %d\n",profile_RCL_dist);\ printf(" RCL_dist: %d\n",profile_RCL_dist);\
printf(" RCL_len: %d\n",profile_RCL_len);\ printf(" RCL_len: %d\n",profile_RCL_len);\
printf(" RCL_pointIfLeftOfRay: %d\n",profile_RCL_pointIfLeftOfRay);\ printf(" RCL_pointIfLeftOfRay: %d\n",profile_RCL_pointIfLeftOfRay);\
printf(" RCL_castRaySquare: %d\n",profile_RCL_castRaySquare);\
printf(" RCL_castRayMultiHit : %d\n",profile_RCL_castRayMultiHit);\ printf(" RCL_castRayMultiHit : %d\n",profile_RCL_castRayMultiHit);\
printf(" RCL_castRay: %d\n",profile_RCL_castRay);\ printf(" RCL_castRay: %d\n",profile_RCL_castRay);\
printf(" RCL_normalize: %d\n",profile_RCL_normalize);\ printf(" RCL_normalize: %d\n",profile_RCL_normalize);\
@ -715,13 +713,12 @@ static inline int8_t RCL_pointIfLeftOfRay(RCL_Vector2D point, RCL_Ray ray)
} }
/** /**
DEPRECATED in favor of DDA.
Casts a ray within a single square, to collide with the square borders. Casts a ray within a single square, to collide with the square borders.
*/ */
void RCL_castRaySquare(RCL_Ray *localRay, RCL_Vector2D *nextCellOff, void RCL_castRaySquare(RCL_Ray *localRay, RCL_Vector2D *nextCellOff,
RCL_Vector2D *collOff) RCL_Vector2D *collOff)
{ {
RCL_profileCall(RCL_castRaySquare);
nextCellOff->x = 0; nextCellOff->x = 0;
nextCellOff->y = 0; nextCellOff->y = 0;
@ -786,8 +783,6 @@ void RCL_castRaySquare(RCL_Ray *localRay, RCL_Vector2D *nextCellOff,
collOff->y += nextCellOff->y; collOff->y += nextCellOff->y;
} }
int aaaaaa = 0;
void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc,
RCL_ArrayFunction typeFunc, RCL_HitResult *hitResults, RCL_ArrayFunction typeFunc, RCL_HitResult *hitResults,
uint16_t *hitResultsLen, RCL_RayConstraints constraints) uint16_t *hitResultsLen, RCL_RayConstraints constraints)
@ -806,75 +801,71 @@ void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc,
RCL_Unit squareType = arrayFunc(currentSquare.x,currentSquare.y); RCL_Unit squareType = arrayFunc(currentSquare.x,currentSquare.y);
RCL_Vector2D no, co; // next cell offset, collision offset // DDA variables
RCL_Vector2D nextSideDist; // dist. from start to the next side in given axis
no.x = 0; // just to supress a warning
no.y = 0;
co.x = 0;
co.y = 0;
RCL_Vector2D nextSideDist;
RCL_Vector2D delta; RCL_Vector2D delta;
RCL_Unit currentDist = 0; RCL_Unit currentDist = 0;
RCL_Vector2D step; RCL_Vector2D step; // -1 or 1 for each axis
int8_t stepHorizontal = 0; // whether the last step was hor. or vert.
nextSideDist.x = 0; nextSideDist.x = 0;
nextSideDist.y = 0; nextSideDist.y = 0;
RCL_Unit dirVecLength = RCL_len(ray.direction); RCL_Unit dirVecLength = RCL_len(ray.direction);
delta.x = RCL_absVal((RCL_UNITS_PER_SQUARE * dirVecLength) / RCL_nonZero(ray.direction.x)); delta.x = RCL_absVal((RCL_UNITS_PER_SQUARE * dirVecLength) /
delta.y = RCL_absVal((RCL_UNITS_PER_SQUARE * dirVecLength) / RCL_nonZero(ray.direction.y)); RCL_nonZero(ray.direction.x));
int8_t stepHorizontal = 0;
delta.y = RCL_absVal((RCL_UNITS_PER_SQUARE * dirVecLength) /
RCL_nonZero(ray.direction.y));
// init DDA
if (ray.direction.x < 0) if (ray.direction.x < 0)
{ {
step.x = -1; step.x = -1;
nextSideDist.x = (RCL_wrap(ray.start.x,RCL_UNITS_PER_SQUARE) * delta.x) / RCL_UNITS_PER_SQUARE; nextSideDist.x = (RCL_wrap(ray.start.x,RCL_UNITS_PER_SQUARE) * delta.x) /
RCL_UNITS_PER_SQUARE;
} }
else else
{ {
step.x = 1; step.x = 1;
nextSideDist.x = ((RCL_wrap(RCL_UNITS_PER_SQUARE - ray.start.x,RCL_UNITS_PER_SQUARE)) * delta.x) / RCL_UNITS_PER_SQUARE; nextSideDist.x =
((RCL_wrap(RCL_UNITS_PER_SQUARE - ray.start.x,RCL_UNITS_PER_SQUARE)) *
delta.x) / RCL_UNITS_PER_SQUARE;
} }
if (ray.direction.y < 0) if (ray.direction.y < 0)
{ {
step.y = -1; step.y = -1;
nextSideDist.y = (RCL_wrap(ray.start.y,RCL_UNITS_PER_SQUARE) * delta.y) / RCL_UNITS_PER_SQUARE; nextSideDist.y = (RCL_wrap(ray.start.y,RCL_UNITS_PER_SQUARE) * delta.y) /
RCL_UNITS_PER_SQUARE;
} }
else else
{ {
step.y = 1; step.y = 1;
nextSideDist.y = ((RCL_wrap(RCL_UNITS_PER_SQUARE - ray.start.y,RCL_UNITS_PER_SQUARE)) * delta.y) / RCL_UNITS_PER_SQUARE; nextSideDist.y =
((RCL_wrap(RCL_UNITS_PER_SQUARE - ray.start.y,RCL_UNITS_PER_SQUARE)) *
delta.y) / RCL_UNITS_PER_SQUARE;
} }
// DDA loop
for (uint16_t i = 0; i < constraints.maxSteps; ++i) for (uint16_t i = 0; i < constraints.maxSteps; ++i)
{ {
RCL_Unit currentType = arrayFunc(currentSquare.x,currentSquare.y); RCL_Unit currentType = arrayFunc(currentSquare.x,currentSquare.y);
if (currentType != squareType) if (currentType != squareType)
{ {
// collision // collision
RCL_HitResult h; RCL_HitResult h;
h.arrayValue = currentType; h.arrayValue = currentType;
h.doorRoll = 0; h.doorRoll = 0;
h.position = currentPos; h.position = currentPos;
h.square = currentSquare; h.square = currentSquare;
// h.distance = RCL_dist(initialPos,currentPos); h.distance = currentDist;
h.distance =
currentDist;
if (stepHorizontal) if (stepHorizontal)
{ {
@ -888,11 +879,13 @@ if (stepHorizontal)
} }
RCL_Unit diff = h.position.x - ray.start.x; RCL_Unit diff = h.position.x - ray.start.x;
h.position.y = ray.start.y + ((ray.direction.y * diff) / RCL_nonZero(ray.direction.x)); h.position.y = ray.start.y + ((ray.direction.y * diff) /
RCL_nonZero(ray.direction.x));
h.textureCoord = h.position.y; h.textureCoord = h.position.y;
h.distance = h.distance =
((h.position.x - ray.start.x) * RCL_UNITS_PER_SQUARE) / RCL_nonZero(ray.direction.x); ((h.position.x - ray.start.x) * RCL_UNITS_PER_SQUARE) /
RCL_nonZero(ray.direction.x);
} }
else else
{ {
@ -906,49 +899,18 @@ else
} }
RCL_Unit diff = h.position.y - ray.start.y; RCL_Unit diff = h.position.y - ray.start.y;
h.position.x = ray.start.x + ((ray.direction.x * diff) / RCL_nonZero(ray.direction.y)); h.position.x = ray.start.x + ((ray.direction.x * diff) /
RCL_nonZero(ray.direction.y));
h.textureCoord = h.position.x; h.textureCoord = h.position.x;
h.distance = h.distance =
((h.position.y - ray.start.y) * RCL_UNITS_PER_SQUARE) / RCL_nonZero(ray.direction.y); ((h.position.y - ray.start.y) * RCL_UNITS_PER_SQUARE) /
RCL_nonZero(ray.direction.y);
} }
if (typeFunc != 0) if (typeFunc != 0)
h.type = typeFunc(currentSquare.x,currentSquare.y); h.type = typeFunc(currentSquare.x,currentSquare.y);
/*
if (no.y > 0)
{
h.direction = 0;
#if RCL_COMPUTE_WALL_TEXCOORDS == 1
h.textureCoord = RCL_wrap(currentPos.x,RCL_UNITS_PER_SQUARE);
#endif
}
else if (no.x > 0)
{
h.direction = 1;
#if RCL_COMPUTE_WALL_TEXCOORDS == 1
h.textureCoord =
RCL_wrap(RCL_UNITS_PER_SQUARE - currentPos.y,RCL_UNITS_PER_SQUARE);
#endif
}
else if (no.y < 0)
{
h.direction = 2;
#if RCL_COMPUTE_WALL_TEXCOORDS == 1
h.textureCoord =
RCL_wrap(RCL_UNITS_PER_SQUARE - currentPos.x,RCL_UNITS_PER_SQUARE);
#endif
}
else
{
h.direction = 3;
#if RCL_COMPUTE_WALL_TEXCOORDS == 1
h.textureCoord = RCL_wrap(currentPos.y,RCL_UNITS_PER_SQUARE);
#endif
}
*/
#if RCL_COMPUTE_WALL_TEXCOORDS == 1 #if RCL_COMPUTE_WALL_TEXCOORDS == 1
if (_RCL_rollFunction != 0) if (_RCL_rollFunction != 0)
h.doorRoll = _RCL_rollFunction(currentSquare.x,currentSquare.y); h.doorRoll = _RCL_rollFunction(currentSquare.x,currentSquare.y);
@ -964,16 +926,13 @@ h.distance =
break; break;
} }
// ray.start.x = RCL_wrap(currentPos.x,RCL_UNITS_PER_SQUARE); // DDA step
// ray.start.y = RCL_wrap(currentPos.y,RCL_UNITS_PER_SQUARE);
if (nextSideDist.x < nextSideDist.y) if (nextSideDist.x < nextSideDist.y)
{ {
currentDist = nextSideDist.x; currentDist = nextSideDist.x;
nextSideDist.x += delta.x; nextSideDist.x += delta.x;
currentSquare.x += step.x; currentSquare.x += step.x;
stepHorizontal = 1; stepHorizontal = 1;
} }
else else
@ -983,17 +942,6 @@ currentDist = nextSideDist.y;
currentSquare.y += step.y; currentSquare.y += step.y;
stepHorizontal = 0; stepHorizontal = 0;
} }
// RCL_castRaySquare(&ray,&no,&co);
// currentSquare.x += no.x;
// currentSquare.y += no.y;
// offset into the next cell
// currentPos.x += co.x;
// currentPos.y += co.y;
} }
} }
@ -1040,9 +988,6 @@ void RCL_castRaysMultiHit(RCL_Camera cam, RCL_ArrayFunction arrayFunc,
for (int16_t i = 0; i < cam.resolution.x; ++i) for (int16_t i = 0; i < cam.resolution.x; ++i)
{ {
aaaaaa = i == 100;
r.direction.x = dir1.x + currentDX / cam.resolution.x; r.direction.x = dir1.x + currentDX / cam.resolution.x;
r.direction.y = dir1.y + currentDY / cam.resolution.x; r.direction.y = dir1.y + currentDY / cam.resolution.x;
@ -1152,8 +1097,6 @@ static inline int16_t _RCL_drawHorizontal(
if (doCoords)/*constant condition - compiler should optimize it out*/\ if (doCoords)/*constant condition - compiler should optimize it out*/\
{\ {\
RCL_Unit d = _RCL_floorPixelDistances[pixPos];\ RCL_Unit d = _RCL_floorPixelDistances[pixPos];\
/* d = (d * RCL_UNITS_PER_SQUARE) / rayCameraCos;*/\
/* ^ inverse of RCL_adjustDistance(...) */\
pixelInfo->texCoords.x =\ pixelInfo->texCoords.x =\
_RCL_camera.position.x + ((d * dx) / (pixelInfo->hit.distance));\ _RCL_camera.position.x + ((d * dx) / (pixelInfo->hit.distance));\
pixelInfo->texCoords.y =\ pixelInfo->texCoords.y =\

2
test.c
View file

@ -285,7 +285,7 @@ int main()
0, 0,
0, 0,
100, 100, 100, 100,
10, 9, 9, 10,
10240, 10240, 10240, 10240,
16)) 16))
return 1; return 1;