mirror of
https://git.coom.tech/drummyfish/raycastlib.git
synced 2024-11-23 20:49:57 +01:00
Make ceiling optional
This commit is contained in:
parent
751014a252
commit
657b5a2891
1 changed files with 63 additions and 39 deletions
58
raycastlib.h
58
raycastlib.h
|
@ -20,21 +20,20 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef RAYCAST_TINY
|
#ifndef RAYCAST_TINY
|
||||||
|
#define UNITS_PER_SQUARE 1024 ///< N. of Units in a side of a spatial square.
|
||||||
#define UNITS_PER_SQUARE 1024 ///< No. of Units in a side of a spatial square.
|
typedef int32_t Unit; /**< Smallest spatial unit, there is UNITS_PER_SQUARE
|
||||||
typedef int32_t Unit; /**< Smallest spatial unit, there is UNITS_PER_SQUARE
|
|
||||||
units in a square's length. This effectively
|
units in a square's length. This effectively
|
||||||
serves the purpose of a fixed-point arithmetic. */
|
serves the purpose of a fixed-point arithmetic. */
|
||||||
typedef int32_t int_maybe32_t;
|
#define UNIT_INFINITY 2147483647;
|
||||||
typedef uint32_t uint_maybe32_t;
|
|
||||||
|
|
||||||
|
typedef int32_t int_maybe32_t;
|
||||||
|
typedef uint32_t uint_maybe32_t;
|
||||||
#else
|
#else
|
||||||
|
#define UNITS_PER_SQUARE 64
|
||||||
#define UNITS_PER_SQUARE 64
|
typedef int16_t Unit;
|
||||||
typedef int16_t Unit;
|
#define UNIT_INFINITY 32767;
|
||||||
typedef int16_t int_maybe32_t;
|
typedef int16_t int_maybe32_t;
|
||||||
typedef uint16_t uint_maybe32_t;
|
typedef uint16_t uint_maybe32_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VERTICAL_FOV (UNITS_PER_SQUARE / 2)
|
#define VERTICAL_FOV (UNITS_PER_SQUARE / 2)
|
||||||
|
@ -179,6 +178,16 @@ Unit perspectiveScale(Unit originalSize, Unit distance);
|
||||||
void castRaysMultiHit(Camera cam, ArrayFunction arrayFunc,
|
void castRaysMultiHit(Camera cam, ArrayFunction arrayFunc,
|
||||||
ColumnFunction columnFunc, RayConstraints constraints);
|
ColumnFunction columnFunc, RayConstraints constraints);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Renders a complete camera view.
|
||||||
|
|
||||||
|
@param cam camera whose view to render
|
||||||
|
@param floorHeightFunc function that returns floor height (in Units)
|
||||||
|
@param ceilingHeightFunc same as floorHeightFunc but for ceiling, can also be
|
||||||
|
0 (no ceiling will be rendered)
|
||||||
|
@param pixelFunc callback function to draw a single pixel on screen
|
||||||
|
@param constraints constraints for each cast ray
|
||||||
|
*/
|
||||||
void render(Camera cam, ArrayFunction floorHeightFunc, ArrayFunction
|
void render(Camera cam, ArrayFunction floorHeightFunc, ArrayFunction
|
||||||
ceilingHeightFunc, PixelFunction pixelFunc, RayConstraints constraints);
|
ceilingHeightFunc, PixelFunction pixelFunc, RayConstraints constraints);
|
||||||
|
|
||||||
|
@ -588,7 +597,7 @@ Unit _floorCeilFunction(int16_t x, int16_t y)
|
||||||
// TODO: adjust also for RAYCAST_TINY
|
// TODO: adjust also for RAYCAST_TINY
|
||||||
|
|
||||||
Unit f = _floorFunction(x,y);
|
Unit f = _floorFunction(x,y);
|
||||||
Unit c = _ceilFunction(x,y);
|
Unit c = _ceilFunction != 0 ? _ceilFunction(x,y) : 0;
|
||||||
|
|
||||||
return ((f & 0x0000ffff) << 16) | (c & 0x0000ffff);
|
return ((f & 0x0000ffff) << 16) | (c & 0x0000ffff);
|
||||||
}
|
}
|
||||||
|
@ -623,7 +632,9 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
|
||||||
dist = dist == 0 ? 1 : dist; // prevent division by zero
|
dist = dist == 0 ? 1 : dist; // prevent division by zero
|
||||||
|
|
||||||
Unit wallHeight = _floorFunction(hit.square.x,hit.square.y);
|
Unit wallHeight = _floorFunction(hit.square.x,hit.square.y);
|
||||||
Unit wallHeightCeil = _ceilFunction(hit.square.x,hit.square.y);
|
|
||||||
|
Unit wallHeightCeil = _ceilFunction != 0 ?
|
||||||
|
_ceilFunction(hit.square.x,hit.square.y) : 0;
|
||||||
|
|
||||||
Unit worldZ2 = wallHeight - _camera.height;
|
Unit worldZ2 = wallHeight - _camera.height;
|
||||||
|
|
||||||
|
@ -681,6 +692,8 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
|
||||||
|
|
||||||
// draw ceiling until wall
|
// draw ceiling until wall
|
||||||
|
|
||||||
|
if (_ceilFunction != 0)
|
||||||
|
{
|
||||||
Unit ceilCameraDiff = absVal(worldZPrevCeil) * VERTICAL_DEPTH_MULTIPLY;
|
Unit ceilCameraDiff = absVal(worldZPrevCeil) * VERTICAL_DEPTH_MULTIPLY;
|
||||||
|
|
||||||
for (int_maybe32_t i = y2; i < z1ScreenCeil; ++i)
|
for (int_maybe32_t i = y2; i < z1ScreenCeil; ++i)
|
||||||
|
@ -689,6 +702,7 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
|
||||||
p.depth = i * _floorDepthStep + ceilCameraDiff;
|
p.depth = i * _floorDepthStep + ceilCameraDiff;
|
||||||
_pixelFunction(p);
|
_pixelFunction(p);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// draw floor wall
|
// draw floor wall
|
||||||
|
|
||||||
|
@ -711,9 +725,12 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
|
||||||
|
|
||||||
// draw ceiling wall
|
// draw ceiling wall
|
||||||
|
|
||||||
|
if (_ceilFunction != 0)
|
||||||
|
{
|
||||||
iTo = y > zBottomCeil ? zBottomCeil : y;
|
iTo = y > zBottomCeil ? zBottomCeil : y;
|
||||||
|
|
||||||
for (int_maybe32_t i = z1ScreenCeil > y2 ? z1ScreenCeil : y2; i < iTo; ++i)
|
for (int_maybe32_t i = z1ScreenCeil > y2 ? z1ScreenCeil : y2; i < iTo;
|
||||||
|
++i)
|
||||||
{
|
{
|
||||||
p.position.y = i;
|
p.position.y = i;
|
||||||
p.hit = hit;
|
p.hit = hit;
|
||||||
|
@ -724,6 +741,7 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
|
||||||
|
|
||||||
_pixelFunction(p);
|
_pixelFunction(p);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
y = y > zTop ? zTop : y;
|
y = y > zTop ? zTop : y;
|
||||||
worldZPrev = worldZ2;
|
worldZPrev = worldZ2;
|
||||||
|
@ -740,7 +758,7 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
|
||||||
p.isWall = 0;
|
p.isWall = 0;
|
||||||
|
|
||||||
Unit floorCameraDiff = absVal(worldZPrev) * VERTICAL_DEPTH_MULTIPLY;
|
Unit floorCameraDiff = absVal(worldZPrev) * VERTICAL_DEPTH_MULTIPLY;
|
||||||
Unit horizon = y2 < _middleRow ? _middleRow : y2;
|
Unit horizon = (y2 < _middleRow || _ceilFunction == 0) ? _middleRow : y2;
|
||||||
|
|
||||||
for (int_maybe32_t i = y; i >= horizon; --i)
|
for (int_maybe32_t i = y; i >= horizon; --i)
|
||||||
{
|
{
|
||||||
|
@ -752,6 +770,8 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
|
||||||
|
|
||||||
// draw ceiling until horizon
|
// draw ceiling until horizon
|
||||||
|
|
||||||
|
if (_ceilFunction != 0)
|
||||||
|
{
|
||||||
Unit ceilCameraDiff = absVal(worldZPrevCeil) * VERTICAL_DEPTH_MULTIPLY;
|
Unit ceilCameraDiff = absVal(worldZPrevCeil) * VERTICAL_DEPTH_MULTIPLY;
|
||||||
horizon = y > _middleRow ? _middleRow : y;
|
horizon = y > _middleRow ? _middleRow : y;
|
||||||
|
|
||||||
|
@ -762,6 +782,7 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
|
||||||
|
|
||||||
_pixelFunction(p);
|
_pixelFunction(p);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#undef VERTICAL_DEPTH_MULTIPLY
|
#undef VERTICAL_DEPTH_MULTIPLY
|
||||||
}
|
}
|
||||||
|
@ -781,9 +802,12 @@ void render(Camera cam, ArrayFunction floorHeightFunc, ArrayFunction
|
||||||
divRoundDown(cam.position.x,UNITS_PER_SQUARE),
|
divRoundDown(cam.position.x,UNITS_PER_SQUARE),
|
||||||
divRoundDown(cam.position.y,UNITS_PER_SQUARE)) -1 * cam.height;
|
divRoundDown(cam.position.y,UNITS_PER_SQUARE)) -1 * cam.height;
|
||||||
|
|
||||||
_startCeilHeight = ceilingHeightFunc(
|
_startCeilHeight =
|
||||||
|
ceilingHeightFunc != 0 ?
|
||||||
|
ceilingHeightFunc(
|
||||||
divRoundDown(cam.position.x,UNITS_PER_SQUARE),
|
divRoundDown(cam.position.x,UNITS_PER_SQUARE),
|
||||||
divRoundDown(cam.position.y,UNITS_PER_SQUARE)) -1 * cam.height;
|
divRoundDown(cam.position.y,UNITS_PER_SQUARE)) -1 * cam.height
|
||||||
|
: UNIT_INFINITY;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
_floorDepthStep = (12 * UNITS_PER_SQUARE) / cam.resolution.y;
|
_floorDepthStep = (12 * UNITS_PER_SQUARE) / cam.resolution.y;
|
||||||
|
|
Loading…
Reference in a new issue