1
// Copyright (C) 2002-2011 Nikolaus Gebhardt
2
// This file is part of the "Irrlicht Engine".
3
// For conditions of distribution and use, see copyright notice in irrlicht.h
5
#include "CTextSceneNode.h"
6
#include "ISceneManager.h"
7
#include "IVideoDriver.h"
8
#include "ICameraSceneNode.h"
9
#include "IGUISpriteBank.h"
10
#include "SMeshBuffer.h"
21
CTextSceneNode::CTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
22
gui::IGUIFont* font, scene::ISceneCollisionManager* coll,
23
const core::vector3df& position, const wchar_t* text,
25
: ITextSceneNode(parent, mgr, id, position), Text(text), Color(color),
26
Font(font), Coll(coll)
30
setDebugName("CTextSceneNode");
36
setAutomaticCulling(scene::EAC_OFF);
40
CTextSceneNode::~CTextSceneNode()
46
void CTextSceneNode::OnRegisterSceneNode()
49
SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT);
51
ISceneNode::OnRegisterSceneNode();
55
void CTextSceneNode::render()
60
core::position2d<s32> pos = Coll->getScreenCoordinatesFrom3DPosition(getAbsolutePosition(),
61
SceneManager->getActiveCamera());
63
core::rect<s32> r(pos, core::dimension2d<s32>(1,1));
64
Font->draw(Text.c_str(), r, Color, true, true);
68
//! returns the axis aligned bounding box of this node
69
const core::aabbox3d<f32>& CTextSceneNode::getBoundingBox() const
74
//! sets the text string
75
void CTextSceneNode::setText(const wchar_t* text)
81
//! sets the color of the text
82
void CTextSceneNode::setTextColor(video::SColor color)
88
//!--------------------------------- CBillboardTextSceneNode ----------------------------------------------
92
CBillboardTextSceneNode::CBillboardTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
93
gui::IGUIFont* font,const wchar_t* text,
94
const core::vector3df& position, const core::dimension2d<f32>& size,
95
video::SColor colorTop,video::SColor shade_bottom )
96
: IBillboardTextSceneNode(parent, mgr, id, position),
97
Font(0), ColorTop(colorTop), ColorBottom(shade_bottom), Mesh(0)
100
setDebugName("CBillboardTextSceneNode");
103
Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
104
Material.MaterialTypeParam = 1.f / 255.f;
105
Material.BackfaceCulling = false;
106
Material.Lighting = false;
107
Material.ZBuffer = video::ECFN_LESSEQUAL;
108
Material.ZWriteEnable = false;
112
// doesn't support other font types
113
if (font->getType() == gui::EGFT_BITMAP)
115
Font = (gui::IGUIFontBitmap*)font;
118
// mesh with one buffer per texture
120
for (u32 i=0; i<Font->getSpriteBank()->getTextureCount(); ++i)
122
SMeshBuffer *mb = new SMeshBuffer();
123
mb->Material = Material;
124
mb->Material.setTexture(0, Font->getSpriteBank()->getTexture(i));
125
Mesh->addMeshBuffer(mb);
131
os::Printer::log("Sorry, CBillboardTextSceneNode does not support this font type", ELL_INFORMATION);
138
setAutomaticCulling ( scene::EAC_BOX );
143
CBillboardTextSceneNode::~CBillboardTextSceneNode()
154
//! sets the text string
155
void CBillboardTextSceneNode::setText(const wchar_t* text)
165
for (u32 j=0; j < Mesh->getMeshBufferCount(); ++j)
167
((SMeshBuffer*)Mesh->getMeshBuffer(j))->Indices.clear();
168
((SMeshBuffer*)Mesh->getMeshBuffer(j))->Vertices.clear();
174
const core::array< core::rect<s32> > &sourceRects = Font->getSpriteBank()->getPositions();
175
const core::array< gui::SGUISprite > &sprites = Font->getSpriteBank()->getSprites();
181
for ( i = 0; i != Text.size (); ++i )
185
u32 spriteno = Font->getSpriteNoFromChar( &text[i] );
186
u32 rectno = sprites[spriteno].Frames[0].rectNumber;
187
u32 texno = sprites[spriteno].Frames[0].textureNumber;
189
dim[0] = core::reciprocal ( (f32) Font->getSpriteBank()->getTexture(texno)->getSize().Width );
190
dim[1] = core::reciprocal ( (f32) Font->getSpriteBank()->getTexture(texno)->getSize().Height );
192
const core::rect<s32>& s = sourceRects[rectno];
194
// add space for letter to buffer
195
SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(texno);
196
u32 firstInd = buf->Indices.size();
197
u32 firstVert = buf->Vertices.size();
198
buf->Indices.set_used(firstInd + 6);
199
buf->Vertices.set_used(firstVert + 4);
201
tex[0] = (s.LowerRightCorner.X * dim[0]) + 0.5f*dim[0]; // half pixel
202
tex[1] = (s.LowerRightCorner.Y * dim[1]) + 0.5f*dim[1];
203
tex[2] = (s.UpperLeftCorner.Y * dim[1]) - 0.5f*dim[1];
204
tex[3] = (s.UpperLeftCorner.X * dim[0]) - 0.5f*dim[0];
206
buf->Vertices[firstVert+0].TCoords.set(tex[0], tex[1]);
207
buf->Vertices[firstVert+1].TCoords.set(tex[0], tex[2]);
208
buf->Vertices[firstVert+2].TCoords.set(tex[3], tex[2]);
209
buf->Vertices[firstVert+3].TCoords.set(tex[3], tex[1]);
211
buf->Vertices[firstVert+0].Color = ColorBottom;
212
buf->Vertices[firstVert+3].Color = ColorBottom;
213
buf->Vertices[firstVert+1].Color = ColorTop;
214
buf->Vertices[firstVert+2].Color = ColorTop;
216
buf->Indices[firstInd+0] = (u16)firstVert+0;
217
buf->Indices[firstInd+1] = (u16)firstVert+2;
218
buf->Indices[firstInd+2] = (u16)firstVert+1;
219
buf->Indices[firstInd+3] = (u16)firstVert+0;
220
buf->Indices[firstInd+4] = (u16)firstVert+3;
221
buf->Indices[firstInd+5] = (u16)firstVert+2;
227
info.Width = (f32)s.getWidth();
229
info.Kerning = (f32)Font->getKerningWidth(&Text[i], tp);
230
info.firstInd = firstInd;
231
info.firstVert = firstVert;
233
Symbol.push_back(info);
239
void CBillboardTextSceneNode::OnAnimate(u32 timeMs)
241
if (!IsVisible || !Font || !Mesh)
244
ICameraSceneNode* camera = SceneManager->getActiveCamera();
249
f32 textLength = 0.f;
251
for(i=0; i!=Symbol.size(); ++i)
253
SSymbolInfo &info = Symbol[i];
254
textLength += info.Kerning + info.Width;
259
//const core::matrix4 &m = camera->getViewFrustum()->Matrices[ video::ETS_VIEW ];
261
// make billboard look to camera
262
core::vector3df pos = getAbsolutePosition();
264
core::vector3df campos = camera->getAbsolutePosition();
265
core::vector3df target = camera->getTarget();
266
core::vector3df up = camera->getUpVector();
267
core::vector3df view = target - campos;
270
core::vector3df horizontal = up.crossProduct(view);
271
if ( horizontal.getLength() == 0 )
273
horizontal.set(up.Y,up.X,up.Z);
276
horizontal.normalize();
277
core::vector3df space = horizontal;
279
horizontal *= 0.5f * Size.Width;
281
core::vector3df vertical = horizontal.crossProduct(view);
282
vertical.normalize();
283
vertical *= 0.5f * Size.Height;
288
pos += space * (Size.Width * -0.5f);
290
for ( i = 0; i!= Symbol.size(); ++i )
292
SSymbolInfo &info = Symbol[i];
293
f32 infw = info.Width / textLength;
294
f32 infk = info.Kerning / textLength;
295
f32 w = (Size.Width * infw * 0.5f);
298
SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(info.bufNo);
300
buf->Vertices[info.firstVert+0].Normal = view;
301
buf->Vertices[info.firstVert+1].Normal = view;
302
buf->Vertices[info.firstVert+2].Normal = view;
303
buf->Vertices[info.firstVert+3].Normal = view;
305
buf->Vertices[info.firstVert+0].Pos = pos + (space * w) + vertical;
306
buf->Vertices[info.firstVert+1].Pos = pos + (space * w) - vertical;
307
buf->Vertices[info.firstVert+2].Pos = pos - (space * w) - vertical;
308
buf->Vertices[info.firstVert+3].Pos = pos - (space * w) + vertical;
310
pos += space * (Size.Width*infk + w);
315
for (i=0; i< Mesh->getMeshBufferCount() ; ++i)
316
Mesh->getMeshBuffer(i)->recalculateBoundingBox();
317
Mesh->recalculateBoundingBox();
319
BBox = Mesh->getBoundingBox();
320
core::matrix4 mat( getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE );
321
mat.transformBoxEx(BBox);
324
void CBillboardTextSceneNode::OnRegisterSceneNode()
326
SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT);
327
ISceneNode::OnRegisterSceneNode();
332
void CBillboardTextSceneNode::render()
337
video::IVideoDriver* driver = SceneManager->getVideoDriver();
341
driver->setTransform(video::ETS_WORLD, mat);
343
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
345
driver->setMaterial(Mesh->getMeshBuffer(i)->getMaterial());
346
driver->drawMeshBuffer(Mesh->getMeshBuffer(i));
349
if ( DebugDataVisible & scene::EDS_BBOX )
351
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
354
driver->setMaterial(m);
355
driver->draw3DBox(BBox, video::SColor(0,208,195,152));
360
//! returns the axis aligned bounding box of this node
361
const core::aabbox3d<f32>& CBillboardTextSceneNode::getBoundingBox() const
367
//! sets the size of the billboard
368
void CBillboardTextSceneNode::setSize(const core::dimension2d<f32>& size)
372
if (Size.Width == 0.0f)
375
if (Size.Height == 0.0f )
378
//f32 avg = (size.Width + size.Height)/6;
379
//BBox.MinEdge.set(-avg,-avg,-avg);
380
//BBox.MaxEdge.set(avg,avg,avg);
384
video::SMaterial& CBillboardTextSceneNode::getMaterial(u32 i)
386
if (Mesh && Mesh->getMeshBufferCount() > i )
387
return Mesh->getMeshBuffer(i)->getMaterial();
393
//! returns amount of materials used by this scene node.
394
u32 CBillboardTextSceneNode::getMaterialCount() const
397
return Mesh->getMeshBufferCount();
403
//! gets the size of the billboard
404
const core::dimension2d<f32>& CBillboardTextSceneNode::getSize() const
410
//! sets the color of the text
411
void CBillboardTextSceneNode::setTextColor(video::SColor color)
416
//! Set the color of all vertices of the billboard
417
//! \param overallColor: the color to set
418
void CBillboardTextSceneNode::setColor(const video::SColor & overallColor)
423
for ( u32 i = 0; i != Text.size (); ++i )
425
const SSymbolInfo &info = Symbol[i];
426
SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(info.bufNo);
427
buf->Vertices[info.firstVert+0].Color = overallColor;
428
buf->Vertices[info.firstVert+1].Color = overallColor;
429
buf->Vertices[info.firstVert+2].Color = overallColor;
430
buf->Vertices[info.firstVert+3].Color = overallColor;
435
//! Set the color of the top and bottom vertices of the billboard
436
//! \param topColor: the color to set the top vertices
437
//! \param bottomColor: the color to set the bottom vertices
438
void CBillboardTextSceneNode::setColor(const video::SColor & topColor, const video::SColor & bottomColor)
443
ColorBottom = bottomColor;
445
for ( u32 i = 0; i != Text.size (); ++i )
447
const SSymbolInfo &info = Symbol[i];
448
SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(info.bufNo);
449
buf->Vertices[info.firstVert+0].Color = ColorBottom;
450
buf->Vertices[info.firstVert+3].Color = ColorBottom;
451
buf->Vertices[info.firstVert+1].Color = ColorTop;
452
buf->Vertices[info.firstVert+2].Color = ColorTop;
457
//! Gets the color of the top and bottom vertices of the billboard
458
//! \param topColor: stores the color of the top vertices
459
//! \param bottomColor: stores the color of the bottom vertices
460
void CBillboardTextSceneNode::getColor(video::SColor & topColor, video::SColor & bottomColor) const
463
bottomColor = ColorBottom;
467
} // end namespace scene
468
} // end namespace irr