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

Start simple render

This commit is contained in:
Miloslav Číž 2018-09-11 08:09:34 +02:00
parent 1105264305
commit 2a689d6f7a

View file

@ -245,6 +245,9 @@ void render(Camera cam, ArrayFunction floorHeightFunc,
ArrayFunction ceilingHeightFunc, ArrayFunction typeFunction, ArrayFunction ceilingHeightFunc, ArrayFunction typeFunction,
PixelFunction pixelFunc, RayConstraints constraints); PixelFunction pixelFunc, RayConstraints constraints);
void renderSimple(Camera cam, ArrayFunction floorHeightFunc,
ArrayFunction typeFunc, PixelFunction pixelFunc, RayConstraints constraints);
/** /**
Function that moves given camera and makes it collide with walls and Function that moves given camera and makes it collide with walls and
potentially also floor and ceilings. It's meant to help implement player potentially also floor and ceilings. It's meant to help implement player
@ -690,6 +693,22 @@ Unit _floorCeilFunction(int16_t x, int16_t y)
return ((f & 0x0000ffff) << 16) | (c & 0x0000ffff); return ((f & 0x0000ffff) << 16) | (c & 0x0000ffff);
} }
inline Unit adjustDistance(Unit distance, Camera camera, Ray ray)
{
/* FIXME/TODO: The adjusted (=orthogonal, camera-space) distance could
possibly be computed more efficiently by not computing Euclidean
distance at all, but rather compute the distance of the collision
point from the projection plane (line). */
Unit result =
(distance *
vectorsAngleCos(angleToDirection(camera.direction),ray.direction)) /
UNITS_PER_SQUARE;
return result == 0 ? 1 : result;
// ^ prevent division by zero
}
void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray) void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
{ {
int_maybe32_t y = _camResYLimit; // screen y (for floor), will only go up int_maybe32_t y = _camResYLimit; // screen y (for floor), will only go up
@ -708,16 +727,7 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
{ {
HitResult hit = hits[j]; HitResult hit = hits[j];
/* FIXME/TODO: The adjusted (=orthogonal, camera-space) distance could Unit dist = adjustDistance(hit.distance,_camera,ray);
possibly be computed more efficiently by not computing Euclidean
distance at all, but rather compute the distance of the collision
point from the projection plane (line). */
Unit dist = // adjusted distance
(hit.distance * vectorsAngleCos(angleToDirection(_camera.direction),
ray.direction)) / UNITS_PER_SQUARE;
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);
@ -901,7 +911,7 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
absVal(worldZPrevCeil) * VERTICAL_DEPTH_MULTIPLY : UNITS_PER_SQUARE; absVal(worldZPrevCeil) * VERTICAL_DEPTH_MULTIPLY : UNITS_PER_SQUARE;
horizon = y > _middleRow ? _middleRow : y; horizon = y > _middleRow ? _middleRow : y;
horizon = clamp(horizon,0,_camera.resolution.y); horizon = clamp(horizon,0,_camResYLimit);
for (int_maybe32_t i = y2; i < horizon; ++i) for (int_maybe32_t i = y2; i < horizon; ++i)
{ {
@ -913,6 +923,76 @@ void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
#undef VERTICAL_DEPTH_MULTIPLY #undef VERTICAL_DEPTH_MULTIPLY
} }
void _columnFunctionSimple(HitResult *hits, uint16_t hitCount, uint16_t x,
Ray ray)
{
int16_t y = 0;
int16_t wallScreenHeight = 0;
Unit dist = 1;
PixelInfo p;
p.position.x = x;
if (hitCount > 0)
{
HitResult hit = hits[0];
p.hit = hit;
dist = adjustDistance(hit.distance,_camera,ray);
int16_t wallHeightWorld = _floorFunction(hit.square.x,hit.square.y);
wallScreenHeight = perspectiveScale((wallHeightWorld *
_camera.resolution.y) / UNITS_PER_SQUARE,dist);
}
int16_t wallStart = clamp(_middleRow - wallScreenHeight / 2,0,_camResYLimit);
int16_t wallEnd = clamp(wallStart + wallScreenHeight,0,_camResYLimit);
// draw ceiling
p.isWall = 0;
p.isFloor = 0;
p.isHorizon = 1;
p.depth = 1;
while (y < wallStart)
{
p.position.y = y;
_pixelFunction(p);
++y;
}
// draw wall
p.isWall = 1;
p.isFloor = 1;
p.depth = dist;
int16_t coordHelper = 0;
while (y < wallEnd)
{
p.position.y = y;
if (_computeTextureCoords)
p.textureCoordY = (coordHelper * UNITS_PER_SQUARE) / wallScreenHeight;
_pixelFunction(p);
++y;
++coordHelper;
}
// draw floor
p.isWall = 0;
p.depth = 1;
while (y < _camera.resolution.y)
{
p.position.y = y;
_pixelFunction(p);
++y;
}
}
void render(Camera cam, ArrayFunction floorHeightFunc, void render(Camera cam, ArrayFunction floorHeightFunc,
ArrayFunction ceilingHeightFunc, ArrayFunction typeFunction, ArrayFunction ceilingHeightFunc, ArrayFunction typeFunction,
PixelFunction pixelFunc, RayConstraints constraints) PixelFunction pixelFunc, RayConstraints constraints)
@ -950,6 +1030,25 @@ void render(Camera cam, ArrayFunction floorHeightFunc,
_columnFunction,constraints); _columnFunction,constraints);
} }
void renderSimple(Camera cam, ArrayFunction floorHeightFunc,
ArrayFunction typeFunc, PixelFunction pixelFunc, RayConstraints constraints)
{
_pixelFunction = pixelFunc;
_floorFunction = floorHeightFunc;
_camera = cam;
_camResYLimit = cam.resolution.y - 1;
_middleRow = cam.resolution.y / 2;
_computeTextureCoords = constraints.computeTextureCoords;
// TODO
_floorDepthStep = (12 * UNITS_PER_SQUARE) / cam.resolution.y;
constraints.maxHits = 1;
castRaysMultiHit(cam,_floorFunction,typeFunc,_columnFunctionSimple,
constraints);
}
Vector2D normalize(Vector2D v) Vector2D normalize(Vector2D v)
{ {
profileCall(normalize); profileCall(normalize);