summaryrefslogtreecommitdiff
path: root/src/vertex.h
diff options
context:
space:
mode:
authorSimponic <loganthebean222@gmail.com>2020-08-04 23:36:21 -0600
committerSimponic <loganthebean222@gmail.com>2020-08-04 23:36:21 -0600
commitebd81999b71ada201a316060fa47a7a66a277935 (patch)
tree930be8337e1144ba227bedb3e72e4473309c28e8 /src/vertex.h
parentb323ae0ca067deb0a48e3d9088160383d698a28f (diff)
downloadsimple3dengine-ebd81999b71ada201a316060fa47a7a66a277935.tar.gz
simple3dengine-ebd81999b71ada201a316060fa47a7a66a277935.zip
Added files
Diffstat (limited to 'src/vertex.h')
-rw-r--r--src/vertex.h112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/vertex.h b/src/vertex.h
new file mode 100644
index 0000000..7880495
--- /dev/null
+++ b/src/vertex.h
@@ -0,0 +1,112 @@
+#include "defs.h"
+#include "fixed.h"
+#include "pt.h"
+#include <math.h>
+
+#ifndef VERTEX_H
+#define VERTEX_H
+
+typedef struct VERTEX {
+ FIXED x;
+ FIXED y;
+ FIXED z;
+} VERTEX;
+
+static inline POINT viewportToScreen (POINT *point) {
+ // Convert a viewport coordinate to screen x, y
+ return createPoint(fixed_multiply(point->x, fixed_divide(WINDOW_WIDTH << FIX_SHIFT, viewport_width << FIX_SHIFT)),
+ fixed_multiply(point->y, fixed_divide(WINDOW_HEIGHT << FIX_SHIFT, viewport_height << FIX_SHIFT))
+ );
+}
+
+static inline POINT projectVertex(VERTEX *vertex) {
+ // Project a vertex to a point
+ POINT temp;
+ if (vertex->z != 0) {
+ // Make sure we don't divide by zero
+ temp = createPoint(fixed_multiply(vertex->x, fixed_divide(ZPlane << FIX_SHIFT, vertex->z)),
+ fixed_multiply(vertex->y, fixed_divide(ZPlane << FIX_SHIFT, vertex->z))
+ );
+ }
+ else {
+ temp = createPoint(0, 0);
+ }
+ temp = viewportToScreen(&temp);
+ return temp;
+}
+
+static inline VERTEX createVertex(FIXED x, FIXED y, FIXED z) {
+ // Create a vertex from data
+ VERTEX temp;
+ temp.x = x;
+ temp.y = y;
+ temp.z = z;
+ return temp;
+}
+
+static inline VERTEX addVertices(VERTEX *a, VERTEX *b) {
+ // Add two vertices together
+ VERTEX temp = createVertex(a->x + b->x, a->y + b->y, a->z + b->z);
+ return temp;
+}
+
+static inline void applyXRotation(VERTEX *vertex, FIXED xRotation) {
+ // Apply rotation to vertex on x-axis
+ FIXED sinTheta = float_to_fixed(sin(fixed_to_float(xRotation) * (3.14159 / 180)));
+ FIXED cosTheta = float_to_fixed(cos(fixed_to_float(xRotation) * (3.14159 / 180)));
+ FIXED y = vertex->y;
+ FIXED z = vertex->z;
+ vertex->y = fixed_multiply(y, cosTheta) - fixed_multiply(z, sinTheta);
+ vertex->z = fixed_multiply(z, cosTheta) + fixed_multiply(y, sinTheta);
+}
+
+static inline void applyYRotation(VERTEX *vertex, FIXED yRotation) {
+ // Apply rotation to vertex on y-axis
+ FIXED sinTheta = float_to_fixed(sin(fixed_to_float(yRotation) * (3.14159 / 180)));
+ FIXED cosTheta = float_to_fixed(cos(fixed_to_float(yRotation) * (3.14159 / 180)));
+ FIXED x = vertex->x;
+ FIXED z = vertex->z;
+ vertex->x = fixed_multiply(x, cosTheta) + fixed_multiply(z, sinTheta);
+ vertex->z = fixed_multiply(z, cosTheta) - fixed_multiply(x, sinTheta);
+}
+
+static inline void applyZRotation(VERTEX *vertex, FIXED zRotation) {
+ // Apply rotation to vertex on z-axis
+ FIXED sinTheta = float_to_fixed(sin(fixed_to_float(zRotation) * (3.14159 / 180)));
+ FIXED cosTheta = float_to_fixed(cos(fixed_to_float(zRotation) * (3.14159 / 180)));
+ FIXED x = vertex->x;
+ FIXED y = vertex->y;
+ vertex->x = fixed_multiply(x, cosTheta) - fixed_multiply(y, sinTheta);
+ vertex->y = fixed_multiply(y, cosTheta) + fixed_multiply(x, sinTheta);
+}
+
+static inline VERTEX crossProduct(VERTEX *a, VERTEX *b) {
+ // Calculate the cross product of two vertices
+ return createVertex(
+ fixed_multiply(a->y, b->z) - fixed_multiply(a->z, b->y),
+ fixed_multiply(a->z, b->x) - fixed_multiply(a->x, b->z),
+ fixed_multiply(a->x, b->y) - fixed_multiply(a->y, b->x)
+ );
+}
+
+static inline FIXED dotProduct(VERTEX *a, VERTEX *b) {
+ // Dot two vertices
+ FIXED product = fixed_multiply(a->x, b->x) +
+ fixed_multiply(a->y, b->y) +
+ fixed_multiply(a->z, b->z);
+ return product;
+}
+
+static inline void normalizeVertex(VERTEX *vertex) {
+ // Normalize (magnitude = 1) a vertex
+ float x = fixed_to_float(vertex->x);
+ float y = fixed_to_float(vertex->y);
+ float z = fixed_to_float(vertex->z);
+ float d = sqrtf(x*x + y*y + z*z);
+
+ vertex->x = float_to_fixed(fixed_to_float(vertex->x) / d);
+ vertex->y = float_to_fixed(fixed_to_float(vertex->y) / d);
+ vertex->z = float_to_fixed(fixed_to_float(vertex->z) / d);
+}
+
+#endif // VERTEX_H