mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
fix collision tree
This commit is contained in:
parent
d9ea79170f
commit
daba5332b9
@ -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
|
||||||
|
245
include/scene.h
245
include/scene.h
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
BIN
test/res/models/cubes.glb
Normal file
Binary file not shown.
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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
|
||||||
|
@ -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");
|
||||||
|
Loading…
Reference in New Issue
Block a user