From e97ea1c5cc3c86894d8a32460ef098338bdcf660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 16 May 2019 22:02:50 +0200 Subject: [PATCH] Fix z-divide --- s3l.h | 15 +++++++++++++-- testSDL.c | 13 +++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/s3l.h b/s3l.h index e76ff0b..95a77c1 100644 --- a/s3l.h +++ b/s3l.h @@ -323,7 +323,7 @@ typedef S3L_Unit S3L_Mat4[4][4]; /**< 4x4 matrix, used mostly for 3D transforms. The indexing is this: matrix[column][row]. */ #define S3L_writeMat4(m)\ - printf("Mat4:\n %d %d %d %d\n %d %d %d %d\n %d %d %d %d\n %d %d %d %d\n"\ + printfi"Mat4:\n %d %d %d %d\n %d %d %d %d\n %d %d %d %d\n %d %d %d %d\n"\ ,(m)[0][0],(m)[1][0],(m)[2][0],(m)[3][0],\ (m)[0][1],(m)[1][1],(m)[2][1],(m)[3][1],\ (m)[0][2],(m)[1][2],(m)[2][2],(m)[3][2],\ @@ -1356,7 +1356,14 @@ void S3L_makeCameraMatrix(S3L_Transform3D cameraTransform, S3L_Mat4 *m) static inline void S3L_perspectiveDivide(S3L_Vec4 *vector, S3L_Unit focalLength) { - S3L_Unit divisor = S3L_nonZero(vector->z); + S3L_Unit divisor = vector->z > 0 ? vector->z : (-1 * (vector->z - 1)); + /* ^ This has two purposes: + + 1. Prevent division by zero. + 2. Prevent a "rapid flip" of the vertex, e.g.: having a vertex + [100,0,0.1] z-divides it to [1000,0], but when it shift a short + distance to [100,0,-0.1], it z-divides to [-1000,0], rapidly flipping + from right to the left. */ vector->x = (vector->x * focalLength) / divisor; vector->y = (vector->y * focalLength) / divisor; @@ -1398,8 +1405,12 @@ void S3L_drawModelIndexed( transformed##n.x = pointModel.x;\ transformed##n.y = pointModel.y;\ transformed##n.z = pointModel.z;\ + transformed##n.w = S3L_FRACTIONS_PER_UNIT;\ S3L_perspectiveDivide(&transformed##n,camera->focalLength); + /* TODO: maybe create an option that would use a cache here to not + transform the same point twice? */ + project(0) project(1) project(2) diff --git a/testSDL.c b/testSDL.c index f2272a7..b9a9ed8 100644 --- a/testSDL.c +++ b/testSDL.c @@ -127,6 +127,18 @@ S3L_DrawConfig conf; void draw() { +/* + if (frame % 128 == 0) + { + printf("frame: %d\n",frame); + printf("camera:\n"); + printf(" translation: "); + S3L_writeVec4(camera.transform.translation); + printf(" rotation: "); + S3L_writeVec4(camera.transform.rotation); + } +*/ + offScreenPixels = 0; clearScreen(); @@ -198,6 +210,7 @@ int main() S3L_initCamera(&camera); camera.transform.translation.z = -S3L_FRACTIONS_PER_UNIT * 2; + // camera.transform.translation.x = S3L_FRACTIONS_PER_UNIT; // camera.transform.translation.y = S3L_FRACTIONS_PER_UNIT;