This commit is contained in:
sam
2026-03-17 09:34:15 +05:45
parent 0fe796ea19
commit 493338d91b
5 changed files with 107 additions and 31 deletions
+89 -14
View File
@@ -1,7 +1,7 @@
package ion
import b2 "vendor:box2d"
import array "core:container/small_array"
import "core:fmt"
static_index :: i32
@@ -41,6 +41,7 @@ engine_entity_flags_enum :: enum u64 {
POLYGON_IS_BOX,
MULTI_BODIES,
CHAIN,
CHAIN_CUSTOM,
MULTI_SHAPES,
}
@@ -56,7 +57,8 @@ engine_entity_def :: struct {
centers : [2]b2.Vec2,
size : b2.Vec2,
is_loop : bool,
vertices : array.Small_Array(b2.MAX_POLYGON_VERTICES, b2.Vec2),
vertices : [dynamic; b2.MAX_POLYGON_VERTICES]b2.Vec2,
name_buf : [255]u8 `fmt:"-" cbor:"-"`,
entity_flags : engine_entity_flags,
@@ -65,11 +67,47 @@ engine_entity_def :: struct {
//For chain bodies
//It will replicate itself to the body count and connect themselves with rev_joints
body_count : i32,
rev_joint : b2.RevoluteJointDef,
half_link_length : f32
body_count : i32,
//If chain not custom then the dynamic list of link_length will be used to create the chain
//Handle the link_length like vertices
rev_joint : b2.RevoluteJointDef,
link_length_array : [dynamic]b2.Vec2,
}
compare_engine_entity_def :: proc(a, b : engine_entity_def) -> bool
{
ret := false
ret &= a.body_def == b.body_def
ret &= a.shape_def == b.shape_def
ret &= a.shape_type == b.shape_type
ret &= a.radius == b.radius
ret &= a.scale == b.scale
ret &= a.centers == b.centers
ret &= a.size == b.size
ret &= a.is_loop == b.is_loop
//ret &= a.vertices[:] == b.vertices[:]
ret &= a.name_buf == b.name_buf
if a.entity_flags != b.entity_flags{
fmt.println("Hello world")
}
ret &= a.entity_flags == b.entity_flags
ret &= a.index == b.index
ret &= a.body_count == b.body_count
ret &= a.rev_joint == b.rev_joint
//ret &= a.link_length[:] == b.link_length[:]
return ret
}
engine_entity :: struct {
body_id : b2.BodyId,
shape_id : b2.ShapeId,
@@ -132,17 +170,17 @@ engine_entity_single_body :: proc(def : ^engine_entity_def, world_id: b2.WorldId
capsule
)
}
case .chainSegmentShape:
case .chainSegmentShape:
{
chain_def := b2.DefaultChainDef()
verts :[dynamic]b2.Vec2
for &v in array.slice(&def.vertices){
for &v in def.vertices[:]{
v *= def.scale
}
for v in array.slice(&def.vertices){
for v in def.vertices[:]{
//If it's not a looped chain then it needs two defination
if !def.is_loop do append(&verts, v)
@@ -150,7 +188,6 @@ engine_entity_single_body :: proc(def : ^engine_entity_def, world_id: b2.WorldId
append(&verts, v)
}
slice := array.slice(&def.vertices)
chain_def.points = &verts[0]
chain_def.count = i32(len(verts))
@@ -171,10 +208,10 @@ engine_entity_single_body :: proc(def : ^engine_entity_def, world_id: b2.WorldId
}
case .segmentShape:
{
for &v in array.slice(&def.vertices){
for &v in def.vertices[:]{
v *= def.scale
}
segment : b2.Segment = {point1 = array.get(def.vertices, 0), point2 = array.get(def.vertices, 2)}
segment : b2.Segment = {point1 = def.vertices[0], point2 = def.vertices[2]}
new_entity.shape_id = b2.CreateSegmentShape(new_entity.body_id, def.shape_def, segment)
def.scale = 1
@@ -193,14 +230,14 @@ engine_entity_single_body :: proc(def : ^engine_entity_def, world_id: b2.WorldId
{
//def.size *= def.scale
for &v in array.slice(&def.vertices){
for &v in 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
for p, i in def.vertices[:]{
if i >= int(len(def.vertices)) do break
append_elem(&points, p)
}
sort_points_ccw(points[:])
@@ -222,6 +259,44 @@ engine_entity_single_body :: proc(def : ^engine_entity_def, world_id: b2.WorldId
return new_entity
}
engine_create_chain_shape :: proc(def : ^engine_entity_def, world_id: b2.WorldId, index : i32) -> engine_entity
{
joint_def := def.rev_joint
orig_pos := def.body_def.position
position := def.body_def.position
prev_body_id : b2.BodyId
engine_entity := engine_entity_single_body(def, world_id, index)
for i in def.link_length_array[:]
{
rot := b2.ComputeRotationBetweenUnitVectors(def.body_def.position, position)
def.body_def.rotation = rot
def.body_def.position = position
engine_entity = engine_entity_single_body(def, world_id, index)
pivot := position - i
if i != 0
{
joint_def.bodyIdA = prev_body_id
joint_def.bodyIdB = engine_entity.body_id
joint_def.localAnchorA = b2.Body_GetLocalPoint(joint_def.bodyIdA, pivot)
joint_def.localAnchorB = b2.Body_GetLocalPoint(joint_def.bodyIdB, pivot)
joint_id := b2.CreateRevoluteJoint(world_id, joint_def)
}
position += 2 * i
prev_body_id = engine_entity.body_id
}
def.body_def.position = orig_pos
return engine_entity
}