base_math refactor progress
This commit is contained in:
parent
a844aaa225
commit
b61cf28266
2
build.c
2
build.c
@ -625,7 +625,7 @@ void OnBuild(StringList cli_args)
|
|||||||
{
|
{
|
||||||
if (arg_msvc)
|
if (arg_msvc)
|
||||||
{
|
{
|
||||||
StringListAppend(&perm, &compile_args, Lit("/O2"));
|
StringListAppend(&perm, &compile_args, Lit("/O2 /GL "));
|
||||||
StringListAppend(&perm, &link_args, Lit("/LTCG"));
|
StringListAppend(&perm, &link_args, Lit("/LTCG"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -45,7 +45,7 @@ internal P_WindowSettings default_window_settings(P_Window *window)
|
|||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
|
|
||||||
V2 monitor_size = P_GetWindowMonitorSize(window);
|
Vec2 monitor_size = P_GetWindowMonitorSize(window);
|
||||||
|
|
||||||
i32 width = 1280;
|
i32 width = 1280;
|
||||||
i32 height = math_round_to_int(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT));
|
i32 height = math_round_to_int(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT));
|
||||||
|
|||||||
@ -960,8 +960,8 @@ Ase_DecodedSheet ase_decode_sheet(Arena *arena, String encoded)
|
|||||||
/* Assert all data was read */
|
/* Assert all data was read */
|
||||||
Assert(BB_NumBytesRemaining(&br) == 0);
|
Assert(BB_NumBytesRemaining(&br) == 0);
|
||||||
|
|
||||||
res.image_size = V2FromXY(image_width, image_height);
|
res.image_size = V2(image_width, image_height);
|
||||||
res.frame_size = V2FromXY(frame_width, frame_height);
|
res.frame_size = V2(frame_width, frame_height);
|
||||||
res.num_frames = num_frames;
|
res.num_frames = num_frames;
|
||||||
res.num_spans = num_spans;
|
res.num_spans = num_spans;
|
||||||
res.num_slice_keys = num_slice_keys;
|
res.num_slice_keys = num_slice_keys;
|
||||||
|
|||||||
@ -51,8 +51,8 @@ Struct(Ase_DecodedImage) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Struct(Ase_DecodedSheet) {
|
Struct(Ase_DecodedSheet) {
|
||||||
V2 image_size;
|
Vec2 image_size;
|
||||||
V2 frame_size;
|
Vec2 frame_size;
|
||||||
u32 num_frames;
|
u32 num_frames;
|
||||||
u32 num_spans;
|
u32 num_spans;
|
||||||
u32 num_slice_keys;
|
u32 num_slice_keys;
|
||||||
|
|||||||
@ -366,11 +366,11 @@ typedef i32 b32;
|
|||||||
|
|
||||||
Global const u32 _f32_infinity_u32 = 0x7f800000;
|
Global const u32 _f32_infinity_u32 = 0x7f800000;
|
||||||
Global const f32 *_f32_infinity = (f32 *)&_f32_infinity_u32;
|
Global const f32 *_f32_infinity = (f32 *)&_f32_infinity_u32;
|
||||||
#define F32_INFINITY (*_f32_infinity)
|
#define F32Infinity (*_f32_infinity)
|
||||||
|
|
||||||
Global const u64 _f64_infinity_u64 = 0x7ff0000000000000ULL;
|
Global const u64 _f64_infinity_u64 = 0x7ff0000000000000ULL;
|
||||||
Global const f64 *_f64_infinity = (f64 *)&_f64_infinity_u64;
|
Global const f64 *_f64_infinity = (f64 *)&_f64_infinity_u64;
|
||||||
#define F64_INFINITY (*_f64_infinity)
|
#define F64Infinity (*_f64_infinity)
|
||||||
|
|
||||||
Global const u32 _f32_nan_u32 = 0x7f800001;
|
Global const u32 _f32_nan_u32 = 0x7f800001;
|
||||||
Global const f32 *_f32_nan = (f32 *)&_f32_nan_u32;
|
Global const f32 *_f32_nan = (f32 *)&_f32_nan_u32;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -6,124 +6,102 @@
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Floating point vector2 types
|
//~ Floating point vector2 types
|
||||||
|
|
||||||
#define V2FromXY(x, y) CppCompatInitListType(V2) { (x), (y) }
|
Struct(Vec2) {
|
||||||
#define V2FromV2I32(v) V2FromXY((v).x, (v).y)
|
|
||||||
Struct(V2) {
|
|
||||||
f32 x, y;
|
f32 x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(V2Array) {
|
Struct(V2Array) {
|
||||||
V2 *points;
|
Vec2 *points;
|
||||||
u64 count;
|
u64 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Floating point vector3 types
|
//~ Floating point vector3 types
|
||||||
|
|
||||||
#define V3FromXYZ(x, y, z) ((V3) { (x), (y), (z) })
|
Struct(Vec3) {
|
||||||
Struct(V3) {
|
|
||||||
f32 x, y, z;
|
f32 x, y, z;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(V3Array) {
|
Struct(V3Array) {
|
||||||
V3 *points;
|
Vec3 *points;
|
||||||
u64 count;
|
u64 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Floating point vector4 types
|
//~ Floating point vector4 types
|
||||||
|
|
||||||
#define V4FromXYZW(x, y, z, w) ((V4) { (x), (y), (z), (w) })
|
Struct(Vec4) {
|
||||||
Struct(V4) {
|
|
||||||
f32 x, y, z, w;
|
f32 x, y, z, w;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(V4Array) {
|
Struct(V4Array) {
|
||||||
V4 *points;
|
Vec4 *points;
|
||||||
u64 count;
|
u64 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Integer vector2 types
|
//~ Integer vec2 types
|
||||||
|
|
||||||
#define V2I32FromXY(x, y) CppCompatInitListType(V2I32) { (x), (y) }
|
Struct(Vec2I32) {
|
||||||
Struct(V2I32) {
|
|
||||||
i32 x, y;
|
i32 x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Integer vector3 types
|
//~ Integer vector3 types
|
||||||
|
|
||||||
#define V3I32FromXYZ(x, y, z) CppCompatInitListType(V3I32) { (x), (y), (z) }
|
Struct(Vec3I32) {
|
||||||
Struct(V3I32) {
|
|
||||||
i32 x, y, z;
|
i32 x, y, z;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//~ Mat4x4 types
|
|
||||||
|
|
||||||
Struct(Mat4x4)
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct { V4 bx, by, bz, bw; };
|
|
||||||
f32 e[4][4];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Xform types
|
//~ Xform types
|
||||||
|
|
||||||
Struct(Xform) {
|
Struct(Xform)
|
||||||
V2 bx; /* X basis vector (x axis) */
|
{
|
||||||
V2 by; /* Y basis vector (y axis)*/
|
Vec2 bx; /* X basis vector (x axis) */
|
||||||
V2 og; /* Translation vector (origin) */
|
Vec2 by; /* Y basis vector (y axis)*/
|
||||||
|
Vec2 og; /* Translation vector (origin) */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* (T)ranslation, (R)otation, (S)cale */
|
/* (T)ranslation, (R)otation, (S)cale */
|
||||||
#define MakeTrs(...) ((Trs) { .t = V2FromXY(0,0), .s = V2FromXY(1, 1), .r = 0, __VA_ARGS__ })
|
|
||||||
Struct(Trs)
|
Struct(Trs)
|
||||||
{
|
{
|
||||||
V2 t;
|
Vec2 t;
|
||||||
V2 s;
|
Vec2 s;
|
||||||
f32 r;
|
f32 r;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Rect types
|
//~ Rect types
|
||||||
|
|
||||||
#define RectFromScalar(_x, _y, _width, _height) (Rect) { .x = (_x), .y = (_y), .width = (_width), .height = (_height) }
|
|
||||||
#define RectFromV2(_pos, _size) (Rect) { .pos = (_pos), .size = (_size) }
|
|
||||||
Struct(Rect) {
|
Struct(Rect) {
|
||||||
union {
|
union {
|
||||||
struct { f32 x, y, width, height; };
|
struct { f32 x, y, width, height; };
|
||||||
struct { V2 pos, size; };
|
struct { Vec2 pos, size; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Values expected to be normalized 0.0 -> 1.0 */
|
/* Values expected to be normalized 0.0 -> 1.0 */
|
||||||
#define ClipAll ((ClipRect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } })
|
|
||||||
Struct(ClipRect)
|
Struct(ClipRect)
|
||||||
{
|
{
|
||||||
V2 p0, p1;
|
Vec2 p0, p1;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Axis aligned bounding box types
|
//~ Axis aligned bounding box types
|
||||||
|
|
||||||
Struct(Aabb) {
|
Struct(Aabb) {
|
||||||
V2 p0, p1;
|
Vec2 p0, p1;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Quad types
|
//~ Quad types
|
||||||
|
|
||||||
#define QuadUnitSquare (Quad) { .p0 = V2FromXY(0, 0), .p1 = V2FromXY(0, 1), .p2 = V2FromXY(1, 1), .p3 = V2FromXY(1, 0) }
|
|
||||||
#define QuadUnitSquareCentered (Quad) { .p0 = V2FromXY(-0.5f, -0.5f), .p1 = V2FromXY(0.5f, -0.5f), .p2 = V2FromXY(0.5f, 0.5f), .p3 = V2FromXY(-0.5f, 0.5f) }
|
|
||||||
Struct(Quad) {
|
Struct(Quad) {
|
||||||
union {
|
union {
|
||||||
struct { V2 p0, p1, p2, p3; };
|
struct { Vec2 p0, p1, p2, p3; };
|
||||||
struct { V2 e[4]; };
|
struct { Vec2 e[4]; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -138,57 +116,70 @@ Struct(SoftSpring)
|
|||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Clamping
|
//~ Mat4x4 types
|
||||||
|
|
||||||
u8 min_u8(u8 a, u8 b);
|
Struct(Mat4x4)
|
||||||
u8 max_u8(u8 a, u8 b);
|
{
|
||||||
u32 min_u32(u32 a, u32 b);
|
union
|
||||||
u32 max_u32(u32 a, u32 b);
|
{
|
||||||
u64 min_u64(u64 a, u64 b);
|
struct { Vec4 bx, by, bz, bw; };
|
||||||
u64 max_u64(u64 a, u64 b);
|
f32 e[4][4];
|
||||||
i32 min_i32(i32 a, i32 b);
|
};
|
||||||
i32 max_i32(i32 a, i32 b);
|
};
|
||||||
i64 min_i64(i64 a, i64 b);
|
|
||||||
i64 max_i64(i64 a, i64 b);
|
|
||||||
f32 min_f32(f32 a, f32 b);
|
|
||||||
f32 max_f32(f32 a, f32 b);
|
|
||||||
f64 min_f64(f64 a, f64 b);
|
|
||||||
f64 max_f64(f64 a, f64 b);
|
|
||||||
|
|
||||||
u32 clamp_u32(u32 v, u32 min, u32 max);
|
|
||||||
u64 clamp_u64(u64 v, u64 min, u64 max);
|
|
||||||
i32 clamp_i32(i32 v, i32 min, i32 max);
|
|
||||||
i64 clamp_i64(i64 v, i64 min, i64 max);
|
|
||||||
f32 clamp_f32(f32 v, f32 min, f32 max);
|
|
||||||
f64 clamp_f64(f64 v, f64 min, f64 max);
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Rounding
|
//~ Min / max
|
||||||
|
|
||||||
|
//- Min
|
||||||
|
u8 MinU8(u8 a, u8 b);
|
||||||
|
i8 MinI8(i8 a, i8 b);
|
||||||
|
u32 MinU32(u32 a, u32 b);
|
||||||
|
i32 MinI32(i32 a, i32 b);
|
||||||
|
f32 MinF32(f32 a, f32 b);
|
||||||
|
u64 MinU64(u64 a, u64 b);
|
||||||
|
i64 MinI64(i64 a, i64 b);
|
||||||
|
f64 MinF64(f64 a, f64 b);
|
||||||
|
|
||||||
|
//- Max
|
||||||
|
u8 MaxU8(u8 a, u8 b);
|
||||||
|
i8 MaxI8(i8 a, i8 b);
|
||||||
|
u32 MaxU32(u32 a, u32 b);
|
||||||
|
i32 MaxI32(i32 a, i32 b);
|
||||||
|
f32 MaxF32(f32 a, f32 b);
|
||||||
|
u64 MaxU64(u64 a, u64 b);
|
||||||
|
i64 MaxI64(i64 a, i64 b);
|
||||||
|
f64 MaxF64(f64 a, f64 b);
|
||||||
|
|
||||||
|
//- Clamp
|
||||||
|
u32 ClampU32(u32 v, u32 min, u32 max);
|
||||||
|
i32 ClampI32(i32 v, i32 min, i32 max);
|
||||||
|
f32 ClampF32(f32 v, f32 min, f32 max);
|
||||||
|
u64 ClampU64(u64 v, u64 min, u64 max);
|
||||||
|
i64 ClampI64(i64 v, i64 min, i64 max);
|
||||||
|
f64 ClampF64(f64 v, f64 min, f64 max);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Rounding ops
|
||||||
|
|
||||||
|
//- Round
|
||||||
f32 math_round(f32 f);
|
f32 math_round(f32 f);
|
||||||
f64 math_round64(f64 f);
|
f64 math_round64(f64 f);
|
||||||
i32 math_round_to_int(f32 f);
|
i32 math_round_to_int(f32 f);
|
||||||
i64 math_round_to_int64(f64 f);
|
i64 math_round_to_int64(f64 f);
|
||||||
|
|
||||||
////////////////////////////////
|
//- Floor
|
||||||
//~ Flooring
|
|
||||||
|
|
||||||
f32 math_floor(f32 f);
|
f32 math_floor(f32 f);
|
||||||
f64 math_floor64(f64 f);
|
f64 math_floor64(f64 f);
|
||||||
i32 math_floor_to_int(f32 f);
|
i32 math_floor_to_int(f32 f);
|
||||||
i64 math_floor_to_int64(f64 f);
|
i64 math_floor_to_int64(f64 f);
|
||||||
|
|
||||||
////////////////////////////////
|
//- Ceil
|
||||||
//~ Ceiling
|
|
||||||
|
|
||||||
f32 math_ceil(f32 f);
|
f32 math_ceil(f32 f);
|
||||||
f64 math_ceil64(f64 f);
|
f64 math_ceil64(f64 f);
|
||||||
i32 math_ceil_to_int(f32 f);
|
i32 math_ceil_to_int(f32 f);
|
||||||
i64 math_ceil_to_int64(f64 f);
|
i64 math_ceil_to_int64(f64 f);
|
||||||
|
|
||||||
////////////////////////////////
|
//- Trunc
|
||||||
//~ Truncing
|
|
||||||
|
|
||||||
f32 math_trunc(f32 f);
|
f32 math_trunc(f32 f);
|
||||||
f64 math_trunc64(f64 f);
|
f64 math_trunc64(f64 f);
|
||||||
|
|
||||||
@ -207,39 +198,18 @@ i32 math_fsign(f32 f);
|
|||||||
i64 math_fsign64(f64 f);
|
i64 math_fsign64(f64 f);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Integer bs
|
//~ Integer sign
|
||||||
|
|
||||||
u32 math_abs_i32(i32 v);
|
u32 math_abs_i32(i32 v);
|
||||||
u64 math_abs_i64(i64 v);
|
u64 math_abs_i64(i64 v);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ U64 pow
|
//~ Exponential ops
|
||||||
|
|
||||||
/* Taken from https://gist.github.com/orlp/3551590 */
|
|
||||||
u64 math_pow_u64(u64 base, u8 exp);
|
u64 math_pow_u64(u64 base, u8 exp);
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//~ Logn
|
|
||||||
|
|
||||||
/* Based on FreeBSD's implementation
|
|
||||||
* https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_logf.c */
|
|
||||||
f32 math_ln(f32 x);
|
f32 math_ln(f32 x);
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//~ Exp
|
|
||||||
|
|
||||||
/* Based on FreeBSD's implementation
|
|
||||||
* https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_expf.c */
|
|
||||||
f32 math_exp(f32 x);
|
f32 math_exp(f32 x);
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//~ Pow
|
|
||||||
|
|
||||||
f32 math_pow(f32 a, f32 b);
|
f32 math_pow(f32 a, f32 b);
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//~ Sqrt
|
|
||||||
|
|
||||||
f32 math_sqrt(f32 x);
|
f32 math_sqrt(f32 x);
|
||||||
f64 math_sqrt64(f64 x);
|
f64 math_sqrt64(f64 x);
|
||||||
f32 math_rsqrt(f32 x);
|
f32 math_rsqrt(f32 x);
|
||||||
@ -247,44 +217,14 @@ f32 math_rsqrt(f32 x);
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Trig
|
//~ Trig
|
||||||
|
|
||||||
/* Functions based on Cephes implementation (https://www.netlib.org/cephes/):
|
|
||||||
* - math_sin_approx
|
|
||||||
* - math_cos_approx
|
|
||||||
* - math_reduce_positive_to_pio4
|
|
||||||
* - math_atan
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* TODO: Vectorize */
|
|
||||||
|
|
||||||
//- Reduce
|
|
||||||
/* Reduce postive x to range [0, Pi/4] (Cody-Waite argument reduction).
|
|
||||||
* Returns 0 if x > (2^24 - 1);
|
|
||||||
* Sets octant_out=-1 on error. */
|
|
||||||
f32 math_reduce_positive_to_pio4(f32 x, i32 *octant_out);
|
f32 math_reduce_positive_to_pio4(f32 x, i32 *octant_out);
|
||||||
|
|
||||||
//- Sin approximation
|
|
||||||
/* Approximate sin in range [0, Pi/4] */
|
|
||||||
f32 math_sin_approx(f32 x);
|
f32 math_sin_approx(f32 x);
|
||||||
|
|
||||||
//- Cos approximation
|
|
||||||
f32 math_cos_approx(f32 x);
|
f32 math_cos_approx(f32 x);
|
||||||
|
|
||||||
//- Sin
|
|
||||||
f32 math_sin(f32 x);
|
f32 math_sin(f32 x);
|
||||||
|
|
||||||
//- Cos
|
|
||||||
f32 math_cos(f32 x);
|
f32 math_cos(f32 x);
|
||||||
|
|
||||||
//- ArcTan
|
|
||||||
f32 math_atan(f32 x);
|
f32 math_atan(f32 x);
|
||||||
|
|
||||||
//- ArcTan2
|
|
||||||
f32 math_atan2(f32 y, f32 x);
|
f32 math_atan2(f32 y, f32 x);
|
||||||
|
|
||||||
//- ArcSin
|
|
||||||
f32 math_asin(f32 x);
|
f32 math_asin(f32 x);
|
||||||
|
|
||||||
//- ArcCos
|
|
||||||
f32 math_acos(f32 x);
|
f32 math_acos(f32 x);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
@ -304,166 +244,162 @@ f32 math_lerp_angle(f32 a, f32 b, f32 t);
|
|||||||
//~ Int lerp
|
//~ Int lerp
|
||||||
|
|
||||||
i32 math_lerp_i32(i32 val0, i32 val1, f32 t);
|
i32 math_lerp_i32(i32 val0, i32 val1, f32 t);
|
||||||
|
|
||||||
//- Lerp i64
|
|
||||||
i64 math_lerp_i64(i64 val0, i64 val1, f64 t);
|
i64 math_lerp_i64(i64 val0, i64 val1, f64 t);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ V2 operations
|
//~ Vec2 operations
|
||||||
|
|
||||||
b32 v2_is_zero(V2 a);
|
#define V2(x, y) CppCompatInitListType(Vec2) { (x), (y) }
|
||||||
b32 v2_eq(V2 a, V2 b);
|
#define V2FromV2I32(v) V2((v).x, (v).y)
|
||||||
|
|
||||||
|
b32 v2_is_zero(Vec2 a);
|
||||||
|
b32 v2_eq(Vec2 a, Vec2 b);
|
||||||
|
|
||||||
//- Mul
|
//- Mul
|
||||||
|
Vec2 v2_mul(Vec2 a, f32 s);
|
||||||
V2 v2_mul(V2 a, f32 s);
|
Vec2 v2_mul_v2(Vec2 a, Vec2 b);
|
||||||
V2 v2_mul_v2(V2 a, V2 b);
|
Vec2 v2_neg(Vec2 a);
|
||||||
V2 v2_neg(V2 a);
|
|
||||||
|
|
||||||
//- Div
|
//- Div
|
||||||
|
Vec2 v2_div(Vec2 a, f32 s);
|
||||||
V2 v2_div(V2 a, f32 s);
|
Vec2 v2_div_v2(Vec2 a, Vec2 b);
|
||||||
V2 v2_div_v2(V2 a, V2 b);
|
|
||||||
|
|
||||||
//- Add
|
//- Add
|
||||||
|
Vec2 v2_add(Vec2 a, Vec2 b);
|
||||||
V2 v2_add(V2 a, V2 b);
|
Vec2 v2_sub(Vec2 a, Vec2 b);
|
||||||
V2 v2_sub(V2 a, V2 b);
|
|
||||||
|
|
||||||
//- Len
|
//- Len
|
||||||
|
f32 v2_len(Vec2 a);
|
||||||
f32 v2_len(V2 a);
|
f32 v2_len_sq(Vec2 a);
|
||||||
f32 v2_len_sq(V2 a);
|
Vec2 v2_with_len(Vec2 a, f32 len);
|
||||||
V2 v2_with_len(V2 a, f32 len);
|
Vec2 v2_clamp_len(Vec2 a, f32 max);
|
||||||
V2 v2_clamp_len(V2 a, f32 max);
|
f32 v2_distance(Vec2 a, Vec2 b);
|
||||||
f32 v2_distance(V2 a, V2 b);
|
Vec2 v2_norm(Vec2 a);
|
||||||
V2 v2_norm(V2 a);
|
|
||||||
|
|
||||||
|
|
||||||
//- Dot
|
//- Dot
|
||||||
|
f32 v2_dot(Vec2 a, Vec2 b);
|
||||||
f32 v2_dot(V2 a, V2 b);
|
f32 v2_wedge(Vec2 a, Vec2 b);
|
||||||
|
Vec2 v2_perp(Vec2 a);
|
||||||
/* Returns signed area between vectors (positive in clockwise direction)
|
Vec2 v2_perp_mul(Vec2 a, f32 s);
|
||||||
* AKA perpendicular dot product
|
Vec2 v2_perp_towards_dir(Vec2 v, Vec2 dir);
|
||||||
* AKA 2d cross-product */
|
|
||||||
f32 v2_wedge(V2 a, V2 b);
|
|
||||||
|
|
||||||
/* Clockwise (right) perpendicular vector */
|
|
||||||
V2 v2_perp(V2 a);
|
|
||||||
|
|
||||||
/* Clockwise (right) perpendicular vector scaled by s */
|
|
||||||
V2 v2_perp_mul(V2 a, f32 s);
|
|
||||||
|
|
||||||
V2 v2_perp_towards_dir(V2 v, V2 dir);
|
|
||||||
|
|
||||||
//- Round / floor / ceil
|
//- Round / floor / ceil
|
||||||
|
Vec2 v2_round(Vec2 a);
|
||||||
V2 v2_round(V2 a);
|
Vec2I32 v2_round_to_int(Vec2 a);
|
||||||
V2I32 v2_round_to_int(V2 a);
|
Vec2 v2_floor(Vec2 a);
|
||||||
V2 v2_floor(V2 a);
|
Vec2 v2_ceil(Vec2 a);
|
||||||
V2 v2_ceil(V2 a);
|
|
||||||
|
|
||||||
//- Angle
|
//- Angle
|
||||||
|
i32 v2_winding(Vec2 a, Vec2 b);
|
||||||
/* Returns 1 if winding between vectors a & b is clockwise or straight, -1 if counter-clockwise */
|
Vec2 v2_rotated(Vec2 v, f32 a);
|
||||||
i32 v2_winding(V2 a, V2 b);
|
Vec2 v2_from_angle(f32 a);
|
||||||
V2 v2_rotated(V2 v, f32 a);
|
f32 v2_angle(Vec2 v);
|
||||||
V2 v2_from_angle(f32 a);
|
f32 v2_angle_from_dirs(Vec2 dir1, Vec2 dir2);
|
||||||
f32 v2_angle(V2 v);
|
f32 v2_angle_from_points(Vec2 pt1, Vec2 pt2);
|
||||||
f32 v2_angle_from_dirs(V2 dir1, V2 dir2);
|
|
||||||
f32 v2_angle_from_points(V2 pt1, V2 pt2);
|
|
||||||
|
|
||||||
//- Closest point
|
//- Closest point
|
||||||
|
Vec2 v2_closest_point_ray(Vec2 ray_pos, Vec2 ray_dir_norm, Vec2 p);
|
||||||
V2 v2_closest_point_ray(V2 ray_pos, V2 ray_dir_norm, V2 p);
|
|
||||||
|
|
||||||
//- Lerp
|
//- Lerp
|
||||||
|
Vec2 v2_lerp(Vec2 val0, Vec2 val1, f32 t);
|
||||||
/* Interpolate position vectors */
|
Vec2 v2_slerp(Vec2 val0, Vec2 val1, f32 t);
|
||||||
V2 v2_lerp(V2 val0, V2 val1, f32 t);
|
|
||||||
|
|
||||||
/* Interpolate direction vectors (spherical lerp) */
|
|
||||||
V2 v2_slerp(V2 val0, V2 val1, f32 t);
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ V2I32 Operations
|
//~ Vec3 operations
|
||||||
|
|
||||||
b32 v2i32_eq(V2I32 a, V2I32 b);
|
#define V3(x, y, z) ((Vec3) { (x), (y), (z) })
|
||||||
V2I32 v2i32_neg(V2I32 a);
|
|
||||||
V2I32 v2i32_add(V2I32 a, V2I32 b);
|
|
||||||
V2I32 v2i32_sub(V2I32 a, V2I32 b);
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Mat4x4 operations
|
//~ Vec4 operations
|
||||||
|
|
||||||
Mat4x4 mat4x4_from_xform(Xform xf);
|
#define V4(x, y, z, w) ((Vec4) { (x), (y), (z), (w) })
|
||||||
Mat4x4 mat4x4_from_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near_z, f32 far_z);
|
|
||||||
Mat4x4 mat4x4_mul(Mat4x4 m1, Mat4x4 m2);
|
////////////////////////////////
|
||||||
|
//~ Vec2I32 Operations
|
||||||
|
|
||||||
|
#define V2I32(x, y) CppCompatInitListType(Vec2I32) { (x), (y) }
|
||||||
|
b32 v2i32_eq(Vec2I32 a, Vec2I32 b);
|
||||||
|
Vec2I32 v2i32_neg(Vec2I32 a);
|
||||||
|
Vec2I32 v2i32_add(Vec2I32 a, Vec2I32 b);
|
||||||
|
Vec2I32 v2i32_sub(Vec2I32 a, Vec2I32 b);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Vec3I32 operations
|
||||||
|
|
||||||
|
#define V3I32(x, y, z) CppCompatInitListType(Vec3I32) { (x), (y), (z) }
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Xform operations
|
//~ Xform operations
|
||||||
|
|
||||||
/* Construct identity xform */
|
b32 XformEq(Xform xf1, Xform xf2);
|
||||||
#define XFORM_IDENT CppCompatInitListType(Xform) { .bx = V2FromXY(1, 0), .by = V2FromXY(0, 1) }
|
|
||||||
#define XFORM_IDENT_NOCAST { .bx = V2FromXY(1, 0), .by = V2FromXY(0, 1) }
|
|
||||||
|
|
||||||
#define XFORM_POS(p) CppCompatInitListType(Xform) { .bx = V2FromXY(1, 0), .by = V2FromXY(0, 1), .og = (p) }
|
//- Initialization
|
||||||
|
#define XformIdentity CppCompatInitListType(Xform) { .bx = V2(1, 0), .by = V2(0, 1) }
|
||||||
|
#define XformIdentityNoCast { .bx = V2(1, 0), .by = V2(0, 1) }
|
||||||
|
Xform XformFromPos(Vec2 v);
|
||||||
|
Xform XformFromRot(f32 r);
|
||||||
|
Xform XformFromScale(Vec2 scale);
|
||||||
|
Xform XformFromTrs(Trs trs);
|
||||||
|
Xform XformFromRect(Rect rect);
|
||||||
|
|
||||||
/* Takes a translation, rotation, and scale as optional parameters for constructing an xform */
|
//- Translation
|
||||||
#define XFORM_TRS(...) xform_from_trs((Trs) { .t = V2FromXY(0,0), .s = V2FromXY(1, 1), .r = 0, __VA_ARGS__ })
|
Xform TranslateXform(Xform xf, Vec2 v);
|
||||||
|
Xform WorldTranslateXform(Xform xf, Vec2 v);
|
||||||
|
|
||||||
Xform xform_mul(Xform a, Xform b);;
|
//- Rotation
|
||||||
Xform xform_rotated(Xform xf, f32 angle);;
|
Xform RotateXform(Xform xf, f32 r);
|
||||||
Xform xform_scaled(Xform xf, V2 v);;
|
Xform WorldRotateXform(Xform xf, f32 r);
|
||||||
V2 xform_basis_mul_v2(Xform xf, V2 v);;
|
Xform WorldRotateXformBasis(Xform xf, f32 r);
|
||||||
V2 xform_mul_v2(Xform xf, V2 v);;
|
Xform XformWIthWorldRotation(Xform xf, f32 r);
|
||||||
f32 xform_get_determinant(Xform xf);;
|
|
||||||
V2 xform_get_scale(Xform xf);;
|
|
||||||
f32 xform_get_rotation(Xform xf);;
|
|
||||||
|
|
||||||
b32 xform_eq(Xform xf1, Xform xf2);
|
//- Scale
|
||||||
|
Xform ScaleXform(Xform xf, Vec2 scale);
|
||||||
|
Xform WorldScaleXform(Xform xf, Vec2 scale);
|
||||||
|
|
||||||
Xform xform_from_pos(V2 v);
|
//- Lerp
|
||||||
Xform xform_from_rotation(f32 r);
|
Xform LerpXform(Xform a, Xform b, f32 t);
|
||||||
Xform xform_from_scale(V2 scale);
|
|
||||||
Xform xform_from_trs(Trs trs);
|
|
||||||
Xform xform_from_rect(Rect rect);
|
|
||||||
Xform xform_translated(Xform xf, V2 v);
|
|
||||||
Xform xform_translated_world(Xform xf, V2 v);
|
|
||||||
Xform xform_rotated(Xform xf, f32 r);
|
|
||||||
Xform xform_rotated_world(Xform xf, f32 r);
|
|
||||||
Xform xform_basis_rotated_world(Xform xf, f32 r);
|
|
||||||
Xform xform_basis_with_rotation_world(Xform xf, f32 r);
|
|
||||||
Xform xform_scaled(Xform xf, V2 scale);
|
|
||||||
Xform xform_scaled_world(Xform xf, V2 scale);
|
|
||||||
Xform xform_lerp(Xform a, Xform b, f32 t);
|
|
||||||
Xform xform_invert(Xform xf);
|
|
||||||
Xform xform_mul(Xform a, Xform b);
|
|
||||||
V2 xform_basis_mul_v2(Xform xf, V2 v);
|
|
||||||
V2 xform_mul_v2(Xform xf, V2 v);
|
|
||||||
Xform xform_basis(Xform xf);
|
|
||||||
V2 xform_basis_invert_mul_v2(Xform xf, V2 v);
|
|
||||||
|
|
||||||
/* TODO: Get rid of this? Just force caller to use invert manually since it's expensive. */
|
//- Invert
|
||||||
V2 xform_invert_mul_v2(Xform xf, V2 v);
|
Xform InvertXform(Xform xf);
|
||||||
|
|
||||||
Quad xform_mul_quad(Xform xf, Quad quad);
|
//- Mul
|
||||||
f32 xform_get_determinant(Xform xf);
|
Vec2 MulXformV2(Xform xf, Vec2 v);
|
||||||
V2 xform_get_right(Xform xf);
|
Xform MulXform(Xform a, Xform b);
|
||||||
V2 xform_get_left(Xform xf);
|
Quad MulXformQuad(Xform xf, Quad quad);
|
||||||
V2 xform_get_up(Xform xf);
|
Vec2 MulXformBasisV2(Xform xf, Vec2 v);
|
||||||
V2 xform_get_down(Xform xf);
|
Vec2 InvertXformMulV2(Xform xf, Vec2 v);
|
||||||
f32 xform_get_rotation(Xform xf);
|
Vec2 InvertXformBasisMulV2(Xform xf, Vec2 v);
|
||||||
V2 xform_get_scale(Xform xf);
|
|
||||||
|
//- Helpers
|
||||||
|
Xform GetXformBasis(Xform xf);
|
||||||
|
f32 GetXformDeterminant(Xform xf);
|
||||||
|
Vec2 GetXformRight(Xform xf);
|
||||||
|
Vec2 GetXformLeft(Xform xf);
|
||||||
|
Vec2 GetXformUp(Xform xf);
|
||||||
|
Vec2 GetXformDown(Xform xf);
|
||||||
|
f32 GetXformRotation(Xform xf);
|
||||||
|
Vec2 GetXformScale(Xform xf);
|
||||||
|
|
||||||
|
//- Trs
|
||||||
|
#define TRS(...) ((Trs) { .t = V2(0,0), .s = V2(1, 1), .r = 0, __VA_ARGS__ })
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Rect operations
|
||||||
|
|
||||||
|
#define RectFromScalar(_x, _y, _width, _height) (Rect) { .x = (_x), .y = (_y), .width = (_width), .height = (_height) }
|
||||||
|
#define RectFromV2(_pos, _size) (Rect) { .pos = (_pos), .size = (_size) }
|
||||||
|
#define ClipAll ((ClipRect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } })
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Quad operations
|
//~ Quad operations
|
||||||
|
|
||||||
|
#define QuadUnitSquare (Quad) { .p0 = V2(0, 0), .p1 = V2(0, 1), .p2 = V2(1, 1), .p3 = V2(1, 0) }
|
||||||
|
#define QuadUnitSquareCentered (Quad) { .p0 = V2(-0.5f, -0.5f), .p1 = V2(0.5f, -0.5f), .p2 = V2(0.5f, 0.5f), .p3 = V2(-0.5f, 0.5f) }
|
||||||
|
|
||||||
Quad quad_from_rect(Rect rect);
|
Quad quad_from_rect(Rect rect);
|
||||||
Quad quad_from_aabb(Aabb aabb);
|
Quad quad_from_aabb(Aabb aabb);
|
||||||
Quad quad_from_line(V2 start, V2 end, f32 thickness);
|
Quad quad_from_line(Vec2 start, Vec2 end, f32 thickness);
|
||||||
Quad quad_from_ray(V2 pos, V2 rel, f32 thickness);
|
Quad quad_from_ray(Vec2 pos, Vec2 rel, f32 thickness);
|
||||||
Quad quad_scale(Quad q, f32 s);
|
Quad quad_scale(Quad q, f32 s);
|
||||||
Quad quad_round(Quad quad);
|
Quad quad_round(Quad quad);
|
||||||
Quad quad_floor(Quad quad);
|
Quad quad_floor(Quad quad);
|
||||||
@ -471,9 +407,16 @@ Quad quad_floor(Quad quad);
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Polygon operations
|
//~ Polygon operations
|
||||||
|
|
||||||
V2 math_poly_center(V2Array a);
|
Vec2 math_poly_center(V2Array a);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Spring operations
|
//~ Spring operations
|
||||||
|
|
||||||
SoftSpring math_spring_init(f32 hertz, f32 damping_ratio, f32 dt);
|
SoftSpring math_spring_init(f32 hertz, f32 damping_ratio, f32 dt);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Mat4x4 operations
|
||||||
|
|
||||||
|
Mat4x4 mat4x4_from_xform(Xform xf);
|
||||||
|
Mat4x4 mat4x4_from_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near_z, f32 far_z);
|
||||||
|
Mat4x4 mat4x4_mul(Mat4x4 m1, Mat4x4 m2);
|
||||||
|
|||||||
@ -97,9 +97,9 @@ String string_from_float(Arena *arena, f64 f, u32 precision)
|
|||||||
|
|
||||||
if (IsF32Nan(f)) {
|
if (IsF32Nan(f)) {
|
||||||
final_len += string_copy(arena, LIT("NaN")).len;
|
final_len += string_copy(arena, LIT("NaN")).len;
|
||||||
} else if (f == F64_INFINITY) {
|
} else if (f == F64Infinity) {
|
||||||
final_len += string_copy(arena, LIT("inf")).len;
|
final_len += string_copy(arena, LIT("inf")).len;
|
||||||
} else if (f == -F64_INFINITY) {
|
} else if (f == -F64Infinity) {
|
||||||
final_len += string_copy(arena, LIT("-inf")).len;
|
final_len += string_copy(arena, LIT("-inf")).len;
|
||||||
} else {
|
} else {
|
||||||
if (f < 0) {
|
if (f < 0) {
|
||||||
@ -190,7 +190,7 @@ String string_copy(Arena *arena, String src)
|
|||||||
String string_copy_to_string(String dst, String src)
|
String string_copy_to_string(String dst, String src)
|
||||||
{
|
{
|
||||||
String res = ZI;
|
String res = ZI;
|
||||||
res.len = min_u64(dst.len, src.len);
|
res.len = MinU64(dst.len, src.len);
|
||||||
res.text = dst.text;
|
res.text = dst.text;
|
||||||
MEMCPY(res.text, src.text, res.len);
|
MEMCPY(res.text, src.text, res.len);
|
||||||
return res;
|
return res;
|
||||||
@ -229,7 +229,7 @@ StringArray string_split(Arena *arena, String str, String delim)
|
|||||||
for (i64 i = 0; i < (i64)str.len - (i64)delim.len; ++i) {
|
for (i64 i = 0; i < (i64)str.len - (i64)delim.len; ++i) {
|
||||||
String cmp = ZI;
|
String cmp = ZI;
|
||||||
cmp.text = &str.text[i];
|
cmp.text = &str.text[i];
|
||||||
cmp.len = min_i64(str.len - i, delim.len);
|
cmp.len = MinI64(str.len - i, delim.len);
|
||||||
|
|
||||||
b32 is_delimiter = string_eq(cmp, delim);
|
b32 is_delimiter = string_eq(cmp, delim);
|
||||||
if (is_delimiter) {
|
if (is_delimiter) {
|
||||||
@ -321,7 +321,7 @@ b32 string_eq(String str1, String str2)
|
|||||||
i32 string_cmp(String str1, String str2)
|
i32 string_cmp(String str1, String str2)
|
||||||
{
|
{
|
||||||
i32 res = 0;
|
i32 res = 0;
|
||||||
for (u64 i = 0; i < min_u64(str1.len, str2.len); ++i) {
|
for (u64 i = 0; i < MinU64(str1.len, str2.len); ++i) {
|
||||||
res = str1.text[i] - str2.text[i];
|
res = str1.text[i] - str2.text[i];
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
break;
|
break;
|
||||||
@ -699,7 +699,7 @@ char *cstr_from_string(Arena *arena, String src)
|
|||||||
char *cstr_buff_from_string(String dst_buff, String src)
|
char *cstr_buff_from_string(String dst_buff, String src)
|
||||||
{
|
{
|
||||||
if (dst_buff.len > 0) {
|
if (dst_buff.len > 0) {
|
||||||
u64 len = min_u64(src.len, dst_buff.len - 1);
|
u64 len = MinU64(src.len, dst_buff.len - 1);
|
||||||
MEMCPY(dst_buff.text, src.text, len);
|
MEMCPY(dst_buff.text, src.text, len);
|
||||||
dst_buff.text[len] = 0;
|
dst_buff.text[len] = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -120,7 +120,7 @@ Inline Dict *dict_init(Arena *arena, u64 bins_count)
|
|||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
Dict *dict = PushStruct(arena, Dict);
|
Dict *dict = PushStruct(arena, Dict);
|
||||||
dict->bins_count = max_u64(bins_count, 1); /* Ensure at least 1 bin */
|
dict->bins_count = MaxU64(bins_count, 1); /* Ensure at least 1 bin */
|
||||||
dict->bins = PushArray(arena, DictBin, dict->bins_count);
|
dict->bins = PushArray(arena, DictBin, dict->bins_count);
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -156,7 +156,7 @@ void BB_WriteUBitsNoMagic(BB_Writer *bw, u64 value, u8 num_bits)
|
|||||||
{
|
{
|
||||||
/* Write unaligned bits */
|
/* Write unaligned bits */
|
||||||
u8 *at = bw->base + (bw->cur_bit >> 3);
|
u8 *at = bw->base + (bw->cur_bit >> 3);
|
||||||
u8 num_mix_bits = min_u8((8 - offset), num_bits);
|
u8 num_mix_bits = MinU8((8 - offset), num_bits);
|
||||||
u8 mix_byte = (u8)((value & ((1 << num_mix_bits) - 1)) << offset);
|
u8 mix_byte = (u8)((value & ((1 << num_mix_bits) - 1)) << offset);
|
||||||
*at |= mix_byte;
|
*at |= mix_byte;
|
||||||
value >>= num_mix_bits;
|
value >>= num_mix_bits;
|
||||||
@ -240,7 +240,7 @@ void BB_WriteIV(BB_Writer *bw, i64 value)
|
|||||||
num_bits += 7;
|
num_bits += 7;
|
||||||
unsigned_value >>= 7;
|
unsigned_value >>= 7;
|
||||||
}
|
}
|
||||||
num_bits = min_u8(num_bits, 64);
|
num_bits = MinU8(num_bits, 64);
|
||||||
tc = BB_TwosComplimentFromUint(-value, num_bits);
|
tc = BB_TwosComplimentFromUint(-value, num_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +458,7 @@ u64 BB_ReadUBitsNoMagic(BB_Reader *br, u8 num_bits)
|
|||||||
if (offset)
|
if (offset)
|
||||||
{
|
{
|
||||||
u8 *at = br->base + (br->cur_bit >> 3);
|
u8 *at = br->base + (br->cur_bit >> 3);
|
||||||
num_trailing_bits = min_u8(8 - offset, num_bits);
|
num_trailing_bits = MinU8(8 - offset, num_bits);
|
||||||
u8 mix_byte = *at;
|
u8 mix_byte = *at;
|
||||||
mix_byte >>= offset;
|
mix_byte >>= offset;
|
||||||
mix_byte &= (1 << num_trailing_bits) - 1;
|
mix_byte &= (1 << num_trailing_bits) - 1;
|
||||||
@ -550,7 +550,7 @@ i64 BB_ReadIV(BB_Reader *br)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
num_bits = min_u8(num_bits, 64);
|
num_bits = MinU8(num_bits, 64);
|
||||||
|
|
||||||
i64 res;
|
i64 res;
|
||||||
if (sign_bit)
|
if (sign_bit)
|
||||||
|
|||||||
@ -26,28 +26,28 @@ internal void _dbgbreakable(void)
|
|||||||
#define DBGSTEP
|
#define DBGSTEP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
internal CLD_SupportPoint collider_get_support_point_internal(CLD_Shape *shape, Xform xf, V2 dir, i32 ignore)
|
internal CLD_SupportPoint collider_get_support_point_internal(CLD_Shape *shape, Xform xf, Vec2 dir, i32 ignore)
|
||||||
{
|
{
|
||||||
V2 *points = shape->points;
|
Vec2 *points = shape->points;
|
||||||
u32 count = shape->count;
|
u32 count = shape->count;
|
||||||
f32 radius = shape->radius;
|
f32 radius = shape->radius;
|
||||||
|
|
||||||
dir = v2_rotated(dir, -xform_get_rotation(xf));
|
dir = v2_rotated(dir, -GetXformRotation(xf));
|
||||||
dir = v2_mul_v2(dir, xform_get_scale(xf));
|
dir = v2_mul_v2(dir, GetXformScale(xf));
|
||||||
|
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
/* Skip 'ignore' on single point colliders */
|
/* Skip 'ignore' on single point colliders */
|
||||||
ignore = -1;
|
ignore = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2 furthest = ZI;
|
Vec2 furthest = ZI;
|
||||||
u32 furthest_index = 0;
|
u32 furthest_index = 0;
|
||||||
f32 furthest_dot = -F32_INFINITY;
|
f32 furthest_dot = -F32Infinity;
|
||||||
for (u32 i = 0; i < count; ++i) {
|
for (u32 i = 0; i < count; ++i) {
|
||||||
if ((i32)i == ignore) {
|
if ((i32)i == ignore) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
V2 p = points[i];
|
Vec2 p = points[i];
|
||||||
f32 dot = v2_dot(dir, p);
|
f32 dot = v2_dot(dir, p);
|
||||||
if (dot > furthest_dot) {
|
if (dot > furthest_dot) {
|
||||||
furthest = p;
|
furthest = p;
|
||||||
@ -61,7 +61,7 @@ internal CLD_SupportPoint collider_get_support_point_internal(CLD_Shape *shape,
|
|||||||
furthest = v2_add(furthest, dir);
|
furthest = v2_add(furthest, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
furthest = xform_mul_v2(xf, furthest);
|
furthest = MulXformV2(xf, furthest);
|
||||||
|
|
||||||
CLD_SupportPoint res;
|
CLD_SupportPoint res;
|
||||||
res.p = furthest;
|
res.p = furthest;
|
||||||
@ -81,12 +81,12 @@ CLD_Shape collider_from_quad(Quad quad)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLD_SupportPoint collider_get_support_point(CLD_Shape *shape, Xform xf, V2 dir)
|
CLD_SupportPoint collider_get_support_point(CLD_Shape *shape, Xform xf, Vec2 dir)
|
||||||
{
|
{
|
||||||
return collider_get_support_point_internal(shape, xf, dir, -1);
|
return collider_get_support_point_internal(shape, xf, dir, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal CLD_MenkowskiPoint get_menkowski_point(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, V2 dir)
|
internal CLD_MenkowskiPoint get_menkowski_point(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, Vec2 dir)
|
||||||
{
|
{
|
||||||
CLD_MenkowskiPoint res;
|
CLD_MenkowskiPoint res;
|
||||||
res.s0 = collider_get_support_point(shape0, xf0, dir);
|
res.s0 = collider_get_support_point(shape0, xf0, dir);
|
||||||
@ -102,20 +102,20 @@ internal CLD_MenkowskiPoint get_menkowski_point(CLD_Shape *shape0, CLD_Shape *sh
|
|||||||
Aabb collider_aabb_from_collider(CLD_Shape *shape, Xform xf)
|
Aabb collider_aabb_from_collider(CLD_Shape *shape, Xform xf)
|
||||||
{
|
{
|
||||||
Aabb res;
|
Aabb res;
|
||||||
res.p0.x = collider_get_support_point(shape, xf, V2FromXY(-1, 0)).p.x - COLLISION_TOLERANCE;
|
res.p0.x = collider_get_support_point(shape, xf, V2(-1, 0)).p.x - COLLISION_TOLERANCE;
|
||||||
res.p0.y = collider_get_support_point(shape, xf, V2FromXY(0, -1)).p.y - COLLISION_TOLERANCE;
|
res.p0.y = collider_get_support_point(shape, xf, V2(0, -1)).p.y - COLLISION_TOLERANCE;
|
||||||
res.p1.x = collider_get_support_point(shape, xf, V2FromXY(1, 0)).p.x + COLLISION_TOLERANCE;
|
res.p1.x = collider_get_support_point(shape, xf, V2(1, 0)).p.x + COLLISION_TOLERANCE;
|
||||||
res.p1.y = collider_get_support_point(shape, xf, V2FromXY(0, 1)).p.y + COLLISION_TOLERANCE;
|
res.p1.y = collider_get_support_point(shape, xf, V2(0, 1)).p.y + COLLISION_TOLERANCE;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Aabb collider_aabb_from_combined_aabb(Aabb b0, Aabb b1)
|
Aabb collider_aabb_from_combined_aabb(Aabb b0, Aabb b1)
|
||||||
{
|
{
|
||||||
Aabb res;
|
Aabb res;
|
||||||
res.p0.x = min_f32(min_f32(b0.p0.x, b0.p1.x), min_f32(b1.p0.x, b1.p1.x));
|
res.p0.x = MinF32(MinF32(b0.p0.x, b0.p1.x), MinF32(b1.p0.x, b1.p1.x));
|
||||||
res.p0.y = min_f32(min_f32(b0.p0.y, b0.p1.y), min_f32(b1.p0.y, b1.p1.y));
|
res.p0.y = MinF32(MinF32(b0.p0.y, b0.p1.y), MinF32(b1.p0.y, b1.p1.y));
|
||||||
res.p1.x = max_f32(max_f32(b0.p0.x, b0.p1.x), max_f32(b1.p0.x, b1.p1.x));
|
res.p1.x = MaxF32(MaxF32(b0.p0.x, b0.p1.x), MaxF32(b1.p0.x, b1.p1.x));
|
||||||
res.p1.y = max_f32(max_f32(b0.p0.y, b0.p1.y), max_f32(b1.p0.y, b1.p1.y));
|
res.p1.y = MaxF32(MaxF32(b0.p0.y, b0.p1.y), MaxF32(b1.p0.y, b1.p1.y));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ b32 collider_test_aabb(Aabb box0, Aabb box1)
|
|||||||
|
|
||||||
struct gjk_result {
|
struct gjk_result {
|
||||||
CLD_MenkowskiSimplex simplex;
|
CLD_MenkowskiSimplex simplex;
|
||||||
V2 final_dir;
|
Vec2 final_dir;
|
||||||
|
|
||||||
/* If 1, simplex represents triangle inside of menkowski difference
|
/* If 1, simplex represents triangle inside of menkowski difference
|
||||||
* encapsulating the origin. If 0, simplex represents the closest
|
* encapsulating the origin. If 0, simplex represents the closest
|
||||||
@ -163,17 +163,17 @@ internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1,
|
|||||||
{
|
{
|
||||||
b32 overlapping = 0;
|
b32 overlapping = 0;
|
||||||
CLD_MenkowskiSimplex s = ZI;
|
CLD_MenkowskiSimplex s = ZI;
|
||||||
V2 dir = ZI;
|
Vec2 dir = ZI;
|
||||||
CLD_MenkowskiPoint m = ZI;
|
CLD_MenkowskiPoint m = ZI;
|
||||||
|
|
||||||
/* First point is support point in shape's general directions to eachother */
|
/* First point is support point in shape's general directions to eachother */
|
||||||
dir = v2_sub(xf1.og, xf0.og);
|
dir = v2_sub(xf1.og, xf0.og);
|
||||||
if (v2_is_zero(dir)) dir = V2FromXY(1, 0);
|
if (v2_is_zero(dir)) dir = V2(1, 0);
|
||||||
s.a = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
s.a = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||||
s.len = 1;
|
s.len = 1;
|
||||||
|
|
||||||
V2 removed_a = ZI;
|
Vec2 removed_a = ZI;
|
||||||
V2 removed_b = ZI;
|
Vec2 removed_b = ZI;
|
||||||
u32 num_removed = 0;
|
u32 num_removed = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (s.len == 1) {
|
if (s.len == 1) {
|
||||||
@ -226,13 +226,13 @@ internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1,
|
|||||||
|
|
||||||
/* Determine region of the simplex in which the origin lies */
|
/* Determine region of the simplex in which the origin lies */
|
||||||
DBGSTEP;
|
DBGSTEP;
|
||||||
V2 vab = v2_sub(s.b.p, s.a.p);
|
Vec2 vab = v2_sub(s.b.p, s.a.p);
|
||||||
V2 vac = v2_sub(s.c.p, s.a.p);
|
Vec2 vac = v2_sub(s.c.p, s.a.p);
|
||||||
V2 vbc = v2_sub(s.c.p, s.b.p);
|
Vec2 vbc = v2_sub(s.c.p, s.b.p);
|
||||||
|
|
||||||
V2 rab_dir = v2_perp_towards_dir(vab, v2_neg(vac));
|
Vec2 rab_dir = v2_perp_towards_dir(vab, v2_neg(vac));
|
||||||
V2 rac_dir = v2_perp_towards_dir(vac, v2_neg(vab));
|
Vec2 rac_dir = v2_perp_towards_dir(vac, v2_neg(vab));
|
||||||
V2 rbc_dir = v2_perp_towards_dir(vbc, vab);
|
Vec2 rbc_dir = v2_perp_towards_dir(vbc, vab);
|
||||||
|
|
||||||
f32 rab_dot = v2_dot(rab_dir, v2_neg(s.a.p));
|
f32 rab_dot = v2_dot(rab_dir, v2_neg(s.a.p));
|
||||||
f32 rac_dot = v2_dot(rac_dir, v2_neg(s.a.p));
|
f32 rac_dot = v2_dot(rac_dir, v2_neg(s.a.p));
|
||||||
@ -313,7 +313,7 @@ internal struct gjk_result gjk_get_simplex(CLD_Shape *shape0, CLD_Shape *shape1,
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct epa_result {
|
struct epa_result {
|
||||||
V2 normal;
|
Vec2 normal;
|
||||||
CLD_MenkowskiFeature closest_feature; /* Represents closest feature (edge or point) to origin on menkowski difference */
|
CLD_MenkowskiFeature closest_feature; /* Represents closest feature (edge or point) to origin on menkowski difference */
|
||||||
|
|
||||||
#if COLLIDER_DEBUG
|
#if COLLIDER_DEBUG
|
||||||
@ -331,7 +331,7 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
|||||||
TempArena scratch = BeginScratchNoConflict();
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
|
|
||||||
CLD_MenkowskiFeature closest_feature = ZI;
|
CLD_MenkowskiFeature closest_feature = ZI;
|
||||||
V2 normal = ZI;
|
Vec2 normal = ZI;
|
||||||
|
|
||||||
CLD_MenkowskiPoint *proto = 0;
|
CLD_MenkowskiPoint *proto = 0;
|
||||||
u32 proto_count = 0;
|
u32 proto_count = 0;
|
||||||
@ -355,7 +355,7 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
|||||||
|
|
||||||
/* Find dir from origin to closest edge */
|
/* Find dir from origin to closest edge */
|
||||||
/* FIXME: Winding order of ps & pe index */
|
/* FIXME: Winding order of ps & pe index */
|
||||||
f32 closest_len_sq = F32_INFINITY;
|
f32 closest_len_sq = F32Infinity;
|
||||||
CLD_MenkowskiPoint closest_a = ZI;
|
CLD_MenkowskiPoint closest_a = ZI;
|
||||||
CLD_MenkowskiPoint closest_b = ZI;
|
CLD_MenkowskiPoint closest_b = ZI;
|
||||||
u32 closest_b_index = 0;
|
u32 closest_b_index = 0;
|
||||||
@ -365,11 +365,11 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
|||||||
CLD_MenkowskiPoint a = proto[a_index];
|
CLD_MenkowskiPoint a = proto[a_index];
|
||||||
CLD_MenkowskiPoint b = proto[b_index];
|
CLD_MenkowskiPoint b = proto[b_index];
|
||||||
|
|
||||||
V2 vab = v2_sub(b.p, a.p);
|
Vec2 vab = v2_sub(b.p, a.p);
|
||||||
V2 vao = v2_neg(a.p);
|
Vec2 vao = v2_neg(a.p);
|
||||||
|
|
||||||
f32 proj_ratio = clamp_f32(v2_dot(vao, vab) / v2_len_sq(vab), 0, 1);
|
f32 proj_ratio = ClampF32(v2_dot(vao, vab) / v2_len_sq(vab), 0, 1);
|
||||||
V2 proj = v2_add(a.p, v2_mul(vab, proj_ratio));
|
Vec2 proj = v2_add(a.p, v2_mul(vab, proj_ratio));
|
||||||
|
|
||||||
f32 proj_len_sq = v2_len_sq(proj);
|
f32 proj_len_sq = v2_len_sq(proj);
|
||||||
if (proj_len_sq < closest_len_sq - min_unique_pt_dist_sq) {
|
if (proj_len_sq < closest_len_sq - min_unique_pt_dist_sq) {
|
||||||
@ -379,10 +379,10 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
|||||||
closest_len_sq = proj_len_sq;
|
closest_len_sq = proj_len_sq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
V2 vab = v2_sub(closest_b.p, closest_a.p);
|
Vec2 vab = v2_sub(closest_b.p, closest_a.p);
|
||||||
|
|
||||||
/* Find new point in dir */
|
/* Find new point in dir */
|
||||||
V2 dir = v2_mul(v2_perp(vab), winding);
|
Vec2 dir = v2_mul(v2_perp(vab), winding);
|
||||||
CLD_MenkowskiPoint m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
CLD_MenkowskiPoint m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||||
|
|
||||||
#if COLLIDER_DEBUG
|
#if COLLIDER_DEBUG
|
||||||
@ -406,8 +406,8 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
|||||||
//const f32 validity_epsilon = 0.00000000001f; /* Arbitrary */
|
//const f32 validity_epsilon = 0.00000000001f; /* Arbitrary */
|
||||||
const f32 validity_epsilon = min_unique_pt_dist_sq; /* Arbitrary */
|
const f32 validity_epsilon = min_unique_pt_dist_sq; /* Arbitrary */
|
||||||
|
|
||||||
V2 vam = v2_sub(m.p, closest_a.p);
|
Vec2 vam = v2_sub(m.p, closest_a.p);
|
||||||
V2 vbm = v2_sub(closest_b.p, closest_a.p);
|
Vec2 vbm = v2_sub(closest_b.p, closest_a.p);
|
||||||
|
|
||||||
f32 dot = v2_dot(vab, vam) / v2_len_sq(vab);
|
f32 dot = v2_dot(vab, vam) / v2_len_sq(vab);
|
||||||
|
|
||||||
@ -461,7 +461,7 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
|||||||
|
|
||||||
#if COLLIDER_DEBUG
|
#if COLLIDER_DEBUG
|
||||||
res.dbg_step = dbg_step;
|
res.dbg_step = dbg_step;
|
||||||
u32 len = min_u32(proto_count, countof(res.prototype.points));
|
u32 len = MinU32(proto_count, countof(res.prototype.points));
|
||||||
for (u32 i = 0; i < len; ++i) {
|
for (u32 i = 0; i < len; ++i) {
|
||||||
res.prototype.points[i] = proto[i].p;
|
res.prototype.points[i] = proto[i].p;
|
||||||
}
|
}
|
||||||
@ -477,16 +477,16 @@ internal struct epa_result epa_get_normal_from_gjk(CLD_Shape *shape0, CLD_Shape
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct clip_line_to_line_result {
|
struct clip_line_to_line_result {
|
||||||
V2 a0_clipped, b0_clipped;
|
Vec2 a0_clipped, b0_clipped;
|
||||||
V2 a1_clipped, b1_clipped;
|
Vec2 a1_clipped, b1_clipped;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal struct clip_line_to_line_result clip_line_to_line(V2 a0, V2 b0, V2 a1, V2 b1, V2 normal)
|
internal struct clip_line_to_line_result clip_line_to_line(Vec2 a0, Vec2 b0, Vec2 a1, Vec2 b1, Vec2 normal)
|
||||||
{
|
{
|
||||||
V2 vab0 = v2_sub(b0, a0);
|
Vec2 vab0 = v2_sub(b0, a0);
|
||||||
V2 vab1 = v2_sub(b1, a1);
|
Vec2 vab1 = v2_sub(b1, a1);
|
||||||
V2 va0a1 = v2_sub(a1, a0);
|
Vec2 va0a1 = v2_sub(a1, a0);
|
||||||
V2 vb0b1 = v2_sub(b1, b0);
|
Vec2 vb0b1 = v2_sub(b1, b0);
|
||||||
f32 vab0_w = v2_wedge(vab0, normal);
|
f32 vab0_w = v2_wedge(vab0, normal);
|
||||||
f32 vab1_w = v2_wedge(vab1, normal);
|
f32 vab1_w = v2_wedge(vab1, normal);
|
||||||
f32 va0a1_w = v2_wedge(va0a1, normal);
|
f32 va0a1_w = v2_wedge(va0a1, normal);
|
||||||
@ -497,15 +497,15 @@ internal struct clip_line_to_line_result clip_line_to_line(V2 a0, V2 b0, V2 a1,
|
|||||||
f32 b0t;
|
f32 b0t;
|
||||||
{
|
{
|
||||||
f32 w = 1 / vab0_w;
|
f32 w = 1 / vab0_w;
|
||||||
a0t = clamp_f32(va0a1_w * w, 0, 1);
|
a0t = ClampF32(va0a1_w * w, 0, 1);
|
||||||
b0t = clamp_f32(vb0b1_w * -w, 0, 1);
|
b0t = ClampF32(vb0b1_w * -w, 0, 1);
|
||||||
}
|
}
|
||||||
f32 a1t;
|
f32 a1t;
|
||||||
f32 b1t;
|
f32 b1t;
|
||||||
{
|
{
|
||||||
f32 w = 1 / vab1_w;
|
f32 w = 1 / vab1_w;
|
||||||
a1t = clamp_f32(-va0a1_w * w, 0, 1);
|
a1t = ClampF32(-va0a1_w * w, 0, 1);
|
||||||
b1t = clamp_f32(-vb0b1_w * -w, 0, 1);
|
b1t = ClampF32(-vb0b1_w * -w, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct clip_line_to_line_result res;
|
struct clip_line_to_line_result res;
|
||||||
@ -516,10 +516,10 @@ internal struct clip_line_to_line_result clip_line_to_line(V2 a0, V2 b0, V2 a1,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal V2 clip_point_to_line(V2 a, V2 b, V2 p, V2 normal)
|
internal Vec2 clip_point_to_line(Vec2 a, Vec2 b, Vec2 p, Vec2 normal)
|
||||||
{
|
{
|
||||||
V2 vab = v2_sub(b, a);
|
Vec2 vab = v2_sub(b, a);
|
||||||
V2 vap = v2_sub(p, a);
|
Vec2 vap = v2_sub(p, a);
|
||||||
|
|
||||||
f32 vab_w = v2_wedge(vab, normal);
|
f32 vab_w = v2_wedge(vab, normal);
|
||||||
f32 vap_w = v2_wedge(vap, normal);
|
f32 vap_w = v2_wedge(vap, normal);
|
||||||
@ -527,10 +527,10 @@ internal V2 clip_point_to_line(V2 a, V2 b, V2 p, V2 normal)
|
|||||||
f32 t;
|
f32 t;
|
||||||
{
|
{
|
||||||
f32 w = 1 / vab_w;
|
f32 w = 1 / vab_w;
|
||||||
t = clamp_f32(vap_w * w, 0, 1);
|
t = ClampF32(vap_w * w, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
V2 res = v2_add(a, v2_mul(vab, t));
|
Vec2 res = v2_add(a, v2_mul(vab, t));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,7 +549,7 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
|||||||
CLD_CollisionPoint points[2] = ZI;
|
CLD_CollisionPoint points[2] = ZI;
|
||||||
u32 num_points = 0;
|
u32 num_points = 0;
|
||||||
b32 colliding = 0;
|
b32 colliding = 0;
|
||||||
V2 normal = ZI;
|
Vec2 normal = ZI;
|
||||||
|
|
||||||
#if COLLIDER_DEBUG
|
#if COLLIDER_DEBUG
|
||||||
u32 dbg_step = 0;
|
u32 dbg_step = 0;
|
||||||
@ -584,17 +584,17 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
|||||||
CLD_MenkowskiFeature f = epa_res.closest_feature;
|
CLD_MenkowskiFeature f = epa_res.closest_feature;
|
||||||
/* Shapes not overlapping, determine if distance between shapes within tolerance */
|
/* Shapes not overlapping, determine if distance between shapes within tolerance */
|
||||||
if (f.len == 1) {
|
if (f.len == 1) {
|
||||||
V2 p = v2_neg(f.a.p);
|
Vec2 p = v2_neg(f.a.p);
|
||||||
if (v2_len_sq(p) <= (tolerance * tolerance)) {
|
if (v2_len_sq(p) <= (tolerance * tolerance)) {
|
||||||
colliding = 1;
|
colliding = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Project origin to determine if distance is within tolerance. */
|
/* Project origin to determine if distance is within tolerance. */
|
||||||
Assert(f.len == 2);
|
Assert(f.len == 2);
|
||||||
V2 vab = v2_sub(f.b.p, f.a.p);
|
Vec2 vab = v2_sub(f.b.p, f.a.p);
|
||||||
V2 vao = v2_neg(f.a.p);
|
Vec2 vao = v2_neg(f.a.p);
|
||||||
f32 ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
|
f32 ratio = ClampF32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
|
||||||
V2 p = v2_add(f.a.p, v2_mul(vab, ratio));
|
Vec2 p = v2_add(f.a.p, v2_mul(vab, ratio));
|
||||||
if (v2_len_sq(p) <= (tolerance * tolerance)) {
|
if (v2_len_sq(p) <= (tolerance * tolerance)) {
|
||||||
colliding = 1;
|
colliding = 1;
|
||||||
}
|
}
|
||||||
@ -641,10 +641,10 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
|||||||
b1 = a1;
|
b1 = a1;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2 vab0 = v2_sub(b0.p, a0.p);
|
Vec2 vab0 = v2_sub(b0.p, a0.p);
|
||||||
V2 vab1 = v2_sub(b1.p, a1.p);
|
Vec2 vab1 = v2_sub(b1.p, a1.p);
|
||||||
V2 vab0_norm = v2_norm(vab0);
|
Vec2 vab0_norm = v2_norm(vab0);
|
||||||
V2 vab1_norm = v2_norm(vab1);
|
Vec2 vab1_norm = v2_norm(vab1);
|
||||||
|
|
||||||
/* Swap points based on normal direction for consistent clipping */
|
/* Swap points based on normal direction for consistent clipping */
|
||||||
if (v2_wedge(normal, vab0) < 0) {
|
if (v2_wedge(normal, vab0) < 0) {
|
||||||
@ -683,29 +683,29 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 a_sep = F32_INFINITY;
|
f32 a_sep = F32Infinity;
|
||||||
f32 b_sep = F32_INFINITY;
|
f32 b_sep = F32Infinity;
|
||||||
V2 a_midpoint = ZI;
|
Vec2 a_midpoint = ZI;
|
||||||
V2 b_midpoint = ZI;
|
Vec2 b_midpoint = ZI;
|
||||||
b32 ignore_a = 1;
|
b32 ignore_a = 1;
|
||||||
b32 ignore_b = 1;
|
b32 ignore_b = 1;
|
||||||
if (!collapse0 && !collapse1) {
|
if (!collapse0 && !collapse1) {
|
||||||
/* Clip line to line */
|
/* Clip line to line */
|
||||||
struct clip_line_to_line_result clip_res = clip_line_to_line(a0.p, b0.p, a1.p, b1.p, normal);
|
struct clip_line_to_line_result clip_res = clip_line_to_line(a0.p, b0.p, a1.p, b1.p, normal);
|
||||||
V2 a0_clipped = clip_res.a0_clipped;
|
Vec2 a0_clipped = clip_res.a0_clipped;
|
||||||
V2 a1_clipped = clip_res.a1_clipped;
|
Vec2 a1_clipped = clip_res.a1_clipped;
|
||||||
V2 b0_clipped = clip_res.b0_clipped;
|
Vec2 b0_clipped = clip_res.b0_clipped;
|
||||||
V2 b1_clipped = clip_res.b1_clipped;
|
Vec2 b1_clipped = clip_res.b1_clipped;
|
||||||
/* Calc midpoint between clipped a & b */
|
/* Calc midpoint between clipped a & b */
|
||||||
V2 va0a1_clipped = v2_sub(a1_clipped, a0_clipped);
|
Vec2 va0a1_clipped = v2_sub(a1_clipped, a0_clipped);
|
||||||
V2 vb0b1_clipped = v2_sub(b1_clipped, b0_clipped);
|
Vec2 vb0b1_clipped = v2_sub(b1_clipped, b0_clipped);
|
||||||
a_sep = v2_dot(va0a1_clipped, normal);
|
a_sep = v2_dot(va0a1_clipped, normal);
|
||||||
b_sep = v2_dot(vb0b1_clipped, normal);
|
b_sep = v2_dot(vb0b1_clipped, normal);
|
||||||
a_midpoint = v2_add(a0_clipped, v2_mul(va0a1_clipped, 0.5f));
|
a_midpoint = v2_add(a0_clipped, v2_mul(va0a1_clipped, 0.5f));
|
||||||
b_midpoint = v2_add(b0_clipped, v2_mul(vb0b1_clipped, 0.5f));
|
b_midpoint = v2_add(b0_clipped, v2_mul(vb0b1_clipped, 0.5f));
|
||||||
ignore_a = 0;
|
ignore_a = 0;
|
||||||
ignore_b = 0;
|
ignore_b = 0;
|
||||||
V2 vfin = v2_sub(b_midpoint, a_midpoint);
|
Vec2 vfin = v2_sub(b_midpoint, a_midpoint);
|
||||||
if (v2_len_sq(vfin) < (0.005 * 0.005)) {
|
if (v2_len_sq(vfin) < (0.005 * 0.005)) {
|
||||||
if (a_sep > b_sep) {
|
if (a_sep > b_sep) {
|
||||||
ignore_a = 1;
|
ignore_a = 1;
|
||||||
@ -718,8 +718,8 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
|||||||
res.b0_clipped = b0_clipped;
|
res.b0_clipped = b0_clipped;
|
||||||
res.b1_clipped = b1_clipped;
|
res.b1_clipped = b1_clipped;
|
||||||
} else {
|
} else {
|
||||||
V2 p0 = a0.p;
|
Vec2 p0 = a0.p;
|
||||||
V2 p1 = a1.p;
|
Vec2 p1 = a1.p;
|
||||||
/* TODO: Choose ID based on closest clipped point */
|
/* TODO: Choose ID based on closest clipped point */
|
||||||
if (collapse1 && !collapse0) {
|
if (collapse1 && !collapse0) {
|
||||||
/* Project a1 onto vab0 */
|
/* Project a1 onto vab0 */
|
||||||
@ -730,7 +730,7 @@ CLD_CollisionResult collider_collision_points(CLD_Shape *shape0, CLD_Shape *shap
|
|||||||
p1 = clip_point_to_line(a1.p, b1.p, a0.p, normal);
|
p1 = clip_point_to_line(a1.p, b1.p, a0.p, normal);
|
||||||
}
|
}
|
||||||
/* Calc midpoint */
|
/* Calc midpoint */
|
||||||
V2 vsep = v2_sub(p1, p0);
|
Vec2 vsep = v2_sub(p1, p0);
|
||||||
a_midpoint = v2_add(p0, v2_mul(vsep, 0.5f));
|
a_midpoint = v2_add(p0, v2_mul(vsep, 0.5f));
|
||||||
a_sep = v2_dot(normal, p1) - v2_dot(normal, p0);
|
a_sep = v2_dot(normal, p1) - v2_dot(normal, p0);
|
||||||
ignore_a = 0;
|
ignore_a = 0;
|
||||||
@ -789,8 +789,8 @@ CLD_ClosestResult collider_closest_points(CLD_Shape *shape0, CLD_Shape *shape1,
|
|||||||
const f32 min_unique_pt_dist_sq = MIN_UNIQUE_PT_DIST_SQ;
|
const f32 min_unique_pt_dist_sq = MIN_UNIQUE_PT_DIST_SQ;
|
||||||
const u32 max_epa_iterations = MAX_EPA_ITERATIONS;
|
const u32 max_epa_iterations = MAX_EPA_ITERATIONS;
|
||||||
|
|
||||||
V2 p0 = ZI;
|
Vec2 p0 = ZI;
|
||||||
V2 p1 = ZI;
|
Vec2 p1 = ZI;
|
||||||
b32 colliding = 0;
|
b32 colliding = 0;
|
||||||
|
|
||||||
#if COLLIDER_DEBUG
|
#if COLLIDER_DEBUG
|
||||||
@ -834,9 +834,9 @@ CLD_ClosestResult collider_closest_points(CLD_Shape *shape0, CLD_Shape *shape1,
|
|||||||
f32 ratio;
|
f32 ratio;
|
||||||
{
|
{
|
||||||
/* Determine ratio between edge a & b that projected origin lies */
|
/* Determine ratio between edge a & b that projected origin lies */
|
||||||
V2 vab = v2_sub(f.b.p, f.a.p);
|
Vec2 vab = v2_sub(f.b.p, f.a.p);
|
||||||
V2 vao = v2_neg(f.a.p);
|
Vec2 vao = v2_neg(f.a.p);
|
||||||
ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
|
ratio = ClampF32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
|
||||||
}
|
}
|
||||||
/* Shape 0 */
|
/* Shape 0 */
|
||||||
p0 = v2_sub(f.b.s0.p, f.a.s0.p);
|
p0 = v2_sub(f.b.s0.p, f.a.s0.p);
|
||||||
@ -879,11 +879,11 @@ f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
|
|||||||
f32 t0_sep = 0;
|
f32 t0_sep = 0;
|
||||||
f32 t1_sep = 0;
|
f32 t1_sep = 0;
|
||||||
f32 t = 0;
|
f32 t = 0;
|
||||||
f32 t_sep = F32_INFINITY;
|
f32 t_sep = F32Infinity;
|
||||||
|
|
||||||
/* Find direction p0 -> p1 at t=0 */
|
/* Find direction p0 -> p1 at t=0 */
|
||||||
V2 dir;
|
Vec2 dir;
|
||||||
V2 dir_neg;
|
Vec2 dir_neg;
|
||||||
{
|
{
|
||||||
CLD_ClosestResult closest_points_res = collider_closest_points(c0, c1, xf0_t0, xf1_t0);
|
CLD_ClosestResult closest_points_res = collider_closest_points(c0, c1, xf0_t0, xf1_t0);
|
||||||
if (closest_points_res.colliding) {
|
if (closest_points_res.colliding) {
|
||||||
@ -897,8 +897,8 @@ f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
V2 p0 = collider_get_support_point(c0, xf0_t1, dir).p;
|
Vec2 p0 = collider_get_support_point(c0, xf0_t1, dir).p;
|
||||||
V2 p1 = collider_get_support_point(c1, xf1_t1, dir_neg).p;
|
Vec2 p1 = collider_get_support_point(c1, xf1_t1, dir_neg).p;
|
||||||
t1_sep = v2_dot(dir, v2_sub(p1, p0));
|
t1_sep = v2_dot(dir, v2_sub(p1, p0));
|
||||||
if (t1_sep > 0) {
|
if (t1_sep > 0) {
|
||||||
/* Shapes are not penetrating at t=1 */
|
/* Shapes are not penetrating at t=1 */
|
||||||
@ -919,11 +919,11 @@ f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
|
|||||||
t = (-t1_sep / m) + t1;
|
t = (-t1_sep / m) + t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Xform xf0 = xform_lerp(xf0_t0, xf0_t1, t);
|
Xform xf0 = LerpXform(xf0_t0, xf0_t1, t);
|
||||||
Xform xf1 = xform_lerp(xf1_t0, xf1_t1, t);
|
Xform xf1 = LerpXform(xf1_t0, xf1_t1, t);
|
||||||
|
|
||||||
V2 p0 = collider_get_support_point(c0, xf0, dir).p;
|
Vec2 p0 = collider_get_support_point(c0, xf0, dir).p;
|
||||||
V2 p1 = collider_get_support_point(c1, xf1, dir_neg).p;
|
Vec2 p1 = collider_get_support_point(c1, xf1, dir_neg).p;
|
||||||
t_sep = v2_dot(dir, v2_sub(p1, p0));
|
t_sep = v2_dot(dir, v2_sub(p1, p0));
|
||||||
|
|
||||||
/* Update bracket */
|
/* Update bracket */
|
||||||
@ -949,13 +949,13 @@ f32 collider_time_of_impact(CLD_Shape *c0, CLD_Shape *c1,
|
|||||||
/* TODO: Remove this (debugging) */
|
/* TODO: Remove this (debugging) */
|
||||||
V2Array menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, u32 detail)
|
V2Array menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, u32 detail)
|
||||||
{
|
{
|
||||||
V2Array res = { .points = PushDry(arena, V2) };
|
V2Array res = { .points = PushDry(arena, Vec2) };
|
||||||
for (u64 i = 0; i < detail; ++i) {
|
for (u64 i = 0; i < detail; ++i) {
|
||||||
f32 angle = ((f32)i / detail) * (2 * Pi);
|
f32 angle = ((f32)i / detail) * (2 * Pi);
|
||||||
V2 dir = v2_from_angle(angle);
|
Vec2 dir = v2_from_angle(angle);
|
||||||
CLD_MenkowskiPoint m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
CLD_MenkowskiPoint m = get_menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||||
if (res.count == 0 || !v2_eq(m.p, res.points[res.count - 1])) {
|
if (res.count == 0 || !v2_eq(m.p, res.points[res.count - 1])) {
|
||||||
*PushStructNoZero(arena, V2) = m.p;
|
*PushStructNoZero(arena, Vec2) = m.p;
|
||||||
++res.count;
|
++res.count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -966,16 +966,16 @@ V2Array menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0,
|
|||||||
V2Array cloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
|
V2Array cloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1)
|
||||||
{
|
{
|
||||||
/* FIXME: Account for radius */
|
/* FIXME: Account for radius */
|
||||||
V2Array res = { .points = PushDry(arena, V2) };
|
V2Array res = { .points = PushDry(arena, Vec2) };
|
||||||
V2 *points0 = shape0->points;
|
Vec2 *points0 = shape0->points;
|
||||||
V2 *points1 = shape1->points;
|
Vec2 *points1 = shape1->points;
|
||||||
u32 count0 = shape0->count;
|
u32 count0 = shape0->count;
|
||||||
u32 count1 = shape1->count;
|
u32 count1 = shape1->count;
|
||||||
for (u64 i = 0; i < count0; ++i) {
|
for (u64 i = 0; i < count0; ++i) {
|
||||||
V2 p0 = xform_mul_v2(xf0, points0[i]);
|
Vec2 p0 = MulXformV2(xf0, points0[i]);
|
||||||
for (u64 j = 0; j < count1; ++j) {
|
for (u64 j = 0; j < count1; ++j) {
|
||||||
V2 p1 = xform_mul_v2(xf1, points1[j]);
|
Vec2 p1 = MulXformV2(xf1, points1[j]);
|
||||||
*PushStructNoZero(arena, V2) = v2_sub(p0, p1);
|
*PushStructNoZero(arena, Vec2) = v2_sub(p0, p1);
|
||||||
++res.count;
|
++res.count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -989,14 +989,14 @@ V2Array cloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xfo
|
|||||||
#if 0
|
#if 0
|
||||||
b32 collider_collision_boolean(CLD_Shape *shape0, CLD_Shape *shape1)
|
b32 collider_collision_boolean(CLD_Shape *shape0, CLD_Shape *shape1)
|
||||||
{
|
{
|
||||||
struct { V2 a, b, c; } s = ZI;
|
struct { Vec2 a, b, c; } s = ZI;
|
||||||
|
|
||||||
/* FIXME: Infinite loop when shapes exactly overlap same space? */
|
/* FIXME: Infinite loop when shapes exactly overlap same space? */
|
||||||
V2 dir, p;
|
Vec2 dir, p;
|
||||||
|
|
||||||
/* First point is support point in shape's general directions to eachother */
|
/* First point is support point in shape's general directions to eachother */
|
||||||
dir = v2_sub(starting_point(shape1), starting_point(shape0));
|
dir = v2_sub(starting_point(shape1), starting_point(shape0));
|
||||||
if (v2_is_zero(dir)) dir = V2FromXY(1, 0);
|
if (v2_is_zero(dir)) dir = V2(1, 0);
|
||||||
s.a = get_menkowski_point(shape0, shape1, dir);
|
s.a = get_menkowski_point(shape0, shape1, dir);
|
||||||
|
|
||||||
/* Second point is support point towards origin */
|
/* Second point is support point towards origin */
|
||||||
@ -1018,9 +1018,9 @@ b32 collider_collision_boolean(CLD_Shape *shape0, CLD_Shape *shape1)
|
|||||||
s.b = s.a;
|
s.b = s.a;
|
||||||
s.a = p;
|
s.a = p;
|
||||||
|
|
||||||
V2 vab = v2_sub(s.b, s.a);
|
Vec2 vab = v2_sub(s.b, s.a);
|
||||||
V2 vac = v2_sub(s.c, s.a);
|
Vec2 vac = v2_sub(s.c, s.a);
|
||||||
V2 a_to_origin = v2_neg(s.a);
|
Vec2 a_to_origin = v2_neg(s.a);
|
||||||
|
|
||||||
dir = v2_perp_towards_dir(vab, v2_neg(vac)); /* Normal of ab pointing away from c */
|
dir = v2_perp_towards_dir(vab, v2_neg(vac)); /* Normal of ab pointing away from c */
|
||||||
if (v2_dot(dir, a_to_origin) >= 0) {
|
if (v2_dot(dir, a_to_origin) >= 0) {
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
Struct(CLD_Shape) {
|
Struct(CLD_Shape) {
|
||||||
V2 points[8];
|
Vec2 points[8];
|
||||||
u32 count;
|
u32 count;
|
||||||
f32 radius;
|
f32 radius;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(CLD_SupportPoint) {
|
Struct(CLD_SupportPoint) {
|
||||||
V2 p;
|
Vec2 p;
|
||||||
u32 i; /* Index of original point in shape */
|
u32 i; /* Index of original point in shape */
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(CLD_MenkowskiPoint) {
|
Struct(CLD_MenkowskiPoint) {
|
||||||
V2 p; /* Menkowski difference point */
|
Vec2 p; /* Menkowski difference point */
|
||||||
CLD_SupportPoint s0; /* Support point of first shape in dir */
|
CLD_SupportPoint s0; /* Support point of first shape in dir */
|
||||||
CLD_SupportPoint s1; /* Support point of second shape in -dir */
|
CLD_SupportPoint s1; /* Support point of second shape in -dir */
|
||||||
};
|
};
|
||||||
@ -26,18 +26,18 @@ Struct(CLD_MenkowskiFeature) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Struct(CLD_CollisionPoint) {
|
Struct(CLD_CollisionPoint) {
|
||||||
V2 point;
|
Vec2 point;
|
||||||
f32 separation;
|
f32 separation;
|
||||||
u32 id; /* Based on polygon edge-to-edge */
|
u32 id; /* Based on polygon edge-to-edge */
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(CLD_Prototype) {
|
Struct(CLD_Prototype) {
|
||||||
V2 points[64];
|
Vec2 points[64];
|
||||||
u32 len;
|
u32 len;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(CLD_CollisionResult) {
|
Struct(CLD_CollisionResult) {
|
||||||
V2 normal;
|
Vec2 normal;
|
||||||
CLD_CollisionPoint points[2];
|
CLD_CollisionPoint points[2];
|
||||||
u32 num_points;
|
u32 num_points;
|
||||||
|
|
||||||
@ -47,12 +47,12 @@ Struct(CLD_CollisionResult) {
|
|||||||
CLD_Prototype prototype;
|
CLD_Prototype prototype;
|
||||||
|
|
||||||
/* For debugging */
|
/* For debugging */
|
||||||
V2 a0, b0, a1, b1;
|
Vec2 a0, b0, a1, b1;
|
||||||
V2 a0_clipped, b0_clipped, a1_clipped, b1_clipped;
|
Vec2 a0_clipped, b0_clipped, a1_clipped, b1_clipped;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(CLD_ClosestResult) {
|
Struct(CLD_ClosestResult) {
|
||||||
V2 p0, p1;
|
Vec2 p0, p1;
|
||||||
b32 colliding;
|
b32 colliding;
|
||||||
|
|
||||||
/* For debugging */
|
/* For debugging */
|
||||||
@ -63,7 +63,7 @@ Struct(CLD_ClosestResult) {
|
|||||||
|
|
||||||
CLD_Shape collider_from_quad(Quad quad);
|
CLD_Shape collider_from_quad(Quad quad);
|
||||||
|
|
||||||
CLD_SupportPoint collider_get_support_point(CLD_Shape *shape, Xform xf, V2 dir);
|
CLD_SupportPoint collider_get_support_point(CLD_Shape *shape, Xform xf, Vec2 dir);
|
||||||
|
|
||||||
Aabb collider_aabb_from_collider(CLD_Shape *shape, Xform xf);
|
Aabb collider_aabb_from_collider(CLD_Shape *shape, Xform xf);
|
||||||
|
|
||||||
|
|||||||
@ -65,8 +65,8 @@
|
|||||||
# define SIM_MAX_LINEAR_VELOCITY 500
|
# define SIM_MAX_LINEAR_VELOCITY 500
|
||||||
# define SIM_MAX_ANGULAR_VELOCITY (Tau * 20)
|
# define SIM_MAX_ANGULAR_VELOCITY (Tau * 20)
|
||||||
#else
|
#else
|
||||||
# define SIM_MAX_LINEAR_VELOCITY F32_INFINITY
|
# define SIM_MAX_LINEAR_VELOCITY F32Infinity
|
||||||
# define SIM_MAX_ANGULAR_VELOCITY F32_INFINITY
|
# define SIM_MAX_ANGULAR_VELOCITY F32Infinity
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define COLLIDER_DEBUG 0
|
#define COLLIDER_DEBUG 0
|
||||||
|
|||||||
@ -11,7 +11,7 @@ D_StartupReceipt draw_startup(F_StartupReceipt *font_sr)
|
|||||||
__prof;
|
__prof;
|
||||||
(UNUSED)font_sr;
|
(UNUSED)font_sr;
|
||||||
u32 pixel_white = 0xFFFFFFFF;
|
u32 pixel_white = 0xFFFFFFFF;
|
||||||
G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32FromXY(1, 1), &pixel_white);
|
G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(1, 1), &pixel_white);
|
||||||
return (D_StartupReceipt) { 0 };
|
return (D_StartupReceipt) { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,14 +73,14 @@ void draw_poly(G_RenderSig *sig, V2Array vertices, u32 color)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_circle(G_RenderSig *sig, V2 pos, f32 radius, u32 color, u32 detail)
|
void draw_circle(G_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detail)
|
||||||
{
|
{
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
|
|
||||||
V2 *points = PushArrayNoZero(scratch.arena, V2, detail);
|
Vec2 *points = PushArrayNoZero(scratch.arena, Vec2, detail);
|
||||||
for (u32 i = 0; i < detail; ++i) {
|
for (u32 i = 0; i < detail; ++i) {
|
||||||
f32 angle = ((f32)i / (f32)detail) * Tau;
|
f32 angle = ((f32)i / (f32)detail) * Tau;
|
||||||
V2 p = V2FromXY(
|
Vec2 p = V2(
|
||||||
radius * math_cos(angle),
|
radius * math_cos(angle),
|
||||||
radius * math_sin(angle)
|
radius * math_sin(angle)
|
||||||
);
|
);
|
||||||
@ -111,7 +111,7 @@ void draw_quad(G_RenderSig *sig, Quad quad, u32 color)
|
|||||||
* Line shapes
|
* Line shapes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void draw_gradient_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, u32 start_color, u32 end_color)
|
void draw_gradient_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 start_color, u32 end_color)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
Quad quad = quad_from_line(start, end, thickness);
|
Quad quad = quad_from_line(start, end, thickness);
|
||||||
@ -124,13 +124,13 @@ void draw_gradient_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, u32 s
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, u32 color)
|
void draw_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 color)
|
||||||
{
|
{
|
||||||
Quad quad = quad_from_line(start, end, thickness);
|
Quad quad = quad_from_line(start, end, thickness);
|
||||||
draw_quad(sig, quad, color);
|
draw_quad(sig, quad, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_ray(G_RenderSig *sig, V2 pos, V2 rel, f32 thickness, u32 color)
|
void draw_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, u32 color)
|
||||||
{
|
{
|
||||||
Quad quad = quad_from_ray(pos, rel, thickness);
|
Quad quad = quad_from_ray(pos, rel, thickness);
|
||||||
draw_quad(sig, quad, color);
|
draw_quad(sig, quad, color);
|
||||||
@ -140,28 +140,28 @@ void draw_poly_line(G_RenderSig *sig, V2Array points, b32 loop, f32 thickness, u
|
|||||||
{
|
{
|
||||||
if (points.count >= 2) {
|
if (points.count >= 2) {
|
||||||
for (u64 i = 1; i < points.count; ++i) {
|
for (u64 i = 1; i < points.count; ++i) {
|
||||||
V2 p1 = points.points[i - 1];
|
Vec2 p1 = points.points[i - 1];
|
||||||
V2 p2 = points.points[i];
|
Vec2 p2 = points.points[i];
|
||||||
Quad q = quad_from_line(p1, p2, thickness);
|
Quad q = quad_from_line(p1, p2, thickness);
|
||||||
draw_quad(sig, q, color);
|
draw_quad(sig, q, color);
|
||||||
}
|
}
|
||||||
if (loop && points.count > 2) {
|
if (loop && points.count > 2) {
|
||||||
V2 p1 = points.points[points.count - 1];
|
Vec2 p1 = points.points[points.count - 1];
|
||||||
V2 p2 = points.points[0];
|
Vec2 p2 = points.points[0];
|
||||||
Quad q = quad_from_line(p1, p2, thickness);
|
Quad q = quad_from_line(p1, p2, thickness);
|
||||||
draw_quad(sig, q, color);
|
draw_quad(sig, q, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_circle_line(G_RenderSig *sig, V2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
|
void draw_circle_line(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
|
||||||
{
|
{
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
|
|
||||||
V2 *points = PushArrayNoZero(scratch.arena, V2, detail);
|
Vec2 *points = PushArrayNoZero(scratch.arena, Vec2, detail);
|
||||||
for (u32 i = 0; i < detail; ++i) {
|
for (u32 i = 0; i < detail; ++i) {
|
||||||
f32 angle = ((f32)i / (f32)detail) * Tau;
|
f32 angle = ((f32)i / (f32)detail) * Tau;
|
||||||
V2 p = V2FromXY(
|
Vec2 p = V2(
|
||||||
radius * math_cos(angle),
|
radius * math_cos(angle),
|
||||||
radius * math_sin(angle)
|
radius * math_sin(angle)
|
||||||
);
|
);
|
||||||
@ -179,31 +179,31 @@ void draw_circle_line(G_RenderSig *sig, V2 pos, f32 radius, f32 thickness, u32 c
|
|||||||
|
|
||||||
void draw_quad_line(G_RenderSig *sig, Quad quad, f32 thickness, u32 color)
|
void draw_quad_line(G_RenderSig *sig, Quad quad, f32 thickness, u32 color)
|
||||||
{
|
{
|
||||||
V2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
|
Vec2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
|
||||||
V2Array a = { .points = points, .count = countof(points) };
|
V2Array a = { .points = points, .count = countof(points) };
|
||||||
draw_poly_line(sig, a, 1, thickness, color);
|
draw_poly_line(sig, a, 1, thickness, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_arrow_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, f32 arrowhead_height, u32 color)
|
void draw_arrow_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, f32 arrowhead_height, u32 color)
|
||||||
{
|
{
|
||||||
const f32 head_width_ratio = 0.5f; /* Width of arrowhead relative to its length */
|
const f32 head_width_ratio = 0.5f; /* Width of arrowhead relative to its length */
|
||||||
|
|
||||||
const f32 max_height_to_line_ratio = 0.9f; /* Maximum length of arrowhead relative to total line length */
|
const f32 max_height_to_line_ratio = 0.9f; /* Maximum length of arrowhead relative to total line length */
|
||||||
arrowhead_height = min_f32(arrowhead_height, v2_len(v2_sub(end, start)) * max_height_to_line_ratio);
|
arrowhead_height = MinF32(arrowhead_height, v2_len(v2_sub(end, start)) * max_height_to_line_ratio);
|
||||||
|
|
||||||
V2 head_start_dir = v2_sub(start, end);
|
Vec2 head_start_dir = v2_sub(start, end);
|
||||||
head_start_dir = v2_norm(head_start_dir);
|
head_start_dir = v2_norm(head_start_dir);
|
||||||
head_start_dir = v2_mul(head_start_dir, arrowhead_height);
|
head_start_dir = v2_mul(head_start_dir, arrowhead_height);
|
||||||
|
|
||||||
V2 head_start = v2_add(end, head_start_dir);
|
Vec2 head_start = v2_add(end, head_start_dir);
|
||||||
|
|
||||||
V2 head_p1_dir = v2_perp_mul(head_start_dir, head_width_ratio);
|
Vec2 head_p1_dir = v2_perp_mul(head_start_dir, head_width_ratio);
|
||||||
V2 head_p2_dir = v2_neg(head_p1_dir);
|
Vec2 head_p2_dir = v2_neg(head_p1_dir);
|
||||||
|
|
||||||
V2 head_p1 = v2_add(head_start, head_p1_dir);
|
Vec2 head_p1 = v2_add(head_start, head_p1_dir);
|
||||||
V2 head_p2 = v2_add(head_start, head_p2_dir);
|
Vec2 head_p2 = v2_add(head_start, head_p2_dir);
|
||||||
|
|
||||||
V2 head_points[] = { end, head_p1, head_p2 };
|
Vec2 head_points[] = { end, head_p1, head_p2 };
|
||||||
V2Array head_points_v2_array = {
|
V2Array head_points_v2_array = {
|
||||||
.points = head_points,
|
.points = head_points,
|
||||||
.count = countof(head_points)
|
.count = countof(head_points)
|
||||||
@ -214,9 +214,9 @@ void draw_arrow_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, f32 arro
|
|||||||
draw_quad(sig, line_quad, color);
|
draw_quad(sig, line_quad, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_arrow_ray(G_RenderSig *sig, V2 pos, V2 rel, f32 thickness, f32 arrowhead_height, u32 color)
|
void draw_arrow_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, f32 arrowhead_height, u32 color)
|
||||||
{
|
{
|
||||||
V2 end = v2_add(pos, rel);
|
Vec2 end = v2_add(pos, rel);
|
||||||
draw_arrow_line(sig, pos, end, thickness, arrowhead_height, color);
|
draw_arrow_line(sig, pos, end, thickness, arrowhead_height, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,18 +226,18 @@ void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 t
|
|||||||
V2Array poly = ZI;
|
V2Array poly = ZI;
|
||||||
if (shape.radius == 0) {
|
if (shape.radius == 0) {
|
||||||
poly.count = shape.count;
|
poly.count = shape.count;
|
||||||
poly.points = PushArrayNoZero(scratch.arena, V2, shape.count);
|
poly.points = PushArrayNoZero(scratch.arena, Vec2, shape.count);
|
||||||
for (u32 i = 0; i < shape.count; ++i) {
|
for (u32 i = 0; i < shape.count; ++i) {
|
||||||
V2 p = xform_mul_v2(shape_xf, shape.points[i]);
|
Vec2 p = MulXformV2(shape_xf, shape.points[i]);
|
||||||
poly.points[i] = p;
|
poly.points[i] = p;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
poly.count = detail;
|
poly.count = detail;
|
||||||
poly.points = PushArrayNoZero(scratch.arena, V2, detail);
|
poly.points = PushArrayNoZero(scratch.arena, Vec2, detail);
|
||||||
for (u32 i = 0; i < detail; ++i) {
|
for (u32 i = 0; i < detail; ++i) {
|
||||||
f32 angle = ((f32)i / (f32)detail) * Tau;
|
f32 angle = ((f32)i / (f32)detail) * Tau;
|
||||||
V2 dir = V2FromXY(math_cos(angle), math_sin(angle));
|
Vec2 dir = V2(math_cos(angle), math_sin(angle));
|
||||||
V2 p = collider_get_support_point(&shape, shape_xf, dir).p;
|
Vec2 p = collider_get_support_point(&shape, shape_xf, dir).p;
|
||||||
poly.points[i] = p;
|
poly.points[i] = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,7 +249,7 @@ void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 t
|
|||||||
* Grid
|
* Grid
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, V2 offset)
|
void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, Vec2 offset)
|
||||||
{
|
{
|
||||||
i32 grid_id = 0;
|
i32 grid_id = 0;
|
||||||
{
|
{
|
||||||
@ -370,8 +370,8 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
line_width += tg->advance;
|
line_width += tg->advance;
|
||||||
top_offset = min_f32(top_offset, tg->off_y);
|
top_offset = MinF32(top_offset, tg->off_y);
|
||||||
bottom_offset = max_f32(bottom_offset, tg->off_y + tg->height);
|
bottom_offset = MaxF32(bottom_offset, tg->off_y + tg->height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -390,7 +390,7 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
|||||||
}
|
}
|
||||||
last_line = node;
|
last_line = node;
|
||||||
last_line_bottom_offset = bottom_offset;
|
last_line_bottom_offset = bottom_offset;
|
||||||
widest_line = max_f32(widest_line, line_width);
|
widest_line = MaxF32(widest_line, line_width);
|
||||||
++num_lines;
|
++num_lines;
|
||||||
}
|
}
|
||||||
string_codepoint_iter_end(&iter);
|
string_codepoint_iter_end(&iter);
|
||||||
@ -440,7 +440,7 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
|||||||
|
|
||||||
u64 line_number = 0;
|
u64 line_number = 0;
|
||||||
for (struct drawable_line *line = first_line; line; line = line->next) {
|
for (struct drawable_line *line = first_line; line; line = line->next) {
|
||||||
V2 draw_pos = bounds.pos;
|
Vec2 draw_pos = bounds.pos;
|
||||||
draw_pos.y += line_number * line_spacing - first_line_top_offset;
|
draw_pos.y += line_number * line_spacing - first_line_top_offset;
|
||||||
|
|
||||||
/* Alignment */
|
/* Alignment */
|
||||||
@ -459,9 +459,9 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
|||||||
/* Draw glyphs */
|
/* Draw glyphs */
|
||||||
for (u64 i = 0; i < line->num_glyphs; ++i) {
|
for (u64 i = 0; i < line->num_glyphs; ++i) {
|
||||||
struct drawable_glyph *tg = &line->glyphs[i];
|
struct drawable_glyph *tg = &line->glyphs[i];
|
||||||
V2 pos = V2FromXY(draw_pos.x + tg->off_x, draw_pos.y + tg->off_y);
|
Vec2 pos = V2(draw_pos.x + tg->off_x, draw_pos.y + tg->off_y);
|
||||||
V2 size = V2FromXY(tg->width, tg->height);
|
Vec2 size = V2(tg->width, tg->height);
|
||||||
Xform xf = xform_from_rect(RectFromV2(pos, size));
|
Xform xf = XformFromRect(RectFromV2(pos, size));
|
||||||
draw_ui_rect(sig, DRAW_UI_RECT_PARAMS(.xf = xf, .texture = params.font->texture, .tint = params.color, .clip = tg->clip));
|
draw_ui_rect(sig, DRAW_UI_RECT_PARAMS(.xf = xf, .texture = params.font->texture, .tint = params.color, .clip = tg->clip));
|
||||||
draw_pos.x += tg->advance;
|
draw_pos.x += tg->advance;
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ Struct(D_MaterialParams) {
|
|||||||
ClipRect clip;
|
ClipRect clip;
|
||||||
u32 tint;
|
u32 tint;
|
||||||
b32 is_light;
|
b32 is_light;
|
||||||
V3 light_emittance;
|
Vec3 light_emittance;
|
||||||
};
|
};
|
||||||
|
|
||||||
void draw_material(G_RenderSig *sig, D_MaterialParams params);
|
void draw_material(G_RenderSig *sig, D_MaterialParams params);
|
||||||
@ -30,7 +30,7 @@ void draw_poly_ex(G_RenderSig *sig, V2Array vertices, G_Indices indices, u32 col
|
|||||||
|
|
||||||
void draw_poly(G_RenderSig *sig, V2Array points, u32 color);
|
void draw_poly(G_RenderSig *sig, V2Array points, u32 color);
|
||||||
|
|
||||||
void draw_circle(G_RenderSig *sig, V2 pos, f32 radius, u32 color, u32 detail);
|
void draw_circle(G_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detail);
|
||||||
|
|
||||||
void draw_quad(G_RenderSig *sig, Quad quad, u32 color);
|
void draw_quad(G_RenderSig *sig, Quad quad, u32 color);
|
||||||
|
|
||||||
@ -38,21 +38,21 @@ void draw_quad(G_RenderSig *sig, Quad quad, u32 color);
|
|||||||
* Line shapes
|
* Line shapes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void draw_gradient_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, u32 start_color, u32 end_color);
|
void draw_gradient_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 start_color, u32 end_color);
|
||||||
|
|
||||||
void draw_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, u32 color);
|
void draw_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 color);
|
||||||
|
|
||||||
void draw_ray(G_RenderSig *sig, V2 pos, V2 rel, f32 thickness, u32 color);
|
void draw_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, u32 color);
|
||||||
|
|
||||||
void draw_poly_line(G_RenderSig *sig, V2Array points, b32 loop, f32 thickness, u32 color);
|
void draw_poly_line(G_RenderSig *sig, V2Array points, b32 loop, f32 thickness, u32 color);
|
||||||
|
|
||||||
void draw_circle_line(G_RenderSig *sig, V2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
|
void draw_circle_line(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
|
||||||
|
|
||||||
void draw_quad_line(G_RenderSig *sig, Quad quad, f32 thickness, u32 color);
|
void draw_quad_line(G_RenderSig *sig, Quad quad, f32 thickness, u32 color);
|
||||||
|
|
||||||
void draw_arrow_line(G_RenderSig *sig, V2 start, V2 end, f32 thickness, f32 arrowhead_height, u32 color);
|
void draw_arrow_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, f32 arrowhead_height, u32 color);
|
||||||
|
|
||||||
void draw_arrow_ray(G_RenderSig *sig, V2 pos, V2 rel, f32 thickness, f32 arrowhead_height, u32 color);
|
void draw_arrow_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, f32 arrowhead_height, u32 color);
|
||||||
|
|
||||||
void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 thickness, u32 color, u32 detail);
|
void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 thickness, u32 color, u32 detail);
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 t
|
|||||||
* Grid
|
* Grid
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, V2 offset);
|
void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, Vec2 offset);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* UI
|
* UI
|
||||||
@ -118,7 +118,7 @@ typedef i32 D_TextOffsetY; enum {
|
|||||||
|
|
||||||
Struct(D_TextParams) {
|
Struct(D_TextParams) {
|
||||||
F_Font *font;
|
F_Font *font;
|
||||||
V2 pos;
|
Vec2 pos;
|
||||||
f32 scale;
|
f32 scale;
|
||||||
u32 color;
|
u32 color;
|
||||||
D_TextAlignment alignment;
|
D_TextAlignment alignment;
|
||||||
|
|||||||
@ -100,7 +100,7 @@ internal P_JobDef(font_load_asset_job, job)
|
|||||||
resource_close(&res);
|
resource_close(&res);
|
||||||
|
|
||||||
/* Send texture to GPU */
|
/* Send texture to GPU */
|
||||||
G_Resource *texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32FromXY(result.image_width, result.image_height), result.image_pixels);
|
G_Resource *texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(result.image_width, result.image_height), result.image_pixels);
|
||||||
|
|
||||||
/* Allocate store memory */
|
/* Allocate store memory */
|
||||||
F_Font *font = 0;
|
F_Font *font = 0;
|
||||||
|
|||||||
@ -37,7 +37,7 @@ Struct(G_RenderCmdDesc)
|
|||||||
ClipRect clip;
|
ClipRect clip;
|
||||||
u32 tint;
|
u32 tint;
|
||||||
b32 is_light;
|
b32 is_light;
|
||||||
V3 light_emittance;
|
Vec3 light_emittance;
|
||||||
u32 grid_cmd_id;
|
u32 grid_cmd_id;
|
||||||
} material;
|
} material;
|
||||||
struct
|
struct
|
||||||
@ -57,7 +57,7 @@ Struct(G_RenderCmdDesc)
|
|||||||
{
|
{
|
||||||
f32 line_thickness;
|
f32 line_thickness;
|
||||||
f32 line_spacing;
|
f32 line_spacing;
|
||||||
V2 offset;
|
Vec2 offset;
|
||||||
u32 bg0_color;
|
u32 bg0_color;
|
||||||
u32 bg1_color;
|
u32 bg1_color;
|
||||||
u32 line_color;
|
u32 line_color;
|
||||||
@ -69,8 +69,8 @@ Struct(G_RenderCmdDesc)
|
|||||||
|
|
||||||
Struct(G_RenderParams)
|
Struct(G_RenderParams)
|
||||||
{
|
{
|
||||||
V2I32 ui_size;
|
Vec2I32 ui_size;
|
||||||
V2I32 render_size;
|
Vec2I32 render_size;
|
||||||
Xform world_to_render_xf;
|
Xform world_to_render_xf;
|
||||||
Xform render_to_ui_xf;
|
Xform render_to_ui_xf;
|
||||||
b32 effects_disabled;
|
b32 effects_disabled;
|
||||||
@ -125,9 +125,9 @@ void gp_resource_release(G_Resource *resource);
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Texture operations
|
//~ Texture operations
|
||||||
|
|
||||||
G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, V2I32 size, void *initial_data);
|
G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, Vec2I32 size, void *initial_data);
|
||||||
|
|
||||||
V2I32 gp_texture_get_size(G_Resource *texture);
|
Vec2I32 gp_texture_get_size(G_Resource *texture);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Render operations
|
//~ Render operations
|
||||||
@ -147,7 +147,7 @@ G_MemoryInfo gp_query_memory_info(void);
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Swapchain
|
//~ Swapchain
|
||||||
|
|
||||||
G_Swapchain *gp_swapchain_alloc(P_Window *window, V2I32 resolution);
|
G_Swapchain *gp_swapchain_alloc(P_Window *window, Vec2I32 resolution);
|
||||||
|
|
||||||
void gp_swapchain_release(G_Swapchain *gp_swapchain);
|
void gp_swapchain_release(G_Swapchain *gp_swapchain);
|
||||||
|
|
||||||
@ -161,4 +161,4 @@ void gp_swapchain_wait(G_Swapchain *gp_swapchain);
|
|||||||
/* 1. Clears the backbuffer and ensures it's at size `backbuffer_resolution`
|
/* 1. Clears the backbuffer and ensures it's at size `backbuffer_resolution`
|
||||||
* 2. Blits `texture` to the backbuffer using `texture_xf`
|
* 2. Blits `texture` to the backbuffer using `texture_xf`
|
||||||
* 3. Presents the backbuffer */
|
* 3. Presents the backbuffer */
|
||||||
void gp_present(G_Swapchain *gp_swapchain, V2I32 backbuffer_resolution, G_Resource *texture, Xform texture_xf, i32 vsync);
|
void gp_present(G_Swapchain *gp_swapchain, Vec2I32 backbuffer_resolution, G_Resource *texture, Xform texture_xf, i32 vsync);
|
||||||
|
|||||||
@ -214,7 +214,7 @@ struct dx12_resource {
|
|||||||
|
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS gpu_address; /* NOTE: 0 for textures */
|
D3D12_GPU_VIRTUAL_ADDRESS gpu_address; /* NOTE: 0 for textures */
|
||||||
|
|
||||||
V2I32 texture_size;
|
Vec2I32 texture_size;
|
||||||
struct dx12_resource *next_free;
|
struct dx12_resource *next_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ struct swapchain {
|
|||||||
IDXGISwapChain3 *swapchain;
|
IDXGISwapChain3 *swapchain;
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
HANDLE waitable;
|
HANDLE waitable;
|
||||||
V2I32 resolution;
|
Vec2I32 resolution;
|
||||||
struct swapchain_buffer buffers[DX12_SWAPCHAIN_BUFFER_COUNT];
|
struct swapchain_buffer buffers[DX12_SWAPCHAIN_BUFFER_COUNT];
|
||||||
|
|
||||||
struct swapchain *next_free;
|
struct swapchain *next_free;
|
||||||
@ -2064,7 +2064,7 @@ internal struct command_buffer *_command_list_push_buffer(struct command_list *c
|
|||||||
Assert(data_len % data_stride == 0);
|
Assert(data_len % data_stride == 0);
|
||||||
|
|
||||||
/* Determine size */
|
/* Determine size */
|
||||||
u64 size = max_u64(DX12_COMMAND_BUFFER_MIN_SIZE, align_up_pow2(data_len));
|
u64 size = MaxU64(DX12_COMMAND_BUFFER_MIN_SIZE, align_up_pow2(data_len));
|
||||||
|
|
||||||
/* Allocate buffer */
|
/* Allocate buffer */
|
||||||
struct command_buffer_group *cb_group = 0;
|
struct command_buffer_group *cb_group = 0;
|
||||||
@ -2150,7 +2150,7 @@ internal struct command_buffer *_command_list_push_buffer(struct command_list *c
|
|||||||
desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
|
desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
|
||||||
desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||||
desc.Buffer.FirstElement = 0;
|
desc.Buffer.FirstElement = 0;
|
||||||
desc.Buffer.NumElements = max_u32(data_len / data_stride, 1);
|
desc.Buffer.NumElements = MaxU32(data_len / data_stride, 1);
|
||||||
desc.Buffer.StructureByteStride = data_stride;
|
desc.Buffer.StructureByteStride = data_stride;
|
||||||
desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
|
desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
|
||||||
ID3D12Device_CreateShaderResourceView(G.device, r->resource, &desc, r->srv_descriptor->handle);
|
ID3D12Device_CreateShaderResourceView(G.device, r->resource, &desc, r->srv_descriptor->handle);
|
||||||
@ -2204,7 +2204,7 @@ internal P_JobDef(dx12_wait_fence_job, job)
|
|||||||
* Texture
|
* Texture
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, V2I32 size, void *initial_data)
|
G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, Vec2I32 size, void *initial_data)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
if (size.x <= 0 || size.y <= 0) {
|
if (size.x <= 0 || size.y <= 0) {
|
||||||
@ -2271,7 +2271,7 @@ G_Resource *gp_texture_alloc(G_TextureFormat format, u32 flags, V2I32 size, void
|
|||||||
return (G_Resource *)r;
|
return (G_Resource *)r;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2I32 gp_texture_get_size(G_Resource *resource)
|
Vec2I32 gp_texture_get_size(G_Resource *resource)
|
||||||
{
|
{
|
||||||
struct dx12_resource *r = (struct dx12_resource *)resource;
|
struct dx12_resource *r = (struct dx12_resource *)resource;
|
||||||
return r->texture_size;
|
return r->texture_size;
|
||||||
@ -2458,7 +2458,7 @@ internal D3D12_INDEX_BUFFER_VIEW ibv_from_command_buffer(struct command_buffer *
|
|||||||
return ibv;
|
return ibv;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, V2I32 size, D3D12_RESOURCE_STATES initial_state)
|
internal struct dx12_resource *gbuff_alloc(DXGI_FORMAT format, Vec2I32 size, D3D12_RESOURCE_STATES initial_state)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
|
D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
|
||||||
@ -2548,7 +2548,7 @@ struct material_instance_desc {
|
|||||||
ClipRect clip;
|
ClipRect clip;
|
||||||
u32 tint;
|
u32 tint;
|
||||||
b32 is_light;
|
b32 is_light;
|
||||||
V3 light_emittance;
|
Vec3 light_emittance;
|
||||||
u32 grid_id;
|
u32 grid_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2562,7 +2562,7 @@ struct ui_rect_instance_desc {
|
|||||||
struct material_grid_desc {
|
struct material_grid_desc {
|
||||||
f32 line_thickness;
|
f32 line_thickness;
|
||||||
f32 line_spacing;
|
f32 line_spacing;
|
||||||
V2 offset;
|
Vec2 offset;
|
||||||
u32 bg0_color;
|
u32 bg0_color;
|
||||||
u32 bg1_color;
|
u32 bg1_color;
|
||||||
u32 line_color;
|
u32 line_color;
|
||||||
@ -2695,13 +2695,13 @@ G_Resource *gp_run_render(G_RenderSig *gp_render_sig, G_RenderParams params)
|
|||||||
struct render_sig *rsig = (struct render_sig *)gp_render_sig;
|
struct render_sig *rsig = (struct render_sig *)gp_render_sig;
|
||||||
++rsig->frame_index;
|
++rsig->frame_index;
|
||||||
|
|
||||||
V2I32 ui_size = V2I32FromXY(max_i32(params.ui_size.x, 1), max_i32(params.ui_size.y, 1));
|
Vec2I32 ui_size = V2I32(MaxI32(params.ui_size.x, 1), MaxI32(params.ui_size.y, 1));
|
||||||
V2I32 render_size = V2I32FromXY(max_i32(params.render_size.x, 1), max_i32(params.render_size.y, 1));
|
Vec2I32 render_size = V2I32(MaxI32(params.render_size.x, 1), MaxI32(params.render_size.y, 1));
|
||||||
Xform world_to_render_xf = params.world_to_render_xf;
|
Xform world_to_render_xf = params.world_to_render_xf;
|
||||||
Xform render_to_ui_xf = params.render_to_ui_xf;
|
Xform render_to_ui_xf = params.render_to_ui_xf;
|
||||||
|
|
||||||
Rect ui_viewport = RectFromV2(V2FromXY(0, 0), V2FromXY(ui_size.x, ui_size.y));
|
Rect ui_viewport = RectFromV2(V2(0, 0), V2(ui_size.x, ui_size.y));
|
||||||
Rect render_viewport = RectFromV2(V2FromXY(0, 0), V2FromXY(render_size.x, render_size.y));
|
Rect render_viewport = RectFromV2(V2(0, 0), V2(render_size.x, render_size.y));
|
||||||
|
|
||||||
|
|
||||||
/* Allocate render buffers */
|
/* Allocate render buffers */
|
||||||
@ -2747,12 +2747,12 @@ G_Resource *gp_run_render(G_RenderSig *gp_render_sig, G_RenderParams params)
|
|||||||
__profn("Run render");
|
__profn("Run render");
|
||||||
__profnc_dx12(cl->cq->prof, cl->cl, "Run render", Rgb32F(0.5, 0.2, 0.2));
|
__profnc_dx12(cl->cq->prof, cl->cl, "Run render", Rgb32F(0.5, 0.2, 0.2));
|
||||||
Mat4x4 world_to_render_vp_matrix = calculate_vp(world_to_render_xf, render_viewport.width, render_viewport.height);
|
Mat4x4 world_to_render_vp_matrix = calculate_vp(world_to_render_xf, render_viewport.width, render_viewport.height);
|
||||||
Mat4x4 ui_vp_matrix = calculate_vp(XFORM_IDENT, ui_viewport.width, ui_viewport.height);
|
Mat4x4 ui_vp_matrix = calculate_vp(XformIdentity, ui_viewport.width, ui_viewport.height);
|
||||||
Mat4x4 blit_vp_matrix = ZI;
|
Mat4x4 blit_vp_matrix = ZI;
|
||||||
{
|
{
|
||||||
Xform xf = render_to_ui_xf;
|
Xform xf = render_to_ui_xf;
|
||||||
xf = xform_scaled(xf, V2FromXY(render_size.x, render_size.y));
|
xf = ScaleXform(xf, V2(render_size.x, render_size.y));
|
||||||
xf = xform_translated(xf, V2FromXY(0.5, 0.5));
|
xf = TranslateXform(xf, V2(0.5, 0.5));
|
||||||
blit_vp_matrix = calculate_vp(xf, ui_viewport.width, ui_viewport.height);
|
blit_vp_matrix = calculate_vp(xf, ui_viewport.width, ui_viewport.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2950,7 +2950,7 @@ G_Resource *gp_run_render(G_RenderSig *gp_render_sig, G_RenderParams params)
|
|||||||
|
|
||||||
/* Update step */
|
/* Update step */
|
||||||
if (step_length == -1) {
|
if (step_length == -1) {
|
||||||
step_length = max_i32(render_size.x, render_size.y) / 2;
|
step_length = MaxI32(render_size.x, render_size.y) / 2;
|
||||||
} else {
|
} else {
|
||||||
step_length /= 2;
|
step_length /= 2;
|
||||||
}
|
}
|
||||||
@ -3201,7 +3201,7 @@ internal void swapchain_init_resources(struct swapchain *swapchain)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
G_Swapchain *gp_swapchain_alloc(P_Window *window, V2I32 resolution)
|
G_Swapchain *gp_swapchain_alloc(P_Window *window, Vec2I32 resolution)
|
||||||
{
|
{
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
HWND hwnd = (HWND)P_GetInternalWindowHandle(window);
|
HWND hwnd = (HWND)P_GetInternalWindowHandle(window);
|
||||||
@ -3282,11 +3282,11 @@ void gp_swapchain_wait(G_Swapchain *gp_swapchain)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
internal struct swapchain_buffer *update_swapchain(struct swapchain *swapchain, V2I32 resolution)
|
internal struct swapchain_buffer *update_swapchain(struct swapchain *swapchain, Vec2I32 resolution)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
resolution.x = max_i32(resolution.x, 1);
|
resolution.x = MaxI32(resolution.x, 1);
|
||||||
resolution.y = max_i32(resolution.y, 1);
|
resolution.y = MaxI32(resolution.y, 1);
|
||||||
b32 should_rebuild = !v2i32_eq(swapchain->resolution, resolution);
|
b32 should_rebuild = !v2i32_eq(swapchain->resolution, resolution);
|
||||||
if (should_rebuild) {
|
if (should_rebuild) {
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
@ -3360,15 +3360,15 @@ internal void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s
|
|||||||
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
||||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps);
|
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps);
|
||||||
|
|
||||||
Rect viewport_rect = RectFromV2(V2FromXY(0, 0), V2FromXY(swapchain->resolution.x, swapchain->resolution.y));
|
Rect viewport_rect = RectFromV2(V2(0, 0), V2(swapchain->resolution.x, swapchain->resolution.y));
|
||||||
D3D12_VIEWPORT viewport = viewport_from_rect(viewport_rect);
|
D3D12_VIEWPORT viewport = viewport_from_rect(viewport_rect);
|
||||||
D3D12_RECT scissor = scissor_from_rect(viewport_rect);
|
D3D12_RECT scissor = scissor_from_rect(viewport_rect);
|
||||||
|
|
||||||
Mat4x4 vp_matrix = ZI;
|
Mat4x4 vp_matrix = ZI;
|
||||||
{
|
{
|
||||||
Xform xf = src_xf;
|
Xform xf = src_xf;
|
||||||
xf = xform_scaled(xf, V2FromXY(src->texture_size.x, src->texture_size.y));
|
xf = ScaleXform(xf, V2(src->texture_size.x, src->texture_size.y));
|
||||||
xf = xform_translated(xf, V2FromXY(0.5, 0.5));
|
xf = TranslateXform(xf, V2(0.5, 0.5));
|
||||||
vp_matrix = calculate_vp(xf, viewport.Width, viewport.Height);
|
vp_matrix = calculate_vp(xf, viewport.Width, viewport.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3434,7 +3434,7 @@ internal void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s
|
|||||||
pipeline_scope_end(pipeline_scope);
|
pipeline_scope_end(pipeline_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp_present(G_Swapchain *gp_swapchain, V2I32 backbuffer_resolution, G_Resource *texture, Xform texture_xf, i32 vsync)
|
void gp_present(G_Swapchain *gp_swapchain, Vec2I32 backbuffer_resolution, G_Resource *texture, Xform texture_xf, i32 vsync)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct swapchain *swapchain = (struct swapchain *)gp_swapchain;
|
struct swapchain *swapchain = (struct swapchain *)gp_swapchain;
|
||||||
|
|||||||
@ -479,7 +479,7 @@ internal f64 interpret_number(String src)
|
|||||||
if (whole_present) {
|
if (whole_present) {
|
||||||
u64 pos = whole_left;
|
u64 pos = whole_left;
|
||||||
while (pos <= whole_right) {
|
while (pos <= whole_right) {
|
||||||
u8 digit = min_u8(src.text[pos] - 48, 9);
|
u8 digit = MinU8(src.text[pos] - 48, 9);
|
||||||
u64 exp = whole_right - pos;
|
u64 exp = whole_right - pos;
|
||||||
res += digit * math_pow_u64(10, exp);
|
res += digit * math_pow_u64(10, exp);
|
||||||
++pos;
|
++pos;
|
||||||
@ -492,7 +492,7 @@ internal f64 interpret_number(String src)
|
|||||||
u64 frac_whole = 0;
|
u64 frac_whole = 0;
|
||||||
u64 pos = fraction_left;
|
u64 pos = fraction_left;
|
||||||
while (pos <= fraction_right) {
|
while (pos <= fraction_right) {
|
||||||
u8 digit = min_u8(src.text[pos] - 48, 9);
|
u8 digit = MinU8(src.text[pos] - 48, 9);
|
||||||
u64 exp = fraction_right - pos;
|
u64 exp = fraction_right - pos;
|
||||||
frac_whole += digit * math_pow_u64(10, exp);
|
frac_whole += digit * math_pow_u64(10, exp);
|
||||||
++pos;
|
++pos;
|
||||||
@ -506,7 +506,7 @@ internal f64 interpret_number(String src)
|
|||||||
u64 exponent_whole = 0;
|
u64 exponent_whole = 0;
|
||||||
u64 pos = exponent_left;
|
u64 pos = exponent_left;
|
||||||
while (pos <= exponent_right) {
|
while (pos <= exponent_right) {
|
||||||
u8 digit = min_u8(src.text[pos] - 48, 9);
|
u8 digit = MinU8(src.text[pos] - 48, 9);
|
||||||
u64 exp = exponent_right - pos;
|
u64 exp = exponent_right - pos;
|
||||||
exponent_whole += digit * math_pow_u64(10, exp);
|
exponent_whole += digit * math_pow_u64(10, exp);
|
||||||
++pos;
|
++pos;
|
||||||
|
|||||||
@ -56,14 +56,14 @@ Inline struct K_float K_FloatFromF32(f32 v)
|
|||||||
|
|
||||||
typedef struct K_float2 K_float2;
|
typedef struct K_float2 K_float2;
|
||||||
struct K_float2 { f32 v[2]; };
|
struct K_float2 { f32 v[2]; };
|
||||||
Inline struct K_float2 K_Float2FromV2(V2 v)
|
Inline struct K_float2 K_Float2FromV2(Vec2 v)
|
||||||
{
|
{
|
||||||
return (struct K_float2) { .v[0] = v.x, .v[1] = v.y };
|
return (struct K_float2) { .v[0] = v.x, .v[1] = v.y };
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct K_float3 K_float3;
|
typedef struct K_float3 K_float3;
|
||||||
struct K_float3 { f32 v[3]; };
|
struct K_float3 { f32 v[3]; };
|
||||||
Inline struct K_float3 K_Float3FromV3(V3 v)
|
Inline struct K_float3 K_Float3FromV3(Vec3 v)
|
||||||
{
|
{
|
||||||
return (struct K_float3) { .v[0] = v.x, .v[1] = v.y, .v[2] = v.z };
|
return (struct K_float3) { .v[0] = v.x, .v[1] = v.y, .v[2] = v.z };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,8 +48,8 @@ Global struct {
|
|||||||
P_Mutex mutex;
|
P_Mutex mutex;
|
||||||
|
|
||||||
/* Listener */
|
/* Listener */
|
||||||
V2 listener_pos;
|
Vec2 listener_pos;
|
||||||
V2 listener_dir;
|
Vec2 listener_dir;
|
||||||
|
|
||||||
/* Track list */
|
/* Track list */
|
||||||
Arena *track_arena;
|
Arena *track_arena;
|
||||||
@ -67,8 +67,8 @@ M_StartupReceipt mixer_startup(void)
|
|||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
G.track_arena = AllocArena(Gibi(64));
|
G.track_arena = AllocArena(Gibi(64));
|
||||||
G.listener_pos = V2FromXY(0, 0);
|
G.listener_pos = V2(0, 0);
|
||||||
G.listener_dir = V2FromXY(0, -1);
|
G.listener_dir = V2(0, -1);
|
||||||
return (M_StartupReceipt) { 0 };
|
return (M_StartupReceipt) { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ void mixer_track_set(M_Handle handle, M_TrackDesc desc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mixer_set_listener(V2 pos, V2 dir)
|
void mixer_set_listener(Vec2 pos, Vec2 dir)
|
||||||
{
|
{
|
||||||
P_Lock lock = P_LockE(&G.mutex);
|
P_Lock lock = P_LockE(&G.mutex);
|
||||||
{
|
{
|
||||||
@ -267,8 +267,8 @@ M_PcmF32 mixer_update(Arena *arena, u64 frame_count)
|
|||||||
res.count = frame_count * 2;
|
res.count = frame_count * 2;
|
||||||
res.samples = PushArray(arena, f32, res.count);
|
res.samples = PushArray(arena, f32, res.count);
|
||||||
|
|
||||||
V2 listener_pos = V2FromXY(0, 0);
|
Vec2 listener_pos = V2(0, 0);
|
||||||
V2 listener_dir = V2FromXY(0, 0);
|
Vec2 listener_dir = V2(0, 0);
|
||||||
|
|
||||||
/* Create temp array of mixes */
|
/* Create temp array of mixes */
|
||||||
struct mix **mixes = 0;
|
struct mix **mixes = 0;
|
||||||
@ -305,7 +305,7 @@ M_PcmF32 mixer_update(Arena *arena, u64 frame_count)
|
|||||||
M_TrackDesc desc = mix->desc;
|
M_TrackDesc desc = mix->desc;
|
||||||
struct effect_data *effect_data = &mix->effect_data;
|
struct effect_data *effect_data = &mix->effect_data;
|
||||||
b32 source_is_stereo = source->flags & SOUND_FLAG_STEREO;
|
b32 source_is_stereo = source->flags & SOUND_FLAG_STEREO;
|
||||||
f32 speed = max_f32(0, desc.speed);
|
f32 speed = MaxF32(0, desc.speed);
|
||||||
|
|
||||||
/* Determine sample range */
|
/* Determine sample range */
|
||||||
u64 source_samples_count = 0;
|
u64 source_samples_count = 0;
|
||||||
@ -407,14 +407,14 @@ M_PcmF32 mixer_update(Arena *arena, u64 frame_count)
|
|||||||
const f32 rolloff_scale = 6.0f;
|
const f32 rolloff_scale = 6.0f;
|
||||||
const f32 pan_scale = 0.75;
|
const f32 pan_scale = 0.75;
|
||||||
|
|
||||||
V2 pos = desc.pos;
|
Vec2 pos = desc.pos;
|
||||||
|
|
||||||
/* If sound pos = listener pos, pretend sound is close in front of listener. */
|
/* If sound pos = listener pos, pretend sound is close in front of listener. */
|
||||||
if (v2_eq(listener_pos, pos)) {
|
if (v2_eq(listener_pos, pos)) {
|
||||||
pos = v2_add(listener_pos, v2_mul(listener_dir, 0.001f));
|
pos = v2_add(listener_pos, v2_mul(listener_dir, 0.001f));
|
||||||
}
|
}
|
||||||
V2 sound_rel = v2_sub(pos, listener_pos);
|
Vec2 sound_rel = v2_sub(pos, listener_pos);
|
||||||
V2 sound_rel_dir = v2_norm(sound_rel);
|
Vec2 sound_rel_dir = v2_norm(sound_rel);
|
||||||
|
|
||||||
/* Calculate volume */
|
/* Calculate volume */
|
||||||
f32 volume_start = effect_data->spatial_volume;
|
f32 volume_start = effect_data->spatial_volume;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
.speed = 1.0, \
|
.speed = 1.0, \
|
||||||
.looping = 0, \
|
.looping = 0, \
|
||||||
\
|
\
|
||||||
.pos = V2FromXY(0, 0), \
|
.pos = V2(0, 0), \
|
||||||
\
|
\
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
})
|
})
|
||||||
@ -20,7 +20,7 @@ Struct(M_TrackDesc) {
|
|||||||
b32 looping;
|
b32 looping;
|
||||||
|
|
||||||
/* MIXER_FLAG_SPATIALIZE */
|
/* MIXER_FLAG_SPATIALIZE */
|
||||||
V2 pos;
|
Vec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(M_Handle) {
|
Struct(M_Handle) {
|
||||||
@ -42,7 +42,7 @@ M_Handle mixer_play(SND_Sound *sound);
|
|||||||
M_Handle mixer_play_ex(SND_Sound *sound, M_TrackDesc desc);
|
M_Handle mixer_play_ex(SND_Sound *sound, M_TrackDesc desc);
|
||||||
M_TrackDesc mixer_track_get(M_Handle handle);
|
M_TrackDesc mixer_track_get(M_Handle handle);
|
||||||
void mixer_track_set(M_Handle handle, M_TrackDesc desc);
|
void mixer_track_set(M_Handle handle, M_TrackDesc desc);
|
||||||
void mixer_set_listener(V2 pos, V2 dir);
|
void mixer_set_listener(Vec2 pos, Vec2 dir);
|
||||||
|
|
||||||
/* Mixing */
|
/* Mixing */
|
||||||
M_PcmF32 mixer_update(Arena *arena, u64 frame_request_count);
|
M_PcmF32 mixer_update(Arena *arena, u64 frame_request_count);
|
||||||
|
|||||||
@ -248,10 +248,10 @@ Struct(P_WindowEvent)
|
|||||||
u32 text_codepoint;
|
u32 text_codepoint;
|
||||||
|
|
||||||
/* P_WindowEventKind_CURSOR_MOVE */
|
/* P_WindowEventKind_CURSOR_MOVE */
|
||||||
V2 cursor_position;
|
Vec2 cursor_position;
|
||||||
|
|
||||||
/* P_WindowEventKind_MOUSE_MOVE */
|
/* P_WindowEventKind_MOUSE_MOVE */
|
||||||
V2 mouse_delta;
|
Vec2 mouse_delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(P_WindowEventArray)
|
Struct(P_WindowEventArray)
|
||||||
@ -421,7 +421,7 @@ P_WindowEventArray P_PopWindowEvents(Arena *arena, P_Window *window);
|
|||||||
void P_UpdateWindowSettings(P_Window *window, P_WindowSettings *settings);
|
void P_UpdateWindowSettings(P_Window *window, P_WindowSettings *settings);
|
||||||
P_WindowSettings P_GetWindowSettings(P_Window *window);
|
P_WindowSettings P_GetWindowSettings(P_Window *window);
|
||||||
void P_ShowWindow(P_Window *window);
|
void P_ShowWindow(P_Window *window);
|
||||||
void P_SetWindowCursorPos(P_Window *window, V2 pos);
|
void P_SetWindowCursorPos(P_Window *window, Vec2 pos);
|
||||||
void P_ShowWindowCursor(P_Window *window);
|
void P_ShowWindowCursor(P_Window *window);
|
||||||
void P_HideWindowCursor(P_Window *window);
|
void P_HideWindowCursor(P_Window *window);
|
||||||
void P_EnableWindoweCursorClip(P_Window *window, Rect bounds);
|
void P_EnableWindoweCursorClip(P_Window *window, Rect bounds);
|
||||||
@ -429,8 +429,8 @@ void P_DisableWindoweCursorClip(P_Window *window);
|
|||||||
void P_ToggleWindowTopmost(P_Window *window);
|
void P_ToggleWindowTopmost(P_Window *window);
|
||||||
|
|
||||||
//- Window info
|
//- Window info
|
||||||
V2 P_GetWindowSize(P_Window *window);
|
Vec2 P_GetWindowSize(P_Window *window);
|
||||||
V2 P_GetWindowMonitorSize(P_Window *window);
|
Vec2 P_GetWindowMonitorSize(P_Window *window);
|
||||||
u64 P_GetInternalWindowHandle(P_Window *window);
|
u64 P_GetInternalWindowHandle(P_Window *window);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|||||||
@ -104,13 +104,13 @@ P_W32_Thread *P_W32_AllocThread(P_W32_ThreadFunc *entry_point, void *thread_data
|
|||||||
|
|
||||||
/* Copy thread name to params */
|
/* Copy thread name to params */
|
||||||
{
|
{
|
||||||
u64 cstr_len = min_u64((countof(t->thread_name_cstr) - 1), thread_name.len);
|
u64 cstr_len = MinU64((countof(t->thread_name_cstr) - 1), thread_name.len);
|
||||||
MEMCPY(t->thread_name_cstr, thread_name.text, cstr_len * sizeof(*t->thread_name_cstr));
|
MEMCPY(t->thread_name_cstr, thread_name.text, cstr_len * sizeof(*t->thread_name_cstr));
|
||||||
t->thread_name_cstr[cstr_len] = 0;
|
t->thread_name_cstr[cstr_len] = 0;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
String16 thread_name16 = string16_from_string(scratch.arena, thread_name);
|
String16 thread_name16 = string16_from_string(scratch.arena, thread_name);
|
||||||
u64 wstr_len = min_u64((countof(t->thread_name_wstr) - 1), thread_name16.len);
|
u64 wstr_len = MinU64((countof(t->thread_name_wstr) - 1), thread_name16.len);
|
||||||
MEMCPY(t->thread_name_wstr, thread_name16.text, wstr_len * sizeof(*t->thread_name_wstr));
|
MEMCPY(t->thread_name_wstr, thread_name16.text, wstr_len * sizeof(*t->thread_name_wstr));
|
||||||
t->thread_name_wstr[wstr_len] = 0;
|
t->thread_name_wstr[wstr_len] = 0;
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ b32 P_W32_TryReleaseThread(P_W32_Thread *thread, f32 timeout_seconds)
|
|||||||
void P_W32_WaitReleaseThread(P_W32_Thread *thread)
|
void P_W32_WaitReleaseThread(P_W32_Thread *thread)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
b32 success = P_W32_TryReleaseThread(thread, F32_INFINITY);
|
b32 success = P_W32_TryReleaseThread(thread, F32Infinity);
|
||||||
Assert(success);
|
Assert(success);
|
||||||
(UNUSED)success;
|
(UNUSED)success;
|
||||||
}
|
}
|
||||||
@ -907,7 +907,7 @@ P_W32_ThreadDef(P_W32_JobWorkerEntryFunc, worker_ctx_arg)
|
|||||||
{
|
{
|
||||||
u64 current_scheduler_cycle = Atomic64Fetch(&g->current_scheduler_cycle.v);
|
u64 current_scheduler_cycle = Atomic64Fetch(&g->current_scheduler_cycle.v);
|
||||||
i64 current_scheduler_cycle_period_ns = Atomic64Fetch(&g->current_scheduler_cycle_period_ns.v);
|
i64 current_scheduler_cycle_period_ns = Atomic64Fetch(&g->current_scheduler_cycle_period_ns.v);
|
||||||
wait_time = current_scheduler_cycle + max_i64((i64)((f64)wait_timeout_ns / (f64)current_scheduler_cycle_period_ns), 1);
|
wait_time = current_scheduler_cycle + MaxI64((i64)((f64)wait_timeout_ns / (f64)current_scheduler_cycle_period_ns), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 wait_addr_bin_index = (u64)wait_addr % P_W32_NumWaitAddrBins;
|
u64 wait_addr_bin_index = (u64)wait_addr % P_W32_NumWaitAddrBins;
|
||||||
@ -1537,7 +1537,7 @@ LRESULT CALLBACK P_W32_Win32WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
|
|||||||
/* Update position */
|
/* Update position */
|
||||||
if (cursor_flags & P_W32_CursorFlag_Position)
|
if (cursor_flags & P_W32_CursorFlag_Position)
|
||||||
{
|
{
|
||||||
V2 window_space_pos = window->cursor_set_position;
|
Vec2 window_space_pos = window->cursor_set_position;
|
||||||
POINT p = { window_space_pos.x, window_space_pos.y };
|
POINT p = { window_space_pos.x, window_space_pos.y };
|
||||||
ClientToScreen(window->hwnd, &p);
|
ClientToScreen(window->hwnd, &p);
|
||||||
SetCursorPos(p.x, p.y);
|
SetCursorPos(p.x, p.y);
|
||||||
@ -1557,10 +1557,10 @@ LRESULT CALLBACK P_W32_Win32WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
|
|||||||
i32 top = window->y + math_round_to_int(window->cursor_clip_bounds.y);
|
i32 top = window->y + math_round_to_int(window->cursor_clip_bounds.y);
|
||||||
i32 bottom = top + math_round_to_int(window->cursor_clip_bounds.height);
|
i32 bottom = top + math_round_to_int(window->cursor_clip_bounds.height);
|
||||||
RECT clip = {
|
RECT clip = {
|
||||||
.left = clamp_i32(left, window->x, window->x + window->width),
|
.left = ClampI32(left, window->x, window->x + window->width),
|
||||||
.right = clamp_i32(right, window->x, window->x + window->width),
|
.right = ClampI32(right, window->x, window->x + window->width),
|
||||||
.top = clamp_i32(top, window->y, window->y + window->height),
|
.top = ClampI32(top, window->y, window->y + window->height),
|
||||||
.bottom = clamp_i32(bottom, window->y, window->y + window->height)
|
.bottom = ClampI32(bottom, window->y, window->y + window->height)
|
||||||
};
|
};
|
||||||
ClipCursor(&clip);
|
ClipCursor(&clip);
|
||||||
}
|
}
|
||||||
@ -1789,7 +1789,7 @@ LRESULT CALLBACK P_W32_Win32WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
|
|||||||
(P_WindowEvent)
|
(P_WindowEvent)
|
||||||
{
|
{
|
||||||
.kind = P_WindowEventKind_CursorMove,
|
.kind = P_WindowEventKind_CursorMove,
|
||||||
.cursor_position = V2FromXY(x, y)
|
.cursor_position = V2(x, y)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} break;
|
} break;
|
||||||
@ -1815,7 +1815,7 @@ LRESULT CALLBACK P_W32_Win32WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
|
|||||||
{
|
{
|
||||||
i32 x = raw.data.mouse.lLastX;
|
i32 x = raw.data.mouse.lLastX;
|
||||||
i32 y = raw.data.mouse.lLastY;
|
i32 y = raw.data.mouse.lLastY;
|
||||||
V2 delta = V2FromXY(x, y);
|
Vec2 delta = V2(x, y);
|
||||||
P_W32_ProcessWindowEvent(
|
P_W32_ProcessWindowEvent(
|
||||||
window,
|
window,
|
||||||
(P_WindowEvent)
|
(P_WindowEvent)
|
||||||
@ -1995,7 +1995,7 @@ void P_Run(i32 count, P_JobFunc *func, void *sig, P_Pool pool_kind, P_Priority p
|
|||||||
P_CounterAdd(counter, count);
|
P_CounterAdd(counter, count);
|
||||||
}
|
}
|
||||||
P_W32_Fiber *fiber = P_W32_FiberFromId(FiberId());
|
P_W32_Fiber *fiber = P_W32_FiberFromId(FiberId());
|
||||||
priority = clamp_i32(priority, fiber->job_priority, P_Priority_Count - 1); /* A job cannot create a job with a higher priority than itself */
|
priority = ClampI32(priority, fiber->job_priority, P_Priority_Count - 1); /* A job cannot create a job with a higher priority than itself */
|
||||||
if (pool_kind == P_Pool_Inherit)
|
if (pool_kind == P_Pool_Inherit)
|
||||||
{
|
{
|
||||||
pool_kind = fiber->job_pool;
|
pool_kind = fiber->job_pool;
|
||||||
@ -2700,7 +2700,7 @@ void P_ShowWindow(P_Window *p_window)
|
|||||||
P_Unlock(&lock);
|
P_Unlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_SetWindowCursorPos(P_Window *p_window, V2 pos)
|
void P_SetWindowCursorPos(P_Window *p_window, Vec2 pos)
|
||||||
{
|
{
|
||||||
P_W32_Window *window = (P_W32_Window *)p_window;
|
P_W32_Window *window = (P_W32_Window *)p_window;
|
||||||
window->cursor_set_position = pos;
|
window->cursor_set_position = pos;
|
||||||
@ -2745,16 +2745,16 @@ void P_ToggleWindowTopmost(P_Window *p_window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//- Window info
|
//- Window info
|
||||||
V2 P_GetWindowSize(P_Window *p_window)
|
Vec2 P_GetWindowSize(P_Window *p_window)
|
||||||
{
|
{
|
||||||
P_W32_Window *window = (P_W32_Window *)p_window;
|
P_W32_Window *window = (P_W32_Window *)p_window;
|
||||||
return V2FromXY((f32)window->width, (f32)window->height);
|
return V2((f32)window->width, (f32)window->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
V2 P_GetWindowMonitorSize(P_Window *p_window)
|
Vec2 P_GetWindowMonitorSize(P_Window *p_window)
|
||||||
{
|
{
|
||||||
P_W32_Window *window = (P_W32_Window *)p_window;
|
P_W32_Window *window = (P_W32_Window *)p_window;
|
||||||
return V2FromXY((f32)window->monitor_width, (f32)window->monitor_height);
|
return V2((f32)window->monitor_width, (f32)window->monitor_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 P_GetInternalWindowHandle(P_Window *p_window)
|
u64 P_GetInternalWindowHandle(P_Window *p_window)
|
||||||
@ -2831,7 +2831,7 @@ P_Address P_AddressFromString(String str)
|
|||||||
}
|
}
|
||||||
u64 ip_len = 0;
|
u64 ip_len = 0;
|
||||||
u64 port_len = 0;
|
u64 port_len = 0;
|
||||||
u64 parse_len = min_u64(min_u64(str.len, countof(ip_buff) - 1), countof(port_buff) - 1);
|
u64 parse_len = MinU64(MinU64(str.len, countof(ip_buff) - 1), countof(port_buff) - 1);
|
||||||
if (colon_count > 1 && str.text[0] == '[')
|
if (colon_count > 1 && str.text[0] == '[')
|
||||||
{
|
{
|
||||||
/* Parse ipv6 with port */
|
/* Parse ipv6 with port */
|
||||||
@ -2887,7 +2887,7 @@ P_Address P_AddressFromString(String str)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Copy address without port */
|
/* Copy address without port */
|
||||||
ip_len = min_u64(str.len, countof(ip_buff) - 1);
|
ip_len = MinU64(str.len, countof(ip_buff) - 1);
|
||||||
MEMCPY(ip_buff, str.text, ip_len);
|
MEMCPY(ip_buff, str.text, ip_len);
|
||||||
}
|
}
|
||||||
if (ip_len > 0)
|
if (ip_len > 0)
|
||||||
@ -3253,7 +3253,7 @@ void P_Panic(String msg)
|
|||||||
u64 wstr_len = 0;
|
u64 wstr_len = 0;
|
||||||
|
|
||||||
wchar_t prefix[] = L"A fatal error has occured and the application needs to exit:\n\n";
|
wchar_t prefix[] = L"A fatal error has occured and the application needs to exit:\n\n";
|
||||||
MEMCPY(wstr, prefix, min_u64(countof(g->panic_wstr), (countof(prefix) << 1)));
|
MEMCPY(wstr, prefix, MinU64(countof(g->panic_wstr), (countof(prefix) << 1)));
|
||||||
wstr_len += countof(prefix) - 1;
|
wstr_len += countof(prefix) - 1;
|
||||||
|
|
||||||
/* Perform manual string encode to avoid any implicit memory
|
/* Perform manual string encode to avoid any implicit memory
|
||||||
|
|||||||
@ -224,7 +224,7 @@ Struct(P_W32_Window)
|
|||||||
/* FIXME: Use a cmd buffer for updating cursor (and maybe also settings).
|
/* FIXME: Use a cmd buffer for updating cursor (and maybe also settings).
|
||||||
* Current setup means cursor_set calls can be applied out of order */
|
* Current setup means cursor_set calls can be applied out of order */
|
||||||
u32 cursor_set_flags;
|
u32 cursor_set_flags;
|
||||||
V2 cursor_set_position;
|
Vec2 cursor_set_position;
|
||||||
Rect cursor_clip_bounds;
|
Rect cursor_clip_bounds;
|
||||||
|
|
||||||
Atomic32 topmost_toggles;
|
Atomic32 topmost_toggles;
|
||||||
|
|||||||
@ -76,13 +76,13 @@ SimStartupReceipt sim_startup(void)
|
|||||||
G.nil_ent->ss = sim_snapshot_nil();
|
G.nil_ent->ss = sim_snapshot_nil();
|
||||||
G.nil_ent->valid = 0;
|
G.nil_ent->valid = 0;
|
||||||
G.nil_ent->id = SIM_ENT_NIL_ID;
|
G.nil_ent->id = SIM_ENT_NIL_ID;
|
||||||
G.nil_ent->_local_xform = XFORM_IDENT;
|
G.nil_ent->_local_xform = XformIdentity;
|
||||||
G.nil_ent->_xform = XFORM_IDENT;
|
G.nil_ent->_xform = XformIdentity;
|
||||||
G.nil_ent->_is_xform_dirty = 0;
|
G.nil_ent->_is_xform_dirty = 0;
|
||||||
G.nil_ent->friction = 0.5f;
|
G.nil_ent->friction = 0.5f;
|
||||||
G.nil_ent->mass_unscaled = 1;
|
G.nil_ent->mass_unscaled = 1;
|
||||||
G.nil_ent->inertia_unscaled = 1;
|
G.nil_ent->inertia_unscaled = 1;
|
||||||
G.nil_ent->sprite_local_xform = XFORM_IDENT;
|
G.nil_ent->sprite_local_xform = XformIdentity;
|
||||||
G.nil_ent->sprite_tint = ColorWhite;
|
G.nil_ent->sprite_tint = ColorWhite;
|
||||||
|
|
||||||
/* Lock nil arena */
|
/* Lock nil arena */
|
||||||
@ -343,8 +343,8 @@ Snapshot *sim_snapshot_alloc(Client *client, Snapshot *src, u64 tick)
|
|||||||
root->ss = ss;
|
root->ss = ss;
|
||||||
root->valid = 1;
|
root->valid = 1;
|
||||||
root->is_root = 1;
|
root->is_root = 1;
|
||||||
root->mass_unscaled = F32_INFINITY;
|
root->mass_unscaled = F32Infinity;
|
||||||
root->inertia_unscaled = F32_INFINITY;
|
root->inertia_unscaled = F32Infinity;
|
||||||
sim_ent_set_id(root, SIM_ENT_ROOT_ID);
|
sim_ent_set_id(root, SIM_ENT_ROOT_ID);
|
||||||
++ss->num_ents_allocated;
|
++ss->num_ents_allocated;
|
||||||
++ss->num_ents_reserved;
|
++ss->num_ents_reserved;
|
||||||
@ -540,26 +540,26 @@ Snapshot *sim_snapshot_from_closest_tick_gte(Client *client, u64 tick)
|
|||||||
* Tile
|
* Tile
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
V2I32 sim_world_tile_index_from_pos(V2 pos)
|
Vec2I32 sim_world_tile_index_from_pos(Vec2 pos)
|
||||||
{
|
{
|
||||||
V2I32 res = V2I32FromXY(pos.x * SIM_TILES_PER_UNIT_SQRT, pos.y * SIM_TILES_PER_UNIT_SQRT);
|
Vec2I32 res = V2I32(pos.x * SIM_TILES_PER_UNIT_SQRT, pos.y * SIM_TILES_PER_UNIT_SQRT);
|
||||||
res.x -= pos.x < 0;
|
res.x -= pos.x < 0;
|
||||||
res.y -= pos.y < 0;
|
res.y -= pos.y < 0;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2 sim_pos_from_world_tile_index(V2I32 world_tile_index)
|
Vec2 sim_pos_from_world_tile_index(Vec2I32 world_tile_index)
|
||||||
{
|
{
|
||||||
V2 res = ZI;
|
Vec2 res = ZI;
|
||||||
f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT;
|
f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT;
|
||||||
res.x = (f32)world_tile_index.x * tile_size;
|
res.x = (f32)world_tile_index.x * tile_size;
|
||||||
res.y = (f32)world_tile_index.y * tile_size;
|
res.y = (f32)world_tile_index.y * tile_size;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2I32 sim_local_tile_index_from_world_tile_index(V2I32 world_tile_index)
|
Vec2I32 sim_local_tile_index_from_world_tile_index(Vec2I32 world_tile_index)
|
||||||
{
|
{
|
||||||
V2I32 res = world_tile_index;
|
Vec2I32 res = world_tile_index;
|
||||||
res.x += res.x < 0;
|
res.x += res.x < 0;
|
||||||
res.y += res.y < 0;
|
res.y += res.y < 0;
|
||||||
res.x = res.x % SIM_TILES_PER_CHUNK_SQRT;
|
res.x = res.x % SIM_TILES_PER_CHUNK_SQRT;
|
||||||
@ -569,17 +569,17 @@ V2I32 sim_local_tile_index_from_world_tile_index(V2I32 world_tile_index)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2I32 sim_world_tile_index_from_local_tile_index(V2I32 tile_chunk_index, V2I32 local_tile_index)
|
Vec2I32 sim_world_tile_index_from_local_tile_index(Vec2I32 tile_chunk_index, Vec2I32 local_tile_index)
|
||||||
{
|
{
|
||||||
V2I32 res = ZI;
|
Vec2I32 res = ZI;
|
||||||
res.x = (tile_chunk_index.x * SIM_TILES_PER_CHUNK_SQRT) + local_tile_index.x;
|
res.x = (tile_chunk_index.x * SIM_TILES_PER_CHUNK_SQRT) + local_tile_index.x;
|
||||||
res.y = (tile_chunk_index.y * SIM_TILES_PER_CHUNK_SQRT) + local_tile_index.y;
|
res.y = (tile_chunk_index.y * SIM_TILES_PER_CHUNK_SQRT) + local_tile_index.y;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2I32 sim_tile_chunk_index_from_world_tile_index(V2I32 world_tile_index)
|
Vec2I32 sim_tile_chunk_index_from_world_tile_index(Vec2I32 world_tile_index)
|
||||||
{
|
{
|
||||||
V2I32 res = world_tile_index;
|
Vec2I32 res = world_tile_index;
|
||||||
res.x += res.x < 0;
|
res.x += res.x < 0;
|
||||||
res.y += res.y < 0;
|
res.y += res.y < 0;
|
||||||
res.x = res.x / SIM_TILES_PER_CHUNK_SQRT;
|
res.x = res.x / SIM_TILES_PER_CHUNK_SQRT;
|
||||||
@ -589,9 +589,9 @@ V2I32 sim_tile_chunk_index_from_world_tile_index(V2I32 world_tile_index)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_snapshot_set_tile(Snapshot *ss, V2I32 world_tile_index, TileKind tile_kind)
|
void sim_snapshot_set_tile(Snapshot *ss, Vec2I32 world_tile_index, TileKind tile_kind)
|
||||||
{
|
{
|
||||||
V2I32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
|
Vec2I32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
|
||||||
|
|
||||||
EntId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
|
EntId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
|
||||||
Ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
|
Ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
|
||||||
@ -602,7 +602,7 @@ void sim_snapshot_set_tile(Snapshot *ss, V2I32 world_tile_index, TileKind tile_k
|
|||||||
chunk_ent->tile_chunk_index = chunk_index;
|
chunk_ent->tile_chunk_index = chunk_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2I32 local_index = sim_local_tile_index_from_world_tile_index(world_tile_index);
|
Vec2I32 local_index = sim_local_tile_index_from_world_tile_index(world_tile_index);
|
||||||
chunk_ent->tile_chunk_tiles[local_index.x + (local_index.y * SIM_TILES_PER_CHUNK_SQRT)] = tile_kind;
|
chunk_ent->tile_chunk_tiles[local_index.x + (local_index.y * SIM_TILES_PER_CHUNK_SQRT)] = tile_kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,7 +643,7 @@ Snapshot *sim_snapshot_alloc_from_lerp(Client *client, Snapshot *ss0, Snapshot *
|
|||||||
/* Blend entities */
|
/* Blend entities */
|
||||||
{
|
{
|
||||||
__profn("Lerp snapshot entities");
|
__profn("Lerp snapshot entities");
|
||||||
u64 num_entities = min_u64(ss0->num_ents_reserved, ss1->num_ents_reserved);
|
u64 num_entities = MinU64(ss0->num_ents_reserved, ss1->num_ents_reserved);
|
||||||
for (u64 i = 0; i < num_entities; ++i) {
|
for (u64 i = 0; i < num_entities; ++i) {
|
||||||
Ent *e = &ss->ents[i];
|
Ent *e = &ss->ents[i];
|
||||||
Ent *e0 = &ss0->ents[i];
|
Ent *e0 = &ss0->ents[i];
|
||||||
|
|||||||
@ -157,9 +157,9 @@ typedef i32 ControlFlag; enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Struct(ControlData) {
|
Struct(ControlData) {
|
||||||
V2 move; /* Movement direction vector (speed of 0 -> 1) */
|
Vec2 move; /* Movement direction vector (speed of 0 -> 1) */
|
||||||
V2 focus; /* Focus direction vector (where does the controller want to look) */
|
Vec2 focus; /* Focus direction vector (where does the controller want to look) */
|
||||||
V2 dbg_cursor; /* Where is the user's cursor in the world (used for things like editing the world) */
|
Vec2 dbg_cursor; /* Where is the user's cursor in the world (used for things like editing the world) */
|
||||||
u32 flags;
|
u32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -233,12 +233,12 @@ Snapshot *sim_snapshot_from_closest_tick_lte(Client *client, u64 tick);
|
|||||||
Snapshot *sim_snapshot_from_closest_tick_gte(Client *client, u64 tick);
|
Snapshot *sim_snapshot_from_closest_tick_gte(Client *client, u64 tick);
|
||||||
|
|
||||||
/* Tile */
|
/* Tile */
|
||||||
V2I32 sim_world_tile_index_from_pos(V2 pos);
|
Vec2I32 sim_world_tile_index_from_pos(Vec2 pos);
|
||||||
V2 sim_pos_from_world_tile_index(V2I32 world_tile_index);
|
Vec2 sim_pos_from_world_tile_index(Vec2I32 world_tile_index);
|
||||||
V2I32 sim_local_tile_index_from_world_tile_index(V2I32 world_tile_index);
|
Vec2I32 sim_local_tile_index_from_world_tile_index(Vec2I32 world_tile_index);
|
||||||
V2I32 sim_world_tile_index_from_local_tile_index(V2I32 tile_chunk_index, V2I32 local_tile_index);
|
Vec2I32 sim_world_tile_index_from_local_tile_index(Vec2I32 tile_chunk_index, Vec2I32 local_tile_index);
|
||||||
V2I32 sim_tile_chunk_index_from_world_tile_index(V2I32 world_tile_index);
|
Vec2I32 sim_tile_chunk_index_from_world_tile_index(Vec2I32 world_tile_index);
|
||||||
void sim_snapshot_set_tile(Snapshot *ss, V2I32 world_tile_index, TileKind tile_kind);
|
void sim_snapshot_set_tile(Snapshot *ss, Vec2I32 world_tile_index, TileKind tile_kind);
|
||||||
|
|
||||||
/* Lerp */
|
/* Lerp */
|
||||||
Snapshot *sim_snapshot_alloc_from_lerp(Client *client, Snapshot *ss0, Snapshot *ss1, f64 blend);
|
Snapshot *sim_snapshot_alloc_from_lerp(Client *client, Snapshot *ss0, Snapshot *ss1, f64 blend);
|
||||||
|
|||||||
@ -289,7 +289,7 @@ EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the deterministic id of the tile chunk that should be produced at chunk pos */
|
/* Returns the deterministic id of the tile chunk that should be produced at chunk pos */
|
||||||
EntId sim_ent_tile_chunk_id_from_tile_chunk_index(V2I32 chunk_index)
|
EntId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_index)
|
||||||
{
|
{
|
||||||
EntId res = ZI;
|
EntId res = ZI;
|
||||||
res.uid = SIM_ENT_TILE_CHUNK_BASIS_UID;
|
res.uid = SIM_ENT_TILE_CHUNK_BASIS_UID;
|
||||||
@ -421,7 +421,7 @@ internal Xform sim_ent_get_xform_internal(Snapshot *ss, Ent *ent)
|
|||||||
} else {
|
} else {
|
||||||
Ent *parent = sim_ent_from_id(ss, ent->parent);
|
Ent *parent = sim_ent_from_id(ss, ent->parent);
|
||||||
xf = sim_ent_get_xform_internal(ss, parent);
|
xf = sim_ent_get_xform_internal(ss, parent);
|
||||||
xf = xform_mul(xf, ent->_local_xform);
|
xf = MulXform(xf, ent->_local_xform);
|
||||||
ent->_xform = xf;
|
ent->_xform = xf;
|
||||||
ent->_is_xform_dirty = 0;
|
ent->_is_xform_dirty = 0;
|
||||||
}
|
}
|
||||||
@ -443,7 +443,7 @@ Xform sim_ent_get_xform(Ent *ent)
|
|||||||
Snapshot *ss = ent->ss;
|
Snapshot *ss = ent->ss;
|
||||||
Ent *parent = sim_ent_from_id(ss, ent->parent);
|
Ent *parent = sim_ent_from_id(ss, ent->parent);
|
||||||
xf = sim_ent_get_xform_internal(ss, parent);
|
xf = sim_ent_get_xform_internal(ss, parent);
|
||||||
xf = xform_mul(xf, ent->_local_xform);
|
xf = MulXform(xf, ent->_local_xform);
|
||||||
ent->_xform = xf;
|
ent->_xform = xf;
|
||||||
ent->_is_xform_dirty = 0;
|
ent->_is_xform_dirty = 0;
|
||||||
}
|
}
|
||||||
@ -462,7 +462,7 @@ Xform sim_ent_get_local_xform(Ent *ent)
|
|||||||
|
|
||||||
void sim_ent_set_xform(Ent *ent, Xform xf)
|
void sim_ent_set_xform(Ent *ent, Xform xf)
|
||||||
{
|
{
|
||||||
if (!xform_eq(xf, ent->_xform)) {
|
if (!XformEq(xf, ent->_xform)) {
|
||||||
Snapshot *ss = ent->ss;
|
Snapshot *ss = ent->ss;
|
||||||
/* Update local xform */
|
/* Update local xform */
|
||||||
if (ent->is_top) {
|
if (ent->is_top) {
|
||||||
@ -470,7 +470,7 @@ void sim_ent_set_xform(Ent *ent, Xform xf)
|
|||||||
} else {
|
} else {
|
||||||
Ent *parent = sim_ent_from_id(ss, ent->parent);
|
Ent *parent = sim_ent_from_id(ss, ent->parent);
|
||||||
Xform parent_global = sim_ent_get_xform_internal(ss, parent);
|
Xform parent_global = sim_ent_get_xform_internal(ss, parent);
|
||||||
ent->_local_xform = xform_mul(xform_invert(parent_global), xf);
|
ent->_local_xform = MulXform(InvertXform(parent_global), xf);
|
||||||
}
|
}
|
||||||
ent->_xform = xf;
|
ent->_xform = xf;
|
||||||
ent->_is_xform_dirty = 0;
|
ent->_is_xform_dirty = 0;
|
||||||
@ -480,7 +480,7 @@ void sim_ent_set_xform(Ent *ent, Xform xf)
|
|||||||
|
|
||||||
void sim_ent_set_local_xform(Ent *ent, Xform xf)
|
void sim_ent_set_local_xform(Ent *ent, Xform xf)
|
||||||
{
|
{
|
||||||
if (!xform_eq(xf, ent->_local_xform)) {
|
if (!XformEq(xf, ent->_local_xform)) {
|
||||||
ent->_local_xform = xf;
|
ent->_local_xform = xf;
|
||||||
ent->_is_xform_dirty = 1;
|
ent->_is_xform_dirty = 1;
|
||||||
sim_ent_mark_child_xforms_dirty(ent->ss, ent);
|
sim_ent_mark_child_xforms_dirty(ent->ss, ent);
|
||||||
@ -491,7 +491,7 @@ void sim_ent_set_local_xform(Ent *ent, Xform xf)
|
|||||||
* Ent movement
|
* Ent movement
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
void sim_ent_set_linear_velocity(Ent *ent, V2 velocity)
|
void sim_ent_set_linear_velocity(Ent *ent, Vec2 velocity)
|
||||||
{
|
{
|
||||||
if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
ent->linear_velocity = v2_clamp_len(velocity, SIM_MAX_LINEAR_VELOCITY);
|
ent->linear_velocity = v2_clamp_len(velocity, SIM_MAX_LINEAR_VELOCITY);
|
||||||
@ -501,37 +501,37 @@ void sim_ent_set_linear_velocity(Ent *ent, V2 velocity)
|
|||||||
void sim_ent_set_angular_velocity(Ent *ent, f32 velocity)
|
void sim_ent_set_angular_velocity(Ent *ent, f32 velocity)
|
||||||
{
|
{
|
||||||
if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
if (sim_ent_has_prop(ent, SEPROP_KINEMATIC) || sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
ent->angular_velocity = clamp_f32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_VELOCITY);
|
ent->angular_velocity = ClampF32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_VELOCITY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_ent_apply_linear_impulse(Ent *ent, V2 impulse, V2 point)
|
void sim_ent_apply_linear_impulse(Ent *ent, Vec2 impulse, Vec2 point)
|
||||||
{
|
{
|
||||||
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
V2 center = xf.og;
|
Vec2 center = xf.og;
|
||||||
f32 scale = math_fabs(xform_get_determinant(xf));
|
f32 scale = math_fabs(GetXformDeterminant(xf));
|
||||||
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
|
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
|
||||||
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
|
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
|
||||||
|
|
||||||
V2 vcp = v2_sub(point, center);
|
Vec2 vcp = v2_sub(point, center);
|
||||||
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
|
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
|
||||||
sim_ent_set_angular_velocity(ent, v2_wedge(vcp, impulse) * inv_inertia);
|
sim_ent_set_angular_velocity(ent, v2_wedge(vcp, impulse) * inv_inertia);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_ent_apply_linear_impulse_to_center(Ent *ent, V2 impulse)
|
void sim_ent_apply_linear_impulse_to_center(Ent *ent, Vec2 impulse)
|
||||||
{
|
{
|
||||||
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
f32 scale = math_fabs(xform_get_determinant(xf));
|
f32 scale = math_fabs(GetXformDeterminant(xf));
|
||||||
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
|
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
|
||||||
|
|
||||||
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
|
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_ent_apply_force_to_center(Ent *ent, V2 force)
|
void sim_ent_apply_force_to_center(Ent *ent, Vec2 force)
|
||||||
{
|
{
|
||||||
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
ent->force = v2_add(ent->force, force);
|
ent->force = v2_add(ent->force, force);
|
||||||
@ -542,7 +542,7 @@ void sim_ent_apply_angular_impulse(Ent *ent, f32 impulse)
|
|||||||
{
|
{
|
||||||
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
f32 scale = math_fabs(xform_get_determinant(xf));
|
f32 scale = math_fabs(GetXformDeterminant(xf));
|
||||||
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
|
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
|
||||||
sim_ent_set_angular_velocity(ent, ent->angular_velocity + impulse * inv_inertia);
|
sim_ent_set_angular_velocity(ent, ent->angular_velocity + impulse * inv_inertia);
|
||||||
}
|
}
|
||||||
@ -559,21 +559,21 @@ void sim_ent_apply_torque(Ent *ent, f32 torque)
|
|||||||
* Tile
|
* Tile
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
Ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, V2I32 chunk_index)
|
Ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, Vec2I32 chunk_index)
|
||||||
{
|
{
|
||||||
EntId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
|
EntId chunk_id = sim_ent_tile_chunk_id_from_tile_chunk_index(chunk_index);
|
||||||
Ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
|
Ent *chunk_ent = sim_ent_from_id(ss, chunk_id);
|
||||||
return chunk_ent;
|
return chunk_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, V2I32 world_tile_index)
|
Ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, Vec2I32 world_tile_index)
|
||||||
{
|
{
|
||||||
V2I32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
|
Vec2I32 chunk_index = sim_tile_chunk_index_from_world_tile_index(world_tile_index);
|
||||||
Ent *chunk_ent = sim_tile_chunk_from_chunk_index(ss, chunk_index);
|
Ent *chunk_ent = sim_tile_chunk_from_chunk_index(ss, chunk_index);
|
||||||
return chunk_ent;
|
return chunk_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
TileKind sim_get_chunk_tile(Ent *chunk_ent, V2I32 local_tile_index)
|
TileKind sim_get_chunk_tile(Ent *chunk_ent, Vec2I32 local_tile_index)
|
||||||
{
|
{
|
||||||
TileKind res = chunk_ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
|
TileKind res = chunk_ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
|
||||||
return res;
|
return res;
|
||||||
@ -588,13 +588,13 @@ void sim_ent_lerp(Ent *e, Ent *e0, Ent *e1, f64 blend)
|
|||||||
if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)
|
if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)
|
||||||
&& sim_ent_id_eq(e0->id, e1->id)
|
&& sim_ent_id_eq(e0->id, e1->id)
|
||||||
&& e0->continuity_gen == e1->continuity_gen) {
|
&& e0->continuity_gen == e1->continuity_gen) {
|
||||||
e->_local_xform = xform_lerp(e0->_local_xform, e1->_local_xform, blend);
|
e->_local_xform = LerpXform(e0->_local_xform, e1->_local_xform, blend);
|
||||||
|
|
||||||
if (e->is_top) {
|
if (e->is_top) {
|
||||||
/* TODO: Cache parent & child xforms in sim */
|
/* TODO: Cache parent & child xforms in sim */
|
||||||
Xform e0_xf = sim_ent_get_xform(e0);
|
Xform e0_xf = sim_ent_get_xform(e0);
|
||||||
Xform e1_xf = sim_ent_get_xform(e1);
|
Xform e1_xf = sim_ent_get_xform(e1);
|
||||||
sim_ent_set_xform(e, xform_lerp(e0_xf, e1_xf, blend));
|
sim_ent_set_xform(e, LerpXform(e0_xf, e1_xf, blend));
|
||||||
}
|
}
|
||||||
|
|
||||||
e->control_force = math_lerp_f32(e0->control_force, e1->control_force, blend);
|
e->control_force = math_lerp_f32(e0->control_force, e1->control_force, blend);
|
||||||
@ -606,12 +606,12 @@ void sim_ent_lerp(Ent *e, Ent *e0, Ent *e1, f64 blend)
|
|||||||
e->control.move = v2_lerp(e0->control.move, e1->control.move, blend);
|
e->control.move = v2_lerp(e0->control.move, e1->control.move, blend);
|
||||||
e->control.focus = v2_lerp(e0->control.focus, e1->control.focus, blend);
|
e->control.focus = v2_lerp(e0->control.focus, e1->control.focus, blend);
|
||||||
|
|
||||||
e->sprite_local_xform = xform_lerp(e0->sprite_local_xform, e1->sprite_local_xform, blend);
|
e->sprite_local_xform = LerpXform(e0->sprite_local_xform, e1->sprite_local_xform, blend);
|
||||||
e->animation_last_frame_change_time_ns = math_lerp_i64(e0->animation_last_frame_change_time_ns, e1->animation_last_frame_change_time_ns, (f64)blend);
|
e->animation_last_frame_change_time_ns = math_lerp_i64(e0->animation_last_frame_change_time_ns, e1->animation_last_frame_change_time_ns, (f64)blend);
|
||||||
e->animation_frame = (u32)math_round_to_int(math_lerp_f32(e0->animation_frame, e1->animation_frame, blend));
|
e->animation_frame = (u32)math_round_to_int(math_lerp_f32(e0->animation_frame, e1->animation_frame, blend));
|
||||||
|
|
||||||
e->camera_quad_xform = xform_lerp(e0->camera_quad_xform, e1->camera_quad_xform, blend);
|
e->camera_quad_xform = LerpXform(e0->camera_quad_xform, e1->camera_quad_xform, blend);
|
||||||
e->camera_xform_target = xform_lerp(e0->camera_xform_target, e1->camera_xform_target, blend);
|
e->camera_xform_target = LerpXform(e0->camera_xform_target, e1->camera_xform_target, blend);
|
||||||
e->shake = math_lerp_f32(e0->shake, e1->shake, blend);
|
e->shake = math_lerp_f32(e0->shake, e1->shake, blend);
|
||||||
|
|
||||||
e->tracer_gradient_start = v2_lerp(e0->tracer_gradient_start, e1->tracer_gradient_start, blend);
|
e->tracer_gradient_start = v2_lerp(e0->tracer_gradient_start, e1->tracer_gradient_start, blend);
|
||||||
@ -697,7 +697,7 @@ void sim_ent_encode(BB_Writer *bw, Ent *e0, Ent *e1)
|
|||||||
u64 pos = 0;
|
u64 pos = 0;
|
||||||
e1->ss = e0->ss;
|
e1->ss = e0->ss;
|
||||||
while (pos < sizeof(*e1)) {
|
while (pos < sizeof(*e1)) {
|
||||||
u64 chunk_size = min_u64(pos + 8, sizeof(*e1)) - pos;
|
u64 chunk_size = MinU64(pos + 8, sizeof(*e1)) - pos;
|
||||||
u8 *chunk0 = (u8 *)e0 + pos;
|
u8 *chunk0 = (u8 *)e0 + pos;
|
||||||
u8 *chunk1 = (u8 *)e1 + pos;
|
u8 *chunk1 = (u8 *)e1 + pos;
|
||||||
if (BB_WriteBit(bw, !MEMEQ(chunk0, chunk1, chunk_size))) {
|
if (BB_WriteBit(bw, !MEMEQ(chunk0, chunk1, chunk_size))) {
|
||||||
@ -722,7 +722,7 @@ void sim_ent_decode(BB_Reader *br, Ent *e)
|
|||||||
while (pos < sizeof(*e)) {
|
while (pos < sizeof(*e)) {
|
||||||
u8 *chunk = (u8 *)e + pos;
|
u8 *chunk = (u8 *)e + pos;
|
||||||
if (BB_ReadBit(br)) {
|
if (BB_ReadBit(br)) {
|
||||||
u64 chunk_size = min_u64(pos + 8, sizeof(*e)) - pos;
|
u64 chunk_size = MinU64(pos + 8, sizeof(*e)) - pos;
|
||||||
u64 bits = BB_ReadUBits(br, 64);
|
u64 bits = BB_ReadUBits(br, 64);
|
||||||
MEMCPY(chunk, &bits, chunk_size);
|
MEMCPY(chunk, &bits, chunk_size);
|
||||||
}
|
}
|
||||||
@ -752,7 +752,7 @@ void sim_ent_encode(BB_Writer *bw, Ent *e0, Ent *e1)
|
|||||||
u64 pos = 0;
|
u64 pos = 0;
|
||||||
e1->ss = e0->ss;
|
e1->ss = e0->ss;
|
||||||
while (pos < sizeof(*e1)) {
|
while (pos < sizeof(*e1)) {
|
||||||
u64 chunk_size = min_u64(pos + 8, sizeof(*e1)) - pos;
|
u64 chunk_size = MinU64(pos + 8, sizeof(*e1)) - pos;
|
||||||
u8 *chunk0 = (u8 *)e0 + pos;
|
u8 *chunk0 = (u8 *)e0 + pos;
|
||||||
u8 *chunk1 = (u8 *)e1 + pos;
|
u8 *chunk1 = (u8 *)e1 + pos;
|
||||||
if (MEMEQ(chunk0, chunk1, chunk_size)) {
|
if (MEMEQ(chunk0, chunk1, chunk_size)) {
|
||||||
@ -780,7 +780,7 @@ void sim_ent_decode(BB_Reader *br, Ent *e)
|
|||||||
while (pos < sizeof(decoded)) {
|
while (pos < sizeof(decoded)) {
|
||||||
u8 *chunk = (u8 *)&decoded + pos;
|
u8 *chunk = (u8 *)&decoded + pos;
|
||||||
if (BB_ReadBit(br)) {
|
if (BB_ReadBit(br)) {
|
||||||
u64 chunk_size = min_u64(pos + 8, sizeof(decoded)) - pos;
|
u64 chunk_size = MinU64(pos + 8, sizeof(decoded)) - pos;
|
||||||
u64 bits = BB_ReadUBits(br, 64);
|
u64 bits = BB_ReadUBits(br, 64);
|
||||||
MEMCPY(chunk, &bits, chunk_size);
|
MEMCPY(chunk, &bits, chunk_size);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -157,7 +157,7 @@ Struct(Ent) {
|
|||||||
|
|
||||||
/* FIXME: Move out of here */
|
/* FIXME: Move out of here */
|
||||||
u8 tile_chunk_tiles[SIM_TILES_PER_CHUNK_SQRT * SIM_TILES_PER_CHUNK_SQRT];
|
u8 tile_chunk_tiles[SIM_TILES_PER_CHUNK_SQRT * SIM_TILES_PER_CHUNK_SQRT];
|
||||||
V2I32 tile_chunk_index;
|
Vec2I32 tile_chunk_index;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Client */
|
/* Client */
|
||||||
@ -169,7 +169,7 @@ Struct(Ent) {
|
|||||||
ClientHandle player_client_handle; /* The client handle on the master sim's machine */
|
ClientHandle player_client_handle; /* The client handle on the master sim's machine */
|
||||||
|
|
||||||
ControlData player_control;
|
ControlData player_control;
|
||||||
V2 player_cursor_pos;
|
Vec2 player_cursor_pos;
|
||||||
|
|
||||||
EntId player_hovered_ent;
|
EntId player_hovered_ent;
|
||||||
EntId player_control_ent;
|
EntId player_control_ent;
|
||||||
@ -186,7 +186,7 @@ Struct(Ent) {
|
|||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Collider */
|
/* Collider */
|
||||||
|
|
||||||
V2 collision_dir; /* If set, then only collisions coming from this direction will generate contacts (used for walls to prevent ghost collisions) */
|
Vec2 collision_dir; /* If set, then only collisions coming from this direction will generate contacts (used for walls to prevent ghost collisions) */
|
||||||
CLD_Shape local_collider;
|
CLD_Shape local_collider;
|
||||||
|
|
||||||
#if COLLIDER_DEBUG
|
#if COLLIDER_DEBUG
|
||||||
@ -244,10 +244,10 @@ Struct(Ent) {
|
|||||||
f32 angular_ground_friction;
|
f32 angular_ground_friction;
|
||||||
|
|
||||||
/* Use sim_ent_set_linear_velocity & sim_ent_set_angular_velocity to set */
|
/* Use sim_ent_set_linear_velocity & sim_ent_set_angular_velocity to set */
|
||||||
V2 linear_velocity; /* m/s */
|
Vec2 linear_velocity; /* m/s */
|
||||||
f32 angular_velocity; /* rad/s */
|
f32 angular_velocity; /* rad/s */
|
||||||
|
|
||||||
V2 force;
|
Vec2 force;
|
||||||
f32 torque;
|
f32 torque;
|
||||||
|
|
||||||
f32 linear_damping;
|
f32 linear_damping;
|
||||||
@ -259,7 +259,7 @@ Struct(Ent) {
|
|||||||
S_Tag sprite;
|
S_Tag sprite;
|
||||||
String sprite_span_name;
|
String sprite_span_name;
|
||||||
u32 sprite_tint;
|
u32 sprite_tint;
|
||||||
V3 sprite_emittance;
|
Vec3 sprite_emittance;
|
||||||
|
|
||||||
String sprite_collider_slice; /* Collider will sync to bounds of this slice if set */
|
String sprite_collider_slice; /* Collider will sync to bounds of this slice if set */
|
||||||
|
|
||||||
@ -327,8 +327,8 @@ Struct(Ent) {
|
|||||||
|
|
||||||
EntId bullet_src;
|
EntId bullet_src;
|
||||||
EntId bullet_tracer;
|
EntId bullet_tracer;
|
||||||
V2 bullet_src_pos;
|
Vec2 bullet_src_pos;
|
||||||
V2 bullet_src_dir;
|
Vec2 bullet_src_dir;
|
||||||
f32 bullet_launch_velocity;
|
f32 bullet_launch_velocity;
|
||||||
f32 bullet_knockback;
|
f32 bullet_knockback;
|
||||||
f32 bullet_explosion_strength;
|
f32 bullet_explosion_strength;
|
||||||
@ -346,13 +346,13 @@ Struct(Ent) {
|
|||||||
|
|
||||||
/* SEPROP_TRACER */
|
/* SEPROP_TRACER */
|
||||||
|
|
||||||
V2 tracer_start;
|
Vec2 tracer_start;
|
||||||
V2 tracer_start_velocity;
|
Vec2 tracer_start_velocity;
|
||||||
f32 tracer_fade_duration; /* Time for tracer to fade from opacity of 1 to 0 */
|
f32 tracer_fade_duration; /* Time for tracer to fade from opacity of 1 to 0 */
|
||||||
|
|
||||||
/* calculated each frame */
|
/* calculated each frame */
|
||||||
V2 tracer_gradient_start;
|
Vec2 tracer_gradient_start;
|
||||||
V2 tracer_gradient_end;
|
Vec2 tracer_gradient_end;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Quake */
|
/* Quake */
|
||||||
@ -508,7 +508,7 @@ Ent *sim_ent_from_id(Snapshot *ss, EntId id);
|
|||||||
EntId sim_ent_random_id(void);
|
EntId sim_ent_random_id(void);
|
||||||
EntId sim_ent_contact_constraint_id_from_contacting_ids(EntId player_id, EntId id0, EntId id1);
|
EntId sim_ent_contact_constraint_id_from_contacting_ids(EntId player_id, EntId id0, EntId id1);
|
||||||
EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1);
|
EntId sim_ent_collision_debug_id_from_ids(EntId player_id, EntId id0, EntId id1);
|
||||||
EntId sim_ent_tile_chunk_id_from_tile_chunk_index(V2I32 chunk_start);
|
EntId sim_ent_tile_chunk_id_from_tile_chunk_index(Vec2I32 chunk_start);
|
||||||
|
|
||||||
/* Query */
|
/* Query */
|
||||||
Ent *sim_ent_find_first_match_one(Snapshot *ss, EntProp prop);
|
Ent *sim_ent_find_first_match_one(Snapshot *ss, EntProp prop);
|
||||||
@ -525,18 +525,18 @@ void sim_ent_set_xform(Ent *ent, Xform xf);
|
|||||||
void sim_ent_set_local_xform(Ent *ent, Xform xf);
|
void sim_ent_set_local_xform(Ent *ent, Xform xf);
|
||||||
|
|
||||||
/* Movement */
|
/* Movement */
|
||||||
void sim_ent_set_linear_velocity(Ent *ent, V2 velocity);
|
void sim_ent_set_linear_velocity(Ent *ent, Vec2 velocity);
|
||||||
void sim_ent_set_angular_velocity(Ent *ent, f32 velocity);
|
void sim_ent_set_angular_velocity(Ent *ent, f32 velocity);
|
||||||
void sim_ent_apply_linear_impulse(Ent *ent, V2 impulse, V2 world_point);
|
void sim_ent_apply_linear_impulse(Ent *ent, Vec2 impulse, Vec2 world_point);
|
||||||
void sim_ent_apply_linear_impulse_to_center(Ent *ent, V2 impulse);
|
void sim_ent_apply_linear_impulse_to_center(Ent *ent, Vec2 impulse);
|
||||||
void sim_ent_apply_force_to_center(Ent *ent, V2 force);
|
void sim_ent_apply_force_to_center(Ent *ent, Vec2 force);
|
||||||
void sim_ent_apply_angular_impulse(Ent *ent, f32 impulse);
|
void sim_ent_apply_angular_impulse(Ent *ent, f32 impulse);
|
||||||
void sim_ent_apply_torque(Ent *ent, f32 torque);
|
void sim_ent_apply_torque(Ent *ent, f32 torque);
|
||||||
|
|
||||||
/* Tile */
|
/* Tile */
|
||||||
Ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, V2I32 chunk_index);
|
Ent *sim_tile_chunk_from_chunk_index(Snapshot *ss, Vec2I32 chunk_index);
|
||||||
Ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, V2I32 world_tile_index);
|
Ent *sim_tile_chunk_from_world_tile_index(Snapshot *ss, Vec2I32 world_tile_index);
|
||||||
TileKind sim_get_chunk_tile(Ent *chunk_ent, V2I32 local_tile_index);
|
TileKind sim_get_chunk_tile(Ent *chunk_ent, Vec2I32 local_tile_index);
|
||||||
|
|
||||||
/* Lerp */
|
/* Lerp */
|
||||||
void sim_ent_lerp(Ent *e, Ent *e0, Ent *e1, f64 blend);
|
void sim_ent_lerp(Ent *e, Ent *e0, Ent *e1, f64 blend);
|
||||||
|
|||||||
@ -130,7 +130,7 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
|
|||||||
/* Update / insert returned contacts */
|
/* Update / insert returned contacts */
|
||||||
for (u32 i = 0; i < collider_res.num_points; ++i) {
|
for (u32 i = 0; i < collider_res.num_points; ++i) {
|
||||||
CLD_CollisionPoint *res_point = &collider_res.points[i];
|
CLD_CollisionPoint *res_point = &collider_res.points[i];
|
||||||
V2 point = res_point->point;
|
Vec2 point = res_point->point;
|
||||||
f32 sep = res_point->separation;
|
f32 sep = res_point->separation;
|
||||||
u32 id = res_point->id;
|
u32 id = res_point->id;
|
||||||
ContactPoint *contact = 0;
|
ContactPoint *contact = 0;
|
||||||
@ -162,9 +162,9 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
|
|||||||
|
|
||||||
/* Skip solve based on collision direction */
|
/* Skip solve based on collision direction */
|
||||||
{
|
{
|
||||||
V2 normal = collider_res.normal;
|
Vec2 normal = collider_res.normal;
|
||||||
V2 dir0 = e0->collision_dir;
|
Vec2 dir0 = e0->collision_dir;
|
||||||
V2 dir1 = e1->collision_dir;
|
Vec2 dir1 = e1->collision_dir;
|
||||||
f32 threshold = 0.5;
|
f32 threshold = 0.5;
|
||||||
b32 is_wrong_dir = 0;
|
b32 is_wrong_dir = 0;
|
||||||
if (!v2_is_zero(dir0)) {
|
if (!v2_is_zero(dir0)) {
|
||||||
@ -186,23 +186,23 @@ void phys_create_and_update_contacts(PhysStepCtx *ctx, f32 elapsed_dt, u64 phys_
|
|||||||
data.dt = elapsed_dt;
|
data.dt = elapsed_dt;
|
||||||
|
|
||||||
/* Calculate point */
|
/* Calculate point */
|
||||||
V2 midpoint = collider_res.points[0].point;
|
Vec2 midpoint = collider_res.points[0].point;
|
||||||
if (collider_res.num_points > 1) {
|
if (collider_res.num_points > 1) {
|
||||||
midpoint = v2_add(midpoint, v2_mul(v2_sub(collider_res.points[1].point, midpoint), 0.5f));
|
midpoint = v2_add(midpoint, v2_mul(v2_sub(collider_res.points[1].point, midpoint), 0.5f));
|
||||||
}
|
}
|
||||||
data.point = midpoint;
|
data.point = midpoint;
|
||||||
|
|
||||||
/* Calculate relative velocity */
|
/* Calculate relative velocity */
|
||||||
V2 vrel;
|
Vec2 vrel;
|
||||||
{
|
{
|
||||||
V2 v0 = e0->linear_velocity;
|
Vec2 v0 = e0->linear_velocity;
|
||||||
V2 v1 = e1->linear_velocity;
|
Vec2 v1 = e1->linear_velocity;
|
||||||
f32 w0 = e0->angular_velocity;
|
f32 w0 = e0->angular_velocity;
|
||||||
f32 w1 = e1->angular_velocity;
|
f32 w1 = e1->angular_velocity;
|
||||||
V2 vcp1 = v2_sub(midpoint, e1_xf.og);
|
Vec2 vcp1 = v2_sub(midpoint, e1_xf.og);
|
||||||
V2 vcp0 = v2_sub(midpoint, e0_xf.og);
|
Vec2 vcp0 = v2_sub(midpoint, e0_xf.og);
|
||||||
V2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
Vec2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
||||||
V2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
|
Vec2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
|
||||||
vrel = v2_sub(vel0, vel1);
|
vrel = v2_sub(vel0, vel1);
|
||||||
}
|
}
|
||||||
data.vrel = vrel;
|
data.vrel = vrel;
|
||||||
@ -281,8 +281,8 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration)
|
|||||||
Ent *e0 = sim_ent_from_id(ss, constraint->e0);
|
Ent *e0 = sim_ent_from_id(ss, constraint->e0);
|
||||||
Ent *e1 = sim_ent_from_id(ss, constraint->e1);
|
Ent *e1 = sim_ent_from_id(ss, constraint->e1);
|
||||||
if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
|
if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
|
||||||
V2 normal = constraint->normal;
|
Vec2 normal = constraint->normal;
|
||||||
V2 tangent = v2_perp(normal);
|
Vec2 tangent = v2_perp(normal);
|
||||||
|
|
||||||
Xform e0_xf = sim_ent_get_xform(e0);
|
Xform e0_xf = sim_ent_get_xform(e0);
|
||||||
Xform e1_xf = sim_ent_get_xform(e1);
|
Xform e1_xf = sim_ent_get_xform(e1);
|
||||||
@ -296,14 +296,14 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration)
|
|||||||
{
|
{
|
||||||
/* If not simulated locally or ent is not dynamic, pretend contact mass is infinite */
|
/* If not simulated locally or ent is not dynamic, pretend contact mass is infinite */
|
||||||
if (sim_ent_should_simulate(e0) && sim_ent_has_prop(e0, SEPROP_DYNAMIC)) {
|
if (sim_ent_should_simulate(e0) && sim_ent_has_prop(e0, SEPROP_DYNAMIC)) {
|
||||||
f32 scale = math_fabs(xform_get_determinant(e0_xf));
|
f32 scale = math_fabs(GetXformDeterminant(e0_xf));
|
||||||
f32 scaled_mass = e0->mass_unscaled * scale;
|
f32 scaled_mass = e0->mass_unscaled * scale;
|
||||||
f32 scaled_inertia = e0->inertia_unscaled * scale;
|
f32 scaled_inertia = e0->inertia_unscaled * scale;
|
||||||
inv_m0 = 1.f / scaled_mass;
|
inv_m0 = 1.f / scaled_mass;
|
||||||
inv_i0 = 1.f / scaled_inertia;
|
inv_i0 = 1.f / scaled_inertia;
|
||||||
}
|
}
|
||||||
if (sim_ent_should_simulate(e1) && sim_ent_has_prop(e1, SEPROP_DYNAMIC)) {
|
if (sim_ent_should_simulate(e1) && sim_ent_has_prop(e1, SEPROP_DYNAMIC)) {
|
||||||
f32 scale = math_fabs(xform_get_determinant(e1_xf));
|
f32 scale = math_fabs(GetXformDeterminant(e1_xf));
|
||||||
f32 scaled_mass = e1->mass_unscaled * scale;
|
f32 scaled_mass = e1->mass_unscaled * scale;
|
||||||
f32 scaled_inertia = e1->inertia_unscaled * scale;
|
f32 scaled_inertia = e1->inertia_unscaled * scale;
|
||||||
inv_m1 = 1.f / scaled_mass;
|
inv_m1 = 1.f / scaled_mass;
|
||||||
@ -319,8 +319,8 @@ void phys_prepare_contacts(PhysStepCtx *ctx, u64 phys_iteration)
|
|||||||
/* Update / insert returned contacts */
|
/* Update / insert returned contacts */
|
||||||
for (u32 i = 0; i < num_points; ++i) {
|
for (u32 i = 0; i < num_points; ++i) {
|
||||||
ContactPoint *contact = &constraint->points[i];
|
ContactPoint *contact = &constraint->points[i];
|
||||||
V2 vcp0 = contact->vcp0;
|
Vec2 vcp0 = contact->vcp0;
|
||||||
V2 vcp1 = contact->vcp1;
|
Vec2 vcp1 = contact->vcp1;
|
||||||
|
|
||||||
/* Normal mass */
|
/* Normal mass */
|
||||||
{
|
{
|
||||||
@ -396,21 +396,21 @@ void phys_warm_start_contacts(PhysStepCtx *ctx)
|
|||||||
f32 inv_i0 = constraint->inv_i0;
|
f32 inv_i0 = constraint->inv_i0;
|
||||||
f32 inv_i1 = constraint->inv_i1;
|
f32 inv_i1 = constraint->inv_i1;
|
||||||
|
|
||||||
V2 v0 = e0->linear_velocity;
|
Vec2 v0 = e0->linear_velocity;
|
||||||
V2 v1 = e1->linear_velocity;
|
Vec2 v1 = e1->linear_velocity;
|
||||||
f32 w0 = e0->angular_velocity;
|
f32 w0 = e0->angular_velocity;
|
||||||
f32 w1 = e1->angular_velocity;
|
f32 w1 = e1->angular_velocity;
|
||||||
|
|
||||||
/* Warm start */
|
/* Warm start */
|
||||||
V2 normal = constraint->normal;
|
Vec2 normal = constraint->normal;
|
||||||
V2 tangent = v2_perp(normal);
|
Vec2 tangent = v2_perp(normal);
|
||||||
f32 inv_num_points = 1.f / num_points;
|
f32 inv_num_points = 1.f / num_points;
|
||||||
for (u32 i = 0; i < num_points; ++i) {
|
for (u32 i = 0; i < num_points; ++i) {
|
||||||
ContactPoint *point = &constraint->points[i];
|
ContactPoint *point = &constraint->points[i];
|
||||||
V2 vcp0 = point->vcp0;
|
Vec2 vcp0 = point->vcp0;
|
||||||
V2 vcp1 = point->vcp1;
|
Vec2 vcp1 = point->vcp1;
|
||||||
|
|
||||||
V2 impulse = v2_add(v2_mul(normal, point->normal_impulse), v2_mul(tangent, point->tangent_impulse));
|
Vec2 impulse = v2_add(v2_mul(normal, point->normal_impulse), v2_mul(tangent, point->tangent_impulse));
|
||||||
impulse = v2_mul(impulse, inv_num_points);
|
impulse = v2_mul(impulse, inv_num_points);
|
||||||
|
|
||||||
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
|
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
|
||||||
@ -441,8 +441,8 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
|
|||||||
Ent *e0 = sim_ent_from_id(ss, constraint->e0);
|
Ent *e0 = sim_ent_from_id(ss, constraint->e0);
|
||||||
Ent *e1 = sim_ent_from_id(ss, constraint->e1);
|
Ent *e1 = sim_ent_from_id(ss, constraint->e1);
|
||||||
|
|
||||||
V2 v0 = e0->linear_velocity;
|
Vec2 v0 = e0->linear_velocity;
|
||||||
V2 v1 = e1->linear_velocity;
|
Vec2 v1 = e1->linear_velocity;
|
||||||
f32 w0 = e0->angular_velocity;
|
f32 w0 = e0->angular_velocity;
|
||||||
f32 w1 = e1->angular_velocity;
|
f32 w1 = e1->angular_velocity;
|
||||||
|
|
||||||
@ -457,13 +457,13 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
|
|||||||
f32 inv_i1 = constraint->inv_i1;
|
f32 inv_i1 = constraint->inv_i1;
|
||||||
|
|
||||||
/* Normal impulse */
|
/* Normal impulse */
|
||||||
V2 normal = constraint->normal;
|
Vec2 normal = constraint->normal;
|
||||||
for (u32 point_index = 0; point_index < num_points; ++point_index) {
|
for (u32 point_index = 0; point_index < num_points; ++point_index) {
|
||||||
ContactPoint *point = &constraint->points[point_index];
|
ContactPoint *point = &constraint->points[point_index];
|
||||||
V2 vcp0 = point->vcp0;
|
Vec2 vcp0 = point->vcp0;
|
||||||
V2 vcp1 = point->vcp1;
|
Vec2 vcp1 = point->vcp1;
|
||||||
V2 p0 = v2_add(e0_xf.og, vcp0);
|
Vec2 p0 = v2_add(e0_xf.og, vcp0);
|
||||||
V2 p1 = v2_add(e1_xf.og, vcp1);
|
Vec2 p1 = v2_add(e1_xf.og, vcp1);
|
||||||
|
|
||||||
/* FIXME: Should separation use the rotated contact points? */
|
/* FIXME: Should separation use the rotated contact points? */
|
||||||
f32 separation = v2_dot(v2_sub(p1, p0), normal) + point->starting_separation;
|
f32 separation = v2_dot(v2_sub(p1, p0), normal) + point->starting_separation;
|
||||||
@ -481,12 +481,12 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
|
|||||||
f32 pushout_velocity = constraint->pushout_velocity;
|
f32 pushout_velocity = constraint->pushout_velocity;
|
||||||
mass_scale = softness.mass_scale;
|
mass_scale = softness.mass_scale;
|
||||||
impulse_scale = softness.impulse_scale;
|
impulse_scale = softness.impulse_scale;
|
||||||
velocity_bias = max_f32(softness.bias_rate * separation, -pushout_velocity);
|
velocity_bias = MaxF32(softness.bias_rate * separation, -pushout_velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
V2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
Vec2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
||||||
V2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
|
Vec2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
|
||||||
V2 vrel = v2_sub(vel0, vel1);
|
Vec2 vrel = v2_sub(vel0, vel1);
|
||||||
|
|
||||||
f32 k = point->inv_normal_mass;
|
f32 k = point->inv_normal_mass;
|
||||||
|
|
||||||
@ -495,11 +495,11 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
|
|||||||
f32 j = ((k * mass_scale) * (vn - velocity_bias)) - (point->normal_impulse * impulse_scale);
|
f32 j = ((k * mass_scale) * (vn - velocity_bias)) - (point->normal_impulse * impulse_scale);
|
||||||
|
|
||||||
f32 old_impulse = point->normal_impulse;
|
f32 old_impulse = point->normal_impulse;
|
||||||
f32 new_impulse = max_f32(old_impulse + j, 0);
|
f32 new_impulse = MaxF32(old_impulse + j, 0);
|
||||||
f32 delta = new_impulse - old_impulse;
|
f32 delta = new_impulse - old_impulse;
|
||||||
point->normal_impulse = new_impulse;
|
point->normal_impulse = new_impulse;
|
||||||
|
|
||||||
V2 impulse = v2_mul(normal, delta);
|
Vec2 impulse = v2_mul(normal, delta);
|
||||||
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
|
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
|
||||||
v1 = v2_add(v1, v2_mul(impulse, inv_m1));
|
v1 = v2_add(v1, v2_mul(impulse, inv_m1));
|
||||||
w0 -= v2_wedge(vcp0, impulse) * inv_i0;
|
w0 -= v2_wedge(vcp0, impulse) * inv_i0;
|
||||||
@ -507,15 +507,15 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Tangent impulse */
|
/* Tangent impulse */
|
||||||
V2 tangent = v2_perp(normal);
|
Vec2 tangent = v2_perp(normal);
|
||||||
for (u32 point_index = 0; point_index < num_points; ++point_index) {
|
for (u32 point_index = 0; point_index < num_points; ++point_index) {
|
||||||
ContactPoint *point = &constraint->points[point_index];
|
ContactPoint *point = &constraint->points[point_index];
|
||||||
V2 vcp0 = point->vcp0;
|
Vec2 vcp0 = point->vcp0;
|
||||||
V2 vcp1 = point->vcp1;
|
Vec2 vcp1 = point->vcp1;
|
||||||
|
|
||||||
V2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
Vec2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
||||||
V2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
|
Vec2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
|
||||||
V2 vrel = v2_sub(vel0, vel1);
|
Vec2 vrel = v2_sub(vel0, vel1);
|
||||||
|
|
||||||
f32 k = point->inv_tangent_mass;
|
f32 k = point->inv_tangent_mass;
|
||||||
|
|
||||||
@ -525,11 +525,11 @@ void phys_solve_contacts(PhysStepCtx *ctx, f32 dt, b32 apply_bias)
|
|||||||
|
|
||||||
f32 max_friction = constraint->friction * point->normal_impulse;
|
f32 max_friction = constraint->friction * point->normal_impulse;
|
||||||
f32 old_impulse = point->tangent_impulse;
|
f32 old_impulse = point->tangent_impulse;
|
||||||
f32 new_impulse = clamp_f32(old_impulse + j, -max_friction, max_friction);
|
f32 new_impulse = ClampF32(old_impulse + j, -max_friction, max_friction);
|
||||||
f32 delta = new_impulse - old_impulse;
|
f32 delta = new_impulse - old_impulse;
|
||||||
point->tangent_impulse = new_impulse;
|
point->tangent_impulse = new_impulse;
|
||||||
|
|
||||||
V2 impulse = v2_mul(tangent, delta);
|
Vec2 impulse = v2_mul(tangent, delta);
|
||||||
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
|
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
|
||||||
v1 = v2_add(v1, v2_mul(impulse, inv_m1));
|
v1 = v2_add(v1, v2_mul(impulse, inv_m1));
|
||||||
w0 -= v2_wedge(vcp0, impulse) * inv_i0;
|
w0 -= v2_wedge(vcp0, impulse) * inv_i0;
|
||||||
@ -559,7 +559,7 @@ MotorJoint phys_motor_joint_from_def(MotorJointDesc def)
|
|||||||
MotorJoint res = ZI;
|
MotorJoint res = ZI;
|
||||||
res.e0 = def.e0;
|
res.e0 = def.e0;
|
||||||
res.e1 = def.e1;
|
res.e1 = def.e1;
|
||||||
res.correction_rate = clamp_f32(def.correction_rate, 0, 1);
|
res.correction_rate = ClampF32(def.correction_rate, 0, 1);
|
||||||
res.max_force = def.max_force;
|
res.max_force = def.max_force;
|
||||||
res.max_torque = def.max_torque;
|
res.max_torque = def.max_torque;
|
||||||
return res;
|
return res;
|
||||||
@ -590,8 +590,8 @@ void phys_prepare_motor_joints(PhysStepCtx *ctx)
|
|||||||
f32 inv_i0;
|
f32 inv_i0;
|
||||||
f32 inv_i1;
|
f32 inv_i1;
|
||||||
{
|
{
|
||||||
f32 scale0 = math_fabs(xform_get_determinant(e0_xf));
|
f32 scale0 = math_fabs(GetXformDeterminant(e0_xf));
|
||||||
f32 scale1 = math_fabs(xform_get_determinant(e1_xf));
|
f32 scale1 = math_fabs(GetXformDeterminant(e1_xf));
|
||||||
inv_m0 = 1.f / (e0->mass_unscaled * scale0);
|
inv_m0 = 1.f / (e0->mass_unscaled * scale0);
|
||||||
inv_m1 = 1.f / (e1->mass_unscaled * scale1);
|
inv_m1 = 1.f / (e1->mass_unscaled * scale1);
|
||||||
inv_i0 = 1.f / (e0->inertia_unscaled * scale0);
|
inv_i0 = 1.f / (e0->inertia_unscaled * scale0);
|
||||||
@ -602,23 +602,23 @@ void phys_prepare_motor_joints(PhysStepCtx *ctx)
|
|||||||
joint->inv_i0 = inv_i0;
|
joint->inv_i0 = inv_i0;
|
||||||
joint->inv_i1 = inv_i1;
|
joint->inv_i1 = inv_i1;
|
||||||
|
|
||||||
joint->point_local_e0 = V2FromXY(0, 0);
|
joint->point_local_e0 = V2(0, 0);
|
||||||
joint->point_local_e1 = V2FromXY(0, 0);
|
joint->point_local_e1 = V2(0, 0);
|
||||||
|
|
||||||
V2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
|
Vec2 vcp0 = v2_sub(MulXformV2(e0_xf, joint->point_local_e0), e0_xf.og);
|
||||||
V2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
|
Vec2 vcp1 = v2_sub(MulXformV2(e1_xf, joint->point_local_e1), e1_xf.og);
|
||||||
|
|
||||||
Xform linear_mass_xf = ZI;
|
Xform linear_mass_xf = ZI;
|
||||||
linear_mass_xf.bx.x = inv_m0 + inv_m1 + vcp0.y * vcp0.y * inv_i0 + vcp1.y * vcp1.y * inv_i1;
|
linear_mass_xf.bx.x = inv_m0 + inv_m1 + vcp0.y * vcp0.y * inv_i0 + vcp1.y * vcp1.y * inv_i1;
|
||||||
linear_mass_xf.bx.y = -vcp0.y * vcp0.x * inv_i0 - vcp1.y * vcp1.x * inv_i1;
|
linear_mass_xf.bx.y = -vcp0.y * vcp0.x * inv_i0 - vcp1.y * vcp1.x * inv_i1;
|
||||||
linear_mass_xf.by.x = linear_mass_xf.bx.y;
|
linear_mass_xf.by.x = linear_mass_xf.bx.y;
|
||||||
linear_mass_xf.by.y = inv_m0 + inv_m1 + vcp0.x * vcp0.x * inv_i0 + vcp1.x * vcp1.x * inv_i1;
|
linear_mass_xf.by.y = inv_m0 + inv_m1 + vcp0.x * vcp0.x * inv_i0 + vcp1.x * vcp1.x * inv_i1;
|
||||||
joint->linear_mass_xf = xform_invert(linear_mass_xf);
|
joint->linear_mass_xf = InvertXform(linear_mass_xf);
|
||||||
|
|
||||||
joint->angular_mass = 1.f / (inv_i0 + inv_i1);
|
joint->angular_mass = 1.f / (inv_i0 + inv_i1);
|
||||||
|
|
||||||
#if !SIM_PHYSICS_ENABLE_WARM_STARTING
|
#if !SIM_PHYSICS_ENABLE_WARM_STARTING
|
||||||
joint->linear_impulse = V2FromXY(0, 0);
|
joint->linear_impulse = V2(0, 0);
|
||||||
joint->angular_impulse = 0;
|
joint->angular_impulse = 0;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -651,8 +651,8 @@ void phys_warm_start_motor_joints(PhysStepCtx *ctx)
|
|||||||
f32 inv_i0 = joint->inv_i0;
|
f32 inv_i0 = joint->inv_i0;
|
||||||
f32 inv_i1 = joint->inv_i1;
|
f32 inv_i1 = joint->inv_i1;
|
||||||
|
|
||||||
V2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
|
Vec2 vcp0 = v2_sub(MulXformV2(e0_xf, joint->point_local_e0), e0_xf.og);
|
||||||
V2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
|
Vec2 vcp1 = v2_sub(MulXformV2(e1_xf, joint->point_local_e1), e1_xf.og);
|
||||||
|
|
||||||
sim_ent_set_linear_velocity(e0, v2_sub(e0->linear_velocity, v2_mul(joint->linear_impulse, inv_m0)));
|
sim_ent_set_linear_velocity(e0, v2_sub(e0->linear_velocity, v2_mul(joint->linear_impulse, inv_m0)));
|
||||||
sim_ent_set_linear_velocity(e1, v2_add(e1->linear_velocity, v2_mul(joint->linear_impulse, inv_m1)));
|
sim_ent_set_linear_velocity(e1, v2_add(e1->linear_velocity, v2_mul(joint->linear_impulse, inv_m1)));
|
||||||
@ -683,8 +683,8 @@ void phys_solve_motor_joints(PhysStepCtx *ctx, f32 dt)
|
|||||||
f32 inv_i0 = joint->inv_i0;
|
f32 inv_i0 = joint->inv_i0;
|
||||||
f32 inv_i1 = joint->inv_i1;
|
f32 inv_i1 = joint->inv_i1;
|
||||||
|
|
||||||
V2 v0 = e0->linear_velocity;
|
Vec2 v0 = e0->linear_velocity;
|
||||||
V2 v1 = e1->linear_velocity;
|
Vec2 v1 = e1->linear_velocity;
|
||||||
f32 w0 = e0->angular_velocity;
|
f32 w0 = e0->angular_velocity;
|
||||||
f32 w1 = e1->angular_velocity;
|
f32 w1 = e1->angular_velocity;
|
||||||
|
|
||||||
@ -694,12 +694,12 @@ void phys_solve_motor_joints(PhysStepCtx *ctx, f32 dt)
|
|||||||
/* Angular constraint */
|
/* Angular constraint */
|
||||||
{
|
{
|
||||||
f32 max_impulse = joint->max_torque * dt;
|
f32 max_impulse = joint->max_torque * dt;
|
||||||
f32 angular_separation = math_unwind_angle(xform_get_rotation(e1_xf) - xform_get_rotation(e0_xf));
|
f32 angular_separation = math_unwind_angle(GetXformRotation(e1_xf) - GetXformRotation(e0_xf));
|
||||||
|
|
||||||
f32 angular_bias = angular_separation * correction_rate * inv_dt;
|
f32 angular_bias = angular_separation * correction_rate * inv_dt;
|
||||||
|
|
||||||
f32 old_impulse = joint->angular_impulse;
|
f32 old_impulse = joint->angular_impulse;
|
||||||
f32 new_impulse = clamp_f32(old_impulse + (-joint->angular_mass * (w1 - w0 + angular_bias)), -max_impulse, max_impulse);
|
f32 new_impulse = ClampF32(old_impulse + (-joint->angular_mass * (w1 - w0 + angular_bias)), -max_impulse, max_impulse);
|
||||||
joint->angular_impulse = new_impulse;
|
joint->angular_impulse = new_impulse;
|
||||||
|
|
||||||
f32 delta = new_impulse - old_impulse;
|
f32 delta = new_impulse - old_impulse;
|
||||||
@ -709,22 +709,22 @@ void phys_solve_motor_joints(PhysStepCtx *ctx, f32 dt)
|
|||||||
|
|
||||||
/* Linear constraint */
|
/* Linear constraint */
|
||||||
{
|
{
|
||||||
V2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
|
Vec2 vcp0 = v2_sub(MulXformV2(e0_xf, joint->point_local_e0), e0_xf.og);
|
||||||
V2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
|
Vec2 vcp1 = v2_sub(MulXformV2(e1_xf, joint->point_local_e1), e1_xf.og);
|
||||||
|
|
||||||
f32 max_impulse = joint->max_force * dt;
|
f32 max_impulse = joint->max_force * dt;
|
||||||
|
|
||||||
V2 linear_separation = v2_sub(v2_add(e1_xf.og, vcp1), v2_add(e0_xf.og, vcp0));
|
Vec2 linear_separation = v2_sub(v2_add(e1_xf.og, vcp1), v2_add(e0_xf.og, vcp0));
|
||||||
V2 linear_bias = v2_mul(linear_separation, correction_rate * inv_dt);
|
Vec2 linear_bias = v2_mul(linear_separation, correction_rate * inv_dt);
|
||||||
|
|
||||||
V2 vrel = v2_sub(v2_add(v1, v2_perp_mul(vcp1, w1)), v2_add(v0, v2_perp_mul(vcp0, w0)));
|
Vec2 vrel = v2_sub(v2_add(v1, v2_perp_mul(vcp1, w1)), v2_add(v0, v2_perp_mul(vcp0, w0)));
|
||||||
V2 impulse = v2_neg(xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vrel, linear_bias)));
|
Vec2 impulse = v2_neg(MulXformBasisV2(joint->linear_mass_xf, v2_add(vrel, linear_bias)));
|
||||||
|
|
||||||
V2 old_impulse = joint->linear_impulse;
|
Vec2 old_impulse = joint->linear_impulse;
|
||||||
V2 new_impulse = v2_clamp_len(v2_add(old_impulse, impulse), max_impulse);
|
Vec2 new_impulse = v2_clamp_len(v2_add(old_impulse, impulse), max_impulse);
|
||||||
joint->linear_impulse = new_impulse;
|
joint->linear_impulse = new_impulse;
|
||||||
|
|
||||||
V2 delta = v2_sub(new_impulse, old_impulse);
|
Vec2 delta = v2_sub(new_impulse, old_impulse);
|
||||||
v0 = v2_sub(v0, v2_mul(delta, inv_m0));
|
v0 = v2_sub(v0, v2_mul(delta, inv_m0));
|
||||||
v1 = v2_add(v1, v2_mul(delta, inv_m1));
|
v1 = v2_add(v1, v2_mul(delta, inv_m1));
|
||||||
w0 -= v2_wedge(vcp0, delta) * inv_i0;
|
w0 -= v2_wedge(vcp0, delta) * inv_i0;
|
||||||
@ -786,24 +786,24 @@ void phys_prepare_mouse_joints(PhysStepCtx *ctx)
|
|||||||
f32 inv_m;
|
f32 inv_m;
|
||||||
f32 inv_i;
|
f32 inv_i;
|
||||||
{
|
{
|
||||||
f32 scale = math_fabs(xform_get_determinant(xf));
|
f32 scale = math_fabs(GetXformDeterminant(xf));
|
||||||
inv_m = 1.f / (ent->mass_unscaled * scale);
|
inv_m = 1.f / (ent->mass_unscaled * scale);
|
||||||
inv_i = 1.f / (ent->inertia_unscaled * scale);
|
inv_i = 1.f / (ent->inertia_unscaled * scale);
|
||||||
}
|
}
|
||||||
joint->inv_m = inv_m;
|
joint->inv_m = inv_m;
|
||||||
joint->inv_i = inv_i;
|
joint->inv_i = inv_i;
|
||||||
|
|
||||||
V2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
|
Vec2 vcp = v2_sub(MulXformV2(xf, joint->point_local_start), xf.og);
|
||||||
|
|
||||||
Xform linear_mass_xf = ZI;
|
Xform linear_mass_xf = ZI;
|
||||||
linear_mass_xf.bx.x = inv_m + inv_i * vcp.y * vcp.y;
|
linear_mass_xf.bx.x = inv_m + inv_i * vcp.y * vcp.y;
|
||||||
linear_mass_xf.bx.y = -inv_i * vcp.x * vcp.y;
|
linear_mass_xf.bx.y = -inv_i * vcp.x * vcp.y;
|
||||||
linear_mass_xf.by.x = linear_mass_xf.bx.y;
|
linear_mass_xf.by.x = linear_mass_xf.bx.y;
|
||||||
linear_mass_xf.by.y = inv_m + inv_i * vcp.x * vcp.x;
|
linear_mass_xf.by.y = inv_m + inv_i * vcp.x * vcp.x;
|
||||||
joint->linear_mass_xf = xform_invert(linear_mass_xf);
|
joint->linear_mass_xf = InvertXform(linear_mass_xf);
|
||||||
|
|
||||||
#if !SIM_PHYSICS_ENABLE_WARM_STARTING
|
#if !SIM_PHYSICS_ENABLE_WARM_STARTING
|
||||||
joint->linear_impulse = V2FromXY(0, 0);
|
joint->linear_impulse = V2(0, 0);
|
||||||
joint->angular_impulse = 0;
|
joint->angular_impulse = 0;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -829,7 +829,7 @@ void phys_warm_start_mouse_joints(PhysStepCtx *ctx)
|
|||||||
f32 inv_m = joint->inv_m;
|
f32 inv_m = joint->inv_m;
|
||||||
f32 inv_i = joint->inv_i;
|
f32 inv_i = joint->inv_i;
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
V2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
|
Vec2 vcp = v2_sub(MulXformV2(xf, joint->point_local_start), xf.og);
|
||||||
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)));
|
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)));
|
||||||
sim_ent_set_angular_velocity(ent, ent->angular_velocity + ((v2_wedge(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i));
|
sim_ent_set_angular_velocity(ent, ent->angular_velocity + ((v2_wedge(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i));
|
||||||
}
|
}
|
||||||
@ -848,7 +848,7 @@ void phys_solve_mouse_joints(PhysStepCtx *ctx, f32 dt)
|
|||||||
MouseJoint *joint = &joint_ent->mouse_joint_data;
|
MouseJoint *joint = &joint_ent->mouse_joint_data;
|
||||||
Ent *ent = sim_ent_from_id(ss, joint->target);
|
Ent *ent = sim_ent_from_id(ss, joint->target);
|
||||||
if (sim_ent_should_simulate(ent)) {
|
if (sim_ent_should_simulate(ent)) {
|
||||||
V2 v = ent->linear_velocity;
|
Vec2 v = ent->linear_velocity;
|
||||||
f32 w = ent->angular_velocity;
|
f32 w = ent->angular_velocity;
|
||||||
|
|
||||||
f32 inv_m = joint->inv_m;
|
f32 inv_m = joint->inv_m;
|
||||||
@ -870,25 +870,25 @@ void phys_solve_mouse_joints(PhysStepCtx *ctx, f32 dt)
|
|||||||
|
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
|
|
||||||
V2 point_start = xform_mul_v2(xf, joint->point_local_start);
|
Vec2 point_start = MulXformV2(xf, joint->point_local_start);
|
||||||
V2 point_end = joint->point_end;
|
Vec2 point_end = joint->point_end;
|
||||||
|
|
||||||
V2 vcp = v2_sub(point_start, xf.og);
|
Vec2 vcp = v2_sub(point_start, xf.og);
|
||||||
V2 separation = v2_sub(point_start, point_end);
|
Vec2 separation = v2_sub(point_start, point_end);
|
||||||
|
|
||||||
SoftSpring softness = math_spring_init(joint->linear_spring_hz, joint->linear_spring_damp, dt);
|
SoftSpring softness = math_spring_init(joint->linear_spring_hz, joint->linear_spring_damp, dt);
|
||||||
f32 bias_rate = softness.bias_rate;
|
f32 bias_rate = softness.bias_rate;
|
||||||
f32 mass_scale = softness.mass_scale;
|
f32 mass_scale = softness.mass_scale;
|
||||||
f32 impulse_scale = softness.impulse_scale;
|
f32 impulse_scale = softness.impulse_scale;
|
||||||
|
|
||||||
V2 bias = v2_mul(separation, bias_rate);
|
Vec2 bias = v2_mul(separation, bias_rate);
|
||||||
V2 vel = v2_add(v, v2_perp_mul(vcp, w));
|
Vec2 vel = v2_add(v, v2_perp_mul(vcp, w));
|
||||||
V2 b = xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vel, bias));
|
Vec2 b = MulXformBasisV2(joint->linear_mass_xf, v2_add(vel, bias));
|
||||||
|
|
||||||
V2 impulse = v2_mul(b, -mass_scale);
|
Vec2 impulse = v2_mul(b, -mass_scale);
|
||||||
impulse = v2_sub(impulse, v2_mul(joint->linear_impulse, impulse_scale));
|
impulse = v2_sub(impulse, v2_mul(joint->linear_impulse, impulse_scale));
|
||||||
|
|
||||||
V2 old_impulse = joint->linear_impulse;
|
Vec2 old_impulse = joint->linear_impulse;
|
||||||
joint->linear_impulse = v2_add(joint->linear_impulse, impulse);
|
joint->linear_impulse = v2_add(joint->linear_impulse, impulse);
|
||||||
|
|
||||||
joint->linear_impulse = v2_clamp_len(joint->linear_impulse, max_impulse);
|
joint->linear_impulse = v2_clamp_len(joint->linear_impulse, max_impulse);
|
||||||
@ -955,8 +955,8 @@ void phys_prepare_weld_joints(PhysStepCtx *ctx)
|
|||||||
f32 inv_i0;
|
f32 inv_i0;
|
||||||
f32 inv_i1;
|
f32 inv_i1;
|
||||||
{
|
{
|
||||||
f32 scale0 = math_fabs(xform_get_determinant(e0_xf));
|
f32 scale0 = math_fabs(GetXformDeterminant(e0_xf));
|
||||||
f32 scale1 = math_fabs(xform_get_determinant(e1_xf));
|
f32 scale1 = math_fabs(GetXformDeterminant(e1_xf));
|
||||||
inv_m0 = 1.f / (e0->mass_unscaled * scale0);
|
inv_m0 = 1.f / (e0->mass_unscaled * scale0);
|
||||||
inv_m1 = 1.f / (e1->mass_unscaled * scale1);
|
inv_m1 = 1.f / (e1->mass_unscaled * scale1);
|
||||||
inv_i0 = 1.f / (e0->inertia_unscaled * scale0);
|
inv_i0 = 1.f / (e0->inertia_unscaled * scale0);
|
||||||
@ -968,8 +968,8 @@ void phys_prepare_weld_joints(PhysStepCtx *ctx)
|
|||||||
joint->inv_i1 = inv_i1;
|
joint->inv_i1 = inv_i1;
|
||||||
|
|
||||||
#if !SIM_PHYSICS_ENABLE_WARM_STARTING
|
#if !SIM_PHYSICS_ENABLE_WARM_STARTING
|
||||||
joint->linear_impulse0 = V2FromXY(0, 0);
|
joint->linear_impulse0 = V2(0, 0);
|
||||||
joint->linear_impulse1 = V2FromXY(0, 0);
|
joint->linear_impulse1 = V2(0, 0);
|
||||||
joint->angular_impulse0 = 0;
|
joint->angular_impulse0 = 0;
|
||||||
joint->angular_impulse1 = 0;
|
joint->angular_impulse1 = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -998,7 +998,7 @@ void phys_warm_start_weld_joints(PhysStepCtx *ctx)
|
|||||||
f32 inv_m = joint->inv_m0;
|
f32 inv_m = joint->inv_m0;
|
||||||
f32 inv_i = joint->inv_i0;
|
f32 inv_i = joint->inv_i0;
|
||||||
Xform xf = sim_ent_get_xform(e1);
|
Xform xf = sim_ent_get_xform(e1);
|
||||||
V2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
|
Vec2 vcp = v2_sub(MulXformV2(xf, joint->point_local_start), xf.og);
|
||||||
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)));
|
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)));
|
||||||
ent->angular_velocity += (v2_wedge(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i;
|
ent->angular_velocity += (v2_wedge(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i;
|
||||||
}
|
}
|
||||||
@ -1034,9 +1034,9 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt)
|
|||||||
Xform xf0 = sim_ent_get_xform(e0);
|
Xform xf0 = sim_ent_get_xform(e0);
|
||||||
Xform xf1 = sim_ent_get_xform(e1);
|
Xform xf1 = sim_ent_get_xform(e1);
|
||||||
|
|
||||||
Xform target_xf1 = xform_mul(xf0, joint->xf0_to_xf1);
|
Xform target_xf1 = MulXform(xf0, joint->xf0_to_xf1);
|
||||||
|
|
||||||
V2 v1 = e1->linear_velocity;
|
Vec2 v1 = e1->linear_velocity;
|
||||||
f32 w1 = e1->angular_velocity;
|
f32 w1 = e1->angular_velocity;
|
||||||
|
|
||||||
/* Angular constraint */
|
/* Angular constraint */
|
||||||
@ -1044,7 +1044,7 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt)
|
|||||||
SoftSpring softness = math_spring_init(joint->angular_spring_hz, joint->angular_spring_damp, dt);
|
SoftSpring softness = math_spring_init(joint->angular_spring_hz, joint->angular_spring_damp, dt);
|
||||||
f32 inv_i1 = joint->inv_i1;
|
f32 inv_i1 = joint->inv_i1;
|
||||||
f32 k = 1 / inv_i1;
|
f32 k = 1 / inv_i1;
|
||||||
f32 separation = math_unwind_angle(xform_get_rotation(target_xf1) - xform_get_rotation(xf1));
|
f32 separation = math_unwind_angle(GetXformRotation(target_xf1) - GetXformRotation(xf1));
|
||||||
f32 bias = -separation * softness.bias_rate;
|
f32 bias = -separation * softness.bias_rate;
|
||||||
f32 b = (w1 + bias) * k;
|
f32 b = (w1 + bias) * k;
|
||||||
f32 impulse = -softness.mass_scale * b - joint->angular_impulse1 * softness.impulse_scale;
|
f32 impulse = -softness.mass_scale * b - joint->angular_impulse1 * softness.impulse_scale;
|
||||||
@ -1057,17 +1057,17 @@ void phys_solve_weld_joints(PhysStepCtx *ctx, f32 dt)
|
|||||||
SoftSpring softness = math_spring_init(joint->linear_spring_hz, joint->linear_spring_damp, dt);
|
SoftSpring softness = math_spring_init(joint->linear_spring_hz, joint->linear_spring_damp, dt);
|
||||||
f32 inv_m1 = joint->inv_m1;
|
f32 inv_m1 = joint->inv_m1;
|
||||||
|
|
||||||
V2 separation = v2_sub(xf1.og, target_xf1.og);
|
Vec2 separation = v2_sub(xf1.og, target_xf1.og);
|
||||||
|
|
||||||
f32 k = 1 / inv_m1;
|
f32 k = 1 / inv_m1;
|
||||||
|
|
||||||
V2 bias = v2_mul(separation, softness.bias_rate);
|
Vec2 bias = v2_mul(separation, softness.bias_rate);
|
||||||
V2 b = v2_mul(v2_add(v1, bias), k);
|
Vec2 b = v2_mul(v2_add(v1, bias), k);
|
||||||
|
|
||||||
V2 impulse = v2_mul(b, -softness.mass_scale);
|
Vec2 impulse = v2_mul(b, -softness.mass_scale);
|
||||||
impulse = v2_sub(impulse, v2_mul(joint->linear_impulse1, softness.impulse_scale));
|
impulse = v2_sub(impulse, v2_mul(joint->linear_impulse1, softness.impulse_scale));
|
||||||
|
|
||||||
V2 old_impulse = joint->linear_impulse1;
|
Vec2 old_impulse = joint->linear_impulse1;
|
||||||
joint->linear_impulse1 = v2_add(joint->linear_impulse1, impulse);
|
joint->linear_impulse1 = v2_add(joint->linear_impulse1, impulse);
|
||||||
|
|
||||||
impulse = v2_sub(joint->linear_impulse1, old_impulse);
|
impulse = v2_sub(joint->linear_impulse1, old_impulse);
|
||||||
@ -1090,11 +1090,11 @@ internal Xform get_derived_xform(Ent *ent, f32 dt)
|
|||||||
{
|
{
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
|
|
||||||
V2 step_linear_velocity = v2_mul(ent->linear_velocity, dt);
|
Vec2 step_linear_velocity = v2_mul(ent->linear_velocity, dt);
|
||||||
f32 step_angular_velocity = ent->angular_velocity * dt;
|
f32 step_angular_velocity = ent->angular_velocity * dt;
|
||||||
|
|
||||||
xf.og = v2_add(xf.og, step_linear_velocity);
|
xf.og = v2_add(xf.og, step_linear_velocity);
|
||||||
xf = xform_basis_rotated_world(xf, step_angular_velocity);
|
xf = WorldRotateXformBasis(xf, step_angular_velocity);
|
||||||
return xf;
|
return xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,18 +1109,18 @@ void phys_integrate_forces(PhysStepCtx *ctx, f32 dt)
|
|||||||
b32 is_dynamic = sim_ent_has_prop(ent, SEPROP_DYNAMIC);
|
b32 is_dynamic = sim_ent_has_prop(ent, SEPROP_DYNAMIC);
|
||||||
b32 is_kinematic = sim_ent_has_prop(ent, SEPROP_KINEMATIC);
|
b32 is_kinematic = sim_ent_has_prop(ent, SEPROP_KINEMATIC);
|
||||||
if (is_dynamic || is_kinematic) {
|
if (is_dynamic || is_kinematic) {
|
||||||
V2 linear_velocity = ent->linear_velocity;
|
Vec2 linear_velocity = ent->linear_velocity;
|
||||||
f32 angular_velocity = ent->angular_velocity;
|
f32 angular_velocity = ent->angular_velocity;
|
||||||
f32 linear_damping_factor = max_f32(1.0f - (ent->linear_damping * dt), 0);
|
f32 linear_damping_factor = MaxF32(1.0f - (ent->linear_damping * dt), 0);
|
||||||
f32 angular_damping_factor = max_f32(1.0f - (ent->angular_damping * dt), 0);
|
f32 angular_damping_factor = MaxF32(1.0f - (ent->angular_damping * dt), 0);
|
||||||
|
|
||||||
/* Integrate forces */
|
/* Integrate forces */
|
||||||
if (is_dynamic) {
|
if (is_dynamic) {
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
f32 det_abs = math_fabs(xform_get_determinant(xf));
|
f32 det_abs = math_fabs(GetXformDeterminant(xf));
|
||||||
f32 mass = ent->mass_unscaled * det_abs;
|
f32 mass = ent->mass_unscaled * det_abs;
|
||||||
f32 inertia = ent->inertia_unscaled * det_abs;
|
f32 inertia = ent->inertia_unscaled * det_abs;
|
||||||
V2 force_accel = v2_mul(v2_div(ent->force, mass), dt);
|
Vec2 force_accel = v2_mul(v2_div(ent->force, mass), dt);
|
||||||
f32 torque_accel = (ent->torque / inertia) * dt;
|
f32 torque_accel = (ent->torque / inertia) * dt;
|
||||||
linear_velocity = v2_add(linear_velocity, force_accel);
|
linear_velocity = v2_add(linear_velocity, force_accel);
|
||||||
angular_velocity += torque_accel;
|
angular_velocity += torque_accel;
|
||||||
@ -1133,7 +1133,7 @@ void phys_integrate_forces(PhysStepCtx *ctx, f32 dt)
|
|||||||
/* Update entity */
|
/* Update entity */
|
||||||
sim_ent_set_linear_velocity(ent, linear_velocity);
|
sim_ent_set_linear_velocity(ent, linear_velocity);
|
||||||
sim_ent_set_angular_velocity(ent, angular_velocity);
|
sim_ent_set_angular_velocity(ent, angular_velocity);
|
||||||
ent->force = V2FromXY(0, 0);
|
ent->force = V2(0, 0);
|
||||||
ent->torque = 0;
|
ent->torque = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1257,7 +1257,7 @@ void phys_step(PhysStepCtx *ctx, f32 timestep)
|
|||||||
const f32 min_toi = 0.000001f;
|
const f32 min_toi = 0.000001f;
|
||||||
const f32 tolerance = 0.0001f;
|
const f32 tolerance = 0.0001f;
|
||||||
const u32 max_iterations = 16;
|
const u32 max_iterations = 16;
|
||||||
f32 earliest_toi = max_f32(phys_determine_earliest_toi(ctx, step_dt, tolerance, max_iterations), min_toi);
|
f32 earliest_toi = MaxF32(phys_determine_earliest_toi(ctx, step_dt, tolerance, max_iterations), min_toi);
|
||||||
step_dt = remaining_dt * earliest_toi;
|
step_dt = remaining_dt * earliest_toi;
|
||||||
#else
|
#else
|
||||||
(UNUSED)phys_determine_earliest_toi;
|
(UNUSED)phys_determine_earliest_toi;
|
||||||
|
|||||||
@ -2,9 +2,9 @@ typedef struct CollisionData CollisionData;
|
|||||||
struct CollisionData {
|
struct CollisionData {
|
||||||
EntId e0;
|
EntId e0;
|
||||||
EntId e1;
|
EntId e1;
|
||||||
V2 point;
|
Vec2 point;
|
||||||
V2 normal; /* Normal of the collision from e0 to e1 */
|
Vec2 normal; /* Normal of the collision from e0 to e1 */
|
||||||
V2 vrel; /* Relative velocity at point of collision */
|
Vec2 vrel; /* Relative velocity at point of collision */
|
||||||
b32 is_start; /* Did this collision just begin */
|
b32 is_start; /* Did this collision just begin */
|
||||||
f32 dt; /* How much time elapsed in the step when this event occurred (this will equal the physics timestep unless an early time of impact occurred) */
|
f32 dt; /* How much time elapsed in the step when this event occurred (this will equal the physics timestep unless an early time of impact occurred) */
|
||||||
};
|
};
|
||||||
@ -34,8 +34,8 @@ struct ContactPoint {
|
|||||||
* shouldn't really be affected by rotation accross substeps
|
* shouldn't really be affected by rotation accross substeps
|
||||||
* (imagine re-building the manifold of a rotated shape, it would still be
|
* (imagine re-building the manifold of a rotated shape, it would still be
|
||||||
* on the same side of the shape that it originally occured on) */
|
* on the same side of the shape that it originally occured on) */
|
||||||
V2 vcp0;
|
Vec2 vcp0;
|
||||||
V2 vcp1;
|
Vec2 vcp1;
|
||||||
|
|
||||||
u32 id; /* ID generated during clipping */
|
u32 id; /* ID generated during clipping */
|
||||||
f32 starting_separation; /* How far are original points along normal */
|
f32 starting_separation; /* How far are original points along normal */
|
||||||
@ -47,7 +47,7 @@ struct ContactPoint {
|
|||||||
|
|
||||||
/* Debugging */
|
/* Debugging */
|
||||||
#if DeveloperIsEnabled
|
#if DeveloperIsEnabled
|
||||||
V2 dbg_pt;
|
Vec2 dbg_pt;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ struct ContactConstraint {
|
|||||||
f32 inv_i0;
|
f32 inv_i0;
|
||||||
f32 inv_i1;
|
f32 inv_i1;
|
||||||
|
|
||||||
V2 normal; /* Normal vector of collision from e0 -> e1 */
|
Vec2 normal; /* Normal vector of collision from e0 -> e1 */
|
||||||
u64 last_iteration;
|
u64 last_iteration;
|
||||||
ContactPoint points[2];
|
ContactPoint points[2];
|
||||||
u32 num_points;
|
u32 num_points;
|
||||||
@ -82,8 +82,8 @@ struct CollisionDebugData {
|
|||||||
ContactPoint points[2];
|
ContactPoint points[2];
|
||||||
u32 num_points;
|
u32 num_points;
|
||||||
|
|
||||||
V2 closest0;
|
Vec2 closest0;
|
||||||
V2 closest1;
|
Vec2 closest1;
|
||||||
|
|
||||||
Xform xf0;
|
Xform xf0;
|
||||||
Xform xf1;
|
Xform xf1;
|
||||||
@ -120,11 +120,11 @@ struct MotorJoint {
|
|||||||
f32 inv_i0;
|
f32 inv_i0;
|
||||||
f32 inv_i1;
|
f32 inv_i1;
|
||||||
|
|
||||||
V2 linear_impulse;
|
Vec2 linear_impulse;
|
||||||
f32 angular_impulse;
|
f32 angular_impulse;
|
||||||
|
|
||||||
V2 point_local_e0;
|
Vec2 point_local_e0;
|
||||||
V2 point_local_e1;
|
Vec2 point_local_e1;
|
||||||
|
|
||||||
Xform linear_mass_xf;
|
Xform linear_mass_xf;
|
||||||
f32 angular_mass;
|
f32 angular_mass;
|
||||||
@ -143,8 +143,8 @@ void phys_solve_motor_joints(PhysStepCtx *ctx, f32 dt);
|
|||||||
typedef struct MouseJointDesc MouseJointDesc;
|
typedef struct MouseJointDesc MouseJointDesc;
|
||||||
struct MouseJointDesc {
|
struct MouseJointDesc {
|
||||||
EntId target;
|
EntId target;
|
||||||
V2 point_local_start;
|
Vec2 point_local_start;
|
||||||
V2 point_end;
|
Vec2 point_end;
|
||||||
f32 linear_spring_hz;
|
f32 linear_spring_hz;
|
||||||
f32 linear_spring_damp;
|
f32 linear_spring_damp;
|
||||||
f32 angular_spring_hz;
|
f32 angular_spring_hz;
|
||||||
@ -155,8 +155,8 @@ struct MouseJointDesc {
|
|||||||
typedef struct MouseJoint MouseJoint;
|
typedef struct MouseJoint MouseJoint;
|
||||||
struct MouseJoint {
|
struct MouseJoint {
|
||||||
EntId target;
|
EntId target;
|
||||||
V2 point_local_start;
|
Vec2 point_local_start;
|
||||||
V2 point_end;
|
Vec2 point_end;
|
||||||
f32 linear_spring_hz;
|
f32 linear_spring_hz;
|
||||||
f32 linear_spring_damp;
|
f32 linear_spring_damp;
|
||||||
f32 angular_spring_hz;
|
f32 angular_spring_hz;
|
||||||
@ -166,7 +166,7 @@ struct MouseJoint {
|
|||||||
f32 inv_m;
|
f32 inv_m;
|
||||||
f32 inv_i;
|
f32 inv_i;
|
||||||
|
|
||||||
V2 linear_impulse;
|
Vec2 linear_impulse;
|
||||||
f32 angular_impulse;
|
f32 angular_impulse;
|
||||||
|
|
||||||
Xform linear_mass_xf;
|
Xform linear_mass_xf;
|
||||||
@ -188,7 +188,7 @@ struct WeldJointDesc {
|
|||||||
EntId e1;
|
EntId e1;
|
||||||
|
|
||||||
/* The xform that transforms a point in e0's space into the desired e1 space
|
/* The xform that transforms a point in e0's space into the desired e1 space
|
||||||
* (IE `xf` * V2FromXY(0, 0) should evaluate to the local point that e1's origin will lie) */
|
* (IE `xf` * V2(0, 0) should evaluate to the local point that e1's origin will lie) */
|
||||||
Xform xf;
|
Xform xf;
|
||||||
|
|
||||||
f32 linear_spring_hz;
|
f32 linear_spring_hz;
|
||||||
@ -213,8 +213,8 @@ struct WeldJoint {
|
|||||||
f32 inv_i0;
|
f32 inv_i0;
|
||||||
f32 inv_i1;
|
f32 inv_i1;
|
||||||
|
|
||||||
V2 linear_impulse0;
|
Vec2 linear_impulse0;
|
||||||
V2 linear_impulse1;
|
Vec2 linear_impulse1;
|
||||||
f32 angular_impulse0;
|
f32 angular_impulse0;
|
||||||
f32 angular_impulse1;
|
f32 angular_impulse1;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -69,16 +69,16 @@ Space *space_from_entry(SpaceEntry *entry)
|
|||||||
* Cell
|
* Cell
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
internal V2I32 world_to_cell_coords(f32 cell_size, V2 world_pos)
|
internal Vec2I32 world_to_cell_coords(f32 cell_size, Vec2 world_pos)
|
||||||
{
|
{
|
||||||
f32 x = world_pos.x;
|
f32 x = world_pos.x;
|
||||||
f32 y = world_pos.y;
|
f32 y = world_pos.y;
|
||||||
x = (x + ((x >= 0) - (x < 0)) * cell_size) / cell_size;
|
x = (x + ((x >= 0) - (x < 0)) * cell_size) / cell_size;
|
||||||
y = (y + ((y >= 0) - (y < 0)) * cell_size) / cell_size;
|
y = (y + ((y >= 0) - (y < 0)) * cell_size) / cell_size;
|
||||||
return V2I32FromXY((i32)x, (i32)y);
|
return V2I32((i32)x, (i32)y);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal i32 cell_coords_to_bin_index(Space *space, V2I32 cell_pos)
|
internal i32 cell_coords_to_bin_index(Space *space, Vec2I32 cell_pos)
|
||||||
{
|
{
|
||||||
i32 num_bins_sqrt = space->num_bins_sqrt;
|
i32 num_bins_sqrt = space->num_bins_sqrt;
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ internal i32 cell_coords_to_bin_index(Space *space, V2I32 cell_pos)
|
|||||||
return bin_index;
|
return bin_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpaceCell *space_get_cell(Space *space, V2I32 cell_pos)
|
SpaceCell *space_get_cell(Space *space, Vec2I32 cell_pos)
|
||||||
{
|
{
|
||||||
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
|
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
|
||||||
SpaceCellBin *bin = &space->bins[bin_index];
|
SpaceCellBin *bin = &space->bins[bin_index];
|
||||||
@ -114,7 +114,7 @@ SpaceCell *space_get_cell(Space *space, V2I32 cell_pos)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void space_cell_node_alloc(V2I32 cell_pos, SpaceEntry *entry)
|
internal void space_cell_node_alloc(Vec2I32 cell_pos, SpaceEntry *entry)
|
||||||
{
|
{
|
||||||
Space *space = space_from_entry(entry);
|
Space *space = space_from_entry(entry);
|
||||||
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
|
i32 bin_index = cell_coords_to_bin_index(space, cell_pos);
|
||||||
@ -311,22 +311,22 @@ void space_entry_update_aabb(SpaceEntry *entry, Aabb new_aabb)
|
|||||||
Space *space = space_from_entry(entry);
|
Space *space = space_from_entry(entry);
|
||||||
f32 cell_size = space->cell_size;
|
f32 cell_size = space->cell_size;
|
||||||
|
|
||||||
V2I32 old_cell_p0 = V2I32FromXY(0, 0);
|
Vec2I32 old_cell_p0 = V2I32(0, 0);
|
||||||
V2I32 old_cell_p1 = V2I32FromXY(0, 0);
|
Vec2I32 old_cell_p1 = V2I32(0, 0);
|
||||||
if (entry->first_node) {
|
if (entry->first_node) {
|
||||||
Aabb old_aabb = entry->aabb;
|
Aabb old_aabb = entry->aabb;
|
||||||
old_cell_p0 = world_to_cell_coords(cell_size, old_aabb.p0);
|
old_cell_p0 = world_to_cell_coords(cell_size, old_aabb.p0);
|
||||||
old_cell_p1 = world_to_cell_coords(cell_size, old_aabb.p1);
|
old_cell_p1 = world_to_cell_coords(cell_size, old_aabb.p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
V2I32 new_cell_p0 = world_to_cell_coords(cell_size, new_aabb.p0);
|
Vec2I32 new_cell_p0 = world_to_cell_coords(cell_size, new_aabb.p0);
|
||||||
V2I32 new_cell_p1 = world_to_cell_coords(cell_size, new_aabb.p1);
|
Vec2I32 new_cell_p1 = world_to_cell_coords(cell_size, new_aabb.p1);
|
||||||
|
|
||||||
/* Release outdated nodes */
|
/* Release outdated nodes */
|
||||||
SpaceCellNode *n = entry->first_node;
|
SpaceCellNode *n = entry->first_node;
|
||||||
while (n) {
|
while (n) {
|
||||||
SpaceCell *cell = n->cell;
|
SpaceCell *cell = n->cell;
|
||||||
V2I32 cell_pos = cell->pos;
|
Vec2I32 cell_pos = cell->pos;
|
||||||
if (cell_pos.x < new_cell_p0.x || cell_pos.x > new_cell_p1.x || cell_pos.y < new_cell_p0.y || cell_pos.y > new_cell_p1.y) {
|
if (cell_pos.x < new_cell_p0.x || cell_pos.x > new_cell_p1.x || cell_pos.y < new_cell_p0.y || cell_pos.y > new_cell_p1.y) {
|
||||||
/* Cell is outside of new AABB */
|
/* Cell is outside of new AABB */
|
||||||
SpaceCellNode *next = n->next_in_entry;
|
SpaceCellNode *next = n->next_in_entry;
|
||||||
@ -342,7 +342,7 @@ void space_entry_update_aabb(SpaceEntry *entry, Aabb new_aabb)
|
|||||||
for (i32 x = new_cell_p0.x; x <= new_cell_p1.x; ++x) {
|
for (i32 x = new_cell_p0.x; x <= new_cell_p1.x; ++x) {
|
||||||
if (x != 0 && y != 0 && (x < old_cell_p0.x || x > old_cell_p1.x || y < old_cell_p0.y || y > old_cell_p1.y)) {
|
if (x != 0 && y != 0 && (x < old_cell_p0.x || x > old_cell_p1.x || y < old_cell_p0.y || y > old_cell_p1.y)) {
|
||||||
/* Cell is outside of old AABB */
|
/* Cell is outside of old AABB */
|
||||||
space_cell_node_alloc(V2I32FromXY(x, y), entry);
|
space_cell_node_alloc(V2I32(x, y), entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,7 +364,7 @@ SpaceIter space_iter_begin_aabb(Space *space, Aabb aabb)
|
|||||||
iter.cell_end = world_to_cell_coords(cell_size, aabb.p1);
|
iter.cell_end = world_to_cell_coords(cell_size, aabb.p1);
|
||||||
if (iter.cell_start.x > iter.cell_end.x || iter.cell_start.y > iter.cell_end.y) {
|
if (iter.cell_start.x > iter.cell_end.x || iter.cell_start.y > iter.cell_end.y) {
|
||||||
/* Swap cell_start & cell_end */
|
/* Swap cell_start & cell_end */
|
||||||
V2I32 tmp = iter.cell_start;
|
Vec2I32 tmp = iter.cell_start;
|
||||||
iter.cell_start = iter.cell_end;
|
iter.cell_start = iter.cell_end;
|
||||||
iter.cell_end = tmp;
|
iter.cell_end = tmp;
|
||||||
}
|
}
|
||||||
@ -381,9 +381,9 @@ SpaceEntry *space_iter_next(SpaceIter *iter)
|
|||||||
{
|
{
|
||||||
Space *space = iter->space;
|
Space *space = iter->space;
|
||||||
Aabb iter_aabb = iter->aabb;
|
Aabb iter_aabb = iter->aabb;
|
||||||
V2I32 cell_start = iter->cell_start;
|
Vec2I32 cell_start = iter->cell_start;
|
||||||
V2I32 cell_end = iter->cell_end;
|
Vec2I32 cell_end = iter->cell_end;
|
||||||
V2I32 cell_cur = iter->cell_cur;
|
Vec2I32 cell_cur = iter->cell_cur;
|
||||||
i32 span = cell_end.x - cell_start.x;
|
i32 span = cell_end.x - cell_start.x;
|
||||||
|
|
||||||
SpaceCellNode *next_node = 0;
|
SpaceCellNode *next_node = 0;
|
||||||
|
|||||||
@ -42,7 +42,7 @@ typedef struct SpaceCellBin SpaceCellBin;
|
|||||||
typedef struct SpaceCell SpaceCell;
|
typedef struct SpaceCell SpaceCell;
|
||||||
struct SpaceCell {
|
struct SpaceCell {
|
||||||
b32 valid;
|
b32 valid;
|
||||||
V2I32 pos;
|
Vec2I32 pos;
|
||||||
|
|
||||||
SpaceCellNode *first_node;
|
SpaceCellNode *first_node;
|
||||||
SpaceCellNode *last_node;
|
SpaceCellNode *last_node;
|
||||||
@ -82,9 +82,9 @@ typedef struct SpaceIter SpaceIter;
|
|||||||
struct SpaceIter {
|
struct SpaceIter {
|
||||||
Aabb aabb;
|
Aabb aabb;
|
||||||
Space *space;
|
Space *space;
|
||||||
V2I32 cell_start;
|
Vec2I32 cell_start;
|
||||||
V2I32 cell_end;
|
Vec2I32 cell_end;
|
||||||
V2I32 cell_cur;
|
Vec2I32 cell_cur;
|
||||||
SpaceCellNode *prev;
|
SpaceCellNode *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ Space *space_from_entry(SpaceEntry *entry);
|
|||||||
* Cell
|
* Cell
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
SpaceCell *space_get_cell(Space *space, V2I32 cell_pos);
|
SpaceCell *space_get_cell(Space *space, Vec2I32 cell_pos);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Entry
|
* Entry
|
||||||
|
|||||||
@ -90,7 +90,7 @@ internal Ent *test_spawn_chucker(Ent *parent)
|
|||||||
sim_ent_enable_prop(zone, SEPROP_SENSOR);
|
sim_ent_enable_prop(zone, SEPROP_SENSOR);
|
||||||
CLD_Shape collider = ZI;
|
CLD_Shape collider = ZI;
|
||||||
collider.count = 2;
|
collider.count = 2;
|
||||||
collider.points[1] = V2FromXY(0, -0.5);
|
collider.points[1] = V2(0, -0.5);
|
||||||
collider.radius = 0.1f;
|
collider.radius = 0.1f;
|
||||||
zone->local_collider = collider;
|
zone->local_collider = collider;
|
||||||
|
|
||||||
@ -108,11 +108,11 @@ internal Ent *test_spawn_employee(Ent *parent)
|
|||||||
|
|
||||||
Ent *e = sim_ent_alloc_sync_src(parent);
|
Ent *e = sim_ent_alloc_sync_src(parent);
|
||||||
|
|
||||||
V2 pos = V2FromXY(1, -1);
|
Vec2 pos = V2(1, -1);
|
||||||
|
|
||||||
//V2 size = V2FromXY(0.5, 0.5);
|
//Vec2 size = V2(0.5, 0.5);
|
||||||
//V2 size = V2FromXY(0.5, 0.25);
|
//Vec2 size = V2(0.5, 0.25);
|
||||||
V2 size = V2FromXY(1.0, 1.0);
|
Vec2 size = V2(1.0, 1.0);
|
||||||
|
|
||||||
//f32 r = Pi / 4;
|
//f32 r = Pi / 4;
|
||||||
f32 r = 0;
|
f32 r = 0;
|
||||||
@ -130,11 +130,11 @@ internal Ent *test_spawn_employee(Ent *parent)
|
|||||||
e->sprite_span_name = LIT("idle.two_handed");
|
e->sprite_span_name = LIT("idle.two_handed");
|
||||||
e->layer = SIM_LAYER_SHOULDERS;
|
e->layer = SIM_LAYER_SHOULDERS;
|
||||||
|
|
||||||
e->local_collider.points[0] = V2FromXY(0, 0);
|
e->local_collider.points[0] = V2(0, 0);
|
||||||
e->local_collider.count = 1;
|
e->local_collider.count = 1;
|
||||||
e->local_collider.radius = 0.25f;
|
e->local_collider.radius = 0.25f;
|
||||||
|
|
||||||
Xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
|
Xform xf = XformFromTrs(TRS(.t = pos, .r = r, .s = size));
|
||||||
//xf.bx.y = -1.f;
|
//xf.bx.y = -1.f;
|
||||||
|
|
||||||
sim_ent_set_xform(e, xf);
|
sim_ent_set_xform(e, xf);
|
||||||
@ -148,7 +148,7 @@ internal Ent *test_spawn_employee(Ent *parent)
|
|||||||
|
|
||||||
|
|
||||||
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
|
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
|
||||||
e->sprite_emittance = V3FromXYZ(1, 1, 1);
|
e->sprite_emittance = V3(1, 1, 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ internal Ent *test_spawn_employee(Ent *parent)
|
|||||||
e->control_force_max_speed = 7;
|
e->control_force_max_speed = 7;
|
||||||
|
|
||||||
//e->control_torque = 5000;
|
//e->control_torque = 5000;
|
||||||
e->control_torque = F32_INFINITY;
|
e->control_torque = F32Infinity;
|
||||||
|
|
||||||
sim_ent_enable_prop(e, SEPROP_DYNAMIC);
|
sim_ent_enable_prop(e, SEPROP_DYNAMIC);
|
||||||
sim_ent_enable_prop(e, SEPROP_SOLID);
|
sim_ent_enable_prop(e, SEPROP_SOLID);
|
||||||
@ -178,7 +178,7 @@ internal Ent *test_spawn_employee(Ent *parent)
|
|||||||
employee->equipped = e->id;
|
employee->equipped = e->id;
|
||||||
|
|
||||||
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
|
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
|
||||||
e->sprite_emittance = V3FromXYZ(1, 1, 1);
|
e->sprite_emittance = V3(1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return employee;
|
return employee;
|
||||||
@ -189,7 +189,7 @@ internal Ent *test_spawn_camera(Ent *parent, Ent *follow)
|
|||||||
Ent *camera_ent = sim_ent_nil();
|
Ent *camera_ent = sim_ent_nil();
|
||||||
if (follow->valid) {
|
if (follow->valid) {
|
||||||
camera_ent = sim_ent_alloc_sync_src(parent);
|
camera_ent = sim_ent_alloc_sync_src(parent);
|
||||||
sim_ent_set_xform(camera_ent, XFORM_IDENT);
|
sim_ent_set_xform(camera_ent, XformIdentity);
|
||||||
|
|
||||||
sim_ent_enable_prop(camera_ent, SEPROP_CAMERA);
|
sim_ent_enable_prop(camera_ent, SEPROP_CAMERA);
|
||||||
sim_ent_enable_prop(camera_ent, SEPROP_CAMERA_ACTIVE);
|
sim_ent_enable_prop(camera_ent, SEPROP_CAMERA_ACTIVE);
|
||||||
@ -197,16 +197,16 @@ internal Ent *test_spawn_camera(Ent *parent, Ent *follow)
|
|||||||
|
|
||||||
f32 width = (f32)DEFAULT_CAMERA_WIDTH;
|
f32 width = (f32)DEFAULT_CAMERA_WIDTH;
|
||||||
f32 height = (f32)DEFAULT_CAMERA_HEIGHT;
|
f32 height = (f32)DEFAULT_CAMERA_HEIGHT;
|
||||||
camera_ent->camera_quad_xform = XFORM_TRS(.s = V2FromXY(width, height));
|
camera_ent->camera_quad_xform = XformFromTrs(TRS(.s = V2(width, height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return camera_ent;
|
return camera_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Ent *test_spawn_explosion(Ent *parent, V2 pos, f32 strength, f32 radius)
|
internal Ent *test_spawn_explosion(Ent *parent, Vec2 pos, f32 strength, f32 radius)
|
||||||
{
|
{
|
||||||
Ent *ent = sim_ent_alloc_sync_src(parent);
|
Ent *ent = sim_ent_alloc_sync_src(parent);
|
||||||
sim_ent_set_xform(ent, XFORM_POS(pos));
|
sim_ent_set_xform(ent, XformFromPos(pos));
|
||||||
|
|
||||||
sim_ent_enable_prop(ent, SEPROP_EXPLOSION);
|
sim_ent_enable_prop(ent, SEPROP_EXPLOSION);
|
||||||
ent->explosion_strength = strength;
|
ent->explosion_strength = strength;
|
||||||
@ -219,7 +219,7 @@ internal Ent *test_spawn_explosion(Ent *parent, V2 pos, f32 strength, f32 radius
|
|||||||
return ent;
|
return ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void test_teleport(Ent *ent, V2 pos)
|
internal void test_teleport(Ent *ent, Vec2 pos)
|
||||||
{
|
{
|
||||||
//++ent->continuity_gen;
|
//++ent->continuity_gen;
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
@ -227,7 +227,7 @@ internal void test_teleport(Ent *ent, V2 pos)
|
|||||||
sim_ent_set_xform(ent, xf);
|
sim_ent_set_xform(ent, xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void test_spawn_entities1(Ent *parent, V2 pos)
|
internal void test_spawn_entities1(Ent *parent, Vec2 pos)
|
||||||
{
|
{
|
||||||
(UNUSED)pos;
|
(UNUSED)pos;
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ internal void test_spawn_entities1(Ent *parent, V2 pos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void test_spawn_entities2(Ent *parent, V2 pos)
|
internal void test_spawn_entities2(Ent *parent, Vec2 pos)
|
||||||
{
|
{
|
||||||
(UNUSED)pos;
|
(UNUSED)pos;
|
||||||
|
|
||||||
@ -251,8 +251,8 @@ internal void test_spawn_entities2(Ent *parent, V2 pos)
|
|||||||
Ent *e = sim_ent_alloc_sync_src(parent);
|
Ent *e = sim_ent_alloc_sync_src(parent);
|
||||||
|
|
||||||
f32 rot = 0;
|
f32 rot = 0;
|
||||||
V2 size = V2FromXY(0.125, 0.125);
|
Vec2 size = V2(0.125, 0.125);
|
||||||
Xform xf = XFORM_TRS(.t = pos, .r = rot, .s = size);
|
Xform xf = XformFromTrs(TRS(.t = pos, .r = rot, .s = size));
|
||||||
sim_ent_set_xform(e, xf);
|
sim_ent_set_xform(e, xf);
|
||||||
|
|
||||||
e->sprite = sprite_tag_from_path(LIT("sprite/tile.ase"));
|
e->sprite = sprite_tag_from_path(LIT("sprite/tile.ase"));
|
||||||
@ -273,7 +273,7 @@ internal void test_spawn_entities2(Ent *parent, V2 pos)
|
|||||||
f32 r = rand_f64_from_state(&rand, 1, 5);
|
f32 r = rand_f64_from_state(&rand, 1, 5);
|
||||||
f32 g = rand_f64_from_state(&rand, 1, 5);
|
f32 g = rand_f64_from_state(&rand, 1, 5);
|
||||||
f32 b = rand_f64_from_state(&rand, 1, 5);
|
f32 b = rand_f64_from_state(&rand, 1, 5);
|
||||||
e->sprite_emittance = V3FromXYZ(r, g, b);
|
e->sprite_emittance = V3(r, g, b);
|
||||||
e->sprite_tint = Rgba32F(r / 5, g / 5, b / 5, 1);
|
e->sprite_tint = Rgba32F(r / 5, g / 5, b / 5, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,8 +293,8 @@ internal void test_spawn_entities2(Ent *parent, V2 pos)
|
|||||||
Ent *e = sim_ent_alloc_sync_src(parent);
|
Ent *e = sim_ent_alloc_sync_src(parent);
|
||||||
|
|
||||||
f32 r = Pi / 4;
|
f32 r = Pi / 4;
|
||||||
V2 size = V2FromXY(0.5, 0.25);
|
Vec2 size = V2(0.5, 0.25);
|
||||||
Xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
|
Xform xf = XformFromTrs(.t = pos, .r = r, .s = size);
|
||||||
sim_ent_set_xform(e, xf);
|
sim_ent_set_xform(e, xf);
|
||||||
|
|
||||||
e->sprite = sprite_tag_from_path(LIT("sprite/bullet.ase"));
|
e->sprite = sprite_tag_from_path(LIT("sprite/bullet.ase"));
|
||||||
@ -311,7 +311,7 @@ internal void test_spawn_entities2(Ent *parent, V2 pos)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void test_spawn_entities3(Ent *parent, V2 pos)
|
internal void test_spawn_entities3(Ent *parent, Vec2 pos)
|
||||||
{
|
{
|
||||||
(UNUSED)pos;
|
(UNUSED)pos;
|
||||||
|
|
||||||
@ -321,8 +321,8 @@ internal void test_spawn_entities3(Ent *parent, V2 pos)
|
|||||||
Ent *e = sim_ent_alloc_sync_src(parent);
|
Ent *e = sim_ent_alloc_sync_src(parent);
|
||||||
|
|
||||||
f32 r = 0;
|
f32 r = 0;
|
||||||
V2 size = V2FromXY(1, 1);
|
Vec2 size = V2(1, 1);
|
||||||
Xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
|
Xform xf = XformFromTrs(TRS(.t = pos, .r = r, .s = size));
|
||||||
sim_ent_set_xform(e, xf);
|
sim_ent_set_xform(e, xf);
|
||||||
|
|
||||||
e->sprite = sprite_tag_from_path(LIT("sprite/box.ase"));
|
e->sprite = sprite_tag_from_path(LIT("sprite/box.ase"));
|
||||||
@ -336,7 +336,7 @@ internal void test_spawn_entities3(Ent *parent, V2 pos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void test_spawn_entities4(Ent *parent, V2 pos)
|
internal void test_spawn_entities4(Ent *parent, Vec2 pos)
|
||||||
{
|
{
|
||||||
(UNUSED)pos;
|
(UNUSED)pos;
|
||||||
|
|
||||||
@ -344,8 +344,8 @@ internal void test_spawn_entities4(Ent *parent, V2 pos)
|
|||||||
Ent *e = sim_ent_alloc_sync_src(parent);
|
Ent *e = sim_ent_alloc_sync_src(parent);
|
||||||
|
|
||||||
f32 r = 0;
|
f32 r = 0;
|
||||||
V2 size = V2FromXY(2, 1);
|
Vec2 size = V2(2, 1);
|
||||||
Xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
|
Xform xf = XformFromTrs(TRS(.t = pos, .r = r, .s = size));
|
||||||
sim_ent_set_xform(e, xf);
|
sim_ent_set_xform(e, xf);
|
||||||
|
|
||||||
//e->sprite = sprite_tag_from_path(LIT("sprite/box.ase"));
|
//e->sprite = sprite_tag_from_path(LIT("sprite/box.ase"));
|
||||||
@ -353,28 +353,28 @@ internal void test_spawn_entities4(Ent *parent, V2 pos)
|
|||||||
e->layer = SIM_LAYER_SHOULDERS;
|
e->layer = SIM_LAYER_SHOULDERS;
|
||||||
|
|
||||||
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
|
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
|
||||||
e->sprite_emittance = V3FromXYZ(2, 2, 2);
|
e->sprite_emittance = V3(2, 2, 2);
|
||||||
|
|
||||||
e->sprite_tint = Rgb32F(1, 1, 1);
|
e->sprite_tint = Rgb32F(1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void test_spawn_tile(Snapshot *world, V2 world_pos)
|
internal void test_spawn_tile(Snapshot *world, Vec2 world_pos)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
Ent *e = sim_ent_alloc_sync_src(parent);
|
Ent *e = sim_ent_alloc_sync_src(parent);
|
||||||
|
|
||||||
i32 sign_x = (world_pos.x >= 0) - (world_pos.x < 0);
|
i32 sign_x = (world_pos.x >= 0) - (world_pos.x < 0);
|
||||||
i32 sign_y = (world_pos.y >= 0) - (world_pos.y < 0);
|
i32 sign_y = (world_pos.y >= 0) - (world_pos.y < 0);
|
||||||
V2I32 tile_index = V2I32FromXY(world_pos.x * SIM_TILES_PER_UNIT_SQRT, world_pos.y * SIM_TILES_PER_UNIT_SQRT);
|
Vec2I32 tile_index = V2I32(world_pos.x * SIM_TILES_PER_UNIT_SQRT, world_pos.y * SIM_TILES_PER_UNIT_SQRT);
|
||||||
world_pos.x -= sign_x < 0;
|
world_pos.x -= sign_x < 0;
|
||||||
world_pos.y -= sign_y < 0;
|
world_pos.y -= sign_y < 0;
|
||||||
|
|
||||||
V2 tile_size = V2FromXY(1.f / SIM_TILES_PER_UNIT_SQRT, 1.f / SIM_TILES_PER_UNIT_SQRT);
|
Vec2 tile_size = V2(1.f / SIM_TILES_PER_UNIT_SQRT, 1.f / SIM_TILES_PER_UNIT_SQRT);
|
||||||
|
|
||||||
V2 pos = V2FromXY((f32)tile_index.x / SIM_TILES_PER_UNIT_SQRT, (f32)tile_index.y / SIM_TILES_PER_UNIT_SQRT);
|
Vec2 pos = V2((f32)tile_index.x / SIM_TILES_PER_UNIT_SQRT, (f32)tile_index.y / SIM_TILES_PER_UNIT_SQRT);
|
||||||
pos = v2_add(pos, v2_mul(V2FromXY(tile_size.x * sign_x, tile_size.y * sign_y), 0.5));
|
pos = v2_add(pos, v2_mul(V2(tile_size.x * sign_x, tile_size.y * sign_y), 0.5));
|
||||||
|
|
||||||
Xform xf = XFORM_TRS(.t = pos);
|
Xform xf = XformFromTrs(.t = pos);
|
||||||
sim_ent_set_xform(e, xf);
|
sim_ent_set_xform(e, xf);
|
||||||
|
|
||||||
e->layer = SIM_LAYER_WALLS;
|
e->layer = SIM_LAYER_WALLS;
|
||||||
@ -384,7 +384,7 @@ internal void test_spawn_tile(Snapshot *world, V2 world_pos)
|
|||||||
{
|
{
|
||||||
S_Scope *scope = sprite_scope_begin();
|
S_Scope *scope = sprite_scope_begin();
|
||||||
S_Sheet *sheet = sprite_sheet_from_tag_await(scope, e->sprite);
|
S_Sheet *sheet = sprite_sheet_from_tag_await(scope, e->sprite);
|
||||||
e->sprite_local_xform = XFORM_TRS(.s = v2_div(sheet->frame_size, PIXELS_PER_UNIT));
|
e->sprite_local_xform = XformFromTrs(.s = v2_div(sheet->frame_size, PIXELS_PER_UNIT));
|
||||||
sprite_scope_end(scope);
|
sprite_scope_end(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +392,7 @@ internal void test_spawn_tile(Snapshot *world, V2 world_pos)
|
|||||||
Quad collider_quad = quad_from_rect(RectFromScalar(-tile_size.x / 2, -tile_size.y / 2, tile_size.y, tile_size.y));
|
Quad collider_quad = quad_from_rect(RectFromScalar(-tile_size.x / 2, -tile_size.y / 2, tile_size.y, tile_size.y));
|
||||||
e->local_collider = collider_from_quad(collider_quad);
|
e->local_collider = collider_from_quad(collider_quad);
|
||||||
#else
|
#else
|
||||||
V2I32 tile_index = sim_world_tile_index_from_pos(world_pos);
|
Vec2I32 tile_index = sim_world_tile_index_from_pos(world_pos);
|
||||||
sim_snapshot_set_tile(world, tile_index, SIM_TILE_KIND_WALL);
|
sim_snapshot_set_tile(world, tile_index, SIM_TILE_KIND_WALL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -467,8 +467,8 @@ internal void test_generate_walls(Snapshot *world)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct wall_node {
|
struct wall_node {
|
||||||
V2I32 start;
|
Vec2I32 start;
|
||||||
V2I32 end;
|
Vec2I32 end;
|
||||||
i32 wall_dir; /* = 0 up, 1 = right, 2 = down, 3 = left */
|
i32 wall_dir; /* = 0 up, 1 = right, 2 = down, 3 = left */
|
||||||
struct wall_node *next;
|
struct wall_node *next;
|
||||||
};
|
};
|
||||||
@ -483,9 +483,9 @@ internal void test_generate_walls(Snapshot *world)
|
|||||||
/* Generate horizontal wall nodes */
|
/* Generate horizontal wall nodes */
|
||||||
for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
|
for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
|
||||||
Ent *chunk = x_sorted_tile_chunks[sorted_index];
|
Ent *chunk = x_sorted_tile_chunks[sorted_index];
|
||||||
V2I32 chunk_index = chunk->tile_chunk_index;
|
Vec2I32 chunk_index = chunk->tile_chunk_index;
|
||||||
Ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2I32FromXY(chunk_index.x, chunk_index.y - 1));
|
Ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y - 1));
|
||||||
Ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2I32FromXY(chunk_index.x, chunk_index.y + 1));
|
Ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y + 1));
|
||||||
/* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */
|
/* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */
|
||||||
i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + !bottom_chunk->valid;
|
i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + !bottom_chunk->valid;
|
||||||
i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + 1;
|
i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + 1;
|
||||||
@ -497,17 +497,17 @@ internal void test_generate_walls(Snapshot *world)
|
|||||||
i32 desired_wall_dir = -1;
|
i32 desired_wall_dir = -1;
|
||||||
TileKind tile = SIM_TILE_KIND_NONE;
|
TileKind tile = SIM_TILE_KIND_NONE;
|
||||||
if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) {
|
if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) {
|
||||||
tile = sim_get_chunk_tile(chunk, V2I32FromXY(tile_x, tile_y));
|
tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y));
|
||||||
}
|
}
|
||||||
if (tile_x < SIM_TILES_PER_CHUNK_SQRT) {
|
if (tile_x < SIM_TILES_PER_CHUNK_SQRT) {
|
||||||
TileKind top_tile = SIM_TILE_KIND_NONE;
|
TileKind top_tile = SIM_TILE_KIND_NONE;
|
||||||
if (tile_y == 0) {
|
if (tile_y == 0) {
|
||||||
if (top_chunk->valid) {
|
if (top_chunk->valid) {
|
||||||
V2I32 top_tile_local_index = V2I32FromXY(tile_x, SIM_TILES_PER_CHUNK_SQRT - 1);
|
Vec2I32 top_tile_local_index = V2I32(tile_x, SIM_TILES_PER_CHUNK_SQRT - 1);
|
||||||
top_tile = sim_get_chunk_tile(top_chunk, top_tile_local_index);
|
top_tile = sim_get_chunk_tile(top_chunk, top_tile_local_index);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
top_tile = sim_get_chunk_tile(chunk, V2I32FromXY(tile_x, tile_y - 1));
|
top_tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y - 1));
|
||||||
}
|
}
|
||||||
if (tile == SIM_TILE_KIND_WALL) {
|
if (tile == SIM_TILE_KIND_WALL) {
|
||||||
/* Process wall tile */
|
/* Process wall tile */
|
||||||
@ -524,8 +524,8 @@ internal void test_generate_walls(Snapshot *world)
|
|||||||
|
|
||||||
/* Stop wall */
|
/* Stop wall */
|
||||||
if (wall_dir >= 0 && desired_wall_dir != wall_dir) {
|
if (wall_dir >= 0 && desired_wall_dir != wall_dir) {
|
||||||
V2I32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32FromXY(wall_start, tile_y));
|
Vec2I32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_start, tile_y));
|
||||||
V2I32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32FromXY(wall_end, tile_y));
|
Vec2I32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_end, tile_y));
|
||||||
struct wall_node *node = 0;
|
struct wall_node *node = 0;
|
||||||
if (wall_start == 0) {
|
if (wall_start == 0) {
|
||||||
u64 start_hash = rand_u64_from_seed(*(u64 *)&start);
|
u64 start_hash = rand_u64_from_seed(*(u64 *)&start);
|
||||||
@ -572,9 +572,9 @@ internal void test_generate_walls(Snapshot *world)
|
|||||||
/* Generate vertical wall nodes */
|
/* Generate vertical wall nodes */
|
||||||
for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
|
for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) {
|
||||||
Ent *chunk = y_sorted_tile_chunks[sorted_index];
|
Ent *chunk = y_sorted_tile_chunks[sorted_index];
|
||||||
V2I32 chunk_index = chunk->tile_chunk_index;
|
Vec2I32 chunk_index = chunk->tile_chunk_index;
|
||||||
Ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2I32FromXY(chunk_index.x - 1, chunk_index.y));
|
Ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x - 1, chunk_index.y));
|
||||||
Ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2I32FromXY(chunk_index.x + 1, chunk_index.y));
|
Ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x + 1, chunk_index.y));
|
||||||
/* If there's no chunk to the right of this one, then do an extra iteration (since walls are created on the left of each tile) */
|
/* If there's no chunk to the right of this one, then do an extra iteration (since walls are created on the left of each tile) */
|
||||||
i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + 1;
|
i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + 1;
|
||||||
i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + !right_chunk->valid;
|
i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + !right_chunk->valid;
|
||||||
@ -586,18 +586,18 @@ internal void test_generate_walls(Snapshot *world)
|
|||||||
i32 desired_wall_dir = -1;
|
i32 desired_wall_dir = -1;
|
||||||
TileKind tile = SIM_TILE_KIND_NONE;
|
TileKind tile = SIM_TILE_KIND_NONE;
|
||||||
if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) {
|
if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) {
|
||||||
tile = sim_get_chunk_tile(chunk, V2I32FromXY(tile_x, tile_y));
|
tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile_y < SIM_TILES_PER_CHUNK_SQRT) {
|
if (tile_y < SIM_TILES_PER_CHUNK_SQRT) {
|
||||||
TileKind left_tile = SIM_TILE_KIND_NONE;
|
TileKind left_tile = SIM_TILE_KIND_NONE;
|
||||||
if (tile_x == 0) {
|
if (tile_x == 0) {
|
||||||
if (left_chunk->valid) {
|
if (left_chunk->valid) {
|
||||||
V2I32 left_tile_local_index = V2I32FromXY(SIM_TILES_PER_CHUNK_SQRT - 1, tile_y);
|
Vec2I32 left_tile_local_index = V2I32(SIM_TILES_PER_CHUNK_SQRT - 1, tile_y);
|
||||||
left_tile = sim_get_chunk_tile(left_chunk, left_tile_local_index);
|
left_tile = sim_get_chunk_tile(left_chunk, left_tile_local_index);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
left_tile = sim_get_chunk_tile(chunk, V2I32FromXY(tile_x - 1, tile_y));
|
left_tile = sim_get_chunk_tile(chunk, V2I32(tile_x - 1, tile_y));
|
||||||
}
|
}
|
||||||
if (tile == SIM_TILE_KIND_WALL) {
|
if (tile == SIM_TILE_KIND_WALL) {
|
||||||
/* Process wall tile */
|
/* Process wall tile */
|
||||||
@ -614,8 +614,8 @@ internal void test_generate_walls(Snapshot *world)
|
|||||||
|
|
||||||
/* Stop wall */
|
/* Stop wall */
|
||||||
if (wall_dir >= 0 && desired_wall_dir != wall_dir) {
|
if (wall_dir >= 0 && desired_wall_dir != wall_dir) {
|
||||||
V2I32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32FromXY(tile_x, wall_start));
|
Vec2I32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(tile_x, wall_start));
|
||||||
V2I32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32FromXY(tile_x, wall_end));
|
Vec2I32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(tile_x, wall_end));
|
||||||
struct wall_node *node = 0;
|
struct wall_node *node = 0;
|
||||||
if (wall_start == 0) {
|
if (wall_start == 0) {
|
||||||
u64 start_hash = rand_u64_from_seed(*(u64 *)&start);
|
u64 start_hash = rand_u64_from_seed(*(u64 *)&start);
|
||||||
@ -664,17 +664,17 @@ internal void test_generate_walls(Snapshot *world)
|
|||||||
Ent *wall_ent = sim_ent_alloc_sync_src(root);
|
Ent *wall_ent = sim_ent_alloc_sync_src(root);
|
||||||
sim_ent_enable_prop(wall_ent, SEPROP_WALL);
|
sim_ent_enable_prop(wall_ent, SEPROP_WALL);
|
||||||
|
|
||||||
V2 start = sim_pos_from_world_tile_index(node->start);
|
Vec2 start = sim_pos_from_world_tile_index(node->start);
|
||||||
V2 end = sim_pos_from_world_tile_index(node->end);
|
Vec2 end = sim_pos_from_world_tile_index(node->end);
|
||||||
|
|
||||||
Xform xf = XFORM_POS(start);
|
Xform xf = XformFromPos(start);
|
||||||
sim_ent_set_xform(wall_ent, xf);
|
sim_ent_set_xform(wall_ent, xf);
|
||||||
|
|
||||||
sim_ent_enable_prop(wall_ent, SEPROP_SOLID);
|
sim_ent_enable_prop(wall_ent, SEPROP_SOLID);
|
||||||
wall_ent->local_collider.count = 2;
|
wall_ent->local_collider.count = 2;
|
||||||
wall_ent->local_collider.points[1] = v2_sub(end, start);
|
wall_ent->local_collider.points[1] = v2_sub(end, start);
|
||||||
|
|
||||||
V2 dirs[4] = { V2FromXY(0, -1), V2FromXY(1, 0), V2FromXY(0, 1), V2FromXY(-1, 0) };
|
Vec2 dirs[4] = { V2(0, -1), V2(1, 0), V2(0, 1), V2(-1, 0) };
|
||||||
Assert(node->wall_dir >= 0 && (u32)node->wall_dir < countof(dirs));
|
Assert(node->wall_dir >= 0 && (u32)node->wall_dir < countof(dirs));
|
||||||
wall_ent->collision_dir = dirs[node->wall_dir];
|
wall_ent->collision_dir = dirs[node->wall_dir];
|
||||||
|
|
||||||
@ -721,8 +721,8 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
|
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
|
||||||
/* Bullet impact */
|
/* Bullet impact */
|
||||||
if (sim_ent_has_prop(e0, SEPROP_BULLET)) {
|
if (sim_ent_has_prop(e0, SEPROP_BULLET)) {
|
||||||
V2 normal = data->normal; /* Impact normal */
|
Vec2 normal = data->normal; /* Impact normal */
|
||||||
V2 vrel = data->vrel; /* Impact velocity */
|
Vec2 vrel = data->vrel; /* Impact velocity */
|
||||||
|
|
||||||
Ent *bullet = e0;
|
Ent *bullet = e0;
|
||||||
Ent *target = e1;
|
Ent *target = e1;
|
||||||
@ -730,7 +730,7 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
|
|
||||||
/* Process collision if bullet already spent or * target share same top level parent */
|
/* Process collision if bullet already spent or * target share same top level parent */
|
||||||
if (!bullet->bullet_has_hit && !sim_ent_id_eq(src->top, target->top) && sim_ent_has_prop(target, SEPROP_SOLID)) {
|
if (!bullet->bullet_has_hit && !sim_ent_id_eq(src->top, target->top) && sim_ent_has_prop(target, SEPROP_SOLID)) {
|
||||||
V2 point = data->point;
|
Vec2 point = data->point;
|
||||||
|
|
||||||
/* Update tracer */
|
/* Update tracer */
|
||||||
Ent *tracer = sim_ent_from_id(world, bullet->bullet_tracer);
|
Ent *tracer = sim_ent_from_id(world, bullet->bullet_tracer);
|
||||||
@ -738,17 +738,17 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
Xform xf = sim_ent_get_xform(tracer);
|
Xform xf = sim_ent_get_xform(tracer);
|
||||||
xf.og = point;
|
xf.og = point;
|
||||||
sim_ent_set_xform(tracer, xf);
|
sim_ent_set_xform(tracer, xf);
|
||||||
sim_ent_set_linear_velocity(tracer, V2FromXY(0, 0));
|
sim_ent_set_linear_velocity(tracer, V2(0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update target */
|
/* Update target */
|
||||||
V2 knockback = v2_mul(v2_norm(vrel), bullet->bullet_knockback);
|
Vec2 knockback = v2_mul(v2_norm(vrel), bullet->bullet_knockback);
|
||||||
sim_ent_apply_linear_impulse(target, knockback, point);
|
sim_ent_apply_linear_impulse(target, knockback, point);
|
||||||
|
|
||||||
/* Create test blood */
|
/* Create test blood */
|
||||||
/* TODO: Remove this */
|
/* TODO: Remove this */
|
||||||
{
|
{
|
||||||
Xform xf = XFORM_TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, Tau));
|
Xform xf = XformFromTrs(TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, Tau)));
|
||||||
Ent *decal = sim_ent_alloc_sync_src(root);
|
Ent *decal = sim_ent_alloc_sync_src(root);
|
||||||
decal->sprite = sprite_tag_from_path(LIT("sprite/blood.ase"));
|
decal->sprite = sprite_tag_from_path(LIT("sprite/blood.ase"));
|
||||||
decal->sprite_tint = Rgba32F(1, 1, 1, 0.25f);
|
decal->sprite_tint = Rgba32F(1, 1, 1, 0.25f);
|
||||||
@ -756,7 +756,7 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
sim_ent_set_xform(decal, xf);
|
sim_ent_set_xform(decal, xf);
|
||||||
|
|
||||||
f32 perp_range = 0.5;
|
f32 perp_range = 0.5;
|
||||||
V2 linear_velocity = v2_mul(normal, 0.5);
|
Vec2 linear_velocity = v2_mul(normal, 0.5);
|
||||||
linear_velocity = v2_add(linear_velocity, v2_mul(v2_perp(normal), rand_f64_from_state(&step_ctx->rand, -perp_range, perp_range)));
|
linear_velocity = v2_add(linear_velocity, v2_mul(v2_perp(normal), rand_f64_from_state(&step_ctx->rand, -perp_range, perp_range)));
|
||||||
|
|
||||||
f32 angular_velocity_range = 5;
|
f32 angular_velocity_range = 5;
|
||||||
@ -793,8 +793,8 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
|
|
||||||
Xform victim_xf = sim_ent_get_xform(victim);
|
Xform victim_xf = sim_ent_get_xform(victim);
|
||||||
CLD_ClosestResult closest_points = collider_closest_points(&origin_collider, &victim->local_collider, xf, victim_xf);
|
CLD_ClosestResult closest_points = collider_closest_points(&origin_collider, &victim->local_collider, xf, victim_xf);
|
||||||
V2 dir = v2_sub(closest_points.p1, closest_points.p0);
|
Vec2 dir = v2_sub(closest_points.p1, closest_points.p0);
|
||||||
V2 point = closest_points.p1;
|
Vec2 point = closest_points.p1;
|
||||||
f32 distance = v2_len(dir);
|
f32 distance = v2_len(dir);
|
||||||
#if 0
|
#if 0
|
||||||
if (closest_points.colliding) {
|
if (closest_points.colliding) {
|
||||||
@ -815,7 +815,7 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
if (distance < radius) {
|
if (distance < radius) {
|
||||||
const f32 falloff_curve = 3; /* Cubic falloff */
|
const f32 falloff_curve = 3; /* Cubic falloff */
|
||||||
f32 strength_factor = math_pow(1 - distance/radius, falloff_curve);
|
f32 strength_factor = math_pow(1 - distance/radius, falloff_curve);
|
||||||
V2 impulse = v2_with_len(dir, strength_center * strength_factor);
|
Vec2 impulse = v2_with_len(dir, strength_center * strength_factor);
|
||||||
sim_ent_apply_linear_impulse(victim, impulse, point);
|
sim_ent_apply_linear_impulse(victim, impulse, point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -856,7 +856,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
* Begin frame
|
* Begin frame
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
world->sim_dt_ns = max_i64(0, sim_dt_ns);
|
world->sim_dt_ns = MaxI64(0, sim_dt_ns);
|
||||||
world->sim_time_ns += world->sim_dt_ns;
|
world->sim_time_ns += world->sim_dt_ns;
|
||||||
f32 sim_dt = SecondsFromNs(world->sim_dt_ns);
|
f32 sim_dt = SecondsFromNs(world->sim_dt_ns);
|
||||||
|
|
||||||
@ -1032,7 +1032,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
u32 count = 1;
|
u32 count = 1;
|
||||||
f32 spread = 0;
|
f32 spread = 0;
|
||||||
for (u32 j = 0; j < count; ++j) {
|
for (u32 j = 0; j < count; ++j) {
|
||||||
V2 pos = player->player_cursor_pos;
|
Vec2 pos = player->player_cursor_pos;
|
||||||
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
||||||
test_spawn_entities1(root, pos);
|
test_spawn_entities1(root, pos);
|
||||||
}
|
}
|
||||||
@ -1042,7 +1042,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
u32 count = 1;
|
u32 count = 1;
|
||||||
f32 spread = 0;
|
f32 spread = 0;
|
||||||
for (u32 j = 0; j < count; ++j) {
|
for (u32 j = 0; j < count; ++j) {
|
||||||
V2 pos = player->player_cursor_pos;
|
Vec2 pos = player->player_cursor_pos;
|
||||||
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
||||||
test_spawn_entities2(root, pos);
|
test_spawn_entities2(root, pos);
|
||||||
}
|
}
|
||||||
@ -1052,7 +1052,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
u32 count = 1;
|
u32 count = 1;
|
||||||
f32 spread = 0;
|
f32 spread = 0;
|
||||||
for (u32 j = 0; j < count; ++j) {
|
for (u32 j = 0; j < count; ++j) {
|
||||||
V2 pos = player->player_cursor_pos;
|
Vec2 pos = player->player_cursor_pos;
|
||||||
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
||||||
test_spawn_entities3(root, pos);
|
test_spawn_entities3(root, pos);
|
||||||
}
|
}
|
||||||
@ -1062,7 +1062,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
u32 count = 1;
|
u32 count = 1;
|
||||||
f32 spread = 0;
|
f32 spread = 0;
|
||||||
for (u32 j = 0; j < count; ++j) {
|
for (u32 j = 0; j < count; ++j) {
|
||||||
V2 pos = player->player_cursor_pos;
|
Vec2 pos = player->player_cursor_pos;
|
||||||
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
||||||
test_spawn_entities4(root, pos);
|
test_spawn_entities4(root, pos);
|
||||||
}
|
}
|
||||||
@ -1206,15 +1206,15 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
/* Update sprite local xform */
|
/* Update sprite local xform */
|
||||||
{
|
{
|
||||||
S_SheetSlice slice = sprite_sheet_get_slice(sheet, LIT("pivot"), ent->animation_frame);
|
S_SheetSlice slice = sprite_sheet_get_slice(sheet, LIT("pivot"), ent->animation_frame);
|
||||||
V2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
|
Vec2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
|
||||||
|
|
||||||
V2 dir = v2_mul_v2(sprite_size, slice.dir);
|
Vec2 dir = v2_mul_v2(sprite_size, slice.dir);
|
||||||
f32 rot = v2_angle(dir) + Pi / 2;
|
f32 rot = v2_angle(dir) + Pi / 2;
|
||||||
|
|
||||||
Xform xf = XFORM_IDENT;
|
Xform xf = XformIdentity;
|
||||||
xf = xform_rotated(xf, -rot);
|
xf = RotateXform(xf, -rot);
|
||||||
xf = xform_scaled(xf, sprite_size);
|
xf = ScaleXform(xf, sprite_size);
|
||||||
xf = xform_translated(xf, v2_neg(slice.center));
|
xf = TranslateXform(xf, v2_neg(slice.center));
|
||||||
ent->sprite_local_xform = xf;
|
ent->sprite_local_xform = xf;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1224,7 +1224,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
Xform cxf = ent->sprite_local_xform;
|
Xform cxf = ent->sprite_local_xform;
|
||||||
|
|
||||||
S_SheetSlice slice = sprite_sheet_get_slice(sheet, ent->sprite_collider_slice, ent->animation_frame);
|
S_SheetSlice slice = sprite_sheet_get_slice(sheet, ent->sprite_collider_slice, ent->animation_frame);
|
||||||
ent->local_collider = collider_from_quad(xform_mul_quad(cxf, quad_from_rect(slice.rect)));
|
ent->local_collider = collider_from_quad(MulXformQuad(cxf, quad_from_rect(slice.rect)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test collider */
|
/* Test collider */
|
||||||
@ -1232,24 +1232,24 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
if (sim_ent_has_prop(ent, SEPROP_TEST)) {
|
if (sim_ent_has_prop(ent, SEPROP_TEST)) {
|
||||||
//if ((1)) {
|
//if ((1)) {
|
||||||
#if 0
|
#if 0
|
||||||
ent->local_collider.points[0] = V2FromXY(0, 0);
|
ent->local_collider.points[0] = V2(0, 0);
|
||||||
ent->local_collider.count = 1;
|
ent->local_collider.count = 1;
|
||||||
ent->local_collider.radius = 0.5;
|
ent->local_collider.radius = 0.5;
|
||||||
#elif 0
|
#elif 0
|
||||||
ent->local_collider.points[0] = v2_with_len(V2FromXY(0.08f, 0.17f), 0.15f);
|
ent->local_collider.points[0] = v2_with_len(V2(0.08f, 0.17f), 0.15f);
|
||||||
ent->local_collider.points[1] = v2_with_len(V2FromXY(-0.07f, -0.2f), 0.15f);
|
ent->local_collider.points[1] = v2_with_len(V2(-0.07f, -0.2f), 0.15f);
|
||||||
ent->local_collider.count = 2;
|
ent->local_collider.count = 2;
|
||||||
ent->local_collider.radius = 0.075f;
|
ent->local_collider.radius = 0.075f;
|
||||||
#elif 1
|
#elif 1
|
||||||
#if 0
|
#if 0
|
||||||
/* "Bad" winding order */
|
/* "Bad" winding order */
|
||||||
ent->local_collider.points[0] = V2FromXY(-0.15, 0.15);
|
ent->local_collider.points[0] = V2(-0.15, 0.15);
|
||||||
ent->local_collider.points[1] = V2FromXY(0.15, 0.15);
|
ent->local_collider.points[1] = V2(0.15, 0.15);
|
||||||
ent->local_collider.points[2] = V2FromXY(0, -0.15);
|
ent->local_collider.points[2] = V2(0, -0.15);
|
||||||
#else
|
#else
|
||||||
ent->local_collider.points[0] = V2FromXY(0, -0.15);
|
ent->local_collider.points[0] = V2(0, -0.15);
|
||||||
ent->local_collider.points[1] = V2FromXY(0.15, 0.15);
|
ent->local_collider.points[1] = V2(0.15, 0.15);
|
||||||
ent->local_collider.points[2] = V2FromXY(-0.15, 0.15);
|
ent->local_collider.points[2] = V2(-0.15, 0.15);
|
||||||
#endif
|
#endif
|
||||||
ent->local_collider.count = 3;
|
ent->local_collider.count = 3;
|
||||||
ent->local_collider.radius = 0.25;
|
ent->local_collider.radius = 0.25;
|
||||||
@ -1279,12 +1279,12 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
Xform parent_sprite_xf = parent->sprite_local_xform;
|
Xform parent_sprite_xf = parent->sprite_local_xform;
|
||||||
|
|
||||||
S_SheetSlice attach_slice = sprite_sheet_get_slice(parent_sheet, ent->attach_slice, parent->animation_frame);
|
S_SheetSlice attach_slice = sprite_sheet_get_slice(parent_sheet, ent->attach_slice, parent->animation_frame);
|
||||||
V2 attach_pos = xform_mul_v2(parent_sprite_xf, attach_slice.center);
|
Vec2 attach_pos = MulXformV2(parent_sprite_xf, attach_slice.center);
|
||||||
V2 attach_dir = xform_basis_mul_v2(parent_sprite_xf, attach_slice.dir);
|
Vec2 attach_dir = MulXformBasisV2(parent_sprite_xf, attach_slice.dir);
|
||||||
|
|
||||||
Xform xf = sim_ent_get_local_xform(ent);
|
Xform xf = sim_ent_get_local_xform(ent);
|
||||||
xf.og = attach_pos;
|
xf.og = attach_pos;
|
||||||
xf = xform_basis_with_rotation_world(xf, v2_angle(attach_dir) + Pi / 2);
|
xf = XformWIthWorldRotation(xf, v2_angle(attach_dir) + Pi / 2);
|
||||||
sim_ent_set_local_xform(ent, xf);
|
sim_ent_set_local_xform(ent, xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1355,8 +1355,8 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
|
S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
|
||||||
Xform sprite_local_xform = ent->sprite_local_xform;
|
Xform sprite_local_xform = ent->sprite_local_xform;
|
||||||
S_SheetSlice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame);
|
S_SheetSlice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame);
|
||||||
V2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center);
|
Vec2 rel_pos = MulXformV2(sprite_local_xform, out_slice.center);
|
||||||
V2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir);
|
Vec2 rel_dir = MulXformBasisV2(sprite_local_xform, out_slice.dir);
|
||||||
|
|
||||||
/* Spawn bullet */
|
/* Spawn bullet */
|
||||||
Ent *bullet;
|
Ent *bullet;
|
||||||
@ -1374,7 +1374,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
/* Point collider */
|
/* Point collider */
|
||||||
bullet->local_collider.points[0] = V2FromXY(0, 0);
|
bullet->local_collider.points[0] = V2(0, 0);
|
||||||
bullet->local_collider.count = 1;
|
bullet->local_collider.count = 1;
|
||||||
#else
|
#else
|
||||||
bullet->sprite = sprite_tag_from_path(LIT("sprite/bullet.ase"));
|
bullet->sprite = sprite_tag_from_path(LIT("sprite/bullet.ase"));
|
||||||
@ -1402,8 +1402,8 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
|
S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
|
||||||
Xform sprite_local_xform = ent->sprite_local_xform;
|
Xform sprite_local_xform = ent->sprite_local_xform;
|
||||||
S_SheetSlice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame);
|
S_SheetSlice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame);
|
||||||
V2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center);
|
Vec2 rel_pos = MulXformV2(sprite_local_xform, out_slice.center);
|
||||||
V2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir);
|
Vec2 rel_dir = MulXformBasisV2(sprite_local_xform, out_slice.dir);
|
||||||
|
|
||||||
/* Spawn bullet */
|
/* Spawn bullet */
|
||||||
Ent *bullet;
|
Ent *bullet;
|
||||||
@ -1422,7 +1422,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
bullet->layer = SIM_LAYER_BULLETS;
|
bullet->layer = SIM_LAYER_BULLETS;
|
||||||
|
|
||||||
/* Point collider */
|
/* Point collider */
|
||||||
bullet->local_collider.points[0] = V2FromXY(0, 0);
|
bullet->local_collider.points[0] = V2(0, 0);
|
||||||
bullet->local_collider.count = 1;
|
bullet->local_collider.count = 1;
|
||||||
bullet->local_collider.radius = 0.05f;
|
bullet->local_collider.radius = 0.05f;
|
||||||
|
|
||||||
@ -1455,7 +1455,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
|
|
||||||
Xform xf0 = sim_ent_get_xform(ent);
|
Xform xf0 = sim_ent_get_xform(ent);
|
||||||
Xform xf1 = sim_ent_get_xform(target);
|
Xform xf1 = sim_ent_get_xform(target);
|
||||||
Xform xf0_to_xf1 = xform_mul(xform_invert(xf0), xf1);
|
Xform xf0_to_xf1 = MulXform(InvertXform(xf0), xf1);
|
||||||
|
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_WELD_JOINT);
|
sim_ent_enable_prop(joint_ent, SEPROP_WELD_JOINT);
|
||||||
WeldJointDesc def = phys_weld_joint_def_init();
|
WeldJointDesc def = phys_weld_joint_def_init();
|
||||||
@ -1491,8 +1491,8 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
if (is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
if (is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc_sync_src(root);
|
joint_ent = sim_ent_alloc_sync_src(root);
|
||||||
joint_ent->predictor = ent->predictor;
|
joint_ent->predictor = ent->predictor;
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32Infinity;
|
||||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
joint_ent->inertia_unscaled = F32Infinity;
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
|
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_KINEMATIC);
|
sim_ent_enable_prop(joint_ent, SEPROP_KINEMATIC);
|
||||||
ent->move_joint = joint_ent->id;
|
ent->move_joint = joint_ent->id;
|
||||||
@ -1508,7 +1508,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sim_ent_should_simulate(joint_ent)) {
|
if (sim_ent_should_simulate(joint_ent)) {
|
||||||
sim_ent_set_xform(joint_ent, XFORM_IDENT); /* Reset joint ent position */
|
sim_ent_set_xform(joint_ent, XformIdentity); /* Reset joint ent position */
|
||||||
sim_ent_set_linear_velocity(joint_ent, v2_mul(v2_clamp_len(ent->control.move, 1), ent->control_force_max_speed));
|
sim_ent_set_linear_velocity(joint_ent, v2_mul(v2_clamp_len(ent->control.move, 1), ent->control_force_max_speed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1525,15 +1525,15 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
|
|
||||||
if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) {
|
if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) {
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
Xform sprite_xf = xform_mul(xf, ent->sprite_local_xform);
|
Xform sprite_xf = MulXform(xf, ent->sprite_local_xform);
|
||||||
|
|
||||||
/* Retrieve / create aim joint */
|
/* Retrieve / create aim joint */
|
||||||
Ent *joint_ent = sim_ent_from_id(world, ent->aim_joint);
|
Ent *joint_ent = sim_ent_from_id(world, ent->aim_joint);
|
||||||
if (is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
if (is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc_sync_src(root);
|
joint_ent = sim_ent_alloc_sync_src(root);
|
||||||
joint_ent->predictor = ent->predictor;
|
joint_ent->predictor = ent->predictor;
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32Infinity;
|
||||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
joint_ent->inertia_unscaled = F32Infinity;
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_KINEMATIC); /* Since we'll be setting velocity manually */
|
sim_ent_enable_prop(joint_ent, SEPROP_KINEMATIC); /* Since we'll be setting velocity manually */
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_MOTOR_JOINT);
|
sim_ent_enable_prop(joint_ent, SEPROP_MOTOR_JOINT);
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
|
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
|
||||||
@ -1555,11 +1555,11 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
/* Solve for final angle using law of sines */
|
/* Solve for final angle using law of sines */
|
||||||
f32 new_angle;
|
f32 new_angle;
|
||||||
{
|
{
|
||||||
V2 ent_pos = xf.og;
|
Vec2 ent_pos = xf.og;
|
||||||
V2 focus_pos = v2_add(ent_pos, ent->control.focus);
|
Vec2 focus_pos = v2_add(ent_pos, ent->control.focus);
|
||||||
|
|
||||||
V2 sprite_hold_pos;
|
Vec2 sprite_hold_pos;
|
||||||
V2 sprite_hold_dir;
|
Vec2 sprite_hold_dir;
|
||||||
{
|
{
|
||||||
S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
|
S_Sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
|
||||||
S_SheetSlice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame);
|
S_SheetSlice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame);
|
||||||
@ -1567,23 +1567,23 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
sprite_hold_dir = slice.dir;
|
sprite_hold_dir = slice.dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2 hold_dir = xform_basis_mul_v2(sprite_xf, sprite_hold_dir);
|
Vec2 hold_dir = MulXformBasisV2(sprite_xf, sprite_hold_dir);
|
||||||
V2 hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos);
|
Vec2 hold_pos = MulXformV2(sprite_xf, sprite_hold_pos);
|
||||||
if (v2_eq(hold_pos, ent_pos)) {
|
if (v2_eq(hold_pos, ent_pos)) {
|
||||||
/* If hold pos is same as origin (E.G if pivot is being used as hold pos), then move hold pos forward a tad to avoid issue */
|
/* If hold pos is same as origin (E.G if pivot is being used as hold pos), then move hold pos forward a tad to avoid issue */
|
||||||
sprite_hold_pos = v2_add(sprite_hold_pos, V2FromXY(0, -1));
|
sprite_hold_pos = v2_add(sprite_hold_pos, V2(0, -1));
|
||||||
hold_pos = xform_mul_v2(sprite_xf, sprite_hold_pos);
|
hold_pos = MulXformV2(sprite_xf, sprite_hold_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 forward_hold_angle_offset;
|
f32 forward_hold_angle_offset;
|
||||||
{
|
{
|
||||||
Xform xf_unrotated = xform_basis_with_rotation_world(xf, 0);
|
Xform xf_unrotated = XformWIthWorldRotation(xf, 0);
|
||||||
V2 hold_pos_unrotated = xform_mul_v2(xf_unrotated, xform_mul_v2(ent->sprite_local_xform, sprite_hold_pos));
|
Vec2 hold_pos_unrotated = MulXformV2(xf_unrotated, MulXformV2(ent->sprite_local_xform, sprite_hold_pos));
|
||||||
forward_hold_angle_offset = v2_angle_from_dirs(V2FromXY(0, -1), v2_sub(hold_pos_unrotated, xf_unrotated.og));
|
forward_hold_angle_offset = v2_angle_from_dirs(V2(0, -1), v2_sub(hold_pos_unrotated, xf_unrotated.og));
|
||||||
}
|
}
|
||||||
|
|
||||||
V2 hold_ent_dir = v2_sub(ent_pos, hold_pos);
|
Vec2 hold_ent_dir = v2_sub(ent_pos, hold_pos);
|
||||||
V2 focus_ent_dir = v2_sub(ent_pos, focus_pos);
|
Vec2 focus_ent_dir = v2_sub(ent_pos, focus_pos);
|
||||||
|
|
||||||
f32 hold_ent_len = v2_len(hold_ent_dir);
|
f32 hold_ent_len = v2_len(hold_ent_dir);
|
||||||
f32 focus_ent_len = v2_len(focus_ent_dir);
|
f32 focus_ent_len = v2_len(focus_ent_dir);
|
||||||
@ -1592,14 +1592,14 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
f32 final_focus_angle_btw_ent_and_hold = math_asin((math_sin(final_hold_angle_btw_ent_and_focus) * hold_ent_len) / focus_ent_len);
|
f32 final_focus_angle_btw_ent_and_hold = math_asin((math_sin(final_hold_angle_btw_ent_and_focus) * hold_ent_len) / focus_ent_len);
|
||||||
f32 final_ent_angle_btw_focus_and_hold = Pi - (final_focus_angle_btw_ent_and_hold + final_hold_angle_btw_ent_and_focus);
|
f32 final_ent_angle_btw_focus_and_hold = Pi - (final_focus_angle_btw_ent_and_hold + final_hold_angle_btw_ent_and_focus);
|
||||||
|
|
||||||
new_angle = math_unwind_angle(v2_angle_from_dirs(V2FromXY(0, -1), v2_sub(focus_pos, ent_pos)) + final_ent_angle_btw_focus_and_hold - forward_hold_angle_offset);
|
new_angle = math_unwind_angle(v2_angle_from_dirs(V2(0, -1), v2_sub(focus_pos, ent_pos)) + final_ent_angle_btw_focus_and_hold - forward_hold_angle_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 new_vel = 0;
|
f32 new_vel = 0;
|
||||||
if (!IsF32Nan(new_angle)) {
|
if (!IsF32Nan(new_angle)) {
|
||||||
const f32 angle_error_allowed = 0.001f;
|
const f32 angle_error_allowed = 0.001f;
|
||||||
Xform joint_xf = sim_ent_get_xform(joint_ent);
|
Xform joint_xf = sim_ent_get_xform(joint_ent);
|
||||||
f32 diff = math_unwind_angle(new_angle - xform_get_rotation(joint_xf));
|
f32 diff = math_unwind_angle(new_angle - GetXformRotation(joint_xf));
|
||||||
if (math_fabs(diff) > angle_error_allowed) {
|
if (math_fabs(diff) > angle_error_allowed) {
|
||||||
/* Instantly snap joint ent to new angle */
|
/* Instantly snap joint ent to new angle */
|
||||||
new_vel = diff / sim_dt;
|
new_vel = diff / sim_dt;
|
||||||
@ -1653,7 +1653,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
if (!sim_ent_should_simulate(player)) continue;
|
if (!sim_ent_should_simulate(player)) continue;
|
||||||
if (!sim_ent_has_prop(player, SEPROP_PLAYER)) continue;
|
if (!sim_ent_has_prop(player, SEPROP_PLAYER)) continue;
|
||||||
|
|
||||||
V2 cursor = player->player_cursor_pos;
|
Vec2 cursor = player->player_cursor_pos;
|
||||||
b32 start_dragging = player->player_dbg_drag_start;
|
b32 start_dragging = player->player_dbg_drag_start;
|
||||||
b32 stop_dragging = player->player_dbg_drag_stop;
|
b32 stop_dragging = player->player_dbg_drag_stop;
|
||||||
|
|
||||||
@ -1670,8 +1670,8 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
/* FIXME: Joint ent may never release */
|
/* FIXME: Joint ent may never release */
|
||||||
joint_ent = sim_ent_alloc_local(root);
|
joint_ent = sim_ent_alloc_local(root);
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32Infinity;
|
||||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
joint_ent->inertia_unscaled = F32Infinity;
|
||||||
player->player_dbg_drag_joint_ent = joint_ent->id;
|
player->player_dbg_drag_joint_ent = joint_ent->id;
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_MOUSE_JOINT);
|
sim_ent_enable_prop(joint_ent, SEPROP_MOUSE_JOINT);
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
|
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
|
||||||
@ -1683,10 +1683,10 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
if (sim_ent_id_eq(joint_ent->mouse_joint_data.target, target_ent->id)) {
|
if (sim_ent_id_eq(joint_ent->mouse_joint_data.target, target_ent->id)) {
|
||||||
def.point_local_start = joint_ent->mouse_joint_data.point_local_start;
|
def.point_local_start = joint_ent->mouse_joint_data.point_local_start;
|
||||||
} else {
|
} else {
|
||||||
def.point_local_start = xform_invert_mul_v2(xf, cursor);
|
def.point_local_start = InvertXformMulV2(xf, cursor);
|
||||||
}
|
}
|
||||||
def.point_end = cursor;
|
def.point_end = cursor;
|
||||||
def.max_force = F32_INFINITY;
|
def.max_force = F32Infinity;
|
||||||
def.linear_spring_hz = 5;
|
def.linear_spring_hz = 5;
|
||||||
def.linear_spring_damp = 0.7f;
|
def.linear_spring_damp = 0.7f;
|
||||||
def.angular_spring_hz = 1;
|
def.angular_spring_hz = 1;
|
||||||
@ -1731,11 +1731,11 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
if (!sim_ent_should_simulate(ent)) continue;
|
if (!sim_ent_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SEPROP_TRACER)) continue;
|
if (!sim_ent_has_prop(ent, SEPROP_TRACER)) continue;
|
||||||
|
|
||||||
V2 end = sim_ent_get_xform(ent).og;
|
Vec2 end = sim_ent_get_xform(ent).og;
|
||||||
|
|
||||||
V2 tick_velocity = v2_mul(ent->tracer_start_velocity, sim_dt);
|
Vec2 tick_velocity = v2_mul(ent->tracer_start_velocity, sim_dt);
|
||||||
V2 gradient_start = v2_add(ent->tracer_gradient_start, tick_velocity);
|
Vec2 gradient_start = v2_add(ent->tracer_gradient_start, tick_velocity);
|
||||||
V2 gradient_end = v2_add(ent->tracer_gradient_end, tick_velocity);
|
Vec2 gradient_end = v2_add(ent->tracer_gradient_end, tick_velocity);
|
||||||
|
|
||||||
if (v2_dot(tick_velocity, v2_sub(gradient_start, end)) > 0) {
|
if (v2_dot(tick_velocity, v2_sub(gradient_start, end)) > 0) {
|
||||||
/* Tracer has disappeared */
|
/* Tracer has disappeared */
|
||||||
@ -1763,8 +1763,8 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
sim_ent_enable_prop(ent, SEPROP_SENSOR);
|
sim_ent_enable_prop(ent, SEPROP_SENSOR);
|
||||||
sim_ent_enable_prop(ent, SEPROP_TOI);
|
sim_ent_enable_prop(ent, SEPROP_TOI);
|
||||||
|
|
||||||
V2 pos = xform_mul_v2(src_xf, ent->bullet_src_pos);
|
Vec2 pos = MulXformV2(src_xf, ent->bullet_src_pos);
|
||||||
V2 vel = xform_basis_mul_v2(src_xf, ent->bullet_src_dir);
|
Vec2 vel = MulXformBasisV2(src_xf, ent->bullet_src_dir);
|
||||||
vel = v2_with_len(vel, ent->bullet_launch_velocity);
|
vel = v2_with_len(vel, ent->bullet_launch_velocity);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -1776,7 +1776,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Xform xf = XFORM_TRS(.t = pos, .r = v2_angle(vel) + Pi / 2);
|
Xform xf = XformFromTrs(TRS(.t = pos, .r = v2_angle(vel) + Pi / 2));
|
||||||
sim_ent_set_xform(ent, xf);
|
sim_ent_set_xform(ent, xf);
|
||||||
|
|
||||||
sim_ent_enable_prop(ent, SEPROP_KINEMATIC);
|
sim_ent_enable_prop(ent, SEPROP_KINEMATIC);
|
||||||
@ -1797,7 +1797,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
/* Spawn quake */
|
/* Spawn quake */
|
||||||
{
|
{
|
||||||
Ent *quake = sim_ent_alloc_sync_src(root);
|
Ent *quake = sim_ent_alloc_sync_src(root);
|
||||||
sim_ent_set_xform(quake, XFORM_POS(pos));
|
sim_ent_set_xform(quake, XformFromPos(pos));
|
||||||
quake->quake_intensity = 0.2f;
|
quake->quake_intensity = 0.2f;
|
||||||
quake->quake_fade = quake->quake_intensity / 0.1f;
|
quake->quake_fade = quake->quake_intensity / 0.1f;
|
||||||
sim_ent_enable_prop(quake, SEPROP_QUAKE);
|
sim_ent_enable_prop(quake, SEPROP_QUAKE);
|
||||||
@ -1822,23 +1822,23 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
|
|
||||||
f32 aspect_ratio = 1.0;
|
f32 aspect_ratio = 1.0;
|
||||||
{
|
{
|
||||||
Xform quad_xf = xform_mul(sim_ent_get_xform(ent), ent->camera_quad_xform);
|
Xform quad_xf = MulXform(sim_ent_get_xform(ent), ent->camera_quad_xform);
|
||||||
V2 camera_size = xform_get_scale(quad_xf);
|
Vec2 camera_size = GetXformScale(quad_xf);
|
||||||
if (!v2_is_zero(camera_size)) {
|
if (!v2_is_zero(camera_size)) {
|
||||||
aspect_ratio = camera_size.x / camera_size.y;
|
aspect_ratio = camera_size.x / camera_size.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f32 ratio_y = 0.33f;
|
f32 ratio_y = 0.33f;
|
||||||
f32 ratio_x = ratio_y / aspect_ratio;
|
f32 ratio_x = ratio_y / aspect_ratio;
|
||||||
V2 camera_focus_dir = v2_mul_v2(follow->control.focus, V2FromXY(ratio_x, ratio_y));
|
Vec2 camera_focus_dir = v2_mul_v2(follow->control.focus, V2(ratio_x, ratio_y));
|
||||||
V2 camera_focus_pos = v2_add(sim_ent_get_xform(follow).og, camera_focus_dir);
|
Vec2 camera_focus_pos = v2_add(sim_ent_get_xform(follow).og, camera_focus_dir);
|
||||||
ent->camera_xform_target = xf;
|
ent->camera_xform_target = xf;
|
||||||
ent->camera_xform_target.og = camera_focus_pos;
|
ent->camera_xform_target.og = camera_focus_pos;
|
||||||
|
|
||||||
/* Lerp camera */
|
/* Lerp camera */
|
||||||
if (ent->camera_applied_lerp_continuity_gen_plus_one == ent->camera_lerp_continuity_gen + 1) {
|
if (ent->camera_applied_lerp_continuity_gen_plus_one == ent->camera_lerp_continuity_gen + 1) {
|
||||||
f32 t = 1 - math_pow(2.f, -20.f * (f32)sim_dt);
|
f32 t = 1 - math_pow(2.f, -20.f * (f32)sim_dt);
|
||||||
xf = xform_lerp(xf, ent->camera_xform_target, t);
|
xf = LerpXform(xf, ent->camera_xform_target, t);
|
||||||
} else {
|
} else {
|
||||||
/* Skip lerp */
|
/* Skip lerp */
|
||||||
xf = ent->camera_xform_target;
|
xf = ent->camera_xform_target;
|
||||||
@ -1870,7 +1870,7 @@ void sim_step(SimStepCtx *ctx)
|
|||||||
if (!sim_ent_should_simulate(ent)) continue;
|
if (!sim_ent_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SEPROP_QUAKE)) continue;
|
if (!sim_ent_has_prop(ent, SEPROP_QUAKE)) continue;
|
||||||
|
|
||||||
ent->quake_intensity = max_f32(0, ent->quake_intensity - (ent->quake_fade * sim_dt));
|
ent->quake_intensity = MaxF32(0, ent->quake_intensity - (ent->quake_fade * sim_dt));
|
||||||
if (ent->quake_intensity <= 0) {
|
if (ent->quake_intensity <= 0) {
|
||||||
sim_ent_enable_prop(ent, SEPROP_RELEASE);
|
sim_ent_enable_prop(ent, SEPROP_RELEASE);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -206,19 +206,19 @@ S_StartupReceipt sprite_startup(void)
|
|||||||
u32 width = 64;
|
u32 width = 64;
|
||||||
u32 height = 64;
|
u32 height = 64;
|
||||||
u32 *pixels = generate_purple_black_image(scratch.arena, width, height);
|
u32 *pixels = generate_purple_black_image(scratch.arena, width, height);
|
||||||
G.nil_texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32FromXY(width, height), pixels);
|
G.nil_texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(width, height), pixels);
|
||||||
EndScratch(scratch);
|
EndScratch(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init loading sheet */
|
/* Init loading sheet */
|
||||||
G.loading_sheet = PushStruct(G.perm_arena, S_Sheet);
|
G.loading_sheet = PushStruct(G.perm_arena, S_Sheet);
|
||||||
G.loading_sheet->image_size = V2FromXY(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
G.loading_sheet->image_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
||||||
G.loading_sheet->frame_size = V2FromXY(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
G.loading_sheet->frame_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
||||||
|
|
||||||
/* Init nil sheet */
|
/* Init nil sheet */
|
||||||
G.nil_sheet = PushStruct(G.perm_arena, S_Sheet);
|
G.nil_sheet = PushStruct(G.perm_arena, S_Sheet);
|
||||||
G.nil_sheet->image_size = V2FromXY(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
G.nil_sheet->image_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
||||||
G.nil_sheet->frame_size = V2FromXY(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
G.nil_sheet->frame_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
||||||
G.nil_sheet->loaded = 1;
|
G.nil_sheet->loaded = 1;
|
||||||
}
|
}
|
||||||
SetArenaReadonly(G.perm_arena);
|
SetArenaReadonly(G.perm_arena);
|
||||||
@ -304,7 +304,7 @@ internal void push_load_job(struct cache_ref ref, S_Tag tag)
|
|||||||
cmd->ref = scope_ensure_ref_from_ref(cmd->scope, ref)->ref;
|
cmd->ref = scope_ensure_ref_from_ref(cmd->scope, ref)->ref;
|
||||||
cmd->tag = tag;
|
cmd->tag = tag;
|
||||||
{
|
{
|
||||||
u64 copy_len = min_u64(tag.path.len, countof(cmd->tag_path_buff));
|
u64 copy_len = MinU64(tag.path.len, countof(cmd->tag_path_buff));
|
||||||
cmd->tag.path.text = cmd->tag_path_buff;
|
cmd->tag.path.text = cmd->tag_path_buff;
|
||||||
MEMCPY(cmd->tag.path.text, tag.path.text, copy_len);
|
MEMCPY(cmd->tag.path.text, tag.path.text, copy_len);
|
||||||
}
|
}
|
||||||
@ -353,7 +353,7 @@ internal void cache_entry_load_texture(struct cache_ref ref, S_Tag tag)
|
|||||||
e->texture->height = decoded.height;
|
e->texture->height = decoded.height;
|
||||||
e->texture->valid = 1;
|
e->texture->valid = 1;
|
||||||
e->texture->loaded = 1;
|
e->texture->loaded = 1;
|
||||||
e->texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, 0, V2I32FromXY(decoded.width, decoded.height), decoded.pixels);
|
e->texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, 0, V2I32(decoded.width, decoded.height), decoded.pixels);
|
||||||
/* TODO: Query gpu for more accurate texture size in VRAM */
|
/* TODO: Query gpu for more accurate texture size in VRAM */
|
||||||
memory_size += (decoded.width * decoded.height) * sizeof(*decoded.pixels);
|
memory_size += (decoded.width * decoded.height) * sizeof(*decoded.pixels);
|
||||||
success = 1;
|
success = 1;
|
||||||
@ -397,8 +397,8 @@ internal S_Sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
|
|||||||
|
|
||||||
Assert(ase.num_frames >= 1);
|
Assert(ase.num_frames >= 1);
|
||||||
|
|
||||||
V2 frame_size = ase.frame_size;
|
Vec2 frame_size = ase.frame_size;
|
||||||
V2 frame_center = v2_mul(ase.frame_size, 0.5f);
|
Vec2 frame_center = v2_mul(ase.frame_size, 0.5f);
|
||||||
|
|
||||||
/* Init frames */
|
/* Init frames */
|
||||||
{
|
{
|
||||||
@ -410,8 +410,8 @@ internal S_Sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
|
|||||||
for (Ase_Frame *ase_frame = ase.frame_head; ase_frame; ase_frame = ase_frame->next) {
|
for (Ase_Frame *ase_frame = ase.frame_head; ase_frame; ase_frame = ase_frame->next) {
|
||||||
u32 index = ase_frame->index;
|
u32 index = ase_frame->index;
|
||||||
|
|
||||||
V2 clip_p1 = { (f32)ase_frame->x1 / (f32)ase.image_size.x, (f32)ase_frame->y1 / (f32)ase.image_size.y };
|
Vec2 clip_p1 = { (f32)ase_frame->x1 / (f32)ase.image_size.x, (f32)ase_frame->y1 / (f32)ase.image_size.y };
|
||||||
V2 clip_p2 = { (f32)ase_frame->x2 / (f32)ase.image_size.x, (f32)ase_frame->y2 / (f32)ase.image_size.y };
|
Vec2 clip_p2 = { (f32)ase_frame->x2 / (f32)ase.image_size.x, (f32)ase_frame->y2 / (f32)ase.image_size.y };
|
||||||
|
|
||||||
sheet.frames[index] = (S_SheetFrame) {
|
sheet.frames[index] = (S_SheetFrame) {
|
||||||
.index = index,
|
.index = index,
|
||||||
@ -533,11 +533,11 @@ internal S_Sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
|
|||||||
Rect rect_px = RectFromScalar(x1_px, y1_px, width_px, height_px);
|
Rect rect_px = RectFromScalar(x1_px, y1_px, width_px, height_px);
|
||||||
Rect rect = RectFromScalar(x1, y1, width, height);
|
Rect rect = RectFromScalar(x1, y1, width, height);
|
||||||
/* Center */
|
/* Center */
|
||||||
V2 center_px = V2FromXY(x1_px + (width_px * 0.5f), y1_px + (height_px * 0.5f));
|
Vec2 center_px = V2(x1_px + (width_px * 0.5f), y1_px + (height_px * 0.5f));
|
||||||
V2 center = V2FromXY(x1 + (width * 0.5f), y1 + (height * 0.5f));
|
Vec2 center = V2(x1 + (width * 0.5f), y1 + (height * 0.5f));
|
||||||
/* Dir */
|
/* Dir */
|
||||||
V2 dir_px = V2FromXY(center_px.x, -1);
|
Vec2 dir_px = V2(center_px.x, -1);
|
||||||
V2 dir = V2FromXY(0, -1);
|
Vec2 dir = V2(0, -1);
|
||||||
|
|
||||||
slice->rect_px = rect_px;
|
slice->rect_px = rect_px;
|
||||||
slice->center_px = center_px;
|
slice->center_px = center_px;
|
||||||
@ -614,8 +614,8 @@ internal S_Sheet init_sheet_from_ase_result(Arena *arena, Ase_DecodedSheet ase)
|
|||||||
for (u32 i = 0; i < ase.num_frames; ++i) {
|
for (u32 i = 0; i < ase.num_frames; ++i) {
|
||||||
/* Use ray slice in ray group */
|
/* Use ray slice in ray group */
|
||||||
S_SheetSlice *ray_slice = &ray_slice_group->frame_slices[i * point_slices_per_frame];
|
S_SheetSlice *ray_slice = &ray_slice_group->frame_slices[i * point_slices_per_frame];
|
||||||
V2 ray_end = ray_slice->center_px;
|
Vec2 ray_end = ray_slice->center_px;
|
||||||
V2 ray_end_norm = ray_slice->center;
|
Vec2 ray_end_norm = ray_slice->center;
|
||||||
|
|
||||||
/* Apply to each point slice in point group */
|
/* Apply to each point slice in point group */
|
||||||
for (u32 j = 0; j < point_slices_per_frame; ++j) {
|
for (u32 j = 0; j < point_slices_per_frame; ++j) {
|
||||||
@ -1078,10 +1078,10 @@ S_SheetSlice sprite_sheet_get_slice(S_Sheet *sheet, String name, u32 frame_index
|
|||||||
S_SheetSlice res = ZI;
|
S_SheetSlice res = ZI;
|
||||||
if (string_eq(name, LIT("pivot"))) {
|
if (string_eq(name, LIT("pivot"))) {
|
||||||
/* 'pivot' slice does not exist, return center */
|
/* 'pivot' slice does not exist, return center */
|
||||||
res.center = V2FromXY(0, 0);
|
res.center = V2(0, 0);
|
||||||
res.center_px = v2_mul(sheet->frame_size, 0.5f);
|
res.center_px = v2_mul(sheet->frame_size, 0.5f);
|
||||||
res.dir_px = V2FromXY(res.center_px.x, 0);
|
res.dir_px = V2(res.center_px.x, 0);
|
||||||
res.dir = V2FromXY(0, -0.5);
|
res.dir = V2(0, -0.5);
|
||||||
} else {
|
} else {
|
||||||
res = sprite_sheet_get_slice(sheet, LIT("pivot"), frame_index);
|
res = sprite_sheet_get_slice(sheet, LIT("pivot"), frame_index);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,8 +65,8 @@ typedef struct S_Sheet S_Sheet;
|
|||||||
struct S_Sheet {
|
struct S_Sheet {
|
||||||
b32 loaded;
|
b32 loaded;
|
||||||
b32 valid;
|
b32 valid;
|
||||||
V2 image_size;
|
Vec2 image_size;
|
||||||
V2 frame_size;
|
Vec2 frame_size;
|
||||||
|
|
||||||
u32 frames_count;
|
u32 frames_count;
|
||||||
S_SheetFrame *frames;
|
S_SheetFrame *frames;
|
||||||
@ -112,13 +112,13 @@ struct S_SheetSlice {
|
|||||||
|
|
||||||
/* Values are in the range -0.5 (top / left edge) -> +0.5 (bottom / right edge) */
|
/* Values are in the range -0.5 (top / left edge) -> +0.5 (bottom / right edge) */
|
||||||
Rect rect;
|
Rect rect;
|
||||||
V2 center;
|
Vec2 center;
|
||||||
V2 dir;
|
Vec2 dir;
|
||||||
|
|
||||||
/* '_px' values retain the original sprite pixel dimensions */
|
/* '_px' values retain the original sprite pixel dimensions */
|
||||||
Rect rect_px;
|
Rect rect_px;
|
||||||
V2 center_px;
|
Vec2 center_px;
|
||||||
V2 dir_px;
|
Vec2 dir_px;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct S_SheetSliceArray S_SheetSliceArray;
|
typedef struct S_SheetSliceArray S_SheetSliceArray;
|
||||||
|
|||||||
@ -53,7 +53,7 @@ Global struct {
|
|||||||
EntId debug_following;
|
EntId debug_following;
|
||||||
b32 debug_camera;
|
b32 debug_camera;
|
||||||
b32 debug_camera_panning;
|
b32 debug_camera_panning;
|
||||||
V2 debug_camera_pan_start;
|
Vec2 debug_camera_pan_start;
|
||||||
b32 debug_draw;
|
b32 debug_draw;
|
||||||
|
|
||||||
/* Debug console */
|
/* Debug console */
|
||||||
@ -102,21 +102,21 @@ Global struct {
|
|||||||
|
|
||||||
/* Per-frame */
|
/* Per-frame */
|
||||||
|
|
||||||
V2 screen_size;
|
Vec2 screen_size;
|
||||||
V2 screen_cursor;
|
Vec2 screen_cursor;
|
||||||
|
|
||||||
Xform ui_to_screen_xf;
|
Xform ui_to_screen_xf;
|
||||||
V2 ui_size;
|
Vec2 ui_size;
|
||||||
V2 ui_cursor;
|
Vec2 ui_cursor;
|
||||||
|
|
||||||
Xform render_to_ui_xf;
|
Xform render_to_ui_xf;
|
||||||
V2 render_size;
|
Vec2 render_size;
|
||||||
|
|
||||||
Xform world_to_render_xf;
|
Xform world_to_render_xf;
|
||||||
Xform world_to_ui_xf;
|
Xform world_to_ui_xf;
|
||||||
V2 world_cursor;
|
Vec2 world_cursor;
|
||||||
|
|
||||||
V2 focus_send;
|
Vec2 focus_send;
|
||||||
} G = ZI, DebugAlias(G, G_user);
|
} G = ZI, DebugAlias(G, G_user);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -220,8 +220,8 @@ struct user_startup_receipt user_startup(F_StartupReceipt *font_sr,
|
|||||||
G.local_to_user_client = sim_client_alloc(G.local_to_user_client_store);
|
G.local_to_user_client = sim_client_alloc(G.local_to_user_client_store);
|
||||||
|
|
||||||
/* GPU handles */
|
/* GPU handles */
|
||||||
G.world_to_ui_xf = XFORM_IDENT;
|
G.world_to_ui_xf = XformIdentity;
|
||||||
G.world_to_render_xf = XFORM_IDENT;
|
G.world_to_render_xf = XformIdentity;
|
||||||
G.render_sig = gp_render_sig_alloc();
|
G.render_sig = gp_render_sig_alloc();
|
||||||
|
|
||||||
G.console_logs_arena = AllocArena(Gibi(64));
|
G.console_logs_arena = AllocArena(Gibi(64));
|
||||||
@ -229,7 +229,7 @@ struct user_startup_receipt user_startup(F_StartupReceipt *font_sr,
|
|||||||
P_RegisterLogCallback(debug_console_log_callback, P_LogLevel_Debug);
|
P_RegisterLogCallback(debug_console_log_callback, P_LogLevel_Debug);
|
||||||
|
|
||||||
G.window = P_AllocWindow();
|
G.window = P_AllocWindow();
|
||||||
G.swapchain = gp_swapchain_alloc(G.window, V2I32FromXY(100, 100));
|
G.swapchain = gp_swapchain_alloc(G.window, V2I32(100, 100));
|
||||||
P_ShowWindow(G.window);
|
P_ShowWindow(G.window);
|
||||||
|
|
||||||
/* Start jobs */
|
/* Start jobs */
|
||||||
@ -258,9 +258,9 @@ internal void debug_draw_xform(Xform xf, u32 color_x, u32 color_y)
|
|||||||
f32 thickness = 2.f;
|
f32 thickness = 2.f;
|
||||||
f32 arrowhead_len = 15.f;
|
f32 arrowhead_len = 15.f;
|
||||||
|
|
||||||
V2 pos = xform_mul_v2(G.world_to_ui_xf, xf.og);
|
Vec2 pos = MulXformV2(G.world_to_ui_xf, xf.og);
|
||||||
V2 x_ray = xform_basis_mul_v2(G.world_to_ui_xf, xform_get_right(xf));
|
Vec2 x_ray = MulXformBasisV2(G.world_to_ui_xf, GetXformRight(xf));
|
||||||
V2 y_ray = xform_basis_mul_v2(G.world_to_ui_xf, xform_get_up(xf));
|
Vec2 y_ray = MulXformBasisV2(G.world_to_ui_xf, GetXformUp(xf));
|
||||||
|
|
||||||
f32 ray_scale = 1;
|
f32 ray_scale = 1;
|
||||||
x_ray = v2_mul(x_ray, ray_scale);
|
x_ray = v2_mul(x_ray, ray_scale);
|
||||||
@ -271,7 +271,7 @@ internal void debug_draw_xform(Xform xf, u32 color_x, u32 color_y)
|
|||||||
|
|
||||||
//u32 color_quad = Rgba32F(0, 1, 1, 0.3);
|
//u32 color_quad = Rgba32F(0, 1, 1, 0.3);
|
||||||
//Quad quad = quad_from_rect(RectFromScalar(0, 0, 1, -1));
|
//Quad quad = quad_from_rect(RectFromScalar(0, 0, 1, -1));
|
||||||
//quad = xform_mul_quad(xf, quad_scale(quad, 0.075f));
|
//quad = MulXformQuad(xf, quad_scale(quad, 0.075f));
|
||||||
//draw_quad(G.render_sig, quad, color);
|
//draw_quad(G.render_sig, quad, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,10 +283,10 @@ internal void debug_draw_movement(Ent *ent)
|
|||||||
u32 color_vel = ColorOrange;
|
u32 color_vel = ColorOrange;
|
||||||
|
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
V2 velocity = ent->linear_velocity;
|
Vec2 velocity = ent->linear_velocity;
|
||||||
|
|
||||||
V2 pos = xform_mul_v2(G.world_to_ui_xf, xf.og);
|
Vec2 pos = MulXformV2(G.world_to_ui_xf, xf.og);
|
||||||
V2 vel_ray = xform_basis_mul_v2(G.world_to_ui_xf, velocity);
|
Vec2 vel_ray = MulXformBasisV2(G.world_to_ui_xf, velocity);
|
||||||
|
|
||||||
if (v2_len(vel_ray) > 0.00001) {
|
if (v2_len(vel_ray) > 0.00001) {
|
||||||
draw_arrow_ray(G.render_sig, pos, vel_ray, thickness, arrow_len, color_vel);
|
draw_arrow_ray(G.render_sig, pos, vel_ray, thickness, arrow_len, color_vel);
|
||||||
@ -352,7 +352,7 @@ internal String get_ent_debug_text(Arena *arena, Ent *ent)
|
|||||||
|
|
||||||
/* Pos */
|
/* Pos */
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
V2 linear_velocity = ent->linear_velocity;
|
Vec2 linear_velocity = ent->linear_velocity;
|
||||||
f32 angular_velocity = ent->angular_velocity;
|
f32 angular_velocity = ent->angular_velocity;
|
||||||
res.len += string_format(arena, LIT("pos: (%F, %F)\n"), FMT_FLOAT(xf.og.x), FMT_FLOAT(xf.og.y)).len;
|
res.len += string_format(arena, LIT("pos: (%F, %F)\n"), FMT_FLOAT(xf.og.x), FMT_FLOAT(xf.og.y)).len;
|
||||||
res.len += string_format(arena, LIT("linear velocity: (%F, %F)\n"), FMT_FLOAT(linear_velocity.x), FMT_FLOAT(linear_velocity.y)).len;
|
res.len += string_format(arena, LIT("linear velocity: (%F, %F)\n"), FMT_FLOAT(linear_velocity.x), FMT_FLOAT(linear_velocity.y)).len;
|
||||||
@ -416,7 +416,7 @@ internal void draw_debug_console(i32 level, b32 minimized)
|
|||||||
__prof;
|
__prof;
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
|
|
||||||
V2 desired_start_pos = V2FromXY(10, minimized ? 100 : 600);
|
Vec2 desired_start_pos = V2(10, minimized ? 100 : 600);
|
||||||
i64 fade_time_ns = NsFromSeconds(10);
|
i64 fade_time_ns = NsFromSeconds(10);
|
||||||
f32 fade_curve = 0.5;
|
f32 fade_curve = 0.5;
|
||||||
f32 spacing = 0;
|
f32 spacing = 0;
|
||||||
@ -437,9 +437,9 @@ internal void draw_debug_console(i32 level, b32 minimized)
|
|||||||
u32 error_colors[2] = { Rgb32F(0.4, 0.1, 0.1), Rgb32F(0.5, 0.2, 0.2) };
|
u32 error_colors[2] = { Rgb32F(0.4, 0.1, 0.1), Rgb32F(0.5, 0.2, 0.2) };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
V2 draw_pos = desired_start_pos;
|
Vec2 draw_pos = desired_start_pos;
|
||||||
f32 bounds_top = F32_INFINITY;
|
f32 bounds_top = F32Infinity;
|
||||||
f32 bounds_bottom = -F32_INFINITY;
|
f32 bounds_bottom = -F32Infinity;
|
||||||
|
|
||||||
if (G.console_logs_height < desired_start_pos.y) {
|
if (G.console_logs_height < desired_start_pos.y) {
|
||||||
draw_pos.y = G.console_logs_height;
|
draw_pos.y = G.console_logs_height;
|
||||||
@ -454,7 +454,7 @@ internal void draw_debug_console(i32 level, b32 minimized)
|
|||||||
for (struct console_log *log = G.last_console_log; log; log = log->prev) {
|
for (struct console_log *log = G.last_console_log; log; log = log->prev) {
|
||||||
f32 opacity = 0.75;
|
f32 opacity = 0.75;
|
||||||
if (minimized) {
|
if (minimized) {
|
||||||
f32 lin = 1.0 - clamp_f64((f64)(now_ns - log->time_ns) / (f64)fade_time_ns, 0, 1);
|
f32 lin = 1.0 - ClampF64((f64)(now_ns - log->time_ns) / (f64)fade_time_ns, 0, 1);
|
||||||
opacity *= math_pow(lin, fade_curve);
|
opacity *= math_pow(lin, fade_curve);
|
||||||
}
|
}
|
||||||
if (draw_pos.y > -desired_start_pos.y && opacity > 0) {
|
if (draw_pos.y > -desired_start_pos.y && opacity > 0) {
|
||||||
@ -488,8 +488,8 @@ internal void draw_debug_console(i32 level, b32 minimized)
|
|||||||
draw_pos.y -= draw_bounds.height + spacing;
|
draw_pos.y -= draw_bounds.height + spacing;
|
||||||
log->bounds = draw_bounds;
|
log->bounds = draw_bounds;
|
||||||
|
|
||||||
bounds_top = min_f32(bounds_top, draw_bounds.y);
|
bounds_top = MinF32(bounds_top, draw_bounds.y);
|
||||||
bounds_bottom = max_f32(bounds_bottom, draw_bounds.y + draw_bounds.height);
|
bounds_bottom = MaxF32(bounds_bottom, draw_bounds.y + draw_bounds.height);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@ -498,7 +498,7 @@ internal void draw_debug_console(i32 level, b32 minimized)
|
|||||||
}
|
}
|
||||||
P_Unlock(&lock);
|
P_Unlock(&lock);
|
||||||
}
|
}
|
||||||
if (bounds_top < F32_INFINITY && bounds_bottom > -F32_INFINITY) {
|
if (bounds_top < F32Infinity && bounds_bottom > -F32Infinity) {
|
||||||
G.console_logs_height = bounds_bottom - bounds_top;
|
G.console_logs_height = bounds_bottom - bounds_top;
|
||||||
}
|
}
|
||||||
EndScratch(scratch);
|
EndScratch(scratch);
|
||||||
@ -753,9 +753,9 @@ internal void user_update(P_Window *window)
|
|||||||
|
|
||||||
Ent *hovered_ent = sim_ent_nil();
|
Ent *hovered_ent = sim_ent_nil();
|
||||||
{
|
{
|
||||||
Xform mouse_xf = xform_from_pos(G.world_cursor);
|
Xform mouse_xf = XformFromPos(G.world_cursor);
|
||||||
CLD_Shape mouse_shape = ZI;
|
CLD_Shape mouse_shape = ZI;
|
||||||
mouse_shape.points[0] = V2FromXY(0, 0);
|
mouse_shape.points[0] = V2(0, 0);
|
||||||
mouse_shape.count = 1;
|
mouse_shape.count = 1;
|
||||||
mouse_shape.radius = 0.01f;
|
mouse_shape.radius = 0.01f;
|
||||||
for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) {
|
||||||
@ -849,13 +849,13 @@ internal void user_update(P_Window *window)
|
|||||||
f32 angle0 = rand_f64_from_seed(angle_seed0, 0, Tau);
|
f32 angle0 = rand_f64_from_seed(angle_seed0, 0, Tau);
|
||||||
f32 angle1 = rand_f64_from_seed(angle_seed1, 0, Tau);
|
f32 angle1 = rand_f64_from_seed(angle_seed1, 0, Tau);
|
||||||
|
|
||||||
V2 vec0 = v2_with_len(v2_from_angle(angle0), shake);
|
Vec2 vec0 = v2_with_len(v2_from_angle(angle0), shake);
|
||||||
/* NOTE: vec1 not completely accurate since shake can change between frames, it's just a prediction */
|
/* NOTE: vec1 not completely accurate since shake can change between frames, it's just a prediction */
|
||||||
V2 vec1 = v2_with_len(v2_from_angle(angle1), shake);
|
Vec2 vec1 = v2_with_len(v2_from_angle(angle1), shake);
|
||||||
|
|
||||||
/* TODO: Cubic interp? */
|
/* TODO: Cubic interp? */
|
||||||
f32 blend = (f32)(G.ss_blended->sim_time_ns % frequency_ns) / (f32)frequency_ns;
|
f32 blend = (f32)(G.ss_blended->sim_time_ns % frequency_ns) / (f32)frequency_ns;
|
||||||
V2 vec = v2_lerp(vec0, vec1, blend);
|
Vec2 vec = v2_lerp(vec0, vec1, blend);
|
||||||
|
|
||||||
Xform xf = sim_ent_get_xform(ent);
|
Xform xf = sim_ent_get_xform(ent);
|
||||||
xf.og = v2_add(xf.og, v2_mul(vec, shake));
|
xf.og = v2_add(xf.og, v2_mul(vec, shake));
|
||||||
@ -869,14 +869,14 @@ internal void user_update(P_Window *window)
|
|||||||
|
|
||||||
if (G.debug_camera) {
|
if (G.debug_camera) {
|
||||||
G.ui_size = G.screen_size;
|
G.ui_size = G.screen_size;
|
||||||
G.ui_to_screen_xf = XFORM_IDENT;
|
G.ui_to_screen_xf = XformIdentity;
|
||||||
G.ui_to_screen_xf.og = v2_round(G.ui_to_screen_xf.og);
|
G.ui_to_screen_xf.og = v2_round(G.ui_to_screen_xf.og);
|
||||||
} else {
|
} else {
|
||||||
/* Determine ui size by camera & window dimensions */
|
/* Determine ui size by camera & window dimensions */
|
||||||
f32 aspect_ratio = (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT);
|
f32 aspect_ratio = (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT);
|
||||||
if (local_camera->valid) {
|
if (local_camera->valid) {
|
||||||
Xform quad_xf = xform_mul(sim_ent_get_xform(local_camera), local_camera->camera_quad_xform);
|
Xform quad_xf = MulXform(sim_ent_get_xform(local_camera), local_camera->camera_quad_xform);
|
||||||
V2 camera_size = xform_get_scale(quad_xf);
|
Vec2 camera_size = GetXformScale(quad_xf);
|
||||||
if (!v2_is_zero(camera_size)) {
|
if (!v2_is_zero(camera_size)) {
|
||||||
aspect_ratio = camera_size.x / camera_size.y;
|
aspect_ratio = camera_size.x / camera_size.y;
|
||||||
}
|
}
|
||||||
@ -888,25 +888,25 @@ internal void user_update(P_Window *window)
|
|||||||
} else {
|
} else {
|
||||||
height = math_ceil(width / aspect_ratio);
|
height = math_ceil(width / aspect_ratio);
|
||||||
}
|
}
|
||||||
G.ui_size = V2FromXY(width, height);
|
G.ui_size = V2(width, height);
|
||||||
|
|
||||||
/* Center ui in window */
|
/* Center ui in window */
|
||||||
f32 x = math_round(G.screen_size.x / 2 - width / 2);
|
f32 x = math_round(G.screen_size.x / 2 - width / 2);
|
||||||
f32 y = math_round(G.screen_size.y / 2 - height / 2);
|
f32 y = math_round(G.screen_size.y / 2 - height / 2);
|
||||||
G.ui_to_screen_xf = XFORM_TRS(.t = V2FromXY(x, y));
|
G.ui_to_screen_xf = XformFromTrs(TRS(.t = V2(x, y)));
|
||||||
G.ui_to_screen_xf.og = v2_round(G.ui_to_screen_xf.og);
|
G.ui_to_screen_xf.og = v2_round(G.ui_to_screen_xf.og);
|
||||||
}
|
}
|
||||||
|
|
||||||
G.ui_cursor = xform_mul_v2(xform_invert(G.ui_to_screen_xf), G.screen_cursor);
|
G.ui_cursor = MulXformV2(InvertXform(G.ui_to_screen_xf), G.screen_cursor);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update world to ui xform from camera
|
* Update world to ui xform from camera
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
if (G.debug_camera) {
|
if (G.debug_camera) {
|
||||||
G.world_to_ui_xf = xform_basis_with_rotation_world(G.world_to_ui_xf, 0);
|
G.world_to_ui_xf = XformWIthWorldRotation(G.world_to_ui_xf, 0);
|
||||||
|
|
||||||
V2 world_cursor = xform_invert_mul_v2(G.world_to_ui_xf, G.ui_cursor);
|
Vec2 world_cursor = InvertXformMulV2(G.world_to_ui_xf, G.ui_cursor);
|
||||||
|
|
||||||
/* Pan view */
|
/* Pan view */
|
||||||
if (G.bind_states[USER_BIND_KIND_PAN].is_held) {
|
if (G.bind_states[USER_BIND_KIND_PAN].is_held) {
|
||||||
@ -914,9 +914,9 @@ internal void user_update(P_Window *window)
|
|||||||
G.debug_camera_pan_start = world_cursor;
|
G.debug_camera_pan_start = world_cursor;
|
||||||
G.debug_camera_panning = 1;
|
G.debug_camera_panning = 1;
|
||||||
}
|
}
|
||||||
V2 offset = v2_neg(v2_sub(G.debug_camera_pan_start, world_cursor));
|
Vec2 offset = v2_neg(v2_sub(G.debug_camera_pan_start, world_cursor));
|
||||||
G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, offset);
|
G.world_to_ui_xf = TranslateXform(G.world_to_ui_xf, offset);
|
||||||
world_cursor = xform_invert_mul_v2(G.world_to_ui_xf, G.ui_cursor);
|
world_cursor = InvertXformMulV2(G.world_to_ui_xf, G.ui_cursor);
|
||||||
G.debug_camera_pan_start = world_cursor;
|
G.debug_camera_pan_start = world_cursor;
|
||||||
} else {
|
} else {
|
||||||
G.debug_camera_panning = 0;
|
G.debug_camera_panning = 0;
|
||||||
@ -928,66 +928,66 @@ internal void user_update(P_Window *window)
|
|||||||
/* Zoom to cursor */
|
/* Zoom to cursor */
|
||||||
f32 zoom_rate = 2;
|
f32 zoom_rate = 2;
|
||||||
f32 zoom = math_pow(zoom_rate, input_zooms);
|
f32 zoom = math_pow(zoom_rate, input_zooms);
|
||||||
G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, world_cursor);
|
G.world_to_ui_xf = TranslateXform(G.world_to_ui_xf, world_cursor);
|
||||||
G.world_to_ui_xf = xform_scaled(G.world_to_ui_xf, V2FromXY(zoom, zoom));
|
G.world_to_ui_xf = ScaleXform(G.world_to_ui_xf, V2(zoom, zoom));
|
||||||
G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, v2_neg(world_cursor));
|
G.world_to_ui_xf = TranslateXform(G.world_to_ui_xf, v2_neg(world_cursor));
|
||||||
}
|
}
|
||||||
G.world_to_ui_xf.og = v2_round(G.world_to_ui_xf.og);
|
G.world_to_ui_xf.og = v2_round(G.world_to_ui_xf.og);
|
||||||
} else {
|
} else {
|
||||||
Xform xf = sim_ent_get_xform(local_camera);
|
Xform xf = sim_ent_get_xform(local_camera);
|
||||||
|
|
||||||
V2 world_center = xf.og;
|
Vec2 world_center = xf.og;
|
||||||
f32 rot = xform_get_rotation(xf);
|
f32 rot = GetXformRotation(xf);
|
||||||
|
|
||||||
/* Scale view into viewport based on camera size */
|
/* Scale view into viewport based on camera size */
|
||||||
V2 scale = G.ui_size;
|
Vec2 scale = G.ui_size;
|
||||||
{
|
{
|
||||||
Xform quad_xf = xform_mul(xf, local_camera->camera_quad_xform);
|
Xform quad_xf = MulXform(xf, local_camera->camera_quad_xform);
|
||||||
V2 camera_size = xform_get_scale(quad_xf);
|
Vec2 camera_size = GetXformScale(quad_xf);
|
||||||
if (!v2_is_zero(camera_size)) {
|
if (!v2_is_zero(camera_size)) {
|
||||||
scale = v2_div_v2(G.ui_size, camera_size);
|
scale = v2_div_v2(G.ui_size, camera_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scale.x = min_f32(scale.x, scale.y);
|
scale.x = MinF32(scale.x, scale.y);
|
||||||
scale.y = scale.x;
|
scale.y = scale.x;
|
||||||
|
|
||||||
V2 ui_center = v2_mul(G.ui_size, 0.5);
|
Vec2 ui_center = v2_mul(G.ui_size, 0.5);
|
||||||
Trs trs = MakeTrs(.t = v2_sub(ui_center, world_center), .r = rot, .s = scale);
|
Trs trs = TRS(.t = v2_sub(ui_center, world_center), .r = rot, .s = scale);
|
||||||
V2 pivot = world_center;
|
Vec2 pivot = world_center;
|
||||||
G.world_to_ui_xf = XFORM_IDENT;
|
G.world_to_ui_xf = XformIdentity;
|
||||||
G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, pivot);
|
G.world_to_ui_xf = TranslateXform(G.world_to_ui_xf, pivot);
|
||||||
G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, trs.t);
|
G.world_to_ui_xf = TranslateXform(G.world_to_ui_xf, trs.t);
|
||||||
G.world_to_ui_xf = xform_rotated(G.world_to_ui_xf, trs.r);
|
G.world_to_ui_xf = RotateXform(G.world_to_ui_xf, trs.r);
|
||||||
G.world_to_ui_xf = xform_scaled(G.world_to_ui_xf, trs.s);
|
G.world_to_ui_xf = ScaleXform(G.world_to_ui_xf, trs.s);
|
||||||
G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, v2_neg(pivot));
|
G.world_to_ui_xf = TranslateXform(G.world_to_ui_xf, v2_neg(pivot));
|
||||||
G.world_to_ui_xf.og = v2_round(G.world_to_ui_xf.og);
|
G.world_to_ui_xf.og = v2_round(G.world_to_ui_xf.og);
|
||||||
}
|
}
|
||||||
|
|
||||||
G.world_cursor = xform_invert_mul_v2(G.world_to_ui_xf, G.ui_cursor);
|
G.world_cursor = InvertXformMulV2(G.world_to_ui_xf, G.ui_cursor);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update world to render xform from world to ui xform
|
* Update world to render xform from world to ui xform
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
b32 effects_disabled = 0;
|
b32 effects_disabled = 0;
|
||||||
G.render_size = v2_round(V2FromXY(RENDER_WIDTH, RENDER_HEIGHT));
|
G.render_size = v2_round(V2(RENDER_WIDTH, RENDER_HEIGHT));
|
||||||
|
|
||||||
if (G.debug_camera) {
|
if (G.debug_camera) {
|
||||||
G.render_size = G.ui_size;
|
G.render_size = G.ui_size;
|
||||||
effects_disabled = 1;
|
effects_disabled = 1;
|
||||||
G.world_to_render_xf = G.world_to_ui_xf;
|
G.world_to_render_xf = G.world_to_ui_xf;
|
||||||
} else {
|
} else {
|
||||||
Xform ui_to_world_xf = xform_invert(G.world_to_ui_xf);
|
Xform ui_to_world_xf = InvertXform(G.world_to_ui_xf);
|
||||||
V2 world_center = xform_mul_v2(ui_to_world_xf, v2_mul(G.ui_size, 0.5));
|
Vec2 world_center = MulXformV2(ui_to_world_xf, v2_mul(G.ui_size, 0.5));
|
||||||
|
|
||||||
V2 scale = V2FromXY(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
Vec2 scale = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
||||||
|
|
||||||
Xform xf = XFORM_IDENT;
|
Xform xf = XformIdentity;
|
||||||
|
|
||||||
xf = xform_translated(xf, v2_mul(G.render_size, 0.5));
|
xf = TranslateXform(xf, v2_mul(G.render_size, 0.5));
|
||||||
|
|
||||||
xf = xform_scaled(xf, scale);
|
xf = ScaleXform(xf, scale);
|
||||||
xf = xform_translated(xf, v2_mul(world_center, -1));
|
xf = TranslateXform(xf, v2_mul(world_center, -1));
|
||||||
xf.og = v2_round(xf.og);
|
xf.og = v2_round(xf.og);
|
||||||
|
|
||||||
G.world_to_render_xf = xf;
|
G.world_to_render_xf = xf;
|
||||||
@ -1000,8 +1000,8 @@ internal void user_update(P_Window *window)
|
|||||||
{
|
{
|
||||||
Xform world_to_ui_xf = G.world_to_ui_xf;
|
Xform world_to_ui_xf = G.world_to_ui_xf;
|
||||||
Xform world_to_render_xf = G.world_to_render_xf;
|
Xform world_to_render_xf = G.world_to_render_xf;
|
||||||
Xform render_to_world_xf = xform_invert(world_to_render_xf);
|
Xform render_to_world_xf = InvertXform(world_to_render_xf);
|
||||||
Xform render_to_ui_xf = xform_mul(world_to_ui_xf, render_to_world_xf);
|
Xform render_to_ui_xf = MulXform(world_to_ui_xf, render_to_world_xf);
|
||||||
G.render_to_ui_xf = render_to_ui_xf;
|
G.render_to_ui_xf = render_to_ui_xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1010,10 +1010,10 @@ internal void user_update(P_Window *window)
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
{
|
{
|
||||||
V2 up = V2FromXY(0, -1);
|
Vec2 up = V2(0, -1);
|
||||||
V2 ui_center = v2_mul(G.ui_size, 0.5f);
|
Vec2 ui_center = v2_mul(G.ui_size, 0.5f);
|
||||||
V2 listener_pos = xform_invert_mul_v2(G.world_to_ui_xf, ui_center);
|
Vec2 listener_pos = InvertXformMulV2(G.world_to_ui_xf, ui_center);
|
||||||
V2 listener_dir = v2_norm(xform_basis_invert_mul_v2(G.world_to_ui_xf, up));
|
Vec2 listener_dir = v2_norm(InvertXformBasisMulV2(G.world_to_ui_xf, up));
|
||||||
mixer_set_listener(listener_pos, listener_dir);
|
mixer_set_listener(listener_pos, listener_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1024,14 +1024,14 @@ internal void user_update(P_Window *window)
|
|||||||
{
|
{
|
||||||
f32 thickness = 2;
|
f32 thickness = 2;
|
||||||
|
|
||||||
V2 offset = v2_neg(xform_mul_v2(G.world_to_render_xf, V2FromXY(0, 0)));
|
Vec2 offset = v2_neg(MulXformV2(G.world_to_render_xf, V2(0, 0)));
|
||||||
f32 spacing = xform_get_scale(G.world_to_render_xf).x;
|
f32 spacing = GetXformScale(G.world_to_render_xf).x;
|
||||||
|
|
||||||
V2 pos = xform_invert_mul_v2(G.world_to_render_xf, V2FromXY(0, 0));
|
Vec2 pos = InvertXformMulV2(G.world_to_render_xf, V2(0, 0));
|
||||||
V2 size = xform_basis_invert_mul_v2(G.world_to_render_xf, G.render_size);
|
Vec2 size = InvertXformBasisMulV2(G.world_to_render_xf, G.render_size);
|
||||||
u32 color0 = Rgba32F(0.17f, 0.17f, 0.17f, 1.f);
|
u32 color0 = Rgba32F(0.17f, 0.17f, 0.17f, 1.f);
|
||||||
u32 color1 = Rgba32F(0.15f, 0.15f, 0.15f, 1.f);
|
u32 color1 = Rgba32F(0.15f, 0.15f, 0.15f, 1.f);
|
||||||
draw_grid(G.render_sig, xform_from_rect(RectFromV2(pos, size)), color0, color1, Rgba32(0x3f, 0x3f, 0x3f, 0xFF), ColorRed, ColorGreen, thickness, spacing, offset);
|
draw_grid(G.render_sig, XformFromRect(RectFromV2(pos, size)), color0, color1, Rgba32(0x3f, 0x3f, 0x3f, 0xFF), ColorRed, ColorGreen, thickness, spacing, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -1070,7 +1070,7 @@ internal void user_update(P_Window *window)
|
|||||||
for (u64 entry_index = 0; entry_index < G.tile_cache.num_reserved_entries; ++entry_index) {
|
for (u64 entry_index = 0; entry_index < G.tile_cache.num_reserved_entries; ++entry_index) {
|
||||||
struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index];
|
struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index];
|
||||||
if (entry->valid) {
|
if (entry->valid) {
|
||||||
V2I32 chunk_pos = entry->pos;
|
Vec2I32 chunk_pos = entry->pos;
|
||||||
Ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos);
|
Ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos);
|
||||||
if (entry->applied_dirty_gen != chunk_ent->dirty_gen) {
|
if (entry->applied_dirty_gen != chunk_ent->dirty_gen) {
|
||||||
entry->applied_dirty_gen = chunk_ent->dirty_gen;
|
entry->applied_dirty_gen = chunk_ent->dirty_gen;
|
||||||
@ -1094,7 +1094,7 @@ internal void user_update(P_Window *window)
|
|||||||
for (u64 entry_index = 0; entry_index < G.tile_cache.num_reserved_entries; ++entry_index) {
|
for (u64 entry_index = 0; entry_index < G.tile_cache.num_reserved_entries; ++entry_index) {
|
||||||
struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index];
|
struct tile_cache_entry *entry = &G.tile_cache.entries[entry_index];
|
||||||
if (entry->valid) {
|
if (entry->valid) {
|
||||||
V2I32 chunk_pos = entry->pos;
|
Vec2I32 chunk_pos = entry->pos;
|
||||||
Ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos);
|
Ent *chunk_ent = sim_ent_from_chunk_pos(chunk_pos);
|
||||||
if (entry->applied_dirty_gen != chunk_ent->dirty_gen) {
|
if (entry->applied_dirty_gen != chunk_ent->dirty_gen) {
|
||||||
entry->applied_dirty_gen = chunk_ent->dirty_gen;
|
entry->applied_dirty_gen = chunk_ent->dirty_gen;
|
||||||
@ -1104,14 +1104,14 @@ internal void user_update(P_Window *window)
|
|||||||
* [L ] X [R ]
|
* [L ] X [R ]
|
||||||
* [BL] [B] [BR]
|
* [BL] [B] [BR]
|
||||||
*/
|
*/
|
||||||
V2I32 chunk_pos_tl = V2I32FromXY(chunk_pos.x - 1, chunk_pos.y - 1);
|
Vec2I32 chunk_pos_tl = V2I32(chunk_pos.x - 1, chunk_pos.y - 1);
|
||||||
V2I32 chunk_pos_t = V2I32FromXY(chunk_pos.x, chunk_pos.y - 1);
|
Vec2I32 chunk_pos_t = V2I32(chunk_pos.x, chunk_pos.y - 1);
|
||||||
V2I32 chunk_pos_tr = V2I32FromXY(chunk_pos.x + 1, chunk_pos.y - 1);
|
Vec2I32 chunk_pos_tr = V2I32(chunk_pos.x + 1, chunk_pos.y - 1);
|
||||||
V2I32 chunk_pos_l = V2I32FromXY(chunk_pos.x - 1, chunk_pos.y);
|
Vec2I32 chunk_pos_l = V2I32(chunk_pos.x - 1, chunk_pos.y);
|
||||||
V2I32 chunk_pos_r = V2I32FromXY(chunk_pos.x + 1, chunk_pos.y);
|
Vec2I32 chunk_pos_r = V2I32(chunk_pos.x + 1, chunk_pos.y);
|
||||||
V2I32 chunk_pos_bl = V2I32FromXY(chunk_pos.x - 1, chunk_pos.y + 1);
|
Vec2I32 chunk_pos_bl = V2I32(chunk_pos.x - 1, chunk_pos.y + 1);
|
||||||
V2I32 chunk_pos_b = V2I32FromXY(chunk_pos.x, chunk_pos.y + 1);
|
Vec2I32 chunk_pos_b = V2I32(chunk_pos.x, chunk_pos.y + 1);
|
||||||
V2I32 chunk_pos_br = V2I32FromXY(chunk_pos.x + 1, chunk_pos.y + 1);
|
Vec2I32 chunk_pos_br = V2I32(chunk_pos.x + 1, chunk_pos.y + 1);
|
||||||
Ent *chunk_ent_tl = sim_ent_from_chunk_pos(chunk_pos_tl);
|
Ent *chunk_ent_tl = sim_ent_from_chunk_pos(chunk_pos_tl);
|
||||||
Ent *chunk_ent_t = sim_ent_from_chunk_pos(chunk_pos_t);
|
Ent *chunk_ent_t = sim_ent_from_chunk_pos(chunk_pos_t);
|
||||||
Ent *chunk_ent_tr = sim_ent_from_chunk_pos(chunk_pos_tr);
|
Ent *chunk_ent_tr = sim_ent_from_chunk_pos(chunk_pos_tr);
|
||||||
@ -1179,23 +1179,23 @@ internal void user_update(P_Window *window)
|
|||||||
b32 skip_debug_draw_transform = sim_ent_has_prop(ent, SEPROP_CAMERA);
|
b32 skip_debug_draw_transform = sim_ent_has_prop(ent, SEPROP_CAMERA);
|
||||||
skip_debug_draw_transform = 1;
|
skip_debug_draw_transform = 1;
|
||||||
|
|
||||||
Xform sprite_xform = xform_mul(xf, ent->sprite_local_xform);
|
Xform sprite_xform = MulXform(xf, ent->sprite_local_xform);
|
||||||
|
|
||||||
/* Draw tracer */
|
/* Draw tracer */
|
||||||
/* TODO: Enable this */
|
/* TODO: Enable this */
|
||||||
#if 0
|
#if 0
|
||||||
if (sim_ent_has_prop(ent, SEPROP_TRACER)) {
|
if (sim_ent_has_prop(ent, SEPROP_TRACER)) {
|
||||||
V2 velocity = ent->tracer_start_velocity;
|
Vec2 velocity = ent->tracer_start_velocity;
|
||||||
|
|
||||||
V2 a = ent->tracer_start;
|
Vec2 a = ent->tracer_start;
|
||||||
V2 b = xf.og;
|
Vec2 b = xf.og;
|
||||||
V2 c = ent->tracer_gradient_start;
|
Vec2 c = ent->tracer_gradient_start;
|
||||||
V2 d = ent->tracer_gradient_end;
|
Vec2 d = ent->tracer_gradient_end;
|
||||||
|
|
||||||
V2 vcd = v2_sub(d, c);
|
Vec2 vcd = v2_sub(d, c);
|
||||||
V2 vca = v2_sub(a, c);
|
Vec2 vca = v2_sub(a, c);
|
||||||
V2 vdb = v2_sub(b, d);
|
Vec2 vdb = v2_sub(b, d);
|
||||||
V2 vdc = v2_neg(vcd);
|
Vec2 vdc = v2_neg(vcd);
|
||||||
|
|
||||||
f32 opacity_a = 1;
|
f32 opacity_a = 1;
|
||||||
f32 opacity_b = 1;
|
f32 opacity_b = 1;
|
||||||
@ -1206,8 +1206,8 @@ internal void user_update(P_Window *window)
|
|||||||
} else {
|
} else {
|
||||||
opacity_a = v2_dot(vcd, vca) / v2_len_sq(vcd);
|
opacity_a = v2_dot(vcd, vca) / v2_len_sq(vcd);
|
||||||
}
|
}
|
||||||
opacity_a = clamp_f32(opacity_a, 0, 1);
|
opacity_a = ClampF32(opacity_a, 0, 1);
|
||||||
opacity_b = clamp_f32(1.f - (v2_dot(vdc, vdb) / v2_len_sq(vdc)), 0, 1);
|
opacity_b = ClampF32(1.f - (v2_dot(vdc, vdb) / v2_len_sq(vdc)), 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 thickness = 0.01f;
|
f32 thickness = 0.01f;
|
||||||
@ -1229,7 +1229,7 @@ internal void user_update(P_Window *window)
|
|||||||
/* TODO: Fade in placeholder if texture isn't loaded */
|
/* TODO: Fade in placeholder if texture isn't loaded */
|
||||||
if (sheet->loaded && texture->loaded) {
|
if (sheet->loaded && texture->loaded) {
|
||||||
b32 is_light = sim_ent_has_prop(ent, SEPROP_LIGHT_TEST);
|
b32 is_light = sim_ent_has_prop(ent, SEPROP_LIGHT_TEST);
|
||||||
V3 emittance = ent->sprite_emittance;
|
Vec3 emittance = ent->sprite_emittance;
|
||||||
u32 tint = ent->sprite_tint;
|
u32 tint = ent->sprite_tint;
|
||||||
S_SheetFrame frame = sprite_sheet_get_frame(sheet, ent->animation_frame);
|
S_SheetFrame frame = sprite_sheet_get_frame(sheet, ent->animation_frame);
|
||||||
D_MaterialParams params = DRAW_MATERIAL_PARAMS(.xf = sprite_xform, .texture = texture->gp_texture, .tint = tint, .clip = frame.clip, .is_light = is_light, .light_emittance = emittance);
|
D_MaterialParams params = DRAW_MATERIAL_PARAMS(.xf = sprite_xform, .texture = texture->gp_texture, .tint = tint, .clip = frame.clip, .is_light = is_light, .light_emittance = emittance);
|
||||||
@ -1240,21 +1240,21 @@ internal void user_update(P_Window *window)
|
|||||||
/* Draw tiles */
|
/* Draw tiles */
|
||||||
/* TODO: Something better */
|
/* TODO: Something better */
|
||||||
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
|
if (sim_ent_has_prop(ent, SEPROP_TILE_CHUNK)) {
|
||||||
V2I32 chunk_index = ent->tile_chunk_index;
|
Vec2I32 chunk_index = ent->tile_chunk_index;
|
||||||
S_Tag tile_sprite = sprite_tag_from_path(LIT("sprite/tile.ase"));
|
S_Tag tile_sprite = sprite_tag_from_path(LIT("sprite/tile.ase"));
|
||||||
S_Texture *tile_texture = sprite_texture_from_tag_async(sprite_frame_scope, tile_sprite);
|
S_Texture *tile_texture = sprite_texture_from_tag_async(sprite_frame_scope, tile_sprite);
|
||||||
if (tile_texture->loaded) {
|
if (tile_texture->loaded) {
|
||||||
f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT;
|
f32 tile_size = 1.f / SIM_TILES_PER_UNIT_SQRT;
|
||||||
for (i32 tile_y = 0; tile_y < SIM_TILES_PER_CHUNK_SQRT; ++tile_y) {
|
for (i32 tile_y = 0; tile_y < SIM_TILES_PER_CHUNK_SQRT; ++tile_y) {
|
||||||
for (i32 tile_x = 0; tile_x < SIM_TILES_PER_CHUNK_SQRT; ++tile_x) {
|
for (i32 tile_x = 0; tile_x < SIM_TILES_PER_CHUNK_SQRT; ++tile_x) {
|
||||||
V2I32 local_tile_index = V2I32FromXY(tile_x, tile_y);
|
Vec2I32 local_tile_index = V2I32(tile_x, tile_y);
|
||||||
TileKind tile = ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
|
TileKind tile = ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
|
||||||
//if (tile > -1) {
|
//if (tile > -1) {
|
||||||
if (tile == SIM_TILE_KIND_WALL) {
|
if (tile == SIM_TILE_KIND_WALL) {
|
||||||
V2I32 world_tile_index = sim_world_tile_index_from_local_tile_index(chunk_index, local_tile_index);
|
Vec2I32 world_tile_index = sim_world_tile_index_from_local_tile_index(chunk_index, local_tile_index);
|
||||||
V2 pos = sim_pos_from_world_tile_index(world_tile_index);
|
Vec2 pos = sim_pos_from_world_tile_index(world_tile_index);
|
||||||
Xform tile_xf = xform_from_rect(RectFromV2(pos, V2FromXY(tile_size, tile_size)));
|
Xform tile_xf = XformFromRect(RectFromV2(pos, V2(tile_size, tile_size)));
|
||||||
D_MaterialParams params = DRAW_MATERIAL_PARAMS(.xf = tile_xf, .texture = tile_texture->gp_texture, .is_light = 1, .light_emittance = V3FromXYZ(0, 0, 0));
|
D_MaterialParams params = DRAW_MATERIAL_PARAMS(.xf = tile_xf, .texture = tile_texture->gp_texture, .is_light = 1, .light_emittance = V3(0, 0, 0));
|
||||||
draw_material(G.render_sig, params);
|
draw_material(G.render_sig, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1283,7 +1283,7 @@ internal void user_update(P_Window *window)
|
|||||||
f32 thickness = 1;
|
f32 thickness = 1;
|
||||||
u32 color = Rgba32F(1, 0, 1, 0.5);
|
u32 color = Rgba32F(1, 0, 1, 0.5);
|
||||||
Quad quad = quad_from_aabb(aabb);
|
Quad quad = quad_from_aabb(aabb);
|
||||||
quad = xform_mul_quad(G.world_to_ui_xf, quad);
|
quad = MulXformQuad(G.world_to_ui_xf, quad);
|
||||||
draw_quad_line(G.render_sig, quad, thickness, color);
|
draw_quad_line(G.render_sig, quad, thickness, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1291,10 +1291,10 @@ internal void user_update(P_Window *window)
|
|||||||
if (ent == local_control || sim_ent_id_eq(ent->id, G.debug_following)) {
|
if (ent == local_control || sim_ent_id_eq(ent->id, G.debug_following)) {
|
||||||
S_Sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite);
|
S_Sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite);
|
||||||
S_SheetSlice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame);
|
S_SheetSlice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame);
|
||||||
V2 start = xform_mul_v2(sprite_xform, slice.center);
|
Vec2 start = MulXformV2(sprite_xform, slice.center);
|
||||||
start = xform_mul_v2(G.world_to_ui_xf, start);
|
start = MulXformV2(G.world_to_ui_xf, start);
|
||||||
V2 end = v2_add(xf.og, ent->control.focus);
|
Vec2 end = v2_add(xf.og, ent->control.focus);
|
||||||
end = xform_mul_v2(G.world_to_ui_xf, end);
|
end = MulXformV2(G.world_to_ui_xf, end);
|
||||||
draw_arrow_line(G.render_sig, start, end, 3, 10, Rgba32F(1, 1, 1, 0.5));
|
draw_arrow_line(G.render_sig, start, end, 3, 10, Rgba32F(1, 1, 1, 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1314,21 +1314,21 @@ internal void user_update(P_Window *window)
|
|||||||
for (u32 j = 0; j < group->per_frame_count; ++j) {
|
for (u32 j = 0; j < group->per_frame_count; ++j) {
|
||||||
S_SheetSlice slice = group->frame_slices[(ent->animation_frame * group->per_frame_count) + j];
|
S_SheetSlice slice = group->frame_slices[(ent->animation_frame * group->per_frame_count) + j];
|
||||||
|
|
||||||
V2 center = xform_mul_v2(sprite_xform, slice.center);
|
Vec2 center = MulXformV2(sprite_xform, slice.center);
|
||||||
center = xform_mul_v2(G.world_to_ui_xf, center);
|
center = MulXformV2(G.world_to_ui_xf, center);
|
||||||
|
|
||||||
if (!slice.has_ray) {
|
if (!slice.has_ray) {
|
||||||
Quad quad = quad_from_rect(slice.rect);
|
Quad quad = quad_from_rect(slice.rect);
|
||||||
quad = xform_mul_quad(sprite_xform, quad);
|
quad = MulXformQuad(sprite_xform, quad);
|
||||||
quad = xform_mul_quad(G.world_to_ui_xf, quad);
|
quad = MulXformQuad(G.world_to_ui_xf, quad);
|
||||||
draw_quad_line(G.render_sig, quad, 2, quad_color);
|
draw_quad_line(G.render_sig, quad, 2, quad_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_circle(G.render_sig, center, 3, point_color, 20);
|
draw_circle(G.render_sig, center, 3, point_color, 20);
|
||||||
|
|
||||||
if (slice.has_ray) {
|
if (slice.has_ray) {
|
||||||
V2 ray = xform_basis_mul_v2(sprite_xform, slice.dir);
|
Vec2 ray = MulXformBasisV2(sprite_xform, slice.dir);
|
||||||
ray = xform_basis_mul_v2(G.world_to_ui_xf, ray);
|
ray = MulXformBasisV2(G.world_to_ui_xf, ray);
|
||||||
ray = v2_with_len(ray, 25);
|
ray = v2_with_len(ray, 25);
|
||||||
draw_arrow_ray(G.render_sig, center, ray, 2, 10, ray_color);
|
draw_arrow_ray(G.render_sig, center, ray, 2, 10, ray_color);
|
||||||
}
|
}
|
||||||
@ -1345,8 +1345,8 @@ internal void user_update(P_Window *window)
|
|||||||
|
|
||||||
u32 color = ColorYellow;
|
u32 color = ColorYellow;
|
||||||
f32 radius = 3;
|
f32 radius = 3;
|
||||||
V2 point = xform_mul_v2(e1_xf, ent->weld_joint_data.point_local_e1);
|
Vec2 point = MulXformV2(e1_xf, ent->weld_joint_data.point_local_e1);
|
||||||
point = xform_mul_v2(G.world_to_ui_xf, point);
|
point = MulXformV2(G.world_to_ui_xf, point);
|
||||||
draw_circle(G.render_sig, point, radius, color, 10);
|
draw_circle(G.render_sig, point, radius, color, 10);
|
||||||
|
|
||||||
DEBUGBREAKABLE;
|
DEBUGBREAKABLE;
|
||||||
@ -1358,10 +1358,10 @@ internal void user_update(P_Window *window)
|
|||||||
Ent *target = sim_ent_from_id(G.ss_blended, ent->mouse_joint_data.target);
|
Ent *target = sim_ent_from_id(G.ss_blended, ent->mouse_joint_data.target);
|
||||||
Xform target_xf = sim_ent_get_xform(target);
|
Xform target_xf = sim_ent_get_xform(target);
|
||||||
u32 color = ColorWhite;
|
u32 color = ColorWhite;
|
||||||
V2 point_start = xform_mul_v2(target_xf, ent->mouse_joint_data.point_local_start);
|
Vec2 point_start = MulXformV2(target_xf, ent->mouse_joint_data.point_local_start);
|
||||||
V2 point_end = G.world_cursor;
|
Vec2 point_end = G.world_cursor;
|
||||||
point_start = xform_mul_v2(G.world_to_ui_xf, point_start);
|
point_start = MulXformV2(G.world_to_ui_xf, point_start);
|
||||||
point_end = xform_mul_v2(G.world_to_ui_xf, point_end);
|
point_end = MulXformV2(G.world_to_ui_xf, point_end);
|
||||||
draw_arrow_line(G.render_sig, point_start, point_end, 3, 10, color);
|
draw_arrow_line(G.render_sig, point_start, point_end, 3, 10, color);
|
||||||
draw_circle(G.render_sig, point_start, 4, color, 10);
|
draw_circle(G.render_sig, point_start, 4, color, 10);
|
||||||
}
|
}
|
||||||
@ -1374,29 +1374,29 @@ internal void user_update(P_Window *window)
|
|||||||
{
|
{
|
||||||
/* Draw collider using support points */
|
/* Draw collider using support points */
|
||||||
u32 detail = 32;
|
u32 detail = 32;
|
||||||
Xform collider_draw_xf = xform_mul(G.world_to_ui_xf, xf);
|
Xform collider_draw_xf = MulXform(G.world_to_ui_xf, xf);
|
||||||
draw_collider_line(G.render_sig, collider, collider_draw_xf, thickness, color, detail);
|
draw_collider_line(G.render_sig, collider, collider_draw_xf, thickness, color, detail);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
/* Draw collider shape points */
|
/* Draw collider shape points */
|
||||||
for (u32 i = 0; i < collider.count; ++i) {
|
for (u32 i = 0; i < collider.count; ++i) {
|
||||||
V2 p = xform_mul_v2(xform_mul(G.world_to_ui_xf, xf), collider.points[i]);
|
Vec2 p = MulXformV2(MulXform(G.world_to_ui_xf, xf), collider.points[i]);
|
||||||
draw_circle(G.render_sig, p, 3, ColorBlue, 10);
|
draw_circle(G.render_sig, p, 3, ColorBlue, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (collider.count == 1 && collider.radius > 0) {
|
if (collider.count == 1 && collider.radius > 0) {
|
||||||
/* Draw upwards line for circle */
|
/* Draw upwards line for circle */
|
||||||
V2 start = xf.og;
|
Vec2 start = xf.og;
|
||||||
V2 end = collider_get_support_point(&collider, xf, v2_neg(xf.by)).p;
|
Vec2 end = collider_get_support_point(&collider, xf, v2_neg(xf.by)).p;
|
||||||
start = xform_mul_v2(G.world_to_ui_xf, start);
|
start = MulXformV2(G.world_to_ui_xf, start);
|
||||||
end = xform_mul_v2(G.world_to_ui_xf, end);
|
end = MulXformV2(G.world_to_ui_xf, end);
|
||||||
draw_line(G.render_sig, start, end, thickness, color);
|
draw_line(G.render_sig, start, end, thickness, color);
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
/* Draw support point at focus dir */
|
/* Draw support point at focus dir */
|
||||||
{
|
{
|
||||||
V2 p = collider_support_point(&collider, xf, ent->control.focus);
|
Vec2 p = collider_support_point(&collider, xf, ent->control.focus);
|
||||||
p = xform_mul_v2(G.world_to_ui_xf, p);
|
p = MulXformV2(G.world_to_ui_xf, p);
|
||||||
draw_circle(G.render_sig, p, 3, ColorRed, 10);
|
draw_circle(G.render_sig, p, 3, ColorRed, 10);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1417,11 +1417,11 @@ internal void user_update(P_Window *window)
|
|||||||
for (u32 i = 0; i < data->num_points; ++i) {
|
for (u32 i = 0; i < data->num_points; ++i) {
|
||||||
u32 color = (data->skip_solve || data->wrong_dir) ? Alpha32F(ColorYellow, 0.3) : Rgba32F(0.8, 0.2, 0.2, 1);
|
u32 color = (data->skip_solve || data->wrong_dir) ? Alpha32F(ColorYellow, 0.3) : Rgba32F(0.8, 0.2, 0.2, 1);
|
||||||
ContactPoint point = data->points[i];
|
ContactPoint point = data->points[i];
|
||||||
V2 dbg_pt = point.dbg_pt;
|
Vec2 dbg_pt = point.dbg_pt;
|
||||||
|
|
||||||
/* Draw point */
|
/* Draw point */
|
||||||
{
|
{
|
||||||
draw_circle(G.render_sig, xform_mul_v2(G.world_to_ui_xf, dbg_pt), radius, color, 10);
|
draw_circle(G.render_sig, MulXformV2(G.world_to_ui_xf, dbg_pt), radius, color, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw normal */
|
/* Draw normal */
|
||||||
@ -1429,8 +1429,8 @@ internal void user_update(P_Window *window)
|
|||||||
f32 len = 0.1f;
|
f32 len = 0.1f;
|
||||||
f32 arrow_thickness = 2;
|
f32 arrow_thickness = 2;
|
||||||
f32 arrow_height = 5;
|
f32 arrow_height = 5;
|
||||||
V2 start = xform_mul_v2(G.world_to_ui_xf, dbg_pt);
|
Vec2 start = MulXformV2(G.world_to_ui_xf, dbg_pt);
|
||||||
V2 end = xform_mul_v2(G.world_to_ui_xf, v2_add(dbg_pt, v2_mul(v2_norm(data->normal), len)));
|
Vec2 end = MulXformV2(G.world_to_ui_xf, v2_add(dbg_pt, v2_mul(v2_norm(data->normal), len)));
|
||||||
draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrow_height, color);
|
draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrow_height, color);
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
@ -1461,7 +1461,7 @@ internal void user_update(P_Window *window)
|
|||||||
FMT_UINT(data->num_points));
|
FMT_UINT(data->num_points));
|
||||||
|
|
||||||
|
|
||||||
draw_text(G.render_sig, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_ui_xf, dbg_pt)), V2FromXY(0, offset_px)), text);
|
draw_text(G.render_sig, disp_font, v2_add(v2_round(MulXformV2(G.world_to_ui_xf, dbg_pt)), V2(0, offset_px)), text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1487,8 +1487,8 @@ internal void user_update(P_Window *window)
|
|||||||
{
|
{
|
||||||
f32 radius = 4;
|
f32 radius = 4;
|
||||||
u32 color = Rgba32F(1, 1, 0, 0.5);
|
u32 color = Rgba32F(1, 1, 0, 0.5);
|
||||||
V2 a = xform_mul_v2(G.world_to_ui_xf, data->closest0);
|
Vec2 a = MulXformV2(G.world_to_ui_xf, data->closest0);
|
||||||
V2 b = xform_mul_v2(G.world_to_ui_xf, data->closest1);
|
Vec2 b = MulXformV2(G.world_to_ui_xf, data->closest1);
|
||||||
draw_circle(G.render_sig, a, radius, color, 10);
|
draw_circle(G.render_sig, a, radius, color, 10);
|
||||||
draw_circle(G.render_sig, b, radius, color, 10);
|
draw_circle(G.render_sig, b, radius, color, 10);
|
||||||
}
|
}
|
||||||
@ -1505,27 +1505,27 @@ internal void user_update(P_Window *window)
|
|||||||
u32 color_a_clipped = Rgba32F(1, 0, 0, 1);
|
u32 color_a_clipped = Rgba32F(1, 0, 0, 1);
|
||||||
u32 color_b_clipped = Rgba32F(0, 1, 0, 1);
|
u32 color_b_clipped = Rgba32F(0, 1, 0, 1);
|
||||||
{
|
{
|
||||||
V2 a = xform_mul_v2(G.world_to_ui_xf, collider_res.a0);
|
Vec2 a = MulXformV2(G.world_to_ui_xf, collider_res.a0);
|
||||||
V2 b = xform_mul_v2(G.world_to_ui_xf, collider_res.b0);
|
Vec2 b = MulXformV2(G.world_to_ui_xf, collider_res.b0);
|
||||||
draw_line(G.render_sig, a, b, thickness, color_line);
|
draw_line(G.render_sig, a, b, thickness, color_line);
|
||||||
draw_circle(G.render_sig, a, radius, color_a, 10);
|
draw_circle(G.render_sig, a, radius, color_a, 10);
|
||||||
draw_circle(G.render_sig, b, radius, color_b, 10);
|
draw_circle(G.render_sig, b, radius, color_b, 10);
|
||||||
|
|
||||||
V2 a_clipped = xform_mul_v2(G.world_to_ui_xf, collider_res.a0_clipped);
|
Vec2 a_clipped = MulXformV2(G.world_to_ui_xf, collider_res.a0_clipped);
|
||||||
V2 b_clipped = xform_mul_v2(G.world_to_ui_xf, collider_res.b0_clipped);
|
Vec2 b_clipped = MulXformV2(G.world_to_ui_xf, collider_res.b0_clipped);
|
||||||
draw_line(G.render_sig, a_clipped, b_clipped, thickness, color_line_clipped);
|
draw_line(G.render_sig, a_clipped, b_clipped, thickness, color_line_clipped);
|
||||||
draw_circle(G.render_sig, a_clipped, radius, color_a_clipped, 10);
|
draw_circle(G.render_sig, a_clipped, radius, color_a_clipped, 10);
|
||||||
draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
|
draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
V2 a = xform_mul_v2(G.world_to_ui_xf, collider_res.a1);
|
Vec2 a = MulXformV2(G.world_to_ui_xf, collider_res.a1);
|
||||||
V2 b = xform_mul_v2(G.world_to_ui_xf, collider_res.b1);
|
Vec2 b = MulXformV2(G.world_to_ui_xf, collider_res.b1);
|
||||||
draw_line(G.render_sig, a, b, thickness, color_line);
|
draw_line(G.render_sig, a, b, thickness, color_line);
|
||||||
draw_circle(G.render_sig, a, radius, color_a, 10);
|
draw_circle(G.render_sig, a, radius, color_a, 10);
|
||||||
draw_circle(G.render_sig, b, radius, color_b, 10);
|
draw_circle(G.render_sig, b, radius, color_b, 10);
|
||||||
|
|
||||||
V2 a_clipped = xform_mul_v2(G.world_to_ui_xf, collider_res.a1_clipped);
|
Vec2 a_clipped = MulXformV2(G.world_to_ui_xf, collider_res.a1_clipped);
|
||||||
V2 b_clipped = xform_mul_v2(G.world_to_ui_xf, collider_res.b1_clipped);
|
Vec2 b_clipped = MulXformV2(G.world_to_ui_xf, collider_res.b1_clipped);
|
||||||
draw_line(G.render_sig, a_clipped, b_clipped, thickness, color_line_clipped);
|
draw_line(G.render_sig, a_clipped, b_clipped, thickness, color_line_clipped);
|
||||||
draw_circle(G.render_sig, a_clipped, radius, color_a_clipped, 10);
|
draw_circle(G.render_sig, a_clipped, radius, color_a_clipped, 10);
|
||||||
draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
|
draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
|
||||||
@ -1564,12 +1564,12 @@ internal void user_update(P_Window *window)
|
|||||||
);
|
);
|
||||||
String text = string_format(temp.arena, fmt,
|
String text = string_format(temp.arena, fmt,
|
||||||
FMT_FLOAT_P(e0_xf.og.x, 24), FMT_FLOAT_P(e0_xf.og.y, 24),
|
FMT_FLOAT_P(e0_xf.og.x, 24), FMT_FLOAT_P(e0_xf.og.y, 24),
|
||||||
FMT_FLOAT_P(xform_get_rotation(e0_xf), 24),
|
FMT_FLOAT_P(GetXformRotation(e0_xf), 24),
|
||||||
FMT_FLOAT_P(e1_xf.og.x, 24), FMT_FLOAT_P(e1_xf.og.y, 24),
|
FMT_FLOAT_P(e1_xf.og.x, 24), FMT_FLOAT_P(e1_xf.og.y, 24),
|
||||||
FMT_FLOAT_P(xform_get_rotation(e1_xf), 24));
|
FMT_FLOAT_P(GetXformRotation(e1_xf), 24));
|
||||||
|
|
||||||
|
|
||||||
draw_text(G.render_sig, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_ui_xf, V2FromXY(0, 0))), V2FromXY(0, offset_px)), text);
|
draw_text(G.render_sig, disp_font, v2_add(v2_round(MulXformV2(G.world_to_ui_xf, V2(0, 0))), V2(0, offset_px)), text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1584,7 +1584,7 @@ internal void user_update(P_Window *window)
|
|||||||
|
|
||||||
V2Array m = menkowski(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf, detail);
|
V2Array m = menkowski(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf, detail);
|
||||||
|
|
||||||
for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_to_ui_xf, m.points[i]);
|
for (u64 i = 0; i < m.count; ++i) m.points[i] = MulXformV2(G.world_to_ui_xf, m.points[i]);
|
||||||
draw_poly_line(G.render_sig, m, 1, thickness, color);
|
draw_poly_line(G.render_sig, m, 1, thickness, color);
|
||||||
//draw_poly(G.render_sig, m, color);
|
//draw_poly(G.render_sig, m, color);
|
||||||
}
|
}
|
||||||
@ -1597,7 +1597,7 @@ internal void user_update(P_Window *window)
|
|||||||
V2Array m = cloud(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf);
|
V2Array m = cloud(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf);
|
||||||
|
|
||||||
for (u64 i = 0; i < m.count; ++i) {
|
for (u64 i = 0; i < m.count; ++i) {
|
||||||
V2 p = xform_mul_v2(G.world_to_ui_xf, m.points[i]);
|
Vec2 p = MulXformV2(G.world_to_ui_xf, m.points[i]);
|
||||||
draw_circle(G.render_sig, p, radius, color, 10);
|
draw_circle(G.render_sig, p, radius, color, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1611,7 +1611,7 @@ internal void user_update(P_Window *window)
|
|||||||
.points = collider_res.prototype.points,
|
.points = collider_res.prototype.points,
|
||||||
.count = collider_res.prototype.len
|
.count = collider_res.prototype.len
|
||||||
};
|
};
|
||||||
for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_to_ui_xf, m.points[i]);
|
for (u64 i = 0; i < m.count; ++i) m.points[i] = MulXformV2(G.world_to_ui_xf, m.points[i]);
|
||||||
draw_poly_line(G.render_sig, m, 1, thickness, color);
|
draw_poly_line(G.render_sig, m, 1, thickness, color);
|
||||||
for (u64 i = 0; i < m.count; ++i) draw_circle(G.render_sig, m.points[i], 10, color, 10);
|
for (u64 i = 0; i < m.count; ++i) draw_circle(G.render_sig, m.points[i], 10, color, 10);
|
||||||
}
|
}
|
||||||
@ -1625,8 +1625,8 @@ internal void user_update(P_Window *window)
|
|||||||
u32 color_third = Rgba32F(0, 0, 1, 0.75);
|
u32 color_third = Rgba32F(0, 0, 1, 0.75);
|
||||||
|
|
||||||
struct collider_menkowski_simplex simplex = collider_res.simplex;
|
struct collider_menkowski_simplex simplex = collider_res.simplex;
|
||||||
V2 simplex_points[] = { simplex.a.p, simplex.b.p, simplex.c.p };
|
Vec2 simplex_points[] = { simplex.a.p, simplex.b.p, simplex.c.p };
|
||||||
for (u64 i = 0; i < countof(simplex_points); ++i) simplex_points[i] = xform_mul_v2(G.world_to_ui_xf, simplex_points[i]);
|
for (u64 i = 0; i < countof(simplex_points); ++i) simplex_points[i] = MulXformV2(G.world_to_ui_xf, simplex_points[i]);
|
||||||
V2Array simplex_array = { .count = simplex.len, .points = simplex_points };
|
V2Array simplex_array = { .count = simplex.len, .points = simplex_points };
|
||||||
|
|
||||||
if (simplex.len >= 1) {
|
if (simplex.len >= 1) {
|
||||||
@ -1652,8 +1652,8 @@ internal void user_update(P_Window *window)
|
|||||||
f32 len = 0.1f;
|
f32 len = 0.1f;
|
||||||
f32 arrow_thickness = 4;
|
f32 arrow_thickness = 4;
|
||||||
f32 arrowhead_height = 10;
|
f32 arrowhead_height = 10;
|
||||||
V2 start = xform_mul_v2(G.world_to_ui_xf, V2FromXY(0, 0));
|
Vec2 start = MulXformV2(G.world_to_ui_xf, V2(0, 0));
|
||||||
V2 end = xform_mul_v2(G.world_to_ui_xf, v2_mul(v2_norm(collider_res.normal), len));
|
Vec2 end = MulXformV2(G.world_to_ui_xf, v2_mul(v2_norm(collider_res.normal), len));
|
||||||
draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrowhead_height, color);
|
draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrowhead_height, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1667,8 +1667,8 @@ internal void user_update(P_Window *window)
|
|||||||
f32 thickness = 2;
|
f32 thickness = 2;
|
||||||
f32 arrow_height = 15;
|
f32 arrow_height = 15;
|
||||||
|
|
||||||
V2 start = xform_mul_v2(G.world_to_ui_xf, xf.og);
|
Vec2 start = MulXformV2(G.world_to_ui_xf, xf.og);
|
||||||
V2 end = xform_mul_v2(G.world_to_ui_xf, parent_xf.og);
|
Vec2 end = MulXformV2(G.world_to_ui_xf, parent_xf.og);
|
||||||
draw_arrow_line(G.render_sig, start, end, thickness, arrow_height, color);
|
draw_arrow_line(G.render_sig, start, end, thickness, arrow_height, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1677,9 +1677,9 @@ internal void user_update(P_Window *window)
|
|||||||
u32 color = ent == local_camera ? Rgba32F(1, 1, 1, 0.5) : Rgba32F(0, 0.75, 0, 0.5);
|
u32 color = ent == local_camera ? Rgba32F(1, 1, 1, 0.5) : Rgba32F(0, 0.75, 0, 0.5);
|
||||||
f32 thickness = 3;
|
f32 thickness = 3;
|
||||||
|
|
||||||
Xform quad_xf = xform_mul(xf, ent->camera_quad_xform);
|
Xform quad_xf = MulXform(xf, ent->camera_quad_xform);
|
||||||
Quad quad = xform_mul_quad(quad_xf, QuadUnitSquareCentered);
|
Quad quad = MulXformQuad(quad_xf, QuadUnitSquareCentered);
|
||||||
quad = xform_mul_quad(G.world_to_ui_xf, quad);
|
quad = MulXformQuad(G.world_to_ui_xf, quad);
|
||||||
|
|
||||||
draw_quad_line(G.render_sig, quad, thickness, color);
|
draw_quad_line(G.render_sig, quad, thickness, color);
|
||||||
}
|
}
|
||||||
@ -1692,11 +1692,11 @@ internal void user_update(P_Window *window)
|
|||||||
/* Draw crosshair or show cursor */
|
/* Draw crosshair or show cursor */
|
||||||
if (!G.debug_camera) {
|
if (!G.debug_camera) {
|
||||||
__profn("Draw crosshair");
|
__profn("Draw crosshair");
|
||||||
V2 crosshair_pos = G.ui_cursor;
|
Vec2 crosshair_pos = G.ui_cursor;
|
||||||
S_Tag crosshair = sprite_tag_from_path(LIT("sprite/crosshair.ase"));
|
S_Tag crosshair = sprite_tag_from_path(LIT("sprite/crosshair.ase"));
|
||||||
S_Texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair);
|
S_Texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair);
|
||||||
V2 size = V2FromXY(t->width, t->height);
|
Vec2 size = V2(t->width, t->height);
|
||||||
Xform xf = XFORM_TRS(.t = crosshair_pos, .s = size);
|
Xform xf = XformFromTrs(TRS(.t = crosshair_pos, .s = size));
|
||||||
draw_ui_rect(G.render_sig, DRAW_UI_RECT_PARAMS(.xf = xf, .texture = t->gp_texture));
|
draw_ui_rect(G.render_sig, DRAW_UI_RECT_PARAMS(.xf = xf, .texture = t->gp_texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1709,10 +1709,10 @@ internal void user_update(P_Window *window)
|
|||||||
P_ShowWindowCursor(G.window);
|
P_ShowWindowCursor(G.window);
|
||||||
} else {
|
} else {
|
||||||
S_Texture *t = sprite_texture_from_tag_async(sprite_frame_scope, sprite_tag_from_path(LIT("sprite/crosshair.ase")));
|
S_Texture *t = sprite_texture_from_tag_async(sprite_frame_scope, sprite_tag_from_path(LIT("sprite/crosshair.ase")));
|
||||||
V2 size = V2FromXY(t->width, t->height);
|
Vec2 size = V2(t->width, t->height);
|
||||||
Rect cursor_clip = RectFromV2(G.ui_screen_offset, G.ui_size);
|
Rect cursor_clip = RectFromV2(G.ui_screen_offset, G.ui_size);
|
||||||
cursor_clip.pos = v2_add(cursor_clip.pos, v2_mul(size, 0.5f));
|
cursor_clip.pos = v2_add(cursor_clip.pos, v2_mul(size, 0.5f));
|
||||||
cursor_clip.pos = v2_add(cursor_clip.pos, V2FromXY(1, 1));
|
cursor_clip.pos = v2_add(cursor_clip.pos, V2(1, 1));
|
||||||
cursor_clip.size = v2_sub(cursor_clip.size, size);
|
cursor_clip.size = v2_sub(cursor_clip.size, size);
|
||||||
P_HideWindowCursor(G.window);
|
P_HideWindowCursor(G.window);
|
||||||
P_EnableWindoweCursorClip(G.window, cursor_clip);
|
P_EnableWindoweCursorClip(G.window, cursor_clip);
|
||||||
@ -1734,7 +1734,7 @@ internal void user_update(P_Window *window)
|
|||||||
move_speed *= walk_ratio;
|
move_speed *= walk_ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
V2 input_move_dir = ZI;
|
Vec2 input_move_dir = ZI;
|
||||||
{
|
{
|
||||||
for (enum user_bind_kind bind = 0; bind < (i32)countof(G.bind_states); ++bind) {
|
for (enum user_bind_kind bind = 0; bind < (i32)countof(G.bind_states); ++bind) {
|
||||||
struct bind_state state = G.bind_states[bind];
|
struct bind_state state = G.bind_states[bind];
|
||||||
@ -1769,14 +1769,14 @@ internal void user_update(P_Window *window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input_move_dir = xform_basis_invert_mul_v2(G.world_to_ui_xf, input_move_dir); /* Make move dir relative to world view */
|
input_move_dir = InvertXformBasisMulV2(G.world_to_ui_xf, input_move_dir); /* Make move dir relative to world view */
|
||||||
input_move_dir = v2_mul(v2_norm(input_move_dir), move_speed);
|
input_move_dir = v2_mul(v2_norm(input_move_dir), move_speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!G.debug_camera) {
|
if (!G.debug_camera) {
|
||||||
G.focus_send = v2_sub(G.world_cursor, sim_ent_get_xform(local_control).og);
|
G.focus_send = v2_sub(G.world_cursor, sim_ent_get_xform(local_control).og);
|
||||||
}
|
}
|
||||||
V2 input_aim_dir = G.focus_send;
|
Vec2 input_aim_dir = G.focus_send;
|
||||||
|
|
||||||
/* Queue player control cmd */
|
/* Queue player control cmd */
|
||||||
{
|
{
|
||||||
@ -1901,7 +1901,7 @@ internal void user_update(P_Window *window)
|
|||||||
if (G.debug_draw && hovered_ent->valid) {
|
if (G.debug_draw && hovered_ent->valid) {
|
||||||
Ent *ent = hovered_ent;
|
Ent *ent = hovered_ent;
|
||||||
|
|
||||||
V2 pos = v2_add(G.ui_cursor, V2FromXY(15, 15));
|
Vec2 pos = v2_add(G.ui_cursor, V2(15, 15));
|
||||||
F_Font *font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f);
|
F_Font *font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f);
|
||||||
if (font) {
|
if (font) {
|
||||||
TempArena temp = BeginTempArena(scratch.arena);
|
TempArena temp = BeginTempArena(scratch.arena);
|
||||||
@ -1971,19 +1971,19 @@ internal void user_update(P_Window *window)
|
|||||||
text.len += string_copy(temp.arena, LIT("\n")).len;
|
text.len += string_copy(temp.arena, LIT("\n")).len;
|
||||||
text.len += string_copy(temp.arena, LIT("\n")).len;
|
text.len += string_copy(temp.arena, LIT("\n")).len;
|
||||||
|
|
||||||
V2 world_cursor = G.world_cursor;
|
Vec2 world_cursor = G.world_cursor;
|
||||||
text.len += string_format(temp.arena, LIT("cursor world: %F, %F"), FMT_FLOAT(world_cursor.x), FMT_FLOAT(world_cursor.y)).len;
|
text.len += string_format(temp.arena, LIT("cursor world: %F, %F"), FMT_FLOAT(world_cursor.x), FMT_FLOAT(world_cursor.y)).len;
|
||||||
text.len += string_copy(temp.arena, LIT("\n")).len;
|
text.len += string_copy(temp.arena, LIT("\n")).len;
|
||||||
|
|
||||||
V2I32 world_tile_cursor = sim_world_tile_index_from_pos(world_cursor);
|
Vec2I32 world_tile_cursor = sim_world_tile_index_from_pos(world_cursor);
|
||||||
text.len += string_format(temp.arena, LIT("cursor world tile: %F, %F"), FMT_SINT(world_tile_cursor.x), FMT_SINT(world_tile_cursor.y)).len;
|
text.len += string_format(temp.arena, LIT("cursor world tile: %F, %F"), FMT_SINT(world_tile_cursor.x), FMT_SINT(world_tile_cursor.y)).len;
|
||||||
text.len += string_copy(temp.arena, LIT("\n")).len;
|
text.len += string_copy(temp.arena, LIT("\n")).len;
|
||||||
|
|
||||||
V2I32 local_tile_cursor = sim_local_tile_index_from_world_tile_index(world_tile_cursor);
|
Vec2I32 local_tile_cursor = sim_local_tile_index_from_world_tile_index(world_tile_cursor);
|
||||||
text.len += string_format(temp.arena, LIT("cursor local tile: %F, %F"), FMT_SINT(local_tile_cursor.x), FMT_SINT(local_tile_cursor.y)).len;
|
text.len += string_format(temp.arena, LIT("cursor local tile: %F, %F"), FMT_SINT(local_tile_cursor.x), FMT_SINT(local_tile_cursor.y)).len;
|
||||||
text.len += string_copy(temp.arena, LIT("\n")).len;
|
text.len += string_copy(temp.arena, LIT("\n")).len;
|
||||||
|
|
||||||
V2I32 tile_chunk_cursor = sim_tile_chunk_index_from_world_tile_index(world_tile_cursor);
|
Vec2I32 tile_chunk_cursor = sim_tile_chunk_index_from_world_tile_index(world_tile_cursor);
|
||||||
text.len += string_format(temp.arena, LIT("cursor tile chunk: %F, %F"), FMT_SINT(tile_chunk_cursor.x), FMT_SINT(tile_chunk_cursor.y)).len;
|
text.len += string_format(temp.arena, LIT("cursor tile chunk: %F, %F"), FMT_SINT(tile_chunk_cursor.x), FMT_SINT(tile_chunk_cursor.y)).len;
|
||||||
text.len += string_copy(temp.arena, LIT("\n")).len;
|
text.len += string_copy(temp.arena, LIT("\n")).len;
|
||||||
text.len += string_copy(temp.arena, LIT("\n")).len;
|
text.len += string_copy(temp.arena, LIT("\n")).len;
|
||||||
@ -2027,7 +2027,7 @@ internal void user_update(P_Window *window)
|
|||||||
//draw_text(G.render_sig, font, pos, string_format(temp.arena, LIT("blended world entities: %F/%F"), FMT_UINT(G.ss_blended->num_ents_allocated), FMT_UINT(G.ss_blended->num_ents_reserved)));
|
//draw_text(G.render_sig, font, pos, string_format(temp.arena, LIT("blended world entities: %F/%F"), FMT_UINT(G.ss_blended->num_ents_allocated), FMT_UINT(G.ss_blended->num_ents_reserved)));
|
||||||
//draw_text(G.render_sig, font, pos, text);
|
//draw_text(G.render_sig, font, pos, text);
|
||||||
|
|
||||||
V2 pos = V2FromXY(10, G.ui_size.y);
|
Vec2 pos = V2(10, G.ui_size.y);
|
||||||
D_TextOffsetY offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM;
|
D_TextOffsetY offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM;
|
||||||
draw_text(G.render_sig, DRAW_TEXT_PARAMS(.font = font, .pos = pos, .str = text, .offset_y = offset_y, .color = ColorWhite));
|
draw_text(G.render_sig, DRAW_TEXT_PARAMS(.font = font, .pos = pos, .str = text, .offset_y = offset_y, .color = ColorWhite));
|
||||||
EndTempArena(temp);
|
EndTempArena(temp);
|
||||||
@ -2052,9 +2052,9 @@ internal void user_update(P_Window *window)
|
|||||||
|
|
||||||
{
|
{
|
||||||
__profn("Render");
|
__profn("Render");
|
||||||
V2I32 world_resolution = v2_round_to_int(G.render_size);
|
Vec2I32 world_resolution = v2_round_to_int(G.render_size);
|
||||||
V2I32 user_resolution = v2_round_to_int(G.ui_size);
|
Vec2I32 user_resolution = v2_round_to_int(G.ui_size);
|
||||||
V2I32 backbuffer_resolution = v2_round_to_int(G.screen_size);
|
Vec2I32 backbuffer_resolution = v2_round_to_int(G.screen_size);
|
||||||
|
|
||||||
/* Draw world to user texture */
|
/* Draw world to user texture */
|
||||||
G_Resource *render_texture = 0;
|
G_Resource *render_texture = 0;
|
||||||
@ -2446,7 +2446,7 @@ internal P_JobDef(local_sim_job, _)
|
|||||||
/* Release unneeded received snapshots */
|
/* Release unneeded received snapshots */
|
||||||
/* TDOO: Cap how many client snapshots we're willing to retain */
|
/* TDOO: Cap how many client snapshots we're willing to retain */
|
||||||
if (client->double_ack > 0) {
|
if (client->double_ack > 0) {
|
||||||
u64 keep_tick = min_u64(client->double_ack, local_client->last_tick);
|
u64 keep_tick = MinU64(client->double_ack, local_client->last_tick);
|
||||||
if (keep_tick > 0) {
|
if (keep_tick > 0) {
|
||||||
sim_snapshot_release_ticks_in_range(client, 0, keep_tick - 1);
|
sim_snapshot_release_ticks_in_range(client, 0, keep_tick - 1);
|
||||||
}
|
}
|
||||||
@ -2583,7 +2583,7 @@ internal P_JobDef(local_sim_job, _)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Release unneeded master snapshots */
|
/* Release unneeded master snapshots */
|
||||||
u64 keep_master_tick = min_u64(left_snapshot->tick, master_client->double_ack);
|
u64 keep_master_tick = MinU64(left_snapshot->tick, master_client->double_ack);
|
||||||
if (keep_master_tick > 0) {
|
if (keep_master_tick > 0) {
|
||||||
sim_snapshot_release_ticks_in_range(master_client, 0, keep_master_tick - 1);
|
sim_snapshot_release_ticks_in_range(master_client, 0, keep_master_tick - 1);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user