00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Entity.h"
00018 #include "GameManager.h"
00019
00020
00021
00022
00023 u32 Entity::mIDCount = 0;
00024
00025
00026 Entity::Entity(const std::string &name, Entity *parent, AssetGroup *group)
00027 : pParent(NULL), pAssetGroup(group), mName(name), mPosition(0, 0, 0), mIsAddingChild(false)
00028 {
00029 mID = mIDCount++;
00030
00031
00032 createEventSlot("onPositionChange");
00033 createEventSlot("onRotationChange");
00034 createEventSlot("onUpdate");
00035 createEventSlot("onRender");
00036 createEventSlot("onPause");
00037 createEventSlot("onUnPause");
00038
00039
00040 setParent(parent);
00041 }
00042
00043
00044 Entity::~Entity()
00045 {
00046
00047 removeChildren();
00048 removeComponents();
00049 removeParent();
00050 }
00051
00052
00053 u32 Entity::getID() const
00054 {
00055 return mID;
00056 }
00057
00058
00059 const std::string& Entity::getName() const
00060 {
00061 return mName;
00062 }
00063
00064
00065 bool Entity::addChild(Entity *entity)
00066 {
00067
00068 if(mIsAddingChild)
00069 return true;
00070
00071
00072 if(entity == NULL)
00073 return false;
00074
00075
00076 if(getChild(entity->getName()))
00077 return false;
00078
00079
00080 mIsAddingChild = true;
00081 entity->setParent(this);
00082 mIsAddingChild = false;
00083
00084 mChildren.push_back(entity);
00085 entity->grab();
00086
00087 return true;
00088 }
00089
00090
00091 bool Entity::addComponent(EntityComponent *component)
00092 {
00093
00094 if(component == NULL)
00095 return false;
00096
00097
00098 if(getComponent(component->getName()))
00099 return false;
00100
00101
00102 mComponents.push_back(component);
00103 component->grab();
00104
00105 return true;
00106 }
00107
00108
00109 AssetGroup* Entity::getAssetGroup()
00110 {
00111 return pAssetGroup;
00112 }
00113
00114
00115 Entity* Entity::getChild(const u32 id)
00116 {
00117 for(u32 i = 0; i < mChildren.size(); i++)
00118 {
00119 if(mChildren[i]->getID() == id)
00120 return mChildren[i];
00121 }
00122
00123 return NULL;
00124 }
00125
00126
00127 Entity* Entity::getChild(const std::string &name)
00128 {
00129 for(u32 i = 0; i < mChildren.size(); i++)
00130 {
00131 if(mChildren[i]->getName() == name)
00132 return mChildren[i];
00133 }
00134
00135 return NULL;
00136 }
00137
00138
00139 EntityComponent* Entity::getComponent(const u32 id)
00140 {
00141 for(u32 i = 0; i < mComponents.size(); i++)
00142 {
00143 if(mComponents[i]->getID() == id)
00144 return mComponents[i];
00145 }
00146
00147 return NULL;
00148 }
00149
00150
00151 EntityComponent* Entity::getComponent(const std::string &name)
00152 {
00153 for(u32 i = 0; i < mComponents.size(); i++)
00154 {
00155 if(mComponents[i]->getName() == name)
00156 return mComponents[i];
00157 }
00158
00159 return NULL;
00160 }
00161
00162
00163 Entity* Entity::getParent() const
00164 {
00165 return pParent;
00166 }
00167
00168
00169 const vector3df& Entity::getAbsolutePosition() const
00170 {
00171 return mAbsolutePosition;
00172 }
00173
00174
00175 const vector3df& Entity::getPosition() const
00176 {
00177 return mPosition;
00178 }
00179
00180
00181 const vector3df& Entity::getAbsoluteRotation() const
00182 {
00183 return mAbsoluteRotation;
00184 }
00185
00186
00187 const vector3df& Entity::getRotation() const
00188 {
00189 return mRotation;
00190 }
00191
00192
00193 bool Entity::loadXML(const std::string &fileName)
00194 {
00195
00196 IFileSystem *fileSystem = GameManager::Instance()->getDevice()->getFileSystem();
00197
00198
00199 if(!fileSystem->existFile(fileName.c_str()))
00200 return false;
00201
00202
00203 IXMLReader *file = fileSystem->createXMLReader(fileName.c_str());
00204
00205 bool result = loadXML(file);
00206
00207 file->drop();
00208 return result;
00209 }
00210
00211
00212 bool Entity::loadXML(IXMLReader *file)
00213 {
00214
00215 if(!file)
00216 return false;
00217
00218
00219 while(file->read())
00220 {
00221 switch(file->getNodeType())
00222 {
00223 case io::EXN_ELEMENT:
00224
00225
00226 if(stringw("Entity") == file->getNodeName())
00227 {
00228 stringc parentFile = file->getAttributeValue(L"parent");
00229
00230
00231 if(parentFile != "")
00232 {
00233
00234 Entity *retrievedParent = NULL;
00235
00236 if(pAssetGroup != NULL)
00237 {
00238 EntityProcessor *processor = static_cast<EntityProcessor*>
00239 (pAssetGroup->getAssetProcessor("entities"));
00240
00241 retrievedParent = processor->getEntity(parentFile.c_str());
00242 }
00243
00244 else
00245 retrievedParent = GameManager::Instance()->getEntityManager()->getEntity(parentFile.c_str());
00246
00247 if(retrievedParent == NULL && pAssetGroup == NULL)
00248 {
00249 if(GameManager::Instance()->getEntityManager()->getEntity(mName) != NULL)
00250 {
00251 retrievedParent = GameManager::Instance()->getEntityManager()->
00252 createEntityFromXML(parentFile.c_str());
00253 }
00254
00255 else
00256 {
00257 retrievedParent = GameManager::Instance()->getEntityManager()->
00258 createEntityFromXML(parentFile.c_str(), NULL, NULL, false);
00259 }
00260 }
00261
00262
00263 if(retrievedParent != NULL)
00264 setParent(retrievedParent);
00265 }
00266 }
00267
00268
00269 if(stringw("absolutePosition") == file->getNodeName())
00270 {
00271 setAbsolutePosition(vector3df( file->getAttributeValueAsFloat(L"x"),
00272 file->getAttributeValueAsFloat(L"y"),
00273 file->getAttributeValueAsFloat(L"z") ));
00274 }
00275
00276
00277 else if(stringw("position") == file->getNodeName())
00278 {
00279 setPosition(vector3df( file->getAttributeValueAsFloat(L"x"),
00280 file->getAttributeValueAsFloat(L"y"),
00281 file->getAttributeValueAsFloat(L"z") ));
00282 }
00283
00284
00285 else if(stringw("absoluteRotation") == file->getNodeName())
00286 {
00287 setAbsoluteRotation(vector3df( file->getAttributeValueAsFloat(L"x"),
00288 file->getAttributeValueAsFloat(L"y"),
00289 file->getAttributeValueAsFloat(L"z") ));
00290 }
00291
00292
00293 else if(stringw("rotation") == file->getNodeName())
00294 {
00295 setRotation(vector3df( file->getAttributeValueAsFloat(L"x"),
00296 file->getAttributeValueAsFloat(L"y"),
00297 file->getAttributeValueAsFloat(L"z") ));
00298 }
00299
00300
00301 else if(stringw("components") == file->getNodeName())
00302 parseComponentsXML(file, this);
00303
00304 break;
00305
00306 case io::EXN_ELEMENT_END:
00307
00308
00309 if(stringw("Entity") == file->getNodeName())
00310 return true;
00311
00312 break;
00313
00314 default:
00315 break;
00316 }
00317 }
00318
00319
00320 return false;
00321 }
00322
00323
00324 void Entity::removeChildren()
00325 {
00326 while(mChildren.size() > 0)
00327 {
00328
00329
00330 mChildren[0]->removeParent();
00331 }
00332 }
00333
00334
00335 void Entity::removeComponents()
00336 {
00337 for(u32 i = 0; i < mComponents.size(); i++)
00338 mComponents[i]->drop();
00339
00340 mComponents.clear();
00341 }
00342
00343
00344 bool Entity::removeChild(Entity *entity)
00345 {
00346
00347 if(entity == NULL)
00348 return false;
00349
00350
00351 vector<Entity*>::iterator it;
00352
00353 for(it = mChildren.begin(); it < mChildren.end(); it++)
00354 {
00355 Entity *ent = *it;
00356
00357 if(ent == entity)
00358 {
00359 mChildren.erase(it);
00360 ent->removeParent();
00361 ent->drop();
00362 return true;
00363 }
00364 }
00365
00366
00367 return false;
00368 }
00369
00370
00371 bool Entity::removeChild(const u32 id)
00372 {
00373
00374 vector<Entity*>::iterator it;
00375
00376 for(it = mChildren.begin(); it < mChildren.end(); it++)
00377 {
00378 Entity *ent = *it;
00379
00380 if(ent->getID() == id)
00381 {
00382 mChildren.erase(it);
00383 ent->removeParent();
00384 ent->drop();
00385 return true;
00386 }
00387 }
00388
00389
00390 return false;
00391 }
00392
00393
00394 bool Entity::removeChild(const std::string &name)
00395 {
00396
00397 vector<Entity*>::iterator it;
00398
00399 for(it = mChildren.begin(); it < mChildren.end(); it++)
00400 {
00401 Entity *ent = *it;
00402
00403 if(ent->getName() == name)
00404 {
00405 mChildren.erase(it);
00406 ent->removeParent();
00407 ent->drop();
00408 return true;
00409 }
00410 }
00411
00412
00413 return false;
00414 }
00415
00416
00417 bool Entity::removeComponent(EntityComponent *component)
00418 {
00419
00420 if(component == NULL)
00421 return false;
00422
00423
00424 vector<EntityComponent*>::iterator it;
00425
00426 for(it = mComponents.begin(); it < mComponents.end(); it++)
00427 {
00428 EntityComponent *comp = *it;
00429
00430 if(comp == component)
00431 {
00432 comp->drop();
00433 mComponents.erase(it);
00434 return true;
00435 }
00436 }
00437
00438
00439 return false;
00440 }
00441
00442
00443 bool Entity::removeComponent(const u32 id)
00444 {
00445
00446 vector<EntityComponent*>::iterator it;
00447
00448 for(it = mComponents.begin(); it < mComponents.end(); it++)
00449 {
00450 EntityComponent *comp = *it;
00451
00452 if(comp->getID() == id)
00453 {
00454 comp->drop();
00455 mComponents.erase(it);
00456 return true;
00457 }
00458 }
00459
00460
00461 return false;
00462 }
00463
00464
00465 bool Entity::removeComponent(const std::string &name)
00466 {
00467
00468 vector<EntityComponent*>::iterator it;
00469
00470 for(it = mComponents.begin(); it < mComponents.end(); it++)
00471 {
00472 EntityComponent *comp = *it;
00473
00474 if(comp->getName() == name)
00475 {
00476 comp->drop();
00477 mComponents.erase(it);
00478 return true;
00479 }
00480 }
00481
00482
00483 return false;
00484 }
00485
00486
00487 void Entity::removeParent()
00488 {
00489 if(pParent != NULL)
00490 {
00491 Entity *parent = pParent;
00492 pParent = NULL;
00493
00494 parent->removeChild(this);
00495 parent->drop();
00496
00497 parent->disconnectEventSignal("onPositionChange", this);
00498 parent->disconnectEventSignal("onRotationChange", this);
00499 parent->disconnectEventSignal("onUpdate", this);
00500 parent->disconnectEventSignal("onRender", this);
00501 parent->disconnectEventSignal("onPause", this);
00502 parent->disconnectEventSignal("onUnPause", this);
00503 }
00504 }
00505
00506
00507 void Entity::setAbsolutePosition(const vector3df &position)
00508 {
00509 vector3df diff = position - mAbsolutePosition;
00510
00511 mAbsolutePosition = position;
00512 mPosition += diff;
00513
00514 emitEvent("onPositionChange", &diff);
00515 }
00516
00517
00518 void Entity::setPosition(const vector3df &position)
00519 {
00520 vector3df diff = position - mPosition;
00521
00522 mPosition = position;
00523 mAbsolutePosition += diff;
00524
00525 emitEvent("onPositionChange", &diff);
00526 }
00527
00528
00529 bool Entity::setParent(Entity *parent)
00530 {
00531
00532 if(parent == NULL)
00533 return false;
00534
00535
00536
00537
00538 grab();
00539
00540
00541 removeParent();
00542
00543
00544 if(!parent->addChild(this))
00545 {
00546 drop();
00547 return false;
00548 }
00549
00550 pParent = parent;
00551 pParent->grab();
00552
00553
00554 setAbsolutePosition(pParent->getAbsolutePosition());
00555 setPosition(pParent->getPosition());
00556
00557 setAbsoluteRotation(pParent->getAbsoluteRotation());
00558 setRotation(pParent->getRotation());
00559
00560
00561 pParent->connectEventSignal("onPositionChange", this, &Entity::onPositionChange);
00562 pParent->connectEventSignal("onRotationChange", this, &Entity::onRotationChange);
00563 pParent->connectEventSignal("onUpdate", this, &Entity::onUpdate);
00564 pParent->connectEventSignal("onRender", this, &Entity::onRender);
00565 pParent->connectEventSignal("onPause", this, &Entity::onPause);
00566 pParent->connectEventSignal("onUnPause", this, &Entity::onUnPause);
00567
00568
00569 drop();
00570
00571 return true;
00572 }
00573
00574
00575 void Entity::setAbsoluteRotation(const vector3df &rotation)
00576 {
00577 vector3df diff = rotation - mAbsoluteRotation;
00578
00579 mAbsoluteRotation = rotation;
00580 mRotation += diff;
00581
00582 emitEvent("onRotationChange", &diff);
00583 }
00584
00585
00586 void Entity::setRotation(const vector3df &rotation)
00587 {
00588 vector3df diff = rotation - mRotation;
00589
00590 mRotation = rotation;
00591 mAbsoluteRotation += diff;
00592
00593 emitEvent("onRotationChange", &diff);
00594 }
00595
00596
00597 void Entity::onPositionChange(void *p)
00598 {
00599 vector3df diff = reinterpret_cast<vector3df*>(p)[0];
00600
00601 mAbsolutePosition += diff;
00602 mPosition += diff;
00603
00604 emitEvent("onPositionChange", &diff);
00605 }
00606
00607
00608 void Entity::onRotationChange(void *p)
00609 {
00610 vector3df diff = reinterpret_cast<vector3df*>(p)[0];
00611
00612 mAbsoluteRotation += diff;
00613 mRotation += diff;
00614
00615 emitEvent("onRotationChange", &diff);
00616 }
00617
00618
00619 void Entity::onUpdate(void *p)
00620 {
00621 emitEvent("onUpdate", p);
00622 }
00623
00624
00625 void Entity::onRender(void *p)
00626 {
00627 emitEvent("onRender", p);
00628 }
00629
00630
00631 void Entity::onPause(void *p)
00632 {
00633 emitEvent("onPause", p);
00634 }
00635
00636
00637 void Entity::onUnPause(void *p)
00638 {
00639 emitEvent("onUnPause", p);
00640 }
00641
00642