/** General tests for raycastlib, use to test new version, different platforms etc. license: CC0 */ #define RCL_PROFILE #define RCL_PIXEL_FUNCTION pixelFunc #include #include "../raycastlib.h" #include static const char renderSimpleExpect[] = ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,EEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,EEEEEEEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,EEEEEEEEEEEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FEEEEEEEEEEEEEEEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," "ddddddddddddddde,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," "dddddddddddddddeeeeeeeeeeeeeeee,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffg,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhi,,,,,FFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDD,,,,,,,,," "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhii....FFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhh.........FFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggg...............FFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffg.....................FFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeeffffffff...........................FFFFFFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeeeeeeff.....................................FFEEEEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeeeeeeee..............................................EEEEEEEEEEEEEDDDDDDDDDDD" "dddddddddddddddeeeeeeeeee........................................................EEEEEEEEDDDDDDDDDDD" "dddddddddddddddeee....................................................................EEEDDDDDDDDDDD" "ddddddddddddd.............................................................................DDDDDDDDDD" "ddddddd........................................................................................DDDDD" "dd.................................................................................................D" "...................................................................................................."; static const char renderComplexExpect[] = ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,EEDDe,,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,EEEEEEDDee,,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,EEEEEEEEEEEDDeee,,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,EEEEEEEEEEEEEEEDDeeee,,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFEEEEEEEEEEEEEEEDDeeeef,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeef,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeef,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeef,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeef,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeef,,,," ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeef,,,," "ddddddddddddddd,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeef,,,," "dddddddddddddddeeeeeeeeeeeeeee,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeef,,,," "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffff,,,,,,,,,,,,,,,,,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeef,,,," "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhh,,,,,,FFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhiiiiiiFFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhhhhhhii....FFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffggggggggghhh..........FFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffgggggg................FFFFFFEEEEEEEEEEEEEEEDDeeeefGGGG" "dddddddddddddddeeeeeeeeeeeeeeeeeefffffffffffffg.....................FFFFFFEEEEEEEEEEEEEEEDDeeeef...." "dddddddddddddddeeeeeeeeeeeeeeeeeefffffff............................FFFFFFEEEEEEEEEEEEEEEDDeeeef...." "dddddddddddddddeeeeeeeeeeeeeeeeeeff.....................................FFEEEEEEEEEEEEEEEDDeeeefF..." "dddddddddddddddeeeeeeeeeeeeee................................................EEEEEEEEEEEEDDeeeefFFFE" "dddddddddddddddeeeeeeee...........................................................EEEEEEEDDeeeefFFFE" "dddddddddddddddeee....................................................................EEEDDeeee....." "ddddddddddd.................................................................................ee......" "ddddddd............................................................................................." "...................................................................................................." "...................................................................................................."; RCL_Unit testArrayFunc(int16_t x, int16_t y) { if (x == 1 & y == 8) return RCL_UNITS_PER_SQUARE * 3; if (x == 2 & y == 8) return -1 * RCL_UNITS_PER_SQUARE / 4; return (x < 0 || x >= 10 || y < 0 || y >= 10) ? (RCL_UNITS_PER_SQUARE * 2) : 0; } int testSingleRay(RCL_Unit startX, RCL_Unit startY, RCL_Unit dirX, RCL_Unit dirY, int16_t expectSquareX, int16_t expectSquareY, int16_t expectPointX, int16_t expectPointY, int16_t tolerateError) { RCL_Ray r; r.start.x = startX; r.start.y = startY; r.direction.x = dirX; r.direction.y = dirY; printf("- casting ray:\n"); RCL_logRay(r); RCL_HitResult h = RCL_castRay(r,testArrayFunc); printf("- result:\n"); RCL_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) printf("\nOK\n\n"); else printf("\nFAIL\n\n"); return result; } 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) { int result; RCL_Camera c; RCL_initCamera(&c); c.resolution.x = resX; c.resolution.y = resY; c.position.x = camX; c.position.y = camY; c.direction = camDir; c.height = camZ; RCL_Vector2D pos; RCL_Unit height; pos.x = posX; pos.y = posY; height = posZ; RCL_PixelInfo p; printf("- mapping pixel: %d %d %d\n",posX,posY,posZ); p = RCL_mapToScreen(pos,height,c); printf("- result:\n"); RCL_logPixelInfo(p); 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; } // 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() { RCL_Ray r; 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; RCL_Vector2D directions[8]; for (int i = 0; i < 8; ++i) directions[i] = RCL_angleToDirection(RCL_UNITS_PER_SQUARE / 8 * i); for (int i = 0; i < 1000000; ++i) { r.direction = directions[i % 8]; RCL_castRay(r,testArrayFunc); } } void benchmarkMapping() { RCL_Camera c; c.resolution.x = 1024; c.resolution.y = 768; c.position.x = RCL_UNITS_PER_SQUARE / 2; c.position.y = RCL_UNITS_PER_SQUARE * 2; c.direction = RCL_UNITS_PER_SQUARE / 8; c.height = 0; RCL_PixelInfo p; RCL_Vector2D pos; RCL_Unit height; pos.x = -1024 * RCL_UNITS_PER_SQUARE; pos.y = -512 * RCL_UNITS_PER_SQUARE; height = 0; for (int i = 0; i < 1000000; ++i) { p = RCL_mapToScreen(pos,height,c); pos.x += 4; pos.y += 8; height = (height + 16) % 1024; } } int renderMode = 0; uint32_t *pixelCounts = 0; RCL_Camera countCamera; int countOK = 1; #define TEST_SCREEN_RES_X 100 #define TEST_SCREEN_RES_Y 40 char testScreen[TEST_SCREEN_RES_X * TEST_SCREEN_RES_Y]; void pixelFunc(RCL_PixelInfo *p) { if (renderMode == 0) // count pixels { 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]++; } else if (renderMode == 1) { char c = '?'; if (p->isFloor) c = '.'; else c = ','; if (p->isWall) c = (p->hit.direction % 2 ? 'a' : 'A') + p->depth / 512; testScreen[p->position.y * TEST_SCREEN_RES_X + p->position.x] = c; } } 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 (each should be rendered exactly once)...\n"); RCL_RayConstraints constraints; RCL_Camera c; RCL_initRayConstraints(&constraints); constraints.maxSteps = 32; 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 (int32_t i = 0; i < camResX * camResY; ++i) pixels[i] = 0; pixelCounts = pixels; countCamera = c; renderMode = 0; countOK = 1; if (complexRender) RCL_renderComplex(c,testArrayFunc,testArrayFunc,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; } int testRender(int8_t simple) { printf("\nTesting rendering\n"); renderMode = 1; RCL_Camera c; RCL_initCamera(&c); c.resolution.x = TEST_SCREEN_RES_X; c.resolution.y = TEST_SCREEN_RES_Y; c.position.x = 2 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2; // 3000;//5 * RCL_UNITS_PER_SQUARE; c.position.y = 5 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2; //5000;//5 * RCL_UNITS_PER_SQUARE; c.direction = 625;//700; c.height = 1500;//1000; RCL_RayConstraints constraints; RCL_initRayConstraints(&constraints); constraints.maxHits = 7; constraints.maxSteps = 20; renderMode = 1; for (uint32_t i = 0; i < TEST_SCREEN_RES_X * TEST_SCREEN_RES_Y; ++i) testScreen[i] = '?'; if (simple) { RCL_renderSimple(c,testArrayFunc,0,0,constraints); } else { RCL_renderComplex(c,testArrayFunc,0,0,constraints); } for (uint32_t i = 0; i < TEST_SCREEN_RES_X * TEST_SCREEN_RES_Y; ++i) { if ((i % TEST_SCREEN_RES_X) == 0) printf(" \n"); printf("%c",testScreen[i]); } const char *expect = simple ? renderSimpleExpect : renderComplexExpect; for (uint32_t i = 0; i < TEST_SCREEN_RES_X * TEST_SCREEN_RES_Y; ++i) if (expect[i] != testScreen[i]) { printf("\n\nFAIL!\n"); return 0; } printf("\n\nOK\n"); return 1; } void benchmarkRender() { RCL_Camera c; RCL_initCamera(&c); c.resolution.x = 640; c.resolution.y = 300; c.position.x = 10; c.position.y = 12; c.direction = 100; c.height = 200; RCL_RayConstraints constraints; RCL_initRayConstraints(&constraints); constraints.maxHits = 10; constraints.maxSteps = 12; renderMode = 255; // don't write pixels for (int i = 0; i < 100; ++i) RCL_renderComplex(c,testArrayFunc,testArrayFunc,0,constraints); } int main() { printf("Testing raycastlib.\n"); if (!testSingleRay( 3 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2, 4 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2, 100, 50, 10, 7, 10240, 7936, 16)) return 1; if (!testSingleRay( 0, 0, 100, 100, 9, 10, 10240, 10240, 16)) return 1; if (!testSingleRay( 400, 6811, -629,805, -1, 7, -1, 7325, 16)) return 1; if (!testSingleRay( -4 * RCL_UNITS_PER_SQUARE - RCL_UNITS_PER_SQUARE / 2, 7 * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 3, 100,-100, 0, 2, 1, 2900, 16)) return 1; printf("testing perspective scale...\n"); for (RCL_Unit i = 1; i < 100; ++i) { RCL_Unit size = i * 3; RCL_Unit distance = i * 6 + 200; RCL_Unit scaled = RCL_perspectiveScaleHorizontal(size,distance); RCL_Unit distance2 = RCL_perspectiveScaleHorizontalInverse(size,scaled); if (RCL_abs(distance - distance2 > 2)) printf("ERROR: distance: %d, distance inverse: %d\n",distance,distance2); } printf("OK\n"); 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 / 2, 512, 0, 120, 60, 0)) return 1; if (!testPixelCount( - RCL_UNITS_PER_SQUARE, 0, 300, -600, -120, 64, 68, 1)) return 1; printf("OK\n"); if (!testSingleMapping( RCL_UNITS_PER_SQUARE, RCL_UNITS_PER_SQUARE * 2, 0, 800, 640, RCL_UNITS_PER_SQUARE / 2, 0, RCL_UNITS_PER_SQUARE / 4, (RCL_UNITS_PER_SQUARE * 5) / 6, 287, 365, 2027 )) return 1; if (!testRender(0)) return 1; if (!testRender(1)) return 1; printf("benchmark:\n"); long t; t = measureTime(benchCastRays); printf("cast 1000000 rays: %ld ms\n",t); t = measureTime(benchmarkMapping); printf("map point to screen 1000000 times: %ld ms\n",t); t = measureTime(benchmarkRender); printf("render 100 times: %ld ms\n",t); printf("\n===== all OK =====\n"); return 0; }