vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PointShell_Object_Data.h
Go to the documentation of this file.
1 #ifndef POINTSHELL_OBJECT_DATA_H
2 #define POINTSHELL_OBJECT_DATA_H
3 
4 #include <list>
5 #include <vector>
6 #include <stack>
7 #include <string>
8 
10 
11 #include "GeometryLoaderBase.h"
12 #include "SP_Object_Data_Base.h"
13 #include <vrecko/Ability.h>
14 #include <vrecko/Scene.h>
15 #include <helpers/DynamicTree.h>
16 #include <helpers/BufFile.h>
17 
18 #include <osg/BoundingBox>
19 #include <osg/PolygonMode>
20 #include <osg/StateSet>
21 #include <osg/Geode>
22 #include <osg/ShapeDrawable>
23 #include <osg/Material>
24 #include <osg/Geometry>
25 
26 
27 #define FACE(x) ((FaceBase*)getFace(x))
28 #define VERTEX(x) ((VertexBase*)getVertex(x))
29 
30 namespace APSpacePartitioning {
31 
32 template <class _NodeType>
34 public:
35 
36  /*
37  * enumeration list of supported pointshell creatin lists
38  */
39  enum CreationType {
45  };
46 
49  PointShellGeneric_Object_Data(const char *abName);
51 
52  virtual bool isHierarchyCreated() { return bCreated;}
56  vector<pair<osg::Vec3f,osg::Vec3f>> getPolygons(){
57  vector<pair<osg::Vec3f,osg::Vec3f>> out;
58  for (int p = 0 ; p < polygonsCount; p++) {
59  out.push_back(make_pair(polygons[p].first,polygons[p].second));
60  }
61  return out;
62  }
66  vector<pair<osg::Vec3f,float>> getDrawSpheres(){
67  vector<pair<osg::Vec3f,float>> out;
68  PointShell_SimpleNode* child = treeLOD.GetRoot()->lpChild;
69  while (child->lpNext){
70  out.push_back(make_pair(child->pos,child->radius));
71  child = child->lpNext;
72  }
73  return out;
74  }
75 
76  virtual int getPolygonsCount(){return getFaceCount();}
78  virtual void destroyPointShells();
79  virtual void destroyPointShell(CreationType type);
85  if (creationType == LOD_Hierarchy) {
86  return treeLOD.GetCount();
87  } else if (creationType == Simple){
88  return treeSimple.GetCount();
89  } else if (creationType == ByVoxels_SingleLevel){
90  return treeSingleLevel.GetCount();
91  } else if (creationType == ByVoxels_MultiLevel){
92  return treeMultiLevel.GetCount();
93  }
94  return NULL;
95  }
99  _NodeType* getRoot(){
100  if (creationType == LOD_Hierarchy) {
101  return treeLOD.GetRoot();
102  } else if (creationType == Simple){
103  return treeSimple.GetRoot();
104  } else if (creationType == ByVoxels_SingleLevel){
105  return treeSingleLevel.GetRoot();
106  } else if (creationType == ByVoxels_MultiLevel){
107  return treeMultiLevel.GetRoot();
108  }
109  return NULL;
110 
111  }
112 
113  /*
114  * returns the top node (Root) of the tree by requested CreationType
115  */
116  _NodeType* getRoot(CreationType type) {
117  if (type == Simple) {
118  return treeSimple.GetRoot();
119  } else if (type == LOD_Hierarchy) {
120  return treeLOD.GetRoot();
121  } else if (type == ByVoxels_SingleLevel){
122  return treeSingleLevel.GetRoot();
123  } else if (type == ByVoxels_MultiLevel){
124  return treeMultiLevel.GetRoot();
125  }
126  return NULL;
127  }
128  float maxDist;
129  osg::Vec3f maxDistVect;
131  int getCollisions(int id){getNodeWithIDFromTree( treeCollisions.getRoot(), id);}
133 protected:
134  pair<osg::Vec3f,osg::Vec3f>* polygons;
153  bool bCreated;
155  void buildLODTree();
158  bool loadNodeFromFileRec(_NodeType *node, vrecko::BufferedFile *bfile, DynamicTree<_NodeType>* t ); // recursive load
159 
161  bool saveNodeToFileRec(_NodeType *node, vrecko::BufferedFileWrite *bfile); // recursive save
162 
163  //for testing purposes
165 
166  bool ready(){
168  treeLODCreated = (treeLOD.GetCount() > 0);
171 
172  if (creationType == LOD_Hierarchy) {
174  } else if ( creationType == Simple){
176  } else if ( creationType == ByVoxels_SingleLevel) {
178  } else if ( creationType == ByVoxels_MultiLevel) {
180  }
181 
182  return bCreated;
183  }
184  virtual bool coreHierarchyCreation(void);
185 };
186 
187 
188 class PointShell_SimpleNode : public DynTreeNode<PointShell_SimpleNode> {
189 public:
190  osg::Vec3 pos;
191  osg::Vec3 iNorm; // inward normal (opposite of the usual normal!)
192  float radius;
193  int id;
195 
197  return
198  bfile->readFloat(&pos.x()) &&
199  bfile->readFloat(&pos.y()) &&
200  bfile->readFloat(&pos.z()) &&
201  bfile->readFloat(&iNorm.x()) &&
202  bfile->readFloat(&iNorm.y()) &&
203  bfile->readFloat(&iNorm.z()) &&
204  bfile->readFloat(&radius) &&
205  bfile->readInt(&id) &&
206  bfile->readInt(&collisions);
207  }
208 
210  return
211  bfile->writeFloat(pos.x()) &&
212  bfile->writeFloat(pos.y()) &&
213  bfile->writeFloat(pos.z()) &&
214  bfile->writeFloat(iNorm.x()) &&
215  bfile->writeFloat(iNorm.y()) &&
216  bfile->writeFloat(iNorm.z()) &&
217  bfile->writeFloat(radius) &&
218  bfile->writeInt(id) &&
219  bfile->writeInt(collisions);
220  }
221 };
222 
223 
224 class PointShell_Object_Data: public PointShellGeneric_Object_Data<PointShell_SimpleNode> {
225 public:
228 
229  virtual bool loadXMLParameters(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *pParametersNode);
230 
232  float getMaximumDistance();
233  int getPointShellRootSize();
234  osg::Vec3f getMaximumDistanceVector();
235 
236  osg::Vec4f PointShell_Object_Data::getColor(int collisions){
237  float percentage = (float)collisions/(float)collisionsMax;
238  if (collisionsMax == 0) collisionsMax++;
239  //(log(x+1)*1.4)^0.5 where x = 0 to 1
240  float c = (float)collisions/(float)collisionsMax;
241  // c (x) is now 0 to 1
242  float cR = pow(log(c+1)*1.4,0.5);
243  osg::Vec4f color;
244  float red = min(cR/0.5f,1.0f);
245  float green = min((1-cR)/0.5f,1.0);
246  float blue = 0;
247  color.set(red,green,blue,1.0);
248  return color;
249  }
250 
251 protected:
252  void createSimple(); // simple hierarchy creation (onlu vertices are taken)
253  void createLODHierarchy(); // LOD hierarchyh based on LOD Progressive Mesh decimation
254  void createSingleLevel(double minx, double miny, double minz, double velm); // unknown
255  void createMultiLevel(double minx, double miny, double minz, double velm); // unknown
256 
257  // comutation of Bounding boxes for hierarchy
260 
261  //createds a LOD Tree from given lodbuilder
263  //inserting a point into a tree as a child of p.
265 
266  // save a subdivided mesh to file to not compute again
268  // load a subdivided mesh
270 
271  int voxResolution; // resolution of the voxel grid used when creating the PointShell SingleLevel/MultiLevel
272  int spBranchingFactor; // Controls the creation of different PointShell hierarchy levels.
273  // Size of the n-th level is "spBranchingFactor ^ n"
274 
275  // lod parameters
284 
285  // stored collisions amounth
288 
289  struct PSpoint {
290  double x,y,z;
291  double a,b,c;
292  };
293 
294  vector<PSpoint> voxels;
295  vector<PSpoint> ordered;
296  vector< vector<PSpoint> > levels;
297 
298  inline double distance_sqr(PSpoint *voxel1, PSpoint *voxel2) {
299  return (pow(voxel2->x - voxel1->x, 2) + pow(voxel2->y - voxel1->y, 2) + pow(voxel2->z - voxel1->z, 2));
300  }
301 
302  inline double distance(PSpoint *voxel1, PSpoint *voxel2) {
303  return (sqrt(distance_sqr(voxel1, voxel2)));
304  }
305 
306  bool constructPointShellCacheDataName(char *pOutDataName);
307  bool constructPointShellCacheDataName(char *pOutDataName, CreationType type);
308  bool constructPointShellSubdividedMeshDataName(char *pOutDataName);
309 
310  bool loadFromCache(const char *pModelFileName); // -> depending on the options there can be many caches for a single model
311  bool saveToCache(const char *pModelFileName);
312 
313  virtual bool coreHierarchyCreation(void);
314 
315  // saving pointshell collisions
318 
320 
321 };
322 
323 
324 template <class _NodeType>
326  bCreated = false;
327 }
328 
329 
330 template <class _NodeType>
332  destroyPointShells();
333  delete [] polygons;
334 }
335 
336 
337 template <class _NodeType>
339 
340  if (!pOwner)
341  return false;
342 
343  destroyPointShell(Simple);
344 
345  if (!loadGeometry((EnvironmentObject*)pOwner)) {
346  logger.warningLog("PointShell generation aborted - no geometry found (Obj ID: %d).", ((EnvironmentObject*)pOwner)->getID());
347  return false;
348  }
349 
350 
352 
353  node = new PointShell_SimpleNode(); // empty root
354  treeSimple.AddNode(NULL, node);
355 
356  for (unsigned long dw = 0; dw < getVertexCount(); dw++) {
357  // transfer vertices into the PointShell structure
358  node = new PointShell_SimpleNode();
359  node->pos = ((VertexBase*)getVertex(dw))->pos;
360  node->iNorm = -((VertexBase*)getVertex(dw))->normal;
361  treeSimple.AddNode(treeSimple.GetRoot(), node);
362  }
363 
364  //computation of maximum distance in object
365  //and storing a maximum distance of vector.
366  osg::Vec3f v1, v2;
367  for (int s = 0; s < (int)getVertexCount();s++){
368  v1 = ((VertexBase*)getVertex(s))->pos;
369  for (int e = 0;e < (int)getVertexCount();e++){
370  v2 = ((VertexBase*)getVertex(e))->pos;
371  if (maxDist < (v1-v2).length2()){
372  maxDist = (v1-v2).length2();
373  maxDistVect.set((v1-v2).x(),(v1-v2).y(),(v1-v2).z());
374  }
375  }
376  }
377  maxDist = sqrt(maxDist);
378 
379  bCreated = true;
380 
381  return true;
382 }
383 
384 
385 template <class _NodeType>
387  treeSimple.Clear(true);
388  treeLOD.Clear(true);
389  treeSingleLevel.Clear(true);
390  treeMultiLevel.Clear(true);
391 
392  bCreated = false;
393 }
394 
395 template <class _NodeType>
397  if (type == Simple) {
398  treeSimple.Clear(true);
399  } else if (type == LOD_Hierarchy){
400  treeLOD.Clear(true);
401  } else if (type == ByVoxels_SingleLevel) {
402  treeSingleLevel.Clear(true);
403  } else if (type == ByVoxels_MultiLevel) {
404  treeMultiLevel.Clear(true);
405  }
406 
407  bCreated = false;
408 }
409 
410 
411 template <class _NodeType>
413  int i;
414 
415  t->Clear(true);
416 
417  if (!bfile->readInt(&i) || (i != 1)) // version
418  return false;
419 
420  bool b;
421  if (!bfile->readBool(&b))
422  return false;
423 
424  if (!b) // -> not even a root node, we are done here
425  return true;
426 
427  t->AddNode(NULL, new PointShell_SimpleNode()); // simple root node
428 
429  if (!loadNodeFromFileRec(t->GetRoot(), bfile,t))
430  return false;
431 
432  return true;
433 }
434 
435 
436 template <class _NodeType>
438 
439  if (!node->loadDataFromFile(bfile))
440  return false;
441 
442  _NodeType *child;
443  bool b;
444  while (true) {
445  bfile->readBool(&b);
446  if (!b) // no more children
447  break;
448 
449  child = new PointShell_SimpleNode();
450  if (!(t->AddNode(node, child)))
451  return false;
452 
453  if (!loadNodeFromFileRec(child, bfile,t))
454  return false;
455 
456  }
457 
458  return true;
459 }
460 
461 
462 template <class _NodeType>
464  bfile->writeInt(1); // version
465 
466  if (!(t->GetRoot())) {
467  bfile->writeBool(false);
468  } else {
469  bfile->writeBool(true);
470  if (!saveNodeToFileRec(t->GetRoot(), bfile))
471  return false;
472  }
473 
474  return true;
475 }
476 
477 
478 template <class _NodeType>
480  if (!node->saveDataToFile(bfile))
481  return false;
482 
483  _NodeType *child = node->lpChild;
484  while (child) {
485  bfile->writeBool(true); // i.e. next child exists
486  saveNodeToFileRec(child, bfile);
487  child = child->lpNext;
488  }
489  bfile->writeBool(false); // i.e. there is no next child
490 
491  return true;
492 }
493 
494 } // namespace APSpacePartitioning
495 
496 
497 #endif
498