#include "Scene.h" #include "Utils.h" #include "Material.h" namespace dae { #pragma region Base Scene //Initialize Scene with Default Solid Color Material (RED) Scene::Scene() : m_Materials({ new Material_SolidColor({1,0,0}) }) { m_SphereGeometries.reserve(32); m_PlaneGeometries.reserve(32); m_TriangleMeshGeometries.reserve(32); m_Lights.reserve(32); } Scene::~Scene() { for (auto& pMaterial : m_Materials) { delete pMaterial; pMaterial = nullptr; } m_Materials.clear(); } void dae::Scene::GetClosestHit(const Ray& ray, HitRecord& closestHit) const { HitRecord tempHit {}; //Checks through all the sphere for (int idx{0};m_SphereGeometries.size() > idx;idx++) { if (GeometryUtils::HitTest_Sphere(m_SphereGeometries[idx], ray, tempHit)) // Check if there's a hit from spheres { if (tempHit.t < closestHit.t) { closestHit = tempHit; } } } //Checks through all the planes for (int idx{ 0 }; m_PlaneGeometries.size() > idx; idx++) { if (GeometryUtils::HitTest_Plane(m_PlaneGeometries[idx],ray,tempHit)) // Check if there's a hit from planes { if (tempHit.t < closestHit.t) { closestHit = tempHit; } } } //Checks through all the Triangles for (int idx{ 0 }; m_Triangles.size() > idx; idx++) { if (GeometryUtils::HitTest_Triangle(m_Triangles[idx], ray, tempHit)) // Check if there's a hit from planes { if (tempHit.t < closestHit.t) { closestHit = tempHit; } } } //Checks through all the Triangles Meshes for (int idx{ 0 }; m_TriangleMeshGeometries.size() > idx; idx++) { if (GeometryUtils::HitTest_TriangleMesh(m_TriangleMeshGeometries[idx], ray, tempHit)) // Check if there's a hit from planes { if (tempHit.t < closestHit.t) { closestHit = tempHit; } } } tempHit = closestHit; } bool Scene::DoesHit(const Ray& ray) const { //Checks through all the sphere for (int idx{ 0 }; idx < m_SphereGeometries.size() ; ++idx) { if (GeometryUtils::HitTest_Sphere(m_SphereGeometries[idx], ray)) // Check if there's a hit from spheres { return true; } } for (int idx{ 0 }; idx < m_PlaneGeometries.size(); ++idx) { if (GeometryUtils::HitTest_Plane(m_PlaneGeometries[idx], ray)) // Check if there's a hit from planes { return true; } } //Checks through all the Triangles for (int idx{ 0 }; idx < m_Triangles.size(); ++idx) { if (GeometryUtils::HitTest_Triangle(m_Triangles[idx], ray)) { return true; } } //Checks through all the Triangles Meshes for (int idx{ 0 };idx < m_TriangleMeshGeometries.size(); idx++) { if (GeometryUtils::HitTest_TriangleMesh(m_TriangleMeshGeometries[idx], ray)) // Check if there's a hit from planes { return true; } } return false; } #pragma region Scene Helpers Sphere* Scene::AddSphere(const Vector3& origin, float radius, unsigned char materialIndex) { Sphere s; s.origin = origin; s.radius = radius; s.materialIndex = materialIndex; m_SphereGeometries.emplace_back(s); return &m_SphereGeometries.back(); } Plane* Scene::AddPlane(const Vector3& origin, const Vector3& normal, unsigned char materialIndex) { Plane p; p.origin = origin; p.normal = normal; p.materialIndex = materialIndex; m_PlaneGeometries.emplace_back(p); return &m_PlaneGeometries.back(); } TriangleMesh* Scene::AddTriangleMesh(TriangleCullMode cullMode, unsigned char materialIndex) { TriangleMesh m{}; m.cullMode = cullMode; m.materialIndex = materialIndex; m_TriangleMeshGeometries.emplace_back(m); return &m_TriangleMeshGeometries.back(); } Light* Scene::AddPointLight(const Vector3& origin, float intensity, const ColorRGB& color) { Light l; l.origin = origin; l.intensity = intensity; l.color = color; l.type = LightType::Point; m_Lights.emplace_back(l); return &m_Lights.back(); } Light* Scene::AddDirectionalLight(const Vector3& direction, float intensity, const ColorRGB& color) { Light l; l.direction = direction; l.intensity = intensity; l.color = color; l.type = LightType::Directional; m_Lights.emplace_back(l); return &m_Lights.back(); } unsigned char Scene::AddMaterial(Material* pMaterial) { m_Materials.push_back(pMaterial); return static_cast(m_Materials.size() - 1); } #pragma endregion #pragma endregion #pragma region SCENE W1 void Scene_W1::Initialize() { //default: Material id0 >> SolidColor Material (RED) constexpr unsigned char matId_Solid_Red = 0; const unsigned char matId_Solid_Blue = AddMaterial(new Material_SolidColor{ colors::Blue }); const unsigned char matId_Solid_Yellow = AddMaterial(new Material_SolidColor{ colors::Yellow }); const unsigned char matId_Solid_Green = AddMaterial(new Material_SolidColor{ colors::Green }); const unsigned char matId_Solid_Magenta = AddMaterial(new Material_SolidColor{ colors::Magenta }); //Spheres AddSphere({ -25.f, 0.f, 100.f }, 50.f, matId_Solid_Red); AddSphere({ 25.f, 0.f, 100.f }, 50.f, matId_Solid_Blue); //Plane AddPlane({ -75.f, 0.f, 0.f }, { 1.f, 0.f,0.f }, matId_Solid_Green); AddPlane({ 75.f, 0.f, 0.f }, { -1.f, 0.f,0.f }, matId_Solid_Green); AddPlane({ 0.f, -75.f, 0.f }, { 0.f, 1.f,0.f }, matId_Solid_Yellow); AddPlane({ 0.f, 75.f, 0.f }, { 0.f, -1.f,0.f }, matId_Solid_Yellow); AddPlane({ 0.f, 0.f, 125.f }, { 0.f, 0.f,-1.f }, matId_Solid_Magenta); } #pragma endregion void Scene_W2::Initialize() { m_Camera.origin = { 0.f,3.f,-9.f }; m_Camera.fovAngle = 45.f; //default: Material id0 >> SolidColorMaterial (RED) constexpr unsigned char matId_Solid_Red = 0; const unsigned char matId_Solid_Blue = AddMaterial(new Material_SolidColor{ colors::Blue }); const unsigned char matId_Solid_Yellow = AddMaterial(new Material_SolidColor{ colors::Yellow }); const unsigned char matId_Solid_Green = AddMaterial(new Material_SolidColor{ colors::Green }); const unsigned char matId_Solid_Magenta = AddMaterial(new Material_SolidColor{ colors::Magenta }); const unsigned char matId_Solid_Porple = AddMaterial(new Material_SolidColor{ ColorRGB(207, 159, 255)}); //Plane AddPlane({ -5.f,0.f,0.f }, { 1.f,0.f,0.f }, matId_Solid_Green); AddPlane({ 5.f,0.f,0.f }, { -1.f,0.f,0.f }, matId_Solid_Green); AddPlane({ 0.f,0.f,0.f }, { 0.f,1.f,0.f }, matId_Solid_Yellow); AddPlane({ 0.f,10.f,0.f }, { 0.f,-1.f,0.f }, matId_Solid_Yellow); AddPlane({ 0.f,0.f,10.f }, { 0.f,0.f,-1.f }, matId_Solid_Magenta); //Spheres AddSphere({-1.75f,1.f,0.f}, .75f, matId_Solid_Red); AddSphere({0.f,1.f,0.f}, .75f, matId_Solid_Blue); AddSphere({ 1.75f,1.f,0.f }, .75f, matId_Solid_Red); AddSphere({ -1.75f,3.f,0.f }, .75f, matId_Solid_Blue); AddSphere({ 0.f,3.f,0.f }, .75f, matId_Solid_Red); AddSphere({ 1.75f,3.f,0.f }, .75f, matId_Solid_Blue); /*AddSphere({ 0.f,5.f,0.f }, .75f, matId_Solid_Porple);*/ //Light AddPointLight({ 0.f,5.f,-5.f }, 70.f, colors::White); } void Scene_W3::Initialize() { m_Camera.origin = { 0.f,3.f,-9.f }; m_Camera.fovAngle = 45.f; const auto matCT_GrayRoughMetal = AddMaterial(new Material_CookTorrence({.972f,.960f,.915f},1.f,1.f)); const auto matCT_GrayMediumMetal = AddMaterial(new Material_CookTorrence({ .972f,.960f,.915f }, 1.f, .6f)); const auto matCT_GraySmoothMetal = AddMaterial(new Material_CookTorrence({ .972f,.960f,.915f }, 1.f, .1f)); const auto matCT_GrayRoughPlastic = AddMaterial(new Material_CookTorrence({ .75f,.75f,.75f },0.f, 1.f)); const auto matCT_GrayMediumPlastic = AddMaterial(new Material_CookTorrence({ .75f,.75f,.75f },0.f, .6f)); const auto matCT_GraySmoothPlastic = AddMaterial(new Material_CookTorrence({ .75f,.75f,.75f },0.f, .1f)); const auto matLambert_GrayBlue = AddMaterial(new Material_Lambert({ .49f,.57f,.57f }, 1.f)); //Plane AddPlane(Vector3{0.f,0.f,10.f}, Vector3{0.f,0.f,-1.f},matLambert_GrayBlue);//Back AddPlane(Vector3{0.f,0.f,0.f}, Vector3{0.f,1.f,0.f},matLambert_GrayBlue);//Bottom AddPlane(Vector3{0.f,10.f,0.f}, Vector3{0.f,-1.f,0.f},matLambert_GrayBlue);//Top AddPlane(Vector3{ 5.f,0.f,0.f}, Vector3{-1.f,0.f,0.f},matLambert_GrayBlue);//Right AddPlane(Vector3{-5.f,0.f,0.f}, Vector3{ 1.f,0.f,0.f},matLambert_GrayBlue);//Left //Temporary Lambert-Phong Spheres & Materials //const auto matLambertPhong1 = AddMaterial(new Material_LambertPhong(colors::Blue, 0.5, 0.5, 3.f)); //const auto matLambertPhong2 = AddMaterial(new Material_LambertPhong(colors::Blue, 0.5, 0.5, 15.f)); //const auto matLambertPhong3 = AddMaterial(new Material_LambertPhong(colors::Blue, 0.5, 0.5, 50.f)); //AddSphere({ -1.75f,1.f,0.f }, .75f, matLambertPhong1); //AddSphere({ 0.f,1.f,0.f }, .75f, matLambertPhong2); //AddSphere({ 1.75f,1.f,0.f }, .75f, matLambertPhong3); //Spheres AddSphere({ -1.75f,1.f,0.f },.75f, matCT_GrayRoughMetal); AddSphere({ 0.f,1.f,0.f }, .75f, matCT_GrayMediumMetal); AddSphere({ 1.75f,1.f,0.f }, .75f, matCT_GraySmoothMetal); AddSphere({ -1.75f,3.f,0.f },.75f, matCT_GrayRoughPlastic); AddSphere({ 0.f,3.f,0.f }, .75f, matCT_GrayMediumPlastic); AddSphere({ 1.75f,3.f,0.f }, .75f, matCT_GraySmoothPlastic); //Light AddPointLight(Vector3{ 0.f,5.f,5.f }, 50.f, ColorRGB{ 1.f,.61f,.45f }); //Backlight AddPointLight(Vector3{-2.5f,5.f,-5.f }, 70.f, ColorRGB{ 1.f,.8f,.45f }); //Front Light Left AddPointLight(Vector3{2.5f,2.5f,-5.f }, 50.f, ColorRGB{ .34f,.47f,.68f }); //Front Light Right //PHONG TEST SCENE //m_Camera.origin = { 0.f,1.f,-5.f }; //m_Camera.fovAngle = 45.f; ////Materials //const auto matLambert_Red = AddMaterial(new Material_Lambert(colors::Red,1.f)); //const auto matLambert_Blue = AddMaterial(new Material_LambertPhong(colors::Blue,1.f,1.f,60.f)); //const auto matLambert_Yellow = AddMaterial(new Material_Lambert(colors::Yellow, 1.f)); ////Spheres //AddSphere({ -.75f,1.f,.0f }, 1.f, matLambert_Red); //AddSphere({ .75f,1.f,.0f }, 1.f, matLambert_Blue); ////Plane //AddPlane({ 0.f,0.f,0.f }, { 0.f,1.f,0.f }, matLambert_Yellow); ////Light //AddPointLight({ 0.f,5.f,5.f }, 25.f,colors::White); //AddPointLight({ 0.f,2.5f,-5.f },25.f,colors::White); } void Scene_W4_Bunny::Initialize() { m_Camera.origin = { 0.f, 1.f, -5.f }; m_Camera.fovAngle = 45.f; // Materials const auto matLambert_GrayBlue = AddMaterial(new Material_Lambert({ 0.49f, 0.57f, 0.57f }, 1.f)); const auto matLambert_White = AddMaterial(new Material_Lambert(colors::White, 1.f)); // Planes AddPlane({ 0.f, 0.f, 10.f },{ 0.f, 0.f, -1.f }, matLambert_GrayBlue); // BACK AddPlane({ 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }, matLambert_GrayBlue); // BOTTOM AddPlane({ 0.f, 10.f, 0.f },{ 0.f, -1.f, 0.f }, matLambert_GrayBlue); // TOP AddPlane({ 5.f, 0.f, 0.f }, { -1.f, 0.f, 0.f }, matLambert_GrayBlue); // RIGHT AddPlane({ -5.f, 0.f, 0.f },{ 1.f, 0.f, 0.f }, matLambert_GrayBlue); // LEFT // Triangle (Temp) //auto triangle = Triangle{ { -.75f, .5f, 0.f }, { -.75f, 2.f, 0.f }, { .75f, .5f, 0.f } }; //triangle.cullMode = TriangleCullMode::FrontFaceCulling; //triangle.materialIndex = matLambert_White; //m_Triangles.emplace_back(triangle); //const auto triangleMesh = AddTriangleMesh(TriangleCullMode::NoCulling, matLambert_White); //triangleMesh->positions = { { -0.75f, -1.f, 0.f}, { -0.75f, 1.f, 0.f}, // { 0.75f, 1.f, 1.f}, { 0.75f, -1.f, 0.f} }; //triangleMesh->indices = { // 0, 1, 2, // Triangle 1 // 0, 2, 3 // Triangle 2 //}; //triangleMesh->CalculateNormals(); //triangleMesh->Translate({ 0.f,1.5f,0.f }); //triangleMesh->RotateY(45); //triangleMesh->UpdateTransforms(); pMesh = AddTriangleMesh(TriangleCullMode::BackFaceCulling, matLambert_White); Utils::ParseOBJ("Resources/lowpoly_bunny.obj", pMesh->positions, pMesh->normals, pMesh->indices); //pMesh->positions = { { -0.75f, -1.f, 0.f}, //v0 // { -0.75f, 1.f, 0.f}, //v1 // { 0.75f, 1.f, 1.f}, //v2 // { 0.75f, -1.f, 0.f} };//v3 //pMesh->indices = { // 0, 1, 2, // Triangle 1 // 0, 2, 3 // Triangle 2 //}; //pMesh->CalculateNormals(); //pMesh->Translate({ 0.f,1.5f,0.f }); pMesh->RotateY(60); pMesh->UpdateTransforms(); // Light AddPointLight({ 0.f, 5.f, 5.f }, 50.f, ColorRGB{ 1.f, .61f, .45f }); // Backlight AddPointLight({ -2.5f, 5.f, -5.f }, 70.f, ColorRGB{ 1.f, .8f, .45f }); // Front Light Left AddPointLight({ 2.5f, 5.f, -5.f }, 50.f, ColorRGB{ .34f, .47f, .68f }); // Front Light Right } void Scene_W4_Bunny::Update(dae::Timer* pTimer) { Scene::Update(pTimer); } void Scene_W4_ReferenceScene::Initialize() { sceneName = "Reference Scene"; m_Camera.origin = { 0.f, 3.f, -9.f }; m_Camera.fovAngle = 45.f; // Materials const auto matCT_GrayRoughMetal = AddMaterial(new Material_CookTorrence({ 0.972f, 0.960f, 0.915f }, 1.f, 1.0f)); const auto matCT_GrayMediumMetal = AddMaterial(new Material_CookTorrence({ 0.972f, 0.960f, 0.915f }, 1.f, 0.6f)); const auto matCT_GraySmoothMetal = AddMaterial(new Material_CookTorrence({ 0.972f, 0.960f, 0.915f }, 1.f, 0.1f)); const auto matCT_GrayRoughPlastic = AddMaterial(new Material_CookTorrence({ 0.75f , 0.75f , 0.75f }, 0.f, 1.0f)); const auto matCT_GrayMediumPlastic = AddMaterial(new Material_CookTorrence({ 0.75f , 0.75f , 0.75f }, 0.f, 0.6f)); const auto matCT_GraySmoothPlastic = AddMaterial(new Material_CookTorrence({ 0.75f , 0.75f , 0.75f }, 0.f, 0.1f)); const auto matLambert_GrayBlue = AddMaterial(new Material_Lambert({ 0.49f, 0.57f, 0.57f }, 1.f)); const auto matLambert_White = AddMaterial(new Material_Lambert(colors::White, 1.f)); // Plane AddPlane(Vector3{ 0.f, 0.f, 10.f }, Vector3{ 0.f, 0.f, -1.f }, matLambert_GrayBlue); // BACK AddPlane(Vector3{ 0.f, 0.f, 0.f }, Vector3{ 0.f, 1.f, 0.f }, matLambert_GrayBlue); // BOTTOM AddPlane(Vector3{ 0.f, 10.f, 0.f }, Vector3{ 0.f, -1.f, 0.f }, matLambert_GrayBlue); // TOP AddPlane(Vector3{ 5.f, 0.f, 0.f }, Vector3{ -1.f, 0.f, 0.f }, matLambert_GrayBlue); // RIGHT AddPlane(Vector3{ -5.f, 0.f, 0.f }, Vector3{ 1.f, 0.f, 0.f }, matLambert_GrayBlue); // LEFT // Spheres AddSphere({ -1.75f, 1.f, 0.f, }, 0.75f, matCT_GrayRoughMetal); AddSphere({ 0.f , 1.f, 0.f, }, 0.75f, matCT_GrayMediumMetal); AddSphere({ 1.75f, 1.f, 0.f, }, 0.75f, matCT_GraySmoothMetal); AddSphere({ -1.75f, 3.f, 0.f, }, 0.75f, matCT_GrayRoughPlastic); AddSphere({ 0.f , 3.f, 0.f, }, 0.75f, matCT_GrayMediumPlastic); AddSphere({ 1.75f, 3.f, 0.f, }, 0.75f, matCT_GraySmoothPlastic); // Triangle const Triangle baseTriangle = { Vector3(-0.75f, 1.5f, 0.f) //v0 , Vector3(0.75f, 0.0f, 0.f) //v1 , Vector3(-0.75f, 0.0f, 0.f) }; //v2 // Triangle Meshes m_Meshes[0] = AddTriangleMesh(TriangleCullMode::BackFaceCulling, matLambert_White); m_Meshes[0]->AppendTriangle(baseTriangle, true); m_Meshes[0]->Translate({ -1.75f, 4.5f, 0.f }); m_Meshes[0]->UpdateTransforms(); m_Meshes[1] = AddTriangleMesh(TriangleCullMode::FrontFaceCulling, matLambert_White); m_Meshes[1]->AppendTriangle(baseTriangle, true); m_Meshes[1]->Translate({ 0.f, 4.5f, 0.f }); m_Meshes[1]->UpdateTransforms(); m_Meshes[2] = AddTriangleMesh(TriangleCullMode::NoCulling, matLambert_White); m_Meshes[2]->AppendTriangle(baseTriangle, true); m_Meshes[2]->Translate({ 1.75f, 4.5f, 0.f }); m_Meshes[2]->UpdateTransforms(); // Light AddPointLight({ 0.f , 5.f , 5.f }, 50.f, ColorRGB{ 1.f , 0.61f, 0.45f }); // BackLight AddPointLight({ -2.5f , 5.f , -5.f }, 70.f, ColorRGB{ 1.f , 0.8f , 0.45f }); // Front Light Left AddPointLight({ 2.5f , 2.5f, -5.f }, 50.f, ColorRGB{ 0.34f, 0.47f, 0.68f }); } void Scene_W4_ReferenceScene::Update(dae::Timer* pTimer) { Scene::Update(pTimer); const auto yawAngle = (cos(pTimer->GetTotal()) + 1.f) / 2.f * PI_2; for (const auto m : m_Meshes) { m->RotateY(yawAngle); m->UpdateTransforms(); } } }