Skyscraper 2.0
object.cpp
Go to the documentation of this file.
1/*
2 Scalable Building Simulator - Generic Object Class
3 The Skyscraper Project - Version 2.0
4 Copyright (C)2004-2024 Ryan Thoryk
5 https://www.skyscrapersim.net
6 https://sourceforge.net/projects/skyscraper/
7 Contact - ryan@skyscrapersim.net
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22*/
23
24#include <OgreLogManager.h>
25#include "globals.h"
26#include "sbs.h"
27#include "scenenode.h"
28#include "profiler.h"
29#include "object.h"
30
31namespace SBS {
32
34{
35 Parent = parent;
36 sbs = 0;
37
38 if (parent)
39 sbs = parent->GetRoot();
40}
41
43{
44 //return parent object
45 return Parent;
46}
47
49{
50 return sbs;
51}
52
53const std::string& ObjectBase::GetName()
54{
55 //return object name
56 return Name;
57}
58
60{
61 //get base name of the scene node, which includes the instance and object ID
62
63 std::string number;
64 if (Parent)
65 number = ToString(Parent->GetNumber());
66 else
67 number = ToString(sbs->GetNumber());
68
69 return ToString(sbs->InstanceNumber) + ":(" + number + ")";
70}
71
72void ObjectBase::SetName(const std::string &name)
73{
74 //set object name
75 Name = name;
76}
77
78void ObjectBase::Report(const std::string &message)
79{
80 Ogre::LogManager::getSingleton().logMessage(sbs->InstancePrompt + " " + message);
81 sbs->LastNotification = message;
82}
83
84bool ObjectBase::ReportError(const std::string &message)
85{
86 Ogre::LogManager::getSingleton().logMessage(sbs->InstancePrompt + " " + message, Ogre::LML_CRITICAL);
87 sbs->LastError = message;
88 return false;
89}
90
92{
93 Permanent = false;
94 linenum = 0;
95 Number = -1;
96 parent_deleting = false;
97 node = 0;
98 values_set = false;
99 initialized = false;
100 loop_enabled = false;
101
102 //register object with engine
103 if (parent)
104 Number = sbs->RegisterObject(this);
105 else
106 Number = 0; //root object
107}
108
110{
111 //remove object from engine
112
113 //clean up scene node
114 if (node)
116
117 //unregister this object from parent
118 if (sbs)
119 {
120 if (Parent && sbs->FastDelete == false)
121 {
122 EnableLoop(false);
123 Parent->RemoveChild(this);
124 }
125 }
126
127 //delete scene node
128 if (node)
129 delete node;
130 node = 0;
131
132 //exit if at end of engine deletion
133 if (!sbs)
134 return;
135
136 //if fastdelete is enabled, don't unregister (just delete)
137 if (sbs->FastDelete == true)
138 return;
139
141 sbs->Report("Deleted object " + ToString(Number) + ": " + Name);
142}
143
144void Object::SetValues(const std::string &type, const std::string &name, bool is_permanent, bool is_movable)
145{
146 //set object values
147
148 //exit if settings have already been set
149 if (values_set == true)
150 return;
151
152 values_set = true;
153 Permanent = is_permanent;
154 Type = type;
155 Name = name;
156
157 //create scene node object
158 if (is_movable == true)
159 node = new SceneNode(this, Name);
160
161 //register as child object if object has a valid parent
162 if (Parent)
163 Parent->AddChild(this);
164}
165
167{
168 //return permanent state
169 return Permanent;
170}
171
173{
174 return node != 0;
175}
176
177const std::string& Object::GetType()
178{
179 //return object type string
180 return Type;
181}
182
184{
185 //return object's global numeric identifier
186 return Number;
187}
188
190{
191 if (!object)
192 return;
193
194 //add a child object to the internal array
195 children.emplace_back(object);
196
197 //add child's scene node
198 if (object->GetSceneNode())
199 {
200 if (node)
201 node->AddChild(object->GetSceneNode());
202 else if (object->GetSceneNode())
203 //if parent doesn't have a scenenode, but child does, add child to engine root node
204 sbs->GetSceneNode()->AddChild(object->GetSceneNode());
205 }
206}
207
209{
210 if (!object)
211 return;
212
213 //remove a child object in the internal array
214 if (GetChildrenCount() > 0)
215 {
216 for (int i = 0; i < GetChildrenCount(); i++)
217 {
218 if (children[i] == object)
219 {
220 children.erase(children.begin() + i);
221 break;
222 }
223 }
224 }
225
226 //remove child's scene node
227 if (node)
228 node->RemoveChild(object->GetSceneNode());
229}
230
232{
233 //return pointer to child object from an array index
234 if (index < (int)children.size())
235 return children[index];
236 else
237 return 0;
238}
239
241{
242 //return number of child objects
243 return (int)children.size();
244}
245
247{
248 return node;
249}
250
252{
253 //show object's 3D bounding box
254
255 if (node)
256 node->ShowBoundingBox(value);
257}
258
259void Object::Move(const Vector3 &vector, Real speed, bool force)
260{
261 //move an object
262
263 SBS_PROFILE("Object::Move");
264
265 if (!node)
266 return;
267
268 node->Move(vector, speed, force);
269
270 //notify about movement
271 NotifyMove();
272}
273
274void Object::Move(Real X, Real Y, Real Z, Real speed, bool force)
275{
276 Vector3 pos (X, Y, Z);
277 Move(pos, speed, force);
278}
279
280void Object::SetPosition(const Vector3 &position, bool relative, bool force)
281{
282 //set position of object
283
284 if (!node)
285 return;
286
287 node->SetPosition(position, relative, force);
288
289 //notify about movement
290 NotifyMove();
291}
292
293void Object::SetPosition(Real X, Real Y, Real Z, bool relative, bool force)
294{
295 Vector3 pos (X, Y, Z);
296 SetPosition(pos, relative, force);
297}
298
299void Object::SetPositionY(Real value, bool force)
300{
301 //set position of only Y vector
302
303 Vector3 pos (GetPosition().x, value, GetPosition().z);
304 SetPosition(pos, false, force);
305}
306
308{
309 //get position of object
310 //if relative is true, position is relative of parent object
311
312 if (!node)
313 return Vector3::ZERO;
314
315 return node->GetPosition(relative);
316}
317
318void Object::SetRotation(const Vector3 &rotation)
319{
320 //rotate object
321
322 SBS_PROFILE("Object::Rotate");
323
324 if (!node)
325 return;
326
327 node->SetRotation(rotation);
328
329 //notify about rotation
330 NotifyRotate();
331}
332
334{
335 Vector3 rot (X, Y, Z);
336 SetRotation(rot);
337}
338
339void Object::Rotate(const Vector3 &vector, Real speed)
340{
341 //rotates object in a relative amount
342
343 Vector3 rot = GetRotation() + (vector * speed);
344 SetRotation(rot);
345}
346
347void Object::Rotate(Real X, Real Y, Real Z, Real speed)
348{
349 Vector3 rot (X, Y, Z);
350 Rotate(rot, speed);
351}
352
354{
355 //get rotation of object
356
357 if (!node)
358 return Vector3::ZERO;
359
360 return node->GetRotation();
361}
362
364{
365 if (!node)
366 return Quaternion::ZERO;
367
368 return node->GetOrientation(relative);
369}
370
371void Object::SetOrientation(const Quaternion &q, bool relative)
372{
373 if (!node)
374 return;
375
376 return node->SetOrientation(q, relative);
377}
378
379void Object::NotifyMove(bool parent)
380{
381 //notify about a move
382 //if parent is true, this function was called from a parent object
383
384 if (!node)
385 return;
386
387 //sync positioning, for child scene nodes
388 if (parent == true)
389 node->Update();
390
391 NotifyChildren(true, false);
392 OnMove(parent);
393}
394
395void Object::NotifyRotate(bool parent)
396{
397 //notify about a rotate
398 //if parent is true, this function was called from a parent object
399
400 if (!node)
401 return;
402
403 //sync positioning, for child scene nodes
404 if (parent == true)
405 node->Update();
406
407 NotifyChildren(false, true);
408 OnRotate(parent);
409}
410
411void Object::NotifyChildren(bool move, bool rotate)
412{
413 //notify child objects about a parent move or rotate
414
415 SBS_PROFILE("Object::NotifyChildren");
416
417 int count = GetChildrenCount();
418
419 if (count == 0)
420 return;
421
422 for (int i = 0; i < count; i++)
423 {
424 if (move == true)
425 children[i]->NotifyMove(true);
426 if (rotate == true)
427 children[i]->NotifyRotate(true);
428 }
429}
430
432{
433 //change parent of object
434
435 //require valid parents
436 if (!Parent || !new_parent)
437 return;
438
439 if (new_parent == Parent)
440 return;
441
442 //get original positioning
443 Vector3 pos = GetPosition();
444
445 //get original orientation
446 Quaternion q;
447 if (node)
448 q = node->GetOrientation();
449
450 //switch parent
451 Parent->RemoveChild(this);
452 Parent = new_parent;
453 Parent->AddChild(this);
454
455 //restore absolute positioning
456 SetPosition(pos);
457
458 //restore orientation
459 if (node)
460 {
462 NotifyRotate();
463 }
464
465 sbs->Report("Changed parent of object '" + ToString(Number) + ": " + Name + "' to '" + ToString(new_parent->GetNumber()) + ": " + new_parent->GetName() + "'");
466}
467
469{
470 //returns true if object is a child of the SBS engine object (is a global object)
471
472 if (Number == 0 || !Parent)
473 return false;
474
475 return (Parent->GetNumber() == 0);
476}
477
478void Object::Init(bool children)
479{
480 //initialize object
481
482 //call custom object initialization code
483 if (initialized == false)
484 {
485 OnInit();
486 initialized = true;
487 }
488
489 //initialize children
490 if (children == true)
491 InitChildren();
492}
493
495{
496 //initialize child objects
497
498 int count = GetChildrenCount();
499
500 if (count == 0)
501 return;
502
503 for (int i = 0; i < count; i++)
504 children[i]->Init();
505}
506
507void Object::EnableLoop(bool value)
508{
509 //enable or disable dynamic runloop
510
511 if (!GetParent())
512 return;
513
514 if (loop_enabled == value)
515 return;
516
517 Object *parent = GetParent();
518 if (parent->GetType() == "Mesh")
519 parent = parent->GetParent();
520
521 if (value == true)
522 parent->RegisterLoop(this);
523 else
524 parent->UnregisterLoop(this);
525
526 loop_enabled = value;
527}
528
530{
531 //register a child object dynamic runloop
532
533 if (!object)
534 return;
535
536 for (size_t i = 0; i < runloops.size(); i++)
537 {
538 if (runloops[i] == object)
539 return;
540 }
541
542 runloops.emplace_back(object);
543}
544
546{
547 //unregister a child object dynamic runloop
548
549 if (!object)
550 return;
551
552 if (runloops.empty())
553 return;
554
555 if (runloops.back() == object)
556 {
557 runloops.pop_back();
558 return;
559 }
560
561 for (size_t i = 0; i < runloops.size(); i++)
562 {
563 if (runloops[i] == object)
564 {
565 runloops.erase(runloops.begin() + i);
566 return;
567 }
568 }
569}
570
572{
573 //run dynamic child runloops
574
575 for (size_t i = 0; i < runloops.size(); i++)
576 {
577 if (runloops[i])
578 runloops[i]->Loop();
579 }
580}
581
583{
584 //have this object delete itself (make a deletion request to the sim engine root)
585 //this is a dangerous function; make sure no more calls are made to this object when calling this,
586 //and make sure that this is the last function called by this object
587
588 sbs->Report("Self-destructing object " + ToString(Number));
589 return sbs->DeleteObject(this);
590}
591
593{
594 //get base name of the scene node, which includes the instance and object ID
595
596 std::string number = ToString(GetNumber());
597
598 return ToString(sbs->InstanceNumber) + ":(" + number + ")";
599}
600
601}
friend class Object
Definition object.h:34
std::string GetNameBase()
Definition object.cpp:59
SBS * GetRoot()
Definition object.cpp:48
std::string Name
Definition object.h:52
Object * Parent
Definition object.h:51
const std::string & GetName()
Definition object.cpp:53
virtual bool ReportError(const std::string &message)
Definition object.cpp:84
Object * GetParent()
Definition object.cpp:42
ObjectBase(Object *parent)
Definition object.cpp:33
virtual void Report(const std::string &message)
Definition object.cpp:78
void SetName(const std::string &name)
Definition object.cpp:72
bool values_set
Definition object.h:138
virtual void OnRotate(bool parent)
Definition object.h:94
bool parent_deleting
Definition object.h:64
bool IsPermanent()
Definition object.cpp:166
virtual void SetRotation(const Vector3 &rotation)
Definition object.cpp:318
void RegisterLoop(Object *object)
Definition object.cpp:529
bool IsMovable()
Definition object.cpp:172
int linenum
Definition object.h:62
void LoopChildren()
Definition object.cpp:571
bool Permanent
Definition object.h:133
void ShowBoundingBox(bool value)
Definition object.cpp:251
void NotifyRotate(bool parent=false)
Definition object.cpp:395
virtual Vector3 GetPosition(bool relative=false)
Definition object.cpp:307
void SetOrientation(const Quaternion &q, bool relative=false)
Definition object.cpp:371
void NotifyMove(bool parent=false)
Definition object.cpp:379
int GetNumber()
Definition object.cpp:183
SceneNode * GetSceneNode()
Definition object.cpp:246
void InitChildren()
Definition object.cpp:494
std::vector< Object * > runloops
Definition object.h:140
std::string GetNameBase()
Definition object.cpp:592
void SetValues(const std::string &type, const std::string &name, bool is_permanent, bool is_movable=true)
Definition object.cpp:144
Quaternion GetOrientation(bool relative=false)
Definition object.cpp:363
bool initialized
Definition object.h:139
virtual void Move(const Vector3 &vector, Real speed=1.0, bool force=false)
Definition object.cpp:259
void UnregisterLoop(Object *object)
Definition object.cpp:545
void RemoveChild(Object *object)
Definition object.cpp:208
virtual void OnInit()
Definition object.h:104
virtual void OnMove(bool parent)
Definition object.h:93
void ChangeParent(Object *new_parent)
Definition object.cpp:431
virtual Vector3 GetRotation()
Definition object.cpp:353
int Number
Definition object.h:135
Object * GetChild(int index)
Definition object.cpp:231
void Init(bool children=true)
Definition object.cpp:478
int GetChildrenCount()
Definition object.cpp:240
std::vector< Object * > children
Definition object.h:136
void EnableLoop(bool value)
Definition object.cpp:507
bool IsGlobal()
Definition object.cpp:468
const std::string & GetType()
Definition object.cpp:177
bool loop_enabled
Definition object.h:141
virtual void SetPosition(const Vector3 &position, bool relative=false, bool force=false)
Definition object.cpp:280
std::string Type
Definition object.h:134
virtual void SetPositionY(Real value, bool force=false)
Definition object.cpp:299
virtual ~Object()
Definition object.cpp:109
virtual void Rotate(const Vector3 &vector, Real speed=1.0)
Definition object.cpp:339
void NotifyChildren(bool move, bool rotate)
Definition object.cpp:411
void AddChild(Object *object)
Definition object.cpp:189
bool SelfDestruct()
Definition object.cpp:582
SceneNode * node
Definition object.h:137
bool FastDelete
Definition sbs.h:188
int InstanceNumber
Definition sbs.h:197
int RegisterObject(Object *object)
Definition sbs.cpp:2491
std::string InstancePrompt
Definition sbs.h:432
std::string LastNotification
Definition sbs.h:190
std::string LastError
Definition sbs.h:189
bool UnregisterObject(int number)
Definition sbs.cpp:2499
bool DeleteObject(Object *object)
Definition sbs.cpp:2597
void ShowBoundingBox(bool value)
Definition scenenode.cpp:94
void RemoveChild(SceneNode *scenenode)
Definition scenenode.cpp:82
Vector3 GetRotation()
void SetOrientation(const Quaternion &q, bool relative=false)
void SetPosition(const Vector3 &position, bool relative=false, bool force=false)
void Move(const Vector3 &vector, Real speed=1.0, bool force=false)
void DetachAllObjects()
Definition scenenode.cpp:66
void SetRotation(const Vector3 &rotation)
Vector3 GetPosition(bool relative=false)
Quaternion GetOrientation(bool relative=false)
void AddChild(SceneNode *scenenode)
Definition scenenode.cpp:74
Ogre::Vector3 Vector3
Definition globals.h:58
Ogre::Real Real
Definition globals.h:57
Ogre::Quaternion Quaternion
Definition globals.h:60
std::string ToString(int number)
Definition globals.cpp:279
#define SBS_PROFILE(name)
Definition profiler.h:131