#include "Scene.h" Light::Light() { position_ = Vector3DW(0, 0, 0); redIntensity_ = 0; greenIntensity_ = 0; blueIntensity_ = 0; } Light::Light(real redIntensity, real greenIntensity, real blueIntensity) { position_ = Vector3DW(0, 0, 0); redIntensity_ = redIntensity; greenIntensity_ = greenIntensity; blueIntensity_ = blueIntensity; } Light::Light(Vector3DW position, real redIntensity, real greenIntensity, real blueIntensity) { position_ = position; redIntensity_ = redIntensity; greenIntensity_ = greenIntensity; blueIntensity_ = blueIntensity; } Vector3DW Light::getPosition() { return position_; } void Light::setPosition(Vector3DW position) { position_ = position; } real Light::getRedIntensity() { return redIntensity_; } real Light::getGreenIntensity() { return greenIntensity_; } real Light::getBlueIntensity() { return blueIntensity_; } void Light::setRedIntensity(real redIntensity) { redIntensity_ = redIntensity; } void Light::setGreenIntensity(real greenIntensity) { greenIntensity_ = greenIntensity; } void Light::setBlueIntensity(real blueIntensity) { blueIntensity_ = blueIntensity; } void Light::setIntensity(real redIntensity, real greenIntensity, real blueIntensity) { redIntensity_ = redIntensity; greenIntensity_ = greenIntensity; blueIntensity_ = blueIntensity; } Scene::Scene(Color backColor, Light ambientLight) { objects_.clear(); lights_.clear(); backColor_ = backColor; ambientLight_ = ambientLight; } Color Scene::getBackColor() { return backColor_; } void Scene::setBackColor(Color backColor) { backColor_ = backColor; } Light Scene::getAmbientLight() { return ambientLight_; } void Scene::setAmbientLight(Light ambientLight) { ambientLight_ = ambientLight; } void Scene::clear() { objects_.clear(); lights_.clear(); } void Scene::addObject(Object3D* obj) { objects_.push_back(obj); } void Scene::addLight(Light* light) { lights_.push_back(light); } Color Scene::rayTrace(Vector3DW rOrigin, Vector3DW rDirection, bool& hitObject, int maxReflections) { Vector3DW intersectionPoint(0, 0, 0); Vector3DW intersectionNormal(0, 0, 0); real intersectionDistance; real ka = 0; real kd = 0; real ks = 0; Color color = backColor_; real ka1 = 0; real kd1 = 0; real ks1 = 0; Color color1 = backColor_; Vector3DW finalPoint(0, 0, 0); Vector3DW finalNormal(0, 0, 0); real minDistance = (real)999999999; rDirection.normalize(); hitObject = false; for(int i=0; irayIntersect(rOrigin, rDirection, intersectionPoint, intersectionNormal, intersectionDistance, color1, ka1, kd1, ks1)) { hitObject = true; if(intersectionDistance < minDistance) { minDistance = intersectionDistance; color = color1; ka = ka1; kd = kd1; ks = ks1; // objects_[i]->getMaterial()->getColorInfo(xTexture, yTexture, color, ka, kd, ks); finalPoint = intersectionPoint; finalNormal = intersectionNormal; } } } if(maxReflections == -1) return color; Vector3DW L, R, V, RE; real NL, RV; int r = 0; int g = 0; int b = 0; Color reflectedColor; bool hasShadow = false; V = rDirection * (real)-1; if(hitObject) { for(i=0; igetPosition() - finalPoint; L.normalize(); NL = finalNormal * L; // R = finalNormal * ((real)2 * NL) - L; R = L.reflectAround(finalNormal); if(NL<0) NL=0; RV = R * V; r += ambientLight_.getRedIntensity() * ka * ((real)color.getR()); g += ambientLight_.getGreenIntensity() * ka * ((real)color.getG()); b += ambientLight_.getBlueIntensity() * ka * ((real)color.getB()); if(NL>0) reflectedColor = rayTrace(finalPoint + L*(real)0.1, L, hasShadow, -1); if(!hasShadow) { if(NL>0) { r += (lights_[i]->getRedIntensity() * kd * ((real)color.getR()) * NL); g += (lights_[i]->getGreenIntensity() * kd * ((real)color.getG()) * NL); b += (lights_[i]->getBlueIntensity() * kd * ((real)color.getB()) * NL); } if(RV>0) { r += (lights_[i]->getRedIntensity() * (ks * (real)255) * pow(RV, 16)); g += (lights_[i]->getGreenIntensity() * (ks * (real)255) * pow(RV, 16)); b += (lights_[i]->getBlueIntensity() * (ks * (real)255) * pow(RV, 16)); } if((ks>0)&&(maxReflections>0)) { // RE = finalNormal * ((real)2 * (finalNormal * V)) - V; RE = V.reflectAround(finalNormal); reflectedColor = rayTrace(finalPoint + RE*(real)0.1, RE, hasShadow, maxReflections-1); r += ks * reflectedColor.getR(); g += ks * reflectedColor.getG(); b += ks * reflectedColor.getB(); } } if(r>255) r=255; if(g>255) g=255; if(b>255) b=255; color.setRGB((unsigned char)r, (unsigned char)g, (unsigned char)b); } } return color; } void Scene::drawOpenGL() { for(int i=0; idrawOpenGL(); } } Camera::Camera(Scene* scene, Vector3DW eye, Vector3DW at, Vector3DW up, real fovy, real nearp, real farp) { scene_ = scene; eye_ = eye; at_ = at; up_ = up; fovy_ = fovy; nearp_ = nearp; farp_ = farp; } Vector3DW Camera::getEye() { return eye_; } Vector3DW Camera::getAt() { return at_; } Vector3DW Camera::getUp() { return up_; } void Camera::setEye(Vector3DW eye) { eye_ = eye; } void Camera::setAt(Vector3DW at) { at_ = at; } void Camera::setUp(Vector3DW up) { up_ = up; } void Camera::rayTrace(unsigned char* data, int width, int height) { if(data==NULL) return; if(scene_==NULL) return; Vector3DW view = at_ - eye_; Vector3DW Ze = view * (-1.0/view.getNorm()); Vector3DW Xe = (up_ % Ze); Xe.normalize(); Vector3DW Ye = Ze % Xe; real A = nearp_; real B = A*tan(fovy_/2.0); real C = (B*(real)width)/(real)height; Vector3DW Pii = (Ze*A + Ye*B + Xe*C)*-1; Vector3DW u = Xe*((2*C)/(real)width); Vector3DW v = Ye*((2*B)/(real)height); int index; Color pixelColor(0, 0, 0); bool baux; for(int i=0; irayTrace(eye_, Pii + u*xMult + v*yMult, baux, 1); data[index ] = pixelColor.getR(); data[index+1] = pixelColor.getG(); data[index+2] = pixelColor.getB(); } } } void Camera::zBuffer(unsigned char* data, int width, int height) { glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* gluLookAt( at_.getX(), at_.getY(), at_.getZ(), eye_.getX(), eye_.getY(), eye_.getZ(), up_.getX(), up_.getY(), up_.getZ() ); scene_->drawOpenGL(); */ glTranslatef(10, 0, 0); glColor3d(1, 0, 0); glutSolidSphere(5, 32, 32); glFlush(); glReadBuffer(GL_BACK); glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); } StereoscopicCamera::StereoscopicCamera(Scene* scene, Vector3DW midEye, real distEyes, Vector3DW at, Vector3DW up, real fovy, real nearp, real farp) { scene_ = scene; midEye_ = midEye; distEyes_ = distEyes; at_ = at; up_ = up; fovy_ = fovy; nearp_ = nearp; farp_ = farp; redFactor_ = 1.0; greenFactor_ = 1.0; blueFactor_ = 1.0; leftCamera_ = NULL; rightCamera_ = NULL; setCameras(); } StereoscopicCamera::~StereoscopicCamera() { deleteCameras(); } void StereoscopicCamera::deleteCameras() { if(leftCamera_) delete(leftCamera_); if(rightCamera_) delete(rightCamera_); leftCamera_ = NULL; rightCamera_ = NULL; } void StereoscopicCamera::setCameras() { Vector3DW eyeOffset = up_ % (at_ - midEye_); eyeOffset.normalize(); eyeOffset = eyeOffset * (distEyes_ / 2.0); deleteCameras(); leftCamera_ = new Camera(scene_, midEye_ + eyeOffset, at_, up_, fovy_, nearp_, farp_); rightCamera_ = new Camera(scene_, midEye_ - eyeOffset, at_, up_, fovy_, nearp_, farp_); } Vector3DW StereoscopicCamera::getMidEye() { return midEye_; } real StereoscopicCamera::getDistEyes() { return distEyes_; } Vector3DW StereoscopicCamera::getAt() { return at_; } Vector3DW StereoscopicCamera::getUp() { return up_; } void StereoscopicCamera::setMidEye(Vector3DW midEye) { midEye_ = midEye; setCameras(); } void StereoscopicCamera::setDistEyes(real distEyes) { distEyes_ = distEyes; setCameras(); } void StereoscopicCamera::setAt(Vector3DW at) { at_ = at; setCameras(); } void StereoscopicCamera::setUp(Vector3DW up) { up_ = up; setCameras(); } void StereoscopicCamera::setColorFactors(real redFactor, real greenFactor, real blueFactor) { redFactor_ = redFactor; greenFactor_ = greenFactor; blueFactor_ = blueFactor; } void StereoscopicCamera::rayTrace(unsigned char* data, int width, int height) { if(data==NULL) return; if(scene_==NULL) return; if(leftCamera_==NULL) return; if(rightCamera_==NULL) return; int index = 0; unsigned char* img_aux = (unsigned char*)malloc(width*height*3); leftCamera_->rayTrace(data, width, height); rightCamera_->rayTrace(img_aux, width, height); for(int i=0; i