1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/raycastlib.git synced 2024-11-24 20:59:58 +01:00
raycastlib/test.c

396 lines
7.6 KiB
C
Raw Normal View History

2018-08-23 09:25:34 +02:00
/**
Tests for raycastlib.
license: CC0
*/
2018-09-21 08:56:17 +02:00
#define RCL_PROFILE
2018-08-31 15:38:02 +02:00
2018-09-21 08:56:17 +02:00
#define RCL_HORIZONTAL_FOV RCL_UNITS_PER_SQUARE / 2
#define RCL_PIXEL_FUNCTION pixelFunc
2018-09-17 15:05:38 +02:00
2018-08-23 02:46:40 +02:00
#include <stdio.h>
2018-08-23 03:04:52 +02:00
#include "raycastlib.h"
2018-08-31 11:20:36 +02:00
#include <sys/time.h>
2018-08-23 02:46:40 +02:00
2018-09-21 08:56:17 +02:00
RCL_Unit testArrayFunc(int16_t x, int16_t y)
2018-08-23 02:46:40 +02:00
{
2018-08-23 03:04:52 +02:00
if (x > 12 || y > 12)
return x * y;
2018-08-23 02:46:40 +02:00
return (x < 0 || y < 0 || x > 9 || y > 9) ? 1 : 0;
}
2018-09-21 08:56:17 +02:00
RCL_Unit testArrayFunc2(int16_t x, int16_t y)
2018-09-05 11:37:12 +02:00
{
2018-09-21 08:56:17 +02:00
return testArrayFunc(x,y) + 10 * RCL_UNITS_PER_SQUARE;
2018-09-05 11:37:12 +02:00
}
2018-08-23 02:46:40 +02:00
/**
Simple automatic test function.
*/
2018-09-21 08:56:17 +02:00
int testSingleRay(RCL_Unit startX, RCL_Unit startY, RCL_Unit dirX, RCL_Unit dirY,
2018-08-23 02:46:40 +02:00
int16_t expectSquareX, int16_t expectSquareY, int16_t expectPointX,
int16_t expectPointY, int16_t tolerateError)
{
2018-09-21 08:56:17 +02:00
RCL_Ray r;
2018-08-23 02:46:40 +02:00
r.start.x = startX;
r.start.y = startY;
r.direction.x = dirX;
r.direction.y = dirY;
printf("- casting ray:\n");
2018-09-21 08:56:17 +02:00
RCL_logRay(r);
2018-08-23 02:46:40 +02:00
2018-09-21 08:56:17 +02:00
RCL_HitResult h = RCL_castRay(r,testArrayFunc);
2018-08-23 02:46:40 +02:00
printf("- result:\n");
2018-09-21 08:56:17 +02:00
RCL_logHitResult(h);
2018-08-23 02:46:40 +02:00
int result =
h.square.x == expectSquareX &&
h.square.y == expectSquareY &&
h.position.x <= expectPointX + tolerateError &&
h.position.x >= expectPointX - tolerateError &&
h.position.y <= expectPointY + tolerateError &&
h.position.y >= expectPointY - tolerateError;
if (result)
2018-08-23 03:04:52 +02:00
printf("\nOK\n\n");
2018-08-23 02:46:40 +02:00
else
2018-08-23 03:04:52 +02:00
printf("\nFAIL\n\n");
2018-08-23 02:46:40 +02:00
return result;
}
2018-09-21 08:56:17 +02:00
int testSingleMapping(RCL_Unit posX, RCL_Unit posY, RCL_Unit posZ, uint32_t resX,
uint32_t resY, RCL_Unit camX, RCL_Unit camY, RCL_Unit camZ, RCL_Unit camDir,
RCL_Unit expectX, RCL_Unit expectY, RCL_Unit expectZ)
2018-09-04 13:01:14 +02:00
{
int result;
2018-09-21 08:56:17 +02:00
RCL_Camera c;
2018-09-04 13:01:14 +02:00
c.resolution.x = resX;
c.resolution.y = resY;
2018-09-04 18:55:18 +02:00
c.position.x = camX;
2018-09-04 13:01:14 +02:00
c.position.y = camY;
c.direction = camDir;
2018-09-04 18:55:18 +02:00
c.height = camZ;
2018-09-04 13:01:14 +02:00
2018-09-21 08:56:17 +02:00
RCL_Vector2D pos;
RCL_Unit height;
2018-09-04 13:01:14 +02:00
pos.x = posX;
pos.y = posY;
height = posZ;
2018-09-21 08:56:17 +02:00
RCL_PixelInfo p;
2018-09-04 13:01:14 +02:00
printf("- mapping pixel: %d %d %d\n",posX,posY,posZ);
2018-09-21 08:56:17 +02:00
p = RCL_mapToScreen(pos,height,c);
2018-09-04 13:01:14 +02:00
printf("- result:\n");
2018-09-21 08:56:17 +02:00
RCL_logPixelInfo(p);
2018-09-04 13:01:14 +02:00
result = p.position.x == expectX && p.position.y == expectY &&
p.depth == expectZ;
if (result)
printf("\nOK\n\n");
else
printf("\nFAIL\n\n");
return result;
}
2018-08-31 11:20:36 +02:00
// returns milliseconds
long measureTime(void (*func)(void))
{
long start, end;
struct timeval timecheck;
gettimeofday(&timecheck, NULL);
start = (long) timecheck.tv_sec * 1000 + (long) timecheck.tv_usec / 1000;
func();
gettimeofday(&timecheck, NULL);
end = (long) timecheck.tv_sec * 1000 + (long) timecheck.tv_usec / 1000;
return end - start;
}
void benchCastRays()
{
2018-09-21 08:56:17 +02:00
RCL_Ray r;
2018-08-31 11:20:36 +02:00
2018-09-21 08:56:17 +02:00
r.start.x = RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2;
r.start.y = 2 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 4;
2018-08-31 11:20:36 +02:00
2018-09-21 08:56:17 +02:00
RCL_Vector2D directions[8];
2018-08-31 11:20:36 +02:00
for (int i = 0; i < 8; ++i)
2018-09-21 08:56:17 +02:00
directions[i] = RCL_angleToDirection(RCL_UNITS_PER_SQUARE / 8 * i);
2018-08-31 11:20:36 +02:00
for (int i = 0; i < 1000000; ++i)
{
r.direction = directions[i % 8];
2018-09-21 08:56:17 +02:00
RCL_castRay(r,testArrayFunc);
2018-08-31 11:20:36 +02:00
}
}
2018-09-04 12:39:26 +02:00
void benchmarkMapping()
{
2018-09-21 08:56:17 +02:00
RCL_Camera c;
2018-09-04 12:39:26 +02:00
c.resolution.x = 1024;
c.resolution.y = 768;
2018-09-21 08:56:17 +02:00
c.position.x = RCL_UNITS_PER_SQUARE / 2;
c.position.y = RCL_UNITS_PER_SQUARE * 2;
c.direction = RCL_UNITS_PER_SQUARE / 8;
2018-09-04 12:39:26 +02:00
c.height = 0;
2018-09-21 08:56:17 +02:00
RCL_PixelInfo p;
2018-09-04 12:39:26 +02:00
2018-09-21 08:56:17 +02:00
RCL_Vector2D pos;
RCL_Unit height;
2018-09-04 12:39:26 +02:00
2018-09-21 08:56:17 +02:00
pos.x = -1024 * RCL_UNITS_PER_SQUARE;
pos.y = -512 * RCL_UNITS_PER_SQUARE;
2018-09-04 12:39:26 +02:00
height = 0;
for (int i = 0; i < 1000000; ++i)
{
2018-09-21 08:56:17 +02:00
p = RCL_mapToScreen(pos,height,c);
2018-09-04 12:39:26 +02:00
pos.x += 4;
pos.y += 8;
height = (height + 16) % 1024;
}
}
2018-09-21 09:20:57 +02:00
int countPixels = 0;
uint32_t *pixelCounts = 0;
RCL_Camera countCamera;
int countOK = 1;
2018-09-21 08:56:17 +02:00
void pixelFunc(RCL_PixelInfo *p)
2018-09-04 19:32:47 +02:00
{
2018-09-21 09:20:57 +02:00
if (countPixels)
{
if (p->position.x >= countCamera.resolution.x || p->position.x < 0 ||
p->position.y >= countCamera.resolution.y || p->position.y < 0)
{
printf("ERROR: writing pixel outside screen at %d %d!\n",
p->position.x,p->position.y);
countOK = 0;
}
else
pixelCounts[p->position.y * countCamera.resolution.x + p->position.x]++;
}
}
int testPixelCount(RCL_Unit camX, RCL_Unit camY, RCL_Unit camZ,
RCL_Unit camDir, RCL_Unit camShear, uint16_t camResX, uint16_t camResY,
int complexRender)
{
printf("Counting rendered pixels...\n");
RCL_RayConstraints constraints;
RCL_Camera c;
RCL_initRayConstraints(&constraints);
RCL_initCamera(&c);
c.position.x = camX;
c.position.y = camY;
c.direction = camDir;
c.shear = camShear;
c.height = camZ;
c.resolution.x = camResX;
c.resolution.y = camResY;
uint32_t pixels[camResX * camResY];
for (uint32_t i = 0; i < camResX * camResY; ++i)
pixels[i] = 0;
pixelCounts = pixels;
countCamera = c;
countPixels = 1;
countOK = 1;
if (complexRender)
RCL_renderComplex(c,testArrayFunc,testArrayFunc2,0,constraints);
else
RCL_renderSimple(c,testArrayFunc,0,0,constraints);
for (uint32_t y = 0; y < camResY; ++y)
for (uint32_t x = 0; x < camResX; ++x)
{
uint32_t index = y * camResX + x;
if (pixels[index] != 1)
{
printf("ERROR: pixel at %d %d written %d times!\n",x,y,pixels[index]);
countOK = 0;
}
}
return countOK;
}
2018-09-04 19:32:47 +02:00
void benchmarkRender()
{
2018-09-21 08:56:17 +02:00
RCL_Camera c;
2018-09-04 19:32:47 +02:00
c.resolution.x = 640;
c.resolution.y = 300;
c.position.x = 10;
c.position.y = 12;
c.direction = 100;
c.height = 200;
2018-09-21 08:56:17 +02:00
RCL_RayConstraints constraints;
2018-09-04 19:32:47 +02:00
constraints.maxHits = 10;
constraints.maxSteps = 12;
2018-09-21 09:20:57 +02:00
countPixels = 0;
2018-09-04 19:32:47 +02:00
for (int i = 0; i < 100; ++i)
2018-09-21 08:56:17 +02:00
RCL_renderComplex(c,testArrayFunc,testArrayFunc2,0,constraints);
2018-09-04 19:32:47 +02:00
}
2018-08-23 02:46:40 +02:00
int main()
{
printf("Testing raycastlib.\n");
if (!testSingleRay(
2018-09-21 08:56:17 +02:00
3 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2,
4 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2,
2018-08-23 02:46:40 +02:00
100, 50,
10, 7,
10240, 7936,
16))
return 1;
2018-08-23 03:04:52 +02:00
if (!testSingleRay(
0,
0,
100, 100,
10, 9,
2018-08-31 10:59:32 +02:00
10240, 10240,
2018-08-23 03:04:52 +02:00
16))
return 1;
2018-08-31 10:59:32 +02:00
if (!testSingleRay(
400,
6811,
-629,805,
-1, 7,
-1, 7325,
16))
return 1;
2018-09-02 21:43:44 +02:00
if (!testSingleRay(
2018-09-21 08:56:17 +02:00
-4 * RCL_UNITS_PER_SQUARE - RCL_UNITS_PER_SQUARE / 2,
7 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 3,
2018-09-02 21:43:44 +02:00
100,-100,
0, 2,
1, 2900,
16))
return 1;
2018-09-17 15:05:38 +02:00
printf("testing perspective scale...\n");
2018-09-21 08:56:17 +02:00
for (RCL_Unit i = 1; i < 100; ++i)
2018-09-17 15:05:38 +02:00
{
2018-09-21 08:56:17 +02:00
RCL_Unit size = i * 3;
RCL_Unit distance = i * 6 + 200;
2018-09-17 15:05:38 +02:00
2018-09-21 08:56:17 +02:00
RCL_Unit scaled = RCL_perspectiveScale(size,distance);
RCL_Unit distance2 = RCL_perspectiveScaleInverse(size,scaled);
2018-09-17 15:05:38 +02:00
2018-09-21 08:56:17 +02:00
if (RCL_absVal(distance - distance2 > 2))
2018-09-17 15:05:38 +02:00
printf("ERROR: distance: %d, distance inverse: %d\n",distance,distance2);
}
printf("OK\n");
2018-09-21 09:20:57 +02:00
if (!testPixelCount(
RCL_UNITS_PER_SQUARE / 2,
RCL_UNITS_PER_SQUARE / 2,
RCL_UNITS_PER_SQUARE / 2,
0,
0,
128,
64,
1))
return 1;
if (!testPixelCount(
3 * RCL_UNITS_PER_SQUARE + 100,
4 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 3,
RCL_UNITS_PER_SQUARE,
312,
0,
200,
63,
0))
return 1;
if (!testPixelCount(
- RCL_UNITS_PER_SQUARE,
0,
300,
-600,
-120,
64,
68,
1))
return 1;
printf("OK\n");
2018-09-17 15:05:38 +02:00
/*
2018-09-04 13:01:14 +02:00
if (!testSingleMapping(
2018-09-21 08:56:17 +02:00
-RCL_UNITS_PER_SQUARE,
2018-09-04 13:01:14 +02:00
0,
2018-09-21 08:56:17 +02:00
RCL_UNITS_PER_SQUARE / 2,
2018-09-04 13:01:14 +02:00
1280,
640,
0,
0,
0,
2018-09-21 08:56:17 +02:00
RCL_UNITS_PER_SQUARE / 2,
2018-09-04 18:55:18 +02:00
640,
0,
2018-09-04 13:01:14 +02:00
1024
))
return -1;
2018-09-17 15:05:38 +02:00
*/
2018-08-31 10:59:32 +02:00
printf("benchmark:\n");
2018-08-31 11:20:36 +02:00
long t;
t = measureTime(benchCastRays);
printf("cast 1000000 rays: %ld ms\n",t);
2018-09-04 12:39:26 +02:00
t = measureTime(benchmarkMapping);
printf("map point to screen 1000000 times: %ld ms\n",t);
2018-09-04 19:32:47 +02:00
t = measureTime(benchmarkRender);
printf("render 100 times: %ld ms\n",t);
2018-08-31 15:38:02 +02:00
printf("\n");
printProfile();
2018-08-23 02:46:40 +02:00
return 0;
}