Start implementing a span allocator

This commit is contained in:
Sergey Poznyak 2025-01-13 02:46:54 +04:00
parent 587104651c
commit 2b3739937a
4 changed files with 109 additions and 39 deletions

View File

@ -0,0 +1,81 @@
package spanpool
import "core:slice"
Element :: struct($E: typeid) {
value: $T,
gen: i32,
}
Span :: struct {
first, len: i32,
}
Span_Pool :: struct($E: typeid) {
elems: [dynamic]Element(E),
free_spans: [dynamic]Span,
}
Handle :: struct {
first: i32,
len: i32,
gen: i32,
}
allocate :: proc(s: ^$T/Span_Pool($E), elems: []T) -> (handle: Handle) {
handle = _allocate(s, len(elems))
for i in 0..<handle.len {
s.elems[i + handle.first].value = elems[i]
}
}
_allocate :: proc(s: ^$T/Span_Pool($E), count: i32) -> (handle: Handle) {
handle.len = count
maybe_existing_span: Maybe(i32)
for span, i in s.free_spans {
if span.len >= count {
maybe_existing_span = i
break
}
}
existing_span, ok := maybe_existing_span.?
if ok {
span := s.free_spans[existing_span]
handle.first = span.first
new_len := span.len - count
if new_len == 0 {
ordered_remove(&s.free_spans, existing_span)
} else {
s.free_spans[existing_span].first += count
s.free_spans[existing_span].len = new_len
}
} else {
handle.first = len(s.elems)
resize(&s.elems, len(s.elems) + count)
}
// Now figure out the generation index
max_gen := 0
for i in handle.first..<handle.first + handle.len {
gen = max(s.elems[i].gen)
}
handle.gen = max_gen + 1
for i in handle.first..<handle.first + handle.len {
s.elems[i].gen = handle.gen
}
return
}
free :: proc(s: ^$T/Span_Pool($E), handle: Handle) {
append(&s.free_spans, Span{first = handle.first, len = handle.len})
}
reconcile :: proc(s: ^$T/Span_Pool($E)) {
}

View File

@ -0,0 +1 @@
package spanpool

View File

@ -581,7 +581,7 @@ draw :: proc() {
mesh := car_model.meshes[hit_mesh_idx] mesh := car_model.meshes[hit_mesh_idx]
vertices := (cast([^]rl.Vector3)mesh.vertices)[:mesh.vertexCount] vertices := (cast([^]rl.Vector3)mesh.vertices)[:mesh.vertexCount]
indices := mesh.indices[:mesh.triangleCount * 3] indices := mesh.indices[:mesh.triangleCount * 3]
car_halfedge := halfedge.mesh_from_vertex_index_list(vertices, indices, context.temp_allocator) car_halfedge := halfedge.mesh_from_vertex_index_list(vertices, indices, 3, context.temp_allocator)
face_idx := halfedge.Face_Index(mesh_col.prim) face_idx := halfedge.Face_Index(mesh_col.prim)
face := car_halfedge.faces[face_idx] face := car_halfedge.faces[face_idx]

View File

@ -32,11 +32,13 @@ Half_Edge_Mesh :: struct {
mesh_from_vertex_index_list :: proc( mesh_from_vertex_index_list :: proc(
vertices: []Vec3, vertices: []Vec3,
indices: []u16, indices: []u16,
vertices_per_face: int = 3,
allocator := context.allocator, allocator := context.allocator,
) -> Half_Edge_Mesh { ) -> Half_Edge_Mesh {
num_faces := len(indices) / vertices_per_face
mesh: Half_Edge_Mesh mesh: Half_Edge_Mesh
verts := make([]Vertex, len(vertices), allocator) verts := make([]Vertex, len(vertices), allocator)
faces := make([]Face, len(indices) / 3, allocator) faces := make([]Face, num_faces, allocator)
edges := make([]Half_Edge, len(indices), allocator) edges := make([]Half_Edge, len(indices), allocator)
mesh.vertices = verts mesh.vertices = verts
@ -50,49 +52,35 @@ mesh_from_vertex_index_list :: proc(
temp_edges: map[[2]u16]Edge_Index = make_map(map[[2]u16]Edge_Index, context.temp_allocator) temp_edges: map[[2]u16]Edge_Index = make_map(map[[2]u16]Edge_Index, context.temp_allocator)
triangle_num := len(indices) / 3 for f in 0 ..< num_faces {
for i in 0 ..< triangle_num { for i in 0..<vertices_per_face {
i1, i2, i3 := indices[i * 3 + 0], indices[i * 3 + 1], indices[i * 3 + 2] e := f * vertices_per_face + i
// v1, v2, v3 := vertices[i1], vertices[i2], vertices[i3] index := indices[e]
e1, e2, e3 := i * 3 + 0, i * 3 + 1, i * 3 + 2
faces[i].edge = Edge_Index(e1) if i == 0 {
edges[e1] = { faces[f].edge = Edge_Index(e)
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 { next_edge := f * vertices_per_face + ((i + 1) % vertices_per_face)
{min(i1, i2), max(i1, i2)}, prev_edge := f * vertices_per_face + ((i - 1) % vertices_per_face)
{min(i2, i3), max(i2, i3)},
{min(i3, i1), max(i3, i1)},
}
for stable_idx, j in edge_stable_indices { edges[e] = {
origin = Vertex_Index(index),
twin = -1,
face = Face_Index(f),
next = Edge_Index(next_edge),
prev = Edge_Index(prev_edge),
}
next_index := indices[next_edge]
stable_idx := [2]u16{min(index, next_index), max(index, next_index)}
twin, ok := temp_edges[stable_idx] twin, ok := temp_edges[stable_idx]
ei := i * 3 + j
if ok { if ok {
edges[ei].twin = twin edges[e].twin = twin
edges[twin].twin = Edge_Index(ei) edges[twin].twin = Edge_Index(e)
} else { } else {
temp_edges[stable_idx] = Edge_Index(ei) temp_edges[stable_idx] = Edge_Index(e)
} }
} }
} }