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

📄 scene.cpp

📁 file code.zip are used to implement ray tracing technology.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "scene.h"

#define CLOSE(X, Y)		(fabs((X) - (Y)) < 0.00001)

Scene::Scene(string fname)   
{ //constructor that also reads in an SDL file 
		Scene(); read(fname); 
} 


void Scene::freeScene()  
{ // release the object and light lists 
	GeomObj *p = obj; 
	while(p) 
	{ 
		GeomObj* q = p; 
		p = p->next; 
		delete q; 
	} 
	Light * q = light; 
	while(q) 
	{ 
		Light* r = q; 
		q = q->next; 
		delete r; 
	} 
} 

string Scene::nexttoken(void) 
{
	char c;
	string token;
	int lastchar = 1;
	if (!f_in) {return(token); }
	if (f_in->eof()) {return(token);}
	while (f_in->get(c))
	{
		if (f_in->eof()) {
			return(token);
		}
		switch (c) {
		case '\n': nextline += 1;
		case ' ' :
		case '\t':
		case '\a':
		case '\b':
		case '\v':
		case '\f':
		case '\r': {
			if ( lastchar == 0 ) {return(token);}break; }
		case '{': {
			token = c; return(token); break;}
		case '}': {
			token = c;
			return(token);
			break; }
		case '!': {
			while ( c != '\n' && f_in->get(c)) {
			}
			nextline++; break;}
		default: {
			token = token + c;
			lastchar = 0;

			if ((f_in->peek() == '{') ||
				(f_in->peek() == '}') ) {
				if ( lastchar == 0 ) {
					return(token);
				} else {
					f_in->get(c);
					token = c;
					return(token);
				}
			}
			line = nextline;
					}
		}
	}
	return(" ");
} 

//<<<<<<<<<<<<<<< Scene :: read >>>>>>>>>>>>>>>> 
bool Scene:: read(string fname)// return true if ok; else false 
{ 
	file_in = new ifstream(fname.c_str()); 
	if(!(*file_in)) 
	{  
		cout << "I can't find or open file: " << fname << endl;  
		return false; 
	} 
	f_in = new strstream(); 
	line = nextline = 1; 
	def_stack = new DefUnitStack(); 
	char ch; 
	freeScene(); //delete any previous scene 
	 
	// initialize all for reading: 
	obj = tail = NULL; 
	light = NULL; 
	affStk.tos = new AffineNode; 
	affStk.tos->next = NULL; 
	 
	while (file_in->get(ch)) {*f_in << ch;} // read whole file 
	while(1) //read file, collecting objects, until EOF or an error 
	{ 
		GeomObj * shp = getObject(); // get the next shape 
		if(!shp) break; // no object: either error or EOF 
		shp->next = NULL; // to be safe 
		if(obj == NULL){ obj = tail = shp;} // empty list so far 
		else{tail->next = shp; tail = shp;} // add new object to queue 
	}	
	file_in->close(); 
	cleanUp(); // delete temp lists, etc. 
	return true; 
} 

float Scene::getFloat() 
{ 
	strstream tmp; 
	float number; 
	string str = nexttoken();   
		tmp << str; 
	if(!(tmp >> number)) 
	{ 
		cerr << "Line " << line << ": error getting float" << endl; 
		exit(-1); 
	} 
	else  
	{ 
		char t; 
		if ( (tmp >> t ) )  
		{ 
			cerr << "Line " << line << ": bum chars in number" << endl; 
			exit(-1);     
		}  
	} 
	return number; 
} 

bool Scene::isidentifier(string keyword) { 
	string temp = keyword; 
	if (!isalpha(temp[0])) return(false); 
	for (unsigned int count = 1; count < temp.length(); count++) { 
		if ((!isalnum(temp[count]))&& (temp[count]!='.')) return(false); 
	} 
	return(true); 
} 

void Scene::cleanUp()  
{
	// release stuff after parsing file 
	affStk.releaseAffines(); 		//delete affine stack 
	def_stack->release(); 
	delete def_stack; // release the DefUnitStack memory 
} 


Scene::TokenType Scene::whichtoken(string keyword)  
{ 
	string temp = keyword; 
	if ( temp == "light" )            return (LIGHT); 
	if ( temp == "rotate" )           return (ROTATE); 
	if ( temp == "translate" )        return (TRANSLATE); 
	if ( temp == "scale")             return (SCALE); 
	if ( temp == "push")        	  return (PUSH); 
	if ( temp == "pop")				  return (POP); 
	if ( temp == "identityAffine")    return (IDENTITYAFFINE); 
	if ( temp == "cube")              return (CUBE); 
	if ( temp == "sphere")            return (SPHERE); 
	if ( temp == "torus")             return (TORUS); 
	if ( temp == "plane")             return (PLANE); 
	if ( temp == "checkerboard")      return (CHECKERBOARD); 
	if ( temp == "square")            return (SQUARE); 
	if ( temp == "cylinder")          return (CYLINDER); 
	if ( temp == "taperedCylinder")   return (TAPEREDCYLINDER); 
	if ( temp == "cone")              return (CONE); 
	if ( temp == "tetrahedron")       return (TETRAHEDRON);
	if ( temp == "octahedron")        return (OCTAHEDRON); 
	if ( temp == "dodecahedron")      return (DODECAHEDRON); 
	if ( temp == "icosahedron")       return (ICOSAHEDRON); 
	if ( temp == "buckyball")         return (BUCKYBALL); 
	if ( temp == "diamond")           return (DIAMOND); 
	if ( temp == "teapot")			  return (TEAPOT); 
	if ( temp == "union")             return (UNION); 
	if ( temp == "intersection")      return (INTERSECTION); 
	if ( temp == "difference")        return (DIFFERENCEa); 
	if ( temp == "mesh")              return (MESH);
	if ( temp == "makePixmap")        return (MAKEPIXMAP); 
	if ( temp == "defaultMaterials")  return (DEFAULTMATERIALS); 
	if ( temp == "ambient")           return (AMBIENT); 
	if ( temp == "diffuse")           return (DIFFUSE); 
	if ( temp == "specular")          return (SPECULAR); 
	if ( temp == "specularFraction")  return (SPECULARFRACTION); 
	if ( temp == "surfaceRoughness")  return (SURFACEROUGHNESS); 
	if ( temp == "emissive")          return (EMISSIVE); 
	if ( temp == "specularExponent")  return (SPECULAREXPONENT);
	if ( temp == "speedOfLight")      return (SPEEDOFLIGHT); 
	if ( temp == "transparency")      return (TRANSPARENCY); 
	if ( temp == "reflectivity")      return (REFLECTIVITY); 
	if ( temp == "parameters")        return (PARAMETERS); 
	if ( temp == "texture")			  return (TEXTURE); 
	if ( temp == "globalAmbient")	  return (GLOBALAMBIENT); 
	if ( temp == "minReflectivity")	  return (MINREFLECTIVITY); 
	if ( temp == "minTransparency")	  return (MINTRANSPARENCY); 
	if ( temp == "maxRecursionDepth") return (MAXRECURSIONDEPTH); 
	if ( temp == "background")        return (BACKGROUND); 
	if ( temp == "{")                 return (LFTCURLY); 
	if ( temp == "}")                 return (RGHTCURLY); 
	if ( temp == "def")               return (DEF); 
	if ( temp == "use")               return (USE); 
    if ( temp == "eye")				  return (EYE);
    if ( temp == "lookAt")			  return (LOOKAT);
    if ( temp == "up")				  return (UP);
    if ( temp == "nearPlane")		  return (NEARPLANE);
    if ( temp == "farPlane")		  return (FARPLANE);
    if ( temp == "viewAngle")		  return (VIEWANGLE);
	if ( temp == " " )                return (T_NULL); 
	if ( isidentifier(temp) )         return (IDENT); 
	//cout << temp << ":" << temp.length() << endl; 
	return(UNKNOWN);
}

// <<<<<<<<<<<<<< Scene :: getObject >>>>>>>>>>>>>>>
GeomObj* Scene :: getObject() 
{ //reads tokens from stream f_in (a data member of Scene), 
	// building lights, getting materials, doing transformations, 
	// until it finds a new object 
	// returns NULL if any error occurs, or end of file 
	string s;			 
	GeomObj * newShape; 
	TokenType typ; 
	while ((typ = (whichtoken( s = nexttoken() ))) != T_NULL)  
	{ 
		if(typ == UNION || typ == INTERSECTION || typ == DIFFERENCEa) 
		{ 
			switch(typ)
			{
			case UNION:				newShape = new UnionBool();	break;
			case INTERSECTION:		newShape = new IntersectionBool();	break;
			case DIFFERENCEa:		newShape = new DifferenceBool();break;
			} // end of little switch
			GeomObj* p = newShape;
			p = getObject(); // get left child
			if(!p) return NULL; // Error! should always get an object
			((Boolean*)newShape)->left  = p; // hook it up
			p = getObject();// get right child
			if(!p) return NULL;
			((Boolean*)newShape)->right = p; // hook it up
			return newShape;
		}// end of if(typ == UNION etc.... 

		switch(typ)  
		{ 
		case LIGHT: { 
			Point3 p; 
			Color3 c; 
			p.x = getFloat(); p.y = getFloat();	p.z = getFloat(); 
			c.red = getFloat(); c.green = getFloat();	c.blue = getFloat(); 
			Light *l = new Light; 
			l->setPosition(p); 
			l->setColor(c); 
			l->next = light; //put it on the list 
			light = l; break;} 
		case ROTATE: { 
			float angle; 
			Vector3 u; 
			angle = getFloat(); u.x = getFloat();  
			u.y = getFloat(); u.z = getFloat(); 
			affStk.rotate(angle,u);break;} 
		case TRANSLATE: { 
			Vector3 d; 
			d.x = getFloat(); d.y = getFloat(); d.z = getFloat(); 
			affStk.translate(d);break;} 
		case SCALE: { 
			float sx, sy, sz; 
			sx = getFloat(); sy = getFloat(); sz = getFloat(); 
			affStk.scale(sx, sy, sz);break;} 
		case PUSH: affStk.dup(); break;  
		case POP:  affStk.popAndDrop(); break; 
		case IDENTITYAFFINE: affStk.setIdentity();break;		 
		case AMBIENT: { 
			float dr, dg, db; 
			dr = getFloat(); dg = getFloat(); db = getFloat(); 
			currMtrl.ambient.set(dr,dg,db); break;} 
		case DIFFUSE: { 
			float dr,dg,db; 
			dr = getFloat(); dg = getFloat(); db = getFloat(); 
			currMtrl.diffuse.set(dr,dg,db); break;} 
		case SPECULAR:{  
			float dr,dg,db; 
			dr = getFloat(); dg = getFloat(); db = getFloat(); 
			currMtrl.specular.set(dr,dg,db); break;} 
		case EMISSIVE: { 
			float dr,dg,db; 
			dr = getFloat(); dg = getFloat(); db = getFloat(); 
			currMtrl.emissive.set(dr,dg,db); break;} 
		case PARAMETERS: { // get a list of numParams parameters 
			currMtrl.numParams = (int)getFloat(); 
			for(int i = 0; i < currMtrl.numParams; i++) 
				currMtrl.params[i] = getFloat(); 
			break;}			 
		case SPECULARFRACTION: currMtrl.specularFraction = getFloat(); break; 
		case SURFACEROUGHNESS: currMtrl.surfaceRoughness = getFloat(); break; 
		case TEXTURE: { // get type, 0 for none 
				currMtrl.textureType = (int)getFloat();} 
				break; 
		case DEFAULTMATERIALS: 	currMtrl.setDefault();break; 
		case SPEEDOFLIGHT: currMtrl.speedOfLight = getFloat(); break; 
		case SPECULAREXPONENT: currMtrl.specularExponent = getFloat(); break; 
		case TRANSPARENCY:currMtrl.transparency = getFloat(); break; 
		case REFLECTIVITY: currMtrl.reflectivity = getFloat(); break; 
		case GLOBALAMBIENT: 
			ambient.red = getFloat(); ambient.green = getFloat(); 
			ambient.blue = getFloat(); break; 
		case BACKGROUND:  
			background.red = getFloat(); 
			background.green = getFloat();  
			background.blue = getFloat();break; 
		case MAKEPIXMAP: {	// get BMP file name for a pixmap
			// to be implemented, along the lines:
			int which = getFloat();// index of this pixmap in pixmap array
			if(which < 0 || which > 7){cout << "\nbad index of RGBpixmap!\n";}
			string fname = nexttoken(); // get file name for mesh
			
			
			if(!pixmap[which].readBMPFile(fname))
			{// read BMP file into this pixmap
			cout << " \ncan't read that RGBpixmap file!\n";
			return NULL;  }
			pixmap[which].setTexture (currMtrl.textureType );
			pixmap[which].draw();
			/*GeomObj * p= newShape;

			p = getObject();
			
			if( p == new Plane) {
				pixmap[which].getObj(p);
				
				bindTexture(currMtrl.textureType );
				}*/
			
			
			
			break;}// end of case: MAKEPIXMAP
		case MINREFLECTIVITY: minReflectivity = getFloat(); break; 
		case MINTRANSPARENCY:minTransparency = getFloat(); break; 
		case MAXRECURSIONDEPTH: maxRecursionDepth = (int)getFloat(); break; 
		case T_NULL: break; // The null token represents end-of-file  
		case DEF: { 
			string name, temp, lb, rb; 
			int l = line; 

⌨️ 快捷键说明

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