more prediction testing
This commit is contained in:
parent
cdc876e71f
commit
64aff1893d
383
src/pp/pp.c
383
src/pp/pp.c
@ -1351,9 +1351,6 @@ void P_ClearFrames(P_World *world, i64 tick_min, i64 tick_max)
|
|||||||
|
|
||||||
P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
|
P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
|
||||||
{
|
{
|
||||||
Assert(!(src_frame->world == world && tick <= src_frame->tick)); // Can't read from tick that is being overwritten by new tick
|
|
||||||
P_ClearFrames(world, tick, I64Max);
|
|
||||||
|
|
||||||
P_Frame *frame = world->first_free_frame;
|
P_Frame *frame = world->first_free_frame;
|
||||||
if (frame)
|
if (frame)
|
||||||
{
|
{
|
||||||
@ -1395,12 +1392,6 @@ P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
|
|||||||
frame->constraints_count = 0;
|
frame->constraints_count = 0;
|
||||||
frame->constraints = PushStructsNoZero(world->frames_arena, P_Constraint, frame->max_constraints);
|
frame->constraints = PushStructsNoZero(world->frames_arena, P_Constraint, frame->max_constraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 hash = MixU64(tick);
|
|
||||||
P_FrameBin *bin = &world->frame_bins[hash % world->frame_bins_count];
|
|
||||||
|
|
||||||
DllQueuePushNPZ(&P_NilFrame, world->first_frame, world->last_frame, frame, next, prev);
|
|
||||||
DllQueuePushNPZ(0, bin->first, bin->last, frame, next_in_bin, prev_in_bin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy ents
|
// Copy ents
|
||||||
@ -1422,6 +1413,17 @@ P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
|
|||||||
++frame->ents_count;
|
++frame->ents_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear frames
|
||||||
|
P_ClearFrames(world, tick, I64Max);
|
||||||
|
|
||||||
|
// Insert frame
|
||||||
|
{
|
||||||
|
u64 hash = MixU64(tick);
|
||||||
|
P_FrameBin *bin = &world->frame_bins[hash % world->frame_bins_count];
|
||||||
|
DllQueuePushNPZ(&P_NilFrame, world->first_frame, world->last_frame, frame, next, prev);
|
||||||
|
DllQueuePushNPZ(0, bin->first, bin->last, frame, next_in_bin, prev_in_bin);
|
||||||
|
}
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1525,8 +1527,7 @@ void P_StepFrame(P_Frame *frame)
|
|||||||
|
|
||||||
for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy))
|
for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy))
|
||||||
{
|
{
|
||||||
// if (guy->is_guy && (!is_predicting || guy == local_guy))
|
if (guy->is_guy && (!is_predicting || guy == local_guy))
|
||||||
if (guy->is_guy)
|
|
||||||
{
|
{
|
||||||
P_Control control = guy->control;
|
P_Control control = guy->control;
|
||||||
|
|
||||||
@ -1603,8 +1604,176 @@ void P_StepFrame(P_Frame *frame)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Generate guy-on-guy constraints
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Not like this
|
||||||
|
|
||||||
|
for (P_Ent *ent0 = P_FirstEnt(frame); !P_IsEntNil(ent0); ent0 = P_NextEnt(ent0))
|
||||||
|
{
|
||||||
|
if (ent0->is_guy)
|
||||||
|
{
|
||||||
|
P_Shape shape0 = P_WorldShapeFromEnt(ent0);
|
||||||
|
for (P_Ent *ent1 = P_FirstEnt(frame); !P_IsEntNil(ent1); ent1 = P_NextEnt(ent1))
|
||||||
|
{
|
||||||
|
if (ent1->is_guy && ent1->key.v > ent0->key.v)
|
||||||
|
{
|
||||||
|
P_Shape shape1 = P_WorldShapeFromEnt(ent1);
|
||||||
|
|
||||||
|
// TODO: World query
|
||||||
|
P_CollisionResult collision = P_CollisionResultFromShapes(shape0, shape1);
|
||||||
|
if (collision.collision_points_count > 0)
|
||||||
|
{
|
||||||
|
// FIXME: Key lookup
|
||||||
|
P_Constraint *constraint = 0;
|
||||||
|
{
|
||||||
|
b32 match = 0;
|
||||||
|
for (i64 constraint_idx = 0; constraint_idx < frame->constraints_count; ++constraint_idx)
|
||||||
|
{
|
||||||
|
constraint = &frame->constraints[constraint_idx];
|
||||||
|
if (P_MatchKey(constraint->ent0, ent0->key) && P_MatchKey(constraint->ent1, ent1->key))
|
||||||
|
{
|
||||||
|
match = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!match)
|
||||||
|
{
|
||||||
|
if (frame->constraints_count < frame->max_constraints)
|
||||||
|
{
|
||||||
|
constraint = &frame->constraints[frame->constraints_count];
|
||||||
|
frame->constraints_count += 1;
|
||||||
|
ZeroStruct(constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (constraint)
|
||||||
|
{
|
||||||
|
constraint->flags = P_ConstraintFlag_Gentle | P_ConstraintFlag_NoWarmStart;
|
||||||
|
constraint->last_touched_tick = frame->tick;
|
||||||
|
constraint->normal = collision.collision_normal;
|
||||||
|
// constraint->friction = SqrtF32(ent0->friction * ent1->friction);
|
||||||
|
constraint->friction = 0;
|
||||||
|
|
||||||
|
// TODO: Real masses
|
||||||
|
f32 inv_m0 = 10;
|
||||||
|
f32 inv_m1 = 10;
|
||||||
|
f32 inv_i0 = 0;
|
||||||
|
f32 inv_i1 = 0;
|
||||||
|
|
||||||
|
// Treat non-predicted guys as infinite-mass
|
||||||
|
if (is_predicting && ent0 != local_guy)
|
||||||
|
{
|
||||||
|
inv_m0 = 0;
|
||||||
|
}
|
||||||
|
if (is_predicting && ent1 != local_guy)
|
||||||
|
{
|
||||||
|
inv_m1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constraint->ent0 = ent0->key;
|
||||||
|
constraint->ent1 = ent1->key;
|
||||||
|
// constraint->static_center1 = shape1.center_of_mass;
|
||||||
|
|
||||||
|
constraint->inv_m0 = inv_m0;
|
||||||
|
constraint->inv_m1 = inv_m1;
|
||||||
|
constraint->inv_i0 = inv_i0;
|
||||||
|
constraint->inv_i1 = inv_i1;
|
||||||
|
|
||||||
|
// Delete old contacts that are no longer present
|
||||||
|
for (i32 contact_point_idx = 0; contact_point_idx < constraint->points_count; ++contact_point_idx)
|
||||||
|
{
|
||||||
|
P_ContactPoint *contact = &constraint->points[contact_point_idx];
|
||||||
|
u32 id = contact->id;
|
||||||
|
b32 match = 0;
|
||||||
|
for (i32 collision_point_idx = 0; collision_point_idx < collision.collision_points_count; ++collision_point_idx)
|
||||||
|
{
|
||||||
|
if (collision.collision_points[collision_point_idx].id == id)
|
||||||
|
{
|
||||||
|
match = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!match)
|
||||||
|
{
|
||||||
|
// Delete contact by replacing with last in array
|
||||||
|
*contact = constraint->points[constraint->points_count - 1];
|
||||||
|
constraint->points_count -= 1;
|
||||||
|
contact_point_idx -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create / update contacts from collision
|
||||||
|
for (i32 collision_point_idx = 0; collision_point_idx < collision.collision_points_count; ++collision_point_idx)
|
||||||
|
{
|
||||||
|
P_CollisionPoint collision_point = collision.collision_points[collision_point_idx];
|
||||||
|
|
||||||
|
u32 id = collision_point.id;
|
||||||
|
P_ContactPoint *contact = 0;
|
||||||
|
{
|
||||||
|
for (i32 contact_point_idx = 0; contact_point_idx < constraint->points_count; ++contact_point_idx)
|
||||||
|
{
|
||||||
|
P_ContactPoint *tmp = &constraint->points[contact_point_idx];
|
||||||
|
if (tmp->id == id)
|
||||||
|
{
|
||||||
|
contact = tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!contact)
|
||||||
|
{
|
||||||
|
contact = &constraint->points[constraint->points_count];
|
||||||
|
constraint->points_count += 1;
|
||||||
|
ZeroStruct(contact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contact->id = id;
|
||||||
|
|
||||||
|
Vec2 vcp0 = SubVec2(collision_point.p, shape0.center_of_mass);
|
||||||
|
Vec2 vcp1 = SubVec2(collision_point.p, shape1.center_of_mass);
|
||||||
|
|
||||||
|
contact->vcp0 = vcp0;
|
||||||
|
contact->vcp1 = vcp1;
|
||||||
|
contact->starting_separation = collision_point.separation;
|
||||||
|
|
||||||
|
// Debug draw
|
||||||
|
// {
|
||||||
|
// // P_Ent *ent0 = P_EntFromKey(frame, constraint->ent0);
|
||||||
|
// // P_Ent *ent1 = P_EntFromKey(frame, constraint->ent1);
|
||||||
|
// Vec2 normal = constraint->normal;
|
||||||
|
// Vec2 center0 = Zi;
|
||||||
|
// Vec2 center1 = Zi;
|
||||||
|
// if (!P_IsEntNil(ent0)) center0 = P_WorldShapeFromEnt(ent0).center_of_mass;
|
||||||
|
// if (!P_IsEntNil(ent1)) center1 = P_WorldShapeFromEnt(ent1).center_of_mass;
|
||||||
|
// Vec2 p0 = AddVec2(center0, vcp0);
|
||||||
|
// Vec2 p1 = AddVec2(center1, vcp1);
|
||||||
|
// P_DebugDrawPoint(p0, Color_Cyan);
|
||||||
|
// P_DebugDrawLine(p0, AddVec2(p0, normal), Color_White);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// //////////////////////////////
|
// //////////////////////////////
|
||||||
// //- Generate guy-on-guy constraints
|
// //- Generate solid constraints
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1650,7 +1819,7 @@ void P_StepFrame(P_Frame *frame)
|
|||||||
// }
|
// }
|
||||||
// if (constraint)
|
// if (constraint)
|
||||||
// {
|
// {
|
||||||
// constraint->flags = P_ConstraintFlag_Gentle | P_ConstraintFlag_NoWarmStart;
|
// constraint->flags = P_ConstraintFlag_Solid;
|
||||||
// constraint->last_touched_tick = frame->tick;
|
// constraint->last_touched_tick = frame->tick;
|
||||||
// constraint->normal = collision.collision_normal;
|
// constraint->normal = collision.collision_normal;
|
||||||
// // constraint->friction = SqrtF32(ent0->friction * ent1->friction);
|
// // constraint->friction = SqrtF32(ent0->friction * ent1->friction);
|
||||||
@ -1663,14 +1832,15 @@ void P_StepFrame(P_Frame *frame)
|
|||||||
// f32 inv_i1 = 0;
|
// f32 inv_i1 = 0;
|
||||||
|
|
||||||
// // Treat non-predicted guys as infinite-mass
|
// // Treat non-predicted guys as infinite-mass
|
||||||
// // if (is_predicting && ent0 != local_guy)
|
// if (is_predicting && ent0 != local_guy)
|
||||||
// // {
|
// {
|
||||||
// // inv_m0 = 0;
|
// inv_m0 = 0;
|
||||||
// // }
|
// }
|
||||||
// // if (is_predicting && ent1 != local_guy)
|
// if (is_predicting && ent1 != local_guy)
|
||||||
// // {
|
// {
|
||||||
// // inv_m1 = 0;
|
// inv_m1 = 0;
|
||||||
// // }
|
// }
|
||||||
|
|
||||||
|
|
||||||
// constraint->ent0 = ent0->key;
|
// constraint->ent0 = ent0->key;
|
||||||
// constraint->ent1 = ent1->key;
|
// constraint->ent1 = ent1->key;
|
||||||
@ -1762,175 +1932,6 @@ void P_StepFrame(P_Frame *frame)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
//- Generate solid constraints
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: Not like this
|
|
||||||
|
|
||||||
for (P_Ent *ent0 = P_FirstEnt(frame); !P_IsEntNil(ent0); ent0 = P_NextEnt(ent0))
|
|
||||||
{
|
|
||||||
if (ent0->is_guy)
|
|
||||||
{
|
|
||||||
P_Shape shape0 = P_WorldShapeFromEnt(ent0);
|
|
||||||
for (P_Ent *ent1 = P_FirstEnt(frame); !P_IsEntNil(ent1); ent1 = P_NextEnt(ent1))
|
|
||||||
{
|
|
||||||
if (ent1->is_guy && ent1->key.v > ent0->key.v)
|
|
||||||
{
|
|
||||||
P_Shape shape1 = P_WorldShapeFromEnt(ent1);
|
|
||||||
|
|
||||||
// TODO: World query
|
|
||||||
P_CollisionResult collision = P_CollisionResultFromShapes(shape0, shape1);
|
|
||||||
if (collision.collision_points_count > 0)
|
|
||||||
{
|
|
||||||
// FIXME: Key lookup
|
|
||||||
P_Constraint *constraint = 0;
|
|
||||||
{
|
|
||||||
b32 match = 0;
|
|
||||||
for (i64 constraint_idx = 0; constraint_idx < frame->constraints_count; ++constraint_idx)
|
|
||||||
{
|
|
||||||
constraint = &frame->constraints[constraint_idx];
|
|
||||||
if (P_MatchKey(constraint->ent0, ent0->key) && P_MatchKey(constraint->ent1, ent1->key))
|
|
||||||
{
|
|
||||||
match = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!match)
|
|
||||||
{
|
|
||||||
if (frame->constraints_count < frame->max_constraints)
|
|
||||||
{
|
|
||||||
constraint = &frame->constraints[frame->constraints_count];
|
|
||||||
frame->constraints_count += 1;
|
|
||||||
ZeroStruct(constraint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (constraint)
|
|
||||||
{
|
|
||||||
constraint->flags = P_ConstraintFlag_Solid;
|
|
||||||
constraint->last_touched_tick = frame->tick;
|
|
||||||
constraint->normal = collision.collision_normal;
|
|
||||||
// constraint->friction = SqrtF32(ent0->friction * ent1->friction);
|
|
||||||
constraint->friction = 0;
|
|
||||||
|
|
||||||
// TODO: Real masses
|
|
||||||
f32 inv_m0 = 10;
|
|
||||||
f32 inv_m1 = 10;
|
|
||||||
f32 inv_i0 = 0;
|
|
||||||
f32 inv_i1 = 0;
|
|
||||||
|
|
||||||
// Treat non-predicted guys as infinite-mass
|
|
||||||
// if (is_predicting && ent0 != local_guy)
|
|
||||||
// {
|
|
||||||
// inv_m0 = 0;
|
|
||||||
// }
|
|
||||||
// if (is_predicting && ent1 != local_guy)
|
|
||||||
// {
|
|
||||||
// inv_m1 = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
constraint->ent0 = ent0->key;
|
|
||||||
constraint->ent1 = ent1->key;
|
|
||||||
// constraint->static_center1 = shape1.center_of_mass;
|
|
||||||
|
|
||||||
constraint->inv_m0 = inv_m0;
|
|
||||||
constraint->inv_m1 = inv_m1;
|
|
||||||
constraint->inv_i0 = inv_i0;
|
|
||||||
constraint->inv_i1 = inv_i1;
|
|
||||||
|
|
||||||
// Delete old contacts that are no longer present
|
|
||||||
for (i32 contact_point_idx = 0; contact_point_idx < constraint->points_count; ++contact_point_idx)
|
|
||||||
{
|
|
||||||
P_ContactPoint *contact = &constraint->points[contact_point_idx];
|
|
||||||
u32 id = contact->id;
|
|
||||||
b32 match = 0;
|
|
||||||
for (i32 collision_point_idx = 0; collision_point_idx < collision.collision_points_count; ++collision_point_idx)
|
|
||||||
{
|
|
||||||
if (collision.collision_points[collision_point_idx].id == id)
|
|
||||||
{
|
|
||||||
match = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!match)
|
|
||||||
{
|
|
||||||
// Delete contact by replacing with last in array
|
|
||||||
*contact = constraint->points[constraint->points_count - 1];
|
|
||||||
constraint->points_count -= 1;
|
|
||||||
contact_point_idx -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create / update contacts from collision
|
|
||||||
for (i32 collision_point_idx = 0; collision_point_idx < collision.collision_points_count; ++collision_point_idx)
|
|
||||||
{
|
|
||||||
P_CollisionPoint collision_point = collision.collision_points[collision_point_idx];
|
|
||||||
|
|
||||||
u32 id = collision_point.id;
|
|
||||||
P_ContactPoint *contact = 0;
|
|
||||||
{
|
|
||||||
for (i32 contact_point_idx = 0; contact_point_idx < constraint->points_count; ++contact_point_idx)
|
|
||||||
{
|
|
||||||
P_ContactPoint *tmp = &constraint->points[contact_point_idx];
|
|
||||||
if (tmp->id == id)
|
|
||||||
{
|
|
||||||
contact = tmp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!contact)
|
|
||||||
{
|
|
||||||
contact = &constraint->points[constraint->points_count];
|
|
||||||
constraint->points_count += 1;
|
|
||||||
ZeroStruct(contact);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
contact->id = id;
|
|
||||||
|
|
||||||
Vec2 vcp0 = SubVec2(collision_point.p, shape0.center_of_mass);
|
|
||||||
Vec2 vcp1 = SubVec2(collision_point.p, shape1.center_of_mass);
|
|
||||||
|
|
||||||
contact->vcp0 = vcp0;
|
|
||||||
contact->vcp1 = vcp1;
|
|
||||||
contact->starting_separation = collision_point.separation;
|
|
||||||
|
|
||||||
// Debug draw
|
|
||||||
{
|
|
||||||
// P_Ent *ent0 = P_EntFromKey(frame, constraint->ent0);
|
|
||||||
// P_Ent *ent1 = P_EntFromKey(frame, constraint->ent1);
|
|
||||||
Vec2 normal = constraint->normal;
|
|
||||||
Vec2 center0 = Zi;
|
|
||||||
Vec2 center1 = Zi;
|
|
||||||
if (!P_IsEntNil(ent0)) center0 = P_WorldShapeFromEnt(ent0).center_of_mass;
|
|
||||||
if (!P_IsEntNil(ent1)) center1 = P_WorldShapeFromEnt(ent1).center_of_mass;
|
|
||||||
Vec2 p0 = AddVec2(center0, vcp0);
|
|
||||||
Vec2 p1 = AddVec2(center1, vcp1);
|
|
||||||
P_DebugDrawPoint(p0, Color_Cyan);
|
|
||||||
P_DebugDrawLine(p0, AddVec2(p0, normal), Color_White);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Prune constraints
|
//- Prune constraints
|
||||||
|
|
||||||
@ -2230,7 +2231,7 @@ void P_StepFrame(P_Frame *frame)
|
|||||||
|
|
||||||
for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||||
{
|
{
|
||||||
// if (!is_predicting || ent == local_guy)
|
if (!is_predicting || ent == local_guy)
|
||||||
{
|
{
|
||||||
Xform xf = ent->xf;
|
Xform xf = ent->xf;
|
||||||
xf.og = AddVec2(xf.og, MulVec2(ent->solved_v, solver_dt));
|
xf.og = AddVec2(xf.og, MulVec2(ent->solved_v, solver_dt));
|
||||||
|
|||||||
@ -3238,7 +3238,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Predict
|
// Predict
|
||||||
P_Frame *predict_frame = &P_NilFrame;
|
P_Frame *predict_frame = predict_world->last_frame;
|
||||||
|
if (frame->predict_to != prev_frame->predict_to)
|
||||||
{
|
{
|
||||||
if (predict_world->tiles_hash != sim_world->tiles_hash)
|
if (predict_world->tiles_hash != sim_world->tiles_hash)
|
||||||
{
|
{
|
||||||
@ -3253,7 +3254,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
for (i64 predict_tick = first_predict_tick + 1; predict_tick <= last_predict_tick; ++predict_tick)
|
for (i64 predict_tick = first_predict_tick + 1; predict_tick <= last_predict_tick; ++predict_tick)
|
||||||
{
|
{
|
||||||
predict_frame = P_PushFrame(predict_world, predict_world->last_frame, predict_tick);
|
predict_frame = P_PushFrame(predict_world, predict_world->last_frame, predict_tick);
|
||||||
P_Ent *predict_player = P_EntFromKey(predict_frame, local_player->key);
|
P_Ent *predict_player = P_EntFromKey(predict_frame, V.player_key);
|
||||||
if (!P_IsEntNil(predict_player))
|
if (!P_IsEntNil(predict_player))
|
||||||
{
|
{
|
||||||
P_Control *predict_control = &local_controls[predict_tick % max_local_controls];
|
P_Control *predict_control = &local_controls[predict_tick % max_local_controls];
|
||||||
@ -3271,13 +3272,18 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
b32 old_debug_draw = P_tl.debug_draw_enabled;
|
b32 old_debug_draw = P_tl.debug_draw_enabled;
|
||||||
|
Vec4 old_debug_tint = P_tl.debug_tint;
|
||||||
|
{
|
||||||
P_tl.debug_draw_enabled = TweakBool("Debug draw intermediate prediction steps", 0);
|
P_tl.debug_draw_enabled = TweakBool("Debug draw intermediate prediction steps", 0);
|
||||||
|
P_tl.debug_tint = VEC4(0.8, 0, 0, 0.25);
|
||||||
P_StepFrame(predict_frame);
|
P_StepFrame(predict_frame);
|
||||||
|
}
|
||||||
P_tl.debug_draw_enabled = old_debug_draw;
|
P_tl.debug_draw_enabled = old_debug_draw;
|
||||||
|
P_tl.debug_tint = old_debug_tint;
|
||||||
}
|
}
|
||||||
|
|
||||||
predict_frame = predict_world->last_frame;
|
predict_frame = predict_world->last_frame;
|
||||||
P_DebugDrawFrame(predict_frame);
|
// P_DebugDrawFrame(predict_frame);
|
||||||
|
|
||||||
// TODO: Extract information that occurred between first & last prediction, like bullet hits etc?
|
// TODO: Extract information that occurred between first & last prediction, like bullet hits etc?
|
||||||
}
|
}
|
||||||
@ -3344,6 +3350,104 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// //////////////////////////////
|
||||||
|
// //- Update corrected world
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// P_Frame *correct_frame = &P_NilFrame;
|
||||||
|
// {
|
||||||
|
// if (correct_world->tiles_hash != predict_world->tiles_hash)
|
||||||
|
// {
|
||||||
|
// correct_world->tiles_hash = predict_world->tiles_hash;
|
||||||
|
// CopyStructs(correct_world->tiles, predict_world->tiles, P_TilesCount);
|
||||||
|
// tiles_dirty = 1;
|
||||||
|
// }
|
||||||
|
// correct_world->seed = predict_world->seed;
|
||||||
|
|
||||||
|
// P_ClearFrames(correct_world, I64Min, I64Max);
|
||||||
|
// correct_frame = P_PushFrame(correct_world, predict_world->last_frame, predict_world->last_frame->tick);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // P_Frame *correct_frame = correct_world->last_frame;
|
||||||
|
// // {
|
||||||
|
// // if (correct_world->tiles_hash != predict_world->tiles_hash)
|
||||||
|
// // {
|
||||||
|
// // correct_world->tiles_hash = predict_world->tiles_hash;
|
||||||
|
// // CopyStructs(correct_world->tiles, predict_world->tiles, P_TilesCount);
|
||||||
|
// // }
|
||||||
|
// // correct_world->seed = predict_world->seed;
|
||||||
|
|
||||||
|
// // if (correct_world->last_frame->tick != predict_frame->tick)
|
||||||
|
// // {
|
||||||
|
// // correct_frame = P_PushFrame(correct_world, correct_world->last_frame, predict_frame->tick);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // // P_ClearFrames(correct_world, I64Min, correct_world->last_frame->tick - 1);
|
||||||
|
// // // P_Frame *prev_correct_frame = correct_world->last_frame;
|
||||||
|
|
||||||
|
// // {
|
||||||
|
// // f32 correction_rate = 1;
|
||||||
|
// // // f32 correction_rate = 30 * frame->dt;
|
||||||
|
// // P_EntList spawn_ents = Zi;
|
||||||
|
// // for (P_Ent *predict_ent = P_FirstEnt(predict_frame); !P_IsEntNil(predict_ent); predict_ent = P_NextEnt(predict_ent))
|
||||||
|
// // {
|
||||||
|
// // P_Ent *correct_ent = P_EntFromKey(correct_frame, predict_ent->key);
|
||||||
|
// // if (P_IsEntNil(correct_ent))
|
||||||
|
// // {
|
||||||
|
// // correct_ent = P_PushTempEnt(frame->arena, &spawn_ents);
|
||||||
|
// // *correct_ent = *predict_ent;
|
||||||
|
// // }
|
||||||
|
// // else
|
||||||
|
// // {
|
||||||
|
// // // TODO: Unified blend logic between local world & correct world
|
||||||
|
// // correct_ent->xf = LerpXform(correct_ent->xf, predict_ent->xf, correction_rate);
|
||||||
|
// // correct_ent->solved_v = LerpVec2(correct_ent->solved_v, predict_ent->solved_v, correction_rate);
|
||||||
|
// // correct_ent->solved_w = LerpF32(correct_ent->solved_w, predict_ent->solved_w, correction_rate);
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // P_SpawnEntsFromList(correct_frame, spawn_ents);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // // Prune ents
|
||||||
|
// // {
|
||||||
|
// // i64 ents_to_prune_count = 0;
|
||||||
|
// // P_Ent **ents_to_prune = PushStructsNoZero(frame->arena, P_Ent *, correct_frame->ents_count);
|
||||||
|
// // for (P_Ent *ent = P_FirstEnt(correct_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||||
|
// // {
|
||||||
|
// // if (ent->exists <= 0 || P_IsEntNil(P_EntFromKey(predict_frame, ent->key)))
|
||||||
|
// // {
|
||||||
|
// // ents_to_prune[ents_to_prune_count] = ent;
|
||||||
|
// // ents_to_prune_count += 1;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // for (i64 prune_idx = 0; prune_idx < ents_to_prune_count; ++prune_idx)
|
||||||
|
// // {
|
||||||
|
// // P_Ent *ent = ents_to_prune[prune_idx];
|
||||||
|
// // P_EntBin *bin = &correct_frame->ent_bins[ent->key.v % correct_frame->ent_bins_count];
|
||||||
|
// // DllQueueRemoveNP(bin->first, bin->last, ent, next_in_bin, prev_in_bin);
|
||||||
|
// // DllQueueRemoveNPZ(&P_NilEnt, correct_frame->first_ent, correct_frame->last_ent, ent, next, prev);
|
||||||
|
// // correct_frame->ents_count -= 1;
|
||||||
|
// // SllStackPush(correct_world->first_free_ent, ent);
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
|
||||||
|
// // // P_Frame *prev_correct_frame = P_PushFrame(correct_world, predict_world->last_frame, predict_world->last_frame->tick);
|
||||||
|
|
||||||
|
// // P_DebugDrawFrame(correct_frame);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Update local world
|
//- Update local world
|
||||||
|
|
||||||
@ -3360,6 +3464,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
P_ClearFrames(local_world, I64Min, I64Max);
|
P_ClearFrames(local_world, I64Min, I64Max);
|
||||||
local_frame = P_PushFrame(local_world, predict_world->last_frame, predict_world->last_frame->tick);
|
local_frame = P_PushFrame(local_world, predict_world->last_frame, predict_world->last_frame->tick);
|
||||||
|
|
||||||
|
P_DebugDrawFrame(local_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user