Refactor draw to be separate and handle ortho draw
This commit is contained in:
+291
-217
File diff suppressed because it is too large
Load Diff
+110
-8
@@ -1,23 +1,26 @@
|
||||
package edit2d
|
||||
|
||||
import "core:fmt"
|
||||
import "base:intrinsics"
|
||||
|
||||
import "core:encoding/cbor"
|
||||
import b2 "vendor:box2d"
|
||||
import "base:runtime"
|
||||
import im "shared:odin-imgui"
|
||||
import "shared:odin-imgui/imgui_impl_glfw"
|
||||
import "shared:odin-imgui/imgui_impl_opengl3"
|
||||
import gl "vendor:OpenGL"
|
||||
import "vendor:glfw"
|
||||
import draw "shared:Edit2D/draw"
|
||||
import e2_draw "shared:Edit2D/draw"
|
||||
import "core:reflect"
|
||||
import mu "vendor:microui"
|
||||
|
||||
|
||||
|
||||
engine_state :: struct
|
||||
{
|
||||
window : glfw.WindowHandle,
|
||||
draw : draw.Draw,
|
||||
draw : e2_draw.Draw,
|
||||
restart, pause : bool,
|
||||
substep_count : u32,
|
||||
|
||||
@@ -30,6 +33,7 @@ engine_state :: struct
|
||||
|
||||
input : input_state,
|
||||
|
||||
mu_ctx : mu.Context,
|
||||
}
|
||||
|
||||
MAX_KEYS :: 512
|
||||
@@ -95,18 +99,25 @@ engine_check_types :: proc($Game: typeid)
|
||||
This will only be called once to initilize the engine
|
||||
initilize graphics library, glfw, callbacks
|
||||
*/
|
||||
engine_init :: proc($GameType : typeid, state: ^engine_state)
|
||||
engine_init :: proc($GameType : typeid, state: ^engine_state, font_path : string="")
|
||||
{
|
||||
|
||||
|
||||
engine_check_types(GameType)
|
||||
|
||||
assert(glfw.Init() == true)
|
||||
|
||||
glfw.WindowHint(glfw.SCALE_TO_MONITOR, 1)
|
||||
|
||||
glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 4)
|
||||
glfw.WindowHint(glfw.OPENGL_DEBUG_CONTEXT, true)
|
||||
glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 5)
|
||||
glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
|
||||
|
||||
state.window = glfw.CreateWindow(state.width, state.height, state.title, nil, nil)
|
||||
|
||||
|
||||
//gl.DebugMessageControl(gl.DONT_CARE, gl.DONT_CARE, gl.DONT_CARE, 0, nil, gl.TRUE);
|
||||
|
||||
assert(state.window != nil)
|
||||
|
||||
glfw.MakeContextCurrent(state.window)
|
||||
@@ -139,7 +150,7 @@ engine_init :: proc($GameType : typeid, state: ^engine_state)
|
||||
imgui_impl_glfw.InitForOpenGL(state.window, true)
|
||||
imgui_impl_opengl3.Init("#version 150")
|
||||
|
||||
state.draw.cam = draw.camera_init()
|
||||
state.draw.cam = e2_draw.camera_init()
|
||||
|
||||
display_w, display_h := glfw.GetFramebufferSize(state.window)
|
||||
state.draw.cam.width = display_w
|
||||
@@ -147,7 +158,7 @@ engine_init :: proc($GameType : typeid, state: ^engine_state)
|
||||
state.draw.cam.zoom = 15
|
||||
state.draw.show_ui = true
|
||||
|
||||
draw.draw_create(&state.draw, &state.draw.cam)
|
||||
e2_draw.draw_create(&state.draw, &state.draw.cam, font_path)
|
||||
|
||||
cbor.tag_register_type({
|
||||
marshal = proc(_: ^cbor.Tag_Implementation, e: cbor.Encoder, v: any) -> cbor.Marshal_Error {
|
||||
@@ -159,6 +170,16 @@ engine_init :: proc($GameType : typeid, state: ^engine_state)
|
||||
},
|
||||
}, 201, rawptr)
|
||||
|
||||
|
||||
//Glyph and microui
|
||||
{
|
||||
|
||||
mu.init(&state.mu_ctx)
|
||||
state.mu_ctx.style.font = cast(mu.Font)&state.draw.glyph
|
||||
state.mu_ctx.text_width = mui_text_width
|
||||
state.mu_ctx.text_height = mui_text_height
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +190,25 @@ update_frame :: proc(state: ^engine_state)
|
||||
|
||||
keyboard_update(state)
|
||||
|
||||
x, y:= glfw.GetCursorPos(state.window)
|
||||
|
||||
mu.input_mouse_move(&state.mu_ctx, i32(x), i32(y))
|
||||
{
|
||||
for key in key_map
|
||||
{
|
||||
if is_key_pressed(state, key) do mu.input_key_down(&state.mu_ctx, key_map[key])
|
||||
if is_key_released(state, key) do mu.input_key_up(&state.mu_ctx, key_map[key])
|
||||
}
|
||||
|
||||
for key in mouse_map
|
||||
{
|
||||
if is_key_pressed(state, key) do mu.input_mouse_down(&state.mu_ctx, i32(x), i32(y), mouse_map[key])
|
||||
if is_key_released(state, key) do mu.input_mouse_up(&state.mu_ctx,i32(x), i32(y), mouse_map[key])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
gl.ClearColor(0.4, 0.5, 0.6, 1.0)
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||
|
||||
@@ -187,6 +227,68 @@ end_frame :: proc(state: ^engine_state)
|
||||
{
|
||||
im.Render()
|
||||
imgui_impl_opengl3.RenderDrawData(im.GetDrawData())
|
||||
|
||||
|
||||
//Microui
|
||||
{
|
||||
|
||||
cmd: ^mu.Command
|
||||
|
||||
draw := &state.draw
|
||||
for mu.next_command(&state.mu_ctx, &cmd)
|
||||
{
|
||||
#partial switch c in cmd.variant{
|
||||
case ^mu.Command_Text:
|
||||
{
|
||||
color := c.color
|
||||
append(&draw.texts, e2_draw.TextItem{c.str, {f32(c.pos.x), f32(c.pos.y)}, {c.color.r, color.g, color.b, color.a}})
|
||||
}
|
||||
case ^mu.Command_Rect:
|
||||
{
|
||||
rect := c.rect
|
||||
pos :[2]f32= {f32(rect.x), f32(rect.y)}
|
||||
wh :[2]f32= {f32(rect.w), f32(rect.h)}
|
||||
w, h := wh.x, wh.y
|
||||
|
||||
|
||||
points : [4][2]f32 = {
|
||||
{pos.x + w, pos.y},
|
||||
{pos.x, pos.y},
|
||||
{pos.x, pos.y + h},
|
||||
{pos.x + w, pos.y + h},
|
||||
}
|
||||
|
||||
for &p, i in &points do points[i] = e2_draw.camera_convert_screen_to_world(&draw.cam, p)
|
||||
color := c.color
|
||||
hex_color := e2_draw.make_hex_color({color.r, color.g, color.b, color.a})
|
||||
e2_draw.solid_polygon_add(&draw.polygons, {q = b2.Rot{c = 1}}, &points[0], 4, 0, hex_color)
|
||||
}
|
||||
case ^mu.Command_Clip:
|
||||
{
|
||||
rect := c.rect
|
||||
gl.Scissor(rect.x, state.height - (rect.y + rect.h), rect.w, rect.h)
|
||||
}
|
||||
case ^mu.Command_Icon:{
|
||||
|
||||
if c.id == .CHECK
|
||||
{
|
||||
pos :[2]f32= {f32(c.rect.x), f32(c.rect.y)}
|
||||
|
||||
pos.x += f32(c.rect.w)/2.0
|
||||
pos.y += f32(c.rect.h)/2.0
|
||||
pos = e2_draw.camera_convert_screen_to_world(&draw.cam, pos)
|
||||
|
||||
e2_draw.solid_circle_add(&draw.solid_circles,{p = pos, q = b2.Rot{c = 1}} , 0.1,{255, 255, 255, 255})
|
||||
}else{
|
||||
fmt.println(c.id)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
glfw.SwapBuffers(state.window)
|
||||
}
|
||||
|
||||
@@ -236,9 +338,9 @@ is_key_released :: #force_inline proc(state: ^engine_state, key : i32) -> bool{
|
||||
}
|
||||
|
||||
|
||||
draw_flush :: proc(d: ^draw.Draw)
|
||||
draw_flush :: proc(d: ^e2_draw.Draw)
|
||||
{
|
||||
draw.draw_flush(d)
|
||||
e2_draw.draw_flush(d)
|
||||
}
|
||||
|
||||
|
||||
|
||||
+30
-13
@@ -1,5 +1,6 @@
|
||||
package e2glyph
|
||||
|
||||
import "core:fmt"
|
||||
/*
|
||||
Provides text rendering using glfw, stb_truetype for the engine
|
||||
|
||||
@@ -52,11 +53,13 @@ GlyphState :: struct {
|
||||
}
|
||||
|
||||
|
||||
glyph_init :: proc(glyph: ^GlyphState, filepath : string) {
|
||||
glyph_init :: proc(glyph: ^GlyphState, font_path : string = "") {
|
||||
|
||||
ok : bool
|
||||
glyph.program_id, ok = gl.load_shaders_source(#load("./shaders/font_vert.glsl"), #load("./shaders/font_frag.glsl"), )
|
||||
|
||||
gl.UseProgram(glyph.program_id)
|
||||
|
||||
gl.CreateBuffers(1, &glyph.rect_instances_vbo)
|
||||
gl.CreateVertexArrays(1, &glyph.vao)
|
||||
|
||||
@@ -82,9 +85,18 @@ glyph_init :: proc(glyph: ^GlyphState, filepath : string) {
|
||||
gl.CreateTextures(gl.TEXTURE_RECTANGLE, 1, &glyph.atlas_texture)
|
||||
gl.TextureStorage2D(glyph.atlas_texture, 1, gl.RGB8, glyph.atlas_width, glyph.atlas_height)
|
||||
|
||||
font_data, _ := os.read_entire_file_from_path(filepath, context.allocator)
|
||||
|
||||
stbtt.InitFont(&glyph.font_info, &font_data[0], 0)
|
||||
if !os.exists(font_path)
|
||||
{
|
||||
fmt.eprintln("Font not provided or not exist using default font")
|
||||
font_data := #load("./mononoki-Regular.ttf", []byte)
|
||||
stbtt.InitFont(&glyph.font_info, &font_data[0], 0)
|
||||
}else
|
||||
{
|
||||
font_data, _ := os.read_entire_file_from_path(font_path, context.allocator)
|
||||
stbtt.InitFont(&glyph.font_info, &font_data[0], 0)
|
||||
}
|
||||
|
||||
|
||||
gl.UseProgram(0)
|
||||
}
|
||||
@@ -98,6 +110,7 @@ glyph_draw_font :: proc(glyph_state: ^GlyphState, text: string, pos : [2]f32, co
|
||||
coverage_adjustment: f32 = 0.0
|
||||
text_color: [4]f32 = {f32( color.r)/ 255.0 ,f32(color.g)/255.0, f32(color.b)/255.0, f32(color.a)/255.0}
|
||||
|
||||
|
||||
glyph_state.rect_buffer = make([dynamic]GlyphRectInstance, 0, 1000)
|
||||
{
|
||||
//put every glyph in text into rect_buffer
|
||||
@@ -138,13 +151,15 @@ glyph_draw_font :: proc(glyph_state: ^GlyphState, text: string, pos : [2]f32, co
|
||||
glyph_state.curr.y += math.round(line_height)
|
||||
|
||||
} else if c == '\t' {
|
||||
|
||||
glyph_state.curr.x += 2 * glyph_state.font_size_pt
|
||||
} else {
|
||||
|
||||
|
||||
horizontal_filter_padding, subpixel_positioning_left_padding: i32 = 1, 1
|
||||
assert(codepoint <= 127)
|
||||
if codepoint >= 127{
|
||||
return
|
||||
}
|
||||
assert(codepoint < 127)
|
||||
glyph_atlas := glyph_state.atlas_items[codepoint]
|
||||
|
||||
if !glyph_atlas.filled
|
||||
@@ -283,17 +298,19 @@ glyph_draw_font :: proc(glyph_state: ^GlyphState, text: string, pos : [2]f32, co
|
||||
gl.Enable(gl.BLEND)
|
||||
gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC1_COLOR)
|
||||
|
||||
gl.BindVertexArray(glyph_state.vao)
|
||||
gl.UseProgram(glyph_state.program_id)
|
||||
gl.ProgramUniform2f(glyph_state.program_id, 0, f32(glyph_state.width) / 2.0, f32(glyph_state.height) / 2.0)
|
||||
gl.ProgramUniform1ui(glyph_state.program_id, 1, u32(coverage_adjustment))
|
||||
gl.ProgramUniform1ui(glyph_state.program_id, 2, 0)
|
||||
gl.BindTextureUnit(0, glyph_state.atlas_texture)
|
||||
gl.UseProgram( glyph_state.program_id)
|
||||
gl.BindVertexArray( glyph_state.vao)
|
||||
gl.ProgramUniform2f( glyph_state.program_id, 0, f32(glyph_state.width) / 2.0, f32(glyph_state.height) / 2.0)
|
||||
gl.ProgramUniform1ui( glyph_state.program_id, 1, u32(coverage_adjustment))
|
||||
gl.ProgramUniform1ui( glyph_state.program_id, 2, 0)
|
||||
gl.BindTextureUnit(0, glyph_state.atlas_texture)
|
||||
gl.DrawArraysInstanced(gl.TRIANGLES, 0, 6, i32(len(glyph_state.rect_buffer)))
|
||||
|
||||
gl.Disable(gl.BLEND)
|
||||
|
||||
gl.UseProgram(0)
|
||||
gl.BindVertexArray(0)
|
||||
|
||||
//gl.UseProgram(0)
|
||||
//gl.BindVertexArray(0)
|
||||
|
||||
gl.InvalidateBufferData(glyph_state.rect_instances_vbo)
|
||||
}
|
||||
|
||||
Binary file not shown.
+115
-25
@@ -1,15 +1,23 @@
|
||||
#+feature dynamic-literals
|
||||
package edit2d
|
||||
import im "shared:odin-imgui"
|
||||
import mu "vendor:microui"
|
||||
import e2_glyph "./glyph"
|
||||
import "core:fmt"
|
||||
import "vendor:glfw"
|
||||
import b2 "vendor:box2d"
|
||||
|
||||
/*
|
||||
This library will only account for box2d's entities editing
|
||||
This library will only account for box2d's entities editing
|
||||
|
||||
It only deals with one world_id, which means typically one level
|
||||
It only deals with one world_id, which means typically one level
|
||||
|
||||
All the interface follows a pattern
|
||||
All the interface follows a pattern
|
||||
i.e. It takes interface_state pointer and returns a boolean indicating weather the world needs to be reloaded
|
||||
i.e. It takes interface_state pointer and returns a boolean indicating weather the world needs to be reloaded
|
||||
|
||||
|
||||
Interface should handle microui
|
||||
|
||||
*/
|
||||
|
||||
EditMode :: enum
|
||||
@@ -41,6 +49,51 @@ interface_state :: struct
|
||||
}
|
||||
|
||||
|
||||
|
||||
key_map : map[i32]mu.Key = {
|
||||
glfw.KEY_LEFT_SHIFT = .SHIFT,
|
||||
glfw.KEY_RIGHT_SHIFT = .SHIFT,
|
||||
glfw.KEY_LEFT_CONTROL = .CTRL,
|
||||
glfw.KEY_RIGHT = .CTRL,
|
||||
glfw.KEY_LEFT_ALT = .ALT,
|
||||
glfw.KEY_RIGHT_ALT = .ALT,
|
||||
glfw.KEY_BACKSPACE = .BACKSPACE,
|
||||
glfw.KEY_DELETE = .DELETE,
|
||||
glfw.KEY_ENTER = .RETURN,
|
||||
glfw.KEY_LEFT = .LEFT,
|
||||
glfw.KEY_RIGHT = .RIGHT,
|
||||
glfw.KEY_HOME = .HOME,
|
||||
glfw.KEY_END = .END,
|
||||
glfw.KEY_A = .A,
|
||||
glfw.KEY_X = .X,
|
||||
glfw.KEY_C = .C,
|
||||
glfw.KEY_V = .V
|
||||
}
|
||||
|
||||
mouse_map : map[i32]mu.Mouse = {
|
||||
glfw.MOUSE_BUTTON_LEFT = .LEFT,
|
||||
glfw.MOUSE_BUTTON_RIGHT = .RIGHT,
|
||||
glfw.MOUSE_BUTTON_MIDDLE= .MIDDLE,
|
||||
}
|
||||
|
||||
|
||||
|
||||
//interface_get_font
|
||||
|
||||
mui_text_width :: proc(font: mu.Font, str: string) -> i32
|
||||
{
|
||||
glyph := cast(^e2_glyph.GlyphState)font
|
||||
return i32(len(str)) * i32(glyph.font_size_pt)
|
||||
}
|
||||
|
||||
mui_text_height :: proc(font: mu.Font) -> i32
|
||||
{
|
||||
glyph := cast(^e2_glyph.GlyphState)font
|
||||
return i32(glyph.font_size_pt)
|
||||
}
|
||||
|
||||
|
||||
interface_get_default :: proc(interface: ^interface_state)
|
||||
{
|
||||
interface.selected_entity = 0
|
||||
interface.vertex_index = new(i32)
|
||||
@@ -50,7 +103,8 @@ interface_get_default :: proc(interface: ^interface_state)
|
||||
}
|
||||
|
||||
interface_draw_options :: proc(state: ^engine_state)
|
||||
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)
|
||||
@@ -70,6 +124,48 @@ interface_draw_options :: proc(state: ^engine_state) {
|
||||
}
|
||||
|
||||
mu_interface_game_mode :: proc(state: ^engine_state, interface: ^interface_state)
|
||||
{
|
||||
if mu.begin_window(&state.mu_ctx, "Edit Mode", {1700, 0, 250, 170})
|
||||
{
|
||||
for type in EditMode
|
||||
{
|
||||
b : bool = interface.edit_mode == type
|
||||
if .CHANGE in mu.checkbox(&state.mu_ctx, fmt.tprint(type), &b) do interface.edit_mode = type
|
||||
}
|
||||
mu.end_window(&state.mu_ctx)
|
||||
}
|
||||
}
|
||||
|
||||
mu_interface_draw_options :: proc(state: ^engine_state)
|
||||
{
|
||||
if mu.begin_window(&state.mu_ctx, "Options", {200, 150, 200, 400}){
|
||||
debug_draw := &state.draw.debug_draw
|
||||
|
||||
mu.label(&state.mu_ctx, "Zoom")
|
||||
mu.slider(&state.mu_ctx, &state.draw.cam.zoom,0, 100)
|
||||
|
||||
mu.checkbox(&state.mu_ctx, "Shapes", &debug_draw.drawShapes)
|
||||
mu.checkbox(&state.mu_ctx, "Joints", &debug_draw.drawJoints)
|
||||
mu.checkbox(&state.mu_ctx, "Joint Extras", &debug_draw.drawJointExtras)
|
||||
mu.checkbox(&state.mu_ctx, "Bounds", &debug_draw.drawBounds)
|
||||
mu.checkbox(&state.mu_ctx, "Contact Points", &debug_draw.drawContacts)
|
||||
mu.checkbox(&state.mu_ctx, "Contact Normals", &debug_draw.drawContactNormals)
|
||||
mu.checkbox(&state.mu_ctx, "Contact Inpulses", &debug_draw.drawContactImpulses)
|
||||
mu.checkbox(&state.mu_ctx, "Contact Features", &debug_draw.drawContactFeatures)
|
||||
mu.checkbox(&state.mu_ctx, "Friction Inpulses", &debug_draw.drawFrictionImpulses)
|
||||
mu.checkbox(&state.mu_ctx, "Mass ", &debug_draw.drawMass)
|
||||
mu.checkbox(&state.mu_ctx, "Body Names", &debug_draw.drawBodyNames)
|
||||
mu.checkbox(&state.mu_ctx, "Graph Colors", &debug_draw.drawGraphColors)
|
||||
mu.checkbox(&state.mu_ctx, "Islands ", &debug_draw.drawIslands)
|
||||
|
||||
mu.label(&state.mu_ctx, "Rotation")
|
||||
mu.slider(&state.mu_ctx, &state.draw.cam.rotation, 0, 360)
|
||||
|
||||
mu.end_window(&state.mu_ctx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface_all :: proc(interface: ^interface_state) -> bool
|
||||
{
|
||||
ret := false
|
||||
@@ -79,27 +175,26 @@ interface_all :: proc(interface: ^interface_state) -> bool
|
||||
}
|
||||
|
||||
state := interface.state
|
||||
if im.Begin("Edit Mode", nil)
|
||||
{
|
||||
for type in EditMode
|
||||
{
|
||||
if im.RadioButton(fmt.ctprint(type), interface.edit_mode == type)
|
||||
{
|
||||
interface.edit_mode = type
|
||||
}
|
||||
}
|
||||
}
|
||||
im.End()
|
||||
mu.begin(&state.mu_ctx)
|
||||
|
||||
//test_window(&state.mu_ctx)
|
||||
mu_interface_draw_options(interface.state)
|
||||
mu_interface_game_mode(state, interface)
|
||||
|
||||
if im.Begin("Box2d interface")
|
||||
{
|
||||
if im.BeginTabBar("Tabs")
|
||||
{
|
||||
|
||||
if mu.begin_window(&state.mu_ctx, "B2d Interface", {1700, 150, 250, 250})
|
||||
if im.BeginTabItem("Entity", nil, {.Leading})
|
||||
{
|
||||
if .ACTIVE in mu.header(&state.mu_ctx, "Entity", {.AUTO_SIZE})
|
||||
if interface_entity(interface) do ret = true
|
||||
im.EndTabItem()
|
||||
{
|
||||
if interface_entity(interface) do ret = true
|
||||
|
||||
}
|
||||
mu.end_window(&state.mu_ctx)
|
||||
}
|
||||
|
||||
if im.BeginTabItem("Joints", nil, {})
|
||||
{
|
||||
@@ -108,15 +203,10 @@ interface_all :: proc(interface: ^interface_state) -> bool
|
||||
}
|
||||
|
||||
im.EndTabBar()
|
||||
if im.BeginTabItem("Draw Options", nil, {})
|
||||
{
|
||||
interface_draw_options(interface.state)
|
||||
im.EndTabItem()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
mu.end(&state.mu_ctx)
|
||||
im.End()
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
+89
-2
@@ -2,6 +2,7 @@ package edit2d
|
||||
|
||||
import b2 "vendor:box2d"
|
||||
import im "shared:odin-imgui"
|
||||
import mu "vendor:microui"
|
||||
import "core:slice"
|
||||
import draw "./draw"
|
||||
import "core:fmt"
|
||||
@@ -122,6 +123,92 @@ interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_ent
|
||||
return false
|
||||
}
|
||||
|
||||
mu_interface_shape_def_editor :: proc(
|
||||
state : ^engine_state,
|
||||
def : ^engine_entity_def) -> bool
|
||||
{
|
||||
shape_def := &def.shape_def
|
||||
|
||||
mu.label(&state.mu_ctx, "Shape Type")
|
||||
for type in b2.ShapeType
|
||||
{
|
||||
b := def.shape_type == type
|
||||
if .CHANGE in mu.checkbox(&state.mu_ctx, fmt.tprint(type), &b) do def.shape_type = type
|
||||
}
|
||||
|
||||
switch def.shape_type
|
||||
{
|
||||
case .circleShape:{
|
||||
mu.label(&state.mu_ctx, "Radius")
|
||||
mu.slider(&state.mu_ctx, &def.radius, 0, 40)
|
||||
}
|
||||
|
||||
case .polygonShape:{
|
||||
mu.label(&state.mu_ctx, "Size")
|
||||
mu.slider(&state.mu_ctx, &def.size[0], -500, 500)
|
||||
mu.slider(&state.mu_ctx, &def.size[1], -500, 500)
|
||||
}
|
||||
|
||||
case .capsuleShape:{
|
||||
mu.label(&state.mu_ctx, "Center 1")
|
||||
mu.slider(&state.mu_ctx, &def.centers[0][0], -100, 100)
|
||||
mu.slider(&state.mu_ctx, &def.centers[0][1], -100, 100)
|
||||
mu.label(&state.mu_ctx, "Center 2")
|
||||
mu.slider(&state.mu_ctx, &def.centers[1][0], -100, 100)
|
||||
mu.slider(&state.mu_ctx, &def.centers[1][1], -100, 100)
|
||||
mu.label(&state.mu_ctx, "Radius")
|
||||
mu.slider(&state.mu_ctx, &def.radius, 0, 40)
|
||||
}
|
||||
|
||||
case .chainSegmentShape:{
|
||||
mu.checkbox(&state.mu_ctx, "Is Loop", &def.is_loop)
|
||||
}
|
||||
case .segmentShape:{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
mu.label(&state.mu_ctx, "Density")
|
||||
mu.slider(&state.mu_ctx, &def.shape_def.density, 0, 100)
|
||||
|
||||
if .SUBMIT in mu.button(&state.mu_ctx, "Flip horizontally") do flip_points(def.vertices[:], .Horizontal)
|
||||
if .SUBMIT in mu.button(&state.mu_ctx, "Flip Vertically ") do flip_points(def.vertices[:], .Vertical)
|
||||
|
||||
if .ACTIVE in mu.begin_treenode(&state.mu_ctx, "Events and contacts")
|
||||
{
|
||||
mu.checkbox(&state.mu_ctx, "Is sensor", &def.shape_def.isSensor)
|
||||
mu.checkbox(&state.mu_ctx, "Enable Sensor Events", &def.shape_def.enableSensorEvents)
|
||||
mu.checkbox(&state.mu_ctx, "Enable Contact Events", &def.shape_def.enableContactEvents)
|
||||
mu.checkbox(&state.mu_ctx, "Enable Hit Events", &def.shape_def.enableHitEvents)
|
||||
mu.checkbox(&state.mu_ctx, "Enable Presolve Events", &def.shape_def.enablePreSolveEvents)
|
||||
mu.checkbox(&state.mu_ctx, "Invoke contact Creation", &def.shape_def.invokeContactCreation)
|
||||
mu.checkbox(&state.mu_ctx, "Update body mass ", &def.shape_def.updateBodyMass)
|
||||
|
||||
mu.end_treenode(&state.mu_ctx)
|
||||
}
|
||||
|
||||
if .ACTIVE in mu.begin_treenode(&state.mu_ctx, "Material")
|
||||
{
|
||||
mu.label(&state.mu_ctx, "Friction")
|
||||
mu.slider(&state.mu_ctx, &def.shape_def.material.friction, 0, 1)
|
||||
|
||||
mu.label(&state.mu_ctx, "Restitution")
|
||||
mu.slider(&state.mu_ctx, &def.shape_def.material.restitution, 0, 1)
|
||||
|
||||
mu.label(&state.mu_ctx, "Rolling Resistance")
|
||||
mu.slider(&state.mu_ctx, &def.shape_def.material.rollingResistance, 0, 1)
|
||||
|
||||
mu.label(&state.mu_ctx, "Tangent Speed")
|
||||
mu.slider(&state.mu_ctx, &def.shape_def.material.tangentSpeed, 0, 1)
|
||||
|
||||
//if .ACTIVE in mu.begin_treenode(&state.mu_ctx, "Color")
|
||||
|
||||
mu.end_treenode(&state.mu_ctx)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool
|
||||
{
|
||||
@@ -211,7 +298,6 @@ interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool
|
||||
im.Separator()
|
||||
im.TreePop()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -238,8 +324,9 @@ interface_entity :: proc(interface: ^interface_state) -> bool
|
||||
|
||||
if im.CollapsingHeader("Shape Edit")
|
||||
{
|
||||
interface_shape_def_editor(def)
|
||||
//interface_shape_def_editor(def)
|
||||
}
|
||||
mu_interface_shape_def_editor(interface.state, def)
|
||||
|
||||
im.Separator()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user