OSDN Git Service

1c2e3ec645272d92c961dd04e3f08aac0fc347b2
[skyscrapersim/skyscraper.git] / src / directional.cpp
1 /* $Id$ */
2
3 /*
4         Scalable Building Simulator - Directional Indicator Class
5         The Skyscraper Project - Version 1.5 Alpha
6         Copyright (C)2005-2009 Ryan Thoryk
7         http://www.skyscrapersim.com
8         http://sourceforge.net/projects/skyscraper
9         Contact - ryan@tliquest.net
10
11         This program is free software; you can redistribute it and/or
12         modify it under the terms of the GNU General Public License
13         as published by the Free Software Foundation; either version 2
14         of the License, or (at your option) any later version.
15
16         This program is distributed in the hope that it will be useful,
17         but WITHOUT ANY WARRANTY; without even the implied warranty of
18         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19         GNU General Public License for more details.
20
21         You should have received a copy of the GNU General Public License
22         along with this program; if not, write to the Free Software
23         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24 */
25
26 #include "globals.h"
27 #include "directional.h"
28 #include "sbs.h"
29 #include "elevator.h"
30
31 extern SBS *sbs; //external pointer to the SBS engine
32
33 DirectionalIndicator::DirectionalIndicator(int elevator, int floor, bool single, bool vertical, const char *BackTexture, const char *uptexture, const char *uptexture_lit, const char *downtexture, const char *downtexture_lit, float CenterX, float CenterZ, float voffset, const char *direction, float BackWidth, float BackHeight, bool ShowBack, float tw, float th)
34 {
35         //create a directional indicator
36
37         IsEnabled = true;
38         elevator_num = elevator;
39         floor_num = floor;
40         Direction = direction;
41         UpTextureUnlit = uptexture;
42         UpTextureLit = uptexture_lit;
43         DownTextureUnlit = downtexture;
44         DownTextureLit = downtexture_lit;
45         UpStatus = false;
46         DownStatus = false;
47         Single = single;
48         Vertical = vertical;
49
50         //create object mesh
51         csString buffer, buffer2, buffer3;
52         buffer2 = elevator;
53         buffer3 = floor;
54         buffer = "Directional Indicator " + buffer2 + ":" + buffer3 + ":Back";
55         buffer.Trim();
56         DirectionalMeshBack = sbs->engine->CreateSectorWallsMesh (sbs->area, buffer.GetData());
57         Directional_back_state = scfQueryInterface<iThingFactoryState> (DirectionalMeshBack->GetMeshObject()->GetFactory());
58         DirectionalMeshBack->SetZBufMode(CS_ZBUF_USE);
59         DirectionalMeshBack->SetRenderPriority(sbs->engine->GetObjectRenderPriority());
60
61         if (Single == false)
62         {
63                 buffer = "Directional Indicator " + buffer2 + ":" + buffer3 + ":Up";
64                 DirectionalMeshUp = CS::Geometry::GeneralMeshBuilder::CreateFactoryAndMesh(sbs->engine, sbs->area, buffer, buffer + " factory");
65                 DirectionalMeshUp->SetZBufMode(CS_ZBUF_USE);
66                 DirectionalMeshUp->SetRenderPriority(sbs->engine->GetObjectRenderPriority());
67                 csRef<iMaterialWrapper> mat = sbs->engine->GetMaterialList()->FindByName(UpTextureUnlit);
68                 DirectionalMeshUp->GetMeshObject()->SetMaterialWrapper(mat);
69
70                 buffer = "Directional Indicator " + buffer2 + ":" + buffer3 + ":Down";
71                 DirectionalMeshDown = CS::Geometry::GeneralMeshBuilder::CreateFactoryAndMesh(sbs->engine, sbs->area, buffer, buffer + " factory");
72                 DirectionalMeshDown->SetZBufMode(CS_ZBUF_USE);
73                 DirectionalMeshDown->SetRenderPriority(sbs->engine->GetObjectRenderPriority());
74                 mat = sbs->engine->GetMaterialList()->FindByName(DownTextureUnlit);
75                 DirectionalMeshDown->GetMeshObject()->SetMaterialWrapper(mat);
76         }
77         else
78         {
79                 buffer = "Directional Indicator " + buffer2 + ":" + buffer3 + ":Arrow";
80                 DirectionalMesh = CS::Geometry::GeneralMeshBuilder::CreateFactoryAndMesh(sbs->engine, sbs->area, buffer, buffer + " factory");
81                 DirectionalMesh->SetZBufMode(CS_ZBUF_USE);
82                 DirectionalMesh->SetRenderPriority(sbs->engine->GetAlphaRenderPriority());
83                 DirectionalMesh->GetMeshObject()->SetMixMode(CS_FX_ALPHA);
84                 csRef<iMaterialWrapper> mat = sbs->engine->GetMaterialList()->FindByName(UpTextureUnlit);
85                 DirectionalMesh->GetMeshObject()->SetMaterialWrapper(mat);
86         }
87
88         sbs->ResetTextureMapping(true);
89
90         //create panel
91         if (ShowBack == true)
92         {
93                 if (Direction == "front" || Direction == "back")
94                 {
95                         if (Direction == "front")
96                                 sbs->DrawWalls(true, false, false, false, false, false);
97                         else
98                                 sbs->DrawWalls(false, true, false, false, false, false);
99                         sbs->AddWallMain(Directional_back_state, "Panel", BackTexture, 0, CenterX - (BackWidth / 2), CenterZ, CenterX + (BackWidth / 2), CenterZ, BackHeight, BackHeight, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset, tw, th);
100                         sbs->ResetWalls();
101                 }
102                 if (Direction == "left" || Direction == "right")
103                 {
104                         if (Direction == "left")
105                                 sbs->DrawWalls(true, false, false, false, false, false);
106                         else
107                                 sbs->DrawWalls(false, true, false, false, false, false);
108                         sbs->AddWallMain(Directional_back_state, "Panel", BackTexture, 0, CenterX, CenterZ + (BackWidth / 2), CenterX, CenterZ - (BackWidth / 2), BackHeight, BackHeight, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset, tw, th);
109                         sbs->ResetWalls();
110                 }
111         }
112
113         //create indicator lanterns
114         int bottomfloor = sbs->GetElevator(elevator)->GetBottomFloor();
115         int topfloor = sbs->GetElevator(elevator)->GetTopFloor();
116
117         if (Direction == "front" || Direction == "back")
118         {
119                 float x1, x2;
120                 float offset;
121                 if (Direction == "front")
122                 {
123                         offset = -0.01f;
124                         x1 = CenterX - (BackWidth / 4);
125                         x2 = CenterX + (BackWidth / 4);
126                 }
127                 else
128                 {
129                         offset = 0.01f;
130                         x2 = CenterX - (BackWidth / 4);
131                         x1 = CenterX + (BackWidth / 4);
132                 }
133                 if (Single == false)
134                 {
135                         if (Vertical == true)
136                         {
137                                 if (floor > bottomfloor && floor < topfloor)
138                                 {
139                                         sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 4), 1, 1);
140                                         sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 7), 1, 1);
141                                 }
142                                 else
143                                 {
144                                         if (floor < topfloor)
145                                                 sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
146                                         if (floor > bottomfloor)
147                                                 sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
148                                 }
149                         }
150                         else
151                         {
152                                 //horizontal lights
153                                 if (floor > bottomfloor && floor < topfloor)
154                                 {
155                                         float x3, x4;
156                                         if (Direction == "front")
157                                         {
158                                                 x1 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 4);
159                                                 x2 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 6);
160                                                 x3 = (CenterX - (BackWidth / 2)) + (BackWidth / 7);
161                                                 x4 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 3);
162                                         }
163                                         else
164                                         {
165                                                 x1 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 6);
166                                                 x2 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7) * 4);
167                                                 x3 = (CenterX - (BackWidth / 2)) + ((BackWidth / 7)) * 3;
168                                                 x4 = (CenterX - (BackWidth / 2)) + (BackWidth / 7);
169                                         }
170                                         sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
171                                         sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, x3, CenterZ + offset, x4, CenterZ + offset, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
172                                 }
173                                 else
174                                 {
175                                         if (floor < topfloor)
176                                                 sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
177                                         if (floor > bottomfloor)
178                                                 sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
179                                 }
180                         }
181                 }
182                 else
183                         sbs->AddGenWall(DirectionalMesh, UpTextureUnlit, x1, CenterZ + offset, x2, CenterZ + offset, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
184         }
185         else
186         {
187                 float z1, z2;
188                 float offset;
189                 if (Direction == "left")
190                 {
191                         offset = -0.01f;
192                         z2 = CenterZ - (BackWidth / 4);
193                         z1 = CenterZ + (BackWidth / 4);
194                 }
195                 else
196                 {
197                         //right
198                         offset = 0.01f;
199                         z1 = CenterZ - (BackWidth / 4);
200                         z2 = CenterZ + (BackWidth / 4);
201                 }
202                 if (Single == false)
203                 {
204                         if (Vertical == true)
205                         {
206                                 if (floor > bottomfloor && floor < topfloor)
207                                 {
208                                         sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 4), 1, 1);
209                                         sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 7), 1, 1);
210                                 }
211                                 else
212                                 {
213                                         if (floor < topfloor)
214                                                 sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
215                                         if (floor > bottomfloor)
216                                                 sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
217                                 }
218                         }
219                         else
220                         {
221                                 //horizontal lights
222                                 if (floor > bottomfloor && floor < topfloor)
223                                 {
224                                         float z3, z4;
225                                         if (Direction == "left")
226                                         {
227                                                 z1 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 6);
228                                                 z2 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 4);
229                                                 z3 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7)) * 3;
230                                                 z4 = (CenterZ - (BackWidth / 2)) + (BackWidth / 7);
231                                         }
232                                         else
233                                         {
234                                                 z1 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 4);
235                                                 z2 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 6);
236                                                 z3 = (CenterZ - (BackWidth / 2)) + (BackWidth / 7);
237                                                 z4 = (CenterZ - (BackWidth / 2)) + ((BackWidth / 7) * 3);
238                                         }
239                                         sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
240                                         sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, CenterX + offset, z3, CenterX + offset, z4, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
241                                 }
242                                 else
243                                 {
244                                         if (floor < topfloor)
245                                                 sbs->AddGenWall(DirectionalMeshUp, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
246                                         if (floor > bottomfloor)
247                                                 sbs->AddGenWall(DirectionalMeshDown, DownTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 7) * 2, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + ((BackHeight / 7) * 2.5), 1, 1);
248                                 }
249                         }
250                 }
251                 else
252                         sbs->AddGenWall(DirectionalMesh, UpTextureUnlit, CenterX + offset, z1, CenterX + offset, z2, (BackHeight / 6) * 4, sbs->GetFloor(floor)->Altitude + sbs->GetFloor(floor)->InterfloorHeight + voffset + (BackHeight / 6), 1, 1);
253         }
254         sbs->ResetTextureMapping();
255 }
256
257 DirectionalIndicator::~DirectionalIndicator()
258 {
259
260 }
261
262 void DirectionalIndicator::Enabled(bool value)
263 {
264         //turns panel on/off
265         if (value == IsEnabled)
266                 return;
267
268         sbs->EnableMesh(DirectionalMeshBack, value);
269         if (DirectionalMeshUp)
270                 sbs->EnableMesh(DirectionalMeshUp, value);
271         if (DirectionalMeshDown)
272                 sbs->EnableMesh(DirectionalMeshDown, value);
273         if (DirectionalMesh)
274                 sbs->EnableMesh(DirectionalMesh, value);
275
276         IsEnabled = value;
277 }
278
279 void DirectionalIndicator::UpLight(bool value)
280 {
281         //turn on the 'up' directional light
282         if (value == UpStatus)
283                 return;
284
285         //exit if indicator is disabled
286         if (IsEnabled == false)
287                 return;
288
289         //set light status
290         if (value == true)
291                 SetLights(1, 0);
292         else
293                 SetLights(2, 0);
294
295         UpStatus = value;
296 }
297
298 void DirectionalIndicator::DownLight(bool value)
299 {
300         //turn on the 'down' directional light
301         if (value == DownStatus)
302                 return;
303
304         //exit if indicator is disabled
305         if (IsEnabled == false)
306                 return;
307
308         //set light status
309         if (value == true)
310                 SetLights(0, 1);
311         else
312                 SetLights(0, 2);
313
314         DownStatus = value;
315 }
316
317 void DirectionalIndicator::SetLights(int up, int down)
318 {
319         //set status of directional lights
320         //values are 0 for no change, 1 for on, and 2 for off
321
322         if (Single == false)
323         {
324                 if (up == 1 && DirectionalMeshUp)
325                         sbs->ChangeTexture(DirectionalMeshUp, UpTextureLit);
326                 if (up == 2 && DirectionalMeshUp)
327                         sbs->ChangeTexture(DirectionalMeshUp, UpTextureUnlit);
328                 if (down == 1 && DirectionalMeshDown)
329                         sbs->ChangeTexture(DirectionalMeshDown, DownTextureLit);
330                 if (down == 2 && DirectionalMeshDown)
331                         sbs->ChangeTexture(DirectionalMeshDown, DownTextureUnlit);
332         }
333         else
334         {
335                 if (DirectionalMesh)
336                 {
337                         if (up == 1)
338                                 sbs->ChangeTexture(DirectionalMesh, UpTextureLit);
339                         if (down == 1)
340                                 sbs->ChangeTexture(DirectionalMesh, DownTextureLit);
341                         if (up == 2 || down == 2)
342                                 sbs->ChangeTexture(DirectionalMesh, UpTextureUnlit);
343                 }
344         }
345 }