vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PointMove.h
Go to the documentation of this file.
1 #ifndef _POINT_MOVE_H
2 #define _POINT_MOVE_H
3 
4 #include "Tool.h"
5 
6 namespace APRoomEdit {
7 
8  // tool that moves with individualpoints of walls
9  // group means that with the point will be moving all connected walls
10  // simple means that just the selected one
11  class PointMove : public Tool {
12  public:
13  PointMove() {type=POINTMOVE;simple=true;}
14  virtual ~PointMove() {}
15 
16  virtual bool loadXMLParameters(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *pParametersNode) {
17  std::string mode = "";
18  if (findXMLNode(pParametersNode, "Mode")) {
19  ReaderWriter::getStringValue(mode, pParametersNode, "Mode");
20  name = mode;
21  }
22  simple = (mode == "simple");
23  return true;
24  }
25 
26  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) {
27  if (simple && (curWall != NULL) && (curPoint->getWalls()->size()>1)) {
28  PointType Type;
29  if (curWall->getPoint(WG_Q_POINT) == curPoint) {
30  Type = WG_Q_POINT;
31  }
32  else {
33  Type = WG_R_POINT;
34  }
35  osg::Vec2 tempVector = curWall->getVector(Type);
36  if (tempVector.length() <= (RE_MIN_LENGTH + 2.5*RE_DEFAULT_2_WIDTH)) {
37  movingPoint = curPoint;
38  }
39  else {
40  tempVector.normalize();
41  tempVector *= (2.5*RE_DEFAULT_2_WIDTH);
42  movingPoint = new WG_Point(curPoint->getPosition() + tempVector);
43  curWall->setPoint(movingPoint, Type);
44  movingPoint->setId(points->size());
45  points->push_back(movingPoint);
46  }
47  }
48  else
49  movingPoint = curPoint;
50 
51  setDirty(true);
52  }
53 
54  virtual void update(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, osg::Vec3& movingVector) {
55  osg::Vec2 tempPosition = movingPoint->getPosition() + osg::Vec2(movingVector.x(), movingVector.z());
56 
57  WG_Wall* wall;
58  osg::Vec2 vector, position;
59  osg::Vec2 curVec, minVec = osg::Vec2(10000.0, 10000.0);
60 
61  bool oneWall = (movingPoint->getWalls()->size()==1);
62 
63  if (oneWall) {
64  wall = movingPoint->getWalls()->at(0).first.get();
65  if (wall->getPoint(WG_Q_POINT) == movingPoint) {
66  position = wall->getPoint(WG_R_POINT)->getPosition();
67  vector = wall->getVector(WG_R_POINT);
68  }
69  else {
70  position = wall->getPoint(WG_Q_POINT)->getPosition();
71  vector = wall->getVector(WG_Q_POINT);
72  }
73  vector.set(-vector.y(), vector.x());
74  }
75 
76  WG_Wall* resWall;
77  for (unsigned int i=0; i<walls->size(); i++) {
78  WG_Wall* wallI = walls->at(i).get();
79  resWall = NULL;
80  osg::Vec2 crossPoint;
81  if (oneWall) {
82  // tests length of the selected wall
83  osg::Vec2 tvector = wallI->getVector(WG_Q_POINT);
84  tvector.set(-tvector.y(), tvector.x());
85  osg::Vec2 tposition = wallI->getPoint(WG_Q_POINT)->getPosition();
86 
87  if (WG_Geometry::getCrossingPoint(crossPoint, position, vector, tposition, tvector, true)) {
88  curVec = position - crossPoint;
89  if (curVec.length() < minVec.length()) {
90  minVec = curVec;
91  resWall = wallI;
92  }
93  }
94 
95  if (resWall != NULL) {
96  tempPosition = (minVec - position)*(-1);
97  }
98  }
99  else {
100  // test if there is another wall in the way of point
101  bool skip = false;
102  for (unsigned int j=0; j<movingPoint->getWalls()->size(); j++) {
103  skip = (wallI == movingPoint->getWalls()->at(j).first.get());
104  if (skip)
105  break;
106  }
107  if (!skip) {
108  WG_Vertices* qV = wallI->getVertices(WG_Q_POINT);
109  WG_Vertices* rV = wallI->getVertices(WG_R_POINT);
110  bool b1 = WG_Geometry::barycentricTest(tempPosition,
111  osg::Vec2(qV->getBottomCCWVertex().x(), qV->getBottomCCWVertex().z()),
112  osg::Vec2(qV->getBottomCWVertex().x(), qV->getBottomCWVertex().z()),
113  osg::Vec2(rV->getBottomCCWVertex().x(), rV->getBottomCCWVertex().z()));
114  bool b2 = WG_Geometry::barycentricTest(tempPosition,
115  osg::Vec2(qV->getBottomCCWVertex().x(), qV->getBottomCCWVertex().z()),
116  osg::Vec2(qV->getBottomCWVertex().x(), qV->getBottomCWVertex().z()),
117  osg::Vec2(rV->getBottomCWVertex().x(), rV->getBottomCWVertex().z()));
118  if (b1 || b2)
119  return;
120  }
121  }
122  }
123 
124  // tests length and angles of all walls and their neighbours on both sides of the walls
125  for (unsigned int k=0; k<movingPoint->getWalls()->size(); k++) {
126  WG_Wall* wallK = movingPoint->getWalls()->at(k).first.get();
127  PointType ptype = movingPoint->getWalls()->at(k).second;
128  PointType opptype = (ptype == WG_Q_POINT ? WG_R_POINT : WG_Q_POINT);
129 
130  osg::Vec2 length = wallK->getPoint(opptype)->getPosition() - tempPosition;
131  if (length.length() < RE_MIN_LENGTH)
132  return;
133 
134  float angleCW, angleCCW, angle, angleCompare, angleMin;
135  osg::Vec2 v;
136  std::pair<osg::ref_ptr<WG_Wall>, PointType> wallCW;
137  std::pair<osg::ref_ptr<WG_Wall>, PointType> wallCCW;
138  if (wallK->getPoint(ptype)->getWallNeighbours(wallK, wallCW, wallCCW)) {
139  angleCW = wallCW.first->getAngle(wallCW.second);
140  angleCCW = wallCCW.first->getAngle(wallCCW.second);
141  v = wallK->getPoint(opptype)->getPosition() - tempPosition;
142  angle = WG_Geometry::getAngle(v);
143  angleCompare = angleCCW - angle;
144  angleMin = 5+RE_MIN_ANGLE(wallK->getVector(WG_Q_POINT).length(),
145  wallCCW.first->getVector(WG_Q_POINT).length());
146  if ((angleCompare < angleMin) && (angleCompare > - angleMin))
147  return;
148  angleCompare = angle - angleCW;
149  angleMin = 5+RE_MIN_ANGLE(wallK->getVector(WG_Q_POINT).length(),
150  wallCW.first->getVector(WG_Q_POINT).length());
151  if ((angleCompare < angleMin) && (angleCompare > - angleMin))
152  return;
153  }
154 
155  if (wallK->getPoint(opptype)->getWallNeighbours(wallK, wallCW, wallCCW)) {
156  angleCW = wallCW.first->getAngle(wallCW.second);
157  angleCCW = wallCCW.first->getAngle(wallCCW.second);
158  v = tempPosition - wallK->getPoint(opptype)->getPosition();
159  angle = WG_Geometry::getAngle(v);
160  angleCompare = angleCCW - angle;
161  angleMin = 5+RE_MIN_ANGLE(wallK->getVector(WG_Q_POINT).length(),
162  wallCCW.first->getVector(WG_Q_POINT).length());
163  if ((angleCompare < angleMin) && (angleCompare > - angleMin))
164  return;
165  angleCompare = angle - angleCW;
166  angleMin = 5+RE_MIN_ANGLE(wallK->getVector(WG_Q_POINT).length(),
167  wallCW.first->getVector(WG_Q_POINT).length());
168  if ((angleCompare < angleMin) && (angleCompare > - angleMin))
169  return;
170  }
171  }
172 
173 
174  // after setting new position, it is needed to recompute vertices
175  movingPoint->setPosition(tempPosition);
176  for (unsigned int l=0; l<movingPoint->getWalls()->size(); l++) {
177  PointType typeL = (movingPoint->getWalls()->at(l).second == WG_Q_POINT ? WG_R_POINT : WG_Q_POINT);
178  WG_Wall* wallL = movingPoint->getWalls()->at(l).first.get();
180  wallL->computeAttrVertices();
181  for (unsigned int m=0; m<wallL->getPoint(typeL)->getWalls()->size(); m++)
182  wallL->getPoint(typeL)->getWalls()->at(m).first->computeAttrVertices();
183  }
184  setDirty(true);
185  }
186 
187  virtual void terminate(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) {
188 
189  // aplies snapping
190  if (movingPoint->getWalls()->size()==1) {
191  WG_Wall* crossedWall = NULL;
192  WG_Wall* mpWall = movingPoint->getWalls()->at(0).first.get();
193  osg::Vec2 vertexCW;
194  osg::Vec2 vertexCCW;
195  mpWall->computeAttrVertices();
196  if (WG_Q_POINT == movingPoint->getWalls()->at(0).second) {
197  vertexCW = mpWall->getVertices(WG_Q_POINT)->getNormalCWVertex();
198  vertexCCW = mpWall->getVertices(WG_Q_POINT)->getNormalCCWVertex();
199  }
200  else {
201  vertexCW = mpWall->getVertices(WG_R_POINT)->getNormalCWVertex();
202  vertexCCW = mpWall->getVertices(WG_R_POINT)->getNormalCCWVertex();
203  }
204 
205  for (unsigned int i=0; i<walls->size(); i++) {
206  WG_Wall* wallI = walls->at(i).get();
207  WG_Vertices* qV = wallI->getVertices(WG_Q_POINT);
208  WG_Vertices* rV = wallI->getVertices(WG_R_POINT);
209  bool b1 = WG_Geometry::barycentricTest(movingPoint->getPosition(),
210  osg::Vec2(qV->getBottomCCWVertex().x(), qV->getBottomCCWVertex().z()),
211  osg::Vec2(qV->getBottomCWVertex().x(), qV->getBottomCWVertex().z()),
212  osg::Vec2(rV->getBottomCCWVertex().x(), rV->getBottomCCWVertex().z()));
213  bool b2 = WG_Geometry::barycentricTest(movingPoint->getPosition(),
214  osg::Vec2(qV->getBottomCCWVertex().x(), qV->getBottomCCWVertex().z()),
215  osg::Vec2(qV->getBottomCWVertex().x(), qV->getBottomCWVertex().z()),
216  osg::Vec2(rV->getBottomCWVertex().x(), rV->getBottomCWVertex().z()));
217  if (b1 || b2) {
218  if (wallI != mpWall) {
219  crossedWall = wallI;
220  i=walls->size();
221  }
222  }
223  }
224 
225  if (crossedWall != NULL) {
226  WG_Point* resQ = crossedWall->getPoint(WG_Q_POINT);
227  osg::Vec2 resQvector = crossedWall->getVector(WG_Q_POINT);
228  WG_Point* resR = crossedWall->getPoint(WG_R_POINT);
229  WG_Wall* newWall = NULL;
230 
231  osg::Vec2 crossPoint;
232 
233  osg::Vec2 mpNormal = osg::Vec2(-mpWall->getVector(WG_Q_POINT).y(), mpWall->getVector(WG_Q_POINT).x());
234  osg::Vec2 qNormal = osg::Vec2(-resQvector.y(), resQvector.x());
235 
236  if (WG_Geometry::getCrossingPoint(crossPoint, movingPoint->getPosition(), mpNormal, resQ->getPosition(), qNormal, false)) {
237  osg::Vec2 resQvec = resQ->getPosition() - crossPoint;
238  osg::Vec2 resRvec = resR->getPosition() - crossPoint;
239  if (resQvec.length() < resRvec.length()) {
240  if (resQvec.length() < RE_MIN_LENGTH) {
241  mpWall->setPoint(resQ, movingPoint->getWalls()->at(0).second);
242  }
243  else {
244  movingPoint->setPosition(crossPoint);
245  newWall = new WG_Wall(resR, movingPoint);
246  newWall->setId(walls->size());
247  walls->push_back(newWall);
248  crossedWall->setPoint(movingPoint, WG_R_POINT);
249  }
250  }
251  else {
252  if (resRvec.length() < RE_MIN_LENGTH) {
253  mpWall->setPoint(resR, movingPoint->getWalls()->at(0).second);
254  }
255  else {
256  movingPoint->setPosition(crossPoint);
257  newWall = new WG_Wall(resR, movingPoint);
258  newWall->setId(walls->size());
259  walls->push_back(newWall);
260  crossedWall->setPoint(movingPoint, WG_R_POINT);
261  }
262  }
263  crossedWall->computeAttrVectorsAndAngles();
264  mpWall->computeAttrVectorsAndAngles();
265  crossedWall->computeAttrVertices();
266  mpWall->computeAttrVertices();
267  if (newWall) {
268  newWall->computeAttrVertices();
269  newWall->computeAttrVertices();
270  }
271  }
272  else
273  logger.warningLog("Cannot merge the walls.");
274  }
275  }
276 
277  setDirty(true);
278  }
279 
280  private:
281  bool simple;
282  WG_Point* movingPoint;
283  };
284 
285 }
286 
287 #endif
288