
local demo_dir = gh_utils.get_demo_dir()
local lib_dir = gh_utils.get_lib_dir() 		

dofile(lib_dir .. "lua/gx_cam_lib_v1.lua")
dofile(lib_dir .. "lua/libfont/libfont1.lua")   
dofile(lib_dir .. "lua/imgui.lua")    






winW, winH = gh_window.getsize(0)


win_hovered = 0





-- A 2D camera. In this demo, there will be only 2D rendering.
--
camera_ortho = gh_camera.create_ortho(-winW/2, winW/2, -winH/2, winH/2, 1.0, 10.0)
gh_camera.set_viewport(camera_ortho, 0, 0, winW, winH)
gh_camera.set_position(camera_ortho, 0, 0, 4)






-- The mega color shader!
--
color_prog = gh_node.getid("color_prog")
gh_gpu_program.uniform4f(color_prog, "color", 1, 1, 1, 1)




--
-- Box2D works in MKS units (Meter / Kilogram / Second). For objects size, one unit is one meter.
-- Then if you create a quad with create_quad(10, 10) you will get a 10x10 meter quad in BoX2D.
-- It's not a problem for Box2D but it's a big quad and don't expect it will move fast like a small object.
-- A big object like in reality, will move slowly (for example if it is falling from a 100 meters tower).
-- To deal with graphics rendering, we will decouple the physics size and 3D/2D rendering size and we will use
-- a rendering_scale factor. So a 2x2 meters Box2D obstacle will be rendered with a 20x20 quad if the rendering_scale=10.
--
-- All rendering details can be found in the FRAME script after the world_step_simulation() call.
-- 
rendering_scale = 50.0
world_y_offset = -200




-- The ground: 100m x 2m
--
ground_size = {x=20.0, y=0.5}
ground = gh_mesh.create_quad(ground_size.x, ground_size.y)





triangle = gh_mesh.create_v2()
local num_vertices = 3
local num_faces = 0 -- non-indexed rendering
local ret = gh_mesh.alloc_mesh_data(triangle, num_vertices, num_faces)
if (ret == 1) then
  gh_mesh.set_vertex_position(triangle, 0, -1, -1, 0, 1)
  gh_mesh.set_vertex_position(triangle, 1, 0, 1, 0, 1)
  gh_mesh.set_vertex_position(triangle, 2, 1, -1, 0, 1)

  gh_mesh.set_vertices_color(triangle, 1, 1, 1, 1)
end  









gh_renderer.set_vsync(0)

last_time = gh_utils.get_elapsed_time()


gl_renderer = gh_renderer.get_renderer_model()
gl_version = gh_renderer.get_api_version()


fps_time = 0
fps = 0
frames = 0


run_simulation = 1
reset_simulation = 0

wireframe = 0



------------------------------------------------------------------------------
-- Box2D Physcis 
------------------------------------------------------------------------------


function deg2rad(deg)
  return deg*3.14159265/180.0
end

function rad2deg(rad)
  return rad*180.0/3.14159265
end


box2d_version = {major=0, minor=0, revision=0}

box2d_version.major, box2d_version.minor, box2d_version.revision = gh_box2d.get_version()


-- Like other physics engines, Box2D does not like variable time step for the simulation.
-- So we will run a simulation every 1/60 second and no more. The number of simulations is not linked
-- to the framerate.
--
sim_time = 0
sim_dt = 1.0/60.0



-- Inits the Box2D engine.
gh_box2d.init()


-- Creates a scene
b2_world = gh_box2d.world_init()


-- Sets the gravity
world_gravity = {x=0, y=-10}
gh_box2d.world_set_gravity(b2_world, world_gravity.x, world_gravity.y)



-- The static ground
--
local density = 0.0
local friction = 0.5
local restitution = 0.1

b2_ground = gh_box2d.world_create_actor(b2_world, 0, -ground_size.y/2,     "static")
gh_box2d.actor_box_set_size(b2_ground, ground_size.x/2, ground_size.y/2)
gh_box2d.actor_box_build(b2_ground)
gh_box2d.actor_set_friction(b2_ground, friction)
gh_box2d.actor_set_restitution(b2_ground, restitution)




-- A dynamic triangle shape
--
density = 1000.0
friction = 0.4
restitution = 0.05


b2_triangle = gh_box2d.world_create_actor(b2_world, -3, 10,  "dynamic")
gh_box2d.actor_add_vertices(b2_triangle, -1,-1)
gh_box2d.actor_add_vertices(b2_triangle,  0, 1)
gh_box2d.actor_add_vertices(b2_triangle,  1,-1)
gh_box2d.actor_polygon_build(b2_triangle)
gh_box2d.actor_set_density(b2_triangle, density)
gh_box2d.actor_set_friction(b2_triangle, friction)
gh_box2d.actor_set_restitution(b2_triangle, restitution)

gh_box2d.actor_set_damping(b2_triangle, 0.0, 0.1)
gh_box2d.actor_set_transform(b2_triangle, -3, 10,   deg2rad(60.0))
gh_box2d.actor_set_linear_velocity(b2_triangle, 0.0, 0.0)
gh_box2d.actor_set_angular_velocity(b2_triangle, deg2rad(0.0))
-- Sleeping is not allowed here!!!!
gh_box2d.actor_set_sleeping_allowed(b2_triangle, 0)





-- A dynamic shaped polygon
-- This polygon has 5 edges.
--
polygon_vertices = {
  {x=-1.0, y=-1.0},
  {x=-1.0, y= 1.0},
  {x= 1.0, y= 1.0},
  {x= 2.0, y= 0.0},
  {x= 1.0, y=-2.0},
}

b2_polygon = gh_box2d.world_create_actor(b2_world, 3, 10,  "dynamic")

numpverts = #polygon_vertices
for i=1, numpverts do
  local vertex = polygon_vertices[i]
  gh_box2d.actor_add_vertices(b2_polygon, vertex.x, vertex.y)
end

gh_box2d.actor_polygon_build(b2_polygon)
gh_box2d.actor_set_density(b2_polygon, density)
gh_box2d.actor_set_friction(b2_polygon, friction)
gh_box2d.actor_set_restitution(b2_polygon, restitution)

gh_box2d.actor_set_damping(b2_polygon, 0.0,  0.1)
gh_box2d.actor_set_transform(b2_polygon, 3, 10,   deg2rad(-60.0))
gh_box2d.actor_set_linear_velocity(b2_polygon, 0.0, 0.0)
gh_box2d.actor_set_angular_velocity(b2_polygon, deg2rad(0.0))
-- Sleeping is not allowed here!!!!
gh_box2d.actor_set_sleeping_allowed(b2_polygon, 0)








-- The edge normal depends on the winding order. A CCW (counter-clockwise winding) order orients the normal outwards 
-- and a CW (clockwise winding) order orients the normal inwards.
--
-- Here: CCW to get an outwards normal
--
chain_vertices = {
  {x=12.0, y=1.0},
  {x=10.0, y=-0.5},
  {x=7.0, y=-1.2},
  {x=6.0, y=-1.0},
  {x=5.0, y=-1.75},
  {x=4.0, y=-2.0},
  {x=3.0, y=-2.5},
  {x=2.0, y=-2.8},
  {x=1.0, y=-2.8},
  {x=0.0, y=-2.8},
  {x=-0.5, y=-2.0},
  {x=-1, y=-0.5},
  {x=-3, y=0},
  {x=-5, y=1},
  {x=-6, y=2},
  {x=-8, y=2.5},
}


--b2_chain = gh_box2d.world_create_actor(b2_world, 0, 1,  "static")
b2_chain = gh_box2d.world_create_actor(b2_world, 0, 1,  "kinematic")

local numverts = #chain_vertices

for i=1, numverts do
  local vertex = chain_vertices[i]
  gh_box2d.actor_add_vertices(b2_chain, vertex.x, vertex.y)
end

gh_box2d.actor_chain_build(b2_chain)
gh_box2d.actor_set_transform(b2_chain, 0, 3,   deg2rad(0.0))
gh_box2d.actor_set_friction(b2_chain, 0.3)
gh_box2d.actor_set_restitution(b2_chain, 0.4)



-- Let's create the chain object for rendering.
--
local LINE_RENDER_DEFAULT = 0 
local LINE_RENDER_STRIP = 1 
local LINE_RENDER_LOOP = 2

chain = gh_polyline.create_v2(numverts, LINE_RENDER_STRIP)

for i=1, numverts do
  local vertex = chain_vertices[i]
  gh_polyline.set_vertex_position(chain, i-1, vertex.x, vertex.y, 0, 1)
end

gh_polyline.set_vertices_color_v2(chain, 1, 1, 1, 1)














-- polygon.lua is a micro lib to manage the creation and rendering of polygons with more than 4 edges.
--
dofile(demo_dir .. "polygon.lua")    

polygon1 = new_polygon()
polygon_init(polygon1, polygon_vertices)

