Updates 3
This commit is contained in:
parent
d53c1a3ae6
commit
bce37a3b7e
@ -20,7 +20,6 @@ import "core:hash"
|
||||
import "core:log"
|
||||
import "core:math"
|
||||
import "core:math/linalg"
|
||||
import "core:slice"
|
||||
import "game:physics"
|
||||
import "game:physics/bvh"
|
||||
import "game:render"
|
||||
@ -484,10 +483,12 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
||||
if true {
|
||||
for x in 0 ..< 10 {
|
||||
for y in 0 ..< 10 {
|
||||
box_name := name.from_string(fmt.tprintf("box[{},{}]", x, y))
|
||||
physics.immediate_body(
|
||||
&world.physics_scene,
|
||||
hash.fnv32a(slice.to_bytes([]int{(x | y << 8)})),
|
||||
u32(box_name),
|
||||
physics.Body_Config {
|
||||
name = box_name,
|
||||
initial_pos = {-5, 0.5 + f32(y) * 1.1, f32(x) * 3 + 10},
|
||||
initial_rot = linalg.QUATERNIONF32_IDENTITY,
|
||||
shapes = {
|
||||
@ -696,15 +697,20 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
||||
{
|
||||
level_model := assets.get_model(&g_mem.assetman, "assets/testblend.glb")
|
||||
|
||||
for i in 0 ..< level_model.meshCount {
|
||||
for i in 0 ..< min(level_model.meshCount, 32) {
|
||||
mesh := &level_model.meshes[i]
|
||||
|
||||
if mesh.triangleCount > 0 {
|
||||
assert(mesh.vertexCount <= i32(max(u16)))
|
||||
m := level_model.transform
|
||||
pos := physics.Vec3{m[3][0], m[3][1], m[3][2]}
|
||||
rotation := linalg.quaternion_from_matrix4_f32(auto_cast level_model.transform)
|
||||
physics.immediate_level_geom(
|
||||
&world.physics_scene,
|
||||
hash.fnv32a(transmute([]byte)(fmt.tprintf("level mesh {}", i))),
|
||||
{
|
||||
rotation = linalg.QUATERNIONF32_IDENTITY,
|
||||
position = pos,
|
||||
rotation = rotation,
|
||||
vertices = (cast([^]rl.Vector3)mesh.vertices)[:mesh.vertexCount],
|
||||
indices = mesh.indices[:mesh.triangleCount * 3],
|
||||
},
|
||||
@ -1051,7 +1057,7 @@ draw_world :: proc(world: ^World) {
|
||||
|
||||
sim_state := physics.get_sim_state(&world.physics_scene)
|
||||
|
||||
level_model := assets.get_model(&g_mem.assetman, "assets/testblend.glb")
|
||||
// level_model := assets.get_model(&g_mem.assetman, "assets/testblend.glb")
|
||||
|
||||
car_body := physics.get_body(sim_state, world.car_handle)
|
||||
car_model := assets.get_model(&g_mem.assetman, "assets/ice_cream_truck.glb")
|
||||
@ -1127,7 +1133,7 @@ draw_world :: proc(world: ^World) {
|
||||
// .VEC3,
|
||||
// )
|
||||
|
||||
render.draw_model(level_model, {}, 1)
|
||||
// render.draw_model(level_model, {}, 1)
|
||||
|
||||
render.draw_model(car_model, {}, car_matrix)
|
||||
|
||||
|
@ -47,6 +47,12 @@ Mesh_BVH :: struct {
|
||||
mesh: Mesh,
|
||||
}
|
||||
|
||||
destroy_mesh_bvh :: proc(bvh: ^Mesh_BVH) {
|
||||
destroy_bvh(&bvh.bvh)
|
||||
delete(bvh.mesh.vertices)
|
||||
delete(bvh.mesh.indices)
|
||||
}
|
||||
|
||||
Node :: struct {
|
||||
aabb: AABB,
|
||||
// Index of the left child, right child is left_child + 1
|
||||
|
@ -14,6 +14,12 @@ import "libs:tracy"
|
||||
_ :: fmt
|
||||
_ :: log
|
||||
|
||||
@(private = "file")
|
||||
Traversal :: struct {
|
||||
node_idx: i32,
|
||||
should_draw: bool,
|
||||
}
|
||||
|
||||
// Assuming rl.BeginMode3D was called before this
|
||||
debug_draw_bvh_bounds_mesh :: proc(bvh: ^BVH, mesh: Mesh, pos: rl.Vector3, node_index: int) {
|
||||
old_width := rlgl.GetLineWidth()
|
||||
@ -23,10 +29,6 @@ debug_draw_bvh_bounds_mesh :: proc(bvh: ^BVH, mesh: Mesh, pos: rl.Vector3, node_
|
||||
temp := runtime.default_temp_allocator_temp_begin()
|
||||
defer runtime.default_temp_allocator_temp_end(temp)
|
||||
|
||||
Traversal :: struct {
|
||||
node_idx: i32,
|
||||
should_draw: bool,
|
||||
}
|
||||
nodes_to_process: queue.Queue(Traversal)
|
||||
queue.init(&nodes_to_process, queue.DEFAULT_CAPACITY, context.temp_allocator)
|
||||
|
||||
@ -100,10 +102,6 @@ debug_draw_bvh_bounds :: proc(bvh: ^BVH, primitive_bounds: []AABB, node_index: i
|
||||
temp := runtime.default_temp_allocator_temp_begin()
|
||||
defer runtime.default_temp_allocator_temp_end(temp)
|
||||
|
||||
Traversal :: struct {
|
||||
node_idx: i32,
|
||||
should_draw: bool,
|
||||
}
|
||||
nodes_to_process: queue.Queue(Traversal)
|
||||
queue.init(&nodes_to_process, queue.DEFAULT_CAPACITY, context.temp_allocator)
|
||||
|
||||
|
@ -54,6 +54,16 @@ draw_debug_scene :: proc(scene: ^Scene) {
|
||||
|
||||
sim_state := get_sim_state(scene)
|
||||
|
||||
// Static_TLAS
|
||||
if true && sim_state.static_tlas.built {
|
||||
bvh.debug_draw_bvh_bounds_mesh(
|
||||
&sim_state.static_tlas.bvh_tree.bvh,
|
||||
sim_state.static_tlas.bvh_tree.mesh,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
// Dynamic TLAS
|
||||
if true && sim_state.dynamic_tlas.built {
|
||||
bvh.debug_draw_bvh_bounds(
|
||||
@ -99,20 +109,20 @@ draw_debug_scene :: proc(scene: ^Scene) {
|
||||
}
|
||||
}
|
||||
|
||||
if true {
|
||||
for &level_geom, geom_idx in sim_state.level_geoms {
|
||||
if level_geom.alive {
|
||||
vertices, indices := get_level_geom_data(sim_state, level_geom.geometry)
|
||||
// if true {
|
||||
// for &level_geom, geom_idx in sim_state.level_geoms {
|
||||
// if level_geom.alive {
|
||||
// vertices, indices := get_level_geom_data(sim_state, level_geom.geometry)
|
||||
|
||||
for i in 0 ..< len(indices) / 3 {
|
||||
i1, i2, i3 := indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2]
|
||||
v1, v2, v3 := vertices[i1], vertices[i2], vertices[i3]
|
||||
// for i in 0 ..< len(indices) / 3 {
|
||||
// i1, i2, i3 := indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2]
|
||||
// v1, v2, v3 := vertices[i1], vertices[i2], vertices[i3]
|
||||
|
||||
rl.DrawTriangle3D(v1, v2, v3, debug.int_to_color(i32(geom_idx + 1)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// rl.DrawTriangle3D(v1, v2, v3, debug.int_to_color(i32(geom_idx + 1)))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
for _, i in sim_state.suspension_constraints {
|
||||
wheel := &sim_state.suspension_constraints_slice[i]
|
||||
|
@ -5,7 +5,6 @@ import "core:log"
|
||||
import "core:math"
|
||||
import lg "core:math/linalg"
|
||||
import "game:halfedge"
|
||||
import "game:name"
|
||||
import "libs:tracy"
|
||||
|
||||
_ :: log
|
||||
@ -264,9 +263,6 @@ body_get_convex_shape_by_linear_index_world :: proc(
|
||||
mesh: collision.Convex,
|
||||
) {
|
||||
tracy.Zone()
|
||||
if shape_linear_idx == 1 {
|
||||
log.debugf("linear idx: %v, body %v", shape_linear_idx, name.to_string(body.name))
|
||||
}
|
||||
shape_idx := get_shape_by_index(sim_state, body.shape, shape_linear_idx)
|
||||
return body_get_convex_shape_world(sim_state, body, sim_state.shapes[shape_idx], allocator)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package physics
|
||||
|
||||
import "bvh"
|
||||
import "collision"
|
||||
import lg "core:math/linalg"
|
||||
import "game:container/spanpool"
|
||||
@ -23,6 +24,7 @@ Contact_Pair_Bodies :: struct {
|
||||
}
|
||||
Contact_Pair_Body_Level :: struct {
|
||||
a: Body_Handle,
|
||||
b: Level_Geom_Handle,
|
||||
shape_a: i32,
|
||||
tri_idx: i32,
|
||||
}
|
||||
@ -47,11 +49,12 @@ make_contact_pair_bodies :: proc(
|
||||
}
|
||||
|
||||
make_contact_pair_body_level :: proc(
|
||||
body: i32,
|
||||
body: Body_Handle,
|
||||
level_geom_handle: Level_Geom_Handle,
|
||||
shape_a: i32,
|
||||
tri_idx: i32,
|
||||
) -> Contact_Pair_Body_Level {
|
||||
return {index_to_body_handle(int(body)), shape_a, tri_idx}
|
||||
return {body, level_geom_handle, shape_a, tri_idx}
|
||||
}
|
||||
|
||||
Contact_Container :: struct {
|
||||
@ -107,6 +110,10 @@ Sim_State :: struct {
|
||||
geometry_vertices_pool: spanpool.Span_Pool(Vec3),
|
||||
geometry_indices_pool: spanpool.Span_Pool(u16),
|
||||
|
||||
// BLAS for level geom
|
||||
blas_nodes_pool: spanpool.Span_Pool(bvh.Node),
|
||||
blas_primitives_pool: spanpool.Span_Pool(u16),
|
||||
|
||||
// Temp stuff, kept for one frame, allocated from temp_allocator
|
||||
static_tlas: Static_TLAS,
|
||||
dynamic_tlas: Dynamic_TLAS,
|
||||
@ -154,6 +161,8 @@ copy_sim_state :: proc(dst: ^Sim_State, src: ^Sim_State) {
|
||||
spanpool.copy(&dst.gear_ratios_pool, src.gear_ratios_pool)
|
||||
spanpool.copy(&dst.geometry_vertices_pool, src.geometry_vertices_pool)
|
||||
spanpool.copy(&dst.geometry_indices_pool, src.geometry_indices_pool)
|
||||
spanpool.copy(&dst.blas_nodes_pool, src.blas_nodes_pool)
|
||||
spanpool.copy(&dst.blas_primitives_pool, src.blas_primitives_pool)
|
||||
}
|
||||
|
||||
copy_physics_scene :: proc(dst, src: ^Scene) {
|
||||
@ -377,9 +386,16 @@ Geometry_Handle :: struct {
|
||||
indices: spanpool.Handle,
|
||||
}
|
||||
|
||||
BLAS_Handle :: struct {
|
||||
nodes: spanpool.Handle,
|
||||
primitives: spanpool.Handle,
|
||||
}
|
||||
|
||||
Level_Geom :: struct {
|
||||
alive: bool,
|
||||
aabb: AABB,
|
||||
geometry: Geometry_Handle,
|
||||
blas: BLAS_Handle,
|
||||
x: Vec3,
|
||||
q: Quat,
|
||||
next_plus_one: i32,
|
||||
@ -416,19 +432,19 @@ is_handle_valid :: proc {
|
||||
is_level_geom_handle_valid,
|
||||
}
|
||||
|
||||
index_to_body_handle :: proc(idx: int) -> Body_Handle {
|
||||
index_to_body_handle :: #force_inline proc(idx: int) -> Body_Handle {
|
||||
return Body_Handle(idx + 1)
|
||||
}
|
||||
|
||||
index_to_level_geom :: proc(idx: int) -> Level_Geom_Handle {
|
||||
index_to_level_geom :: #force_inline proc(idx: int) -> Level_Geom_Handle {
|
||||
return Level_Geom_Handle(idx + 1)
|
||||
}
|
||||
|
||||
body_handle_to_index :: proc(handle: Body_Handle) -> int {
|
||||
body_handle_to_index :: #force_inline proc(handle: Body_Handle) -> int {
|
||||
return int(handle) - 1
|
||||
}
|
||||
|
||||
level_geom_handle_to_index :: proc(handle: Level_Geom_Handle) -> int {
|
||||
level_geom_handle_to_index :: #force_inline proc(handle: Level_Geom_Handle) -> int {
|
||||
return int(handle) - 1
|
||||
}
|
||||
|
||||
@ -913,6 +929,13 @@ get_level_geom_data :: proc(
|
||||
return
|
||||
}
|
||||
|
||||
get_level_geom_blas :: proc(sim_state: ^Sim_State, handle: BLAS_Handle) -> (bvh: bvh.BVH) {
|
||||
bvh.nodes = spanpool.resolve_slice(&sim_state.blas_nodes_pool, handle.nodes)
|
||||
bvh.primitives = spanpool.resolve_slice(&sim_state.blas_primitives_pool, handle.primitives)
|
||||
bvh.nodes_used = i32(len(bvh.nodes))
|
||||
return
|
||||
}
|
||||
|
||||
update_level_geom_from_config :: proc(
|
||||
sim_state: ^Sim_State,
|
||||
level_geom: Level_Geom_Ptr,
|
||||
@ -921,6 +944,40 @@ update_level_geom_from_config :: proc(
|
||||
level_geom.x = config.position
|
||||
level_geom.q = config.rotation
|
||||
|
||||
// TODO: figure out if asset changed and rebuild only then
|
||||
}
|
||||
|
||||
add_level_geom :: proc(sim_state: ^Sim_State, config: Level_Geom_Config) -> Level_Geom_Handle {
|
||||
assert(len(config.vertices) > 0)
|
||||
assert(len(config.vertices) <= int(max(u16)))
|
||||
|
||||
sim_state.num_level_geoms += 1
|
||||
|
||||
level_geom: Level_Geom
|
||||
level_geom.alive = true
|
||||
update_level_geom_from_config(sim_state, &level_geom, config)
|
||||
|
||||
blas :=
|
||||
bvh.build_bvh_from_mesh(bvh.Mesh{vertices = config.vertices, indices = config.indices}, context.temp_allocator).bvh
|
||||
|
||||
level_geom.blas.nodes = spanpool.allocate_elems(
|
||||
&sim_state.blas_nodes_pool,
|
||||
..blas.nodes[:blas.nodes_used],
|
||||
)
|
||||
level_geom.blas.primitives = spanpool.allocate_elems(
|
||||
&sim_state.blas_primitives_pool,
|
||||
..blas.primitives,
|
||||
)
|
||||
|
||||
aabb_min, aabb_max: Vec3 = max(f32), min(f32)
|
||||
for v in config.vertices {
|
||||
aabb_min = lg.min(aabb_min, v)
|
||||
aabb_max = lg.max(aabb_max, v)
|
||||
}
|
||||
|
||||
level_geom.aabb.center = (aabb_max + aabb_min) * 0.5
|
||||
level_geom.aabb.extent = (aabb_max - aabb_min) * 0.5
|
||||
|
||||
if spanpool.is_handle_valid(&sim_state.geometry_vertices_pool, level_geom.geometry.vertices) {
|
||||
spanpool.free(&sim_state.geometry_vertices_pool, level_geom.geometry.vertices)
|
||||
spanpool.free(&sim_state.geometry_indices_pool, level_geom.geometry.indices)
|
||||
@ -934,14 +991,6 @@ update_level_geom_from_config :: proc(
|
||||
&sim_state.geometry_indices_pool,
|
||||
..config.indices,
|
||||
)
|
||||
}
|
||||
|
||||
add_level_geom :: proc(sim_state: ^Sim_State, config: Level_Geom_Config) -> Level_Geom_Handle {
|
||||
sim_state.num_level_geoms += 1
|
||||
|
||||
level_geom: Level_Geom
|
||||
level_geom.alive = true
|
||||
update_level_geom_from_config(sim_state, &level_geom, config)
|
||||
|
||||
if sim_state.first_free_level_geom_plus_one > 0 {
|
||||
index := sim_state.first_free_level_geom_plus_one
|
||||
@ -962,6 +1011,9 @@ remove_level_geom :: proc(sim_state: ^Sim_State, handle: Level_Geom_Handle) {
|
||||
|
||||
spanpool.free(&sim_state.geometry_vertices_pool, level_geom.geometry.vertices)
|
||||
spanpool.free(&sim_state.geometry_indices_pool, level_geom.geometry.indices)
|
||||
|
||||
spanpool.free(&sim_state.blas_nodes_pool, level_geom.blas.nodes)
|
||||
spanpool.free(&sim_state.blas_primitives_pool, level_geom.blas.primitives)
|
||||
}
|
||||
|
||||
_get_first_free_body :: proc(sim_state: ^Sim_State) -> i32 {
|
||||
@ -983,6 +1035,7 @@ destry_sim_state :: proc(sim_state: ^Sim_State) {
|
||||
spanpool.destroy_spanpool(&sim_state.geometry_vertices_pool)
|
||||
spanpool.destroy_spanpool(&sim_state.geometry_indices_pool)
|
||||
|
||||
static_tlas_destroy(&sim_state.static_tlas)
|
||||
dynamic_tlas_destroy(&sim_state.dynamic_tlas)
|
||||
}
|
||||
|
||||
|
@ -71,8 +71,9 @@ Step_Mode :: enum {
|
||||
}
|
||||
|
||||
Static_TLAS :: struct {
|
||||
bvh_tree: bvh.Mesh_BVH,
|
||||
tri_to_level_geom: []Level_Geom_Handle,
|
||||
bvh_tree: bvh.BVH,
|
||||
level_geom_aabbs: []bvh.AABB,
|
||||
built: bool,
|
||||
}
|
||||
|
||||
// Top Level Acceleration Structure
|
||||
@ -82,70 +83,43 @@ Dynamic_TLAS :: struct {
|
||||
built: bool,
|
||||
}
|
||||
|
||||
build_static_tlas :: proc(sim_state: ^Sim_State) -> Static_TLAS {
|
||||
build_static_tlas :: proc(sim_state: ^Sim_State, out_tlas: ^Static_TLAS) {
|
||||
tracy.Zone()
|
||||
|
||||
num_vertices, num_indices: int
|
||||
static_tlas_destroy(out_tlas)
|
||||
|
||||
level_geom_aabbs := make([]bvh.AABB, len(sim_state.level_geoms))
|
||||
level_geom_indices := make([]u16, len(sim_state.level_geoms), context.temp_allocator)
|
||||
|
||||
{
|
||||
for i in 0 ..< len(sim_state.level_geoms) {
|
||||
level_geom := &sim_state.level_geoms[i]
|
||||
|
||||
if level_geom.alive {
|
||||
num_vertices += int(level_geom.geometry.vertices.len)
|
||||
num_indices += int(level_geom.geometry.indices.len)
|
||||
}
|
||||
}
|
||||
aabb := &level_geom_aabbs[i]
|
||||
level_geom_indices[i] = u16(i)
|
||||
|
||||
if num_vertices == 0 {
|
||||
return Static_TLAS{}
|
||||
}
|
||||
|
||||
vertices := make([]bvh.Vec3, num_vertices, context.temp_allocator)
|
||||
indices := make([]u16, num_indices, context.temp_allocator)
|
||||
|
||||
tri_to_level_geom := make([]Level_Geom_Handle, num_indices / 3, context.temp_allocator)
|
||||
|
||||
num_vertices, num_indices = 0, 0
|
||||
|
||||
for i in 0 ..< len(sim_state.level_geoms) {
|
||||
level_geom := &sim_state.level_geoms[i]
|
||||
|
||||
if level_geom.alive {
|
||||
geom_verts, geom_inds := get_level_geom_data(sim_state, level_geom.geometry)
|
||||
|
||||
base_vertex := num_vertices
|
||||
copy_slice(vertices[base_vertex:], geom_verts)
|
||||
num_vertices += len(geom_verts)
|
||||
|
||||
for j in 0 ..< len(geom_inds) {
|
||||
if num_indices %% 3 == 0 {
|
||||
tri := num_indices / 3
|
||||
tri_to_level_geom[tri] = index_to_level_geom(i)
|
||||
}
|
||||
ind := geom_inds[j]
|
||||
indices[num_indices] = u16(base_vertex + int(ind))
|
||||
num_indices += 1
|
||||
aabb.min = level_geom.aabb.center - level_geom.aabb.extent
|
||||
aabb.max = level_geom.aabb.center + level_geom.aabb.extent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.debugf("num vertices {}, len vertices {}", num_vertices, len(vertices))
|
||||
assert(num_vertices == len(vertices))
|
||||
assert(num_indices == len(indices))
|
||||
sim_state_bvh := bvh.build_bvh_from_aabbs(level_geom_aabbs, level_geom_indices)
|
||||
|
||||
// for i in 0 ..< len(indices) / 3 {
|
||||
// tri := get_triangle(vertices, indices, i)
|
||||
// rl.DrawTriangle3D(tri[0], tri[1], tri[2], rl.RED)
|
||||
// }
|
||||
|
||||
result := Static_TLAS {
|
||||
bvh_tree = bvh.build_bvh_from_mesh(
|
||||
bvh.Mesh{vertices = vertices, indices = indices},
|
||||
context.temp_allocator,
|
||||
),
|
||||
tri_to_level_geom = tri_to_level_geom,
|
||||
out_tlas^ = Static_TLAS {
|
||||
built = true,
|
||||
bvh_tree = sim_state_bvh,
|
||||
level_geom_aabbs = level_geom_aabbs,
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
static_tlas_destroy :: proc(static_tlas: ^Static_TLAS) {
|
||||
if static_tlas.built {
|
||||
bvh.destroy_bvh(&static_tlas.bvh_tree)
|
||||
delete(static_tlas.level_geom_aabbs)
|
||||
static_tlas^ = {}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: free intermediate temp allocs
|
||||
@ -160,18 +134,16 @@ build_dynamic_tlas :: proc(
|
||||
|
||||
dynamic_tlas_destroy(out_tlas)
|
||||
|
||||
body_aabbs := make([]bvh.AABB, sim_state.num_bodies, allocator)
|
||||
body_indices := make([]u16, sim_state.num_bodies, context.temp_allocator)
|
||||
body_aabbs := make([]bvh.AABB, len(sim_state.bodies_slice), allocator)
|
||||
body_indices := make([]u16, len(sim_state.bodies_slice), context.temp_allocator)
|
||||
|
||||
{
|
||||
aabb_index := 0
|
||||
for i in 0 ..< len(sim_state.bodies_slice) {
|
||||
body := &sim_state.bodies_slice[i]
|
||||
|
||||
if body.alive {
|
||||
aabb := &body_aabbs[aabb_index]
|
||||
body_indices[aabb_index] = u16(i)
|
||||
aabb_index += 1
|
||||
aabb := &body_aabbs[i]
|
||||
body_indices[i] = u16(i)
|
||||
|
||||
phys_aabb := body_get_aabb(body)
|
||||
|
||||
@ -221,11 +193,24 @@ raycasts_level :: proc(
|
||||
ray.origin = origin
|
||||
ray.dir = dir
|
||||
ray.dir_inv = 1.0 / dir
|
||||
it := bvh.iterator_intersect_leaf_ray(&tlas.bvh_tree.bvh, ray, distance)
|
||||
it := bvh.iterator_intersect_leaf_ray(&tlas.bvh_tree, ray, distance)
|
||||
|
||||
for leaf_node in bvh.iterator_intersect_leaf_next(&it) {
|
||||
for j in 0 ..< leaf_node.prim_len {
|
||||
tri_idx := tlas.bvh_tree.bvh.primitives[leaf_node.child_or_prim_start + j]
|
||||
level_geom_handle := index_to_level_geom(
|
||||
int(tlas.bvh_tree.primitives[leaf_node.child_or_prim_start + j]),
|
||||
)
|
||||
level_geom := get_level_geom(sim_state, level_geom_handle)
|
||||
blas := get_level_geom_blas(sim_state, level_geom.blas)
|
||||
vertices, indices := get_level_geom_data(sim_state, level_geom.geometry)
|
||||
|
||||
blas_it := bvh.iterator_intersect_leaf_ray(&blas, ray, distance)
|
||||
for blas_leaf_node in bvh.iterator_intersect_leaf_next(&it) {
|
||||
for k in 0 ..< blas_leaf_node.prim_len {
|
||||
tri_idx := blas.primitives[blas_leaf_node.child_or_prim_start + k]
|
||||
}
|
||||
}
|
||||
|
||||
tri := get_triangle(
|
||||
tlas.bvh_tree.mesh.vertices,
|
||||
tlas.bvh_tree.mesh.indices,
|
||||
@ -388,8 +373,8 @@ remove_invalid_contacts :: proc(
|
||||
should_remove |= !get_body(sim_state, Body_Handle(contact.b)).alive
|
||||
|
||||
if !should_remove {
|
||||
aabb_a := dyn_tlas.body_aabbs[int(contact.a) - 1]
|
||||
aabb_b := dyn_tlas.body_aabbs[int(contact.b) - 1]
|
||||
aabb_a := dyn_tlas.body_aabbs[body_handle_to_index(contact.a)]
|
||||
aabb_b := dyn_tlas.body_aabbs[body_handle_to_index(Body_Handle(contact.b))]
|
||||
|
||||
should_remove |= !bvh.test_aabb_vs_aabb(aabb_a, aabb_b)
|
||||
}
|
||||
@ -398,14 +383,18 @@ remove_invalid_contacts :: proc(
|
||||
should_remove |= !get_body(sim_state, contact.a).alive
|
||||
|
||||
if !should_remove {
|
||||
should_remove |= int(contact.tri_idx * 3) > len(static_tlas.bvh_tree.mesh.indices)
|
||||
level_geom_handle := Level_Geom_Handle(contact.b)
|
||||
tri_offset :=
|
||||
static_tlas.level_geom_tri_offset[level_geom_handle_to_index(level_geom_handle)]
|
||||
tri_idx := tri_offset + int(contact.local_tri_idx)
|
||||
should_remove |= (tri_idx * 3) >= len(static_tlas.bvh_tree.mesh.indices)
|
||||
|
||||
if !should_remove {
|
||||
aabb_a := dyn_tlas.body_aabbs[int(contact.a) - 1]
|
||||
aabb_a := dyn_tlas.body_aabbs[body_handle_to_index(contact.a)]
|
||||
tri := get_triangle(
|
||||
static_tlas.bvh_tree.mesh.vertices,
|
||||
static_tlas.bvh_tree.mesh.indices,
|
||||
int(contact.tri_idx),
|
||||
tri_idx,
|
||||
)
|
||||
aabb_b := get_triangle_aabb(tri)
|
||||
|
||||
@ -424,9 +413,10 @@ remove_invalid_contacts :: proc(
|
||||
)
|
||||
} else {
|
||||
pair = make_contact_pair_body_level(
|
||||
i32(body_handle_to_index(contact.a)),
|
||||
Body_Handle(contact.a),
|
||||
Level_Geom_Handle(contact.b),
|
||||
contact.shape_a,
|
||||
contact.tri_idx,
|
||||
contact.local_tri_idx,
|
||||
)
|
||||
}
|
||||
return
|
||||
@ -554,11 +544,16 @@ find_new_contacts :: proc(
|
||||
)
|
||||
prim_aabb := get_triangle_aabb(tri)
|
||||
level_geom_handle := static_tlas.tri_to_level_geom[tri_idx]
|
||||
local_tri_idx :=
|
||||
int(tri_idx) -
|
||||
static_tlas.level_geom_tri_offset[level_geom_handle_to_index(level_geom_handle)]
|
||||
assert(local_tri_idx >= 0)
|
||||
|
||||
if bvh.test_aabb_vs_aabb(body_aabb, prim_aabb) {
|
||||
|
||||
shapes_it := shapes_iterator(sim_state, body.shape)
|
||||
for shape, shape_idx in shapes_iterator_next(&shapes_it) {
|
||||
for shape in shapes_iterator_next(&shapes_it) {
|
||||
shape_idx := shapes_it.counter - 1
|
||||
shape_aabb := shape_get_aabb(shape^)
|
||||
shape_aabb = body_transform_shape_aabb(body, shape_aabb)
|
||||
bvh_shape_aabb := bvh.AABB {
|
||||
@ -567,9 +562,10 @@ find_new_contacts :: proc(
|
||||
}
|
||||
|
||||
pair := make_contact_pair_body_level(
|
||||
i32(body_idx),
|
||||
index_to_body_handle(int(body_idx)),
|
||||
level_geom_handle,
|
||||
shape_idx,
|
||||
i32(tri_idx),
|
||||
i32(local_tri_idx),
|
||||
)
|
||||
|
||||
if bvh.test_aabb_vs_aabb(prim_aabb, bvh_shape_aabb) &&
|
||||
@ -586,7 +582,7 @@ find_new_contacts :: proc(
|
||||
a = index_to_body_handle(i),
|
||||
shape_a = shape_idx,
|
||||
b = i32(level_geom_handle),
|
||||
tri_idx = i32(tri_idx),
|
||||
local_tri_idx = i32(local_tri_idx),
|
||||
}
|
||||
|
||||
sim_state.contact_container.lookup[pair] = i32(new_contact_idx)
|
||||
@ -665,7 +661,7 @@ Contact :: struct {
|
||||
b: i32,
|
||||
// shape index in each body
|
||||
shape_a, shape_b: i32,
|
||||
tri_idx: i32,
|
||||
local_tri_idx: i32,
|
||||
prev_x_a, prev_x_b: Vec3,
|
||||
prev_q_a, prev_q_b: Quat,
|
||||
manifold: collision.Contact_Manifold,
|
||||
@ -737,17 +733,17 @@ update_contacts :: proc(sim_state: ^Sim_State, static_tlas: ^Static_TLAS) {
|
||||
case .Body_vs_Body:
|
||||
m2 = body_get_convex_shape_by_linear_index_world(sim_state, body2, contact.shape_b)
|
||||
case .Body_vs_Level:
|
||||
// level_geom := get_level_geom(sim_state, Level_Geom_Handle(contact.b))
|
||||
level_geom_handle := Level_Geom_Handle(contact.b)
|
||||
tri_idx :=
|
||||
static_tlas.level_geom_tri_offset[level_geom_handle_to_index(level_geom_handle)] +
|
||||
int(contact.local_tri_idx)
|
||||
tri := get_triangle(
|
||||
static_tlas.bvh_tree.mesh.vertices,
|
||||
static_tlas.bvh_tree.mesh.indices,
|
||||
int(contact.tri_idx),
|
||||
tri_idx,
|
||||
)
|
||||
// rl.DrawTriangle3D(tri[0], tri[1], tri[2], rl.BLUE)
|
||||
|
||||
m2 = collision.double_sided_triangle_to_convex(tri, context.temp_allocator)
|
||||
// m2 = level_geom_get_convex_shape(sim_state, level_geom, int(contact.tri_idx))
|
||||
// he.debug_draw_mesh_wires(m2, rl.BLUE)
|
||||
}
|
||||
|
||||
// Raw manifold has contact points in world space
|
||||
@ -818,7 +814,7 @@ pgs_solve_contacts :: proc(
|
||||
inv_dt: f32,
|
||||
apply_bias: bool,
|
||||
) {
|
||||
bias_rate, mass_coef, impulse_coef := calculate_soft_constraint_params(16, 1, dt)
|
||||
bias_rate, mass_coef, impulse_coef := calculate_soft_constraint_params(30, 0.8, dt)
|
||||
if !apply_bias {
|
||||
mass_coef = 1
|
||||
bias_rate = 0
|
||||
@ -1521,7 +1517,7 @@ simulate_step :: proc(scene: ^Scene, sim_state: ^Sim_State, config: Solver_Confi
|
||||
dt := f32(dt_64)
|
||||
inv_dt := f32(inv_dt_64)
|
||||
|
||||
sim_state.static_tlas = build_static_tlas(sim_state)
|
||||
build_static_tlas(sim_state, &sim_state.static_tlas)
|
||||
build_dynamic_tlas(sim_state, config, &sim_state.dynamic_tlas)
|
||||
|
||||
remove_invalid_contacts(sim_state, sim_state.static_tlas, sim_state.dynamic_tlas)
|
||||
|
Loading…
x
Reference in New Issue
Block a user