00001 #include "MaterialLoader.h"
00002 #include <stdexcept>
00003 #include "../bxdf/BSDF.h"
00004 #include "../bxdf/CookTorrance.h"
00005 #include "../bxdf/Phong.h"
00006 #include "../bxdf/Lambertian.h"
00007 #include "conversion.hpp"
00008 #include "../materials/BSDFMaterial.h"
00009 #include "../materials/DielectricMaterial.h"
00010 #include "../materials/MirrorMaterial.h"
00011 #include "../materials/ImageMaterial.h"
00012 #include "../materials/WoodMaterial.h"
00013 #include "../materials/WallMaterial.h"
00014
00015 using namespace std;
00016
00017 namespace rcrt
00018 {
00019
00020 MaterialLoader::MaterialLoader(string matFile):XMLLoader(matFile),initialised(false)
00021 {
00022 }
00023
00024 MaterialLoader::~MaterialLoader()
00025 {
00026 }
00027
00028 void MaterialLoader::init()
00029 {
00030 initialised = true;
00031
00032 nextStartTag("materials");
00033 nextStartTag("");
00034 std::string tagName = parser.getName();
00035 while(tagName == "mat"){
00036 string name = parser.getAttributeValue("","name");
00037 string type = parser.getAttributeValue("","type");
00038
00039 cout << "loading " << type << " material " << name << endl;
00040
00041 nextStartTag("ior");
00042 complex<float> ior(convertTo<float>(parser.getAttributeValue("","r")),
00043 convertTo<float>(parser.getAttributeValue("","i")));
00044
00045 if(type == "bsdf"){
00046 tagName = initBSDF(name,ior);
00047 } else if (type == "wood"){
00048 tagName = initWood(name,ior);
00049 } else if (type == "wall"){
00050 tagName = initWall(name,ior);
00051 } else if (type == "floor"){
00052 tagName = initFloor(name,ior);
00053 } else if (type == "dielectric"){
00054 tagName = initDielectric(name,ior);
00055 } else if (type == "water"){
00056 tagName = initWater(name,ior);
00057 } else if (type == "mirror"){
00058 tagName = initMirror(name,ior);
00059 } else if (type == "tex"){
00060 tagName = initImg(name,ior);
00061 }
00062 }
00063
00064 }
00065
00066 string MaterialLoader::initBSDF(std::string name, std::complex<float> ior)
00067 {
00068 bool found = nextStartTag("bxdf");
00069 if(!found){
00070 throw runtime_error("[MaterialLoader] Defined a BSDFMaterial, but no bxdf tag found.");
00071 }
00072 BSDF bsdf;
00073 string tagName = parser.getName();
00074 while(tagName == "bxdf"){
00075 string type = parser.getAttributeValue("","t");
00076 if(type == "cookt"){
00077 loadCookT(&bsdf, ior);
00078 } else if(type == "phong"){
00079 loadPhong(&bsdf);
00080 } else if(type == "lambert"){
00081 loadLambert(&bsdf);
00082 }
00083
00084 eof = !nextStartTag("");
00085 if(eof)
00086 break;
00087 tagName = parser.getName();
00088 }
00089 materials.insert(make_pair(name,new BSDFMaterial(bsdf, ior)));
00090 return tagName;
00091 }
00092
00093 string MaterialLoader::initWood(std::string name, std::complex<float> ior)
00094 {
00095
00096 std::cout << "init wood material" << std::endl;
00097 nextStartTag("org");
00098 Point3D org(convertTo<float>(parser.getAttributeValue("","x")),
00099 convertTo<float>(parser.getAttributeValue("","y")),
00100 convertTo<float>(parser.getAttributeValue("","z")));
00101 nextStartTag("dir");
00102 Vec3D dir(convertTo<float>(parser.getAttributeValue("","x")),
00103 convertTo<float>(parser.getAttributeValue("","y")),
00104 convertTo<float>(parser.getAttributeValue("","z")));
00105 nextStartTag("light");
00106 RGBColor light(convertTo<float>(parser.getAttributeValue("","r")),
00107 convertTo<float>(parser.getAttributeValue("","g")),
00108 convertTo<float>(parser.getAttributeValue("","b")));
00109 nextStartTag("dark");
00110 RGBColor dark(convertTo<float>(parser.getAttributeValue("","r")),
00111 convertTo<float>(parser.getAttributeValue("","g")),
00112 convertTo<float>(parser.getAttributeValue("","b")));
00113 materials.insert(make_pair(name,new WoodMaterial(org, dir.normalize(), light, dark)));
00114 nextStartTag("");
00115 return parser.getName();
00116
00117 }
00118
00119 string MaterialLoader::initWall(std::string name, std::complex<float> ior)
00120 {
00121 BSDF b;
00122
00123 b.addBXDF(new Lambertian(RGBColor(0.960784314,0.901960784,0.803921569)));
00124 std::cout << "init wall material" << std::endl;
00125 materials.insert(make_pair(name,new WallMaterial(b,14)));
00126 nextStartTag("");
00127 return parser.getName();
00128
00129 }
00130
00131 string MaterialLoader::initFloor(std::string name, std::complex<float> ior)
00132 {
00133 BSDF b;
00134
00135 b.addBXDF(new Lambertian(RGBColor(0.647058824,0.254901961,0.117647059)));
00136 std::cout << "init floor material" << std::endl;
00137 materials.insert(make_pair(name,new WallMaterial(b,12)));
00138 nextStartTag("");
00139 return parser.getName();
00140
00141 }
00142
00143 string MaterialLoader::initDielectric(std::string name, std::complex<float> ior)
00144 {
00145 nextStartTag("absorb");
00146 RGBColor absorb(convertTo<float>(parser.getAttributeValue("","r")),
00147 convertTo<float>(parser.getAttributeValue("","g")),
00148 convertTo<float>(parser.getAttributeValue("","b")));
00149 materials.insert(make_pair(name,new DielectricMaterial(ior.real(), absorb)));
00150 nextStartTag("");
00151 return parser.getName();
00152 }
00153
00154 string MaterialLoader::initWater(std::string name, std::complex<float> ior)
00155 {
00156 nextStartTag("absorb");
00157 RGBColor absorb(convertTo<float>(parser.getAttributeValue("","r")),
00158 convertTo<float>(parser.getAttributeValue("","g")),
00159 convertTo<float>(parser.getAttributeValue("","b")));
00160 DielectricMaterial* mat = new DielectricMaterial(ior.real(), absorb);
00161
00162
00163 materials.insert(make_pair(name,mat));
00164 nextStartTag("");
00165 return parser.getName();
00166 }
00167
00168 string MaterialLoader::initMirror(std::string name, std::complex<float> ior)
00169 {
00170
00171
00172 }
00173
00174 string MaterialLoader::initImg(std::string name, std::complex<float> ior)
00175 {
00176 nextStartTag("tex");
00177 string file = parser.getAttributeValue("","file");
00178 int resX = convertTo<int>(parser.getAttributeValue("","resX"));
00179 int resY = convertTo<int>(parser.getAttributeValue("","resY"));
00180 Image* img = new Image(resX, resY);
00181 img->LoadImage(file.c_str());
00182 ImageTexture* imgTex = new ImageTexture(img);
00183 materials.insert(make_pair(name,new ImageMaterial(imgTex, ior)));
00184
00185 nextStartTag("");
00186 return parser.getName();
00187 }
00188
00189 void MaterialLoader::loadCookT(BSDF* bsdf, complex<float> ior)
00190 {
00191 nextStartTag("diff");
00192 RGBColor diff(convertTo<float>(parser.getAttributeValue("","r")),
00193 convertTo<float>(parser.getAttributeValue("","g")),
00194 convertTo<float>(parser.getAttributeValue("","b")));
00195 nextStartTag("spec");
00196 RGBColor spec(convertTo<float>(parser.getAttributeValue("","r")),
00197 convertTo<float>(parser.getAttributeValue("","g")),
00198 convertTo<float>(parser.getAttributeValue("","b")));
00199 nextStartTag("rough");
00200 float rms = convertTo<float>(parser.getAttributeValue("","val"));
00201 bsdf->addBXDF(new CookTorrance(diff, spec, rms, ior));
00202 }
00203
00204 void MaterialLoader::loadPhong(BSDF* bsdf)
00205 {
00206 nextStartTag("diff");
00207 RGBColor diff(convertTo<float>(parser.getAttributeValue("","r")),
00208 convertTo<float>(parser.getAttributeValue("","g")),
00209 convertTo<float>(parser.getAttributeValue("","b")));
00210 nextStartTag("spec");
00211 RGBColor spec(convertTo<float>(parser.getAttributeValue("","r")),
00212 convertTo<float>(parser.getAttributeValue("","g")),
00213 convertTo<float>(parser.getAttributeValue("","b")));
00214 nextStartTag("n");
00215 float n = convertTo<float>(parser.getAttributeValue("","val"));
00216 bsdf->addBXDF(new Phong(diff, spec, n));
00217 }
00218
00219 void MaterialLoader::loadLambert(BSDF* bsdf)
00220 {
00221 nextStartTag("col");
00222 RGBColor col(convertTo<float>(parser.getAttributeValue("","r")),
00223 convertTo<float>(parser.getAttributeValue("","g")),
00224 convertTo<float>(parser.getAttributeValue("","b")));
00225
00226 bsdf->addBXDF(new Lambertian(col));
00227 }
00228
00229 Material* MaterialLoader::getMaterial(std::string name)
00230 {
00231 map<string, Material*>::iterator iter = materials.find(name);
00232 if( iter != materials.end() ) {
00233 return iter->second;
00234 }
00235 return 0;
00236 }
00237
00238 bool MaterialLoader::nextFrame()
00239 {
00240 if(!initialised)
00241 init();
00242
00243 return true;
00244 }
00245
00246 bool MaterialLoader::goToFrame(const int& n)
00247 {
00248 if(!initialised)
00249 init();
00250
00251 return true;
00252 }
00253
00254
00255 }