?? scene.cpp
字號:
#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 + -