Basic lelel import working, collisions for level geo broken
This commit is contained in:
parent
a81e81c52c
commit
7da986970e
BIN
assets/blender/test_level_blend/Plane.glb
(Stored with Git LFS)
BIN
assets/blender/test_level_blend/Plane.glb
(Stored with Git LFS)
Binary file not shown.
@ -1,41 +1,41 @@
|
||||
(inst
|
||||
:model "assets/blender/testblend_blend/Bakery.glb"
|
||||
:pos (0.000000 12.000000 0.000000)
|
||||
:pos (0.000000 0.000000 12.000000)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (1.000000 1.000000 1.000000))
|
||||
(inst
|
||||
:model "assets/blender/test_level_blend/Plane.glb"
|
||||
:pos (0.000000 0.000000 0.000000)
|
||||
:pos (0.000000 -1.000000 0.000000)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (22.469545 22.469545 22.469545))
|
||||
(inst
|
||||
:model "assets/blender/testblend_blend/Fire_Station.glb"
|
||||
:pos (9.000000 13.000000 0.000000)
|
||||
:pos (9.000000 0.000000 13.000000)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (1.000000 1.000000 1.000000))
|
||||
(inst
|
||||
:model "assets/blender/testblend_blend/Gas_Station_Shop.glb"
|
||||
:pos (-8.000000 11.000000 0.000000)
|
||||
:pos (-8.000000 0.000000 11.000000)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (1.000000 1.000000 1.000000))
|
||||
(inst
|
||||
:model "assets/blender/testblend_blend/Gas_Station_Shop.glb"
|
||||
:pos (-16.000000 11.000000 0.000000)
|
||||
:pos (-16.000000 0.000000 11.000000)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (1.000000 1.000000 1.000000))
|
||||
(inst
|
||||
:model "assets/blender/testblend_blend/Gas_Station_Shop.glb"
|
||||
:pos (-15.559284 0.259853 1.609015)
|
||||
:pos (-15.559284 1.609015 0.259853)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (1.000000 1.000000 1.000000))
|
||||
(inst
|
||||
:model "assets/blender/testblend_blend/Green_House.glb"
|
||||
:pos (14.000000 -7.000000 0.000000)
|
||||
:pos (14.000000 0.000000 -7.000000)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (1.000000 1.000000 1.000000))
|
||||
(inst
|
||||
:model "assets/blender/testblend_blend/Hotel.glb"
|
||||
:pos (8.000000 -18.000000 0.000000)
|
||||
:pos (8.000000 0.000000 -18.000000)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (1.000000 1.000000 1.000000))
|
||||
(inst
|
||||
@ -43,8 +43,3 @@
|
||||
:pos (0.000000 0.000000 0.000000)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (1.000000 1.000000 1.000000))
|
||||
(inst
|
||||
:model "assets/blender/ice_cream_truck_blend/Split.glb"
|
||||
:pos (-1.000000 3.000000 0.000000)
|
||||
:rot (0.000000 0.000000 0.000000 1.000000)
|
||||
:scale (1.000000 1.000000 1.000000))
|
||||
|
@ -70,7 +70,7 @@ for obj in visible_objects:
|
||||
instance_sexpr = (
|
||||
'(inst'
|
||||
f'\n\t:model "assets/{model_path}"'
|
||||
f'\n\t:pos ({loc.x:.6f} {loc.y:.6f} {loc.z:.6f}) '
|
||||
f'\n\t:pos ({loc.x:.6f} {loc.z:.6f} {loc.y:.6f})'
|
||||
f'\n\t:rot ({rot.x:.6f} {rot.y:.6f} {rot.z:.6f} {rot.w:.6f})'
|
||||
f'\n\t:scale ({scale.x:.6f} {scale.y:.6f} {scale.z:.6f}))'
|
||||
)
|
||||
|
@ -4,6 +4,7 @@ import "common:name"
|
||||
import "core:container/intrusive/list"
|
||||
import "core:fmt"
|
||||
import "core:io"
|
||||
import "core:strconv"
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
import "core:unicode"
|
||||
@ -151,7 +152,13 @@ parse_atom :: proc(ctx: ^SEXP_Parser) -> (atom: Atom, error: Error) {
|
||||
result := ctx.data[start:ctx.pos]
|
||||
ctx.pos = next
|
||||
return result, nil
|
||||
|
||||
case '0' ..= '9', '-', '+':
|
||||
value, n, ok := strconv.parse_f64_prefix(ctx.data[ctx.pos:])
|
||||
if !ok {
|
||||
return nil, make_error(ctx, "failed to parse number")
|
||||
}
|
||||
ctx.pos += n
|
||||
return value, nil
|
||||
}
|
||||
|
||||
return nil, make_error(ctx, fmt.tprintf("unknown atom {}", c))
|
||||
@ -233,6 +240,43 @@ iterator_next_checked :: proc(it: ^List_Iterator) -> Sexp {
|
||||
return node.expr
|
||||
}
|
||||
|
||||
iterator_has_more :: proc(it: List_Iterator) -> bool {
|
||||
return it.curr != nil
|
||||
}
|
||||
|
||||
iterator_expect_list :: proc(it: ^List_Iterator) -> (Sexp_List, bool) {
|
||||
next, ok := iterator_next(it)
|
||||
|
||||
if !ok {
|
||||
return {}, false
|
||||
}
|
||||
|
||||
list_expr: Sexp_List
|
||||
list_expr, ok = next.expr.(Sexp_List)
|
||||
|
||||
return list_expr, ok
|
||||
}
|
||||
|
||||
iterator_expect_atom :: proc(it: ^List_Iterator, $T: typeid) -> (T, bool) {
|
||||
next, ok := iterator_next(it)
|
||||
|
||||
if !ok {
|
||||
return {}, false
|
||||
}
|
||||
|
||||
atom_expr: Atom
|
||||
atom_expr, ok = next.expr.(Atom)
|
||||
|
||||
if !ok {
|
||||
return {}, false
|
||||
}
|
||||
|
||||
result: T
|
||||
result, ok = atom_expr.(T)
|
||||
|
||||
return result, ok
|
||||
}
|
||||
|
||||
print_list :: proc(it: List_Iterator, w: io.Writer) -> io.Error {
|
||||
it := it
|
||||
io.write_byte(w, '(') or_return
|
||||
@ -402,6 +446,16 @@ print_pretty_error :: proc(w: io.Writer, data: string, error: Error) -> io.Error
|
||||
return nil
|
||||
}
|
||||
|
||||
// Prints pretty error to temp string
|
||||
temp_pretty_error :: proc(data: string, error: Error) -> string {
|
||||
builder: strings.Builder
|
||||
strings.builder_init(&builder, context.temp_allocator)
|
||||
|
||||
writer := strings.to_writer(&builder)
|
||||
print_pretty_error(writer, data, error)
|
||||
return strings.to_string(builder)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_parse :: proc(t: ^testing.T) {
|
||||
ctx: SEXP_Parser
|
||||
|
@ -81,3 +81,7 @@ to_string :: proc(name: Name) -> string {
|
||||
sync.atomic_rw_mutex_shared_guard(&global_container.lock)
|
||||
return global_container.names_array[name]
|
||||
}
|
||||
|
||||
to_cstring :: proc(name: Name) -> cstring {
|
||||
return strings.unsafe_string_to_cstring(to_string(name))
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package assets
|
||||
|
||||
import "common:encoding/sexp"
|
||||
import "common:name"
|
||||
import "core:log"
|
||||
import "core:math"
|
||||
import lg "core:math/linalg"
|
||||
@ -57,6 +59,18 @@ destroy_loaded_bvh :: proc(loaded_bvh: ^Loaded_BVH) {
|
||||
|
||||
Curve_2D :: [][2]f32
|
||||
|
||||
Scene_Instance :: struct {
|
||||
model: name.Name,
|
||||
// TODO: common format definitions
|
||||
pos: rl.Vector3,
|
||||
rot: rl.Quaternion,
|
||||
scale: rl.Vector3,
|
||||
}
|
||||
|
||||
Scene_Desc :: struct {
|
||||
instances: []Scene_Instance,
|
||||
}
|
||||
|
||||
Asset_Manager :: struct {
|
||||
textures: Asset_Cache(rl.Texture2D),
|
||||
models: Asset_Cache(rl.Model),
|
||||
@ -65,6 +79,7 @@ Asset_Manager :: struct {
|
||||
music: Asset_Cache(rl.Music),
|
||||
curves_1d: Asset_Cache([]f32),
|
||||
curves_2d: Asset_Cache(Curve_2D),
|
||||
scenes: Asset_Cache(Scene_Desc),
|
||||
bvhs: map[cstring]Loaded_BVH,
|
||||
curves: map[cstring]Loaded_Curve_2D,
|
||||
}
|
||||
@ -203,6 +218,104 @@ CURVE_2D_CSV_LOADER :: Asset_Cache_Loader(Curve_2D) {
|
||||
},
|
||||
}
|
||||
|
||||
SCENE_DESC_LOADER :: Asset_Cache_Loader(Scene_Desc) {
|
||||
load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (Scene_Desc, bool) {
|
||||
data, err := physfs.read_entire_file(string(path), context.temp_allocator)
|
||||
if err != nil {
|
||||
log.errorf("Failed to read curve: %s, %v", path, err)
|
||||
return {}, false
|
||||
}
|
||||
|
||||
parser: sexp.SEXP_Parser
|
||||
parser.data = string(data)
|
||||
parsed, err2 := sexp.parse(&parser, context.temp_allocator)
|
||||
|
||||
if err2 != nil {
|
||||
log.errorf(
|
||||
"Failed to parse curve: %s\n%s",
|
||||
path,
|
||||
sexp.temp_pretty_error(parser.data, err2),
|
||||
)
|
||||
}
|
||||
|
||||
inst_identifier := sexp.Ident(name.from_string("inst"))
|
||||
|
||||
num_instances: int
|
||||
|
||||
top_it := sexp.iterator_list(parsed)
|
||||
for top_level_expr in sexp.iterator_next(&top_it) {
|
||||
list_expr := top_level_expr.expr.(sexp.Sexp_List) or_continue
|
||||
|
||||
it := sexp.iterator_list(list_expr)
|
||||
ident := sexp.iterator_expect_atom(&it, sexp.Ident) or_continue
|
||||
|
||||
if ident != inst_identifier {
|
||||
continue
|
||||
}
|
||||
|
||||
num_instances += 1
|
||||
}
|
||||
|
||||
instances := make([]Scene_Instance, num_instances)
|
||||
num_instances = 0
|
||||
|
||||
top_it = sexp.iterator_list(parsed)
|
||||
for top_level_expr in sexp.iterator_next(&top_it) {
|
||||
list_expr := top_level_expr.expr.(sexp.Sexp_List) or_continue
|
||||
|
||||
it := sexp.iterator_list(list_expr)
|
||||
ident := sexp.iterator_expect_atom(&it, sexp.Ident) or_continue
|
||||
|
||||
if ident != inst_identifier {
|
||||
continue
|
||||
}
|
||||
|
||||
inst: Scene_Instance
|
||||
|
||||
for sexp.iterator_has_more(it) {
|
||||
key := sexp.iterator_expect_atom(&it, sexp.Tag) or_continue
|
||||
|
||||
switch name.Name(key) {
|
||||
case name.from_string("model"):
|
||||
model_path := sexp.iterator_expect_atom(&it, string) or_continue
|
||||
inst.model = name.from_string(model_path)
|
||||
case name.from_string("pos"):
|
||||
pos_list := sexp.iterator_expect_list(&it) or_continue
|
||||
pos_it := sexp.iterator_list(pos_list)
|
||||
x := sexp.iterator_expect_atom(&pos_it, f64) or_continue
|
||||
y := sexp.iterator_expect_atom(&pos_it, f64) or_continue
|
||||
z := sexp.iterator_expect_atom(&pos_it, f64) or_continue
|
||||
|
||||
inst.pos = {f32(x), f32(y), f32(z)}
|
||||
case name.from_string("rot"):
|
||||
rot_list := sexp.iterator_expect_list(&it) or_continue
|
||||
rot_it := sexp.iterator_list(rot_list)
|
||||
inst.rot.x = f32(sexp.iterator_expect_atom(&rot_it, f64) or_continue)
|
||||
inst.rot.y = f32(sexp.iterator_expect_atom(&rot_it, f64) or_continue)
|
||||
inst.rot.z = f32(sexp.iterator_expect_atom(&rot_it, f64) or_continue)
|
||||
inst.rot.w = f32(sexp.iterator_expect_atom(&rot_it, f64) or_continue)
|
||||
case name.from_string("scale"):
|
||||
scale_list := sexp.iterator_expect_list(&it) or_continue
|
||||
scale_it := sexp.iterator_list(scale_list)
|
||||
x := sexp.iterator_expect_atom(&scale_it, f64) or_continue
|
||||
y := sexp.iterator_expect_atom(&scale_it, f64) or_continue
|
||||
z := sexp.iterator_expect_atom(&scale_it, f64) or_continue
|
||||
|
||||
inst.scale = {f32(x), f32(y), f32(z)}
|
||||
}
|
||||
}
|
||||
|
||||
instances[num_instances] = inst
|
||||
num_instances += 1
|
||||
}
|
||||
|
||||
return Scene_Desc{instances = instances[:num_instances]}, true
|
||||
},
|
||||
unload = proc(scene_desc: Scene_Desc) {
|
||||
delete(scene_desc.instances)
|
||||
},
|
||||
}
|
||||
|
||||
assetman_init :: proc(assetman: ^Asset_Manager) {
|
||||
assetman.models = {
|
||||
loader = MODEL_LOADER,
|
||||
@ -225,6 +338,9 @@ assetman_init :: proc(assetman: ^Asset_Manager) {
|
||||
assetman.curves_2d = {
|
||||
loader = CURVE_2D_CSV_LOADER,
|
||||
}
|
||||
assetman.scenes = {
|
||||
loader = SCENE_DESC_LOADER,
|
||||
}
|
||||
}
|
||||
|
||||
Asset_Cache_Result :: enum {
|
||||
@ -238,6 +354,7 @@ assetcache_fetch_or_load :: proc(
|
||||
ac: ^$T/Asset_Cache($E),
|
||||
path: cstring,
|
||||
payload: Asset_Cache_Loader_Payload = nil,
|
||||
force_no_reload := false,
|
||||
) -> (
|
||||
value: E,
|
||||
modtime: physfs.sint64,
|
||||
@ -250,7 +367,7 @@ assetcache_fetch_or_load :: proc(
|
||||
if has_existing {
|
||||
new_modtime := physfs.getLastModTime(path)
|
||||
|
||||
if existing.modtime == new_modtime {
|
||||
if force_no_reload || existing.modtime == new_modtime {
|
||||
result = .Cached
|
||||
return existing.value, new_modtime, result
|
||||
} else {
|
||||
@ -408,7 +525,9 @@ get_bvh :: proc(assetman: ^Asset_Manager, path: cstring) -> (Loaded_BVH, bool) {
|
||||
copy(vertices[vert_count:], mesh_vertices)
|
||||
|
||||
for j in 0 ..< len(mesh_indices) {
|
||||
indices[indices_count + j] = u16(vert_count) + mesh_indices[j]
|
||||
index := vert_count + int(mesh_indices[j])
|
||||
assert(index <= int(max(u16)))
|
||||
indices[indices_count + j] = u16(index)
|
||||
}
|
||||
|
||||
vert_count += len(mesh_vertices)
|
||||
@ -446,6 +565,20 @@ get_curve_2d :: proc(assetman: ^Asset_Manager, path: cstring) -> (curve: Curve_2
|
||||
return
|
||||
}
|
||||
|
||||
// Reads a two column comma separated csv file as a curve
|
||||
get_scene_desc :: proc(
|
||||
assetman: ^Asset_Manager,
|
||||
path: name.Name,
|
||||
force_no_reload := false,
|
||||
) -> (
|
||||
scene: Scene_Desc,
|
||||
reloaded: bool,
|
||||
) {
|
||||
res: Asset_Cache_Result
|
||||
scene, _, res = assetcache_fetch_or_load(&assetman.scenes, name.to_cstring(path))
|
||||
return scene, (res == .Loaded || res == .Reloaded)
|
||||
}
|
||||
|
||||
get_convex :: proc(assetman: ^Asset_Manager, path: cstring) -> (result: Loaded_Convex) {
|
||||
bytes, err := physfs.read_entire_file(string(path), context.temp_allocator)
|
||||
if err != nil {
|
||||
@ -852,6 +985,7 @@ shutdown :: proc(assetman: ^Asset_Manager) {
|
||||
assetcache_destroy(&assetman.music)
|
||||
assetcache_destroy(&assetman.curves_1d)
|
||||
assetcache_destroy(&assetman.curves_2d)
|
||||
assetcache_destroy(&assetman.scenes)
|
||||
|
||||
for _, &loaded_bvh in assetman.bvhs {
|
||||
destroy_loaded_bvh(&loaded_bvh)
|
||||
|
107
game/game.odin
107
game/game.odin
@ -17,7 +17,6 @@ package game
|
||||
import "assets"
|
||||
import "common:name"
|
||||
import "core:fmt"
|
||||
import "core:hash"
|
||||
import "core:log"
|
||||
import "core:math"
|
||||
import "core:math/linalg"
|
||||
@ -48,6 +47,65 @@ Debug_Draw_State :: struct {
|
||||
draw_physics_scene: bool,
|
||||
}
|
||||
|
||||
Scene :: struct {
|
||||
scene_desc_path: name.Name,
|
||||
level_geoms: []physics.Level_Geom_Handle,
|
||||
}
|
||||
|
||||
scene_destroy :: proc(world: ^World, scene: ^Scene) {
|
||||
scene.scene_desc_path = name.NONE
|
||||
sim_state := physics.get_sim_state(&world.physics_scene)
|
||||
for handle in scene.level_geoms {
|
||||
physics.remove_level_geom(sim_state, handle)
|
||||
}
|
||||
delete(scene.level_geoms)
|
||||
scene.level_geoms = nil
|
||||
}
|
||||
|
||||
immediate_scene :: proc(world: ^World, scene: ^Scene, path: cstring) {
|
||||
path_name := name.from_string(string(path))
|
||||
|
||||
desc, reloaded := assets.get_scene_desc(&g_mem.assetman, path_name)
|
||||
|
||||
if reloaded || scene.scene_desc_path != path_name {
|
||||
scene_destroy(world, scene)
|
||||
|
||||
scene.scene_desc_path = path_name
|
||||
|
||||
sim_state := physics.get_sim_state(&world.physics_scene)
|
||||
for inst in desc.instances {
|
||||
physics.add_level_geom(
|
||||
sim_state,
|
||||
physics.Level_Geom_Config {
|
||||
position = inst.pos,
|
||||
rotation = inst.rot,
|
||||
source = physics.Level_Geometry_Asset(name.to_string(inst.model)),
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scene_copy :: proc(dst, src: ^Scene) {
|
||||
dst.scene_desc_path = src.scene_desc_path
|
||||
if len(dst.level_geoms) != len(src.level_geoms) {
|
||||
delete(dst.level_geoms)
|
||||
dst.level_geoms = make([]physics.Level_Geom_Handle, len(src.level_geoms))
|
||||
}
|
||||
copy(dst.level_geoms, src.level_geoms)
|
||||
}
|
||||
|
||||
scene_draw :: proc(scene: ^Scene) {
|
||||
desc, _ := assets.get_scene_desc(&g_mem.assetman, scene.scene_desc_path, true)
|
||||
for geo in desc.instances {
|
||||
render.draw_model(
|
||||
assets.get_model(&g_mem.assetman, name.to_cstring(geo.model)),
|
||||
{},
|
||||
auto_cast linalg.matrix4_from_trs(geo.pos, geo.rot, geo.scale),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
World :: struct {
|
||||
player_pos: rl.Vector3,
|
||||
track: Track,
|
||||
@ -57,6 +115,7 @@ World :: struct {
|
||||
car_handle: physics.Body_Handle,
|
||||
engine_handle: physics.Engine_Handle,
|
||||
debug_state: Debug_Draw_State,
|
||||
main_scene: Scene,
|
||||
}
|
||||
world_init :: proc(world: ^World) {
|
||||
physics.scene_init(&world.physics_scene, &g_mem.assetman)
|
||||
@ -64,6 +123,7 @@ world_init :: proc(world: ^World) {
|
||||
copy_world :: proc(dst, src: ^World) {
|
||||
copy_track(&dst.track, &src.track)
|
||||
physics.copy_physics_scene(&dst.physics_scene, &src.physics_scene)
|
||||
scene_copy(&dst.main_scene, &src.main_scene)
|
||||
dst.player_pos = src.player_pos
|
||||
dst.pause = src.pause
|
||||
dst.car_com = src.car_com
|
||||
@ -73,6 +133,7 @@ copy_world :: proc(dst, src: ^World) {
|
||||
}
|
||||
destroy_world :: proc(world: ^World) {
|
||||
destroy_track(&world.track)
|
||||
scene_destroy(world, &world.main_scene)
|
||||
physics.scene_destroy(&world.physics_scene)
|
||||
}
|
||||
|
||||
@ -699,46 +760,7 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
||||
wheel.turn_angle = TURN_ANGLE * turn_vel_correction * turn_input
|
||||
}
|
||||
|
||||
{
|
||||
physics.immediate_level_geom(
|
||||
&world.physics_scene,
|
||||
u32(name.from_string("level_geom_from_asset")),
|
||||
{
|
||||
position = physics.Vec3{5, 0, 0},
|
||||
rotation = linalg.QUATERNIONF32_IDENTITY,
|
||||
source = physics.Level_Geometry_Asset(
|
||||
"assets/blender/test_level_blend/NurbsPath.glb",
|
||||
),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
level_model := assets.get_model(&g_mem.assetman, "assets/testblend.glb")
|
||||
|
||||
for i in 0 ..< level_model.meshCount {
|
||||
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))),
|
||||
{
|
||||
position = pos,
|
||||
rotation = rotation,
|
||||
source = physics.Level_Geometry_Mesh {
|
||||
vertices = (cast([^]rl.Vector3)mesh.vertices)[:mesh.vertexCount],
|
||||
indices = mesh.indices[:mesh.triangleCount * 3],
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
immediate_scene(world, &world.main_scene, "assets/blender/test_level_blend/Scene.scn")
|
||||
|
||||
if len(world.track.points) > 1 {
|
||||
interpolated_points := calculate_spline_interpolated_points(
|
||||
@ -1094,7 +1116,6 @@ 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")
|
||||
car_model := assets.get_model(&g_mem.assetman, "assets/ice_cream_truck.glb")
|
||||
|
||||
phys_debug_state: physics.Debug_State
|
||||
@ -1183,7 +1204,7 @@ draw_world :: proc(world: ^World) {
|
||||
// .VEC3,
|
||||
// )
|
||||
|
||||
render.draw_model(level_model, {}, 1)
|
||||
scene_draw(&world.main_scene)
|
||||
|
||||
render.draw_model(car_model, {}, car_matrix)
|
||||
|
||||
|
@ -967,6 +967,7 @@ get_level_geom_data :: proc(
|
||||
)
|
||||
if reloaded {
|
||||
level_geom.aabb = bvh_aabb_to_phys_aabb(loaded_bvh.aabb)
|
||||
level_geom.aabb = aabb_transform(level_geom.aabb, level_geom.x, level_geom.q)
|
||||
}
|
||||
vertices = loaded_bvh.vertices
|
||||
indices = loaded_bvh.indices
|
||||
@ -989,6 +990,7 @@ get_level_geom_blas :: proc(sim_state: ^Sim_State, handle: Level_Geom_Handle) ->
|
||||
)
|
||||
if reloaded {
|
||||
level_geom.aabb = bvh_aabb_to_phys_aabb(loaded_bvh.aabb)
|
||||
level_geom.aabb = aabb_transform(level_geom.aabb, level_geom.x, level_geom.q)
|
||||
}
|
||||
|
||||
bvh = loaded_bvh.bvh
|
||||
@ -1074,6 +1076,8 @@ add_level_geom :: proc(sim_state: ^Sim_State, config: Level_Geom_Config) -> Leve
|
||||
}
|
||||
}
|
||||
|
||||
level_geom.aabb = aabb_transform(level_geom.aabb, level_geom.x, level_geom.q)
|
||||
|
||||
if sim_state.first_free_level_geom_plus_one > 0 {
|
||||
index := sim_state.first_free_level_geom_plus_one
|
||||
new_level_geom := get_level_geom(sim_state, Level_Geom_Handle(index))
|
||||
|
@ -200,6 +200,7 @@ raycasts_level :: proc(
|
||||
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_handle)
|
||||
vertices, indices := get_level_geom_data(sim_state, level_geom_handle)
|
||||
|
||||
@ -210,7 +211,13 @@ raycasts_level :: proc(
|
||||
for k in 0 ..< blas_leaf_node.prim_len {
|
||||
tri_idx := int(blas.primitives[blas_leaf_node.child_or_prim_start + k])
|
||||
|
||||
tri := get_triangle(vertices, indices, tri_idx)
|
||||
tri := get_transformed_triangle(
|
||||
vertices,
|
||||
indices,
|
||||
tri_idx,
|
||||
level_geom.x,
|
||||
level_geom.q,
|
||||
)
|
||||
|
||||
hit_t, tmp_normal, _, ok := collision.intersect_ray_triangle(
|
||||
{origin, origin + dir},
|
||||
@ -392,7 +399,13 @@ remove_invalid_contacts :: proc(
|
||||
|
||||
if !should_remove {
|
||||
aabb_a := dyn_tlas.body_aabbs[body_handle_to_index(contact.a)]
|
||||
tri := get_triangle(vertices, indices, tri_idx)
|
||||
tri := get_transformed_triangle(
|
||||
vertices,
|
||||
indices,
|
||||
tri_idx,
|
||||
level_geom.x,
|
||||
level_geom.q,
|
||||
)
|
||||
aabb_b := get_triangle_aabb(tri)
|
||||
|
||||
should_remove |= !bvh.test_aabb_vs_aabb(aabb_a, aabb_b)
|
||||
@ -555,7 +568,13 @@ find_new_contacts :: proc(
|
||||
tri_idx := int(
|
||||
blas.primitives[blas_leaf_node.child_or_prim_start + k],
|
||||
)
|
||||
tri := get_triangle(vertices, indices, tri_idx)
|
||||
tri := get_transformed_triangle(
|
||||
vertices,
|
||||
indices,
|
||||
tri_idx,
|
||||
level_geom.x,
|
||||
level_geom.q,
|
||||
)
|
||||
prim_aabb := get_triangle_aabb(tri)
|
||||
|
||||
if bvh.test_aabb_vs_aabb(body_aabb, prim_aabb) {
|
||||
@ -804,8 +823,15 @@ update_contacts :: proc(sim_state: ^Sim_State, static_tlas: ^Static_TLAS) {
|
||||
)
|
||||
case .Body_vs_Level:
|
||||
level_geom_handle := Level_Geom_Handle(contact.b)
|
||||
level_geom := get_level_geom(sim_state, level_geom_handle)
|
||||
vertices, indices := get_level_geom_data(sim_state, level_geom_handle)
|
||||
tri := get_triangle(vertices, indices, int(contact.local_tri_idx))
|
||||
tri := get_transformed_triangle(
|
||||
vertices,
|
||||
indices,
|
||||
int(contact.local_tri_idx),
|
||||
level_geom.x,
|
||||
level_geom.q,
|
||||
)
|
||||
|
||||
m2 = collision.double_sided_triangle_to_convex(tri, context.temp_allocator)
|
||||
}
|
||||
|
BIN
src_assets/test_level.blend
(Stored with Git LFS)
BIN
src_assets/test_level.blend
(Stored with Git LFS)
Binary file not shown.
BIN
src_assets/test_level.blend1
(Stored with Git LFS)
BIN
src_assets/test_level.blend1
(Stored with Git LFS)
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user