AnimatLab  2
Test
VortexAnimatSim/OsgGeometry.cpp
1 #include "StdAfx.h"
2 #include <stdarg.h>
3 #include "VsMovableItem.h"
4 #include "VsBody.h"
5 #include "VsJoint.h"
6 #include "VsMotorizedJoint.h"
7 #include "VsRigidBody.h"
8 #include "VsOrganism.h"
9 #include "VsStructure.h"
10 #include "VsClassFactory.h"
11 #include "VsSimulator.h"
12 #include "VsOsgUserData.h"
13 #include "VsOsgUserDataVisitor.h"
14 
15 //#include "VsSimulationRecorder.h"
16 #include "VsMouseSpring.h"
17 #include "VsLight.h"
18 #include "VsCameraManipulator.h"
19 #include "VsDragger.h"
20 
21 namespace VortexAnimatSim
22 {
23  namespace Environment
24  {
25 
26 #pragma region CreateGeometry_Code
27 
28 
29 void VORTEX_PORT ApplyVertexTransform(osg::Node *node, osg::Matrix omat)
30 {
31  if (!node)
32  return;
33 
38  //osg::Node *parent = node->getParent(0);
39 
41  //osg::Node *temp = new vtGroup;
42 
43  //osg::Matrix omat;
44  //ConvertMatrix4(&mat, &omat);
45 
46  osg::MatrixTransform *transform = new osg::MatrixTransform;
47  transform->setMatrix(omat);
48  // Tell OSG that it can be optimized
49  transform->setDataVariance(osg::Object::STATIC);
50 
51  //temp->addChild(transform);
52  transform->addChild(node);
53 
55  //parent->removeChild(node);
56 
57  // Now do some OSG voodoo, which should spread the transform downward
58  // through the loaded model, and delete the transform.
59  osgUtil::Optimizer optimizer;
60  optimizer.optimize(transform, osgUtil::Optimizer::FLATTEN_STATIC_TRANSFORMS);
61 
65  //parent->addChild(temp->getChild(0));
66 }
67 
68 osg::Geometry VORTEX_PORT *CreateBoxGeometry(float xsize, float ysize, float zsize, float fltXSegWidth, float fltYSegWidth, float fltZSegWidth)
69 {
70  //if(! hor || ! vert || ! depth)
71  //{
72  // SWARNING << "makeBox: illegal parameters hor=" << hor << ", vert="
73  // << vert << ", depth=" << depth << std::endl;
74  // return NULL;
75  //}
76 
77  osg::Vec3 sizeMin(-xsize/2.0f, -ysize/2.0f, -zsize/2.0f);
78  osg::Vec3 sizeMax(xsize/2.0f, ysize/2.0f, zsize/2.0f);
79  osg::Vec3 steps( (int) ((xsize/fltXSegWidth)+0.5f), (int) ((ysize/fltYSegWidth)+0.5f), (int) ((zsize/fltZSegWidth)+0.5f) );
80  osg::Vec3 SegWidths(fltXSegWidth, fltYSegWidth, fltZSegWidth);
81 
82  osg::Geometry* boxGeom = new osg::Geometry();
83  osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array();
84  osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array();
85  osg::ref_ptr<osg::Vec2Array> texts = new osg::Vec2Array();
86  int iLen = 0;
87  int iPos = 0;
88 
89 #pragma region X-constant-loops
90 
91  //Side 1
92  float fltY1 = sizeMin.y();
93  float fltY2 = fltY1 + SegWidths.y();
94  float fltZ1 = sizeMin.z();
95  float fltZ2 = fltZ1 + SegWidths.z();
96  for(int iy=0; iy<(int) steps.y(); iy++)
97  {
98  for(int iz=0; iz<(int) steps.z(); iz++)
99  {
100  verts->push_back(osg::Vec3(sizeMin.x(), fltY1, fltZ1)); // 0
101  verts->push_back(osg::Vec3(sizeMin.x(), fltY1, fltZ2)); // 3
102  verts->push_back(osg::Vec3(sizeMin.x(), fltY2, fltZ2)); // 5
103  verts->push_back(osg::Vec3(sizeMin.x(), fltY2, fltZ1)); // 1
104 
105  norms->push_back(osg::Vec3(-1, 0, 0));
106  norms->push_back(osg::Vec3(-1, 0, 0));
107  norms->push_back(osg::Vec3(-1, 0, 0));
108  norms->push_back(osg::Vec3(-1, 0, 0));
109 
110  texts->push_back(osg::Vec2( 0.f, 0.f)); // 0
111  texts->push_back(osg::Vec2( 1.f, 0.f)); // 1
112  texts->push_back(osg::Vec2( 1.f, 1.f)); // 4
113  texts->push_back(osg::Vec2( 0.f, 1.f)); // 2
114 
115  fltZ1+=SegWidths.z(); fltZ2+=SegWidths.z();
116  }
117 
118  fltY1+=SegWidths.y(); fltY2+=SegWidths.y();
119  fltZ1 = sizeMin.z(); fltZ2 = fltZ1 + SegWidths.z();
120  }
121 
122  //Side 2 opposite
123  fltY1 = sizeMin.y();
124  fltY2 = fltY1 + SegWidths.y();
125  fltZ1 = sizeMin.z();
126  fltZ2 = fltZ1 + SegWidths.z();
127  for(int iy=0; iy<(int) steps.y(); iy++)
128  {
129  for(int iz=0; iz<(int) steps.z(); iz++)
130  {
131  verts->push_back(osg::Vec3(sizeMax.x(), fltY1, fltZ1)); // 0
132  verts->push_back(osg::Vec3(sizeMax.x(), fltY2, fltZ1)); // 3
133  verts->push_back(osg::Vec3(sizeMax.x(), fltY2, fltZ2)); // 5
134  verts->push_back(osg::Vec3(sizeMax.x(), fltY1, fltZ2)); // 1
135 
136  norms->push_back(osg::Vec3(1, 0, 0));
137  norms->push_back(osg::Vec3(1, 0, 0));
138  norms->push_back(osg::Vec3(1, 0, 0));
139  norms->push_back(osg::Vec3(1, 0, 0));
140 
141  texts->push_back(osg::Vec2( 0.f, 0.f)); // 3
142  texts->push_back(osg::Vec2( 1.f, 0.f)); // 6
143  texts->push_back(osg::Vec2( 1.f, 1.f)); // 7
144  texts->push_back(osg::Vec2( 0.f, 1.f)); // 5
145 
146  fltZ1+=SegWidths.z(); fltZ2+=SegWidths.z();
147  }
148 
149  fltY1+=SegWidths.y(); fltY2+=SegWidths.y();
150  fltZ1 = sizeMin.z(); fltZ2 = fltZ1 + SegWidths.z();
151  }
152 
153 #pragma endregion
154 
155 
156 #pragma region Y-constant-loops
157 
158  //Side 1
159  float fltX1 = sizeMin.x();
160  float fltX2 = fltX1 + SegWidths.x();
161  fltZ1 = sizeMin.z();
162  fltZ2 = fltZ1 + SegWidths.z();
163  for(int ix=0; ix<(int) steps.x(); ix++)
164  {
165  for(int iz=0; iz<(int) steps.z(); iz++)
166  {
167  verts->push_back(osg::Vec3(fltX1, sizeMin.y(), fltZ1)); // 0
168  verts->push_back(osg::Vec3(fltX2, sizeMin.y(), fltZ1)); // 3
169  verts->push_back(osg::Vec3(fltX2, sizeMin.y(), fltZ2)); // 5
170  verts->push_back(osg::Vec3(fltX1, sizeMin.y(), fltZ2)); // 1
171 
172  norms->push_back(osg::Vec3( 0, -1, 0));
173  norms->push_back(osg::Vec3( 0, -1, 0));
174  norms->push_back(osg::Vec3( 0, -1, 0));
175  norms->push_back(osg::Vec3( 0, -1, 0));
176 
177  texts->push_back(osg::Vec2( 0.f, 0.f)); // 0
178  texts->push_back(osg::Vec2( 1.f, 0.f)); // 3
179  texts->push_back(osg::Vec2( 1.f, 1.f)); // 5
180  texts->push_back(osg::Vec2( 0.f, 1.f)); // 1
181 
182  fltZ1+=SegWidths.z(); fltZ2+=SegWidths.z();
183  }
184 
185  fltX1+=SegWidths.x(); fltX2+=SegWidths.x();
186  fltZ1 = sizeMin.z(); fltZ2 = fltZ1 + SegWidths.z();
187  }
188 
189  //Side 2 opposite
190  fltX1 = sizeMin.x();
191  fltX2 = fltX1 + SegWidths.x();
192  fltZ1 = sizeMin.z();
193  fltZ2 = fltZ1 + SegWidths.z();
194  for(int ix=0; ix<(int) steps.x(); ix++)
195  {
196  for(int iz=0; iz<(int) steps.z(); iz++)
197  {
198  verts->push_back(osg::Vec3(fltX2, sizeMax.y(), fltZ1)); // 0
199  verts->push_back(osg::Vec3(fltX1, sizeMax.y(), fltZ1)); // 3
200  verts->push_back(osg::Vec3(fltX1, sizeMax.y(), fltZ2)); // 5
201  verts->push_back(osg::Vec3(fltX2, sizeMax.y(), fltZ2)); // 1
202 
203  norms->push_back(osg::Vec3( 0, 1, 0));
204  norms->push_back(osg::Vec3( 0, 1, 0));
205  norms->push_back(osg::Vec3( 0, 1, 0));
206  norms->push_back(osg::Vec3( 0, 1, 0));
207 
208  texts->push_back(osg::Vec2( 0.f, 0.f)); // 6
209  texts->push_back(osg::Vec2( 1.f, 0.f)); // 2
210  texts->push_back(osg::Vec2( 1.f, 1.f)); // 4
211  texts->push_back(osg::Vec2( 0.f, 1.f)); // 7
212 
213  fltZ1+=SegWidths.z(); fltZ2+=SegWidths.z();
214  }
215 
216  fltX1+=SegWidths.x(); fltX2+=SegWidths.x();
217  fltZ1 = sizeMin.z(); fltZ2 = fltZ1 + SegWidths.z();
218  }
219 
220 #pragma endregion
221 
222 
223 #pragma region Z-constant-loops
224 
225  //Side 1
226  fltX1 = sizeMin.x();
227  fltX2 = fltX1 + SegWidths.x();
228  fltY1 = sizeMin.y();
229  fltY2 = fltY1 + SegWidths.y();
230  for(int ix=0; ix<(int) steps.x(); ix++)
231  {
232  for(int iy=0; iy<(int) steps.y(); iy++)
233  {
234  verts->push_back(osg::Vec3(fltX1, fltY1, sizeMax.z())); // 0
235  verts->push_back(osg::Vec3(fltX2, fltY1, sizeMax.z())); // 3
236  verts->push_back(osg::Vec3(fltX2, fltY2, sizeMax.z())); // 5
237  verts->push_back(osg::Vec3(fltX1, fltY2, sizeMax.z())); // 1
238 
239  norms->push_back(osg::Vec3( 0, 0, 1));
240  norms->push_back(osg::Vec3( 0, 0, 1));
241  norms->push_back(osg::Vec3( 0, 0, 1));
242  norms->push_back(osg::Vec3( 0, 0, 1));
243 
244  texts->push_back(osg::Vec2( 0.f, 0.f)); // 1
245  texts->push_back(osg::Vec2( 1.f, 0.f)); // 5
246  texts->push_back(osg::Vec2( 1.f, 1.f)); // 7
247  texts->push_back(osg::Vec2( 0.f, 1.f)); // 4
248 
249  fltY1+=SegWidths.y(); fltY2+=SegWidths.y();
250  }
251 
252  fltX1+=SegWidths.x(); fltX2+=SegWidths.x();
253  fltY1 = sizeMin.y(); fltY2 = fltY1 + SegWidths.y();
254  }
255 
256  //Side 2 opposite
257  fltX1 = sizeMin.x();
258  fltX2 = fltX1 + SegWidths.x();
259  fltY1 = sizeMin.y();
260  fltY2 = fltY1 + SegWidths.y();
261  for(int ix=0; ix<(int) steps.x(); ix++)
262  {
263  for(int iy=0; iy<(int) steps.y(); iy++)
264  {
265  verts->push_back(osg::Vec3(fltX2, fltY1, sizeMin.z())); // 0
266  verts->push_back(osg::Vec3(fltX1, fltY1, sizeMin.z())); // 3
267  verts->push_back(osg::Vec3(fltX1, fltY2, sizeMin.z())); // 5
268  verts->push_back(osg::Vec3(fltX2, fltY2, sizeMin.z())); // 1
269 
270  norms->push_back(osg::Vec3( 0, 0, -1));
271  norms->push_back(osg::Vec3( 0, 0, -1));
272  norms->push_back(osg::Vec3( 0, 0, -1));
273  norms->push_back(osg::Vec3( 0, 0, -1));
274 
275  texts->push_back(osg::Vec2( 0.f, 0.f)); // 3
276  texts->push_back(osg::Vec2( 1.f, 0.f)); // 0
277  texts->push_back(osg::Vec2( 1.f, 1.f)); // 2
278  texts->push_back(osg::Vec2( 0.f, 1.f)); // 6
279 
280  fltY1+=SegWidths.y(); fltY2+=SegWidths.y();
281  }
282 
283  fltX1+=SegWidths.x(); fltX2+=SegWidths.x();
284  fltY1 = sizeMin.y(); fltY2 = fltY1 + SegWidths.y();
285  }
286 
287 #pragma endregion
288 
289  // create the geometry
290  boxGeom->setVertexArray(verts.get());
291  boxGeom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, verts->size()));
292 
293  boxGeom->setNormalArray(norms.get());
294  boxGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
295 
296  boxGeom->setTexCoordArray( 0, texts.get() );
297 
298  osg::Vec4Array* colors = new osg::Vec4Array;
299  colors->push_back(osg::Vec4(1,1,1,1));
300  boxGeom->setColorArray(colors);
301  boxGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
302 
303  return boxGeom;
304 }
305 
319 osg::Geometry VORTEX_PORT *CreateConeGeometry(float height,
320  float topradius,
321  float botradius,
322  int sides,
323  bool doSide,
324  bool doTop,
325  bool doBottom)
326 {
327  if(height <= 0 || topradius < 0 || botradius < 0 || sides < 3)
328  {
329  //SWARNING << "makeConicalFrustum: illegal parameters height=" << height
330  // << ", topradius=" << topradius
331  // << ", botradius=" << botradius
332  // << ", sides=" << sides
333  // << std::endl;
334  return NULL;
335  }
336 
337  osg::ref_ptr<osg::Vec3Array> p = new osg::Vec3Array();
338  osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array();
339  osg::ref_ptr<osg::Vec2Array> t = new osg::Vec2Array();
340 
341  osg::Geometry* coneGeom = new osg::Geometry();
342  osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array();
343  osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array();
344  osg::ref_ptr<osg::Vec2Array> texts = new osg::Vec2Array();
345 
346  int j;
347  float delta = 2.f * osg::PI / sides;
348  float beta, x, z;
349  float incl = (botradius - topradius) / height;
350  float nlen = 1.f / sqrt(1 + incl * incl);
351  int iLen = 0;
352  int iPos = 0;
353 
354  if(doSide)
355  {
356  int baseindex = p->size();
357 
358  for(j = 0; j <= sides; j++)
359  {
360  beta = j * delta;
361  x = sin(beta);
362  z = -cos(beta);
363 
364  p->push_back(osg::Vec3(x * topradius, height/2, z * topradius));
365  n->push_back(osg::Vec3(x/nlen, incl/nlen, z/nlen));
366  t->push_back(osg::Vec2(1.f - j / float(sides), 1));
367  }
368 
369  for(j = 0; j <= sides; j++)
370  {
371  beta = j * delta;
372  x = sin(beta);
373  z = -cos(beta);
374 
375  p->push_back(osg::Vec3(x * botradius, -height/2, z * botradius));
376  n->push_back(osg::Vec3(x/nlen, incl/nlen, z/nlen));
377  t->push_back(osg::Vec2(1.f - j / float(sides), 0));
378  }
379 
380  for(j = 0; j <= sides; j++)
381  {
382  verts->push_back(p->at(baseindex + sides + 1 + j));
383  verts->push_back(p->at(baseindex + j));
384 
385  norms->push_back(n->at(baseindex + sides + 1 + j));
386  norms->push_back(n->at(baseindex + j));
387 
388  texts->push_back(t->at(baseindex + sides + 1 + j));
389  texts->push_back(t->at(baseindex + j));
390  }
391 
392  iLen = 2 * (sides + 1);
393  coneGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, iPos, iLen));
394  iPos+=iLen;
395  }
396 
397  if(doTop && topradius > 0)
398  {
399  int baseindex = p->getNumElements();
400 
401  // need to duplicate the points fornow, as we don't have multi-index geo yet
402 
403  for(j = sides - 1; j >= 0; j--)
404  {
405  beta = j * delta;
406  x = topradius * sin(beta);
407  z = -topradius * cos(beta);
408 
409  p->push_back(osg::Vec3(x, height/2, z));
410  n->push_back(osg::Vec3(0, 1, 0));
411  t->push_back(osg::Vec2(x / topradius / 2 + .5f, -z / topradius / 2 + .5f));
412  }
413 
414  for(j = 0; j < sides; j++)
415  {
416  verts->push_back(p->at(baseindex + j));
417  norms->push_back(n->at(baseindex + j));
418  texts->push_back(t->at(baseindex + j));
419  }
420 
421  iLen = sides;
422  coneGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, iPos, iLen));
423  iPos+=iLen;
424  }
425 
426  if(doBottom && botradius > 0 )
427  {
428  int baseindex = p->getNumElements();
429 
430  // need to duplicate the points fornow, as we don't have multi-index geo yet
431 
432  for(j = sides - 1; j >= 0; j--)
433  {
434  beta = j * delta;
435  x = botradius * sin(beta);
436  z = -botradius * cos(beta);
437 
438  p->push_back(osg::Vec3(x, -height/2, z));
439  n->push_back(osg::Vec3(0, -1, 0));
440  t->push_back(osg::Vec2(x / botradius / 2 + .5f, z / botradius / 2 + .5f));
441  }
442 
443  for(j = 0; j < sides; j++)
444  {
445  verts->push_back(p->at(baseindex + sides - 1 - j));
446  norms->push_back(n->at(baseindex + sides - 1 - j));
447  texts->push_back(t->at(baseindex + sides - 1 - j));
448  }
449 
450  iLen = sides;
451  coneGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, iPos, iLen));
452  iPos+=iLen;
453  }
454 
455  // create the geometry
456  coneGeom->setVertexArray(verts.get());
457 
458  coneGeom->setNormalArray(norms.get());
459  coneGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
460 
461  coneGeom->setTexCoordArray( 0, texts.get() );
462 
463  osg::Vec4Array* colors = new osg::Vec4Array;
464  colors->push_back(osg::Vec4(1,1,1,1));
465  coneGeom->setColorArray(colors);
466  coneGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
467 
468  return coneGeom;
469 }
470 
472 //
473 // \param[in] latres Number of subdivisions along latitudes.
474 // \param[in] longres Number of subdivisions along longitudes.
475 // \param[in] radius Radius of sphere.
476 // \return GeometryTransitPtr to a newly created Geometry core.
477 //
478 // \sa OSG::makeLatLongSphere
479 //
480 // \ingroup GrpSystemDrawablesGeometrySimpleGeometry
481 // */
482 osg::Geometry VORTEX_PORT *CreateSphereGeometry(int latres,
483  int longres,
484  float radius)
485 {
486  if(radius <= 0 || latres < 4 || longres < 4)
487  {
488  //SWARNING << "makeLatLongSphere: illegal parameters "
489  // << "latres=" << latres
490  // << ", longres=" << longres
491  // << ", radius=" << radius
492  // << std::endl;
493  return NULL;
494  }
495 
496  osg::ref_ptr<osg::Vec3Array> p = new osg::Vec3Array();
497  osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array();
498  osg::ref_ptr<osg::Vec2Array> t = new osg::Vec2Array();
499 
500  int a, b;
501  float theta, phi;
502  float cosTheta, sinTheta;
503  float latDelta, longDelta;
504 
505  // calc the vertices
506 
507  latDelta = osg::PI / latres;
508  longDelta = 2.f * osg::PI / longres;
509 
510  for(a = 0, theta = -osg::PI / 2; a <= latres; a++, theta += latDelta)
511  {
512  cosTheta = cos(theta);
513  sinTheta = sin(theta);
514 
515  for(b = 0, phi = -osg::PI; b <= longres; b++, phi += longDelta)
516  {
517  float cosPhi, sinPhi;
518 
519  cosPhi = cos(phi);
520  sinPhi = sin(phi);
521 
522  n->push_back(osg::Vec3(cosTheta * sinPhi,
523  sinTheta,
524  cosTheta * cosPhi));
525 
526  p->push_back(osg::Vec3( cosTheta * sinPhi * radius,
527  sinTheta * radius,
528  cosTheta * cosPhi * radius));
529 
530  t->push_back(osg::Vec2(b / float(longres),
531  a / float(latres)));
532  }
533  }
534 
535 
536  osg::Geometry* sphereGeom = new osg::Geometry();
537 
538  osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array();
539  osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array();
540  osg::ref_ptr<osg::Vec2Array> texts = new osg::Vec2Array();
541 
542  // create the faces
543  int iLen = (latres + 1) * 2;
544  int iPos = 0;
545  for(a = 0; a < longres; a++)
546  {
547  for(b = 0; b <= latres; b++)
548  {
549  verts->push_back(p->at(b * (longres+1) + a));
550  verts->push_back(p->at(b * (longres+1) + a + 1));
551 
552  norms->push_back(n->at(b * (longres+1) + a));
553  norms->push_back(n->at(b * (longres+1) + a + 1));
554 
555  texts->push_back(t->at(b * (longres+1) + a));
556  texts->push_back(t->at(b * (longres+1) + a + 1));
557  }
558 
559  sphereGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, iPos, iLen));
560  iPos+=iLen;
561  }
562 
563  // create the geometry
564  sphereGeom->setVertexArray(verts.get());
565 
566  sphereGeom->setNormalArray(norms.get());
567  sphereGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
568 
569  sphereGeom->setTexCoordArray( 0, texts.get() );
570 
571  osg::Vec4Array* colors = new osg::Vec4Array;
572  colors->push_back(osg::Vec4(1,1,1,1));
573  sphereGeom->setColorArray(colors);
574  sphereGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
575 
576  return sphereGeom;
577 }
578 
579 
591 osg::Geometry VORTEX_PORT *CreateEllipsoidGeometry(int latres,
592  int longres,
593  float rSemiMajorAxis,
594  float rSemiMinorAxis)
595 {
596  if(rSemiMajorAxis <= 0 || rSemiMinorAxis <= 0 || latres < 4 || longres < 4)
597  {
598  //SWARNING << "makeLatLongSphere: illegal parameters "
599  // << "latres=" << latres
600  // << ", longres=" << longres
601  // << ", rSemiMajorAxis=" << rSemiMajorAxis
602  // << ", rSemiMinorAxis=" << rSemiMinorAxis
603  // << std::endl;
604  return NULL;
605  }
606 
607  osg::ref_ptr<osg::Vec3Array> p = new osg::Vec3Array();
608  osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array();
609  osg::ref_ptr<osg::Vec2Array> t = new osg::Vec2Array();
610 
611  int a, b;
612  float theta, phi;
613  float cosTheta, sinTheta;
614  float latDelta, longDelta;
615 
616  // calc the vertices
617 
618  latDelta = osg::PI / latres;
619  longDelta = 2.f * osg::PI / longres;
620 
621  float rSemiMajorAxisSquare = rSemiMajorAxis * rSemiMajorAxis;
622 
623  float e2 = (rSemiMajorAxisSquare -
624  rSemiMinorAxis * rSemiMinorAxis) / (rSemiMajorAxisSquare);
625 
626  for(a = 0, theta = -osg::PI / 2; a <= latres; a++, theta += latDelta)
627  {
628  cosTheta = cos(theta);
629  sinTheta = sin(theta);
630 
631  float v = rSemiMajorAxis / sqrt(1 - (e2 * sinTheta * sinTheta));
632 
633  for(b = 0, phi = -osg::PI; b <= longres; b++, phi += longDelta)
634  {
635  float cosPhi, sinPhi;
636 
637  cosPhi = cos(phi);
638  sinPhi = sin(phi);
639 
640 
641  n->push_back(osg::Vec3(cosTheta * sinPhi,
642  sinTheta,
643  cosTheta * cosPhi));
644 
645  p->push_back(osg::Vec3(cosTheta * sinPhi * v,
646  sinTheta * ((1 - e2) * v),
647  cosTheta * cosPhi * v));
648 
649  t->push_back(osg::Vec2(b / float(longres),
650  a / float(latres)));
651 
652  }
653  }
654 
655  osg::Geometry* sphereGeom = new osg::Geometry();
656 
657  osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array();
658  osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array();
659  osg::ref_ptr<osg::Vec2Array> texts = new osg::Vec2Array();
660 
661  // create the faces
662  int iLen = (latres + 1) * 2;
663  int iPos = 0;
664 
665  for(a = 0; a < longres; a++)
666  {
667  for(b = 0; b <= latres; b++)
668  {
669  verts->push_back(p->at(b * (longres+1) + a));
670  verts->push_back(p->at(b * (longres+1) + a + 1));
671 
672  norms->push_back(n->at(b * (longres+1) + a));
673  norms->push_back(n->at(b * (longres+1) + a + 1));
674 
675  texts->push_back(t->at(b * (longres+1) + a));
676  texts->push_back(t->at(b * (longres+1) + a + 1));
677  }
678 
679  sphereGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, iPos, iLen));
680  iPos+=iLen;
681  }
682 
683 
684  // create the geometry
685  sphereGeom->setVertexArray(verts.get());
686 
687  sphereGeom->setNormalArray(norms.get());
688  sphereGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
689 
690  sphereGeom->setTexCoordArray( 0, texts.get() );
691 
692  osg::Vec4Array* colors = new osg::Vec4Array;
693  colors->push_back(osg::Vec4(1,1,1,1));
694  sphereGeom->setColorArray(colors);
695  sphereGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
696 
697  return sphereGeom;
698 }
699 
700 osg::Geometry VORTEX_PORT *CreatePlaneGeometry(float fltCornerX, float fltCornerY, float fltXSize, float fltYSize, float fltXGrid, float fltYGrid, bool bBothSides)
701 {
702  float A = fltCornerX;
703  float B = fltCornerY;
704  float C = fltCornerX + fltXSize;
705  float D = fltCornerY + fltYSize;
706 
707  osg::Geometry *geom = new osg::Geometry;
708 
709  // Create an array of four vertices.
710  osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
711  geom->setVertexArray( v.get() );
712  v->push_back( osg::Vec3( A, B, 0 ) );
713  v->push_back( osg::Vec3( C, B, 0 ) );
714  v->push_back( osg::Vec3( C, D, 0 ) );
715  v->push_back( osg::Vec3( A, D, 0 ) );
716 
717  if(bBothSides)
718  {
719  v->push_back( osg::Vec3( C, B, 0 ) );
720  v->push_back( osg::Vec3( A, B, 0 ) );
721  v->push_back( osg::Vec3( A, D, 0 ) );
722  v->push_back( osg::Vec3( C, D, 0 ) );
723  }
724 
725  // Create a Vec2Array of texture coordinates for texture unit 0
726  // and attach it to the geom.
727  osg::ref_ptr<osg::Vec2Array> tc = new osg::Vec2Array;
728  geom->setTexCoordArray( 0, tc.get() );
729  tc->push_back( osg::Vec2( 0.f, 0.f ) );
730  tc->push_back( osg::Vec2( fltXGrid, 0.f ) );
731  tc->push_back( osg::Vec2( fltXGrid, fltYGrid ) );
732  tc->push_back( osg::Vec2( 0.f, fltYGrid ) );
733 
734  if(bBothSides)
735  {
736  tc->push_back( osg::Vec2( 0.f, 0.f ) );
737  tc->push_back( osg::Vec2( fltXGrid, 0.f ) );
738  tc->push_back( osg::Vec2( fltXGrid, fltYGrid ) );
739  tc->push_back( osg::Vec2( 0.f, fltYGrid ) );
740  }
741 
742  // Create an array for the single normal.
743  osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array;
744  n->push_back( osg::Vec3( 0.f, 0.f, -1.f ) );
745  geom->setNormalArray( n.get() );
746  geom->setNormalBinding( osg::Geometry::BIND_OVERALL );
747 
748  // Draw a four-vertex quad from the stored data.
749  geom->addPrimitiveSet(new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );
750 
751  return geom;
752 }
753 
754 bool VORTEX_PORT OsgMatricesEqual(osg::Matrix v1, osg::Matrix v2)
755 {
756  for(int iRow=0; iRow<4; iRow++)
757  for(int iCol=0; iCol<4; iCol++)
758  if(fabs(v1(iRow,iCol)-v2(iRow,iCol)) > 1e-5)
759  return false;
760 
761  return true;
762 }
763 
764 osg::Quat VORTEX_PORT EulerToQuaternion(float fX, float fY, float fZ)
765 {
766  //Vx::VxTransform vTrans;
767  //vTrans.createFromTranslationAndEulerAngles(vTrans, vEuler);
768 
769 
770  //Vx::VxEulerAngles vAngle(fX, fY, fZ);
771  //VxReal44 M;
772  //vAngle.toVxMatrix44(M);
773 
774  float c1 = cos(fY/2);
775  float c2 = cos(fZ/2);
776  float c3 = cos(fX/2);
777 
778  float s1 = sin(fY/2);
779  float s2 = sin(fZ/2);
780  float s3 = sin(fX/2);
781 
782  float c1c2 = c1 * c2;
783  float s1s2 = s1 * s2;
784 
785  float w =c1c2 * c3 - s1s2 * s3;
786  float x =c1c2 * s3 + s1s2 * c3;
787  float y =s1*c2 * c3 + c1 * s2*s3;
788  float z =c1*s2 * c3 - s1 * c2*s3;
789 
790  return osg::Quat(x, y, z, w);
791 }
792 
793 CStdFPoint VORTEX_PORT QuaterionToEuler(osg::Quat vQ)
794 {
795  Vx::VxQuaternion vxQuat(vQ.w(), vQ.x(), vQ.y(), vQ.z());
796  Vx::VxVector3 vEuler;
797  vxQuat.toEulerXYZ(&vEuler);
798  CStdFPoint vRot(vEuler.x(), vEuler.y(), vEuler.z());
799  return vRot;
800 }
801 
802 /*
803 osg::Quat EulerToQuaternion(float fX, float fY, float fZ)
804 {
805  float cos_z_2 = cosf(0.5*fZ);
806  float cos_y_2 = cosf(0.5*fY);
807  float cos_x_2 = cosf(0.5*fX);
808 
809  float sin_z_2 = sinf(0.5*fZ);
810  float sin_y_2 = sinf(0.5*fY);
811  float sin_x_2 = sinf(0.5*fX);
812 
813  // and now compute quaternion
814  float w = cos_z_2*cos_y_2*cos_x_2 + sin_z_2*sin_y_2*sin_x_2;
815  float x = cos_z_2*cos_y_2*sin_x_2 - sin_z_2*sin_y_2*cos_x_2;
816  float y = cos_z_2*sin_y_2*cos_x_2 + sin_z_2*cos_y_2*sin_x_2;
817  float z = sin_z_2*cos_y_2*cos_x_2 - cos_z_2*sin_y_2*sin_x_2;
818 
819  return osg::Quat(x, y, z, w);
820 }
821 
822 CStdFPoint QuaterionToEuler(osg::Quat vQuat)
823 {
824  osg::Vec4d v = vQuat.asVec4();
825  float sqw = v.w()*v.w();
826  float sqx = v.x()*v.x();
827  float sqy = v.y()*v.y();
828  float sqz = v.z()*v.z();
829 
830  CStdFPoint vEuler;
831  vEuler.x = atan2f(2.f * (v.x()*v.y() + v.z()*v.w()), sqx - sqy - sqz + sqw);
832  vEuler.y = asinf(-2.f * (v.x()*v.z() - v.y()*v.w()));
833  vEuler.z = atan2f(2.f * (v.y()*v.z() + v.x()*v.w()), -sqx - sqy + sqz + sqw);
834  return vEuler;
835 }
836 
837 CStdFPoint QuaterionToEuler(osg::Quat q1)
838 {
839  double sqw = q1.w()*q1.w();
840  double sqx = q1.x()*q1.x();
841  double sqy = q1.y()*q1.y();
842  double sqz = q1.z()*q1.z();
843  double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
844  double test = q1.x()*q1.y() + q1.z()*q1.w();
845  float heading, attitude, bank;
846 
847  if (test > 0.499*unit)
848  { // singularity at north pole
849  heading = 2 * atan2(q1.x(),q1.w());
850  attitude = PI_HALF;
851  bank = 0;
852  }
853  else if (test < -0.499*unit)
854  { // singularity at south pole
855  heading = -2 * atan2(q1.x(),q1.w());
856  attitude = -PI_HALF;
857  bank = 0;
858  }
859  else
860  {
861  heading = atan2(2*q1.y()*q1.w()-2*q1.x()*q1.z() , sqx - sqy - sqz + sqw);
862  attitude = asin(2*test/unit);
863  bank = atan2(2*q1.x()*q1.w()-2*q1.y()*q1.z() , -sqx + sqy - sqz + sqw);
864  }
865 
866  CStdFPoint vRot(bank, heading, attitude);
867  return vRot;
868 }
869 */
870 
871 osg::Matrix VORTEX_PORT SetupMatrix(CStdFPoint &localPos, CStdFPoint &localRot)
872 {
873  Vx::VxReal3 vLoc = {localPos.x, localPos.y, localPos.z};
874  Vx::VxReal3 vRot = {localRot.x, localRot.y, localRot.z};
875  Vx::VxTransform vTrans = Vx::VxTransform::createFromTranslationAndEulerAngles(vLoc, vRot);
876 
877  osg::Matrix osgLocalMatrix;
878  VxOSG::copyVxReal44_to_OsgMatrix(osgLocalMatrix, vTrans.m);
879 
880  return osgLocalMatrix;
881 }
882 
883 osg::Matrix VORTEX_PORT SetupMatrix(CStdFPoint &localPos, osg::Quat qRot)
884 {
885  osg::Matrix osgLocalMatrix;
886  osgLocalMatrix.makeIdentity();
887 
888  //convert cstdpoint to osg::Vec3
889  osg::Vec3 vPos(localPos.x, localPos.y, localPos.z);
890 
891  //build the matrix
892  osgLocalMatrix.makeRotate(qRot);
893  osgLocalMatrix.setTrans(vPos);
894 
895  return osgLocalMatrix;
896 }
897 
898 
899 osg::Matrix VORTEX_PORT LoadMatrix(CStdXml &oXml, std::string strElementName)
900 {
901  std::string strMatrix = oXml.GetChildString(strElementName);
902 
903  CStdArray<std::string> aryElements;
904  int iCount = Std_Split(strMatrix, ",", aryElements);
905 
906  if(iCount != 16)
907  THROW_PARAM_ERROR(Al_Err_lMatrixElementCountInvalid, Al_Err_strMatrixElementCountInvalid, "Matrix count", iCount);
908 
909  float aryMT[4][4];
910  int iIndex=0;
911  for(int iX=0; iX<4; iX++)
912  for(int iY=0; iY<4; iY++, iIndex++)
913  aryMT[iX][iY] = atof(aryElements[iIndex].c_str());
914 
915  osg::Matrix osgMT(aryMT[0][0], aryMT[0][1], aryMT[0][2], aryMT[0][3],
916  aryMT[1][0], aryMT[1][1], aryMT[1][2], aryMT[1][3],
917  aryMT[2][0], aryMT[2][1], aryMT[2][2], aryMT[2][3],
918  aryMT[3][0], aryMT[3][1], aryMT[3][2], aryMT[3][3]);
919 
920  return osgMT;
921 }
922 
923 std::string VORTEX_PORT SaveMatrixString(osg::Matrix osgMT)
924 {
925  std::string strMatrix = "";
926  for(int iX=0; iX<4; iX++)
927  {
928  for(int iY=0; iY<4; iY++)
929  {
930  strMatrix += STR(osgMT(iX, iY));
931  if(iY < 3) strMatrix += ",";
932  }
933  if(iX < 3) strMatrix += ",";
934  }
935 
936  return strMatrix;
937 }
938 
939 void VORTEX_PORT SaveMatrix(CStdXml &oXml, std::string strElementName, osg::Matrix osgMT)
940 {
941  std::string strMatrix = SaveMatrixString(osgMT);
942  oXml.AddChildElement(strElementName, strMatrix);
943 }
944 
945 
946 void VORTEX_PORT AddNodeTexture(osg::Node *osgNode, std::string strTexture, osg::StateAttribute::GLMode eTextureMode)
947 {
948  if(osgNode)
949  {
950  if(!Std_IsBlank(strTexture))
951  {
952  osg::ref_ptr<osg::Image> image = osgDB::readImageFile(strTexture);
953  if(!image)
954  THROW_PARAM_ERROR(Vs_Err_lTextureLoad, Vs_Err_strTextureLoad, "Image File", strTexture);
955 
956  osg::StateSet* state = osgNode->getOrCreateStateSet();
957  osg::ref_ptr<osg::Texture2D> osgTexture = new osg::Texture2D(image.get());
958  osgTexture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
959 
960  osgTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
961  osgTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
962 
963  state->setTextureAttributeAndModes(0, osgTexture.get());
964  state->setTextureMode(0, eTextureMode, osg::StateAttribute::ON);
965  state->setMode(GL_BLEND,osg::StateAttribute::ON);
966  }
967  }
968 }
969 
970 void VORTEX_PORT SetNodeColor(osg::Node *osgNode, CStdColor &vAmbient, CStdColor &vDiffuse, CStdColor &vSpecular, float fltShininess)
971 {
972  if(osgNode)
973  {
974  //create a material to use with this node
975  osg::ref_ptr<osg::Material> osgMaterial = new osg::Material();
976 
977  //create a stateset for this node
978  osg::StateSet *osgStateSet = osgNode->getOrCreateStateSet();
979 
980  //set the diffuse property of this node to the color of this body
981  osgMaterial->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(vAmbient[0], vAmbient[1], vAmbient[2], 1));
982  osgMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(vDiffuse[0], vDiffuse[1], vDiffuse[2], vDiffuse[3]));
983  osgMaterial->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(vSpecular[0], vSpecular[1], vSpecular[2], 1));
984  osgMaterial->setShininess(osg::Material::FRONT_AND_BACK, fltShininess);
985  osgStateSet->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
986 
987  //apply the material
988  osgStateSet->setAttribute(osgMaterial.get(), osg::StateAttribute::ON);
989  }
990 }
991 
992 osg::MatrixTransform VORTEX_PORT *CreateLinearAxis(float fltGripScale, CStdFPoint vRotAxis)
993 {
994  CStdFPoint vPos(0, 0, 0), vRot(0, 0, 0);
995  float fltCylinderRadius = fltGripScale * 0.01f;
996  float fltTipRadius = fltGripScale * 0.03f;
997  float fltCylinderHeight = fltGripScale * 2.5;
998  float fltTipHeight = fltGripScale * 0.05f;
999 
1000  //Create the X-axis transform.
1001  osg::MatrixTransform *osgAxis = new osg::MatrixTransform();
1002  vPos.Set(0, 0, 0); vRot = (vRotAxis * -(VX_PI/2));
1003  osgAxis->setMatrix(SetupMatrix(vPos, vRot));
1004 
1005  //Create the cylinder for the hinge
1006  osg::ref_ptr<osg::Geometry> osgCylinderGeom = CreateConeGeometry(fltCylinderHeight, fltCylinderRadius, fltCylinderRadius, 30, true, true, true);
1007  osg::ref_ptr<osg::Geode> osgAxisCylinder = new osg::Geode;
1008  osgAxisCylinder->addDrawable(osgCylinderGeom.get());
1009  osgAxis->addChild(osgAxisCylinder.get());
1010 
1011  osg::ref_ptr<osg::MatrixTransform> osgAxisConeMT = new osg::MatrixTransform();
1012  vPos.Set(0, (fltCylinderHeight/2), 0); vRot.Set(0, 0, 0);
1013  osgAxisConeMT->setMatrix(SetupMatrix(vPos, vRot));
1014 
1015  osg::ref_ptr<osg::Geometry> osgAxisTipGeom = CreateConeGeometry(fltTipHeight, 0, fltTipRadius, 30, true, true, true);
1016  osg::ref_ptr<osg::Geode> osgAxisTip = new osg::Geode;
1017  osgAxisTip->addDrawable(osgAxisTipGeom.get());
1018  osgAxisConeMT->addChild(osgAxisTip.get());
1019  osgAxis->addChild(osgAxisConeMT.get());
1020 
1021  return osgAxis;
1022 }
1023 
1024 osg::Vec3Array VORTEX_PORT *CreateCircleVerts( int plane, int segments, float radius )
1025 {
1026  const double angle( osg::PI * 2. / (double) segments );
1027  osg::Vec3Array* v = new osg::Vec3Array;
1028  int idx, count;
1029  double x(0.), y(0.), z(0.);
1030  double height;
1031  double original_radius = radius;
1032 
1033  for(count = 0; count <= segments/4; count++)
1034  {
1035  height = original_radius*sin(count*angle);
1036  radius = cos(count*angle)*radius;
1037 
1038 
1039  switch(plane)
1040  {
1041  case 0: // X
1042  x = height;
1043  break;
1044  case 1: //Y
1045  y = height;
1046  break;
1047  case 2: //Z
1048  z = height;
1049  break;
1050  }
1051 
1052  for( idx=0; idx<segments; idx++)
1053  {
1054  double cosAngle = cos(idx*angle);
1055  double sinAngle = sin(idx*angle);
1056  switch (plane) {
1057  case 0: // X
1058  y = radius*cosAngle;
1059  z = radius*sinAngle;
1060  break;
1061  case 1: // Y
1062  x = radius*cosAngle;
1063  z = radius*sinAngle;
1064  break;
1065  case 2: // Z
1066  x = radius*cosAngle;
1067  y = radius*sinAngle;
1068  break;
1069  }
1070  v->push_back( osg::Vec3( x, y, z ) );
1071  }
1072  }
1073  return v;
1074 }
1075 
1076 osg::Geode VORTEX_PORT *CreateCircle( int plane, int segments, float radius, float width )
1077 {
1078  osg::Geode* geode = new osg::Geode;
1079  osg::LineWidth* lw = new osg::LineWidth( width );
1080  geode->getOrCreateStateSet()->setAttributeAndModes( lw, osg::StateAttribute::ON );
1081 
1082  osg::Geometry* geom = new osg::Geometry;
1083  osg::Vec3Array* v = CreateCircleVerts( plane, segments, radius );
1084  geom->setVertexArray( v );
1085 
1086  osg::Vec4Array* c = new osg::Vec4Array;
1087  c->push_back( osg::Vec4( 1., 1., 1., 1. ) );
1088  geom->setColorArray( c );
1089  geom->setColorBinding( osg::Geometry::BIND_OVERALL );
1090  geom->addPrimitiveSet( new osg::DrawArrays( GL_LINE_LOOP, 0, segments ) );
1091 
1092  geode->addDrawable( geom );
1093 
1094  return geode;
1095 }
1096 
1097 osg::Geometry VORTEX_PORT *CreateTorusGeometry(float innerRadius,
1098  float outerRadius,
1099  int sides,
1100  int rings)
1101 {
1102  if(innerRadius <= 0 || outerRadius <= 0 || sides < 3 || rings < 3)
1103  {
1104  //SWARNING << "makeTorus: illegal parameters innerRadius=" << innerRadius
1105  // << ", outerRadius=" << outerRadius
1106  // << ", sides=" << sides
1107  // << ", rings=" << rings
1108  // << std::endl;
1109  //return GeometryTransitPtr(NULL);
1110  return NULL;
1111  }
1112 
1113  int a, b;
1114  float theta, phi;
1115  float cosTheta, sinTheta;
1116  float ringDelta, sideDelta;
1117 
1118  // calc the vertices
1119 
1120  osg::ref_ptr<osg::Vec3Array> p = new osg::Vec3Array();
1121  osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array();
1122  osg::ref_ptr<osg::Vec2Array> tx = new osg::Vec2Array();
1123 
1124  ringDelta = 2.f * osg::PI / rings;
1125  sideDelta = 2.f * osg::PI / sides;
1126 
1127  for(a = 0, theta = 0.0; a <= rings; a++, theta += ringDelta)
1128  {
1129  cosTheta = cos(theta);
1130  sinTheta = sin(theta);
1131 
1132  for(b = 0, phi = 0; b <= sides; b++, phi += sideDelta)
1133  {
1134  float cosPhi, sinPhi, dist;
1135 
1136  cosPhi = cos(phi);
1137  sinPhi = sin(phi);
1138  dist = outerRadius + innerRadius * cosPhi;
1139 
1140  n->push_back(osg::Vec3(cosTheta * cosPhi,
1141  -sinTheta * cosPhi,
1142  sinPhi));
1143  p->push_back(osg::Vec3(cosTheta * dist,
1144  -sinTheta * dist,
1145  innerRadius * sinPhi));
1146  tx->push_back(osg::Vec2(- a / float(rings), b / float(sides)));
1147  }
1148  }
1149 
1150  // create the faces
1151  osg::Geometry* torusGeom = new osg::Geometry();
1152 
1153  osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array();
1154  osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array();
1155  osg::ref_ptr<osg::Vec2Array> texts = new osg::Vec2Array();
1156 
1157  int iLen = (rings + 1) * 2;
1158  int iPos = 0;
1159  for(a = 0; a < sides; a++)
1160  {
1161  for(b = 0; b <= rings; b++)
1162  {
1163  verts->push_back(p->at(b * (sides+1) + a));
1164  verts->push_back(p->at(b * (sides+1) + a + 1));
1165 
1166  norms->push_back(n->at(b * (sides+1) + a));
1167  norms->push_back(n->at(b * (sides+1) + a + 1));
1168 
1169  texts->push_back(tx->at(b * (sides+1) + a));
1170  texts->push_back(tx->at(b * (sides+1) + a + 1));
1171  }
1172 
1173  torusGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, iPos, iLen));
1174  iPos+=iLen;
1175  }
1176 
1177 
1178  // create the geometry
1179  torusGeom->setVertexArray(verts.get());
1180 
1181  torusGeom->setNormalArray(norms.get());
1182  torusGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
1183 
1184  torusGeom->setTexCoordArray( 0, texts.get() );
1185 
1186  osg::Vec4Array* colors = new osg::Vec4Array;
1187  colors->push_back(osg::Vec4(1,1,1,1));
1188  torusGeom->setColorArray(colors);
1189  torusGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
1190 
1191  return torusGeom;
1192 }
1193 
1194 osg::Node VORTEX_PORT *CreateHeightField(std::string heightFile, float fltSegWidth, float fltSegLength, float fltMaxHeight, osg::HeightField **osgMap)
1195 {
1196  osg::Image* heightMap = osgDB::readImageFile(heightFile);
1197 
1198  if(!heightMap)
1199  THROW_PARAM_ERROR(Vs_Err_lHeightFieldImageNotDefined, Vs_Err_strHeightFieldImageNotDefined, "Filename", heightFile);
1200 
1201  osg::HeightField* heightField = new osg::HeightField();
1202  *osgMap = heightField;
1203  heightField->allocate(heightMap->s(), heightMap->t());
1204  heightField->setOrigin(osg::Vec3(-(heightMap->s()*fltSegWidth) / 2, -(heightMap->t()*fltSegLength) / 2, 0));
1205  heightField->setXInterval(fltSegWidth);
1206  heightField->setYInterval(fltSegLength);
1207  heightField->setSkirtHeight(1.0f);
1208 
1209  for (int r = 0; r < heightField->getNumRows(); r++)
1210  {
1211  for (int c = 0; c < heightField->getNumColumns(); c++)
1212  heightField->setHeight(c, r, ((*heightMap->data(c, r)) / 255.0f) * fltMaxHeight);
1213  }
1214 
1215  osg::Geode* geode = new osg::Geode();
1216  geode->addDrawable(new osg::ShapeDrawable(heightField));
1217 
1218  //osg::Texture2D* tex = new osg::Texture2D(osgDB::readImageFile(texFile));
1219  //tex->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR_MIPMAP_LINEAR);
1220  //tex->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
1221  //tex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
1222  //tex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
1223  //geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex);
1224 
1225  return geode;
1226 }
1227 
1228 Vx::VxHeightField VORTEX_PORT *CreateVxHeightField(osg::HeightField *osgHeightField, float fltSegWidth, float fltSegLength, float fltBaseHeight, float fltXCenter, float fltYCenter)
1229 {
1230  Vx::VxHeightField *vxHeightField = new Vx::VxHeightField();
1231 
1232  VxArray<VxReal> vHeights;
1233 
1234  //Lets create the height array.
1235  int iCols = osgHeightField->getNumColumns();
1236  int iRows = osgHeightField->getNumRows();
1237  for(int iRow=0; iRow<iRows; iRow++)
1238  for(int iCol=0; iCol<iCols; iCol++)
1239  vHeights.push_back(osgHeightField->getHeight(iCol, iRow) + fltBaseHeight);
1240 
1241  int iSize = vHeights.size();
1242  osg::Vec3 vCenter(fltXCenter, fltYCenter, 0);
1243  osg::Vec3 vOrigin = osgHeightField->getOrigin();
1244  vOrigin += vCenter;
1245 
1246  vxHeightField->build((iCols-1), (iRows-1), fltSegWidth, fltSegLength, vOrigin.x(), vOrigin.y(), vHeights);
1247 
1248  return vxHeightField;
1249 }
1250 
1251 
1252 osg::Geometry VORTEX_PORT *CreateOsgFromVxConvexMesh(Vx::VxConvexMesh *vxGeometry)
1253 {
1254  // calc the vertices
1255  osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array();
1256  osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array();
1257  osg::Geometry* osgGeom = new osg::Geometry();
1258 
1259  Vx::VxReal3 vVertex;
1260  int iCurVertex=0;
1261  int iPolyCount = vxGeometry->getPolygonCount();
1262  for(int iPoly=0; iPoly<iPolyCount; iPoly++)
1263  {
1264  int iVertexCount = vxGeometry->getPolygonVertexCount(iPoly);
1265 
1266  osg::ref_ptr<osg::DrawElementsUInt> osgPolygon = new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0);
1267 
1268  for(int iVertex=0; iVertex<iVertexCount; iVertex++)
1269  {
1270  vxGeometry->getPolygonVertex(iPoly, iVertex, vVertex);
1271  verts->push_back( osg::Vec3( vVertex[0], vVertex[1], vVertex[2]) );
1272 
1273  osgPolygon->push_back(iCurVertex);
1274  iCurVertex++;
1275  }
1276 
1277  osgGeom->addPrimitiveSet(osgPolygon.get());
1278 
1279  //Get the normal for this polygon.
1280  vxGeometry->getPolygonNormal(iPoly, vVertex);
1281  norms->push_back( osg::Vec3( vVertex[0], vVertex[1], vVertex[2]) );
1282  }
1283 
1284  // create the geometry
1285  osgGeom->setVertexArray(verts.get());
1286 
1287  osgGeom->setNormalArray(norms.get());
1288  osgGeom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
1289 
1290  osg::Vec4Array* colors = new osg::Vec4Array;
1291  colors->push_back(osg::Vec4(1,1,1,1));
1292  osgGeom->setColorArray(colors);
1293  osgGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
1294 
1295  return osgGeom;
1296 }
1297 
1298 /*
1299 osg::Geometry *CreateHeightFieldGeometry(std::string strFilename, float fltLeftCorner, float fltUpperCorner,
1300  float fltSegmentWidth, float fltSegmentLength,
1301  float fltMinElevation, float fltMaxElevation)
1302 {
1303  std::string strHeightMap = "C:\\Projects\\AnimatLabSDK\\Experiments\\MeshTest2\\TerrainTest\\TerrainTest_HeightMap.jpg"
1304  std::string strNormalsMap = "C:\\Projects\\AnimatLabSDK\\Experiments\\MeshTest2\\TerrainTest\\TerrainTest_NormalsMap.jpg"
1305  std::string strTextureMap = "C:\\Projects\\AnimatLabSDK\\Experiments\\MeshTest2\\TerrainTest\\TerrainTest_TextureMap.jpg"
1306 
1307  //load the images.
1308  osg::Image *imgHeight = osgDB::readImageFile(strHeightMap.c_str());
1309  if(!imgHeight)
1310  THROW_TEXT_ERROR(Vs_Err_lHeightFieldImageNotDefined, Vs_Err_strHeightFieldImageNotDefined, " Height Map: " + strHeightMap);
1311 
1312  osg::Image *imgNormals = osgDB::readImageFile(strNormalsMap.c_str());
1313  if(!imgNormals)
1314  THROW_TEXT_ERROR(Vs_Err_lHeightFieldImageNotDefined, Vs_Err_strHeightFieldImageNotDefined, " Normals Map: " + strNormalsMap);
1315 
1316  //Verify that the images have the same width/height/ and depth.
1317  if( (imgHeight->s() != imgNormals->s()) )
1318  THROW_TEXT_ERROR(Vs_Err_lHeightFieldImageMismatch, Vs_Err_strHeightFieldImageMismatch, " Height map: " + strHeightMap);
1319 
1320  if( (imgHeight->t() != imgNormals->t())) )
1321  THROW_TEXT_ERROR(Vs_Err_lHeightFieldImageMismatch, Vs_Err_strHeightFieldImageMismatch, " Height map: " + strHeightMap);
1322 
1323  if( (imgHeight->r() != imgNormals->r()) )
1324  THROW_TEXT_ERROR(Vs_Err_lHeightFieldImageMismatch, Vs_Err_strHeightFieldImageMismatch, " Height map: " + strHeightMap);
1325 
1326  int iWidth = imgHeight->s();
1327  int iLength = imgHeight->t();
1328 
1329  float fltWidthSize = iWidth*fltSegmentWidth;
1330  float fltLengthSize = iLength*fltSegmentLength;
1331 
1332  int iWidthSteps = (int) (fltWidthSize/fltSegmentWidth);
1333  int iLengthSteps = (int) (fltWidthSize/fltSegmentWidth);
1334 
1335  //osg::Geometry* boxGeom = new osg::Geometry();
1336  osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array();
1337  osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array();
1338  osg::ref_ptr<osg::Vec2Array> texts = new osg::Vec2Array();
1339  int iLen = 0;
1340  int iPos = 0;
1341 
1342  float fltX1 = fltLeftCorner;
1343  float fltX2 = fltX1 + fltSegmentWidth;
1344  fltZ1 = fltUpperCorner;
1345  fltZ2 = fltZ1 + fltSegmentLength;
1346  for(int ix=0; ix<(int) steps.x(); ix++)
1347  {
1348  for(int iz=0; iz<(int) steps.z(); iz++)
1349  {
1350  osg::Vec4 vHeight = imgHeight->getColor(ix, iz);
1351  osg::Vec4 vNorm = imgNormals->getColor(ix, iz);
1352 
1353  verts->push_back(osg::Vec3(fltX1, sizeMin.y(), fltZ1)); // 0
1354  verts->push_back(osg::Vec3(fltX2, sizeMin.y(), fltZ1)); // 3
1355  verts->push_back(osg::Vec3(fltX2, sizeMin.y(), fltZ2)); // 5
1356  verts->push_back(osg::Vec3(fltX1, sizeMin.y(), fltZ2)); // 1
1357 
1358  norms->push_back(osg::Vec3( 0, -1, 0));
1359  norms->push_back(osg::Vec3( 0, -1, 0));
1360  norms->push_back(osg::Vec3( 0, -1, 0));
1361  norms->push_back(osg::Vec3( 0, -1, 0));
1362 
1363  texts->push_back(osg::Vec2( 0.f, 0.f)); // 0
1364  texts->push_back(osg::Vec2( 1.f, 0.f)); // 3
1365  texts->push_back(osg::Vec2( 1.f, 1.f)); // 5
1366  texts->push_back(osg::Vec2( 0.f, 1.f)); // 1
1367 
1368  fltZ1+=fltSegmentLength; fltZ2+=fltSegmentLength;
1369  }
1370 
1371  fltX1+=fltSegmentWidth; fltX2+=fltSegmentWidth;
1372  fltZ1 = fltUpperCorner; fltZ2 = fltZ1 + fltSegmentLength;
1373  }
1374 
1375  // create the geometry
1376  boxGeom->setVertexArray(verts.get());
1377  boxGeom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, verts->size()));
1378 
1379  boxGeom->setNormalArray(norms.get());
1380  boxGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
1381 
1382  boxGeom->setTexCoordArray( 0, texts.get() );
1383 
1384  osg::Vec4Array* colors = new osg::Vec4Array;
1385  colors->push_back(osg::Vec4(1,1,1,1));
1386  boxGeom->setColorArray(colors);
1387  boxGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
1388 
1389  return boxGeom;
1390 }
1391 */
1392 
1393 #pragma endregion
1394 
1395  } // Environment
1396 //} //VortexAnimatSim
1397 
1398 }
int Std_Split(const std::string &input, const std::string &delimiter, CStdArray< std::string > &results)
Splits a string into an array of subparts based on a delimiter.
Declares the vortex organism class.
osg::Geometry * CreateConeGeometry(float height, float topradius, float botradius, int sides, bool doSide, bool doTop, bool doBottom)
osg::Geometry * CreateSphereGeometry(int latres, int longres, float radius)
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
osg::Geometry * CreateEllipsoidGeometry(int latres, int longres, float rSemiMajorAxis, float rSemiMinorAxis)
bool Std_IsBlank(std::string strVal)
Trims a string and tests if a string is blank.
Declares the vortex Light class.
Declares the vortex structure class.