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