vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Geometry.h
Go to the documentation of this file.
1 #ifndef _Geometry_H
2 #define _Geometry_H
3 
4 #include <vrecko/Logger.h>
5 
7 #include <xercesc/parsers/XercesDOMParser.hpp>
8 #include <xercesc/dom/DOM.hpp>
9 #include <xercesc/sax/HandlerBase.hpp>
10 #include <xercesc/util/XMLString.hpp>
11 #include <xercesc/util/PlatformUtils.hpp>
12 
13 #include <osg/Geometry>
14 #include <vector>
15 #include <cmath>
16 #include <osg/ref_ptr>
17 #include <iostream>
18 #include "RealCmp.h"
19 
20 #define RE_DEFAULT_HEIGHT 20.0
21 #define RE_DEFAULT_BOTTOM 0.0
22 #define RE_DEFAULT_2_WIDTH 0.75
23 #define RE_MIN_LENGTH 5.0
24 #define RE_DEFAULT_COLOR osg::Vec3(1.0, 1.0, 1.0)
25 #define RE_MIN_ANGLE(x,y) ((x)<(y) ? 2*(RE_DEG_2_RAD_RATIO)*asin((RE_DEFAULT_2_WIDTH)/(x)) : 2*(RE_DEG_2_RAD_RATIO)*asin((RE_DEFAULT_2_WIDTH)/(y)))
26 
27 #define RE_DEG_2_RAD_RATIO (180.0 / 3.141592653589793238)
28 
29 #define RE_WALL_ANGLES_COMPUTED 1
30 #define RE_WALL_DRAWN 2
31 
32 using namespace vrecko;
33 
34 namespace WGeometry
35 {
36  enum PointType {
39  };
40 
42  // class with helpful geometric methods
43  class WG_Geometry {
44  public:
47 
48  static bool getCrossingPoint(osg::Vec2& destPoint, osg::Vec2 pPoint, osg::Vec2 pNormal, osg::Vec2 rPoint, osg::Vec2 rNormal, bool justStroke) {
49  float d1, d2, div;
50  float resultX, resultY;
51  float param, tparam;
52 
53  d1 = -1*(pPoint.x() * pNormal.x() + pPoint.y() * pNormal.y());
54  d2 = -1*(rPoint.x() * rNormal.x() + rPoint.y() * rNormal.y());
55  div = (rNormal.x() * pNormal.y() - pNormal.x() * rNormal.y());
56 
57  bool result = false;
58 
59  if (!RealCmp<float>::compareEQ(div, 0.0f)) { // are not parallel
60  resultX = (d1 * rNormal.y() - d2 * pNormal.y()) / div;
61  if (RealCmp<float>::compareEQ(pNormal.y(), 0.0f)) {
62  resultY = (-d2 - rNormal.x() * resultX) / rNormal.y();
63  }
64  else {
65  resultY = (-d1 - pNormal.x() * resultX) / pNormal.y();
66  }
67 
68  if (RealCmp<float>::compareEQ(pNormal.x(), 0.0f))
69  param = (resultX - pPoint.x()) / pNormal.y();
70  else
71  param = (resultY - pPoint.y()) / (-pNormal.x());
72 
73  if (RealCmp<float>::compareEQ(rNormal.x(), 0.0f))
74  tparam = (resultX - rPoint.x()) / rNormal.y();
75  else
76  tparam = (resultY - rPoint.y()) / (-rNormal.x());
77 
78  destPoint = osg::Vec2(resultX, resultY);
79  if (justStroke)
80  result = ((param > 0.000009) && (param < 0.999999) && (tparam > 0.000009) && (tparam < 0.999999));
81  else
82  result = true;
83  }
84 
85  return result;
86  }
87 
88  static bool barycentricTest(osg::Vec2 P, osg::Vec2 A, osg::Vec2 B, osg::Vec2 C) {
89  // Compute vectors
90  osg::Vec2 v0 = C - A,
91  v1 = B - A,
92  v2 = P - A;
93 
94  // Compute dot products
95  float dot00 = v0 * v0,
96  dot01 = v0 * v1,
97  dot02 = v0 * v2,
98  dot11 = v1 * v1,
99  dot12 = v1 * v2;
100 
101  // Compute barycentric coordinates
102  float invDenom = 1 / (dot00 * dot11 - dot01 * dot01),
103  u = (dot11 * dot02 - dot01 * dot12) * invDenom,
104  v = (dot00 * dot12 - dot01 * dot02) * invDenom;
105 
106  // Check if point is in triangle
107  return (u >= 0) && (v >= 0) && (u + v <= 1);
108  }
109 
110 
111  static float getAngle(osg::Vec2& vector) {
112 
113  float angle, toSum = 0;
114  if (RealCmp<float>::compareEQ(vector.x(), 0.0f)) {
115  if (vector.y() >= 0) {
116  angle = 90;
117  }
118  else {
119  angle = 270;
120  }
121  }
122  else if(RealCmp<float>::compareEQ(vector.y(), 0.0f)) {
123  if (vector.x() >= 0) {
124  angle = 0;
125  }
126  else {
127  angle = 180;
128  }
129  }
130  else {
131  if ((vector.x() > 0) && (vector.y() > 0)) {
132  toSum = 0;
133  }
134  else if ((vector.x() < 0) && (vector.y() > 0)) {
135  toSum = 180;
136  }
137  else if ((vector.x() < 0) && (vector.y() < 0)) {
138  toSum = 180;
139  }
140  else {
141  toSum = 360;
142  }
143  angle = ((atan(vector.y() / vector.x())*RE_DEG_2_RAD_RATIO) + toSum);
144  }
145  return angle;
146  }
147  };
148 
149  class WG_Wall;
150 
152  // class which just stores some vertices (used in WGWall)
153  class WG_Vertices {
154  public:
155  WG_Vertices() { validVertices = false; }
156  virtual ~WG_Vertices() {}
157 
159  // setters and getters
160  void setTopCWVertex(osg::Vec3 P) { topCWVertex = P; }
161  osg::Vec3 getTopCWVertex() { return topCWVertex; }
162 
163  void setTopCCWVertex(osg::Vec3 P) { topCCWVertex = P; }
164  osg::Vec3 getTopCCWVertex() { return topCCWVertex; }
165 
166  void setBottomCWVertex(osg::Vec3 P) { bottomCWVertex = P; }
167  osg::Vec3 getBottomCWVertex() { return bottomCWVertex; }
168 
169  void setBottomCCWVertex(osg::Vec3 P) { bottomCCWVertex = P; }
170  osg::Vec3 getBottomCCWVertex() { return bottomCCWVertex; }
171 
172  void setNormalCWVertex(osg::Vec2 P) { normalCWVertex = P; }
173  osg::Vec2 getNormalCWVertex() { return normalCWVertex; }
174 
175  void setNormalCCWVertex(osg::Vec2 P) { normalCCWVertex = P; }
176  osg::Vec2 getNormalCCWVertex() { return normalCCWVertex; }
177 
178  void setValidVertices(bool valid) { validVertices = valid; }
179  bool areValidVertices() { return validVertices; }
180 
181  private:
182  osg::Vec3 topCWVertex;
183  osg::Vec3 topCCWVertex;
184  osg::Vec3 bottomCWVertex;
185  osg::Vec3 bottomCCWVertex;
186 
187  osg::Vec2 normalCWVertex;
188  osg::Vec2 normalCCWVertex;
189 
190  bool validVertices;
191  };
192 
193 
195  // class representin a point of a wall
196  class WG_Point : public osg::Referenced {
197  public:
198  WG_Point(osg::Vec2 position, float height = RE_DEFAULT_HEIGHT) { this->position = position; this->height = height; }
199  virtual ~WG_Point() { plusVertices.clear(); plusNormals.clear(); plusColors.clear(); }
200 
202  // setters and getters
203  void setPosition(osg::Vec2 position) {
204  this->position = position;
205  }
206  osg::Vec2 getPosition() { return position; }
207 
208  float getHeight() { return height; }
209 
210  void addWall(WG_Wall* wall, PointType connectionPointType, bool compute = true);
211  void removeWall(WG_Wall* wall);
212  std::vector<std::pair<osg::ref_ptr<WG_Wall>, PointType> >* getWalls() { return &walls; }
213 
214  void setId(unsigned int i) { id = i; }
215  unsigned int getId() { return id; }
216 
217  void setIndexTop(unsigned int i) { indexTop = i; }
218  unsigned int getIndexTop() { return indexTop; }
219 
220  void setIndexBottom(unsigned int i) { indexBottom = i; }
221  unsigned int getIndexBottom() { return indexBottom; }
222 
223  std::vector<osg::Vec3>* getPlusVertices() { return &plusVertices; }
224  std::vector<osg::Vec3>* getPlusNormals() { return &plusNormals; }
225  std::vector<osg::Vec3>* getPlusColors() { return &plusColors; }
226 
228  // returns wall neighbours from the attribute walls
229  bool getWallNeighbours(WG_Wall* wall, std::pair<osg::ref_ptr<WG_Wall>, PointType>& wallCW, std::pair<osg::ref_ptr<WG_Wall>, PointType>& wallCCW);
230 
231  private:
232  osg::Vec2 position;
233  float height;
234 
235  unsigned int id; // = index to array of points in WallGeometry Ability
236 
237  std::vector<std::pair<osg::ref_ptr<WG_Wall>, PointType> > walls; // walls connected to the point
238 
239  unsigned int indexTop;
240  unsigned int indexBottom;
241 
242  std::vector<osg::Vec3> plusVertices; // used when drawing walls
243  std::vector<osg::Vec3> plusNormals;
244  std::vector<osg::Vec3> plusColors;
245  };
246 
247  enum HoleType {
250  };
251 
252 
254  // class representin a hole in the wall
255  class WG_Hole {
256  public:
257  WG_Hole(float position, float y, float height, float width, HoleType type) {
258  this->position = position;
259  this->y = y;
260  this->height = height;
261  this->width = width;
262  this->type = type;
263  }
264  ~WG_Hole() {}
265 
267  // setters and getters
268  void setPosition(float position) { this->position = position; }
269  float getPosition() { return position; }
270 
271  void setY(float y) { this->y = y; }
272  float getY() { return y; }
273 
274  void setHeight(float height) { this->height = height; }
275  float getHeight() { return height; }
276 
277  void setWidth(float width) { this->width = width; }
278  float getWidth() { return width; }
279 
280  void setType(HoleType type) { this->type = type; }
281  HoleType getType() { return type; }
282 
283  WG_Vertices* getQVertices() { return &qVertices; }
284  WG_Vertices* getRVertices() { return &rVertices; }
285 
286  private:
287  float position; // distance from Q
288  float y;
289 
290  float height;
291  float width;
292  HoleType type;
293  WG_Vertices qVertices;
294  WG_Vertices rVertices;
295  };
296 
297 
299  // important class representing a wall
300  class WG_Wall : public osg::Referenced {
301  public:
302  WG_Wall(WG_Point* qPoint, WG_Point* rPoint, bool compute = true) {
303  flag = 0; q = qPoint; r = rPoint;
304  qAttr.color = RE_DEFAULT_COLOR;
305  rAttr.color = RE_DEFAULT_COLOR;
306  computeAttrVectorsAndAngles();
307 
308  qPoint->addWall(this, WG_Q_POINT, compute);
309  rPoint->addWall(this, WG_R_POINT, compute);
310 
311  if (compute)
312  computeAttrVertices();
313  }
314  virtual ~WG_Wall() {}
315 
317  // setters and getters
318  void setPoints(WG_Point* qPoint, WG_Point* rPoint) {
319  q->removeWall(this); r->removeWall(this);
320  q = qPoint; r = rPoint;
321  computeAttrVectorsAndAngles();
322  q->addWall(this, WG_Q_POINT);
323  r->addWall(this, WG_R_POINT);
324  computeAttrVertices();
325  }
326 
327  void setPoint(WG_Point* point, PointType type) {
328  if (type==WG_Q_POINT) {
329  q->removeWall(this);
330  q = point;
331  computeAttrVectorsAndAngles();
332  q->addWall(this, WG_Q_POINT);
333  }
334  else {
335  r->removeWall(this);
336  r = point;
337  computeAttrVectorsAndAngles();
338  r->addWall(this, WG_R_POINT);
339  }
340  computeAttrVertices();
341  }
342 
343  WG_Point* getPoint(PointType type) { return (type==WG_Q_POINT ? q.get() : r.get()); }
344  osg::ref_ptr<WG_Point> getPointRef(PointType type) { return (type==WG_Q_POINT ? q : r); }
345 
346  osg::Vec2 getVector(PointType type) { return (type==WG_Q_POINT ? qAttr.vector : rAttr.vector); }
347  float getAngle(PointType type) { return (type==WG_Q_POINT ? qAttr.angle : rAttr.angle); }
348  WG_Vertices* getVertices(PointType type) { return (type==WG_Q_POINT ? &(qAttr.vertices) : &(rAttr.vertices)); }
349 
350  void setColor(osg::Vec3 color, PointType type) { type==WG_Q_POINT ? qAttr.color = color : rAttr.color = color; }
351  osg::Vec3 getColor(PointType type) { return (type==WG_Q_POINT ? qAttr.color : rAttr.color); }
352 
353  void setId(unsigned int i) { id = i; }
354  unsigned int getId() { return id; }
355 
356  void setFlag(int flag) { this->flag = flag; }
357  int getFlag() { return flag; }
358 
359  void setTopNormal(osg::Vec3 n) { topNormal = n; }
360  osg::Vec3 getTopNormal() { return topNormal; }
361 
362  void setBottomNormal(osg::Vec3 n) { bottomNormal = n; }
363  osg::Vec3 getBottomNormal() { return bottomNormal; }
364 
365  void setFaceNormal(osg::Vec3 n, PointType type) { (type==WG_Q_POINT ? qrNormal = n : rqNormal = n); }
366  osg::Vec3 getFaceNormal(PointType type) { return (type==WG_Q_POINT ? qrNormal : rqNormal); }
367 
368  std::vector<WG_Hole>* getHoles() { return &holes; }
369 
371  // computes both angles an vectors
372  void computeAttrVectorsAndAngles();
373  bool areAnglesComputed() { return flag & RE_WALL_ANGLES_COMPUTED; }
374 
376  // computes vertices and normals for vertexArray and normalArray
377  void computeAttrVertices(PointType type);
378  void computeAttrVertices() { computeAttrVertices(WG_Q_POINT); computeAttrVertices(WG_R_POINT); computeAttrNormals(); computeHoleVertices(); }
379 
380  bool computeAttrNormals();
381  void computeHoleVertices();
382 
383  private:
384  struct PointRelatedAttr {
385  osg::Vec2 vector; // started from the point
386  float angle; // CCW angle of the vector
387 
388  WG_Vertices vertices;
389  osg::Vec3 color; // color of the quad that has front face with vector going left to right
390  };
391 
392  osg::ref_ptr<WG_Point> q;
393  PointRelatedAttr qAttr;
394 
395  osg::ref_ptr<WG_Point> r;
396  PointRelatedAttr rAttr;
397 
398  int flag;
399  unsigned int id;
400 
401  osg::Vec3 topNormal;
402  osg::Vec3 bottomNormal;
403  osg::Vec3 qrNormal;
404  osg::Vec3 rqNormal;
405 
406  std::vector<WG_Hole> holes;
407 
409  // sets vector P2 - P1 and angle into corresponding attributes
410  void setVectorAndAngle(WG_Point* P1, WG_Point* P2, PointRelatedAttr* attr);
411 
413  // computes normal from 3 points that form a triangle (half of a quad)
414  osg::Vec3 computeNormal(osg::Vec3 V1, osg::Vec3 V2, osg::Vec3 V3) {
415  osg::Vec3 A = V1 - V2;
416  osg::Vec3 B = V3 - V2;
417  osg::Vec3 normal = osg::Vec3((A.y() * B.z() - A.z() * B.y()), (A.z() * B.x() - A.x() * B.z()), (A.x() * B.y() - A.y() * B.x()));
418  normal.normalize();
419  return normal;
420  }
421 
422  };
423 
424 
425 }
426 
427 #endif
428