feat: players interpolation & add hud.set_allow_pause(...)
This commit is contained in:
parent
036e13a2ca
commit
2fa71b3bf0
@ -19,7 +19,7 @@ function on_render()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local rx, ry, rz = player.get_rot(pid)
|
local rx, ry, rz = player.get_rot(pid, true)
|
||||||
rig:set_matrix(headIndex, mat4.rotate({1, 0, 0}, ry))
|
rig:set_matrix(headIndex, mat4.rotate({1, 0, 0}, ry))
|
||||||
rig:set_matrix(bodyIndex, mat4.rotate({0, 1, 0}, rx))
|
rig:set_matrix(bodyIndex, mat4.rotate({0, 1, 0}, rx))
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,7 @@ local Skeleton = {__index={
|
|||||||
set_visible=function(self, i, b) return __skeleton.set_visible(self.eid, i, b) end,
|
set_visible=function(self, i, b) return __skeleton.set_visible(self.eid, i, b) end,
|
||||||
get_color=function(self) return __skeleton.get_color(self.eid) end,
|
get_color=function(self) return __skeleton.get_color(self.eid) end,
|
||||||
set_color=function(self, color) return __skeleton.set_color(self.eid, color) end,
|
set_color=function(self, color) return __skeleton.set_color(self.eid, color) end,
|
||||||
|
set_interpolated=function(self, b) return __skeleton.set_interpolated(self.eid, b) end,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
local function new_Skeleton(eid)
|
local function new_Skeleton(eid)
|
||||||
|
|||||||
@ -223,7 +223,8 @@ void Hud::cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Hud::processInput(bool visible) {
|
void Hud::processInput(bool visible) {
|
||||||
if (!Window::isFocused() && !pause && !isInventoryOpen()) {
|
auto menu = gui.getMenu();
|
||||||
|
if (!Window::isFocused() && !menu->hasOpenPage() && !isInventoryOpen()) {
|
||||||
setPause(true);
|
setPause(true);
|
||||||
}
|
}
|
||||||
if (!pause && visible && Events::jactive(BIND_HUD_INVENTORY)) {
|
if (!pause && visible && Events::jactive(BIND_HUD_INVENTORY)) {
|
||||||
@ -318,14 +319,13 @@ void Hud::update(bool visible) {
|
|||||||
if (!visible && inventoryOpen) {
|
if (!visible && inventoryOpen) {
|
||||||
closeInventory();
|
closeInventory();
|
||||||
}
|
}
|
||||||
if (pause && menu->getCurrent().panel == nullptr) {
|
if (pause && !menu->hasOpenPage()) {
|
||||||
setPause(false);
|
setPause(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gui.isFocusCaught()) {
|
if (!gui.isFocusCaught()) {
|
||||||
processInput(visible);
|
processInput(visible);
|
||||||
}
|
}
|
||||||
if ((pause || inventoryOpen) == Events::_cursor_locked) {
|
if ((menu->hasOpenPage() || inventoryOpen) == Events::isCursorLocked()) {
|
||||||
Events::toggleCursor();
|
Events::toggleCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,7 +590,9 @@ void Hud::draw(const DrawContext& ctx){
|
|||||||
const Viewport& viewport = ctx.getViewport();
|
const Viewport& viewport = ctx.getViewport();
|
||||||
const uint width = viewport.getWidth();
|
const uint width = viewport.getWidth();
|
||||||
const uint height = viewport.getHeight();
|
const uint height = viewport.getHeight();
|
||||||
|
auto menu = gui.getMenu();
|
||||||
|
|
||||||
|
darkOverlay->setVisible(menu->hasOpenPage());
|
||||||
updateElementsPosition(viewport);
|
updateElementsPosition(viewport);
|
||||||
|
|
||||||
uicamera->setFov(height);
|
uicamera->setFov(height);
|
||||||
@ -676,19 +678,20 @@ void Hud::setPause(bool pause) {
|
|||||||
if (this->pause == pause) {
|
if (this->pause == pause) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (allowPause) {
|
||||||
this->pause = pause;
|
this->pause = pause;
|
||||||
|
}
|
||||||
|
|
||||||
if (inventoryOpen) {
|
if (inventoryOpen) {
|
||||||
closeInventory();
|
closeInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& menu = gui.getMenu();
|
const auto& menu = gui.getMenu();
|
||||||
if (pause) {
|
if (menu->hasOpenPage()) {
|
||||||
menu->setPage("pause");
|
|
||||||
} else {
|
|
||||||
menu->reset();
|
menu->reset();
|
||||||
|
} else {
|
||||||
|
menu->setPage("pause");
|
||||||
}
|
}
|
||||||
darkOverlay->setVisible(pause);
|
|
||||||
menu->setVisible(pause);
|
menu->setVisible(pause);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,3 +724,12 @@ void Hud::setDebugCheats(bool flag) {
|
|||||||
debugPanel->setZIndex(2);
|
debugPanel->setZIndex(2);
|
||||||
gui.add(debugPanel);
|
gui.add(debugPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hud::setAllowPause(bool flag) {
|
||||||
|
if (pause) {
|
||||||
|
auto menu = gui.getMenu();
|
||||||
|
setPause(false);
|
||||||
|
menu->setPage("pause", true);
|
||||||
|
}
|
||||||
|
allowPause = flag;
|
||||||
|
}
|
||||||
|
|||||||
@ -113,6 +113,8 @@ class Hud : public util::ObjectsKeeper {
|
|||||||
bool showContentPanel = true;
|
bool showContentPanel = true;
|
||||||
/// @brief Provide cheat controllers to the debug panel
|
/// @brief Provide cheat controllers to the debug panel
|
||||||
bool allowDebugCheats = true;
|
bool allowDebugCheats = true;
|
||||||
|
/// @brief Allow actual pause
|
||||||
|
bool allowPause = true;
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
/// @brief UI element will be dynamicly positioned near to inventory or in screen center
|
/// @brief UI element will be dynamicly positioned near to inventory or in screen center
|
||||||
std::shared_ptr<gui::UINode> secondUI;
|
std::shared_ptr<gui::UINode> secondUI;
|
||||||
@ -206,6 +208,8 @@ public:
|
|||||||
|
|
||||||
void setDebugCheats(bool flag);
|
void setDebugCheats(bool flag);
|
||||||
|
|
||||||
|
void setAllowPause(bool flag);
|
||||||
|
|
||||||
static bool showGeneratorMinimap;
|
static bool showGeneratorMinimap;
|
||||||
|
|
||||||
/// @brief Runtime updating debug visualization texture
|
/// @brief Runtime updating debug visualization texture
|
||||||
|
|||||||
@ -168,8 +168,9 @@ void LevelScreen::updateHotkeys() {
|
|||||||
|
|
||||||
void LevelScreen::update(float delta) {
|
void LevelScreen::update(float delta) {
|
||||||
gui::GUI* gui = engine.getGUI();
|
gui::GUI* gui = engine.getGUI();
|
||||||
|
auto menu = gui->getMenu();
|
||||||
|
|
||||||
bool inputLocked = hud->isPause() ||
|
bool inputLocked = menu->hasOpenPage() ||
|
||||||
hud->isInventoryOpen() ||
|
hud->isInventoryOpen() ||
|
||||||
gui->isFocusCaught();
|
gui->isFocusCaught();
|
||||||
if (!gui->isFocusCaught()) {
|
if (!gui->isFocusCaught()) {
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "window/Camera.hpp"
|
#include "window/Camera.hpp"
|
||||||
#include "objects/Player.hpp"
|
#include "objects/Player.hpp"
|
||||||
#include "objects/Players.hpp"
|
#include "objects/Players.hpp"
|
||||||
|
#include "objects/Entities.hpp"
|
||||||
#include "logic/LevelController.hpp"
|
#include "logic/LevelController.hpp"
|
||||||
#include "util/stringutil.hpp"
|
#include "util/stringutil.hpp"
|
||||||
#include "engine/Engine.hpp"
|
#include "engine/Engine.hpp"
|
||||||
@ -159,7 +160,11 @@ void Decorator::update(float delta, const Camera& camera) {
|
|||||||
renderer.texts->remove(textsIter->second);
|
renderer.texts->remove(textsIter->second);
|
||||||
textsIter = playerTexts.erase(textsIter);
|
textsIter = playerTexts.erase(textsIter);
|
||||||
} else {
|
} else {
|
||||||
note->setPosition(player->getPosition() + glm::vec3(0, 1, 0));
|
glm::vec3 position = player->getPosition();
|
||||||
|
if (auto entity = level.entities->get(player->getEntity())) {
|
||||||
|
position = entity->getInterpolatedPosition();
|
||||||
|
}
|
||||||
|
note->setPosition(position + glm::vec3(0, 1, 0));
|
||||||
++textsIter;
|
++textsIter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -274,8 +274,9 @@ void WorldRenderer::renderHands(
|
|||||||
glm::mat4(1.0f), -glm::pi<float>() * 0.5f, glm::vec3(0, 1, 0)
|
glm::mat4(1.0f), -glm::pi<float>() * 0.5f, glm::vec3(0, 1, 0)
|
||||||
);
|
);
|
||||||
prevRotation = rotation;
|
prevRotation = rotation;
|
||||||
|
glm::vec3 cameraRotation = player.getRotation();
|
||||||
auto offset = -(camera.position - player.getPosition());
|
auto offset = -(camera.position - player.getPosition());
|
||||||
float angle = glm::radians(player.rotation.x - 90);
|
float angle = glm::radians(cameraRotation.x - 90);
|
||||||
float cos = glm::cos(angle);
|
float cos = glm::cos(angle);
|
||||||
float sin = glm::sin(angle);
|
float sin = glm::sin(angle);
|
||||||
|
|
||||||
|
|||||||
@ -166,7 +166,7 @@ void GUI::actFocused() {
|
|||||||
focus->keyPressed(key);
|
focus->keyPressed(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Events::_cursor_locked) {
|
if (!Events::isCursorLocked()) {
|
||||||
if (Events::clicked(mousecode::BUTTON_1) &&
|
if (Events::clicked(mousecode::BUTTON_1) &&
|
||||||
(Events::jclicked(mousecode::BUTTON_1) || Events::delta.x || Events::delta.y))
|
(Events::jclicked(mousecode::BUTTON_1) || Events::delta.x || Events::delta.y))
|
||||||
{
|
{
|
||||||
@ -189,7 +189,7 @@ void GUI::act(float delta, const Viewport& vp) {
|
|||||||
auto prevfocus = focus;
|
auto prevfocus = focus;
|
||||||
|
|
||||||
updateTooltip(delta);
|
updateTooltip(delta);
|
||||||
if (!Events::_cursor_locked) {
|
if (!Events::isCursorLocked()) {
|
||||||
actMouse(delta);
|
actMouse(delta);
|
||||||
} else {
|
} else {
|
||||||
if (hover) {
|
if (hover) {
|
||||||
|
|||||||
@ -91,6 +91,10 @@ Page& Menu::getCurrent() {
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Menu::hasOpenPage() const {
|
||||||
|
return current.panel != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::clearHistory() {
|
void Menu::clearHistory() {
|
||||||
pageStack = std::stack<Page>();
|
pageStack = std::stack<Page>();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,5 +64,7 @@ namespace gui {
|
|||||||
|
|
||||||
/// @brief Get current page
|
/// @brief Get current page
|
||||||
Page& getCurrent();
|
Page& getCurrent();
|
||||||
|
|
||||||
|
bool hasOpenPage() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,6 +73,7 @@ void LevelController::update(float delta, bool pause) {
|
|||||||
if (player->isSuspended()) {
|
if (player->isSuspended()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
player->rotationInterpolation.updateTimer(delta);
|
||||||
player->updateEntity();
|
player->updateEntity();
|
||||||
glm::vec3 position = player->getPosition();
|
glm::vec3 position = player->getPosition();
|
||||||
player->chunks->configure(
|
player->chunks->configure(
|
||||||
|
|||||||
@ -54,7 +54,7 @@ void CameraControl::refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CameraControl::updateMouse(PlayerInput& input) {
|
void CameraControl::updateMouse(PlayerInput& input) {
|
||||||
glm::vec3& rotation = player.rotation;
|
glm::vec3 rotation = player.getRotation();
|
||||||
|
|
||||||
float sensitivity =
|
float sensitivity =
|
||||||
(input.zoom ? settings.sensitivity.get() / 4.f
|
(input.zoom ? settings.sensitivity.get() / 4.f
|
||||||
@ -75,6 +75,8 @@ void CameraControl::updateMouse(PlayerInput& input) {
|
|||||||
rotation.x += 360.f;
|
rotation.x += 360.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.setRotation(rotation);
|
||||||
|
|
||||||
camera->rotation = glm::mat4(1.0f);
|
camera->rotation = glm::mat4(1.0f);
|
||||||
camera->rotate(
|
camera->rotate(
|
||||||
glm::radians(rotation.y),
|
glm::radians(rotation.y),
|
||||||
|
|||||||
@ -130,6 +130,22 @@ static int l_set_color(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_is_interpolated(lua::State* L) {
|
||||||
|
if (auto entity = get_entity(L, 1)) {
|
||||||
|
auto& skeleton = entity->getSkeleton();
|
||||||
|
return lua::pushboolean(L, skeleton.interpolation.isEnabled());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_set_interpolated(lua::State* L) {
|
||||||
|
if (auto entity = get_entity(L, 1)) {
|
||||||
|
auto& skeleton = entity->getSkeleton();
|
||||||
|
skeleton.interpolation.setEnabled(lua::toboolean(L, 2));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg skeletonlib[] = {
|
const luaL_Reg skeletonlib[] = {
|
||||||
{"get_model", lua::wrap<l_get_model>},
|
{"get_model", lua::wrap<l_get_model>},
|
||||||
{"set_model", lua::wrap<l_set_model>},
|
{"set_model", lua::wrap<l_set_model>},
|
||||||
@ -142,4 +158,6 @@ const luaL_Reg skeletonlib[] = {
|
|||||||
{"set_visible", lua::wrap<l_set_visible>},
|
{"set_visible", lua::wrap<l_set_visible>},
|
||||||
{"get_color", lua::wrap<l_get_color>},
|
{"get_color", lua::wrap<l_get_color>},
|
||||||
{"set_color", lua::wrap<l_set_color>},
|
{"set_color", lua::wrap<l_set_color>},
|
||||||
|
{"is_interpolated", lua::wrap<l_is_interpolated>},
|
||||||
|
{"set_interpolated", lua::wrap<l_set_interpolated>},
|
||||||
{NULL, NULL}};
|
{NULL, NULL}};
|
||||||
|
|||||||
@ -170,6 +170,11 @@ static int l_set_debug_cheats(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_set_allow_pause(lua::State* L) {
|
||||||
|
hud->setAllowPause(lua::toboolean(L, 1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg hudlib[] = {
|
const luaL_Reg hudlib[] = {
|
||||||
{"open_inventory", lua::wrap<l_open_inventory>},
|
{"open_inventory", lua::wrap<l_open_inventory>},
|
||||||
{"close_inventory", lua::wrap<l_close_inventory>},
|
{"close_inventory", lua::wrap<l_close_inventory>},
|
||||||
@ -187,5 +192,6 @@ const luaL_Reg hudlib[] = {
|
|||||||
{"_is_content_access", lua::wrap<l_is_content_access>},
|
{"_is_content_access", lua::wrap<l_is_content_access>},
|
||||||
{"_set_content_access", lua::wrap<l_set_content_access>},
|
{"_set_content_access", lua::wrap<l_set_content_access>},
|
||||||
{"_set_debug_cheats", lua::wrap<l_set_debug_cheats>},
|
{"_set_debug_cheats", lua::wrap<l_set_debug_cheats>},
|
||||||
|
{"set_allow_pause", lua::wrap<l_set_allow_pause>},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -61,7 +61,7 @@ static int l_set_vel(lua::State* L) {
|
|||||||
|
|
||||||
static int l_get_rot(lua::State* L) {
|
static int l_get_rot(lua::State* L) {
|
||||||
if (auto player = get_player(L, 1)) {
|
if (auto player = get_player(L, 1)) {
|
||||||
return lua::pushvec_stack(L, player->rotation);
|
return lua::pushvec_stack(L, player->getRotation(lua::toboolean(L, 2)));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ static int l_set_rot(lua::State* L) {
|
|||||||
if (!player) {
|
if (!player) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
glm::vec3& rotation = player->rotation;
|
glm::vec3 rotation = player->getRotation();
|
||||||
|
|
||||||
auto x = lua::tonumber(L, 2);
|
auto x = lua::tonumber(L, 2);
|
||||||
auto y = lua::tonumber(L, 3);
|
auto y = lua::tonumber(L, 3);
|
||||||
@ -82,6 +82,7 @@ static int l_set_rot(lua::State* L) {
|
|||||||
rotation.x = x;
|
rotation.x = x;
|
||||||
rotation.y = y;
|
rotation.y = y;
|
||||||
rotation.z = z;
|
rotation.z = z;
|
||||||
|
player->setRotation(rotation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,18 @@ void Transform::refresh() {
|
|||||||
dirty = false;
|
dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Entity::setInterpolatedPosition(const glm::vec3& position) {
|
||||||
|
getSkeleton().interpolation.refresh(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Entity::getInterpolatedPosition() const {
|
||||||
|
const auto& skeleton = getSkeleton();
|
||||||
|
if (skeleton.interpolation.isEnabled()) {
|
||||||
|
return skeleton.interpolation.getCurrent();
|
||||||
|
}
|
||||||
|
return getTransform().pos;
|
||||||
|
}
|
||||||
|
|
||||||
void Entity::destroy() {
|
void Entity::destroy() {
|
||||||
if (isValid()) {
|
if (isValid()) {
|
||||||
entities.despawn(id);
|
entities.despawn(id);
|
||||||
@ -561,11 +573,14 @@ void Entities::render(
|
|||||||
if (transform.dirty) {
|
if (transform.dirty) {
|
||||||
transform.refresh();
|
transform.refresh();
|
||||||
}
|
}
|
||||||
|
if (skeleton.interpolation.isEnabled()) {
|
||||||
|
skeleton.interpolation.updateTimer(delta);
|
||||||
|
}
|
||||||
const auto& pos = transform.pos;
|
const auto& pos = transform.pos;
|
||||||
const auto& size = transform.size;
|
const auto& size = transform.size;
|
||||||
if (!frustum || frustum->isBoxVisible(pos - size, pos + size)) {
|
if (!frustum || frustum->isBoxVisible(pos - size, pos + size)) {
|
||||||
const auto* rigConfig = skeleton.config;
|
const auto* rigConfig = skeleton.config;
|
||||||
rigConfig->render(assets, batch, skeleton, transform.combined);
|
rigConfig->render(assets, batch, skeleton, transform.combined, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -170,6 +170,10 @@ public:
|
|||||||
registry.get<EntityId>(entity).player = id;
|
registry.get<EntityId>(entity).player = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setInterpolatedPosition(const glm::vec3& position);
|
||||||
|
|
||||||
|
glm::vec3 getInterpolatedPosition() const;
|
||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -181,6 +181,7 @@ void Player::teleport(glm::vec3 position) {
|
|||||||
if (auto entity = level.entities->get(eid)) {
|
if (auto entity = level.entities->get(eid)) {
|
||||||
entity->getRigidbody().hitbox.position = position;
|
entity->getRigidbody().hitbox.position = position;
|
||||||
entity->getTransform().setPos(position);
|
entity->getTransform().setPos(position);
|
||||||
|
entity->setInterpolatedPosition(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +297,18 @@ glm::vec3 Player::getSpawnPoint() const {
|
|||||||
return spawnpoint;
|
return spawnpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Player::getRotation(bool interpolated) const {
|
||||||
|
if (interpolated) {
|
||||||
|
return rotationInterpolation.getCurrent();
|
||||||
|
}
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::setRotation(const glm::vec3& rotation) {
|
||||||
|
this->rotation = rotation;
|
||||||
|
rotationInterpolation.refresh(rotation);
|
||||||
|
}
|
||||||
|
|
||||||
dv::value Player::serialize() const {
|
dv::value Player::serialize() const {
|
||||||
auto root = dv::object();
|
auto root = dv::object();
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "interfaces/Serializable.hpp"
|
#include "interfaces/Serializable.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "voxels/voxel.hpp"
|
#include "voxels/voxel.hpp"
|
||||||
|
#include "util/Interpolation.hpp"
|
||||||
|
|
||||||
class Chunks;
|
class Chunks;
|
||||||
class Camera;
|
class Camera;
|
||||||
@ -55,11 +56,15 @@ class Player : public Serializable {
|
|||||||
bool loadingChunks = true;
|
bool loadingChunks = true;
|
||||||
entityid_t eid;
|
entityid_t eid;
|
||||||
entityid_t selectedEid = 0;
|
entityid_t selectedEid = 0;
|
||||||
|
|
||||||
|
glm::vec3 rotation {};
|
||||||
public:
|
public:
|
||||||
|
util::VecInterpolation<3, float, true> rotationInterpolation {true};
|
||||||
|
|
||||||
std::unique_ptr<Chunks> chunks;
|
std::unique_ptr<Chunks> chunks;
|
||||||
std::shared_ptr<Camera> fpCamera, spCamera, tpCamera;
|
std::shared_ptr<Camera> fpCamera, spCamera, tpCamera;
|
||||||
std::shared_ptr<Camera> currentCamera;
|
std::shared_ptr<Camera> currentCamera;
|
||||||
glm::vec3 rotation {};
|
|
||||||
CursorSelection selection {};
|
CursorSelection selection {};
|
||||||
|
|
||||||
Player(
|
Player(
|
||||||
@ -123,6 +128,9 @@ public:
|
|||||||
void setSpawnPoint(glm::vec3 point);
|
void setSpawnPoint(glm::vec3 point);
|
||||||
glm::vec3 getSpawnPoint() const;
|
glm::vec3 getSpawnPoint() const;
|
||||||
|
|
||||||
|
glm::vec3 getRotation(bool interpolated=false) const;
|
||||||
|
void setRotation(const glm::vec3& rotation);
|
||||||
|
|
||||||
dv::value serialize() const override;
|
dv::value serialize() const override;
|
||||||
void deserialize(const dv::value& src) override;
|
void deserialize(const dv::value& src) override;
|
||||||
|
|
||||||
|
|||||||
@ -6,9 +6,8 @@
|
|||||||
#include "graphics/commons/Model.hpp"
|
#include "graphics/commons/Model.hpp"
|
||||||
#include "graphics/render/ModelBatch.hpp"
|
#include "graphics/render/ModelBatch.hpp"
|
||||||
|
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
#include <glm/gtx/norm.hpp>
|
#include <glm/gtx/matrix_decompose.hpp>
|
||||||
|
|
||||||
using namespace rigging;
|
using namespace rigging;
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ SkeletonConfig::SkeletonConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t SkeletonConfig::update(
|
size_t SkeletonConfig::update(
|
||||||
size_t index, Skeleton& skeleton, Bone* node, glm::mat4 matrix
|
size_t index, Skeleton& skeleton, Bone* node, const glm::mat4& matrix
|
||||||
) const {
|
) const {
|
||||||
auto boneMatrix = skeleton.pose.matrices[index];
|
auto boneMatrix = skeleton.pose.matrices[index];
|
||||||
auto boneOffset = node->getOffset();
|
auto boneOffset = node->getOffset();
|
||||||
@ -90,17 +89,32 @@ size_t SkeletonConfig::update(
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonConfig::update(Skeleton& skeleton, glm::mat4 matrix) const {
|
void SkeletonConfig::update(
|
||||||
|
Skeleton& skeleton, const glm::mat4& matrix, const glm::vec3& position
|
||||||
|
) const {
|
||||||
|
if (skeleton.interpolation.isEnabled()) {
|
||||||
|
const auto& interpolation = skeleton.interpolation;
|
||||||
|
glm::vec3 scale, translation, skew;
|
||||||
|
glm::quat rotation;
|
||||||
|
glm::vec4 perspective;
|
||||||
|
glm::decompose(matrix, scale, rotation, translation, skew, perspective);
|
||||||
|
|
||||||
|
auto delta = interpolation.getCurrent() - position;
|
||||||
|
auto interpolatedMatrix = glm::translate(matrix, delta);
|
||||||
|
update(0, skeleton, root.get(), interpolatedMatrix);
|
||||||
|
} else {
|
||||||
update(0, skeleton, root.get(), matrix);
|
update(0, skeleton, root.get(), matrix);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SkeletonConfig::render(
|
void SkeletonConfig::render(
|
||||||
const Assets& assets,
|
const Assets& assets,
|
||||||
ModelBatch& batch,
|
ModelBatch& batch,
|
||||||
Skeleton& skeleton,
|
Skeleton& skeleton,
|
||||||
const glm::mat4& matrix
|
const glm::mat4& matrix,
|
||||||
|
const glm::vec3& position
|
||||||
) const {
|
) const {
|
||||||
update(skeleton, matrix);
|
update(skeleton, matrix, position);
|
||||||
|
|
||||||
if (!skeleton.visible) {
|
if (!skeleton.visible) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/gtx/norm.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cmath>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
|
#include "util/Interpolation.hpp"
|
||||||
|
|
||||||
class Assets;
|
class Assets;
|
||||||
class ModelBatch;
|
class ModelBatch;
|
||||||
@ -83,6 +86,8 @@ namespace rigging {
|
|||||||
bool visible;
|
bool visible;
|
||||||
glm::vec3 tint {1.0f, 1.0f, 1.0f};
|
glm::vec3 tint {1.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
|
util::VecInterpolation<3, float> interpolation {false};
|
||||||
|
|
||||||
Skeleton(const SkeletonConfig* config);
|
Skeleton(const SkeletonConfig* config);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,7 +105,7 @@ namespace rigging {
|
|||||||
std::vector<Bone*> nodes;
|
std::vector<Bone*> nodes;
|
||||||
|
|
||||||
size_t update(
|
size_t update(
|
||||||
size_t index, Skeleton& skeleton, Bone* node, glm::mat4 matrix
|
size_t index, Skeleton& skeleton, Bone* node, const glm::mat4& matrix
|
||||||
) const;
|
) const;
|
||||||
public:
|
public:
|
||||||
SkeletonConfig(
|
SkeletonConfig(
|
||||||
@ -109,12 +114,18 @@ namespace rigging {
|
|||||||
size_t nodesCount
|
size_t nodesCount
|
||||||
);
|
);
|
||||||
|
|
||||||
void update(Skeleton& skeleton, glm::mat4 matrix) const;
|
void update(
|
||||||
|
Skeleton& skeleton,
|
||||||
|
const glm::mat4& matrix,
|
||||||
|
const glm::vec3& position
|
||||||
|
) const;
|
||||||
|
|
||||||
void render(
|
void render(
|
||||||
const Assets& assets,
|
const Assets& assets,
|
||||||
ModelBatch& batch,
|
ModelBatch& batch,
|
||||||
Skeleton& skeleton,
|
Skeleton& skeleton,
|
||||||
const glm::mat4& matrix
|
const glm::mat4& matrix,
|
||||||
|
const glm::vec3& position
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
Skeleton instance() const {
|
Skeleton instance() const {
|
||||||
|
|||||||
60
src/util/Interpolation.hpp
Normal file
60
src/util/Interpolation.hpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
namespace util {
|
||||||
|
template<int N, typename T, bool angular=false>
|
||||||
|
class VecInterpolation {
|
||||||
|
bool enabled;
|
||||||
|
glm::vec<N, T> prevPos {std::numeric_limits<T>::quiet_NaN()};
|
||||||
|
glm::vec<N, T> nextPos {};
|
||||||
|
T refreshInterval = 0.0;
|
||||||
|
T timer = 0.0;
|
||||||
|
T intervalUpdateFactor = 0.1;
|
||||||
|
public:
|
||||||
|
VecInterpolation(bool enabled) : enabled(enabled) {}
|
||||||
|
|
||||||
|
void refresh(const glm::vec<N, T>& position) {
|
||||||
|
auto current = getCurrent();
|
||||||
|
prevPos = current;
|
||||||
|
nextPos = position;
|
||||||
|
refreshInterval = timer * intervalUpdateFactor +
|
||||||
|
refreshInterval * (1.0 - intervalUpdateFactor);
|
||||||
|
timer = 0.0;
|
||||||
|
|
||||||
|
if constexpr (angular) {
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
T diff = nextPos[i] - prevPos[i];
|
||||||
|
if (glm::abs(diff) > 180.0f) {
|
||||||
|
nextPos[i] += (diff > 0.0f ? -360.0f : 360.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateTimer(T delta) {
|
||||||
|
timer += delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec<N, T> getCurrent() const {
|
||||||
|
if (refreshInterval < 0.001 || std::isnan(prevPos.x)) {
|
||||||
|
return nextPos;
|
||||||
|
}
|
||||||
|
T t = timer / refreshInterval;
|
||||||
|
return nextPos * t + prevPos * (1.0f - t);
|
||||||
|
}
|
||||||
|
|
||||||
|
T getRefreshInterval() const {
|
||||||
|
return refreshInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEnabled() const {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEnabled(bool enabled) {
|
||||||
|
this->enabled = enabled;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -18,8 +18,8 @@ uint Events::currentFrame = 0;
|
|||||||
int Events::scroll = 0;
|
int Events::scroll = 0;
|
||||||
glm::vec2 Events::delta = {};
|
glm::vec2 Events::delta = {};
|
||||||
glm::vec2 Events::cursor = {};
|
glm::vec2 Events::cursor = {};
|
||||||
bool Events::cursor_drag = false;
|
bool Events::cursorDrag = false;
|
||||||
bool Events::_cursor_locked = false;
|
bool Events::cursorLocked = false;
|
||||||
std::vector<uint> Events::codepoints;
|
std::vector<uint> Events::codepoints;
|
||||||
std::vector<keycode> Events::pressedKeys;
|
std::vector<keycode> Events::pressedKeys;
|
||||||
std::unordered_map<std::string, Binding> Events::bindings;
|
std::unordered_map<std::string, Binding> Events::bindings;
|
||||||
@ -61,10 +61,10 @@ bool Events::jclicked(int button) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Events::toggleCursor() {
|
void Events::toggleCursor() {
|
||||||
cursor_drag = false;
|
cursorDrag = false;
|
||||||
_cursor_locked = !_cursor_locked;
|
cursorLocked = !cursorLocked;
|
||||||
Window::setCursorMode(
|
Window::setCursorMode(
|
||||||
_cursor_locked ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL
|
cursorLocked ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,11 +170,11 @@ void Events::setButton(int button, bool b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Events::setPosition(float xpos, float ypos) {
|
void Events::setPosition(float xpos, float ypos) {
|
||||||
if (Events::cursor_drag) {
|
if (Events::cursorDrag) {
|
||||||
Events::delta.x += xpos - Events::cursor.x;
|
Events::delta.x += xpos - Events::cursor.x;
|
||||||
Events::delta.y += ypos - Events::cursor.y;
|
Events::delta.y += ypos - Events::cursor.y;
|
||||||
} else {
|
} else {
|
||||||
Events::cursor_drag = true;
|
Events::cursorDrag = true;
|
||||||
}
|
}
|
||||||
Events::cursor.x = xpos;
|
Events::cursor.x = xpos;
|
||||||
Events::cursor.y = ypos;
|
Events::cursor.y = ypos;
|
||||||
@ -249,3 +249,7 @@ void Events::enableBindings() {
|
|||||||
binding.enable = true;
|
binding.enable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Events::isCursorLocked() {
|
||||||
|
return cursorLocked;
|
||||||
|
}
|
||||||
|
|||||||
@ -19,12 +19,12 @@ class Events {
|
|||||||
static bool keys[KEYS_BUFFER_SIZE];
|
static bool keys[KEYS_BUFFER_SIZE];
|
||||||
static uint frames[KEYS_BUFFER_SIZE];
|
static uint frames[KEYS_BUFFER_SIZE];
|
||||||
static uint currentFrame;
|
static uint currentFrame;
|
||||||
static bool cursor_drag;
|
static bool cursorDrag;
|
||||||
|
static bool cursorLocked;
|
||||||
public:
|
public:
|
||||||
static int scroll;
|
static int scroll;
|
||||||
static glm::vec2 delta;
|
static glm::vec2 delta;
|
||||||
static glm::vec2 cursor;
|
static glm::vec2 cursor;
|
||||||
static bool _cursor_locked;
|
|
||||||
static std::vector<uint> codepoints;
|
static std::vector<uint> codepoints;
|
||||||
static std::vector<keycode> pressedKeys;
|
static std::vector<keycode> pressedKeys;
|
||||||
static std::unordered_map<std::string, Binding> bindings;
|
static std::unordered_map<std::string, Binding> bindings;
|
||||||
@ -65,4 +65,6 @@ public:
|
|||||||
BindType bindType
|
BindType bindType
|
||||||
);
|
);
|
||||||
static void enableBindings();
|
static void enableBindings();
|
||||||
|
|
||||||
|
static bool isCursorLocked();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -389,7 +389,9 @@ void Window::toggleFullscreen() {
|
|||||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||||
|
|
||||||
if (Events::_cursor_locked) Events::toggleCursor();
|
if (Events::isCursorLocked()){
|
||||||
|
Events::toggleCursor();
|
||||||
|
}
|
||||||
|
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
glfwGetWindowPos(window, &posX, &posY);
|
glfwGetWindowPos(window, &posX, &posY);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user