rounded shape drawing
This commit is contained in:
parent
03eed624c9
commit
5a3f5ad12b
@ -348,7 +348,8 @@ PackedVec4 PackVec4(Vec4 v);
|
|||||||
b32 MatchXform(Xform xf1, Xform xf2);
|
b32 MatchXform(Xform xf1, Xform xf2);
|
||||||
|
|
||||||
//- Initialization
|
//- Initialization
|
||||||
#define XformIdentity (Xform) { .bx = VEC2(1, 0), .by = VEC2(0, 1) }
|
#define XformIdentity (Xform) { .bx = { .x = 1 }, .by = { .y = 1 } }
|
||||||
|
#define CompXformIdentity { .bx = { .x = 1 }, .by = { .y = 1 } }
|
||||||
Xform XformFromPos(Vec2 v);
|
Xform XformFromPos(Vec2 v);
|
||||||
Xform XformFromRot(f32 r);
|
Xform XformFromRot(f32 r);
|
||||||
Xform XformFromScale(Vec2 scale);
|
Xform XformFromScale(Vec2 scale);
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
S_SharedState S_shared_state = ZI;
|
S_SharedState S_shared_state = ZI;
|
||||||
Readonly S_Ent S_nil_ent = ZI;
|
|
||||||
|
Readonly S_Ent S_nil_ent = {
|
||||||
|
.local_to_parent_xf = CompXformIdentity,
|
||||||
|
.final_local_to_world_xf = CompXformIdentity,
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Startup
|
//~ Startup
|
||||||
@ -38,7 +42,7 @@ void S_Shutdown(void)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Nil helpers
|
//~ Nil helpers
|
||||||
|
|
||||||
b32 S_IsKeyNil(S_EntKey key)
|
b32 S_IsKeyNil(S_Key key)
|
||||||
{
|
{
|
||||||
return key.v.hi == 0 && key.v.lo == 0;
|
return key.v.hi == 0 && key.v.lo == 0;
|
||||||
}
|
}
|
||||||
@ -48,15 +52,48 @@ b32 S_IsEntNil(S_Ent *ent)
|
|||||||
return ent == 0 || ent == &S_nil_ent;
|
return ent == 0 || ent == &S_nil_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 S_MatchEntKey(S_EntKey a, S_EntKey b)
|
b32 S_MatchKey(S_Key a, S_Key b)
|
||||||
{
|
{
|
||||||
return a.v.hi == b.v.hi && a.v.lo == b.v.lo;
|
return a.v.hi == b.v.hi && a.v.lo == b.v.lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Shape helpers
|
||||||
|
|
||||||
|
S_Shape S_MulXformShape(Xform xf, S_Shape shape)
|
||||||
|
{
|
||||||
|
S_Shape result = shape;
|
||||||
|
for (i32 i = 0; i < shape.points_count; ++i)
|
||||||
|
{
|
||||||
|
shape.points[i] = MulXformV2(xf, shape.points[i]);
|
||||||
|
}
|
||||||
|
Vec2 scale = ScaleFromXform(xf);
|
||||||
|
result.radius *= MaxF32(scale.x, scale.y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2 S_SupportPointFromShape(S_Shape shape, Vec2 dir)
|
||||||
|
{
|
||||||
|
Vec2 result = ZI;
|
||||||
|
f32 max_dot = -F32Infinity;
|
||||||
|
for (i32 i = 0; i < shape.points_count; ++i)
|
||||||
|
{
|
||||||
|
Vec2 p = shape.points[i];
|
||||||
|
f32 dot = DotVec2(p, dir);
|
||||||
|
if (dot > max_dot)
|
||||||
|
{
|
||||||
|
max_dot = dot;
|
||||||
|
result = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = AddVec2(result, MulVec2(dir, shape.radius));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Lookup helpers
|
//~ Lookup helpers
|
||||||
|
|
||||||
S_Ent *S_EntFromKey(S_World *world, S_EntKey key)
|
S_Ent *S_EntFromKey(S_World *world, S_Key key)
|
||||||
{
|
{
|
||||||
S_Ent *ent = &S_nil_ent;
|
S_Ent *ent = &S_nil_ent;
|
||||||
if (!S_IsKeyNil(key))
|
if (!S_IsKeyNil(key))
|
||||||
@ -64,7 +101,7 @@ S_Ent *S_EntFromKey(S_World *world, S_EntKey key)
|
|||||||
S_EntLookupNode *n = world->ent_bins[key.v.lo % world->ent_bins_count];
|
S_EntLookupNode *n = world->ent_bins[key.v.lo % world->ent_bins_count];
|
||||||
for (; n; n = n->next)
|
for (; n; n = n->next)
|
||||||
{
|
{
|
||||||
if (S_MatchEntKey(n->ent->key, key))
|
if (S_MatchKey(n->ent->key, key))
|
||||||
{
|
{
|
||||||
ent = n->ent;
|
ent = n->ent;
|
||||||
break;
|
break;
|
||||||
@ -94,7 +131,7 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
|
|||||||
for (i64 ent_idx = 0; ent_idx < world->allocated_ents_count; ++ent_idx)
|
for (i64 ent_idx = 0; ent_idx < world->allocated_ents_count; ++ent_idx)
|
||||||
{
|
{
|
||||||
S_Ent *ent = &world->ents[ent_idx];
|
S_Ent *ent = &world->ents[ent_idx];
|
||||||
S_EntKey key = ent->key;
|
S_Key key = ent->key;
|
||||||
S_EntLookupNode *n = PushStruct(arena, S_EntLookupNode);
|
S_EntLookupNode *n = PushStruct(arena, S_EntLookupNode);
|
||||||
n->ent = ent;
|
n->ent = ent;
|
||||||
S_EntLookupNode **bin = &world->ent_bins[ent->key.v.lo % world->ent_bins_count];
|
S_EntLookupNode **bin = &world->ent_bins[ent->key.v.lo % world->ent_bins_count];
|
||||||
@ -116,7 +153,7 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
|
|||||||
for (i64 ent_idx = 0; ent_idx < world->allocated_ents_count; ++ent_idx)
|
for (i64 ent_idx = 0; ent_idx < world->allocated_ents_count; ++ent_idx)
|
||||||
{
|
{
|
||||||
S_Ent *ent = &world->ents[ent_idx];
|
S_Ent *ent = &world->ents[ent_idx];
|
||||||
if (S_MatchEntKey(ent->key, S_RootEntKey))
|
if (S_MatchKey(ent->key, S_RootKey))
|
||||||
{
|
{
|
||||||
n->ent = ent;
|
n->ent = ent;
|
||||||
break;
|
break;
|
||||||
@ -180,7 +217,7 @@ JobDef(S_SimWorker, _, __)
|
|||||||
S_Ent *root_ent = &empty_ss->ents[empty_ss->ents_count++];
|
S_Ent *root_ent = &empty_ss->ents[empty_ss->ents_count++];
|
||||||
{
|
{
|
||||||
*root_ent = S_nil_ent;
|
*root_ent = S_nil_ent;
|
||||||
root_ent->key = S_RootEntKey;
|
root_ent->key = S_RootKey;
|
||||||
}
|
}
|
||||||
/* Create test ent */
|
/* Create test ent */
|
||||||
S_Ent *test_ent = &empty_ss->ents[empty_ss->ents_count++];
|
S_Ent *test_ent = &empty_ss->ents[empty_ss->ents_count++];
|
||||||
@ -188,19 +225,16 @@ JobDef(S_SimWorker, _, __)
|
|||||||
*test_ent = S_nil_ent;
|
*test_ent = S_nil_ent;
|
||||||
// test_ent->shape.points_count = 1;
|
// test_ent->shape.points_count = 1;
|
||||||
// test_ent->shape.radius = 0.25;
|
// test_ent->shape.radius = 0.25;
|
||||||
test_ent->key = ((S_EntKey) { .v.hi = 0x66444f20b7e41f3d, .v.lo = 0x5a2df684b9430943 });
|
test_ent->key = ((S_Key) { .v.hi = 0x66444f20b7e41f3d, .v.lo = 0x5a2df684b9430943 });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
S_Shape *shape = &test_ent->shape;
|
S_Shape *shape = &test_ent->local_shape;
|
||||||
shape->points_count = 4;
|
shape->points_count = 4;
|
||||||
shape->points[0] = VEC2(100, 100);
|
shape->points[0] = VEC2(100, 100);
|
||||||
shape->points[1] = VEC2(200, 100);
|
shape->points[1] = VEC2(200, 100);
|
||||||
shape->points[2] = VEC2(150, 200);
|
shape->points[2] = VEC2(150, 200);
|
||||||
shape->points[3] = VEC2(125, 200);
|
shape->points[3] = VEC2(125, 200);
|
||||||
// test_ent->shape.radius = 0.25;
|
// shape->radius = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -218,7 +252,7 @@ JobDef(S_SimWorker, _, __)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Begin sim loop
|
//- Sim loop
|
||||||
|
|
||||||
b32 shutdown = 0;
|
b32 shutdown = 0;
|
||||||
while (!shutdown)
|
while (!shutdown)
|
||||||
@ -260,6 +294,9 @@ JobDef(S_SimWorker, _, __)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Update entities from user control
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Publish sim state
|
//- Publish sim state
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Key types
|
//~ Key types
|
||||||
|
|
||||||
#define S_NilEntKey ((S_EntKey) { 0 })
|
#define S_NilKey ((S_Key) { 0 })
|
||||||
#define S_RootEntKey ((S_EntKey) { .v.hi = 0x75ebb7a47d1ca753, .v.lo = 0x2d505fc8961e5576 })
|
#define S_RootKey ((S_Key) { .v.hi = 0x75ebb7a47d1ca753, .v.lo = 0x2d505fc8961e5576 })
|
||||||
|
|
||||||
Struct(S_EntKey)
|
Struct(S_Key)
|
||||||
{
|
{
|
||||||
U128 v;
|
U128 v;
|
||||||
};
|
};
|
||||||
@ -15,7 +15,7 @@ Struct(S_EntKey)
|
|||||||
Struct(S_Shape)
|
Struct(S_Shape)
|
||||||
{
|
{
|
||||||
f32 radius;
|
f32 radius;
|
||||||
u32 points_count;
|
i32 points_count;
|
||||||
Vec2 points[8];
|
Vec2 points[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,18 +36,22 @@ Enum(S_EntProp)
|
|||||||
Struct(S_Ent)
|
Struct(S_Ent)
|
||||||
{
|
{
|
||||||
//- Tree data
|
//- Tree data
|
||||||
S_EntKey parent;
|
S_Key parent;
|
||||||
S_EntKey first;
|
S_Key first;
|
||||||
S_EntKey last;
|
S_Key last;
|
||||||
S_EntKey next;
|
S_Key next;
|
||||||
S_EntKey prev;
|
S_Key prev;
|
||||||
i64 count;
|
i64 count;
|
||||||
|
|
||||||
//- Persistent data
|
//- Persistent data
|
||||||
S_EntKey key;
|
S_Key key;
|
||||||
|
|
||||||
//- Build data
|
//- Build data
|
||||||
S_Shape shape;
|
S_Shape local_shape;
|
||||||
|
Xform local_to_parent_xf;
|
||||||
|
|
||||||
|
//- Final data
|
||||||
|
Xform final_local_to_world_xf;
|
||||||
|
|
||||||
//- Per-world data
|
//- Per-world data
|
||||||
i64 pre_idx;
|
i64 pre_idx;
|
||||||
@ -177,14 +181,20 @@ void S_Shutdown(void);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Nil helpers
|
//~ Nil helpers
|
||||||
|
|
||||||
b32 S_IsKeyNil(S_EntKey key);
|
b32 S_IsKeyNil(S_Key key);
|
||||||
b32 S_IsEntNil(S_Ent *ent);
|
b32 S_IsEntNil(S_Ent *ent);
|
||||||
b32 S_MatchEntKey(S_EntKey a, S_EntKey b);
|
b32 S_MatchKey(S_Key a, S_Key b);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Shape helpers
|
||||||
|
|
||||||
|
S_Shape S_MulXformShape(Xform xf, S_Shape shape);
|
||||||
|
Vec2 S_SupportPointFromShape(S_Shape shape, Vec2 dir);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Lookup helpers
|
//~ Lookup helpers
|
||||||
|
|
||||||
S_Ent *S_EntFromKey(S_World *world, S_EntKey key);
|
S_Ent *S_EntFromKey(S_World *world, S_Key key);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Snapshot helpers
|
//~ Snapshot helpers
|
||||||
|
|||||||
@ -352,15 +352,15 @@ JobDef(V_VisWorker, _, __)
|
|||||||
|
|
||||||
// Xform xf = ent->final_to_world_xf;
|
// Xform xf = ent->final_to_world_xf;
|
||||||
Xform xf = XformIdentity;
|
Xform xf = XformIdentity;
|
||||||
S_Shape shape = ent->shape;
|
S_Shape shape = S_MulXformShape(ent->final_local_to_world_xf, ent->local_shape);
|
||||||
for (u32 point_idx = 0; point_idx < shape.points_count; ++point_idx)
|
for (i32 point_idx = 0; point_idx < shape.points_count; ++point_idx)
|
||||||
{
|
{
|
||||||
Vec2 *p = &shape.points[point_idx];
|
Vec2 *p = &shape.points[point_idx];
|
||||||
*p = MulXformV2(xf, *p);
|
*p = MulXformV2(xf, *p);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec4 color = Color_Red;
|
Vec4 color = Color_Red;
|
||||||
V_DrawShape(dverts_arena, dvert_idx_arena, shape, LinearFromSrgb(color));
|
V_DrawShape(dverts_arena, dvert_idx_arena, shape, LinearFromSrgb(color), 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|||||||
@ -1,16 +1,35 @@
|
|||||||
void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin)
|
void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin, i32 detail)
|
||||||
{
|
{
|
||||||
/* FIXME: Rounding */
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
|
|
||||||
i32 verts_count = shape.points_count;
|
Vec2Array draw_points = ZI;
|
||||||
|
if (shape.radius == 0)
|
||||||
|
{
|
||||||
|
draw_points.points = shape.points;
|
||||||
|
draw_points.count = shape.points_count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
draw_points.points = PushStructsNoZero(scratch.arena, Vec2, detail);
|
||||||
|
draw_points.count = detail;
|
||||||
|
for (i32 i = 0; i < detail; ++i)
|
||||||
|
{
|
||||||
|
f32 rad = ((f32)i / (f32)detail) * Tau;
|
||||||
|
Vec2 dir = Vec2FromAngle(rad);
|
||||||
|
Vec2 sp = S_SupportPointFromShape(shape, dir);
|
||||||
|
draw_points.points[i] = sp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i32 verts_count = draw_points.count;
|
||||||
if (verts_count >= 3)
|
if (verts_count >= 3)
|
||||||
{
|
{
|
||||||
i32 idx_offset = ArenaCount(verts_arena, V_DVert);
|
i32 idx_offset = ArenaCount(verts_arena, V_DVert);
|
||||||
V_DVert *dverts = PushStructsNoZero(verts_arena, V_DVert, verts_count);
|
V_DVert *dverts = PushStructsNoZero(verts_arena, V_DVert, verts_count);
|
||||||
for (i32 point_idx = 0; point_idx < (i32)shape.points_count; ++point_idx)
|
for (i32 point_idx = 0; point_idx < (i32)draw_points.count; ++point_idx)
|
||||||
{
|
{
|
||||||
V_DVert *dvert = &dverts[point_idx];
|
V_DVert *dvert = &dverts[point_idx];
|
||||||
dvert->pos = shape.points[point_idx];
|
dvert->pos = draw_points.points[point_idx];
|
||||||
dvert->color_lin = color_lin;
|
dvert->color_lin = color_lin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,4 +46,6 @@ void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color
|
|||||||
indices[tri_offset + 2] = i + 2;
|
indices[tri_offset + 2] = i + 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EndScratch(scratch);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin);
|
void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin, i32 detail);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user