#include "dxstdafx.h" #include "World.hpp" World::World() { virtualWorldObjects = 0x0; virtualWorldVertices = 0x0; virtualWorldLights = 0x0; nVirtualWorldObjects = 0; nVirtualWorldVertices = 0; nVirtualWorldLights = 0; } void World::createScene(Intersectable* obj) { obliterate(); nVirtualWorldLights = 0; virtualWorldLights = new Light*[1]; nVirtualWorldObjects = 1; virtualWorldObjects = new Intersectable*[nVirtualWorldObjects]; nVirtualWorldVertices = 4; virtualWorldVertices = new Vector[nVirtualWorldVertices]; virtualWorldObjects[0] = obj; kdtree = new KDTree(virtualWorldObjects, nVirtualWorldObjects); } void World::createScene() { obliterate(); eyePosition = Vector(10.0f, 0.0f, 0.0f); lookPosition = Vector(0.0f, 0.0f, 0.0f); nVirtualWorldLights = 1; virtualWorldLights = new Light*[1]; nVirtualWorldObjects = 9; virtualWorldObjects = new Intersectable*[nVirtualWorldObjects]; nVirtualWorldVertices = 4; virtualWorldVertices = new Vector[nVirtualWorldVertices]; virtualWorldVertices[0] = Vector(2.0f, 1.9f, 2.0f); virtualWorldVertices[1] = Vector(2.0f, 1.9f, -2.0f); virtualWorldVertices[2] = Vector(-2.0f, 1.9f, -2.0f); virtualWorldVertices[3] = Vector(-2.0f, 1.9f, 2.0f); virtualWorldLights[0] = new SquareLight(virtualWorldVertices, 4, Vector(500.0f, 500.0f, 500.0f)); virtualWorldSummedLightLuminance = virtualWorldLights[0]->getLuminance(); int iObject = 0; virtualWorldObjects[iObject++] = new PlaneXAligned(-2.0f, true, &Material::DIFFUSEBLUE); virtualWorldObjects[iObject++] = new PlaneXAligned(11.0f, false, &Material::DIFFUSEGREEN); virtualWorldObjects[iObject++] = new PlaneYAligned(-2.0f, true, &Material::DIFFUSEGREEN); virtualWorldObjects[iObject++] = new PlaneYAligned(2.0f, false, &Material::DIFFUSEYELLOW); virtualWorldObjects[iObject++] = new PlaneZAligned(-2.0f, true, &Material::DIFFUSERED); virtualWorldObjects[iObject++] = new PlaneZAligned(2.0f, false, &Material::DIFFUSEORANGE); virtualWorldObjects[iObject++] = new Triangle( virtualWorldVertices + 1, virtualWorldVertices, virtualWorldVertices + 2, new Material(Vector::RGBWHITE, Vector::RGBBLACK, 0.0f, Vector(100000.0f, 100000.0f, 10000.0f), Vector::RGBBLACK, 0.0f)); virtualWorldObjects[iObject++] = new Triangle( virtualWorldVertices, virtualWorldVertices + 3, virtualWorldVertices + 2, new Material(Vector::RGBWHITE, Vector::RGBBLACK, 0.0f, Vector(100000.0f, 100000.0f, 10000.0f), Vector::RGBBLACK, 0.0f)); virtualWorldObjects[iObject++] = new Sphere(Vector(0.0f, 0.0f, 0.0f), 1.0f, &Material::SHINYBLACK); nVirtualWorldObjects = iObject; kdtree = new KDTree(virtualWorldObjects, nVirtualWorldObjects); } void World::createScene(std::istream& isc) { obliterate(); nVirtualWorldMaterials = nVirtualWorldObjects = 0; objectArraySize = materialArraySize = lightArraySize = 8; virtualWorldMaterials = new Material*[8]; virtualWorldObjects = new Intersectable*[8]; eyePosition = Vector(10.0f, 0.0f, 0.0f); lookPosition = Vector(0.0f, 0.0f, 0.0f); upwards = Vector(0.0f, 1.0f, 0.0f); char keyword[200]; do{ isc >> keyword; if(strcmp(keyword,"eyePosition") == 0) isc >> eyePosition; else if(strcmp(keyword,"lookPosition") == 0) isc >> lookPosition; else if(strcmp(keyword,"upwards") == 0) isc >> upwards; else if(strcmp(keyword,"Material") == 0) { if(nVirtualWorldMaterials == materialArraySize) { materialArraySize += 4; Material** largerArray = new Material*[materialArraySize]; for(int d=0;d> ky; for(int i=0; i < nVirtualWorldMaterials; i++) { skymat1 = virtualWorldMaterials[i]; if(strcmp(ky, skymat1->getName()) == 0) break; } isc >> ky; for(int i=0; i < nVirtualWorldMaterials; i++) { skymat2 = virtualWorldMaterials[i]; if(strcmp(ky, skymat2->getName()) == 0) break; } isc >> ky; for(int i=0; i < nVirtualWorldMaterials; i++) { skymat3 = virtualWorldMaterials[i]; if(strcmp(ky, skymat3->getName()) == 0) break; } isc >> ky; for(int i=0; i < nVirtualWorldMaterials; i++) { skymat4 = virtualWorldMaterials[i]; if(strcmp(ky, skymat4->getName()) == 0) break; } int rows, cols; float edge, street, minHeight, maxHeight; isc >> rows >> cols; { objectArraySize += rows * cols * 6; Intersectable** largerArray = new Intersectable*[objectArraySize]; for(int d=0;d> edge >> street >> minHeight >> maxHeight; for(int r=0; r < rows; r++) for(int c=0; c < cols; c++) { Material* skymat; float marand = (float)rand() / (float)RAND_MAX; if(marand < 0.25f) skymat = skymat1; else if(marand < 0.5f) skymat = skymat2; else if(marand < 0.75f) skymat = skymat3; else skymat = skymat4; float xMin = r * (edge + street); float xMax = xMin + edge; float yMin = c * (edge + street); float yMax = yMin + edge; float height = minHeight + (maxHeight - minHeight) * (float)rand() / (float)RAND_MAX; PlaneXAligned* p = new PlaneXAligned(xMin, false, skymat); p->yMin = yMin; p->yMax = yMax; p->zMin = 0.0f; p->zMax = height; p->bbox.minPoint.x = p->bbox.maxPoint.x = xMin; p->bbox.maxPoint.y = yMax; p->bbox.maxPoint.z = height; p->bbox.minPoint.y = yMin; p->bbox.minPoint.z = 0.0f; virtualWorldObjects[nVirtualWorldObjects++] = p; p = new PlaneXAligned(xMax, true, skymat); p->yMin = yMin; p->yMax = yMax; p->zMin = 0.0f; p->zMax = height; p->bbox.minPoint.x = p->bbox.maxPoint.x = xMax; p->bbox.maxPoint.y = yMax; p->bbox.maxPoint.z = height; p->bbox.minPoint.y = yMin; p->bbox.minPoint.z = 0.0f; virtualWorldObjects[nVirtualWorldObjects++] = p; PlaneYAligned* py = new PlaneYAligned(yMin, false, skymat); py->xMin = xMin; py->xMax = xMax; py->zMin = 0.0f; py->zMax = height; py->bbox.minPoint.y = py->bbox.maxPoint.y = yMin; py->bbox.maxPoint.x = xMax; py->bbox.maxPoint.z = height; py->bbox.minPoint.x = xMin; py->bbox.minPoint.z = 0.0f; virtualWorldObjects[nVirtualWorldObjects++] = py; py = new PlaneYAligned(yMax, true, skymat); py->xMin = xMin; py->xMax = xMax; py->zMin = 0.0f; py->zMax = height; py->bbox.minPoint.y = py->bbox.maxPoint.y = yMax; py->bbox.maxPoint.x = xMax; py->bbox.maxPoint.z = height; py->bbox.minPoint.x = xMin; py->bbox.minPoint.z = 0.0f; virtualWorldObjects[nVirtualWorldObjects++] = py; PlaneZAligned* pz = new PlaneZAligned(0.0f, false, skymat); pz->xMin = xMin; pz->xMax = xMax; pz->yMin = yMin; pz->yMax = yMax; pz->bbox.minPoint.z = pz->bbox.maxPoint.z = 0.0; pz->bbox.maxPoint.x = xMax; pz->bbox.maxPoint.y = yMax; pz->bbox.minPoint.x = xMin; pz->bbox.minPoint.y = yMin; virtualWorldObjects[nVirtualWorldObjects++] = pz; pz = new PlaneZAligned(height, true, skymat); pz->xMin = xMin; pz->xMax = xMax; pz->yMin = yMin; pz->yMax = yMax; pz->bbox.minPoint.z = pz->bbox.maxPoint.z = height; pz->bbox.maxPoint.x = xMax; pz->bbox.maxPoint.y = yMax; pz->bbox.minPoint.x = xMin; pz->bbox.minPoint.y = yMin; virtualWorldObjects[nVirtualWorldObjects++] = pz; } } }while(strcmp(keyword,"end") != 0); nVirtualWorldLights = 0; for(int iLightCounter=0;iLightCounter < nVirtualWorldObjects;iLightCounter++) if(virtualWorldObjects[iLightCounter]->getMaterial()->isEmissive()) nVirtualWorldLights++; virtualWorldLights = new Light*[nVirtualWorldLights]; int iLightPlacer = 0; virtualWorldSummedLightLuminance = 0.0f; for(int iLightMaker=0;iLightMaker < nVirtualWorldObjects;iLightMaker++) if(virtualWorldObjects[iLightMaker]->getMaterial()->isEmissive()) { virtualWorldLights[iLightPlacer] = virtualWorldObjects[iLightMaker]->makeLight(); virtualWorldSummedLightLuminance += virtualWorldLights[iLightPlacer]->getLuminance(); iLightPlacer++; } kdtree = new KDTree(virtualWorldObjects, nVirtualWorldObjects); } void World::obliterate() { if(virtualWorldObjects) delete virtualWorldObjects; if(virtualWorldVertices) delete virtualWorldVertices; if(virtualWorldLights) delete virtualWorldLights; } /* nVirtualWorldLights = 4; virtualWorldLights = new Light[4]; nVirtualWorldVertices = 81; virtualWorldVertices = new Vector[nVirtualWorldVertices]; float b = 1.0f / sqrtf(2.0f); virtualWorldLights[0] = Light(Vector(10.0f, 0.0f, 14.0f), Vector(110000.0f, 110000.0f, 110000.0f), Vector(b, 0.0f, -b)); virtualWorldLights[1] = Light(Vector(-10.0f, 0.0f, 14.0f), Vector(110000.0f, 110000.0f, 110000.0f), Vector(-b, 0.0f, -b)); virtualWorldLights[2] = Light(Vector(0.0f, 10.0f, 14.0f), Vector(110000.0f, 110000.0f, 110000.0f), Vector(0.0f, b, -b)); virtualWorldLights[3] = Light(Vector(0.0f, -10.0f, 14.0f), Vector(110000.0f, 110000.0f, 110000.0f), Vector(0.0f, -b, -b)); virtualWorldSummedLightLuminance = virtualWorldLights[0].getLuminance() + virtualWorldLights[1].getLuminance() + virtualWorldLights[2].getLuminance() + virtualWorldLights[3].getLuminance() ; Material* tmat = new Material(Vector(0.6f, 0.6f, 0.1f), Vector(0.3f, 0.3f, 0.3f), 3.0f); // Material* glass = new Material(Vector(0.1f, 0.5f, 0.1f), Vector(0.15f, 0.15f, 0.15f), 3.0f); // glass->makeRefractiveAndIdeal(0.95f, Vector(0.7f, 0.6f, 0.5f), Vector(0.25f, 0.2f, 0.15f)); // Material* woodmat = new WoodMaterial(); nVirtualWorldObjects = 7; virtualWorldObjects = new Intersectable*[19]; TriangleMesh* pot = new TriangleMesh(isc, tmat); // TriangleMesh* not = new TriangleMesh(isc, &Material::YELLOWPLASTIC); Transformed* trs; trs = new Transformed(pot); virtualWorldObjects[6] = trs; //dragon: // trs->scale(0.08f); // trs->rotateY(3.14f); // trs->rotateX(1.55f); // trs->rotateY(0.3f); // trs->translate(Vector(0.0f, -16.5f, 0.0f)); // trs = new Transformed(not); // virtualWorldObjects[6] = trs; trs->scale(2.9f); // trs->rotateZ(1.55f); // trs->translate(Vector(0.0f, -7.0f, 10.0f)); // trs->translate(Vector(y%3 * 10.0f - 10.0f, (y/3) * 10.0f - 10.0f, 0.0f)); virtualWorldObjects[0] = new PlaneZAligned(-15.0f, true, &Material::DIFFUSEORANGE); virtualWorldObjects[1] = new PlaneZAligned(50.0f, false, &Material::DIFFUSEWHITE); virtualWorldObjects[2] = new PlaneXAligned(-15.0f, true, &Material::DIFFUSELIGHTBLUE); virtualWorldObjects[3] = new PlaneXAligned(15.0f, false, &Material::DIFFUSEGREEN); virtualWorldObjects[4] = new PlaneYAligned(-15.0f, true, &Material::DIFFUSEYELLOW); virtualWorldObjects[5] = new PlaneYAligned(15.0f, false, &Material::DIFFUSEORANGE); // virtualWorldObjects[6] = new Cylinder(Vector(-11.0f, 0.0f, -28.0f), 15.0f, 35.0f, -25.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[7] = new Sphere(Vector(3.3f, 2.8f, 5.0f), 2.0f, glass); // virtualWorldObjects[8] = new Cylinder(Vector(-15.0f, 0.0f, 10.0f), 2.5f, 15.0f, -15.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[9] = new Cylinder(Vector(-15.0f, 0.0f, 0.0f), 2.5f, 15.0f, -15.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[10] = new Cylinder(Vector(-15.0f, 0.0f, -10.0f), 2.5f, 15.0f, -15.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[11] = new Cylinder(Vector(-10.0f, 0.0f, -15.0f), 2.5f, 15.0f, -15.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[12] = new Cylinder(Vector(0.0f, 0.0f, -15.0f), 2.5f, 15.0f, -15.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[13] = new Cylinder(Vector(15.0f, 0.0f, 10.0f), 2.5f, 15.0f, -15.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[14] = new Cylinder(Vector(15.0f, 0.0f, 0.0f), 2.5f, 15.0f, -15.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[15] = new Cylinder(Vector(15.0f, 0.0f, -10.0f), 2.5f, 15.0f, -15.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[16] = new Cylinder(Vector(10.0f, 0.0f, -15.0f), 2.5f, 15.0f, -15.0f, &Material::DIFFUSEWHITE); // virtualWorldObjects[17] = new Sphere(Vector(10.0f, -12.99f, -3.0f), 2.0f, glass); // virtualWorldObjects[18] = new Sphere(Vector(-10.0f, -12.99f, 5.0f), 2.0f, glass); // virtualWorldObjects[0] = new Sphere(Vector(0.0f, 1.0f, 0.0f), 2.0f, &Material::DIFFUSEWHITE); */ void World::createEnvironmentMap(std::istream& isc) { int division = 1; const Material* material = &Material::DIFFUSEORANGE; Vector centre(0.0f, 0.0f, 0.0f); float radius = 10000.0f; char key[200]; do { isc >> key; if(strcmp(key,"radius") == 0) isc >> radius; else if(strcmp(key,"centre")==0) isc >> centre; else if(strcmp(key,"division")==0) isc >> division; else if(strcmp(key,"material") == 0) { isc >> key; for(int i=0; i < nVirtualWorldMaterials; i++) { material = virtualWorldMaterials[i]; if(strcmp(key, material->getName()) == 0) break; } } } while(strcmp(key,"end")!=0); { objectArraySize += division * division * 6; Intersectable** largerArray = new Intersectable*[objectArraySize]; for(int d=0;dyMin = (2.0 * radius / division) * q - radius; p->yMax = p->yMin + 2.0 * radius / division; p->zMin = (2.0 * radius / division) * w - radius; p->zMax = p->zMin + 2.0 * radius / division; p->bbox.minPoint.x = p->bbox.maxPoint.x = -radius; p->bbox.minPoint.y = p->yMin; p->bbox.maxPoint.y = p->yMax; p->bbox.minPoint.z = p->zMin; p->bbox.maxPoint.z = p->zMax; virtualWorldObjects[nVirtualWorldObjects] = p; nVirtualWorldObjects++; } } for(q=0; qyMin = (2.0 * radius / division) * q - radius; p->yMax = p->yMin + 2.0 * radius / division; p->zMin = (2.0 * radius / division) * w - radius; p->zMax = p->zMin + 2.0 * radius / division; p->bbox.minPoint.x = p->bbox.maxPoint.x = radius; p->bbox.minPoint.y = p->yMin; p->bbox.maxPoint.y = p->yMax; p->bbox.minPoint.z = p->zMin; p->bbox.maxPoint.z = p->zMax; virtualWorldObjects[nVirtualWorldObjects] = p; nVirtualWorldObjects++; } } for(q=0; qxMin = (2.0 * radius / division) * q - radius; p->xMax = p->xMin + 2.0 * radius / division; p->zMin = (2.0 * radius / division) * w - radius; p->zMax = p->zMin + 2.0 * radius / division; p->bbox.minPoint.y = p->bbox.maxPoint.y = -radius; p->bbox.minPoint.x = p->xMin; p->bbox.maxPoint.x = p->xMax; p->bbox.minPoint.z = p->zMin; p->bbox.maxPoint.z = p->zMax; virtualWorldObjects[nVirtualWorldObjects] = p; nVirtualWorldObjects++; } } for(q=0; qxMin = (2.0 * radius / division) * q - radius; p->xMax = p->xMin + 2.0 * radius / division; p->zMin = (2.0 * radius / division) * w - radius; p->zMax = p->zMin + 2.0 * radius / division; p->bbox.minPoint.y = p->bbox.maxPoint.y = radius; p->bbox.minPoint.x = p->xMin; p->bbox.maxPoint.x = p->xMax; p->bbox.minPoint.z = p->zMin; p->bbox.maxPoint.z = p->zMax; virtualWorldObjects[nVirtualWorldObjects] = p; nVirtualWorldObjects++; } } for(q=0; qyMin = (2.0 * radius / division) * q - radius; p->yMax = p->yMin + 2.0 * radius / division; p->xMin = (2.0 * radius / division) * w - radius; p->xMax = p->xMin + 2.0 * radius / division; p->bbox.minPoint.z = p->bbox.maxPoint.z = -radius; p->bbox.minPoint.y = p->yMin; p->bbox.maxPoint.y = p->yMax; p->bbox.minPoint.x = p->xMin; p->bbox.maxPoint.x = p->xMax; virtualWorldObjects[nVirtualWorldObjects] = p; nVirtualWorldObjects++; } } for(q=0; qyMin = (2.0 * radius / division) * q - radius; p->yMax = p->yMin + 2.0 * radius / division; p->xMin = (2.0 * radius / division) * w - radius; p->xMax = p->xMin + 2.0 * radius / division; p->bbox.minPoint.z = p->bbox.maxPoint.z = radius; p->bbox.minPoint.y = p->yMin; p->bbox.maxPoint.y = p->yMax; p->bbox.minPoint.x = p->xMin; p->bbox.maxPoint.x = p->xMax; virtualWorldObjects[nVirtualWorldObjects] = p; nVirtualWorldObjects++; } } }