nejaka fyzika
This commit is contained in:
parent
87db261a10
commit
1a628d8f89
@ -6,11 +6,11 @@
|
||||
namespace TSR {
|
||||
|
||||
class Camera {
|
||||
glm::vec3 forward_backward_vector;
|
||||
glm::vec3 world_up;
|
||||
void UpdateVectors();
|
||||
|
||||
public:
|
||||
glm::vec3 forward_backward_vector;
|
||||
glm::vec3 front_vector;
|
||||
glm::vec3 up_vector;
|
||||
glm::vec3 right_vector;
|
||||
|
||||
154
src/tsr/entity_cct.cpp
Normal file
154
src/tsr/entity_cct.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
#include "entity_cct.hpp"
|
||||
#include "game.hpp"
|
||||
#include "tsr.hpp"
|
||||
#include "entity_cct.hpp"
|
||||
|
||||
using namespace TSR;
|
||||
|
||||
// component functions
|
||||
static int CCTMove(CCTComponent& comp, const glm::vec3& disp, float dt) {
|
||||
PxControllerFilters filters;
|
||||
//filters.mCCTFilterCallback = nullptr;
|
||||
//filters.mFilterCallback = nullptr;
|
||||
|
||||
PxVec3 disp_px(disp.x, disp.y, disp.z);
|
||||
auto col = comp.cct->move(disp_px, 0.001f, dt, filters);
|
||||
|
||||
int ret = CCT_COLLISION_NONE;
|
||||
if (col & PxControllerCollisionFlag::eCOLLISION_DOWN)
|
||||
ret |= CCT_COLLISION_DOWN;
|
||||
|
||||
if (col & PxControllerCollisionFlag::eCOLLISION_UP)
|
||||
ret |= CCT_COLLISION_UP;
|
||||
|
||||
if (col & PxControllerCollisionFlag::eCOLLISION_SIDES)
|
||||
ret |= CCT_COLLISION_SIDE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void CCTSetPos(CCTComponent& comp, const glm::vec3& pos) {
|
||||
PxExtendedVec3 pos_px(pos.x, pos.y, pos.z);
|
||||
comp.cct->setFootPosition(pos_px);
|
||||
}
|
||||
|
||||
static glm::vec3 CCTGetPos(CCTComponent& comp) {
|
||||
auto pos_px = comp.cct->getFootPosition();
|
||||
return glm::vec3(pos_px.x, pos_px.y, pos_px.z);
|
||||
}
|
||||
|
||||
static bool CCTTurnToAngle(CCTComponent& comp, float target, float step) {
|
||||
if (target < comp.angle)
|
||||
target += glm::two_pi<float>();
|
||||
|
||||
auto diff_angle = target - comp.angle;
|
||||
if (diff_angle > glm::pi<float>())
|
||||
diff_angle -= glm::two_pi<float>();
|
||||
|
||||
if (glm::abs(diff_angle) <= step) {
|
||||
comp.angle = target;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
comp.angle += glm::sign(diff_angle) * step;
|
||||
comp.angle = glm::mod(comp.angle, glm::two_pi<float>());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool CCTTurnTo(CCTComponent& comp, const glm::vec3& pos, float step) {
|
||||
auto diff = pos - CCTGetPos(comp);
|
||||
auto target = std::atan2(pos.x, pos.z);
|
||||
|
||||
return CCTTurnToAngle(comp, target, step);
|
||||
}
|
||||
|
||||
// component
|
||||
CCTComponent::CCTComponent(float radius, float height, const glm::vec3& pos) :
|
||||
angle(0.0f)
|
||||
{
|
||||
PxCapsuleControllerDesc desc;
|
||||
|
||||
auto material = AssetMap::Get<PhysicsMaterial>("physics/default.material.json");
|
||||
|
||||
desc.position = PxExtendedVec3(pos.x, pos.y, pos.z);
|
||||
desc.radius = radius;
|
||||
desc.height = height;
|
||||
desc.material = material->Get();
|
||||
desc.scaleCoeff = 1.0f;
|
||||
desc.contactOffset = 0.05f;
|
||||
desc.slopeLimit = glm::cos(glm::radians(70.0f));
|
||||
desc.stepOffset = 0.3f;
|
||||
//desc.
|
||||
|
||||
desc.climbingMode = PxCapsuleClimbingMode::eCONSTRAINED;
|
||||
desc.nonWalkableMode = PxControllerNonWalkableMode::ePREVENT_CLIMBING_AND_FORCE_SLIDING;
|
||||
|
||||
Game::Physics().GetCCTManager()->setOverlapRecoveryModule(true);
|
||||
|
||||
cct = Game::Physics().GetCCTManager()->createController(desc);
|
||||
if (!cct)
|
||||
Throw("(CCT) createController failed!");
|
||||
|
||||
}
|
||||
|
||||
CCTComponent::~CCTComponent() {
|
||||
cct->release();
|
||||
}
|
||||
|
||||
// CCT SYSTEM
|
||||
|
||||
void CCTSystem::AddCCT(entt::entity ent, float radius, float height) {
|
||||
auto& reg = Game::Registry();
|
||||
const auto& trans = reg.get<TransformComponent>(ent);
|
||||
auto& comp = reg.emplace_or_replace<CCTComponent>(ent, radius, height, trans.trans.pos);
|
||||
}
|
||||
|
||||
void CCTSystem::RemoveCCT(entt::entity ent) {
|
||||
auto& reg = Game::Registry();
|
||||
reg.erase<CCTComponent>(ent);
|
||||
}
|
||||
|
||||
int CCTSystem::Move(entt::entity ent, const glm::vec3& disp, float dt) {
|
||||
auto& reg = Game::Registry();
|
||||
auto& comp = reg.get<CCTComponent>(ent);
|
||||
return CCTMove(comp, disp, dt);
|
||||
}
|
||||
|
||||
void CCTSystem::SetPos(entt::entity ent, const glm::vec3& pos) {
|
||||
auto& reg = Game::Registry();
|
||||
auto& comp = reg.get<CCTComponent>(ent);
|
||||
CCTSetPos(comp, pos);
|
||||
}
|
||||
|
||||
glm::vec3 TSR::CCTSystem::GetPos(entt::entity ent) {
|
||||
auto& reg = Game::Registry();
|
||||
auto& comp = reg.get<CCTComponent>(ent);
|
||||
return CCTGetPos(comp);
|
||||
}
|
||||
|
||||
bool CCTSystem::TurnTo(entt::entity ent, const glm::vec3& pos, float step) {
|
||||
auto& reg = Game::Registry();
|
||||
auto& comp = reg.get<CCTComponent>(ent);
|
||||
|
||||
return CCTTurnTo(comp, pos, step);
|
||||
}
|
||||
|
||||
bool TSR::CCTSystem::TurnToAngle(entt::entity ent, float target, float step) {
|
||||
auto& reg = Game::Registry();
|
||||
auto& comp = reg.get<CCTComponent>(ent);
|
||||
|
||||
return CCTTurnToAngle(comp, target, step);
|
||||
}
|
||||
|
||||
void CCTSystem::Update() {
|
||||
auto& reg = Game::Registry();
|
||||
|
||||
auto v = reg.view<CCTComponent, TransformComponent>();
|
||||
for (auto [ent, cct, trans] : v.each()) {
|
||||
auto pos = cct.cct->getFootPosition();
|
||||
trans.trans.pos = glm::vec3(pos.x, pos.y, pos.z);
|
||||
trans.trans.rot = glm::quat(glm::vec3(0.0f, cct.angle, 0.0f));
|
||||
}
|
||||
|
||||
}
|
||||
36
src/tsr/entity_cct.hpp
Normal file
36
src/tsr/entity_cct.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "entity.hpp"
|
||||
|
||||
namespace TSR {
|
||||
|
||||
enum {
|
||||
CCT_COLLISION_NONE = 0,
|
||||
CCT_COLLISION_DOWN = 1 << 0,
|
||||
CCT_COLLISION_UP = 1 << 1,
|
||||
CCT_COLLISION_SIDE = 1 << 2,
|
||||
};
|
||||
|
||||
struct CCTComponent {
|
||||
PxController* cct;
|
||||
float angle;
|
||||
|
||||
CCTComponent(float radius, float height, const glm::vec3& pos);
|
||||
CCTComponent(const CCTComponent& other) = delete;
|
||||
~CCTComponent();
|
||||
};
|
||||
|
||||
class CCTSystem {
|
||||
|
||||
public:
|
||||
static void AddCCT(entt::entity ent, float radius, float height);
|
||||
static void RemoveCCT(entt::entity ent);
|
||||
static int Move(entt::entity ent, const glm::vec3& disp, float dt);
|
||||
static void SetPos(entt::entity ent, const glm::vec3& pos);
|
||||
static glm::vec3 GetPos(entt::entity ent);
|
||||
static bool TurnTo(entt::entity ent, const glm::vec3& pos, float step);
|
||||
static bool TurnToAngle(entt::entity ent, float target, float step);
|
||||
|
||||
static void Update();
|
||||
|
||||
};
|
||||
}
|
||||
@ -212,6 +212,9 @@ void ModelSystem::Render(TSR::Renderer& renderer) {
|
||||
|
||||
CreateTransMatFast(model.ctx.model_matrix, MixTransforms(trans1, trans2, frame_t));
|
||||
|
||||
// temp
|
||||
renderer.AddDebugLine(model.ctx.model_matrix[3], model.ctx.model_matrix[3] + glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
|
||||
if (model.model->IsSkeletal() && !Window::KeyDown(GLFW_KEY_V)) {
|
||||
|
||||
auto& sk_bones = model.model->GetSkeleton().Bones();
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include "model.hpp"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "../tsr/renderer.hpp"
|
||||
#include "renderer.hpp"
|
||||
|
||||
namespace TSR {
|
||||
|
||||
|
||||
149
src/tsr/game.cpp
149
src/tsr/game.cpp
@ -1,21 +1,44 @@
|
||||
#include "game.hpp"
|
||||
#include "entity_model.hpp"
|
||||
#include "entity_cct.hpp"
|
||||
#include "window.hpp"
|
||||
#include "camera.hpp"
|
||||
#include "worldmap.hpp"
|
||||
#include "physics.hpp"
|
||||
|
||||
using namespace TSR;
|
||||
|
||||
entt::registry Game::s_registry;
|
||||
std::unique_ptr<PhysicsScene> Game::s_physics_scene;
|
||||
std::unique_ptr<WorldMap> Game::s_map;
|
||||
|
||||
uint64_t Game::s_sv_frame = 0;
|
||||
float Game::s_frame_t = 0.0f;
|
||||
int Game::s_tps = 50;
|
||||
|
||||
bool Game::s_debug_draw = false;
|
||||
|
||||
static Camera cam;
|
||||
|
||||
static entt::entity ent1;
|
||||
static entt::entity player;
|
||||
|
||||
static WorldMap* s_map;
|
||||
void Game::StartGame(const std::string& map_name) {
|
||||
s_sv_frame = 0;
|
||||
s_frame_t = 0.0f;
|
||||
|
||||
s_registry.clear();
|
||||
|
||||
s_physics_scene = std::make_unique<PhysicsScene>();
|
||||
s_map = std::make_unique<WorldMap>(map_name, s_physics_scene.get());
|
||||
|
||||
}
|
||||
|
||||
void Game::EndGame() {
|
||||
s_registry.clear();
|
||||
s_map.reset();
|
||||
s_physics_scene.reset();
|
||||
}
|
||||
|
||||
void Game::Run() {
|
||||
|
||||
@ -23,14 +46,17 @@ void Game::Run() {
|
||||
WindowWrapper ww("TSR test", 640, 480);
|
||||
////Audio::Init();
|
||||
|
||||
Physics::Init();
|
||||
|
||||
Renderer renderer;
|
||||
|
||||
WorldMap map("maps/kalbatest1.mapproject.json");
|
||||
StartGame("maps/kalbatest1.mapproject.json");
|
||||
|
||||
while (!map.Loaded())
|
||||
map.LoadNext();
|
||||
while (!s_map->Loaded())
|
||||
s_map->LoadNext();
|
||||
|
||||
s_map = ↦
|
||||
|
||||
//s_physics_scene->EnableDebug(false);
|
||||
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
auto ent = Game::Registry().create();
|
||||
@ -47,16 +73,35 @@ void Game::Run() {
|
||||
|
||||
}
|
||||
|
||||
ent1 = Game::Registry().create();
|
||||
ModelSystem::AddModel(ent1, "models/skrin.mdl.json");
|
||||
ModelSystem::Anim(ent1, "init");
|
||||
ModelSystem::Anim(ent1, "open_left");
|
||||
ModelSystem::Anim(ent1, "open_right");
|
||||
auto& trans = Registry().emplace_or_replace<TransformComponent>(ent1);
|
||||
glm::vec3 pos(0.0f, 5.0f, 0.0f);
|
||||
trans.trans.pos = pos;
|
||||
trans.trans.rot = glm::quat(glm::vec3(0.0f));
|
||||
trans.trans.scl = glm::vec3(1.0f);
|
||||
{
|
||||
ent1 = Game::Registry().create();
|
||||
ModelSystem::AddModel(ent1, "models/skrin.mdl.json");
|
||||
ModelSystem::Anim(ent1, "init");
|
||||
ModelSystem::Anim(ent1, "open_left");
|
||||
ModelSystem::Anim(ent1, "open_right");
|
||||
auto& trans = Registry().emplace_or_replace<TransformComponent>(ent1);
|
||||
glm::vec3 pos(0.0f, 5.0f, 0.0f);
|
||||
trans.trans.pos = pos;
|
||||
trans.trans.rot = glm::quat(glm::vec3(0.0f));
|
||||
trans.trans.scl = glm::vec3(1.0f);
|
||||
}
|
||||
|
||||
{
|
||||
player = Game::Registry().create();
|
||||
ModelSystem::AddModel(player, "models/test_skeletal.mdl.json");
|
||||
ModelSystem::Anim(player, "init");
|
||||
ModelSystem::Anim(player, "ruce");
|
||||
auto& trans = Registry().emplace_or_replace<TransformComponent>(player);
|
||||
glm::vec3 pos(0.0f, 5.0f, 0.0f);
|
||||
trans.trans.pos = pos;
|
||||
trans.trans.rot = glm::quat(glm::vec3(0.0f));
|
||||
trans.trans.scl = glm::vec3(1.0f);
|
||||
|
||||
CCTSystem::AddCCT(player, 0.25f, 1.2f);
|
||||
|
||||
}
|
||||
|
||||
cam.third_person_distance = 5.0f;
|
||||
|
||||
Window::SetInputMode(GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
Window::SetCursorPosCallback([](GLFWwindow* window, double xpos, double ypos) {
|
||||
@ -76,6 +121,12 @@ void Game::Run() {
|
||||
Window::SetKeyCallback([](GLFWwindow* window, int key, int scancode, int action, int mods) {
|
||||
if (action == GLFW_PRESS) {
|
||||
switch (key) {
|
||||
case GLFW_KEY_F1:
|
||||
s_debug_draw = !s_debug_draw;
|
||||
s_physics_scene->EnableDebug(s_debug_draw);
|
||||
break;
|
||||
|
||||
|
||||
case GLFW_KEY_E:
|
||||
ModelSystem::Anim(ent1, "open_left");
|
||||
ModelSystem::Anim(ent1, "open_right");
|
||||
@ -122,41 +173,75 @@ void Game::Run() {
|
||||
|
||||
ClFrame(renderer, 0.0f);
|
||||
}
|
||||
|
||||
EndGame();
|
||||
Physics::Close();
|
||||
}
|
||||
|
||||
void Game::SvFrame() {
|
||||
ModelSystem::Animate();
|
||||
++s_sv_frame;
|
||||
|
||||
float time = 1.0f / (float)s_tps;
|
||||
|
||||
//if (Window::KeyDown(GLFW_KEY_W))
|
||||
// cam.ProcessMovement(Camera::Movement::FORWARD, time);
|
||||
//if (Window::KeyDown(GLFW_KEY_S))
|
||||
// cam.ProcessMovement(Camera::Movement::BACKWARD, time);
|
||||
//if (Window::KeyDown(GLFW_KEY_A))
|
||||
// cam.ProcessMovement(Camera::Movement::LEFT, time);
|
||||
//if (Window::KeyDown(GLFW_KEY_D))
|
||||
// cam.ProcessMovement(Camera::Movement::RIGHT, time);
|
||||
//if (Window::KeyDown(GLFW_KEY_SPACE))
|
||||
// cam.ProcessMovement(Camera::Movement::UP, time);
|
||||
//if (Window::KeyDown(GLFW_KEY_LEFT_SHIFT))
|
||||
// cam.ProcessMovement(Camera::Movement::DOWN, time);
|
||||
|
||||
float move_forward = 0.0f;
|
||||
float move_right = 0.0f;
|
||||
|
||||
if (Window::KeyDown(GLFW_KEY_W))
|
||||
cam.ProcessMovement(Camera::Movement::FORWARD, time);
|
||||
move_forward += 1.0f;
|
||||
if (Window::KeyDown(GLFW_KEY_S))
|
||||
cam.ProcessMovement(Camera::Movement::BACKWARD, time);
|
||||
move_forward -= 1.0f;
|
||||
if (Window::KeyDown(GLFW_KEY_A))
|
||||
cam.ProcessMovement(Camera::Movement::LEFT, time);
|
||||
move_right -= 1.0f;
|
||||
if (Window::KeyDown(GLFW_KEY_D))
|
||||
cam.ProcessMovement(Camera::Movement::RIGHT, time);
|
||||
if (Window::KeyDown(GLFW_KEY_SPACE))
|
||||
cam.ProcessMovement(Camera::Movement::UP, time);
|
||||
if (Window::KeyDown(GLFW_KEY_LEFT_SHIFT))
|
||||
cam.ProcessMovement(Camera::Movement::DOWN, time);
|
||||
move_right += 1.0f;
|
||||
|
||||
if (move_forward != 0.0f || move_right != 0.0f) {
|
||||
auto move_vector = cam.forward_backward_vector * move_forward + cam.right_vector * move_right;
|
||||
|
||||
auto move_angle = std::atan2(move_vector.x, move_vector.z);
|
||||
|
||||
CCTSystem::TurnToAngle(player, move_angle, 6.0f / TPS());
|
||||
|
||||
auto& cctcomp = Registry().get<CCTComponent>(player);
|
||||
|
||||
glm::vec3 forward_vector(std::sin(cctcomp.angle), -1.0f, std::cos(cctcomp.angle));
|
||||
CCTSystem::Move(player, forward_vector * (5.0f / TPS()), time);
|
||||
}
|
||||
|
||||
CCTSystem::Update();
|
||||
ModelSystem::Animate();
|
||||
|
||||
s_physics_scene->StepSimulation(time);
|
||||
|
||||
++s_sv_frame;
|
||||
}
|
||||
|
||||
void Game::ClFrame(Renderer& renderer, float frame_t) {
|
||||
|
||||
|
||||
|
||||
int w, h;
|
||||
Window::GetFramebufferSize(w, h);
|
||||
|
||||
renderer.SetProjection((float)w / (float)h, 90.0f, 0.1f, 1000.0f);
|
||||
//r.SetViewMatrix(glm::lookAt(glm::vec3(-1.0f, 2.0f, 2.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
renderer.SetViewMatrix(cam.GetViewMatrix());
|
||||
//r.SetViewMatrix(glm::lookAt(glm::vec3(10.0f, 5.0f, 3.0f), glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
|
||||
ModelSystem::Render(renderer);
|
||||
s_map->Draw(renderer);
|
||||
|
||||
if (s_debug_draw)
|
||||
s_physics_scene->DrawDebug(renderer);
|
||||
|
||||
cam.position = glm::vec3(Registry().get<ModelComponent>(player).ctx.model_matrix[3]) + glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
renderer.SetViewMatrix(cam.GetViewMatrix());
|
||||
|
||||
renderer.Render(w, h);
|
||||
|
||||
Window::PollEvents();
|
||||
|
||||
@ -6,25 +6,40 @@
|
||||
#include <memory>
|
||||
#include <entt/entt.hpp>
|
||||
#include "renderer.hpp"
|
||||
#include "worldmap.hpp"
|
||||
#include "physics.hpp"
|
||||
|
||||
namespace TSR {
|
||||
|
||||
|
||||
class Game {
|
||||
|
||||
static entt::registry s_registry;
|
||||
static std::unique_ptr<WorldMap> s_map;
|
||||
static std::unique_ptr<PhysicsScene> s_physics_scene;
|
||||
|
||||
static uint64_t s_sv_frame;
|
||||
static float s_frame_t;
|
||||
static int s_tps;
|
||||
|
||||
static bool s_debug_draw;
|
||||
|
||||
static void StartGame(const std::string& map_name);
|
||||
static void EndGame();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static void Run();
|
||||
static void SvFrame();
|
||||
static void ClFrame(Renderer& renderer, float frame_t);
|
||||
|
||||
static entt::registry& Registry() { return s_registry; }
|
||||
static PhysicsScene& Physics() { return *s_physics_scene; }
|
||||
static uint64_t FrameNum() { return s_sv_frame; }
|
||||
static float FrameT() { return s_frame_t; }
|
||||
static int TPS() { return s_tps; }
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct TransformComponent {
|
||||
|
||||
@ -50,7 +50,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
IAData TSR::ParseIA(const std::string& str, std::vector<BoneRef>& bone_list) {
|
||||
IAData TSR::ParseIA(const std::string& str, std::vector<BoneRef>* bone_list) {
|
||||
IAData data;
|
||||
|
||||
ReadStream rs(str.data(), str.length());
|
||||
@ -77,14 +77,14 @@ IAData TSR::ParseIA(const std::string& str, std::vector<BoneRef>& bone_list) {
|
||||
// skip reserved header
|
||||
rs.Seek(16);
|
||||
|
||||
if (data.is_skeletal) {
|
||||
if (data.is_skeletal && bone_list) {
|
||||
auto num_bones = rs.Read<uint32_t>();
|
||||
if (num_bones >= TSR_MAX_BONES)
|
||||
throw ParseException("Max bones exceeded");
|
||||
|
||||
bone_list.resize(num_bones);
|
||||
bone_list->resize(num_bones);
|
||||
|
||||
for (auto& bone : bone_list) {
|
||||
for (auto& bone : *bone_list) {
|
||||
bone.name = rs.ReadStr();
|
||||
bone.offset = rs.Read<glm::mat4>();
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ namespace TSR {
|
||||
bool is_skeletal;
|
||||
};
|
||||
|
||||
IAData ParseIA(const std::string& str, std::vector<BoneRef>& bone_list);
|
||||
IAData ParseIA(const std::string& str, std::vector<BoneRef>* bone_list = nullptr);
|
||||
void ParseSK(const std::string& str, std::vector<BoneInfo>& bone_list);
|
||||
void ParseSKAN(const std::string& str, std::vector<SkAnimChannel>& chan_list, size_t& duration, float& tps);
|
||||
}
|
||||
|
||||
@ -21,7 +21,11 @@ SkAnim::SkAnim(const std::string& name) {
|
||||
ParseSKAN(skan_str, m_channels, m_duration, m_tps);
|
||||
}
|
||||
|
||||
Model::Model(const std::string& name) {
|
||||
Model::Model(const std::string& name) :
|
||||
m_shape(SHAPE_NONE),
|
||||
m_shape_offset(0.0f),
|
||||
m_shape_size(0.0f)
|
||||
{
|
||||
|
||||
auto model_str = Filesystem::Read(name);
|
||||
|
||||
@ -104,6 +108,7 @@ Model::Model(const std::string& name) {
|
||||
m_part_names.insert({ part_json.at("name").get<std::string>(), m_parts.size() - 1 });
|
||||
}
|
||||
|
||||
// ANIMATIONS
|
||||
if (model_json.contains("animations")) {
|
||||
const auto& anims_json = model_json.at("animations");
|
||||
for (const auto& anim_json : anims_json) {
|
||||
@ -133,6 +138,28 @@ Model::Model(const std::string& name) {
|
||||
// events
|
||||
}
|
||||
}
|
||||
|
||||
// SHAPE
|
||||
if (model_json.contains("shape")) {
|
||||
const auto& shape_json = model_json.at("shape");
|
||||
|
||||
if (shape_json.is_string()) {
|
||||
m_shape = SHAPE_TRIANGLE_MESH;
|
||||
m_trimesh = AssetMap::Get<PhysicsTriangleMesh>(shape_json.get<std::string>());
|
||||
}
|
||||
else {
|
||||
std::string shape_type("none");
|
||||
|
||||
if (shape_json.contains("type"))
|
||||
shape_json.at("type").get_to(shape_type);
|
||||
|
||||
if (shape_type == "box") {
|
||||
m_shape = SHAPE_BOX;
|
||||
m_shape_offset = JsonGetVec<3>(shape_json.at("offset"));
|
||||
m_shape_size = JsonGetVec<3>(shape_json.at("size"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (nlohmann::json::exception ex) {
|
||||
Throw(ex.what());
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "assets.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "physics.hpp"
|
||||
|
||||
namespace TSR {
|
||||
|
||||
@ -38,6 +39,13 @@ namespace TSR {
|
||||
typedef int AnimationId;
|
||||
typedef int PartId;
|
||||
|
||||
enum ModelShape {
|
||||
SHAPE_NONE,
|
||||
SHAPE_TRIANGLE_MESH,
|
||||
SHAPE_BOX,
|
||||
SHAPE_COUNT
|
||||
};
|
||||
|
||||
class Model : public Asset {
|
||||
AssetPtr<Skeleton> m_skeleton;
|
||||
|
||||
@ -47,6 +55,11 @@ namespace TSR {
|
||||
std::vector<Animation> m_animations;
|
||||
std::map<std::string, AnimationId> m_anim_names;
|
||||
|
||||
ModelShape m_shape;
|
||||
AssetPtr<PhysicsTriangleMesh> m_trimesh;
|
||||
glm::vec3 m_shape_offset;
|
||||
glm::vec3 m_shape_size;
|
||||
|
||||
public:
|
||||
|
||||
Model(const std::string& name);
|
||||
@ -68,6 +81,11 @@ namespace TSR {
|
||||
const Animation& GetAnim(int id) { return m_animations[id]; }
|
||||
bool IsSkeletal() const { return m_skeleton.get() != nullptr; }
|
||||
bool HasAnimations() const { return m_animations.size() > 0; }
|
||||
ModelShape Shape() const { return m_shape; }
|
||||
const glm::vec3& ShapeOffset() const { return m_shape_offset; }
|
||||
const glm::vec3& ShapeSize() const { return m_shape_size; }
|
||||
const PhysicsTriangleMesh& TriMesh() const { return *m_trimesh; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
187
src/tsr/physics.cpp
Normal file
187
src/tsr/physics.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include "physics.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "ia.hpp"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace TSR;
|
||||
using namespace nlohmann;
|
||||
|
||||
PxDefaultErrorCallback Physics::s_default_error_cb;
|
||||
PxDefaultAllocator Physics::s_default_allocator_cb;
|
||||
|
||||
PxFoundation* Physics::s_foundation = nullptr;
|
||||
PxPhysics* Physics::s_physics = nullptr;
|
||||
PxCooking* Physics::s_cooking = nullptr;
|
||||
PxPvd* Physics::s_pvd = nullptr;
|
||||
|
||||
void Physics::Init() {
|
||||
// PHYSX init
|
||||
static PxDefaultErrorCallback gDefaultErrorCallback;
|
||||
static PxDefaultAllocator gDefaultAllocatorCallback;
|
||||
|
||||
s_foundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback);
|
||||
if (!s_foundation)
|
||||
Throw("(PX) PxCreateFoundation failed!");
|
||||
|
||||
bool recordMemoryAllocations = true;
|
||||
|
||||
auto mPvd = PxCreatePvd(*s_foundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate("localhost", 5425, 10);
|
||||
mPvd->connect(*transport, PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
PxTolerancesScale scale;
|
||||
|
||||
s_physics = PxCreatePhysics(PX_PHYSICS_VERSION, *s_foundation, scale, recordMemoryAllocations, mPvd);
|
||||
if (!s_physics)
|
||||
Throw("(PX) PxCreatePhysics failed!");
|
||||
|
||||
s_cooking = PxCreateCooking(PX_PHYSICS_VERSION, *s_foundation, PxCookingParams(scale));
|
||||
if (!s_cooking)
|
||||
Throw("(PX) PxCreateCooking failed!");
|
||||
|
||||
PxCookingParams params(scale);
|
||||
s_cooking->setParams(params);
|
||||
}
|
||||
|
||||
void Physics::Close() {
|
||||
s_cooking->release();
|
||||
s_physics->release();
|
||||
s_foundation->release();
|
||||
}
|
||||
|
||||
PhysicsScene::PhysicsScene() {
|
||||
PxSceneDesc sceneDesc(Physics::GetPhysics()->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
// create CPU dispatcher which mNbThreads worker threads
|
||||
m_cpu_dispatcher = PxDefaultCpuDispatcherCreate(1);
|
||||
if (!m_cpu_dispatcher)
|
||||
Throw("(PX) PxDefaultCpuDispatcherCreate failed!");
|
||||
|
||||
sceneDesc.cpuDispatcher = m_cpu_dispatcher;
|
||||
|
||||
if (!sceneDesc.filterShader)
|
||||
sceneDesc.filterShader = &PxDefaultSimulationFilterShader;
|
||||
|
||||
m_scene = Physics::GetPhysics()->createScene(sceneDesc);
|
||||
if (!m_scene)
|
||||
Throw("(PX) createScene failed!");
|
||||
|
||||
m_cct_manager = PxCreateControllerManager(*m_scene);
|
||||
if (!m_cct_manager)
|
||||
Throw("(PX) PxCreateControllerManager failed!");
|
||||
|
||||
m_scene->userData = this;
|
||||
}
|
||||
|
||||
PhysicsScene::~PhysicsScene() {
|
||||
m_cct_manager->release();
|
||||
m_scene->release();
|
||||
}
|
||||
|
||||
void PhysicsScene::StepSimulation(float time) {
|
||||
m_scene->simulate(time);
|
||||
m_scene->fetchResults(true);
|
||||
}
|
||||
|
||||
void PhysicsScene::EnableDebug(bool enable) {
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eSCALE, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eACTOR_AXES, enable ? 2.0f : 0.0f);
|
||||
////m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_EDGES, enable ? 1.0f : 0.0f);
|
||||
////m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_COMPOUNDS, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_AABBS, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eMBP_REGIONS, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eACTOR_AXES, enable ? 0.5f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eBODY_ANG_VELOCITY, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eBODY_AXES, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eBODY_LIN_VELOCITY, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eBODY_MASS_AXES, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_AABBS, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_AXES, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_COMPOUNDS, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_DYNAMIC, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_EDGES, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_FNORMALS, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_STATIC, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eCONTACT_ERROR, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eCONTACT_FORCE, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eCONTACT_NORMAL, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eCONTACT_POINT, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eCULL_BOX, enable ? 1.0f : 0.0f);
|
||||
//m_scene->setVisualizationParameter(PxVisualizationParameter::eFORCE_DWORD, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eJOINT_LIMITS, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eJOINT_LOCAL_FRAMES, enable ? 1.0f : 0.0f);
|
||||
m_scene->setVisualizationParameter(PxVisualizationParameter::eWORLD_AXES, enable ? 1.0f : 0.0f);
|
||||
|
||||
}
|
||||
|
||||
static glm::vec4 U32ColorToVec4(uint32_t rgba_value) {
|
||||
float red = static_cast<float>((rgba_value >> 24) & 0xFF) / 255.0f;
|
||||
float green = static_cast<float>((rgba_value >> 16) & 0xFF) / 255.0f;
|
||||
float blue = static_cast<float>((rgba_value >> 8) & 0xFF) / 255.0f;
|
||||
float alpha = static_cast<float>(rgba_value & 0xFF) / 255.0f;
|
||||
|
||||
return glm::vec4(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
void PhysicsScene::DrawDebug(Renderer& renderer) {
|
||||
const PxRenderBuffer& rb = m_scene->getRenderBuffer();
|
||||
for (PxU32 i = 0; i < rb.getNbLines(); i++) {
|
||||
const PxDebugLine& line = rb.getLines()[i];
|
||||
|
||||
glm::vec3 pos1(line.pos0.x, line.pos0.y, line.pos0.z);
|
||||
glm::vec3 pos2(line.pos1.x, line.pos1.y, line.pos1.z);
|
||||
glm::vec3 color1 = U32ColorToVec4(line.color0);
|
||||
glm::vec3 color2 = U32ColorToVec4(line.color1);
|
||||
|
||||
renderer.AddDebugLine(pos1, pos2, color1, color2);
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsMaterial::PhysicsMaterial(const std::string& path) {
|
||||
float static_friction, dynamic_friction, restitution;
|
||||
try {
|
||||
auto j_material = json::parse(Filesystem::Read(path));
|
||||
|
||||
j_material.at("static_friction").get_to(static_friction);
|
||||
j_material.at("dynamic_friction").get_to(dynamic_friction);
|
||||
j_material.at("restitution").get_to(restitution);
|
||||
}
|
||||
catch (json::exception ex) {
|
||||
Throw(ex.what());
|
||||
}
|
||||
|
||||
m_material = Physics::GetPhysics()->createMaterial(static_friction, dynamic_friction, restitution);
|
||||
m_material->userData = this;
|
||||
}
|
||||
|
||||
PhysicsMaterial::~PhysicsMaterial() {
|
||||
m_material->release();
|
||||
}
|
||||
|
||||
PhysicsTriangleMesh::PhysicsTriangleMesh(const std::string& path) {
|
||||
auto ia_str = Filesystem::Read(path);
|
||||
|
||||
auto mia3 = ParseIA(ia_str);
|
||||
|
||||
PxTriangleMeshDesc mesh_desc;
|
||||
mesh_desc.points.count = mia3.num_vertices;
|
||||
mesh_desc.points.stride = sizeof(PxVec3);
|
||||
mesh_desc.points.data = mia3.vertices_ptr;
|
||||
|
||||
mesh_desc.triangles.count = mia3.num_indices / 3;
|
||||
mesh_desc.triangles.stride = 3 * sizeof(PxU32);
|
||||
mesh_desc.triangles.data = mia3.indices_ptr;
|
||||
|
||||
#ifdef _DEBUG
|
||||
// mesh should be validated before cooked without the mesh cleaning
|
||||
bool res = Physics::GetCooking()->validateTriangleMesh(mesh_desc);
|
||||
PX_ASSERT(res);
|
||||
#endif
|
||||
|
||||
m_mesh = Physics::GetCooking()->createTriangleMesh(mesh_desc, Physics::GetPhysics()->getPhysicsInsertionCallback());
|
||||
}
|
||||
|
||||
PhysicsTriangleMesh::~PhysicsTriangleMesh() {
|
||||
m_mesh->release();
|
||||
}
|
||||
69
src/tsr/physics.hpp
Normal file
69
src/tsr/physics.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
#include <PxPhysics.h>
|
||||
#include <PxFoundation.h>
|
||||
#include <PxConfig.h>
|
||||
#include <PxPhysicsAPI.h>
|
||||
#include <PxFiltering.h>
|
||||
#include "tsr.hpp"
|
||||
#include "assets.hpp"
|
||||
#include "renderer.hpp"
|
||||
|
||||
namespace TSR {
|
||||
using namespace physx;
|
||||
|
||||
class Physics {
|
||||
|
||||
static PxDefaultErrorCallback s_default_error_cb;
|
||||
static PxDefaultAllocator s_default_allocator_cb;
|
||||
|
||||
static PxFoundation* s_foundation;
|
||||
static PxPhysics* s_physics;
|
||||
static PxCooking* s_cooking;
|
||||
static PxPvd* s_pvd;
|
||||
public:
|
||||
static void Init();
|
||||
static void Close();
|
||||
|
||||
static PxPhysics* GetPhysics() { return s_physics; }
|
||||
static PxCooking* GetCooking() { return s_cooking; }
|
||||
};
|
||||
|
||||
class PhysicsScene {
|
||||
PxDefaultCpuDispatcher* m_cpu_dispatcher;
|
||||
PxScene* m_scene;
|
||||
PxControllerManager* m_cct_manager;
|
||||
|
||||
public:
|
||||
PhysicsScene();
|
||||
~PhysicsScene();
|
||||
|
||||
PxScene* GetScene() { return m_scene; }
|
||||
PxControllerManager* GetCCTManager() { return m_cct_manager; }
|
||||
|
||||
void StepSimulation(float time);
|
||||
|
||||
void EnableDebug(bool enable);
|
||||
void DrawDebug(Renderer& renderer);
|
||||
};
|
||||
|
||||
class PhysicsMaterial : public Asset {
|
||||
PxMaterial* m_material;
|
||||
|
||||
public:
|
||||
PhysicsMaterial(const std::string& path);
|
||||
~PhysicsMaterial();
|
||||
|
||||
PxMaterial* Get() const { return m_material; }
|
||||
};
|
||||
|
||||
class PhysicsTriangleMesh : public Asset {
|
||||
PxTriangleMesh* m_mesh;
|
||||
|
||||
public:
|
||||
PhysicsTriangleMesh(const std::string& path);
|
||||
~PhysicsTriangleMesh();
|
||||
|
||||
PxTriangleMesh* Get() const { return m_mesh; }
|
||||
};
|
||||
|
||||
}
|
||||
@ -141,7 +141,7 @@ static inline void SetAttribPointers(Size... sizes) {
|
||||
Mesh::Mesh(const std::string& name) {
|
||||
auto file_str = Filesystem::Read(name);
|
||||
|
||||
auto ia = ParseIA(file_str, m_bones);
|
||||
auto ia = ParseIA(file_str, &m_bones);
|
||||
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
@ -181,6 +181,31 @@ Mesh::~Mesh() {
|
||||
glDeleteVertexArrays(1, &m_vao);
|
||||
}
|
||||
|
||||
DebugVAO::DebugVAO() {
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
glGenBuffers(1, &m_vbo); // Generate 1 buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * 2, NULL, GL_STREAM_DRAW);
|
||||
|
||||
SetAttribPointers<GLfloat, GLfloat>(3, 3);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void DebugVAO::Draw(std::vector<DebugVertex>& vertices, bool lines) {
|
||||
glBindVertexArray(m_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(DebugVertex) * vertices.size(), &vertices[0], GL_STREAM_DRAW);
|
||||
glDrawArrays(lines ? GL_LINES : GL_POINTS, 0, vertices.size());
|
||||
}
|
||||
|
||||
DebugVAO::~DebugVAO() {
|
||||
glDeleteBuffers(1, &m_vbo);
|
||||
glDeleteVertexArrays(1, &m_vao);
|
||||
}
|
||||
|
||||
InstancedSSBO::InstancedSSBO(const std::vector<BasicDrawCtx>& data) : m_size(data.size()) {
|
||||
glBindVertexArray(0);
|
||||
|
||||
@ -319,6 +344,7 @@ Renderer::Renderer() :
|
||||
m_shader_xz(Filesystem::Read("shaders/basic.vs"), Filesystem::Read("shaders/xz.fs"), "XZ"),
|
||||
m_shader_xz_xz_mask_uv(Filesystem::Read("shaders/basic.vs"), Filesystem::Read("shaders/xz_xz_mask_uv.fs"), "XZ_XZ_MASK_UV"),
|
||||
m_shader_skeletal(Filesystem::Read("shaders/skeletal.vs"), Filesystem::Read("shaders/skeletal.fs"), "SKELETAL"),
|
||||
m_shader_debug(Filesystem::Read("shaders/debug.vs"), Filesystem::Read("shaders/debug.fs"), "DEBUG"),
|
||||
m_proj_matrix(1.0f),
|
||||
m_view_matrix(1.0f),
|
||||
m_viewport_buf(AssetMap::Get<Mesh>("viewport.ia2")),
|
||||
@ -541,18 +567,27 @@ void Renderer::Render(int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
if (!m_debug_lines.empty()) {
|
||||
glStencilFunc(GL_ALWAYS, 0, 0xFF);
|
||||
m_shader_debug.Use();
|
||||
glUniformMatrix4fv(m_shader_debug.U(SU_VP), 1, GL_FALSE, glm::value_ptr(mat_vp));
|
||||
|
||||
m_debug_vao.Draw(m_debug_lines, true);
|
||||
}
|
||||
|
||||
//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
//glStencilFunc(GL_EQUAL, 0, 0xFF);
|
||||
//glStencilMask(0x00);
|
||||
|
||||
// draw skybox
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
m_shader_screen.Use();
|
||||
|
||||
@ -582,4 +617,6 @@ void Renderer::Render(int width, int height) {
|
||||
|
||||
for (int i = 0; i < RT_COUNT; ++i)
|
||||
m_draw_lists[i].clear();
|
||||
|
||||
m_debug_lines.clear();
|
||||
}
|
||||
|
||||
@ -74,6 +74,24 @@ namespace TSR {
|
||||
}
|
||||
};
|
||||
|
||||
struct DebugVertex {
|
||||
glm::vec3 pos;
|
||||
glm::vec3 color;
|
||||
};
|
||||
|
||||
class DebugVAO {
|
||||
GLuint m_vao;
|
||||
GLuint m_vbo;
|
||||
|
||||
public:
|
||||
DebugVAO();
|
||||
DebugVAO(const DebugVAO&) = delete;
|
||||
DebugVAO(DebugVAO&&) = delete;
|
||||
~DebugVAO();
|
||||
|
||||
void Draw(std::vector<DebugVertex>& vertices, bool lines);
|
||||
};
|
||||
|
||||
struct Drawable {
|
||||
RenderType type;
|
||||
|
||||
@ -268,6 +286,7 @@ namespace TSR {
|
||||
static RenderType s_rt_instanced_map[RT_COUNT];
|
||||
|
||||
std::vector<DrawRef> m_draw_lists[RT_COUNT];
|
||||
std::vector<DebugVertex> m_debug_lines;
|
||||
|
||||
Shader m_shader_basic;
|
||||
Shader m_shader_basic_instanced;
|
||||
@ -277,10 +296,12 @@ namespace TSR {
|
||||
Shader m_shader_xz_xz_mask_uv;
|
||||
Shader m_shader_screen;
|
||||
Shader m_shader_skeletal;
|
||||
Shader m_shader_debug;
|
||||
//float m_aspect_ratio;
|
||||
std::unique_ptr<FramebuffersWrapper> m_fbs;
|
||||
|
||||
std::shared_ptr<Mesh> m_viewport_buf;
|
||||
DebugVAO m_debug_vao;
|
||||
|
||||
int m_last_width, m_last_height;
|
||||
|
||||
@ -300,6 +321,11 @@ namespace TSR {
|
||||
m_draw_lists[s_rt_instanced_map[draw_ref.drawable->type]].push_back(draw_ref);
|
||||
}
|
||||
|
||||
void AddDebugLine(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& color1 = glm::vec3(1.0f), const glm::vec3& color2 = glm::vec3(1.0f)) {
|
||||
m_debug_lines.push_back({ p1, color1 });
|
||||
m_debug_lines.push_back({ p2, color2 });
|
||||
}
|
||||
|
||||
void SetViewMatrix(const glm::mat4& view_matrix) {
|
||||
m_view_matrix = view_matrix;
|
||||
}
|
||||
|
||||
@ -1,10 +1,16 @@
|
||||
#include "worldmap.hpp"
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
using namespace TSR;
|
||||
|
||||
static const char* color_strs[] = { "color1", "color2", "color3", "color4" };
|
||||
|
||||
WorldMap::WorldMap(const std::string& map_path) : m_loading_phase(LoadingPhase::FIRST), m_map_path(map_path), m_loaded_models(0) {}
|
||||
WorldMap::WorldMap(const std::string& map_path, PhysicsScene* physics_scene) :
|
||||
m_loading_phase(LoadingPhase::FIRST),
|
||||
m_map_path(map_path),
|
||||
m_loaded_models(0),
|
||||
m_physics_scene(physics_scene)
|
||||
{}
|
||||
|
||||
int WorldMap::LoadNext() {
|
||||
switch (m_loading_phase) {
|
||||
@ -40,7 +46,11 @@ int WorldMap::LoadNext() {
|
||||
if (j_object.contains("scale"))
|
||||
j_object.at("scale").get_to(scale);
|
||||
|
||||
ctx.model_matrix = glm::scale(glm::rotate(glm::translate(glm::mat4(1.0f), pos), glm::radians(rot), glm::vec3(0.0f, 1.0f, 0.0f)), glm::vec3(scale));
|
||||
PhysicalObject phyobj;
|
||||
ctx.model_matrix = glm::rotate(glm::translate(glm::mat4(1.0f), pos), glm::radians(rot), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
phyobj.m_transform = PxTransform(PxMat44(glm::value_ptr(ctx.model_matrix)));
|
||||
ctx.model_matrix = glm::scale(ctx.model_matrix, glm::vec3(scale));
|
||||
phyobj.m_scale = scale;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
auto& cns = color_strs[i];
|
||||
@ -49,7 +59,7 @@ int WorldMap::LoadNext() {
|
||||
}
|
||||
|
||||
model_instances.m_contexts.push_back(ctx);
|
||||
|
||||
model_instances.m_physical_objects.push_back(phyobj);
|
||||
}
|
||||
|
||||
m_loading_iter = m_loading_obj_data.cbegin();
|
||||
@ -93,6 +103,40 @@ int WorldMap::LoadNext() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (s->Shape() == SHAPE_TRIANGLE_MESH) {
|
||||
auto material = AssetMap::Get<PhysicsMaterial>("physics/default.material.json");
|
||||
auto& shape = s->TriMesh();
|
||||
|
||||
for (const auto& phyobj : models.second.m_physical_objects) {
|
||||
PxRigidStatic* actor = Physics::GetPhysics()->createRigidStatic(phyobj.m_transform);
|
||||
PxShape* px_shape = PxRigidActorExt::createExclusiveShape(*actor, PxTriangleMeshGeometry(shape.Get(), PxMeshScale(phyobj.m_scale)), *material->Get());
|
||||
|
||||
m_physics_scene->GetScene()->addActor(*actor);
|
||||
|
||||
//actor->release();
|
||||
}
|
||||
|
||||
}
|
||||
else if (s->Shape() == SHAPE_BOX) {
|
||||
auto material = AssetMap::Get<PhysicsMaterial>("physics/default.material.json");
|
||||
|
||||
for (const auto& phyobj : models.second.m_physical_objects) {
|
||||
auto transform = phyobj.m_transform;
|
||||
auto size = s->ShapeSize();
|
||||
auto offset = s->ShapeOffset();
|
||||
transform.p = transform.p + PxVec3(offset.x * phyobj.m_scale, offset.y * phyobj.m_scale, offset.z * phyobj.m_scale);
|
||||
|
||||
PxRigidStatic* actor = Physics::GetPhysics()->createRigidStatic(transform);
|
||||
|
||||
PxShape* px_shape = PxRigidActorExt::createExclusiveShape(*actor, PxBoxGeometry(size.x * phyobj.m_scale, size.y * phyobj.m_scale, size.z * phyobj.m_scale), *material->Get());
|
||||
m_physics_scene->GetScene()->addActor(*actor);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return 10 + (90 * m_loaded_models / m_loading_obj_data.size());
|
||||
|
||||
break;
|
||||
|
||||
@ -4,12 +4,14 @@
|
||||
//#include "audio.hpp"
|
||||
#include "window.hpp"
|
||||
#include "tsr.hpp"
|
||||
#include "physics.hpp"
|
||||
|
||||
namespace TSR {
|
||||
|
||||
class WorldMap {
|
||||
// general
|
||||
std::string m_map_path;
|
||||
PhysicsScene* m_physics_scene;
|
||||
|
||||
// loading
|
||||
enum class LoadingPhase {
|
||||
@ -19,8 +21,14 @@ namespace TSR {
|
||||
FINISHED,
|
||||
} m_loading_phase;
|
||||
|
||||
struct PhysicalObject {
|
||||
PxTransform m_transform;
|
||||
float m_scale;
|
||||
};
|
||||
|
||||
struct ModelInstances {
|
||||
std::vector<BasicDrawCtx> m_contexts;
|
||||
std::vector<PhysicalObject> m_physical_objects;
|
||||
};
|
||||
|
||||
using LoadingObjData = std::map<std::string, ModelInstances>;
|
||||
@ -39,7 +47,7 @@ namespace TSR {
|
||||
std::vector<MapObject> m_objects_instanced;
|
||||
|
||||
public:
|
||||
WorldMap(const std::string& map_path);
|
||||
WorldMap(const std::string& map_path, PhysicsScene* physics_scene);
|
||||
|
||||
bool Loaded() const { return m_loading_phase == LoadingPhase::FINISHED; }
|
||||
const std::string& Name() { return m_map_path; }
|
||||
|
||||
@ -129,6 +129,8 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\tsr\entity_cct.cpp" />
|
||||
<ClCompile Include="src\tsr\physics.cpp" />
|
||||
<ClCompile Include="src\tsr\camera.cpp" />
|
||||
<ClCompile Include="src\tsr\model.cpp" />
|
||||
<ClCompile Include="src\tsr\entity_model.cpp" />
|
||||
@ -142,6 +144,8 @@
|
||||
<ClCompile Include="src\tsr\worldmap.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\tsr\entity_cct.hpp" />
|
||||
<ClInclude Include="src\tsr\physics.hpp" />
|
||||
<ClInclude Include="src\tsr\camera.hpp" />
|
||||
<ClInclude Include="src\tsr\model.hpp" />
|
||||
<ClInclude Include="src\tsr\entity_model.hpp" />
|
||||
|
||||
@ -48,6 +48,12 @@
|
||||
<ClCompile Include="src\tsr\worldmap.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\tsr\physics.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\tsr\entity_cct.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\tsr\window.hpp">
|
||||
@ -89,5 +95,11 @@
|
||||
<ClInclude Include="src\tsr\worldmap.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\tsr\physics.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\tsr\entity_cct.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
x
Reference in New Issue
Block a user