fix collision tree

This commit is contained in:
bailehuni 2024-03-14 04:25:02 +00:00
parent d9ea79170f
commit daba5332b9
11 changed files with 403 additions and 298 deletions

View File

@ -16,94 +16,93 @@ namespace engine {
// A uniform struct that holds data of type T // A uniform struct that holds data of type T
template <typename T> template <typename T>
struct UniformDescriptor { struct UniformDescriptor {
const gfx::DescriptorSetLayout* layout; const gfx::DescriptorSetLayout* layout;
const gfx::DescriptorSet* set; const gfx::DescriptorSet* set;
struct UniformBufferData { struct UniformBufferData {
T data; T data;
} uniform_buffer_data; } uniform_buffer_data;
gfx::UniformBuffer* uniform_buffer; gfx::UniformBuffer* uniform_buffer;
};
struct Line {
glm::vec3 pos1;
glm::vec3 pos2;
}; };
class Renderer : private ApplicationComponent { class Renderer : private ApplicationComponent {
public: public:
Renderer(Application& app, gfx::GraphicsSettings settings); Renderer(Application& app, gfx::GraphicsSettings settings);
~Renderer(); ~Renderer();
void PreRender(bool window_is_resized, glm::mat4 camera_transform); void PreRender(bool window_is_resized, glm::mat4 camera_transform);
// staticList can be nullptr to render nothing // staticList can be nullptr to render nothing
void Render(const RenderList* static_list, const RenderList* dynamic_list); void Render(const RenderList* static_list, const RenderList* dynamic_list, const std::vector<Line>& debug_lines);
// getters // getters
GFXDevice* GetDevice() { return device_.get(); } GFXDevice* GetDevice() { return device_.get(); }
const gfx::DescriptorSetLayout* GetGlobalSetLayout() { const gfx::DescriptorSetLayout* GetGlobalSetLayout() { return global_uniform.layout; }
return global_uniform.layout;
}
const gfx::DescriptorSetLayout* GetFrameSetLayout() { const gfx::DescriptorSetLayout* GetFrameSetLayout() { return frame_uniform.layout; }
return frame_uniform.layout;
}
const gfx::DescriptorSetLayout* GetMaterialSetLayout() { const gfx::DescriptorSetLayout* GetMaterialSetLayout() { return material_set_layout; }
return material_set_layout;
}
std::unordered_map<gfx::SamplerInfo, const gfx::Sampler*> samplers; std::unordered_map<gfx::SamplerInfo, const gfx::Sampler*> samplers;
private: private:
std::unique_ptr<GFXDevice> device_; std::unique_ptr<GFXDevice> device_;
struct CameraSettings { struct CameraSettings {
float vertical_fov_radians = glm::radians(70.0f); float vertical_fov_radians = glm::radians(70.0f);
float clip_near = 0.5f; float clip_near = 0.5f;
float clip_far = 1000.0f; float clip_far = 1000.0f;
} camera_settings_; } camera_settings_;
// ALL vertex shaders must begin with: // ALL vertex shaders must begin with:
/* /*
layout(set = 0, binding = 0) uniform GlobalSetUniformBuffer { layout(set = 0, binding = 0) uniform GlobalSetUniformBuffer {
mat4 proj; mat4 proj;
} globalSetUniformBuffer; } globalSetUniformBuffer;
layout(set = 1, binding = 0) uniform FrameSetUniformBuffer { layout(set = 1, binding = 0) uniform FrameSetUniformBuffer {
mat4 view; mat4 view;
} frameSetUniformBuffer; } frameSetUniformBuffer;
layout( push_constant ) uniform Constants { layout( push_constant ) uniform Constants {
mat4 model; mat4 model;
} constants; } constants;
*/ */
// ALL fragment shaders must begin with: // ALL fragment shaders must begin with:
/* /*
layout(set = 2, binding = 0) uniform sampler2D materialSetAlbedoSampler; layout(set = 2, binding = 0) uniform sampler2D materialSetAlbedoSampler;
layout(set = 2, binding = 1) uniform sampler2D materialSetNormalSampler; layout(set = 2, binding = 1) uniform sampler2D materialSetNormalSampler;
layout(set = 2, binding = 2) uniform sampler2D materialSetOcclusionSampler; layout(set = 2, binding = 2) uniform sampler2D materialSetOcclusionSampler;
layout(set = 2, binding = 3) uniform sampler2D materialSetMetallicRoughnessSampler; layout(set = 2, binding = 3) uniform sampler2D materialSetMetallicRoughnessSampler;
*/ */
// in vertex shader // in vertex shader
UniformDescriptor<glm::mat4> global_uniform; // rarely updates; set 0 UniformDescriptor<glm::mat4> global_uniform; // rarely updates; set 0
UniformDescriptor<glm::mat4> frame_uniform; // updates once per frame; set 1 UniformDescriptor<glm::mat4> frame_uniform; // updates once per frame; set 1
// in fragment shader // in fragment shader
const gfx::DescriptorSetLayout* material_set_layout; // set 2; set bound per material const gfx::DescriptorSetLayout* material_set_layout; // set 2; set bound per material
float viewport_aspect_ratio_ = 1.0f; float viewport_aspect_ratio_ = 1.0f;
const gfx::Pipeline* last_bound_pipeline_ = nullptr; const gfx::Pipeline* last_bound_pipeline_ = nullptr;
struct DebugRenderingThings { struct DebugRenderingThings {
const gfx::Pipeline* pipeline = nullptr; const gfx::Pipeline* pipeline = nullptr;
// have a simple vertex buffer with 2 points that draws a line // have a simple vertex buffer with 2 points that draws a line
const gfx::Buffer* vertex_buffer = nullptr; const gfx::Buffer* vertex_buffer = nullptr;
// shader will take 2 clip space xyzw coords as push constants to define the line // shader will take 2 clip space xyzw coords as push constants to define the line
} debug_rendering_things_{}; } debug_rendering_things_{};
void DrawRenderList(gfx::DrawBuffer* draw_buffer, const RenderList& render_list); void DrawRenderList(gfx::DrawBuffer* draw_buffer, const RenderList& render_list);
}; };
} // namespace engine } // namespace engine
#endif #endif

View File

@ -12,140 +12,167 @@
#include "ecs.h" #include "ecs.h"
#include "event_system.h" #include "event_system.h"
#include "components/transform.h"
namespace engine { namespace engine {
class Application; class Application;
class Scene { class Scene {
public: public:
Scene(Application* app); Scene(Application* app);
Scene(const Scene&) = delete; Scene(const Scene&) = delete;
Scene& operator=(const Scene&) = delete; Scene& operator=(const Scene&) = delete;
~Scene(); ~Scene();
void Update(float ts); void Update(float ts);
Application* app() { return app_; } Application* app() { return app_; }
EventSystem* event_system() { return event_system_.get(); } EventSystem* event_system() { return event_system_.get(); }
/* ecs stuff */ /* ecs stuff */
Entity CreateEntity(const std::string& tag, Entity parent = 0, Entity CreateEntity(const std::string& tag, Entity parent = 0, const glm::vec3& pos = glm::vec3{0.0f, 0.0f, 0.0f},
const glm::vec3& pos = glm::vec3{0.0f, 0.0f, 0.0f}, const glm::quat& rot = glm::quat{1.0f, 0.0f, 0.0f, 0.0f}, const glm::vec3& scl = glm::vec3{1.0f, 1.0f, 1.0f});
const glm::quat& rot = glm::quat{1.0f, 0.0f, 0.0f, 0.0f},
const glm::vec3& scl = glm::vec3{1.0f, 1.0f, 1.0f});
Entity GetEntity(const std::string& tag, Entity parent = 0); Entity GetEntity(const std::string& tag, Entity parent = 0);
size_t GetComponentSignaturePosition(size_t hash); size_t GetComponentSignaturePosition(size_t hash);
template <typename T> template <typename T>
void RegisterComponent() { void RegisterComponent()
size_t hash = typeid(T).hash_code(); {
assert(component_arrays_.contains(hash) == false && size_t hash = typeid(T).hash_code();
"Registering component type more than once."); assert(component_arrays_.contains(hash) == false && "Registering component type more than once.");
component_arrays_.emplace(hash, std::make_unique<ComponentArray<T>>()); component_arrays_.emplace(hash, std::make_unique<ComponentArray<T>>());
size_t signature_position = next_signature_position_; size_t signature_position = next_signature_position_;
++next_signature_position_; ++next_signature_position_;
assert(signature_position < kMaxComponents && assert(signature_position < kMaxComponents && "Registering too many components!");
"Registering too many components!"); assert(component_signature_positions_.contains(hash) == false);
assert(component_signature_positions_.contains(hash) == false); component_signature_positions_.emplace(hash, signature_position);
component_signature_positions_.emplace(hash, signature_position);
}
template <typename T>
T* GetComponent(Entity entity) {
auto array = GetComponentArray<T>();
return array->GetData(entity);
}
template <typename T>
T* AddComponent(Entity entity, const T& comp = T{}) {
size_t hash = typeid(T).hash_code();
auto array = GetComponentArray<T>();
array->InsertData(entity, comp); // errors if entity already exists in array
// set the component bit for this entity
size_t signature_position = component_signature_positions_.at(hash);
auto& signature_ref = signatures_.at(entity);
signature_ref.set(signature_position);
for (auto& [system_hash, system] : ecs_systems_) {
if (system->entities_.contains(entity)) continue;
if ((system->signature_ & signature_ref) == system->signature_) {
system->entities_.insert(entity);
system->OnComponentInsert(entity);
}
} }
return array->GetData(entity); template <typename T>
} T* GetComponent(Entity entity)
{
// check if component exists on entity:
size_t hash = typeid(T).hash_code();
size_t signature_position = component_signature_positions_.at(hash);
const auto& entity_signature = signatures_.at(entity);
if (entity_signature.test(signature_position) == false) {
return nullptr;
}
template <typename T> auto array = GetComponentArray<T>();
void RegisterSystem() { return array->GetData(entity);
size_t hash = typeid(T).hash_code();
ecs_systems_.emplace_back(hash, std::make_unique<T>(this));
}
template <typename T>
T* GetSystem() {
size_t hash = typeid(T).hash_code();
System* found_system = nullptr;
for (auto& [system_hash, system] : ecs_systems_) {
if (hash == system_hash) found_system = system.get();
} }
if (found_system == nullptr) {
throw std::runtime_error("Unable to find system"); // because GetComponent<Transformzzzzzz takes too long
TransformComponent* GetTransform(Entity entity) {
return GetComponent<TransformComponent>(entity);
} }
T* casted_ptr = dynamic_cast<T*>(found_system);
if (casted_ptr == nullptr) { glm::vec3& GetPosition(Entity entity) {
throw std::runtime_error("Failed to cast system pointer!"); return GetTransform(entity)->position;
} }
return casted_ptr;
}
private: glm::quat& GetRotation(Entity entity) {
Application* const app_; return GetTransform(entity)->rotation;
public:
Entity next_entity_id_ = 1; // 0 is not a valid entity
private:
uint64_t framecount_ = 0;
/* ecs stuff */
size_t next_signature_position_ = 0;
// maps component hashes to signature positions
std::unordered_map<size_t, size_t> component_signature_positions_{};
// maps entity ids to their signatures
std::unordered_map<Entity, std::bitset<kMaxComponents>> signatures_{};
// maps component hashes to their arrays
std::unordered_map<size_t, std::unique_ptr<IComponentArray>>
component_arrays_{};
// hashes and associated systems
std::vector<std::pair<size_t, std::unique_ptr<System>>> ecs_systems_{};
template <typename T>
ComponentArray<T>* GetComponentArray() {
size_t hash = typeid(T).hash_code();
auto it = component_arrays_.find(hash);
if (it == component_arrays_.end()) {
throw std::runtime_error("Cannot find component array.");
} }
auto ptr = it->second.get();
auto casted_ptr = dynamic_cast<ComponentArray<T>*>(ptr);
assert(casted_ptr != nullptr);
return casted_ptr;
}
std::unique_ptr<EventSystem> event_system_{}; glm::vec3& GetScale(Entity entity) {
return GetTransform(entity)->scale;
}
template <typename T>
T* AddComponent(Entity entity, const T& comp = T{})
{
size_t hash = typeid(T).hash_code();
auto array = GetComponentArray<T>();
array->InsertData(entity, comp); // errors if entity already exists in array
// set the component bit for this entity
size_t signature_position = component_signature_positions_.at(hash);
auto& signature_ref = signatures_.at(entity);
signature_ref.set(signature_position);
for (auto& [system_hash, system] : ecs_systems_) {
if (system->entities_.contains(entity)) continue;
if ((system->signature_ & signature_ref) == system->signature_) {
system->entities_.insert(entity);
system->OnComponentInsert(entity);
}
}
return array->GetData(entity);
}
template <typename T>
void RegisterSystem()
{
size_t hash = typeid(T).hash_code();
ecs_systems_.emplace_back(hash, std::make_unique<T>(this));
}
template <typename T>
T* GetSystem()
{
size_t hash = typeid(T).hash_code();
System* found_system = nullptr;
for (auto& [system_hash, system] : ecs_systems_) {
if (hash == system_hash) found_system = system.get();
}
if (found_system == nullptr) {
throw std::runtime_error("Unable to find system");
}
T* casted_ptr = dynamic_cast<T*>(found_system);
if (casted_ptr == nullptr) {
throw std::runtime_error("Failed to cast system pointer!");
}
return casted_ptr;
}
private:
Application* const app_;
public:
Entity next_entity_id_ = 1; // 0 is not a valid entity
private:
uint64_t framecount_ = 0;
/* ecs stuff */
size_t next_signature_position_ = 0;
// maps component hashes to signature positions
std::unordered_map<size_t, size_t> component_signature_positions_{};
// maps entity ids to their signatures
std::unordered_map<Entity, std::bitset<kMaxComponents>> signatures_{};
// maps component hashes to their arrays
std::unordered_map<size_t, std::unique_ptr<IComponentArray>> component_arrays_{};
// hashes and associated systems
std::vector<std::pair<size_t, std::unique_ptr<System>>> ecs_systems_{};
template <typename T>
ComponentArray<T>* GetComponentArray()
{
size_t hash = typeid(T).hash_code();
auto it = component_arrays_.find(hash);
if (it == component_arrays_.end()) {
throw std::runtime_error("Cannot find component array.");
}
auto ptr = it->second.get();
auto casted_ptr = dynamic_cast<ComponentArray<T>*>(ptr);
assert(casted_ptr != nullptr);
return casted_ptr;
}
std::unique_ptr<EventSystem> event_system_{};
}; };
} // namespace engine } // namespace engine
#endif #endif

View File

@ -33,7 +33,7 @@ class CollisionSystem : public System {
Raycast GetRaycast(Ray ray); Raycast GetRaycast(Ray ray);
private: public:
// one node of the BVH // one node of the BVH
struct BiTreeNode { struct BiTreeNode {
enum class Type : uint8_t { BoundingVolume, Entity, Empty }; enum class Type : uint8_t { BoundingVolume, Entity, Empty };
@ -53,11 +53,12 @@ class CollisionSystem : public System {
PrimitiveInfo(const AABB& aabb, Entity entity_idx); PrimitiveInfo(const AABB& aabb, Entity entity_idx);
}; };
std::vector<BiTreeNode> bvh_{};
private:
size_t colliders_size_last_update_ = 0; size_t colliders_size_last_update_ = 0;
size_t colliders_size_now_ = 0; size_t colliders_size_now_ = 0;
std::vector<BiTreeNode> bvh_{};
bool RaycastTreeNode(const Ray& ray, const BiTreeNode& node, glm::vec3& location, float& t, Entity& object_index); bool RaycastTreeNode(const Ray& ray, const BiTreeNode& node, glm::vec3& location, float& t, Entity& object_index);
static int BuildNode(std::vector<PrimitiveInfo>& prims, std::vector<BiTreeNode>& tree_nodes); static int BuildNode(std::vector<PrimitiveInfo>& prims, std::vector<BiTreeNode>& tree_nodes);

View File

@ -33,7 +33,7 @@ void main() {
const float roughness = metallic_roughness.b; const float roughness = metallic_roughness.b;
const float roughness_2 = roughness * roughness; const float roughness_2 = roughness * roughness;
const vec3 light_colour = vec3(1.0, 1.0, 1.0) * 2.4; const vec3 light_colour = vec3(1.0, 1.0, 1.0) * 5.0;
const vec3 emission = vec3(0.0, 0.0, 0.0); const vec3 emission = vec3(0.0, 0.0, 0.0);
const float ao = texture(materialSetOcclusionSampler, fragUV).r; const float ao = texture(materialSetOcclusionSampler, fragUV).r;
@ -42,8 +42,8 @@ void main() {
const vec3 N = GetNormal(); const vec3 N = GetNormal();
const vec3 V = normalize(fragViewPosTangentSpace - fragPosTangentSpace); const vec3 V = normalize(fragViewPosTangentSpace - fragPosTangentSpace);
//const vec3 L = normalize(fragLightPosTangentSpace - fragPosTangentSpace); const vec3 L = normalize(fragLightPosTangentSpace - fragPosTangentSpace);
const vec3 L = normalize(vec3(5.0, 0.0, 3.0)); //const vec3 L = normalize(vec3(5.0, 0.0, 3.0));
const vec3 H = normalize(V + L); const vec3 H = normalize(V + L);
//const vec3 dielectric_brdf = FresnelMix(); //const vec3 dielectric_brdf = FresnelMix();

View File

@ -25,6 +25,7 @@
#include "resources/texture.h" #include "resources/texture.h"
#include "systems/mesh_render_system.h" #include "systems/mesh_render_system.h"
#include "components/transform.h" #include "components/transform.h"
#include "components/collider.h"
#include "scene.h" #include "scene.h"
#include "scene_manager.h" #include "scene_manager.h"
#include "window.h" #include "window.h"
@ -34,6 +35,7 @@
#include <direct.h> #include <direct.h>
#define WIN_MAX_PATH 260 #define WIN_MAX_PATH 260
#endif #endif
#include <systems/collisions.h>
static struct ImGuiThings { static struct ImGuiThings {
ImGuiContext* context; ImGuiContext* context;
@ -114,8 +116,8 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
shaderSettings.cull_backface = true; shaderSettings.cull_backface = true;
shaderSettings.write_z = true; shaderSettings.write_z = true;
shaderSettings.render_order = 0; shaderSettings.render_order = 0;
auto fancyShader = std::make_unique<Shader>(renderer(), GetResourcePath("engine/shaders/fancy.vert"), auto fancyShader =
GetResourcePath("engine/shaders/fancy.frag"), shaderSettings); std::make_unique<Shader>(renderer(), GetResourcePath("engine/shaders/fancy.vert"), GetResourcePath("engine/shaders/fancy.frag"), shaderSettings);
GetResourceManager<Shader>()->AddPersistent("builtin.fancy", std::move(fancyShader)); GetResourceManager<Shader>()->AddPersistent("builtin.fancy", std::move(fancyShader));
} }
{ {
@ -129,14 +131,14 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
shaderSettings.cull_backface = true; shaderSettings.cull_backface = true;
shaderSettings.write_z = false; shaderSettings.write_z = false;
shaderSettings.render_order = 1; shaderSettings.render_order = 1;
auto skyboxShader = std::make_unique<Shader>(renderer(), GetResourcePath("engine/shaders/skybox.vert"), auto skyboxShader =
GetResourcePath("engine/shaders/skybox.frag"), shaderSettings); std::make_unique<Shader>(renderer(), GetResourcePath("engine/shaders/skybox.vert"), GetResourcePath("engine/shaders/skybox.frag"), shaderSettings);
GetResourceManager<Shader>()->AddPersistent("builtin.skybox", std::move(skyboxShader)); GetResourceManager<Shader>()->AddPersistent("builtin.skybox", std::move(skyboxShader));
} }
/* default textures */ /* default textures */
{ {
const uint8_t pixel[4] = { 255, 255, 255, 255 }; const uint8_t pixel[4] = {255, 255, 255, 255};
gfx::SamplerInfo samplerInfo{}; gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest; samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest; samplerInfo.magnify = gfx::Filter::kNearest;
@ -146,7 +148,7 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
GetResourceManager<Texture>()->AddPersistent("builtin.white", std::move(whiteTexture)); GetResourceManager<Texture>()->AddPersistent("builtin.white", std::move(whiteTexture));
} }
{ {
const uint8_t pixel[4] = { 0, 0, 0, 255 }; const uint8_t pixel[4] = {0, 0, 0, 255};
gfx::SamplerInfo samplerInfo{}; gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest; samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest; samplerInfo.magnify = gfx::Filter::kNearest;
@ -156,7 +158,7 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
GetResourceManager<Texture>()->AddPersistent("builtin.black", std::move(blackTexture)); GetResourceManager<Texture>()->AddPersistent("builtin.black", std::move(blackTexture));
} }
{ {
const uint8_t pixel[4] = { 127, 127, 255, 255 }; const uint8_t pixel[4] = {127, 127, 255, 255};
gfx::SamplerInfo samplerInfo{}; gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest; samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest; samplerInfo.magnify = gfx::Filter::kNearest;
@ -166,7 +168,7 @@ Application::Application(const char* appName, const char* appVersion, gfx::Graph
GetResourceManager<Texture>()->AddPersistent("builtin.normal", std::move(normalTexture)); GetResourceManager<Texture>()->AddPersistent("builtin.normal", std::move(normalTexture));
} }
{ {
const uint8_t pixel[4] = { 255, 0, 127, 255 }; const uint8_t pixel[4] = {255, 0, 127, 255};
gfx::SamplerInfo samplerInfo{}; gfx::SamplerInfo samplerInfo{};
samplerInfo.minify = gfx::Filter::kNearest; samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.magnify = gfx::Filter::kNearest; samplerInfo.magnify = gfx::Filter::kNearest;
@ -268,7 +270,7 @@ void Application::GameLoop()
int depth = find_depth(i, 0); int depth = find_depth(i, 0);
for (int j = 0; j < depth; ++j) tabs += std::string{" "}; for (int j = 0; j < depth; ++j) tabs += std::string{" "};
ImGui::Text("%s%s", tabs.c_str(), t->tag.c_str()); ImGui::Text("%s%s", tabs.c_str(), t->tag.c_str());
//ImGui::Text("%.1f %.1f %.1f", t->position.x, t->position.y, t->position.z); // ImGui::Text("%.1f %.1f %.1f", t->position.x, t->position.y, t->position.z);
} }
} }
else { else {
@ -283,6 +285,7 @@ void Application::GameLoop()
const RenderList* static_list = nullptr; const RenderList* static_list = nullptr;
const RenderList* dynamic_list = nullptr; const RenderList* dynamic_list = nullptr;
glm::mat4 camera_transform{1.0f}; glm::mat4 camera_transform{1.0f};
std::vector<Line> debug_lines{};
if (scene) { if (scene) {
camera_transform = scene->GetComponent<TransformComponent>(scene->GetEntity("camera"))->world_matrix; camera_transform = scene->GetComponent<TransformComponent>(scene->GetEntity("camera"))->world_matrix;
auto mesh_render_system = scene->GetSystem<MeshRenderSystem>(); auto mesh_render_system = scene->GetSystem<MeshRenderSystem>();
@ -290,7 +293,7 @@ void Application::GameLoop()
dynamic_list = mesh_render_system->GetDynamicRenderList(); dynamic_list = mesh_render_system->GetDynamicRenderList();
} }
renderer_->PreRender(window()->GetWindowResized(), camera_transform); renderer_->PreRender(window()->GetWindowResized(), camera_transform);
renderer_->Render(static_list, dynamic_list); renderer_->Render(static_list, dynamic_list, debug_lines);
/* poll events */ /* poll events */
window_->GetInputAndEvents(); window_->GetInputAndEvents();

View File

@ -61,8 +61,8 @@ Renderer::Renderer(Application& app, gfx::GraphicsSettings settings) : Applicati
debug_pipeline_info.vertex_format = debug_vertex_format; debug_pipeline_info.vertex_format = debug_vertex_format;
debug_pipeline_info.alpha_blending = false; debug_pipeline_info.alpha_blending = false;
debug_pipeline_info.backface_culling = false; // probably ignored for line rendering debug_pipeline_info.backface_culling = false; // probably ignored for line rendering
debug_pipeline_info.write_z = false; // lines don't need the depth buffer debug_pipeline_info.write_z = false; // lines don't need the depth buffer
//debug_pipeline_info.descriptor_set_layouts = empty; // debug_pipeline_info.descriptor_set_layouts = empty;
debug_pipeline_info.line_primitives = true; debug_pipeline_info.line_primitives = true;
debug_rendering_things_.pipeline = device_->CreatePipeline(debug_pipeline_info); debug_rendering_things_.pipeline = device_->CreatePipeline(debug_pipeline_info);
@ -104,7 +104,7 @@ void Renderer::PreRender(bool window_is_resized, glm::mat4 camera_transform)
device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data); device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
} }
void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_list) void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_list, const std::vector<Line>& debug_lines)
{ {
last_bound_pipeline_ = nullptr; last_bound_pipeline_ = nullptr;
@ -124,8 +124,20 @@ void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_l
// draw debug shit here // draw debug shit here
device_->CmdBindPipeline(draw_buffer, debug_rendering_things_.pipeline); device_->CmdBindPipeline(draw_buffer, debug_rendering_things_.pipeline);
glm::vec4 debug_positions[2] = {}; glm::vec4 debug_positions[2] = {};
debug_positions[0] = global_uniform.uniform_buffer_data.data * frame_uniform.uniform_buffer_data.data * glm::vec4{ 0.0f, 0.0f, 0.0f, 1.0f }; for (const Line& l : debug_lines) {
debug_positions[1] = global_uniform.uniform_buffer_data.data * frame_uniform.uniform_buffer_data.data * glm::vec4{ 0.0f, 0.0f, 1.0f, 1.0f }; debug_positions[0] = global_uniform.uniform_buffer_data.data * frame_uniform.uniform_buffer_data.data * glm::vec4(l.pos1, 1.0f);
debug_positions[1] = global_uniform.uniform_buffer_data.data * frame_uniform.uniform_buffer_data.data * glm::vec4(l.pos2, 1.0f);
device_->CmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(glm::vec4) * 2, debug_positions);
device_->CmdDraw(draw_buffer, 2, 1, 0, 0);
}
// also make a lil crosshair
debug_positions[0] = glm::vec4(-0.05f, 0.0f, 0.0f, 1.0f);
debug_positions[1] = glm::vec4(0.05f, 0.0f, 0.0f, 1.0f);
device_->CmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(glm::vec4) * 2, debug_positions);
device_->CmdDraw(draw_buffer, 2, 1, 0, 0);
debug_positions[0] = glm::vec4(0.0f, -0.05f, 0.0f, 1.0f);
debug_positions[1] = glm::vec4(0.0f, 0.05f, 0.0f, 1.0f);
device_->CmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(glm::vec4) * 2, debug_positions); device_->CmdPushConstants(draw_buffer, debug_rendering_things_.pipeline, 0, sizeof(glm::vec4) * 2, debug_positions);
device_->CmdDraw(draw_buffer, 2, 1, 0, 0); device_->CmdDraw(draw_buffer, 2, 1, 0, 0);

View File

@ -78,13 +78,37 @@ void CollisionSystem::OnUpdate(float ts)
transformed_box.max = t->world_matrix * glm::vec4(c->aabb.max, 1.0f); transformed_box.max = t->world_matrix * glm::vec4(c->aabb.max, 1.0f);
// if a mesh is not rotated a multiple of 90 degrees, the box will not fit the mesh // if a mesh is not rotated a multiple of 90 degrees, the box will not fit the mesh
// TODO fix it // TODO fix it
prims.emplace_back(c->aabb, entity);
// correct min and max
AABB box{};
box.min.x = fminf(transformed_box.min.x, transformed_box.max.x);
box.min.y = fminf(transformed_box.min.y, transformed_box.max.y);
box.min.z = fminf(transformed_box.min.z, transformed_box.max.z);
box.max.x = fmaxf(transformed_box.min.x, transformed_box.max.x);
box.max.y = fmaxf(transformed_box.min.y, transformed_box.max.y);
box.max.z = fmaxf(transformed_box.min.z, transformed_box.max.z);
prims.emplace_back(box, entity);
} }
bvh_.clear(); bvh_.clear();
bvh_.reserve(entities_.size() * 3 / 2); // from testing, bvh is usually 20% larger than number of objects bvh_.reserve(entities_.size() * 3 / 2); // from testing, bvh is usually 20% larger than number of objects
BuildNode(prims, bvh_); BuildNode(prims, bvh_);
// check AABB mins and maxes are the correct order
for (const auto& node : bvh_) {
if (node.type1 != BiTreeNode::Type::Empty) {
if (node.box1.max.x < node.box1.min.x) abort();
if (node.box1.max.y < node.box1.min.y) abort();
if (node.box1.max.z < node.box1.min.z) abort();
}
if (node.type2 != BiTreeNode::Type::Empty) {
if (node.box2.max.x < node.box2.min.x) abort();
if (node.box2.max.y < node.box2.min.y) abort();
if (node.box2.max.z < node.box2.min.z) abort();
}
}
LOG_INFO("BUILT BVH!"); LOG_INFO("BUILT BVH!");
colliders_size_last_update_ = colliders_size_now_; colliders_size_last_update_ = colliders_size_now_;
@ -94,10 +118,13 @@ void CollisionSystem::OnUpdate(float ts)
Raycast CollisionSystem::GetRaycast(Ray ray) Raycast CollisionSystem::GetRaycast(Ray ray)
{ {
Raycast res{}; Raycast res{};
res.hit = false;
ray.direction = glm::normalize(ray.direction); ray.direction = glm::normalize(ray.direction);
res.hit = RaycastTreeNode(ray, bvh_.back(), res.location, res.distance, res.hit_entity); if (!bvh_.empty()) {
res.hit = RaycastTreeNode(ray, bvh_.back(), res.location, res.distance, res.hit_entity);
}
return res; return res;
} }
@ -109,20 +136,41 @@ CollisionSystem::PrimitiveInfo::PrimitiveInfo(const AABB& aabb, Entity entity_id
int CollisionSystem::BuildNode(std::vector<PrimitiveInfo>& prims, std::vector<BiTreeNode>& tree_nodes) int CollisionSystem::BuildNode(std::vector<PrimitiveInfo>& prims, std::vector<BiTreeNode>& tree_nodes)
{ {
if (prims.size() == 0) throw std::runtime_error("Cannot build BVH with no primitives!"); if (prims.size() == 0) abort();
std::array<std::function<bool(const PrimitiveInfo&, const PrimitiveInfo&)>, 3> centroid_tests{ std::array<std::function<bool(const PrimitiveInfo&, const PrimitiveInfo&)>, 3> centroid_tests{
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool { return (p1.centroid.x < p2.centroid.x); }, [](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool {
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool { return (p1.centroid.y < p2.centroid.y); }, return (p1.centroid.x < p2.centroid.x);
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool { return (p1.centroid.z < p2.centroid.z); }}; },
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool {
return (p1.centroid.y < p2.centroid.y);
},
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool {
return (p1.centroid.z < p2.centroid.z);
}
};
std::array<std::function<bool(const PrimitiveInfo&, const PrimitiveInfo&)>, 3> box_min_tests{ std::array<std::function<bool(const PrimitiveInfo&, const PrimitiveInfo&)>, 3> box_min_tests{
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool { return (p1.box.min.x < p2.box.min.x); }, [](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool {
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool { return (p1.box.min.y < p2.box.min.y); }, return (p1.box.min.x < p2.box.min.x);
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool { return (p1.box.min.z < p2.box.min.z); }}; },
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool {
return (p1.box.min.y < p2.box.min.y);
},
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool {
return (p1.box.min.z < p2.box.min.z);
}
};
std::array<std::function<bool(const PrimitiveInfo&, const PrimitiveInfo&)>, 3> box_max_tests{ std::array<std::function<bool(const PrimitiveInfo&, const PrimitiveInfo&)>, 3> box_max_tests{
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool { return (p1.box.max.x < p2.box.max.x); }, [](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool {
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool { return (p1.box.max.y < p2.box.max.y); }, return (p1.box.max.x < p2.box.max.x);
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool { return (p1.box.max.z < p2.box.max.z); }}; },
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool {
return (p1.box.max.y < p2.box.max.y);
},
[](const PrimitiveInfo& p1, const PrimitiveInfo& p2) -> bool {
return (p1.box.max.z < p2.box.max.z);
}
};
BiTreeNode node{}; BiTreeNode node{};
@ -132,7 +180,7 @@ int CollisionSystem::BuildNode(std::vector<PrimitiveInfo>& prims, std::vector<Bi
sorted_prims.reserve(prims.size()); sorted_prims.reserve(prims.size());
int sorted_prims_split_index = 0; int sorted_prims_split_index = 0;
float sah = std::numeric_limits<float>().infinity(); // surface area heuristic float sah = std::numeric_limits<float>().infinity(); // surface area heuristic
// try along each axis // try along each axis
for (int axis = 0; axis < 3; axis++) { for (int axis = 0; axis < 3; axis++) {
@ -142,91 +190,79 @@ int CollisionSystem::BuildNode(std::vector<PrimitiveInfo>& prims, std::vector<Bi
std::sort(prims.begin(), prims.end(), centroid_tests[axis]); std::sort(prims.begin(), prims.end(), centroid_tests[axis]);
// std::cout << "Sorting on axis " << axis << "...\n"; //std::cout << "Sorting on axis " << axis << "...\n";
for (const auto& p : prims) { for (const auto& p : prims) {
// std::cout << p.centroid.x << "\t" << p.centroid.y << "\t" << p.centroid.z << "\n"; //std::cout << p.centroid.x << "\t" << p.centroid.y << "\t" << p.centroid.z << "\n";
} }
// std::cout << "\n\n\n"; //std::cout << "\n\n\n";
// break; //break;
// split the boxes // split the boxes
for (int i = 0; i < prims.size() - 1; i++) { for (int i = 0; i < prims.size() - 1; i++) {
float box1_main_min = float box1_main_min = reinterpret_cast<const float*>(&(std::min_element(prims.begin(), prims.begin() + i + 1, box_min_tests[axis])->box.min))[axis];
reinterpret_cast<const float*>(&(std::min_element(prims.begin(), prims.begin() + i + 1, box_min_tests[axis])->box.min))[axis]; float box1_main_max = reinterpret_cast<const float*>(&(std::max_element(prims.begin(), prims.begin() + i + 1, box_max_tests[axis])->box.max))[axis];
float box1_main_max = float box2_main_min = reinterpret_cast<const float*>(&(std::min_element(prims.begin() + i + 1, prims.end(), box_min_tests[axis])->box.min))[axis];
reinterpret_cast<const float*>(&(std::max_element(prims.begin(), prims.begin() + i + 1, box_max_tests[axis])->box.max))[axis]; float box2_main_max = reinterpret_cast<const float*>(&(std::max_element(prims.begin() + i + 1, prims.end(), box_max_tests[axis])->box.max))[axis];
float box2_main_min =
reinterpret_cast<const float*>(&(std::min_element(prims.begin() + i + 1, prims.end(), box_min_tests[axis])->box.min))[axis];
float box2_main_max =
reinterpret_cast<const float*>(&(std::max_element(prims.begin() + i + 1, prims.end(), box_max_tests[axis])->box.max))[axis];
float box1_min1 = float box1_min1 = reinterpret_cast<const float*>(&(std::min_element(prims.begin(), prims.begin() + i + 1, box_min_tests[other_axis1])->box.min))[other_axis1];
reinterpret_cast<const float*>(&(std::min_element(prims.begin(), prims.begin() + i + 1, box_min_tests[other_axis1])->box.min))[other_axis1]; float box1_max1 = reinterpret_cast<const float*>(&(std::max_element(prims.begin(), prims.begin() + i + 1, box_max_tests[other_axis1])->box.max))[other_axis1];
float box1_max1 = float box1_min2 = reinterpret_cast<const float*>(&(std::min_element(prims.begin(), prims.begin() + i + 1, box_min_tests[other_axis2])->box.min))[other_axis2];
reinterpret_cast<const float*>(&(std::max_element(prims.begin(), prims.begin() + i + 1, box_max_tests[other_axis1])->box.max))[other_axis1]; float box1_max2 = reinterpret_cast<const float*>(&(std::max_element(prims.begin(), prims.begin() + i + 1, box_max_tests[other_axis2])->box.max))[other_axis2];
float box1_min2 =
reinterpret_cast<const float*>(&(std::min_element(prims.begin(), prims.begin() + i + 1, box_min_tests[other_axis2])->box.min))[other_axis2];
float box1_max2 =
reinterpret_cast<const float*>(&(std::max_element(prims.begin(), prims.begin() + i + 1, box_max_tests[other_axis2])->box.max))[other_axis2];
float box2_min1 = float box2_min1 = reinterpret_cast<const float*>(&(std::min_element(prims.begin() + i + 1, prims.end(), box_min_tests[other_axis1])->box.min))[other_axis1];
reinterpret_cast<const float*>(&(std::min_element(prims.begin() + i + 1, prims.end(), box_min_tests[other_axis1])->box.min))[other_axis1]; float box2_max1 = reinterpret_cast<const float*>(&(std::max_element(prims.begin() + i + 1, prims.end(), box_max_tests[other_axis1])->box.max))[other_axis1];
float box2_max1 = float box2_min2 = reinterpret_cast<const float*>(&(std::min_element(prims.begin() + i + 1, prims.end(), box_min_tests[other_axis2])->box.min))[other_axis2];
reinterpret_cast<const float*>(&(std::max_element(prims.begin() + i + 1, prims.end(), box_max_tests[other_axis1])->box.max))[other_axis1]; float box2_max2 = reinterpret_cast<const float*>(&(std::max_element(prims.begin() + i + 1, prims.end(), box_max_tests[other_axis2])->box.max))[other_axis2];
float box2_min2 =
reinterpret_cast<const float*>(&(std::min_element(prims.begin() + i + 1, prims.end(), box_min_tests[other_axis2])->box.min))[other_axis2];
float box2_max2 =
reinterpret_cast<const float*>(&(std::max_element(prims.begin() + i + 1, prims.end(), box_max_tests[other_axis2])->box.max))[other_axis2];
AABB box1{}, box2{}; AABB box1{}, box2{};
switch (axis) { switch (axis) {
case 0: case 0:
// x // x
box1.min.x = box1_main_min; box1.min.x = box1_main_min;
box1.min.y = box1_min1; box1.min.y = box1_min1;
box1.min.z = box1_min2; box1.min.z = box1_min2;
box1.max.x = box1_main_max; box1.max.x = box1_main_max;
box1.max.y = box1_max1; box1.max.y = box1_max1;
box1.max.z = box1_max2; box1.max.z = box1_max2;
box2.min.x = box2_main_min; box2.min.x = box2_main_min;
box2.min.y = box2_min1; box2.min.y = box2_min1;
box2.min.z = box2_min2; box2.min.z = box2_min2;
box2.max.x = box2_main_max; box2.max.x = box2_main_max;
box2.max.y = box2_max1; box2.max.y = box2_max1;
box2.max.z = box2_max2; box2.max.z = box2_max2;
break; break;
case 1: case 1:
// y // y
box1.min.x = box1_min2; box1.min.x = box1_min2;
box1.min.y = box1_main_min; box1.min.y = box1_main_min;
box1.min.z = box1_min1; box1.min.z = box1_min1;
box1.max.x = box1_max2; box1.max.x = box1_max2;
box1.max.y = box1_main_max; box1.max.y = box1_main_max;
box1.max.z = box1_max1; box1.max.z = box1_max1;
box2.min.x = box2_min2; box2.min.x = box2_min2;
box2.min.y = box2_main_min; box2.min.y = box2_main_min;
box2.min.z = box2_min1; box2.min.z = box2_min1;
box2.max.x = box2_max2; box2.max.x = box2_max2;
box2.max.y = box2_main_max; box2.max.y = box2_main_max;
box2.max.z = box2_max1; box2.max.z = box2_max1;
break; break;
case 2: case 2:
// z // z
box1.min.x = box1_min1; box1.min.x = box1_min1;
box1.min.y = box1_min2; box1.min.y = box1_min2;
box1.min.z = box1_main_min; box1.min.z = box1_main_min;
box1.max.x = box1_max1; box1.max.x = box1_max1;
box1.max.y = box1_max2; box1.max.y = box1_max2;
box1.max.z = box1_main_max; box1.max.z = box1_main_max;
box2.min.x = box2_min1; box2.min.x = box2_min1;
box2.min.y = box2_min2; box2.min.y = box2_min2;
box2.min.z = box2_main_min; box2.min.z = box2_main_min;
box2.max.x = box2_max1; box2.max.x = box2_max1;
box2.max.y = box2_max2; box2.max.y = box2_max2;
box2.max.z = box2_main_max; box2.max.z = box2_main_max;
break; break;
} }
const float combined_surface_area = (GetBoxArea(box1) * (i + 1)) + (GetBoxArea(box2) * (prims.size() - (i + 1))); const float combined_surface_area = (GetBoxArea(box1) * (i + 1)) + (GetBoxArea(box2) * (prims.size() - (i + 1)));
if (combined_surface_area < sah) { if (combined_surface_area < sah) {
@ -235,7 +271,7 @@ int CollisionSystem::BuildNode(std::vector<PrimitiveInfo>& prims, std::vector<Bi
optimal_box2 = box2; optimal_box2 = box2;
sorted_prims = prims; // VECTOR COPY! sorted_prims = prims; // VECTOR COPY!
sorted_prims_split_index = i; sorted_prims_split_index = i;
std::cout << "picking new boxes, axis: " << axis << " i: " << i << " sah: " << combined_surface_area << "\n"; //std::cout << "picking new boxes, axis: " << axis << " i: " << i << " sah: " << combined_surface_area << "\n";
} }
} }
} }
@ -254,6 +290,7 @@ int CollisionSystem::BuildNode(std::vector<PrimitiveInfo>& prims, std::vector<Bi
node.index2 = index2; node.index2 = index2;
node.type1 = BiTreeNode::Type::BoundingVolume; node.type1 = BiTreeNode::Type::BoundingVolume;
node.type2 = BiTreeNode::Type::BoundingVolume; node.type2 = BiTreeNode::Type::BoundingVolume;
} }
else { else {
if (prims.size() == 2) { if (prims.size() == 2) {

BIN
test/res/models/cubes.glb Normal file

Binary file not shown.

View File

@ -39,7 +39,7 @@ void CameraControllerSystem::OnUpdate(float ts)
if (scene_->app()->input_manager()->GetButton("sprint")) speed *= 10.0f; if (scene_->app()->input_manager()->GetButton("sprint")) speed *= 10.0f;
float dx = scene_->app()->input_manager()->GetAxis("movex"); float dx = scene_->app()->input_manager()->GetAxis("movex");
float dy = (-scene_->app()->input_manager()->GetAxis("movey")); float dy = scene_->app()->input_manager()->GetAxis("movey");
// calculate new pitch and yaw // calculate new pitch and yaw
@ -55,15 +55,35 @@ void CameraControllerSystem::OnUpdate(float ts)
// update position relative to camera direction in xz plane // update position relative to camera direction in xz plane
const glm::vec3 d2x_rotated = glm::rotateZ(glm::vec3{dx, 0.0f, 0.0f}, c->yaw); const glm::vec3 d2x_rotated = glm::rotateZ(glm::vec3{dx, 0.0f, 0.0f}, c->yaw);
const glm::vec3 d2y_rotated = glm::rotateZ(glm::rotateX(glm::vec3{0.0f, 0.0f, dy}, c->pitch), c->yaw); const glm::vec3 d2y_rotated = glm::rotateZ(glm::vec3{0.0f, dy, 0.0f}, c->yaw);
glm::vec3 h_vel = (d2x_rotated + d2y_rotated); glm::vec3 h_vel = (d2x_rotated + d2y_rotated);
h_vel *= speed; h_vel *= speed;
t->position += h_vel * dt; t->position += h_vel * dt;
// gravity stuff here:
constexpr float g = -9.81f; // constant velocity gravity???
constexpr float player_height = 71.0f * 25.4f / 1000.0f;
c->vel.z += g * dt;
// check for collision during next frame and push back and remove velocity in the normal of the collision direction if so
engine::Ray ray{};
ray.origin = t->position;
ray.origin.z -= player_height; // check for collision from the player's feet
ray.direction = c->
const engine::Raycast fall_raycast = scene_->GetSystem<engine::CollisionSystem>()->GetRaycast(fall_ray);
if (fall_raycast.hit && fall_raycast.distance < player_height + (-c->fall_vel * dt)) {
t->position.z += -(fall_raycast.distance - player_height);
c->fall_vel = 0.0f;
}
else {
t->position.z += c->fall_vel * dt;
}
constexpr float kMaxDistanceFromOrigin = 10000.0f; constexpr float kMaxDistanceFromOrigin = 10000.0f;
if (glm::length(t->position) > kMaxDistanceFromOrigin) { if (glm::length(t->position) > kMaxDistanceFromOrigin) {
t->position = {0.0f, 5.0f, 0.0f}; t->position = {0.0f, 0.0f, 10.0f};
} }
/* ROTATION STUFF */ /* ROTATION STUFF */
@ -90,13 +110,14 @@ void CameraControllerSystem::OnUpdate(float ts)
/* user interface inputs */ /* user interface inputs */
if (scene_->app()->window()->GetKeyPress(engine::inputs::Key::K_P)) { if (scene_->app()->window()->GetKeyPress(engine::inputs::Key::K_P)) {
std::string pos_string{"x: " + std::to_string(t->world_matrix[3][0]) + " y: " + std::to_string(t->world_matrix[3][1]) + " z: " + std::to_string(t->world_matrix[3][2])}; std::string pos_string{"x: " + std::to_string(t->world_matrix[3][0]) + " y: " + std::to_string(t->world_matrix[3][1]) +
" z: " + std::to_string(t->world_matrix[3][2])};
LOG_INFO("position {}", pos_string); LOG_INFO("position {}", pos_string);
LOG_INFO("rotation w: {} x: {} y: {} z: {}", t->rotation.w, t->rotation.x, t->rotation.y, t->rotation.z); LOG_INFO("rotation w: {} x: {} y: {} z: {}", t->rotation.w, t->rotation.x, t->rotation.y, t->rotation.z);
} }
if (scene_->app()->window()->GetKeyPress(engine::inputs::Key::K_R)) { if (scene_->app()->window()->GetKeyPress(engine::inputs::Key::K_R)) {
t->position = {0.0f, 5.0f, 0.0f}; t->position = {0.0f, 0.0f, 10.0f};
} }
if (scene_->app()->input_manager()->GetButtonPress("fullscreen")) { if (scene_->app()->input_manager()->GetButtonPress("fullscreen")) {
@ -113,11 +134,12 @@ void CameraControllerSystem::OnUpdate(float ts)
if (scene_->app()->window()->GetButtonPress(engine::inputs::MouseButton::M_LEFT)) { if (scene_->app()->window()->GetButtonPress(engine::inputs::MouseButton::M_LEFT)) {
engine::Ray ray{}; engine::Ray ray{};
ray.origin.x = t->world_matrix[3][0]; ray.origin = t->position;
ray.origin.y = t->world_matrix[3][1]; ray.direction = glm::vec3(glm::mat4_cast(t->rotation) * glm::vec4{0.0f, 0.0f, -1.0f, 1.0f});
ray.origin.z = t->world_matrix[3][2];
ray.direction = glm::vec3{ 0.0f, 0.0f, -1.0f };
engine::Raycast cast = scene_->GetSystem<engine::CollisionSystem>()->GetRaycast(ray); engine::Raycast cast = scene_->GetSystem<engine::CollisionSystem>()->GetRaycast(ray);
LOG_INFO("Raycast success? {}", cast.hit ? "YES" : "NO"); if (cast.hit) {
LOG_INFO("Raycast hit {}", scene_->GetComponent<engine::TransformComponent>(cast.hit_entity)->tag);
LOG_INFO("Distance: {} m", cast.distance);
}
} }
} }

View File

@ -11,6 +11,7 @@ struct CameraControllerComponent {
static constexpr float kCameraSensitivity = 0.007f; static constexpr float kCameraSensitivity = 0.007f;
float yaw = 0.0f; float yaw = 0.0f;
float pitch = glm::half_pi<float>(); float pitch = glm::half_pi<float>();
glm::vec3 vel{ 0.0f, 0.0f, 0.0f };
}; };
class CameraControllerSystem class CameraControllerSystem

View File

@ -103,16 +103,19 @@ void PlayGame(GameSettings settings)
floor_renderable->material->SetMetallicRoughnessTexture(floor_mr); floor_renderable->material->SetMetallicRoughnessTexture(floor_mr);
floor_renderable->material->SetOcclusionTexture(app.GetResource<engine::Texture>("builtin.white")); floor_renderable->material->SetOcclusionTexture(app.GetResource<engine::Texture>("builtin.white"));
floor_renderable->visible = true ; floor_renderable->visible = true ;
auto floor_col = main_scene->AddComponent<engine::ColliderComponent>(floor);
floor_col->aabb.min = glm::vec3{0.0f, 0.0f, 0.0f};
floor_col->aabb.max = glm::vec3{100.0f, 100.0f, 0.1f };
engine::Entity redcube = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/redcube.glb"));
engine::Entity normal_map_test = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/normalmaptest.glb"));
main_scene->GetComponent<engine::TransformComponent>(normal_map_test)->position += glm::vec3{-10.0f, 0.0f, 1.0f};
engine::Entity monke = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/monke.glb")); engine::Entity monke = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/monke.glb"));
main_scene->GetComponent<engine::TransformComponent>(monke)->position.y += 10.0f;
engine::Entity bottle = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/bottle.glb")); //engine::Entity bottle = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/bottle.glb"));
main_scene->GetComponent<engine::TransformComponent>(bottle)->scale *= 50.0f; //main_scene->GetComponent<engine::TransformComponent>(bottle)->scale *= 10.0f;
main_scene->GetComponent<engine::TransformComponent>(bottle)->position.z += 50.0f;; //main_scene->GetComponent<engine::TransformComponent>(bottle)->position.x += 25.0f;
//main_scene->GetComponent<engine::TransformComponent>(bottle)->position.z += 5.0f;
/* skybox */ /* skybox */
engine::Entity skybox = main_scene->CreateEntity("skybox"); engine::Entity skybox = main_scene->CreateEntity("skybox");