00001
00002 #include <stdexcept>
00003
00004 #include "SceneBuilderFactories.h"
00005
00006 #include "Primitive.h"
00007 #include "Scene.h"
00008 #include "PerspectiveCamera.h"
00009 #include "DepthOfFieldCamera.h"
00010 #include "Vec3f.h"
00011 #include "PointLight.h"
00012 #include "QuadAreaLight.h"
00013 #include "CloudShader.h"
00014 #include "MirrorShader.h"
00015 #include "PhongShader.h"
00016 #include "TransparentShader.h"
00017 #include "CombineShader.h"
00018 #include "RefractiveShader.h"
00019 #include "RGBAColor.h"
00020 #include "Object.h"
00021 #include "QuotedString.h"
00022 #include "Texture.h"
00023 #include "Texture2D.h"
00024 #include "OBJObject.h"
00025 #include "SphereObject.h"
00026 #include "CookTorranceShader.h"
00027 #include "WoodShader.h"
00028 #include "PhysicsStep.h"
00029
00030
00037 Camera * PerspectiveCameraFactory::create(const std::string & type, std::stringstream & line)
00038 {
00039 if (type != "perspectivecamera")
00040 return NULL;
00041
00042
00043 Vec3f pos, dir, up;
00044 float angle;
00045 int x, y;
00046
00047 line.clear();
00048 line >> std::ws >> pos >> std::ws >> dir >> std::ws >> up;
00049 line.clear();
00050 line >> std::ws >> angle >> std::ws >> x >> std::ws >> y;
00051 line.clear();
00052
00053 return new PerspectiveCamera(pos, dir, up, angle, x, y);
00054 }
00055
00056
00063 Camera * DepthOfFieldCameraFactory::create(const std::string & type, std::stringstream & line)
00064 {
00065 if (type != "depthoffieldcamera")
00066 return NULL;
00067
00068
00069
00070 Vec3f pos, dir, up;
00071 float angle, focus, aperture;
00072 int x, y, samples;
00073
00074 line.clear();
00075 line >> std::ws >> pos >> std::ws >> dir >> std::ws >> up;
00076 line >> std::ws >> angle >> std::ws >> x >> std::ws >> y;
00077 line >> std::ws >> samples >> std::ws >> focus >> std::ws >> aperture;
00078 line.clear();
00079
00080 DepthOfFieldCamera * cam = new DepthOfFieldCamera(pos, dir, up, angle, x, y);
00081 cam->setDepthSamples(samples);
00082 cam->setFocusDistance(focus);
00083 cam->setAperture(aperture);
00084 return cam;
00085 }
00086
00087
00094 Light * PointLightFactory::create(const std::string & type, std::stringstream & line)
00095 {
00096 if (type != "pointlight")
00097 return NULL;
00098
00099 RGBAColor intensity;
00100 Vec3f position;
00101
00102 line.clear();
00103 line >> std::ws >> intensity >> std::ws >> position;
00104 line.clear();
00105
00106 return new PointLight(intensity, position);
00107 }
00108
00109
00116 Light * QuadAreaLightFactory::create(const std::string & type, std::stringstream & line)
00117 {
00118 if (type != "quadarealight")
00119 return NULL;
00120
00121
00122 RGBAColor power;
00123 Vec3f position, v1, v2;
00124 int rays = 0;
00125
00126 line.clear();
00127 line >> std::ws >> power >> std::ws >> position >> std::ws >> v1 >> std::ws >> v2 >> std::ws >> rays;
00128 line.clear();
00129
00130 QuadAreaLight * ql = new QuadAreaLight(power, position, v1, v2);
00131 ql->setNumberOfRays(rays);
00132 return ql;
00133 }
00134
00135
00142 Texture * Texture2DFactory::create(const std::string & type, std::stringstream & line)
00143 {
00144 if (type != "texture2d")
00145 return NULL;
00146
00147 std::string tmp;
00148 QuotedString filename;
00149 Mode w;
00150 InterpolationMode i;
00151
00152 line.clear();
00153 line >> std::ws >> filename >> std::ws >> tmp >> std::ws;
00154 if (tmp == "WRAP")
00155 w = WRAP;
00156 else if (tmp == "REPEAT")
00157 w = REPEAT;
00158 else
00159 throw std::logic_error("Unknown wrap mode \"" + tmp + "\"");
00160 line >> tmp;
00161 if (tmp == "NEAREST")
00162 i = NEAREST;
00163 else if (tmp == "LINEAR")
00164 i = LINEAR;
00165 else
00166 throw std::logic_error("Unknown interpolation mode \"" + tmp + "\"");
00167 line.clear();
00168
00169 Texture2D * tex = new Texture2D(filename.str());
00170 tex->setWrapMode(w);
00171 tex->setInterpolationMode(i);
00172 return tex;
00173 }
00174
00175
00181 void TexturedShaderFactory::readTextures( std::stringstream & line,
00182 std::vector<Texture *> & texes )
00183 {
00184 std::string tmp;
00185 texes.clear();
00186
00187
00188 line.clear();
00189 line >> std::ws;
00190 while (!line.eof())
00191 {
00192 line >> tmp >> std::ws;
00193 line.clear();
00194 if (tmp == "endtex" || tmp == "notex")
00195 break;
00196 else if (tmp == "tex")
00197 {
00198
00199 line >> tmp >> std::ws;
00200 line.clear();
00201 Texture * tex = mTextures[tmp];
00202 if (!tex)
00203 throw std::logic_error("Undefined texture \"" + tmp + "\"");
00204 texes.push_back(tex);
00205 }
00206 else
00207 throw std::logic_error("Unknown token \"" + tmp + "\"");
00208 }
00209 }
00210
00211
00218 void TexturedShaderFactory::readBump( std::stringstream & line,
00219 Texture *& bump,
00220 float & bumppar )
00221 {
00222 std::string tmp;
00223 bump = NULL;
00224 bumppar = 0;
00225
00226
00227 line.clear();
00228 line >> std::ws >> tmp >> std::ws;
00229 if (tmp != "nobump")
00230 {
00231 if (tmp == "bump")
00232 {
00233
00234 line >> tmp >> std::ws;
00235 line.clear();
00236 bump = mTextures[tmp];
00237 if (!bump)
00238 throw std::logic_error("Undefined bump texture \"" + tmp + "\"");
00239 line >> bumppar >> std::ws;
00240 line.clear();
00241 }
00242 else
00243 throw std::logic_error("Unknown token \"" + tmp + "\"");
00244 }
00245
00246 }
00247
00248
00256 Shader * CloudShaderFactory::create(const std::string & type, std::stringstream & line, Scene * scene)
00257 {
00258 if (type != "cloudshader")
00259 return NULL;
00260
00261 Texture * bump = NULL;
00262 float bumppar = 0;
00263 RGBAColor col;
00264
00265
00266 readBump(line, bump, bumppar);
00267
00268
00269 line >> col;
00270 line.clear();
00271
00272 CloudShader * sh = new CloudShader(scene, col);
00273 if (bump)
00274 {
00275 sh->setBumpTexture(bump);
00276 sh->setBumpCoefficient(bumppar);
00277 }
00278
00279 return sh;
00280 }
00281
00282
00290 Shader * WoodShaderFactory::create(const std::string & type, std::stringstream & line, Scene * scene)
00291 {
00292 if (type != "woodshader")
00293 return NULL;
00294
00295 Texture * bump = NULL;
00296 float bumppar = 0;
00297 RGBAColor col;
00298
00299
00300 readBump(line, bump, bumppar);
00301
00302
00303 line >> col;
00304 line.clear();
00305
00306 WoodShader * sh = new WoodShader(scene, col);
00307 if (bump)
00308 {
00309 sh->setBumpTexture(bump);
00310 sh->setBumpCoefficient(bumppar);
00311 }
00312
00313 return sh;
00314 }
00315
00316
00324 Shader * MirrorShaderFactory::create(const std::string & type, std::stringstream & line, Scene * scene)
00325 {
00326 if (type != "mirrorshader")
00327 return NULL;
00328
00329 Texture * bump = NULL;
00330 float bumppar = 0;
00331 RGBAColor col;
00332
00333
00334 readBump(line, bump, bumppar);
00335
00336
00337 line >> col;
00338 line.clear();
00339
00340 MirrorShader * sh = new MirrorShader(scene, col);
00341 if (bump)
00342 {
00343 sh->setBumpTexture(bump);
00344 sh->setBumpCoefficient(bumppar);
00345 }
00346
00347 return sh;
00348 }
00349
00350
00358 Shader * PhongShaderFactory::create(const std::string & type, std::stringstream & line, Scene * scene)
00359 {
00360 if (type != "phongshader")
00361 return NULL;
00362
00363
00364
00365
00366 std::vector<Texture *> texes;
00367 Texture * bump = NULL;
00368 float bumppar = 0;
00369 RGBAColor col;
00370 float ka, kd, ks, ke;
00371
00372 readTextures(line, texes);
00373 readBump(line, bump, bumppar);
00374
00375
00376 line >> col >> std::ws >> ka >> std::ws >> kd >> std::ws >> ks >> std::ws >> ke;
00377 line.clear();
00378
00379 PhongShader * sh = new PhongShader(scene, col, ka, kd, ks, ke);
00380 if (bump)
00381 {
00382 sh->setBumpTexture(bump);
00383 sh->setBumpCoefficient(bumppar);
00384 }
00385 for (unsigned int i = 0; i < texes.size(); i++)
00386 sh->addTexture(texes[i]);
00387
00388 return sh;
00389 }
00390
00391
00399 Shader * CookTorranceShaderFactory::create(const std::string & type, std::stringstream & line, Scene * scene)
00400 {
00401 if (type != "cooktorranceshader")
00402 return NULL;
00403
00404
00405
00406
00407 std::vector<Texture *> texes;
00408 Texture * bump = NULL;
00409 float bumppar = 0;
00410 RGBAColor col;
00411 float ka, kd, ks, slope, lambda;
00412
00413 readTextures(line, texes);
00414 readBump(line, bump, bumppar);
00415
00416
00417 line >> col >> std::ws >> ka >> std::ws >> kd >> std::ws >> ks >> std::ws >> slope >> std::ws >> lambda;
00418 line.clear();
00419
00420 CookTorranceShader * sh = new CookTorranceShader(scene, col, ka, kd, ks, slope, lambda);
00421 if (bump)
00422 {
00423 sh->setBumpTexture(bump);
00424 sh->setBumpCoefficient(bumppar);
00425 }
00426 for (unsigned int i = 0; i < texes.size(); i++)
00427 sh->addTexture(texes[i]);
00428
00429 return sh;
00430 }
00431
00432
00440 Shader * TransparentShaderFactory::create(const std::string & type, std::stringstream & line, Scene * scene)
00441 {
00442 if (type != "transparentshader")
00443 return NULL;
00444
00445 RGBAColor col;
00446
00447
00448 line >> col;
00449 line.clear();
00450
00451 TransparentShader * sh = new TransparentShader(scene, col);
00452
00453 return sh;
00454 }
00455
00456
00464 Shader * CombineShaderFactory::create(const std::string & type, std::stringstream & line, Scene * scene)
00465 {
00466 if (type != "combineshader")
00467 return NULL;
00468
00469
00470 std::vector<Texture *> texes;
00471 std::pair<Shader *, float> lsh;
00472 std::pair<Shader *, float> tsh;
00473 bool b = false;
00474 std::string tmp;
00475
00476 readTextures(line, texes);
00477
00478
00479 line.clear();
00480 line >> std::ws >> std::boolalpha >> b >> std::ws;
00481 line.clear();
00482
00483
00484 line.clear();
00485 line >> std::ws >> tmp >> std::ws;
00486 line.clear();
00487 if (tmp == "nosh")
00488 {
00489 lsh = std::make_pair(static_cast<Shader *>(NULL), 0.0f);
00490 }
00491 else if (tmp == "sh")
00492 {
00493 float alpha = 0;
00494
00495 line >> tmp >> std::ws >> alpha >> std::ws;
00496 line.clear();
00497 Shader * sh = mShaders[tmp];
00498 if (!sh)
00499 throw std::logic_error("Undefined shader \"" + tmp + "\"");
00500 lsh = std::make_pair(sh, alpha);
00501 }
00502 else
00503 throw std::logic_error("Unknown token \"" + tmp + "\"");
00504
00505
00506 line.clear();
00507 line >> std::ws >> tmp >> std::ws;
00508 line.clear();
00509 if (tmp == "nosh")
00510 {
00511 tsh = std::make_pair(static_cast<Shader *>(NULL), 0.0f);
00512 }
00513 else if (tmp == "sh")
00514 {
00515 float alpha = 0;
00516
00517 line >> tmp >> std::ws >> alpha >> std::ws;
00518 line.clear();
00519 Shader * sh = mShaders[tmp];
00520 if (!sh)
00521 throw std::logic_error("Undefined shader \"" + tmp + "\"");
00522 tsh = std::make_pair(sh, alpha);
00523 }
00524 else
00525 throw std::logic_error("Unknown token \"" + tmp + "\"");
00526
00527 CombineShader * csh = new CombineShader(scene, b);
00528 csh->setLightingShader(lsh.first, lsh.second);
00529 csh->setTransparentShader(tsh.first, tsh.second);
00530 for (unsigned int i = 0; i < texes.size(); i++)
00531 csh->addTexture(texes[i]);
00532
00533 return csh;
00534 }
00535
00536
00544 Shader * RefractiveShaderFactory::create(const std::string & type, std::stringstream & line, Scene * scene)
00545 {
00546 if (type != "refractiveshader")
00547 return NULL;
00548
00549
00550 Texture * bump = NULL;
00551 float bumppar = 0.0f;
00552 RGBAColor col;
00553 float ridx = 1.0f;
00554
00555
00556 readBump(line, bump, bumppar);
00557
00558
00559 line >> col >> std::ws >> ridx >> std::ws;
00560 line.clear();
00561
00562 RefractiveShader * sh = new RefractiveShader(scene, col, ridx);
00563 if (bump)
00564 {
00565 sh->setBumpTexture(bump);
00566 sh->setBumpCoefficient(bumppar);
00567 }
00568
00569 return sh;
00570 }
00571
00572
00579 Object * OBJObjectFactory::create(const std::string & type, std::stringstream & line)
00580 {
00581 if (type != "object")
00582 return NULL;
00583
00584 QuotedString objfile;
00585 std::string shadername;
00586 bool shadows = true;
00587
00588 line.clear();
00589 line >> std::ws >> objfile >> std::ws >> shadername >> std::ws >> std::boolalpha >> shadows;
00590 line.clear();
00591
00592 Object * obj = new OBJObject(objfile.str());
00593 obj->setCastShadows(shadows);
00594 Shader * sh = mShaders[shadername];
00595 if (!sh)
00596 throw std::logic_error("Undefined shader \"" + shadername + "\"");
00597 obj->setShader(sh);
00598 return obj;
00599 }
00600
00601
00608 Object * SphereObjectFactory::create(const std::string & type, std::stringstream & line)
00609 {
00610 if (type != "sphere")
00611 return NULL;
00612
00613 std::string shadername;
00614 bool shadows = true;
00615
00616 line.clear();
00617 line >> std::ws >> shadername >> std::ws >> std::boolalpha >> shadows;
00618 line.clear();
00619
00620 Object * obj = new SphereObject();
00621 obj->setCastShadows(shadows);
00622 Shader * sh = mShaders[shadername];
00623 if (!sh)
00624 throw std::logic_error("Undefined shader \"" + shadername + "\"");
00625 obj->setShader(sh);
00626 return obj;
00627 }
00628
00629
00636 Object * CopyObjectFactory::create(const std::string & type, std::stringstream & line)
00637 {
00638 if (type != "copyobject")
00639 return NULL;
00640
00641 std::string objname;
00642 bool shadows = true;
00643
00644 line.clear();
00645 line >> std::ws >> objname >> std::ws >> std::boolalpha >> shadows;
00646 line.clear();
00647
00648 Object * otherobj = mObjects[objname];
00649 if (!otherobj)
00650 throw std::logic_error("Undefined object \"" + objname + "\"");
00651 Object * obj = otherobj->createCopy();
00652 obj->setCastShadows(shadows);
00653 return obj;
00654 }
00655
00656
00663 bool Translator::transform(const std::string & type, std::stringstream & line)
00664 {
00665 if (type != "translate")
00666 return false;
00667
00668 std::string objname;
00669 Vec3f v;
00670
00671 line.clear();
00672 line >> std::ws >> objname >> std::ws >> v;
00673 line.clear();
00674
00675 Object * obj = mObjects[objname];
00676 if (!obj)
00677 throw std::logic_error("Undefined object \"" + objname + "\"");
00678 obj->translate(v);
00679 return true;
00680 }
00681
00682
00689 bool Rotator::transform(const std::string & type, std::stringstream & line)
00690 {
00691 if (type != "rotate")
00692 return false;
00693
00694 std::string objname;
00695 float angle;
00696 Vec3f axis;
00697
00698 line.clear();
00699 line >> std::ws >> objname >> std::ws >> angle >> std::ws >> axis;
00700 line.clear();
00701
00702 Object * obj = mObjects[objname];
00703 if (!obj)
00704 throw std::logic_error("Undefined object \"" + objname + "\"");
00705 obj->rotate(angle / 180.0 * M_PI, axis);
00706 return true;
00707 }
00708
00709
00716 bool Scaler::transform(const std::string & type, std::stringstream & line)
00717 {
00718 if (type != "scale")
00719 return false;
00720
00721 std::string objname;
00722 float x, y, z;
00723
00724 line.clear();
00725 line >> std::ws >> objname >> std::ws >> x >> std::ws >> y >> std::ws >> z;
00726 line.clear();
00727
00728 Object * obj = mObjects[objname];
00729 if (!obj)
00730 throw std::logic_error("Undefined object \"" + objname + "\"");
00731 obj->scale(x, y, z);
00732 return true;
00733 }
00734
00735
00742 Animator * PhysicsStepParser::create(const std::string & type, std::stringstream & line)
00743 {
00744 if (type != "shot")
00745 return false;
00746
00747 std::string objname;
00748 unsigned int framenr;
00749 Vec3f v, w;
00750
00751 line.clear();
00752 line >> std::ws >> objname >> std::ws >> framenr >> std::ws >> v >> std::ws >> w;
00753 line.clear();
00754
00755 Object * obj = mObjects[objname];
00756 if (!obj)
00757 throw std::logic_error("Undefined object \"" + objname + "\"");
00758 PhysicsStep * ps = new PhysicsStep(obj, framenr, v, w);
00759
00760 return ps;
00761 }
00762
00763