⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scene.cpp

📁 file code.zip are used to implement ray tracing technology.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			string inp; 
			name = nexttoken(); 
			if ( whichtoken(name) != IDENT ) { 
				cout << "Error:  Identifier expected." << endl; 
				return NULL; 
			} 
			if ( def_stack->search(name) ) { 
				cout << line << ": " << name; 
				cout << ": attempt to redefine. " << endl; 
				return NULL; 
			} 
			lb = nexttoken(); 
			if ( whichtoken(lb) != LFTCURLY ) { 
				cout << "Error: { expected." << endl; 
				return NULL; 
			} 
			while ( whichtoken( temp = nexttoken()) != RGHTCURLY ) { 
				//cout << temp << endl; 
				inp = inp + temp + " "; 
				if (!f_in) { 
					cout << "Error: end of file detected." << endl; 
					return NULL; 
				} 
			} 
			// Push the contents of the string on the stack. 
			def_stack->push(name, inp); 
			break;} // end of case: DEF 
		case USE:
		{ 
			string name; 
			name = nexttoken(); 
			if ( whichtoken(name) != IDENT ) { 
				cout << line << ": " << name; 
				cout << ": identifier expected."; 
				return NULL; 
			} 
			if (! def_stack->search(name) ) { 
				cout << line << ": " << name; 
				cout << ": not defined."; 
				return NULL; 
			} 
		//	cout << def_stack->contents(name) << endl; 
			temp_fin = new strstream; 
			*temp_fin << def_stack->contents(name);
			 
			char *c = new char[temp_fin->pcount()];
			int n = temp_fin->pcount() ;
			int i = n - 1;
			while(temp_fin->get(c[i])){
			 i--;
			}
			i++;
			while(i< n)
			  f_in->putback(c[i++]);
			delete(c);
		}
		break; // end of case: USE 

        // Camera Definitions
        case EYE:
            eye.x = getFloat();
            eye.y = getFloat();
            eye.z = getFloat();
            break;

        case LOOKAT:
            lookAt.x = getFloat();
            lookAt.y = getFloat();
            lookAt.z = getFloat();
            break;

        case UP:
            up.x = getFloat();
            up.y = getFloat();
            up.z = getFloat();
            break;

        case NEARPLANE:
            nearPlane = getFloat();
            break;

        case FARPLANE:
            farPlane = getFloat();
            break;

        case VIEWANGLE:
            angle = getFloat();
            break;

		default:  { // inner switch for Shapes 
			switch(typ)  
			{ 
			case SQUARE:		newShape = new Square; 
				
				break;
			case CUBE:			newShape = new Cube; 
				newShape->drawOpenGL();
				break;
			case SPHERE:		newShape = new Sphere;
				
				break;
			case TORUS:			newShape = new Torus;break; 
			case PLANE:			newShape = new Plane;break; 
			case CHECKERBOARD:	newShape = new Checkerboard(getFloat(), getFloat()); break; 

			case TAPEREDCYLINDER:	newShape = new TaperedCylinder;  
				((TaperedCylinder*)newShape)->smallRadius = getFloat(); break; 
			case CONE:			newShape = new Cone; break;
			case CYLINDER:		newShape = new Cylinder; break; 

			case OCTAHEDRON:	newShape = new Octahedron; break; 
			case TETRAHEDRON:	newShape = new Tetrahedron; break; 
			case DODECAHEDRON:	newShape = new Dodecahedron; break; 
			case ICOSAHEDRON:	newShape = new Icosahedron; break; 
			case BUCKYBALL:		newShape = new BuckyBall; break; 
			case DIAMOND:		newShape = new Diamond; break; 

			case TEAPOT:		newShape = new Teapot; break; 

			case MESH: {// get a filename (with extension) for this mesh		 
				string fname = nexttoken(); // get file name for mesh 
				newShape = new Mesh(fname); break; 
				}// end of case: MESH 
		   default: { 
				cerr << "Line " << nextline << ": unknown keyword " << s << endl; 
				return NULL; 
			    }	 
			} // end of inner switch 

			// common things to do to all Shapes 
		   ((Shape*)newShape)->mtrl.set(currMtrl); 

		   // load transform and its inverse 
		   ((Shape*)newShape)->transf.set(*(affStk.tos->affn)); 
		   ((Shape*)newShape)->invTransf.set(*(affStk.tos->invAffn)); 

		   return newShape; 
		}// end of default: block			 
    } // end of outer switch 
  }  // end of while
 return NULL; 
}  


void Scene::makeLightsOpenGL(void)
{
	if(light == NULL)
		return;
	GLfloat light_position[] = { light->pos.x, light->pos.y, light->pos.z, 0};
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	glEnable(GL_LIGHT0);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_DEPTH_TEST);		 
	return;
}

void Scene::drawSceneOpenGL(void)
{
	for(GeomObj *p = obj; p; p=p->next)
	   p->drawOpenGL();
	return;
}

void Scene::drawSceneCanvas(void)
{
	for(GeomObj *p = obj; p; p=p->next)
	   p->drawCanvas();
	return;
}

void Scene::printScene(void)
{
	for(GeomObj *p=obj; p; p=p->next)
	   p->print();
	return;
}

void Scene::xfrmNormal(Vector3 &N2, Affine4 transf, Vector3 &N1)
{
    float v[4];
    N1.build4tuple(v);
    Affine4 t;
    transf.transpose(t);
    t.applyTransform(v);
    N2.set(v[0],v[1],v[2]);
    return;
}

Color3 Scene::shade(Ray &ray)
{
	Color3 color(0, 0, 0);
	Intersection best;

	// Retrieve the first object intersection
	getFirstHit(ray, best);

	// If not intersection then return background color
	if(best.numHits == 0) {
		return background;
	}

    // The point of intersection
    Point3 p = ray.calculatePointOnRay(best.hit[0].hitTime);

	// Retrieve pointer to object hit
	Shape *myObj = (Shape*)best.hit[0].hitObject;

    // The surfact normal at the point of intersection
    Vector3 N;
    xfrmNormal(N, myObj->invTransf, best.hit[0].hitNormal);
    N.normalize();

	// Only compute surface properties when entering (not when exiting)
	// Calculate the local intensity
	color = phongLighting(myObj->mtrl, p, N, ray);

	// Calculate color contribution from reflections and refractions
	if(ray.getRecurseLevel() == maxRecursionDepth) return color;
	if(myObj->mtrl.reflectivity > 0) spawnReflectedRay(myObj->mtrl, p, N, ray, color);

	return color;
}

void Scene::spawnReflectedRay(Material mtrl, Point3 p, Vector3 N, Ray ray, Color3 &color)
{
    // Increment counter
    reflRays++;

    // Calculate the reflection direction
    Vector3 newDir(ray.getDir());
    newDir.normalize();
    float f = 2 * newDir.dot(N);
    Vector3 temp;
    temp.set(N);
    temp.scale(f);
    temp.flip();
    newDir.add(temp);
    newDir.normalize();

    // Create the reflection ray
    Ray reflected(p, newDir);
    reflected.nudgeForward(mtrl.nudgeValue);
    reflected.setRecurseLevel(ray.getRecurseLevel() + 1);

    // Add the color contribution
    Color3 reflectColor;
    reflectColor = shade(reflected);
    reflectColor.scale(mtrl.reflectivity);

    // Set the resulting color
    color.add(reflectColor);
}

Color3 Scene::phongLighting(Material mtrl, Point3 p, Vector3 N, Ray ray)
{
    // Add emissive component and ambient component
	Color3 result;
    result.set(mtrl.emissive);
    result.add(ambient, mtrl.ambient);

    // View vector is always back along the ray (even when reflecting or refracting)
	Vector3 V(ray.getDir());
	V.flip();

	// Loop through the lights to calculate specular and diffuse
    for(Light *l = light; l != NULL; l=l->next)
    {
        // Increment the counter
        shadowRays++;

        // Check if the object is in shadow for this light
		Ray feeler(p); feeler.setDir(l);
        feeler.nudgeForward(mtrl.nudgeValue);
        if(isInShadow(feeler)) continue;

        // Calculate the diffuse component according to Lambert equation
        Vector3 L;
		L.setDiff(l->pos, p);
		L.normalize();

        float lambert = L.dot(N);
        if(lambert > 0.0f)
        {
            Color3 diffuseColor;
            diffuseColor.add(l->color, mtrl.diffuse);
            diffuseColor.scale(lambert);
            result.add(diffuseColor);
        }

        // Calculate the Specular component according to Blinn-Phong equation
        Vector3 H(L); H.add(V);
		if(!CLOSE(H.x*H.x + H.y*H.y + H.z*H.z, 0))
			H.normalize();

        float phong = H.dot(N);
        if(phong > 0.0f)
        {
            phong = pow(phong, mtrl.specularExponent);
            Color3 specularColor;
            specularColor.add(l->color, mtrl.specular);
            specularColor.scale(phong);
            result.add(specularColor);
        }

		// Add distance attenuation
		result.scale(feeler.getAttenuation());
    }

	return result;
}

void Scene::getFirstHit(Ray &ray, Intersection &best)
{
	Intersection inter;
	best.numHits = 0;

	for(GeomObj *pObj=obj; pObj != NULL; pObj = pObj->next)
	{
		if(!pObj->hit(ray, inter))
			continue;
	   
		if(best.numHits == 0 || inter.hit[0].hitTime < best.hit[0].hitTime)
			best.set(inter);
	}
}
  
bool Scene::isInShadow(Ray &feeler)
{
    Intersection i;
    float attenuate = 1.0;
    for(GeomObj* p = obj; p; p= p->next)
    {
        if(p->hit(feeler, i))
        {
            if(((Shape*)p)->mtrl.transparency == 0.0)
                return true;
            else attenuate *= ((Shape*)p)->mtrl.transparency;
        }
    }

    feeler.setAttenuation(attenuate);
    return false;
}
void Scene::bindTexture(int TextureType) 
{
	glEnable(GL_TEXTURE_2D);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glBindTexture(GL_TEXTURE_2D, TextureType); 
		
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -