vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ObjectMovement.h
Go to the documentation of this file.
1 #ifndef OBJECT_MOVEMENT_H
2 #define OBJECT_MOVEMENT_H
3 
5 
6 #include <vrecko/Ability.h>
8 #include <helpers/DynamicArray.h>
9 #include <osg/Group>
10 #include <osg/ShapeDrawable>
11 #include <osg/Geode>
12 
13 using namespace vrecko;
14 
15 namespace APEditorQAbilities {
16 
18  public:
20  virtual ~ObjectMovement() {};
21 
22  virtual bool initialize(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *parameters = NULL);
23 
24  virtual void update(void);
25 
26  protected:
27  virtual CAINFO* createInfo();
28  virtual void fillDefaultInfo();
29 
32 
33  virtual bool activate();
34  virtual void deactivate();
35 
36  osg::Vec3 firstPointerPos; // pointer position when activated
37  osg::Quat firstPointerRot; // pointer rotation when activated
38 
39  osg::Vec3 firstObjectPos; // object position when activated
40  osg::Quat firstObjectRot; // object rotation when activated
41 
42  unsigned long movingObjectID; // If this is 0, the ability is not activated
43 
45 
46  class SnapBox {
47  public:
48  SnapBox() : color(0.0f, 1.0f, 0.0f, 0.4f) { owner = NULL; };
49  ~SnapBox() { Done(); };
50 
51  void setOwner(ObjectMovement *_owner) { owner = _owner; }
52 
53  void updateShape(const osg::Vec3 &center, const osg::Vec3 &halfLengths, const osg::Matrix &transform);
54  // set new dimensions and position.
55 
56  bool show();
57  bool hide();
58 
59  protected:
60  bool Init();
61  void Done();
62  osg::ref_ptr<EnvironmentObject> graphicObject;
63  osg::ref_ptr<osg::Geode> osgGeode;
64  osg::ref_ptr<osg::MatrixTransform> osgTransform;
65  osg::ref_ptr<osg::Box> shapeBox;
66  osg::ref_ptr<osg::ShapeDrawable> shapeDraw;
67 
68  osg::Vec4 color;
69 
71  };
73  // A few boxes that are used to display active snapping planes.
74 
75 
76  bool objectTransformationFromPointer(EnvironmentObject *eo, osg::Matrix *outTrans);
77  // FIRST PART of the tranformation calculations. From the pointer position/rotation the new object
78  // position/rotation is calculated. The matrix is only calculated and stored in [outTrans].
79  // The transformation will be applied afterwards, after another calculations or adjustments.
80  bool applySnapping(EnvironmentObject *eo, osg::Matrix *inoutTrans);
81  // Another PART of the transformation calculation. [inoutTrans] is already calculated.
82  // This method may adjust the transformtion matrix to snap the object to ... well, anything
83  // in considers good for a snap.
84  // The snapping options will be probably adjustable by the user in runtime.
85  // Returns "true" if any snapping occured.
86 
88  Other = 0,
89  // non-specified type
91  // Horizontal plane with some nice properties.
92  // Usually something like:
93  // - on the upper side of the object used for snapping
94  // - located under the object to be snapped
95  };
96 
97 
98  struct CANDIDATEPLANE {
99  bool bIgnore;
100  // Don't consider this plane in further calculations.
101  // (Plane deletion would cause unnecessary memory movements.)
102 
103  unsigned long objectID; // ID of the object this plane belongs to
104  unsigned long objectSide; // 0..5 - which side was used to generate this plane
105 
106  osg::Vec3 center; // center of the plane
107  osg::Vec3 normal; // (normalized) normal pointing towards the original object center
108 
109  osg::Vec3 halfRect1, halfRect2;
110  // Vectors that define box around the center point.
111  // The box equals to the bounding box of the object that "created" this plane
112 
113  osg::Vec3 shiftVec;
114  float shiftLen2; // length squared (cached)
115 
116  osg::Vec3 snapPoint; // snapping point
117  float hR1SnapMul, hR2SnapMul; // snapPoint = center + halfRect1 * hR1SnapMul + halfRect2 * hR2SnapMul
118 
119  float fMinU, fMaxU, fMinV, fMaxV;
120 
121  float fObjProjectionArea; // Size of the projected BBox of the object-to-be-snapped
122 
124  };
125 
126  //friend int planesCompare (const void * elem1, const void * elem2);
127  friend int planesCompare (const ObjectMovement::CANDIDATEPLANE * elem1, const ObjectMovement::CANDIDATEPLANE * elem2 );
128 
129  osg::BoundingBox objAABox; // BB of the object-to-be-snapped
130  osg::Matrix objAABoxTrans; // and its transformation
131 
132  osg::ref_ptr<EnvironmentObject> shadowObject;
133  // temporary object that is used to visualize an imaginary position (i.e. not-snapped)
135  // An effect that is used on shadowObject
136 
137 
139  DynamicArray<DWORD> selectedPlanes; // the actually selected snapping planes
140 
141 
142  bool addSnappingPlane(
143  unsigned long objectID, unsigned long objectSide,
144  osg::Vec3 &center, osg::Vec3 &normal,
145  osg::Vec3 &halfVec1, osg::Vec3 &halfVec2, osg::Vec3 shiftVec, float shiftLen2, osg::Vec3 &snapPoint,
146  float halfRect1SnapMul, float halfRect2SnapMul,
147  float fMinU, float fMaxU, float fMinV, float fMaxV,
149  bool isPlaneCompatibleWithSelectedSet(int iPlaneIndex);
150  // Is the "plane[iPlaneIndex]" plane compatible with the previously selected ones?
151  // I.e. the object can be snapped to all of them <=> they are not coplanar etc.
152  // Note that plane with the [iPlaneIndex] is not compatible if it was already selected.
153  bool calcFinalShiftFromSelectedSet(osg::Vec3 &outShift, int additionalPlane = -1);
154  // From the set of selected planes calculates the final shift of the object.
155  // Returns false if the intersection of the planes is too far.
156  // You can specify additional plane in [addionalPlane] (index to [planes]; -1 for no plane)
157  bool intersect2Planes(osg::Vec3 &p1p, osg::Vec3 &p1normal, osg::Vec3 &p2p, osg::Vec3 &p2normal,
158  osg::Vec3 &outLineStart, osg::Vec3 &outLineDir);
159  // the 3D intersect of two planes
160  // Input: two planes [p1p + p1normal] and [p2p + p2normal]
161  // Output: the intersection line (when it exists)
162  // Return: true = everything ok
163  // false = the planes are parallel (either no intersection or the whole plane)
164  bool intersectLinePlane(osg::Vec3 &lineStart, osg::Vec3 &lineDir, osg::Vec3 &planePoint,
165  osg::Vec3 &planeNormal, osg::Vec3 &outPoint);
166  // Intersection of a line and a plane.
167  // If "true" is returned [outPoint] will hold the intersection point.
168  bool projectPointOnPlaneUV(osg::Vec3 &point, osg::Vec3 &planePoint, osg::Vec3 &planeNormal,
169  osg::Vec3 &halfVec1, osg::Vec3 &halfVec2, osg::Vec3 *outProjectedPoint,
170  float *outDist, float *outU, float *outV);
171  // The plane is defined by [planePoint + planeNormal], the [halfVec1] and [halfVec2]
172  // are perpendicular vectors in this plane.
173  // Output is:
174  // [outProjectedPoint], [outDist], [outU], [outV]
175  // Where this should hold true:
176  // outProjectedPoint = planePoint + halfVec1 * outU + halfVec2 * outV
177  //
178  // Any of the output pointers can be NULL in case the caller doesn't need that value.
179  // Optimization hint: If you don't need [outU] and [outV] then set them to NULL
180  // to omit those calculations entirely and increase speed significantly.
181 };
182 
183 
184 }
185 
186 
187 #endif