From 5b5989bc024e2f573dc3adcf06d4e6a825b53e62 Mon Sep 17 00:00:00 2001 From: anjingyu Date: Sat, 24 May 2025 00:25:19 +0800 Subject: [PATCH] feat: update --- sww/include/sww/cstl_vector.h | 154 +-- sww/include/sww/vmath.h | 2030 +++++++++++++++++---------------- sww/test/proc_anim.c | 250 ++-- 3 files changed, 1290 insertions(+), 1144 deletions(-) diff --git a/sww/include/sww/cstl_vector.h b/sww/include/sww/cstl_vector.h index 8739931..d6db44a 100644 --- a/sww/include/sww/cstl_vector.h +++ b/sww/include/sww/cstl_vector.h @@ -2,77 +2,86 @@ #include -#define CSTLVector(MNAME, MTYPE) \ - typedef struct _tag##MNAME { \ - size_t reserved; \ - size_t size; \ - MTYPE *buffer; \ - } MNAME; \ - typedef MTYPE *MNAME##Iterator; \ - static int MNAME##_Expand(MNAME *o, size_t new_size) { \ - MTYPE *new_buffer; \ - if (new_size <= o->reserved) { \ - return 1; \ - } \ - new_size <<= 1; \ - new_buffer = (MTYPE *)malloc(new_size * sizeof(MTYPE)); \ - if (new_buffer == NULL) { \ - return 0; \ - } \ - memcpy(new_buffer, o->buffer, o->reserved * sizeof(MTYPE)); \ - free(o->buffer); \ - o->buffer = new_buffer; \ - o->reserved = new_size; \ - return 1; \ - } \ - void MNAME##_Construct(MNAME *o, size_t init_size) { \ - o->reserved = 0; \ - o->size = 0; \ - o->buffer = NULL; \ - MNAME##_Expand(o, init_size); \ - } \ - void MNAME##_Destruct(MNAME *o) { \ - free(o->buffer); \ - o->buffer = NULL; \ - o->size = 0; \ - o->reserved = 0; \ - } \ - void MNAME##_Assign(MNAME *o, MTYPE *first, MTYPE *last) { \ - size_t n = last - first; \ - if (n > o->reserved) { \ - MNAME##_Expand(o, n); \ - } \ - memcpy(o->buffer, first, n * sizeof(MTYPE)); \ - o->size = (n > o->size) ? n : o->size; \ - } \ - void MNAME##_PushBack(MNAME *o, MTYPE e) { \ - if (o->size + 1 > o->reserved) \ - MNAME##_Expand(o, o->size + 1); \ - o->buffer[o->size] = e; \ - o->size++; \ - } \ - void MNAME##_Resize(MNAME *o, size_t size) { \ - if (size > o->reserved) \ - MNAME##_Expand(o, size); \ - else \ - o->size = size; \ - } \ - void MNAME##_Insert(MNAME *o, MNAME##Iterator loc, MTYPE e) { \ - size_t _where = loc - o->buffer; \ - if (o->size + 1 > o->reserved) \ - MNAME##_Expand(o, o->size + 1); \ - loc = o->buffer + _where; \ - memmove(loc + 1, loc, (o->size - (loc - o->buffer)) * sizeof(MTYPE)); \ - *loc = e; \ - o->size++; \ - } \ - MNAME##Iterator MNAME##_Erase(MNAME *o, MNAME##Iterator iter) { \ - size_t remain_bytes; \ - remain_bytes = (o->size - 1 - (iter - o->buffer)) * sizeof(MTYPE); \ - memmove(iter, iter + 1, remain_bytes); \ - o->size--; \ - return iter; \ - } +#define CSTLVector(MNAME, MTYPE) \ + typedef struct _tag##MNAME \ + { \ + size_t reserved; \ + size_t size; \ + MTYPE* buffer; \ + } MNAME; \ + typedef MTYPE* MNAME##Iterator; \ + static int MNAME##_Expand(MNAME* o, size_t new_size) \ + { \ + MTYPE* new_buffer; \ + if (new_size <= o->reserved) { \ + return 1; \ + } \ + new_size <<= 1; \ + new_buffer = (MTYPE*)malloc(new_size * sizeof(MTYPE)); \ + if (new_buffer == NULL) { \ + return 0; \ + } \ + memcpy(new_buffer, o->buffer, o->reserved * sizeof(MTYPE)); \ + free(o->buffer); \ + o->buffer = new_buffer; \ + o->reserved = new_size; \ + return 1; \ + } \ + void MNAME##_Construct(MNAME* o, size_t init_size) \ + { \ + o->reserved = 0; \ + o->size = 0; \ + o->buffer = NULL; \ + MNAME##_Expand(o, init_size); \ + } \ + void MNAME##_Destruct(MNAME* o) \ + { \ + free(o->buffer); \ + o->buffer = NULL; \ + o->size = 0; \ + o->reserved = 0; \ + } \ + void MNAME##_Assign(MNAME* o, MTYPE* first, MTYPE* last) \ + { \ + size_t n = last - first; \ + if (n > o->reserved) { \ + MNAME##_Expand(o, n); \ + } \ + memcpy(o->buffer, first, n * sizeof(MTYPE)); \ + o->size = (n > o->size) ? n : o->size; \ + } \ + void MNAME##_PushBack(MNAME* o, MTYPE e) \ + { \ + if (o->size + 1 > o->reserved) \ + MNAME##_Expand(o, o->size + 1); \ + o->buffer[o->size] = e; \ + o->size++; \ + } \ + void MNAME##_Resize(MNAME* o, size_t size) \ + { \ + if (size > o->reserved) \ + MNAME##_Expand(o, size); \ + else \ + o->size = size; \ + } \ + void MNAME##_Insert(MNAME* o, MNAME##Iterator loc, MTYPE e) \ + { \ + size_t _where = loc - o->buffer; \ + if (o->size + 1 > o->reserved) \ + MNAME##_Expand(o, o->size + 1); \ + loc = o->buffer + _where; \ + memmove(loc + 1, loc, (o->size - (loc - o->buffer)) * sizeof(MTYPE)); \ + *loc = e; \ + o->size++; \ + } \ + MNAME##Iterator MNAME##_Erase(MNAME* o, MNAME##Iterator iter) \ + { \ + size_t remain_bytes; \ + remain_bytes = (o->size - 1 - (iter - o->buffer)) * sizeof(MTYPE); \ + memmove(iter, iter + 1, remain_bytes); \ + o->size--; \ + return iter; \ + } #ifndef CSTL_VECTOR_DEFINITION @@ -86,6 +95,7 @@ #define Vector_Last(o) ((o)->buffer + (o)->size - 1) #define Vector_Clear(o) (o)->size = 0 #define Vector_GetElement(o, i, e) ((o)->buffer[(i)].e) -#define Vector_SetSlement(o, i, e, v) (o)->buffer[(i)].e = (v) +#define Vector_SetElement(o, i, e, v) (o)->buffer[(i)].e = (v) +#define Vector_Set(o, i, v) (o)->buffer[(i)] = (v) #endif /* CSTL_VECTOR_DEFINITION */ diff --git a/sww/include/sww/vmath.h b/sww/include/sww/vmath.h index a86c9e6..d06e74a 100644 --- a/sww/include/sww/vmath.h +++ b/sww/include/sww/vmath.h @@ -26,114 +26,142 @@ #define INTERPOLATE(a, b, t) ((a) + (((b) - (a)) * (t))) #define CLAMP(x, min, max) ((x) < (min)) ? (min) : (((x) > (max)) ? (max) : (x)) #define SATURATE(f) ((f) < 0 ? 0 : ((f) > 1 ? 1 : (f))) -#define DEGREES_TO_RADIANS(d) ((d)*M_PI / 180.0) +#define DEGREES_TO_RADIANS(d) ((d) * M_PI / 180.0) /* Vector Definitions */ -typedef union { - struct { - float x, y; - }; - struct { - float u, v; - }; - struct { - float min, max; - }; - /* Used by Vector2f_Swap */ - struct { - uint32_t ux, uy; - }; - float d[2]; +typedef union +{ + struct + { + float x, y; + }; + struct + { + float u, v; + }; + struct + { + float min, max; + }; + /* Used by Vector2f_Swap */ + struct + { + uint32_t ux, uy; + }; + float d[2]; } Vector2f; -typedef union { - struct { - int32_t x, y; - }; - struct { - int32_t min, max; - }; - struct { - uint32_t w, h; - }; - struct { - uint32_t row, col; - }; - int d[2]; +typedef union +{ + struct + { + int32_t x, y; + }; + struct + { + int32_t min, max; + }; + struct + { + uint32_t w, h; + }; + struct + { + uint32_t row, col; + }; + int d[2]; } Vector2i; -typedef union { - struct { - float x, y, z; - }; - struct { - float r, g, b; - }; - /* Used by Vector3f_Swap */ - struct { - uint32_t ux, uy, uz; - }; - float d[3]; - Vector2f xy; +typedef union +{ + struct + { + float x, y, z; + }; + struct + { + float r, g, b; + }; + /* Used by Vector3f_Swap */ + struct + { + uint32_t ux, uy, uz; + }; + float d[3]; + Vector2f xy; } Vector3f; -typedef union { - struct { - float x, y, z, w; - }; - struct { - float r, g, b, a; - }; - struct { - float minx, miny, maxx, maxy; - }; - struct { - Vector2f min; - Vector2f max; - }; - float d[4]; - Vector3f xyz; - Vector2f xy; +typedef union +{ + struct + { + float x, y, z, w; + }; + struct + { + float r, g, b, a; + }; + struct + { + float minx, miny, maxx, maxy; + }; + struct + { + Vector2f min; + Vector2f max; + }; + float d[4]; + Vector3f xyz; + Vector2f xy; } Vector4f; -typedef struct { - struct { - float x, y; - } center; - struct { - float w, h; - } dims; +typedef struct +{ + struct + { + float x, y; + } center; + struct + { + float w, h; + } dims; } Aabbf; /* Matrix Definitions, D3D math */ -typedef union { - struct { - float m11, m12, m13, m14; - float m21, m22, m23, m24; - float m31, m32, m33, m34; - float m41, m42, m43, m44; - }; - struct { - Vector4f row1; - Vector4f row2; - Vector4f row3; - Vector4f row4; - }; - float m[4][4]; +typedef union +{ + struct + { + float m11, m12, m13, m14; + float m21, m22, m23, m24; + float m31, m32, m33, m34; + float m41, m42, m43, m44; + }; + struct + { + Vector4f row1; + Vector4f row2; + Vector4f row3; + Vector4f row4; + }; + float m[4][4]; } Matrix4x4f; -typedef union { - struct { - float m11, m12, m13; - float m21, m22, m23; - float m31, m32, m33; - }; - struct { - Vector3f row1; - Vector3f row2; - Vector3f row3; - }; - float m[3][3]; +typedef union +{ + struct + { + float m11, m12, m13; + float m21, m22, m23; + float m31, m32, m33; + }; + struct + { + Vector3f row1; + Vector3f row2; + Vector3f row3; + }; + float m[3][3]; } Matrix3x3f; typedef Vector2i Sizei; @@ -147,15 +175,17 @@ typedef Vector4f Point4f; typedef Vector4f Quaternionf; typedef Vector4f BoundingBoxf; -typedef struct { - Point3f origin; - Vector3f direction; +typedef struct +{ + Point3f origin; + Vector3f direction; } Rayf; /* Common Math Functions */ /* interpolation:t [0, 1] */ -static float Interpolatef(float x1, float x2, float t) { - return INTERPOLATE(x1, x2, t); +static float Interpolatef(float x1, float x2, float t) +{ + return INTERPOLATE(x1, x2, t); } /* @@ -174,341 +204,403 @@ static float Floorf(float x) { #define Lerpf Interpolatef -static float Clampf(float f, float min, float max) { - return CLAMP(f, min, max); +static float Clampf(float f, float min, float max) +{ + return CLAMP(f, min, max); } -static float Saturatef(float f) { return SATURATE(f); } +static float Saturatef(float f) +{ + return SATURATE(f); +} /* NOTE(anjingyu): [0, 1) */ -static float Randomf() { return rand() / ((float)RAND_MAX + 1.f); } +static float Randomf() +{ + return rand() / ((float)RAND_MAX + 1.f); +} -static float RandomfIn(float min, float max) { - return min + (max - min) * Randomf(); +static float RandomfIn(float min, float max) +{ + return min + (max - min) * Randomf(); } -static float Degrees2Radiansf(float degrees) { - return DEGREES_TO_RADIANS(degrees); +static float Degrees2Radiansf(float degrees) +{ + return DEGREES_TO_RADIANS(degrees); } /* Re-maps a number from one range to another */ -static float Mapf(float v, Rangef from, Rangef to) { - return (v - from.min) / (from.max - from.min) * (to.max - to.min) + to.min; +static float Mapf(float v, Rangef from, Rangef to) +{ + return (v - from.min) / (from.max - from.min) * (to.max - to.min) + to.min; } /* Normalizes a number from another range into a value between 0 and 1 */ -static float Normalizef(float v, Rangef r) { - return Mapf(v, r, (Rangef){0.f, 1.f}); +static float Normalizef(float v, Rangef r) +{ + return Mapf(v, r, (Rangef){0.f, 1.f}); } /* Vector Operations */ /* Vector2f */ -static void Vector2f_AddInPlace(Vector2f *o, Vector2f other) { - o->x += other.x; - o->y += other.y; +static void Vector2f_AddInPlace(Vector2f* o, Vector2f other) +{ + o->x += other.x; + o->y += other.y; } -static Vector2f Vector2f_Add(Vector2f o, Vector2f other) { - Vector2f r; - r.x = o.x + other.x; - r.y = o.y + other.y; - return r; +static Vector2f Vector2f_Add(Vector2f o, Vector2f other) +{ + Vector2f r; + r.x = o.x + other.x; + r.y = o.y + other.y; + return r; } -static void Vector2f_SubInPlace(Vector2f *o, Vector2f s) { - o->x = o->x - s.x; - o->y = o->y - s.y; +static void Vector2f_SubInPlace(Vector2f* o, Vector2f s) +{ + o->x = o->x - s.x; + o->y = o->y - s.y; } -static Vector2f Vector2f_Sub(Vector2f o, Vector2f s) { - Vector2f r; - r.x = o.x - s.x; - r.y = o.y - s.y; - return r; +static Vector2f Vector2f_Sub(Vector2f o, Vector2f s) +{ + Vector2f r; + r.x = o.x - s.x; + r.y = o.y - s.y; + return r; } -static void Vector2f_MulInPlace(Vector2f *o, float s) { - o->x *= s; - o->y *= s; +static void Vector2f_MulInPlace(Vector2f* o, float s) +{ + o->x *= s; + o->y *= s; } -static Vector2f Vector2f_Mul(Vector2f o, float s) { - Vector2f r; - r.x = o.x * s; - r.y = o.y * s; - return r; +static Vector2f Vector2f_Mul(Vector2f o, float s) +{ + Vector2f r; + r.x = o.x * s; + r.y = o.y * s; + return r; } -static void Vector2f_DivInPlace(Vector2f *o, float s) { - Vector2f_MulInPlace(o, 1.f / s); +static void Vector2f_DivInPlace(Vector2f* o, float s) +{ + Vector2f_MulInPlace(o, 1.f / s); } -static Vector2f Vector2f_Div(Vector2f o, float s) { - return Vector2f_Mul(o, 1.f / s); +static Vector2f Vector2f_Div(Vector2f o, float s) +{ + return Vector2f_Mul(o, 1.f / s); } -static float Vector2f_Dot(Vector2f u, Vector2f v) { - return u.x * v.x + u.y * v.y; +static float Vector2f_Heading(Vector2f o) +{ + return atanf(o.y / o.x); } -static float Vector2f_Cross(Vector2f u, Vector2f v) { - return u.x * v.y - u.y * v.x; +static float Vector2f_Dot(Vector2f u, Vector2f v) +{ + return u.x * v.x + u.y * v.y; } -static float Vector2f_Length(Vector2f v) { - return (float)sqrt(v.x * v.x + v.y * v.y); +static float Vector2f_Cross(Vector2f u, Vector2f v) +{ + return u.x * v.y - u.y * v.x; } -static Vector2f Vector2f_Reflect(Vector2f o, Vector2f normal) { - float idotn2 = (normal.x * o.x + normal.y * o.y) * -2.f; - return (Vector2f){o.x + idotn2 * normal.x, o.y + idotn2 * normal.y}; +static float Vector2f_Length(Vector2f v) +{ + return (float)sqrt(v.x * v.x + v.y * v.y); } -static void Vector2f_NormalizeInPlace(Vector2f *o) { - float length = Vector2f_Length(*o); - if (length > 0.f) { - float inv = 1.f / length; - o->x *= inv; - o->y *= inv; - } +static Vector2f Vector2f_Reflect(Vector2f o, Vector2f normal) +{ + float idotn2 = (normal.x * o.x + normal.y * o.y) * -2.f; + return (Vector2f){o.x + idotn2 * normal.x, o.y + idotn2 * normal.y}; } -static Vector2f Vector2f_Normalize(Vector2f o) { - float length = Vector2f_Length(o); - if (length > 0) { - float inv = 1.f / length; - return (Vector2f){o.x * inv, o.y * inv}; - } - return (Vector2f){0.f, 0.f}; +static void Vector2f_NormalizeInPlace(Vector2f* o) +{ + float length = Vector2f_Length(*o); + if (length > 0.f) { + float inv = 1.f / length; + o->x *= inv; + o->y *= inv; + } } -static void Vector2f_Swap(Vector2f *a, Vector2f *b) { +static Vector2f Vector2f_Normalize(Vector2f o) +{ + float length = Vector2f_Length(o); + if (length > 0) { + float inv = 1.f / length; + return (Vector2f){o.x * inv, o.y * inv}; + } + return (Vector2f){0.f, 0.f}; +} + +static void Vector2f_Swap(Vector2f* a, Vector2f* b) +{ #define _SWAP(a, b) (((a) ^ (b)) && ((b) ^= (a) ^= (b), (a) ^= (b))) - _SWAP(a->ux, b->ux); - _SWAP(a->uy, b->uy); + _SWAP(a->ux, b->ux); + _SWAP(a->uy, b->uy); #undef _SWAP } -static Vector2f Vector2f_Lerp(Vector2f a, Vector2f b, float t) { - return (Vector2f){Lerpf(a.x, b.x, t), Lerpf(a.y, b.y, t)}; +static Vector2f Vector2f_Lerp(Vector2f a, Vector2f b, float t) +{ + return (Vector2f){Lerpf(a.x, b.x, t), Lerpf(a.y, b.y, t)}; } -static Vector2f Vector2f_Saturate(Vector2f o) { - return (Vector2f){Saturatef(o.x), Saturatef(o.y)}; +static Vector2f Vector2f_Saturate(Vector2f o) +{ + return (Vector2f){Saturatef(o.x), Saturatef(o.y)}; } -static BoundingBoxf Vector2f_BoundingBox(uint32_t count, ...) { - BoundingBoxf bb = {FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX}; +static BoundingBoxf Vector2f_BoundingBox(uint32_t count, ...) +{ + BoundingBoxf bb = {FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX}; - va_list args; - va_start(args, count); + va_list args; + va_start(args, count); - uint32_t i = 0; - for (; i < count; i++) { - Vector2f v = va_arg(args, Vector2f); + uint32_t i = 0; + for (; i < count; i++) { + Vector2f v = va_arg(args, Vector2f); - bb.min.x = MIN(bb.min.x, v.x); - bb.min.y = MIN(bb.min.y, v.y); + bb.min.x = MIN(bb.min.x, v.x); + bb.min.y = MIN(bb.min.y, v.y); - bb.max.x = MAX(bb.max.x, v.x); - bb.max.y = MAX(bb.max.y, v.y); - } + bb.max.x = MAX(bb.max.x, v.x); + bb.max.y = MAX(bb.max.y, v.y); + } - va_end(args); - return bb; + va_end(args); + return bb; } /* In the interval or not, include boundary: true: 1, false: 0 */ -static int Intervalf_Contains(Intervalf o, float x) { - return (o.min <= x && x <= o.max) ? 1 : 0; +static int Intervalf_Contains(Intervalf o, float x) +{ + return (o.min <= x && x <= o.max) ? 1 : 0; } /* In the interval or not, without boundary: true: 1, false: 0 */ -static int Intervalf_Surrounds(Intervalf o, float x) { - return (o.min < x && x < o.max) ? 1 : 0; +static int Intervalf_Surrounds(Intervalf o, float x) +{ + return (o.min < x && x < o.max) ? 1 : 0; } -static float Intervalf_Clamp(Intervalf o, float x) { - return Clampf(o.min, o.max, x); +static float Intervalf_Clamp(Intervalf o, float x) +{ + return Clampf(o.min, o.max, x); } /* Vector3f */ -static void Vector3f_AddInPlace(Vector3f *o, Vector3f other) { - o->x += other.x; - o->y += other.y; - o->z += other.z; +static void Vector3f_AddInPlace(Vector3f* o, Vector3f other) +{ + o->x += other.x; + o->y += other.y; + o->z += other.z; } -static Vector3f Vector3f_Add(Vector3f o, Vector3f other) { - Vector3f r; - r.x = o.x + other.x; - r.y = o.y + other.y; - r.z = o.z + other.z; - return r; +static Vector3f Vector3f_Add(Vector3f o, Vector3f other) +{ + Vector3f r; + r.x = o.x + other.x; + r.y = o.y + other.y; + r.z = o.z + other.z; + return r; } -static void Vector3f_SubInPlace(Vector3f *o, Vector3f s) { - o->x = o->x - s.x; - o->y = o->y - s.y; - o->z = o->z - s.z; +static void Vector3f_SubInPlace(Vector3f* o, Vector3f s) +{ + o->x = o->x - s.x; + o->y = o->y - s.y; + o->z = o->z - s.z; } -static Vector3f Vector3f_Sub(Vector3f o, Vector3f s) { - Vector3f r; - r.x = o.x - s.x; - r.y = o.y - s.y; - r.z = o.z - s.z; - return r; +static Vector3f Vector3f_Sub(Vector3f o, Vector3f s) +{ + Vector3f r; + r.x = o.x - s.x; + r.y = o.y - s.y; + r.z = o.z - s.z; + return r; } -static void Vector3f_MulInPlace(Vector3f *o, float s) { - o->x *= s; - o->y *= s; - o->z *= s; +static void Vector3f_MulInPlace(Vector3f* o, float s) +{ + o->x *= s; + o->y *= s; + o->z *= s; } -static Vector3f Vector3f_Mul(Vector3f o, float s) { - Vector3f r; - r.x = o.x * s; - r.y = o.y * s; - r.z = o.z * s; - return r; +static Vector3f Vector3f_Mul(Vector3f o, float s) +{ + Vector3f r; + r.x = o.x * s; + r.y = o.y * s; + r.z = o.z * s; + return r; } -static Vector3f Vector3f_MulVector3f(Vector3f o, Vector3f v) { - Vector3f r; - r.x = o.x * v.x; - r.y = o.y * v.y; - r.z = o.z * v.z; - return r; +static Vector3f Vector3f_MulVector3f(Vector3f o, Vector3f v) +{ + Vector3f r; + r.x = o.x * v.x; + r.y = o.y * v.y; + r.z = o.z * v.z; + return r; } -static Vector3f Vector3f_MulVector3fInPlace(Vector3f *o, Vector3f v) { - o->x = o->x * v.x; - o->y = o->y * v.y; - o->z = o->z * v.z; +static Vector3f Vector3f_MulVector3fInPlace(Vector3f* o, Vector3f v) +{ + o->x = o->x * v.x; + o->y = o->y * v.y; + o->z = o->z * v.z; } -static void Vector3f_DivInPlace(Vector3f *o, float s) { - Vector3f_MulInPlace(o, 1.f / s); +static void Vector3f_DivInPlace(Vector3f* o, float s) +{ + Vector3f_MulInPlace(o, 1.f / s); } -static Vector3f Vector3f_Div(Vector3f o, float s) { - return Vector3f_Mul(o, 1.f / s); +static Vector3f Vector3f_Div(Vector3f o, float s) +{ + return Vector3f_Mul(o, 1.f / s); } -static float Vector3f_Dot(Vector3f u, Vector3f v) { - return u.x * v.x + u.y * v.y + u.z * v.z; +static float Vector3f_Dot(Vector3f u, Vector3f v) +{ + return u.x * v.x + u.y * v.y + u.z * v.z; } -static Vector3f Vector3f_Cross(Vector3f u, Vector3f v) { - return (Vector3f){u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, - u.x * v.y - u.y * v.x}; +static Vector3f Vector3f_Cross(Vector3f u, Vector3f v) +{ + return (Vector3f){u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x}; } -static float Vector3f_Length(Vector3f v) { - return (float)sqrt(v.x * v.x + v.y * v.y + v.z * v.z); +static float Vector3f_Length(Vector3f v) +{ + return (float)sqrt(v.x * v.x + v.y * v.y + v.z * v.z); } -static void Vector3f_NormalizeInPlace(Vector3f *o) { - float length = Vector3f_Length(*o); - if (length > 0.f) { - float inv = 1.f / length; - o->x *= inv; - o->y *= inv; - o->z *= inv; - } +static void Vector3f_NormalizeInPlace(Vector3f* o) +{ + float length = Vector3f_Length(*o); + if (length > 0.f) { + float inv = 1.f / length; + o->x *= inv; + o->y *= inv; + o->z *= inv; + } } -static void Vector3f_Swap(Vector3f *a, Vector3f *b) { +static void Vector3f_Swap(Vector3f* a, Vector3f* b) +{ #define _SWAP(a, b) (((a) ^ (b)) && ((b) ^= (a) ^= (b), (a) ^= (b))) - _SWAP(a->ux, b->ux); - _SWAP(a->uy, b->uy); - _SWAP(a->uz, b->uz); + _SWAP(a->ux, b->ux); + _SWAP(a->uy, b->uy); + _SWAP(a->uz, b->uz); #undef _SWAP } -static Vector3f Vector3f_Normalize(Vector3f o) { - float length = Vector3f_Length(o); - if (length > 0.f) { - float inv = 1.f / length; - return (Vector3f){o.x * inv, o.y * inv, o.z * inv}; - } - return (Vector3f){0.f, 0.f, 0.f}; +static Vector3f Vector3f_Normalize(Vector3f o) +{ + float length = Vector3f_Length(o); + if (length > 0.f) { + float inv = 1.f / length; + return (Vector3f){o.x * inv, o.y * inv, o.z * inv}; + } + return (Vector3f){0.f, 0.f, 0.f}; } -static Vector3f Vector3f_Lerp(Vector3f a, Vector3f b, float t) { - return (Vector3f){Lerpf(a.x, b.x, t), Lerpf(a.y, b.y, t), Lerpf(a.z, b.z, t)}; +static Vector3f Vector3f_Lerp(Vector3f a, Vector3f b, float t) +{ + return (Vector3f){Lerpf(a.x, b.x, t), Lerpf(a.y, b.y, t), Lerpf(a.z, b.z, t)}; } -static Vector3f Vector3f_LerpByX(Vector3f a, Vector3f b, float x) { - float t = (x - a.x) / (b.x - a.x); - return (Vector3f){x, Lerpf(a.y, b.y, t), Lerpf(a.z, b.z, t)}; +static Vector3f Vector3f_LerpByX(Vector3f a, Vector3f b, float x) +{ + float t = (x - a.x) / (b.x - a.x); + return (Vector3f){x, Lerpf(a.y, b.y, t), Lerpf(a.z, b.z, t)}; } -static Vector3f Vector3f_LerpByY(Vector3f a, Vector3f b, float y) { - float t = (y - a.y) / (b.y - a.y); - return (Vector3f){Lerpf(a.x, b.x, t), y, Lerpf(a.z, b.z, t)}; +static Vector3f Vector3f_LerpByY(Vector3f a, Vector3f b, float y) +{ + float t = (y - a.y) / (b.y - a.y); + return (Vector3f){Lerpf(a.x, b.x, t), y, Lerpf(a.z, b.z, t)}; } -static Vector3f Vector3f_LerpByZ(Vector3f a, Vector3f b, float z) { - float t = (z - a.z) / (b.z - a.z); - return (Vector3f){Lerpf(a.x, b.x, t), Lerpf(a.y, b.y, t), z}; +static Vector3f Vector3f_LerpByZ(Vector3f a, Vector3f b, float z) +{ + float t = (z - a.z) / (b.z - a.z); + return (Vector3f){Lerpf(a.x, b.x, t), Lerpf(a.y, b.y, t), z}; } -static Vector3f Vector3f_Saturate(Vector3f o) { - return (Vector3f){Saturatef(o.x), Saturatef(o.y), Saturatef(o.z)}; +static Vector3f Vector3f_Saturate(Vector3f o) +{ + return (Vector3f){Saturatef(o.x), Saturatef(o.y), Saturatef(o.z)}; } -static int Vector3f_NearZero(Vector3f o) { - return (fabsf(o.x) < EPSILON) && (fabsf(o.y) < EPSILON) && - (fabsf(o.z) < EPSILON); +static int Vector3f_NearZero(Vector3f o) +{ + return (fabsf(o.x) < EPSILON) && (fabsf(o.y) < EPSILON) && (fabsf(o.z) < EPSILON); } -static Vector3f Vector3f_Random() { - return (Vector3f){Randomf(), Randomf(), Randomf()}; +static Vector3f Vector3f_Random() +{ + return (Vector3f){Randomf(), Randomf(), Randomf()}; } -static Vector3f Vector3f_RandomIn(float min, float max) { - return (Vector3f){RandomfIn(min, max), RandomfIn(min, max), - RandomfIn(min, max)}; +static Vector3f Vector3f_RandomIn(float min, float max) +{ + return (Vector3f){RandomfIn(min, max), RandomfIn(min, max), RandomfIn(min, max)}; } // 在一个单位球内采样一个点 -static Vector3f Vector3f_RandomInUnitSphere() { - Vector3f p; - while (1) { - p = Vector3f_RandomIn(-1.f, 1.f); - if (Vector3f_Dot(p, p) < 1.f) { - return p; +static Vector3f Vector3f_RandomInUnitSphere() +{ + Vector3f p; + while (1) { + p = Vector3f_RandomIn(-1.f, 1.f); + if (Vector3f_Dot(p, p) < 1.f) { + return p; + } } - } } // 在一个单位球面上采样一个点 -static Vector3f Vector3f_RandomUnitVector() { - return Vector3f_Normalize(Vector3f_RandomInUnitSphere()); +static Vector3f Vector3f_RandomUnitVector() +{ + return Vector3f_Normalize(Vector3f_RandomInUnitSphere()); } // 在 normal 表示的半球内部采样得到一个单位向量 -static Vector3f Vector3f_RandomOnHemisphere(Vector3f normal) { - Vector3f on_unit_sphere = Vector3f_RandomUnitVector(); - if (Vector3f_Dot(normal, on_unit_sphere) >= 0.f) { - return on_unit_sphere; - } else { - return Vector3f_Mul(on_unit_sphere, -1.f); - } +static Vector3f Vector3f_RandomOnHemisphere(Vector3f normal) +{ + Vector3f on_unit_sphere = Vector3f_RandomUnitVector(); + if (Vector3f_Dot(normal, on_unit_sphere) >= 0.f) { + return on_unit_sphere; + } else { + return Vector3f_Mul(on_unit_sphere, -1.f); + } } // 在圆盘内均匀采样 -static Vector3f Vector3f_RandomInUnitDisk() { - Vector3f p; - while (1) { - p = (Vector3f){RandomfIn(-1.f, 1.f), RandomfIn(-1.f, 1.f), 0}; - if (Vector3f_Dot(p, p) < 1.f) { - return p; +static Vector3f Vector3f_RandomInUnitDisk() +{ + Vector3f p; + while (1) { + p = (Vector3f){RandomfIn(-1.f, 1.f), RandomfIn(-1.f, 1.f), 0}; + if (Vector3f_Dot(p, p) < 1.f) { + return p; + } } - } } /** @@ -518,9 +610,10 @@ static Vector3f Vector3f_RandomInUnitDisk() { * @param n 法向 * @return Vector3f */ -static Vector3f Vector3f_Reflect(Vector3f v, Vector3f n) { - // v - 2 * dot(v, n) * n - return Vector3f_Sub(v, Vector3f_Mul(n, 2 * Vector3f_Dot(v, n))); +static Vector3f Vector3f_Reflect(Vector3f v, Vector3f n) +{ + // v - 2 * dot(v, n) * n + return Vector3f_Sub(v, Vector3f_Mul(n, 2 * Vector3f_Dot(v, n))); } /** * @brief 计算折射的折射光线 @@ -530,835 +623,864 @@ static Vector3f Vector3f_Reflect(Vector3f v, Vector3f n) { * @param etai_over_etat 入射介质折射率/出射介质折射率 * @return Vector3f */ -static Vector3f Vector3f_Refract(Vector3f v, Vector3f n, float etai_over_etat) { - float cos_theta = fmin(1.f, Vector3f_Dot(Vector3f_Mul(v, -1.f), n)); - Vector3f r_out_perp = - Vector3f_Mul(Vector3f_Add(v, Vector3f_Mul(n, cos_theta)), etai_over_etat); - Vector3f r_out_parallel = - Vector3f_Mul(n, -sqrt(fabsf(1.f - Vector3f_Dot(r_out_perp, r_out_perp)))); +static Vector3f Vector3f_Refract(Vector3f v, Vector3f n, float etai_over_etat) +{ + float cos_theta = fmin(1.f, Vector3f_Dot(Vector3f_Mul(v, -1.f), n)); + Vector3f r_out_perp = Vector3f_Mul(Vector3f_Add(v, Vector3f_Mul(n, cos_theta)), etai_over_etat); + Vector3f r_out_parallel = + Vector3f_Mul(n, -sqrt(fabsf(1.f - Vector3f_Dot(r_out_perp, r_out_perp)))); - return Vector3f_Add(r_out_perp, r_out_parallel); + return Vector3f_Add(r_out_perp, r_out_parallel); } /* Ray */ -static Point3f Rayf_At(const Rayf *o, float t) { - return Vector3f_Add(o->origin, Vector3f_Mul(o->direction, t)); +static Point3f Rayf_At(const Rayf* o, float t) +{ + return Vector3f_Add(o->origin, Vector3f_Mul(o->direction, t)); } /* * The ray hits the sphere or not * true: 1, false: 0 */ -static int Rayf_IsHitSphere(const Rayf *o, Point3f center, float radius) { - Vector3f oc = Vector3f_Sub(center, o->origin); - // float a = Vector3f_Dot(o->direction, o->direction); - // float b = -2.f * Vector3f_Dot(o->direction, oc); - // float c = Vector3f_Dot(oc, oc) - radius * radius; - // float discriminant = b * b - 4 * a * c; - // Simplify: b = -2h - float a = Vector3f_Dot(o->direction, o->direction); - float h = Vector3f_Dot(o->direction, oc); - float c = Vector3f_Dot(oc, oc) - radius * radius; - float discriminant = h * h - a * c; - - return (discriminant >= 0) ? 1 : 0; +static int Rayf_IsHitSphere(const Rayf* o, Point3f center, float radius) +{ + Vector3f oc = Vector3f_Sub(center, o->origin); + // float a = Vector3f_Dot(o->direction, o->direction); + // float b = -2.f * Vector3f_Dot(o->direction, oc); + // float c = Vector3f_Dot(oc, oc) - radius * radius; + // float discriminant = b * b - 4 * a * c; + // Simplify: b = -2h + float a = Vector3f_Dot(o->direction, o->direction); + float h = Vector3f_Dot(o->direction, oc); + float c = Vector3f_Dot(oc, oc) - radius * radius; + float discriminant = h * h - a * c; + + return (discriminant >= 0) ? 1 : 0; } /* Matrix Operations */ /* Matrix 3x3 */ -static double Matrix3x3f_Det(const Matrix3x3f *o) { - float ret = 0; - float **m = (float **)o->m; +static double Matrix3x3f_Det(const Matrix3x3f* o) +{ + float ret = 0; + float** m = (float**)o->m; - ret += m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + - m[2][0] * m[0][1] * m[1][2]; - ret -= m[2][0] * m[1][1] * m[0][2] + m[0][0] * m[2][1] * m[1][2] + - m[1][0] * m[0][1] * m[2][2]; + ret += m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2]; + ret -= m[2][0] * m[1][1] * m[0][2] + m[0][0] * m[2][1] * m[1][2] + m[1][0] * m[0][1] * m[2][2]; - return ret; + return ret; } -static void Matrix3x3f_ScaleInPlace(Matrix3x3f *o, float s) { - o->m11 *= s; - o->m12 *= s; - o->m13 *= s; +static void Matrix3x3f_ScaleInPlace(Matrix3x3f* o, float s) +{ + o->m11 *= s; + o->m12 *= s; + o->m13 *= s; - o->m21 *= s; - o->m22 *= s; - o->m23 *= s; + o->m21 *= s; + o->m22 *= s; + o->m23 *= s; - o->m31 *= s; - o->m32 *= s; - o->m33 *= s; + o->m31 *= s; + o->m32 *= s; + o->m33 *= s; } -static Matrix3x3f Matrix3x3f_Scale(const Matrix3x3f *o, float s) { - Matrix3x3f r; - r.m11 = o->m11 * s; - r.m12 = o->m12 * s; - r.m13 = o->m13 * s; +static Matrix3x3f Matrix3x3f_Scale(const Matrix3x3f* o, float s) +{ + Matrix3x3f r; + r.m11 = o->m11 * s; + r.m12 = o->m12 * s; + r.m13 = o->m13 * s; - r.m21 = o->m21 * s; - r.m22 = o->m22 * s; - r.m23 = o->m23 * s; + r.m21 = o->m21 * s; + r.m22 = o->m22 * s; + r.m23 = o->m23 * s; - r.m31 = o->m31 * s; - r.m32 = o->m32 * s; - r.m33 = o->m33 * s; + r.m31 = o->m31 * s; + r.m32 = o->m32 * s; + r.m33 = o->m33 * s; - return r; + return r; } -static void Matrix3x3f_Invert(const Matrix3x3f *o, Matrix3x3f *dest) { - float det; - float **m = (float **)o->m; - float a = m[0][0], b = m[0][1], c = m[0][2], d = m[1][0], e = m[1][1], - f = m[1][2], g = m[2][0], h = m[2][1], i = m[2][2]; +static void Matrix3x3f_Invert(const Matrix3x3f* o, Matrix3x3f* dest) +{ + float det; + float** m = (float**)o->m; + float a = m[0][0], b = m[0][1], c = m[0][2], d = m[1][0], e = m[1][1], f = m[1][2], g = m[2][0], + h = m[2][1], i = m[2][2]; - float **dm = (float **)dest->m; + float** dm = (float**)dest->m; - dm[0][0] = e * i - f * h; - dm[0][1] = -(b * i - h * c); - dm[0][2] = b * f - e * c; - dm[1][0] = -(d * i - g * f); - dm[1][1] = a * i - c * g; - dm[1][2] = -(a * f - d * c); - dm[2][0] = d * h - g * e; - dm[2][1] = -(a * h - g * b); - dm[2][2] = a * e - b * d; + dm[0][0] = e * i - f * h; + dm[0][1] = -(b * i - h * c); + dm[0][2] = b * f - e * c; + dm[1][0] = -(d * i - g * f); + dm[1][1] = a * i - c * g; + dm[1][2] = -(a * f - d * c); + dm[2][0] = d * h - g * e; + dm[2][1] = -(a * h - g * b); + dm[2][2] = a * e - b * d; - det = 1.0f / (a * dm[0][0] + b * dm[1][0] + c * dm[2][0]); + det = 1.0f / (a * dm[0][0] + b * dm[1][0] + c * dm[2][0]); - Matrix3x3f_Scale(dest, det); + Matrix3x3f_Scale(dest, det); } -static void Matrix3x3f_TransposeInPlace(Matrix3x3f *o) { +static void Matrix3x3f_TransposeInPlace(Matrix3x3f* o) +{ #define _SWAP(a, b) (((a) ^ (b)) && ((b) ^= (a) ^= (b), (a) ^= (b))) - union { - float f; - int i; - } x, y; - - x.f = o->m12, y.f = o->m21; - _SWAP(x.i, y.i); - x.f = o->m13, y.f = o->m31; - _SWAP(x.i, y.i); - x.f = o->m21, y.f = o->m12; - _SWAP(x.i, y.i); - x.f = o->m23, y.f = o->m32; - _SWAP(x.i, y.i); - x.f = o->m31, y.f = o->m13; - _SWAP(x.i, y.i); - x.f = o->m32, y.f = o->m23; - _SWAP(x.i, y.i); + union + { + float f; + int i; + } x, y; + + x.f = o->m12, y.f = o->m21; + _SWAP(x.i, y.i); + x.f = o->m13, y.f = o->m31; + _SWAP(x.i, y.i); + x.f = o->m21, y.f = o->m12; + _SWAP(x.i, y.i); + x.f = o->m23, y.f = o->m32; + _SWAP(x.i, y.i); + x.f = o->m31, y.f = o->m13; + _SWAP(x.i, y.i); + x.f = o->m32, y.f = o->m23; + _SWAP(x.i, y.i); #undef _SWAP } -static Vector3f Matrix3x3f_MulVector3f(const Matrix3x3f *o, Vector3f v) { - Vector3f dest; +static Vector3f Matrix3x3f_MulVector3f(const Matrix3x3f* o, Vector3f v) +{ + Vector3f dest; - dest.x = o->m11 * v.x + o->m21 * v.y + o->m31 * v.z; - dest.y = o->m12 * v.x + o->m22 * v.y + o->m32 * v.z; - dest.x = o->m13 * v.x + o->m23 * v.y + o->m33 * v.z; + dest.x = o->m11 * v.x + o->m21 * v.y + o->m31 * v.z; + dest.y = o->m12 * v.x + o->m22 * v.y + o->m32 * v.z; + dest.x = o->m13 * v.x + o->m23 * v.y + o->m33 * v.z; - return dest; + return dest; } -static Matrix3x3f Matrix3x3f_InvertTranspose(const Matrix3x3f *o) { - Matrix3x3f dest; - Matrix3x3f_Invert(o, &dest); - Matrix3x3f_TransposeInPlace(&dest); - return dest; +static Matrix3x3f Matrix3x3f_InvertTranspose(const Matrix3x3f* o) +{ + Matrix3x3f dest; + Matrix3x3f_Invert(o, &dest); + Matrix3x3f_TransposeInPlace(&dest); + return dest; } -static Vector3f Vector3f_BarycentricXY(const Vector3f p0, const Vector3f p1, - const Vector3f p2, int32_t px, - int32_t py) { - Vector3f a = {p2.x - p0.x, p1.x - p0.x, p0.x - px}; - Vector3f b = {p2.y - p0.y, p1.y - p0.y, p0.y - py}; +static Vector3f Vector3f_BarycentricXY(const Vector3f p0, const Vector3f p1, const Vector3f p2, + int32_t px, int32_t py) +{ + Vector3f a = {p2.x - p0.x, p1.x - p0.x, p0.x - px}; + Vector3f b = {p2.y - p0.y, p1.y - p0.y, p0.y - py}; - Vector3f u = Vector3f_Cross(a, b); - if (fabsf(u.z) < 1e-2) { - return (Vector3f){-1, 1, 1}; - } - float z1 = 1 / u.z; - float y = u.y * z1; - float z = u.x * z1; - return (Vector3f){1.f - y - z, y, z}; + Vector3f u = Vector3f_Cross(a, b); + if (fabsf(u.z) < 1e-2) { + return (Vector3f){-1, 1, 1}; + } + float z1 = 1 / u.z; + float y = u.y * z1; + float z = u.x * z1; + return (Vector3f){1.f - y - z, y, z}; } -static Vector3f Vector3f_Barycentric(const Vector3f p0, const Vector3f p1, - const Vector3f p2, Vector3f p) { - Vector3f a = {p2.x - p0.x, p1.x - p0.x, p0.x - p.x}; - Vector3f b = {p2.y - p0.y, p1.y - p0.y, p0.y - p.y}; +static Vector3f Vector3f_Barycentric(const Vector3f p0, const Vector3f p1, const Vector3f p2, + Vector3f p) +{ + Vector3f a = {p2.x - p0.x, p1.x - p0.x, p0.x - p.x}; + Vector3f b = {p2.y - p0.y, p1.y - p0.y, p0.y - p.y}; - Vector3f u = Vector3f_Cross(a, b); - if (fabsf(u.z) < 1e-2) { - return (Vector3f){-1, 1, 1}; - } - float z1 = 1 / u.z; - float y = u.y * z1; - float z = u.x * z1; - return (Vector3f){1.f - y - z, y, z}; + Vector3f u = Vector3f_Cross(a, b); + if (fabsf(u.z) < 1e-2) { + return (Vector3f){-1, 1, 1}; + } + float z1 = 1 / u.z; + float y = u.y * z1; + float z = u.x * z1; + return (Vector3f){1.f - y - z, y, z}; } -static Vector3f Vector3f_Barycentric2(const Vector3f pts[3], Vector3f p) { - return Vector3f_Barycentric(pts[0], pts[1], pts[2], p); - /* - Matrix3x3f a = {(float)tri[0].x, (float)tri[0].y, 1.0f, - (float)tri[1].x, (float)tri[1].y, 1.0f, - (float)tri[2].x, (float)tri[2].y, 1.0f}; - if (Matrix3x3f_Det(&a) < 1e-3) { - return (Vector3f){ - -1, 1, 1}; // for a degenerate triangle generate negative - coordinates, - // it will be thrown away by the rasterizator - } - Matrix3x3f dest = Matrix3x3f_InvertTranspose(&a); - return Matrix3x3f_MulVector3f(&dest, - (Vector3f){(float)p.x, (float)p.y, 1.0f}); - */ +static Vector3f Vector3f_Barycentric2(const Vector3f pts[3], Vector3f p) +{ + return Vector3f_Barycentric(pts[0], pts[1], pts[2], p); + /* + Matrix3x3f a = {(float)tri[0].x, (float)tri[0].y, 1.0f, + (float)tri[1].x, (float)tri[1].y, 1.0f, + (float)tri[2].x, (float)tri[2].y, 1.0f}; + if (Matrix3x3f_Det(&a) < 1e-3) { + return (Vector3f){ + -1, 1, 1}; // for a degenerate triangle generate negative + coordinates, + // it will be thrown away by the rasterizator + } + Matrix3x3f dest = Matrix3x3f_InvertTranspose(&a); + return Matrix3x3f_MulVector3f(&dest, + (Vector3f){(float)p.x, (float)p.y, 1.0f}); + */ } -static Vector3f Vector2i_Barycentric(const Vector2i tri[3], const Vector2i p) { - Vector3f r; - float det = (tri[1].y - tri[2].y) * (tri[0].x - tri[2].x) + - (tri[2].x - tri[1].x) * (tri[0].y - tri[2].y); - r.x = ((tri[1].y - tri[2].y) * (p.x - tri[2].x) + - (tri[2].x - tri[1].x) * (p.y - tri[2].y)) / - det; - r.y = ((tri[2].y - tri[0].y) * (p.x - tri[2].x) + - (tri[0].x - tri[2].x) * (p.y - tri[2].y)) / - det; - r.z = 1.f - r.d[0] - r.d[1]; +static Vector3f Vector2i_Barycentric(const Vector2i tri[3], const Vector2i p) +{ + Vector3f r; + float det = (tri[1].y - tri[2].y) * (tri[0].x - tri[2].x) + + (tri[2].x - tri[1].x) * (tri[0].y - tri[2].y); + r.x = + ((tri[1].y - tri[2].y) * (p.x - tri[2].x) + (tri[2].x - tri[1].x) * (p.y - tri[2].y)) / det; + r.y = + ((tri[2].y - tri[0].y) * (p.x - tri[2].x) + (tri[0].x - tri[2].x) * (p.y - tri[2].y)) / det; + r.z = 1.f - r.d[0] - r.d[1]; - return r; + return r; } -static float Vector4f_Length(Vector4f v) { return Vector3f_Length(v.xyz); } +static float Vector4f_Length(Vector4f v) +{ + return Vector3f_Length(v.xyz); +} -static Vector4f Vector4f_Add(Vector4f x, Vector4f y) { - Vector4f z; - z.xyz = Vector3f_Add(x.xyz, y.xyz); - z.w = 1.f; - return z; +static Vector4f Vector4f_Add(Vector4f x, Vector4f y) +{ + Vector4f z; + z.xyz = Vector3f_Add(x.xyz, y.xyz); + z.w = 1.f; + return z; } -static Vector4f Vector4f_Sub(Vector4f x, Vector4f y) { - Vector4f z; - z.xyz = Vector3f_Sub(x.xyz, y.xyz); - z.w = 1.f; - return z; +static Vector4f Vector4f_Sub(Vector4f x, Vector4f y) +{ + Vector4f z; + z.xyz = Vector3f_Sub(x.xyz, y.xyz); + z.w = 1.f; + return z; } -static float Vector4f_Dot(Vector4f x, Vector4f y) { - return Vector3f_Dot(x.xyz, y.xyz); +static float Vector4f_Dot(Vector4f x, Vector4f y) +{ + return Vector3f_Dot(x.xyz, y.xyz); } -static Vector4f Vector4f_Cross(Vector4f x, Vector4f y) { - Vector4f z; - z.xyz = Vector3f_Cross(x.xyz, y.xyz); - z.w = 1.f; - return z; +static Vector4f Vector4f_Cross(Vector4f x, Vector4f y) +{ + Vector4f z; + z.xyz = Vector3f_Cross(x.xyz, y.xyz); + z.w = 1.f; + return z; } -static Vector4f Vector4f_Lerp(Vector4f x1, Vector4f x2, float t) { - Vector4f z; - z.xyz = Vector3f_Lerp(x1.xyz, x2.xyz, t); - z.w = 1.0f; - return z; +static Vector4f Vector4f_Lerp(Vector4f x1, Vector4f x2, float t) +{ + Vector4f z; + z.xyz = Vector3f_Lerp(x1.xyz, x2.xyz, t); + z.w = 1.0f; + return z; } -static void Vector4f_NormalizeInPlace(Vector4f *v) { - Vector3f_NormalizeInPlace(&v->xyz); +static void Vector4f_NormalizeInPlace(Vector4f* v) +{ + Vector3f_NormalizeInPlace(&v->xyz); } -static Vector4f Vector4f_Normalize(Vector4f v) { - Vector4f r = {0.f, 0.f, 0.f, 1.f}; - r.xyz = Vector3f_Normalize(v.xyz); - return r; +static Vector4f Vector4f_Normalize(Vector4f v) +{ + Vector4f r = {0.f, 0.f, 0.f, 1.f}; + r.xyz = Vector3f_Normalize(v.xyz); + return r; } /* AABB */ -static int Aabbf_Contains(Aabbf a, float x, float y) { - return (x >= a.center.x - a.dims.w && x <= a.center.x + a.dims.w) && - (y >= a.center.y - a.dims.h && y <= a.center.y + a.dims.h); +static int Aabbf_Contains(Aabbf a, float x, float y) +{ + return (x >= a.center.x - a.dims.w && x <= a.center.x + a.dims.w) + && (y >= a.center.y - a.dims.h && y <= a.center.y + a.dims.h); } -static int Aabbf_Intersects(Aabbf a, Aabbf b) { - return (fabsf(a.center.x - b.center.x) < (a.dims.w + b.dims.w)) && - (fabsf(a.center.y - b.center.y) < (a.dims.h + b.dims.h)); +static int Aabbf_Intersects(Aabbf a, Aabbf b) +{ + return (fabsf(a.center.x - b.center.x) < (a.dims.w + b.dims.w)) + && (fabsf(a.center.y - b.center.y) < (a.dims.h + b.dims.h)); } /* Quaternion Operations */ -static inline float Quaternionf_Dot(Quaternionf a, Quaternionf b) { - return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +static inline float Quaternionf_Dot(Quaternionf a, Quaternionf b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } -static inline float Quaternionf_Length(Quaternionf q) { - return (float)sqrt(Quaternionf_Dot(q, q)); +static inline float Quaternionf_Length(Quaternionf q) +{ + return (float)sqrt(Quaternionf_Dot(q, q)); } -static inline Quaternionf Quaternionf_Normalize(Quaternionf q) { - float factor = 1 / Quaternionf_Length(q); - return (Quaternionf){q.x * factor, q.y * factor, q.z * factor, q.w * factor}; +static inline Quaternionf Quaternionf_Normalize(Quaternionf q) +{ + float factor = 1 / Quaternionf_Length(q); + return (Quaternionf){q.x * factor, q.y * factor, q.z * factor, q.w * factor}; } -static inline void Quaternionf_SetIdentity(Quaternionf *q) { - q->x = 0.f; - q->y = 0.f; - q->z = 0.f; - q->w = 1.f; +static inline void Quaternionf_SetIdentity(Quaternionf* q) +{ + q->x = 0.f; + q->y = 0.f; + q->z = 0.f; + q->w = 1.f; } // From D3DXMath // // Reference: // https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Source_code -static inline Quaternionf -Quaternionf_RotationRollPitchYaw(float pitch, float yaw, float roll) { - Quaternionf q; - - // The math format: // roll (x), pitch (y), yaw (z), angles are in radians - // double cr = cos(roll * 0.5); - // double sr = sin(roll * 0.5); - // double cp = cos(pitch * 0.5); - // double sp = sin(pitch * 0.5); - // double cy = cos(yaw * 0.5); - // double sy = sin(yaw * 0.5); - // - // q.w = cr * cp * cy + sr * sp * sy; - // q.x = sr * cp * cy - cr * sp * sy; - // q.y = cr * sp * cy + sr * cp * sy; - // q.z = cr * cp * sy - sr * sp * cy; - - // The D3DXMath format(game format): pitch (x), yaw (y), roll (z) - double cp = cos(pitch * 0.5); - double sp = sin(pitch * 0.5); - double cy = cos(yaw * 0.5); - double sy = sin(yaw * 0.5); - double cr = cos(roll * 0.5); - double sr = sin(roll * 0.5); - - q.w = cr * cp * cy + sr * sp * sy; - q.x = cr * sp * cy + sr * cp * sy; - q.y = cr * cp * sy - sr * sp * cy; - q.z = sr * cp * cy - cr * sp * sy; - - return q; +static inline Quaternionf Quaternionf_RotationRollPitchYaw(float pitch, float yaw, float roll) +{ + Quaternionf q; + + // The math format: // roll (x), pitch (y), yaw (z), angles are in radians + // double cr = cos(roll * 0.5); + // double sr = sin(roll * 0.5); + // double cp = cos(pitch * 0.5); + // double sp = sin(pitch * 0.5); + // double cy = cos(yaw * 0.5); + // double sy = sin(yaw * 0.5); + // + // q.w = cr * cp * cy + sr * sp * sy; + // q.x = sr * cp * cy - cr * sp * sy; + // q.y = cr * sp * cy + sr * cp * sy; + // q.z = cr * cp * sy - sr * sp * cy; + + // The D3DXMath format(game format): pitch (x), yaw (y), roll (z) + double cp = cos(pitch * 0.5); + double sp = sin(pitch * 0.5); + double cy = cos(yaw * 0.5); + double sy = sin(yaw * 0.5); + double cr = cos(roll * 0.5); + double sr = sin(roll * 0.5); + + q.w = cr * cp * cy + sr * sp * sy; + q.x = cr * sp * cy + sr * cp * sy; + q.y = cr * cp * sy - sr * sp * cy; + q.z = sr * cp * cy - cr * sp * sy; + + return q; } /* * For spherical linear interpolation, see * 3D Math Primer for Graphics and Game Development, 2nd Edition, Chapter 8 */ -static inline Quaternionf Quaternionf_Slerp(Quaternionf a, Quaternionf b, - float t) { - float cos_angle = Quaternionf_Dot(a, b); - if (cos_angle < 0) { - b = (Quaternionf){-b.x, -b.y, -b.z, -b.w}; - cos_angle = -cos_angle; - } - if (cos_angle > 1 - EPSILON) { - float x = Lerpf(a.x, b.x, t); - float y = Lerpf(a.y, b.y, t); - float z = Lerpf(a.z, b.z, t); - float w = Lerpf(a.w, b.w, t); - return (Quaternionf){x, y, z, w}; - } else { - float angle = (float)acos(cos_angle); - float sin_angle_inv = 1.f / (float)sin(angle); - float angle_a = (1 - t) * angle; - float angle_b = t * angle; - float factor_a = (float)sin(angle_a) * sin_angle_inv; - float factor_b = (float)sin(angle_b) * sin_angle_inv; - float x = factor_a * a.x + factor_b * b.x; - float y = factor_a * a.y + factor_b * b.y; - float z = factor_a * a.z + factor_b * b.z; - float w = factor_a * a.w + factor_b * b.w; - return (Quaternionf){x, y, z, w}; - } -} - -static inline Matrix4x4f Matrix4x4f_Add(Matrix4x4f a, Matrix4x4f b) { - Matrix4x4f r; - int i, j; - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - r.m[i][j] = a.m[i][j] + b.m[i][j]; +static inline Quaternionf Quaternionf_Slerp(Quaternionf a, Quaternionf b, float t) +{ + float cos_angle = Quaternionf_Dot(a, b); + if (cos_angle < 0) { + b = (Quaternionf){-b.x, -b.y, -b.z, -b.w}; + cos_angle = -cos_angle; + } + if (cos_angle > 1 - EPSILON) { + float x = Lerpf(a.x, b.x, t); + float y = Lerpf(a.y, b.y, t); + float z = Lerpf(a.z, b.z, t); + float w = Lerpf(a.w, b.w, t); + return (Quaternionf){x, y, z, w}; + } else { + float angle = (float)acos(cos_angle); + float sin_angle_inv = 1.f / (float)sin(angle); + float angle_a = (1 - t) * angle; + float angle_b = t * angle; + float factor_a = (float)sin(angle_a) * sin_angle_inv; + float factor_b = (float)sin(angle_b) * sin_angle_inv; + float x = factor_a * a.x + factor_b * b.x; + float y = factor_a * a.y + factor_b * b.y; + float z = factor_a * a.z + factor_b * b.z; + float w = factor_a * a.w + factor_b * b.w; + return (Quaternionf){x, y, z, w}; } - } - return r; } -static Matrix4x4f Matrix4x4f_Sub(Matrix4x4f a, Matrix4x4f b) { - Matrix4x4f r; - int i, j; - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - r.m[i][j] = a.m[i][j] - b.m[i][j]; +static inline Matrix4x4f Matrix4x4f_Add(Matrix4x4f a, Matrix4x4f b) +{ + Matrix4x4f r; + int i, j; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + r.m[i][j] = a.m[i][j] + b.m[i][j]; + } } - } - return r; + return r; } -static inline Matrix4x4f Matrix4x4f_MulMatrix4x4(Matrix4x4f o, - Matrix4x4f other) { - Matrix4x4f r; - int i, j; - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - r.m[j][i] = (o.m[j][0] * other.m[0][i]) + (o.m[j][1] * other.m[1][i]) + - (o.m[j][2] * other.m[2][i]) + (o.m[j][3] * other.m[3][i]); +static Matrix4x4f Matrix4x4f_Sub(Matrix4x4f a, Matrix4x4f b) +{ + Matrix4x4f r; + int i, j; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + r.m[i][j] = a.m[i][j] - b.m[i][j]; + } } - } - return r; + return r; +} + +static inline Matrix4x4f Matrix4x4f_MulMatrix4x4(Matrix4x4f o, Matrix4x4f other) +{ + Matrix4x4f r; + int i, j; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + r.m[j][i] = (o.m[j][0] * other.m[0][i]) + (o.m[j][1] * other.m[1][i]) + + (o.m[j][2] * other.m[2][i]) + (o.m[j][3] * other.m[3][i]); + } + } + return r; } -static inline void Matrix4x4f_ScaleInPlace(Matrix4x4f *o, float f) { - int i, j; - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - o->m[i][j] *= f; +static inline void Matrix4x4f_ScaleInPlace(Matrix4x4f* o, float f) +{ + int i, j; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + o->m[i][j] *= f; + } } - } } -static inline Matrix4x4f Matrix4x4f_Scale(Matrix4x4f o, float f) { - Matrix4x4f r; - int i, j; - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - r.m[i][j] = o.m[i][j] * f; +static inline Matrix4x4f Matrix4x4f_Scale(Matrix4x4f o, float f) +{ + Matrix4x4f r; + int i, j; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + r.m[i][j] = o.m[i][j] * f; + } } - } - return r; + return r; } // 0: false, 1: true -static inline int Matrix4x4f_Invert(Matrix4x4f o, Matrix4x4f *inv_out) { - Matrix4x4f inv; - float det; +static inline int Matrix4x4f_Invert(Matrix4x4f o, Matrix4x4f* inv_out) +{ + Matrix4x4f inv; + float det; - inv.m11 = o.m22 * o.m33 * o.m44 - o.m22 * o.m34 * o.m43 - - o.m32 * o.m23 * o.m44 + o.m32 * o.m24 * o.m43 + - o.m42 * o.m23 * o.m34 - o.m43 * o.m24 * o.m33; + inv.m11 = o.m22 * o.m33 * o.m44 - o.m22 * o.m34 * o.m43 - o.m32 * o.m23 * o.m44 + + o.m32 * o.m24 * o.m43 + o.m42 * o.m23 * o.m34 - o.m43 * o.m24 * o.m33; - inv.m21 = -o.m21 * o.m33 * o.m44 + o.m21 * o.m34 * o.m43 + - o.m31 * o.m23 * o.m44 - o.m31 * o.m24 * o.m43 - - o.m41 * o.m23 * o.m34 + o.m41 * o.m24 * o.m33; + inv.m21 = -o.m21 * o.m33 * o.m44 + o.m21 * o.m34 * o.m43 + o.m31 * o.m23 * o.m44 + - o.m31 * o.m24 * o.m43 - o.m41 * o.m23 * o.m34 + o.m41 * o.m24 * o.m33; - inv.m31 = o.m21 * o.m32 * o.m44 - o.m21 * o.m34 * o.m43 - - o.m31 * o.m22 * o.m44 + o.m31 * o.m24 * o.m43 + - o.m41 * o.m22 * o.m34 - o.m41 * o.m24 * o.m32; + inv.m31 = o.m21 * o.m32 * o.m44 - o.m21 * o.m34 * o.m43 - o.m31 * o.m22 * o.m44 + + o.m31 * o.m24 * o.m43 + o.m41 * o.m22 * o.m34 - o.m41 * o.m24 * o.m32; - inv.m41 = -o.m21 * o.m32 * o.m43 + o.m21 * o.m33 * o.m43 + - o.m31 * o.m22 * o.m43 - o.m31 * o.m23 * o.m43 - - o.m41 * o.m22 * o.m33 + o.m41 * o.m23 * o.m32; + inv.m41 = -o.m21 * o.m32 * o.m43 + o.m21 * o.m33 * o.m43 + o.m31 * o.m22 * o.m43 + - o.m31 * o.m23 * o.m43 - o.m41 * o.m22 * o.m33 + o.m41 * o.m23 * o.m32; - inv.m12 = -o.m12 * o.m33 * o.m44 + o.m12 * o.m34 * o.m43 + - o.m32 * o.m13 * o.m44 - o.m32 * o.m14 * o.m43 - - o.m43 * o.m13 * o.m34 + o.m43 * o.m14 * o.m33; + inv.m12 = -o.m12 * o.m33 * o.m44 + o.m12 * o.m34 * o.m43 + o.m32 * o.m13 * o.m44 + - o.m32 * o.m14 * o.m43 - o.m43 * o.m13 * o.m34 + o.m43 * o.m14 * o.m33; - inv.m22 = o.m11 * o.m33 * o.m44 - o.m11 * o.m34 * o.m43 - - o.m31 * o.m13 * o.m44 + o.m31 * o.m14 * o.m43 + - o.m41 * o.m13 * o.m34 - o.m41 * o.m14 * o.m33; + inv.m22 = o.m11 * o.m33 * o.m44 - o.m11 * o.m34 * o.m43 - o.m31 * o.m13 * o.m44 + + o.m31 * o.m14 * o.m43 + o.m41 * o.m13 * o.m34 - o.m41 * o.m14 * o.m33; - inv.m32 = -o.m11 * o.m32 * o.m44 + o.m11 * o.m34 * o.m43 + - o.m31 * o.m12 * o.m44 - o.m31 * o.m14 * o.m43 - - o.m41 * o.m12 * o.m34 + o.m41 * o.m14 * o.m32; + inv.m32 = -o.m11 * o.m32 * o.m44 + o.m11 * o.m34 * o.m43 + o.m31 * o.m12 * o.m44 + - o.m31 * o.m14 * o.m43 - o.m41 * o.m12 * o.m34 + o.m41 * o.m14 * o.m32; - inv.m42 = o.m11 * o.m32 * o.m43 - o.m11 * o.m33 * o.m43 - - o.m31 * o.m12 * o.m43 + o.m31 * o.m13 * o.m43 + - o.m41 * o.m12 * o.m33 - o.m41 * o.m13 * o.m32; + inv.m42 = o.m11 * o.m32 * o.m43 - o.m11 * o.m33 * o.m43 - o.m31 * o.m12 * o.m43 + + o.m31 * o.m13 * o.m43 + o.m41 * o.m12 * o.m33 - o.m41 * o.m13 * o.m32; - inv.m13 = o.m12 * o.m23 * o.m44 - o.m12 * o.m24 * o.m43 - - o.m22 * o.m13 * o.m44 + o.m22 * o.m14 * o.m43 + - o.m43 * o.m13 * o.m24 - o.m43 * o.m14 * o.m23; + inv.m13 = o.m12 * o.m23 * o.m44 - o.m12 * o.m24 * o.m43 - o.m22 * o.m13 * o.m44 + + o.m22 * o.m14 * o.m43 + o.m43 * o.m13 * o.m24 - o.m43 * o.m14 * o.m23; - inv.m23 = -o.m11 * o.m23 * o.m44 + o.m11 * o.m24 * o.m43 + - o.m21 * o.m13 * o.m44 - o.m21 * o.m14 * o.m43 - - o.m41 * o.m13 * o.m24 + o.m41 * o.m14 * o.m23; + inv.m23 = -o.m11 * o.m23 * o.m44 + o.m11 * o.m24 * o.m43 + o.m21 * o.m13 * o.m44 + - o.m21 * o.m14 * o.m43 - o.m41 * o.m13 * o.m24 + o.m41 * o.m14 * o.m23; - inv.m33 = o.m11 * o.m22 * o.m44 - o.m11 * o.m24 * o.m43 - - o.m21 * o.m12 * o.m44 + o.m21 * o.m14 * o.m43 + - o.m41 * o.m12 * o.m24 - o.m41 * o.m14 * o.m22; + inv.m33 = o.m11 * o.m22 * o.m44 - o.m11 * o.m24 * o.m43 - o.m21 * o.m12 * o.m44 + + o.m21 * o.m14 * o.m43 + o.m41 * o.m12 * o.m24 - o.m41 * o.m14 * o.m22; - inv.m43 = -o.m11 * o.m22 * o.m43 + o.m11 * o.m23 * o.m43 + - o.m21 * o.m12 * o.m43 - o.m21 * o.m13 * o.m43 - - o.m41 * o.m12 * o.m23 + o.m41 * o.m13 * o.m22; + inv.m43 = -o.m11 * o.m22 * o.m43 + o.m11 * o.m23 * o.m43 + o.m21 * o.m12 * o.m43 + - o.m21 * o.m13 * o.m43 - o.m41 * o.m12 * o.m23 + o.m41 * o.m13 * o.m22; - inv.m14 = -o.m12 * o.m23 * o.m34 + o.m12 * o.m24 * o.m33 + - o.m22 * o.m13 * o.m34 - o.m22 * o.m14 * o.m33 - - o.m32 * o.m13 * o.m24 + o.m32 * o.m14 * o.m23; + inv.m14 = -o.m12 * o.m23 * o.m34 + o.m12 * o.m24 * o.m33 + o.m22 * o.m13 * o.m34 + - o.m22 * o.m14 * o.m33 - o.m32 * o.m13 * o.m24 + o.m32 * o.m14 * o.m23; - inv.m24 = o.m11 * o.m23 * o.m34 - o.m11 * o.m24 * o.m33 - - o.m21 * o.m13 * o.m34 + o.m21 * o.m14 * o.m33 + - o.m31 * o.m13 * o.m24 - o.m31 * o.m14 * o.m23; + inv.m24 = o.m11 * o.m23 * o.m34 - o.m11 * o.m24 * o.m33 - o.m21 * o.m13 * o.m34 + + o.m21 * o.m14 * o.m33 + o.m31 * o.m13 * o.m24 - o.m31 * o.m14 * o.m23; - inv.m34 = -o.m11 * o.m22 * o.m34 + o.m11 * o.m24 * o.m32 + - o.m21 * o.m12 * o.m34 - o.m21 * o.m14 * o.m32 - - o.m31 * o.m12 * o.m24 + o.m31 * o.m14 * o.m22; + inv.m34 = -o.m11 * o.m22 * o.m34 + o.m11 * o.m24 * o.m32 + o.m21 * o.m12 * o.m34 + - o.m21 * o.m14 * o.m32 - o.m31 * o.m12 * o.m24 + o.m31 * o.m14 * o.m22; - inv.m44 = o.m11 * o.m22 * o.m33 - o.m11 * o.m23 * o.m32 - - o.m21 * o.m12 * o.m33 + o.m21 * o.m13 * o.m32 + - o.m31 * o.m12 * o.m23 - o.m31 * o.m13 * o.m22; + inv.m44 = o.m11 * o.m22 * o.m33 - o.m11 * o.m23 * o.m32 - o.m21 * o.m12 * o.m33 + + o.m21 * o.m13 * o.m32 + o.m31 * o.m12 * o.m23 - o.m31 * o.m13 * o.m22; - det = o.m11 * inv.m11 + o.m12 * inv.m21 + o.m13 * inv.m31 + o.m14 * inv.m41; + det = o.m11 * inv.m11 + o.m12 * inv.m21 + o.m13 * inv.m31 + o.m14 * inv.m41; - if (det == 0.f) { - return 0; - } + if (det == 0.f) { + return 0; + } - *inv_out = Matrix4x4f_Scale(inv, 1.f / det); + *inv_out = Matrix4x4f_Scale(inv, 1.f / det); - return 1; + return 1; } // y = x * m -static inline void Matrix4x4f_Apply(Vector4f *y, const Vector4f *x, - const Matrix4x4f *m) { - float X = x->x, Y = x->y, Z = x->z, W = x->w; - y->x = X * m->m[0][0] + Y * m->m[1][0] + Z * m->m[2][0] + W * m->m[3][0]; - y->y = X * m->m[0][1] + Y * m->m[1][1] + Z * m->m[2][1] + W * m->m[3][1]; - y->z = X * m->m[0][2] + Y * m->m[1][2] + Z * m->m[2][2] + W * m->m[3][2]; - y->w = X * m->m[0][3] + Y * m->m[1][3] + Z * m->m[2][3] + W * m->m[3][3]; -} - -static inline void Matrix4x4f_SetZero(Matrix4x4f *m) { - memset(m->m, 0, sizeof(float) * 16); -} - -static inline void Matrix4x4f_SetIdentity(Matrix4x4f *m) { - Matrix4x4f_SetZero(m); - m->m11 = m->m22 = m->m33 = m->m44 = 1.0f; -} - -static inline void Matrix4x4f_SetTranslate(Matrix4x4f *m, float x, float y, - float z) { - Matrix4x4f_SetIdentity(m); - m->m41 = x; - m->m42 = y; - m->m43 = z; -} - -static inline void Matrix4x4f_SetScale(Matrix4x4f *m, float x, float y, - float z) { - Matrix4x4f_SetIdentity(m); - m->m11 = x; - m->m22 = y; - m->m33 = z; -} - -static inline void Matrix4x4f_SetRotate(Matrix4x4f *m, float x, float y, - float z, float theta) { - float qsin = (float)sin(theta * 0.5f); - float qcos = (float)cos(theta * 0.5f); - Vector4f vec = {x, y, z, 1.0f}; - float w = qcos; - Vector4f_NormalizeInPlace(&vec); - x = vec.x * qsin; - y = vec.y * qsin; - z = vec.z * qsin; - m->m11 = 1 - 2 * y * y - 2 * z * z; - m->m21 = 2 * x * y - 2 * w * z; - m->m31 = 2 * x * z + 2 * w * y; - m->m12 = 2 * x * y + 2 * w * z; - m->m22 = 1 - 2 * x * x - 2 * z * z; - m->m32 = 2 * y * z - 2 * w * x; - m->m13 = 2 * x * z - 2 * w * y; - m->m23 = 2 * y * z + 2 * w * x; - m->m33 = 1 - 2 * x * x - 2 * y * y; - m->m14 = m->m24 = m->m34 = 0.f; - m->m41 = m->m42 = m->m43 = 0.f; - m->m44 = 1.f; -} - -static void Matrix4x4f_SetLookAt(Matrix4x4f *m, Vector4f eye, Vector4f at, - Vector4f up) { - Vector4f xaxis, yaxis, zaxis; - - zaxis = Vector4f_Sub(at, eye); - Vector4f_NormalizeInPlace(&zaxis); - xaxis = Vector4f_Cross(up, zaxis); - Vector4f_NormalizeInPlace(&xaxis); - yaxis = Vector4f_Cross(zaxis, xaxis); - - m->m11 = xaxis.x; - m->m21 = xaxis.y; - m->m31 = xaxis.z; - m->m41 = -Vector4f_Dot(xaxis, eye); - - m->m12 = yaxis.x; - m->m22 = yaxis.y; - m->m32 = yaxis.z; - m->m42 = -Vector4f_Dot(yaxis, eye); - - m->m13 = zaxis.x; - m->m23 = zaxis.y; - m->m33 = zaxis.z; - m->m43 = -Vector4f_Dot(zaxis, eye); - - m->m14 = m->m24 = m->m34 = 0.f; - m->m44 = 1.f; +static inline void Matrix4x4f_Apply(Vector4f* y, const Vector4f* x, const Matrix4x4f* m) +{ + float X = x->x, Y = x->y, Z = x->z, W = x->w; + y->x = X * m->m[0][0] + Y * m->m[1][0] + Z * m->m[2][0] + W * m->m[3][0]; + y->y = X * m->m[0][1] + Y * m->m[1][1] + Z * m->m[2][1] + W * m->m[3][1]; + y->z = X * m->m[0][2] + Y * m->m[1][2] + Z * m->m[2][2] + W * m->m[3][2]; + y->w = X * m->m[0][3] + Y * m->m[1][3] + Z * m->m[2][3] + W * m->m[3][3]; +} + +static inline void Matrix4x4f_SetZero(Matrix4x4f* m) +{ + memset(m->m, 0, sizeof(float) * 16); +} + +static inline void Matrix4x4f_SetIdentity(Matrix4x4f* m) +{ + Matrix4x4f_SetZero(m); + m->m11 = m->m22 = m->m33 = m->m44 = 1.0f; +} + +static inline void Matrix4x4f_SetTranslate(Matrix4x4f* m, float x, float y, float z) +{ + Matrix4x4f_SetIdentity(m); + m->m41 = x; + m->m42 = y; + m->m43 = z; +} + +static inline void Matrix4x4f_SetScale(Matrix4x4f* m, float x, float y, float z) +{ + Matrix4x4f_SetIdentity(m); + m->m11 = x; + m->m22 = y; + m->m33 = z; +} + +static inline void Matrix4x4f_SetRotate(Matrix4x4f* m, float x, float y, float z, float theta) +{ + float qsin = (float)sin(theta * 0.5f); + float qcos = (float)cos(theta * 0.5f); + Vector4f vec = {x, y, z, 1.0f}; + float w = qcos; + Vector4f_NormalizeInPlace(&vec); + x = vec.x * qsin; + y = vec.y * qsin; + z = vec.z * qsin; + m->m11 = 1 - 2 * y * y - 2 * z * z; + m->m21 = 2 * x * y - 2 * w * z; + m->m31 = 2 * x * z + 2 * w * y; + m->m12 = 2 * x * y + 2 * w * z; + m->m22 = 1 - 2 * x * x - 2 * z * z; + m->m32 = 2 * y * z - 2 * w * x; + m->m13 = 2 * x * z - 2 * w * y; + m->m23 = 2 * y * z + 2 * w * x; + m->m33 = 1 - 2 * x * x - 2 * y * y; + m->m14 = m->m24 = m->m34 = 0.f; + m->m41 = m->m42 = m->m43 = 0.f; + m->m44 = 1.f; +} + +static void Matrix4x4f_SetLookAt(Matrix4x4f* m, Vector4f eye, Vector4f at, Vector4f up) +{ + Vector4f xaxis, yaxis, zaxis; + + zaxis = Vector4f_Sub(at, eye); + Vector4f_NormalizeInPlace(&zaxis); + xaxis = Vector4f_Cross(up, zaxis); + Vector4f_NormalizeInPlace(&xaxis); + yaxis = Vector4f_Cross(zaxis, xaxis); + + m->m11 = xaxis.x; + m->m21 = xaxis.y; + m->m31 = xaxis.z; + m->m41 = -Vector4f_Dot(xaxis, eye); + + m->m12 = yaxis.x; + m->m22 = yaxis.y; + m->m32 = yaxis.z; + m->m42 = -Vector4f_Dot(yaxis, eye); + + m->m13 = zaxis.x; + m->m23 = zaxis.y; + m->m33 = zaxis.z; + m->m43 = -Vector4f_Dot(zaxis, eye); + + m->m14 = m->m24 = m->m34 = 0.f; + m->m44 = 1.f; } // D3DXMatrixPerspectiveFovLH -static void Matrix4x4f_SetPerspective(Matrix4x4f *m, float fovy, float aspect, - float zn, float zf) { - float fax = 1.0f / (float)tan(fovy * 0.5f); - Matrix4x4f_SetZero(m); - m->m11 = (float)(fax / aspect); - m->m22 = (float)(fax); - m->m33 = zf / (zf - zn); - m->m43 = -zn * zf / (zf - zn); - m->m34 = 1; -} - -typedef struct { - Matrix4x4f world; // 世界坐标变换 - Matrix4x4f view; // 摄影机坐标变换 - Matrix4x4f projection; // 投影变换 - Matrix4x4f transform; // transform = world * view * projection - float w, h; // 屏幕大小 +static void Matrix4x4f_SetPerspective(Matrix4x4f* m, float fovy, float aspect, float zn, float zf) +{ + float fax = 1.0f / (float)tan(fovy * 0.5f); + Matrix4x4f_SetZero(m); + m->m11 = (float)(fax / aspect); + m->m22 = (float)(fax); + m->m33 = zf / (zf - zn); + m->m43 = -zn * zf / (zf - zn); + m->m34 = 1; +} + +typedef struct +{ + Matrix4x4f world; // 世界坐标变换 + Matrix4x4f view; // 摄影机坐标变换 + Matrix4x4f projection; // 投影变换 + Matrix4x4f transform; // transform = world * view * projection + float w, h; // 屏幕大小 } Transform; // 矩阵更新,计算 transform = world * view * projection -static inline void Transform_Update(Transform *ts) { - ts->transform = Matrix4x4f_MulMatrix4x4( - Matrix4x4f_MulMatrix4x4(ts->world, ts->view), ts->projection); +static inline void Transform_Update(Transform* ts) +{ + ts->transform = + Matrix4x4f_MulMatrix4x4(Matrix4x4f_MulMatrix4x4(ts->world, ts->view), ts->projection); } // 初始化,设置屏幕长宽 -static void Transform_Init(Transform *ts, int width, int height) { - float aspect = (float)width / ((float)height); - Matrix4x4f_SetIdentity(&ts->world); - Matrix4x4f_SetIdentity(&ts->view); - Matrix4x4f_SetPerspective(&ts->projection, 3.1415926f * 0.5f, aspect, 1.0f, - 500.0f); - ts->w = (float)width; - ts->h = (float)height; - Transform_Update(ts); +static void Transform_Init(Transform* ts, int width, int height) +{ + float aspect = (float)width / ((float)height); + Matrix4x4f_SetIdentity(&ts->world); + Matrix4x4f_SetIdentity(&ts->view); + Matrix4x4f_SetPerspective(&ts->projection, 3.1415926f * 0.5f, aspect, 1.0f, 500.0f); + ts->w = (float)width; + ts->h = (float)height; + Transform_Update(ts); } // 将矢量 x 进行 project -static void Transform_Apply(const Transform *ts, Vector4f *y, - const Vector4f *x) { - Matrix4x4f_Apply(y, x, &ts->transform); +static void Transform_Apply(const Transform* ts, Vector4f* y, const Vector4f* x) +{ + Matrix4x4f_Apply(y, x, &ts->transform); } // 检查齐次坐标同 cvv 的边界用于视锥裁剪 -static int Transform_CheckCvv(const Vector4f *v) { - float w = v->w; - int check = 0; - if (v->z < 0.0f) - check |= 1; - if (v->z > w) - check |= 2; - if (v->x < -w) - check |= 4; - if (v->x > w) - check |= 8; - if (v->y < -w) - check |= 16; - if (v->y > w) - check |= 32; - - return check; +static int Transform_CheckCvv(const Vector4f* v) +{ + float w = v->w; + int check = 0; + if (v->z < 0.0f) + check |= 1; + if (v->z > w) + check |= 2; + if (v->x < -w) + check |= 4; + if (v->x > w) + check |= 8; + if (v->y < -w) + check |= 16; + if (v->y > w) + check |= 32; + + return check; } // 归一化,得到屏幕坐标 -static void Transform_Homogenize(const Transform *ts, Vector4f *y, - const Vector4f *x) { - float rhw = 1.0f / x->w; - y->x = (x->x * rhw + 1.0f) * ts->w * 0.5f; - y->y = (1.0f - x->y * rhw) * ts->h * 0.5f; - y->z = x->z * rhw; - y->w = 1.0f; +static void Transform_Homogenize(const Transform* ts, Vector4f* y, const Vector4f* x) +{ + float rhw = 1.0f / x->w; + y->x = (x->x * rhw + 1.0f) * ts->w * 0.5f; + y->y = (1.0f - x->y * rhw) * ts->h * 0.5f; + y->z = x->z * rhw; + y->w = 1.0f; } //===================================================================== // 几何计算:顶点、扫描线、边缘、矩形、步长计算 //===================================================================== -typedef struct { - float r, g, b; +typedef struct +{ + float r, g, b; } Color3f; -typedef struct { - float u, v; +typedef struct +{ + float u, v; } Texcoord2f; -typedef struct { - Point4f pos; - Texcoord2f tc; - Color3f color; - float rhw; +typedef struct +{ + Point4f pos; + Texcoord2f tc; + Color3f color; + float rhw; } Vertexf; -typedef struct { - Vertexf v, v1, v2; +typedef struct +{ + Vertexf v, v1, v2; } Edgef; -typedef struct { - float top, bottom; - Edgef left, right; +typedef struct +{ + float top, bottom; + Edgef left, right; } Trapezoidf; -typedef struct { - Vertexf v, step; - int x, y, w; +typedef struct +{ + Vertexf v, step; + int x, y, w; } Scanlinef; -static void Vertexf_RhwInit(Vertexf *v) { - float rhw = 1.0f / v->pos.w; - v->rhw = rhw; - v->tc.u *= rhw; - v->tc.v *= rhw; - v->color.r *= rhw; - v->color.g *= rhw; - v->color.b *= rhw; -} - -static void Vertexf_Interpolate(Vertexf *y, const Vertexf *x1, - const Vertexf *x2, float t) { - y->pos = Vector4f_Lerp(x1->pos, x2->pos, t); - y->tc.u = Interpolatef(x1->tc.u, x2->tc.u, t); - y->tc.v = Interpolatef(x1->tc.v, x2->tc.v, t); - y->color.r = Interpolatef(x1->color.r, x2->color.r, t); - y->color.g = Interpolatef(x1->color.g, x2->color.g, t); - y->color.b = Interpolatef(x1->color.b, x2->color.b, t); - y->rhw = Interpolatef(x1->rhw, x2->rhw, t); -} - -static void Vertexf_Division(Vertexf *y, const Vertexf *x1, const Vertexf *x2, - float w) { - float inv = 1.0f / w; - y->pos.x = (x2->pos.x - x1->pos.x) * inv; - y->pos.y = (x2->pos.y - x1->pos.y) * inv; - y->pos.z = (x2->pos.z - x1->pos.z) * inv; - y->pos.w = (x2->pos.w - x1->pos.w) * inv; - y->tc.u = (x2->tc.u - x1->tc.u) * inv; - y->tc.v = (x2->tc.v - x1->tc.v) * inv; - y->color.r = (x2->color.r - x1->color.r) * inv; - y->color.g = (x2->color.g - x1->color.g) * inv; - y->color.b = (x2->color.b - x1->color.b) * inv; - y->rhw = (x2->rhw - x1->rhw) * inv; -} - -static void Vertexf_Add(Vertexf *y, const Vertexf *x) { - y->pos.x += x->pos.x; - y->pos.y += x->pos.y; - y->pos.z += x->pos.z; - y->pos.w += x->pos.w; - y->rhw += x->rhw; - y->tc.u += x->tc.u; - y->tc.v += x->tc.v; - y->color.r += x->color.r; - y->color.g += x->color.g; - y->color.b += x->color.b; +static void Vertexf_RhwInit(Vertexf* v) +{ + float rhw = 1.0f / v->pos.w; + v->rhw = rhw; + v->tc.u *= rhw; + v->tc.v *= rhw; + v->color.r *= rhw; + v->color.g *= rhw; + v->color.b *= rhw; +} + +static void Vertexf_Interpolate(Vertexf* y, const Vertexf* x1, const Vertexf* x2, float t) +{ + y->pos = Vector4f_Lerp(x1->pos, x2->pos, t); + y->tc.u = Interpolatef(x1->tc.u, x2->tc.u, t); + y->tc.v = Interpolatef(x1->tc.v, x2->tc.v, t); + y->color.r = Interpolatef(x1->color.r, x2->color.r, t); + y->color.g = Interpolatef(x1->color.g, x2->color.g, t); + y->color.b = Interpolatef(x1->color.b, x2->color.b, t); + y->rhw = Interpolatef(x1->rhw, x2->rhw, t); +} + +static void Vertexf_Division(Vertexf* y, const Vertexf* x1, const Vertexf* x2, float w) +{ + float inv = 1.0f / w; + y->pos.x = (x2->pos.x - x1->pos.x) * inv; + y->pos.y = (x2->pos.y - x1->pos.y) * inv; + y->pos.z = (x2->pos.z - x1->pos.z) * inv; + y->pos.w = (x2->pos.w - x1->pos.w) * inv; + y->tc.u = (x2->tc.u - x1->tc.u) * inv; + y->tc.v = (x2->tc.v - x1->tc.v) * inv; + y->color.r = (x2->color.r - x1->color.r) * inv; + y->color.g = (x2->color.g - x1->color.g) * inv; + y->color.b = (x2->color.b - x1->color.b) * inv; + y->rhw = (x2->rhw - x1->rhw) * inv; +} + +static void Vertexf_Add(Vertexf* y, const Vertexf* x) +{ + y->pos.x += x->pos.x; + y->pos.y += x->pos.y; + y->pos.z += x->pos.z; + y->pos.w += x->pos.w; + y->rhw += x->rhw; + y->tc.u += x->tc.u; + y->tc.v += x->tc.v; + y->color.r += x->color.r; + y->color.g += x->color.g; + y->color.b += x->color.b; } // 根据三角形生成 0-2 个梯形,并且返回合法梯形的数量 -static int Trapezoidf_InitTriangle(Trapezoidf *trap, const Vertexf *p1, - const Vertexf *p2, const Vertexf *p3) { - const Vertexf *p; - float k, x; - - if (p1->pos.y > p2->pos.y) { - p = p1, p1 = p2, p2 = p; - } - - if (p1->pos.y > p3->pos.y) { - p = p1, p1 = p3, p3 = p; - } - - if (p2->pos.y > p3->pos.y) { - p = p2, p2 = p3, p3 = p; - } +static int Trapezoidf_InitTriangle(Trapezoidf* trap, const Vertexf* p1, const Vertexf* p2, + const Vertexf* p3) +{ + const Vertexf* p; + float k, x; + + if (p1->pos.y > p2->pos.y) { + p = p1, p1 = p2, p2 = p; + } - if (p1->pos.y == p2->pos.y && p1->pos.y == p3->pos.y) { - return 0; - } + if (p1->pos.y > p3->pos.y) { + p = p1, p1 = p3, p3 = p; + } - if (p1->pos.x == p2->pos.x && p1->pos.x == p3->pos.x) { - return 0; - } + if (p2->pos.y > p3->pos.y) { + p = p2, p2 = p3, p3 = p; + } - if (p1->pos.y == p2->pos.y) { // triangle down - if (p1->pos.x > p2->pos.x) { - p = p1, p1 = p2, p2 = p; + if (p1->pos.y == p2->pos.y && p1->pos.y == p3->pos.y) { + return 0; } - trap[0].top = p1->pos.y; - trap[0].bottom = p3->pos.y; - trap[0].left.v1 = *p1; - trap[0].left.v2 = *p3; - trap[0].right.v1 = *p2; - trap[0].right.v2 = *p3; - return (trap[0].top < trap[0].bottom) ? 1 : 0; - } + if (p1->pos.x == p2->pos.x && p1->pos.x == p3->pos.x) { + return 0; + } - if (p2->pos.y == p3->pos.y) { // triangle up - if (p2->pos.x > p3->pos.x) { - p = p2, p2 = p3, p3 = p; + if (p1->pos.y == p2->pos.y) { // triangle down + if (p1->pos.x > p2->pos.x) { + p = p1, p1 = p2, p2 = p; + } + trap[0].top = p1->pos.y; + trap[0].bottom = p3->pos.y; + trap[0].left.v1 = *p1; + trap[0].left.v2 = *p3; + trap[0].right.v1 = *p2; + trap[0].right.v2 = *p3; + + return (trap[0].top < trap[0].bottom) ? 1 : 0; } - trap[0].top = p1->pos.y; - trap[0].bottom = p3->pos.y; - trap[0].left.v1 = *p1; - trap[0].left.v2 = *p2; - trap[0].right.v1 = *p1; - trap[0].right.v2 = *p3; - return (trap[0].top < trap[0].bottom) ? 1 : 0; - } + if (p2->pos.y == p3->pos.y) { // triangle up + if (p2->pos.x > p3->pos.x) { + p = p2, p2 = p3, p3 = p; + } + trap[0].top = p1->pos.y; + trap[0].bottom = p3->pos.y; + trap[0].left.v1 = *p1; + trap[0].left.v2 = *p2; + trap[0].right.v1 = *p1; + trap[0].right.v2 = *p3; + + return (trap[0].top < trap[0].bottom) ? 1 : 0; + } - trap[0].top = p1->pos.y; - trap[0].bottom = p2->pos.y; - trap[1].top = p2->pos.y; - trap[1].bottom = p3->pos.y; - - k = (p3->pos.y - p1->pos.y) / (p2->pos.y - p1->pos.y); - x = p1->pos.x + (p2->pos.x - p1->pos.x) * k; - - if (x <= p3->pos.x) { // triangle left - trap[0].left.v1 = *p1; - trap[0].left.v2 = *p2; - trap[0].right.v1 = *p1; - trap[0].right.v2 = *p3; - trap[1].left.v1 = *p2; - trap[1].left.v2 = *p3; - trap[1].right.v1 = *p1; - trap[1].right.v2 = *p3; - } else { // triangle right - trap[0].left.v1 = *p1; - trap[0].left.v2 = *p3; - trap[0].right.v1 = *p1; - trap[0].right.v2 = *p2; - trap[1].left.v1 = *p1; - trap[1].left.v2 = *p3; - trap[1].right.v1 = *p2; - trap[1].right.v2 = *p3; - } + trap[0].top = p1->pos.y; + trap[0].bottom = p2->pos.y; + trap[1].top = p2->pos.y; + trap[1].bottom = p3->pos.y; + + k = (p3->pos.y - p1->pos.y) / (p2->pos.y - p1->pos.y); + x = p1->pos.x + (p2->pos.x - p1->pos.x) * k; + + if (x <= p3->pos.x) { // triangle left + trap[0].left.v1 = *p1; + trap[0].left.v2 = *p2; + trap[0].right.v1 = *p1; + trap[0].right.v2 = *p3; + trap[1].left.v1 = *p2; + trap[1].left.v2 = *p3; + trap[1].right.v1 = *p1; + trap[1].right.v2 = *p3; + } else { // triangle right + trap[0].left.v1 = *p1; + trap[0].left.v2 = *p3; + trap[0].right.v1 = *p1; + trap[0].right.v2 = *p2; + trap[1].left.v1 = *p1; + trap[1].left.v2 = *p3; + trap[1].right.v1 = *p2; + trap[1].right.v2 = *p3; + } - return 2; + return 2; } // 按照 Y 坐标计算出左右两条边纵坐标等于 Y 的顶点 -static void Trapezoidf_EdgeInterpolate(Trapezoidf *trap, float y) { - float s1 = trap->left.v2.pos.y - trap->left.v1.pos.y; - float s2 = trap->right.v2.pos.y - trap->right.v1.pos.y; - float t1 = (y - trap->left.v1.pos.y) / s1; - float t2 = (y - trap->right.v1.pos.y) / s2; - Vertexf_Interpolate(&trap->left.v, &trap->left.v1, &trap->left.v2, t1); - Vertexf_Interpolate(&trap->right.v, &trap->right.v1, &trap->right.v2, t2); +static void Trapezoidf_EdgeInterpolate(Trapezoidf* trap, float y) +{ + float s1 = trap->left.v2.pos.y - trap->left.v1.pos.y; + float s2 = trap->right.v2.pos.y - trap->right.v1.pos.y; + float t1 = (y - trap->left.v1.pos.y) / s1; + float t2 = (y - trap->right.v1.pos.y) / s2; + Vertexf_Interpolate(&trap->left.v, &trap->left.v1, &trap->left.v2, t1); + Vertexf_Interpolate(&trap->right.v, &trap->right.v1, &trap->right.v2, t2); } // 根据左右两边的端点,初始化计算出扫描线的起点和步长 -static void Trapezoidf_InitScanline(const Trapezoidf *trap, Scanlinef *scanline, - int y) { - float width = trap->right.v.pos.x - trap->left.v.pos.x; - scanline->x = (int)(trap->left.v.pos.x + 0.5f); - scanline->w = (int)(trap->right.v.pos.x + 0.5f) - scanline->x; - scanline->y = y; - scanline->v = trap->left.v; - if (trap->left.v.pos.x >= trap->right.v.pos.x) { - scanline->w = 0; - } - Vertexf_Division(&scanline->step, &trap->left.v, &trap->right.v, width); +static void Trapezoidf_InitScanline(const Trapezoidf* trap, Scanlinef* scanline, int y) +{ + float width = trap->right.v.pos.x - trap->left.v.pos.x; + scanline->x = (int)(trap->left.v.pos.x + 0.5f); + scanline->w = (int)(trap->right.v.pos.x + 0.5f) - scanline->x; + scanline->y = y; + scanline->v = trap->left.v; + if (trap->left.v.pos.x >= trap->right.v.pos.x) { + scanline->w = 0; + } + Vertexf_Division(&scanline->step, &trap->left.v, &trap->right.v, width); } diff --git a/sww/test/proc_anim.c b/sww/test/proc_anim.c index 4937ebb..1337ced 100644 --- a/sww/test/proc_anim.c +++ b/sww/test/proc_anim.c @@ -5,115 +5,132 @@ #include "sww/app.h" #include "sww/color.h" +#include "sww/cstl_vector.h" #include "sww/fps_helper.h" #include "sww/rate_helper.h" #include "sww/renderer.h" #include "sww/util.h" #include "sww/vmath.h" #include "sww/window.h" -#include "sww/cstl_vector.h" #define MAX_SCENE 1 -typedef void (*SceneFunc)(swwWindow *); +typedef void (*SceneFunc)(swwWindow*); -typedef struct { - int w; - int h; - int scene; - swwRenderer *renderer; - SceneFunc fs[MAX_SCENE]; +typedef struct +{ + int w; + int h; + int scene; + swwRenderer* renderer; + SceneFunc fs[MAX_SCENE]; } UserData; -void OnKey(swwWindow *o, swwKeycode key, int pressed) { - UserData *ud = swwWindow_GetUserData(o); - if (pressed) { - switch (key) { - case swwKeycode_ESCAPE: { - swwApp_PostQuitEvent(); - } break; - case swwKeycode_W: { - ud->scene = (ud->scene + 1) % MAX_SCENE; - } break; - case swwKeycode_S: { - ud->scene--; - if (ud->scene < 0) { - ud->scene = MAX_SCENE - 1; - } - } break; - default: - break; +void OnKey(swwWindow* o, swwKeycode key, int pressed) +{ + UserData* ud = swwWindow_GetUserData(o); + if (pressed) { + switch (key) { + case swwKeycode_ESCAPE: { + swwApp_PostQuitEvent(); + } break; + case swwKeycode_W: { + ud->scene = (ud->scene + 1) % MAX_SCENE; + } break; + case swwKeycode_S: { + ud->scene--; + if (ud->scene < 0) { + ud->scene = MAX_SCENE - 1; + } + } break; + default: + break; + } } - } } -void OnButton(swwWindow *o, swwButton btn, int pressed) { - if (btn == swwButton_L && pressed) { - } else if (btn == swwButton_R && pressed) { - // Save to bmp file - UserData *ud = swwWindow_GetUserData(o); - uint32_t buf_size = swwUtil_BmpBufferSize(ud->w, ud->h, 1); - uint8_t *buf = (uint8_t *)malloc(buf_size); - uint8_t *wbuf = swwRenderer_LockBuffer(ud->renderer); - FILE *fp = NULL; - swwUtil_SaveBufferToBmpBuffer(buf, buf_size, wbuf, ud->w, ud->h, 1); - fp = fopen("output.bmp", "wb+"); - fwrite(buf, 1, buf_size, fp); - fclose(fp); - free(buf); - } +void OnButton(swwWindow* o, swwButton btn, int pressed) +{ + if (btn == swwButton_L && pressed) { + } else if (btn == swwButton_R && pressed) { + // Save to bmp file + UserData* ud = swwWindow_GetUserData(o); + uint32_t buf_size = swwUtil_BmpBufferSize(ud->w, ud->h, 1); + uint8_t* buf = (uint8_t*)malloc(buf_size); + uint8_t* wbuf = swwRenderer_LockBuffer(ud->renderer); + FILE* fp = NULL; + swwUtil_SaveBufferToBmpBuffer(buf, buf_size, wbuf, ud->w, ud->h, 1); + fp = fopen("output.bmp", "wb+"); + fwrite(buf, 1, buf_size, fp); + fclose(fp); + free(buf); + } } -void OnScroll(swwWindow *o, float offset) {} +void OnScroll(swwWindow* o, float offset) +{} CSTLVector(Point2fVector, Point2f); CSTLVector(FloatVector, float); typedef struct { - Point2fVector joints; - int link_size; // Space between joints + Point2fVector joints; + int link_size; // Space between joints - // Only used in non-FABRIK resolution - FloatVector angles; - float angle_constraint; // Max angle diff between two adjacent joints, higher = loose, lower = rigid + // Only used in non-FABRIK resolution + FloatVector angles; + float angle_constraint; // Max angle diff between two adjacent joints, higher = loose, lower = + // rigid } Chain; -#define Chain_Construct(origin, joint_count, link_size) Chain_ConstructWithAngleConstraint(origin, joint_count, link_size, 2 * M_PI) - -void Chain_ConstructWithAngleConstraint(Chain *o, Point2f origin, int joint_count, int link_size, float angleConstraint) { - o->link_size = link_size; - o->angle_constraint = angle_constraint; - Point2fVector_Construct(&o->joints, 16); // Assumed to be >= 2, otherwise it wouldn't be much of a chain - FloatVector_Construct(&o->angles, 16); +#define Chain_Construct(origin, joint_count, link_size) \ + Chain_ConstructWithAngleConstraint(origin, joint_count, link_size, 2 * M_PI) - Point2fVector_PushBack(&o->joints, origin); - FloatVector_PushBack(&o->angles, 0.f); +void Chain_ConstructWithAngleConstraint(Chain* o, Point2f origin, int joint_count, int link_size, + float angleConstraint) +{ + o->link_size = link_size; + o->angle_constraint = angle_constraint; + Point2fVector_Construct(&o->joints, + 16); // Assumed to be >= 2, otherwise it wouldn't be much of a chain + FloatVector_Construct(&o->angles, 16); - int i = 1; - for (; i < joint_count; i++) { - Point2fVector_PushBack(&o->joints, Vector2f_Add(Point2fVector_At(&o->joints, i - 1), (Vector2f){0, o->link_size})); + Point2fVector_PushBack(&o->joints, origin); FloatVector_PushBack(&o->angles, 0.f); - } + + int i = 1; + for (; i < joint_count; i++) { + Point2fVector_PushBack(&o->joints, Vector2f_Add(Point2fVector_At(&o->joints, i - 1), + (Vector2f){0, o->link_size})); + FloatVector_PushBack(&o->angles, 0.f); + } } -void Chain_Destruct(Chain *o) +void Chain_Destruct(Chain* o) { - Point2fVector_Destruct(&o->joints); - FloatVector_Destruct(&o->angles); + Point2fVector_Destruct(&o->joints); + FloatVector_Destruct(&o->angles); } -/* -void Chain_Resolve(Chain *o, Point2f pos) { - angles.set(0, Vector2f_Sub(pos, joints.get(0)).heading()); - joints.set(0, pos); - for (int i = 1; i < joints.size(); i++) { - float curAngle = PVector.sub(joints.get(i - 1), joints.get(i)).heading(); - angles.set(i, constrainAngle(curAngle, angles.get(i - 1), angleConstraint)); - joints.set(i, PVector.sub(joints.get(i - 1), PVector.fromAngle(angles.get(i)).setMag(linkSize))); - } +void Chain_Resolve(Chain* o, Point2f pos) +{ + Vector_Set(&o->angles, 0, Vector2f_Heading(Vector2f_Sub(pos, Vector_At(&o->joints, 0)))); + Vector_Set(&o->joints, 0, pos); + + int i = 1; + for (; i < Vector_Size(&o->joints); i++) { + float cur_angle = + Vechtor2f_Heading(Vector2f_Sub(Vector_At(&o->joints, i - 1), Vector_At(&o->joints, i))); + Vector_Set(&o->angles, i, + constrainAngle(cur_angle, Vector_At(&o->angles, i - 1), o->angle_constraint)); + Vector_Set(&o->joints, i, + Vector2f_Sub(Vector_At(&o->joints, i - 1), + Vector2f_FromAngle(Vector_At(&o->angles., i)).setMag(linkSize))); + } } +/* void Chain_FabrikResolve(Chain *o, PVector pos, PVector anchor) { // Forward pass joints.set(0, pos); @@ -145,55 +162,52 @@ void display() { */ /* Chain */ -void Scene1(swwWindow *o) { - UserData *ud = swwWindow_GetUserData(o); +void Scene1(swwWindow* o) +{ + UserData* ud = swwWindow_GetUserData(o); - int h = ud->h; - int w = ud->w; + int h = ud->h; + int w = ud->w; } -int main() { - const uint32_t w = 512; - const uint32_t h = 512; - swwWindowCallback callback = {OnKey, OnButton, OnScroll}; - swwFpsHelper fps; - swwRateHelper rh; - - swwApp_Initialize(); - - UserData ud = {w, - h, - 0, - NULL, - {Scene1}}; - - swwWindow *window = swwWindow_Create("SWW Proc Animation", w, h); - ud.renderer = swwRenderer_CreateAttachWindow(window, kSoftwareRenderer); - swwWindow_SetUserData(window, &ud); - - swwWindow_SetCallback(window, &callback); - swwRenderer_EnablePerfMonitor(ud.renderer, 1); - swwFpsHelper_Construct(&fps, 1.f); - - swwRateHelper_Construct(&rh, 30.f); - while (!swwApp_ShouldExit()) { - swwRenderer_ClearWhite(ud.renderer); - ud.fs[ud.scene](window); - swwRenderer_Present(ud.renderer); - - swwApp_PollEvent(); - swwRateHelper_Sleep(&rh); - - if (swwFpsHelper_Update(&fps, ud.renderer)) { - printf("FPS: %s \r", swwFpsHelper_Get(&fps)); - fflush(stdout); +int main() +{ + const uint32_t w = 512; + const uint32_t h = 512; + swwWindowCallback callback = {OnKey, OnButton, OnScroll}; + swwFpsHelper fps; + swwRateHelper rh; + + swwApp_Initialize(); + + UserData ud = {w, h, 0, NULL, {Scene1}}; + + swwWindow* window = swwWindow_Create("SWW Proc Animation", w, h); + ud.renderer = swwRenderer_CreateAttachWindow(window, kSoftwareRenderer); + swwWindow_SetUserData(window, &ud); + + swwWindow_SetCallback(window, &callback); + swwRenderer_EnablePerfMonitor(ud.renderer, 1); + swwFpsHelper_Construct(&fps, 1.f); + + swwRateHelper_Construct(&rh, 30.f); + while (!swwApp_ShouldExit()) { + swwRenderer_ClearWhite(ud.renderer); + ud.fs[ud.scene](window); + swwRenderer_Present(ud.renderer); + + swwApp_PollEvent(); + swwRateHelper_Sleep(&rh); + + if (swwFpsHelper_Update(&fps, ud.renderer)) { + printf("FPS: %s \r", swwFpsHelper_Get(&fps)); + fflush(stdout); + } } - } - swwRenderer_Destroy(ud.renderer); - swwWindow_Destroy(window); - swwApp_Cleanup(); + swwRenderer_Destroy(ud.renderer); + swwWindow_Destroy(window); + swwApp_Cleanup(); - return 0; + return 0; } -