SO3Engine
SO3Lines.cpp
Go to the documentation of this file.
1
2#include "SO3Utils/SO3Lines.h"
4
5namespace SO3
6{
7
8bool SLines::_material_created = false;
9
10SLines::SLines(const Ogre::ColourValue& defaultColour, bool dashed, bool disableDepth) : SimpleRenderable()
11{
12 colour = defaultColour;
13
14 mRenderOp.vertexData = new Ogre::VertexData();
15 mRenderOp.indexData = 0;
16 mRenderOp.vertexData->vertexCount = 0;
17 mRenderOp.vertexData->vertexStart = 0;
18 mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST;
19 mRenderOp.useIndexes = false;
20 _drawn = false;
21 mDashed = dashed;
22
23 if (!_material_created)
24 {
25 Ogre::StringVector resourceGroups = Ogre::ResourceGroupManager::getSingletonPtr()->getResourceGroups();
26 if(std::find(resourceGroups.begin(), resourceGroups.end(), SO3_INTERNAL_RESOURCE_GROUP) == resourceGroups.end())
27 Ogre::ResourceGroupManager::getSingletonPtr()->createResourceGroup(SO3_INTERNAL_RESOURCE_GROUP);
28
29 Ogre::MaterialPtr autocolour = Ogre::MaterialManager::getSingleton().create(std::string(SO3_INTERNAL_RESOURCE_GROUP)+"/LineAuto", SO3_INTERNAL_RESOURCE_GROUP);
30 autocolour->setReceiveShadows(false);
31 autocolour->getTechnique(0)->setLightingEnabled(true);
32 autocolour->getTechnique(0)->getPass(0)->setVertexProgram("SO3/VS/LINECUSTOMCOLOR");
33 autocolour->getTechnique(0)->getPass(0)->setFragmentProgram("SO3/FP/LINECUSTOMCOLOR");
34
35 Ogre::MaterialPtr autocolournodepth = Ogre::MaterialManager::getSingleton().create(std::string(SO3_INTERNAL_RESOURCE_GROUP) + "/LineAutoNoDepth", SO3_INTERNAL_RESOURCE_GROUP);
36 autocolournodepth->setReceiveShadows(false);
37 autocolournodepth->getTechnique(0)->setLightingEnabled(true);
38 autocolournodepth->getTechnique(0)->setDepthFunction(Ogre::CMPF_ALWAYS_PASS);
39 autocolournodepth->getTechnique(0)->getPass(0)->setVertexProgram("SO3/VS/LINECUSTOMCOLOR");
40 autocolournodepth->getTechnique(0)->getPass(0)->setFragmentProgram("SO3/FP/LINECUSTOMCOLOR");
41 _material_created = true;
42 }
43
44 setCastShadows(false);
45 std::string matName = (disableDepth) ? "/LineAutoNoDepth" : "/LineAuto";
46 Ogre::MaterialPtr linemat = Ogre::MaterialManager::getSingleton().getByName(std::string(SO3_INTERNAL_RESOURCE_GROUP) + matName, SO3_INTERNAL_RESOURCE_GROUP);
47 setMaterial(linemat);
48 setCustomParameter(0, Ogre::Vector4(colour.r, colour.g, colour.b, colour.a));
49}
50
52{
53 Clear();
54 delete mRenderOp.vertexData;
55}
56
58{
59 _points.clear();
60 ClearDraw();
61}
62
63void SLines::ClearDraw()
64{
65 if (_drawn)
66 {
67 _drawn = false;
68 mRenderOp.vertexData->vertexCount = 0;
69 }
70}
71
72Ogre::ColourValue SLines::GetColour()
73{
74 return colour;
75}
76
77void SLines::SetColour(const Ogre::ColourValue& newColour)
78{
79 colour = newColour;
80 setCustomParameter(0, Ogre::Vector4(colour.r, colour.g, colour.b, colour.a));
81}
82
83void SLines::AddLine(const Ogre::Vector3& start, const Ogre::Vector3& end)
84{
85 ClearDraw();
86 // TODO optim last point = start point
87 _points.push_back(start);
88 _points.push_back(end);
89}
90
91void SLines::AddLine(const Ogre::Real& start_x, const Ogre::Real& start_y, const Ogre::Real& start_z, const Ogre::Real& end_x, const Ogre::Real& end_y, const Ogre::Real& end_z)
92{
93 AddLine(Ogre::Vector3(start_x,start_y,start_z), Ogre::Vector3(end_x,end_y,end_z));
94}
95
96void SLines::AddPoint(const size_t& pointIndex, const Ogre::Vector3& pt)
97{
98 if(pointIndex <= _points.size())
99 {
100 ClearDraw();
101 if(pointIndex >= (_points.size() - 1))
102 _points.push_back(pt);
103 else
104 _points.insert(_points.begin() + pointIndex + 1, pt);
105 }
106 else
107 SO3_EXCEPT(SExceptionOutOfBound, "Index out of bound, no such point!", "SLines::AddPoint", true);
108}
109
110void SLines::AddPoint(const size_t& pointIndex, const Ogre::Real& x, const Ogre::Real& y, const Ogre::Real& z)
111{
112 AddPoint(pointIndex, Ogre::Vector3(x, y, z));
113}
114
115void SLines::AddPoint(const Ogre::Vector3& pt)
116{
117 ClearDraw();
118 _points.push_back(pt);
119}
120
121void SLines::AddPoint(const Ogre::Real& x, const Ogre::Real& y, const Ogre::Real& z)
122{
123 AddPoint(Ogre::Vector3(x, y, z));
124}
125
126void SLines::RemovePoint(const size_t& pointIndex)
127{
128 if(pointIndex <= _points.size())
129 {
130 ClearDraw();
131 _points.erase(_points.begin() + pointIndex);
132 }
133 else
134 SO3_EXCEPT(SExceptionOutOfBound, "Index out of bound, no such point!", "SLines::RemovePoint", true);
135}
136
138{
139 return _points.size();
140}
141
142Ogre::Vector3 SLines::GetPoint(const size_t& pointIndex)
143{
144 if(pointIndex <= _points.size())
145 {
146 return _points[pointIndex];
147 }
148 else
149 {
150 SO3_EXCEPT(SExceptionOutOfBound, "Index out of bound, no such point!", "SLines::GetPoint", true);
151 return Ogre::Vector3::ZERO;
152 }
153}
154
155void SLines::SetPoint(const size_t& pointIndex, const Ogre::Vector3& pt)
156{
157 if(pointIndex <= _points.size())
158 {
159 ClearDraw();
160 _points[pointIndex] = pt;
161 }
162 else
163 SO3_EXCEPT(SExceptionOutOfBound, "Index out of bound, no such point!", "SLines::SetPoint", true);
164}
165
166void SLines::SetPoint(const size_t& pointIndex, const Ogre::Real& x, const Ogre::Real& y, const Ogre::Real& z)
167{
168 SetPoint(pointIndex, Ogre::Vector3(x, y, z));
169}
170
171void SLines::SetDashed(bool dashed)
172{
173 mDashed = dashed;
174}
175
177{
178 return mDashed;
179}
180
182{
183 if (mDashed)
184 {
185 DrawDash();
186 return;
187 }
188
189 if (_drawn || _points.size() < 2)
190 return;
191 else
192 _drawn = true;
193
194 // Initialization, count * 2 - (first and last) for continuous lines
195 mRenderOp.vertexData->vertexCount = (_points.size() * 2) - 2;
196
197 Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
198 Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
199
200 //clear bindings
201 bind->unsetAllBindings();
202
203 // Setup vertex struct
204 decl->removeAllElements();
205 size_t currOffset = 0;
206
207 // positions
208 decl->addElement(0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
209 currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
210
211 decl->addElement(0, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
212 currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
213
214 // Get vertex buffer
215 Ogre::HardwareVertexBufferSharedPtr vbuf;
216 vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(0),
217 mRenderOp.vertexData->vertexCount,
218 Ogre::HardwareBuffer::HBU_DYNAMIC);
219 bind->setBinding(0, vbuf);
220
221 // Drawing stuff
222 float* pFloat;
223 unsigned int size = (unsigned int)_points.size();
224 unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_WRITE_ONLY));
225 for(unsigned int i = 0; i < size; i++)
226 {
227 // VES_POSITION
228 decl->getElement(0)->baseVertexPointerToElement(pVert, &pFloat);
229 *pFloat++ = _points[i].x;
230 *pFloat++ = _points[i].y;
231 *pFloat++ = _points[i].z;
232
233 // VES_TEXTURE_COORDINATES
234 *pFloat++ = 0.0f;
235 *pFloat++ = 0.0f;
236
237 // Update pVert
238 pVert += vbuf->getVertexSize();
239
240 // double the vertex if this is not the first or last point
241 if ((i != 0) && (i < size - 1))
242 {
243 // VES_POSITION
244 decl->getElement(0)->baseVertexPointerToElement(pVert, &pFloat);
245 *pFloat++ = _points[i].x;
246 *pFloat++ = _points[i].y;
247 *pFloat++ = _points[i].z;
248
249 // VES_TEXTURE_COORDINATES
250 *pFloat++ = 0.0f;
251 *pFloat++ = 0.0f;
252
253 // Update pVert
254 pVert += vbuf->getVertexSize();
255 }
256 }
257
258 vbuf->unlock();
259 mBox.setInfinite();
260}
261
263{
264 if (_drawn || _points.empty())
265 return;
266 else
267 _drawn = true;
268
269 mRenderOp.vertexData->vertexCount = _points.size();
270
271 Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
272 Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
273
274 //clear bindings
275 bind->unsetAllBindings();
276
277 // Setup vertex struct
278 decl->removeAllElements();
279 decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
280
281 Ogre::HardwareVertexBufferSharedPtr vbuf;
282 vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(0),
283 mRenderOp.vertexData->vertexCount,
284 Ogre::HardwareBuffer::HBU_DYNAMIC);
285 bind->setBinding(0, vbuf);
286
287 // Drawing stuff
288 float* pFloat;
289 unsigned int size = (unsigned int)_points.size();
290 unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_WRITE_ONLY));
291 for(unsigned int i = 0; i < size; i++)
292 {
293 // VES_POSITION
294 decl->getElement(0)->baseVertexPointerToElement(pVert, &pFloat);
295 *pFloat++ = _points[i].x;
296 *pFloat++ = _points[i].y;
297 *pFloat = _points[i].z;
298
299 // Update pVert
300 pVert += vbuf->getVertexSize();
301 }
302
303 vbuf->unlock();
304 mBox.setInfinite();
305}
306
307Ogre::Real SLines::getSquaredViewDepth(const Ogre::Camera* cam) const
308{
309 Ogre::Vector3 vMin, vMax, vMid, vDist;
310 vMin = mBox.getMinimum();
311 vMax = mBox.getMaximum();
312 vMid = ((vMin - vMax) * 0.5) + vMin;
313 vDist = cam->getDerivedPosition() - vMid;
314
315 return vDist.squaredLength();
316}
317
319{
320 return Ogre::Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength()));
321}
322
323}
SException indicating that an attempt to get a tab element with a given index out of bound.
void SetColour(const Ogre::ColourValue &newColour)
Definition SO3Lines.cpp:77
SLines(const Ogre::ColourValue &defaultColour=Ogre::ColourValue::White, bool dashed=false, bool disableDepth=false)
Definition SO3Lines.cpp:10
void SetPoint(const size_t &pointIndex, const Ogre::Vector3 &pt)
Definition SO3Lines.cpp:155
void SetDashed(bool dashed)
Definition SO3Lines.cpp:171
Ogre::ColourValue GetColour()
Definition SO3Lines.cpp:72
void AddLine(const Ogre::Vector3 &start, const Ogre::Vector3 &end)
Definition SO3Lines.cpp:83
void RemovePoint(const size_t &pointIndex)
Definition SO3Lines.cpp:126
void Draw()
Definition SO3Lines.cpp:181
bool GetDashed()
Definition SO3Lines.cpp:176
void AddPoint(const size_t &pointIndex, const Ogre::Vector3 &pt)
Definition SO3Lines.cpp:96
size_t GetNumberOfPoints() const
Definition SO3Lines.cpp:137
void Clear()
Definition SO3Lines.cpp:57
virtual Ogre::Real getBoundingRadius() const
Definition SO3Lines.cpp:318
void DrawDash()
Definition SO3Lines.cpp:262
Ogre::Vector3 GetPoint(const size_t &pointIndex)
Definition SO3Lines.cpp:142
virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera *cam) const
Definition SO3Lines.cpp:307