Start implementing a span allocator
This commit is contained in:
parent
587104651c
commit
2b3739937a
81
game/container/spanpool/doc.odin
Normal file
81
game/container/spanpool/doc.odin
Normal 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)) {
|
||||||
|
|
||||||
|
}
|
1
game/container/spanpool/spanpool.odin
Normal file
1
game/container/spanpool/spanpool.odin
Normal file
@ -0,0 +1 @@
|
|||||||
|
package spanpool
|
@ -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]
|
||||||
|
@ -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)},
|
edges[e] = {
|
||||||
|
origin = Vertex_Index(index),
|
||||||
|
twin = -1,
|
||||||
|
face = Face_Index(f),
|
||||||
|
next = Edge_Index(next_edge),
|
||||||
|
prev = Edge_Index(prev_edge),
|
||||||
}
|
}
|
||||||
|
|
||||||
for stable_idx, j in edge_stable_indices {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user