V-ART
transform.cpp
Go to the documentation of this file.
1 
5 // Internal matrix element organization reference
6 // [ matrix[0] matrix[4] matrix[8] matrix[12] ]
7 // Transform = [ matrix[1] matrix[5] matrix[9] matrix[13] ]
8 // [ matrix[2] matrix[6] matrix[10] matrix[14] ]
9 // [ matrix[3] matrix[7] matrix[11] matrix[15] ]
10 
11 #include "vart/transform.h"
12 #include "vart/boundingbox.h"
13 #include "vart/graphicobj.h"
14 
15 #ifdef WIN32
16 #include <windows.h>
17 #endif
18 #ifdef VART_OGL
19 #include <GL/gl.h>
20 #endif
21 
22 using namespace std;
23 
25 {
26 }
27 
29 {
30  return new VART::Transform(*this);
31 }
32 
33 void VART::Transform::SetData(double* data)
34 {
35  int i;
36 
37  for (i=0; i<16; i++)
38  {
39  matrix[i] = (*data);
40  data++;
41  }
42 }
43 
45 {
46  this->Transform::operator=(trans);
47 }
48 
50 {
51  for (int i=0; i<16; ++i)
52  matrix[i] = 0.0;
53  matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.0;
54 }
55 
56 void VART::Transform::MakeTranslation(const VART::Point4D& translationVector)
57 {
58  MakeIdentity();
59  matrix[12] = translationVector.GetX();
60  matrix[13] = translationVector.GetY();
61  matrix[14] = translationVector.GetZ();
62 }
63 
64 void VART::Transform::MakeXRotation(double radians)
65 {
66  MakeIdentity();
67  matrix[5] = cos(radians);
68  matrix[9] = -sin(radians);
69  matrix[6] = sin(radians);
70  matrix[10] = cos(radians);
71 }
72 
73 void VART::Transform::MakeYRotation(double radians)
74 {
75  MakeIdentity();
76  matrix[0] = cos(radians);
77  matrix[8] = sin(radians);
78  matrix[2] = -sin(radians);
79  matrix[10] = cos(radians);
80 }
81 
82 void VART::Transform::MakeZRotation(double radians)
83 {
84  MakeIdentity();
85  matrix[0] = cos(radians);
86  matrix[4] = -sin(radians);
87  matrix[1] = sin(radians);
88  matrix[5] = cos(radians);
89 }
90 
91 void VART::Transform::MakeScale(double sX, double sY, double sZ)
92 {
93  MakeIdentity();
94  matrix[0] = sX;
95  matrix[5] = sY;
96  matrix[10] = sZ;
97 }
98 
99 void VART::Transform::MakeShear(double shX, double shY)
100 {
101  MakeIdentity();
102  matrix[8] = shX;
103  matrix[9] = shY;
104 }
105 
107 {
108  VART::Point4D result;
109 
110  return VART::Point4D( matrix[0]*point.GetX() + matrix[4]*point.GetY()
111  + matrix[8]*point.GetZ() + matrix[12]*point.GetW(),
112  matrix[1]*point.GetX() + matrix[5]*point.GetY()
113  + matrix[9]*point.GetZ() + matrix[13]*point.GetW(),
114  matrix[2]*point.GetX() + matrix[6]*point.GetY()
115  + matrix[10]*point.GetZ() + matrix[14]*point.GetW(),
116  matrix[3]*point.GetX() + matrix[7]*point.GetY()
117  + matrix[11]*point.GetZ() + matrix[15]*point.GetW());
118 }
119 
121 {
122  VART::Transform resultado;
123  for (int i=0; i < 16; ++i)
124  resultado.matrix[i] =
125  matrix[i%4] *t.matrix[i/4*4] +matrix[(i%4)+4] *t.matrix[i/4*4+1]
126  + matrix[(i%4)+8]*t.matrix[i/4*4+2]+matrix[(i%4)+12]*t.matrix[i/4*4+3];
127  return resultado;
128 }
129 
131 {
132  this->SceneNode::operator=(t);
133  for (int i=0; i < 16; ++i)
134  matrix[i] = t.matrix[i];
135  return *this;
136 }
137 
139 {
140  for (int i=0; i < 16; ++i)
141  matrix[i] = t.matrix[i];
142 }
143 
145 {
146  CopyMatrix(t * (*this));
147 }
148 
150 {
151  ptPoint->SetXYZW(
152  matrix[0]*ptPoint->GetX()
153  + matrix[4]*ptPoint->GetY()
154  + matrix[8]*ptPoint->GetZ()
155  + matrix[12]*ptPoint->GetW(),
156  matrix[1]*ptPoint->GetX()
157  + matrix[5]*ptPoint->GetY()
158  + matrix[9]*ptPoint->GetZ()
159  + matrix[13]*ptPoint->GetW(),
160  matrix[2]*ptPoint->GetX()
161  + matrix[6]*ptPoint->GetY()
162  + matrix[10]*ptPoint->GetZ()
163  + matrix[14]*ptPoint->GetW(),
164  matrix[3]*ptPoint->GetX()
165  + matrix[7]*ptPoint->GetY()
166  + matrix[11]*ptPoint->GetZ()
167  + matrix[15]*ptPoint->GetW()
168  );
169 }
170 
171 void VART::Transform::MakeRotation(const VART::Point4D& refVec, const float radians)
172 {
173  VART::Point4D projEmY;
174  VART::Point4D vetTemp;
175  VART::Transform tTemp;
176  double anguloY;
177  double anguloZ;
178 
179  //Decompor refVec
180  //Angulo em Y (para levar o vetor ao plano XY)
181  if (Zero(refVec.GetZ()))
182  {
183  anguloY = 0.0;
184  this->MakeIdentity();
185  vetTemp = refVec;
186  }
187  else
188  {
189  // se o vetor nao esta no plano XY...
190  projEmY.SetXYZW(refVec.GetX(), 0, refVec.GetZ(), 0);
191  projEmY.Normalize();
192  if (refVec.GetZ() < 0)
193  anguloY = -(projEmY.AngleTo(VART::Point4D(1,0,0,0)));
194  else
195  anguloY = projEmY.AngleTo(VART::Point4D(1,0,0,0));
196  this->MakeYRotation(anguloY);
197  vetTemp = (*this) * refVec; //refVec no plano XY
198  }
199  //Angulo em Z (para levar o vetor ao X)
200  if (vetTemp.GetY() < 0)
201  anguloZ = vetTemp.AngleTo(VART::Point4D(1,0,0,0));
202  else
203  anguloZ = -(vetTemp.AngleTo(VART::Point4D(1,0,0,0)));
204  tTemp.MakeZRotation(anguloZ);
205  this->CopyMatrix(tTemp * (*this));
206  //Rodar
207  tTemp.MakeXRotation(radians);
208  this->CopyMatrix(tTemp * (*this));
209  //voltar
210  tTemp.MakeZRotation(-anguloZ);
211  this->CopyMatrix(tTemp * (*this));
212  tTemp.MakeYRotation(-anguloY);
213  this->CopyMatrix(tTemp * (*this));
214 }
215 
216 void VART::Transform::MakeRotation(const VART::Point4D& refPoint, const VART::Point4D& refVec,
217  const float radians)
218 {
219  VART::Transform tTemp;
220 
221  this->MakeTranslation(-refPoint);
222  tTemp.MakeRotation(refVec, radians);
223  this->CopyMatrix(tTemp * (*this));
224  tTemp.MakeTranslation(refPoint);
225  this->CopyMatrix(tTemp * (*this));
226 }
227 
229 {
230  result->SetX(matrix[0]);
231  result->SetY(matrix[1]);
232  result->SetZ(matrix[2]);
233  result->SetW(matrix[3]);
234 }
235 
237 {
238  result->SetX(matrix[4]);
239  result->SetY(matrix[5]);
240  result->SetZ(matrix[6]);
241  result->SetW(matrix[7]);
242 }
243 
245 {
246  result->SetX(matrix[8]);
247  result->SetY(matrix[9]);
248  result->SetZ(matrix[10]);
249  result->SetW(matrix[11]);
250 }
251 
253 {
254  result->SetX(matrix[12]);
255  result->SetY(matrix[13]);
256  result->SetZ(matrix[14]);
257  result->SetW(matrix[15]);
258 }
259 
261 {
262 #ifdef VART_OGL
263  bool result = true;
264 
265  glPushMatrix();
266  glMultMatrixd(matrix);
267 
268  list<VART::SceneNode*>::const_iterator iter = childList.begin();
269  for (; iter != childList.end(); ++iter)
270  result &= (*iter)->DrawOGL();
271  glPopMatrix();
272  return result;
273 #else
274  return false;
275 #endif
276 }
277 
279 #ifdef VART_OGL
280  list<VART::SceneNode*>::const_iterator iter;
281 
282  glPushMatrix();
283  glMultMatrixd(matrix);
284 
285  for (iter = childList.begin(); iter != childList.end(); ++iter)
286  (*iter)->DrawForPicking();
287  glPopMatrix();
288 #else
289  cerr << "Error! Transform::DrawForPicking not implemented for non-OpenGL systems!" << endl;
290 #endif
291 }
292 
294 // virtual method
295 
296 // Note: Bounding boxes from children should be transformed first and then merged.
297 // If merged before transforming, errors will occour because VART::BoundingBox::MergeWith
298 // expects aligned bounding boxes.
299 
300  VART::BoundingBox box; // must not be static because it is used in the recursion
301  bool initBBox = false;
302  list<VART::SceneNode*>::const_iterator iter;
303  VART::GraphicObj* objPtr;
304  VART::Transform* transPtr;
305 
306  for (iter = childList.begin(); iter != childList.end(); ++iter) {
307  objPtr = dynamic_cast<VART::GraphicObj*>(*iter);
308  if (objPtr) { // object is a graphic object
309  objPtr->ComputeRecursiveBoundingBox();
310  box = objPtr->GetRecursiveBoundingBox();
311  box.ApplyTransform(*this);
312  if (initBBox)
313  bBox->MergeWith(box);
314  else {
315  bBox->CopyGeometryFrom(box);
316  initBBox = true;
317  }
318  }
319  else { // object is not a graphic object
320  transPtr = dynamic_cast<VART::Transform*>(*iter);
321  if (transPtr) { // object is a transform
322  if (transPtr->RecursiveBoundingBox(&box)) { // object has graphic descendents
323  box.ApplyTransform(*this);
324  if (initBBox)
325  bBox->MergeWith(box);
326  else {
327  bBox->CopyGeometryFrom(box);
328  initBBox = true;
329  }
330  }
331  }
332  // If not a transform, then it must be a light. Ignore it.
333  }
334  }
335  if (initBBox)
336  bBox->ProcessCenter();
337  return initBBox;
338 }
339 
341  list<VART::SceneNode*>::const_iterator iter;
342  VART::GraphicObj* objPtr;
343  VART::Transform* transPtr;
344 
345  for (iter = childList.begin(); iter != childList.end(); ++iter) {
346  objPtr = dynamic_cast<VART::GraphicObj*>(*iter);
347  if (objPtr) { // object is a graphic object
348  objPtr->ToggleVisibility();
349  objPtr->ToggleRecVisibility();
350  }
351  else { // object is not a graphic object
352  transPtr = dynamic_cast<VART::Transform*>(*iter);
353  if (transPtr) { // object is a transform
354  transPtr->ToggleRecVisibility(); // object has graphic descendents
355  }
356  // If not a transform, then it must be a light. Ignore it.
357  }
358  }
359 }
360 
361 #ifndef NDEBUG
363 {
364  for (int i=0; i < 16; ++i)
365  {
366  if (std::isnan(matrix[i]))
367  return true;
368  }
369  return false;
370 }
371 #endif
372 
373 ostream& VART::operator<<(ostream& output, const VART::Transform& t)
374 {
375  int i, j;
376 
377  output.setf(ios::showpoint|ios::fixed);
378  output.precision(6);
379  for (i=0; i<4; ++i)
380  {
381  for (j=0; j<4; ++j)
382  output << setw(12) << t.matrix[i+j*4] << " ";
383  output << endl;
384  }
385  output.unsetf(ios::showpoint|ios::fixed);
386  return output;
387 }
double AngleTo(const Point4D &p) const
Computes the angle up to p.
Definition: point4d.cpp:126
void SetData(double *data)
Set all data in the transform.
Definition: transform.cpp:33
void ToggleRecVisibility()
Toggles the recursive object's visibility.
Definition: transform.cpp:340
Base class for objects that compose a scene graph.
Definition: scenenode.h:25
Points and vectors using homogeneous coordinates.
Definition: point4d.h:22
Point4D operator*(const Point4D &point) const
Applies transformation to a point.
Definition: transform.cpp:106
Header file for V-ART class "GraphicObj".
void MakeRotation(const Point4D &refVec, const float radians)
Turns transform into a rotation (around some reference vetor).
Definition: transform.cpp:171
void SetW(double w)
Definition: point4d.h:115
void ApplyTo(Point4D *ptPoint) const
Applies tranformation to a point.
Definition: transform.cpp:149
Transform & operator=(const Transform &t)
Copies data from anoter transform.
Definition: transform.cpp:130
void MakeTranslation(const Point4D &translationVector)
Turns transform into a translation.
Definition: transform.cpp:56
void Normalize()
Normalizes the point/vector.
Definition: point4d.cpp:88
double GetZ() const
Definition: point4d.h:80
void ComputeRecursiveBoundingBox()
Computes the recursive bounding box.
Definition: graphicobj.cpp:63
void ToggleVisibility()
Toggles the object's visibility.
Definition: graphicobj.cpp:27
void CopyGeometryFrom(const BoundingBox &box)
Copies geometry data from other bounding box.
Definition: boundingbox.cpp:53
std::ostream & operator<<(std::ostream &output, const Joint::DofID &dofId)
void MergeWith(const BoundingBox &box)
Merges a bounding with another, expanding it.
double GetY() const
Definition: point4d.h:79
Axis aligned bounding box.
Definition: boundingbox.h:23
void SetX(double x)
Definition: point4d.h:112
void MakeXRotation(double radians)
Turns transform into a rotation around the X axis.
Definition: transform.cpp:64
Geometric transformations.
Definition: transform.h:24
void GetVectorX(Point4D *result) const
Returns the X vector of the transform.
Definition: transform.cpp:228
void ToggleRecVisibility()
Toggles the recursive object's visibility.
Definition: graphicobj.cpp:31
virtual bool RecursiveBoundingBox(BoundingBox *bBox)
Returns the recursive bounding box.
Definition: transform.cpp:293
An scene node that is associated with a shape.
Definition: graphicobj.h:18
virtual VART::SceneNode * Copy()
Returns a copy of an Transform. Every derived class must reimplements this method, to avoid errors with VART::SceneNode::RecursiveCopy.
Definition: transform.cpp:28
Header file for V-ART class "BoundingBox".
void MakeYRotation(double radians)
Turns transform into a rotation around the Y axis.
Definition: transform.cpp:73
void MakeIdentity()
Turns transform into identity.
Definition: transform.cpp:49
Header file for V-ART class "Transform".
double matrix[16]
Definition: transform.h:171
virtual bool DrawOGL() const
Apply transform to rendering engine.
Definition: transform.cpp:260
void MakeShear(double shX, double shY)
Turns transform into a shear.
Definition: transform.cpp:99
bool HasNaN() const
Check for NaNs inside the matrix.
Definition: transform.cpp:362
void MakeScale(double sX, double sY, double sZ)
Turns transform into a scale.
Definition: transform.cpp:91
void Apply(const Transform &t)
Applies a transformation to itself.
Definition: transform.cpp:144
void SetY(double y)
Definition: point4d.h:113
void SetZ(double z)
Definition: point4d.h:114
void ApplyTransform(const Transform &trans)
Applies transformation to a BoundingBox.
Definition: boundingbox.cpp:70
void SetXYZW(double x, double y, double z, double w)
Definition: point4d.cpp:80
void GetVectorY(Point4D *result) const
Returns the Y vector of the transform.
Definition: transform.cpp:236
void CopyMatrix(const Transform &t)
Copies matrix data from another transform.
Definition: transform.cpp:138
Transform()
Creates an uninitialized transform.
Definition: transform.cpp:24
virtual void DrawForPicking() const
Draws and object, setting pick info.
Definition: transform.cpp:278
double GetW() const
Definition: point4d.h:81
double GetX() const
Definition: point4d.h:78
const BoundingBox & GetRecursiveBoundingBox() const
Returns the recursive bounding box.
Definition: graphicobj.h:58
void MakeZRotation(double radians)
Turns transform into a rotation around the Z axis.
Definition: transform.cpp:82
void GetTranslation(Point4D *result) const
Returns the translation part of the transform.
Definition: transform.cpp:252
void GetVectorZ(Point4D *result) const
Returns the Z vector of the transform.
Definition: transform.cpp:244