Proper AABBs of chunks&objs, camera sweep test
This commit is contained in:
parent
698bcafec0
commit
fd3f981ec0
@ -9,6 +9,26 @@
|
|||||||
#include "cmdfile.hpp"
|
#include "cmdfile.hpp"
|
||||||
#include "utils/files.hpp"
|
#include "utils/files.hpp"
|
||||||
|
|
||||||
|
static AABB3 TransformAABB(const AABB3& aabb, const glm::mat4& mat)
|
||||||
|
{
|
||||||
|
const glm::vec3 corners[] = {
|
||||||
|
glm::vec3(aabb.min.x, aabb.min.y, aabb.min.z), glm::vec3(aabb.max.x, aabb.min.y, aabb.min.z),
|
||||||
|
glm::vec3(aabb.min.x, aabb.max.y, aabb.min.z), glm::vec3(aabb.max.x, aabb.max.y, aabb.min.z),
|
||||||
|
glm::vec3(aabb.min.x, aabb.min.y, aabb.max.z), glm::vec3(aabb.max.x, aabb.min.y, aabb.max.z),
|
||||||
|
glm::vec3(aabb.min.x, aabb.max.y, aabb.max.z), glm::vec3(aabb.max.x, aabb.max.y, aabb.max.z),
|
||||||
|
};
|
||||||
|
|
||||||
|
AABB3 new_aabb;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
glm::vec3 p = mat * glm::vec4(corners[i], 1.0f);
|
||||||
|
new_aabb.AddPoint(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_aabb;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string& filename)
|
std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string& filename)
|
||||||
{
|
{
|
||||||
auto map = std::make_shared<Map>();
|
auto map = std::make_shared<Map>();
|
||||||
@ -58,8 +78,8 @@ std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string&
|
|||||||
|
|
||||||
obj.node.UpdateMatrix();
|
obj.node.UpdateMatrix();
|
||||||
|
|
||||||
obj.aabb.min = trans.position - glm::vec3(10.0f);
|
obj.aabb = TransformAABB(obj.model->GetAABB(), obj.node.matrix);
|
||||||
obj.aabb.max = trans.position + glm::vec3(10.0f);
|
chunk->aabb.AddAABB(obj.aabb);
|
||||||
|
|
||||||
std::string flag;
|
std::string flag;
|
||||||
while (iss >> flag)
|
while (iss >> flag)
|
||||||
@ -79,7 +99,6 @@ std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string&
|
|||||||
iss >> coord.x >> coord.y;
|
iss >> coord.x >> coord.y;
|
||||||
iss >> chunk->aabb.min.x >> chunk->aabb.min.y >> chunk->aabb.min.z;
|
iss >> chunk->aabb.min.x >> chunk->aabb.min.y >> chunk->aabb.min.z;
|
||||||
iss >> chunk->aabb.max.x >> chunk->aabb.max.y >> chunk->aabb.max.z;
|
iss >> chunk->aabb.max.x >> chunk->aabb.max.y >> chunk->aabb.max.z;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (command == "surface")
|
else if (command == "surface")
|
||||||
{
|
{
|
||||||
@ -181,7 +200,6 @@ void assets::Map::Draw(const game::view::DrawArgs& args) const
|
|||||||
|
|
||||||
DrawChunk(args, mesh, chunk);
|
DrawChunk(args, mesh, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void assets::Map::DrawChunk(const game::view::DrawArgs& args, const Mesh& basemesh, const Chunk& chunk) const
|
void assets::Map::DrawChunk(const game::view::DrawArgs& args, const Mesh& basemesh, const Chunk& chunk) const
|
||||||
@ -219,4 +237,3 @@ void assets::Map::DrawChunk(const game::view::DrawArgs& args, const Mesh& baseme
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // CLIENT
|
#endif // CLIENT
|
||||||
|
|
||||||
|
|||||||
@ -45,6 +45,8 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
|
|||||||
|
|
||||||
if (temp_hull)
|
if (temp_hull)
|
||||||
temp_hull->addPoint(btVector3(pos.x, pos.y, pos.z), false);
|
temp_hull->addPoint(btVector3(pos.x, pos.y, pos.z), false);
|
||||||
|
|
||||||
|
model->aabb_.AddPoint(pos);
|
||||||
}
|
}
|
||||||
else if (command == "f")
|
else if (command == "f")
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "skeleton.hpp"
|
#include "skeleton.hpp"
|
||||||
#include "utils/defs.hpp"
|
#include "utils/defs.hpp"
|
||||||
|
#include "utils/aabb.hpp"
|
||||||
#include "collision/trianglemesh.hpp"
|
#include "collision/trianglemesh.hpp"
|
||||||
|
|
||||||
#ifdef CLIENT
|
#ifdef CLIENT
|
||||||
@ -45,6 +46,7 @@ public:
|
|||||||
|
|
||||||
const std::shared_ptr<const Skeleton>& GetSkeleton() const { return skeleton_; }
|
const std::shared_ptr<const Skeleton>& GetSkeleton() const { return skeleton_; }
|
||||||
CLIENT_ONLY(const std::shared_ptr<const Mesh>& GetMesh() const { return mesh_; })
|
CLIENT_ONLY(const std::shared_ptr<const Mesh>& GetMesh() const { return mesh_; })
|
||||||
|
const AABB3& GetAABB() const { return aabb_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<collision::TriangleMesh> cmesh_;
|
std::unique_ptr<collision::TriangleMesh> cmesh_;
|
||||||
@ -52,7 +54,8 @@ private:
|
|||||||
std::unique_ptr<btCollisionShape> cshape_;
|
std::unique_ptr<btCollisionShape> cshape_;
|
||||||
|
|
||||||
std::shared_ptr<const Skeleton> skeleton_;
|
std::shared_ptr<const Skeleton> skeleton_;
|
||||||
CLIENT_ONLY(std::shared_ptr<const Mesh> mesh_;)
|
CLIENT_ONLY(std::shared_ptr<const Mesh> mesh_;);
|
||||||
|
AABB3 aabb_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -66,7 +66,6 @@ void App::Frame()
|
|||||||
session_->Update(updinfo);
|
session_->Update(updinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
float aspect = static_cast<float>(viewport_size_.x) / static_cast<float>(viewport_size_.y);
|
|
||||||
|
|
||||||
renderer_.Begin(viewport_size_.x, viewport_size_.y);
|
renderer_.Begin(viewport_size_.x, viewport_size_.y);
|
||||||
renderer_.ClearColor(glm::vec3(0.5f, 0.7f, 1.0f));
|
renderer_.ClearColor(glm::vec3(0.5f, 0.7f, 1.0f));
|
||||||
@ -78,43 +77,11 @@ void App::Frame()
|
|||||||
params.screen_height = viewport_size_.y;
|
params.screen_height = viewport_size_.y;
|
||||||
|
|
||||||
const game::view::WorldView* world;
|
const game::view::WorldView* world;
|
||||||
if (session_ && (world = session_->GetWorld()))
|
if (session_)
|
||||||
{
|
{
|
||||||
// glm::mat4 view = glm::lookAt(glm::vec3(15.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -13.0f), glm::vec3(0.0f, 0.0f, 1.0f));
|
session_->Draw(dlist_, params);
|
||||||
glm::mat4 proj = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 3000.0f);
|
|
||||||
glm::vec3 eye;
|
|
||||||
glm::mat4 view;
|
|
||||||
session_->GetViewInfo(eye, view);
|
|
||||||
|
|
||||||
params.view_proj = proj * view;
|
|
||||||
params.cam_pos = eye;
|
|
||||||
|
|
||||||
game::view::DrawArgs draw_args(dlist_, params.view_proj, eye, viewport_size_, 500.0f);
|
|
||||||
world->Draw(draw_args);
|
|
||||||
|
|
||||||
glm::mat4 camera_world = glm::inverse(view);
|
|
||||||
audiomaster_.SetListenerOrientation(camera_world);
|
|
||||||
|
|
||||||
if (time_ - last_send_time_ > 0.040f)
|
|
||||||
{
|
|
||||||
net::ViewYawQ yaw_q;
|
|
||||||
net::ViewPitchQ pitch_q;
|
|
||||||
yaw_q.Encode(session_->GetYaw());
|
|
||||||
pitch_q.Encode(session_->GetPitch());
|
|
||||||
|
|
||||||
if (yaw_q.value != view_yaw_q_.value || pitch_q.value != view_pitch_q_.value)
|
|
||||||
{
|
|
||||||
auto msg = BeginMsg(net::MSG_VIEWANGLES);
|
|
||||||
msg.Write(yaw_q.value);
|
|
||||||
msg.Write(pitch_q.value);
|
|
||||||
|
|
||||||
view_yaw_q_.value = yaw_q.value;
|
|
||||||
view_pitch_q_.value = pitch_q.value;
|
|
||||||
last_send_time_ = time_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw chat
|
// draw chat
|
||||||
UpdateChat();
|
UpdateChat();
|
||||||
DrawChat(dlist_);
|
DrawChat(dlist_);
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public:
|
|||||||
void SetInput(game::PlayerInputFlags input) { input_ = input; }
|
void SetInput(game::PlayerInputFlags input) { input_ = input; }
|
||||||
void MouseMove(const glm::vec2& delta);
|
void MouseMove(const glm::vec2& delta);
|
||||||
|
|
||||||
float GetTime() const { return delta_time_; }
|
float GetTime() const { return time_; }
|
||||||
float GetDeltaTime() const { return delta_time_; }
|
float GetDeltaTime() const { return delta_time_; }
|
||||||
|
|
||||||
audio::Master& GetAudioMaster() { return audiomaster_; }
|
audio::Master& GetAudioMaster() { return audiomaster_; }
|
||||||
@ -55,12 +55,10 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
float time_ = 0.0f;
|
float time_ = 0.0f;
|
||||||
float last_send_time_ = 0.0f;
|
|
||||||
glm::ivec2 viewport_size_ = {800, 600};
|
glm::ivec2 viewport_size_ = {800, 600};
|
||||||
game::PlayerInputFlags input_ = 0;
|
game::PlayerInputFlags input_ = 0;
|
||||||
game::PlayerInputFlags prev_input_ = 0;
|
game::PlayerInputFlags prev_input_ = 0;
|
||||||
net::ViewYawQ view_yaw_q_;
|
|
||||||
net::ViewPitchQ view_pitch_q_;
|
|
||||||
|
|
||||||
float prev_time_ = 0.0f;
|
float prev_time_ = 0.0f;
|
||||||
float delta_time_ = 0.0f;
|
float delta_time_ = 0.0f;
|
||||||
|
|||||||
@ -2,34 +2,22 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
collision::DynamicsWorld::DynamicsWorld(std::shared_ptr<const assets::Map> map)
|
collision::DynamicsWorld::DynamicsWorld()
|
||||||
: map_(std::move(map)), bt_dispatcher_(&bt_cfg_),
|
: bt_dispatcher_(&bt_cfg_),
|
||||||
bt_world_(&bt_dispatcher_, &bt_broadphase_, &bt_solver_, &bt_cfg_), bt_veh_raycaster_(&bt_world_)
|
bt_world_(&bt_dispatcher_, &bt_broadphase_, &bt_solver_, &bt_cfg_), bt_veh_raycaster_(&bt_world_)
|
||||||
{
|
{
|
||||||
bt_world_.setGravity(btVector3(0, 0, -9.81f));
|
bt_world_.setGravity(btVector3(0, 0, -9.81f));
|
||||||
|
|
||||||
bt_broadphase_.getOverlappingPairCache()->setInternalGhostPairCallback(&bt_ghost_pair_cb_);
|
bt_broadphase_.getOverlappingPairCache()->setInternalGhostPairCallback(&bt_ghost_pair_cb_);
|
||||||
|
|
||||||
AddMapCollision();
|
|
||||||
|
|
||||||
// btTransform t;
|
|
||||||
// t.setIdentity();
|
|
||||||
// t.setOrigin(btVector3(0,0,-12));
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: remove
|
|
||||||
// static btDefaultMotionState motion(t);
|
|
||||||
// static btBoxShape box(btVector3(100, 100, 2));
|
|
||||||
// btRigidBody::btRigidBodyConstructionInfo rbInfo(0.0f, &motion, &box, btVector3(0,0,0));
|
|
||||||
// static btRigidBody body(rbInfo);
|
|
||||||
// bt_world_.addRigidBody(&body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void collision::DynamicsWorld::AddMapCollision()
|
void collision::DynamicsWorld::AddMapCollision(std::shared_ptr<const assets::Map> map)
|
||||||
{
|
{
|
||||||
if (!map_) // is perfectly possible that there is no map in this world
|
if (!map)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
map_ = std::move(map);
|
||||||
|
|
||||||
// add basemodel
|
// add basemodel
|
||||||
const auto& basemodel = map_->GetBaseModel();
|
const auto& basemodel = map_->GetBaseModel();
|
||||||
if (basemodel)
|
if (basemodel)
|
||||||
|
|||||||
@ -25,16 +25,15 @@ namespace collision
|
|||||||
class DynamicsWorld
|
class DynamicsWorld
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DynamicsWorld(std::shared_ptr<const assets::Map> map);
|
DynamicsWorld();
|
||||||
|
|
||||||
|
void AddMapCollision(std::shared_ptr<const assets::Map> map);
|
||||||
|
|
||||||
btDynamicsWorld& GetBtWorld() { return bt_world_; }
|
btDynamicsWorld& GetBtWorld() { return bt_world_; }
|
||||||
const btDynamicsWorld& GetBtWorld() const { return bt_world_; }
|
const btDynamicsWorld& GetBtWorld() const { return bt_world_; }
|
||||||
btVehicleRaycaster& GetVehicleRaycaster() { return bt_veh_raycaster_; }
|
btVehicleRaycaster& GetVehicleRaycaster() { return bt_veh_raycaster_; }
|
||||||
|
|
||||||
const std::shared_ptr<const assets::Map>& GetMap() const { return map_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AddMapCollision();
|
|
||||||
void AddModelInstance(const assets::Model& model, const Transform& trans);
|
void AddModelInstance(const assets::Model& model, const Transform& trans);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -552,7 +552,7 @@ static const char* GetRandomCarModel()
|
|||||||
|
|
||||||
void game::OpenWorld::SpawnBot()
|
void game::OpenWorld::SpawnBot()
|
||||||
{
|
{
|
||||||
auto roads = GetMap()->GetGraph("roads");
|
auto roads = GetMap().GetGraph("roads");
|
||||||
|
|
||||||
if (!roads)
|
if (!roads)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,13 +5,12 @@
|
|||||||
#include "assets/cache.hpp"
|
#include "assets/cache.hpp"
|
||||||
#include "utils/allocnum.hpp"
|
#include "utils/allocnum.hpp"
|
||||||
|
|
||||||
static std::shared_ptr<const assets::Map> LoadMapByName(const std::string& mapname)
|
game::World::World(std::string mapname) : mapname_(std::move(mapname))
|
||||||
{
|
{
|
||||||
return assets::CacheManager::GetMap("data/" + mapname + ".map");
|
map_ = assets::CacheManager::GetMap("data/" + mapname_ + ".map");
|
||||||
|
AddMapCollision(map_);
|
||||||
}
|
}
|
||||||
|
|
||||||
game::World::World(std::string mapname) : DynamicsWorld(LoadMapByName(mapname)), mapname_(std::move(mapname)) {}
|
|
||||||
|
|
||||||
net::EntNum game::World::GetNewEntnum()
|
net::EntNum game::World::GetNewEntnum()
|
||||||
{
|
{
|
||||||
auto entnum = utils::AllocNum(ents_, last_entnum_);
|
auto entnum = utils::AllocNum(ents_, last_entnum_);
|
||||||
|
|||||||
@ -46,7 +46,11 @@ public:
|
|||||||
|
|
||||||
virtual ~World() = default;
|
virtual ~World() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const assets::Map& GetMap() const { return *map_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<const assets::Map> map_;
|
||||||
std::string mapname_;
|
std::string mapname_;
|
||||||
std::map<net::EntNum, std::unique_ptr<Entity>> ents_;
|
std::map<net::EntNum, std::unique_ptr<Entity>> ents_;
|
||||||
net::EntNum last_entnum_ = 0;
|
net::EntNum last_entnum_ = 0;
|
||||||
|
|||||||
@ -35,6 +35,8 @@ game::view::CharacterView::CharacterView(WorldView& world, net::InMessage& msg)
|
|||||||
|
|
||||||
states_[0] = states_[1]; // lerp from the read state to avoid jump
|
states_[0] = states_[1]; // lerp from the read state to avoid jump
|
||||||
|
|
||||||
|
|
||||||
|
radius_ = 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool game::view::CharacterView::ProcessMsg(net::EntMsgType type, net::InMessage& msg)
|
bool game::view::CharacterView::ProcessMsg(net::EntMsgType type, net::InMessage& msg)
|
||||||
|
|||||||
@ -64,18 +64,29 @@ void game::view::ClientSession::ProcessMouseMove(float delta_yaw, float delta_pi
|
|||||||
void game::view::ClientSession::Update(const UpdateInfo& info)
|
void game::view::ClientSession::Update(const UpdateInfo& info)
|
||||||
{
|
{
|
||||||
if (world_)
|
if (world_)
|
||||||
|
{
|
||||||
world_->Update(info);
|
world_->Update(info);
|
||||||
|
SendViewAngles(info.time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void game::view::ClientSession::Draw(gfx::DrawList& dlist, gfx::DrawListParams& params)
|
||||||
|
{
|
||||||
|
if (world_)
|
||||||
|
{
|
||||||
|
DrawWorld(dlist, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::view::ClientSession::GetViewInfo(glm::vec3& eye, glm::mat4& view) const
|
void game::view::ClientSession::GetViewInfo(glm::vec3& eye, glm::mat4& view) const
|
||||||
{
|
{
|
||||||
glm::vec3 center(0.0f, 0.0f, 2.5f);
|
glm::vec3 start(0.0f, 0.0f, 2.0f);
|
||||||
|
|
||||||
if (world_ && follow_ent_)
|
if (follow_ent_)
|
||||||
{
|
{
|
||||||
auto ent = world_->GetEntity(follow_ent_);
|
auto ent = world_->GetEntity(follow_ent_);
|
||||||
if (ent)
|
if (ent)
|
||||||
center += ent->GetRoot().local.position;
|
start += ent->GetRoot().local.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
float yaw_cos = glm::cos(yaw_);
|
float yaw_cos = glm::cos(yaw_);
|
||||||
@ -84,10 +95,12 @@ void game::view::ClientSession::GetViewInfo(glm::vec3& eye, glm::mat4& view) con
|
|||||||
float pitch_sin = glm::sin(pitch_);
|
float pitch_sin = glm::sin(pitch_);
|
||||||
glm::vec3 dir(yaw_cos * pitch_cos, yaw_sin * pitch_cos, pitch_sin);
|
glm::vec3 dir(yaw_cos * pitch_cos, yaw_sin * pitch_cos, pitch_sin);
|
||||||
|
|
||||||
float distance = 8.0f;
|
float distance = 5.0f;
|
||||||
|
glm::vec3 end = start - dir * distance;
|
||||||
|
|
||||||
eye = center - dir * distance;
|
//start.z -= 0.5f; // shift this a bit to make it better when occluded
|
||||||
view = glm::lookAt(eye, center, glm::vec3(0, 0, 1));
|
eye = world_->CameraSweep(start, end);
|
||||||
|
view = glm::lookAt(eye, eye + dir, glm::vec3(0, 0, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
audio::Master& game::view::ClientSession::GetAudioMaster() const
|
audio::Master& game::view::ClientSession::GetAudioMaster() const
|
||||||
@ -124,3 +137,49 @@ bool game::view::ClientSession::ProcessChatMsg(net::InMessage& msg)
|
|||||||
app_.AddChatMessagePrefix("Server", chatm);
|
app_.AddChatMessagePrefix("Server", chatm);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void game::view::ClientSession::DrawWorld(gfx::DrawList& dlist, gfx::DrawListParams& params)
|
||||||
|
{
|
||||||
|
// glm::mat4 view = glm::lookAt(glm::vec3(15.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -13.0f), glm::vec3(0.0f,
|
||||||
|
// 0.0f, 1.0f));
|
||||||
|
float aspect = static_cast<float>(params.screen_width) / static_cast<float>(params.screen_height);
|
||||||
|
|
||||||
|
glm::mat4 proj = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 3000.0f);
|
||||||
|
glm::vec3 eye;
|
||||||
|
glm::mat4 view;
|
||||||
|
GetViewInfo(eye, view);
|
||||||
|
|
||||||
|
params.view_proj = proj * view;
|
||||||
|
params.cam_pos = eye;
|
||||||
|
|
||||||
|
// glm::mat4 fake_view_proj = glm::perspective(glm::radians(30.0f), aspect, 0.1f, 3000.0f) * view;
|
||||||
|
|
||||||
|
game::view::DrawArgs draw_args(dlist, params.view_proj, eye, glm::ivec2(params.screen_width, params.screen_height),
|
||||||
|
500.0f);
|
||||||
|
world_->Draw(draw_args);
|
||||||
|
|
||||||
|
glm::mat4 camera_world = glm::inverse(view);
|
||||||
|
GetAudioMaster().SetListenerOrientation(camera_world);
|
||||||
|
}
|
||||||
|
|
||||||
|
void game::view::ClientSession::SendViewAngles(float time)
|
||||||
|
{
|
||||||
|
if (time - last_send_time_ < 0.040f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
net::ViewYawQ yaw_q;
|
||||||
|
net::ViewPitchQ pitch_q;
|
||||||
|
yaw_q.Encode(yaw_);
|
||||||
|
pitch_q.Encode(pitch_);
|
||||||
|
|
||||||
|
if (yaw_q.value == view_yaw_q_.value && pitch_q.value == view_pitch_q_.value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto msg = app_.BeginMsg(net::MSG_VIEWANGLES);
|
||||||
|
msg.Write(yaw_q.value);
|
||||||
|
msg.Write(pitch_q.value);
|
||||||
|
|
||||||
|
view_yaw_q_.value = yaw_q.value;
|
||||||
|
view_pitch_q_.value = pitch_q.value;
|
||||||
|
last_send_time_ = time;
|
||||||
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "worldview.hpp"
|
#include "worldview.hpp"
|
||||||
|
|
||||||
#include "gfx/draw_list.hpp"
|
#include "gfx/draw_list.hpp"
|
||||||
|
#include "gfx/renderer.hpp"
|
||||||
#include "net/defs.hpp"
|
#include "net/defs.hpp"
|
||||||
#include "net/inmessage.hpp"
|
#include "net/inmessage.hpp"
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ public:
|
|||||||
void ProcessMouseMove(float delta_yaw, float delta_pitch);
|
void ProcessMouseMove(float delta_yaw, float delta_pitch);
|
||||||
|
|
||||||
void Update(const UpdateInfo& info);
|
void Update(const UpdateInfo& info);
|
||||||
|
void Draw(gfx::DrawList& dlist, gfx::DrawListParams& params);
|
||||||
|
|
||||||
const WorldView* GetWorld() const { return world_.get(); }
|
const WorldView* GetWorld() const { return world_.get(); }
|
||||||
|
|
||||||
@ -31,15 +33,15 @@ public:
|
|||||||
|
|
||||||
audio::Master& GetAudioMaster() const;
|
audio::Master& GetAudioMaster() const;
|
||||||
|
|
||||||
float GetYaw() const { return yaw_; }
|
|
||||||
float GetPitch() const { return pitch_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// msg handlers
|
// msg handlers
|
||||||
bool ProcessWorldMsg(net::InMessage& msg);
|
bool ProcessWorldMsg(net::InMessage& msg);
|
||||||
bool ProcessCameraMsg(net::InMessage& msg);
|
bool ProcessCameraMsg(net::InMessage& msg);
|
||||||
bool ProcessChatMsg(net::InMessage& msg);
|
bool ProcessChatMsg(net::InMessage& msg);
|
||||||
|
|
||||||
|
void DrawWorld(gfx::DrawList& dlist, gfx::DrawListParams& params);
|
||||||
|
void SendViewAngles(float time);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
App& app_;
|
App& app_;
|
||||||
|
|
||||||
@ -48,6 +50,9 @@ private:
|
|||||||
float yaw_ = 0.0f, pitch_ = 0.0f;
|
float yaw_ = 0.0f, pitch_ = 0.0f;
|
||||||
net::EntNum follow_ent_ = 0;
|
net::EntNum follow_ent_ = 0;
|
||||||
|
|
||||||
|
net::ViewYawQ view_yaw_q_;
|
||||||
|
net::ViewPitchQ view_pitch_q_;
|
||||||
|
float last_send_time_ = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace game::view
|
} // namespace game::view
|
||||||
@ -11,6 +11,7 @@ game::view::WorldView::WorldView(ClientSession& session) :
|
|||||||
audiomaster_(session_.GetAudioMaster())
|
audiomaster_(session_.GetAudioMaster())
|
||||||
{
|
{
|
||||||
map_ = assets::CacheManager::GetMap("data/openworld.map");
|
map_ = assets::CacheManager::GetMap("data/openworld.map");
|
||||||
|
AddMapCollision(map_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool game::view::WorldView::ProcessMsg(net::MessageType type, net::InMessage& msg)
|
bool game::view::WorldView::ProcessMsg(net::MessageType type, net::InMessage& msg)
|
||||||
@ -53,6 +54,31 @@ void game::view::WorldView::Draw(const DrawArgs& args) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 game::view::WorldView::CameraSweep(const glm::vec3& start, const glm::vec3& end)
|
||||||
|
{
|
||||||
|
const auto& bt_world = GetBtWorld();
|
||||||
|
|
||||||
|
static const btSphereShape shape(0.1f);
|
||||||
|
|
||||||
|
btVector3 bt_start(start.x, start.y, start.z);
|
||||||
|
btVector3 bt_end(end.x, end.y, end.z);
|
||||||
|
|
||||||
|
btTransform from, to;
|
||||||
|
from.setIdentity();
|
||||||
|
from.setOrigin(bt_start);
|
||||||
|
to.setIdentity();
|
||||||
|
to.setOrigin(bt_end);
|
||||||
|
|
||||||
|
btCollisionWorld::ClosestConvexResultCallback cb(bt_start, bt_end);
|
||||||
|
|
||||||
|
bt_world.convexSweepTest(&shape, from, to, cb);
|
||||||
|
|
||||||
|
if (!cb.hasHit())
|
||||||
|
return end;
|
||||||
|
|
||||||
|
return glm::mix(start, end, cb.m_closestHitFraction);
|
||||||
|
}
|
||||||
|
|
||||||
game::view::EntityView* game::view::WorldView::GetEntity(net::EntNum entnum)
|
game::view::EntityView* game::view::WorldView::GetEntity(net::EntNum entnum)
|
||||||
{
|
{
|
||||||
auto it = ents_.find(entnum);
|
auto it = ents_.find(entnum);
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include "draw_args.hpp"
|
#include "draw_args.hpp"
|
||||||
#include "net/defs.hpp"
|
#include "net/defs.hpp"
|
||||||
#include "net/inmessage.hpp"
|
#include "net/inmessage.hpp"
|
||||||
|
#include "collision/dynamicsworld.hpp"
|
||||||
#include "entityview.hpp"
|
#include "entityview.hpp"
|
||||||
|
|
||||||
namespace game::view
|
namespace game::view
|
||||||
@ -12,7 +12,7 @@ namespace game::view
|
|||||||
|
|
||||||
class ClientSession;
|
class ClientSession;
|
||||||
|
|
||||||
class WorldView
|
class WorldView : public collision::DynamicsWorld
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WorldView(ClientSession& session);
|
WorldView(ClientSession& session);
|
||||||
@ -22,10 +22,11 @@ public:
|
|||||||
void Update(const UpdateInfo& info);
|
void Update(const UpdateInfo& info);
|
||||||
void Draw(const DrawArgs& args) const;
|
void Draw(const DrawArgs& args) const;
|
||||||
|
|
||||||
EntityView* GetEntity(net::EntNum entnum);
|
glm::vec3 CameraSweep(const glm::vec3& start, const glm::vec3& end);
|
||||||
|
|
||||||
float GetTime() const { return time_; }
|
|
||||||
|
|
||||||
|
EntityView* GetEntity(net::EntNum entnum);
|
||||||
|
|
||||||
|
float GetTime() const { return time_; }
|
||||||
audio::Master& GetAudioMaster() const { return audiomaster_; }
|
audio::Master& GetAudioMaster() const { return audiomaster_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -22,6 +22,12 @@ struct AABB
|
|||||||
max = glm::max(max, point);
|
max = glm::max(max, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddAABB(const AABB& other)
|
||||||
|
{
|
||||||
|
min = glm::min(min, other.min);
|
||||||
|
max = glm::max(max, other.max);
|
||||||
|
}
|
||||||
|
|
||||||
bool CollidesWith(const AABB<dim>& other) const;
|
bool CollidesWith(const AABB<dim>& other) const;
|
||||||
|
|
||||||
AABB<dim> Intersection(const AABB<dim>& other) const
|
AABB<dim> Intersection(const AABB<dim>& other) const
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user