235 lines
6.0 KiB
Odin

package physics
import "game:container/spanpool"
import he "game:halfedge"
import "libs:tracy"
Convex_Container :: struct {
vertices: spanpool.Span_Pool(he.Vertex),
faces: spanpool.Span_Pool(he.Face),
edges: spanpool.Span_Pool(he.Half_Edge),
}
Convex_Handle :: struct {
vertices: spanpool.Handle,
faces: spanpool.Handle,
edges: spanpool.Handle,
}
convex_container_add :: proc(
container: ^Convex_Container,
mesh: he.Half_Edge_Mesh,
) -> (
handle: Convex_Handle,
) {
handle.vertices = spanpool.allocate_elems(&container.vertices, ..mesh.vertices)
handle.faces = spanpool.allocate_elems(&container.faces, ..mesh.faces)
handle.edges = spanpool.allocate_elems(&container.edges, ..mesh.edges)
return
}
convex_container_get_mesh :: proc(
container: ^Convex_Container,
handle: Convex_Handle,
) -> (
mesh: he.Half_Edge_Mesh,
) {
tracy.Zone()
mesh.vertices = spanpool.resolve_slice(&container.vertices, handle.vertices)
mesh.faces = spanpool.resolve_slice(&container.faces, handle.faces)
mesh.edges = spanpool.resolve_slice(&container.edges, handle.edges)
// TODO: save and return mesh center
avg_scale := 1.0 / f32(len(mesh.vertices))
for v in mesh.vertices {
mesh.center += v.pos * avg_scale
}
return
}
convex_container_remove :: proc(container: ^Convex_Container, handle: Convex_Handle) {
spanpool.free(&container.vertices, handle.vertices)
spanpool.free(&container.faces, handle.faces)
spanpool.free(&container.edges, handle.edges)
}
convex_container_reconcile :: proc(container: ^Convex_Container) {
spanpool.reconcile(&container.vertices)
spanpool.reconcile(&container.faces)
spanpool.reconcile(&container.edges)
}
convex_container_copy :: proc(dst: ^Convex_Container, src: Convex_Container) {
spanpool.copy(&dst.vertices, src.vertices)
spanpool.copy(&dst.faces, src.faces)
spanpool.copy(&dst.edges, src.edges)
}
convex_container_destroy :: proc(container: ^Convex_Container) {
spanpool.destroy_spanpool(&container.vertices)
spanpool.destroy_spanpool(&container.faces)
spanpool.destroy_spanpool(&container.edges)
}
//
// import "core:container/intrusive/list"
// import "game:container/spanpool"
// import "game:halfedge"
// import rl "libs:raylib"
//
// Shape_Container :: struct {
// shapes: spanpool.Span_Pool(Shape_Instance),
// }
//
// destroy_shape_container :: proc(container: ^Shape_Container) {
// spanpool.destroy_spanpool(&container.shapes)
// }
//
// Shape_Handle :: distinct spanpool.Handle
//
// Shape_Sphere :: struct {
// radius: f32,
// }
//
// Shape_Convex :: struct {
// using mesh: halfedge.Half_Edge_Mesh,
// }
//
// box_to_convex :: proc(box: Shape_Box, allocator := context.allocator) -> (convex: Shape_Convex) {
// vertices := make([]Vec3, 8, context.temp_allocator)
//
// for corner, i in BOX_CORNERS_NORM {
// vertices[i] = corner * box.size
// }
//
// convex.mesh = halfedge.mesh_from_vertex_index_list(vertices, box_indices[:], 4, allocator)
//
// return
// }
//
// Shape_Box :: struct {
// size: Vec3,
// }
//
// Shape_Union :: struct {
// children: Shape_Handle,
// }
//
// Shape_Variant :: union {
// Shape_Sphere,
// Shape_Box,
// Shape_Union,
// }
//
// Shape_Instance :: struct {
// pos: Vec3,
// rot: Quat,
// shape: Shape_Variant,
// }
//
// Shape_Desc_Union :: struct {
// children: list.List,
// }
//
// Shape_Desc_Variant :: union {
// Shape_Desc_Union,
// Shape_Sphere,
// Shape_Box,
// }
//
// Shape_Desc :: struct {
// pos: Vec3,
// rot: Quat,
// shape: Shape_Desc_Variant,
// using link: list.Node,
// }
//
// shape_desc_add_child :: proc(
// desc: ^Shape_Desc,
// child: Shape_Desc,
// allocator := context.temp_allocator,
// ) {
// union_shape := desc.shape.(Shape_Desc_Union)
//
// allocated_child := new(Shape_Desc, allocator)
// allocated_child^ = child
//
// list.push_back(&union_shape.children, &allocated_child.link)
// }
//
// shape_container_add :: proc(
// c: ^Shape_Container,
// desc: Shape_Desc,
// loc := #caller_location,
// ) -> Shape_Handle {
// root_handle := spanpool.allocate_num(&c.shapes, 1)
// shape_container_add_internal(c, Shape_Handle(root_handle), 0, desc, loc = loc)
// return Shape_Handle(root_handle)
// }
//
// shape_container_free :: proc(c: ^Shape_Container, handle: Shape_Handle, loc := #caller_location) {
// assert(handle.len == 1)
//
// shape_container_free_internal(c, handle, 0, loc = loc)
// spanpool.free(&c.shapes, spanpool.Handle(handle), loc = loc)
// }
//
// shape_container_add_internal :: proc(
// c: ^Shape_Container,
// handle: Shape_Handle,
// idx: i32,
// desc: Shape_Desc,
// loc := #caller_location,
// ) {
// shape_ptr := &spanpool.resolve_slice(&c.shapes, spanpool.Handle(handle))[idx]
// switch s in desc.shape {
// case Shape_Sphere:
// shape_ptr.shape = s
// case Shape_Box:
// shape_ptr.shape = s
// case Shape_Desc_Union:
// child_len: i32
// {
// it := list.iterator_head(s.children, Shape_Desc, "link")
// for child in list.iterate_next(&it) {
// child_len += 1
// }
// }
// {
// children_handle := spanpool.allocate_num(&c.shapes, child_len)
// shape_ptr = &spanpool.resolve_slice(&c.shapes, spanpool.Handle(handle))[idx] // Re-resolve handle because spanpool might have reallocated
//
// shape_ptr.shape = Shape_Union {
// children = Shape_Handle(children_handle),
// }
//
// it := list.iterator_head(s.children, Shape_Desc, "link")
// i: i32
// for child in list.iterate_next(&it) {
// shape_container_add_internal(c, Shape_Handle(children_handle), i, child^)
// i += 1
// }
// }
// }
// }
//
// shape_container_free_internal :: proc(
// c: ^Shape_Container,
// handle: Shape_Handle,
// idx: i32,
// loc := #caller_location,
// ) {
// shape := spanpool.resolve_slice(&c.shapes, spanpool.Handle(handle))[idx]
// switch s in shape.shape {
// case Shape_Box, Shape_Sphere:
// // Nothing to do
// case Shape_Union:
// for i in 0 ..< s.children.len {
// shape_container_free_internal(c, s.children, i)
// }
// spanpool.free(&c.shapes, spanpool.Handle(s.children), loc = loc)
// }
// }