/* * 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" //***TODO*** verticies is vertices typedef float j3Matrix4x4T[4][4]; typedef struct { jint16 x; jint16 y; jint16 z; } j3FacingT; typedef struct { float x; float y; float z; } j3VertexT, j3Vector3DT; typedef struct { j3VertexT local; // Original vertex positions j3VertexT world; // After rotation, scale, translation (in that order) 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? float normalLength; // Magnatude of surface normal juint16 index[3]; // We do this instead of just a typedef so it works with stretch_buffer } j3TriangleT; typedef struct { juint16 vertexCount; // How many verticies are in the list juint16 triangleCount; // How many triangles are in the list j3CoordinatesT *verticies; // List of verticies 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 bool positionDirty; // Did the position change? bool rotationDirty; // Did the rotation change? bool scaleDirty; // Did the scale change? } j3ObjectT; typedef struct { juint16 objectCount; j3ObjectT *objects; } j3WorldT; #define jtCameraSetClippingBounds(x1, y1, x2, y2) \ clipMinX = (x1); j3MathCheckBounds(clipMinX, 0, 319); \ clipMinY = (y1); j3MathCheckBounds(clipMiny, 0, 199); \ clipMaxX = (x2); j3MathCheckBounds(clipMaxX, 0, 319); \ clipMaxY = (y2); j3MathCheckBounds(clipMaxy, 0, 199) #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) #define j3ObjectMove(ob, px, py, pz) \ ob.position.x += (px); \ ob.position.y += (py); \ ob.position.z += (pz); \ ob.positionDirty = true #define j3ObjectMoveTo(ob, px, py, pz) \ ob.position.x = (px); \ ob.position.y = (py); \ ob.position.z = (pz); \ ob.positionDirty = true #define j3ObjectRotate(ob, px, py, pz) \ ob.rotation.x += (px); j3MathWrapBounds(ob.rotation.x, 0, 360); \ ob.rotation.y += (py); j3MathWrapBounds(ob.rotation.y, 0, 360); \ ob.rotation.z += (pz); j3MathWrapBounds(ob.rotation.z, 0, 360); \ ob.rotationDirty = true #define j3ObjectRotateTo(ob, px, py, pz) \ ob.rotation.x = (px); j3MathWrapBounds(ob.rotation.x, 0, 360); \ ob.rotation.y = (py); j3MathWrapBounds(ob.rotation.y, 0, 360); \ ob.rotation.z = (pz); j3MathWrapBounds(ob.rotation.z, 0, 360); \ ob.rotationDirty = true #define j3ObjectScale(ob, px, py, pz) \ ob.scale.x += (px); \ ob.scale.y += (py); \ ob.scale.z += (pz); \ ob.scaleDirty = true #define j3ObjectScaleTo(ob, px, py, pz) \ ob.scale.x = (px); \ ob.scale.y = (py); \ ob.scale.z = (pz); \ ob.scaleDirty = true // Syntatic sugar #define j3DrawSolid(o) _j3DrawSolid(&(o)) #define j3DrawWireframe(o) _j3DrawWireframe(&(o)) #define j3ObjectReset(o) _j3ObjectReset(&(o)) #define j3ObjectUpdate(o) _j3ObjectUpdate(&(o)) #define j3WorldFree(w) _j3WorldFree((j3WorldT **)&(w)) #define j3WorldLoad(w, f) _j3WorldLoad((j3WorldT **)&(w), (f)) // Prototypes void j3DrawTriangle2D(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3, jint16 y3, jint16 color); void j3MathCrossProduct3D(j3Vector3DT *u, j3Vector3DT *v, j3Vector3DT *normal); float 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); float j3MathVectorMagnatude3D(j3Vector3DT *v); void j3UtilShutdown(void); void j3UtilStartup(void); // Private Prototypes void _j3DrawSolid(j3ObjectT *o); void _j3DrawTriangleBottom(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3, jint16 y3); void _j3DrawTriangleTop(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3, jint16 y3); void _j3DrawWireframePair(j3ObjectT *o, juint16 v1, juint16 v2); void _j3DrawWireframe(j3ObjectT *o); void _j3ObjectReset(j3ObjectT *o); void _j3ObjectUpdateNormalLength(j3ObjectT *object, juint16 triangle); void _j3ObjectUpdate(j3ObjectT *o); bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2); void _j3WorldFree(j3WorldT **world); bool _j3WorldLoad(j3WorldT **world, char *file); #endif // H_J3D_