sim iter helpers
This commit is contained in:
parent
5a3f5ad12b
commit
87848eaeac
@ -111,6 +111,92 @@ S_Ent *S_EntFromKey(S_World *world, S_Key key)
|
|||||||
return ent;
|
return ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Iteration helpers
|
||||||
|
|
||||||
|
void S_ResetIter(Arena *arena, S_Iter *iter, S_World *world, S_Key key, S_IterKind kind)
|
||||||
|
{
|
||||||
|
iter->kind = kind;
|
||||||
|
iter->world = world;
|
||||||
|
for (S_IterDfsNode *n = iter->first_dfs; n; n = n->next)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter)
|
||||||
|
{
|
||||||
|
S_Ent *result = &S_nil_ent;
|
||||||
|
S_World *world = iter->world;
|
||||||
|
b32 is_post_order = iter->kind == S_IterKind_Post;
|
||||||
|
|
||||||
|
b32 stop = 0;
|
||||||
|
while (!stop)
|
||||||
|
{
|
||||||
|
if (iter->first_dfs)
|
||||||
|
{
|
||||||
|
S_IterDfsNode *n = iter->first_dfs;
|
||||||
|
S_Ent *ent = S_EntFromKey(iter->world, n->ent_key);
|
||||||
|
if (!n->visited)
|
||||||
|
{
|
||||||
|
/* Push children to dfs stack */
|
||||||
|
for (S_Ent *child = S_EntFromKey(world, ent->last); !S_IsEntNil(child); child = S_EntFromKey(world, ent->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;
|
||||||
|
stop = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SllStackPop(iter->first_dfs);
|
||||||
|
if (is_post_order)
|
||||||
|
{
|
||||||
|
result = ent;
|
||||||
|
stop = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stop = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Snapshot helpers
|
//~ Snapshot helpers
|
||||||
|
|
||||||
@ -138,60 +224,6 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
|
|||||||
SllStackPush(*bin, n);
|
SllStackPush(*bin, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sort tree */
|
|
||||||
{
|
|
||||||
i64 ents_count = world->allocated_ents_count;
|
|
||||||
S_Ent **ents_pre = PushStructsNoZero(arena, S_Ent *, ents_count);
|
|
||||||
S_Ent **ents_post = PushStructsNoZero(arena, S_Ent *, ents_count);
|
|
||||||
{
|
|
||||||
Struct(EntNode) { EntNode *next; b32 visited; S_Ent *ent; };
|
|
||||||
EntNode *first_dfs = 0;
|
|
||||||
i64 pre_idx = 0;
|
|
||||||
i64 post_idx = 0;
|
|
||||||
{
|
|
||||||
EntNode *n = PushStruct(scratch.arena, EntNode);
|
|
||||||
for (i64 ent_idx = 0; ent_idx < world->allocated_ents_count; ++ent_idx)
|
|
||||||
{
|
|
||||||
S_Ent *ent = &world->ents[ent_idx];
|
|
||||||
if (S_MatchKey(ent->key, S_RootKey))
|
|
||||||
{
|
|
||||||
n->ent = ent;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SllStackPush(first_dfs, n);
|
|
||||||
}
|
|
||||||
while (first_dfs)
|
|
||||||
{
|
|
||||||
EntNode *n = first_dfs;
|
|
||||||
S_Ent *ent = n->ent;
|
|
||||||
if (!n->visited)
|
|
||||||
{
|
|
||||||
/* Push children to dfs stack */
|
|
||||||
for (S_Ent *child = S_EntFromKey(world, ent->first); !S_IsEntNil(child); child = S_EntFromKey(world, child->prev))
|
|
||||||
{
|
|
||||||
EntNode *child_n = PushStruct(scratch.arena, EntNode);
|
|
||||||
child_n->ent = child;
|
|
||||||
SllStackPush(first_dfs, child_n);
|
|
||||||
}
|
|
||||||
ent->pre_idx = pre_idx++;
|
|
||||||
ents_pre[ent->pre_idx] = ent;
|
|
||||||
n->visited = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SllStackPop(first_dfs);
|
|
||||||
ent->post_idx = post_idx++;
|
|
||||||
ents_post[ent->post_idx] = ent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Assert(pre_idx == post_idx);
|
|
||||||
world->active_ents_count = pre_idx;
|
|
||||||
world->ents_pre = ents_pre;
|
|
||||||
world->ents_post = ents_post;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EndScratch(scratch);
|
EndScratch(scratch);
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
@ -258,6 +290,7 @@ JobDef(S_SimWorker, _, __)
|
|||||||
while (!shutdown)
|
while (!shutdown)
|
||||||
{
|
{
|
||||||
ResetArena(frame_arena);
|
ResetArena(frame_arena);
|
||||||
|
S_Iter ent_iter = ZI;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Begin sim frame
|
//- Begin sim frame
|
||||||
@ -297,6 +330,11 @@ JobDef(S_SimWorker, _, __)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Update entities from user control
|
//- Update entities from user control
|
||||||
|
|
||||||
|
S_ResetIter(frame_arena, &ent_iter, world, S_RootKey, S_IterKind_Post);
|
||||||
|
for (S_Ent *ent = S_NextEnt(frame_arena, &ent_iter); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &ent_iter))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Publish sim state
|
//- Publish sim state
|
||||||
|
|
||||||
|
|||||||
@ -52,10 +52,6 @@ Struct(S_Ent)
|
|||||||
|
|
||||||
//- Final data
|
//- Final data
|
||||||
Xform final_local_to_world_xf;
|
Xform final_local_to_world_xf;
|
||||||
|
|
||||||
//- Per-world data
|
|
||||||
i64 pre_idx;
|
|
||||||
i64 post_idx;
|
|
||||||
} extern Readonly S_nil_ent;
|
} extern Readonly S_nil_ent;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -92,10 +88,6 @@ Struct(S_World)
|
|||||||
|
|
||||||
S_EntLookupNode **ent_bins;
|
S_EntLookupNode **ent_bins;
|
||||||
i64 ent_bins_count;
|
i64 ent_bins_count;
|
||||||
|
|
||||||
S_Ent **ents_pre;
|
|
||||||
S_Ent **ents_post;
|
|
||||||
i64 active_ents_count;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(S_Snapshot)
|
Struct(S_Snapshot)
|
||||||
@ -111,6 +103,30 @@ Struct(S_SnapshotNode)
|
|||||||
S_Snapshot snapshot;
|
S_Snapshot snapshot;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ 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)
|
||||||
|
{
|
||||||
|
S_IterKind kind;
|
||||||
|
S_World *world;
|
||||||
|
S_IterDfsNode *first_dfs;
|
||||||
|
S_IterDfsNode *first_free_dfs;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Command types
|
//~ Command types
|
||||||
|
|
||||||
@ -196,6 +212,12 @@ Vec2 S_SupportPointFromShape(S_Shape shape, Vec2 dir);
|
|||||||
|
|
||||||
S_Ent *S_EntFromKey(S_World *world, S_Key key);
|
S_Ent *S_EntFromKey(S_World *world, S_Key key);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Iteration helpers
|
||||||
|
|
||||||
|
void S_ResetIter(Arena *arena, S_Iter *iter, S_World *world, S_Key key, S_IterKind kind);
|
||||||
|
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Snapshot helpers
|
//~ Snapshot helpers
|
||||||
|
|
||||||
|
|||||||
@ -117,6 +117,7 @@ JobDef(V_VisWorker, _, __)
|
|||||||
while (!shutdown)
|
while (!shutdown)
|
||||||
{
|
{
|
||||||
ResetArena(frame_arena);
|
ResetArena(frame_arena);
|
||||||
|
S_Iter ent_iter = ZI;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Begin vis frame
|
//- Begin vis frame
|
||||||
@ -346,12 +347,10 @@ JobDef(V_VisWorker, _, __)
|
|||||||
//- Build render data
|
//- Build render data
|
||||||
|
|
||||||
/* Build shapes */
|
/* Build shapes */
|
||||||
for (i64 pre_idx = 0; pre_idx < world->active_ents_count; ++pre_idx)
|
S_ResetIter(frame_arena, &ent_iter, world, S_RootKey, S_IterKind_Pre);
|
||||||
|
for (S_Ent *ent = S_NextEnt(frame_arena, &ent_iter); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &ent_iter))
|
||||||
{
|
{
|
||||||
S_Ent *ent = &world->ents[pre_idx];
|
Xform xf = ent->final_local_to_world_xf;
|
||||||
|
|
||||||
// Xform xf = ent->final_to_world_xf;
|
|
||||||
Xform xf = XformIdentity;
|
|
||||||
S_Shape shape = S_MulXformShape(ent->final_local_to_world_xf, ent->local_shape);
|
S_Shape shape = S_MulXformShape(ent->final_local_to_world_xf, ent->local_shape);
|
||||||
for (i32 point_idx = 0; point_idx < shape.points_count; ++point_idx)
|
for (i32 point_idx = 0; point_idx < shape.points_count; ++point_idx)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user