vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Cable.h
Go to the documentation of this file.
1 
2 #ifndef CABLE_H
3 #define CABLE_H
4 
5 //VRECKO
6 
7 //#include <vrecko/World.h> //includovan ve Scene.h
8 #include <vrecko/Ability.h> //incudovane v World.h
9 #include <vrecko/PluginManager.h>
10 
12 
14 #include <vrecko/Scene.h> //chyba pri includu musi byt includovan na konci !!! jinak nelze najit EnvironmentObject
15 
16 //OSG
17 #include <osg/Geode>
18 #include <osg/Geometry>
19 #include <osg/Drawable>
20 #include <osg/ShapeDrawable>
21 
22 
23 using namespace vrecko;
24 
25 namespace AP_CableEditor {
26 
27  #define SPHERE_RADIUS 2.0;
28 
29  #define INTERPOLATION_CATMULL_ROM_ITERATE 1 //iterativni vyhlazovani - vzdy se puli interval (algoritmus se provede n-krat)
30  #define INTERPOLATION_CATMULL_ROM_PER_SEGMENT 2 //nastaveni pevneho poctu bodu na segment (mezi 2 kontrolnimi body bude n interpolovanych)
31 
32 
33  class Cable : public Ability {
34 
35  protected:
36 
37  //urcuje jestli doslo ke zmene kabelu a je potreba prekreslit obalku
39 
40  //promena urcijici, jestli se kabel nachazi v editacnim modu
42 
43  //polomer kabelu
44  float cableRadius;
46 
47  //urcuje natoceni zakladni roviny pro RMF - umoznuje otacet tvarem kabelu kolem jeho osy
48  //v radianech
50 
51  //barva kabelu
52  osg::Vec4f cableColor;
53  osg::Vec4f controlSpheresColor;
54 
55  //vektor kontrolnich bodu
56  //slouzi jako vstup pro interpolacni funkci
57  osg::ref_ptr<osg::Vec3Array> controlPoints;
58 
59  //Tangenty, Normaly a Binormaly interpolovanych bodu
60  osg::ref_ptr<osg::Vec3Array> thisTangents;
61  osg::ref_ptr<osg::Vec3Array> thisNormals;
62  osg::ref_ptr<osg::Vec3Array> thisBinormals;
63 
64  //vektor bodu pro vykresleni interpolovane krivky
65  //slouzi jako vstup pro obalovaci funkci
66  osg::ref_ptr<osg::Vec3Array> interpolatedPoints;
67 
68  //pole urcuje tvar kabelu
69  osg::ref_ptr<osg::Vec3Array> shapePoints;
70 
71  //vektors kontrolnich kouli
72  std::vector<vrecko::EnvironmentObject *> *controlSpheres;
73 
74  //ukazatel na editacni linku
76 
77 
78  //Obalujici EnvironmentObject teto ability
79  //sem se bude vkladat veskera geometrie (krom Kontrolnich kouli)
81 
82  //ulozeni posledni transformace obalky kabelu - pro testovani zmeny polohy, otoceni....
83  osg::ref_ptr<osg::MatrixTransform> lastWrapperTransformation;
84 
85  osg::ref_ptr<osg::Geode> wrapperGeode;
86 
87  unsigned int interpolationsNum;
88  unsigned int interpolationType;
89 
90  string cableID;
91 
92  //--------- DEBUG --------
93 
94  //ukazatel na EO kontrolnich vektoru (tangenta, normala, binormala) ke kazdemu interpolovanemu bodu
95  //pro funkci visualizeVectors
97 
98  //------------------------
99 
100 
101  //_____________________________________________________ Funkce _________________________________________________________________________________
102 
103  //Upravi polohu kontrolnich kouli podle zadane matice
104  void updateSpheresPosition();
105 
106  //Provede reakci na smazani kontrolni koule a na ukonceni VRECKa
107  virtual int processNotification(BaseClass *sender, unsigned long notificationType,
108  void *notificationData);
109 
110  //Visualizace kontrolnich bodu - Vytvori na bodech z vektoru kontrolnich bodu koule
111  //podle polohy se nastavuje poloha kontrolnich bodu viz updateControlPoints()
112  void createSpheres();
113 
114  //Vymaze vsechny kontrolni koule objektu ze sceny
115  void clearSpheres();
116 
117  //aktualizuje kontrolni body na zaklade polohy kontrolnich kouli
118  //Pozor!!! - pokud byl pridan kontrolni bod a nebyla pro nej vytvorena koule, pak tento bod v aktualizovanych kontrolnich bodech nebude
119  // - stejne tak pokud byla smazana koule nektereho bodu, pak tento bod v poli nebude
120  void updateControlPoints();
121 
122 
123  public:
124  Cable();
125  virtual ~Cable();
126 
127  virtual void preInitialize();
128  virtual void postInitialize();
129 
130  void setCableID( string ID) { this->cableID = ID; }
131  string getCableID() {return this->cableID; }
132 
133  void setShape( osg::ref_ptr<osg::Vec3Array> points ){ shapePoints = points; }
134  osg::ref_ptr<osg::Vec3Array> getShape(){ return shapePoints; }
135 
136  void setInterpolation(unsigned int type, unsigned int num) { this->interpolationType = type; this->interpolationsNum = num; }
137  void getInterpolation(unsigned int *type, unsigned int *num) { *type = this->interpolationType; *num = this->interpolationsNum; }
138 
139  void setRadius(float radius){ this->cableRadius = radius; }
140  float getRadius() { return this->cableRadius; }
141 
142  //upraveni polomeru kontrolnich kouli (cableRadius + controlSpheresRadiusAdjust)
143  void setControlSpheresRadiusAdjust(float radius) { this->controlSpheresRadiusAdjust = radius; }
144  float getControlSpheresRadiusAdjust() { return this->controlSpheresRadiusAdjust; }
145 
146  //upravi polomer kouli podle polomeru kabelu
147  void updateControlSpheresRadius();
148 
149  void setCableColor( osg::Vec4f color ) { this->cableColor = color; }
150  osg::Vec4f getCableColor() { return this->cableColor; }
151 
152  void setControlSpheresColor( osg::Vec4f color ) { this->controlSpheresColor = color; }
153  osg::Vec4f ControlSpheresColor() { return this->controlSpheresColor; }
154 
155  //nastavuje/ziskava uhel pootoceni obalky v radianech (otoceni normaly a binormaly zakladni roviny pro RMF)
156  void setShapeRotate( float angle ) { this->basePlaneRotation = angle; }
157  float getShapeRotate() { return this->basePlaneRotation; }
158 
159  //Nastaveni obalky kterou bude tato abilita spravovat - Musi byt nastaveno pri vytvareni ability !"
160  void setEoWrapper (EnvironmentObject *wrapper){ if(wrapper != NULL) thisEoWrapper = wrapper; }
161  EnvironmentObject *getEoWrapper() { return this->thisEoWrapper; }
162 
163 
164  //Vrati obalku kabelu jako Geode objekt
165  osg::Node *getCableWrapperNode() { return thisEoWrapper->getChild(0); }
166 
167  void setControlPoints(osg::ref_ptr<osg::Vec3Array> points) { controlPoints = points; }
168  osg::ref_ptr<osg::Vec3Array> getControlPoints() { return controlPoints; }
169  osg::ref_ptr<osg::Vec3Array> getIntepolatedPoints() { return interpolatedPoints; }
170 
171  void addControlPoint(osg::Vec3f position) { controlPoints->push_back(position); }
172 
173  //vlozi bod na konkretni pozici v poli - pred prvek urceny v "position"
174  void addControlPoint(unsigned int position, osg::Vec3f point);
175 
176  //vlozi bod mezi 2 nejblizsi body - predpoklada ze bod lezi (alespon priblizne) na primce dane 2 kontrolnimi body
177  void addControlPointBetweenLine(osg::Vec3f position);
178 
179  //Interpolacni funkce vezme 4 body (p0,p1,p2,p3) a parametr "t" [0.0f, 1.0f] urcujici polohu bodu mezi body p1 a p2
180  osg::Vec3f getInterpolatedPoint(osg::Vec3 p0, osg::Vec3 p1, osg::Vec3 p2, osg::Vec3 p3, double t = 0.5) const;
181 
182 
183  //vytvori kouli na zadanych souradnicich a vlozi ji do sceny vraci ukazatel na vytvoreny Environment object
184  EnvironmentObject *createSphere(osg::Vec3f center, float radius = 0.25){
185  return createSphere(center, this->cableColor, radius);
186  }
187 
188  EnvironmentObject *createSphere(osg::Vec3f center, osg::Vec4f color, float radius = 0.25);
189 
190  //interpoluje kontrolni body a nastavi je abilite
191  void interpolate();
192 
193  //interpoluje kontrolni body Catmull-Rom algoritmem
194  //kazdy segment mezi 2 body rozdeli na pointsPerSegment interpolovanych bodu
195  // neprovadi kontrolu uhlu mezi kontrolnimi body (zhustovani bodu u ostrych uhlu)
196  // pointsPerSegment - pocet interpolovanych bodu mezi 2 kontrolnimi body
197  // inputPoints - pole bodu pro interpolaci. Musi byt >= 4
198  osg::ref_ptr<osg::Vec3Array> interpolateCatPerSegment(osg::ref_ptr<osg::Vec3Array> inputPoints, unsigned int pointsPerSegment) const;
199 
200  //interpoluje zadane body pulenim intervalu
201  //vraci pole interpolovanych bodu
202  // inputPoints - pole kontrolnich bodu pro interpolaci. Musi byt >= 4
203  // numIterations - pocet iteraci
204  osg::ref_ptr<osg::Vec3Array> interpolateCatIterate(osg::ref_ptr<osg::Vec3Array> inputPoints, unsigned int numIterations) const;
205 
206  //obali interpolovane body a udela z ni kabel
207  //parametr shapePoints - body urcujici tvar kabelu
208  void wrapCable();
209 
210  //vypina nebo zapina aktualizaci kabelu
211  void setUpdate(bool state);
212 
213  //vraci stav ve kterem se momentalne nachazi kabel (editacni rezim)
214  bool getUpdate() { return isUpdateState; }
215 
216  //provadi update polohy kontrolnich bodu a obalky
217  virtual void update();
218 
219  //Ke kazdemu bodu v poli ( !!krome prvniho a posledniho!! ) "points" vypocita jeho tangentu, normalu a binormalu a vrati v polich
220  //v pripade uspechu vraci 0
221  //jinak vraci cislo != 0 a obsah poli tangents, normals, binormals je nedefinovany
222  int computeRMF(osg::Vec3Array *points, osg::Vec3Array *tangents, osg::Vec3Array *normals, osg::Vec3Array *binormals);
223 
224  //vypocita polohu bodu tvaru v danem bode
225  //jako prvni parametr bere pole vektoru/bodu urcujici tvar protazeni
226  //dale pak bod ve kterem se na natoceni pocitat, jeho tangentu, normalu a binormalu
227  //vraci pole prepocetnych vektoru/bodu (otocenych do roviny dane normalou a binormalou)
228  osg::Vec3Array *transformVectors(osg::Vec3Array *vectors, osg::Vec3f point, osg::Vec3f tangent, osg::Vec3f normal, osg::Vec3f binormal, float scale = 1);
229 
230 
231  //Obali kabel a vrati jeho obalku jako jeden geode
232  //shapeVectors -> pole vektoru/body udavajiciho tvar kabelu musi byt definovana v rovine YZ
233  //points -> pole bodu pro obaleni: wrapFrom urcuje index prvniho bodu, wrapNum urcuje kolik bodu se bude obalovat - vzdy ale bez posledniho bodu v poli
234  //tangents, normals, binormals -> pole tangent/normal/binormal prislusejicich k bodum v poli "points" musi platit points->size() == tangents/normals/binormals->size() !!
235  //wrapFrom -> urcuje index od ktereho bodu se bude obalovat
236  //wrapNum -> urcuje kolik bodu se bude obalovat 0 znamena vsechny body v poli, pokud wrapNum < points->size() pouzije se points->size()
237  // Pozn: Vzdy se obaluje o 1 bod mene nez je urceno/obsazeno poli - pokud se maji obali vsechny body je treba posledni bod zduplikovat vcetne jeho tangenty/normaly/binormaly
238  osg::ref_ptr<osg::Geode> wrap(osg::Vec3Array *shapeVectors, osg::Vec3Array *points, osg::Vec3Array *tangents, osg::Vec3Array *normals, osg::Vec3Array *binormals,
239  float scale = 1, unsigned int wrapFrom = 1, unsigned int wrapNum = 0);
240 
241  //debugovaci fce:
242 
243  void visualizeVectors(osg::Vec3Array *points, osg::Vec3Array *tangents, osg::Vec3Array *normals, osg::Vec3Array *binormals);
244 
245  };
246 }
247 
248 #endif