OSDN Git Service

54c3aea21c71f76f8cc1c5eda49b8e4e51534fcc
[skyscrapersim/skyscraper.git] / src / sbs / movingwalkway.cpp
1 /* $Id$ */
2
3 /*
4         Scalable Building Simulator - Moving Walkway Object
5         The Skyscraper Project - Version 1.11 Alpha
6         Copyright (C)2004-2017 Ryan Thoryk
7         http://www.skyscrapersim.com
8         http://sourceforge.net/projects/skyscraper
9         Contact - ryan@skyscrapersim.com
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 "sbs.h"
28 #include "mesh.h"
29 #include "floor.h"
30 #include "sound.h"
31 #include "texture.h"
32 #include "profiler.h"
33 #include "dynamicmesh.h"
34 #include "step.h"
35 #include "movingwalkway.h"
36
37 namespace SBS {
38
39 MovingWalkway::MovingWalkway(Object *parent, const std::string &name, int run, float speed, const std::string &sound_file, const std::string &texture, const std::string &direction, float CenterX, float CenterZ, float width, float treadsize, int num_steps, float voffset, float tw, float th) : Object(parent)
40 {
41         //create a new moving walkway object
42         //run is either 1 for forward motion, -1 for reverse motion, 0 for stop
43         //direction is where the step base is - front, back, left, or right.
44
45         //set up SBS object
46         SetValues("MovingWalkway", "", false);
47
48         std::string Name;
49         Floor *floor = dynamic_cast<Floor*>(parent);
50         if (floor)
51                 Name = "Floor" + ToString(floor->Number) + ":"+ name;
52         else
53                 Name = name;
54         SetName(Name);
55
56         is_enabled = true;
57         SetRun(run);
58         Speed = speed;
59         sbs->IncrementMovingWalkwayCount();
60         start = 0;
61         end = 0;
62
63         //create sound object
64         sound = new Sound(this, name, true);
65         sound->Load(sound_file);
66
67         //move object
68         Move(CenterX, voffset, CenterZ);
69
70         //create step meshes
71         for (int i = 0; i < num_steps; i++)
72         {
73                 Step *mesh = new Step(this, "Step " + ToString(i + 1), 0, 100);
74                 Steps.push_back(mesh);
75         }
76
77         //create steps
78         CreateSteps(texture, direction, width, treadsize, tw, th);
79 }
80
81 MovingWalkway::~MovingWalkway()
82 {
83         if (sound)
84         {
85                 sound->parent_deleting = true;
86                 delete sound;
87         }
88         sound = 0;
89
90         //remove step meshes
91         for (size_t i = 0; i < Steps.size(); i++)
92         {
93                 if (Steps[i])
94                 {
95                         Steps[i]->parent_deleting = true;
96                         delete Steps[i];
97                 }
98                 Steps[i] = 0;
99         }
100
101         //unregister from parent
102         if (sbs->FastDelete == false)
103         {
104                 sbs->DecrementEscalatorCount();
105
106                 //unregister from parent
107                 if (parent_deleting == false)
108                 {
109                         std::string type = GetParent()->GetType();
110
111                         if (type == "Floor")
112                                 static_cast<Floor*>(GetParent())->RemoveMovingWalkway(this);
113                 }
114         }
115 }
116
117 void MovingWalkway::Enabled(bool value)
118 {
119         //enable or disable walkway
120
121         if (is_enabled == value)
122                 return;
123
124         EnableLoop(value);
125
126         for (size_t i = 0; i < Steps.size(); i++)
127                 Steps[i]->Enabled(value);
128
129         if (value == false && sound->IsPlaying() == true)
130                 sound->Stop();
131
132         is_enabled = value;
133 }
134
135 void MovingWalkway::SetRun(int value)
136 {
137         if (value == 0)
138         {
139                 for (size_t i = 0; i < Steps.size(); i++)
140                 {
141                         Steps[i]->vector = Ogre::Vector3::ZERO;
142                         Steps[i]->speed = 0;
143                 }
144         }
145
146         Run = value;
147 }
148
149 void MovingWalkway::Report(const std::string &message)
150 {
151         //general reporting function
152         Object::Report("Moving Walkway " + GetName() + ": " + message);
153 }
154
155 bool MovingWalkway::ReportError(const std::string &message)
156 {
157         //general reporting function
158         return Object::ReportError("Moving Walkway " + GetName() + ": " + message);
159 }
160
161 void MovingWalkway::Loop()
162 {
163         //run loop
164
165         SBS_PROFILE("MovingWalkway::Loop");
166
167         if (!IsEnabled() || Run == 0)
168         {
169                 if (sound->IsPlaying() == true)
170                         sound->Stop();
171                 return;
172         }
173
174         if (sound->IsPlaying() == false)
175         {
176                 sound->SetLoopState(true);
177                 sound->Play();
178         }
179
180         MoveSteps();
181 }
182
183 void MovingWalkway::CreateSteps(const std::string &texture, const std::string &direction, float width, float treadsize, float tw, float th)
184 {
185         //create steps
186         std::string Name = GetName();
187         TrimString(Name);
188         Direction = direction;
189         this->treadsize = treadsize;
190         SetCase(Direction, false);
191         int num_steps = (int)Steps.size();
192
193         sbs->GetTextureManager()->ResetTextureMapping(true);
194         if (Direction == "right" || Direction == "back")
195                 sbs->SetWallOrientation("right");
196         if (Direction == "left" || Direction == "front")
197                 sbs->SetWallOrientation("left");
198
199         for (int i = 1; i <= num_steps; i++)
200         {
201                 float pos = 0;
202                 std::string base = Name + ":" + ToString(i);
203
204                 //create wall object
205                 Wall *wall = Steps[i - 1]->CreateWallObject(base);
206
207                 float thickness = treadsize;
208
209                 sbs->DrawWalls(false, true, false, false, false, false);
210
211                 if (Direction == "right")
212                 {
213                         pos = ((treadsize * num_steps + 1) / 2) - (treadsize * i);
214                         sbs->AddFloorMain(wall, base, texture, 0, 0, -(width / 2), treadsize, width / 2, 0, 0, false, false, tw, th, true);
215                         Steps[i - 1]->Move(Ogre::Vector3(pos, 0, 0));
216                 }
217                 if (Direction == "left")
218                 {
219                         pos = -((treadsize * num_steps + 1) / 2) + (treadsize * i);
220                         sbs->AddFloorMain(wall, base, texture, 0, -treadsize, -(width / 2), 0, width / 2, 0, 0, false, false, tw, th, true);
221                         Steps[i - 1]->Move(Ogre::Vector3(pos, 0, 0));
222                 }
223                 if (Direction == "back")
224                 {
225                         pos = ((treadsize * num_steps + 1) / 2) - (treadsize * i);
226                         sbs->AddFloorMain(wall, base, texture, 0, -(width / 2), 0, width / 2, treadsize, 0, 0, false, false, tw, th, true);
227                         Steps[i - 1]->Move(Ogre::Vector3(0, 0, pos));
228                 }
229                 if (Direction == "front")
230                 {
231                         pos = -((treadsize * num_steps + 1) / 2) + (treadsize * i);
232                         sbs->AddFloorMain(wall, base, texture, 0, -(width / 2), -treadsize, width / 2, 0, 0, 0, false, false, tw, th, true);
233                         Steps[i - 1]->Move(Ogre::Vector3(0, 0, pos));
234                 }
235                 Steps[i - 1]->vector = Ogre::Vector3::ZERO;
236                 Steps[1 - 1]->speed = 0;
237
238                 if (i == 1)
239                         start = Steps[i - 1]->GetPosition();
240                 if (i == num_steps)
241                         end = Steps[i - 1]->GetPosition();
242                 Steps[i - 1]->start = Steps[i - 1]->GetPosition();
243         }
244
245         sbs->ResetWalls(true);
246         sbs->GetTextureManager()->ResetTextureMapping();
247 }
248
249 void MovingWalkway::MoveSteps()
250 {
251         for (size_t i = 0; i < Steps.size(); i++)
252         {
253                 if (Run == 1)
254                 {
255                         if (Direction == "right")
256                         {
257                                 float pos = Steps[i]->GetPosition().x;
258                                 if (pos < end.x - treadsize)
259                                         Steps[i]->SetPosition(start);
260                                 else
261                                         Steps[i]->Move(Ogre::Vector3(-Run, 0, 0), Speed * sbs->delta);
262                         }
263                         if (Direction == "left")
264                         {
265                                 float pos = Steps[i]->GetPosition().x;
266                                 if (pos > end.x + treadsize)
267                                         Steps[i]->SetPosition(start);
268                                 else
269                                         Steps[i]->Move(Ogre::Vector3(Run, 0, 0), Speed * sbs->delta);
270                         }
271                         if (Direction == "back")
272                         {
273                                 float pos = Steps[i]->GetPosition().z;
274                                 if (pos < end.z - treadsize)
275                                         Steps[i]->SetPosition(start);
276                                 else
277                                         Steps[i]->Move(Ogre::Vector3(0, 0, -Run), Speed * sbs->delta);
278                         }
279                         if (Direction == "front")
280                         {
281                                 float pos = Steps[i]->GetPosition().z;
282                                 if (pos > end.z + treadsize)
283                                         Steps[i]->SetPosition(start);
284                                 else
285                                         Steps[i]->Move(Ogre::Vector3(0, 0, Run), Speed * sbs->delta);
286                         }
287                 }
288                 else if (Run == -1)
289                 {
290                         if (Direction == "right")
291                         {
292                                 float pos = Steps[i]->GetPosition().x;
293                                 if (pos > start.x)
294                                         Steps[i]->SetPosition(Ogre::Vector3(end.x - treadsize, end.y, end.z));
295                                 else
296                                         Steps[i]->Move(Ogre::Vector3(-Run, 0, 0), Speed * sbs->delta);
297                         }
298                         if (Direction == "left")
299                         {
300                                 float pos = Steps[i]->GetPosition().x;
301                                 if (pos < start.x)
302                                         Steps[i]->SetPosition(Ogre::Vector3(end.x + treadsize, end.y, end.z));
303                                 else
304                                         Steps[i]->Move(Ogre::Vector3(Run, 0, 0), Speed * sbs->delta);
305                         }
306                         if (Direction == "back")
307                         {
308                                 float pos = Steps[i]->GetPosition().z;
309                                 if (pos > start.z)
310                                         Steps[i]->SetPosition(Ogre::Vector3(end.x, end.y, end.z - treadsize));
311                                 else
312                                         Steps[i]->Move(Ogre::Vector3(0, 0, -Run), Speed * sbs->delta);
313                         }
314                         if (Direction == "front")
315                         {
316                                 float pos = Steps[i]->GetPosition().z;
317                                 if (pos < start.z)
318                                         Steps[i]->SetPosition(Ogre::Vector3(end.x, end.y, end.z + treadsize));
319                                 else
320                                         Steps[i]->Move(Ogre::Vector3(0, 0, Run), Speed * sbs->delta);
321                         }
322                 }
323         }
324 }
325
326 void MovingWalkway::OnClick(Ogre::Vector3 &position, bool shift, bool ctrl, bool alt, bool right)
327 {
328         //cycle run stages if shift-click is performed
329
330         if (shift == true)
331         {
332                 if (Run == 1)
333                 {
334                         Run = 0;
335                         for (size_t i = 0; i < Steps.size(); i++)
336                         {
337                                 Steps[i]->vector = 0;
338                                 Steps[i]->speed = 0;
339                         }
340                 }
341                 else if (Run == 0)
342                         Run = -1;
343                 else if (Run == -1)
344                         Run = 1;
345         }
346 }
347
348 void MovingWalkway::ResetState()
349 {
350         //reset walkway state
351
352         Run = 0;
353         for (size_t i = 0; i < Steps.size(); i++)
354         {
355                 Steps[i]->SetPosition(Steps[i]->start);
356         }
357 }
358
359 }