00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <vos/metaobjects/property/fileproperty.hh>
00025 #include "material.hh"
00026 #include "object3d.hh"
00027
00028 using namespace A3DL;
00029
00030 Material::Material(MetaObject* superobject)
00031 : MetaObject(superobject)
00032 {
00033 }
00034
00035 Material::~Material()
00036 {
00037 }
00038
00039 MetaObject* Material::new_Material(MetaObject* superobject, const string& type)
00040 {
00041 return new Material(superobject);
00042 }
00043
00044 const string Material::getType()
00045 {
00046 return "a3dl:material";
00047 }
00048
00049 void Material::registerExtenders()
00050 {
00051 LocalSite::addLocalObjectExtension(typeid(Material).name(), &Material::new_Material);
00052 LocalSite::addLocalObjectExtension("a3dl:material", &Material::new_Material);
00053 RemoteSite::addRemoteObjectExtension(typeid(Material).name(), &Material::new_Material);
00054 RemoteSite::addRemoteObjectExtension("a3dl:material", &Material::new_Material);
00055 }
00056
00057 void Material::setColor(float r, float g, float b) {
00058 if(r < 0) r = 0;
00059 if(g < 0) g = 0;
00060 if(b < 0) b = 0;
00061 if(r > 1) r = 1;
00062 if(g > 1) g = 1;
00063 if(b > 1) b = 1;
00064 char s[128];
00065 snprintf(s, sizeof(s), "%f %f %f", r, g, b);
00066 Property::setProperty(*this, "a3dl:color", s, "text/x-vector-float", accesscontrol);
00067 }
00068
00069 void Material::getColor(float& r, float& g, float& b)
00070 {
00071 string s, t;
00072 try {
00073 vRef<Property> p = meta_cast<Property*>(&findObject("a3dl:color"));
00074 if(!&p) throw bad_cast();
00075 p->read(s);
00076 t = p->getDataType();
00077
00078
00079 if(t == "text/x-hex-triplet" || t[0] == '#') {
00080 hexStringToFloats(s, r, g, b);
00081 return;
00082 }
00083
00084 sscanf(s.c_str(), "%f %f %f", &r, &g, &b);
00085 if(r < 0) r = 0;
00086 if(g < 0) g = 0;
00087 if(b < 0) b = 0;
00088 if(r > 1) r = 1;
00089 if(g > 1) g = 1;
00090 if(b > 1) b = 1;
00091 } catch(NoSuchObjectError) {
00092 throw;
00093 } catch(bad_cast) {
00094 throw;
00095 } catch(exception& e) {
00096 LOG("A3DL::Material", 0, "INTERNAL ERROR: unexpected exception in getMaterial(double&, double&, double&): " << e.what());
00097 throw;
00098 } catch(...) {
00099 LOG("A3DL::Material", 0, "INTERNAL ERROR: unexpected exception in getMaterial(double&, double&, double&)");
00100 throw;
00101 }
00102 }
00103
00104
00105 void Material::hexStringToFloats(const string& str, float& r, float& g, float& b) {
00106 r = strtol(str.substr(1, 2).c_str(), 0, 16) / 255.0;
00107 g = strtol(str.substr(3, 2).c_str(), 0, 16) / 255.0;
00108 b = strtol(str.substr(5, 2).c_str(), 0, 16) / 255.0;
00109 }
00110
00111 void Material::floatsToHexString(float r, float g, float b, string& str) {
00112 char s[128];
00113 if(r < 0) r = 0;
00114 if(g < 0) g = 0;
00115 if(b < 0) b = 0;
00116 if(r > 1) r = 1;
00117 if(g > 1) g = 1;
00118 if(b > 1) b = 1;
00119 snprintf(s, sizeof(s), "#%.2X%.2X%.2X", (unsigned int)(r*16.0), (unsigned int)(g*16.0), (unsigned int)(b*16.0));
00120 str = s;
00121 }
00122
00123 void Material::insertTextureLayer(int idx, Texture& t)
00124 {
00125 int i, n;
00126 int num;
00127 assert(&t);
00128 const ChildList& cl = getChildren();
00129 for(i = 0, num = 0; i < cl.size(); i++) {
00130 if(cl[i]->contextual_name == "a3dl:texture") num++;
00131 }
00132 if(idx < 0) idx = num + idx + 1;
00133 for(n = 0, i = 0; n < idx; i++) {
00134 if(cl[i]->contextual_name == "a3dl:texture") n++;
00135 }
00136 insertChild(i, "a3dl:texture", &t);
00137 }
00138
00139 Texture* Material::insertTextureLayerFromFile(int idx, const string& filename, const string& datatype)
00140 {
00141 vRef<LocalSite> site = Site::getDefaultPeer();
00142 vRef<Texture> txt = meta_cast<Texture*>(site->createMetaObject("a3dl:texture",
00143 typeid(Texture).name(), 0));
00144 txt->setPropertyAccessControl(accesscontrol);
00145 txt->setImageToFile(filename, datatype);
00146 insertTextureLayer(idx, *txt);
00147 return &txt;
00148 }
00149
00150
00151 void Material::replaceTextureLayer(int idx, Texture& t)
00152 {
00153 int i, n;
00154 int num;
00155 assert(&t);
00156 const ChildList& cl = getChildren();
00157 for(i = 0, num = 0; i < cl.size(); i++) {
00158 if(cl[i]->contextual_name == "a3dl:texture") num++;
00159 }
00160 if(idx < 0) idx = num + idx + 1;
00161 for(n = 0, i = 0; n < idx; i++) {
00162 if(cl[i]->contextual_name == "a3dl:texture") n++;
00163 }
00164 setChild(i, "a3dl:texture", &t);
00165 }
00166
00167 void Material::removeTextureLayer(int idx)
00168 {
00169 int i, n;
00170 int num;
00171
00172 const ChildList& cl = getChildren();
00173 for(i = 0, num = 0; i < cl.size(); i++) {
00174 if(cl[i]->contextual_name == "a3dl:texture") num++;
00175 }
00176 if(idx < 0) idx = num + idx + 1;
00177 for(n = 0, i = 0; n < idx; i++) {
00178 if(cl[i]->contextual_name == "a3dl:texture") n++;
00179 }
00180 removeChild(i);
00181 }
00182
00183 vector<Texture*> Material::getTextureLayers()
00184 {
00185 vector<Texture*> t;
00186 const ChildList& cl = getChildren();
00187 for(ChildList::size_type i = 0; i < cl.size(); i++) {
00188 if(cl[i]->contextual_name == "a3dl:texture") {
00189 if(Texture* tx = meta_cast<Texture*>(cl[i]->child)) t.push_back(tx);
00190 }
00191 }
00192 return t;
00193 }
00194
00195 Texture* Material::getTextureLayer(int idx) {
00196 const ChildList& cl = getChildren();
00197 ChildList::size_type t = 0;
00198 for(ChildList::size_type i = 0; i < cl.size(); i++) {
00199 if(cl[i]->contextual_name == "a3dl:texture") {
00200 if( t == idx) {
00201 Texture* tex = meta_cast<Texture*>(cl[i]->child);
00202 if(tex) {
00203 tex->acquire();
00204 return tex;
00205 } else {
00206 LOG("A3DL::Material", 2, "Warning: child of \"" << getURL().getString() << "\" with contextual name \"a3dl:texture\" and URL \"" << cl[i]->child->getURL().getString() << "\" is not a Texture object!");
00207 t++;
00208 }
00209 } else {
00210 t++;
00211 }
00212 }
00213 }
00214 return 0;
00215 }
00216
00217 void Material::setTransparency(double t, PropertyAccessControl* ac) {
00218 Property::setFloatProperty(*this, "a3dl:transparency", t, 0.0, 1.0, ac);
00219 }
00220
00221 double Material::getTransparency() {
00222 return Property::getFloatProperty(*this, "a3dl:transparency", 0.0, 1.0);
00223 }
00224
00225 Property* Material::getTransparencyObj() {
00226 return meta_cast<Property*>(&findObject("a3dl:transparency"));
00227 }
00228
00229 void Material::setTransparencyObj(Property* p) {
00230 try {
00231 vRef<ParentChildRelation> pcr = findChild("a3dl:transparency");
00232 setChild(pcr->position, "a3dl:transparency", p);
00233 } catch(NoSuchObjectError) {
00234 insertChild(-1, "a3dl:transparency", p);
00235 }
00236 }
00237
00238 void Material::setBlendMode(short m) {
00239 string ms("none");
00240 switch(m) {
00241 case BLEND_ADD:
00242 ms = "add";
00243 break;
00244 case BLEND_MULTIPLY:
00245 ms = "multiply";
00246 break;
00247 case BLEND_DOUBLE_MULTIPLY:
00248 ms = "double multiply";
00249 break;
00250 }
00251 Property::setProperty(*this, "a3dl:blend-mode", ms, "text/plain", accesscontrol);
00252 }
00253
00254 short Material::getBlendMode() {
00255 string s;
00256 vRef<Property> p = meta_cast<Property*>(&findObject("a3dl:blend-mode"));
00257 if(!&p) throw bad_cast();
00258 p->read(s);
00259 if(s == "add")
00260 return BLEND_ADD;
00261 if(s == "multiply")
00262 return BLEND_MULTIPLY;
00263 if(s == "double multiply")
00264 return BLEND_DOUBLE_MULTIPLY;
00265 return BLEND_NORMAL;
00266 }
00267
00268
00269 Property* Material::getBlendModeObj() {
00270 return meta_cast<Property*>(&findObject("a3dl:blend-mode"));
00271 }
00272
00273 void Material::setBlendModeObj(Property* p) {
00274 try {
00275 vRef<ParentChildRelation> pcr = findChild("a3dl:blend-mode");
00276 setChild(pcr->position, "a3dl:blend-mode", p);
00277 } catch(NoSuchObjectError) {
00278 insertChild(-1, "a3dl:blend-mode", p);
00279 }
00280 }
00281
00282 void Material::setBlendColor(double r, double g, double b) {
00283 Object3D::setThreeFloatProperty(*this, "a3dl:blend-color", r, g, b, accesscontrol);
00284 }
00285
00286 void Material::getBlendColor(double& r, double& g, double& b) {
00287 Object3D::getThreeFloatProperty(*this, "a3dl:blend-color", &r, &g, &b);
00288 }
00289
00290
00291 Property* Material::getBlendColorObj() {
00292 return meta_cast<Property*>(&findObject("a3dl:blend-color"));
00293 }
00294
00295 void Material::setBlendColorObj(Property* p) {
00296 try {
00297 vRef<ParentChildRelation> pcr = findChild("a3dl:blend-color");
00298 setChild(pcr->position, "a3dl:blend-color", p);
00299 } catch(NoSuchObjectError) {
00300 insertChild(-1, "a3dl:blend-color", p);
00301 }
00302 }