From 493338d91b67796790bc3e6f2c920084fce97454 Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 17 Mar 2026 09:34:15 +0545 Subject: [PATCH] Refactor --- entity.odin | 103 ++++++++++++++++++++++++++++++++++++------ interface.odin | 5 +- interface_entity.odin | 27 +++++------ interface_joints.odin | 2 +- ion.odin | 1 + 5 files changed, 107 insertions(+), 31 deletions(-) diff --git a/entity.odin b/entity.odin index 9e1f6d0..b2dba45 100644 --- a/entity.odin +++ b/entity.odin @@ -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 +} + + + diff --git a/interface.odin b/interface.odin index 5458d3a..ddffcbd 100644 --- a/interface.odin +++ b/interface.odin @@ -1,6 +1,5 @@ package ion import "core:slice" -import "core:container/small_array" import "core:fmt" import im "shared:odin-imgui" import b2 "vendor:box2d" @@ -20,6 +19,7 @@ EditMode :: enum ENTITY, VERTICES, OVERVIEW, + CHAIN, JOINT, } @@ -32,6 +32,8 @@ interface_state :: struct state : ^engine_state, vertex_index : ^i32, + chain_index : ^i32, + edit_mode : EditMode, curr_joint_index : i32, @@ -43,6 +45,7 @@ interface_state :: struct interface_draw_options :: proc(state: ^engine_state) { debug_draw := &state.draw.debug_draw + im.SliderFloat("Zoom", &state.draw.cam.zoom, 0, 100) im.Checkbox("Shapes", &debug_draw.drawShapes) im.Checkbox("Joints", &debug_draw.drawJoints) im.Checkbox("Joint Extras", &debug_draw.drawJointExtras) diff --git a/interface_entity.odin b/interface_entity.odin index 125560b..62b4164 100644 --- a/interface_entity.odin +++ b/interface_entity.odin @@ -3,7 +3,6 @@ package ion import b2 "vendor:box2d" import im "shared:odin-imgui" import "core:slice" -import "core:container/small_array" import "core:fmt" @@ -174,8 +173,8 @@ interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool im.SliderFloat("Density", &def.shape_def.density, 0, 100) - if im.Button("Flip horizontally") do flip_points(small_array.slice(&def.vertices), .Horizontal) - if im.Button("Flip Vertically ") do flip_points(small_array.slice(&def.vertices), .Vertical) + if im.Button("Flip horizontally") do flip_points(def.vertices[:], .Horizontal) + if im.Button("Flip Vertically ") do flip_points(def.vertices[:], .Vertical) if im.TreeNode("Events and contacts") { im.Checkbox("Is sensor", &def.shape_def.isSensor) @@ -217,7 +216,7 @@ interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool interface_entity :: proc(interface: ^interface_state) -> bool { - entity_selected := interface.selected_entity^ != -1 + entity_selected := (interface.selected_entity^ != -1) && len(interface.entity_defs) > 0 if entity_selected { @@ -226,7 +225,7 @@ interface_entity :: proc(interface: ^interface_state) -> bool ret := false - interface.edit_mode = .ENTITY + //interface.edit_mode = .ENTITY //Flags for flag in engine_entity_flags_enum { @@ -234,14 +233,6 @@ interface_entity :: proc(interface: ^interface_state) -> bool if im.Checkbox(fmt.ctprint(flag), &contains) do def.entity_flags ~= {flag} } - if .CHAIN in def.entity_flags - { - - im.InputInt("Body Count", &def.body_count, 1) - im.SliderFloat("Half Link Length", &def.half_link_length, 1, 10) - - } - im.Separator() if im.CollapsingHeader("Shape Edit") @@ -263,10 +254,16 @@ interface_entity :: proc(interface: ^interface_state) -> bool if .CHAIN in def.entity_flags { - interface_edit_rev_joint_minimal(&def.rev_joint) + im.InputInt("Body Count", &def.body_count) + //im.SliderFloat2("Half Link Length", &def.link_length, -10, 10) + + if im.CollapsingHeader("Chain joint def") + { + interface_edit_rev_joint_minimal(&def.rev_joint) + } } - return def^ != def_old || ret + return !compare_engine_entity_def(def^, def_old) || ret } return false diff --git a/interface_joints.odin b/interface_joints.odin index 6749454..c214962 100644 --- a/interface_joints.odin +++ b/interface_joints.odin @@ -267,7 +267,7 @@ interface_edit_revolute_joint :: proc( interface : ^interface_state ) -> bool interface_joints :: proc(interface: ^interface_state) -> bool { ret := false - interface.edit_mode = .JOINT + //interface.edit_mode = .JOINT if im.BeginCombo("Joint type", fmt.ctprint(interface.curr_joint_type)) { diff --git a/ion.odin b/ion.odin index 6daa650..81e7115 100644 --- a/ion.odin +++ b/ion.odin @@ -102,6 +102,7 @@ engine_init :: proc(state: ^engine_state) return nil }, }, 201, rawptr) + } update_frame :: proc(state: ^engine_state)