1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/small3dlib.git synced 2024-11-20 20:29:58 +01:00

Continue drawModel

This commit is contained in:
Miloslav Číž 2018-11-20 12:45:40 +01:00
parent cc76683114
commit 360df9fe83
2 changed files with 69 additions and 23 deletions

91
s3l.h
View file

@ -59,13 +59,50 @@ typedef int16_t S3L_Unit; /**< Units of measurement in 3D space. There is
typedef int16_t S3L_ScreenCoord;
typedef uint16_t S3L_Index;
typedef struct
{
S3L_Unit x;
S3L_Unit y;
S3L_Unit z;
} S3L_Vec3;
static inline void S3L_initVec3(S3L_Vec3 *v)
{
v->x = 0; v->y = 0; v->z = 0;
}
typedef struct
{
S3L_Vec3 offset;
S3L_Vec3 rotation;
S3L_Vec3 scale;
} S3L_Transform3D;
static inline void S3L_initTransoform3D(S3L_Transform3D *t)
{
S3L_initVec3(&(t->offset));
S3L_initVec3(&(t->rotation));
t->scale.x = S3L_FRACTIONS_PER_UNIT;
t->scale.y = S3L_FRACTIONS_PER_UNIT;
t->scale.z = S3L_FRACTIONS_PER_UNIT;
}
typedef struct
{
uint16_t resolutionX;
uint16_t resolutionY;
S3L_Unit focalLength; ///< Defines the field of view (FOV).
S3L_Transform3D transform;
} S3L_Camera;
static inline void S3L_initCamera(S3L_Camera *c)
{
c->resolutionX = 128;
c->resolutionY = 64;
c->focalLength = S3L_FRACTIONS_PER_UNIT;
S3L_initTransoform3D(&(c->transform));
}
typedef struct
{
S3L_ScreenCoord x; ///< Screen X coordinate.
@ -82,6 +119,16 @@ typedef struct
S3L_Index triangleID;
} S3L_PixelInfo;
static inline void S3L_initPixelInfo(S3L_PixelInfo *p)
{
p->x = 0;
p->y = 0;
p->barycentric0 = S3L_FRACTIONS_PER_UNIT;
p->barycentric1 = 0;
p->barycentric2 = 0;
p->triangleID = 0;
}
#define S3L_BACKFACE_CULLING_NONE 0
#define S3L_BACKFACE_CULLING_CW 1
#define S3L_BACKFACE_CULLING_CCW 2
@ -250,10 +297,7 @@ void S3L_drawTriangle(
}
S3L_PixelInfo p;
p.barycentric0 = 0;
p.barycentric1 = 0;
p.barycentric2 = 0;
S3L_initPixelInfo(&p);
// point mode
@ -511,20 +555,23 @@ void S3L_drawTriangle(
#undef stepSide
}
void S3L_mapViewToScreen(
S3L_Unit viewX,
S3L_Unit viewY,
S3L_Unit viewZ,
uint16_t screenWidth,
uint16_t screenHeight,
S3L_ScreenCoord *screenX,
S3L_ScreenCoord *screenY)
static inline void S3L_mapWorldToCamera(S3L_Vec3 point,
S3L_Transform3D *cameraTransform, S3L_Vec3 *newPoint)
{
uint16_t halfW = screenWidth >> 1; // TODO: precompute earlier?
uint16_t halfH = screenHeight >> 1;
newPoint->x = point.x - cameraTransform->offset.x;
newPoint->y = point.y - cameraTransform->offset.y;
newPoint->z = point.z - cameraTransform->offset.z;
}
*screenX = halfW + (viewX * halfW) / S3L_FRACTIONS_PER_UNIT;
*screenY = halfH - (viewY * halfW) / S3L_FRACTIONS_PER_UNIT;
static inline void S3L_mapCameraToScreen(S3L_Vec3 point, S3L_Camera *camera,
S3L_ScreenCoord *screenX, S3L_ScreenCoord *screenY)
{
uint16_t halfW = camera->resolutionX >> 1; // TODO: precompute earlier?
uint16_t halfH = camera->resolutionY >> 1;
*screenX = halfW + (point.x * halfW) / point.z;
*screenY = halfH - (point.y * halfW) / point.z;
// ^ S3L_FRACTIONS_PER_UNIT cancel out
}
void S3L_drawModel(
@ -540,19 +587,19 @@ void S3L_drawModel(
while (triangleIndex < triangleCount)
{
S3L_ScreenCoord sX0, sY0, sX1, sY1, sX2, sY2;
S3L_Unit vX, vY, vZ;
S3L_Vec3 point, point2;
S3L_Unit indexIndex;
#define mapCoords(n)\
indexIndex = triangleVertexIndices[coordIndex] * 3;\
vX = coords[indexIndex];\
point.x = coords[indexIndex];\
++indexIndex; /* TODO: put into square brackets? */\
vY = coords[indexIndex];\
point.y = coords[indexIndex];\
++indexIndex;\
vZ = coords[indexIndex];\
point.z = coords[indexIndex];\
++coordIndex;\
S3L_mapViewToScreen(\
vX,vY,vZ,camera.resolutionX,camera.resolutionY,&sX##n,&sY##n);
S3L_mapWorldToCamera(point,&camera.transform,&point2);\
S3L_mapCameraToScreen(point2,&camera,&sX##n,&sY##n);
mapCoords(0)
mapCoords(1)

View file

@ -43,7 +43,6 @@ void drawPixel(S3L_PixelInfo *p)
p->barycentric0 / ((float) S3L_FRACTIONS_PER_UNIT) * 255,
p->barycentric1 / ((float) S3L_FRACTIONS_PER_UNIT) * 255,
p->barycentric2 / ((float) S3L_FRACTIONS_PER_UNIT) * 255);
}
const int16_t test_coords[] =