Project

General

Profile

SO3Engine
OgreNewt_Tools.cpp
Go to the documentation of this file.
5#include <iostream>
6
7#include <OgreMaterialManager.h>
8#include <OgreCamera.h>
9#include <OgreHardwareBufferManager.h>
10#include <OgreRoot.h>
11#include <OgreShaderGenerator.h>
12
13namespace OgreNewt
14{
15
16 namespace Converters
17 {
18
20 void MatrixToQuatPos(const float* matrix, Ogre::Quaternion& quat, Ogre::Vector3 &pos)
21 {
22 // this takes a matrix returned by Newton, and creates a Quaternion
23 // and position Vector3, which is more meaningful for Ogre.
24 using namespace Ogre;
25 quat = Quaternion(Matrix3(matrix[0], matrix[4], matrix[8],
26 matrix[1], matrix[5], matrix[9],
27 matrix[2], matrix[6], matrix[10]));
28
29 pos = Vector3(matrix[12], matrix[13], matrix[14]);
30 }
31
33 void QuatPosToMatrix(const Ogre::Quaternion& _quat, const Ogre::Vector3 &pos, dFloat* matrix)
34 {
35 // this takes a Quaternion and a Vector3 and creates a float array
36 // which is more meaningful to Newton.
37
38 using namespace Ogre;
39 Matrix3 rot;
40 Vector3 xcol, ycol, zcol;
41
42 Ogre::Quaternion quat(_quat);
43 quat.normalise();
44 quat.ToRotationMatrix(rot); // creates a 3x3 rotation matrix from the Quaternion.
45
46 xcol = rot.GetColumn(0);
47 ycol = rot.GetColumn(1);
48 zcol = rot.GetColumn(2);
49
50 // now fill the final matrix with the appropriate data:
51 matrix[0] = dFloat(xcol.x);
52 matrix[1] = dFloat(xcol.y);
53 matrix[2] = dFloat(xcol.z);
54 matrix[3] = dFloat(0.0);
55
56 matrix[4] = dFloat(ycol.x);
57 matrix[5] = dFloat(ycol.y);
58 matrix[6] = dFloat(ycol.z);
59 matrix[7] = dFloat(0.0);
60
61 matrix[8] = dFloat(zcol.x);
62 matrix[9] = dFloat(zcol.y);
63 matrix[10] = dFloat(zcol.z);
64 matrix[11] = dFloat(0.0);
65
66 matrix[12] = dFloat(pos.x);
67 matrix[13] = dFloat(pos.y);
68 matrix[14] = dFloat(pos.z);
69 matrix[15] = dFloat(1.0);
70 }
71
72 void MatrixToMatrix4(const dFloat* matrix_in, Ogre::Matrix4& matrix_out)
73 {
74 // from Newton to Ogre::Matrix4
75 matrix_out = Ogre::Matrix4(Ogre::Real(matrix_in[0]), Ogre::Real(matrix_in[4]), Ogre::Real(matrix_in[8]), Ogre::Real(matrix_in[12]),
76 Ogre::Real(matrix_in[1]), Ogre::Real(matrix_in[5]), Ogre::Real(matrix_in[9]), Ogre::Real(matrix_in[13]),
77 Ogre::Real(matrix_in[2]), Ogre::Real(matrix_in[6]), Ogre::Real(matrix_in[10]), Ogre::Real(matrix_in[14]),
78 Ogre::Real(matrix_in[3]), Ogre::Real(matrix_in[7]), Ogre::Real(matrix_in[11]), Ogre::Real(matrix_in[15]));
79 }
80
81 void Matrix4ToMatrix(const Ogre::Matrix4& matrix_in, dFloat* matrix_out)
82 {
83 // from Ogre to Newton.
84 matrix_out[0] = matrix_in[0][0];
85 matrix_out[1] = matrix_in[1][0];
86 matrix_out[2] = matrix_in[2][0];
87 matrix_out[3] = matrix_in[3][0];
88
89 matrix_out[4] = matrix_in[0][1];
90 matrix_out[5] = matrix_in[1][1];
91 matrix_out[6] = matrix_in[2][1];
92 matrix_out[7] = matrix_in[3][1];
93
94 matrix_out[8] = matrix_in[0][2];
95 matrix_out[9] = matrix_in[1][2];
96 matrix_out[10] = matrix_in[2][2];
97 matrix_out[11] = matrix_in[3][2];
98
99 matrix_out[12] = matrix_in[0][3];
100 matrix_out[13] = matrix_in[1][3];
101 matrix_out[14] = matrix_in[2][3];
102 matrix_out[15] = matrix_in[3][3];
103 }
104
105 Ogre::Quaternion grammSchmidt(const Ogre::Vector3& pin)
106 {
107 Ogre::Vector3 front, up, right;
108 front = pin;
109
110 front.normalise();
111 if (Ogre::Math::Abs(front.z) > 0.577f)
112 right = front.crossProduct(Ogre::Vector3(-front.y, front.z, 0.0f));
113 else
114 right = front.crossProduct(Ogre::Vector3(-front.y, front.x, 0.0f));
115 right.normalise();
116 up = right.crossProduct(front);
117
118 Ogre::Matrix3 ret;
119 ret.FromAxes(front, up, right);
120
121 Ogre::Quaternion quat;
122 quat.FromRotationMatrix(ret);
123
124 return quat;
125 }
126 } // end namespace "converters"
127
128
129 namespace CollisionTools
130 {
132
133 int CollisionPointDistance(const OgreNewt::World* world, const Ogre::Vector3& globalpt,
134 const OgreNewt::CollisionPtr& col, const Ogre::Quaternion& colorient, const Ogre::Vector3& colpos,
135 Ogre::Vector3& retpt, Ogre::Vector3& retnormal, int threadIndex)
136 {
137 dFloat matrix[16];
138 dVector gPt;
139 dVector fretPt;
140 dVector fretNorm;
141
142 gPt.m_x = dFloat(globalpt.x);
143 gPt.m_y = dFloat(globalpt.y);
144 gPt.m_z = dFloat(globalpt.z);
145
146 Converters::QuatPosToMatrix(colorient, colpos, matrix);
147 int ret = NewtonCollisionPointDistance(world->getNewtonWorld(), &gPt.m_x, col->getNewtonCollision(), matrix, &fretPt.m_x, &fretNorm.m_x, threadIndex);
148
149 retpt.x = Ogre::Real(fretPt.m_x);
150 retpt.y = Ogre::Real(fretPt.m_y);
151 retpt.z = Ogre::Real(fretPt.m_z);
152
153 retnormal.x = Ogre::Real(fretNorm.m_x);
154 retnormal.y = Ogre::Real(fretNorm.m_y);
155 retnormal.z = Ogre::Real(fretNorm.m_z);
156
157 return ret;
158 }
159
160
161
162
163 int CollisionClosestPoint(const OgreNewt::World* world, const OgreNewt::CollisionPtr& colA, const Ogre::Quaternion& colOrientA, const Ogre::Vector3& colPosA,
164 const OgreNewt::CollisionPtr& colB, const Ogre::Quaternion& colOrientB, const Ogre::Vector3& colPosB,
165 Ogre::Vector3& retPosA, Ogre::Vector3& retPosB, Ogre::Vector3& retNorm, int threadIndex)
166 {
167 dFloat matrixA[16];
168 dFloat matrixB[16];
169 dVector fretPosA;
170 dVector fretPosB;
171 dVector fretNorm;
172
173 Converters::QuatPosToMatrix(colOrientA, colPosA, matrixA);
174 Converters::QuatPosToMatrix(colOrientB, colPosB, matrixB);
175
176 int ret = NewtonCollisionClosestPoint(world->getNewtonWorld(), colA->getNewtonCollision(), matrixA, colB->getNewtonCollision(), matrixB, &fretPosA.m_x, &fretPosB.m_x, &fretNorm.m_x, threadIndex);
177 retPosA.x = Ogre::Real(fretPosA.m_x);
178 retPosA.y = Ogre::Real(fretPosA.m_y);
179 retPosA.z = Ogre::Real(fretPosA.m_z);
180
181 retPosB.x = Ogre::Real(fretPosB.m_x);
182 retPosB.y = Ogre::Real(fretPosB.m_y);
183 retPosB.z = Ogre::Real(fretPosB.m_z);
184
185 retNorm.x = Ogre::Real(fretNorm.m_x);
186 retNorm.y = Ogre::Real(fretNorm.m_y);
187 retNorm.z = Ogre::Real(fretNorm.m_z);
188
189 return ret;
190 }
191
192 Ogre::AxisAlignedBox CollisionCalculateFittingAABB(const OgreNewt::CollisionPtr& col, const Ogre::Quaternion& orient, const Ogre::Vector3& pos)
193 {
194 Ogre::Vector3 max, min;
195
196 for (int i = 0; i < 3; i++)
197 {
198 Ogre::Vector3 currentDir, supportVertex;
199
200 currentDir = Ogre::Vector3::ZERO;
201 currentDir[i] = 1;
202 currentDir = orient*currentDir;
203 supportVertex = CollisionSupportVertex(col, currentDir) - pos;
204 max[i] = supportVertex.dotProduct(currentDir);
205
206 currentDir *= -1.0f;
207 supportVertex = CollisionSupportVertex(col, currentDir) - pos;
208 min[i] = -supportVertex.dotProduct(currentDir);
209 }
210
211 return Ogre::AxisAlignedBox(min, max);
212 }
213
214 Ogre::Vector3 CollisionSupportVertex(const OgreNewt::CollisionPtr& col, const Ogre::Vector3& dir)
215 {
216 Ogre::Vector3 ret;
217 dVector fDir;
218 dVector fRet;
219 fDir.m_x = dFloat(dir.x);
220 fDir.m_y = dFloat(dir.y);
221 fDir.m_z = dFloat(dir.z);
222
223 NewtonCollisionSupportVertex(col->getNewtonCollision(), &fDir.m_x, &fRet.m_x);
224
225 ret.x = Ogre::Real(fRet.m_x);
226 ret.y = Ogre::Real(fRet.m_y);
227 ret.z = Ogre::Real(fRet.m_z);
228
229 return ret;
230 }
231
232 } // end namespace "CollisionTools"
233
234 namespace Springs
235 {
236
237 Ogre::Real calculateSpringDamperAcceleration(Ogre::Real deltaTime, Ogre::Real springK,
238 Ogre::Real stretchDistance, Ogre::Real springDamping, Ogre::Real dampVelocity)
239 {
240 return Ogre::Real(NewtonCalculateSpringDamperAcceleration(deltaTime, springK, stretchDistance, springDamping, dampVelocity));
241 }
242 }
243
244
245 namespace OgreAddons
246 {
257 using namespace Ogre;
258
259 const unsigned short POS_TEX_BINDING = 0;
260 const unsigned short COLOUR_BINDING = 1;
261
262 MovableText::MovableText(const String &name, const String &caption, const String &fontName, Real charHeight, const ColourValue &color)
263 : mpCam(NULL)
264 , mpWin(NULL)
265 , mName(name)
266 , mCaption(caption)
267 , mFontName(fontName)
268 , mCharHeight(charHeight)
269 , mColor(color)
270 , mType("MovableText")
271 , mTimeUntilNextToggle(0)
272 , mSpaceWidth(0)
273 , mUpdateColors(true)
274 , mOnTop(false)
275 , mHorizontalAlignment(H_LEFT)
276 , mVerticalAlignment(V_BELOW)
277 , mGlobalTranslation(0.0)
278 , mLocalTranslation(0.0)
279 {
280 if (name == "")
281 throw Exception(Exception::ERR_INVALIDPARAMS, "Trying to create MovableText without name", "MovableText::MovableText");
282
283 if (caption == "")
284 throw Exception(Exception::ERR_INVALIDPARAMS, "Trying to create MovableText without caption", "MovableText::MovableText");
285
286 mRenderOp.vertexData = NULL;
287 this->setFontName(mFontName);
288 this->_setupGeometry();
289 }
290
292 {
293 if (mRenderOp.vertexData)
294 delete mRenderOp.vertexData;
295 // May cause crashing... check this and comment if it does
296 if (mpMaterial)
297 MaterialManager::getSingletonPtr()->remove(mpMaterial->getName());
298 }
299
300 void MovableText::setFontName(const String &fontName)
301 {
302 if ((Ogre::MaterialManager::getSingletonPtr()->resourceExists(mName + "Material")))
303 {
304 Ogre::MaterialManager::getSingleton().remove(mName + "Material");
305 }
306
307 if (mFontName != fontName || !mpMaterial || !mpFont)
308 {
309 mFontName = fontName;
310 mpFont = FontManager::getSingleton().getByName(mFontName);
311 if (!mpFont)
312 {
313 mpFont = Ogre::FontManager::getSingleton().create(mFontName, "SO3/Internal");
314 mpFont->setParameter("type", "truetype");
315 mpFont->setParameter("source", "bluehigh.ttf");
316 mpFont->setParameter("size", "10");
317 mpFont->setParameter("resolution", "128");
318 //throw Exception(Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + fontName, "MovableText::setFontName");
319 }
320 mpFont->load();
321 if (mpMaterial)
322 {
323 MaterialManager::getSingletonPtr()->remove(mpMaterial->getName());
324 mpMaterial.reset();
325 }
326
327 mpMaterial = mpFont->getMaterial()->clone(mName + "Material");
328 mpMaterial->setDepthCheckEnabled(!mOnTop);
329 mpMaterial->setDepthBias(1.0, 1.0);
330 mpMaterial->setDepthWriteEnabled(mOnTop);
331 mpMaterial->setLightingEnabled(false);
332 mpMaterial->setReceiveShadows(false);
333
334 mpMaterial->getTechnique(0)->setSchemeName(Ogre::MSN_DEFAULT);
335 if (!mpMaterial->isLoaded())
336 mpMaterial->load();
337
338 mNeedUpdate = true;
339 }
340 }
341
342 void MovableText::setCaption(const String &caption)
343 {
344 if (caption != mCaption)
345 {
346 mCaption = caption;
347 mNeedUpdate = true;
348 }
349 }
350
351 void MovableText::setColor(const ColourValue &color)
352 {
353 if (color != mColor)
354 {
355 mColor = color;
356 mUpdateColors = true;
357 }
358 }
359
361 {
362 if (height != mCharHeight)
363 {
364 mCharHeight = height;
365 mNeedUpdate = true;
366 }
367 }
368
370 {
371 if (width != mSpaceWidth)
372 {
373 mSpaceWidth = width;
374 mNeedUpdate = true;
375 }
376 }
377
378 void MovableText::setTextAlignment(const HorizontalAlignment& horizontalAlignment, const VerticalAlignment& verticalAlignment)
379 {
380 if (mHorizontalAlignment != horizontalAlignment)
381 {
382 mHorizontalAlignment = horizontalAlignment;
383 mNeedUpdate = true;
384 }
385 if (mVerticalAlignment != verticalAlignment)
386 {
387 mVerticalAlignment = verticalAlignment;
388 mNeedUpdate = true;
389 }
390 }
391
393 {
394 mGlobalTranslation = trans;
395 }
396
398 {
399 mLocalTranslation = trans;
400 }
401
403 {
404 if (mOnTop != show && mpMaterial)
405 {
406 mOnTop = show;
407 mpMaterial->setDepthBias(1.0, 1.0);
408 mpMaterial->setDepthCheckEnabled(!mOnTop);
409 mpMaterial->setDepthWriteEnabled(mOnTop);
410 }
411 }
412
414 {
415 assert(mpFont);
416 assert(mpMaterial);
417
418 unsigned int vertexCount = static_cast<unsigned int>(mCaption.size() * 6);
419
420 if (mRenderOp.vertexData)
421 {
422 // Removed this test as it causes problems when replacing a caption
423 // of the same size: replacing "Hello" with "hello"
424 // as well as when changing the text alignment
425 //if (mRenderOp.vertexData->vertexCount != vertexCount)
426 {
427 delete mRenderOp.vertexData;
428 mRenderOp.vertexData = NULL;
429 mUpdateColors = true;
430 }
431 }
432
433 if (!mRenderOp.vertexData)
434 mRenderOp.vertexData = new VertexData();
435
436 mRenderOp.indexData = 0;
437 mRenderOp.vertexData->vertexStart = 0;
438 mRenderOp.vertexData->vertexCount = vertexCount;
439 mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
440 mRenderOp.useIndexes = false;
441
442 VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
443 VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding;
444 size_t offset = 0;
445
446 // create/bind positions/tex.ccord. buffer
447 if (!decl->findElementBySemantic(Ogre::VES_POSITION))
448 decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
449
450 offset += VertexElement::getTypeSize(Ogre::VET_FLOAT3);
451
452 if (!decl->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES))
453 decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
454
455 offset += VertexElement::getTypeSize(Ogre::VET_FLOAT2);
456
457 HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING),
458 mRenderOp.vertexData->vertexCount,
459 HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
460 bind->setBinding(POS_TEX_BINDING, ptbuf);
461
462 // Colours - store these in a separate buffer because they change less often
463 if (!decl->findElementBySemantic(VES_DIFFUSE))
464 decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);
465
466 HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING),
467 mRenderOp.vertexData->vertexCount,
468 HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
469 bind->setBinding(COLOUR_BINDING, cbuf);
470
471 size_t charlen = mCaption.size();
472 float *pPCBuff = static_cast<float*>(ptbuf->lock(HardwareBuffer::HBL_DISCARD));
473
474 float largestWidth = 0;
475 float left = 0 * 2.0 - 0.1;
476 float top = -((0 * 2.0) - 0.1);
477
478 Real spaceWidth = mSpaceWidth;
479 // Derive space width from a capital A
480 if (spaceWidth == 0)
481 spaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0f;
482
483 // for calculation of AABB
484 Ogre::Vector3 min, max, currPos;
485 Ogre::Real maxSquaredRadius;
486 bool first = true;
487
488#define GetMax(x,y) x>y ? x : y
489
490 // Use iterator
491 String::iterator i, iend;
492 iend = mCaption.end();
493 bool newLine = true;
494 Real len = 0.0f;
495
496 Real verticalOffset = 0;
497 switch (mVerticalAlignment)
498 {
500 verticalOffset = mCharHeight;
501 break;
503 verticalOffset = 0.5f * mCharHeight;
504 break;
506 verticalOffset = 0.0f;
507 break;
508 }
509 // Raise the first line of the caption
510 top += verticalOffset;
511 for (i = mCaption.begin(); i != iend; ++i)
512 {
513 if (*i == '\n')
514 top += verticalOffset * 2.0f;
515 }
516
517 for (i = mCaption.begin(); i != iend; ++i)
518 {
519 if (newLine)
520 {
521 len = 0.0f;
522 for (String::iterator j = i; j != iend && *j != '\n'; j++)
523 {
524 if (*j == ' ')
525 len += spaceWidth;
526 else
527 len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0f;
528 }
529 newLine = false;
530 }
531
532 if (*i == '\n')
533 {
534 left = 0 * 2.0f - 0.1f;
535 top -= mCharHeight * 2.0f;
536 newLine = true;
537 continue;
538 }
539
540 if (*i == ' ')
541 {
542 // Just leave a gap, no tris
543 left += spaceWidth;
544 // Also reduce tri count
545 mRenderOp.vertexData->vertexCount -= 6;
546 continue;
547 }
548
549 Real horiz_height = mpFont->getGlyphAspectRatio(*i);
550 Real u1, u2, v1, v2;
551 Ogre::Font::UVRect utmp;
552 utmp = mpFont->getGlyphTexCoords(*i);
553 u1 = utmp.left;
554 u2 = utmp.right;
555 v1 = utmp.top;
556 v2 = utmp.bottom;
557
558 // each vert is (x, y, z, u, v)
559 //-------------------------------------------------------------------------------------
560 // First tri
561 //
562 // Upper left
564 *pPCBuff++ = left;
565 else
566 *pPCBuff++ = left - (len / 2);
567 *pPCBuff++ = top;
568 *pPCBuff++ = -0.1;
569 *pPCBuff++ = u1;
570 *pPCBuff++ = v1;
571
572 // Deal with bounds
574 currPos = Ogre::Vector3(left, top, -0.1);
575 else
576 currPos = Ogre::Vector3(left - (len / 2), top, -0.1);
577 if (first)
578 {
579 min = max = currPos;
580 maxSquaredRadius = currPos.squaredLength();
581 first = false;
582 }
583 else
584 {
585 min.makeFloor(currPos);
586 max.makeCeil(currPos);
587 maxSquaredRadius = GetMax(maxSquaredRadius, currPos.squaredLength());
588 }
589
590 top -= mCharHeight * 2.0f;
591
592 // Bottom left
594 *pPCBuff++ = left;
595 else
596 *pPCBuff++ = left - (len / 2);
597 *pPCBuff++ = top;
598 *pPCBuff++ = -0.1;
599 *pPCBuff++ = u1;
600 *pPCBuff++ = v2;
601
602 // Deal with bounds
604 currPos = Ogre::Vector3(left, top, -0.1f);
605 else
606 currPos = Ogre::Vector3(left - (len / 2.0f), top, -0.1f);
607 min.makeFloor(currPos);
608 max.makeCeil(currPos);
609 maxSquaredRadius = GetMax(maxSquaredRadius, currPos.squaredLength());
610
611 top += mCharHeight * 2.0f;
612 left += horiz_height * mCharHeight * 2.0f;
613
614 // Top right
616 *pPCBuff++ = left;
617 else
618 *pPCBuff++ = left - (len / 2.0f);
619 *pPCBuff++ = top;
620 *pPCBuff++ = -0.1;
621 *pPCBuff++ = u2;
622 *pPCBuff++ = v1;
623 //-------------------------------------------------------------------------------------
624
625 // Deal with bounds
627 currPos = Ogre::Vector3(left, top, -0.1f);
628 else
629 currPos = Ogre::Vector3(left - (len / 2.0f), top, -0.1f);
630 min.makeFloor(currPos);
631 max.makeCeil(currPos);
632 maxSquaredRadius = GetMax(maxSquaredRadius, currPos.squaredLength());
633
634 //-------------------------------------------------------------------------------------
635 // Second tri
636 //
637 // Top right (again)
639 *pPCBuff++ = left;
640 else
641 *pPCBuff++ = left - (len / 2.0f);
642 *pPCBuff++ = top;
643 *pPCBuff++ = -0.1f;
644 *pPCBuff++ = u2;
645 *pPCBuff++ = v1;
646
647 currPos = Ogre::Vector3(left, top, -0.1f);
648 min.makeFloor(currPos);
649 max.makeCeil(currPos);
650 maxSquaredRadius = GetMax(maxSquaredRadius, currPos.squaredLength());
651
652 top -= mCharHeight * 2.0f;
653 left -= horiz_height * mCharHeight * 2.0f;
654
655 // Bottom left (again)
657 *pPCBuff++ = left;
658 else
659 *pPCBuff++ = left - (len / 2.0f);
660 *pPCBuff++ = top;
661 *pPCBuff++ = -0.1f;
662 *pPCBuff++ = u1;
663 *pPCBuff++ = v2;
664
665 currPos = Ogre::Vector3(left, top, -0.1f);
666 min.makeFloor(currPos);
667 max.makeCeil(currPos);
668 maxSquaredRadius = GetMax(maxSquaredRadius, currPos.squaredLength());
669
670 left += horiz_height * mCharHeight * 2.0f;
671
672 // Bottom right
674 *pPCBuff++ = left;
675 else
676 *pPCBuff++ = left - (len / 2.0f);
677 *pPCBuff++ = top;
678 *pPCBuff++ = -0.1f;
679 *pPCBuff++ = u2;
680 *pPCBuff++ = v2;
681 //-------------------------------------------------------------------------------------
682
683 currPos = Ogre::Vector3(left, top, -0.1f);
684 min.makeFloor(currPos);
685 max.makeCeil(currPos);
686 maxSquaredRadius = GetMax(maxSquaredRadius, currPos.squaredLength());
687
688 // Go back up with top
689 top += mCharHeight * 2.0f;
690
691 float currentWidth = (left + 0.1f) / 2.0f;
692 if (currentWidth > largestWidth)
693 largestWidth = currentWidth;
694 }
695
696 // Unlock vertex buffer
697 ptbuf->unlock();
698
699 // update AABB/Sphere radius
700 mAABB = Ogre::AxisAlignedBox(min, max);
701 mRadius = Ogre::Math::Sqrt(maxSquaredRadius);
702
703 if (mUpdateColors)
704 this->_updateColors();
705
706 mNeedUpdate = false;
707 }
708
710 {
711 assert(mpFont);
712 assert(mpMaterial);
713
714 // Convert to system-specific
715 RGBA color;
716 Root::getSingleton().convertColourValue(mColor, &color);
717 HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING);
718 if (!vbuf)
719 return;
720
721 RGBA *pDest = static_cast<RGBA*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
722 for (int i = 0; i < (int)mRenderOp.vertexData->vertexCount; ++i)
723 *pDest++ = color;
724 vbuf->unlock();
725
726 mUpdateColors = false;
727 }
728
729 const Quaternion& MovableText::getWorldOrientation(void) const
730 {
731 assert(mpCam);
732 return const_cast<Quaternion&>(mpCam->getDerivedOrientation());
733 }
734
735 const Vector3& MovableText::getWorldPosition(void) const
736 {
737 assert(mParentNode);
738 return mParentNode->_getDerivedPosition();
739 }
740
741 void MovableText::getWorldTransforms(Matrix4 *xform) const
742 {
743 if (this->isVisible() && mpCam)
744 {
745 Matrix3 rot3x3, scale3x3 = Matrix3::IDENTITY;
746
747 // store rotation in a matrix
748 mpCam->getDerivedOrientation().ToRotationMatrix(rot3x3);
749
750 // parent node position
751 Vector3 ppos = mParentNode->_getDerivedPosition() + Vector3::UNIT_Y*mGlobalTranslation;
752 ppos += rot3x3*mLocalTranslation;
753
754 // apply scale
755 scale3x3[0][0] = mParentNode->_getDerivedScale().x / 2;
756 scale3x3[1][1] = mParentNode->_getDerivedScale().y / 2;
757 scale3x3[2][2] = mParentNode->_getDerivedScale().z / 2;
758
759 // apply all transforms to xform
760 *xform = (rot3x3 * scale3x3);
761 xform->setTrans(ppos);
762 }
763 }
764
765 void MovableText::getRenderOperation(RenderOperation &op)
766 {
767 if (this->isVisible())
768 {
769 if (mNeedUpdate)
770 this->_setupGeometry();
771 if (mUpdateColors)
772 this->_updateColors();
773 op = mRenderOp;
774 }
775 }
776
778 {
779 mpCam = cam;
780 }
781
782 void MovableText::_updateRenderQueue(RenderQueue* queue)
783 {
784 if (this->isVisible())
785 {
786 if (mNeedUpdate)
787 this->_setupGeometry();
788 if (mUpdateColors)
789 this->_updateColors();
790
791 queue->addRenderable(this, mRenderQueueID, OGRE_RENDERABLE_DEFAULT_PRIORITY);
792 //queue->addRenderable(this, mRenderQueueID, RENDER_QUEUE_SKIES_LATE);
793 }
794 }
795
796 void MovableText::visitRenderables(Renderable::Visitor* visitor, bool debugRenderables)
797 {
798 visitor->visit(this, 0, debugRenderables);
799 }
800 }
801}
802
represents a shape for collision detection
NewtonCollision *const getNewtonCollision() const
retrieve the Newton pointer
MovableText(const Ogre::String &name, const Ogre::String &caption, const Ogre::String &fontName, Ogre::Real charHeight, const Ogre::ColourValue &color=Ogre::ColourValue::White)
const Ogre::Vector3 & getWorldPosition(void) const
void getRenderOperation(Ogre::RenderOperation &op)
void setColor(const Ogre::ColourValue &color)
HorizontalAlignment mHorizontalAlignment
void setGlobalTranslation(Ogre::Vector3 trans)
void _updateRenderQueue(Ogre::RenderQueue *queue)
void setCaption(const Ogre::String &caption)
void setSpaceWidth(Ogre::Real width)
const Ogre::Quaternion & getWorldOrientation(void) const
void _notifyCurrentCamera(Ogre::Camera *cam)
void setLocalTranslation(Ogre::Vector3 trans)
void visitRenderables(Ogre::Renderable::Visitor *visitor, bool debugRenderables=false)
void setTextAlignment(const HorizontalAlignment &horizontalAlignment, const VerticalAlignment &verticalAlignment)
void setFontName(const Ogre::String &fontName)
void getWorldTransforms(Ogre::Matrix4 *xform) const
void setCharacterHeight(Ogre::Real height)
represents a physics world.
NewtonWorld * getNewtonWorld() const
retrieves a pointer to the NewtonWorld
_OgreNewtExport Ogre::Vector3 CollisionSupportVertex(const OgreNewt::CollisionPtr &col, const Ogre::Vector3 &dir)
Get a vertex of the collision in the given direction.
_OgreNewtExport Ogre::AxisAlignedBox CollisionCalculateFittingAABB(const OgreNewt::CollisionPtr &col, const Ogre::Quaternion &orient=Ogre::Quaternion::IDENTITY, const Ogre::Vector3 &pos=Ogre::Vector3::ZERO)
calculate the AABB of a collision primitive in an arbitrary orientation
_OgreNewtExport int CollisionClosestPoint(const OgreNewt::World *world, const OgreNewt::CollisionPtr &colA, const Ogre::Quaternion &colOrientA, const Ogre::Vector3 &colPosA, const OgreNewt::CollisionPtr &colB, const Ogre::Quaternion &colOrientB, const Ogre::Vector3 &colPosB, Ogre::Vector3 &retPosA, Ogre::Vector3 &retPosB, Ogre::Vector3 &retNorm, int threadIndex)
find the nearest 2 points between 2 collision shapes.
_OgreNewtExport int CollisionPointDistance(const OgreNewt::World *world, const Ogre::Vector3 &globalpt, const OgreNewt::CollisionPtr &col, const Ogre::Quaternion &colorient, const Ogre::Vector3 &colpos, Ogre::Vector3 &retpt, Ogre::Vector3 &retnormal, int threadIndex)
find the point on a collision primitive closest to a global point.
_OgreNewtExport void MatrixToMatrix4(const dFloat *matrix_in, Ogre::Matrix4 &matrix_out)
Take a Newton matrix and make it into an Ogre::Matrix4.
_OgreNewtExport void MatrixToQuatPos(const dFloat *matrix, Ogre::Quaternion &quat, Ogre::Vector3 &pos)
Take a Newton matrix and create a Quaternion + Position_vector.
_OgreNewtExport Ogre::Quaternion grammSchmidt(const Ogre::Vector3 &pin)
_OgreNewtExport void Matrix4ToMatrix(const Ogre::Matrix4 &matrix_in, dFloat *matrix_out)
Take an Ogre::Matrix4 and make it into a Newton-happy matrix.
_OgreNewtExport void QuatPosToMatrix(const Ogre::Quaternion &quat, const Ogre::Vector3 &pos, dFloat *matrix)
Take a Quaternion and Position Matrix and create a Newton-happy float matrix!
const unsigned short POS_TEX_BINDING
const unsigned short COLOUR_BINDING
_OgreNewtExport Ogre::Real calculateSpringDamperAcceleration(Ogre::Real deltaTime, Ogre::Real spingK, Ogre::Real stretchDistance, Ogre::Real springDamping, Ogre::Real dampVelocity)