Big update
This commit is contained in:
@@ -1,3 +1,15 @@
|
|||||||
|
local PLAYER_PHYS_MASS = 80.0
|
||||||
|
local PLAYER_PHYS_RADIUS = 0.40
|
||||||
|
local PLAYER_PHYS_HEIGHT = 1.79
|
||||||
|
local PLAYER_PHYS_JUMPDIST = PLAYER_PHYS_RADIUS
|
||||||
|
local PLAYER_PHYS_JUMPHEIGHT = 2.0
|
||||||
|
local PLAYER_PHYS_JUMPSPEEDY = 5.0
|
||||||
|
local PLAYER_PHYS_WALK_SPEED = 5.5
|
||||||
|
local PLAYER_PHYS_RUN_SPEED_MUL = 1.4
|
||||||
|
local PLAYER_PHYS_MOVE_SPEED_EXP = 1.0
|
||||||
|
local PLAYER_PHYS_FLY_SPEED_EXP = 4.0
|
||||||
|
local AIR_CONTROL = 0.2
|
||||||
|
|
||||||
-- игрок
|
-- игрок
|
||||||
actor_player = inherit_table(actor_base)
|
actor_player = inherit_table(actor_base)
|
||||||
|
|
||||||
@@ -6,61 +18,162 @@ actor_player.m_camera_offset_y = 0.5
|
|||||||
function actor_player:on_init()
|
function actor_player:on_init()
|
||||||
actor_base.on_init(self)
|
actor_base.on_init(self)
|
||||||
|
|
||||||
self:create_body()
|
g_player = self
|
||||||
|
|
||||||
|
self:create_player_body(PLAYER_PHYS_RADIUS, PLAYER_PHYS_HEIGHT - PLAYER_PHYS_RADIUS * 2.0, 80.0, 0.0, 0.0)
|
||||||
|
|
||||||
self:activate_camera()
|
self:activate_camera()
|
||||||
|
|
||||||
local ent = engine.create_entity("test_object")
|
local ent = engine.create_entity("weapon_ump")
|
||||||
engine.add_entity_to_world(ent)
|
engine.add_entity_to_world(ent)
|
||||||
|
|
||||||
self.m_weapon_entity_id = ent:get_id()
|
self.m_weapon_entity_id = ent:get_id()
|
||||||
|
|
||||||
self.m_in_reload = false
|
|
||||||
|
|
||||||
--local ent2 = engine.get_entity_from_id(self.m_weapon_entity_id)
|
|
||||||
--console.print(ent2:get_classname())
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function actor_player:on_shutdown()
|
function actor_player:on_shutdown()
|
||||||
actor_base.on_shutdown(self)
|
actor_base.on_shutdown(self)
|
||||||
|
|
||||||
|
g_player = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function actor_player:on_update(dt)
|
function actor_player:on_update(dt)
|
||||||
actor_base.on_update(self, dt)
|
actor_base.on_update(self, dt)
|
||||||
|
|
||||||
self:update_camera_look()
|
self:update_camera_look() -- C++
|
||||||
--self:update_camera_movement(dt)
|
--self:update_camera() Lua (for perfomance should call from C++)
|
||||||
self:update_body_movement(dt)
|
|
||||||
|
--self:update_camera_movement(dt) -- C++ flying mode
|
||||||
|
--self:update_body_movement(dt) -- C++
|
||||||
|
|
||||||
|
self:update_player_movement(dt)
|
||||||
|
|
||||||
local ent = engine.get_entity_from_id(self.m_weapon_entity_id)
|
local ent = engine.get_entity_from_id(self.m_weapon_entity_id)
|
||||||
ent:set_relative_position_to_camera(self)
|
ent:set_relative_position_to_camera(self)
|
||||||
|
|
||||||
if self:get_action() == ACTION_FIRE and self.m_in_reload == false then
|
self:action_update()
|
||||||
ent:play_animation(ent:find_animation("shoot1"), ANIM_PLAYBACK_NONE)
|
end
|
||||||
engine.play_sound("data/sounds/weapons/ump45_shoot.wav")
|
|
||||||
|
function actor_player:action_update()
|
||||||
|
local action = self:get_action()
|
||||||
|
|
||||||
|
local ent = engine.get_entity_from_id(self.m_weapon_entity_id)
|
||||||
|
if ent then
|
||||||
|
if action == ACTION_FIRE then
|
||||||
|
ent:set_state(WEAPON_FSM_STATE_ATTACK)
|
||||||
|
elseif action == ACTION_RELOAD then
|
||||||
|
ent:set_state(WEAPON_FSM_STATE_RELOAD)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: remove
|
||||||
|
function vec3_magnitude(_x, _y, _z)
|
||||||
|
return math.sqrt(_x * _x + _y * _y + _z * _z)
|
||||||
|
end
|
||||||
|
|
||||||
|
function vec3_normalize(_x, _y, _z)
|
||||||
|
local mag = vec3_magnitude(_x, _y, _z)
|
||||||
|
if mag == 0 then return 0, 0, 0 end
|
||||||
|
return _x / mag, _y / mag, _z / mag
|
||||||
|
end
|
||||||
|
|
||||||
|
function vec3_cross(_x1, _y1, _z1, _x2, _y2, _z2)
|
||||||
|
return _y1 * _z2 - _y2 * _z1,
|
||||||
|
_z1 * _x2 - _z2 * _x1,
|
||||||
|
_x1 * _y2 - _x2 * _y1
|
||||||
|
end
|
||||||
|
|
||||||
|
function actor_player:update_player_movement(dt)
|
||||||
|
local movement = self:get_movement()
|
||||||
|
local speed = 4.0
|
||||||
|
|
||||||
|
local up_x, up_y, up_z = camera.get_up()
|
||||||
|
local front_x, front_y, front_z = camera.get_front()
|
||||||
|
front_y = 0.0
|
||||||
|
|
||||||
|
local final_front_x, final_front_y, final_front_z = vec3_normalize(front_x, front_y, front_z)
|
||||||
|
local cross_x, cross_y, cross_z = vec3_cross(final_front_x, final_front_y, final_front_z,
|
||||||
|
up_x, up_y, up_z)
|
||||||
|
|
||||||
|
local final_cross_x, final_cross_y, final_cross_z = vec3_normalize(cross_x, cross_y, cross_z)
|
||||||
|
|
||||||
|
local dir_x, dir_y, dir_z = 0.0, 0.0, 0.0
|
||||||
|
|
||||||
|
if (movement & EMovementDir_Forward) ~= 0 then
|
||||||
|
dir_x = dir_x + final_front_x
|
||||||
|
dir_y = dir_y + final_front_y
|
||||||
|
dir_z = dir_z + final_front_z
|
||||||
end
|
end
|
||||||
|
|
||||||
if self:get_action() == ACTION_RELOAD and self.m_in_reload == false then
|
if (movement & EMovementDir_Backward) ~= 0 then
|
||||||
ent:play_animation(ent:find_animation("reload"), ANIM_PLAYBACK_NONE)
|
dir_x = dir_x - final_front_x
|
||||||
engine.play_sound("data/sounds/weapons/ump45_reload.wav")
|
dir_y = dir_y - final_front_y
|
||||||
self.m_in_reload = true
|
dir_z = dir_z - final_front_z
|
||||||
end
|
end
|
||||||
|
|
||||||
if ent:get_current_animation() == ent:find_animation("shoot1") and
|
if (movement & EMovementDir_Left) ~= 0 then
|
||||||
ent:get_current_animation_time() >= ent:get_animation_time(ent:find_animation("shoot1")) then
|
dir_x = dir_x - final_cross_x
|
||||||
ent:play_animation(ent:find_animation("idle1"), ANIM_PLAYBACK_REPEAT)
|
dir_y = dir_y - final_cross_y
|
||||||
|
dir_z = dir_z - final_cross_z
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.m_in_reload == true and ent:get_current_animation_time() >= ent:get_animation_time(ent:find_animation("reload")) then
|
if (movement & EMovementDir_Right) ~= 0 then
|
||||||
ent:play_animation(ent:find_animation("idle1"), ANIM_PLAYBACK_REPEAT)
|
dir_x = dir_x + final_cross_x
|
||||||
self.m_in_reload = false
|
dir_y = dir_y + final_cross_y
|
||||||
|
dir_z = dir_z + final_cross_z
|
||||||
end
|
end
|
||||||
-- if ent:get_current_animation() == ent:find_animation("reload") and
|
|
||||||
-- ent:get_current_animation_time() >= ent:get_animation_time(ent:find_animation("reload")) then
|
local current_vel_x, current_vel_y, current_vel_z = self:get_velocity()
|
||||||
-- ent:play_animation(ent:find_animation("idle1"), ANIM_PLAYBACK_NONE)
|
|
||||||
--end
|
local vel_x = dir_x * speed
|
||||||
|
local vel_y = dir_y * speed
|
||||||
|
local vel_z = dir_z * speed
|
||||||
|
|
||||||
|
|
||||||
|
if self:on_ground() then
|
||||||
|
self:set_velocity(vel_x, current_vel_y, vel_z)
|
||||||
|
|
||||||
|
if (movement & EMovementDir_Jump) ~= 0 then
|
||||||
|
self:set_velocity(current_vel_x, PLAYER_PHYS_JUMPSPEEDY, current_vel_z)
|
||||||
|
--console.print("!!! JUMP")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local air_vel_x = current_vel_x + dir_x * speed * AIR_CONTROL * dt
|
||||||
|
local air_vel_y = current_vel_y + dir_y * speed * AIR_CONTROL * dt
|
||||||
|
local air_vel_z = current_vel_z + dir_z * speed * AIR_CONTROL * dt
|
||||||
|
self:set_velocity(air_vel_x, current_vel_y, air_vel_z)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local g_yaw = 0.0
|
||||||
|
local g_pitch = 0.0
|
||||||
|
|
||||||
|
function actor_player:update_camera()
|
||||||
|
if not input.get_lock_mouse() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local mousePosX, mousePosY = input.get_mouse_pos()
|
||||||
|
local sensitivity = 0.15 -- #TODO: input.get_mouse_sensitivity()
|
||||||
|
|
||||||
|
g_yaw = g_yaw + (mousePosX * sensitivity)
|
||||||
|
g_pitch = g_pitch - (mousePosY * sensitivity)
|
||||||
|
|
||||||
|
-- lock axis
|
||||||
|
if g_pitch > 89.0 then g_pitch = 89.0 end
|
||||||
|
if g_pitch < -89.0 then g_pitch = -89.0 end
|
||||||
|
|
||||||
|
camera.set_yaw_pitch(g_yaw, g_pitch)
|
||||||
end
|
end
|
||||||
|
|
||||||
function actor_player:on_collide(other)
|
function actor_player:on_collide(other)
|
||||||
console.print(string.format("actor_player:on_collide: %s", other:get_classname()))
|
--console.print(string.format("actor_player:on_collide: %s", other:get_classname()))
|
||||||
|
|
||||||
|
-- put_debug_string_to_screen(string.format("actor_player:on_collide: %s", other:get_classname()), 4)
|
||||||
|
|
||||||
|
-- FOR TEST
|
||||||
|
-- other:mark_for_delete()
|
||||||
|
end
|
||||||
|
|
||||||
|
function actor_player:get_health()
|
||||||
|
return 100.0
|
||||||
end
|
end
|
||||||
|
|||||||
70
data/scripts/game_hud.lua
Normal file
70
data/scripts/game_hud.lua
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
local RED_COLOR = { 1.0, 0.0, 0.0, 1.0 }
|
||||||
|
local GREEN_COLOR = { 0.0, 1.0, 0.0, 1.0 }
|
||||||
|
local BLUE_COLOR = { 0.0, 0.0, 1.0, 1.0 }
|
||||||
|
local BLACK_COLOR = { 0.0, 0.0, 0.0, 1.0 }
|
||||||
|
local WHITE_COLOR = { 1.0, 1.0, 1.0, 1.0 }
|
||||||
|
|
||||||
|
local draw_test_hud = true
|
||||||
|
local draw_debug_string = false
|
||||||
|
local debug_string_text = ""
|
||||||
|
local debug_string_time = 0.0
|
||||||
|
local debug_string_max_time = 0.0
|
||||||
|
|
||||||
|
function game_hud_draw( )
|
||||||
|
if not draw_test_hud then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- example of color
|
||||||
|
local color = { 0.5, 0.5, 0.1, 1.0 }
|
||||||
|
|
||||||
|
-- example of drawing
|
||||||
|
ui.draw_rect(150.0, 150.0, 350.0, 350.0, BLUE_COLOR)
|
||||||
|
ui.draw_image("data/textures/koshka1.jpg", 160.0, 160.0, 340.0, 340.0, WHITE_COLOR)
|
||||||
|
ui.draw_text("Hello, world!", 200.0, 200.0, GREEN_COLOR)
|
||||||
|
|
||||||
|
if g_player then
|
||||||
|
game_player_hud_draw()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- debug
|
||||||
|
if draw_debug_string then
|
||||||
|
game_debug_string_draw()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function game_player_hud_draw()
|
||||||
|
local display_x, display_y = ui.get_display_size()
|
||||||
|
local color = { 0.0, 0.0, 0.0, 0.3 }
|
||||||
|
local text_color = { 0.0, 0.0, 0.0, 0.6 }
|
||||||
|
local hud_rect_size_x = 200
|
||||||
|
local hud_rect_size_y = 100
|
||||||
|
local offset_text = ui.calc_text_width("Health") + 5
|
||||||
|
|
||||||
|
ui.draw_rect(0.0, display_y, hud_rect_size_x, display_y - hud_rect_size_y, color)
|
||||||
|
|
||||||
|
ui.draw_text("Health", 10.0, display_y - hud_rect_size_y + 20, WHITE_COLOR)
|
||||||
|
ui.draw_text(string.format("%.0f", g_player:get_health()), 10.0 + offset_text, display_y - hud_rect_size_y + 20, WHITE_COLOR)
|
||||||
|
end
|
||||||
|
|
||||||
|
function put_debug_string_to_screen(text, text_time)
|
||||||
|
debug_string_max_time = text_time
|
||||||
|
debug_string_text = text
|
||||||
|
debug_string_time = 0.0
|
||||||
|
draw_debug_string = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function game_debug_string_draw()
|
||||||
|
debug_string_time = debug_string_time + engine.get_delta()
|
||||||
|
|
||||||
|
if debug_string_time >= debug_string_max_time then
|
||||||
|
debug_string_max_time = 0.0
|
||||||
|
debug_string_time = 0.0
|
||||||
|
draw_debug_string = false
|
||||||
|
end
|
||||||
|
|
||||||
|
local offset = ui.calc_text_width(debug_string_text)
|
||||||
|
|
||||||
|
ui.draw_rect(490, 500, 490 + offset + 20, 550, BLACK_COLOR)
|
||||||
|
ui.draw_text(debug_string_text, 500, 500, RED_COLOR)
|
||||||
|
end
|
||||||
@@ -1,25 +1,39 @@
|
|||||||
-- Game initialization script
|
-- Game initialization script
|
||||||
|
|
||||||
console.print("--- Game initialization ---")
|
|
||||||
|
|
||||||
-- загружаем скрипты
|
-- загружаем скрипты
|
||||||
load_script("game_utils.lua")
|
load_script("game_utils.lua")
|
||||||
|
load_script("game_hud.lua")
|
||||||
load_script("game_object.lua")
|
load_script("game_object.lua")
|
||||||
load_script("test_object.lua")
|
load_script("test_object.lua")
|
||||||
|
|
||||||
load_script("weapons/weapon_base.lua")
|
load_script("weapons/weapon_base.lua")
|
||||||
|
|
||||||
|
load_script("weapons/weapon_ump.lua")
|
||||||
|
|
||||||
load_script("actors/actor_base.lua")
|
load_script("actors/actor_base.lua")
|
||||||
|
|
||||||
load_script("actors/actor_player.lua")
|
load_script("actors/actor_player.lua")
|
||||||
|
|
||||||
|
-- глобальные переменные
|
||||||
|
g_player = nil
|
||||||
|
|
||||||
-- глобальная таблица сущностей
|
-- глобальная таблица сущностей
|
||||||
g_entity_table = {
|
g_entity_table = {
|
||||||
-- Lua class -- CPP class -- Description
|
-- Lua class -- CPP class -- Description
|
||||||
|
|
||||||
|
-- Actors
|
||||||
|
|
||||||
{ "actor_player", "ActorBase", "Player entity" },
|
{ "actor_player", "ActorBase", "Player entity" },
|
||||||
|
|
||||||
|
-- Weapons
|
||||||
|
{ "weapon_ump", "WeaponBase", "Weapon UMP" },
|
||||||
|
|
||||||
-- Simple entity
|
-- Simple entity
|
||||||
{ "test_object", "Entity", "Test entity" },
|
{ "test_object", "Entity", "Test entity" },
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sv_game_init( )
|
||||||
|
console.print("--- Game initialization ---")
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
-- weapon_base.lua, Базоавый скрипт оружия
|
-- weapon_base.lua, Базовый скрипт оружия
|
||||||
-- Автор: Кирилл
|
-- Автор: Кирилл
|
||||||
-- Изменяли:
|
-- Изменяли:
|
||||||
-- Дата: 05.03.2026
|
-- Дата: 05.03.2026
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
|
|
||||||
-- индификаторы состояний FSM
|
-- индификаторы состояний FSM
|
||||||
|
WEAPON_FSM_STATE_NONE = 0
|
||||||
WEAPON_FSM_STATE_IDLE = 1
|
WEAPON_FSM_STATE_IDLE = 1
|
||||||
WEAPON_FSM_STATE_ATTACK = 2
|
WEAPON_FSM_STATE_ATTACK = 2
|
||||||
WEAPON_FSM_STATE_ATTACK2 = 3
|
WEAPON_FSM_STATE_ATTACK2 = 3
|
||||||
@@ -17,32 +18,11 @@ weapon_base = inherit_table(game_object)
|
|||||||
-- инициализация FSM
|
-- инициализация FSM
|
||||||
weapon_base.m_fsm = {}
|
weapon_base.m_fsm = {}
|
||||||
|
|
||||||
-- покой
|
|
||||||
weapon_base.m_fsm[WEAPON_FSM_STATE_IDLE] = {
|
|
||||||
anim = "idle", -- имя анимации
|
|
||||||
anim_playback = ANIM_PLAYBACK_REPEAT, -- бесконечно играть
|
|
||||||
anim_speed = 1.0 -- обычная скорость анимации
|
|
||||||
}
|
|
||||||
|
|
||||||
-- атака
|
|
||||||
weapon_base.m_fsm[WEAPON_FSM_STATE_ATTACK] = {
|
|
||||||
anim = "attack", -- имя анимации
|
|
||||||
anim_playback = ANIM_PLAYBACK_NONE,
|
|
||||||
anim_speed = 1.0 -- обычная скорость анимации
|
|
||||||
}
|
|
||||||
|
|
||||||
-- перезарядка
|
|
||||||
weapon_base.m_fsm[WEAPON_FSM_STATE_RELOAD] = {
|
|
||||||
anim = "reload", -- имя анимации
|
|
||||||
anim_playback = ANIM_PLAYBACK_NONE,
|
|
||||||
anim_speed = 1.0 -- обычная скорость анимации
|
|
||||||
}
|
|
||||||
|
|
||||||
function weapon_base:on_init()
|
function weapon_base:on_init()
|
||||||
game_object.on_init(self)
|
game_object.on_init(self)
|
||||||
|
|
||||||
-- начальное состояние FSM
|
-- начальное состояние FSM
|
||||||
self.m_state = WEAPON_FSM_STATE_IDLE
|
self.m_state = WEAPON_FSM_STATE_NONE
|
||||||
self.m_next_state = WEAPON_FSM_STATE_IDLE
|
self.m_next_state = WEAPON_FSM_STATE_IDLE
|
||||||
self.m_state_time = 0.0
|
self.m_state_time = 0.0
|
||||||
self.m_end_state_time = 0.0
|
self.m_end_state_time = 0.0
|
||||||
@@ -64,46 +44,96 @@ function weapon_base:on_fsm_state_update(dt)
|
|||||||
self.m_state_time = self.m_state_time + dt
|
self.m_state_time = self.m_state_time + dt
|
||||||
|
|
||||||
-- проверка на стрельбу
|
-- проверка на стрельбу
|
||||||
if (self.m_state == WEAPON_STATE_ATTACK or
|
if (self.m_state == WEAPON_FSM_STATE_ATTACK or
|
||||||
self.m_state == WEAPON_STATE_ATTACK2) and
|
self.m_state == WEAPON_FSM_STATE_ATTACK2) and
|
||||||
self.m_state_time >= self.m_end_state_time then
|
self.m_state_time >= self.m_end_state_time then
|
||||||
|
|
||||||
-- переходим в ожидание
|
-- переходим в ожидание
|
||||||
self:set_state(WEAPON_STATE_IDLE)
|
self:set_state(WEAPON_FSM_STATE_IDLE)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- костыль, нету анимаций бесконечных
|
-- костыль, нету анимаций бесконечных
|
||||||
if self.m_state == WEAPON_STATE_IDLE and self.m_state_time >= self.m_end_state_time then
|
if self.m_state == WEAPON_FSM_STATE_IDLE and self.m_state_time >= self.m_end_state_time then
|
||||||
-- переходим в ожидание
|
-- переходим в ожидание
|
||||||
self:set_state(WEAPON_STATE_IDLE)
|
self:set_state(WEAPON_FSM_STATE_IDLE)
|
||||||
end
|
end
|
||||||
|
|
||||||
self:fsm_update(dt)
|
self:fsm_update(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
function weapon_base:set_state(next_state)
|
function weapon_base:set_state(next_state)
|
||||||
|
if self.m_state == next_state or self.m_next_state == next_state then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if (self.m_state == WEAPON_FSM_STATE_ATTACK or self.m_state == WEAPON_FSM_STATE_RELOAD)
|
||||||
|
and next_state ~= WEAPON_FSM_STATE_IDLE then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
self.m_next_state = next_state
|
self.m_next_state = next_state
|
||||||
|
console.print(string.format("weapon_base:set_state: switich to '%d' ", next_state))
|
||||||
end
|
end
|
||||||
|
|
||||||
function weapon_base:fsm_update(dt)
|
function weapon_base:fsm_update(dt)
|
||||||
|
|
||||||
-- надо ли менять состояние
|
-- надо ли менять состояние
|
||||||
if self.m_next_state ~= self.m_state then
|
if self.m_next_state ~= self.m_state then
|
||||||
|
|
||||||
if self.m_next_state == WEAPON_STATE_ATTACK then
|
self:on_state_switch(self.m_next_state)
|
||||||
self:set_anim("attack1")
|
|
||||||
elseif self.m_next_state == WEAPON_STATE_ATTACK2 then
|
|
||||||
self:set_anim("attack1")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- сброс времени и установка его на таймер анимации
|
-- сброс времени и установка его на таймер анимации
|
||||||
self.m_state_time = 0.0
|
self.m_state_time = 0.0
|
||||||
self.m_end_state_time = render.get_anim_time(self:get_anim())
|
self.m_end_state_time = self:get_animation_time(self:get_current_animation())
|
||||||
|
|
||||||
-- запускаем атаку
|
console.print(string.format("weapon_base:fsm_update: switched from '%d' to '%d', end time %f ",
|
||||||
if self.m_next_state == WEAPON_STATE_ATTACK or self.m_next_state == WEAPON_STATE_ATTACK2 then
|
self.m_state, self.m_next_state, self.m_end_state_time))
|
||||||
self:attack()
|
|
||||||
end
|
|
||||||
|
|
||||||
self.m_state = self.m_next_state
|
self.m_state = self.m_next_state
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function weapon_base:find_fsm_state(state)
|
||||||
|
for k, v in pairs(self.m_fsm) do
|
||||||
|
if k == state then
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
console.print(string.format("weapon_base:find_fsm_state: state '%d' not found or not registered", state))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function weapon_base:on_state_switch(state)
|
||||||
|
-- ищем стейт в таблице
|
||||||
|
local fsm_state = self:find_fsm_state(state)
|
||||||
|
if not fsm_state then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local anim_id = self:find_animation(fsm_state.anim)
|
||||||
|
self:play_animation(anim_id, fsm_state.anim_playback)
|
||||||
|
end
|
||||||
|
|
||||||
|
function weapon_base:set_relative_position_to_camera( ent )
|
||||||
|
local camX, camY, camZ = camera.get_position()
|
||||||
|
local frontX, frontY, frontZ = camera.get_front()
|
||||||
|
local rightX, rightY, rightZ = camera.get_right()
|
||||||
|
local upX, upY, upZ = camera.get_up()
|
||||||
|
|
||||||
|
self:set_rotation_from_vectors(frontX, frontY, frontZ,
|
||||||
|
rightX, rightY, rightZ,
|
||||||
|
upX, upY, upZ)
|
||||||
|
|
||||||
|
local offsetx = 0.0
|
||||||
|
local offsety = 0.0
|
||||||
|
local offsetz = 0.0
|
||||||
|
|
||||||
|
local x = camX + (rightX * offsetx) + (upX * offsety) + (frontX * offsetz)
|
||||||
|
local y = camY + (rightY * offsetx) + (upY * offsety) + (frontY * offsetz)
|
||||||
|
local z = camZ + (rightZ * offsetx) + (upZ * offsety) + (frontZ * offsetz)
|
||||||
|
self:set_position(x, y, z)
|
||||||
|
|
||||||
|
-- force update transform
|
||||||
|
self:update_transform()
|
||||||
|
end
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
weapon_key = inherit_table(weapon_base)
|
|
||||||
33
data/scripts/weapons/weapon_ump.lua
Normal file
33
data/scripts/weapons/weapon_ump.lua
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
-----------------------------------------------------------
|
||||||
|
-- weapon_base.lua, Базоавый скрипт оружия
|
||||||
|
-- Автор: Кирилл
|
||||||
|
-- Изменяли:
|
||||||
|
-- Дата: 06.03.2026
|
||||||
|
-----------------------------------------------------------
|
||||||
|
weapon_ump = inherit_table(weapon_base)
|
||||||
|
|
||||||
|
-- покой
|
||||||
|
weapon_ump.m_fsm[WEAPON_FSM_STATE_IDLE] = {
|
||||||
|
anim = "idle1", -- имя анимации
|
||||||
|
anim_playback = ANIM_PLAYBACK_REPEAT, -- бесконечно играть
|
||||||
|
anim_speed = 1.0 -- обычная скорость анимации
|
||||||
|
}
|
||||||
|
|
||||||
|
-- атака
|
||||||
|
weapon_ump.m_fsm[WEAPON_FSM_STATE_ATTACK] = {
|
||||||
|
anim = "shoot1", -- имя анимации
|
||||||
|
anim_playback = ANIM_PLAYBACK_NONE,
|
||||||
|
anim_speed = 1.0 -- обычная скорость анимации
|
||||||
|
}
|
||||||
|
|
||||||
|
-- перезарядка
|
||||||
|
weapon_ump.m_fsm[WEAPON_FSM_STATE_RELOAD] = {
|
||||||
|
anim = "reload", -- имя анимации
|
||||||
|
anim_playback = ANIM_PLAYBACK_NONE,
|
||||||
|
anim_speed = 1.0 -- обычная скорость анимации
|
||||||
|
}
|
||||||
|
|
||||||
|
function weapon_ump:on_init()
|
||||||
|
weapon_base.on_init(self)
|
||||||
|
self:load_model("data/models/weapons/v_ump.iqm")
|
||||||
|
end
|
||||||
BIN
data/textures/koshka1.jpg
Normal file
BIN
data/textures/koshka1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
@@ -27,6 +27,12 @@ string m_name
|
|||||||
integer m_id
|
integer m_id
|
||||||
|
|
||||||
|
|
||||||
|
Entity callbacks:
|
||||||
|
on_init() -- on entity creation
|
||||||
|
on_shutdown() -- on entity destroy
|
||||||
|
on_update(delta) -- on entity update
|
||||||
|
on_collide(other) -- on entity collide with another entity
|
||||||
|
|
||||||
Entity methods:
|
Entity methods:
|
||||||
load_model(string filename)
|
load_model(string filename)
|
||||||
|
|
||||||
@@ -40,12 +46,15 @@ get_position() -- return x, y, z
|
|||||||
|
|
||||||
set_rotation(float x, float y, float z) -- setting the euler rotation
|
set_rotation(float x, float y, float z) -- setting the euler rotation
|
||||||
|
|
||||||
|
get_rotation() -- return x, y, z
|
||||||
|
|
||||||
set_rotation_from_vectors(float frontx, float fronty, float frontz,
|
set_rotation_from_vectors(float frontx, float fronty, float frontz,
|
||||||
float rightx, float righty, float rightz,
|
float rightx, float righty, float rightz,
|
||||||
float upx, float upy, float upz) -- rotate around axis
|
float upx, float upy, float upz) -- rotate around axis
|
||||||
|
|
||||||
get_classname() -- return the classname of the entity
|
get_classname() -- return the classname of the entity
|
||||||
get_id() -- return the id of the entity
|
get_id() -- return the id of the entity
|
||||||
|
mark_for_delete() -- mark entity to delete
|
||||||
|
|
||||||
find_animation(string name) -- find a animation in the model
|
find_animation(string name) -- find a animation in the model
|
||||||
play_animation(integer id, integer mode) -- play a animation with specified mode (ANIM_PLAYBACK_NONE, ANIM_PLAYBACK_REPEAT)
|
play_animation(integer id, integer mode) -- play a animation with specified mode (ANIM_PLAYBACK_NONE, ANIM_PLAYBACK_REPEAT)
|
||||||
@@ -57,7 +66,6 @@ get_animation_time(integer id) -- return the time of a animation
|
|||||||
|
|
||||||
ActorBase methods:
|
ActorBase methods:
|
||||||
activate_camera()
|
activate_camera()
|
||||||
|
|
||||||
update_camera_look()
|
update_camera_look()
|
||||||
update_camera_movement(float nubmer)
|
update_camera_movement(float nubmer)
|
||||||
create_body()
|
create_body()
|
||||||
4
docs/экспорт оружия из goldsource.txt
Normal file
4
docs/экспорт оружия из goldsource.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
1. импортировать smd с Y-up осью вверх
|
||||||
|
2. снова экспортировать как GoldSource с Y-up осью3\
|
||||||
|
3. ввести команды для iqm.exe для сборки модели, пример команды:
|
||||||
|
iqm.exe -scale 0.0254 -rotate 0,90,0 v_m3.iqm v_m3-PV.smd after_reload.smd draw.smd idle.smd insert.smd shoot1.smd shoot2.smd start_reload.smd
|
||||||
1
docs/экспорт уровня или модели в obj.txt
Normal file
1
docs/экспорт уровня или модели в obj.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1. ОБЯЗАТЕЛЬНО TRAINGULATE FACE !!!
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "renderdevice.h"
|
#include "renderdevice.h"
|
||||||
#include "imguimanager.h"
|
#include "imguimanager.h"
|
||||||
|
#include "scenemanager.h"
|
||||||
|
|
||||||
// game
|
// game
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
@@ -77,6 +78,431 @@ void debug_overlay_render() {
|
|||||||
// ImGui::PopStyleVar();
|
// ImGui::PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// [SECTION] Example App: Debug Console / ShowExampleAppConsole()
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Demonstrate creating a simple console window, with scrolling, filtering, completion and history.
|
||||||
|
// For the console example, we are using a more C++ like approach of declaring a class to hold both data and functions.
|
||||||
|
struct ExampleAppConsole
|
||||||
|
{
|
||||||
|
char InputBuf[256];
|
||||||
|
ImVector<char*> Items;
|
||||||
|
ImVector<const char*> Commands;
|
||||||
|
ImVector<char*> History;
|
||||||
|
int HistoryPos; // -1: new line, 0..History.Size-1 browsing history.
|
||||||
|
ImGuiTextFilter Filter;
|
||||||
|
bool AutoScroll;
|
||||||
|
bool ScrollToBottom;
|
||||||
|
|
||||||
|
ExampleAppConsole()
|
||||||
|
{
|
||||||
|
ClearLog();
|
||||||
|
memset(InputBuf, 0, sizeof(InputBuf));
|
||||||
|
HistoryPos = -1;
|
||||||
|
|
||||||
|
// "CLASSIFY" is here to provide the test case where "C"+[tab] completes to "CL" and display multiple matches.
|
||||||
|
Commands.push_back("help");
|
||||||
|
Commands.push_back("history");
|
||||||
|
Commands.push_back("clear");
|
||||||
|
Commands.push_back("classify");
|
||||||
|
Commands.push_back("ph_debug_draw");
|
||||||
|
Commands.push_back("r_scene_debug_draw");
|
||||||
|
Commands.push_back("r_show_stats");
|
||||||
|
Commands.push_back("r_entity_debug_draw");
|
||||||
|
Commands.push_back("map");
|
||||||
|
Commands.push_back("quit");
|
||||||
|
AutoScroll = true;
|
||||||
|
ScrollToBottom = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
~ExampleAppConsole()
|
||||||
|
{
|
||||||
|
ClearLog();
|
||||||
|
for (int i = 0; i < History.Size; i++)
|
||||||
|
ImGui::MemFree(History[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Portable helpers
|
||||||
|
static int Stricmp(const char* s1, const char* s2) { int d; while ((d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; } return d; }
|
||||||
|
static int Strnicmp(const char* s1, const char* s2, int n) { int d = 0; while (n > 0 && (d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; n--; } return d; }
|
||||||
|
static char* Strdup(const char* s) { IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = ImGui::MemAlloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)s, len); }
|
||||||
|
static void Strtrim(char* s) { char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; }
|
||||||
|
|
||||||
|
void ClearLog()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Items.Size; i++)
|
||||||
|
ImGui::MemFree(Items[i]);
|
||||||
|
Items.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddLog(const char* fmt, ...) IM_FMTARGS(2)
|
||||||
|
{
|
||||||
|
// FIXME-OPT
|
||||||
|
char buf[1024];
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||||
|
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||||
|
va_end(args);
|
||||||
|
Items.push_back(Strdup(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Draw(const char* title, bool* p_open)
|
||||||
|
{
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||||
|
if (!ImGui::Begin(title, p_open))
|
||||||
|
{
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As a specific feature guaranteed by the library, after calling Begin() the last Item represent the title bar.
|
||||||
|
// So e.g. IsItemHovered() will return true when hovering the title bar.
|
||||||
|
// Here we create a context menu only available from the title bar.
|
||||||
|
if (ImGui::BeginPopupContextItem())
|
||||||
|
{
|
||||||
|
if (ImGui::MenuItem("Close Console"))
|
||||||
|
*p_open = false;
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: display items starting from the bottom
|
||||||
|
#if 0
|
||||||
|
if (ImGui::SmallButton("Add Debug Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); }
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::SmallButton("Add Debug Error")) { AddLog("[error] something went wrong"); }
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::SmallButton("Clear")) { ClearLog(); }
|
||||||
|
ImGui::SameLine();
|
||||||
|
bool copy_to_clipboard = ImGui::SmallButton("Copy");
|
||||||
|
//static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); }
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// Options menu
|
||||||
|
if (ImGui::BeginPopup("Options"))
|
||||||
|
{
|
||||||
|
ImGui::Checkbox("Auto-scroll", &AutoScroll);
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options, Filter
|
||||||
|
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_O, ImGuiInputFlags_Tooltip);
|
||||||
|
if (ImGui::Button("Options"))
|
||||||
|
ImGui::OpenPopup("Options");
|
||||||
|
ImGui::SameLine();
|
||||||
|
Filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180);
|
||||||
|
ImGui::Separator();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Reserve enough left-over height for 1 separator + 1 input text
|
||||||
|
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||||
|
if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_HorizontalScrollbar))
|
||||||
|
{
|
||||||
|
if (ImGui::BeginPopupContextWindow())
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable("Clear")) ClearLog();
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display every line as a separate entry so we can change their color or add custom widgets.
|
||||||
|
// If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end());
|
||||||
|
// NB- if you have thousands of entries this approach may be too inefficient and may require user-side clipping
|
||||||
|
// to only process visible items. The clipper will automatically measure the height of your first item and then
|
||||||
|
// "seek" to display only items in the visible area.
|
||||||
|
// To use the clipper we can replace your standard loop:
|
||||||
|
// for (int i = 0; i < Items.Size; i++)
|
||||||
|
// With:
|
||||||
|
// ImGuiListClipper clipper;
|
||||||
|
// clipper.Begin(Items.Size);
|
||||||
|
// while (clipper.Step())
|
||||||
|
// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
||||||
|
// - That your items are evenly spaced (same height)
|
||||||
|
// - That you have cheap random access to your elements (you can access them given their index,
|
||||||
|
// without processing all the ones before)
|
||||||
|
// You cannot this code as-is if a filter is active because it breaks the 'cheap random-access' property.
|
||||||
|
// We would need random-access on the post-filtered list.
|
||||||
|
// A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices
|
||||||
|
// or offsets of items that passed the filtering test, recomputing this array when user changes the filter,
|
||||||
|
// and appending newly elements as they are inserted. This is left as a task to the user until we can manage
|
||||||
|
// to improve this example code!
|
||||||
|
// If your items are of variable height:
|
||||||
|
// - Split them into same height items would be simpler and facilitate random-seeking into your list.
|
||||||
|
// - Consider using manual call to IsRectVisible() and skipping extraneous decoration from your items.
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1)); // Tighten spacing
|
||||||
|
// if (copy_to_clipboard)
|
||||||
|
// ImGui::LogToClipboard();
|
||||||
|
for (const char* item : Items)
|
||||||
|
{
|
||||||
|
if (!Filter.PassFilter(item))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Normally you would store more information in your item than just a string.
|
||||||
|
// (e.g. make Items[] an array of structure, store color/type etc.)
|
||||||
|
ImVec4 color;
|
||||||
|
bool has_color = false;
|
||||||
|
if (strstr(item, "[error]")) { color = ImVec4(1.0f, 0.4f, 0.4f, 1.0f); has_color = true; }
|
||||||
|
else if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.0f, 0.8f, 0.6f, 1.0f); has_color = true; }
|
||||||
|
if (has_color)
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||||
|
ImGui::TextUnformatted(item);
|
||||||
|
if (has_color)
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
// if (copy_to_clipboard)
|
||||||
|
// ImGui::LogFinish();
|
||||||
|
|
||||||
|
// Keep up at the bottom of the scroll region if we were already at the bottom at the beginning of the frame.
|
||||||
|
// Using a scrollbar or mouse-wheel will take away from the bottom edge.
|
||||||
|
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
|
||||||
|
ImGui::SetScrollHereY(1.0f);
|
||||||
|
ScrollToBottom = false;
|
||||||
|
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// Command-line
|
||||||
|
bool reclaim_focus = false;
|
||||||
|
ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_EscapeClearsAll | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
|
||||||
|
if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this))
|
||||||
|
{
|
||||||
|
char* s = InputBuf;
|
||||||
|
Strtrim(s);
|
||||||
|
if (s[0])
|
||||||
|
ExecCommand(s);
|
||||||
|
strcpy(s, "");
|
||||||
|
reclaim_focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-focus on window apparition
|
||||||
|
ImGui::SetItemDefaultFocus();
|
||||||
|
if (reclaim_focus)
|
||||||
|
ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExecCommand(const char* command_line)
|
||||||
|
{
|
||||||
|
AddLog("# %s\n", command_line);
|
||||||
|
|
||||||
|
const char* full_command_line = command_line;
|
||||||
|
if (const char* arg = strchr(command_line, ' '))
|
||||||
|
{
|
||||||
|
|
||||||
|
static char extracted[1024];
|
||||||
|
strncpy(extracted, command_line, arg - command_line);
|
||||||
|
|
||||||
|
command_line = extracted;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert into history. First find match and delete it so it can be pushed to the back.
|
||||||
|
// This isn't trying to be smart or optimal.
|
||||||
|
HistoryPos = -1;
|
||||||
|
for (int i = History.Size - 1; i >= 0; i--)
|
||||||
|
if (Stricmp(History[i], command_line) == 0)
|
||||||
|
{
|
||||||
|
ImGui::MemFree(History[i]);
|
||||||
|
History.erase(History.begin() + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
History.push_back(Strdup(command_line));
|
||||||
|
|
||||||
|
// Process command
|
||||||
|
if (Stricmp(command_line, "CLEAR") == 0)
|
||||||
|
{
|
||||||
|
ClearLog();
|
||||||
|
}
|
||||||
|
else if (Stricmp(command_line, "HELP") == 0)
|
||||||
|
{
|
||||||
|
AddLog("Commands:");
|
||||||
|
for (int i = 0; i < Commands.Size; i++)
|
||||||
|
AddLog("- %s", Commands[i]);
|
||||||
|
}
|
||||||
|
else if (Stricmp(command_line, "HISTORY") == 0)
|
||||||
|
{
|
||||||
|
int first = History.Size - 10;
|
||||||
|
for (int i = first > 0 ? first : 0; i < History.Size; i++)
|
||||||
|
AddLog("%3d: %s\n", i, History[i]);
|
||||||
|
}
|
||||||
|
else if (Stricmp(command_line, "PH_DEBUG_DRAW") == 0)
|
||||||
|
{
|
||||||
|
if (g_PhysicsWorld)
|
||||||
|
g_PhysicsWorld->ToggleDebugDraw();
|
||||||
|
}
|
||||||
|
else if (Stricmp(command_line, "R_SCENE_DEBUG_DRAW") == 0)
|
||||||
|
{
|
||||||
|
g_sceneManager->toggleDebugRender();
|
||||||
|
}
|
||||||
|
else if (Stricmp(command_line, "R_SHOW_STATS") == 0)
|
||||||
|
{
|
||||||
|
g_render->ToggleShowStats();
|
||||||
|
}
|
||||||
|
else if (Stricmp(command_line, "R_ENTITY_DEBUG_DRAW") == 0)
|
||||||
|
{
|
||||||
|
extern bool g_debugEntityDraw;
|
||||||
|
g_debugEntityDraw = !g_debugEntityDraw;
|
||||||
|
}
|
||||||
|
else if (Stricmp(command_line, "MAP") == 0)
|
||||||
|
{
|
||||||
|
GetEngine()->NewGame(full_command_line + 4);
|
||||||
|
}
|
||||||
|
else if (Stricmp(command_line, "QUIT") == 0)
|
||||||
|
{
|
||||||
|
GetEngine()->RequestExit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddLog("Unknown command: '%s'\n", command_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// On command input, we scroll to bottom even if AutoScroll==false
|
||||||
|
ScrollToBottom = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In C++11 you'd be better off using lambdas for this sort of forwarding callbacks
|
||||||
|
static int TextEditCallbackStub(ImGuiInputTextCallbackData* data)
|
||||||
|
{
|
||||||
|
ExampleAppConsole* console = (ExampleAppConsole*)data->UserData;
|
||||||
|
return console->TextEditCallback(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextEditCallback(ImGuiInputTextCallbackData* data)
|
||||||
|
{
|
||||||
|
//AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd);
|
||||||
|
switch (data->EventFlag)
|
||||||
|
{
|
||||||
|
case ImGuiInputTextFlags_CallbackCompletion:
|
||||||
|
{
|
||||||
|
// Example of TEXT COMPLETION
|
||||||
|
|
||||||
|
// Locate beginning of current word
|
||||||
|
const char* word_end = data->Buf + data->CursorPos;
|
||||||
|
const char* word_start = word_end;
|
||||||
|
while (word_start > data->Buf)
|
||||||
|
{
|
||||||
|
const char c = word_start[-1];
|
||||||
|
if (c == ' ' || c == '\t' || c == ',' || c == ';')
|
||||||
|
break;
|
||||||
|
word_start--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a list of candidates
|
||||||
|
ImVector<const char*> candidates;
|
||||||
|
for (int i = 0; i < Commands.Size; i++)
|
||||||
|
if (Strnicmp(Commands[i], word_start, (int)(word_end - word_start)) == 0)
|
||||||
|
candidates.push_back(Commands[i]);
|
||||||
|
|
||||||
|
if (candidates.Size == 0)
|
||||||
|
{
|
||||||
|
// No match
|
||||||
|
AddLog("No match for \"%.*s\"!\n", (int)(word_end - word_start), word_start);
|
||||||
|
}
|
||||||
|
else if (candidates.Size == 1)
|
||||||
|
{
|
||||||
|
// Single match. Delete the beginning of the word and replace it entirely so we've got nice casing.
|
||||||
|
data->DeleteChars((int)(word_start - data->Buf), (int)(word_end - word_start));
|
||||||
|
data->InsertChars(data->CursorPos, candidates[0]);
|
||||||
|
data->InsertChars(data->CursorPos, " ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Multiple matches. Complete as much as we can..
|
||||||
|
// So inputting "C"+Tab will complete to "CL" then display "CLEAR" and "CLASSIFY" as matches.
|
||||||
|
int match_len = (int)(word_end - word_start);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
bool all_candidates_matches = true;
|
||||||
|
for (int i = 0; i < candidates.Size && all_candidates_matches; i++)
|
||||||
|
if (i == 0)
|
||||||
|
c = toupper(candidates[i][match_len]);
|
||||||
|
else if (c == 0 || c != toupper(candidates[i][match_len]))
|
||||||
|
all_candidates_matches = false;
|
||||||
|
if (!all_candidates_matches)
|
||||||
|
break;
|
||||||
|
match_len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_len > 0)
|
||||||
|
{
|
||||||
|
data->DeleteChars((int)(word_start - data->Buf), (int)(word_end - word_start));
|
||||||
|
data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// List matches
|
||||||
|
AddLog("Possible matches:\n");
|
||||||
|
for (int i = 0; i < candidates.Size; i++)
|
||||||
|
AddLog("- %s\n", candidates[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ImGuiInputTextFlags_CallbackHistory:
|
||||||
|
{
|
||||||
|
// Example of HISTORY
|
||||||
|
const int prev_history_pos = HistoryPos;
|
||||||
|
if (data->EventKey == ImGuiKey_UpArrow)
|
||||||
|
{
|
||||||
|
if (HistoryPos == -1)
|
||||||
|
HistoryPos = History.Size - 1;
|
||||||
|
else if (HistoryPos > 0)
|
||||||
|
HistoryPos--;
|
||||||
|
}
|
||||||
|
else if (data->EventKey == ImGuiKey_DownArrow)
|
||||||
|
{
|
||||||
|
if (HistoryPos != -1)
|
||||||
|
if (++HistoryPos >= History.Size)
|
||||||
|
HistoryPos = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A better implementation would preserve the data on the current input line along with cursor position.
|
||||||
|
if (prev_history_pos != HistoryPos)
|
||||||
|
{
|
||||||
|
const char* history_str = (HistoryPos >= 0) ? History[HistoryPos] : "";
|
||||||
|
data->DeleteChars(0, data->BufTextLen);
|
||||||
|
data->InsertChars(0, history_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static ExampleAppConsole s_console;
|
||||||
|
static bool s_showConsole = false;
|
||||||
|
static bool s_lastLockedMouse = false;
|
||||||
|
|
||||||
|
void PrintToConsole(const char* msg)
|
||||||
|
{
|
||||||
|
s_console.AddLog(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OpenConsole()
|
||||||
|
{
|
||||||
|
s_lastLockedMouse = g_inputManager.GetRelativeMouseMode();
|
||||||
|
g_inputManager.SetRelativeMouseMode(false);
|
||||||
|
|
||||||
|
s_showConsole = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CloseConsole()
|
||||||
|
{
|
||||||
|
g_inputManager.SetRelativeMouseMode(s_lastLockedMouse);
|
||||||
|
s_showConsole = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateConsole()
|
||||||
|
{
|
||||||
|
s_console.Draw("Console", NULL);
|
||||||
|
// ShowExampleAppLog(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
Engine::Engine()
|
Engine::Engine()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -186,6 +612,17 @@ void Engine::Frame_SDL()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_GRAVE) {
|
||||||
|
s_showConsole = !s_showConsole;
|
||||||
|
|
||||||
|
if (s_showConsole)
|
||||||
|
OpenConsole();
|
||||||
|
else
|
||||||
|
CloseConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// keyboard action
|
// keyboard action
|
||||||
if (event.key.key < kMaxKeyboardKeys) {
|
if (event.key.key < kMaxKeyboardKeys) {
|
||||||
if (event.type == SDL_EVENT_KEY_DOWN) {
|
if (event.type == SDL_EVENT_KEY_DOWN) {
|
||||||
@@ -213,6 +650,11 @@ void Engine::Frame_SDL()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
float dt;
|
||||||
|
}
|
||||||
|
|
||||||
void Engine::Frame()
|
void Engine::Frame()
|
||||||
{
|
{
|
||||||
// *** updating
|
// *** updating
|
||||||
@@ -224,11 +666,14 @@ void Engine::Frame()
|
|||||||
if (currentTime <= oldTime)
|
if (currentTime <= oldTime)
|
||||||
currentTime = oldTime + 1;
|
currentTime = oldTime + 1;
|
||||||
|
|
||||||
float dt = oldTime > 0 ? (float)((double)(currentTime - oldTime) / frequency) : (float)(1.0f / 60.0f);
|
dt = oldTime > 0 ? (float)((double)(currentTime - oldTime) / frequency) : (float)(1.0f / 60.0f);
|
||||||
|
|
||||||
// *** ImGui scope begin
|
// *** ImGui scope begin
|
||||||
g_ImGuiManager.BeginFrame();
|
g_ImGuiManager.BeginFrame();
|
||||||
|
|
||||||
|
if (s_showConsole)
|
||||||
|
UpdateConsole();
|
||||||
|
|
||||||
// update physics
|
// update physics
|
||||||
if (g_PhysicsWorld)
|
if (g_PhysicsWorld)
|
||||||
g_PhysicsWorld->Step(dt);
|
g_PhysicsWorld->Step(dt);
|
||||||
@@ -281,6 +726,8 @@ void Engine::RenderFrame()
|
|||||||
if (g_world)
|
if (g_world)
|
||||||
g_world->Render();
|
g_world->Render();
|
||||||
|
|
||||||
|
g_game->Render2D();
|
||||||
|
|
||||||
g_render->RenderStats();
|
g_render->RenderStats();
|
||||||
|
|
||||||
// ImGui scope end ***
|
// ImGui scope end ***
|
||||||
@@ -313,12 +760,14 @@ void Engine::NewGame(const char* mapname)
|
|||||||
Disconnect();
|
Disconnect();
|
||||||
|
|
||||||
g_PhysicsWorld = new PhysicsWorld();
|
g_PhysicsWorld = new PhysicsWorld();
|
||||||
g_PhysicsWorld->ToggleDebugDraw();
|
//g_PhysicsWorld->ToggleDebugDraw();
|
||||||
|
|
||||||
g_world = new World();
|
g_world = new World();
|
||||||
|
|
||||||
g_render->LoadSceneXML(mapname);
|
g_render->LoadSceneXML(mapname);
|
||||||
|
|
||||||
|
CloseConsole();
|
||||||
|
|
||||||
// after initializing client scene and collision system - we initialize the server game
|
// after initializing client scene and collision system - we initialize the server game
|
||||||
g_game->InitForNewMap(mapname);
|
g_game->InitForNewMap(mapname);
|
||||||
}
|
}
|
||||||
@@ -345,6 +794,16 @@ SDL_Window* Engine::GetWindow()
|
|||||||
return m_window;
|
return m_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::RequestExit()
|
||||||
|
{
|
||||||
|
m_run = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Engine::GetDelta()
|
||||||
|
{
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
|
||||||
Engine g_engine;
|
Engine g_engine;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ public:
|
|||||||
|
|
||||||
SDL_Window* GetWindow();
|
SDL_Window* GetWindow();
|
||||||
|
|
||||||
|
void RequestExit();
|
||||||
|
|
||||||
|
float GetDelta();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Window* m_window = nullptr;
|
SDL_Window* m_window = nullptr;
|
||||||
bool m_run = true;
|
bool m_run = true;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "ientity.h"
|
#include "ientity.h"
|
||||||
|
#include "world.h"
|
||||||
|
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
@@ -10,7 +11,8 @@ IEntityBase::IEntityBase() :
|
|||||||
m_rotation(0.0f),
|
m_rotation(0.0f),
|
||||||
m_scale(1.0f),
|
m_scale(1.0f),
|
||||||
m_classname(nullptr),
|
m_classname(nullptr),
|
||||||
m_id(-1)
|
m_id(-1),
|
||||||
|
m_dirtyTransform(true)
|
||||||
{
|
{
|
||||||
m_id = s_entityId++;
|
m_id = s_entityId++;
|
||||||
}
|
}
|
||||||
@@ -43,13 +45,16 @@ const glm::mat4& IEntityBase::GetWorldTransform()
|
|||||||
|
|
||||||
void IEntityBase::UpdateTransform()
|
void IEntityBase::UpdateTransform()
|
||||||
{
|
{
|
||||||
glm::vec3 radiansRotation = glm::radians(m_rotation);
|
if (!m_dirtyTransform)
|
||||||
|
return;
|
||||||
|
|
||||||
glm::mat4 T = glm::translate(glm::mat4(1.0f), m_position);
|
glm::vec3 radiansRotation = glm::vec3(glm::radians(m_rotation.x), glm::radians(m_rotation.y), glm::radians(m_rotation.z));
|
||||||
glm::mat4 R = glm::toMat4(glm::quat(radiansRotation));
|
glm::mat4 rotation = glm::toMat4(glm::quat(radiansRotation));
|
||||||
glm::mat4 S = glm::scale(glm::mat4(1.0f), m_scale);
|
|
||||||
|
|
||||||
m_worldTM = T * R * S;
|
m_worldTM = glm::mat4(1.0f);
|
||||||
|
m_worldTM = glm::translate(m_worldTM, m_position) * rotation * glm::scale(m_worldTM, m_scale);
|
||||||
|
|
||||||
|
m_dirtyTransform = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t IEntityBase::GetID()
|
uint32_t IEntityBase::GetID()
|
||||||
@@ -61,3 +66,14 @@ void IEntityBase::ResetEntityID()
|
|||||||
{
|
{
|
||||||
s_entityId = 0;
|
s_entityId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IEntityBase::MarkForDelete()
|
||||||
|
{
|
||||||
|
if (g_world)
|
||||||
|
g_world->MarkEntityToDelete(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IEntityBase::SetDirty()
|
||||||
|
{
|
||||||
|
m_dirtyTransform = true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ public:
|
|||||||
|
|
||||||
static void ResetEntityID();
|
static void ResetEntityID();
|
||||||
|
|
||||||
|
void MarkForDelete();
|
||||||
|
|
||||||
|
void SetDirty();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 m_position;
|
glm::vec3 m_position;
|
||||||
glm::vec3 m_rotation;
|
glm::vec3 m_rotation;
|
||||||
@@ -39,6 +43,8 @@ protected:
|
|||||||
const char* m_classname;
|
const char* m_classname;
|
||||||
|
|
||||||
uint32_t m_id;
|
uint32_t m_id;
|
||||||
|
|
||||||
|
bool m_dirtyTransform;
|
||||||
};
|
};
|
||||||
|
|
||||||
// registration
|
// registration
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public:
|
|||||||
glm::vec2& GetMouseDeltaPos() { return m_deltaMousePos; }
|
glm::vec2& GetMouseDeltaPos() { return m_deltaMousePos; }
|
||||||
|
|
||||||
void SetRelativeMouseMode(bool relativeMode);
|
void SetRelativeMouseMode(bool relativeMode);
|
||||||
|
bool GetRelativeMouseMode() { return m_relativeMouseMode; }
|
||||||
|
|
||||||
void Frame();
|
void Frame();
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ static int g_day_in_month[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|||||||
int build_id;
|
int build_id;
|
||||||
FILE* g_logFile;
|
FILE* g_logFile;
|
||||||
|
|
||||||
|
extern void PrintToConsole(const char* msg);
|
||||||
|
|
||||||
void CalculateBuildNumber()
|
void CalculateBuildNumber()
|
||||||
{
|
{
|
||||||
static int start_day = 3;
|
static int start_day = 3;
|
||||||
@@ -119,6 +121,8 @@ void Logger::MsgArg(const char* fmt, va_list args)
|
|||||||
|
|
||||||
//sprintf(buffer2, "[%s] %s", timestr, buffer);
|
//sprintf(buffer2, "[%s] %s", timestr, buffer);
|
||||||
|
|
||||||
|
PrintToConsole(buffer);
|
||||||
|
|
||||||
if (g_logFile)
|
if (g_logFile)
|
||||||
{
|
{
|
||||||
fwrite(buffer, sizeof(char), len, g_logFile);
|
fwrite(buffer, sizeof(char), len, g_logFile);
|
||||||
|
|||||||
@@ -136,6 +136,26 @@ void PhysicsWorld::Step(float delta)
|
|||||||
m_world->debugDrawWorld();*/
|
m_world->debugDrawWorld();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PhysicsWorld::TraceRay(TraceRayResult& _result, const glm::vec3& _rayBegin, const glm::vec3& _rayEnd, IEntityBase* _pIgnoreEntity)
|
||||||
|
{
|
||||||
|
btVector3 rayStart = glmVectorToBt(_rayBegin);
|
||||||
|
btVector3 rayEnd = glmVectorToBt(_rayEnd);
|
||||||
|
|
||||||
|
ClosestRayResultCallback RayResultCallback(rayStart, rayEnd, _pIgnoreEntity);
|
||||||
|
g_PhysicsWorld->GetWorld()->rayTest(rayStart, rayEnd, RayResultCallback);
|
||||||
|
|
||||||
|
if (RayResultCallback.hasHit())
|
||||||
|
{
|
||||||
|
_result.hit = true;
|
||||||
|
|
||||||
|
_result.pEntity = (IEntityBase*)RayResultCallback.m_collisionObject->getUserPointer();
|
||||||
|
_result.position = btVectorToGlm(RayResultCallback.m_hitPointWorld);
|
||||||
|
_result.normal = btVectorToGlm(RayResultCallback.m_hitNormalWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _result.hit;
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicsWorld::ToggleDebugDraw()
|
void PhysicsWorld::ToggleDebugDraw()
|
||||||
{
|
{
|
||||||
m_debugDraw = !m_debugDraw;
|
m_debugDraw = !m_debugDraw;
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ struct SceneCollisionModel
|
|||||||
btTriangleMesh* triangleMesh;
|
btTriangleMesh* triangleMesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TraceRayResult
|
||||||
|
{
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 normal;
|
||||||
|
IEntityBase* pEntity;
|
||||||
|
bool hit;
|
||||||
|
};
|
||||||
|
|
||||||
class PhysicsWorld
|
class PhysicsWorld
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -30,6 +38,8 @@ public:
|
|||||||
|
|
||||||
void Step(float delta);
|
void Step(float delta);
|
||||||
|
|
||||||
|
bool TraceRay(TraceRayResult& _result, const glm::vec3& _rayBegin, const glm::vec3& _rayEnd, IEntityBase* _pIgnoreEntity);
|
||||||
|
|
||||||
btDynamicsWorld* GetWorld() { return m_world; }
|
btDynamicsWorld* GetWorld() { return m_world; }
|
||||||
|
|
||||||
float GetFixedTimeStep() { return m_stepTime; }
|
float GetFixedTimeStep() { return m_stepTime; }
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ RigidBody::~RigidBody()
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// CreatePlayerBody();
|
// CreatePlayerBody_Old();
|
||||||
// UpdateBodyTranslationDirty();
|
// UpdateBodyTranslationDirty();
|
||||||
//
|
//
|
||||||
// if (changeFilterUsableHack)
|
// if (changeFilterUsableHack)
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ void World::Update(float dt)
|
|||||||
// Update entities
|
// Update entities
|
||||||
for (int i = 0; i < m_entities.size(); i++)
|
for (int i = 0; i < m_entities.size(); i++)
|
||||||
{
|
{
|
||||||
|
m_entities[i]->SetDirty();
|
||||||
m_entities[i]->Update(dt);
|
m_entities[i]->Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
380
src/game/actor_base.cpp
Normal file
380
src/game/actor_base.cpp
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
#include "actor_base.h"
|
||||||
|
#include "inputmanager.h"
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
REGISTER_ENTITY(ActorBase);
|
||||||
|
|
||||||
|
ActorBase::ActorBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ActorBase::~ActorBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBase::Update(float dt)
|
||||||
|
{
|
||||||
|
UpdateBodyDirty();
|
||||||
|
|
||||||
|
Entity::Update(dt);
|
||||||
|
|
||||||
|
AfterEngineStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBase::AfterEngineStep()
|
||||||
|
{
|
||||||
|
//btTransform xform = m_rigidBody->getWorldTransform();
|
||||||
|
//m_position = btVectorToGlm(xform.getOrigin());
|
||||||
|
|
||||||
|
m_position = btVectorToGlm(m_ph_motion_state.m_transform.getOrigin());
|
||||||
|
|
||||||
|
glm::vec3 cameraPos = m_position;
|
||||||
|
|
||||||
|
if (m_luaObject.IsTable())
|
||||||
|
{
|
||||||
|
LuaPlus::LuaObject m_camera_offset_y = m_luaObject.GetByName("m_camera_offset_y");
|
||||||
|
if (m_camera_offset_y.IsNumber())
|
||||||
|
cameraPos.y += (float)m_camera_offset_y.ToNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_camera.SetPosition(cameraPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBase::UpdateCameraMovement(float dt)
|
||||||
|
{
|
||||||
|
// calculate player movement
|
||||||
|
float speed = 12.0f * dt;
|
||||||
|
|
||||||
|
uint32_t movementDir = GenMovementDir();
|
||||||
|
|
||||||
|
if (movementDir & EMovementDir_Forward)
|
||||||
|
m_position += speed * m_camera.GetFront();
|
||||||
|
if (movementDir & EMovementDir_Backward)
|
||||||
|
m_position -= speed * m_camera.GetFront();
|
||||||
|
if (movementDir & EMovementDir_Left)
|
||||||
|
m_position -= glm::normalize(glm::cross(m_camera.GetFront(), m_camera.GetUp())) * speed;
|
||||||
|
if (movementDir & EMovementDir_Right)
|
||||||
|
m_position += glm::normalize(glm::cross(m_camera.GetFront(), m_camera.GetUp())) * speed;
|
||||||
|
|
||||||
|
// set position back to camera for calculation view matrix
|
||||||
|
m_camera.SetPosition(m_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBase::UpdateBodyMovement(float dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
glm::vec3 dir = glm::vec3(0.0f);
|
||||||
|
|
||||||
|
glm::vec3 camFront = m_camera.GetFront();
|
||||||
|
camFront.y = 0.0f;
|
||||||
|
camFront = glm::normalize(camFront);
|
||||||
|
|
||||||
|
// calculate player movement
|
||||||
|
float speed = 4.f;
|
||||||
|
|
||||||
|
uint32_t movementDir = GenMovementDir();
|
||||||
|
|
||||||
|
if (movementDir & EMovementDir_Forward)
|
||||||
|
dir += camFront;
|
||||||
|
if (movementDir & EMovementDir_Backward)
|
||||||
|
dir -= camFront;
|
||||||
|
if (movementDir & EMovementDir_Left)
|
||||||
|
dir -= glm::normalize(glm::cross(camFront, m_camera.GetUp()));
|
||||||
|
if (movementDir & EMovementDir_Right)
|
||||||
|
dir += glm::normalize(glm::cross(camFront, m_camera.GetUp()));
|
||||||
|
|
||||||
|
btVector3 currentvel = m_rigidBody->getLinearVelocity();
|
||||||
|
glm::vec3 velocity = dir * speed;
|
||||||
|
|
||||||
|
if (OnGround()) {
|
||||||
|
m_rigidBody->setLinearVelocity(btVector3(velocity.x, currentvel.y(), velocity.z));
|
||||||
|
if (movementDir & EMovementDir_Jump) {
|
||||||
|
m_rigidBody->setLinearVelocity(btVector3(currentvel.x(), PLAYER_PHYS_JUMPSPEEDY, currentvel.z()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float airControl = 0.2f;
|
||||||
|
btVector3 airvel = currentvel + glmVectorToBt(dir * speed * airControl * dt);
|
||||||
|
m_rigidBody->setLinearVelocity(btVector3(airvel.x(), currentvel.y(), airvel.z()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (glm::length(velocity) > 0.1f && OnGround() && !(movementDir & EMovementDir_Jump))
|
||||||
|
m_rigidBody->setLinearVelocity(glmVectorToBt(velocity));
|
||||||
|
|
||||||
|
if ((movementDir & EMovementDir_Jump) && OnGround()) {
|
||||||
|
m_rigidBody->applyCentralImpulse(btVector3(0.0f, PLAYER_PHYS_JUMPSPEEDY, 0.0f));
|
||||||
|
movementDir &= ~EMovementDir_Jump;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBase::UpdateCameraLook()
|
||||||
|
{
|
||||||
|
if (!g_inputManager.GetRelativeMouseMode())
|
||||||
|
return;
|
||||||
|
|
||||||
|
glm::ivec2 mousePos = g_inputManager.GetMousePos();
|
||||||
|
|
||||||
|
// calculate yaw and pitch
|
||||||
|
static float yaw = 0.0f, pitch = 0.0f;
|
||||||
|
|
||||||
|
int deltaX = mousePos.x;
|
||||||
|
int deltaY = mousePos.y;
|
||||||
|
|
||||||
|
float sensitivity = 0.15f;
|
||||||
|
|
||||||
|
yaw += deltaX * sensitivity;
|
||||||
|
pitch -= deltaY * sensitivity;
|
||||||
|
|
||||||
|
if (pitch > 89.0f) pitch = 89.0f;
|
||||||
|
if (pitch < -89.0f) pitch = -89.0f;
|
||||||
|
|
||||||
|
m_camera.SetYawPitch(yaw, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBase::ActivateCamera()
|
||||||
|
{
|
||||||
|
g_inputManager.SetRelativeMouseMode(true);
|
||||||
|
|
||||||
|
g_cameraManager.SetActiveCamera(&m_camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBase::CreatePlayerBody(float radius, float height, float mass, float friction, float damping)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_shape = new btCapsuleShape(radius, height);
|
||||||
|
|
||||||
|
m_mass = mass;
|
||||||
|
btVector3 local_inertia(0.0f, 0.0f, 0.0f);
|
||||||
|
if (m_mass > 0.f) {
|
||||||
|
m_shape->calculateLocalInertia(m_mass, local_inertia);
|
||||||
|
}
|
||||||
|
|
||||||
|
btRigidBody::btRigidBodyConstructionInfo rigid_body_ci(m_mass, nullptr, m_shape, local_inertia);
|
||||||
|
|
||||||
|
m_rigidBody = new btRigidBody(rigid_body_ci);
|
||||||
|
m_rigidBody->setUserPointer(this);
|
||||||
|
m_rigidBody->setMotionState(&m_ph_motion_state);
|
||||||
|
m_ph_motion_state.setBody(m_rigidBody);
|
||||||
|
|
||||||
|
// I'm sure that position is valid
|
||||||
|
btTransform xform;
|
||||||
|
xform.setIdentity();
|
||||||
|
xform.setOrigin(glmVectorToBt(m_position));
|
||||||
|
m_rigidBody->setWorldTransform(xform);
|
||||||
|
|
||||||
|
// ACTOR STUFF
|
||||||
|
m_rigidBody->setAngularFactor(btVector3(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
m_rigidBody->setFriction(friction);
|
||||||
|
m_rigidBody->setAnisotropicFriction(btVector3(0.0f, 0.0f, 0.0f));
|
||||||
|
m_rigidBody->setDamping(damping, 0.0f);
|
||||||
|
|
||||||
|
m_rigidBody->setActivationState(DISABLE_DEACTIVATION);
|
||||||
|
|
||||||
|
// #TODO: body filter and mask
|
||||||
|
g_PhysicsWorld->GetWorld()->addRigidBody(m_rigidBody);
|
||||||
|
|
||||||
|
m_bodyDirty = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBase::CreatePlayerBody_Old()
|
||||||
|
{
|
||||||
|
|
||||||
|
m_shape = new btCapsuleShape(PLAYER_PHYS_RADIUS, PLAYER_PHYS_HEIGHT - PLAYER_PHYS_RADIUS * 2.0);
|
||||||
|
|
||||||
|
m_mass = 80.0f;
|
||||||
|
btVector3 local_inertia(0.0f, 0.0f, 0.0f);
|
||||||
|
if (m_mass > 0.f) {
|
||||||
|
m_shape->calculateLocalInertia(m_mass, local_inertia);
|
||||||
|
}
|
||||||
|
|
||||||
|
btRigidBody::btRigidBodyConstructionInfo rigid_body_ci(m_mass, nullptr, m_shape, local_inertia);
|
||||||
|
|
||||||
|
m_rigidBody = new btRigidBody(rigid_body_ci);
|
||||||
|
m_rigidBody->setUserPointer(this);
|
||||||
|
m_rigidBody->setMotionState(&m_ph_motion_state);
|
||||||
|
m_ph_motion_state.setBody(m_rigidBody);
|
||||||
|
|
||||||
|
// I'm sure that position is valid
|
||||||
|
btTransform xform;
|
||||||
|
xform.setIdentity();
|
||||||
|
xform.setOrigin(glmVectorToBt(m_position));
|
||||||
|
m_rigidBody->setWorldTransform(xform);
|
||||||
|
|
||||||
|
// ACTOR STUFF
|
||||||
|
m_rigidBody->setAngularFactor(btVector3(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
|
||||||
|
//m_rigidBody->setFriction(2.5f);
|
||||||
|
|
||||||
|
m_rigidBody->setFriction(0.0f);
|
||||||
|
m_rigidBody->setAnisotropicFriction(btVector3(0.0f, 0.0f, 0.0f));
|
||||||
|
m_rigidBody->setDamping(0.0f, 0.0f);
|
||||||
|
|
||||||
|
m_rigidBody->setActivationState(DISABLE_DEACTIVATION);
|
||||||
|
|
||||||
|
// #TODO: body filter and mask
|
||||||
|
g_PhysicsWorld->GetWorld()->addRigidBody(m_rigidBody);
|
||||||
|
|
||||||
|
m_bodyDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ActorBase::OnGround()
|
||||||
|
{
|
||||||
|
float rayLength = (PLAYER_PHYS_HEIGHT / 2.0f) + 0.1f;
|
||||||
|
|
||||||
|
btTransform xform = m_rigidBody->getWorldTransform();
|
||||||
|
|
||||||
|
btVector3 rayStart = xform.getOrigin();
|
||||||
|
btVector3 rayEnd = rayStart - btVector3(0.0f, rayLength, 0.0f);
|
||||||
|
|
||||||
|
ClosestRayResultCallback RayResultCallback(rayStart, rayEnd, this);
|
||||||
|
g_PhysicsWorld->GetWorld()->rayTest(rayStart, rayEnd, RayResultCallback);
|
||||||
|
if (RayResultCallback.hasHit()) {
|
||||||
|
btVector3 hitNormal = RayResultCallback.m_hitNormalWorld;
|
||||||
|
if (hitNormal.y() > 0.7f) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBase::RegisterFunctions()
|
||||||
|
{
|
||||||
|
m_luaObject.Register("activate_camera", *this, &ActorBase::Lua_ActivateCamera);
|
||||||
|
m_luaObject.Register("update_camera_look", *this, &ActorBase::Lua_UpdateCameraLook);
|
||||||
|
m_luaObject.Register("update_camera_movement", *this, &ActorBase::Lua_UpdateCameraMovement);
|
||||||
|
m_luaObject.Register("create_player_body", *this, &ActorBase::Lua_CreatePlayerBody);
|
||||||
|
m_luaObject.Register("create_player_body_old", *this, &ActorBase::Lua_CreatePlayerBodyOld);
|
||||||
|
m_luaObject.Register("update_body_movement", *this, &ActorBase::Lua_UpdateBodyMovement);
|
||||||
|
m_luaObject.Register("get_action", *this, &ActorBase::Lua_GetAction);
|
||||||
|
m_luaObject.Register("get_movement", *this, &ActorBase::Lua_GetMovement);
|
||||||
|
m_luaObject.Register("on_ground", *this, &ActorBase::Lua_OnGround);
|
||||||
|
|
||||||
|
//m_luaObject.RegisterDirect("activate_camera", &ActorBase_ActivateCamera);
|
||||||
|
//m_luaObject.RegisterDirect("update_camera_look", &ActorBase_UpdateCameraLook);
|
||||||
|
//m_luaObject.RegisterDirect("update_camera_movement", &ActorBase_UpdateCameraMovement);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::Lua_UpdateCameraMovement(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
LuaPlus::LuaStack stack(state);
|
||||||
|
|
||||||
|
UpdateCameraMovement(stack[2].GetFloat());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::Lua_UpdateBodyMovement(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
LuaPlus::LuaStack stack(state);
|
||||||
|
|
||||||
|
UpdateBodyMovement(stack[2].GetFloat());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::Lua_UpdateCameraLook(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
UpdateCameraLook();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::Lua_ActivateCamera(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
ActivateCamera();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::Lua_CreatePlayerBody(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
LuaPlus::LuaStack stack(state);
|
||||||
|
|
||||||
|
float radius = (float)stack[2].GetNumber();
|
||||||
|
float height = (float)stack[3].GetNumber();
|
||||||
|
float mass = (float)stack[4].GetNumber();
|
||||||
|
float friction = (float)stack[5].GetNumber();
|
||||||
|
float damping = (float)stack[6].GetNumber();
|
||||||
|
|
||||||
|
CreatePlayerBody(radius, height, mass, friction, damping);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::Lua_CreatePlayerBodyOld(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
CreatePlayerBody_Old();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::Lua_GetAction(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
int action = GenAction();
|
||||||
|
state->PushInteger(action);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::Lua_GetMovement(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
uint32_t movement = GenMovementDir();
|
||||||
|
state->PushInteger(movement);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::Lua_OnGround(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
state->PushBoolean(OnGround());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBase::GenAction()
|
||||||
|
{
|
||||||
|
int action = -1;
|
||||||
|
|
||||||
|
if (!g_inputManager.GetRelativeMouseMode())
|
||||||
|
return action;
|
||||||
|
|
||||||
|
if (g_inputManager.GetMouse().IsKeyDown(EMouseButton_Left))
|
||||||
|
action = 0;
|
||||||
|
else if (g_inputManager.GetMouse().IsKeyDown(EMouseButton_Right))
|
||||||
|
action = 1;
|
||||||
|
else if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_R))
|
||||||
|
action = 2;
|
||||||
|
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ActorBase::GenMovementDir()
|
||||||
|
{
|
||||||
|
uint32_t movementDir = EMovementDir_None;
|
||||||
|
|
||||||
|
if (!g_inputManager.GetRelativeMouseMode())
|
||||||
|
return movementDir;
|
||||||
|
|
||||||
|
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_W)) {
|
||||||
|
movementDir |= EMovementDir_Forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_S)) {
|
||||||
|
movementDir |= EMovementDir_Backward;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_A)) {
|
||||||
|
movementDir |= EMovementDir_Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_D)) {
|
||||||
|
movementDir |= EMovementDir_Right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_SPACE)) {
|
||||||
|
movementDir |= EMovementDir_Jump;
|
||||||
|
}
|
||||||
|
|
||||||
|
return movementDir;
|
||||||
|
}
|
||||||
65
src/game/actor_base.h
Normal file
65
src/game/actor_base.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#ifndef ACTOR_BASE_H
|
||||||
|
#define ACTOR_BASE_H
|
||||||
|
|
||||||
|
#include "game_object.h"
|
||||||
|
|
||||||
|
#define PLAYER_PHYS_MASS 80.0
|
||||||
|
#define PLAYER_PHYS_RADIUS 0.40
|
||||||
|
#define PLAYER_PHYS_HEIGHT 1.79
|
||||||
|
#define PLAYER_PHYS_JUMPDIST PLAYER_PHYS_RADIUS
|
||||||
|
#define PLAYER_PHYS_JUMPHEIGHT 2.0
|
||||||
|
#define PLAYER_PHYS_JUMPSPEEDY 5.0
|
||||||
|
#define PLAYER_PHYS_WALK_SPEED ( 5.5 )
|
||||||
|
#define PLAYER_PHYS_RUN_SPEED_MUL 1.4
|
||||||
|
#define PLAYER_PHYS_MOVE_SPEED_EXP 1.0
|
||||||
|
#define PLAYER_PHYS_FLY_SPEED_EXP 4.0
|
||||||
|
|
||||||
|
class ActorBase : public Entity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActorBase();
|
||||||
|
~ActorBase();
|
||||||
|
|
||||||
|
virtual void Update(float dt);
|
||||||
|
|
||||||
|
void AfterEngineStep();
|
||||||
|
|
||||||
|
void UpdateCameraMovement(float dt);
|
||||||
|
|
||||||
|
void UpdateBodyMovement(float dt);
|
||||||
|
|
||||||
|
void UpdateCameraLook();
|
||||||
|
|
||||||
|
void ActivateCamera();
|
||||||
|
|
||||||
|
void CreatePlayerBody(float radius, float height, float mass, float friction, float damping);
|
||||||
|
void CreatePlayerBody_Old();
|
||||||
|
|
||||||
|
bool OnGround();
|
||||||
|
|
||||||
|
// Lua bindings
|
||||||
|
|
||||||
|
virtual void RegisterFunctions();
|
||||||
|
|
||||||
|
int Lua_UpdateCameraMovement(LuaPlus::LuaState* state);
|
||||||
|
int Lua_UpdateBodyMovement(LuaPlus::LuaState* state);
|
||||||
|
int Lua_UpdateCameraLook(LuaPlus::LuaState* state);
|
||||||
|
int Lua_ActivateCamera(LuaPlus::LuaState* state);
|
||||||
|
int Lua_CreatePlayerBody(LuaPlus::LuaState* state);
|
||||||
|
int Lua_CreatePlayerBodyOld(LuaPlus::LuaState* state);
|
||||||
|
int Lua_GetAction(LuaPlus::LuaState* state);
|
||||||
|
int Lua_GetMovement(LuaPlus::LuaState* state);
|
||||||
|
int Lua_OnGround(LuaPlus::LuaState* state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int GenAction();
|
||||||
|
uint32_t GenMovementDir();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Camera m_camera;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !ACTOR_BASE_H
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
#include "ifilesystem.h"
|
#include "ifilesystem.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "engine.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "game_lua_help.h"
|
#include "game_lua_help.h"
|
||||||
|
#include "game_ui.h"
|
||||||
|
#include "inputmanager.h"
|
||||||
#include "ientity.h"
|
#include "ientity.h"
|
||||||
#include "entitymanager.h"
|
#include "entitymanager.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
@@ -105,6 +108,129 @@ void engineAddEntityToWorld(LuaPlus::LuaObject& object)
|
|||||||
g_world->AddEntity(entity);
|
g_world->AddEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LuaPlus::LuaObject engineTraceRay(float rayBeginX, float rayBeginY, float rayBeginZ,
|
||||||
|
float rayEndX, float rayEndY, float rayEndZ, const LuaPlus::LuaObject& ignoreTable)
|
||||||
|
{
|
||||||
|
IEntityBase* pIgnoreEntity = nullptr;
|
||||||
|
if (ignoreTable.IsTable())
|
||||||
|
{
|
||||||
|
LuaPlus::LuaObject ignoreEntityTable = ignoreTable.GetByName("__object");
|
||||||
|
if (ignoreEntityTable.IsLightUserdata())
|
||||||
|
pIgnoreEntity = (IEntityBase*)ignoreEntityTable.GetLightUserdata();
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceRayResult result = {};
|
||||||
|
glm::vec3 rayBegin = glm::vec3(rayBeginX, rayBeginY, rayBeginZ);
|
||||||
|
glm::vec3 rayEnd = glm::vec3(rayEndX, rayEndY, rayEndZ);
|
||||||
|
|
||||||
|
if (g_PhysicsWorld)
|
||||||
|
g_PhysicsWorld->TraceRay(result, rayBegin, rayEnd, pIgnoreEntity);
|
||||||
|
else
|
||||||
|
Logger::Msg("engine.trace_ray(): no server started or game loaded!");
|
||||||
|
|
||||||
|
LuaPlus::LuaObject resultTable = GetLuaState().CreateTable();
|
||||||
|
resultTable.SetNumber("pos_x", result.position.x);
|
||||||
|
resultTable.SetNumber("pos_y", result.position.y);
|
||||||
|
resultTable.SetNumber("pos_z", result.position.z);
|
||||||
|
resultTable.SetNumber("normal_x", result.normal.x);
|
||||||
|
resultTable.SetNumber("normal_y", result.normal.y);
|
||||||
|
resultTable.SetNumber("normal_z", result.normal.z);
|
||||||
|
resultTable.SetInteger("entity_id", result.pEntity ? result.pEntity->GetID() : -1);
|
||||||
|
resultTable.SetInteger("hit", result.hit);
|
||||||
|
return resultTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
float engineGetDelta()
|
||||||
|
{
|
||||||
|
return GetEngine()->GetDelta();
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerEngine()
|
||||||
|
{
|
||||||
|
using namespace LuaPlus;
|
||||||
|
|
||||||
|
// register engine functions
|
||||||
|
LuaObject engineTable = GetLuaState().GetGlobals().CreateTable("engine");
|
||||||
|
engineTable.RegisterDirect("error", &engineError);
|
||||||
|
engineTable.RegisterDirect("warning", &engineWarning);
|
||||||
|
engineTable.RegisterDirect("create_entity", &engineCreateEntity);
|
||||||
|
engineTable.RegisterDirect("add_entity_to_world", &engineAddEntityToWorld);
|
||||||
|
engineTable.RegisterDirect("get_entity_from_id", &engineGetEntityFromID);
|
||||||
|
engineTable.RegisterDirect("play_sound", &enginePlaySound);
|
||||||
|
engineTable.RegisterDirect("get_delta", &engineGetDelta);
|
||||||
|
engineTable.RegisterDirect("trace_ray", &engineTraceRay);
|
||||||
|
|
||||||
|
LuaObject consoleTable = GetLuaState().GetGlobals().CreateTable("console");
|
||||||
|
consoleTable.RegisterDirect("print", &consoleMsg);
|
||||||
|
|
||||||
|
registerCamera();
|
||||||
|
|
||||||
|
registerInput();
|
||||||
|
|
||||||
|
registerEngineUI();
|
||||||
|
|
||||||
|
// action globals
|
||||||
|
GetLuaState().DoString("ACTION_FIRE = 0");
|
||||||
|
GetLuaState().DoString("ACTION_ALT_FIRE = 1");
|
||||||
|
GetLuaState().DoString("ACTION_RELOAD = 2");
|
||||||
|
GetLuaState().DoString("ACTION_USE = 3");
|
||||||
|
|
||||||
|
// animations globals
|
||||||
|
GetLuaState().DoString("ANIM_PLAYBACK_NONE = 0");
|
||||||
|
GetLuaState().DoString("ANIM_PLAYBACK_REPEAT = 1");
|
||||||
|
|
||||||
|
|
||||||
|
char buffer[64];
|
||||||
|
|
||||||
|
#define REGISTER_CONSTANT(constant) \
|
||||||
|
snprintf(buffer, sizeof(buffer), #constant" = %d", constant); \
|
||||||
|
GetLuaState().DoString(buffer)
|
||||||
|
|
||||||
|
REGISTER_CONSTANT(EMovementDir_None);
|
||||||
|
REGISTER_CONSTANT(EMovementDir_Forward);
|
||||||
|
REGISTER_CONSTANT(EMovementDir_Backward);
|
||||||
|
REGISTER_CONSTANT(EMovementDir_Left);
|
||||||
|
REGISTER_CONSTANT(EMovementDir_Right);
|
||||||
|
REGISTER_CONSTANT(EMovementDir_Jump);
|
||||||
|
|
||||||
|
#undef REGISTER_CONSTANT
|
||||||
|
}
|
||||||
|
|
||||||
|
int inputGetMousePos(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
const glm::vec2& pos = g_inputManager.GetMousePos();
|
||||||
|
state->PushNumber(pos.x);
|
||||||
|
state->PushNumber(pos.y);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inputGetDeltaMousePos(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
const glm::vec2& pos = g_inputManager.GetMouseDeltaPos();
|
||||||
|
state->PushNumber(pos.x);
|
||||||
|
state->PushNumber(pos.y);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void inputLock(bool value)
|
||||||
|
{
|
||||||
|
g_inputManager.SetRelativeMouseMode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inputGetLock()
|
||||||
|
{
|
||||||
|
return g_inputManager.GetRelativeMouseMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerInput()
|
||||||
|
{
|
||||||
|
LuaPlus::LuaObject inputTable = GetLuaState().GetGlobals().CreateTable("input");
|
||||||
|
inputTable.Register("get_mouse_pos", &inputGetMousePos);
|
||||||
|
inputTable.Register("get_delta_mouse_pos", &inputGetDeltaMousePos);
|
||||||
|
inputTable.RegisterDirect("lock_mouse", &inputLock);
|
||||||
|
inputTable.RegisterDirect("get_lock_mouse", &inputGetLock);
|
||||||
|
}
|
||||||
|
|
||||||
int cameraGetPos(LuaPlus::LuaState* state)
|
int cameraGetPos(LuaPlus::LuaState* state)
|
||||||
{
|
{
|
||||||
glm::vec3 v = glm::vec3(0.0f);
|
glm::vec3 v = glm::vec3(0.0f);
|
||||||
@@ -191,39 +317,23 @@ int cameraGetPitch(LuaPlus::LuaState* state)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerEngine()
|
void cameraSetYawPitch(float yaw, float pitch)
|
||||||
{
|
{
|
||||||
using namespace LuaPlus;
|
Camera* camera = g_cameraManager.GetActiveCamera();
|
||||||
|
if (camera)
|
||||||
|
camera->SetYawPitch(yaw, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
// register engine functions
|
void registerCamera()
|
||||||
LuaObject engineTable = GetLuaState().GetGlobals().CreateTable("engine");
|
{
|
||||||
engineTable.RegisterDirect("error", &engineError);
|
LuaPlus::LuaObject cameraTable = GetLuaState().GetGlobals().CreateTable("camera");
|
||||||
engineTable.RegisterDirect("warning", &engineWarning);
|
|
||||||
engineTable.RegisterDirect("create_entity", &engineCreateEntity);
|
|
||||||
engineTable.RegisterDirect("add_entity_to_world", &engineAddEntityToWorld);
|
|
||||||
engineTable.RegisterDirect("get_entity_from_id", &engineGetEntityFromID);
|
|
||||||
engineTable.RegisterDirect("play_sound", &enginePlaySound);
|
|
||||||
|
|
||||||
LuaObject consoleTable = GetLuaState().GetGlobals().CreateTable("console");
|
|
||||||
consoleTable.RegisterDirect("print", &consoleMsg);
|
|
||||||
|
|
||||||
LuaObject cameraTable = GetLuaState().GetGlobals().CreateTable("camera");
|
|
||||||
cameraTable.Register("get_position", &cameraGetPos);
|
cameraTable.Register("get_position", &cameraGetPos);
|
||||||
cameraTable.Register("get_front", &cameraGetFront);
|
cameraTable.Register("get_front", &cameraGetFront);
|
||||||
cameraTable.Register("get_right", &cameraGetRight);
|
cameraTable.Register("get_right", &cameraGetRight);
|
||||||
cameraTable.Register("get_up", &cameraGetUp);
|
cameraTable.Register("get_up", &cameraGetUp);
|
||||||
cameraTable.Register("get_yaw", &cameraGetYaw);
|
cameraTable.Register("get_yaw", &cameraGetYaw);
|
||||||
cameraTable.Register("get_pitch", &cameraGetPitch);
|
cameraTable.Register("get_pitch", &cameraGetPitch);
|
||||||
|
cameraTable.RegisterDirect("set_yaw_pitch", &cameraSetYawPitch);
|
||||||
// action globals
|
|
||||||
GetLuaState().DoString("ACTION_FIRE = 0");
|
|
||||||
GetLuaState().DoString("ACTION_ALT_FIRE = 1");
|
|
||||||
GetLuaState().DoString("ACTION_RELOAD = 2");
|
|
||||||
|
|
||||||
// animations globals
|
|
||||||
GetLuaState().DoString("ANIM_PLAYBACK_NONE = 0");
|
|
||||||
GetLuaState().DoString("ANIM_PLAYBACK_REPEAT = 1");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerClasses()
|
void registerClasses()
|
||||||
@@ -477,6 +587,11 @@ void Game::Shutdown()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::Render2D()
|
||||||
|
{
|
||||||
|
gameRenderUI();
|
||||||
|
}
|
||||||
|
|
||||||
//LuaPrototype* pluaprototype = Lua_FindPrototype(classname);
|
//LuaPrototype* pluaprototype = Lua_FindPrototype(classname);
|
||||||
//
|
//
|
||||||
//if (pluaprototype)
|
//if (pluaprototype)
|
||||||
|
|||||||
@@ -18,8 +18,13 @@ public:
|
|||||||
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
|
void Render2D();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Game* g_game;
|
extern Game* g_game;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void registerCamera();
|
||||||
|
|
||||||
|
void registerInput();
|
||||||
|
|||||||
@@ -1,68 +1,9 @@
|
|||||||
|
#include "core.h"
|
||||||
#include "inputmanager.h"
|
#include "inputmanager.h"
|
||||||
#include "debugrender.h"
|
#include "debugrender.h"
|
||||||
#include "game_object.h"
|
#include "game_object.h"
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#define PLAYER_PHYS_MASS 80.0
|
|
||||||
#define PLAYER_PHYS_RADIUS 0.40
|
|
||||||
#define PLAYER_PHYS_HEIGHT 1.79
|
|
||||||
#define PLAYER_PHYS_JUMPDIST PLAYER_PHYS_RADIUS
|
|
||||||
#define PLAYER_PHYS_JUMPHEIGHT 2.0
|
|
||||||
#define PLAYER_PHYS_JUMPSPEEDY 5.0
|
|
||||||
#define PLAYER_PHYS_WALK_SPEED ( 5.5 )
|
|
||||||
#define PLAYER_PHYS_RUN_SPEED_MUL 1.4
|
|
||||||
#define PLAYER_PHYS_MOVE_SPEED_EXP 1.0
|
|
||||||
#define PLAYER_PHYS_FLY_SPEED_EXP 4.0
|
|
||||||
|
|
||||||
// Lua wrappers
|
|
||||||
void Entity_LoadModel(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
LuaPlus::LuaStack stack(state);
|
|
||||||
|
|
||||||
Entity* entity = (Entity*)stack[1].GetByName("__object").GetLightUserdata();
|
|
||||||
entity->LoadModel(stack[2].GetString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Entity_SetVisible(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
LuaPlus::LuaStack stack(state);
|
|
||||||
|
|
||||||
Entity* entity = (Entity*)stack[1].GetByName("__object").GetLightUserdata();
|
|
||||||
entity->SetVisible(stack[2].GetBoolean());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Entity_GetVisible(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
LuaPlus::LuaStack stack(state);
|
|
||||||
|
|
||||||
Entity* entity = (Entity*)stack[1].GetByName("__object").GetLightUserdata();
|
|
||||||
return entity->GetVisible();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase_UpdateCameraMovement(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
LuaPlus::LuaStack stack(state);
|
|
||||||
|
|
||||||
ActorBase* entity = (ActorBase*)stack[1].GetByName("__object").GetLightUserdata();
|
|
||||||
entity->UpdateCameraMovement(stack[2].GetFloat());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase_UpdateCameraLook(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
LuaPlus::LuaStack stack(state);
|
|
||||||
|
|
||||||
ActorBase* entity = (ActorBase*)stack[1].GetByName("__object").GetLightUserdata();
|
|
||||||
entity->UpdateCameraLook();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase_ActivateCamera(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
LuaPlus::LuaStack stack(state);
|
|
||||||
|
|
||||||
ActorBase* entity = (ActorBase*)stack[1].GetByName("__object").GetLightUserdata();
|
|
||||||
entity->ActivateCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_ENTITY(Entity);
|
REGISTER_ENTITY(Entity);
|
||||||
|
|
||||||
Entity::Entity() :
|
Entity::Entity() :
|
||||||
@@ -96,6 +37,20 @@ Entity::~Entity()
|
|||||||
|
|
||||||
m_luaObject.AssignNil();
|
m_luaObject.AssignNil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_rigidBody) {
|
||||||
|
g_PhysicsWorld->GetWorld()->removeRigidBody(m_rigidBody);
|
||||||
|
|
||||||
|
delete m_rigidBody;
|
||||||
|
m_rigidBody = nullptr;
|
||||||
|
|
||||||
|
m_ph_motion_state.setBody(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_shape) {
|
||||||
|
delete m_shape;
|
||||||
|
m_shape = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::Update(float dt)
|
void Entity::Update(float dt)
|
||||||
@@ -113,16 +68,20 @@ void Entity::Update(float dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool g_debugEntityDraw = false;
|
||||||
|
|
||||||
void Entity::Render()
|
void Entity::Render()
|
||||||
{
|
{
|
||||||
if (m_model)
|
if (m_model)
|
||||||
{
|
|
||||||
m_model->Draw(GetWorldTransform(), m_skeleton);
|
m_model->Draw(GetWorldTransform(), m_skeleton);
|
||||||
|
|
||||||
/*BoundingBox bbox = m_boundingBox;
|
|
||||||
|
if (g_debugEntityDraw)
|
||||||
|
{
|
||||||
|
BoundingBox bbox = m_boundingBox;
|
||||||
bbox.TransformAABB(GetWorldTransform());
|
bbox.TransformAABB(GetWorldTransform());
|
||||||
|
|
||||||
g_debugRender->DrawBoundingBox(bbox, glm::vec3(1.0f, 0.0f, 0.0f));*/
|
g_debugRender->DrawBoundingBox(bbox, glm::vec3(1.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,10 +169,7 @@ void Entity::InitFromTable(LuaPlus::LuaObject& _object)
|
|||||||
m_luaObject = _object;
|
m_luaObject = _object;
|
||||||
|
|
||||||
// find functions
|
// find functions
|
||||||
m_onInitFunction = m_luaObject.GetByName("on_init");
|
InitLuaCallbacks();
|
||||||
m_onShutdownFunction = m_luaObject.GetByName("on_shutdown");
|
|
||||||
m_onUpdateFunction = m_luaObject.GetByName("on_update");
|
|
||||||
m_onCollideFunction = m_luaObject.GetByName("on_collide");
|
|
||||||
|
|
||||||
// check
|
// check
|
||||||
//SDL_assert_always(m_onInitFunction.IsFunction() || m_onShutdownFunction.IsFunction() || m_onUpdateFunction.IsFunction());
|
//SDL_assert_always(m_onInitFunction.IsFunction() || m_onShutdownFunction.IsFunction() || m_onUpdateFunction.IsFunction());
|
||||||
@@ -228,6 +184,14 @@ void Entity::InitFromTable(LuaPlus::LuaObject& _object)
|
|||||||
m_luaObject.SetLightUserdata("__object", this);
|
m_luaObject.SetLightUserdata("__object", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Entity::InitLuaCallbacks()
|
||||||
|
{
|
||||||
|
m_onInitFunction = m_luaObject.GetByName("on_init");
|
||||||
|
m_onShutdownFunction = m_luaObject.GetByName("on_shutdown");
|
||||||
|
m_onUpdateFunction = m_luaObject.GetByName("on_update");
|
||||||
|
m_onCollideFunction = m_luaObject.GetByName("on_collide");
|
||||||
|
}
|
||||||
|
|
||||||
void Entity::RegisterBaseFunctions()
|
void Entity::RegisterBaseFunctions()
|
||||||
{
|
{
|
||||||
m_luaObject.Register("load_model", *this, &Entity::Lua_LoadModel);
|
m_luaObject.Register("load_model", *this, &Entity::Lua_LoadModel);
|
||||||
@@ -236,13 +200,21 @@ void Entity::RegisterBaseFunctions()
|
|||||||
m_luaObject.Register("set_position", *this, &Entity::Lua_SetPosition);
|
m_luaObject.Register("set_position", *this, &Entity::Lua_SetPosition);
|
||||||
m_luaObject.Register("get_position", *this, &Entity::Lua_GetPosition);
|
m_luaObject.Register("get_position", *this, &Entity::Lua_GetPosition);
|
||||||
m_luaObject.Register("set_rotation", *this, &Entity::Lua_SetRotation);
|
m_luaObject.Register("set_rotation", *this, &Entity::Lua_SetRotation);
|
||||||
|
m_luaObject.Register("get_rotation", *this, &Entity::Lua_GetRotation);
|
||||||
m_luaObject.Register("set_rotation_from_vectors", *this, &Entity::Lua_SetRotationFromVectors);
|
m_luaObject.Register("set_rotation_from_vectors", *this, &Entity::Lua_SetRotationFromVectors);
|
||||||
m_luaObject.Register("get_classname", *this, &Entity::Lua_GetClassname);
|
m_luaObject.Register("get_classname", *this, &Entity::Lua_GetClassname);
|
||||||
m_luaObject.Register("get_id", *this, &Entity::Lua_GetID);
|
m_luaObject.Register("get_id", *this, &Entity::Lua_GetID);
|
||||||
|
m_luaObject.Register("mark_for_delete", *this, &Entity::Lua_MarkForDelete);
|
||||||
|
|
||||||
|
// physics
|
||||||
|
m_luaObject.Register("set_velocity", *this, &Entity::Lua_SetVelocity);
|
||||||
|
m_luaObject.Register("get_velocity", *this, &Entity::Lua_GetVelocity);
|
||||||
|
m_luaObject.Register("has_rigid_body", *this, &Entity::Lua_HasRigidBody);
|
||||||
|
|
||||||
// animation
|
// animation
|
||||||
m_luaObject.Register("find_animation", *this, &Entity::Lua_FindAnimation);
|
m_luaObject.Register("find_animation", *this, &Entity::Lua_FindAnimation);
|
||||||
m_luaObject.Register("play_animation", *this, &Entity::Lua_PlayAnimation);
|
m_luaObject.Register("play_animation", *this, &Entity::Lua_PlayAnimation);
|
||||||
|
m_luaObject.Register("stop_animation", *this, &Entity::Lua_StopAnimation);
|
||||||
m_luaObject.Register("get_current_animation", *this, &Entity::Lua_GetCurrentAnimation);
|
m_luaObject.Register("get_current_animation", *this, &Entity::Lua_GetCurrentAnimation);
|
||||||
m_luaObject.Register("get_current_animation_time", *this, &Entity::Lua_GetCurrentAnimationTime);
|
m_luaObject.Register("get_current_animation_time", *this, &Entity::Lua_GetCurrentAnimationTime);
|
||||||
m_luaObject.Register("get_animation_time", *this, &Entity::Lua_GetAnimationTime);
|
m_luaObject.Register("get_animation_time", *this, &Entity::Lua_GetAnimationTime);
|
||||||
@@ -299,6 +271,12 @@ void Entity::Help_SetRotationFromVectors(const glm::vec3& front, const glm::vec3
|
|||||||
m_rotation = glm::degrees(glm::eulerAngles(q));
|
m_rotation = glm::degrees(glm::eulerAngles(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Entity::Help_SetVelocity(float x, float y, float z)
|
||||||
|
{
|
||||||
|
if (m_rigidBody)
|
||||||
|
m_rigidBody->setLinearVelocity(btVector3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
int Entity::Lua_LoadModel(LuaPlus::LuaState* state)
|
int Entity::Lua_LoadModel(LuaPlus::LuaState* state)
|
||||||
{
|
{
|
||||||
LuaPlus::LuaStack stack(state);
|
LuaPlus::LuaStack stack(state);
|
||||||
@@ -349,6 +327,14 @@ int Entity::Lua_GetPosition(LuaPlus::LuaState* state)
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Entity::Lua_GetRotation(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
state->PushNumber(m_rotation.x);
|
||||||
|
state->PushNumber(m_rotation.y);
|
||||||
|
state->PushNumber(m_rotation.z);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
int Entity::Lua_SetRotation(LuaPlus::LuaState* state)
|
int Entity::Lua_SetRotation(LuaPlus::LuaState* state)
|
||||||
{
|
{
|
||||||
LuaPlus::LuaStack stack(state);
|
LuaPlus::LuaStack stack(state);
|
||||||
@@ -405,11 +391,58 @@ int Entity::Lua_UpdateTransform(LuaPlus::LuaState* state)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Entity::Lua_MarkForDelete(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
MarkForDelete();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entity::Lua_SetVelocity(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
LuaPlus::LuaStack stack(state);
|
||||||
|
|
||||||
|
float x = stack[2].GetNumber();
|
||||||
|
float y = stack[3].GetNumber();
|
||||||
|
float z = stack[4].GetNumber();
|
||||||
|
|
||||||
|
Help_SetVelocity(x, y, z);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entity::Lua_GetVelocity(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
glm::vec3 velocity = glm::vec3(0.0f);
|
||||||
|
if (m_rigidBody)
|
||||||
|
{
|
||||||
|
velocity = btVectorToGlm(m_rigidBody->getLinearVelocity());
|
||||||
|
}
|
||||||
|
|
||||||
|
state->PushNumber(velocity.x);
|
||||||
|
state->PushNumber(velocity.y);
|
||||||
|
state->PushNumber(velocity.z);
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entity::Lua_HasRigidBody(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
state->PushBoolean(!!m_rigidBody);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int Entity::Lua_FindAnimation(LuaPlus::LuaState* state)
|
int Entity::Lua_FindAnimation(LuaPlus::LuaState* state)
|
||||||
{
|
{
|
||||||
LuaPlus::LuaStack stack(state);
|
LuaPlus::LuaStack stack(state);
|
||||||
const char* name = stack[2].GetString();
|
const char* name = stack[2].GetString();
|
||||||
|
|
||||||
|
if (!stack[2].IsString())
|
||||||
|
{
|
||||||
|
Core::Warning("load_model: first argument is not an string");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_model)
|
if (m_model)
|
||||||
state->PushInteger(m_model->FindAnimation(name));
|
state->PushInteger(m_model->FindAnimation(name));
|
||||||
else
|
else
|
||||||
@@ -421,6 +454,13 @@ int Entity::Lua_FindAnimation(LuaPlus::LuaState* state)
|
|||||||
int Entity::Lua_PlayAnimation(LuaPlus::LuaState* state)
|
int Entity::Lua_PlayAnimation(LuaPlus::LuaState* state)
|
||||||
{
|
{
|
||||||
LuaPlus::LuaStack stack(state);
|
LuaPlus::LuaStack stack(state);
|
||||||
|
|
||||||
|
if (!stack[2].IsNumber())
|
||||||
|
{
|
||||||
|
Core::Warning("play_animation: first argument is not an number");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
AnimationId_t id = stack[2].GetInteger();
|
AnimationId_t id = stack[2].GetInteger();
|
||||||
int mode = stack[3].GetInteger();
|
int mode = stack[3].GetInteger();
|
||||||
|
|
||||||
@@ -430,6 +470,14 @@ int Entity::Lua_PlayAnimation(LuaPlus::LuaState* state)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Entity::Lua_StopAnimation(LuaPlus::LuaState* state)
|
||||||
|
{
|
||||||
|
if (m_skeleton)
|
||||||
|
m_skeleton->StopAnimation();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int Entity::Lua_GetCurrentAnimation(LuaPlus::LuaState* state)
|
int Entity::Lua_GetCurrentAnimation(LuaPlus::LuaState* state)
|
||||||
{
|
{
|
||||||
if (m_skeleton)
|
if (m_skeleton)
|
||||||
@@ -517,336 +565,6 @@ void Entity::UpdateBodyDirty()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_ENTITY(ActorBase);
|
|
||||||
|
|
||||||
ActorBase::ActorBase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ActorBase::~ActorBase()
|
|
||||||
{
|
|
||||||
if (m_rigidBody) {
|
|
||||||
g_PhysicsWorld->GetWorld()->removeRigidBody(m_rigidBody);
|
|
||||||
|
|
||||||
delete m_rigidBody;
|
|
||||||
m_rigidBody = nullptr;
|
|
||||||
|
|
||||||
m_ph_motion_state.setBody(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_shape) {
|
|
||||||
delete m_shape;
|
|
||||||
m_shape = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase::Update(float dt)
|
|
||||||
{
|
|
||||||
static bool s_test = true;
|
|
||||||
|
|
||||||
if (s_test) {
|
|
||||||
UpdateBodyDirty();
|
|
||||||
Entity::Update(dt);
|
|
||||||
AfterEngineStep();
|
|
||||||
} else {
|
|
||||||
ActivateCamera();
|
|
||||||
|
|
||||||
UpdateCameraLook();
|
|
||||||
|
|
||||||
UpdateCameraMovement(dt);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase::AfterEngineStep()
|
|
||||||
{
|
|
||||||
//btTransform xform = m_rigidBody->getWorldTransform();
|
|
||||||
//m_position = btVectorToGlm(xform.getOrigin());
|
|
||||||
|
|
||||||
m_position = btVectorToGlm(m_ph_motion_state.m_transform.getOrigin());
|
|
||||||
|
|
||||||
glm::vec3 cameraPos = m_position;
|
|
||||||
|
|
||||||
if (m_luaObject.IsTable())
|
|
||||||
{
|
|
||||||
LuaPlus::LuaObject m_camera_offset_y = m_luaObject.GetByName("m_camera_offset_y");
|
|
||||||
if (m_camera_offset_y.IsNumber())
|
|
||||||
cameraPos.y += m_camera_offset_y.ToNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_camera.SetPosition(cameraPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase::UpdateCameraMovement(float dt)
|
|
||||||
{
|
|
||||||
// calculate player movement
|
|
||||||
float speed = 12.0f * dt;
|
|
||||||
|
|
||||||
uint32_t movementDir = GenMovementDir();
|
|
||||||
|
|
||||||
if (movementDir & EMovementDir_Forward)
|
|
||||||
m_position += speed * m_camera.GetFront();
|
|
||||||
if (movementDir & EMovementDir_Backward)
|
|
||||||
m_position -= speed * m_camera.GetFront();
|
|
||||||
if (movementDir & EMovementDir_Left)
|
|
||||||
m_position -= glm::normalize(glm::cross(m_camera.GetFront(), m_camera.GetUp())) * speed;
|
|
||||||
if (movementDir & EMovementDir_Right)
|
|
||||||
m_position += glm::normalize(glm::cross(m_camera.GetFront(), m_camera.GetUp())) * speed;
|
|
||||||
|
|
||||||
// set position back to camera for calculation view matrix
|
|
||||||
m_camera.SetPosition(m_position);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase::UpdateBodyMovement(float dt)
|
|
||||||
{
|
|
||||||
|
|
||||||
glm::vec3 dir = glm::vec3(0.0f);
|
|
||||||
|
|
||||||
glm::vec3 camFront = m_camera.GetFront();
|
|
||||||
camFront.y = 0.0f;
|
|
||||||
camFront = glm::normalize(camFront);
|
|
||||||
|
|
||||||
// calculate player movement
|
|
||||||
float speed = 4.f;
|
|
||||||
|
|
||||||
uint32_t movementDir = GenMovementDir();
|
|
||||||
|
|
||||||
if (movementDir & EMovementDir_Forward)
|
|
||||||
dir += camFront;
|
|
||||||
if (movementDir & EMovementDir_Backward)
|
|
||||||
dir -= camFront;
|
|
||||||
if (movementDir & EMovementDir_Left)
|
|
||||||
dir -= glm::normalize(glm::cross(camFront, m_camera.GetUp()));
|
|
||||||
if (movementDir & EMovementDir_Right)
|
|
||||||
dir += glm::normalize(glm::cross(camFront, m_camera.GetUp()));
|
|
||||||
|
|
||||||
btVector3 currentvel = m_rigidBody->getLinearVelocity();
|
|
||||||
glm::vec3 velocity = dir * speed;
|
|
||||||
|
|
||||||
if (OnGround()) {
|
|
||||||
m_rigidBody->setLinearVelocity(btVector3(velocity.x, currentvel.y(), velocity.z));
|
|
||||||
if (movementDir & EMovementDir_Jump) {
|
|
||||||
m_rigidBody->setLinearVelocity(btVector3(currentvel.x(), PLAYER_PHYS_JUMPSPEEDY, currentvel.z()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
float airControl = 0.2f;
|
|
||||||
btVector3 airvel = currentvel + glmVectorToBt(dir * speed * airControl * dt);
|
|
||||||
m_rigidBody->setLinearVelocity(btVector3(airvel.x(), currentvel.y(), airvel.z()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (glm::length(velocity) > 0.1f && OnGround() && !(movementDir & EMovementDir_Jump))
|
|
||||||
m_rigidBody->setLinearVelocity(glmVectorToBt(velocity));
|
|
||||||
|
|
||||||
if ((movementDir & EMovementDir_Jump) && OnGround()) {
|
|
||||||
m_rigidBody->applyCentralImpulse(btVector3(0.0f, PLAYER_PHYS_JUMPSPEEDY, 0.0f));
|
|
||||||
movementDir &= ~EMovementDir_Jump;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase::UpdateCameraLook()
|
|
||||||
{
|
|
||||||
glm::ivec2 mousePos = g_inputManager.GetMousePos();
|
|
||||||
|
|
||||||
// calculate yaw and pitch
|
|
||||||
static float yaw = 0.0f, pitch = 0.0f;
|
|
||||||
|
|
||||||
int deltaX = mousePos.x;
|
|
||||||
int deltaY = mousePos.y;
|
|
||||||
|
|
||||||
float sensitivity = 0.15f;
|
|
||||||
|
|
||||||
yaw += deltaX * sensitivity;
|
|
||||||
pitch -= deltaY * sensitivity;
|
|
||||||
|
|
||||||
if (pitch > 89.0f) pitch = 89.0f;
|
|
||||||
if (pitch < -89.0f) pitch = -89.0f;
|
|
||||||
|
|
||||||
m_camera.SetYawPitch(yaw, pitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase::ActivateCamera()
|
|
||||||
{
|
|
||||||
g_inputManager.SetRelativeMouseMode(true);
|
|
||||||
|
|
||||||
g_cameraManager.SetActiveCamera(&m_camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase::CreatePlayerBody()
|
|
||||||
{
|
|
||||||
|
|
||||||
m_shape = new btCapsuleShape(PLAYER_PHYS_RADIUS, PLAYER_PHYS_HEIGHT - PLAYER_PHYS_RADIUS * 2.0);
|
|
||||||
|
|
||||||
m_mass = 80.0f;
|
|
||||||
btVector3 local_inertia(0.0f, 0.0f, 0.0f);
|
|
||||||
if (m_mass > 0.f) {
|
|
||||||
m_shape->calculateLocalInertia(m_mass, local_inertia);
|
|
||||||
}
|
|
||||||
|
|
||||||
btRigidBody::btRigidBodyConstructionInfo rigid_body_ci(m_mass, nullptr, m_shape, local_inertia);
|
|
||||||
|
|
||||||
m_rigidBody = new btRigidBody(rigid_body_ci);
|
|
||||||
m_rigidBody->setUserPointer(this);
|
|
||||||
m_rigidBody->setMotionState(&m_ph_motion_state);
|
|
||||||
m_ph_motion_state.setBody(m_rigidBody);
|
|
||||||
|
|
||||||
// I'm sure that position is valid
|
|
||||||
btTransform xform;
|
|
||||||
xform.setIdentity();
|
|
||||||
xform.setOrigin(glmVectorToBt(m_position));
|
|
||||||
m_rigidBody->setWorldTransform(xform);
|
|
||||||
|
|
||||||
// ACTOR STUFF
|
|
||||||
m_rigidBody->setAngularFactor(btVector3(0.0f, 0.0f, 0.0f));
|
|
||||||
|
|
||||||
|
|
||||||
//m_rigidBody->setFriction(2.5f);
|
|
||||||
|
|
||||||
m_rigidBody->setFriction(0.0f);
|
|
||||||
m_rigidBody->setAnisotropicFriction(btVector3(0.0f, 0.0f, 0.0f));
|
|
||||||
m_rigidBody->setDamping(0.0f, 0.0f);
|
|
||||||
|
|
||||||
m_rigidBody->setActivationState(DISABLE_DEACTIVATION);
|
|
||||||
|
|
||||||
// #TODO: body filter and mask
|
|
||||||
g_PhysicsWorld->GetWorld()->addRigidBody(m_rigidBody);
|
|
||||||
|
|
||||||
m_bodyDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ActorBase::OnGround()
|
|
||||||
{
|
|
||||||
float rayLength = (PLAYER_PHYS_HEIGHT / 2.0f) + 0.1f;
|
|
||||||
|
|
||||||
btTransform xform = m_rigidBody->getWorldTransform();
|
|
||||||
|
|
||||||
btVector3 rayStart = xform.getOrigin();
|
|
||||||
btVector3 rayEnd = rayStart - btVector3(0.0f, rayLength, 0.0f);
|
|
||||||
|
|
||||||
ClosestRayResultCallback RayResultCallback(rayStart, rayEnd, this);
|
|
||||||
g_PhysicsWorld->GetWorld()->rayTest(rayStart, rayEnd, RayResultCallback);
|
|
||||||
if (RayResultCallback.hasHit()) {
|
|
||||||
btVector3 hitNormal = RayResultCallback.m_hitNormalWorld;
|
|
||||||
if (hitNormal.y() > 0.7f) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorBase::RegisterFunctions()
|
|
||||||
{
|
|
||||||
m_luaObject.Register("activate_camera", *this, &ActorBase::Lua_ActivateCamera);
|
|
||||||
m_luaObject.Register("update_camera_look", *this, &ActorBase::Lua_UpdateCameraLook);
|
|
||||||
m_luaObject.Register("update_camera_movement", *this, &ActorBase::Lua_UpdateCameraMovement);
|
|
||||||
m_luaObject.Register("create_body", *this, &ActorBase::Lua_CreateBody);
|
|
||||||
m_luaObject.Register("update_body_movement", *this, &ActorBase::Lua_UpdateBodyMovement);
|
|
||||||
m_luaObject.Register("get_action", *this, &ActorBase::Lua_GetAction);
|
|
||||||
|
|
||||||
//m_luaObject.RegisterDirect("activate_camera", &ActorBase_ActivateCamera);
|
|
||||||
//m_luaObject.RegisterDirect("update_camera_look", &ActorBase_UpdateCameraLook);
|
|
||||||
//m_luaObject.RegisterDirect("update_camera_movement", &ActorBase_UpdateCameraMovement);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ActorBase::Lua_UpdateCameraMovement(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
LuaPlus::LuaStack stack(state);
|
|
||||||
|
|
||||||
UpdateCameraMovement(stack[2].GetFloat());
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ActorBase::Lua_UpdateBodyMovement(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
LuaPlus::LuaStack stack(state);
|
|
||||||
|
|
||||||
UpdateBodyMovement(stack[2].GetFloat());
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ActorBase::Lua_UpdateCameraLook(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
UpdateCameraLook();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ActorBase::Lua_ActivateCamera(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
ActivateCamera();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ActorBase::Lua_CreateBody(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
CreatePlayerBody();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ActorBase::Lua_GetAction(LuaPlus::LuaState* state)
|
|
||||||
{
|
|
||||||
// uint32_t action = 0;
|
|
||||||
|
|
||||||
//float x, y;
|
|
||||||
//SDL_MouseButtonFlags buttons = SDL_GetMouseState(&x, &y);
|
|
||||||
|
|
||||||
//if (buttons & SDL_BUTTON_MASK(SDL_BUTTON_LEFT))
|
|
||||||
// state->PushInteger(0);
|
|
||||||
//if (buttons & SDL_BUTTON_MASK(SDL_BUTTON_RIGHT))
|
|
||||||
// state->PushInteger(1);
|
|
||||||
//else
|
|
||||||
// state->PushInteger(-1);
|
|
||||||
|
|
||||||
int action = GenAction();
|
|
||||||
state->PushInteger(action);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ActorBase::GenAction()
|
|
||||||
{
|
|
||||||
int action = -1;
|
|
||||||
|
|
||||||
if (g_inputManager.GetMouse().IsKeyDown(EMouseButton_Left))
|
|
||||||
action = 0;
|
|
||||||
else if (g_inputManager.GetMouse().IsKeyDown(EMouseButton_Right))
|
|
||||||
action = 1;
|
|
||||||
else if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_R))
|
|
||||||
action = 2;
|
|
||||||
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ActorBase::GenMovementDir()
|
|
||||||
{
|
|
||||||
uint32_t movementDir = EMovementDir_None;
|
|
||||||
|
|
||||||
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_W)) {
|
|
||||||
movementDir |= EMovementDir_Forward;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_S)) {
|
|
||||||
movementDir |= EMovementDir_Backward;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_A)) {
|
|
||||||
movementDir |= EMovementDir_Left;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_D)) {
|
|
||||||
movementDir |= EMovementDir_Right;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_inputManager.GetKeyboard().IsKeyDown(SDLK_SPACE)) {
|
|
||||||
movementDir |= EMovementDir_Jump;
|
|
||||||
}
|
|
||||||
|
|
||||||
return movementDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_ENTITY(WeaponBase);
|
REGISTER_ENTITY(WeaponBase);
|
||||||
|
|
||||||
WeaponBase::WeaponBase()
|
WeaponBase::WeaponBase()
|
||||||
@@ -859,8 +577,58 @@ WeaponBase::~WeaponBase()
|
|||||||
|
|
||||||
void WeaponBase::Update(float dt)
|
void WeaponBase::Update(float dt)
|
||||||
{
|
{
|
||||||
|
Entity::Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeaponBase::Fire(const glm::vec3& direction, float damage)
|
void WeaponBase::Fire(const glm::vec3& direction, float damage)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//// Lua wrappers
|
||||||
|
//void Entity_LoadModel(LuaPlus::LuaState* state)
|
||||||
|
//{
|
||||||
|
// LuaPlus::LuaStack stack(state);
|
||||||
|
//
|
||||||
|
// Entity* entity = (Entity*)stack[1].GetByName("__object").GetLightUserdata();
|
||||||
|
// entity->LoadModel(stack[2].GetString());
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void Entity_SetVisible(LuaPlus::LuaState* state)
|
||||||
|
//{
|
||||||
|
// LuaPlus::LuaStack stack(state);
|
||||||
|
//
|
||||||
|
// Entity* entity = (Entity*)stack[1].GetByName("__object").GetLightUserdata();
|
||||||
|
// entity->SetVisible(stack[2].GetBoolean());
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//bool Entity_GetVisible(LuaPlus::LuaState* state)
|
||||||
|
//{
|
||||||
|
// LuaPlus::LuaStack stack(state);
|
||||||
|
//
|
||||||
|
// Entity* entity = (Entity*)stack[1].GetByName("__object").GetLightUserdata();
|
||||||
|
// return entity->GetVisible();
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void ActorBase_UpdateCameraMovement(LuaPlus::LuaState* state)
|
||||||
|
//{
|
||||||
|
// LuaPlus::LuaStack stack(state);
|
||||||
|
//
|
||||||
|
// ActorBase* entity = (ActorBase*)stack[1].GetByName("__object").GetLightUserdata();
|
||||||
|
// entity->UpdateCameraMovement(stack[2].GetFloat());
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void ActorBase_UpdateCameraLook(LuaPlus::LuaState* state)
|
||||||
|
//{
|
||||||
|
// LuaPlus::LuaStack stack(state);
|
||||||
|
//
|
||||||
|
// ActorBase* entity = (ActorBase*)stack[1].GetByName("__object").GetLightUserdata();
|
||||||
|
// entity->UpdateCameraLook();
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void ActorBase_ActivateCamera(LuaPlus::LuaState* state)
|
||||||
|
//{
|
||||||
|
// LuaPlus::LuaStack stack(state);
|
||||||
|
//
|
||||||
|
// ActorBase* entity = (ActorBase*)stack[1].GetByName("__object").GetLightUserdata();
|
||||||
|
// entity->ActivateCamera();
|
||||||
|
//}
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ public:
|
|||||||
// Game entity lua bindings
|
// Game entity lua bindings
|
||||||
|
|
||||||
void InitFromTable(LuaPlus::LuaObject& _object);
|
void InitFromTable(LuaPlus::LuaObject& _object);
|
||||||
|
void InitLuaCallbacks();
|
||||||
void RegisterBaseFunctions();
|
void RegisterBaseFunctions();
|
||||||
virtual void RegisterFunctions();
|
virtual void RegisterFunctions();
|
||||||
|
|
||||||
@@ -97,19 +98,27 @@ public:
|
|||||||
void Help_SetPosition(float x, float y, float z);
|
void Help_SetPosition(float x, float y, float z);
|
||||||
void Help_SetRotation(float x, float y, float z);
|
void Help_SetRotation(float x, float y, float z);
|
||||||
void Help_SetRotationFromVectors(const glm::vec3& front, const glm::vec3& right, const glm::vec3& up);
|
void Help_SetRotationFromVectors(const glm::vec3& front, const glm::vec3& right, const glm::vec3& up);
|
||||||
|
void Help_SetVelocity(float x, float y, float z);
|
||||||
|
|
||||||
int Lua_LoadModel(LuaPlus::LuaState* state);
|
int Lua_LoadModel(LuaPlus::LuaState* state);
|
||||||
int Lua_Translate(LuaPlus::LuaState* state);
|
int Lua_Translate(LuaPlus::LuaState* state);
|
||||||
int Lua_SetPosition(LuaPlus::LuaState* state);
|
int Lua_SetPosition(LuaPlus::LuaState* state);
|
||||||
int Lua_GetPosition(LuaPlus::LuaState* state);
|
int Lua_GetPosition(LuaPlus::LuaState* state);
|
||||||
|
int Lua_GetRotation(LuaPlus::LuaState* state);
|
||||||
int Lua_SetRotation(LuaPlus::LuaState* state);
|
int Lua_SetRotation(LuaPlus::LuaState* state);
|
||||||
int Lua_SetRotationFromVectors(LuaPlus::LuaState* state);
|
int Lua_SetRotationFromVectors(LuaPlus::LuaState* state);
|
||||||
int Lua_GetClassname(LuaPlus::LuaState* state);
|
int Lua_GetClassname(LuaPlus::LuaState* state);
|
||||||
int Lua_GetID(LuaPlus::LuaState* state);
|
int Lua_GetID(LuaPlus::LuaState* state);
|
||||||
int Lua_UpdateTransform(LuaPlus::LuaState* state);
|
int Lua_UpdateTransform(LuaPlus::LuaState* state);
|
||||||
|
int Lua_MarkForDelete(LuaPlus::LuaState* state);
|
||||||
|
|
||||||
|
int Lua_SetVelocity(LuaPlus::LuaState* state);
|
||||||
|
int Lua_GetVelocity(LuaPlus::LuaState* state);
|
||||||
|
int Lua_HasRigidBody(LuaPlus::LuaState* state);
|
||||||
|
|
||||||
int Lua_FindAnimation(LuaPlus::LuaState* state);
|
int Lua_FindAnimation(LuaPlus::LuaState* state);
|
||||||
int Lua_PlayAnimation(LuaPlus::LuaState* state);
|
int Lua_PlayAnimation(LuaPlus::LuaState* state);
|
||||||
|
int Lua_StopAnimation(LuaPlus::LuaState* state);
|
||||||
int Lua_GetCurrentAnimation(LuaPlus::LuaState* state);
|
int Lua_GetCurrentAnimation(LuaPlus::LuaState* state);
|
||||||
int Lua_GetCurrentAnimationTime(LuaPlus::LuaState* state);
|
int Lua_GetCurrentAnimationTime(LuaPlus::LuaState* state);
|
||||||
int Lua_GetAnimationTime(LuaPlus::LuaState* state);
|
int Lua_GetAnimationTime(LuaPlus::LuaState* state);
|
||||||
@@ -136,49 +145,6 @@ protected:
|
|||||||
bool m_bodyDirty;
|
bool m_bodyDirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ActorBase : public Entity
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ActorBase();
|
|
||||||
~ActorBase();
|
|
||||||
|
|
||||||
virtual void Update(float dt);
|
|
||||||
|
|
||||||
void AfterEngineStep();
|
|
||||||
|
|
||||||
void UpdateCameraMovement(float dt);
|
|
||||||
|
|
||||||
void UpdateBodyMovement(float dt);
|
|
||||||
|
|
||||||
void UpdateCameraLook();
|
|
||||||
|
|
||||||
void ActivateCamera();
|
|
||||||
|
|
||||||
void CreatePlayerBody();
|
|
||||||
|
|
||||||
bool OnGround();
|
|
||||||
|
|
||||||
// Lua bindings
|
|
||||||
|
|
||||||
virtual void RegisterFunctions();
|
|
||||||
|
|
||||||
int Lua_UpdateCameraMovement(LuaPlus::LuaState* state);
|
|
||||||
int Lua_UpdateBodyMovement(LuaPlus::LuaState* state);
|
|
||||||
int Lua_UpdateCameraLook(LuaPlus::LuaState* state);
|
|
||||||
int Lua_ActivateCamera(LuaPlus::LuaState* state);
|
|
||||||
int Lua_CreateBody(LuaPlus::LuaState* state);
|
|
||||||
int Lua_GetAction(LuaPlus::LuaState* state);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int GenAction();
|
|
||||||
uint32_t GenMovementDir();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Camera m_camera;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class WeaponBase : public Entity
|
class WeaponBase : public Entity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
79
src/game/game_ui.cpp
Normal file
79
src/game/game_ui.cpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#include "core.h"
|
||||||
|
#include "game_ui.h"
|
||||||
|
#include "game_lua_help.h"
|
||||||
|
#include "texturesmanager.h"
|
||||||
|
|
||||||
|
#include <ImGui.h>
|
||||||
|
|
||||||
|
using namespace LuaPlus;
|
||||||
|
|
||||||
|
uint32_t ColorFromLua(const LuaObject& color)
|
||||||
|
{
|
||||||
|
SDL_assert_always(color.IsTable());
|
||||||
|
|
||||||
|
float r = color[1].ToNumber();
|
||||||
|
float g = color[2].ToNumber();
|
||||||
|
float b = color[3].ToNumber();
|
||||||
|
float a = color[4].ToNumber();
|
||||||
|
|
||||||
|
return ImGui::ColorConvertFloat4ToU32(ImVec4(r, g, b, a));
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiDrawText(const char* text, float x, float y, const LuaObject& color)
|
||||||
|
{
|
||||||
|
ImGui::GetBackgroundDrawList()->AddText(ImVec2(x, y), ColorFromLua(color), text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiDrawRect(float x, float y, float w, float h, const LuaObject& color)
|
||||||
|
{
|
||||||
|
ImGui::GetBackgroundDrawList()->AddRectFilled(ImVec2(x, y), ImVec2(w, h), ColorFromLua(color));
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiDrawImage(const char* filename, float x, float y, float w, float h, const LuaObject& color)
|
||||||
|
{
|
||||||
|
ImTextureID texture = (ImTextureID)g_texturesManager->LoadTexture2D(filename);
|
||||||
|
ImGui::GetBackgroundDrawList()->AddImage(texture, ImVec2(x, y), ImVec2(w, h), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), ColorFromLua(color));
|
||||||
|
}
|
||||||
|
|
||||||
|
int uiGetDisplaySize(LuaState* state)
|
||||||
|
{
|
||||||
|
state->PushNumber(ImGui::GetIO().DisplaySize.x);
|
||||||
|
state->PushNumber(ImGui::GetIO().DisplaySize.y);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uiGetMousePos(LuaState* state)
|
||||||
|
{
|
||||||
|
state->PushNumber(ImGui::GetIO().MousePos.x);
|
||||||
|
state->PushNumber(ImGui::GetIO().MousePos.y);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uiCalcTextWidth(LuaState* state)
|
||||||
|
{
|
||||||
|
LuaStack stack(state);
|
||||||
|
SDL_assert_always(stack[1].IsString());
|
||||||
|
|
||||||
|
state->PushNumber(ImGui::CalcTextSize(stack[1].GetString()).x);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerEngineUI()
|
||||||
|
{
|
||||||
|
LuaObject uiTable = GetLuaState().GetGlobals().CreateTable("ui");
|
||||||
|
uiTable.RegisterDirect("draw_text", &uiDrawText);
|
||||||
|
uiTable.RegisterDirect("draw_rect", &uiDrawRect);
|
||||||
|
uiTable.RegisterDirect("draw_image", &uiDrawImage);
|
||||||
|
uiTable.Register("get_display_size", &uiGetDisplaySize);
|
||||||
|
uiTable.Register("get_mouse_pos", &uiGetMousePos);
|
||||||
|
uiTable.Register("calc_text_width", &uiCalcTextWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gameRenderUI()
|
||||||
|
{
|
||||||
|
LuaObject renderFunction = GetLuaState().GetGlobal("game_hud_draw");
|
||||||
|
|
||||||
|
LuaFunctionVoid function = renderFunction;
|
||||||
|
function();
|
||||||
|
}
|
||||||
8
src/game/game_ui.h
Normal file
8
src/game/game_ui.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef GAME_UI_H
|
||||||
|
#define GAME_UI_H
|
||||||
|
|
||||||
|
void registerEngineUI();
|
||||||
|
|
||||||
|
void gameRenderUI();
|
||||||
|
|
||||||
|
#endif // !GAME_UI_H
|
||||||
@@ -674,24 +674,24 @@ void Model::Draw(const glm::mat4& model, SkeletonInstance* instance /*= nullptr*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// debug draw
|
// debug draw
|
||||||
if (instance)
|
//if (instance)
|
||||||
{
|
//{
|
||||||
glm::mat4 worldMat;
|
// glm::mat4 worldMat;
|
||||||
glm::mat4 worldMatParent;
|
// glm::mat4 worldMatParent;
|
||||||
for (int i = 0; i < instance->m_jointMatrices.size(); i++)
|
// for (int i = 0; i < instance->m_jointMatrices.size(); i++)
|
||||||
{
|
// {
|
||||||
worldMat = model * instance->m_jointMatrices[i];
|
// worldMat = model * instance->m_jointMatrices[i];
|
||||||
glm::vec3 worldPos = worldMat[3];
|
// glm::vec3 worldPos = worldMat[3];
|
||||||
// g_debugRender->DrawAxis(worldPos);
|
// // g_debugRender->DrawAxis(worldPos);
|
||||||
|
|
||||||
const Joint& joint = instance->m_joints[i];
|
// const Joint& joint = instance->m_joints[i];
|
||||||
if (joint.parentId != -1)
|
// if (joint.parentId != -1)
|
||||||
{
|
// {
|
||||||
worldMatParent = model * instance->m_jointMatrices[joint.parentId];
|
// worldMatParent = model * instance->m_jointMatrices[joint.parentId];
|
||||||
g_debugRender->DrawLine(worldMat[3], worldMatParent[3], glm::vec3(1.0f, 1.0f, 1.0f));
|
// g_debugRender->DrawLine(worldMat[3], worldMatParent[3], glm::vec3(1.0f, 1.0f, 1.0f));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,7 +764,7 @@ void Model::UpdateSkeletonInstance(SkeletonInstance* instance, float dt)
|
|||||||
instance->m_time += dt;
|
instance->m_time += dt;
|
||||||
|
|
||||||
float frameTime = 1.0f / animation.framerate;
|
float frameTime = 1.0f / animation.framerate;
|
||||||
float totalDuration = animation.numFrames * frameTime;
|
float totalDuration = (animation.numFrames - 1) * frameTime;
|
||||||
|
|
||||||
if (instance->m_time >= totalDuration && instance->m_looped)
|
if (instance->m_time >= totalDuration && instance->m_looped)
|
||||||
instance->m_time = 0.0f;
|
instance->m_time = 0.0f;
|
||||||
@@ -772,11 +772,17 @@ void Model::UpdateSkeletonInstance(SkeletonInstance* instance, float dt)
|
|||||||
float animationFrame = instance->m_time / frameTime;
|
float animationFrame = instance->m_time / frameTime;
|
||||||
int frameA = (int)(floor(animationFrame));
|
int frameA = (int)(floor(animationFrame));
|
||||||
int frameB = (frameA + 1) % animation.numFrames;
|
int frameB = (frameA + 1) % animation.numFrames;
|
||||||
|
float t = animationFrame - frameA;
|
||||||
|
|
||||||
if (!instance->m_looped && frameA >= animation.numFrames - 1)
|
if (!instance->m_looped && frameA >= animation.numFrames - 1)
|
||||||
frameA = animation.numFrames - 1;
|
frameA = animation.numFrames - 1;
|
||||||
|
|
||||||
float t = animationFrame - frameA;
|
if (instance->m_time >= totalDuration)
|
||||||
|
{
|
||||||
|
frameA = animation.numFrames - 1;
|
||||||
|
frameB = animation.numFrames - 1;
|
||||||
|
t = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < instance->m_joints.size(); ++i)
|
for (int i = 0; i < instance->m_joints.size(); ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
static GLuint g_VAO = 0;
|
static GLuint g_VAO = 0;
|
||||||
|
|
||||||
static int g_NumModels = 0;
|
int g_NumModels = 0;
|
||||||
|
|
||||||
// TEMP
|
// TEMP
|
||||||
glm::vec3 g_viewOrigin;
|
glm::vec3 g_viewOrigin;
|
||||||
@@ -77,7 +77,8 @@ Render::Render() :
|
|||||||
m_pWindow(nullptr),
|
m_pWindow(nullptr),
|
||||||
m_pGLContext(nullptr),
|
m_pGLContext(nullptr),
|
||||||
m_pStretchedPicVBuf(nullptr),
|
m_pStretchedPicVBuf(nullptr),
|
||||||
m_usingVAO(false)
|
m_usingVAO(false),
|
||||||
|
m_showStats(true)
|
||||||
{
|
{
|
||||||
m_viewMatrix = glm::identity<glm::mat4>();
|
m_viewMatrix = glm::identity<glm::mat4>();
|
||||||
m_projectionMatrix = glm::identity<glm::mat4>();
|
m_projectionMatrix = glm::identity<glm::mat4>();
|
||||||
@@ -296,6 +297,9 @@ void Render::RenderScene() {
|
|||||||
|
|
||||||
void Render::RenderStats()
|
void Render::RenderStats()
|
||||||
{
|
{
|
||||||
|
if (!m_showStats)
|
||||||
|
return;
|
||||||
|
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
|
|
||||||
snprintf(buffer, sizeof(buffer), "FPS: %.1f", ImGui::GetIO().Framerate);
|
snprintf(buffer, sizeof(buffer), "FPS: %.1f", ImGui::GetIO().Framerate);
|
||||||
@@ -343,6 +347,11 @@ void Render::LoadSceneXML(const char* filename)
|
|||||||
g_sceneManager->loadScene(filename);
|
g_sceneManager->loadScene(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Render::ToggleShowStats()
|
||||||
|
{
|
||||||
|
m_showStats = !m_showStats;
|
||||||
|
}
|
||||||
|
|
||||||
//IRender* GetRender()
|
//IRender* GetRender()
|
||||||
//{
|
//{
|
||||||
// return g_render;
|
// return g_render;
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ public:
|
|||||||
|
|
||||||
SDL_GLContext GetGLContext() { return m_pGLContext; }
|
SDL_GLContext GetGLContext() { return m_pGLContext; }
|
||||||
|
|
||||||
|
void ToggleShowStats();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glm::mat4 m_viewMatrix;
|
glm::mat4 m_viewMatrix;
|
||||||
glm::mat4 m_projectionMatrix;
|
glm::mat4 m_projectionMatrix;
|
||||||
@@ -46,6 +48,7 @@ private:
|
|||||||
GPUBuffer* m_pStretchedPicVBuf;
|
GPUBuffer* m_pStretchedPicVBuf;
|
||||||
|
|
||||||
bool m_usingVAO;
|
bool m_usingVAO;
|
||||||
|
bool m_showStats;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Render* g_render;
|
extern Render* g_render;
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
|
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
|
extern int g_NumModels;
|
||||||
|
static bool g_debugRenderScene = false;
|
||||||
|
|
||||||
static std::string getFileExtension(const std::string& filename)
|
static std::string getFileExtension(const std::string& filename)
|
||||||
{
|
{
|
||||||
size_t whereIsDot = filename.find_last_of('.');
|
size_t whereIsDot = filename.find_last_of('.');
|
||||||
@@ -398,7 +401,8 @@ void SceneManager::renderScene(const glm::mat4& cameraTranslation)
|
|||||||
|
|
||||||
(*it)->RenderObjects();
|
(*it)->RenderObjects();
|
||||||
|
|
||||||
g_debugRender->DrawBoundingBox((*it)->GetBoundingBox(), glm::vec3(1.0f));
|
if (g_debugRenderScene)
|
||||||
|
g_debugRender->DrawBoundingBox((*it)->GetBoundingBox(), glm::vec3(1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,6 +486,11 @@ const char* SceneManager::getSceneName()
|
|||||||
return m_sceneName.c_str();
|
return m_sceneName.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneManager::toggleDebugRender()
|
||||||
|
{
|
||||||
|
g_debugRenderScene = !g_debugRenderScene;
|
||||||
|
}
|
||||||
|
|
||||||
// SceneStaticMesh
|
// SceneStaticMesh
|
||||||
|
|
||||||
SceneStaticMesh::SceneStaticMesh() :
|
SceneStaticMesh::SceneStaticMesh() :
|
||||||
@@ -818,7 +827,7 @@ void R_SceneStaticMesh_BindShader(const glm::mat4& worldMatrix, Texture2D* albed
|
|||||||
{
|
{
|
||||||
glm::vec4 lightPos = glm::vec4(1.0f, 1.0f, 1.0f, 0.0f);
|
glm::vec4 lightPos = glm::vec4(1.0f, 1.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
g_debugRender->DrawAxis(glm::vec3(lightPos));
|
// g_debugRender->DrawAxis(glm::vec3(lightPos));
|
||||||
|
|
||||||
Camera* camera = g_cameraManager.GetActiveCamera();
|
Camera* camera = g_cameraManager.GetActiveCamera();
|
||||||
if (camera)
|
if (camera)
|
||||||
@@ -853,4 +862,6 @@ void SceneStaticMesh::RenderObjects()
|
|||||||
R_SceneStaticMesh_BindShader(s_identity, m_albedoTexture);
|
R_SceneStaticMesh_BindShader(s_identity, m_albedoTexture);
|
||||||
|
|
||||||
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_vbcount);
|
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_vbcount);
|
||||||
|
|
||||||
|
g_NumModels++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ public:
|
|||||||
// \brief Get current scene name.
|
// \brief Get current scene name.
|
||||||
const char* getSceneName();
|
const char* getSceneName();
|
||||||
|
|
||||||
|
// \brief Toggle an debug rendering.
|
||||||
|
void toggleDebugRender();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadSceneXML(const char* filename);
|
void LoadSceneXML(const char* filename);
|
||||||
void loadSkybox(const char*);
|
void loadSkybox(const char*);
|
||||||
|
|||||||
Reference in New Issue
Block a user