00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined (INCLUDED_ENTITYLIB_H)
00023 #define INCLUDED_ENTITYLIB_H
00024
00025 #include "ireference.h"
00026 #include "debugging/debugging.h"
00027
00028 #include "ientity.h"
00029 #include "irender.h"
00030 #include "igl.h"
00031 #include "selectable.h"
00032
00033 #include "generic/callback.h"
00034 #include "math/aabb.h"
00035 #include "undolib.h"
00036 #include "string/pooledstring.h"
00037 #include "generic/referencecounted.h"
00038 #include "scenelib.h"
00039 #include "container/container.h"
00040 #include "eclasslib.h"
00041
00042 #include <list>
00043 #include <set>
00044
00045 inline void arrow_draw (const Vector3& origin, const Vector3& direction)
00046 {
00047 Vector3 up(0, 0, 1);
00048 Vector3 left(-direction[1], direction[0], 0);
00049
00050 Vector3 endpoint(origin + direction * 32.0);
00051
00052 Vector3 tip1(endpoint + direction * (-8.0) + up * (-4.0));
00053 Vector3 tip2(tip1 + up * 8.0);
00054 Vector3 tip3(endpoint + direction * (-8.0) + left * (-4.0));
00055 Vector3 tip4(tip3 + left * 8.0);
00056
00057 glBegin(GL_LINES);
00058
00059 glVertex3fv(origin);
00060 glVertex3fv(endpoint);
00061
00062 glVertex3fv(endpoint);
00063 glVertex3fv(tip1);
00064
00065 glVertex3fv(endpoint);
00066 glVertex3fv(tip2);
00067
00068 glVertex3fv(endpoint);
00069 glVertex3fv(tip3);
00070
00071 glVertex3fv(endpoint);
00072 glVertex3fv(tip4);
00073
00074 glVertex3fv(tip1);
00075 glVertex3fv(tip3);
00076
00077 glVertex3fv(tip3);
00078 glVertex3fv(tip2);
00079
00080 glVertex3fv(tip2);
00081 glVertex3fv(tip4);
00082
00083 glVertex3fv(tip4);
00084 glVertex3fv(tip1);
00085
00086 glEnd();
00087 }
00088
00089 class SelectionIntersection;
00090
00091 inline void aabb_testselect (const AABB& aabb, SelectionTest& test, SelectionIntersection& best)
00092 {
00093 const IndexPointer::index_type indices[24] = { 2, 1, 5, 6, 1, 0, 4, 5, 0, 1, 2, 3, 3, 7, 4, 0, 3, 2, 6, 7, 7, 6, 5,
00094 4, };
00095
00096 Vector3 points[8];
00097 aabb_corners(aabb, points);
00098 test.TestQuads(VertexPointer(reinterpret_cast<VertexPointer::pointer> (points), sizeof(Vector3)), IndexPointer(
00099 indices, 24), best);
00100 }
00101
00102 inline void aabb_draw_wire (const Vector3 points[8])
00103 {
00104 const unsigned char indices[] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
00105 glVertexPointer(3, GL_FLOAT, 0, points);
00106 glDrawElements(GL_LINES, sizeof(indices) / sizeof(indices[0]), GL_UNSIGNED_BYTE, indices);
00107 }
00108
00109 inline void aabb_draw_flatshade (const Vector3 points[8])
00110 {
00111 glBegin(GL_QUADS);
00112
00113 glNormal3fv(aabb_normals[0]);
00114 glVertex3fv(points[2]);
00115 glVertex3fv(points[1]);
00116 glVertex3fv(points[5]);
00117 glVertex3fv(points[6]);
00118
00119 glNormal3fv(aabb_normals[1]);
00120 glVertex3fv(points[1]);
00121 glVertex3fv(points[0]);
00122 glVertex3fv(points[4]);
00123 glVertex3fv(points[5]);
00124
00125 glNormal3fv(aabb_normals[2]);
00126 glVertex3fv(points[0]);
00127 glVertex3fv(points[1]);
00128 glVertex3fv(points[2]);
00129 glVertex3fv(points[3]);
00130
00131 glNormal3fv(aabb_normals[3]);
00132 glVertex3fv(points[0]);
00133 glVertex3fv(points[3]);
00134 glVertex3fv(points[7]);
00135 glVertex3fv(points[4]);
00136
00137 glNormal3fv(aabb_normals[4]);
00138 glVertex3fv(points[3]);
00139 glVertex3fv(points[2]);
00140 glVertex3fv(points[6]);
00141 glVertex3fv(points[7]);
00142
00143 glNormal3fv(aabb_normals[5]);
00144 glVertex3fv(points[7]);
00145 glVertex3fv(points[6]);
00146 glVertex3fv(points[5]);
00147 glVertex3fv(points[4]);
00148
00149 glEnd();
00150 }
00151
00152 inline void aabb_draw_wire (const AABB& aabb)
00153 {
00154 Vector3 points[8];
00155 aabb_corners(aabb, points);
00156 aabb_draw_wire(points);
00157 }
00158
00159 inline void aabb_draw_flatshade (const AABB& aabb)
00160 {
00161 Vector3 points[8];
00162 aabb_corners(aabb, points);
00163 aabb_draw_flatshade(points);
00164 }
00165
00166 inline void aabb_draw_textured (const AABB& aabb)
00167 {
00168 Vector3 points[8];
00169 aabb_corners(aabb, points);
00170
00171 glBegin(GL_QUADS);
00172
00173 glNormal3fv(aabb_normals[0]);
00174 glTexCoord2fv(aabb_texcoord_topleft);
00175 glVertex3fv(points[2]);
00176 glTexCoord2fv(aabb_texcoord_topright);
00177 glVertex3fv(points[1]);
00178 glTexCoord2fv(aabb_texcoord_botright);
00179 glVertex3fv(points[5]);
00180 glTexCoord2fv(aabb_texcoord_botleft);
00181 glVertex3fv(points[6]);
00182
00183 glNormal3fv(aabb_normals[1]);
00184 glTexCoord2fv(aabb_texcoord_topleft);
00185 glVertex3fv(points[1]);
00186 glTexCoord2fv(aabb_texcoord_topright);
00187 glVertex3fv(points[0]);
00188 glTexCoord2fv(aabb_texcoord_botright);
00189 glVertex3fv(points[4]);
00190 glTexCoord2fv(aabb_texcoord_botleft);
00191 glVertex3fv(points[5]);
00192
00193 glNormal3fv(aabb_normals[2]);
00194 glTexCoord2fv(aabb_texcoord_topleft);
00195 glVertex3fv(points[0]);
00196 glTexCoord2fv(aabb_texcoord_topright);
00197 glVertex3fv(points[1]);
00198 glTexCoord2fv(aabb_texcoord_botright);
00199 glVertex3fv(points[2]);
00200 glTexCoord2fv(aabb_texcoord_botleft);
00201 glVertex3fv(points[3]);
00202
00203 glNormal3fv(aabb_normals[3]);
00204 glTexCoord2fv(aabb_texcoord_topleft);
00205 glVertex3fv(points[0]);
00206 glTexCoord2fv(aabb_texcoord_topright);
00207 glVertex3fv(points[3]);
00208 glTexCoord2fv(aabb_texcoord_botright);
00209 glVertex3fv(points[7]);
00210 glTexCoord2fv(aabb_texcoord_botleft);
00211 glVertex3fv(points[4]);
00212
00213 glNormal3fv(aabb_normals[4]);
00214 glTexCoord2fv(aabb_texcoord_topleft);
00215 glVertex3fv(points[3]);
00216 glTexCoord2fv(aabb_texcoord_topright);
00217 glVertex3fv(points[2]);
00218 glTexCoord2fv(aabb_texcoord_botright);
00219 glVertex3fv(points[6]);
00220 glTexCoord2fv(aabb_texcoord_botleft);
00221 glVertex3fv(points[7]);
00222
00223 glNormal3fv(aabb_normals[5]);
00224 glTexCoord2fv(aabb_texcoord_topleft);
00225 glVertex3fv(points[7]);
00226 glTexCoord2fv(aabb_texcoord_topright);
00227 glVertex3fv(points[6]);
00228 glTexCoord2fv(aabb_texcoord_botright);
00229 glVertex3fv(points[5]);
00230 glTexCoord2fv(aabb_texcoord_botleft);
00231 glVertex3fv(points[4]);
00232
00233 glEnd();
00234 }
00235
00236 inline void aabb_draw_solid (const AABB& aabb, RenderStateFlags state)
00237 {
00238 if (state & RENDER_TEXTURE) {
00239 aabb_draw_textured(aabb);
00240 } else {
00241 aabb_draw_flatshade(aabb);
00242 }
00243 }
00244
00245 inline void aabb_draw (const AABB& aabb, RenderStateFlags state)
00246 {
00247 if (state & RENDER_FILL) {
00248 aabb_draw_solid(aabb, state);
00249 } else {
00250 aabb_draw_wire(aabb);
00251 }
00252 }
00253
00254 class RenderableSolidAABB: public OpenGLRenderable
00255 {
00256 const AABB& m_aabb;
00257 public:
00258 RenderableSolidAABB (const AABB& aabb) :
00259 m_aabb(aabb)
00260 {
00261 }
00262 void render (RenderStateFlags state) const
00263 {
00264 aabb_draw_solid(m_aabb, state);
00265 }
00266 };
00267
00268 class RenderableWireframeAABB: public OpenGLRenderable
00269 {
00270 const AABB& m_aabb;
00271 public:
00272 RenderableWireframeAABB (const AABB& aabb) :
00273 m_aabb(aabb)
00274 {
00275 }
00276 void render (RenderStateFlags state) const
00277 {
00278 aabb_draw_wire(m_aabb);
00279 }
00280 };
00281
00286 class KeyValue: public EntityKeyValue
00287 {
00288 typedef UnsortedSet<KeyObserver> KeyObservers;
00289
00290 std::size_t m_refcount;
00291 KeyObservers m_observers;
00292 std::string m_string;
00293 const char* m_empty;
00294 ObservedUndoableObject<std::string> m_undo;
00295 static EntityCreator::KeyValueChangedFunc m_entityKeyValueChanged;
00296 public:
00297
00298 KeyValue (const char* string, const char* empty) :
00299 m_refcount(0), m_string(string), m_empty(empty), m_undo(m_string, UndoImportCaller(*this))
00300 {
00301 notify();
00302 }
00303 ~KeyValue ()
00304 {
00305 ASSERT_MESSAGE(m_observers.empty(), "KeyValue::~KeyValue: observers still attached");
00306 }
00307
00308 static void setKeyValueChangedFunc (EntityCreator::KeyValueChangedFunc func)
00309 {
00310 m_entityKeyValueChanged = func;
00311 }
00312
00313 void IncRef ()
00314 {
00315 ++m_refcount;
00316 }
00317 void DecRef ()
00318 {
00319 if (--m_refcount == 0) {
00320 delete this;
00321 }
00322 }
00323
00324 void instanceAttach (MapFile* map)
00325 {
00326 m_undo.instanceAttach(map);
00327 }
00328 void instanceDetach (MapFile* map)
00329 {
00330 m_undo.instanceDetach(map);
00331 }
00332
00333 void attach (const KeyObserver& observer)
00334 {
00335 (*m_observers.insert(observer))(c_str());
00336 }
00337 void detach (const KeyObserver& observer)
00338 {
00339 observer(m_empty);
00340 m_observers.erase(observer);
00341 }
00342 const char* c_str () const
00343 {
00344 if (m_string.empty())
00345 return m_empty;
00346 return m_string.c_str();
00347 }
00348 void assign (const std::string& other)
00349 {
00350 if (m_string != other) {
00351 m_undo.save();
00352 m_string = other;
00353 notify();
00354 }
00355 }
00356
00357 void notify ()
00358 {
00359 m_entityKeyValueChanged();
00360 KeyObservers::reverse_iterator i = m_observers.rbegin();
00361 while (i != m_observers.rend()) {
00362 (*i++)(c_str());
00363 }
00364 }
00365
00366 void importState (const std::string& string)
00367 {
00368 m_string = string;
00369
00370 notify();
00371 }
00372 typedef MemberCaller1<KeyValue, const std::string&, &KeyValue::importState> UndoImportCaller;
00373 };
00374
00380 class EntityKeyValues: public Entity
00381 {
00382 public:
00383 typedef KeyValue Value;
00384
00385 static StringPool& getPool ()
00386 {
00387 return Static<StringPool, KeyContext>::instance();
00388 }
00389 private:
00390 static EntityCreator::KeyValueChangedFunc m_entityKeyValueChanged;
00391 static Counter* m_counter;
00392
00393 EntityClass* m_eclass;
00394
00395 class KeyContext
00396 {
00397 };
00398 typedef Static<StringPool, KeyContext> KeyPool;
00399 typedef PooledString<KeyPool> Key;
00400 typedef SmartPointer<KeyValue> KeyValuePtr;
00401 typedef UnsortedMap<Key, KeyValuePtr> KeyValues;
00402 KeyValues m_keyValues;
00403
00404 typedef UnsortedSet<Observer*> Observers;
00405 Observers m_observers;
00406
00407 ObservedUndoableObject<KeyValues> m_undo;
00408 bool m_instanced;
00409
00410 bool m_observerMutex;
00411
00412 void notifyInsert (const char* key, Value& value)
00413 {
00414 m_observerMutex = true;
00415 for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) {
00416 (*i)->insert(key, value);
00417 }
00418 m_observerMutex = false;
00419 }
00420 void notifyErase (const char* key, Value& value)
00421 {
00422 m_observerMutex = true;
00423 for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) {
00424 (*i)->erase(key, value);
00425 }
00426 m_observerMutex = false;
00427 }
00428 void forEachKeyValue_notifyInsert ()
00429 {
00430 for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00431 notifyInsert((*i).first.c_str(), *(*i).second);
00432 }
00433 }
00434 void forEachKeyValue_notifyErase ()
00435 {
00436 for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00437 notifyErase((*i).first.c_str(), *(*i).second);
00438 }
00439 }
00440
00441 void insert (const char* key, const KeyValuePtr& keyValue)
00442 {
00443 KeyValues::iterator i = m_keyValues.insert(KeyValues::value_type(key, keyValue));
00444 notifyInsert(key, *(*i).second);
00445
00446 if (m_instanced) {
00447 (*i).second->instanceAttach(m_undo.map());
00448 }
00449 }
00450
00451 void insert (const char* key, const char* value)
00452 {
00453 KeyValues::iterator i = m_keyValues.find(key);
00454 if (i != m_keyValues.end()) {
00455 (*i).second->assign(value);
00456 } else {
00457 m_undo.save();
00458 insert(key, KeyValuePtr(new KeyValue(value, EntityClass_valueForKey(*m_eclass, key))));
00459 }
00460 }
00461
00462 void erase (KeyValues::iterator i)
00463 {
00464 if (m_instanced) {
00465 (*i).second->instanceDetach(m_undo.map());
00466 }
00467
00468 Key key((*i).first);
00469 KeyValuePtr value((*i).second);
00470 m_keyValues.erase(i);
00471 notifyErase(key.c_str(), *value);
00472 }
00473
00474 void erase (const char* key)
00475 {
00476 KeyValues::iterator i = m_keyValues.find(key);
00477 if (i != m_keyValues.end()) {
00478 m_undo.save();
00479 erase(i);
00480 }
00481 }
00482
00488 const char* getKeyValueOrNull (const std::string& key) const
00489 {
00490 KeyValues::const_iterator i = m_keyValues.find(key.c_str());
00491 if (i != m_keyValues.end())
00492 return (*i).second->c_str();
00493 else
00494 return (const char*) 0;
00495 }
00496
00497 public:
00498 bool m_isContainer;
00499
00500 EntityKeyValues (EntityClass* eclass) :
00501 m_eclass(eclass), m_undo(m_keyValues, UndoImportCaller(*this)), m_instanced(false), m_observerMutex(false),
00502 m_isContainer(!eclass->fixedsize)
00503 {
00504 }
00505 EntityKeyValues (const EntityKeyValues& other) :
00506 Entity(other), m_eclass(&other.getEntityClass()), m_undo(m_keyValues, UndoImportCaller(*this)),
00507 m_instanced(false), m_observerMutex(false), m_isContainer(other.m_isContainer)
00508 {
00509 for (KeyValues::const_iterator i = other.m_keyValues.begin(); i != other.m_keyValues.end(); ++i) {
00510 insert((*i).first.c_str(), (*i).second->c_str());
00511 }
00512 }
00513 ~EntityKeyValues ()
00514 {
00515 for (Observers::iterator i = m_observers.begin(); i != m_observers.end();) {
00516
00517 (*i++)->clear();
00518 }
00519 ASSERT_MESSAGE(m_observers.empty(), "EntityKeyValues::~EntityKeyValues: observers still attached");
00520 }
00521
00522 static void setKeyValueChangedFunc (EntityCreator::KeyValueChangedFunc func)
00523 {
00524 m_entityKeyValueChanged = func;
00525 KeyValue::setKeyValueChangedFunc(func);
00526 }
00527 static void setCounter (Counter* counter)
00528 {
00529 m_counter = counter;
00530 }
00531
00532 void importState (const KeyValues& keyValues)
00533 {
00534 for (KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end();) {
00535 erase(i++);
00536 }
00537
00538 for (KeyValues::const_iterator i = keyValues.begin(); i != keyValues.end(); ++i) {
00539 insert((*i).first.c_str(), (*i).second);
00540 }
00541
00542 m_entityKeyValueChanged();
00543 }
00544 typedef MemberCaller1<EntityKeyValues, const KeyValues&, &EntityKeyValues::importState> UndoImportCaller;
00545
00546 void attach (Observer& observer)
00547 {
00548 ASSERT_MESSAGE(!m_observerMutex, "observer cannot be attached during iteration");
00549 m_observers.insert(&observer);
00550 for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00551 observer.insert((*i).first.c_str(), *(*i).second);
00552 }
00553 }
00554 void detach (Observer& observer)
00555 {
00556 ASSERT_MESSAGE(!m_observerMutex, "observer cannot be detached during iteration");
00557 m_observers.erase(&observer);
00558 for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00559 observer.erase((*i).first.c_str(), *(*i).second);
00560 }
00561 }
00562
00563 void forEachKeyValue_instanceAttach (MapFile* map)
00564 {
00565 for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00566 (*i).second->instanceAttach(map);
00567 }
00568 }
00569 void forEachKeyValue_instanceDetach (MapFile* map)
00570 {
00571 for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00572 (*i).second->instanceDetach(map);
00573 }
00574 }
00575
00576 void instanceAttach (MapFile* map)
00577 {
00578 if (m_counter != 0) {
00579 m_counter->increment();
00580 }
00581
00582 m_instanced = true;
00583 forEachKeyValue_instanceAttach(map);
00584 m_undo.instanceAttach(map);
00585 }
00586 void instanceDetach (MapFile* map)
00587 {
00588 if (m_counter != 0) {
00589 m_counter->decrement();
00590 }
00591
00592 m_undo.instanceDetach(map);
00593 forEachKeyValue_instanceDetach(map);
00594 m_instanced = false;
00595 }
00596
00597
00598 EntityClass& getEntityClass () const
00599 {
00600 return *m_eclass;
00601 }
00602 void forEachKeyValue (Visitor& visitor) const
00603 {
00604 for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00605 visitor.visit((*i).first.c_str(), (*i).second->c_str());
00606 }
00607 }
00608
00612 void setKeyValue (const std::string& key, const std::string& value)
00613 {
00614 if (value.empty()) {
00615 erase(key.c_str());
00616 } else {
00617 insert(key.c_str(), value.c_str());
00618 }
00619 m_entityKeyValueChanged();
00620 }
00621
00627 const char* getKeyValue (const std::string& key) const
00628 {
00629 const char* value = getKeyValueOrNull(key);
00630 if (value)
00631 return value;
00632 else
00633 return EntityClass_valueForKey(*m_eclass, key);
00634 }
00635
00639 void addMandatoryKeyValues ()
00640 {
00641 for (EntityClassAttributes::const_iterator i = m_eclass->m_attributes.begin(); i
00642 != m_eclass->m_attributes.end(); ++i) {
00643 if (i->second.m_mandatory && getKeyValueOrNull(i->first) == 0) {
00644 this->setKeyValue(i->first, m_eclass->getDefaultForAttribute(i->first));
00645 g_debug("addMandatoryKeyValues: adding %s\n", i->first.c_str());
00646 }
00647 }
00648 }
00649
00650 bool isContainer () const
00651 {
00652 return m_isContainer;
00653 }
00654 };
00655
00658 class ResourceReference
00659 {
00660 std::string m_name;
00661 Resource* m_resource;
00662 public:
00663 ResourceReference (const std::string& name) :
00664 m_name(name)
00665 {
00666 capture();
00667 }
00668 ResourceReference (const ResourceReference& other) :
00669 m_name(other.m_name)
00670 {
00671 capture();
00672 }
00673 ResourceReference& operator= (const ResourceReference& other)
00674 {
00675 ResourceReference tmp(other);
00676 tmp.swap(*this);
00677 return *this;
00678 }
00679 ~ResourceReference ()
00680 {
00681 GlobalReferenceCache().release(m_name);
00682 }
00683
00684 void capture ()
00685 {
00686 m_resource = GlobalReferenceCache().capture(m_name);
00687 }
00688
00689 const std::string& getName () const
00690 {
00691 return m_name;
00692 }
00693 void setName (const std::string& name)
00694 {
00695 ResourceReference tmp(name);
00696 tmp.swap(*this);
00697 }
00698
00699 void swap (ResourceReference& other)
00700 {
00701 std::swap(m_resource, other.m_resource);
00702 std::swap(m_name, other.m_name);
00703 }
00704
00705 void attach (ModuleObserver& observer)
00706 {
00707 m_resource->attach(observer);
00708 }
00709 void detach (ModuleObserver& observer)
00710 {
00711 m_resource->detach(observer);
00712 }
00713
00714 Resource* get ()
00715 {
00716 return m_resource;
00717 }
00718 };
00719
00720 namespace std
00721 {
00724 inline void swap (ResourceReference& self, ResourceReference& other)
00725 {
00726 self.swap(other);
00727 }
00728 }
00729
00730 #endif