remove entity tree
This commit is contained in:
parent
ed5e95d6d4
commit
af3687f3e5
@ -1,9 +1,7 @@
|
|||||||
S_SharedState S_shared_state = ZI;
|
S_SharedState S_shared_state = ZI;
|
||||||
|
|
||||||
Readonly S_Ent S_nil_ent = {
|
Readonly S_Ent S_nil_ent = {
|
||||||
.local_xf = CompXformIdentity,
|
.xf = CompXformIdentity
|
||||||
.world_xf = CompXformIdentity,
|
|
||||||
.tint = { 0.5, 0.5, 0.5, 1 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -168,86 +166,29 @@ S_Ent *S_EntFromKey(S_Lookup *lookup, S_Key key)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Iteration helpers
|
//~ Iteration helpers
|
||||||
|
|
||||||
S_Ent *S_FirstEntEx(Arena *arena, S_Iter *iter, S_Lookup *lookup, S_Key key, S_IterKind kind)
|
S_Ent *S_FirstEnt(S_Iter *iter, S_World *world)
|
||||||
{
|
{
|
||||||
iter->kind = kind;
|
ZeroStruct(iter);
|
||||||
iter->lookup = lookup;
|
iter->world = world;
|
||||||
for (S_IterDfsNode *n = iter->first_dfs; n; n = n->next)
|
return S_NextEnt(iter);
|
||||||
{
|
|
||||||
n->next = iter->first_free_dfs;
|
|
||||||
iter->first_free_dfs = n;
|
|
||||||
}
|
|
||||||
iter->first_dfs = 0;
|
|
||||||
{
|
|
||||||
S_IterDfsNode *n = iter->first_free_dfs;
|
|
||||||
if (n)
|
|
||||||
{
|
|
||||||
SllStackPop(iter->first_free_dfs);
|
|
||||||
ZeroStruct(n);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
n = PushStruct(arena, S_IterDfsNode);
|
|
||||||
}
|
|
||||||
n->ent_key = key;
|
|
||||||
SllStackPush(iter->first_dfs, n);
|
|
||||||
}
|
|
||||||
return S_NextEnt(arena, iter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter)
|
S_Ent *S_NextEnt(S_Iter *iter)
|
||||||
{
|
{
|
||||||
|
S_World *world = iter->world;
|
||||||
S_Ent *result = &S_nil_ent;
|
S_Ent *result = &S_nil_ent;
|
||||||
S_Lookup *lookup = iter->lookup;
|
|
||||||
b32 is_post_order = iter->kind == S_IterKind_Post;
|
|
||||||
|
|
||||||
b32 stop = 0;
|
i64 ent_idx = iter->cur_idx;
|
||||||
while (!stop)
|
for (; ent_idx < world->ents_count; ++ent_idx)
|
||||||
{
|
{
|
||||||
if (iter->first_dfs)
|
S_Ent *ent = &world->ents[ent_idx];
|
||||||
{
|
if (ent->active)
|
||||||
S_IterDfsNode *n = iter->first_dfs;
|
|
||||||
S_Ent *ent = S_EntFromKey(iter->lookup, n->ent_key);
|
|
||||||
if (!n->visited)
|
|
||||||
{
|
|
||||||
/* Push children to dfs stack */
|
|
||||||
for (S_Ent *child = S_EntFromKey(lookup, ent->last); !S_IsEntNil(child); child = S_EntFromKey(lookup, child->prev))
|
|
||||||
{
|
|
||||||
S_IterDfsNode *child_n = iter->first_free_dfs;
|
|
||||||
if (child_n)
|
|
||||||
{
|
|
||||||
SllStackPop(iter->first_free_dfs);
|
|
||||||
ZeroStruct(child_n);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
child_n = PushStruct(arena, S_IterDfsNode);
|
|
||||||
}
|
|
||||||
child_n->ent_key = child->key;
|
|
||||||
SllStackPush(iter->first_dfs, child_n);
|
|
||||||
}
|
|
||||||
n->visited = 1;
|
|
||||||
if (!is_post_order)
|
|
||||||
{
|
{
|
||||||
result = ent;
|
result = ent;
|
||||||
stop = 1;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SllStackPop(iter->first_dfs);
|
|
||||||
if (is_post_order)
|
|
||||||
{
|
|
||||||
result = ent;
|
|
||||||
stop = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stop = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iter->cur_idx = ent_idx + 1;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -323,17 +264,6 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
f64 sim_dt = SecondsFromNs(sim_dt_ns);
|
f64 sim_dt = SecondsFromNs(sim_dt_ns);
|
||||||
world->tick += 1;
|
world->tick += 1;
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
//- Create root ent
|
|
||||||
|
|
||||||
if (world->tick == 1)
|
|
||||||
{
|
|
||||||
S_Ent *root_ent = PushStruct(ents_arena, S_Ent);
|
|
||||||
*root_ent = S_nil_ent;
|
|
||||||
root_ent->key = S_RootKey;
|
|
||||||
root_ent->active = 1;
|
|
||||||
++world->ents_count;
|
|
||||||
}
|
|
||||||
lookup = S_LookupFromWorld(frame_arena, world);
|
lookup = S_LookupFromWorld(frame_arena, world);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -362,12 +292,8 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
for (S_EntListNode *src_n = cmd.ents.first; src_n; src_n = src_n->next)
|
for (S_EntListNode *src_n = cmd.ents.first; src_n; src_n = src_n->next)
|
||||||
{
|
{
|
||||||
S_Ent *src = &src_n->ent;
|
S_Ent *src = &src_n->ent;
|
||||||
if (S_IsKeyNil(src->parent))
|
|
||||||
{
|
|
||||||
src->parent = S_RootKey;
|
|
||||||
}
|
|
||||||
S_Key key = src->key;
|
S_Key key = src->key;
|
||||||
if (!S_MatchKey(key, S_RootKey) && !S_IsKeyNil(key))
|
if (!S_IsKeyNil(key))
|
||||||
{
|
{
|
||||||
S_Ent *dst = S_EntFromKey(&lookup, key);
|
S_Ent *dst = S_EntFromKey(&lookup, key);
|
||||||
if (S_IsEntNil(dst))
|
if (S_IsEntNil(dst))
|
||||||
@ -396,84 +322,6 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
lookup = S_LookupFromWorld(frame_arena, world);
|
lookup = S_LookupFromWorld(frame_arena, world);
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
//- Build entity tree
|
|
||||||
|
|
||||||
{
|
|
||||||
/* Reset tree links */
|
|
||||||
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
|
|
||||||
{
|
|
||||||
S_Ent *ent = &world->ents[ent_idx];
|
|
||||||
if (ent->active)
|
|
||||||
{
|
|
||||||
ent->first = S_NilKey;
|
|
||||||
ent->last = S_NilKey;
|
|
||||||
ent->next = S_NilKey;
|
|
||||||
ent->prev = S_NilKey;
|
|
||||||
ent->count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
/* Sort ents by key before tree-build (for deterministic child order in parents) */
|
|
||||||
S_Ent **sorted_ents = 0;
|
|
||||||
{
|
|
||||||
sorted_ents = PushStructsNoZero(frame_arena, S_Ent *, world->ents_count);
|
|
||||||
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
|
|
||||||
{
|
|
||||||
sorted_ents[ent_idx] = &world->ents[ent_idx];
|
|
||||||
}
|
|
||||||
Mergesort(sorted_ents, world->ents_count, sizeof(*sorted_ents), S_SortEntsByKeyCmp, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build tree */
|
|
||||||
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
|
|
||||||
{
|
|
||||||
S_Ent *ent = sorted_ents[ent_idx];
|
|
||||||
if (ent->active)
|
|
||||||
{
|
|
||||||
S_Key key = ent->key;
|
|
||||||
S_Ent *parent = S_EntFromKey(&lookup, ent->parent);
|
|
||||||
if (parent->active)
|
|
||||||
{
|
|
||||||
S_Ent *prev = S_EntFromKey(&lookup, parent->last);
|
|
||||||
if (S_IsEntNil(prev))
|
|
||||||
{
|
|
||||||
parent->first = key;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prev->next = key;
|
|
||||||
}
|
|
||||||
ent->prev = prev->key;
|
|
||||||
parent->last = key;
|
|
||||||
++parent->count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prune dangling ents */
|
|
||||||
/* NOTE: If only the top level of a multi-level ent tree is
|
|
||||||
* dangling, the children may be marked inactive one level per tick
|
|
||||||
* since iteration is linear over the array. */
|
|
||||||
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
|
|
||||||
{
|
|
||||||
S_Ent *ent = &world->ents[ent_idx];
|
|
||||||
if (ent->active && !S_MatchKey(ent->key, S_RootKey))
|
|
||||||
{
|
|
||||||
S_Ent *parent = S_EntFromKey(&lookup, ent->parent);
|
|
||||||
if (!parent->active)
|
|
||||||
{
|
|
||||||
ent->active = 0;
|
|
||||||
ent->next_free_ent_num = first_free_ent_num;
|
|
||||||
first_free_ent_num = ent_idx + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lookup = S_LookupFromWorld(frame_arena, world);
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Update ent controls
|
//- Update ent controls
|
||||||
|
|
||||||
@ -494,30 +342,26 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Apply control forces
|
//- Apply control forces
|
||||||
|
|
||||||
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter))
|
for (S_Ent *ent = S_FirstEnt(&iter, world); ent->active; ent = S_NextEnt(&iter))
|
||||||
{
|
{
|
||||||
Xform xf = ent->local_xf;
|
if (!IsVec2Zero(ent->move))
|
||||||
|
{
|
||||||
|
DEBUGBREAKABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Xform xf = ent->xf;
|
||||||
if (!IsVec2Zero(ent->look))
|
if (!IsVec2Zero(ent->look))
|
||||||
{
|
{
|
||||||
xf = XformWithWorldRotation(xf, AngleFromVec2(ent->look));
|
xf = XformWithWorldRotation(xf, AngleFromVec2(ent->look));
|
||||||
}
|
}
|
||||||
xf.og = AddVec2(xf.og, MulVec2(ent->move, ent->move_speed));
|
xf.og = AddVec2(xf.og, MulVec2(ent->move, ent->move_speed));
|
||||||
ent->local_xf = xf;
|
ent->xf = xf;
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
//- Compute pre-solve world transforms
|
|
||||||
|
|
||||||
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter))
|
|
||||||
{
|
|
||||||
ent->old_world_xf = ent->world_xf;
|
|
||||||
ent->world_xf = MulXform(S_EntFromKey(&lookup, ent->parent)->world_xf, ent->local_xf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Solve followers
|
//- Solve followers
|
||||||
|
|
||||||
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter))
|
for (S_Ent *ent = S_FirstEnt(&iter, world); ent->active; ent = S_NextEnt(&iter))
|
||||||
{
|
{
|
||||||
S_Ent *follow = S_EntFromKey(&lookup, ent->follow);
|
S_Ent *follow = S_EntFromKey(&lookup, ent->follow);
|
||||||
if (follow->active)
|
if (follow->active)
|
||||||
@ -527,24 +371,15 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
look_ratio.y = 0.25;
|
look_ratio.y = 0.25;
|
||||||
look_ratio.x = look_ratio.y / (16.0 / 9.0);
|
look_ratio.x = look_ratio.y / (16.0 / 9.0);
|
||||||
|
|
||||||
Vec2 target = MulXformV2(follow->world_xf, follow->local_shape.centroid);
|
Vec2 target = MulXformV2(follow->xf, follow->local_shape.centroid);
|
||||||
target = AddVec2(target, MulVec2Vec2(follow->look, look_ratio));
|
target = AddVec2(target, MulVec2Vec2(follow->look, look_ratio));
|
||||||
|
|
||||||
Xform xf = ent->local_xf;
|
Xform xf = ent->xf;
|
||||||
// xf.og = AddVec2(xf.og, SubVec2(follow->world_xf.og, follow->old_world_xf.og));
|
|
||||||
xf.og = LerpVec2(xf.og, target, follow_speed);
|
xf.og = LerpVec2(xf.og, target, follow_speed);
|
||||||
ent->local_xf = xf;
|
ent->xf = xf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
//- Compute post-solve world transforms
|
|
||||||
|
|
||||||
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter))
|
|
||||||
{
|
|
||||||
ent->world_xf = MulXform(S_EntFromKey(&lookup, ent->parent)->world_xf, ent->local_xf);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Publish sim state
|
//- Publish sim state
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
//~ Key types
|
//~ Key types
|
||||||
|
|
||||||
#define S_NilKey ((S_Key) { 0 })
|
#define S_NilKey ((S_Key) { 0 })
|
||||||
#define S_RootKey ((S_Key) { .v.hi = 0xaaaaaaaaaaaaaaaa, .v.lo = 0xaaaaaaaaaaaaaaaa })
|
|
||||||
|
|
||||||
Struct(S_Key)
|
Struct(S_Key)
|
||||||
{
|
{
|
||||||
@ -38,16 +37,6 @@ Struct(S_Shape)
|
|||||||
|
|
||||||
Struct(S_Ent)
|
Struct(S_Ent)
|
||||||
{
|
{
|
||||||
//////////////////////////////
|
|
||||||
//- Tree links
|
|
||||||
|
|
||||||
S_Key parent;
|
|
||||||
S_Key first;
|
|
||||||
S_Key last;
|
|
||||||
S_Key next;
|
|
||||||
S_Key prev;
|
|
||||||
u64 count;
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Persistent data
|
//- Persistent data
|
||||||
|
|
||||||
@ -57,29 +46,18 @@ Struct(S_Ent)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Build data
|
//- Build data
|
||||||
|
|
||||||
Xform local_xf;
|
Xform xf;
|
||||||
|
S_Shape local_shape;
|
||||||
Vec4 tint;
|
|
||||||
|
|
||||||
S_Key follow;
|
S_Key follow;
|
||||||
S_Key camera;
|
S_Key camera;
|
||||||
|
|
||||||
S_Shape local_shape;
|
|
||||||
|
|
||||||
f32 move_speed;
|
f32 move_speed;
|
||||||
|
|
||||||
Vec2 move;
|
Vec2 move;
|
||||||
Vec2 look;
|
Vec2 look;
|
||||||
|
|
||||||
//////////////////////////////
|
b32 has_weapon;
|
||||||
//- Pre-solve data
|
|
||||||
|
|
||||||
Xform old_world_xf;
|
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
//- Post-solve data
|
|
||||||
|
|
||||||
Xform world_xf;
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Internal sim data
|
//- Internal sim data
|
||||||
@ -151,25 +129,10 @@ Struct(S_SnapshotNode)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Iterator types
|
//~ Iterator types
|
||||||
|
|
||||||
Enum(S_IterKind)
|
|
||||||
{
|
|
||||||
S_IterKind_Pre,
|
|
||||||
S_IterKind_Post,
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(S_IterDfsNode)
|
|
||||||
{
|
|
||||||
S_IterDfsNode *next;
|
|
||||||
b32 visited;
|
|
||||||
S_Key ent_key;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(S_Iter)
|
Struct(S_Iter)
|
||||||
{
|
{
|
||||||
S_IterKind kind;
|
S_World *world;
|
||||||
S_Lookup *lookup;
|
i64 cur_idx;
|
||||||
S_IterDfsNode *first_dfs;
|
|
||||||
S_IterDfsNode *first_free_dfs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -278,9 +241,8 @@ S_Ent *S_EntFromKey(S_Lookup *lookup, S_Key key);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Iteration helpers
|
//~ Iteration helpers
|
||||||
|
|
||||||
#define S_FirstEnt(arena, iter, lookup) S_FirstEntEx((arena), (iter), (lookup), S_RootKey, S_IterKind_Pre)
|
S_Ent *S_FirstEnt(S_Iter *iter, S_World *world);
|
||||||
S_Ent *S_FirstEntEx(Arena *arena, S_Iter *iter, S_Lookup *lookup, S_Key key, S_IterKind kind);
|
S_Ent *S_NextEnt(S_Iter *iter);
|
||||||
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Snapshot helpers
|
//~ Snapshot helpers
|
||||||
|
|||||||
@ -152,7 +152,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
S_Key child_key = S_RandKey();
|
S_Key child_key = S_RandKey();
|
||||||
S_Key camera_key = S_RandKey();
|
S_Key camera_key = S_RandKey();
|
||||||
|
|
||||||
i32 count = 3;
|
i32 count = 2;
|
||||||
for (u64 i = 0; i < count; ++i)
|
for (u64 i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
S_EntListNode *n = PushStruct(frame->arena, S_EntListNode);
|
S_EntListNode *n = PushStruct(frame->arena, S_EntListNode);
|
||||||
@ -165,7 +165,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
/* Test player */
|
/* Test player */
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
ent->tint = Color_Red;
|
|
||||||
ent->key = V.player_key;
|
ent->key = V.player_key;
|
||||||
ent->camera = camera_key;
|
ent->camera = camera_key;
|
||||||
ent->move_speed = 0.1;
|
ent->move_speed = 0.1;
|
||||||
@ -177,32 +176,12 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// ent->local_xf = XformFromPos(VEC2(200, 200));
|
// ent->local_xf = XformFromPos(VEC2(200, 200));
|
||||||
ent->local_xf = XformFromPos(VEC2(0, 0));
|
ent->xf = XformFromPos(VEC2(0, 0));
|
||||||
} break;
|
ent->has_weapon = 1;
|
||||||
|
|
||||||
/* Test child */
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
f32 width = 0.1;
|
|
||||||
f32 height = 1;
|
|
||||||
|
|
||||||
ent->tint = Color_Cyan;
|
|
||||||
ent->key = child_key;
|
|
||||||
ent->parent = V.player_key;
|
|
||||||
{
|
|
||||||
ent->local_shape = S_ShapeFromDesc(
|
|
||||||
.count = 4,
|
|
||||||
.points = {
|
|
||||||
VEC2(-width / 2, -height), VEC2(width / 2, -height),
|
|
||||||
VEC2(width / 2, 0), VEC2(-width / 2, 0),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ent->local_xf = XformFromTrs(TRS(.t = { 0, 0 }, .r = Tau / 4));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
/* Test camera */
|
/* Test camera */
|
||||||
case 2:
|
case 1:
|
||||||
{
|
{
|
||||||
ent->key = camera_key;
|
ent->key = camera_key;
|
||||||
ent->follow = V.player_key;
|
ent->follow = V.player_key;
|
||||||
@ -286,7 +265,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
{
|
{
|
||||||
S_Ent *player = S_EntFromKey(&V.lookup, V.player_key);
|
S_Ent *player = S_EntFromKey(&V.lookup, V.player_key);
|
||||||
S_Ent *camera = S_EntFromKey(&V.lookup, player->camera);
|
S_Ent *camera = S_EntFromKey(&V.lookup, player->camera);
|
||||||
camera_pos = MulXformV2(camera->world_xf, camera->local_shape.centroid);
|
camera_pos = MulXformV2(camera->xf, camera->local_shape.centroid);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -531,7 +510,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
Vec2 look = ZI;
|
Vec2 look = ZI;
|
||||||
{
|
{
|
||||||
S_Ent *player = S_EntFromKey(&V.lookup, V.player_key);
|
S_Ent *player = S_EntFromKey(&V.lookup, V.player_key);
|
||||||
Vec2 center = MulXformV2(player->world_xf, player->local_shape.centroid);
|
Vec2 center = MulXformV2(player->xf, player->local_shape.centroid);
|
||||||
look = SubVec2(world_cursor, center);
|
look = SubVec2(world_cursor, center);
|
||||||
}
|
}
|
||||||
cmd->target = V.player_key;
|
cmd->target = V.player_key;
|
||||||
@ -572,20 +551,40 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
//- Build render data
|
//- Build render data
|
||||||
|
|
||||||
/* Build shape buffers */
|
/* Build shape buffers */
|
||||||
for (S_Ent *ent = S_FirstEnt(frame->arena, &iter, &V.lookup); ent->active; ent = S_NextEnt(frame->arena, &iter))
|
for (S_Ent *ent = S_FirstEnt(&iter, V.world); ent->active; ent = S_NextEnt(&iter))
|
||||||
{
|
{
|
||||||
Xform ent_to_world_xf = ent->world_xf;
|
Xform ent_to_world_xf = ent->xf;
|
||||||
Xform ent_to_draw_xf = MulXform(world_to_draw_xf, ent_to_world_xf);
|
Xform ent_to_draw_xf = MulXform(world_to_draw_xf, ent_to_world_xf);
|
||||||
|
|
||||||
/* Draw shape */
|
b32 is_visible = 1;
|
||||||
b32 is_visible = ent->tint.w != 0;
|
|
||||||
if (is_visible)
|
if (is_visible)
|
||||||
{
|
{
|
||||||
Vec4 color = ent->tint;
|
/* Draw shape */
|
||||||
|
{
|
||||||
|
Vec4 color = Color_Purple;
|
||||||
i32 detail = 32;
|
i32 detail = 32;
|
||||||
S_Shape shape = S_MulXformShape(ent_to_draw_xf, ent->local_shape);
|
S_Shape shape = S_MulXformShape(ent_to_draw_xf, ent->local_shape);
|
||||||
V_DrawShape(frame->dverts_arena, frame->dvert_idxs_arena, shape, LinearFromSrgb(color), detail, V_DrawFlag_Line);
|
V_DrawShape(frame->dverts_arena, frame->dvert_idxs_arena, shape, LinearFromSrgb(color), detail, V_DrawFlag_Line);
|
||||||
}
|
}
|
||||||
|
/* Draw weapon */
|
||||||
|
if (ent->has_weapon)
|
||||||
|
{
|
||||||
|
Vec4 color = Color_Cyan;
|
||||||
|
f32 width = 0.1;
|
||||||
|
f32 height = 1;
|
||||||
|
S_Shape local_shape = S_ShapeFromDesc(
|
||||||
|
.count = 4,
|
||||||
|
.points = {
|
||||||
|
VEC2(-width / 2, -height), VEC2(width / 2, -height),
|
||||||
|
VEC2(width / 2, 0), VEC2(-width / 2, 0),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Xform local_xf = XformFromTrs(TRS(.t = { 0, 0 }, .r = Tau / 4));
|
||||||
|
Xform xf = MulXform(ent_to_draw_xf, local_xf);
|
||||||
|
S_Shape shape = S_MulXformShape(xf, local_shape);
|
||||||
|
V_DrawShape(frame->dverts_arena, frame->dvert_idxs_arena, shape, LinearFromSrgb(color), 10, V_DrawFlag_Line);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user