From b46858cf556f84aa2611daf44245be5cc1c23740 Mon Sep 17 00:00:00 2001 From: Sergey Poznyak Date: Sun, 12 Jan 2025 03:59:33 +0400 Subject: [PATCH] Implementing halfedge mesh --- game/game.odin | 2 + game/halfedge/debug.odin | 7 ++ game/halfedge/halfedge.odin | 101 ++++++++++++++++++++++++++++ game/physics/halfedge/halfedge.odin | 89 ------------------------ 4 files changed, 110 insertions(+), 89 deletions(-) create mode 100644 game/halfedge/debug.odin create mode 100644 game/halfedge/halfedge.odin delete mode 100644 game/physics/halfedge/halfedge.odin diff --git a/game/game.odin b/game/game.odin index b51b06f..db312ef 100644 --- a/game/game.odin +++ b/game/game.odin @@ -22,6 +22,7 @@ import "core:math" import "core:math/linalg" import "game:physics" import "game:physics/bvh" +import "halfedge" import "libs:tracy" import rl "vendor:raylib" import "vendor:raylib/rlgl" @@ -471,6 +472,7 @@ draw :: proc() { car_body := physics.get_body(&world.physics_scene, runtime_world.car_handle) car_model := assets.get_model(&g_mem.assetman, "assets/toyota_corolla_ae86_trueno.glb") + car_halfedge := halfedge.mesh_from_vertex_index_list(car_model.meshes[0].vertices, car_model.meshes[0].indices, context.temp_allocator) mesh_col: bvh.Collision hit_mesh_idx := -1 diff --git a/game/halfedge/debug.odin b/game/halfedge/debug.odin new file mode 100644 index 0000000..6bd7ece --- /dev/null +++ b/game/halfedge/debug.odin @@ -0,0 +1,7 @@ +package halfedge + +import rl "vendor:raylib" + +debug_draw_halfedge_mesh :: proc(mesh: ^Mesh) { + +} diff --git a/game/halfedge/halfedge.odin b/game/halfedge/halfedge.odin new file mode 100644 index 0000000..26d8932 --- /dev/null +++ b/game/halfedge/halfedge.odin @@ -0,0 +1,101 @@ +package halfedge + +import "core:container/small_array" + +Vec3 :: [3]f32 + +Vertex :: struct { + pos: Vec3, + edge: Edge_Index, +} + +Face :: struct { + edge: Edge_Index, +} + +Vertex_Index :: distinct u16 +Face_Index :: distinct i16 +Edge_Index :: distinct i16 + +Half_Edge :: struct { + origin: Vertex_Index, + twin: Edge_Index, + face: Face_Index, + next: Edge_Index, + prev: Edge_Index, +} + +Half_Edge_Mesh :: struct { + vertices: []Vertex, + faces: []Face, + edges: []Half_Edge, +} + +mesh_from_vertex_index_list :: proc( + vertices: []Vec3, + indices: []u16, + allocator := context.allocator, +) -> Half_Edge_Mesh { + mesh: Half_Edge_Mesh + verts := make([]Vertex, len(vertices), allocator) + faces := make([]Face, len(indices) / 3, allocator) + edges := make([]Half_Edge, len(indices), allocator) + + mesh.vertices = verts + mesh.faces = faces + mesh.edges = edges + + for pos, i in vertices { + verts[i].pos = pos + verts[i].edge = -1 + } + + temp_edges: map[[2]u16]Edge_Index = make_map(map[[2]u16]Edge_Index, context.temp_allocator) + + triangle_num := len(indices) / 3 + for i in 0 ..< triangle_num { + i1, i2, i3 := indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2] + v1, v2, v3 := vertices[i1], vertices[i2], vertices[i3] + e1, e2, e3 := i * 3 + 0, i * 3 + 1, i * 3 + 2 + + faces[i].edge = Edge_Index(e1) + edges[e1] = { + origin = Vertex_Index(i1), + twin = -1, + face = Face_Index(i), + next = Edge_Index(e2), + prev = Edge_Index(e3), + } + edges[e2] = { + origin = Vertex_Index(i2), + twin = -1, + face = Face_Index(i), + next = Edge_Index(e3), + prev = Edge_Index(e1), + } + edges[e3] = { + origin = Vertex_Index(i3), + twin = -1, + face = Face_Index(i), + next = Edge_Index(e1), + prev = Edge_Index(e2), + } + + edge_stable_indices := [][2]u16 { + {min(i1, i2), max(i1, i2)}, + {min(i2, i3), max(i2, i3)}, + {min(i3, i1), max(i3, i1)}, + } + + for stable_idx, j in edge_stable_indices { + twin, ok := temp_edges[stable_idx] + ei := i * 3 + j + if ok { + edges[ei].twin = twin + edges[twin].twin = Edge_Index(ei) + } else { + temp_edges[stable_idx] = Edge_Index(ei) + } + } + } +} diff --git a/game/physics/halfedge/halfedge.odin b/game/physics/halfedge/halfedge.odin deleted file mode 100644 index 4f436dd..0000000 --- a/game/physics/halfedge/halfedge.odin +++ /dev/null @@ -1,89 +0,0 @@ -package halfedge - -import "core:container/small_array" - -Vec3 :: [3]f32 - -Vertex :: struct { - pos: Vec3, - edge: i16, -} - -Face :: struct { - edge: i16, -} - -Vertex_Index :: distinct u16 -Face_Index :: distinct i16 -Edge_Index :: distinct i16 - -Half_Edge :: struct { - origin: Vertex_Index, - twin: Edge_Index, - face: Face_Index, - next: Edge_Index, - prev: Edge_Index, -} - -Mesh :: struct { - vertices: []Vertex, - faces: []Face, - edges: []Half_Edge, -} - -mesh_from_vertex_index_list :: proc(vertices: []Vec3, indices: []u16, allocator := context.allocator) { - vertices: [dynamic]Vertex - faces: [dynamic]Face - edges: [dynamic]Half_Edge - - temp_edges: map[[2]u16]small_array.Small_Array(2, Edge_Index) - - triangle_num := len(indices) / 3 - for i in 0.. 0 { - // small_array.push_back(Edge_Index(e1 + j)) - } - } - } -}