Implementing halfedge mesh

This commit is contained in:
Sergey Poznyak 2025-01-12 03:59:33 +04:00
parent ccefa6b952
commit b46858cf55
4 changed files with 110 additions and 89 deletions

View File

@ -22,6 +22,7 @@ import "core:math"
import "core:math/linalg" import "core:math/linalg"
import "game:physics" import "game:physics"
import "game:physics/bvh" import "game:physics/bvh"
import "halfedge"
import "libs:tracy" import "libs:tracy"
import rl "vendor:raylib" import rl "vendor:raylib"
import "vendor:raylib/rlgl" import "vendor:raylib/rlgl"
@ -471,6 +472,7 @@ draw :: proc() {
car_body := physics.get_body(&world.physics_scene, runtime_world.car_handle) 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_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 mesh_col: bvh.Collision
hit_mesh_idx := -1 hit_mesh_idx := -1

7
game/halfedge/debug.odin Normal file
View File

@ -0,0 +1,7 @@
package halfedge
import rl "vendor:raylib"
debug_draw_halfedge_mesh :: proc(mesh: ^Mesh) {
}

101
game/halfedge/halfedge.odin Normal file
View File

@ -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)
}
}
}
}

View File

@ -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..<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 := len(edges)
e2, e3 := e1 + 1, e1 + 2
new_edges := [3]Half_Edge{
{
origin = Vertex_Index(i1),
twin = -1,
face = Face_Index(i),
next = Edge_Index(e2),
prev = Edge_Index(e3),
},
{
origin = Vertex_Index(i2),
twin = -1,
face = Face_Index(i),
next = Edge_Index(e3),
prev = Edge_Index(e1),
},
{
origin = Vertex_Index(i3),
twin = -1,
face = Face_Index(i),
next = Edge_Index(e1),
prev = Edge_Index(e2),
},
}
append(&edges, ..new_edges[:])
temp_indices: [][2]u16 = {
{min(i1, i2), max(i1, i2)},
{min(i2, i3), max(i2, i3)},
{min(i3, i1), max(i3, i1)},
}
for tmp_idx, j in temp_indices {
assert(temp_edges[tmp_idx].len < 2)
if temp_edges[tmp_idx].len > 0 {
// small_array.push_back(Edge_Index(e1 + j))
}
}
}
}