diff --git a/src/pp/pp.c b/src/pp/pp.c index 385304e0..420f1300 100644 --- a/src/pp/pp.c +++ b/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) { diff --git a/src/pp/pp.h b/src/pp/pp.h index 8ba890fd..5035d2ed 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -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;