// add extra methods here void MyScene::rayTrace(Point3 point, Vector3 ray){ HitRecord* hits = new HitRecord(); transformStack.clear(); transformStack.push_back(Matrix4::identity()); castRayAgainstSubgraph(point, ray, root, hits); bool gotHit; double tH, uH, vH; Point3 pH; Vector3 nH; gotHit = hits->getFirstHit(tH, uH, vH, pH, nH); delete hits; int col, row; getScreenCoord(point+ray, col, row); int idx = pxIdx(col, row); if (gotHit){ for (Light& l : lights){ Point3 lPos = l.getPos(); castLight(lPos, pH, l, 0, 0, NULL); } } else{ pixelArray[idx] = (unsigned char)(background[0] * 255); pixelArray[idx + 1] = (unsigned char)(background[1] * 255); pixelArray[idx + 2] = (unsigned char)(background[2] * 255); } }
bool EditOptions::getScreenSize(int &width, int &height) { bool gotPos = false; OovStatus status = readFile(); if(status.ok()) { int tempWidth; if(getScreenCoord("ScreenWidth", tempWidth)) { int tempHeight; if(getScreenCoord("ScreenHeight", tempHeight)) { width = tempWidth; height = tempHeight; gotPos = true; } } } else { status.report(ET_Info, "Unable to get screen size"); } return gotPos; }
void MyScene::castLight(const Point3& src, const Point3& dst, Light& l, int depth, double distance, Color* reflectedColor){ Vector3 ray = dst - src; ray.normalize(); HitRecord* hits = new HitRecord(); castRayAgainstSubgraph(src, ray, root, hits); double t, u, v; Point3 p; Vector3 n; hits->getFirstHit(t, u, v, p, n); Object* o = (Object*)hits->getFirstHitObj(); delete hits; int col, row; getScreenCoord(dst, col, row); int idx = pxIdx(col, row); Color screenColor = Color(pixelArray[idx] / (float)255, pixelArray[idx+1] / (float)255, pixelArray[idx+2] / (float)255); //ambient screenColor[0] += o->ambient[0]; screenColor[1] += o->ambient[1]; screenColor[2] += o->ambient[2]; //not in shadow double diff = (dst - p).length(); if (diff < EPSILON){ Color lightColor = l.getColor(); distance += (dst-src).length(); Point3 falloff = l.getFalloff(); double attenuation = 1 / (double)(falloff[0] + falloff[1] * distance + falloff[2] * distance*distance); //diffuse double dot = n*(-ray); if (dot > 0){ screenColor[0] += (GLfloat)(o->diffuse[0] * lightColor[0] * attenuation*dot); screenColor[1] += (GLfloat)(o->diffuse[1] * lightColor[1] * attenuation*dot); screenColor[2] += (GLfloat)(o->diffuse[2] * lightColor[2] * attenuation*dot); } //reflect ++depth; if ((depth < MAX_RECURSION_DEPTH) && (attenuation > EPSILON)){ Vector3 reflectedRay = 2 * (ray * n) * n - ray; reflectedRay.normalize(); Point3 newSrc = p + EPSILON*reflectedRay; Point3 newDst = p + reflectedRay; double r = o->reflect[0] * lightColor[0] * attenuation*dot; double g = o->reflect[1] * lightColor[1] * attenuation*dot; double b = o->reflect[2] * lightColor[2] * attenuation*dot; if (r > INVISIBLE || g > INVISIBLE || b > INVISIBLE){ Color* reflect = new Color((GLfloat)r, (GLfloat)g, (GLfloat)b); castLight(newSrc, newDst, l, depth, distance, reflect); delete reflect; } } //specular Vector3 reflection = ray - 2 * n*(ray*n); reflection.normalize(); Vector3 look = camera.getLook(); look.normalize(); dot = reflection*(-look); if (dot > 0){ screenColor[0] += (GLfloat)(o->specular[0] * lightColor[0] * attenuation * pow(dot, o->shine)); screenColor[1] += (GLfloat)(o->specular[1] * lightColor[1] * attenuation * pow(dot, o->shine)); screenColor[2] += (GLfloat)(o->specular[2] * lightColor[2] * attenuation * pow(dot, o->shine)); } } if (screenColor[0] > 1){ screenColor[0] = 1; } if (screenColor[1] > 1){ screenColor[1] = 1; } if (screenColor[2] > 1){ screenColor[2] = 1; } pixelArray[idx] = (unsigned char)roundToNearest(screenColor[0]*255); pixelArray[idx + 1] = (unsigned char)roundToNearest(screenColor[1] * 255); pixelArray[idx + 2] = (unsigned char)roundToNearest(screenColor[2] * 255); }