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