diff --git a/raycastlib.h b/raycastlib.h index cb1c55b..68c22c4 100644 --- a/raycastlib.h +++ b/raycastlib.h @@ -164,11 +164,12 @@ #define RCL_logHitResult(h){\ printf("hit:\n");\ - printf(" sqaure: ");\ + printf(" square: ");\ RCL_logV2D(h.square);\ printf(" pos: ");\ RCL_logV2D(h.position);\ printf(" dist: %d\n", h.distance);\ + printf(" dir: %d\n", h.direction);\ printf(" texcoord: %d\n", h.textureCoord);}\ #define RCL_logPixelInfo(p){\ @@ -196,7 +197,7 @@ typedef struct typedef struct { - RCL_Unit distance; /**< Euclidean distance to the hit position, or -1 + RCL_Unit distance; /**< Distance (perpend.) to the hit position, or -1 if no collision happened. */ uint8_t direction; ///< Direction of hit. RCL_Unit textureCoord; /**< Normalized (0 to RCL_UNITS_PER_SQUARE - 1) @@ -785,6 +786,8 @@ void RCL_castRaySquare(RCL_Ray *localRay, RCL_Vector2D *nextCellOff, collOff->y += nextCellOff->y; } +int aaaaaa = 0; + void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, RCL_ArrayFunction typeFunc, RCL_HitResult *hitResults, uint16_t *hitResultsLen, RCL_RayConstraints constraints) @@ -796,7 +799,7 @@ void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, RCL_Vector2D currentSquare; - currentSquare.x = RCL_divRoundDown(ray.start.x, RCL_UNITS_PER_SQUARE); + currentSquare.x = RCL_divRoundDown(ray.start.x,RCL_UNITS_PER_SQUARE); currentSquare.y = RCL_divRoundDown(ray.start.y,RCL_UNITS_PER_SQUARE); *hitResultsLen = 0; @@ -810,25 +813,111 @@ void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, co.x = 0; co.y = 0; +RCL_Vector2D nextSideDist; +RCL_Vector2D delta; +RCL_Unit currentDist = 0; +RCL_Vector2D step; + +nextSideDist.x = 0; +nextSideDist.y = 0; + +RCL_Unit dirVecLength = RCL_len(ray.direction); + +delta.x = RCL_absVal((RCL_UNITS_PER_SQUARE * dirVecLength) / RCL_nonZero(ray.direction.x)); +delta.y = RCL_absVal((RCL_UNITS_PER_SQUARE * dirVecLength) / RCL_nonZero(ray.direction.y)); + +int8_t stepHorizontal = 0; + + + +if (ray.direction.x < 0) +{ + step.x = -1; + nextSideDist.x = (RCL_wrap(ray.start.x,RCL_UNITS_PER_SQUARE) * delta.x) / RCL_UNITS_PER_SQUARE; +} +else +{ + step.x = 1; + 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) +{ + step.y = -1; + nextSideDist.y = (RCL_wrap(ray.start.y,RCL_UNITS_PER_SQUARE) * delta.y) / RCL_UNITS_PER_SQUARE; +} +else +{ + step.y = 1; + nextSideDist.y = ((RCL_wrap(RCL_UNITS_PER_SQUARE - ray.start.y,RCL_UNITS_PER_SQUARE)) * delta.y) / RCL_UNITS_PER_SQUARE; +} + + + for (uint16_t i = 0; i < constraints.maxSteps; ++i) { + + + RCL_Unit currentType = arrayFunc(currentSquare.x,currentSquare.y); if (currentType != squareType) { // collision + RCL_HitResult h; h.arrayValue = currentType; h.doorRoll = 0; h.position = currentPos; h.square = currentSquare; - h.distance = RCL_dist(initialPos,currentPos); +// h.distance = RCL_dist(initialPos,currentPos); +h.distance = + currentDist; + +if (stepHorizontal) +{ + h.position.x = currentSquare.x * RCL_UNITS_PER_SQUARE; + h.direction = 3; + + if (step.x == -1) + { + h.direction = 1; + h.position.x += RCL_UNITS_PER_SQUARE; + } + + 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.textureCoord = h.position.y; + +h.distance = + ((h.position.x - ray.start.x) * RCL_UNITS_PER_SQUARE) / RCL_nonZero(ray.direction.x); +} +else +{ + h.position.y = currentSquare.y * RCL_UNITS_PER_SQUARE; + h.direction = 2; + + if (step.y == -1) + { + h.direction = 0; + h.position.y += RCL_UNITS_PER_SQUARE; + } + + 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.textureCoord = h.position.x; + +h.distance = + ((h.position.y - ray.start.y) * RCL_UNITS_PER_SQUARE) / RCL_nonZero(ray.direction.y); +} + + if (typeFunc != 0) h.type = typeFunc(currentSquare.x,currentSquare.y); - +/* if (no.y > 0) { h.direction = 0; @@ -859,7 +948,7 @@ void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, h.textureCoord = RCL_wrap(currentPos.y,RCL_UNITS_PER_SQUARE); #endif } - +*/ #if RCL_COMPUTE_WALL_TEXCOORDS == 1 if (_RCL_rollFunction != 0) h.doorRoll = _RCL_rollFunction(currentSquare.x,currentSquare.y); @@ -875,17 +964,36 @@ void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, break; } - ray.start.x = RCL_wrap(currentPos.x,RCL_UNITS_PER_SQUARE); - ray.start.y = RCL_wrap(currentPos.y,RCL_UNITS_PER_SQUARE); +// ray.start.x = RCL_wrap(currentPos.x,RCL_UNITS_PER_SQUARE); +// ray.start.y = RCL_wrap(currentPos.y,RCL_UNITS_PER_SQUARE); - RCL_castRaySquare(&ray,&no,&co); - currentSquare.x += no.x; - currentSquare.y += no.y; +if (nextSideDist.x < nextSideDist.y) +{ +currentDist = nextSideDist.x; + nextSideDist.x += delta.x; + currentSquare.x += step.x; + +stepHorizontal = 1; +} +else +{ +currentDist = nextSideDist.y; + nextSideDist.y += delta.y; + currentSquare.y += step.y; +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; +// currentPos.x += co.x; +// currentPos.y += co.y; } } @@ -932,6 +1040,9 @@ void RCL_castRaysMultiHit(RCL_Camera cam, RCL_ArrayFunction arrayFunc, for (int16_t i = 0; i < cam.resolution.x; ++i) { + +aaaaaa = i == 100; + r.direction.x = dir1.x + currentDX / cam.resolution.x; r.direction.y = dir1.y + currentDY / cam.resolution.x; @@ -1041,7 +1152,7 @@ static inline int16_t _RCL_drawHorizontal( if (doCoords)/*constant condition - compiler should optimize it out*/\ {\ RCL_Unit d = _RCL_floorPixelDistances[pixPos];\ - d = (d * RCL_UNITS_PER_SQUARE) / rayCameraCos;\ +/* d = (d * RCL_UNITS_PER_SQUARE) / rayCameraCos;*/\ /* ^ inverse of RCL_adjustDistance(...) */\ pixelInfo->texCoords.x =\ _RCL_camera.position.x + ((d * dx) / (pixelInfo->hit.distance));\ @@ -1184,7 +1295,8 @@ void _RCL_columnFunctionComplex(RCL_HitResult *hits, uint16_t hitCount, uint16_t if (!drawingHorizon) { hit = hits[j]; - distance = RCL_adjustDistance(hit.distance,&_RCL_camera,&ray); + // RCL_adjustDistance(hit.distance,&_RCL_camera,&ray); +distance = hit.distance; fWallHeight = _RCL_floorFunction(hit.square.x,hit.square.y); fZ2World = fWallHeight - _RCL_camera.height; @@ -1374,7 +1486,9 @@ void _RCL_columnFunctionSimple(RCL_HitResult *hits, uint16_t hitCount, uint16_t if (goOn) { - dist = RCL_adjustDistance(hit.distance,&_RCL_camera,&ray); +// dist = RCL_adjustDistance(hit.distance,&_RCL_camera,&ray); + +dist = hit.distance; int16_t wallHeightWorld = _RCL_floorFunction(hit.square.x,hit.square.y);