labels.patch

tdev, 08/06/2010 09:13 am

Download (53.1 kB)

Beam.cpp (working copy)
42 42
#include "FlexMeshWheel.h"
43 43
#include "FlexObj.h"
44 44
#include "FlexAirfoil.h"
45
#include "MovableText.h"
46 45
#include "turboprop.h"
47 46
#include "turbojet.h"
48 47
#include "screwprop.h"
......
56 55
#include "PositionStorage.h"
57 56
#include "network.h"
58 57
#include "PointColDetector.h"
58
#include "PlayerColours.h"
59 59
#ifdef FEAT_TIMING
60 60
#include "BeamStats.h"
61 61
#endif
......
66 66
#include "ScriptEngine.h"
67 67
#endif
68 68

  
69
#ifdef USE_MYGUI
70
#include "gui_3dlabels.h"
71
#endif // USE_MYGUI
72

  
69 73
#include "rornet.h"
70 74
#include "MeshObject.h"
71 75

  
......
295 299
		delete (*it);
296 300
	}
297 301

  
298
	if(netMT)
302
	if(netLabel)
299 303
	{
300
		netMT->setVisible(false);
301
		delete netMT;
302
		netMT = 0;
304
		netLabel->setVisible(false);
305
		GUI_3DLabelManager::getSingleton().remove3DLabel(netLabel);
306
		netLabel = 0;
303 307
	}
304 308

  
305 309
}
......
341 345
	free_soundsource=0;
342 346
	nodedebugstate=-1;
343 347
	debugVisuals=0;
344
	netMT = 0;
348
	netLabel = 0;
345 349
	beam_creak=BEAM_CREAK_DEFAULT;
346 350
	dynamicMapMode=0;
347 351
	meshesVisible=true;
......
365 369
	reset_requested=0;
366 370
	mrtime=0.0;
367 371
	free_flexbody=0;
368
	netLabelNode=0;
369 372
	free_rigidifier=0;
370 373
	autopilot=0;
371 374
	free_rotator=0;
......
452 455
	hfinder=mfinder;
453 456
	mWindow=win;
454 457
	beamsRoot=parent->createChildSceneNode();
455
	deletion_sceneNodes.push_back(netLabelNode);
456 458

  
457 459
	parentNode=parent;
458 460
	//			float gears[]={6.0, 3.0, 1.5, 1.0, 0.75};
......
8069 8071
							//sparks
8070 8072
							if (!nodes[i].iswheel && ns>1.0 && !nodes[i].disable_particles)
8071 8073
							{
8072
								// friction < 10 will remove the 'f' nodes from the spark generation nodes
8073 8074
								if(sparksp) sparksp->allocSparks(nodes[i].AbsPosition, nodes[i].Velocity);
8074 8075
							}
8075 8076
						} else if (gm->fx_type==FX_CLUMPY)
......
10111 10112
	}
10112 10113
	//Flex body
10113 10114
	for (i=0; i<free_flexbody; i++) flexbodies[i]->flexit();
10114

  
10115
	if (netLabelNode && netMT && netMT->isVisible())
10116
	{
10117
		// this ensures that the nickname is always in a readable size
10118
		netLabelNode->setPosition(position+Vector3(0, (maxy-miny), 0));
10119
		Vector3 vdir=(position)-mCamera->getPosition();
10120
		float vlen=vdir.length();
10121
		float h = vlen/30.0;
10122
		if(h<0.6)
10123
			h=0.6;
10124
		netMT->setCharacterHeight(h);
10125
		if(vlen>1000)
10126
			netMT->setCaption(networkUsername + "  (" + StringConverter::toString( (float)(ceil(vlen/100)/10.0) )+ " km)");
10127
		else if (vlen>20 && vlen <= 1000)
10128
			netMT->setCaption(networkUsername + "  (" + StringConverter::toString((int)vlen)+ " m)");
10129
		else
10130
			netMT->setCaption(networkUsername);
10131

  
10132
		//netMT->setAdditionalHeight((maxy-miny)+h+0.1);
10133
		netMT->setVisible(true);
10134
	}
10135 10115
}
10136 10116

  
10137 10117

  
......
10156 10136

  
10157 10137
}
10158 10138

  
10159
void Beam::preMapLabelRenderUpdate(bool mode, float charheight)
10160
{
10161
	static float orgcharheight=0;
10162
	if(mode && netLabelNode)
10163
	{
10164
		netMT->showOnTop(true);
10165
		orgcharheight = netMT->getCharacterHeight();
10166
		netMT->setCharacterHeight(charheight);
10167
		//netMT->setAdditionalHeight(0);
10168
		netMT->setVisible(false);
10169
	} else if(!mode && netLabelNode)
10170
	{
10171
		netMT->showOnTop(false);
10172
		netMT->setCharacterHeight(orgcharheight);
10173
		netMT->setVisible(true);
10174
	}
10175
}
10176

  
10177 10139
void Beam::showSkeleton(bool meshes, bool newMode)
10178 10140
{
10179 10141
	if(lockSkeletonchange)
......
10852 10814
				sprintf(entName, "%s-nodesDebug-%d-Ent", truckname, i);
10853 10815
				Entity *b = tsm->createEntity(entName, "beam.mesh");
10854 10816
				t.id=i;
10855
				t.txt = new MovableText(nodeName, "n"+StringConverter::toString(i));
10856
				t.txt->setFontName("highcontrast_black");
10857
				t.txt->setTextAlignment(MovableText::H_LEFT, MovableText::V_BELOW);
10858
				//t.txt->setAdditionalHeight(0);
10859
				t.txt->showOnTop(true);
10860
				t.txt->setCharacterHeight(0.5);
10861
				t.txt->setColor(ColourValue::White);
10817
				t.label = GUI_3DLabelManager::getSingleton().new3DLabel(b, "n"+StringConverter::toString(i), ColourValue::White);
10862 10818

  
10863 10819
				t.node = tsm->getRootSceneNode()->createChildSceneNode();
10864
				t.node->attachObject(t.txt);
10865 10820
				t.node->attachObject(b);
10866 10821
				t.node->setScale(Vector3(0.05,0.05,0.05));
10867 10822

  
......
10874 10829
			for(int i=0; i<free_beam; i++)
10875 10830
			{
10876 10831
				debugtext_t t;
10877
				char nodeName[255]="";
10832
				char nodeName[255]="", entName[255]="";
10878 10833
				sprintf(nodeName, "%s-beamsDebug-%d", truckname, i);
10834
				sprintf(entName, "%s-nodesDebug-%d-Ent", truckname, i);
10879 10835
				t.id=i;
10880
				t.txt = new MovableText(nodeName, "b"+StringConverter::toString(i));
10881
				t.txt->setFontName("highcontrast_black");
10882
				t.txt->setTextAlignment(MovableText::H_LEFT, MovableText::V_BELOW);
10883
				//t.txt->setAdditionalHeight(0);
10884
				t.txt->showOnTop(true);
10885
				t.txt->setCharacterHeight(1);
10886
				t.txt->setColor(ColourValue::White);
10836
				Entity *b = tsm->createEntity(entName, "beam.mesh");
10837
				t.label = GUI_3DLabelManager::getSingleton().new3DLabel(b, "b"+StringConverter::toString(i), ColourValue::White);
10887 10838

  
10888 10839
				t.node = tsm->getRootSceneNode()->createChildSceneNode();
10889
				t.node->attachObject(t.txt);
10840
				t.node->attachObject(b);
10890 10841

  
10891 10842
				Vector3 pos = beams[i].p1->smoothpos - (beams[i].p1->smoothpos - beams[i].p2->smoothpos)/2;
10892 10843
				t.node->setPosition(pos);
......
10923 10874
		for(std::vector<debugtext_t>::iterator it=nodes_debug.begin(); it!=nodes_debug.end();it++)
10924 10875
		{
10925 10876
			it->node->setPosition(nodes[it->id].smoothpos);
10926
			it->txt->setCaption(StringConverter::toString(nodes[it->id].mass));
10877
			it->label->setCaption(StringConverter::toString(nodes[it->id].mass));
10927 10878
		}
10928 10879
		break;
10929 10880
	case 5: // node-locked
10930 10881
		for(std::vector<debugtext_t>::iterator it=nodes_debug.begin(); it!=nodes_debug.end();it++)
10931 10882
		{
10932
			it->txt->setCaption((nodes[it->id].locked)?"locked":"unlocked");
10883
			it->label->setCaption((nodes[it->id].locked)?"locked":"unlocked");
10933 10884
			it->node->setPosition(nodes[it->id].smoothpos);
10934 10885
		}
10935 10886
		break;
......
10938 10889
		{
10939 10890
			it->node->setPosition(beams[it->id].p1->smoothpos - (beams[it->id].p1->smoothpos - beams[it->id].p2->smoothpos)/2);
10940 10891
			int scale=(int)(beams[it->id].scale * 100);
10941
			it->txt->setCaption(StringConverter::toString(scale));
10892
			it->label->setCaption(StringConverter::toString(scale));
10942 10893
		}
10943 10894
		break;
10944 10895
	case 7: // beam-broken
10945 10896
		for(std::vector<debugtext_t>::iterator it=beams_debug.begin(); it!=beams_debug.end();it++)
10946 10897
		{
10947 10898
			it->node->setPosition(beams[it->id].p1->smoothpos - (beams[it->id].p1->smoothpos - beams[it->id].p2->smoothpos)/2);
10948
			it->txt->setCaption((beams[it->id].broken)?"BROKEN":"");
10899
			it->label->setCaption((beams[it->id].broken)?"BROKEN":"");
10949 10900
		}
10950 10901
		break;
10951 10902
	case 8: // beam-stress
10952 10903
		for(std::vector<debugtext_t>::iterator it=beams_debug.begin(); it!=beams_debug.end();it++)
10953 10904
		{
10954 10905
			it->node->setPosition(beams[it->id].p1->smoothpos - (beams[it->id].p1->smoothpos - beams[it->id].p2->smoothpos)/2);
10955
			it->txt->setCaption(StringConverter::toString((float) fabs(beams[it->id].stress)));
10906
			it->label->setCaption(StringConverter::toString((float) fabs(beams[it->id].stress)));
10956 10907
		}
10957 10908
		break;
10958 10909
	case 9: // beam-strength
10959 10910
		for(std::vector<debugtext_t>::iterator it=beams_debug.begin(); it!=beams_debug.end();it++)
10960 10911
		{
10961 10912
			it->node->setPosition(beams[it->id].p1->smoothpos - (beams[it->id].p1->smoothpos - beams[it->id].p2->smoothpos)/2);
10962
			it->txt->setCaption(StringConverter::toString(beams[it->id].strength));
10913
			it->label->setCaption(StringConverter::toString(beams[it->id].strength));
10963 10914
		}
10964 10915
		break;
10965 10916
	case 10: // beam-hydros
......
10967 10918
		{
10968 10919
			it->node->setPosition(beams[it->id].p1->smoothpos - (beams[it->id].p1->smoothpos - beams[it->id].p2->smoothpos)/2);
10969 10920
			int v = (beams[it->id].L / beams[it->id].Lhydro) * 100;
10970
			it->txt->setCaption(StringConverter::toString(v));
10921
			it->label->setCaption(StringConverter::toString(v));
10971 10922
		}
10972 10923
		break;
10973 10924
	case 11: // beam-commands
......
10975 10926
		{
10976 10927
			it->node->setPosition(beams[it->id].p1->smoothpos - (beams[it->id].p1->smoothpos - beams[it->id].p2->smoothpos)/2);
10977 10928
			int v = (beams[it->id].L / beams[it->id].commandLong) * 100;
10978
			it->txt->setCaption(StringConverter::toString(v));
10929
			it->label->setCaption(StringConverter::toString(v));
10979 10930
		}
10980 10931
		break;
10981 10932
	}
......
10984 10935
void Beam::updateNetworkInfo()
10985 10936
{
10986 10937
#ifdef USE_SOCKETW
10938
#ifdef USE_MYGUI
10987 10939
	if(!net) return;
10988 10940
	bool remote = (state == NETWORKED);
10941
	user_info_t *info = 0;
10989 10942
	if(remote)
10990
	{
10991
		client_t *c = net->getClientInfo(sourceid);
10992
		if(!c) return;
10993
		networkUsername = String(c->user.username);
10994
		networkAuthlevel = c->user.authstatus;
10995
	} else
10996
	{
10997
		user_info_t *info = net->getLocalUserData();
10998
		if(!info) return;
10999
		if(!strlen(info->username)) return;
11000
		networkUsername = String(info->username);
11001
		networkAuthlevel = info->authstatus;
11002
	}
10943
		info = &(net->getClientInfo(sourceid)->user);
10944
	else
10945
		info = net->getLocalUserData();
11003 10946

  
11004
	if (netLabelNode && netMT)
10947
	if(!info) return;
10948
	if(!strlen(info->username)) return;
10949
	
10950
	networkUsername = String(info->username);
10951
	networkAuthlevel = info->authstatus;
10952
	int colourNum = info->colournum;
10953

  
10954
	if (!netLabel)
11005 10955
	{
11006
		// ha, this caused the empty caption bug, but fixed now since we change the caption if its empty:
11007
		netMT->setCaption(networkUsername);
11008
		if(networkAuthlevel & AUTH_ADMIN)
11009
		{
11010
			netMT->setFontName("highcontrast_red");
11011
		} else if(networkAuthlevel & AUTH_RANKED)
11012
		{
11013
			netMT->setFontName("highcontrast_green");
11014
		} else
11015
		{
11016
			netMT->setFontName("highcontrast_black");
11017
		}
11018
		netLabelNode->setVisible(true);
10956
		Ogre::AxisAlignedBox bbox(minx, miny, minz,maxx,maxy,maxz);
10957
		netLabel = GUI_3DLabelManager::getSingleton().new3DLabel(bbox, ColoredTextAreaOverlayElement::StripColors(networkUsername));
11019 10958
	}
11020
	else
11021
	{
11022
		char wname[256];
11023
		sprintf(wname, "netlabel-%s",truckname);
11024
		netMT = new MovableText(wname, ColoredTextAreaOverlayElement::StripColors(networkUsername));
11025
		netMT->setFontName("highcontrast_black");
11026
		netMT->setTextAlignment(MovableText::H_CENTER, MovableText::V_ABOVE);
11027
		//netMT->setAdditionalHeight(2);
11028
		netMT->showOnTop(false);
11029
		netMT->setCharacterHeight(2);
11030
		netMT->setColor(ColourValue::White);
11031 10959

  
11032
		if(networkAuthlevel & AUTH_ADMIN)
11033
		{
11034
			netMT->setFontName("highcontrast_red");
11035
		} else if(networkAuthlevel & AUTH_RANKED)
11036
		{
11037
			netMT->setFontName("highcontrast_green");
11038
		} else
11039
		{
11040
			netMT->setFontName("highcontrast_black");
11041
		}
10960
	netLabel->setTextColour(PlayerColours::getSingleton().getColour(colourNum));
10961
	netLabel->setCaption(ColoredTextAreaOverlayElement::StripColors(networkUsername));
10962
	netLabel->setVisible(true);
11042 10963

  
11043
		netLabelNode=parentNode->createChildSceneNode();
11044
		netLabelNode->attachObject(netMT);
11045
		netLabelNode->setPosition(position);
11046
		netLabelNode->setVisible(true);
11047
		deletion_sceneNodes.push_back(netLabelNode);
11048
		deletion_Objects.push_back(netMT);
11049
	}
10964
#endif //USE_MYGUI
11050 10965
#endif //SOCKETW
11051 10966
}
11052 10967

  
......
11054 10969
{
11055 10970
	//park and recycle vehicle
11056 10971
	state=RECYCLE;
11057
	if(netMT)
11058
		netMT->setCaption("");
10972
	if(netLabel)
10973
	{
10974
		netLabel->setCaption("");
10975
		netLabel->setVisible(false);
10976
		// TODO: remove label
10977
	}
11059 10978
	resetPosition(100000, 100000, false, 100000);
11060
	netLabelNode->setVisible(false);
11061 10979
}
11062 10980

  
11063 10981
void *threadstart(void* vid)
Beam.h (working copy)
369 369
	int first_wheel_node;
370 370
	int netbuffersize;
371 371
	int nodebuffersize;
372
	SceneNode *netLabelNode;
373 372

  
374 373
	std::string getTruckName();
375 374
	std::vector<authorinfo_t> getAuthors();
......
423 422
	float getHeadingDirectionAngle();
424 423
	bool getCustomParticleMode();
425 424
	int getLowestNode();
426
	void preMapLabelRenderUpdate(bool mode, float cheight=0);
427 425
	
428 426
	SceneNode *cablightNode;
429 427
	float tdt;
......
581 579
	Timer *nettimer;
582 580
	int net_toffset;
583 581
	int netcounter;
584
	MovableText *netMT; //, *netDist;
582
	GUI_3DLabel *netLabel;
585 583
	float minimass;
586 584

  
587 585
	// network properties
BeamData.h (working copy)
593 593
struct debugtext
594 594
{
595 595
	int id;
596
	Ogre::MovableText *txt;
596
	GUI_3DLabel *label;
597 597
	Ogre::SceneNode *node;
598 598
};
599 599

  
Character.cpp (working copy)
30 30
#include "NetworkStreamManager.h"
31 31
#include "BeamFactory.h"
32 32
#include "ColoredTextAreaOverlayElement.h"
33
#include "gui_3dlabels.h"
33 34
#include "PlayerColours.h"
34 35

  
35 36
using namespace Ogre;
......
54 55
	beamCoupling=0;
55 56
	//remote = true;
56 57
	last_net_time=0;
57
	netMT=0;
58 58
	networkUsername = String();
59 59
	networkAuthLevel = 0;
60 60

  
......
113 113
Character::~Character()
114 114
{
115 115
	setVisible(false);
116
	if(netMT) delete netMT;
116
	if(label) GUI_3DLabelManager::getSingleton().remove3DLabel(label);
117 117
	if(personode) personode->detachAllObjects();
118 118
#ifdef USE_MYGUI 
119 119
	if(map && mapEnt) map->deleteMapEntity(mapEnt);
......
162 162
	}
163 163

  
164 164
	//LogManager::getSingleton().logMessage(" * updateNetLabel : " + StringConverter::toString(this->source));
165
	if(!netMT)
166
	{
167
		netMT = new MovableText("netlabel-"+myName, ColoredTextAreaOverlayElement::StripColors(networkUsername));
168
		personode->attachObject(netMT);
169
		netMT->setFontName("highcontrast_black");
170
		netMT->setTextAlignment(MovableText::H_CENTER, MovableText::V_ABOVE);
171
		netMT->setAdditionalHeight(2);
172
		netMT->showOnTop(false);
173
		netMT->setCharacterHeight(8);
174
		netMT->setColor(ColourValue::White);
175
	}
165
	if(!label)
166
		label = GUI_3DLabelManager::getSingleton().new3DLabel(personode->getAttachedObject(0), ColoredTextAreaOverlayElement::StripColors(networkUsername));
176 167

  
177
	//LogManager::getSingleton().logMessage(" *label caption: " + String(networkUsername));
178
	//LogManager::getSingleton().logMessage(" *label caption: " + ColoredTextAreaOverlayElement::StripColors(networkUsername));
179
	netMT->setCaption(ColoredTextAreaOverlayElement::StripColors(networkUsername));
180
	if(networkAuthLevel & AUTH_ADMIN)
181
	{
182
		netMT->setFontName("highcontrast_red");
183
	} else if(networkAuthLevel & AUTH_RANKED)
184
	{
185
		netMT->setFontName("highcontrast_green");
186
	} else
187
	{
188
		netMT->setFontName("highcontrast_black");
189
	}
168
	label->setCaption(ColoredTextAreaOverlayElement::StripColors(networkUsername));
169
	label->setTextColour(PlayerColours::getSingleton().getColour(colourNumber));
190 170

  
191 171
	// update character colour
192 172
	updateCharacterColour();
......
603 583

  
604 584
void Character::updateNetLabelSize()
605 585
{
606
	if (!this || !net || !netMT || !netMT->isVisible()) return;
586
	if (!this || !net || !label || !label->getVisible()) return;
607 587

  
608 588
	Vector3 vdir = personode->getPosition() - mCamera->getPosition();
609 589
	float vlen=vdir.length();
590

  
591
	/*
610 592
	float h = vlen * 1.2f;
611 593
	if(h<9)
612 594
		h=9;
613
	netMT->setCharacterHeight(h);
595
	label->setHeight(h);
596
	*/
597

  
614 598
	if(vlen>1000)
615
		netMT->setCaption(networkUsername + "  (" + StringConverter::toString( (float)(ceil(vlen/100)/10.0) )+ " km)");
599
		label->setCaption(networkUsername + "  (" + StringConverter::toString( (float)(ceil(vlen/100)/10.0) )+ " km)");
616 600
	else if (vlen>20 && vlen <= 1000)
617
		netMT->setCaption(networkUsername + "  (" + StringConverter::toString((int)vlen)+ " m)");
601
		label->setCaption(networkUsername + "  (" + StringConverter::toString((int)vlen)+ " m)");
618 602
	else
619
		netMT->setCaption(networkUsername);
603
		label->setCaption(networkUsername);
620 604

  
621
	//netMT->setAdditionalHeight((maxy-miny)+h+0.1);
622
	netMT->setVisible(true);
605
	label->setVisible(true);
623 606
}
624 607

  
625 608
int Character::setBeamCoupling(bool enabled, Beam *truck)
......
629 612
		if(!truck) return 1;
630 613
		beamCoupling = truck;
631 614
		setPhysicsEnabled(false);
632
		if(netMT && netMT->isVisible()) netMT->setVisible(false);
615
		if(label && label->getVisible()) label->setVisible(false);
633 616
		if(net && !remote)
634 617
		{
635 618
			attach_netdata_t data;
......
657 640
	{
658 641
		setPhysicsEnabled(true);
659 642
		beamCoupling=0;
660
		if(netMT && !netMT->isVisible()) netMT->setVisible(true);
643
		if(label && !label->getVisible()) label->setVisible(true);
661 644
		if(net && !remote)
662 645
		{
663 646
			attach_netdata_t data;
Character.h (working copy)
24 24
#include <Ogre.h>
25 25
#include <OgreVector3.h>
26 26
#include "Streamable.h"
27
#include "MovableText.h"
27
#include "gui_3dlabels.h"
28 28
#include "rormemory.h"
29 29

  
30 30
class Water;
......
93 93
	bool remote;
94 94
	bool physicsEnabled;
95 95
	int colourNumber;
96
	Ogre::MovableText *netMT;
96
	GUI_3DLabel *label;
97 97
	MapEntity *mapEnt;
98 98
	Ogre::String networkUsername;
99 99
	int networkAuthLevel;
ChatSystem.h (working copy)
24 24
#include <Ogre.h>
25 25
#include <OgreVector3.h>
26 26
#include "Streamable.h"
27
#include "MovableText.h"
27
#include "gui_3dlabels.h"
28 28
#include "StreamableFactory.h"
29 29
#include "IngameConsole.h"
30 30
#include "rormemory.h"
collisions.cpp (working copy)
22 22
#include "Landusemap.h"
23 23
#include "approxmath.h"
24 24
#include "errorutils.h"
25
#include "gui_3dlabels.h"
25 26
#include "language.h"
26 27

  
27 28
// some gcc fixes
......
1443 1444

  
1444 1445

  
1445 1446
				// setup the label
1446
				String labelName = "label_"+cell_name;
1447 1447
				String labelCaption = cell_name+" "+StringConverter::toString(percent*100,2) + "% usage ("+StringConverter::toString(cc)+"/"+StringConverter::toString(CELL_BLOCKSIZE)+") DEEP: " + StringConverter::toString(deep);
1448
				MovableText *mt = new MovableText(labelName, labelCaption);
1449
				mt->setFontName("highcontrast_black");
1450
				mt->setTextAlignment(MovableText::H_CENTER, MovableText::V_ABOVE);
1451
				mt->setAdditionalHeight(1);
1452
				mt->showOnTop(false);
1453
				mt->setCharacterHeight(0.3);
1454
				mt->setColor(ColourValue::White);
1455
				mo_node->attachObject(mt);
1456

  
1448
				GUI_3DLabel *label = GUI_3DLabelManager::getSingleton().new3DLabel(mo, labelCaption);
1449
				label->setMaxDistance(50);
1450
				label->setLineHeight(8);
1451
				label->setAbove(false);
1457 1452
				mo_node->setVisible(true);
1458 1453
				mo_node->setPosition(Vector3(x+CELL_SIZE/(float)2.0, groundheight, z+CELL_SIZE/(float)2.0));
1459 1454
			}
gui_3dlabels.cpp (revision 0)
1
/*
2
This source file is part of Rigs of Rods
3
Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
4
Copyright 2007,2008,2009 Thomas Fischer
5

  
6
For more information, see http://www.rigsofrods.com/
7

  
8
Rigs of Rods is free software: you can redistribute it and/or modify
9
it under the terms of the GNU General Public License version 3, as 
10
published by the Free Software Foundation.
11

  
12
Rigs of Rods is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16

  
17
You should have received a copy of the GNU General Public License
18
along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
19
*/
20

  
21
// created by Thomas Fischer thomas{AT}thomasfischer{DOT}biz, 28th of July 2010
22

  
23
#ifdef USE_MYGUI
24

  
25
#include "gui_3dlabels.h"
26
#include "gui_manager.h"
27
#include "Settings.h"
28

  
29
#include "language.h"
30
#include "RoRFrameListener.h"
31
#include "network.h"
32
#include "PlayerColours.h"
33
#include "BeamFactory.h"
34

  
35
#include "CharacterFactory.h"
36

  
37
template<> GUI_3DLabelManager * Singleton< GUI_3DLabelManager >::ms_Singleton = 0;
38
GUI_3DLabelManager* GUI_3DLabelManager::getSingletonPtr(void)
39
{
40
	return ms_Singleton;
41
}
42
GUI_3DLabelManager& GUI_3DLabelManager::getSingleton(void)
43
{
44
	assert( ms_Singleton );  return ( *ms_Singleton );
45
}
46

  
47
GUI_3DLabelManager::GUI_3DLabelManager(Ogre::Camera *cam) : mCamera(cam)
48
{
49
	MyGUI::IntSize gui_area = GUIManager::getSingleton().getGUI()->getViewSize();
50
	parentWindow = MyGUI::Gui::getInstance().createWidget<MyGUI::Window>("FlowContainer", 0, 0, gui_area.width, gui_area.height,  MyGUI::Align::Default, "Main");
51
	parentWindow->setVisible(true);
52

  
53
}
54

  
55
GUI_3DLabelManager::~GUI_3DLabelManager()
56
{
57
}
58

  
59
void GUI_3DLabelManager::update(float dt)
60
{
61
	std::vector<GUI_3DLabel *>::iterator it;
62
	for(it = labels.begin(); it != labels.end(); it++)
63
	{
64
		GUI_3DLabel *label = (*it);
65
		MovableObject *obj = label->getObject();
66
		
67
		int labelMode = label->getMode();
68
		Ogre::Real min_x, max_x, min_y, max_y;
69
		
70
		if(labelMode == GUI_3DLabel::LBLMODE_OBJ)
71
			getMinMaxEdgesOfTopAABBIn2D(obj, min_x, min_y, max_x, max_y);
72
		else if(labelMode == GUI_3DLabel::LBLMODE_BB)
73
			getMinMaxEdgesOfTopAABBIn2D(label->getBoundingBox(), min_x, min_y, max_x, max_y);
74
		// TODO: implement GUI_3DLabel::LBLMODE_NODE
75
		
76
		// check if this label is distance limited
77
		if(label->getMaxDistance() > 0 && labelMode == GUI_3DLabel::LBLMODE_OBJ)
78
		{
79
			Ogre::SceneNode *sn = obj->getParentSceneNode();
80
			if(!sn) continue;
81
			float distance = (sn->getPosition() - mCamera->getPosition()).length();
82
			float vis = distance / label->getMaxDistance();
83
			if(vis > 1)
84
			{
85
				// too far away, not visible
86
				label->_setVisible(false);
87
				continue;
88
			} else
89
			{
90
				// visible, but fade out
91
				//label->setAlpha(1 - vis);
92
			}
93
			
94
		}
95

  
96
		// get the width of the bar
97
		MyGUI::IntSize gui_area = GUIManager::getSingleton().getGUI()->getViewSize();
98
		Real relTextWidth = (float)label->_getWidth() / (float)gui_area.width;
99
		Real relTextHeight = (float)label->_getHeight() / (float)gui_area.height;
100

  
101
		// improved on screen check
102
		bool onScreen = false;
103
		if (
104
			(min_x > -relTextWidth) 
105
			&& (max_x < 1.0 + relTextWidth)
106
			&& (min_y > 0.0 - relTextHeight) 
107
			&& (max_y < 1.0 + relTextHeight)
108
			)
109
		   onScreen = true;
110
		
111
		// hide label if wished
112
		if(!label->_getShown())
113
			onScreen=false;
114

  
115
		if(!onScreen)
116
		{
117
			label->_setVisible(false);
118
			continue;
119
		}
120
		label->_setVisible(true);
121

  
122
		if(label->getAbove())
123
		{
124
			label->_setPosition(MyGUI::IntPoint(
125
				(1-(min_x + max_x + relTextWidth)/2) * gui_area.width,
126
				(1-max_y) * gui_area.height - label->_getHeight()
127
				));
128
		} else
129
		{
130
			label->_setPosition(MyGUI::IntPoint(
131
				(1-(min_x + max_x + relTextWidth)/2) * gui_area.width,
132
				(1-max_y) * gui_area.height
133
				));
134
		}
135
	}
136
}
137

  
138
void GUI_3DLabelManager::setVisible(bool value)
139
{
140
	parentWindow->setVisible(value);
141
}
142

  
143
bool GUI_3DLabelManager::getVisible()
144
{
145
	return parentWindow->isVisible();
146
}
147

  
148
void GUI_3DLabelManager::getMinMaxEdgesOfTopAABBIn2D(const Ogre::MovableObject *mov, Ogre::Real& MinX, Ogre::Real& MinY, Ogre::Real& MaxX, Ogre::Real& MaxY)
149
{
150
	if (!mov->isInScene())
151
	   return;
152
 
153
	const Ogre::AxisAlignedBox &AABB = mov->getWorldBoundingBox(true);// the AABB of the target
154
	getMinMaxEdgesOfTopAABBIn2D(AABB, MinX, MinY, MaxX, MaxY);
155
}
156

  
157
void GUI_3DLabelManager::getMinMaxEdgesOfTopAABBIn2D(const Ogre::AxisAlignedBox &AABB, Ogre::Real& MinX, Ogre::Real& MinY, Ogre::Real& MaxX, Ogre::Real& MaxY)
158
{
159
	MinX = 0;
160
	MinY = 0;
161
	MaxX = 0;
162
	MaxY = 0;
163
 
164
	Ogre::Real X[4];// the 2D dots of the AABB in screencoordinates
165
	Ogre::Real Y[4];
166
 
167
	const Ogre::Vector3 CornersOfTopAABB[4] = {	AABB.getCorner(AxisAlignedBox::FAR_LEFT_TOP),
168
										AABB.getCorner(AxisAlignedBox::FAR_RIGHT_TOP),
169
										AABB.getCorner(AxisAlignedBox::NEAR_LEFT_TOP),
170
										AABB.getCorner(AxisAlignedBox::NEAR_RIGHT_TOP)};
171
 
172
	Ogre::Vector3 CameraPlainNormal = mCamera->getDerivedOrientation().zAxis();//The normal vector of the plaine.this points directly infront of the cam
173
 
174
	Ogre::Plane CameraPlain = Plane(CameraPlainNormal,mCamera->getDerivedPosition());//the plaine that devides the space bevor and behin the cam
175
 
176
	for (int i = 0; i < 4; i++)
177
	{
178
	  X[i] = 0;
179
	  Y[i] = 0;
180
 
181
	  getScreenCoordinates(CornersOfTopAABB[i],X[i],Y[i]);// transfor into 2d dots
182
 
183
 
184
	  if (CameraPlain.getSide(CornersOfTopAABB[i]) == Plane::NEGATIVE_SIDE)
185
	  {
186
 
187
		 if (i == 0)// accept the first set of values, no matter how bad it might be.
188
		 {
189
			MinX = X[i];
190
			MinY = Y[i];
191
			MaxX = X[i];
192
			MaxY = Y[i];
193
		 }
194
		 else// now compare if you get "better" values
195
		 {
196
			if (MinX > X[i])// get the x minimum
197
			{
198
			   MinX = X[i];
199
			}
200
			if (MinY > Y[i])// get the y minimum
201
			{
202
			   MinY = Y[i];
203
			}
204
			if (MaxX < X[i])// get the x maximum
205
			{
206
			   MaxX = X[i];
207
			}
208
			if (MaxY < Y[i])// get the y maximum
209
			{
210
			   MaxY = Y[i];
211
			}
212
		 }
213
	  }
214
	  else
215
	  {
216
		MinX = 0;
217
		MinY = 0;
218
		MaxX = 0;
219
		MaxY = 0;
220
		break;
221
	  }
222
	}
223
} 
224
 
225
void GUI_3DLabelManager::getScreenCoordinates(const Ogre::Vector3& position, Ogre::Real& x, Ogre::Real& y)
226
{
227
	Vector3 hcsPosition = mCamera->getProjectionMatrix() * (mCamera->getViewMatrix() * position);
228
 
229
	x = 1.0f - ((hcsPosition.x * 0.5f) + 0.5f);// 0 <= x <= 1 // left := 0,right := 1
230
	y = ((hcsPosition.y * 0.5f) + 0.5f);// 0 <= y <= 1 // bottom := 0,top := 1
231
}
232

  
233
GUI_3DLabel *GUI_3DLabelManager::new3DLabel(Ogre::MovableObject *obj, Ogre::String text, Ogre::ColourValue textColour)
234
{
235
	GUI_3DLabel *l = new GUI_3DLabel(parentWindow, obj, text, textColour);
236
	labels.push_back(l);
237
	return l;
238
}
239

  
240
GUI_3DLabel *GUI_3DLabelManager::new3DLabel(Ogre::SceneNode *node, Ogre::String text, Ogre::ColourValue textColour)
241
{
242
	GUI_3DLabel *l = new GUI_3DLabel(parentWindow, node, text, textColour);
243
	labels.push_back(l);
244
	return l;
245
}
246

  
247
GUI_3DLabel *GUI_3DLabelManager::new3DLabel(Ogre::AxisAlignedBox bbox, Ogre::String text, Ogre::ColourValue textColour)
248
{
249
	GUI_3DLabel *l = new GUI_3DLabel(parentWindow, bbox, text, textColour);
250
	labels.push_back(l);
251
	return l;
252
}
253

  
254

  
255
void GUI_3DLabelManager::remove3DLabel(GUI_3DLabel *lbl)
256
{
257
	// TODO
258
}
259

  
260
#endif // USE_MYGUI
gui_3dlabels.h (revision 0)
1
/*
2
This source file is part of Rigs of Rods
3
Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
4
Copyright 2007,2008,2009 Thomas Fischer
5

  
6
For more information, see http://www.rigsofrods.com/
7

  
8
Rigs of Rods is free software: you can redistribute it and/or modify
9
it under the terms of the GNU General Public License version 3, as 
10
published by the Free Software Foundation.
11

  
12
Rigs of Rods is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16

  
17
You should have received a copy of the GNU General Public License
18
along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
19
*/
20

  
21
// created by Thomas Fischer thomas{AT}thomasfischer{DOT}biz, 28th of July 2010
22

  
23
#ifdef USE_MYGUI 
24

  
25
#ifndef GUI_3DLABELS_H__
26
#define GUI_3DLABELS_H__
27

  
28
#include <MyGUI.h>
29
#include "OgreSingleton.h"
30
#include "OgrePrerequisites.h"
31
#include "OgreColourValue.h"
32
#include "Beam.h"
33

  
34
class GUI_3DLabel : public MemoryAllocatedObject
35
{
36
	friend class GUI_3DLabelManager;
37
protected:
38
	MyGUI::WindowPtr parentWindow;
39
	Ogre::SceneNode *node;
40
	Ogre::MovableObject  *obj;
41
	Ogre::ColourValue colour;
42
	Ogre::String txt;
43
	bool shown;
44
	Ogre::AxisAlignedBox bounding_box;
45
	float maxDist;
46
	bool above;
47
	float lineheight;
48

  
49
	enum {LBLMODE_ERR, LBLMODE_OBJ, LBLMODE_BB, LBLMODE_NODE};
50

  
51
	MyGUI::StaticImagePtr background;
52
	MyGUI::StaticTextPtr  text;
53

  
54
	GUI_3DLabel(MyGUI::WindowPtr _parentWindow, Ogre::MovableObject *_obj, Ogre::String _txt, Ogre::ColourValue _colour) : parentWindow(_parentWindow), node(0), obj(_obj), colour(_colour), txt(_txt), shown(true), bounding_box(Ogre::AxisAlignedBox::BOX_NULL), maxDist(-1), above(true), lineheight(16)
55
	{
56
		createGUI();
57
	}
58

  
59
	GUI_3DLabel(MyGUI::WindowPtr _parentWindow, Ogre::SceneNode *_node, Ogre::String _txt, Ogre::ColourValue _colour) : parentWindow(_parentWindow), node(_node), obj(0), colour(_colour), txt(_txt), shown(true), bounding_box(Ogre::AxisAlignedBox::BOX_NULL), maxDist(-1), above(true), lineheight(16)
60
	{
61
		createGUI();
62
	}
63

  
64
	GUI_3DLabel(MyGUI::WindowPtr _parentWindow, Ogre::AxisAlignedBox bbox, Ogre::String _txt, Ogre::ColourValue _colour) : parentWindow(_parentWindow), node(0), obj(0), colour(_colour), txt(_txt), shown(true), bounding_box(bbox), maxDist(-1), above(true), lineheight(16)
65
	{
66
		createGUI();
67
	}
68

  
69
	int getMode()
70
	{
71
		if(obj)
72
			return LBLMODE_OBJ;
73
		else if(!obj && bounding_box != Ogre::AxisAlignedBox::BOX_NULL)
74
			return LBLMODE_BB;
75
		else if(!obj && bounding_box == Ogre::AxisAlignedBox::BOX_NULL && node)
76
			return LBLMODE_NODE;
77
		return LBLMODE_ERR;
78
	}
79

  
80
	void createGUI()
81
	{
82
		background = parentWindow->createWidget<MyGUI::StaticImage>("StaticImage", 0, 0, 200, lineheight+2,  MyGUI::Align::Default, "Main");
83
		background->setImageTexture("mpbg.png");
84
		text = background->createWidget<MyGUI::StaticText>("StaticText", 2, 2, 200, lineheight,  MyGUI::Align::Default, "helptext");
85
		text->setCaption(txt);
86
		text->setFontName("VeraMoBd");
87
		text->setTextColour(MyGUI::Colour(colour.r,colour.g,colour.b,colour.a));
88
		text->setFontHeight(lineheight);
89
	}
90

  
91
	~GUI_3DLabel()
92
	{
93
	}
94
	
95
	MovableObject *getObject()
96
	{
97
		return obj;
98
	}
99
	
100
	Ogre::SceneNode *getNode()
101
	{
102
		return node;
103
	}
104

  
105
	void _setVisible(bool value)
106
	{
107
		background->setVisible(value);
108
	}
109

  
110
	bool _getVisible()
111
	{
112
		return background->isVisible();
113
	}
114

  
115
	bool _getShown()
116
	{
117
		return shown;
118
	}
119

  
120
	void _setPosition(MyGUI::IntPoint p)
121
	{
122
		background->setPosition(p);
123
	}
124
	
125
	float _getHeight()
126
	{
127
		return background->getHeight();
128
	}
129

  
130
	float _getWidth()
131
	{
132
		return background->getWidth();
133
	}
134

  
135
public:
136
	void setVisible(bool value)
137
	{
138
		shown = value;
139
	}
140

  
141
	bool getVisible()
142
	{
143
		return shown;
144
	}
145

  
146
	void setCaption(Ogre::String _txt)
147
	{
148
		txt = _txt;
149
		text->setCaption(txt);
150
	}
151
	
152
	void setMaxDistance(float dist)
153
	{
154
		maxDist = dist;
155
	}
156

  
157
	void setLineHeight(float val)
158
	{
159
		lineheight = val;
160
		background->setSize(background->getWidth(), lineheight);
161
		text->setSize(text->getWidth(), lineheight);
162
		text->setFontHeight(lineheight);
163
	}
164

  
165
	float getMaxDistance()
166
	{
167
		return maxDist;
168
	}
169

  
170
	void setAlpha(float a)
171
	{
172
		background->setAlpha(a);
173
	}
174

  
175
	float getAlpha()
176
	{
177
		return background->getAlpha();
178
	}
179

  
180
	void setAbove(bool value)
181
	{
182
		above=value;
183
	}
184

  
185
	bool getAbove()
186
	{
187
		return above;
188
	}
189

  
190
	void setTextColour(Ogre::ColourValue col)
191
	{
192
		this->colour = col;
193
		text->setTextColour(MyGUI::Colour(colour.r,colour.g,colour.b,colour.a));
194
	}
195

  
196
	Ogre::AxisAlignedBox getBoundingBox()
197
	{
198
		return bounding_box;
199
	}
200

  
201
	void setBoundingBox(Ogre::AxisAlignedBox b)
202
	{
203
		bounding_box = b;
204
	}
205
};
206

  
207
class GUI_3DLabelManager : public Ogre::Singleton< GUI_3DLabelManager >, public MemoryAllocatedObject
208
{
209
public:
210
	GUI_3DLabelManager(Ogre::Camera *mCamera);
211
	~GUI_3DLabelManager();
212
	static GUI_3DLabelManager& getSingleton(void);
213
	static GUI_3DLabelManager* getSingletonPtr(void);
214

  
215
	void setVisible(bool value);
216
	bool getVisible();
217

  
218
	void update(float dt);
219
	
220
	GUI_3DLabel *new3DLabel(Ogre::MovableObject *mov, Ogre::String text, Ogre::ColourValue textColour = Ogre::ColourValue::Black);
221
	GUI_3DLabel *new3DLabel(Ogre::SceneNode *node, Ogre::String text, Ogre::ColourValue textColour = Ogre::ColourValue::Black);
222
	GUI_3DLabel *new3DLabel(Ogre::AxisAlignedBox bbox, Ogre::String text, Ogre::ColourValue textColour = Ogre::ColourValue::Black);
223
	void remove3DLabel(GUI_3DLabel *lbl);
224
protected:
225
	Ogre::Camera *mCamera;
226
	MyGUI::WindowPtr parentWindow;
227

  
228
	void getMinMaxEdgesOfTopAABBIn2D(const Ogre::MovableObject *mov, Ogre::Real& MinX, Ogre::Real& MinY, Ogre::Real& MaxX, Ogre::Real& MaxY);
229
	void getMinMaxEdgesOfTopAABBIn2D(const Ogre::AxisAlignedBox &AABB, Ogre::Real& MinX, Ogre::Real& MinY, Ogre::Real& MaxX, Ogre::Real& MaxY);
230
	void getScreenCoordinates(const Ogre::Vector3& position, Ogre::Real& x, Ogre::Real& y);
231
	
232
	std::vector<GUI_3DLabel *> labels;
233
};
234

  
235
#endif //GUI_3DLABELS_H__
236

  
237
#else // USE_MYGUI
238
class GUI_3DLabel
239
{
240
};
241
#endif // USE_MYGUI
242

  
MovableText.cpp (working copy)
1
/**
2
* File: MovableText.cpp
3
*
4
* description: This create create a billboarding object that display a text.
5
*
6
* @author  2003 by cTh see gavocanov@rambler.ru
7
* @update  2006 by barraq see nospam@barraquand.com
8
*/
9

  
10
#include "Ogre.h"
11
#include "OgreFontManager.h"
12
#include "MovableText.h"
13
#include "rormemory.h"
14

  
15
using namespace Ogre;
16

  
17
#define POS_TEX_BINDING    0
18
#define COLOUR_BINDING     1
19

  
20
MovableText::MovableText(const String &name, const String &caption, const String &fontName, Real charHeight, const ColourValue &color)
21
: mpCam(NULL)
22
, mpWin(NULL)
23
, mpFont(NULL)
24
, mName(name)
25
, mCaption(caption)
26
, mFontName(fontName)
27
, mCharHeight(charHeight)
28
, mColor(color)
29
, mType("MovableText")
30
, mTimeUntilNextToggle(0)
31
, mSpaceWidth(0)
32
, mUpdateColors(true)
33
, mOnTop(false)
34
, mHorizontalAlignment(H_LEFT)
35
, mVerticalAlignment(V_BELOW)
36
, mAdditionalHeight(0.0)
37
{
38
	if (name == "")
39
		throw Exception(Exception::ERR_INVALIDPARAMS, "Trying to create MovableText without name", "MovableText::MovableText");
40

  
41
	if (caption == "")
42
	//    throw Exception(Exception::ERR_INVALIDPARAMS, "Trying to create MovableText without caption", "MovableText::MovableText");
43
		mCaption = ".";
44

  
45
	mRenderOp.vertexData = NULL;
46
	this->setFontName(mFontName);
47
	this->_setupGeometry();
48
}
49

  
50
MovableText::~MovableText()
51
{
52
	if (mRenderOp.vertexData)
53
		delete mRenderOp.vertexData;
54
}
55

  
56
void MovableText::setFontName(const String &fontName)
57
{
58
	if((Ogre::MaterialManager::getSingletonPtr()->resourceExists(mName + "Material")))
59
	{
60
		Ogre::MaterialManager::getSingleton().remove(mName + "Material");
61
	}
62

  
63
	if (mFontName != fontName || mpMaterial.isNull() || !mpFont)
64
	{
65
		mFontName = fontName;
66
		mpFont = (Font *)FontManager::getSingleton().getByName(mFontName).getPointer();
67
		if (!mpFont)
68
			throw Exception(Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + fontName, "MovableText::setFontName");
69

  
70
		mpFont->load();
71
		if (!mpMaterial.isNull())
72
		{
73
			MaterialManager::getSingletonPtr()->remove(mpMaterial->getName());
74
			mpMaterial.setNull();
75
		}
76

  
77
		mpMaterial = mpFont->getMaterial()->clone(mName + "Material");
78
		if (!mpMaterial->isLoaded())
79
			mpMaterial->load();
80

  
81
		mpMaterial->setDepthCheckEnabled(!mOnTop);
82
		mpMaterial->setDepthBias(1.0,1.0);
83
		mpMaterial->setFog(true);
84
		mpMaterial->setDepthWriteEnabled(mOnTop);
85
		mpMaterial->setLightingEnabled(false);
86
		mNeedUpdate = true;
87
	}
88
}
89

  
90
void MovableText::setCaption(const String &caption)
91
{
92
	if (caption != mCaption)
93
	{
94
		mCaption = caption;
95
		mNeedUpdate = true;
96
	}
97
}
98

  
99
void MovableText::setColor(const ColourValue &color)
100
{
101
	if (color != mColor)
102
	{
103
		mColor = color;
104
		mUpdateColors = true;
105
	}
106
}
107

  
108
void MovableText::setCharacterHeight(Real height)
109
{
110
	if (fabs(height - mCharHeight) > 0.00001f)
111
	{
112
		mCharHeight = height;
113
		mNeedUpdate = true;
114
	}
115
}
116

  
117
void MovableText::setSpaceWidth(Real width)
118
{
119
	if (fabs(width - mSpaceWidth) > 0.00001f)
120
	{
121
		mSpaceWidth = width;
122
		mNeedUpdate = true;
123
	}
124
}
125

  
126
void MovableText::setTextAlignment(const HorizontalAlignment& horizontalAlignment, const VerticalAlignment& verticalAlignment)
127
{
128
	if(mHorizontalAlignment != horizontalAlignment)
129
	{
130
		mHorizontalAlignment = horizontalAlignment;
131
		mNeedUpdate = true;
132
	}
133
	if(mVerticalAlignment != verticalAlignment)
134
	{
135
		mVerticalAlignment = verticalAlignment;
136
		mNeedUpdate = true;
137
	}
138
}
139

  
140
void MovableText::setAdditionalHeight( Real height )
141
{
142
	if (fabs(mAdditionalHeight - height) > 0.00001f)
143
	{
144
		mAdditionalHeight = height;
145
		mNeedUpdate = true;
146
	}
147
}
148

  
149
void MovableText::showOnTop(bool show)
150
{
151
	if( mOnTop != show && !mpMaterial.isNull() )
152
	{
153
		mOnTop = show;
154
		mpMaterial->setDepthBias(1.0,1.0);
155
		mpMaterial->setDepthCheckEnabled(!mOnTop);
156
		mpMaterial->setDepthWriteEnabled(mOnTop);
157
	}
158
}
159

  
160
void MovableText::_setupGeometry()
161
{
162
	assert(mpFont);
163
	assert(!mpMaterial.isNull());
164

  
165
	uint vertexCount = static_cast<uint>(mCaption.size() * 6);
166

  
167
	if (mRenderOp.vertexData)
168
	{
169
		// Removed this test as it causes problems when replacing a caption
170
		// of the same size: replacing "Hello" with "hello"
171
		// as well as when changing the text alignment
172
		//if (mRenderOp.vertexData->vertexCount != vertexCount)
173
		{
174
			delete mRenderOp.vertexData;
175
			mRenderOp.vertexData = NULL;
176
			mUpdateColors = true;
177
		}
178
	}
179

  
180
	if (!mRenderOp.vertexData)
181
		mRenderOp.vertexData = new VertexData();
182

  
183
	mRenderOp.indexData = 0;
184
	mRenderOp.vertexData->vertexStart = 0;
185
	mRenderOp.vertexData->vertexCount = vertexCount;
186
	mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
187
	mRenderOp.useIndexes = false;
188

  
189
	VertexDeclaration  *decl = mRenderOp.vertexData->vertexDeclaration;
190
	VertexBufferBinding   *bind = mRenderOp.vertexData->vertexBufferBinding;
191
	size_t offset = 0;
192

  
193
	// create/bind positions/tex.ccord. buffer
194
	if (!decl->findElementBySemantic(VES_POSITION))
195
		decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);
196

  
197
	offset += VertexElement::getTypeSize(VET_FLOAT3);
198

  
199
	if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES))
200
		decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
201

  
202
	HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING),
203
		mRenderOp.vertexData->vertexCount,
204
		HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
205
	bind->setBinding(POS_TEX_BINDING, ptbuf);
206

  
207
	// Colours - store these in a separate buffer because they change less often
208
	if (!decl->findElementBySemantic(VES_DIFFUSE))
209
		decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);
210

  
211
	HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING),
212
		mRenderOp.vertexData->vertexCount,
213
		HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
214
	bind->setBinding(COLOUR_BINDING, cbuf);
215

  
216
	size_t charlen = mCaption.size();
217
	//Real *pPCBuff = static_cast<Real*>(ptbuf->lock(HardwareBuffer::HBL_NORMAL));
218
	Real *pPCBuff=(Real*)ror_malloc(ptbuf->getSizeInBytes());
219
	Real *oPCBuff=pPCBuff;
220

  
221
	float largestWidth = 0;
222
	float left = 0 * 2.0 - 1.0;
223
	float top = -((0 * 2.0) - 1.0);
224

  
225
	// Derive space width from a capital A
226
	if (fabs(mSpaceWidth) < 0.00001f)
227
		mSpaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0;
228

  
229
	// for calculation of AABB
230
	Ogre::Vector3 min=Ogre::Vector3::ZERO, max=Ogre::Vector3::ZERO, currPos=Ogre::Vector3::ZERO;
231
	Ogre::Real maxSquaredRadius = 0.0f;
232
	bool first = true;
233

  
234
	// Use iterator
235
	String::iterator i, iend;
236
	iend = mCaption.end();
237
	bool newLine = true;
238
	Real len = 0.0f;
239

  
240
	if(mVerticalAlignment == MovableText::V_ABOVE)
241
	{
242
		// Raise the first line of the caption
243
		top += mCharHeight;
244
		for (i = mCaption.begin(); i != iend; ++i)
245
		{
246
			if (*i == '\n')
247
				top += mCharHeight * 2.0;
248
		}
249
	}
250

  
251
	for (i = mCaption.begin(); i != iend; ++i)
252
	{
253
		if (newLine)
254
		{
255
			len = 0.0f;
256
			for (String::iterator j = i; j != iend && *j != '\n'; j++)
257
			{
258
				if (*j == ' ')
259
					len += mSpaceWidth;
260
				else
261
					len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0;
262
			}
263
			newLine = false;
264
		}
265

  
266
		if (*i == '\n')
267
		{
268
			left = 0 * 2.0 - 1.0;
269
			top -= mCharHeight * 2.0;
270
			newLine = true;
271
			continue;
272
		}
273

  
274
		if (*i == ' ')
275
		{
276
			// Just leave a gap, no tris
277
			left += mSpaceWidth;
278
			// Also reduce tri count
279
			mRenderOp.vertexData->vertexCount -= 6;
280
			continue;
281
		}
282

  
283
		Real horiz_height = mpFont->getGlyphAspectRatio(*i);
284
		Real u1, u2, v1, v2;
285
		Ogre::Font::UVRect utmp;
286
		utmp = mpFont->getGlyphTexCoords(*i);
287
		u1 = utmp.left;
288
		u2 = utmp.right;
289
		v1 = utmp.top;
290
		v2 = utmp.bottom;
291

  
292
		// each vert is (x, y, z, u, v)
293
		//-------------------------------------------------------------------------------------
294
		// First tri
295
		//
296
		// Upper left
297
		if(mHorizontalAlignment == MovableText::H_LEFT)
298
			*pPCBuff++ = left;
299
		else
300
			*pPCBuff++ = left - (len / 2);
301
		*pPCBuff++ = top;
302
		*pPCBuff++ = -1.0;
303
		*pPCBuff++ = u1;
304
		*pPCBuff++ = v1;
305

  
306
		// Deal with bounds
307
		if(mHorizontalAlignment == MovableText::H_LEFT)
308
			currPos = Ogre::Vector3(left, top, -1.0);
309
		else
310
			currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
311
		if (first)
312
		{
313
			min = max = currPos;
314
			maxSquaredRadius = currPos.squaredLength();
315
			first = false;
316
		}
317
		else
318
		{
319
			min.makeFloor(currPos);
320
			max.makeCeil(currPos);
321
			maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
322
		}
323

  
324
		top -= mCharHeight * 2.0;
325

  
326
		// Bottom left
327
		if(mHorizontalAlignment == MovableText::H_LEFT)
328
			*pPCBuff++ = left;
329
		else
330
			*pPCBuff++ = left - (len / 2);
331
		*pPCBuff++ = top;
332
		*pPCBuff++ = -1.0;
333
		*pPCBuff++ = u1;
334
		*pPCBuff++ = v2;
335

  
336
		// Deal with bounds
337
		if(mHorizontalAlignment == MovableText::H_LEFT)
338
			currPos = Ogre::Vector3(left, top, -1.0);
339
		else
340
			currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
341
		min.makeFloor(currPos);
342
		max.makeCeil(currPos);
343
		maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
344

  
345
		top += mCharHeight * 2.0;
346
		left += horiz_height * mCharHeight * 2.0;
347

  
348
		// Top right
349
		if(mHorizontalAlignment == MovableText::H_LEFT)
350
			*pPCBuff++ = left;
351
		else
352
			*pPCBuff++ = left - (len / 2);
353
		*pPCBuff++ = top;
354
		*pPCBuff++ = -1.0;
355
		*pPCBuff++ = u2;
356
		*pPCBuff++ = v1;
357
		//-------------------------------------------------------------------------------------
358

  
359
		// Deal with bounds
360
		if(mHorizontalAlignment == MovableText::H_LEFT)
361
			currPos = Ogre::Vector3(left, top, -1.0);
362
		else
363
			currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
364
		min.makeFloor(currPos);
365
		max.makeCeil(currPos);
366
		maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
367

  
368
		//-------------------------------------------------------------------------------------
369
		// Second tri
370
		//
371
		// Top right (again)
372
		if(mHorizontalAlignment == MovableText::H_LEFT)
373
			*pPCBuff++ = left;
374
		else
375
			*pPCBuff++ = left - (len / 2);
376
		*pPCBuff++ = top;
377
		*pPCBuff++ = -1.0;
378
		*pPCBuff++ = u2;
379
		*pPCBuff++ = v1;
380

  
381
		currPos = Ogre::Vector3(left, top, -1.0);
382
		min.makeFloor(currPos);
383
		max.makeCeil(currPos);
384
		maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
385

  
386
		top -= mCharHeight * 2.0;
387
		left -= horiz_height  * mCharHeight * 2.0;
388

  
389
		// Bottom left (again)
390
		if(mHorizontalAlignment == MovableText::H_LEFT)
391
			*pPCBuff++ = left;
392
		else
393
			*pPCBuff++ = left - (len / 2);
394
		*pPCBuff++ = top;
395
		*pPCBuff++ = -1.0;
396
		*pPCBuff++ = u1;
397
		*pPCBuff++ = v2;
398

  
399
		currPos = Ogre::Vector3(left, top, -1.0);
400
		min.makeFloor(currPos);
401
		max.makeCeil(currPos);
402
		maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
403

  
404
		left += horiz_height  * mCharHeight * 2.0;
405

  
406
		// Bottom right
407
		if(mHorizontalAlignment == MovableText::H_LEFT)
... This diff was truncated because it exceeds the maximum size that can be displayed.