235 lines
6.0 KiB
Odin
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)
|
|
// }
|
|
// }
|