#include "scene.hpp" #include #include using namespace Eigen; scene::scene(RTCDevice dev){ m_scene = rtcNewScene(dev); m_dev = dev; } unsigned int scene::add_object(const objl::Mesh& mesh, const Eigen::Matrix4f& transform, bool emitter){ added_meshes.push_back(mesh); return add_object(added_meshes.size() - 1, transform, emitter); } unsigned int scene::add_object(size_t mesh_index, const Eigen::Matrix4f& transform, bool emitter){ using namespace objl; const objl::Mesh& mesh = this->added_meshes[mesh_index]; std::pair xex = {mesh.Vertices[0].Position.X, mesh.Vertices[0].Position.X}; std::pair yex = {mesh.Vertices[0].Position.Y, mesh.Vertices[0].Position.Y}; std::pair zex = {mesh.Vertices[0].Position.Z, mesh.Vertices[0].Position.Z}; for(size_t i = 1;i < mesh.Vertices.size();i++){ xex.first = std::min(mesh.Vertices[i].Position.X, xex.first); yex.first = std::min(mesh.Vertices[i].Position.Y, yex.first); zex.first = std::min(mesh.Vertices[i].Position.Z, zex.first); xex.second = std::max(mesh.Vertices[i].Position.X, xex.second); yex.second = std::max(mesh.Vertices[i].Position.Y, yex.second); zex.second = std::max(mesh.Vertices[i].Position.Z, zex.second); } if(xex.second - xex.first < 0.0001f){ xex.second = 1e30; xex.first = -1e30; } if(yex.second - yex.first < 0.0001f){ yex.second = 1e30; yex.first = -1e30; } if(zex.second - zex.first < 0.0001f){ zex.second = 1e30; zex.first = -1e30; } std::vector rectified_vertices(mesh.Vertices.size()); for(size_t i = 0;i < mesh.Vertices.size();i++){ Vector4f rec_pos; rec_pos.x() = (mesh.Vertices[i].Position.X - xex.first) * (2.0f / (xex.second - xex.first)) - 1.0f; rec_pos.y() = (mesh.Vertices[i].Position.Y - yex.first) * (2.0f / (yex.second - yex.first)) - 1.0f; rec_pos.z() = (mesh.Vertices[i].Position.Z - zex.first) * (2.0f / (zex.second - zex.first)) - 1.0f; rec_pos.w() = 1; rec_pos = transform * rec_pos; rectified_vertices[i].Position.X = rec_pos.x(); rectified_vertices[i].Position.Y = rec_pos.y(); rectified_vertices[i].Position.Z = rec_pos.z(); } RTCGeometry m_geom = rtcNewGeometry(m_dev, RTC_GEOMETRY_TYPE_TRIANGLE); float* vertices = (float*) rtcSetNewGeometryBuffer(m_geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, 3 * sizeof(float), rectified_vertices.size()); unsigned* indices = (unsigned*) rtcSetNewGeometryBuffer(m_geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, 3 * sizeof(unsigned), mesh.Indices.size() / 3); if (vertices && indices){ for(size_t i = 0;i < mesh.Indices.size();i++){ indices[i] = mesh.Indices[i]; } for(size_t i = 0;i < rectified_vertices.size();i++){ vertices[3 * i] = rectified_vertices[i].Position.X; vertices[3 * i + 1] = rectified_vertices[i].Position.Y; vertices[3 * i + 2] = rectified_vertices[i].Position.Z; } } rtcUpdateGeometryBuffer(m_geom, RTC_BUFFER_TYPE_VERTEX, 0); rtcUpdateGeometryBuffer(m_geom, RTC_BUFFER_TYPE_INDEX, 0); rtcCommitGeometry(m_geom); unsigned int geomID = rtcAttachGeometry(m_scene, m_geom); if(emitter){ emitters.emplace(geomID); } this->added_objects.push_back(std::make_unique(mesh_index, material())); this->geom_id_to_object_index_map[geomID] = this->added_objects.size() - 1; return geomID; } unsigned int scene::add_sphere(const Eigen::Vector3f& pos, float rad, bool emitter){ RTCGeometry m_geom = rtcNewGeometry(m_dev, RTC_GEOMETRY_TYPE_SPHERE_POINT); float* vertices = (float*) rtcSetNewGeometryBuffer(m_geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT4, 4 * sizeof(float), 1); vertices[0] = pos.x(); vertices[1] = pos.y(); vertices[2] = pos.z(); vertices[3] = rad; rtcUpdateGeometryBuffer(m_geom, RTC_BUFFER_TYPE_VERTEX, 0); rtcCommitGeometry(m_geom); unsigned int geomID = rtcAttachGeometry(m_scene, m_geom); if(emitter){ emitters.emplace(geomID); } this->added_objects.push_back(std::make_unique(material())); this->geom_id_to_object_index_map[geomID] = this->added_objects.size() - 1; return geomID; } void scene::build(){ rtcSetSceneBuildQuality(m_scene, RTC_BUILD_QUALITY_HIGH); rtcCommitScene(m_scene); } /*scene get_scene(RTCDevice dev){ RTCScene rtcsc = rtcNewScene(dev); objl::Loader loader; loader.LoadFile("ajax.obj"); objl::Mesh& ajaxmesh = loader.LoadedMeshes.at(0); //std::cout << ajaxmesh.Vertices.size() << "\n"; if(ajaxmesh.Indices.size() % 3 != 0){ std::terminate(); } RTCGeometry m_geom = rtcNewGeometry(dev, RTC_GEOMETRY_TYPE_TRIANGLE); float* vertices = (float*) rtcSetNewGeometryBuffer(m_geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, 3 * sizeof(float), ajaxmesh.Vertices.size()); unsigned* indices = (unsigned*) rtcSetNewGeometryBuffer(m_geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, 3 * sizeof(unsigned), ajaxmesh.Indices.size() / 3); if (vertices && indices){ for(size_t i = 0;i < ajaxmesh.Indices.size();i++){ indices[i] = ajaxmesh.Indices[i]; } for(size_t i = 0;i < ajaxmesh.Vertices.size();i++){ vertices[3 * i] = ajaxmesh.Vertices[i].Position.X; vertices[3 * i + 1] = ajaxmesh.Vertices[i].Position.Y; vertices[3 * i + 2] = ajaxmesh.Vertices[i].Position.Z; } } rtcUpdateGeometryBuffer(m_geom, RTC_BUFFER_TYPE_VERTEX, 0); rtcUpdateGeometryBuffer(m_geom, RTC_BUFFER_TYPE_INDEX, 0); rtcCommitGeometry(m_geom); unsigned int geomID = rtcAttachGeometry(rtcsc, m_geom); RTCGeometry m_geom2 = rtcNewGeometry(dev, RTC_GEOMETRY_TYPE_TRIANGLE); vertices = (float*) rtcSetNewGeometryBuffer(m_geom2, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, 3 * sizeof(float), 3); indices = (unsigned*) rtcSetNewGeometryBuffer(m_geom2, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, 3 * sizeof(unsigned), 1); vertices[0] = -11; vertices[1] = 10; vertices[2] = 5; vertices[3] = -11; vertices[4] = 15; vertices[5] = 5; vertices[6] = -20; vertices[7] = 15; vertices[8] = -5; indices[0] = 0; indices[1] = 1; indices[2] = 2; rtcUpdateGeometryBuffer(m_geom2, RTC_BUFFER_TYPE_VERTEX, 0); rtcUpdateGeometryBuffer(m_geom2, RTC_BUFFER_TYPE_INDEX, 0); rtcCommitGeometry(m_geom2); unsigned int geid2 = rtcAttachGeometry(rtcsc, m_geom2); rtcSetSceneBuildQuality(rtcsc, RTC_BUILD_QUALITY_HIGH); rtcCommitScene(rtcsc); scene sc(rtcsc); //sc.emitting.insert({geomID, true}); sc.emitting.insert({geid2, true}); return sc; }*/