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 //add a child object to the internal array
192 children.emplace_back(object);
193
194 //add child's scene node
195 if (object->GetSceneNode())
196 {
197 if (node)
198 node->AddChild(object->GetSceneNode());
199 else if (object->GetSceneNode())
200 //if parent doesn't have a scenenode, but child does, add child to engine root node
201 sbs->GetSceneNode()->AddChild(object->GetSceneNode());
202 }
203}
204
206{
207 //remove a child object in the internal array
208 if (GetChildrenCount() > 0)
209 {
210 for (int i = 0; i < GetChildrenCount(); i++)
211 {
212 if (children[i] == object)
213 {
214 children.erase(children.begin() + i);
215 break;
216 }
217 }
218 }
219
220 //remove child's scene node
221 if (node)
222 node->RemoveChild(object->GetSceneNode());
223}
224
226{
227 //return pointer to child object from an array index
228 if (index < (int)children.size())
229 return children[index];
230 else
231 return 0;
232}
233
235{
236 //return number of child objects
237 return (int)children.size();
238}
239
241{
242 return node;
243}
244
246{
247 //show object's 3D bounding box
248
249 if (node)
250 node->ShowBoundingBox(value);
251}
252
253void Object::Move(const Vector3 &vector, Real speed)
254{
255 //move an object
256
257 SBS_PROFILE("Object::Move");
258
259 if (!node)
260 return;
261
262 node->Move(vector, speed);
263
264 //notify about movement
265 NotifyMove();
266}
267
268void Object::Move(Real X, Real Y, Real Z, Real speed)
269{
270 Vector3 pos (X, Y, Z);
271 Move(pos, speed);
272}
273
274void Object::SetPosition(const Vector3 &position)
275{
276 //set position of object
277
278 if (!node)
279 return;
280
281 node->SetPosition(position);
282
283 //notify about movement
284 NotifyMove();
285}
286
288{
289 //set position of object
290 //position is relative of parent object
291
292 if (!node)
293 return;
294
295 node->SetPositionRelative(position);
296
297 //notify about movement
298 NotifyMove();
299}
300
302{
303 Vector3 pos (X, Y, Z);
304 SetPosition(pos);
305}
306
308{
309 Vector3 pos (X, Y, Z);
311}
312
314{
315 //set position of only Y vector
316
317 Vector3 pos (GetPosition().x, value, GetPosition().z);
318 SetPosition(pos);
319}
320
322{
323 //get position of object
324 //if relative is true, position is relative of parent object
325
326 if (!node)
327 return Vector3::ZERO;
328
329 return node->GetPosition(relative);
330}
331
332void Object::SetRotation(const Vector3 &rotation)
333{
334 //rotate object
335
336 SBS_PROFILE("Object::Rotate");
337
338 if (!node)
339 return;
340
341 node->SetRotation(rotation);
342
343 //notify about rotation
344 NotifyRotate();
345}
346
348{
349 Vector3 rot (X, Y, Z);
350 SetRotation(rot);
351}
352
353void Object::Rotate(const Vector3 &vector, Real speed)
354{
355 //rotates object in a relative amount
356
357 Vector3 rot = GetRotation() + (vector * speed);
358 SetRotation(rot);
359}
360
361void Object::Rotate(Real X, Real Y, Real Z, Real speed)
362{
363 Vector3 rot (X, Y, Z);
364 Rotate(rot, speed);
365}
366
368{
369 //get rotation of object
370
371 if (!node)
372 return Vector3::ZERO;
373
374 return node->GetRotation();
375}
376
378{
379 if (!node)
380 return Quaternion::ZERO;
381
382 return node->GetOrientation(relative);
383}
384
385void Object::SetOrientation(const Quaternion &q, bool relative)
386{
387 if (!node)
388 return;
389
390 return node->SetOrientation(q, relative);
391}
392
393void Object::NotifyMove(bool parent)
394{
395 //notify about a move
396 //if parent is true, this function was called from a parent object
397
398 if (!node)
399 return;
400
401 //sync positioning, for child scene nodes
402 if (parent == true)
403 node->Update();
404
405 NotifyChildren(true, false);
406 OnMove(parent);
407}
408
409void Object::NotifyRotate(bool parent)
410{
411 //notify about a rotate
412 //if parent is true, this function was called from a parent object
413
414 if (!node)
415 return;
416
417 //sync positioning, for child scene nodes
418 if (parent == true)
419 node->Update();
420
421 NotifyChildren(false, true);
422 OnRotate(parent);
423}
424
425void Object::NotifyChildren(bool move, bool rotate)
426{
427 //notify child objects about a parent move or rotate
428
429 SBS_PROFILE("Object::NotifyChildren");
430
431 int count = GetChildrenCount();
432
433 if (count == 0)
434 return;
435
436 for (int i = 0; i < count; i++)
437 {
438 if (move == true)
439 children[i]->NotifyMove(true);
440 if (rotate == true)
441 children[i]->NotifyRotate(true);
442 }
443}
444
446{
447 //change parent of object
448
449 //require valid parents
450 if (!Parent || !new_parent)
451 return;
452
453 if (new_parent == Parent)
454 return;
455
456 //get original positioning
457 Vector3 pos = GetPosition();
458
459 //get original orientation
460 Quaternion q;
461 if (node)
462 q = node->GetOrientation();
463
464 //switch parent
465 Parent->RemoveChild(this);
466 Parent = new_parent;
467 Parent->AddChild(this);
468
469 //restore absolute positioning
470 SetPosition(pos);
471
472 //restore orientation
473 if (node)
474 {
476 NotifyRotate();
477 }
478
479 sbs->Report("Changed parent of object '" + ToString(Number) + ": " + Name + "' to '" + ToString(new_parent->GetNumber()) + ": " + new_parent->GetName() + "'");
480}
481
483{
484 //returns true if object is a child of the SBS engine object (is a global object)
485
486 if (Number == 0 || !Parent)
487 return false;
488
489 return (Parent->GetNumber() == 0);
490}
491
492void Object::Init(bool children)
493{
494 //initialize object
495
496 //call custom object initialization code
497 if (initialized == false)
498 {
499 OnInit();
500 initialized = true;
501 }
502
503 //initialize children
504 if (children == true)
505 InitChildren();
506}
507
509{
510 //initialize child objects
511
512 int count = GetChildrenCount();
513
514 if (count == 0)
515 return;
516
517 for (int i = 0; i < count; i++)
518 children[i]->Init();
519}
520
521void Object::EnableLoop(bool value)
522{
523 //enable or disable dynamic runloop
524
525 if (!GetParent())
526 return;
527
528 if (loop_enabled == value)
529 return;
530
531 Object *parent = GetParent();
532 if (parent->GetType() == "Mesh")
533 parent = parent->GetParent();
534
535 if (value == true)
536 parent->RegisterLoop(this);
537 else
538 parent->UnregisterLoop(this);
539
540 loop_enabled = value;
541}
542
544{
545 //register a child object dynamic runloop
546
547 for (size_t i = 0; i < runloops.size(); i++)
548 {
549 if (runloops[i] == object)
550 return;
551 }
552
553 runloops.emplace_back(object);
554}
555
557{
558 //unregister a child object dynamic runloop
559
560 if (runloops.empty())
561 return;
562
563 if (runloops.back() == object)
564 {
565 runloops.pop_back();
566 return;
567 }
568
569 for (size_t i = 0; i < runloops.size(); i++)
570 {
571 if (runloops[i] == object)
572 {
573 runloops.erase(runloops.begin() + i);
574 return;
575 }
576 }
577}
578
580{
581 //run dynamic child runloops
582
583 for (size_t i = 0; i < runloops.size(); i++)
584 {
585 runloops[i]->Loop();
586 }
587}
588
590{
591 //have this object delete itself (make a deletion request to the sim engine root)
592 //this is a dangerous function; make sure no more calls are made to this object when calling this,
593 //and make sure that this is the last function called by this object
594
595 sbs->Report("Self-destructing object " + ToString(Number));
596 return sbs->DeleteObject(this);
597}
598
600{
601 //get base name of the scene node, which includes the instance and object ID
602
603 std::string number = ToString(GetNumber());
604
605 return ToString(sbs->InstanceNumber) + ":(" + number + ")";
606}
607
608}
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:139
virtual void OnRotate(bool parent)
Definition object.h:96
bool parent_deleting
Definition object.h:64
bool IsPermanent()
Definition object.cpp:166
virtual void SetRotation(const Vector3 &rotation)
Definition object.cpp:332
void RegisterLoop(Object *object)
Definition object.cpp:543
bool IsMovable()
Definition object.cpp:172
virtual void Move(const Vector3 &vector, Real speed=1.0)
Definition object.cpp:253
int linenum
Definition object.h:62
void LoopChildren()
Definition object.cpp:579
bool Permanent
Definition object.h:134
void ShowBoundingBox(bool value)
Definition object.cpp:245
void NotifyRotate(bool parent=false)
Definition object.cpp:409
virtual void SetPositionY(Real value)
Definition object.cpp:313
virtual Vector3 GetPosition(bool relative=false)
Definition object.cpp:321
void SetOrientation(const Quaternion &q, bool relative=false)
Definition object.cpp:385
void NotifyMove(bool parent=false)
Definition object.cpp:393
int GetNumber()
Definition object.cpp:183
SceneNode * GetSceneNode()
Definition object.cpp:240
void InitChildren()
Definition object.cpp:508
void SetPositionRelative(const Vector3 &position)
Definition object.cpp:287
std::vector< Object * > runloops
Definition object.h:141
std::string GetNameBase()
Definition object.cpp:599
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:377
bool initialized
Definition object.h:140
void UnregisterLoop(Object *object)
Definition object.cpp:556
void RemoveChild(Object *object)
Definition object.cpp:205
virtual void OnInit()
Definition object.h:106
virtual void OnMove(bool parent)
Definition object.h:95
void ChangeParent(Object *new_parent)
Definition object.cpp:445
virtual Vector3 GetRotation()
Definition object.cpp:367
int Number
Definition object.h:136
Object * GetChild(int index)
Definition object.cpp:225
void Init(bool children=true)
Definition object.cpp:492
int GetChildrenCount()
Definition object.cpp:234
std::vector< Object * > children
Definition object.h:137
void EnableLoop(bool value)
Definition object.cpp:521
bool IsGlobal()
Definition object.cpp:482
const std::string & GetType()
Definition object.cpp:177
bool loop_enabled
Definition object.h:142
std::string Type
Definition object.h:135
virtual ~Object()
Definition object.cpp:109
virtual void Rotate(const Vector3 &vector, Real speed=1.0)
Definition object.cpp:353
void NotifyChildren(bool move, bool rotate)
Definition object.cpp:425
void AddChild(Object *object)
Definition object.cpp:189
bool SelfDestruct()
Definition object.cpp:589
SceneNode * node
Definition object.h:138
virtual void SetPosition(const Vector3 &position)
Definition object.cpp:274
bool FastDelete
Definition sbs.h:188
int InstanceNumber
Definition sbs.h:197
int RegisterObject(Object *object)
Definition sbs.cpp:2461
std::string InstancePrompt
Definition sbs.h:430
std::string LastNotification
Definition sbs.h:190
std::string LastError
Definition sbs.h:189
bool UnregisterObject(int number)
Definition sbs.cpp:2469
bool DeleteObject(Object *object)
Definition sbs.cpp:2567
void ShowBoundingBox(bool value)
Definition scenenode.cpp:93
void RemoveChild(SceneNode *scenenode)
Definition scenenode.cpp:81
void SetPosition(const Vector3 &position)
Vector3 GetRotation()
void SetOrientation(const Quaternion &q, bool relative=false)
void Move(const Vector3 &vector, Real speed=1.0)
void DetachAllObjects()
Definition scenenode.cpp:65
void SetRotation(const Vector3 &rotation)
void SetPositionRelative(const Vector3 &position)
Vector3 GetPosition(bool relative=false)
Quaternion GetOrientation(bool relative=false)
void AddChild(SceneNode *scenenode)
Definition scenenode.cpp:73
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