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 <stdio.h>
00025 #include <math.h>
00026 #include "object3d.hh"
00027
00028 #ifndef M_PI
00029 # define M_PI 3.14159265358979323846
00030 #endif
00031
00032 using namespace A3DL;
00033
00034 Object3D::Object3D(MetaObject* superobject)
00035 : MetaObject(superobject), accesscontrol(0)
00036 {
00037 }
00038
00039 Object3D::~Object3D()
00040 {
00041 }
00042
00043 void Object3D::setPosition(double x, double y, double z) throw(NoSuchObjectError, AccessControlError, RemoteError)
00044 {
00045 try {
00046 setThreeFloatProperty(*this, "a3dl:position", x, y, z, accesscontrol);
00047 } catch(AccessControlError) {
00048 throw;
00049 } catch(RemoteError) {
00050 throw;
00051 } catch(exception e) {
00052 throw NoSuchObjectError(string("error setting \"position\" property (") + e.what() + ")");
00053 }
00054 }
00055
00056 void Object3D::setOrientation(double x, double y, double z, double rot) throw(NoSuchObjectError, AccessControlError, RemoteError)
00057 {
00058 char c[256];
00059 snprintf(c, 256, "%.15g %.15g %.15g %.15g", x, y, z, rot);
00060 try {
00061 Property::setProperty(*this, "a3dl:orientation", string(c), "text/x-vector-float", accesscontrol);
00062 } catch(AccessControlError) {
00063 throw;
00064 } catch(RemoteError) {
00065 throw;
00066 } catch(exception e) {
00067 throw NoSuchObjectError(string("error setting \"position\" property (") + e.what() + ")");
00068 }
00069 }
00070
00071 void Object3D::setScaling(double x, double y, double z) throw(NoSuchObjectError, AccessControlError, RemoteError)
00072 {
00073 try {
00074 setThreeFloatProperty(*this, "a3dl:scaling", x, y, z, accesscontrol);
00075 } catch(AccessControlError) {
00076 throw;
00077 } catch(RemoteError) {
00078 throw;
00079 } catch(exception e) {
00080 throw NoSuchObjectError(string("error setting \"position\" property (") + e.what() + ")");
00081 }
00082 }
00083
00084 void Object3D::getPosition(double& x, double& y, double& z) throw(NoSuchObjectError, AccessControlError, RemoteError)
00085 {
00086 try {
00087 getThreeFloatProperty(*this, "a3dl:position", &x, &y, &z);
00088 } catch(AccessControlError) {
00089 throw;
00090 } catch(RemoteError) {
00091 throw;
00092 } catch(exception e) {
00093 throw NoSuchObjectError(string("error finding, casting or reading \"position\" property (") + e.what() + ")");
00094 }
00095
00096 }
00097
00098 void Object3D::getOrientation(double& x, double& y, double& z, double& rot) throw(NoSuchObjectError, AccessControlError, RemoteError)
00099 {
00100 try {
00101 rREF(Vobject&, v, findObject("a3dl:orientation"),
00102 string n;
00103 Property* p = meta_cast<Property*>(&v);
00104 if(!p) throw bad_cast();
00105 p->read(n);
00106 sscanf(n.c_str(), "%lg %lg %lg %lg", &x, &y, &z, &rot);
00107 );
00108 } catch(AccessControlError) {
00109 throw;
00110 } catch(RemoteError) {
00111 throw;
00112 } catch(exception e) {
00113 throw NoSuchObjectError(string("error finding, casting or reading \"orientation\" property (") + e.what() + ")");
00114 }
00115 }
00116
00117 void Object3D::getScaling(double& x, double& y, double& z) throw(NoSuchObjectError, AccessControlError, RemoteError)
00118 {
00119 try {
00120 getThreeFloatProperty(*this, "a3dl:scaling", &x, &y, &z);
00121 } catch(AccessControlError) {
00122 throw;
00123 } catch(RemoteError) {
00124 throw;
00125 } catch(exception e) {
00126 throw NoSuchObjectError(string("Error finding, casting or reading \"scaling\" property (") + e.what() + ")");
00127 }
00128 }
00129
00130 void Object3D::setPositionHT(double x, double y, double z) throw(NoSuchObjectError, AccessControlError, RemoteError)
00131 {
00132 try {
00133 setThreeFloatProperty(*this, "a3dl:hardposition", x, y, z, accesscontrol);
00134 } catch(AccessControlError) {
00135 throw;
00136 } catch(RemoteError) {
00137 throw;
00138 } catch(exception e) {
00139 throw NoSuchObjectError(string("error setting \"position\" property (") + e.what() + ")");
00140 }
00141 }
00142
00143 void Object3D::setOrientationHT(double x, double y, double z, double rot) throw(NoSuchObjectError, AccessControlError, RemoteError)
00144 {
00145 char c[256];
00146 snprintf(c, 256, "%.15g %.15g %.15g %.15g", x, y, z, rot);
00147 try {
00148 Property::setProperty(*this, "a3dl:hardorientation", string(c), "text/x-vector-float", accesscontrol);
00149 } catch(AccessControlError) {
00150 throw;
00151 } catch(RemoteError) {
00152 throw;
00153 } catch(exception e) {
00154 throw NoSuchObjectError(string("error setting \"position\" property (") + e.what() + ")");
00155 }
00156 }
00157
00158 void Object3D::setScalingHT(double x, double y, double z) throw(NoSuchObjectError, AccessControlError, RemoteError)
00159 {
00160 try {
00161 setThreeFloatProperty(*this, "a3dl:hardscaling", x, y, z, accesscontrol);
00162 } catch(AccessControlError) {
00163 throw;
00164 } catch(RemoteError) {
00165 throw;
00166 } catch(exception e) {
00167 throw NoSuchObjectError(string("error setting \"position\" property (") + e.what() + ")");
00168 }
00169 }
00170
00171 void Object3D::getPositionHT(double& x, double& y, double& z) throw(NoSuchObjectError, AccessControlError, RemoteError)
00172 {
00173 try {
00174 getThreeFloatProperty(*this, "a3dl:hardposition", &x, &y, &z);
00175 } catch(AccessControlError) {
00176 throw;
00177 } catch(RemoteError) {
00178 throw;
00179 } catch(exception e) {
00180 throw NoSuchObjectError(string("error finding, casting or reading \"position\" property (") + e.what() + ")");
00181 }
00182
00183 }
00184
00185 void Object3D::getOrientationHT(double& x, double& y, double& z, double& rot) throw(NoSuchObjectError, AccessControlError, RemoteError)
00186 {
00187 try {
00188 rREF(Vobject&, v, findObject("a3dl:hardorientation"),
00189 string n;
00190 Property* p = meta_cast<Property*>(&v);
00191 if(!p) throw bad_cast();
00192 p->read(n);
00193 sscanf(n.c_str(), "%lg %lg %lg %lg", &x, &y, &z, &rot);
00194 );
00195 } catch(AccessControlError) {
00196 throw;
00197 } catch(RemoteError) {
00198 throw;
00199 } catch(exception e) {
00200 throw NoSuchObjectError(string("error finding, casting or reading \"orientation\" property (") + e.what() + ")");
00201 }
00202 }
00203
00204 void Object3D::getScalingHT(double& x, double& y, double& z) throw(NoSuchObjectError, AccessControlError, RemoteError)
00205 {
00206 try {
00207 getThreeFloatProperty(*this, "a3dl:hardscaling", &x, &y, &z);
00208 } catch(AccessControlError) {
00209 throw;
00210 } catch(RemoteError) {
00211 throw;
00212 } catch(exception e) {
00213 throw NoSuchObjectError(string("Error finding, casting or reading \"scaling\" property (") + e.what() + ")");
00214 }
00215 }
00216
00217
00218 void Object3D::setThreeFloatProperty(Vobject& vob, const string& name, double x, double y, double z,
00219 PropertyAccessControl* ac)
00220 {
00221 char s[128];
00222 snprintf(s, sizeof(s), "%.15g %.15g %.15g", x, y, z);
00223 Property::setProperty(vob, name, s, "text/x-vector-float", ac);
00224 }
00225
00226 void Object3D::getThreeFloatProperty(Vobject& vob, const string& name, double* x, double* y, double* z) {
00227 string s;
00228 vRef<Property> p = meta_cast<Property*>(&vob.findObject(name));
00229 if(!&p) throw bad_cast();
00230 p->read(s);
00231 sscanf(s.c_str(), "%lg %lg %lg", x, y, z);
00232 }
00233
00234 void Object3D::initialize()
00235 {
00236 setPropertyAccessControl(&NoPropertyAccessControl::static_);
00237 setPosition(0.0, 0.0, 0.0);
00238 setOrientation(0.0, 1.0, 0.0, 0.0);
00239 setScaling(1.0, 1.0, 1.0);
00240 }
00241
00242 MetaObject* Object3D::new_Object3D(MetaObject* superobject, const string& type)
00243 {
00244 return new Object3D(superobject);
00245 }
00246
00247 const string Object3D::getType()
00248 {
00249 return "a3dl:object3D";
00250 }
00251
00252 void Object3D::registerExtenders()
00253 {
00254 LocalSite::addLocalObjectExtension(typeid(Object3D).name(), &Object3D::new_Object3D);
00255 LocalSite::addLocalObjectExtension("a3dl:object3D", &Object3D::new_Object3D);
00256 RemoteSite::addRemoteObjectExtension(typeid(Object3D).name(), &Object3D::new_Object3D);
00257 RemoteSite::addRemoteObjectExtension("a3dl:object3D", &Object3D::new_Object3D);
00258 }
00259
00260 void Object3D::setOrientationWithQuaternion(double x, double y, double z, double w)
00261 throw(NoSuchObjectError, AccessControlError, RemoteError)
00262 {
00263 w = 2.0 * acos(w);
00264 double sp = sin(w/2.0);
00265 if(sp > .0000000001) {
00266 x = x / sp;
00267 y = y / sp;
00268 z = z / sp;
00269 w *= 180.0/M_PI;
00270 } else {
00271 x = y = 0;
00272 z = 1;
00273 w = 0;
00274 }
00275 setOrientation(x, y, z, w);
00276 }
00277
00278 void Object3D::getOrientationAsQuaternion(double& x, double& y, double& z, double& w)
00279 throw(NoSuchObjectError, AccessControlError, RemoteError)
00280 {
00281 double ax, ay, az, phi;
00282 getOrientation(ax, ay, az, phi);
00283
00284 double len = sqrt(ax*ax + ay*ay + az*az);
00285 if(len < .000000001) {
00286 x = 0;
00287 y = 0;
00288 z = 0;
00289 w = 1;
00290 return;
00291 } else {
00292 ax /= len;
00293 ay /= len;
00294 az /= len;
00295 }
00296
00297 double p2 = phi/2.0 * M_PI/180.0;
00298 double ss = sin(p2);
00299 w = cos(p2);
00300 x = ax * ss;
00301 y = ay * ss;
00302 z = az * ss;
00303 }
00304
00305 void Object3D::setOrientationWithQuaternionHT(double x, double y, double z, double w)
00306 throw(NoSuchObjectError, AccessControlError, RemoteError)
00307 {
00308 w = 2.0 * acos(w);
00309 double sp = sin(w/2.0);
00310 if(sp > .0000000001) {
00311 x = x / sp;
00312 y = y / sp;
00313 z = z / sp;
00314 w *= 180.0/M_PI;
00315 } else {
00316 x = y = 0;
00317 z = 1;
00318 w = 0;
00319 }
00320 setOrientationHT(x, y, z, w);
00321 }
00322
00323 void Object3D::getOrientationAsQuaternionHT(double& x, double& y, double& z, double& w)
00324 throw(NoSuchObjectError, AccessControlError, RemoteError)
00325 {
00326 double ax, ay, az, phi;
00327 getOrientationHT(ax, ay, az, phi);
00328
00329 double len = sqrt(ax*ax + ay*ay + az*az);
00330 if(len < .000000001) {
00331 x = 0;
00332 y = 0;
00333 z = 0;
00334 w = 1;
00335 return;
00336 } else {
00337 ax /= len;
00338 ay /= len;
00339 az /= len;
00340 }
00341
00342 double p2 = phi/2.0 * M_PI/180.0;
00343 double ss = sin(p2);
00344 w = cos(p2);
00345 x = ax * ss;
00346 y = ay * ss;
00347 z = az * ss;
00348 }
00349
00350
00351 void Object3D::setOrInsertChild(const string& name, Vobject* obj) {
00352 try {
00353 vRef<ParentChildRelation> pcr = findChild(name);
00354 setChild(pcr->position, name, obj);
00355 } catch(NoSuchObjectError) {
00356 insertChild(-1, name, obj);
00357 }
00358 }
00359
00360 void Object3D::setPositionObj(Property* obj) {
00361 setOrInsertChild("a3dl:position", obj);
00362 }
00363
00364 void Object3D::setOrientationObj(Property* obj) {
00365 setOrInsertChild("a3dl:orientation", obj);
00366 }
00367
00368 void Object3D::setScalingObj(Property* obj) {
00369 setOrInsertChild("a3dl:scaling", obj);
00370 }
00371
00372 Property* Object3D::getPositionObj() {
00373 Property* p = meta_cast<Property*>(&findObject("a3dl:position"));
00374 if(!p) throw bad_cast();
00375 return p;
00376 }
00377
00378 Property* Object3D::getOrientationObj() {
00379 Property* p = meta_cast<Property*>(&findObject("a3dl:orientation"));
00380 if(!p) throw bad_cast();
00381 return p;
00382 }
00383
00384 Property* Object3D::getScalingObj() {
00385 Property* p = meta_cast<Property*>(&findObject("a3dl:scaling"));
00386 if(!p) throw bad_cast();
00387 return p;
00388 }
00389
00390 Material* Object3D::getMaterial(bool create) {
00391 try {
00392 return meta_cast<Material*>(&findObject("a3dl:material"));
00393 } catch(NoSuchObjectError) {
00394 if(create) {
00395 vRef<LocalSite> site = Site::getDefaultPeer();
00396 vRef<Material> mat = meta_cast<Material*>(site->createMetaObject("a3dl:material",
00397 typeid(Material).name(), 0));
00398 mat->setPropertyAccessControl(accesscontrol);
00399 insertChild(-1, "a3dl:material", &mat);
00400 mat->acquire();
00401 return &mat;
00402 } else throw;
00403 }
00404 }
00405
00406 void Object3D::setMaterial(Material* p) {
00407 try {
00408 vRef<ParentChildRelation> pcr = findChild("a3dl:material");
00409 setChild(pcr->position, "a3dl:material", p);
00410 } catch(NoSuchObjectError) {
00411 insertChild(-1, "a3dl:material", p);
00412 }
00413 }
00414
00415 vector<Material*> Object3D::getMaterials()
00416 {
00417 vector<Material*> t;
00418 const ChildList& cl = getChildren();
00419 for(unsigned int i = 0; i < cl.size(); i++) {
00420 if(cl[i]->contextual_name == "a3dl:material") {
00421 if(Material* tx = meta_cast<Material*>(cl[i]->child)) t.push_back(tx);
00422 }
00423 }
00424 return t;
00425 }