Commit 64e2e385 authored by Johannes Braun's avatar Johannes Braun
Browse files

Progress on LS

parent 1befa28c
......@@ -97,20 +97,6 @@ struct BVHNode
uint parent;
};
struct Mesh
{
Vertex* vertices;
Triangle* triangles;
BVHNode* nodes;
uint material;
uint p;
mat4 transformation;
mat4 inverse_transformation;
mat4 normal_matrix;
};
struct Ray
{
vec3 direction;
......@@ -126,6 +112,39 @@ struct Hit
uint mesh;
};
struct Line
{
Hit nearest;
Hit farthest;
};
struct LineSpace
{
Bounds bounds;
uvec3 resolution;
float patch_size;
};
struct Mesh
{
Vertex* vertices;
Triangle* triangles;
BVHNode* nodes;
Line* lines;
uint material;
uint p[3];
LineSpace linespace;
uint offsets[15];
uint poff;
mat4 transformation;
mat4 inverse_transformation;
mat4 normal_matrix;
};
struct Trace
{
Ray ray;
......
......@@ -23,6 +23,33 @@ bool intersectsRayBounds(const in Ray ray, const in Bounds bounds)
return tmax >= 0 && tmin <= tmax;
}
int faceID(float t, float t1, float t2, float t3, float t4, float t5, float t6) {
return t == t1 ? 3 : (t == t2 ? 0 : (t == t3 ? 4 : (t == t4 ? 2 : (t == t5 ? 5 : 3))));
}
bool intersectsRayBounds(const in Ray ray, const in Bounds bounds, inout float tmin, inout float tmax, inout int face_tmin, inout int face_tmax)
{
vec3 dirfrac = 1.0f / ray.direction.xyz;
//intersections with box planes parallel to x, y, z axis
float t1 = (bounds.min.x - ray.origin.x)*dirfrac.x;
float t2 = (bounds.max.x - ray.origin.x)*dirfrac.x;
float t3 = (bounds.min.y - ray.origin.y)*dirfrac.y;
float t4 = (bounds.max.y - ray.origin.y)*dirfrac.y;
float t5 = (bounds.min.z - ray.origin.z)*dirfrac.z;
float t6 = (bounds.max.z - ray.origin.z)*dirfrac.z;
tmin = max(max(min(t1, t2), min(t3, t4)), min(t5, t6));
tmax = min(min(max(t1, t2), max(t3, t4)), max(t5, t6));
face_tmin = faceID(tmin, t1, t2, t3, t4, t5, t6);
face_tmax = faceID(tmax, t1, t2, t3, t4, t5, t6);
return tmax >= 0 && tmin <= tmax;
}
bool intersectsRayBounds(const in Ray ray, const in Bounds bounds, const in float max_t)
{
vec3 dirfrac = 1.0f / ray.direction.xyz;
......
......@@ -6,6 +6,109 @@
#include <raytracer/intersections.glh>
#include <raytracer/std.glh>
const uvec3 c_face_width_axises = { 2, 2, 0 };
const uvec3 c_face_height_axises = { 1, 0, 1 };
uint faceRangeIndex(uint in_face, uint out_face)
{
return uint((((-0.5f * in_face) + 4.5f)*in_face) - 1u + out_face);
}
const uint offsets[15] = { 0, 56644, 125426, 182070, 238714, 307496, 376278, 432922, 489566, 558348, 627130, 695912, 779433, 836077, 904859 };
bool getLineIndex(const in Ray ray, const in Mesh mesh, inout uint line_id, inout bool direction_swapped)
{
float tmin, tmax;
int face_in, face_out;
direction_swapped = false;
if (!intersectsRayBounds(ray, mesh.linespace.bounds, tmin, tmax, face_in, face_out))
return false;
if (face_in < face_out) {
float tmp_t = tmin;
tmin = tmax;
tmax = tmp_t;
int tmp_face = face_in;
face_in = face_out;
face_out = tmp_face;
direction_swapped = true;
}
vec3 entry_point = ray.origin + tmin * ray.direction - mesh.linespace.bounds.min.xyz;
vec3 exit_point = ray.origin + tmax * ray.direction - mesh.linespace.bounds.min.xyz;
int in_axis = face_in % 3;
int out_axis = face_out % 3;
//TODO check if neg faces should be mirrored somehow
uvec2 patch_in = uvec2(c_face_width_axises[in_axis], c_face_height_axises[in_axis]);
uvec2 patch_out = uvec2(c_face_width_axises[out_axis], c_face_height_axises[out_axis]);
uint offset_index = faceRangeIndex(face_in, face_out);
uint offset = offsets[offset_index];
uint start_height = mesh.linespace.resolution[c_face_height_axises[in_axis]];
uint end_width = mesh.linespace.resolution[c_face_width_axises[out_axis]];
uint end_height = mesh.linespace.resolution[c_face_height_axises[out_axis]];
uint start = (patch_in.y + patch_in.x * start_height) * end_width * end_height;
uint end = (patch_out.y + patch_out.x * end_height);
line_id = offset + start + end;
return true;
}
bool linespace__traverse(const in uint mesh_id, const in Ray ray, inout Hit hit) {
Mesh mesh = b_meshes[mesh_id];
//For ease of use, substitute Ray<->OBB for Ray<->AABB by transforming the ray into object space.
Ray ray_in = ray;
ray_in.direction = normalize(mat3(mesh.inverse_transformation) * ray_in.direction.xyz);
ray_in.origin = (mesh.inverse_transformation * vec4(ray_in.origin.xyz, 1)).xyz;
//hit = mesh.linespace.lines[500].nearest;
uint line_id;
bool direction_swapped;
if (!getLineIndex(ray_in, mesh, line_id, direction_swapped))
{
return false;
}
else
{
Line line = mesh.lines[line_id];
hit = line.nearest;
//hit.barycentric = vec2(1, 0);
//hit.triangle = 0;
hit.mesh = mesh_id;
return hit.barycentric.x != -1;
}
/*hit.mesh = mesh_id;
hit.triangle = 0;
uint line_index = getLineIndex(ray_in, mesh);
if (intersectsRayBounds(ray_in, mesh.linespace.bounds, FLT_MAX)) {
hit.barycentric = vec2(1, 0);
return true;
}
return false;*/
//return intersectsRayBounds(ray_in, mesh.linespace.bounds, FLT_MAX);
}
Bounds getNodeBounds(int index, const in Mesh mesh)
{
return mesh.nodes[index].bounds;
......@@ -127,6 +230,16 @@ bool traverse(const in uint mesh_id, const in Ray ray, inout Hit hit, const in b
bool bvh__nearestIntersection(const in Ray ray, inout Hit hit)
{
//return linespace__traverse(0, ray, hit);
//bool hits = false;
//for (int i = 0; i < b_meshes.length(); ++i)
//{
// hits = bool(int(hits) | int(linespace__traverse(i, ray, hit)));
// //current_t = min_t;
//}
//return hits;
float current_t = FLT_MAX;
float min_t = FLT_MAX;
bool hits = false;
......@@ -141,6 +254,17 @@ bool bvh__nearestIntersection(const in Ray ray, inout Hit hit)
bool bvh__intersectsAny(const in Ray ray, const in float max_distance)
{
//
//for (int i = 0; i < b_meshes.length(); ++i)
//{
// if (linespace__traverse(i, ray, unused_hit))
// return true;
// //current_t = min_t;
//}
//return false;
Hit unused_hit;
float current_t = max_distance;
for (int i = 0; i < b_meshes.length(); ++i)
......
#include <glare_core>
#include <advanced/Structures.h>
#include <engine/RadixSort.h>
using namespace glare;
template<typename ValueType, typename ConstructorFunc, ConstructorFunc constructor, void(*destructor)(ValueType), typename ...ConstructParams>
struct late_initializer
{
late_initializer(ConstructParams&&... args)
: m_function([=]() mutable { generate(std::forward<ConstructParams>(args)...); }) {}
late_initializer(late_initializer &&other)
: m_value(other.m_value) {}
~late_initializer() { destructor(m_value); }
late_initializer(late_initializer &other) = delete;
void reset(ValueType&& type) {
if (m_initialized) {
destructor(m_value);
m_value = std::forward<ValueType>(type);
}
}
void reset() {
m_initialized = false;
destructor(m_value);
}
bool valid() const
{
return m_initialized;
}
operator ValueType() const
{
if (!m_initialized) {
m_function();
m_initialized = true;
}
return m_value;
}
private:
void generate(ConstructParams&&... args) {
m_value = constructor(args...);
}
std::function<void()> m_function;
mutable bool m_initialized = false;
mutable ValueType m_value;
};
template<void(*constr)(unsigned, unsigned*)>
inline unsigned constructor()
{
unsigned val;
constr(1, &val);
return val;
}
template<void(*destr)(unsigned, unsigned*)>
inline void destructor(unsigned val)
{
destr(1, &val);
}
template<void(*construct)(unsigned, unsigned*), void(*destruct)(unsigned, unsigned*)>
using handle_t = late_initializer<unsigned, unsigned(), constructor<construct>, destructor<destruct>>;
void genBla(unsigned, unsigned* vals) {
vals[0] = 30120;
Log_Info << "Generated a Bla";
}
void delBla(unsigned, unsigned* vals) {
vals[0] = 0;
Log_Info << "Deleted a Bla";
}
using bla_handle = handle_t<genBla, delBla>;
int main(int argc, char* argv[])
{
{
bla_handle handle;
Log_Info << "Grappling Hook";
Log_Info << "Bla's value is " << unsigned(handle);
Log_Info << "Bla's value is " << unsigned(handle);
Log_Info << "Bla's value is " << unsigned(handle);
handle.reset();
Log_Info << "Bla's value is " << unsigned(handle);
Log_Info << "Bla's value is " << unsigned(handle);
}
Log_Info << sizeof(advanced::Mesh);
quitPromptDefault(0);
return 0;
......
......@@ -48,38 +48,13 @@ namespace glare
//Create a skybox from cube map.
m_skybox = std::make_shared<core::Skybox>(core::Skybox::collectFilesFrom(core::asset("/textures/ryfjallet/")));
initializeScene(m_current_scene_root / "mesh.dae", 1.f);
initializeScene(m_current_scene_root / "bunny.dae", 1.f);
initializeRenderRequirements();
initializeAdvanced();
initializeGUI();
gl::setEnabled(gl::EnableParameter::eMultisample, true);
////////////////////////////////////////////////////////////////////////////////
/////
///// LS STUFF
/////
#define DEBUG__GENERATE_LS
#ifdef DEBUG__GENERATE_LS
m_collector->collect();
//Exemplary Line generation
unsigned line_mesh_id = 0;
const auto &mesh_collector = m_collector->meshCollectors().at(line_mesh_id);
int ls_resolution = 6;
ls::LineSpace linespace(*mesh_collector, ls_resolution);
ls::LineSpaceRenderer linespace_renderer(*m_collector, linespace);
#endif
/////
////////////////////////////////////////////////////////////////////////////////
glare::core::EngineState::opengl_core->loop([&](double delta)
{
//General state updates (camera and so on)
......@@ -110,10 +85,10 @@ namespace glare
}
break;
case AppRenderState::eLineSpace:
{
/* {
linespace_renderer.draw();
}
break;
break;*/
case AppRenderState::ePathtracer:
{
auto &&rt_texture = m_raytracer->render(m_config.window_width, m_config.window_height);
......@@ -125,12 +100,12 @@ namespace glare
drawDebugWindow();
drawSceneSelector();
ImGui::Begin("LineSpace");
/*ImGui::Begin("LineSpace");
ImGui::DragInt("Max. Subdivision", &ls_resolution);
if (ImGui::Button("Rebuild with Settings")) {
linespace.generate(*mesh_collector, ls_resolution);
}
ImGui::End();
ImGui::End();*/
ImGui::Render();
core::LightManager::getInstance().clear();
......@@ -149,6 +124,8 @@ namespace glare
if (!m_scene_data)
{
core::EngineState::quit();
glfwTerminate();
quitPromptDefault(1);
}
m_scene_root = m_scene_data->scenes.begin()->second;
......@@ -171,18 +148,8 @@ namespace glare
#define DEBUG__ADD_ROTATOR
#ifdef DEBUG__ADD_ROTATOR
for (auto &&node : m_scene_root)
{
Log_Info << node->name();
std::string name = "#bun_zipper_res2-mesh";
if (auto&& mesh = node->getComponent<core::MeshRenderer>())
{
if (mesh->getOwner()->name() == name) {
mesh->getOwner()->addComponent(std::make_shared<component::Rotator>());
break;
}
}
if (auto &&node = m_scene_root->findFirstWithName("#bun_zipper_res2-mesh")) {
node->addComponent(std::make_shared<component::Rotator>());
}
#endif
}
......
......@@ -64,14 +64,27 @@ namespace glare
void uniformUpdate(const core::ShaderProgram &program, std::string var_name) const;
};
struct LineSpaceData
{
math::Bounds bounds;
glm::uvec3 resolution;
float patch_size;
};
struct Mesh
{
uint64_t vertex_buffer_ptr;
uint64_t triangle_buffer_ptr;
uint64_t datastructure_buffer_ptr;
uint64_t lines_buffer;
glm::uint material;
glm::uint p;
glm::uint p[3];
LineSpaceData linespace;
glm::uint offsets[15];
glm::uint poff;
glm::mat4 transformation;
glm::mat4 inverse_transformation;
......
#include "LocalCollector.h"
#include <linespace/LineSpace.h>
namespace glare
{
......@@ -51,6 +52,13 @@ namespace glare
m_vertex_buffer->makeResident(gl::Access::eReadOnly);
m_triangle_buffer->makeResident(gl::Access::eReadOnly);
if (!m_linespace) {
m_linespace = std::make_unique<ls::LineSpace>(*this, -1);
}
else {
m_linespace->generate(*this, -1);
}
}
const std::vector<math::Vertex> &LocalCollector::vertices() const
......@@ -87,6 +95,16 @@ namespace glare
mesh.normal_matrix = glm::mat4(glm::mat3(glm::transpose(glm::inverse(m_transform))));
mesh.vertex_buffer_ptr = m_vertex_buffer->getResidentAddress();
mesh.triangle_buffer_ptr = m_triangle_buffer->getResidentAddress();
mesh.linespace.bounds = m_linespace->bounds();
mesh.linespace.patch_size = m_linespace->subdivisions().size;
mesh.linespace.resolution = glm::uvec3(m_linespace->subdivisions().subdivisions);
mesh.lines_buffer = m_linespace->lineBuffer().getResidentAddress();
for (int i = 0; i < 15; ++i) {
mesh.offsets[i] = glm::uint(m_linespace->offsets()[i]);
}
mesh.material = glm::uint(material_index);
return mesh;
}
......
......@@ -8,6 +8,10 @@
namespace glare
{
namespace ls {
class LineSpace;
}
namespace advanced
{
......@@ -49,6 +53,7 @@ namespace glare
size_t m_id = 0;
size_t m_material_id = 0; //!< NOT the buffer position of this material!
std::shared_ptr<LocalDatastructure> m_datastructure;
std::shared_ptr<ls::LineSpace> m_linespace;
math::Bounds m_bounds;
std::vector<math::Vertex> m_vertices;
std::vector<advanced::Triangle> m_triangles;
......
......@@ -32,6 +32,23 @@ namespace glare
const std::vector<std::shared_ptr<NodeType>>& getChildren();
std::shared_ptr<NodeType> findFirst(std::function<bool(const NodeType &node)> predicate) {
for (auto &&node : shared_from_this())
{
if (predicate(*node)) {
return node->shared_from_this();
}
}
return nullptr;
}
std::shared_ptr<NodeType> findFirstWithName(std::string name) {
return findFirst([name](const core::GraphNode &node) {
return node.name() == name;
});
}
class Iterator
{
public:
......
......@@ -99,6 +99,7 @@ namespace glare
}
m_line_buffer.setData(m_lines, gl::BufferUsage::eDynamicRead);
m_line_buffer.makeResident(gl::Access::eReadOnly);
Log_Info << "[Linespace Data] Generation Time: " << clock.time() << "ms";
Log_Info << "[Linespace Data] Lines: " << m_lines.size();
......@@ -194,6 +195,20 @@ namespace glare
return m_lines;
}
const math::Bounds &LineSpace::bounds() const
{
return m_bounds;
}
const math::UniformBoundsSubdivision &LineSpace::subdivisions() const
{
return m_subdivision;
}
const std::array<size_t, 15> &LineSpace::offsets() const
{
return m_offsets;
}
LineSpaceRenderer::LineSpaceRenderer(const advanced::SceneCollector &collector, const LineSpace &linespace)
: m_linespace(linespace), m_collector(collector)
......
......@@ -102,6 +102,9 @@ namespace glare
const core::Buffer<gl::BufferType::eShaderStorage> &lineBuffer() const;
const std::vector<Line> &lines() const;
const math::Bounds &bounds() const;
const math::UniformBoundsSubdivision &subdivisions() const;
const std::array<size_t, 15> &offsets() const;
private:
void calculateOffsets();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment