Files
Edit2D/entity.odin
T
SamratGhale d23c934662 Init
2026-03-10 22:11:28 +05:45

238 lines
4.7 KiB
Odin

package ion
import b2 "vendor:box2d"
import array "core:container/small_array"
static_index :: i32
static_index_global :: struct
{
index : i32,
level : string,
offset : b2.Vec2,
}
/*
This file contains code to handle box2d stuffs of the game code
Don't put game's logic here
*/
revolt_joint_def :: struct
{
using def : b2.RevoluteJointDef,
//Everything else can be stored in the def
entity_a, entity_b : static_index,
}
distance_joint_def :: struct
{
using def : b2.DistanceJointDef,
//Everything else can be stored in the def
entity_a, entity_b : static_index,
}
engine_world :: struct
{
world_id : b2.WorldId,
//This in engine code?
static_indexes : map[static_index]int `cbor:"-"`,
relations : map[^static_index][dynamic]static_index_global `cbor:"-"`,
relations_serializeable : map[ static_index][dynamic]static_index_global,
revolute_joint_defs : [dynamic]revolt_joint_def,
distant_joint_defs : [dynamic]distance_joint_def,
revolute_joints : [dynamic]b2.JointId,
}
engine_entity_flags_enum :: enum u64 {
POLYGON_IS_BOX,
MULTI_BODIES,
MULTI_SHAPES,
}
engine_entity_flags :: bit_set[engine_entity_flags_enum]
engine_entity_def :: struct {
body_def : b2.BodyDef,
shape_def : b2.ShapeDef,
shape_type : b2.ShapeType,
radius, scale : f32,
centers : [2]b2.Vec2,
size : b2.Vec2,
is_loop : bool,
vertices : array.Small_Array(b2.MAX_POLYGON_VERTICES, b2.Vec2),
name_buf : [255]u8 `fmt:"-" cbor:"-"`,
entity_flags : engine_entity_flags,
index : static_index,
body_count : int,
}
engine_entity :: struct {
body_id : b2.BodyId,
shape_id : b2.ShapeId,
//This is if the entity has multiple bodies
bodies : [dynamic]b2.BodyId,
shapes : [dynamic]b2.ShapeId,
joints : [dynamic]b2.JointId,
entity_flags : engine_entity_flags,
index : ^static_index,
}
engine_entity_single_body :: proc(def : ^engine_entity_def, world_id: b2.WorldId, index : i32) -> engine_entity
{
def := def
new_entity : engine_entity
if def.index != 0
{
new_entity.index = new(static_index)
new_entity.index^ = def.index
}
new_entity.body_id = b2.CreateBody(world_id, def.body_def)
switch def.shape_type{
case .circleShape:
{
def.radius *= def.scale
circle := b2.Circle{ radius = def.radius }
def.scale = 1
new_entity.shape_id = b2.CreateCircleShape(new_entity.body_id, def.shape_def, circle)
}
case .capsuleShape:
{
def.radius *= def.scale
def.centers[0] *= def.scale
def.centers[1] *= def.scale
def.scale = 1
capsule := b2.Capsule{
center1 = def.centers[0],
center2 = def.centers[1],
radius = def.radius
}
new_entity.shape_id = b2.CreateCapsuleShape(
new_entity.body_id,
def.shape_def,
capsule
)
}
case .chainSegmentShape:
{
chain_def := b2.DefaultChainDef()
verts :[dynamic]b2.Vec2
for &v in array.slice(&def.vertices){
v *= def.scale
}
for v in array.slice(&def.vertices){
//If it's not a looped chain then it needs two defination
if !def.is_loop do append(&verts, v)
append(&verts, v)
}
slice := array.slice(&def.vertices)
chain_def.points = &verts[0]
chain_def.count = i32(len(verts))
chain_def.isLoop = def.is_loop
c := b2.CreateChain(new_entity.body_id, chain_def)
shapes_data :[10]b2.ShapeId
shapes := b2.Body_GetShapes(new_entity.body_id, shapes_data[:])
for shape in shapes{
b2.Shape_SetUserData(shape, rawptr(uintptr(index)))
}
def.scale = 1
}
case .segmentShape:
{
for &v in array.slice(&def.vertices){
v *= def.scale
}
segment : b2.Segment = {point1 = array.get(def.vertices, 0), point2 = array.get(def.vertices, 2)}
new_entity.shape_id = b2.CreateSegmentShape(new_entity.body_id, def.shape_def, segment)
def.scale = 1
}
case .polygonShape:
{
poly : b2.Polygon
if .POLYGON_IS_BOX in def.entity_flags
{
def.size *= def.scale
poly = b2.MakeBox(def.size.x, def.size.y)
def.scale = 1
}else
{
//def.size *= def.scale
for &v in array.slice(&def.vertices){
v *= def.scale
}
points := make([dynamic]b2.Vec2, 0)
for p, i in array.slice(&def.vertices){
if i >= int(def.vertices.len) do break
append_elem(&points, p)
}
sort_points_ccw(points[:])
hull := b2.ComputeHull(points[:])
poly = b2.MakePolygon(hull, 0)
delete(points)
def.scale = 1
}
new_entity.shape_id = b2.CreatePolygonShape(new_entity.body_id, def.shape_def, poly)
}
}
if def.shape_type != .chainSegmentShape{
b2.Shape_SetUserData(new_entity.shape_id, rawptr(uintptr(index)))
}
return new_entity
}