joeylib3d/j3d/j3d.h
2019-09-24 18:06:44 -05:00

180 lines
6.7 KiB
C

/*
* JoeyLib 3D
* Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
*
* 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_