Code refactor, create chain
This commit is contained in:
+6
-21
@@ -17,26 +17,6 @@ static_index_global :: struct
|
|||||||
Don't put game's logic here
|
Don't put game's logic here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
joint_common :: struct
|
|
||||||
{
|
|
||||||
entity_a, entity_b : static_index,
|
|
||||||
bodyIdA, bodyIdB : b2.BodyId,
|
|
||||||
}
|
|
||||||
|
|
||||||
revolt_joint_def :: struct
|
|
||||||
{
|
|
||||||
//Everything else can be stored in the def
|
|
||||||
entity_a, entity_b : static_index,
|
|
||||||
|
|
||||||
using def : b2.RevoluteJointDef,
|
|
||||||
}
|
|
||||||
|
|
||||||
distance_joint_def :: struct
|
|
||||||
{
|
|
||||||
entity_a, entity_b : static_index,
|
|
||||||
using def : b2.DistanceJointDef,
|
|
||||||
}
|
|
||||||
|
|
||||||
engine_world :: struct
|
engine_world :: struct
|
||||||
{
|
{
|
||||||
world_id : b2.WorldId,
|
world_id : b2.WorldId,
|
||||||
@@ -60,6 +40,7 @@ engine_world :: struct
|
|||||||
engine_entity_flags_enum :: enum u64 {
|
engine_entity_flags_enum :: enum u64 {
|
||||||
POLYGON_IS_BOX,
|
POLYGON_IS_BOX,
|
||||||
MULTI_BODIES,
|
MULTI_BODIES,
|
||||||
|
CHAIN,
|
||||||
MULTI_SHAPES,
|
MULTI_SHAPES,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +63,11 @@ engine_entity_def :: struct {
|
|||||||
|
|
||||||
index : static_index,
|
index : static_index,
|
||||||
|
|
||||||
body_count : int,
|
//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
|
||||||
}
|
}
|
||||||
|
|
||||||
engine_entity :: struct {
|
engine_entity :: struct {
|
||||||
|
|||||||
+34
-365
@@ -40,373 +40,25 @@ interface_state :: struct
|
|||||||
curr_static_index : static_index_global,
|
curr_static_index : static_index_global,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface_body_def_editor :: proc(def: ^engine_entity_def)
|
|
||||||
{
|
|
||||||
if im.BeginCombo("Body Type", fmt.ctprint(def.body_def.type))
|
|
||||||
{
|
|
||||||
for type in b2.BodyType
|
|
||||||
{
|
|
||||||
if im.Selectable(fmt.ctprint(type), def.body_def.type == type) do def.body_def.type = type
|
|
||||||
}
|
|
||||||
im.EndCombo()
|
|
||||||
}
|
|
||||||
|
|
||||||
im.SliderFloat2("Position", &def.body_def.position, -50, 50)
|
|
||||||
|
|
||||||
angle := RAD2DEG * b2.Rot_GetAngle(def.body_def.rotation)
|
|
||||||
|
|
||||||
if im.SliderFloat("Rotation", &angle, 0, 359)
|
|
||||||
{
|
|
||||||
rad := DEG2RAD * angle
|
|
||||||
def.body_def.rotation = b2.MakeRot(rad)
|
|
||||||
}
|
|
||||||
|
|
||||||
im.SliderFloat2("Linear velocity", &def.body_def.linearVelocity, 0, 500)
|
|
||||||
im.SliderFloat("Angular velocity", &def.body_def.angularVelocity, 0, 500)
|
|
||||||
im.SliderFloat("Linear Damping", &def.body_def.linearDamping, 0, 500)
|
|
||||||
im.SliderFloat("Angular Damping", &def.body_def.angularDamping, 0, 500)
|
|
||||||
im.SliderFloat("Gravity Scale", &def.body_def.gravityScale, 0, 100)
|
|
||||||
|
|
||||||
im.Checkbox("Fixed rotation", &def.body_def.fixedRotation)
|
|
||||||
|
|
||||||
if im.InputText("Body Name", cstring(&def.name_buf[0]), 255) {
|
|
||||||
def.body_def.name = cstring(&def.name_buf[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool
|
|
||||||
{
|
|
||||||
shape_def := &def.shape_def
|
|
||||||
|
|
||||||
|
|
||||||
if im.BeginCombo("Shape Type", fmt.ctprint(def.shape_type)) {
|
|
||||||
|
|
||||||
for type in b2.ShapeType
|
|
||||||
{
|
|
||||||
if im.Selectable(fmt.ctprint(type), def.shape_type == type)
|
|
||||||
{
|
|
||||||
def.shape_type = type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
im.EndCombo()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch def.shape_type {
|
|
||||||
|
|
||||||
case .circleShape:
|
|
||||||
{
|
|
||||||
im.SliderFloat("radius", &def.radius, 0, 40)
|
|
||||||
}
|
|
||||||
|
|
||||||
case .polygonShape:
|
|
||||||
{
|
|
||||||
im.SliderFloat2("Size", &def.size, -500, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
case .capsuleShape:
|
|
||||||
{
|
|
||||||
im.SliderFloat2("Center 1", &def.centers[0], -100, 100)
|
|
||||||
im.SliderFloat2("Center 2", &def.centers[0], -100, 100)
|
|
||||||
im.SliderFloat("Radius", &def.radius, 0, 40)
|
|
||||||
}
|
|
||||||
|
|
||||||
case .chainSegmentShape:
|
|
||||||
{
|
|
||||||
im.Checkbox("is loop", &def.is_loop)
|
|
||||||
}
|
|
||||||
|
|
||||||
case .segmentShape:
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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.TreeNode("Events and contacts") {
|
|
||||||
im.Checkbox("Is sensor", &def.shape_def.isSensor)
|
|
||||||
im.Checkbox("Enable Sensor Events", &def.shape_def.enableSensorEvents)
|
|
||||||
im.Checkbox("Enable Contact Events", &def.shape_def.enableContactEvents)
|
|
||||||
im.Checkbox("Enable Hit Events", &def.shape_def.enableHitEvents)
|
|
||||||
im.Checkbox("Enable Presolve Events", &def.shape_def.enablePreSolveEvents)
|
|
||||||
im.Checkbox("Invoke contact Creation", &def.shape_def.invokeContactCreation)
|
|
||||||
im.Checkbox("Update body mass ", &def.shape_def.updateBodyMass)
|
|
||||||
im.TreePop()
|
|
||||||
}
|
|
||||||
|
|
||||||
if im.TreeNode("Material") {
|
|
||||||
im.Separator()
|
|
||||||
|
|
||||||
im.SliderFloat("Friction", &def.shape_def.material.friction, 0, 1)
|
|
||||||
im.SliderFloat("Restitution", &def.shape_def.material.restitution, 0, 1)
|
|
||||||
im.SliderFloat("Rolling Resistance", &def.shape_def.material.rollingResistance, 0, 1)
|
|
||||||
im.SliderFloat("Tangent Speed", &def.shape_def.material.tangentSpeed, 0, 1)
|
|
||||||
im.InputInt("User material id", &def.shape_def.material.userMaterialId)
|
|
||||||
|
|
||||||
//Colorpicker
|
|
||||||
|
|
||||||
if im.TreeNode("Color") {
|
|
||||||
color_f32 := u32_to_float4(def.shape_def.material.customColor)
|
|
||||||
|
|
||||||
if im.ColorPicker4("Custom Color", &color_f32, {.Uint8, .InputRGB}) {
|
|
||||||
def.shape_def.material.customColor = float4_to_u32(color_f32)
|
|
||||||
}
|
|
||||||
im.TreePop()
|
|
||||||
}
|
|
||||||
|
|
||||||
im.Separator()
|
|
||||||
im.TreePop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
interface_draw_options :: proc(state: ^engine_state) {
|
interface_draw_options :: proc(state: ^engine_state) {
|
||||||
if im.BeginTabItem("Controls") {
|
debug_draw := &state.draw.debug_draw
|
||||||
debug_draw := &state.draw.debug_draw
|
|
||||||
|
|
||||||
im.Checkbox("Shapes", &debug_draw.drawShapes)
|
im.Checkbox("Shapes", &debug_draw.drawShapes)
|
||||||
im.Checkbox("Joints", &debug_draw.drawJoints)
|
im.Checkbox("Joints", &debug_draw.drawJoints)
|
||||||
im.Checkbox("Joint Extras", &debug_draw.drawJointExtras)
|
im.Checkbox("Joint Extras", &debug_draw.drawJointExtras)
|
||||||
im.Checkbox("Bounds", &debug_draw.drawBounds)
|
im.Checkbox("Bounds", &debug_draw.drawBounds)
|
||||||
im.Checkbox("Contact Points", &debug_draw.drawContacts)
|
im.Checkbox("Contact Points", &debug_draw.drawContacts)
|
||||||
im.Checkbox("Contact Normals", &debug_draw.drawContactNormals)
|
im.Checkbox("Contact Normals", &debug_draw.drawContactNormals)
|
||||||
im.Checkbox("Contact Inpulses", &debug_draw.drawContactImpulses)
|
im.Checkbox("Contact Inpulses", &debug_draw.drawContactImpulses)
|
||||||
im.Checkbox("Contact Features", &debug_draw.drawContactFeatures)
|
im.Checkbox("Contact Features", &debug_draw.drawContactFeatures)
|
||||||
im.Checkbox("Friction Inpulses", &debug_draw.drawFrictionImpulses)
|
im.Checkbox("Friction Inpulses", &debug_draw.drawFrictionImpulses)
|
||||||
im.Checkbox("Mass ", &debug_draw.drawMass)
|
im.Checkbox("Mass ", &debug_draw.drawMass)
|
||||||
im.Checkbox("Body Names", &debug_draw.drawBodyNames)
|
im.Checkbox("Body Names", &debug_draw.drawBodyNames)
|
||||||
im.Checkbox("Graph Colors", &debug_draw.drawGraphColors)
|
im.Checkbox("Graph Colors", &debug_draw.drawGraphColors)
|
||||||
im.Checkbox("Islands ", &debug_draw.drawIslands)
|
im.Checkbox("Islands ", &debug_draw.drawIslands)
|
||||||
|
im.SliderFloat("Rotation", &state.draw.cam.rotation, 0, 360)
|
||||||
im.SliderFloat("Rotation", &state.draw.cam.rotation, 0, 360)
|
|
||||||
|
|
||||||
im.EndTabItem()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_entity_def) -> bool
|
|
||||||
{
|
|
||||||
|
|
||||||
curr_index := &interface.curr_static_index
|
|
||||||
entity := interface.entities[interface.selected_entity^]
|
|
||||||
|
|
||||||
level := interface.world
|
|
||||||
|
|
||||||
|
|
||||||
if level.relations[entity.index] == nil
|
|
||||||
{
|
|
||||||
level.relations[entity.index] = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
indexes := &level.relations[entity.index]
|
|
||||||
|
|
||||||
if im.InputInt("Index Value", &def.index) do return true
|
|
||||||
|
|
||||||
ret := false
|
|
||||||
|
|
||||||
if def.index != 0
|
|
||||||
{
|
|
||||||
//For now only select from current room
|
|
||||||
|
|
||||||
if im.BeginCombo("Edit Select index", fmt.ctprint(curr_index.index))
|
|
||||||
{
|
|
||||||
for index in level.static_indexes
|
|
||||||
{
|
|
||||||
if im.Selectable(fmt.ctprint(index), curr_index.index == index)
|
|
||||||
{
|
|
||||||
curr_index.index = index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
im.EndCombo()
|
|
||||||
}
|
|
||||||
if curr_index.index != 0
|
|
||||||
{
|
|
||||||
if indexes != nil
|
|
||||||
{
|
|
||||||
if im.Button("Add relation")
|
|
||||||
{
|
|
||||||
if !slice.contains(indexes[:], interface.curr_static_index)
|
|
||||||
{
|
|
||||||
append(indexes, interface.curr_static_index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if indexes != nil{
|
|
||||||
for val, i in indexes
|
|
||||||
{
|
|
||||||
im.Text("%d", val.index)
|
|
||||||
im.SameLine()
|
|
||||||
if im.Button("Delete") {
|
|
||||||
ordered_remove(indexes, i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
interface_edit_revolute_joint :: proc(interface: ^interface_state) -> bool
|
|
||||||
{
|
|
||||||
//Select static index and then get bodyId from it
|
|
||||||
//If chain shapre then allow choosing index
|
|
||||||
|
|
||||||
level := interface.world
|
|
||||||
|
|
||||||
joint_def := interface.curr_revolt_joint
|
|
||||||
|
|
||||||
if im.BeginCombo("Index A", fmt.ctprint(joint_def.entity_a))
|
|
||||||
{
|
|
||||||
|
|
||||||
for i in level.static_indexes
|
|
||||||
{
|
|
||||||
if im.Selectable(fmt.ctprint(i), i == joint_def.entity_a)
|
|
||||||
{
|
|
||||||
joint_def.entity_a = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
im.EndCombo()
|
|
||||||
}
|
|
||||||
|
|
||||||
im.Separator()
|
|
||||||
|
|
||||||
if im.BeginCombo("Index B", fmt.ctprint(joint_def.entity_b))
|
|
||||||
{
|
|
||||||
|
|
||||||
for i in level.static_indexes
|
|
||||||
{
|
|
||||||
if im.Selectable(fmt.ctprint(i), i == joint_def.entity_b)
|
|
||||||
{
|
|
||||||
joint_def.entity_b = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
im.EndCombo()
|
|
||||||
}
|
|
||||||
|
|
||||||
//Now box2d
|
|
||||||
|
|
||||||
im.SliderFloat2("localAnchorA", &joint_def.localAnchorA, -5, 5)
|
|
||||||
im.SliderFloat2("localAnchorB", &joint_def.localAnchorB, -5, 5)
|
|
||||||
|
|
||||||
//Convert to degree to radian
|
|
||||||
im.SliderFloat("Reference Angle", &joint_def.referenceAngle, 0, 100)
|
|
||||||
im.SliderFloat("Target Angle", &joint_def.targetAngle, 0, 100)
|
|
||||||
|
|
||||||
im.Checkbox("Enable Spring", &joint_def.enableSpring)
|
|
||||||
|
|
||||||
im.InputFloat("Hertz ", &joint_def.hertz)
|
|
||||||
|
|
||||||
im.InputFloat("Damping Ratio", &joint_def.dampingRatio)
|
|
||||||
|
|
||||||
im.Checkbox("Enable Limit", &joint_def.enableLimit)
|
|
||||||
|
|
||||||
im.InputFloat("Lower Angle", &joint_def.lowerAngle)
|
|
||||||
im.InputFloat("Upper Angle", &joint_def.upperAngle)
|
|
||||||
|
|
||||||
im.Checkbox("Enable Motor", &joint_def.enableMotor)
|
|
||||||
im.InputFloat("Moror Torque", &joint_def.maxMotorTorque)
|
|
||||||
im.InputFloat("Moror Speed", &joint_def.motorSpeed)
|
|
||||||
im.InputFloat("Draw Size", &joint_def.drawSize)
|
|
||||||
im.Checkbox("Collide Connected", &joint_def.collideConnected)
|
|
||||||
|
|
||||||
if im.Button("Add joint")
|
|
||||||
{
|
|
||||||
//append(&level.revolute_joint_defs, interface.curr_revolt_joint)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
interface_entity :: proc(interface: ^interface_state) -> bool
|
|
||||||
{
|
|
||||||
|
|
||||||
entity_selected := interface.selected_entity^ != -1
|
|
||||||
|
|
||||||
if entity_selected
|
|
||||||
{
|
|
||||||
def := interface.entity_defs[interface.selected_entity^]
|
|
||||||
def_old := def^
|
|
||||||
|
|
||||||
ret := false
|
|
||||||
|
|
||||||
if im.BeginTabItem("Entity", nil, {.Leading})
|
|
||||||
{
|
|
||||||
interface.edit_mode = .ENTITY
|
|
||||||
//Flags
|
|
||||||
for flag in engine_entity_flags_enum
|
|
||||||
{
|
|
||||||
contains := flag in def.entity_flags
|
|
||||||
if im.Checkbox(fmt.ctprint(flag), &contains)
|
|
||||||
{
|
|
||||||
def.entity_flags ~= {flag}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
im.Separator()
|
|
||||||
|
|
||||||
if im.CollapsingHeader("Shape Edit")
|
|
||||||
{
|
|
||||||
interface_shape_def_editor(def)
|
|
||||||
}
|
|
||||||
|
|
||||||
im.Separator()
|
|
||||||
|
|
||||||
if im.CollapsingHeader("Body Edit")
|
|
||||||
{
|
|
||||||
interface_body_def_editor(def)
|
|
||||||
}
|
|
||||||
|
|
||||||
if im.CollapsingHeader("Static Index")
|
|
||||||
{
|
|
||||||
ret |= interface_edit_static_index(interface, def)
|
|
||||||
}
|
|
||||||
|
|
||||||
im.EndTabItem()
|
|
||||||
}
|
|
||||||
|
|
||||||
if im.BeginTabItem("Joints", nil , {})
|
|
||||||
{
|
|
||||||
interface.edit_mode = .JOINT
|
|
||||||
|
|
||||||
if im.BeginCombo("Joint type", fmt.ctprint(interface.curr_joint_type))
|
|
||||||
{
|
|
||||||
for type in b2.JointType
|
|
||||||
{
|
|
||||||
if im.Selectable(fmt.ctprint(type), type == interface.curr_joint_type) do interface.curr_joint_type = type
|
|
||||||
}
|
|
||||||
im.EndCombo()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if interface.curr_joint_type == .distanceJoint
|
|
||||||
{
|
|
||||||
ret |= interface_edit_distance_joint(interface)
|
|
||||||
}
|
|
||||||
if interface.curr_joint_type == .revoluteJoint
|
|
||||||
{
|
|
||||||
ret |= interface_edit_revolute_joint(interface)
|
|
||||||
}
|
|
||||||
im.EndTabItem()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return def^ != def_old || ret
|
|
||||||
}else{
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface_all :: proc(interface: ^interface_state) -> bool
|
interface_all :: proc(interface: ^interface_state) -> bool
|
||||||
{
|
{
|
||||||
@@ -415,9 +67,26 @@ interface_all :: proc(interface: ^interface_state) -> bool
|
|||||||
{
|
{
|
||||||
if im.BeginTabBar("Tabs")
|
if im.BeginTabBar("Tabs")
|
||||||
{
|
{
|
||||||
if interface_entity(interface) do ret = true
|
|
||||||
|
|
||||||
interface_draw_options(interface.state)
|
if im.BeginTabItem("Entity", nil, {.Leading})
|
||||||
|
{
|
||||||
|
if interface_entity(interface) do ret = true
|
||||||
|
im.EndTabItem()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if im.BeginTabItem("Joints", nil, {})
|
||||||
|
{
|
||||||
|
if interface_joints(interface) do ret = true
|
||||||
|
im.EndTabItem()
|
||||||
|
}
|
||||||
|
|
||||||
|
if im.BeginTabItem("Draw Options", nil, {})
|
||||||
|
{
|
||||||
|
interface_draw_options(interface.state)
|
||||||
|
im.EndTabItem()
|
||||||
|
}
|
||||||
|
|
||||||
im.EndTabBar()
|
im.EndTabBar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+150
-20
@@ -5,6 +5,7 @@ import b2 "vendor:box2d"
|
|||||||
import im "shared:odin-imgui"
|
import im "shared:odin-imgui"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
Delete joints
|
Delete joints
|
||||||
Angles in degree
|
Angles in degree
|
||||||
@@ -13,6 +14,27 @@ import im "shared:odin-imgui"
|
|||||||
/*
|
/*
|
||||||
All joints have bodyIdA and bodyIdB
|
All joints have bodyIdA and bodyIdB
|
||||||
*/
|
*/
|
||||||
|
joint_common :: struct
|
||||||
|
{
|
||||||
|
pivot : [2]f32,
|
||||||
|
entity_a, entity_b : static_index,
|
||||||
|
bodyIdA, bodyIdB : b2.BodyId,
|
||||||
|
}
|
||||||
|
|
||||||
|
revolt_joint_def :: struct
|
||||||
|
{
|
||||||
|
pivot : [2]f32,
|
||||||
|
entity_a, entity_b : static_index,
|
||||||
|
using def : b2.RevoluteJointDef,
|
||||||
|
}
|
||||||
|
|
||||||
|
distance_joint_def :: struct
|
||||||
|
{
|
||||||
|
pivot : [2]f32,
|
||||||
|
entity_a, entity_b : static_index,
|
||||||
|
using def : b2.DistanceJointDef,
|
||||||
|
}
|
||||||
|
|
||||||
interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^interface_state) -> bool
|
interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^interface_state) -> bool
|
||||||
{
|
{
|
||||||
level := interface.world
|
level := interface.world
|
||||||
@@ -31,11 +53,17 @@ interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^inter
|
|||||||
Set body A and Body B on the basis of static index so that it can pesist after restart
|
Set body A and Body B on the basis of static index so that it can pesist after restart
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
ret := false
|
||||||
|
|
||||||
if im.BeginCombo("Index A", fmt.ctprint(joint_def.entity_a))
|
if im.BeginCombo("Index A", fmt.ctprint(joint_def.entity_a))
|
||||||
{
|
{
|
||||||
for i in level.static_indexes
|
for i in level.static_indexes
|
||||||
{
|
{
|
||||||
if im.Selectable(fmt.ctprint(i), i == joint_def.entity_a) do joint_def.entity_a = i
|
if im.Selectable(fmt.ctprint(i), i == joint_def.entity_a)
|
||||||
|
{
|
||||||
|
joint_def.entity_a = i
|
||||||
|
ret = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
im.EndCombo()
|
im.EndCombo()
|
||||||
}
|
}
|
||||||
@@ -46,11 +74,19 @@ interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^inter
|
|||||||
{
|
{
|
||||||
for i in level.static_indexes
|
for i in level.static_indexes
|
||||||
{
|
{
|
||||||
if im.Selectable(fmt.ctprint(i), i == joint_def.entity_b) do joint_def.entity_b = i
|
//Set pivot
|
||||||
|
if im.Selectable(fmt.ctprint(i), i == joint_def.entity_b)
|
||||||
|
{
|
||||||
|
joint_def.entity_b = i
|
||||||
|
|
||||||
|
//Get the body's position and set it as default pivot
|
||||||
|
joint_def.pivot = interface.entity_defs[level.static_indexes[i]].body_def.position
|
||||||
|
ret = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
im.EndCombo()
|
im.EndCombo()
|
||||||
}
|
}
|
||||||
return false
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -67,6 +103,11 @@ interface_edit_distance_joint :: proc( interface : ^interface_state ) -> bool
|
|||||||
|
|
||||||
interface.curr_joint_index = i32(len(level.distant_joint_defs))
|
interface.curr_joint_index = i32(len(level.distant_joint_defs))
|
||||||
}
|
}
|
||||||
|
if im.Button("Delete current join")
|
||||||
|
{
|
||||||
|
unordered_remove(&level.distant_joint_defs, interface.curr_joint_index)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
//Select index
|
//Select index
|
||||||
{
|
{
|
||||||
@@ -107,6 +148,51 @@ interface_edit_distance_joint :: proc( interface : ^interface_state ) -> bool
|
|||||||
return old_def != joint_def^
|
return old_def != joint_def^
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface_edit_rev_joint_minimal :: proc(joint_def: ^b2.RevoluteJointDef)
|
||||||
|
{
|
||||||
|
|
||||||
|
im.SliderFloat2("localAnchorA", &joint_def.localAnchorA, -5, 5)
|
||||||
|
im.SliderFloat2("localAnchorB", &joint_def.localAnchorB, -5, 5)
|
||||||
|
|
||||||
|
reference_angle := RAD2DEG * joint_def.referenceAngle
|
||||||
|
if im.SliderFloat("Reference Angle", &reference_angle, 0, 359)
|
||||||
|
{
|
||||||
|
joint_def.referenceAngle = DEG2RAD * reference_angle
|
||||||
|
}
|
||||||
|
|
||||||
|
target_angle := RAD2DEG * joint_def.targetAngle
|
||||||
|
if im.SliderFloat("Target Angle", &target_angle, 0, 359)
|
||||||
|
{
|
||||||
|
joint_def.targetAngle = DEG2RAD * target_angle
|
||||||
|
}
|
||||||
|
|
||||||
|
im.Checkbox("Enable Spring", &joint_def.enableSpring)
|
||||||
|
im.InputFloat("Hertz ", &joint_def.hertz)
|
||||||
|
im.InputFloat("Damping Ratio", &joint_def.dampingRatio)
|
||||||
|
|
||||||
|
lower_angle := RAD2DEG * joint_def.lowerAngle
|
||||||
|
|
||||||
|
if im.SliderFloat("Lower Angle", &lower_angle, 0, 359)
|
||||||
|
{
|
||||||
|
joint_def.lowerAngle = DEG2RAD * lower_angle
|
||||||
|
}
|
||||||
|
|
||||||
|
upper_angle := RAD2DEG * joint_def.upperAngle
|
||||||
|
|
||||||
|
if im.SliderFloat("Upper Angle", &upper_angle, 0, 359)
|
||||||
|
{
|
||||||
|
joint_def.upperAngle = DEG2RAD * upper_angle
|
||||||
|
}
|
||||||
|
|
||||||
|
im.InputFloat("Max Motor Limit", &joint_def.maxMotorTorque)
|
||||||
|
im.InputFloat("Motor Speed", &joint_def.motorSpeed)
|
||||||
|
im.InputFloat("Draw Size", &joint_def.drawSize)
|
||||||
|
im.Checkbox("Enable Motor", &joint_def.enableMotor)
|
||||||
|
im.Checkbox("Enable Limit", &joint_def.enableLimit)
|
||||||
|
im.Checkbox("Collide Connected", &joint_def.collideConnected)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
interface_edit_revolute_joint :: proc( interface : ^interface_state ) -> bool
|
interface_edit_revolute_joint :: proc( interface : ^interface_state ) -> bool
|
||||||
{
|
{
|
||||||
@@ -122,10 +208,17 @@ interface_edit_revolute_joint :: proc( interface : ^interface_state ) -> bool
|
|||||||
interface.curr_joint_index = i32(len(level.revolute_joint_defs))
|
interface.curr_joint_index = i32(len(level.revolute_joint_defs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if im.Button("Delete current join")
|
||||||
|
{
|
||||||
|
unordered_remove(&level.revolute_joint_defs, interface.curr_joint_index)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
//Select index
|
//Select index
|
||||||
if im.BeginCombo("Select joint", fmt.ctprint(interface.curr_joint_index))
|
if im.BeginCombo("Select joint", fmt.ctprint(interface.curr_joint_index))
|
||||||
{
|
{
|
||||||
for i in 0..<len(level.revolute_joint_defs){
|
for i in 0..<len(level.revolute_joint_defs)
|
||||||
|
{
|
||||||
if im.Selectable(fmt.ctprint(i), i32(i) == interface.curr_joint_index) do interface.curr_joint_index = i32(i)
|
if im.Selectable(fmt.ctprint(i), i32(i) == interface.curr_joint_index) do interface.curr_joint_index = i32(i)
|
||||||
}
|
}
|
||||||
im.EndCombo()
|
im.EndCombo()
|
||||||
@@ -136,27 +229,64 @@ interface_edit_revolute_joint :: proc( interface : ^interface_state ) -> bool
|
|||||||
joint_def := &level.revolute_joint_defs[interface.curr_joint_index]
|
joint_def := &level.revolute_joint_defs[interface.curr_joint_index]
|
||||||
old_def := joint_def^
|
old_def := joint_def^
|
||||||
|
|
||||||
if interface_edit_joint_common(cast(^joint_common)joint_def, interface) do return true
|
if interface_edit_joint_common(cast(^joint_common)joint_def, interface)
|
||||||
|
{
|
||||||
|
//Set
|
||||||
|
body_a := interface.entities[level.static_indexes[joint_def.entity_a]].body_id
|
||||||
|
body_b := interface.entities[level.static_indexes[joint_def.entity_b]].body_id
|
||||||
|
|
||||||
|
joint_def.localAnchorA = b2.Body_GetLocalPoint(body_a, joint_def.pivot)
|
||||||
|
joint_def.localAnchorB = b2.Body_GetLocalPoint(body_b, joint_def.pivot)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Highlight the bodies here
|
Highlight the bodies here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
im.SliderFloat2("localAnchorA", &joint_def.localAnchorA, -5, 5)
|
//Assuming pivot is always body b's position
|
||||||
im.SliderFloat2("localAnchorB", &joint_def.localAnchorB, -5, 5)
|
|
||||||
im.SliderFloat("Refresh angle", &joint_def.referenceAngle, 0, 100)
|
//Edit pivot
|
||||||
im.SliderFloat("Target angle", &joint_def.targetAngle, 0, 100)
|
if im.SliderFloat2("Pivot", &joint_def.pivot, -500, 500)
|
||||||
im.Checkbox("Enable Spring", &joint_def.enableSpring)
|
{
|
||||||
im.InputFloat("Hertz ", &joint_def.hertz)
|
body_a := interface.entities[level.static_indexes[joint_def.entity_a]].body_id
|
||||||
im.InputFloat("Damping Ratio", &joint_def.dampingRatio)
|
body_b := interface.entities[level.static_indexes[joint_def.entity_b]].body_id
|
||||||
im.InputFloat("Lower Angle", &joint_def.lowerAngle)
|
|
||||||
im.InputFloat("Upper Angle", &joint_def.upperAngle)
|
joint_def.localAnchorA = b2.Body_GetLocalPoint(body_a, joint_def.pivot)
|
||||||
im.InputFloat("Max Motor Limit", &joint_def.maxMotorTorque)
|
joint_def.localAnchorB = b2.Body_GetLocalPoint(body_b, joint_def.pivot)
|
||||||
im.InputFloat("Motor Speed", &joint_def.motorSpeed)
|
|
||||||
im.InputFloat("Draw Size", &joint_def.drawSize)
|
}
|
||||||
im.Checkbox("Enable Motor", &joint_def.enableMotor)
|
|
||||||
im.Checkbox("Enable Limit", &joint_def.enableLimit)
|
interface_edit_rev_joint_minimal(joint_def)
|
||||||
im.Checkbox("Collide Connected", &joint_def.collideConnected)
|
|
||||||
|
|
||||||
return old_def != joint_def^
|
return old_def != joint_def^
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface_joints :: proc(interface: ^interface_state) -> bool
|
||||||
|
{
|
||||||
|
ret := false
|
||||||
|
interface.edit_mode = .JOINT
|
||||||
|
|
||||||
|
if im.BeginCombo("Joint type", fmt.ctprint(interface.curr_joint_type))
|
||||||
|
{
|
||||||
|
for type in b2.JointType
|
||||||
|
{
|
||||||
|
if im.Selectable(fmt.ctprint(type), type == interface.curr_joint_type) do interface.curr_joint_type = type
|
||||||
|
}
|
||||||
|
im.EndCombo()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if interface.curr_joint_type == .distanceJoint
|
||||||
|
{
|
||||||
|
ret |= interface_edit_distance_joint(interface)
|
||||||
|
}
|
||||||
|
if interface.curr_joint_type == .revoluteJoint
|
||||||
|
{
|
||||||
|
ret |= interface_edit_revolute_joint(interface)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user