vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
WallAdd.h
Go to the documentation of this file.
1 #ifndef _WALL_ADD_H
2 #define _WALL_ADD_H
3 
4 #include "Tool.h"
5 
6 namespace APRoomEdit {
7 
8 
9  // tool that adds new wall into room
10  class WallAdd : public Tool {
11  public:
13  virtual ~WallAdd() {}
14 
15  virtual bool loadXMLParameters(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *pParametersNode) {
16  if (findXMLNode(pParametersNode, "Name")) {
17  ReaderWriter::getStringValue(name, pParametersNode, "Name");
18  } else {
19  name = "WallAdd";
20  }
21  return true;
22  }
23 
24 
25  virtual void init(osgUtil::LineSegmentIntersector::Intersection* intersection, WG_Wall* curWall, WG_Point* curPoint, PointType type, vrecko::EnvironmentObject* pEOOwner, std::vector<osg::ref_ptr<WG_Wall> >* walls, std::vector<osg::ref_ptr<WG_Point> >* points, osg::Geode* pOSGGeode, osg::Vec3Array* pOSGVertexArray) {
26  insideWalls = false;
27  movingPoint = NULL;
28  startingPoint = NULL;
29 
30  if (curWall != NULL) {
31  bool splitted = false;
32  WG_Wall* newWall;
33 
34  osg::Vec2 iPoint = osg::Vec2(intersection->getLocalIntersectPoint().x(), intersection->getLocalIntersectPoint().z());
35  osg::Vec2 iNormal = curWall->getVector(WG_Q_POINT);
36 
37  osg::Vec2 curNormal(-curWall->getVector(WG_Q_POINT).y(),curWall->getVector(WG_Q_POINT).x());
38 
39  osg::Vec2 crossPoint;
40  WG_Geometry::getCrossingPoint(crossPoint, curWall->getPoint(WG_Q_POINT)->getPosition(), curNormal, iPoint, iNormal, false);
41 
42  WG_Point* Q = curWall->getPoint(WG_Q_POINT);
43  WG_Point* R = curWall->getPoint(WG_R_POINT);
44 
45  osg::Vec2 qVec = Q->getPosition() - crossPoint;
46  osg::Vec2 rVec = R->getPosition() - crossPoint;
47 
48  osg::Vec2 mpVector;
49 
50  if ((qVec.length() < RE_MIN_LENGTH) && (rVec.length() < RE_MIN_LENGTH)) {
51  if (qVec.length() < rVec.length()) {
52  startingPoint = Q;
53  }
54  else {
55  startingPoint = R;
56  }
57  }
58  else if (qVec.length() < RE_MIN_LENGTH) {
59  startingPoint = Q;
60  }
61  else if (rVec.length() < RE_MIN_LENGTH) {
62  startingPoint = R;
63  }
64  else {
65  bool isWall;
66  osg::Vec2 dummy, normalI, mpNormal;
67  mpVector = -osg::Vec2(curWall->getFaceNormal(type).x(), curWall->getFaceNormal(type).z());
68  mpVector.normalize();
69  mpVector *= (RE_MIN_LENGTH*1.5);
70  mpNormal = osg::Vec2(-mpVector.y(), mpVector.x());
71 
72  for (unsigned int i=0; i<walls->size(); i++) {
73  normalI = osg::Vec2(-walls->at(i)->getVector(WG_Q_POINT).y(),walls->at(i)->getVector(WG_Q_POINT).x());
74  if (WG_Geometry::getCrossingPoint(dummy,crossPoint, mpNormal, walls->at(i)->getPoint(WG_Q_POINT)->getPosition(), normalI, true)) {
75  isWall = true;
76  break;
77  }
78  }
79 
80  if (isWall) {
81  logger.warningLog("Cannot add wall. Not enough space for a new one. (A wall obstructs.)");
82  return;
83  }
84 
85  startingPoint = new WG_Point(crossPoint);
86  startingPoint->setId(points->size());
87  points->push_back(startingPoint);
88  curWall->setPoint(startingPoint, WG_R_POINT);
89  newWall = new WG_Wall(startingPoint, R);
90  newWall->setId(walls->size());
91  walls->push_back(newWall);
92  splitted = true;
93  }
94 
95  if (startingPoint->getWalls()->size() > 1) {
96  std::pair<osg::ref_ptr<WG_Wall>, PointType> wallCW;
97  std::pair<osg::ref_ptr<WG_Wall>, PointType> wallCCW;
98  startingPoint->getWallNeighbours(curWall, wallCW, wallCCW);
99 
100  float angle = 0;
101  float angle2 = 0;
102  osg::Vec2 vector(0.0,0.0);
103  if (!splitted) {
104  osg::Vec2 vec1, vec2;
105  if (((type == WG_Q_POINT) && (Q == startingPoint))
106  || ((type == WG_R_POINT) && (R == startingPoint))) {
107  vec1 = wallCCW.first->getVector(wallCCW.second);
108  vec1.normalize();
109  vec2 = curWall->getVector(type);
110  vec2.normalize();
111  mpVector = vec1 + vec2;
112  angle2 = curWall->getAngle(type);
113  angle = wallCCW.first->getAngle(wallCCW.second);
114  vector = curWall->getVector(type);
115  }
116  else {
117  vec1 = wallCW.first->getVector(wallCW.second);
118  vec1.normalize();
119  vec2 = curWall->getVector((type == WG_Q_POINT ? WG_R_POINT : WG_Q_POINT));
120  vec2.normalize();
121  mpVector = vec1 + vec2;
122  angle2 = wallCW.first->getAngle(wallCW.second);
123  angle = curWall->getAngle((type == WG_Q_POINT ? WG_R_POINT : WG_Q_POINT));
124  vector = wallCW.first->getVector(wallCW.second);
125  }
126  }
127 
128  float angleCompare = angle - angle2;
129  if (angleCompare < 0)
130  angleCompare += 360;
131  if (angleCompare > 180.0f)
132  mpVector *= (-1);
133 
134  mpVector.normalize();
135  mpVector *= (RE_MIN_LENGTH*1.5);
136 
137  float mpAngle = WG_Geometry::getAngle(mpVector);
138  angleCompare = angle - mpAngle;
139  if (angleCompare < 0)
140  angleCompare += 360;
141  if ((!splitted) && (angleCompare < RE_MIN_ANGLE(mpVector.length(), vector.length()))) {
142  logger.warningLog("Cannot add wall. Not enough space for a new one. (Too small angle.)");
143  }
144  else {
145  movingPoint = new WG_Point(startingPoint->getPosition() + mpVector);
146  movingPoint->setId(points->size());
147  points->push_back(movingPoint);
148  newWall = new WG_Wall(startingPoint, movingPoint);
149  newWall->setId(walls->size());
150  walls->push_back(newWall);
151  }
152  }
153  else {
154  mpVector = osg::Vec2(intersection->getLocalIntersectNormal().x(), intersection->getLocalIntersectNormal().z());
155  mpVector.normalize();
156  mpVector *= (RE_MIN_LENGTH*1.5);
157  movingPoint = new WG_Point(startingPoint->getPosition() + mpVector);
158  movingPoint->setId(points->size());
159  points->push_back(movingPoint);
160  newWall = new WG_Wall(startingPoint, movingPoint);
161  newWall->setId(walls->size());
162  walls->push_back(newWall);
163  }
164  }
165 
166  setDirty(true);
167  }
168 
169  private:
170  WG_Point* startingPoint;
171  WG_Point* movingPoint;
172  bool insideWalls;
173  };
174 
175 }
176 
177 #endif
178