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 <stdarg.h>
00026
00027 #include <vos/metaobjects/property/property.hh>
00028 #include <vos/metaobjects/misc/cod.hh>
00029 #include "polygonmesh.hh"
00030
00031
00032
00033
00034 using namespace A3DL;
00035
00036 PolygonMesh::PolygonMesh(MetaObject* superobject)
00037 : Object3D(superobject), MetaObject(superobject)
00038 {
00039 }
00040
00041 PolygonMesh::~PolygonMesh()
00042 {
00043 }
00044
00045 void PolygonMesh::setVertex(unsigned int which, Vertex& v)
00046 {
00047 string data;
00048
00049 vRef<Vobject> vert = findObject("a3dl:vertices");
00050 Property* pr = meta_cast<Property*>(&vert);
00051 if(!pr) return;
00052 pr->read(data);
00053
00054 unsigned char* newdata;
00055 int newdatasize;
00056 if(which * 3 * 4 > data.size()) {
00057 int existingVerts = data.size() / (3*4);
00058 int needNew = which - existingVerts;
00059 newdatasize = (needNew + 1) * 12;
00060 newdata = (unsigned char*)malloc(newdatasize);
00061 for(int i = 0; i < needNew; i++) {
00062 COD::pack(newdata + i*12, newdatasize, "fff", 0.0, 0.0, 0.0);
00063 }
00064 } else {
00065 newdata = (unsigned char*)malloc(12);
00066 newdatasize = 12;
00067 }
00068 COD::pack(newdata + newdatasize - 12, 12, "fff", v.x, v.y, v.z);
00069 if(which * 3 * 4 > data.size()) pr->write(data.size(), string((char*)newdata, newdatasize));
00070 else pr->write(which * 12, string((char*)newdata, newdatasize));
00071 free(newdata);
00072 }
00073
00074 void PolygonMesh::setNormal(unsigned int which, Vertex& v)
00075 {
00076 string data;
00077
00078 vRef<Vobject> vert = findObject("a3dl:normals");
00079 Property* pr = meta_cast<Property*>(&vert);
00080 if(!pr) return;
00081 pr->read(data);
00082
00083 unsigned char* newdata;
00084 int newdatasize;
00085 if(which * 3 * 4 > data.size()) {
00086 int existingVerts = data.size() / (3*4);
00087 int needNew = which - existingVerts;
00088 newdatasize = (needNew + 1) * 12;
00089 newdata = (unsigned char*)malloc(newdatasize);
00090 for(int i = 0; i < needNew; i++) {
00091 COD::pack(newdata + i*12, newdatasize, "fff", 0.0, 0.0, 0.0);
00092 }
00093 } else {
00094 newdata = (unsigned char*)malloc(12);
00095 newdatasize = 12;
00096 }
00097 COD::pack(newdata + newdatasize - 12, 12, "fff", v.x, v.y, v.z);
00098 if(which * 3 * 4 > data.size()) pr->write(data.size(), string((char*)newdata, newdatasize));
00099 else pr->write(which * 12, string((char*)newdata, newdatasize));
00100 free(newdata);
00101 }
00102
00103
00104 void PolygonMesh::setPolygon(unsigned int which, Polygon& t)
00105 {
00106 string data;
00107
00108 vRef<Vobject> tris = findObject("a3dl:triangles");
00109 Property* pr = meta_cast<Property*>(&tris);
00110 if(!pr) return;
00111 pr->read(data);
00112
00113 if(pr->getDataType() == "packed/triangle-array") {
00114 unsigned char* newdata;
00115 int newdatasize;
00116 if(which * 3 * 4 > data.size()) {
00117 int existingTris = data.size() / (3*4);
00118 int needNew = which - existingTris;
00119 newdatasize = (needNew + 1) * 12;
00120 newdata = (unsigned char*)malloc(newdatasize);
00121 for(int i = 0; i < needNew; i++) {
00122 COD::pack(newdata + i*12, newdatasize, "lll", 0, 1, 2);
00123 }
00124 } else {
00125 newdata = (unsigned char*)malloc(12);
00126 newdatasize = 12;
00127 }
00128 COD::pack(newdata + newdatasize - 12, 12, "lll", t[0], t[1], t[2]);
00129 if(which * 3 * 4 > data.size()) pr->write(data.size(), string((char*)newdata, newdatasize));
00130 else pr->write(which * 12, string((char*)newdata, newdatasize));
00131 free(newdata);
00132 } else if(pr->getDataType() == "packed/polygon-list") {
00133 vector<Polygon> p;
00134 getPolygons(p);
00135 if(which >= p.size()) p.resize(which+1);
00136 p[which] = t;
00137 setPolygons(p);
00138 }
00139 }
00140
00141 void PolygonMesh::setTexel(int which, Texel& uv)
00142 {
00143 string data;
00144
00145 vRef<Vobject> uvobj = findObject("a3dl:texels");
00146 Property* pr = meta_cast<Property*>(&uvobj);
00147 if(!pr) return;
00148 pr->read(data);
00149
00150 unsigned char* newdata;
00151 int newdatasize;
00152 if(which * 8 > (int)data.size()) {
00153 int existingVerts = data.size() / 8;
00154 int needNew = which - existingVerts;
00155 newdatasize = (needNew + 1) * 8;
00156 newdata = (unsigned char*)malloc(newdatasize);
00157 for(int i = 0; i < needNew; i++) {
00158 COD::pack(newdata + i*8, newdatasize, "ff", 0.0, 0.0);
00159 }
00160 } else {
00161 newdata = (unsigned char*)malloc(8);
00162 newdatasize = 8;
00163 }
00164 COD::pack(newdata + newdatasize - 8, 8, "ff", uv.x, uv.y);
00165 if(which * 8 > (int)data.size()) pr->write(data.size(), string((char*)newdata, newdatasize));
00166 else pr->write(which * 8, string((char*)newdata, newdatasize));
00167 free(newdata);
00168 }
00169
00170
00171 void PolygonMesh::setVertices(const vector<Vertex>& v)
00172 {
00173 vRef<Vobject> vertices;
00174 try {
00175 vertices = findObject("a3dl:vertices");
00176 } catch(NoSuchObjectError) {
00177 vRef<Site> s = getSite();
00178 vertices = s->createMetaObject("vertices", typeid(Property).name(), 0);
00179 LocalProperty* lp = meta_cast<LocalProperty*>(&vertices);
00180 if(!lp) throw bad_cast();
00181 lp->insertPropertyAccessControl(-1, accesscontrol);
00182 insertChild(-1, "a3dl:vertices", &vertices);
00183 }
00184 try {
00185 Property* pr = meta_cast<Property*>(&vertices);
00186 if(!pr) throw bad_cast();
00187 unsigned char* data = (unsigned char*)malloc(v.size() * 12);
00188 for(unsigned int i = 0; i < v.size(); i++) {
00189 COD::pack(data + i*12, 12, "fff", v[i].x, v[i].y, v[i].z);
00190 }
00191 pr->replace(string((char*)data, v.size() * 12));
00192 free(data);
00193 } catch(bad_cast) {
00194 }
00195 }
00196
00197 void PolygonMesh::setNormals(const vector<Vertex>& v)
00198 {
00199 vRef<Vobject> vertices;
00200 try {
00201 vertices = findObject("a3dl:normals");
00202 } catch(NoSuchObjectError) {
00203 vRef<Site> s = getSite();
00204 vertices = s->createMetaObject("normals", typeid(Property).name(), 0);
00205 LocalProperty* lp = meta_cast<LocalProperty*>(&vertices);
00206 if(!lp) throw bad_cast();
00207 lp->insertPropertyAccessControl(-1, accesscontrol);
00208 insertChild(-1, "a3dl:normals", &vertices);
00209 }
00210 try {
00211 Property* pr = meta_cast<Property*>(&vertices);
00212 if(!pr) throw bad_cast();
00213 unsigned char* data = (unsigned char*)malloc(v.size() * 12);
00214 for(unsigned int i = 0; i < v.size(); i++) {
00215 COD::pack(data + i*12, 12, "fff", v[i].x, v[i].y, v[i].z);
00216 }
00217 pr->replace(string((char*)data, v.size() * 12));
00218 free(data);
00219 } catch(bad_cast) {
00220 }
00221 }
00222
00223
00224 void PolygonMesh::setPolygons(const vector<Polygon>& t)
00225 {
00226 vRef<Vobject> polygons;
00227
00228 try {
00229 polygons = findObject("a3dl:polygons");
00230 } catch(NoSuchObjectError) {
00231 vRef<Site> s = getSite();
00232 polygons = s->createMetaObject("a3dl:polygons", typeid(Property).name(), 0);
00233 LocalProperty* lp = meta_cast<LocalProperty*>(&polygons);
00234 if(!lp) throw bad_cast();
00235 lp->insertPropertyAccessControl(-1, accesscontrol);
00236 insertChild(-1, "a3dl:polygons", &polygons);
00237 }
00238 bool onlytris = true;
00239 for(vector<Polygon>::size_type i = 0; i < t.size(); i++) {
00240 if(t[i].size() > 3) {
00241 onlytris = false;
00242 break;
00243 }
00244 }
00245 Property* pr = meta_cast<Property*>(&polygons);
00246 if(!pr) return;
00247 if(onlytris) {
00248 unsigned char* data = (unsigned char*)malloc(t.size() * 12);
00249 for(unsigned int i = 0; i < t.size(); i++) {
00250 COD::pack(data + i*12, 12, "lll", t[i][0], t[i][1], t[i][2]);
00251 }
00252 pr->replace(string((char*)data, t.size() * 12), "packed/triangle-array");
00253 free(data);
00254 } else {
00255 int numvertices = 0;
00256 for(vector<Polygon>::size_type i = 0; i < t.size(); i++) {
00257 numvertices += t[i].size();
00258 }
00259
00260 unsigned char* data = (unsigned char*)malloc(t.size() + numvertices*4);
00261 int offset = 0;
00262 for(vector<Polygon>::size_type i = 0; i < t.size(); i++) {
00263 offset += COD::pack(data + offset, 1, "c", t[i].size());
00264 for(vector<int>::size_type n = 0; n < t[i].size(); n++) {
00265 offset += COD::pack(data + offset, 4, "l", t[i][n]);
00266 }
00267 }
00268 pr->replace(string((char*)data, t.size() + numvertices*4), "packed/polygon-list");
00269 free(data);
00270 }
00271 }
00272
00273 void PolygonMesh::setTexels(const vector<Texel>& uv)
00274 {
00275 vRef<Vobject> uvobj;
00276 try {
00277 uvobj = findObject("a3dl:texels");
00278 } catch(NoSuchObjectError) {
00279 vRef<Site> s = getSite();
00280 uvobj = s->createMetaObject("a3dl:texels", typeid(Property).name(), 0);
00281 LocalProperty* lp = meta_cast<LocalProperty*>(&uvobj);
00282 if(!lp) throw bad_cast();
00283 lp->insertPropertyAccessControl(-1, accesscontrol);
00284 insertChild(-1, "a3dl:texels", &uvobj);
00285 }
00286 try {
00287 Property* pr = meta_cast<Property*>(&uvobj);
00288 if(!pr) throw bad_cast();
00289 unsigned char* data = (unsigned char*)malloc(uv.size() * 8);
00290 for(unsigned int i = 0; i < uv.size(); i++) {
00291 COD::pack(data + i*8, 8, "ff", uv[i].x, uv[i].y);
00292 }
00293 pr->replace(string((char*)data, uv.size() * 8));
00294 free(data);
00295 } catch(bad_cast) {
00296 }
00297 }
00298
00299 void PolygonMesh::getVertices(vector<Vertex>& v)
00300 {
00301 string data;
00302
00303 vRef<Vobject> vert = findObject("a3dl:vertices");
00304 Property* pr = meta_cast<Property*>(&vert);
00305 if(!pr) throw bad_cast();
00306 pr->read(data);
00307
00308 int numvert = data.size() / 12;
00309 v.resize(numvert);
00310 for(int i = 0; i < numvert; i++) {
00311 COD::unpack((unsigned char*)data.c_str() + i*12, data.size(), "fff", &v[i].x, &v[i].y, &v[i].z);
00312 }
00313 }
00314
00315 void PolygonMesh::getNormals(vector<Vertex>& n)
00316 {
00317 string data;
00318
00319 vRef<Vobject> norm = findObject("a3dl:normals");
00320 Property* pr = meta_cast<Property*>(&norm);
00321 if(!pr) throw bad_cast();
00322 pr->read(data);
00323
00324 int numvert = data.size() / 12;
00325 n.resize(numvert);
00326 for(int i = 0; i < numvert; i++) {
00327 COD::unpack((unsigned char*)data.c_str() + i*12, data.size(), "fff", &n[i].x, &n[i].y, &n[i].z);
00328 }
00329 }
00330
00331
00332 void PolygonMesh::getPolygons(vector<Polygon>& t)
00333 {
00334 string data;
00335
00336 vRef<Vobject> vert = findObject("a3dl:polygons");
00337 Property* pr = meta_cast<Property*>(&vert);
00338 if(!pr) throw bad_cast();
00339 pr->read(data);
00340
00341 if(pr->getDataType() == "packed/triangle-array") {
00342 int numtri = data.size() / 12;
00343 t.resize(numtri);
00344 for(int i = 0; i < numtri; i++) {
00345 t[i].resize(3);
00346 COD::unpack((unsigned char*)data.c_str() + i*12, data.size(), "lll", &t[i][0], &t[i][1], &t[i][2]);
00347 }
00348 } else if(pr->getDataType() == "packed/polygon-list") {
00349 string::size_type offset = 0;
00350 while(offset < data.size()) {
00351 unsigned char n;
00352 offset += COD::unpack((unsigned char*)data.c_str() + offset, 1, "c", &n);
00353 Polygon p;
00354 for(int i = 0; i < n; i++) {
00355 int v;
00356 offset += COD::unpack((unsigned char*)data.c_str() + offset, 4, "l", &v);
00357 p.push_back(v);
00358 }
00359 t.push_back(p);
00360 }
00361 }
00362 }
00363
00364 void PolygonMesh::getTexels(vector<Texel>& uv)
00365 {
00366 string data;
00367
00368 vRef<Vobject> vert = findObject("a3dl:texels");
00369 Property* pr = meta_cast<Property*>(&vert);
00370 if(!pr) throw bad_cast();
00371 pr->read(data);
00372
00373 int numuv = data.size() / 8;
00374 uv.resize(numuv);
00375 for(int i = 0; i < numuv; i++) {
00376 COD::unpack((unsigned char*)data.c_str() + i*8, data.size(), "ff",
00377 &uv[i].x, &uv[i].y);
00378 }
00379 }
00380
00381 void PolygonMesh::packTextureSpace(unsigned char* data, const TextureSpace& t)
00382 {
00383
00384 unsigned char type = (unsigned char)t.type;
00385
00386 if(t.isPortal) type |= 0x80;
00387
00388 switch(t.type) {
00389 case NoTexture:
00390 COD::pack(data, 50, "cc", type, t.material);
00391 break;
00392 case UVcoord:
00393 COD::pack(data, 50, "cclfflfflff",
00394 type, t.material,
00395 t.Rep.UVcoord.vert1,
00396 t.Rep.UVcoord.u1,
00397 t.Rep.UVcoord.v1,
00398 t.Rep.UVcoord.vert2,
00399 t.Rep.UVcoord.u2,
00400 t.Rep.UVcoord.v2,
00401 t.Rep.UVcoord.vert3,
00402 t.Rep.UVcoord.u3,
00403 t.Rep.UVcoord.v3);
00404 break;
00405 case PolygonPlane:
00406 COD::pack(data, 50, "ccfffffff",
00407 type, t.material,
00408 t.Rep.PolygonPlane.xorg,
00409 t.Rep.PolygonPlane.yorg,
00410 t.Rep.PolygonPlane.zorg,
00411 t.Rep.PolygonPlane.x,
00412 t.Rep.PolygonPlane.y,
00413 t.Rep.PolygonPlane.z,
00414 t.Rep.PolygonPlane.len);
00415 break;
00416 case ArbitraryPlane:
00417 COD::pack(data, 50, "ccfffffffffff",
00418 type, t.material,
00419 t.Rep.ArbitraryPlane.xorg,
00420 t.Rep.ArbitraryPlane.yorg,
00421 t.Rep.ArbitraryPlane.zorg,
00422 t.Rep.ArbitraryPlane.x1,
00423 t.Rep.ArbitraryPlane.y1,
00424 t.Rep.ArbitraryPlane.z1,
00425 t.Rep.ArbitraryPlane.len1,
00426 t.Rep.ArbitraryPlane.x2,
00427 t.Rep.ArbitraryPlane.y2,
00428 t.Rep.ArbitraryPlane.z2,
00429 t.Rep.ArbitraryPlane.len2);
00430 break;
00431 case TexMatrix:
00432 COD::pack(data, 50, "ccffffffffffff",
00433 type, t.material,
00434 t.Rep.Matrix.m11, t.Rep.Matrix.m12, t.Rep.Matrix.m13,
00435 t.Rep.Matrix.m21, t.Rep.Matrix.m22, t.Rep.Matrix.m23,
00436 t.Rep.Matrix.m31, t.Rep.Matrix.m32, t.Rep.Matrix.m33,
00437 t.Rep.Matrix.x, t.Rep.Matrix.y, t.Rep.Matrix.z);
00438 break;
00439 }
00440 }
00441
00442 void PolygonMesh::unpackTextureSpace(const unsigned char* data, TextureSpace& t)
00443 {
00444
00445 unsigned int type;
00446 COD::unpack(data, 2, "cc", &type, &t.material);
00447 t.type = (TextureType)(type & 0x0F);
00448 t.isPortal = ((type & 0x80) == 0x80);
00449
00450 switch(t.type) {
00451 case UVcoord:
00452 COD::unpack(data + 2, 48, "lfflfflff",
00453 &t.Rep.UVcoord.vert1,
00454 &t.Rep.UVcoord.u1,
00455 &t.Rep.UVcoord.v1,
00456 &t.Rep.UVcoord.vert2,
00457 &t.Rep.UVcoord.u2,
00458 &t.Rep.UVcoord.v2,
00459 &t.Rep.UVcoord.vert3,
00460 &t.Rep.UVcoord.u3,
00461 &t.Rep.UVcoord.v3);
00462 break;
00463 case PolygonPlane:
00464 COD::unpack(data + 2, 48, "fffffff",
00465 &t.Rep.PolygonPlane.xorg,
00466 &t.Rep.PolygonPlane.yorg,
00467 &t.Rep.PolygonPlane.zorg,
00468 &t.Rep.PolygonPlane.x,
00469 &t.Rep.PolygonPlane.y,
00470 &t.Rep.PolygonPlane.z,
00471 &t.Rep.PolygonPlane.len);
00472 break;
00473 case ArbitraryPlane:
00474 COD::unpack(data + 2, 48, "fffffffffff",
00475 &t.Rep.ArbitraryPlane.xorg,
00476 &t.Rep.ArbitraryPlane.yorg,
00477 &t.Rep.ArbitraryPlane.zorg,
00478 &t.Rep.ArbitraryPlane.x1,
00479 &t.Rep.ArbitraryPlane.y1,
00480 &t.Rep.ArbitraryPlane.z1,
00481 &t.Rep.ArbitraryPlane.len1,
00482 &t.Rep.ArbitraryPlane.x2,
00483 &t.Rep.ArbitraryPlane.y2,
00484 &t.Rep.ArbitraryPlane.z2,
00485 &t.Rep.ArbitraryPlane.len2);
00486 break;
00487 case TexMatrix:
00488 COD::unpack(data + 2, 48, "ffffffffffff",
00489 &t.Rep.Matrix.m11, &t.Rep.Matrix.m12, &t.Rep.Matrix.m13,
00490 &t.Rep.Matrix.m21, &t.Rep.Matrix.m22, &t.Rep.Matrix.m23,
00491 &t.Rep.Matrix.m31, &t.Rep.Matrix.m32, &t.Rep.Matrix.m33,
00492 &t.Rep.Matrix.x, &t.Rep.Matrix.y, &t.Rep.Matrix.z);
00493 break;
00494 }
00495 }
00496
00497 void PolygonMesh::setTextureSpaces(const vector<TextureSpace>& t)
00498 {
00499 vRef<Vobject> tsobj;
00500 try {
00501 tsobj = findObject("a3dl:texturespaces");
00502 } catch(NoSuchObjectError) {
00503 vRef<Site> s = getSite();
00504 tsobj = s->createMetaObject("a3dl:texturespaces", typeid(Property).name(), 0);
00505 LocalProperty* lp = meta_cast<LocalProperty*>(&tsobj);
00506 if(!lp) throw bad_cast();
00507 lp->insertPropertyAccessControl(-1, accesscontrol);
00508 insertChild(-1, "a3dl:texturespaces", &tsobj);
00509 }
00510 Property* pr = meta_cast<Property*>(&tsobj);
00511 if(!pr) return;
00512 unsigned char* data = (unsigned char*)malloc(t.size() * 50);
00513 memset(data, 0, t.size() * 50);
00514 for(unsigned int i = 0; i < t.size(); i++) {
00515 packTextureSpace(data + i*50, t[i]);
00516 }
00517 pr->replace(string((char*)data, t.size() * 50), "packed/texture-space-array");
00518 free(data);
00519 }
00520
00521
00522
00523 void PolygonMesh::getTextureSpaces(vector<TextureSpace>& t)
00524 {
00525 string data;
00526
00527 vRef<Vobject> tris = findObject("a3dl:texturespaces");
00528 Property* pr = meta_cast<Property*>(&tris);
00529 if(!pr) return;
00530 pr->read(data);
00531
00532 if(pr->getDataType() == "packed/texture-space-array") {
00533 int numts = data.size() / 50;
00534 t.resize(numts);
00535 for(int i = 0; i < numts; i++) {
00536 unpackTextureSpace((unsigned char*)data.c_str() + i*50, t[i]);
00537 }
00538 }
00539 }
00540
00541 void PolygonMesh::setTextureSpace(unsigned int which, const TextureSpace& t)
00542 {
00543 string data;
00544
00545 vRef<Vobject> vert = findObject("a3dl:texturespaces");
00546 Property* pr = meta_cast<Property*>(&vert);
00547 if(!pr) return;
00548 pr->read(data);
00549
00550 unsigned char* newdata;
00551 int newdatasize;
00552 if(which * 50 > data.size()) {
00553 int existingVerts = data.size() / 50;
00554 int needNew = which - existingVerts;
00555 newdatasize = (needNew + 1) * 50;
00556 newdata = (unsigned char*)malloc(newdatasize);
00557 for(int i = 0; i < needNew; i++) {
00558 memset(newdata + i*50, 0, 50);
00559 }
00560 } else {
00561 newdata = (unsigned char*)malloc(50);
00562 newdatasize = 50;
00563 }
00564
00565 packTextureSpace(newdata + newdatasize - 50, t);
00566
00567 if(which * 50 > data.size()) pr->write(data.size(), string((char*)newdata, newdatasize));
00568 else pr->write(which * 50, string((char*)newdata, newdatasize));
00569 free(newdata);
00570 }
00571
00572
00573 void PolygonMesh::setDoubleSided(bool ds)
00574 {
00575 Property::setProperty(*this, "a3dl:doublesided", ds ? "yes" : "no", "text/x-yes-no", accesscontrol);
00576 }
00577
00578 bool PolygonMesh::getDoubleSided()
00579 {
00580 try {
00581 vRef<Vobject> prop = findObject("a3dl:doublesided");
00582 Property& pr = meta_cast<Property&>(*prop);
00583 return (pr.read() == "yes");
00584 } catch(...) {
00585 return false;
00586 }
00587 }
00588
00589 vector<Portal*> PolygonMesh::getPortals()
00590 {
00591 vector<Portal*> t;
00592 const ChildList& cl = getChildren();
00593 for(unsigned int i = 0; i < cl.size(); i++) {
00594 if(cl[i]->contextual_name == "a3dl:portal") {
00595 if(Portal* p = meta_cast<Portal*>(cl[i]->child)) t.push_back(p);
00596 }
00597 }
00598 return t;
00599 }
00600
00601
00602 MetaObject* PolygonMesh::new_PolygonMesh(MetaObject* superobject, const string& type)
00603 {
00604 return new PolygonMesh(superobject);
00605 }
00606
00607 const string PolygonMesh::getType()
00608 {
00609 return "a3dl:object3D.polygonmesh";
00610 }
00611
00612 void PolygonMesh::registerExtenders()
00613 {
00614 LocalSite::addLocalObjectExtension(typeid(PolygonMesh).name(), &PolygonMesh::new_PolygonMesh);
00615 LocalSite::addLocalObjectExtension("a3dl:object3D.polygonmesh", &PolygonMesh::new_PolygonMesh);
00616 RemoteSite::addRemoteObjectExtension(typeid(PolygonMesh).name(), &PolygonMesh::new_PolygonMesh);
00617 RemoteSite::addRemoteObjectExtension("a3dl:object3D.polygonmesh", &PolygonMesh::new_PolygonMesh);
00618 }