2018-08-23 09:25:34 +02:00
|
|
|
/**
|
|
|
|
Tests for raycastlib.
|
|
|
|
|
|
|
|
license: CC0
|
|
|
|
*/
|
|
|
|
|
2018-08-31 15:38:02 +02:00
|
|
|
#define RAYCASTLIB_PROFILE
|
|
|
|
|
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
|
|
|
|
|
|
|
int16_t testArrayFunc(int16_t x, int16_t y)
|
|
|
|
{
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Simple automatic test function.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int testSingleRay(Unit startX, Unit startY, Unit dirX, Unit dirY,
|
|
|
|
int16_t expectSquareX, int16_t expectSquareY, int16_t expectPointX,
|
|
|
|
int16_t expectPointY, int16_t tolerateError)
|
|
|
|
{
|
|
|
|
Ray r;
|
|
|
|
|
|
|
|
r.start.x = startX;
|
|
|
|
r.start.y = startY;
|
|
|
|
r.direction.x = dirX;
|
|
|
|
r.direction.y = dirY;
|
|
|
|
|
|
|
|
printf("- casting ray:\n");
|
|
|
|
logRay(r);
|
|
|
|
|
2018-08-31 13:29:50 +02:00
|
|
|
HitResult h = castRay(r,testArrayFunc);
|
2018-08-23 02:46:40 +02:00
|
|
|
|
|
|
|
printf("- result:\n");
|
|
|
|
logHitResult(h);
|
|
|
|
|
|
|
|
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-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()
|
|
|
|
{
|
|
|
|
Ray r;
|
|
|
|
|
|
|
|
r.start.x = UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;
|
|
|
|
r.start.y = 2 * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 4;
|
|
|
|
|
|
|
|
Vector2D directions[8];
|
|
|
|
|
|
|
|
for (int i = 0; i < 8; ++i)
|
|
|
|
directions[i] = angleToDirection(UNITS_PER_SQUARE / 8 * i);
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000000; ++i)
|
|
|
|
{
|
|
|
|
r.direction = directions[i % 8];
|
2018-08-31 13:29:50 +02:00
|
|
|
castRay(r,testArrayFunc);
|
2018-08-31 11:20:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-04 12:39:26 +02:00
|
|
|
void benchmarkMapping()
|
|
|
|
{
|
|
|
|
Vector2D v;
|
|
|
|
Camera c;
|
|
|
|
|
|
|
|
c.resolution.x = 1024;
|
|
|
|
c.resolution.y = 768;
|
|
|
|
c.position.x = UNITS_PER_SQUARE / 2;
|
|
|
|
c.position.y = UNITS_PER_SQUARE * 2;
|
|
|
|
c.direction = UNITS_PER_SQUARE / 8;
|
|
|
|
c.height = 0;
|
|
|
|
c.fovAngle = UNITS_PER_SQUARE / 2;
|
|
|
|
|
|
|
|
PixelInfo p;
|
|
|
|
|
|
|
|
Vector2D pos;
|
|
|
|
Unit height;
|
|
|
|
|
|
|
|
pos.x = -1024 * UNITS_PER_SQUARE;
|
|
|
|
pos.y = -512 * UNITS_PER_SQUARE;
|
|
|
|
height = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000000; ++i)
|
|
|
|
{
|
|
|
|
p = mapToScreen(pos,height,c);
|
|
|
|
|
|
|
|
pos.x += 4;
|
|
|
|
pos.y += 8;
|
|
|
|
height = (height + 16) % 1024;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-23 02:46:40 +02:00
|
|
|
int main()
|
|
|
|
{
|
|
|
|
printf("Testing raycastlib.\n");
|
|
|
|
|
|
|
|
if (!testSingleRay(
|
|
|
|
3 * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2,
|
|
|
|
4 * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2,
|
|
|
|
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(
|
|
|
|
-4 * UNITS_PER_SQUARE - UNITS_PER_SQUARE / 2,
|
|
|
|
7 * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 3,
|
|
|
|
100,-100,
|
|
|
|
0, 2,
|
|
|
|
1, 2900,
|
|
|
|
16))
|
|
|
|
return 1;
|
|
|
|
|
2018-08-23 09:25:34 +02:00
|
|
|
for (Unit i = -UNITS_PER_SQUARE; i <= UNITS_PER_SQUARE; i += 64)
|
|
|
|
{
|
|
|
|
Unit v = sinInt(i);
|
|
|
|
|
2018-08-23 09:35:10 +02:00
|
|
|
logVector2D(angleToDirection(i));
|
2018-08-23 09:25:34 +02:00
|
|
|
|
2018-08-23 09:35:10 +02:00
|
|
|
//for (int j = 0; j < (v + UNITS_PER_SQUARE) / 64; ++j)
|
|
|
|
// printf(".");
|
|
|
|
|
|
|
|
//printf("\n");
|
2018-08-23 09:25:34 +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-08-31 15:38:02 +02:00
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
printProfile();
|
|
|
|
|
2018-08-23 02:46:40 +02:00
|
|
|
return 0;
|
|
|
|
}
|