working wall collisions
This commit is contained in:
parent
bf56bd7155
commit
09490d8c47
811
src/pp/pp.c
811
src/pp/pp.c
@ -1364,25 +1364,59 @@ P_Space P_SpaceFromFrame(Arena *arena, P_Frame *frame)
|
||||
}
|
||||
}
|
||||
|
||||
//- Debug draw walls
|
||||
//- Push walls to space
|
||||
for (GenWall *wall = first_wall; wall; wall = wall->next)
|
||||
{
|
||||
i64 wall_idx = 0;
|
||||
for (GenWall *wall = first_wall; wall; wall = wall->next)
|
||||
Vec2 p0 = VEC2(wall->start.x / P_TilesPerMeter - P_WorldPitch / 2, wall->start.y / P_TilesPerMeter - P_WorldPitch / 2);
|
||||
Vec2 p1 = VEC2(wall->end.x / P_TilesPerMeter - P_WorldPitch / 2, wall->end.y / P_TilesPerMeter - P_WorldPitch / 2);
|
||||
// P_Shape shape = P_ShapeFromDesc(.count = 2, .points = { p0, p1 });
|
||||
P_Shape shape = P_ShapeFromDesc(.count = 2, .points = { p0, p1 }, .radius = 0.01 );
|
||||
Rng2 aabb = P_BoundingBoxFromShape(shape);
|
||||
aabb = AddRng2Vec2(aabb, VEC2(P_WorldPitch / 2.0, P_WorldPitch / 2.0));
|
||||
aabb.p0 = FloorVec2(aabb.p0);
|
||||
aabb.p1 = CeilVec2(aabb.p1);
|
||||
aabb.p1.x = MaxF32(aabb.p1.x, aabb.p0.x + 1);
|
||||
aabb.p1.y = MaxF32(aabb.p1.y, aabb.p0.y + 1);
|
||||
aabb = IntersectRng2(aabb, space_aabb);
|
||||
u64 id = P_WallShapeIDBasis ^ MixU64s(
|
||||
((u64)wall->start.x << 0) | ((u64)wall->start.y << 32),
|
||||
((u64)wall->end.x << 0) | ((u64)wall->end.y << 32)
|
||||
);
|
||||
for (i32 y = aabb.p0.y; y < aabb.p1.y; ++y)
|
||||
{
|
||||
Vec2 p0 = VEC2(wall->start.x / P_TilesPerMeter - P_WorldPitch / 2, wall->start.y / P_TilesPerMeter - P_WorldPitch / 2);
|
||||
Vec2 p1 = VEC2(wall->end.x / P_TilesPerMeter - P_WorldPitch / 2, wall->end.y / P_TilesPerMeter - P_WorldPitch / 2);
|
||||
u64 color_seed0 = MixU64(wall_idx + 1);
|
||||
u64 color_seed1 = MixU64(color_seed0);
|
||||
u64 color_seed2 = MixU64(color_seed1);
|
||||
Vec4 color = Color_White;
|
||||
color.r = Norm24(color_seed0) * 0.75 + 0.25;
|
||||
color.g = Norm24(color_seed1) * 0.75 + 0.25;
|
||||
color.b = Norm24(color_seed2) * 0.75 + 0.25;
|
||||
P_DebugDrawLine(p0, p1, color);
|
||||
++wall_idx;
|
||||
for (i32 x = aabb.p0.x; x < aabb.p1.x; ++x)
|
||||
{
|
||||
i64 cell_idx = y * P_WorldPitch + x;
|
||||
P_SpaceCell *cell = &space.cells[cell_idx];
|
||||
P_SpaceEntry *entry = PushStruct(arena, P_SpaceEntry);
|
||||
SllStackPush(cell->first, entry);
|
||||
entry->shape = shape;
|
||||
entry->shape_id = id;
|
||||
}
|
||||
}
|
||||
++wall_idx;
|
||||
|
||||
// P_DebugDrawShape(shape, Color_Cyan);
|
||||
}
|
||||
|
||||
//- Debug draw walls
|
||||
// {
|
||||
// i64 wall_idx = 0;
|
||||
// for (GenWall *wall = first_wall; wall; wall = wall->next)
|
||||
// {
|
||||
// Vec2 p0 = VEC2(wall->start.x / P_TilesPerMeter - P_WorldPitch / 2, wall->start.y / P_TilesPerMeter - P_WorldPitch / 2);
|
||||
// Vec2 p1 = VEC2(wall->end.x / P_TilesPerMeter - P_WorldPitch / 2, wall->end.y / P_TilesPerMeter - P_WorldPitch / 2);
|
||||
// u64 color_seed0 = MixU64(wall_idx + 1);
|
||||
// u64 color_seed1 = MixU64(color_seed0);
|
||||
// u64 color_seed2 = MixU64(color_seed1);
|
||||
// Vec4 color = Color_White;
|
||||
// color.r = Norm24(color_seed0) * 0.75 + 0.25;
|
||||
// color.g = Norm24(color_seed1) * 0.75 + 0.25;
|
||||
// color.b = Norm24(color_seed2) * 0.75 + 0.25;
|
||||
// P_DebugDrawLine(p0, p1, color);
|
||||
// ++wall_idx;
|
||||
// }
|
||||
// ++wall_idx;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -2047,175 +2081,172 @@ void P_StepFrame(P_Frame *frame)
|
||||
|
||||
// TODO: Not like this
|
||||
|
||||
if (!is_predicting)
|
||||
for (P_Ent *ent0 = P_FirstEnt(frame); !P_IsEntNil(ent0); ent0 = P_NextEnt(ent0))
|
||||
{
|
||||
for (P_Ent *ent0 = P_FirstEnt(frame); !P_IsEntNil(ent0); ent0 = P_NextEnt(ent0))
|
||||
if (ent0->is_guy)
|
||||
{
|
||||
if (ent0->is_guy)
|
||||
P_Shape shape0 = P_WorldShapeFromEnt(ent0);
|
||||
Rng2 aabb0 = P_BoundingBoxFromShape(shape0);
|
||||
|
||||
Rng2 query_rect = Zi;
|
||||
query_rect.p0 = FloorVec2(aabb0.p0);
|
||||
query_rect.p1 = CeilVec2(aabb0.p1);
|
||||
query_rect.p1.x = MaxF32(query_rect.p1.x, query_rect.p0.x + 1);
|
||||
query_rect.p1.y = MaxF32(query_rect.p1.y, query_rect.p0.y + 1);
|
||||
|
||||
for (i32 query_y = query_rect.p0.y; query_y < query_rect.p1.y; ++query_y)
|
||||
{
|
||||
P_Shape shape0 = P_WorldShapeFromEnt(ent0);
|
||||
Rng2 aabb0 = P_BoundingBoxFromShape(shape0);
|
||||
|
||||
Rng2 query_rect = Zi;
|
||||
query_rect.p0 = FloorVec2(aabb0.p0);
|
||||
query_rect.p1 = CeilVec2(aabb0.p1);
|
||||
query_rect.p1.x = MaxF32(query_rect.p1.x, query_rect.p0.x + 1);
|
||||
query_rect.p1.y = MaxF32(query_rect.p1.y, query_rect.p0.y + 1);
|
||||
|
||||
for (i32 query_y = query_rect.p0.y; query_y < query_rect.p1.y; ++query_y)
|
||||
for (i32 query_x = query_rect.p0.x; query_x < query_rect.p1.x; ++query_x)
|
||||
{
|
||||
for (i32 query_x = query_rect.p0.x; query_x < query_rect.p1.x; ++query_x)
|
||||
P_SpaceCell cell = P_SpaceCellFromPos(&space, VEC2(query_x, query_y));
|
||||
for (P_SpaceEntry *space_entry = cell.first; space_entry; space_entry = space_entry->next)
|
||||
{
|
||||
P_SpaceCell cell = P_SpaceCellFromPos(&space, VEC2(query_x, query_y));
|
||||
for (P_SpaceEntry *space_entry = cell.first; space_entry; space_entry = space_entry->next)
|
||||
Rng2 aabb1 = P_BoundingBoxFromShape(space_entry->shape);
|
||||
P_Ent *ent1 = P_EntFromKey(frame, (P_EntKey) { .v = space_entry->shape_id });
|
||||
if (!P_MatchEntKey(ent0->key, ent1->key) && IsIntersectingRng2(aabb0, aabb1))
|
||||
{
|
||||
Rng2 aabb1 = P_BoundingBoxFromShape(space_entry->shape);
|
||||
P_Ent *ent1 = P_EntFromKey(frame, (P_EntKey) { .v = space_entry->shape_id });
|
||||
if (!P_MatchEntKey(ent0->key, ent1->key) && IsIntersectingRng2(aabb0, aabb1))
|
||||
P_Shape shape1 = space_entry->shape;
|
||||
b32 is_static_collision = P_IsEntNil(ent1);
|
||||
b32 is_guy_on_guy_collision = ent0->is_guy && ent1->is_guy;
|
||||
|
||||
if (is_static_collision || is_guy_on_guy_collision)
|
||||
{
|
||||
P_Shape shape1 = space_entry->shape;
|
||||
b32 is_static_collision = P_IsEntNil(ent1);
|
||||
b32 is_guy_on_guy_collision = ent0->is_guy && ent1->is_guy;
|
||||
|
||||
if (is_static_collision || is_guy_on_guy_collision)
|
||||
P_ConstraintKey constraint_key = Zi;
|
||||
{
|
||||
P_ConstraintKey constraint_key = Zi;
|
||||
// Deterministic shape ID order for consistent constraint lookup
|
||||
u64 shape_id0 = ent0->key.v;
|
||||
u64 shape_id1 = space_entry->shape_id;
|
||||
if (shape_id0 > shape_id1)
|
||||
{
|
||||
// Deterministic shape ID order for consistent constraint lookup
|
||||
u64 shape_id0 = ent0->key.v;
|
||||
u64 shape_id1 = space_entry->shape_id;
|
||||
if (shape_id0 > shape_id1)
|
||||
{
|
||||
u64 tmp = shape_id0;
|
||||
shape_id0 = shape_id1;
|
||||
shape_id1 = tmp;
|
||||
}
|
||||
constraint_key = P_ConstraintKeyFromU64s(shape_id0, shape_id1);
|
||||
u64 tmp = shape_id0;
|
||||
shape_id0 = shape_id1;
|
||||
shape_id1 = tmp;
|
||||
}
|
||||
P_Constraint *constraint = P_ConstraintFromKey(frame, constraint_key);
|
||||
if (constraint->last_touched_tick < frame->tick)
|
||||
constraint_key = P_ConstraintKeyFromU64s(shape_id0, shape_id1);
|
||||
}
|
||||
P_Constraint *constraint = P_ConstraintFromKey(frame, constraint_key);
|
||||
if (constraint->last_touched_tick < frame->tick)
|
||||
{
|
||||
P_CollisionResult collision = P_CollisionResultFromShapes(shape0, shape1);
|
||||
if (collision.collision_points_count > 0)
|
||||
{
|
||||
P_CollisionResult collision = P_CollisionResultFromShapes(shape0, shape1);
|
||||
if (collision.collision_points_count > 0)
|
||||
if (P_IsConstraintNil(constraint))
|
||||
{
|
||||
if (P_IsConstraintNil(constraint))
|
||||
{
|
||||
constraint = P_PushConstraint(frame, constraint_key);
|
||||
}
|
||||
constraint->last_touched_tick = frame->tick;
|
||||
constraint->normal = collision.collision_normal;
|
||||
// constraint->friction = SqrtF32(ent0->friction * ent1->friction);
|
||||
constraint->friction = 0;
|
||||
constraint = P_PushConstraint(frame, constraint_key);
|
||||
}
|
||||
constraint->last_touched_tick = frame->tick;
|
||||
constraint->normal = collision.collision_normal;
|
||||
// constraint->friction = SqrtF32(ent0->friction * ent1->friction);
|
||||
constraint->friction = 0;
|
||||
|
||||
if (is_static_collision)
|
||||
{
|
||||
constraint->flags |= P_ConstraintFlag_Solid;
|
||||
}
|
||||
else if (is_guy_on_guy_collision)
|
||||
{
|
||||
constraint->flags |= P_ConstraintFlag_Gentle;
|
||||
// constraint->flags |= P_ConstraintFlag_NoWarmStart;
|
||||
}
|
||||
if (is_static_collision)
|
||||
{
|
||||
constraint->flags |= P_ConstraintFlag_Solid;
|
||||
}
|
||||
else if (is_guy_on_guy_collision)
|
||||
{
|
||||
constraint->flags |= P_ConstraintFlag_Gentle;
|
||||
// constraint->flags |= P_ConstraintFlag_NoWarmStart;
|
||||
}
|
||||
|
||||
// TODO: Real masses
|
||||
f32 inv_m0 = 10;
|
||||
f32 inv_m1 = 10;
|
||||
f32 inv_i0 = 0;
|
||||
f32 inv_i1 = 0;
|
||||
// TODO: Real masses
|
||||
f32 inv_m0 = 10;
|
||||
f32 inv_m1 = 10;
|
||||
f32 inv_i0 = 0;
|
||||
f32 inv_i1 = 0;
|
||||
|
||||
// Treat statics / non-predicted ents as infinite-mass
|
||||
if (!ent0->is_guy || (is_predicting && !P_MatchEntKey(ent0->key, local_guy->key)))
|
||||
// Treat statics / non-predicted ents as infinite-mass
|
||||
if (!ent0->is_guy || (is_predicting && !P_MatchEntKey(ent0->key, local_guy->key)))
|
||||
{
|
||||
inv_m0 = 0;
|
||||
inv_i0 = 0;
|
||||
}
|
||||
if (!ent1->is_guy || (is_predicting && !P_MatchEntKey(ent1->key, local_guy->key)))
|
||||
{
|
||||
inv_m1 = 0;
|
||||
inv_i1 = 0;
|
||||
}
|
||||
|
||||
constraint->ent0 = ent0->key;
|
||||
constraint->ent1 = ent1->key;
|
||||
constraint->static_center0 = shape0.center_of_mass;
|
||||
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)
|
||||
{
|
||||
inv_m0 = 0;
|
||||
inv_i0 = 0;
|
||||
}
|
||||
if (!ent1->is_guy || (is_predicting && !P_MatchEntKey(ent1->key, local_guy->key)))
|
||||
{
|
||||
inv_m1 = 0;
|
||||
inv_i1 = 0;
|
||||
}
|
||||
|
||||
constraint->ent0 = ent0->key;
|
||||
constraint->ent1 = ent1->key;
|
||||
constraint->static_center0 = shape0.center_of_mass;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
match = 1;
|
||||
contact = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match)
|
||||
if (!contact)
|
||||
{
|
||||
// Delete contact by replacing with last in array
|
||||
*contact = constraint->points[constraint->points_count - 1];
|
||||
constraint->points_count -= 1;
|
||||
contact_point_idx -= 1;
|
||||
contact = &constraint->points[constraint->points_count];
|
||||
constraint->points_count += 1;
|
||||
ZeroStruct(contact);
|
||||
}
|
||||
}
|
||||
contact->id = id;
|
||||
|
||||
// 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];
|
||||
Vec2 vcp0 = SubVec2(collision_point.p, shape0.center_of_mass);
|
||||
Vec2 vcp1 = SubVec2(collision_point.p, shape1.center_of_mass);
|
||||
|
||||
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;
|
||||
contact->vcp0 = vcp0;
|
||||
contact->vcp1 = vcp1;
|
||||
contact->starting_separation = collision_point.separation;
|
||||
|
||||
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);
|
||||
// }
|
||||
}
|
||||
// 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);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2223,469 +2254,10 @@ void P_StepFrame(P_Frame *frame)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 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)
|
||||
// {
|
||||
// P_ConstraintKey constraint_key = P_ConstraintKeyFromU64s(ent0->key.v, ent1->key.v);
|
||||
// P_Constraint *constraint = P_ConstraintFromKey(frame, constraint_key);
|
||||
// if (constraint->last_touched_tick < frame->tick)
|
||||
// {
|
||||
// if (P_IsConstraintNil(constraint))
|
||||
// {
|
||||
// constraint = P_PushConstraint(frame, constraint_key);
|
||||
// }
|
||||
|
||||
// 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 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);
|
||||
// Rng2 aabb = P_BoundingBoxFromShape(shape0);
|
||||
|
||||
// P_Query query = P_QueryFromRect(scratch.arena, aabb, P_QueryFlag_IncludeWalls);
|
||||
|
||||
// for (P_QueryItem *item = query.first; item; item = item->next)
|
||||
// {
|
||||
// P_Shape shape1 = item->shape;
|
||||
|
||||
// // TODO: World query
|
||||
// P_CollisionResult collision = P_CollisionResultFromShapes(shape0, shape1);
|
||||
// if (collision.collision_points_count > 0)
|
||||
// {
|
||||
// P_Constraint *constraint = P_ConstraintFromKey(world_frame, constraint_key);
|
||||
// if (P_IsConstraintNil(constraint))
|
||||
// {
|
||||
// constraint = P_PushConstraint(world_frame, constraint_key);
|
||||
// }
|
||||
|
||||
// if (constraint->last_touched_tick < frame->tick)
|
||||
// {
|
||||
// constraint->last_touched_Tick = frame->tick;
|
||||
// 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);
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// //////////////////////////////
|
||||
// //- 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_MatchEntKey(constraint->ent0, ent0->key) && P_MatchEntKey(constraint->ent1, ent1->key))
|
||||
// {
|
||||
// match = 1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (!match)
|
||||
// {
|
||||
// if (frame->constraints_count < frame->constraints_cap)
|
||||
// {
|
||||
// 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
|
||||
|
||||
@ -2697,12 +2269,7 @@ void P_StepFrame(P_Frame *frame)
|
||||
b32 prune = 1;
|
||||
if (constraint->last_touched_tick == frame->tick)
|
||||
{
|
||||
P_Ent *ent0 = P_EntFromKey(frame, constraint->ent0);
|
||||
P_Ent *ent1 = P_EntFromKey(frame, constraint->ent1);
|
||||
if (!P_IsEntNil(ent0) && !P_IsEntNil(ent1))
|
||||
{
|
||||
prune = 0;
|
||||
}
|
||||
prune = 0;
|
||||
}
|
||||
if (prune)
|
||||
{
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
#define P_NilEntKey ((P_EntKey) { 0 })
|
||||
#define P_NilConstraintKey ((P_EntKey) { 0 })
|
||||
|
||||
#define P_WallShapeIDBasis 0x40d501b4cf6d4f0cull
|
||||
|
||||
Struct(P_EntKey)
|
||||
{
|
||||
u64 v;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user