AnimatLab  2
Test
OsgLine.cpp
1 // OsgLine.cpp: implementation of the OsgLine class.
2 //
4 
5 #include "StdAfx.h"
6 #include "OsgMovableItem.h"
7 #include "OsgBody.h"
8 #include "OsgRigidBody.h"
9 #include "OsgJoint.h"
10 #include "OsgStructure.h"
11 #include "OsgSimulator.h"
12 #include "OsgUserData.h"
13 #include "OsgUserDataVisitor.h"
14 #include "OsgDragger.h"
15 #include "OsgLine.h"
16 
17 
18 namespace OsgAnimatSim
19 {
20  namespace Environment
21  {
22 
24 // Construction/Destruction
26 
27 OsgLine::OsgLine()
28 {
29  m_lpLinesGeom = NULL;
30 }
31 
32 OsgLine::~OsgLine()
33 {
34 
35 try
36 {
37  //Deleted elsewhere
38  m_lpLinesGeom = NULL;
39 }
40 catch(...)
41 {Std_TraceMsg(0, "Caught Error in desctructor of OsgLine\r\n", "", -1, false, true);}
42 }
43 
44 void OsgLine::SetThisLinePointers()
45 {
46  m_lpLineBase = dynamic_cast<LineBase *>(this);
47  if(!m_lpLineBase)
48  THROW_TEXT_ERROR(Osg_Err_lThisPointerNotDefined, Osg_Err_strThisPointerNotDefined, "m_lpLineBase ");
49 }
50 
51 osg::Geometry *OsgLine::CreateLineGeometry()
52 {
53  osg::Geometry* linesGeom = new osg::Geometry();
54  int iCount = BuildLines(linesGeom);
55 
56  // set the colors as before, plus using the above
57  CStdColor &aryDiffuse = *m_lpLineBase->Diffuse();
58  osg::Vec4Array* colors = new osg::Vec4Array;
59  colors->push_back(osg::Vec4(aryDiffuse[0], aryDiffuse[1], aryDiffuse[2], aryDiffuse[3]));
60  linesGeom->setColorArray(colors);
61  linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
62 
63 
64  // set the normal in the same way color.
65  osg::Vec3Array* normals = new osg::Vec3Array;
66  normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
67  linesGeom->setNormalArray(normals);
68  linesGeom->setNormalBinding(osg::Geometry::BIND_OVERALL);
69 
70 
71  // This time we simply use primitive, and hardwire the number of coords to use
72  // since we know up front,
73  osg::PrimitiveSet *lpSet = new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, iCount);
74  linesGeom->addPrimitiveSet(lpSet);
75 
76  linesGeom->setDataVariance(osg::Object::DYNAMIC);
77  linesGeom->setUseDisplayList(false);
78 
79  m_lpLinesGeom = linesGeom;
80  return linesGeom;
81 }
82 
83 int OsgLine::BuildLines(osg::Geometry *linesGeom)
84 {
85  //Always create the graphics. If it is disabled or made not visible we will turn it off.
86  CStdArray<Attachment *> *aryAttachments = m_lpLineBase->AttachmentPoints();
87  int iCount = aryAttachments->GetSize();
88 
89  //If we already have a lines array then delete it and rebuild.
90  if(m_aryLines.valid())
91  m_aryLines.release();
92 
93  m_aryLines = new osg::Vec3Array;
94 
95  //Only draw the line if we have more than one point.
96  if(iCount > 1)
97  {
98  CStdFPoint vPos;
99  Attachment *lpPrevAttach=NULL;
100  Attachment *lpAttach=NULL;
101 
102  for(int iIndex=1; iIndex<iCount; iIndex++)
103  {
104  lpPrevAttach = aryAttachments->at(iIndex-1);
105  lpAttach = aryAttachments->at(iIndex);
106 
107  vPos = lpPrevAttach->AbsolutePosition();
108  m_aryLines->push_back(osg::Vec3(vPos.x, vPos.y, vPos.z));
109 
110  vPos = lpAttach->AbsolutePosition();
111  m_aryLines->push_back(osg::Vec3(vPos.x, vPos.y, vPos.z));
112  }
113  }
114 
115  linesGeom->setVertexArray(m_aryLines.get());
116  linesGeom->dirtyBound();
117 
118  return m_aryLines->getNumElements();
119 }
120 
121 void OsgLine::DrawLine()
122 {
123  CStdArray<Attachment *> *aryAttachments = m_lpLineBase->AttachmentPoints();
124  int iCount = aryAttachments->GetSize();
125 
126  //Only draw the line if we have more than one point.
127  if(iCount > 1)
128  {
129  CStdFPoint vPos;
130  Attachment *lpPrevAttach=NULL;
131  Attachment *lpAttach=NULL;
132  int iLineIdx = 0;
133 
134  for(int iIndex=1; iIndex<iCount; iIndex++)
135  {
136  lpPrevAttach = aryAttachments->at(iIndex-1);
137  lpAttach = aryAttachments->at(iIndex);
138 
139  vPos = lpPrevAttach->AbsolutePosition();
140  (*m_aryLines)[iLineIdx].set(vPos.x, vPos.y, vPos.z);
141 
142  vPos = lpAttach->AbsolutePosition();
143  (*m_aryLines)[iLineIdx+1].set(vPos.x, vPos.y, vPos.z);
144 
145  iLineIdx+=2;
146  }
147 
148  if(m_lpLinesGeom)
149  m_lpLinesGeom->dirtyBound();
150  }
151 }
152 
153 void OsgLine::CalculateForceVector(Attachment *lpPrim, Attachment *lpSec, float fltTension, CStdFPoint &oPrimPos, CStdFPoint &oSecPos, CStdFPoint &oPrimForce)
154 {
155  oPrimPos = lpPrim->AbsolutePosition();
156  oSecPos = lpSec->AbsolutePosition();
157 
158  oPrimForce = oSecPos - oPrimPos;
159  oPrimForce.Normalize();
160  oPrimForce *= fltTension;
161 }
162 
163 void OsgLine::StepLineSimulation(bool bEnabled, float fltTension)
164 {
165  if(bEnabled)
166  {
168  //int iTest = 0;
169  //if(m_lpLineBase->GetSimulator()->Time() >= 0.15)
170  // iTest = iTest;
171 
172  //Dont bother with this unless there is actually tension developed by the muscle.
173  if(fabs(fltTension) > 1e-5)
174  {
175  CStdArray<Attachment *> *aryAttachments = m_lpLineBase->AttachmentPoints();
176  int iCount = aryAttachments->GetSize();
177  Attachment *lpAttach1 = aryAttachments->at(0), *lpAttach2 = NULL;
178  CStdFPoint oPrimPos, oPrimPlusPos, oSecPos, oSecMinusPos;
179  CStdFPoint oPrimForce, oSecForce;
180  RigidBody *lpAttach1Parent, *lpAttach2Parent;
181 
182  //Go through each set of muscle attachments and add the tension force pointing towards the other
183  //attachment point at each connector.
184  for(int iIndex=1; iIndex<iCount; iIndex++)
185  {
186  lpAttach2 = aryAttachments->at(iIndex);
187 
188  lpAttach1Parent = lpAttach1->Parent();
189  lpAttach2Parent = lpAttach2->Parent();
190 
191  CalculateForceVector(lpAttach1, lpAttach2, fltTension, oPrimPos, oPrimPlusPos, oPrimForce);
192  CalculateForceVector(lpAttach2, lpAttach1, fltTension, oSecPos, oSecMinusPos, oSecForce);
193 
194  lpAttach1Parent->AddForceAtWorldPos(oPrimPos.x, oPrimPos.y, oPrimPos.z, oPrimForce.x, oPrimForce.y, oPrimForce.z, true);
195  lpAttach2Parent->AddForceAtWorldPos(oSecPos.x, oSecPos.y, oSecPos.z, oSecForce.x, oSecForce.y, oSecForce.z, true);
196 
197  lpAttach1 = lpAttach2;
198  }
199  }
200  }
201 
202  DrawLine();
203 }
204 
205 
206  } // Visualization
207 } //OsgAnimatSim
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
void Std_TraceMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bLogToFile, bool bPrintHeader)
Traces a message to the debugger window.
Declares the vortex structure class.