/* * JoeyLib 3D * Copyright (C) 2019 Scott Duensing * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #ifndef H_J3D_ #define H_J3D_ #include "joey.h" // Sad start to fixed point math #ifdef JOEY_IIGS //typedef extended jreal; typedef float jreal; #else typedef float jreal; #endif typedef enum { DIRTYNESS_CLEAN = 0x00, DIRTYNESS_SCALE = 0x01, DIRTYNESS_ROTATE = 0x03, DIRTYNESS_TRANSLATE = 0x07, DIRTYNESS_ALL = 0xFF } j3DirtynessT; typedef jreal j3Matrix4x4T[4][4]; typedef struct { jint16 x; jint16 y; jint16 z; } j3FacingT; typedef struct { jreal x; jreal y; jreal z; } j3VertexT, j3Vector3DT; typedef struct { // original -> scaled -> rotated -> translated -> camera j3VertexT original; // Original vertex positions j3VertexT scaled; // After scaling j3VertexT rotated; // After rotation (aka "local") j3VertexT translated; // After translation (aka "world") j3VertexT camera; // Camera space } j3CoordinatesT; typedef struct { jint16 color; // Assigned color of this face jint16 shade; // Color of this face after lighting bool lit; // Do we care about lighting? bool visible; // Can we see this triangle? bool twoSided; // Are both sides visible? jreal normalLength; // Magnatude of surface normal jreal averageDepth; // Average Z depth of this triangle juint16 index[3]; // We do this instead of just a typedef so it works with stretch_buffer } j3TriangleT; typedef struct { jint16 color; // Assigned color of this face bool lit; // Do we care about lighting? bool twoSided; // Are both sides visible? jreal normalLength; // Magnatude of surface normal juint16 index[3]; // We do this instead of just a typedef so it works with stretch_buffer } j3TriangleThinT; typedef struct { juint16 vertexCount; // How many verticies are in the list juint16 triangleCount; // How many triangles are in the list j3CoordinatesT *vertices; // List of vertices as loaded from disk (more v1, v2, v3 than x, y, z) j3TriangleT *triangles; // Triangles built from vertex list j3VertexT position; // Position of object in world j3VertexT rotation; // Rotation of object in world j3VertexT scale; // Scale of object in world j3DirtynessT howDirty; // How much do we need to recalculate? } j3ObjectT; typedef struct { j3ObjectT *object; juint16 triangleNumber; } j3PolyListT; typedef struct { juint16 objectCount; // Number of objects in world j3ObjectT *objects; // Objects data j3PolyListT *polygons; // Polygons to render juint16 polygonCount; // Current visible polygons juint16 triangleCount; // Current triangles in world } j3WorldT; typedef struct { juint16 vertexCount; // How many verticies are in the list juint16 triangleCount; // How many triangles are in the list j3VertexT *vertices; // List of vertices as loaded from disk (more v1, v2, v3 than x, y, z) j3TriangleThinT *triangles; // Triangles built from vertex list } j3PieceT; typedef struct { juint16 pieceCount; // Number of pieces in the prop j3PieceT *pieces; // Piece data } j3PropT; // Couple inline routines #define j3MathCheckBounds(value, min, max) \ if (value < (min)) value = (min); \ if (value > (max)) value = (max) #define j3MathWrapBounds(value, min, max) \ if (value < (min)) value += (max); \ if (value > (max)) value -= (max) // Syntatic sugar #define j3ObjectMove(o, px, py, pz) _j3ObjectMove(&(o), (px), (py), (pz)) #define j3ObjectMoveTo(o, px, py, pz) _j3ObjectMoveTo(&(o), (px), (py), (pz)) #define j3ObjectReset(o) _j3ObjectReset(&(o)) #define j3ObjectRotate(o, px, py, pz) _j3ObjectRotate(&(o), (px), (py), (pz)) #define j3ObjectRotateTo(o, px, py, pz) _j3ObjectRotateTo(&(o), (px), (py), (pz)) #define j3ObjectScale(o, px, py, pz) _j3ObjectScale(&(o), (px), (py), (pz)) #define j3ObjectScaleTo(o, px, py, pz) _j3ObjectScaleTo(&(o), (px), (py), (pz)) #define j3PropFree(p) _j3PropFree((j3PropT **)&(p)) #define j3PropLoad(p, f) _j3PropLoad((j3PropT **)&(p), (f)) #define j3WorldAddProp(w, p) _j3WorldAddProp((j3WorldT **)&(w), (p)) #define j3WorldFree(w) _j3WorldFree((j3WorldT **)&(w)) // Prototypes void j3CameraMove(jreal x, jreal y, jreal z); void j3CameraMoveTo(jreal x, jreal y, jreal z); void j3CameraRotate(jreal x, jreal y, jreal z); void j3CameraRotateTo(jreal x, jreal y, jreal z); void j3CameraSetClippingBounds(jint16 x1, jint16 y1, jint16 x2, jint16 y2); void j3DrawTriangle2D(jint16 x1, jint16 y1, jint16 x2, jint16 y2, jint16 x3, jint16 y3, jint16 color); void j3DrawWorld(j3WorldT *w); void j3MathCrossProduct3D(j3Vector3DT *u, j3Vector3DT *v, j3Vector3DT *normal); jreal j3MathDotProduct3D(j3Vector3DT *u, j3Vector3DT *v); void j3MathMatrix4x4Identity(j3Matrix4x4T result); void j3MathMatrix4x4Mult(j3Matrix4x4T a, j3Matrix4x4T b, j3Matrix4x4T result); void j3MathMakeVector3D(j3VertexT *init, j3VertexT *term, j3Vector3DT *result); jreal j3MathVectorMagnatude3D(j3Vector3DT *v); void j3UtilShutdown(void); void j3UtilStartup(void); // Private Prototypes void _j3ObjectMove(j3ObjectT *o, jreal x, jreal y, jreal z); void _j3ObjectMoveTo(j3ObjectT *o, jreal x, jreal y, jreal z); void _j3ObjectReset(j3ObjectT *o); void _j3ObjectRotate(j3ObjectT *o, jreal x, jreal y, jreal z); void _j3ObjectRotateTo(j3ObjectT *o, jreal x, jreal y, jreal z); void _j3ObjectScale(j3ObjectT *o, jreal x, jreal y, jreal z); void _j3ObjectScaleTo(j3ObjectT *o, jreal x, jreal y, jreal z); void _j3PropFree(j3PropT **prop); jint16 _j3PropLoad(j3PropT **prop, char *file); jint16 _j3WorldAddProp(j3WorldT **world, j3PropT *prop); void _j3WorldFree(j3WorldT **world); #endif // H_J3D_