123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464 |
- /*
- ** Copyright (C) 1996, 1997 Microsoft Corporation. All Rights Reserved.
- **
- ** File: utility.h
- **
- ** Author:
- **
- ** Description:
- ** Header file for the utility library. Basically a set of commonly
- ** used functions.
- **
- ** History:
- */
- #ifndef utl_h
- #define utl_h
- /*
- ** Disable some stupid warning messages that we really don't need and
- ** shouldn't be there (actually, set them to level 4 so I can still see
- ** them if I want to).
- */
- #define _exposed
- #include "CRC.h"
- class UTL;
- class List_utl;
- class Link_utl;
- class Lock_utl;
- template<class T, class Sink = NullFunc> class Slist_utl;
- template<class T, class Sink = NullFunc> class Slink_utl;
- template<class T> class Mlist_utl;
- template<class T> class Mlink_utl;
- struct FPOINT
- {
- float x;
- float y;
- };
- class Rotation;
- // These constants correspond to the maximum length of a file name or a
- // player name. They should correspond to the maximum lengths in the SQL
- // database (for Name and FileName custom data types). Longer names are
- // handled via truncation. DB versions do not include the NULL terminator
- const int c_cbFileNameDB = 12; // keep in sync with
- const int c_cbDescriptionDB = 200;
- const int c_cbNameDB = 24;
- const int c_cbLocAbrevDB = 8;
- const int c_cbFileName = c_cbFileNameDB + 1;
- const int c_cbDescription = c_cbDescriptionDB + 1;
- const int c_cbName = c_cbNameDB + 1;
- const int c_cbLocAbrev = c_cbLocAbrevDB + 1;
- const int c_cbCDKey = 32 + 1; // TODO: fill in the correct length
- const int c_cbPassportName = 256 + 1;
- class _exposed List_utl
- {
- public:
- /*
- ** Return the number of links in *this.
- */
- inline int n(void) const
- {
- return m_n;
- }
- protected:
- List_utl(void);
- inline ~List_utl(void)
- {
- }
- /*
- ** Set the first link of *this to f.
- */
- void first(Link_utl* f);
- /*
- ** Return the current first link in *this.
- */
- inline Link_utl* first(void) const
- {
- return m_first;
- }
- /*
- ** Set the last link of *this to l.
- */
- void last(Link_utl* l);
- /*
- ** Return the current last link in *this.
- */
- inline Link_utl* last(void) const
- {
- return m_last;
- }
- /*
- ** Return's the index'th element (index >= 0),
- ** or the list.n() + index'th element (index < 0).
- ** (note, list[-1] == list.last())
- */
- Link_utl* operator [] (int index) const;
- private:
- Link_utl* m_first;
- Link_utl* m_last;
- int m_n;
- friend class Link_utl;
- };
- class _exposed Link_utl
- {
- public:
- /*
- ** Remove *this from whatever list it is attached to & return true,
- ** do nothing & return false if not attached.
- */
- bool unlink(void);
- protected:
- Link_utl(void);
- ~Link_utl(void)
- {
- }
- /*
- ** Return the pointer to whatever list *this is attached to.
- */
- inline List_utl* list(void) const
- {
- return m_list;
- }
- /*
- ** Insert l immediately after *this & return true.
- ** Do nothing & return false if *this is not part of a list.
- */
- bool next(Link_utl* l);
- /*
- ** Return the next element in the list.
- */
- inline Link_utl* next(void) const
- {
- return m_next;
- }
- /*
- ** Insert l immediately before *this & return true.
- ** Do nothing & return false if *this is not part of a list.
- */
- bool txen(Link_utl* l);
- /*
- ** Return the previous element in the list.
- */
- inline Link_utl* txen(void) const
- {
- return m_txen;
- }
- protected:
- List_utl* m_list;
- Link_utl* m_next;
- Link_utl* m_txen;
- friend List_utl;
- };
- class _exposed Lock_utl
- {
- public:
- Lock_utl(void);
- ~Lock_utl(void);
- /*
- ** Lock or unlock the list. Lock/unlock pairs can be nested.
- ** We are technically lying about the const attribute but that
- ** seems fair since neither lock nor unlock actually modify the
- ** contents of the thing that is locked.
- */
- void lock(void) const;
- void unlock(void) const;
- private:
- HANDLE m_lockedS;
- DWORD m_locking_threadID;
- int m_locks;
- };
- /*
- ** Templated list of T, single thread safe.
- */
- template<class T, class Sink> class Slist_utl : public List_utl
- {
- protected:
- Sink sink;
- public:
- Slist_utl()
- {};
- Slist_utl(const Sink& _sink)
- : sink(_sink) {}
- inline ~Slist_utl(void)
- {
- purge();
- }
- /*
- ** Clear the list.
- ** If deleteF is true, all links are deleted.
- ** If deleteF is false, they are simply unlinked.
- **
- ** Note: when a list's destructor is called, purge(true) is called.
- */
- void purge(bool deleteF = true);
- /*
- ** Create a new Slink which contains a copy of t and
- ** make it the first element of the list. Returns false
- ** iff unable to allocate a new link.
- */
- bool first(const T& t);
- bool last(const T& t);
- /*
- ** These are equivalent to the List_utl versions.
- */
- inline void first(Slink_utl<T, Sink>* l)
- {
- List_utl::first(l);
- sink();
- }
- inline Slink_utl<T, Sink>* first(void) const
- {
- return (Slink_utl<T, Sink>*)List_utl::first();
- }
- inline void last(Slink_utl<T, Sink>* l)
- {
- List_utl::last(l);
- sink();
- }
- inline Slink_utl<T, Sink>* last(void) const
- {
- return (Slink_utl<T, Sink>*)List_utl::last();
- }
- inline Slink_utl<T, Sink>* find(const T& e) const
- {
- Slink_utl<T, Sink>* l;
- for (l = first(); ((l != NULL) && (l->data() != e)); l = l->next())
- {
- //Intentionally empty
- }
- return l;
- }
- inline Slink_utl<T, Sink>* operator [](int index) const
- {
- return (Slink_utl<T, Sink>*)List_utl::operator [](index);
- }
- friend class Slink_utl<T, Sink>;
- };
- /*
- ** Templated list element of T, single thread safe. Each element
- ** contains a copy of T, not a pointer to T.
- */
- template<class T, class Sink> class Slink_utl : public Link_utl
- {
- public:
- /*
- ** Use the default constructor for the data member.
- */
- inline Slink_utl(void)
- {
- }
- /*
- ** Use the copy constructor from t for the data member.
- */
- inline Slink_utl(const T& t)
- :
- m_data(t)
- {
- }
- inline ~Slink_utl(void)
- {
- if (list())
- unlink();
- }
- /*
- ** Return/set the data member of the link.
- */
- inline const T& data(void) const
- {
- return m_data;
- }
- inline T& data(void)
- {
- return m_data;
- }
- inline void data(const T& t)
- {
- m_data = t;
- list()->sink();
- }
- /*
- ** Create a new Slink which contains a copy of t,
- ** insert it after or before *this, and return true.
- ** Do nothing and return false if *this is not attached to a list.
- */
- bool next(const T& t);
- bool txen(const T& t);
- /*
- ** These are equivalent to the List_utl versions.
- */
- inline Slist_utl<T, Sink>* list(void) const
- {
- return (Slist_utl<T, Sink>*)Link_utl::list();
- }
- inline bool next(Slink_utl<T, Sink>* l)
- {
- return Link_utl::next(l);
- }
- inline Slink_utl<T, Sink>* next(void) const
- {
- return (Slink_utl<T, Sink>*)Link_utl::next();
- }
- inline bool txen(Slink_utl<T, Sink>* l)
- {
- return Link_utl::txen(l);
- }
- inline Slink_utl<T, Sink>* txen(void) const
- {
- return (Slink_utl<T, Sink>*)Link_utl::txen();
- }
- __forceinline bool unlink(void)
- {
- Slist_utl<T, Sink>* plist = list();
- bool result = Link_utl::unlink();
- plist->sink();
- return result;
- }
- private:
- T m_data;
- };
- /*
- ** Templated list of T, multi-thread safe (if locked/unlocked properly).
- */
- template<class T> class Mlist_utl : public List_utl, public Lock_utl
- {
- public:
- inline Mlist_utl(void)
- {
- }
- inline ~Mlist_utl(void)
- {
- purge();
- }
- /*
- ** Clear the list.
- */
- void purge(bool deleteF = true); //locked/unlocked
- /*
- ** Create a new Slink which contains a copy of t and
- ** make it the first element of the list. Returns false
- ** if unable to allocate a new link.
- */
- bool first(const T& t); //locked/unlocked
- bool last(const T& t); //locked/unlocked
- /*
- ** These are equivalent to the List_utl versions.
- */
- void first(Mlink_utl<T>* l); //locked/unlocked
- Mlink_utl<T>* first(void) const;
- void last(Mlink_utl<T>* l); //locked/unlocked
- Mlink_utl<T>* last(void) const;
- inline Mlink_utl<T>* find(const T& e) const
- {
- lock();
- Mlink_utl<T>* l;
- for (l = first(); ((l != NULL) && (l->data() != e)); l = l->next())
- {
- //Intentionally empty
- }
- unlock();
- return l;
- }
- Mlink_utl<T>* operator [](int) const;
- friend class Mlink_utl<T>;
- };
- /*
- ** Templated list element of T, multi-thread safe. Each element
- ** contains a copy of T, not a pointer to T.
- */
- template<class T> class Mlink_utl : public Link_utl
- {
- public:
- /*
- ** Use the default constructor for the data member.
- */
- inline Mlink_utl(void)
- {
- }
- /*
- ** Use the copy constructor from t for the data member.
- */
- inline Mlink_utl(const T& t)
- :
- m_data(t)
- {
- }
- inline ~Mlink_utl(void)
- {
- if (list())
- unlink();
- }
- /*
- ** Return the data member of the link.
- */
- inline const T& data(void) const
- {
- return m_data;
- }
- inline T& data(void)
- {
- return m_data;
- }
- inline void data(const T& t)
- {
- m_data = t;
- }
- /*
- ** Create a new Mlink which contains a copy of t,
- ** insert it after or before *this, and return true.
- ** Do nothing and return false if *this is not attached to a list.
- */
- bool next(const T& t);
- bool txen(const T& t);
- /*
- ** These are equivalent to the List_utl versions.
- */
- inline Mlist_utl<T>* list(void) const
- {
- return (Mlist_utl<T>*)Link_utl::list();
- }
- inline bool next(Mlink_utl<T>* l)
- {
- return Link_utl::next(l);
- }
- inline Mlink_utl<T>* next(void) const
- {
- return (Mlink_utl<T>*)Link_utl::next();
- }
- inline bool txen(Mlink_utl<T>* l)
- {
- return Link_utl::txen(l);
- }
- inline Mlink_utl<T>* txen(void) const
- {
- return (Mlink_utl<T>*)Link_utl::txen();
- }
- private:
- T m_data;
- };
- class Rotation
- {
- public:
- Rotation(void);
- Rotation(float x, float y, float z, float a)
- :
- m_axis(x, y, z),
- m_angle(a)
- {
- }
- Rotation(const Vector& xyz, float a)
- :
- m_axis(xyz),
- m_angle(a)
- {
- }
- Rotation(const Rotation&);
- void reset(void);
- void set(const Vector& axis,
- float angle);
- Rotation& operator = (const Rotation&);
- inline float x(void) const
- {
- return m_axis.x;
- }
- inline float y(void) const
- {
- return m_axis.y;
- }
- inline float z(void) const
- {
- return m_axis.z;
- }
- inline float angle(void) const
- {
- return m_angle;
- }
- inline const Vector& axis(void) const
- {
- return m_axis;
- }
- void axis(const Vector& v);
- void angle(float r);
- void x(float t);
- void y(float t);
- void z(float t);
- private:
- Vector m_axis;
- float m_angle;
- };
- const int c_cbFrameName = 20;
- class FrameDataUTL
- {
- public:
- char szName[c_cbFrameName];
- Vector position;
- Vector forward;
- friend bool operator!=(const FrameDataUTL& fd1, const FrameDataUTL& fd2)
- {
- return false;
- }
- };
- typedef Slist_utl<FrameDataUTL> FrameList;
- typedef Slink_utl<FrameDataUTL> FrameLink;
- const int c_nAxes = 3;
- const int c_maxHitTests = 100;
- const int c_minNodeSize = 5;
- const int c_minRootSize = 10;
- class Interval;
- class BoundingBox;
- class Endpoint;
- class HitTest;
- class KDnode;
- class KDroot;
- class CollisionEntry;
- class CollisionQueue;
- class Interval
- {
- public:
- float values[2]; //lo & hi endpoints.
- };
- class BoundingBox
- {
- public:
- Interval axes[c_nAxes];
- };
- class Endpoint
- {
- public:
- float value;
- HitTest* pHitTest;
- bool highF;
- //Bubble-sort based algorith: use when the list is mostly sorted
- static void shortSort(Endpoint** lo,
- Endpoint** hi);
- //Quick-sort based algorithm: the alternative to shortSort
- static void longSort(Endpoint** lo,
- Endpoint** hi);
- };
- class Transform44
- {
- public:
- inline Transform44(void)
- :
- m_position(Vector::GetZero()),
- m_orientation(Orientation::GetIdentity()),
- m_modifiedF(true)
- {
- }
- inline const Vector& GetPosition(void) const
- {
- return m_position;
- }
- inline void SetPosition(const Vector& xyz)
- {
- assert(xyz.Length() < 100000);
- m_position = xyz;
- m_modifiedF = true;
- }
- inline const Orientation& GetOrientation(void) const
- {
- return m_orientation;
- }
- inline void SetOrientation(const Orientation& o)
- {
- m_orientation = o;
- m_modifiedF = true;
- }
- inline const Matrix& GetMatrix(void)
- {
- if (m_modifiedF)
- {
- m_modifiedF = false;
- //m_matrix.SetTranslate(m_position);
- //m_matrix.SetOrientation(m_orientation);
- }
- return m_matrix;
- }
- private:
- Matrix m_matrix;
- Vector m_position;
- Orientation m_orientation;
- bool m_modifiedF;
- };
- typedef char HitTestShape;
- //These do not depend on orientation
- const HitTestShape c_htsPoint = -4;
- const HitTestShape c_htsSphere = -3;
- //And these do, but there is a "closed" form solution for whether a point is inside
- const HitTestShape c_htsEllipse = -2;
- const HitTestShape c_htsCone = -1;
- //but not for this ... the hts is actually the number of distinct
- //convex hulls within the hit test
- const HitTestShape c_htsConvexHullMin = 0;
- const HitTestShape c_htsConvexHullMax = 127;
- typedef void* HitTestID;
- HitTestID const c_htidStaticObject = (HitTestID)(0xffffffff);
- class MultiHullBase
- {
- public:
- MultiHullBase(const Vector& ellipseEquation,
- float originalRadius)
- :
- m_ellipseEquation(ellipseEquation),
- m_originalRadius(originalRadius)
- {
- }
- const Vector& GetFrameOffset(const char* pszFrameName) const
- {
- const FrameDataUTL* pfd = GetFrame(pszFrameName);
- return pfd ? pfd->position : Vector::GetZero();
- }
- const Vector& GetFrameForward(const char* pszFrameName) const
- {
- static const Vector z(0.0f, 0.0f, 1.0f);
- const FrameDataUTL* pfd = GetFrame(pszFrameName);
- return pfd ? pfd->forward : z;
- }
- const FrameDataUTL* GetFrame(const char* pszFrameName) const
- {
- for (FrameLink* pfl = m_frames.first();
- (pfl != NULL);
- pfl = pfl->next())
- {
- const FrameDataUTL& fd = pfl->data();
- if (strcmp(pszFrameName, fd.szName) == 0)
- {
- return &fd;
- }
- }
- return NULL;
- }
- const float GetOriginalRadius(void) const
- {
- return m_originalRadius;
- }
- const Vector& GetEllipseEquation(void) const
- {
- return m_ellipseEquation;
- }
- protected:
- FrameList m_frames;
- float m_originalRadius;
- Vector m_ellipseEquation;
- };
- class HitTest : public Transform44
- {
- public:
- static MultiHullBase* Load(const char* pszFileName);
- static HitTest* Create(const char* pszFileName,
- IObject* data,
- bool staticF,
- HitTestShape htsDefault = c_htsSphere);
- HitTest(IObject* data,
- float radius,
- bool staticF,
- HitTestShape shape)
- :
- m_cRefs(1),
- m_id(NULL),
- m_data(data),
- m_radius(radius),
- m_shape(shape),
- m_shapeTrue(shape),
- m_noHit(NULL),
- m_pvUseTrueShapeSelf(NULL),
- m_pvUseTrueShapeOther(NULL),
- m_deadF(true),
- m_deletedF(false),
- m_staticF(staticF),
- m_velocity(Vector::GetZero()),
- m_timeStart(0),
- m_timeStop(0),
- m_pkdrRoot(NULL)
- {
- assert (data);
- data->AddRef();
- m_endpoints[0][0].highF =
- m_endpoints[1][0].highF =
- m_endpoints[2][0].highF = false;
- m_endpoints[0][1].highF =
- m_endpoints[1][1].highF =
- m_endpoints[2][1].highF = true;
- m_endpoints[0][0].pHitTest = m_endpoints[0][1].pHitTest =
- m_endpoints[1][0].pHitTest = m_endpoints[1][1].pHitTest =
- m_endpoints[2][0].pHitTest = m_endpoints[2][1].pHitTest = this;
- //No addref on m_data ... this hit test is part of m_data
- }
- ~HitTest(void)
- {
- assert (m_data);
- m_data->Release();
- }
- ULONG __stdcall AddRef(void)
- {
- return ++m_cRefs;
- }
- ULONG __stdcall Release(void)
- {
- ULONG cRefs = --m_cRefs;
- if (cRefs == 0)
- delete this;
- return cRefs;
- }
- void SetStaticF(bool staticF)
- {
- m_staticF = staticF;
- }
- void SetBB(Time start, Time stop, float dt);
- void SetStopPosition(void)
- {
- m_stopPosition = GetPosition();
- if (m_tStop > 0.0f)
- m_stopPosition += m_tStop * m_velocity;
- assert (m_stopPosition.LengthSquared() >= 0.0f);
- assert (m_stopPosition.LengthSquared() < 1.0e12f);
- }
- void Move(float t)
- {
- if (!m_staticF)
- {
- SetPosition(GetPosition() + m_velocity * t);
- if (m_tStart <= t)
- m_tStart = 0.0f;
- else
- m_tStart -= t;
- m_tStop -= t;
- assert (GetPosition() * GetPosition() >= 0.0f);
- }
- }
- void AdjustTimes(float t)
- {
- if (!m_staticF)
- {
- if (m_tStart <= t)
- m_tStart = 0.0f;
- else
- m_tStart -= t;
- m_tStop -= t;
- }
- }
- void Move(void)
- {
- if (!m_staticF)
- SetPosition(m_stopPosition);
- }
- virtual void UpdateStaticBB(void)
- {
- UpdateStaticBB(m_radius);
- }
- void UpdateStaticBB(float r)
- {
- assert (m_staticF);
- //let's assume were using the xy & z axes.
- assert (c_nAxes == 3);
- for (int i = 0; (i < c_nAxes); i++)
- {
- float v = GetPosition()[i];
-
- m_boundingBox.axes[i].values[0] = v - r;
- m_boundingBox.axes[i].values[1] = v + r;
- m_endpoints[i][0].value = m_boundingBox.axes[i].values[0];
- m_endpoints[i][1].value = m_boundingBox.axes[i].values[1];
- }
- }
- void UpdateBB(void);
- void Collide(HitTest* pHitTest,
- CollisionQueue* pQueue);
- HitTestShape GetShape(void) const
- {
- return m_shape;
- }
- HitTestShape GetTrueShape(void) const
- {
- return m_shapeTrue;
- }
- virtual void SetShape(HitTestShape shape)
- {
- //Never upgrade to anything more complex than our true shape
- if (shape <= m_shapeTrue)
- m_shape = shape;
- }
- virtual const Vector* GetEllipseEquation(void) const
- {
- return NULL;
- }
- float GetRadius(void) const
- {
- return m_radius;
- }
- virtual void SetRadius(float r)
- {
- m_radius = r;
- }
- virtual float GetScale(void) const
- {
- return 1.0f;
- }
- bool GetDeadF(void) const
- {
- return m_deadF;
- }
- void SetDeadF(bool d)
- {
- m_deadF = d;
- }
- bool GetDeletedF(void) const
- {
- return m_deletedF;
- }
- void SetDeletedF(bool d)
- {
- m_deletedF = d;
- }
- IObject* GetData(void) const
- {
- return m_data;
- }
- HitTest* GetLastTest(void) const
- {
- return m_lastTest;
- }
- void SetLastTest(HitTest* ht)
- {
- m_lastTest = ht;
- }
- const Vector& GetVelocity(void) const
- {
- return m_velocity;
- }
- void SetVelocity(const Vector& v)
- {
- assert (v * v >= 0.0f);
- assert (v.LengthSquared() < (100000.0f * 100000.0f));
- m_velocity = v;
- }
- HitTestID GetID(void) const
- {
- return m_id;
- }
- void SetID(HitTestID id)
- {
- m_id = id;
- }
- HitTest* GetNoHit(void) const
- {
- return m_noHit;
- }
- void SetUseTrueShapeSelf(void* pvUseTrueShapeSelf)
- {
- m_pvUseTrueShapeSelf = pvUseTrueShapeSelf;
- }
- void SetUseTrueShapeOther(void* pvUseTrueShapeOther)
- {
- m_pvUseTrueShapeOther = pvUseTrueShapeOther;
- }
- void SetNoHit(HitTest* ht)
- {
- m_noHit = ht;
- }
- void SetTimeStart(Time t)
- {
- m_timeStart = t;
- }
- void SetTimeStop(Time t)
- {
- m_timeStop = t;
- }
- static bool HullCollide(float* tCollision,
- float tMax,
- HitTest* phtHullA,
- HitTestShape* phtsA,
- HitTest* phtHullB,
- HitTestShape* phtsB,
- const Vector& dP,
- const Vector& dV); //Sense for velocity is reversed from position
- static bool IntervalCollide(float tStart,
- float tStop,
- float maxDeltaT,
- HitTest* phtHullA,
- HitTestShape htsA,
- HitTest* phtHullB,
- HitTestShape htsB,
- const Vector& dP,
- const Vector& dV, //Sense for velocity is reversed from position
- const Orientation& orientationA,
- float* tCollision);
- Vector GetMinExtreme(HitTestShape hts,
- const Vector& position,
- const Orientation& orientation,
- const Vector& direction);
- //position is assumed to be 0, 0, 0; orientation is the identity
- Vector GetMaxExtreme(HitTestShape hts,
- const Vector& direction);
- virtual Vector GetCenter(HitTestShape hts) const
- {
- assert (false); //Should never be called for anything except convex hulls
- return Vector::GetZero();
- }
- void SetKDRoot(KDroot* pkdr)
- {
- m_pkdrRoot = pkdr;
- }
- KDroot* GetKDRoot(void) const
- {
- return m_pkdrRoot;
- }
- virtual const Vector GetFrameOffset(const char* pszFrameName) const
- {
- return Vector::GetZero();
- }
- virtual const Vector& GetFrameForward(const char* pszFrameName) const
- {
- static const Vector z(0.0f, 0.0f, 1.0f);
- return z;
- }
- virtual const FrameDataUTL* GetFrame(const char* pszFrameName) const
- {
- return NULL;
- }
- float GetTstop(void) const
- {
- return m_tStop;
- }
- protected:
- ULONG m_cRefs;
- IObject* m_data;
- void* m_pvUseTrueShapeSelf; //if m_useTrueShapeSelf != NULL and m_useTrueShapeSelf == pht->m_useTrueShapeOther
- void* m_pvUseTrueShapeOther; //then always use the true shape for purposes of collision detection & not the given shape
- KDroot* m_pkdrRoot;
- HitTest* m_noHit;
- HitTestID m_id;
- BoundingBox m_boundingBox;
- Vector m_stopPosition;
- Vector m_velocity;
- float m_radius;
- float m_tStart;
- float m_tStop;
- Time m_timeStart;
- Time m_timeStop;
- Endpoint m_endpoints[c_nAxes][2];
- HitTest* m_lastTest;
- HitTestShape m_shape;
- HitTestShape m_shapeTrue;
- bool m_deletedF;
- bool m_deadF;
- bool m_activeF;
- bool m_staticF;
-
- friend class KDnode;
- friend class KDroot;
- };
- typedef Slist_utl<HitTest*> HitTestList;
- typedef Slink_utl<HitTest*> HitTestLink;
- class KDnode
- {
- public:
- KDnode(KDnode* parent);
- ~KDnode(void);
- void reset(bool highF);
- void pivot(void);
- void test(HitTest* pHitTest,
- CollisionQueue* pQueue) const;
- protected:
- int m_pivotAxis;
- float m_pivotValue;
- KDnode* m_parent;
- KDnode* m_children[2];
- void allocHitTestsEndpoints(int n);
- int m_nHitTests;
- int m_maxHitTests;
- HitTest** m_ppHitTests;
- Endpoint** m_ppEndpoints[c_nAxes];
- };
- class KDroot : public KDnode
- {
- public:
- KDroot(bool bStatic);
- ~KDroot(void);
- void addHitTest(HitTest* pHitTest);
- void deleteHitTest(HitTest* pHitTest);
- void flush(void);
- void update(void);
- private:
- int m_nAdded;
- int m_nDeleted;
- bool m_bStatic;
- };
- class CollisionEntry
- {
- public:
- float m_tCollision;
- HitTest* m_pHitTest1;
- HitTest* m_pHitTest2;
- HitTestShape m_hts1;
- HitTestShape m_hts2;
- //Bubble-sort based algorith: use when the list is mostly sorted
- static void shortSort(CollisionEntry* lo,
- CollisionEntry* hi);
- //Quick-sort based algorithm: the alternative to shortSort
- static void longSort(CollisionEntry* lo,
- CollisionEntry* hi);
- };
- class CollisionQueue
- {
- public:
- CollisionQueue(void);
- CollisionQueue(int m_maxCollisions,
- CollisionEntry* pCollisions);
- ~CollisionQueue(void);
- inline int n(void) const
- {
- return m_nCollisions;
- }
- inline CollisionEntry& operator [] (int i)
- {
- return m_pCollisions[i];
- }
- void sort(int start);
- void flush(int start,
- HitTest* pHitTest1,
- HitTest* pHitTest2);
- void purge(void);
- void addCollision(float tCollision,
- HitTest* pHitTest1,
- HitTestShape hts1,
- HitTest* pHitTest2,
- HitTestShape hts2);
- private:
- int m_nCollisions;
- CollisionEntry* m_pCollisions;
- int m_maxCollisions;
- bool m_fDelete;
- };
- class UTL
- {
- public:
- //Get an artwork file, downloading if needed
- // S_OK ... file exists and has a non-zero length
- // S_FALSE ... file exists, but has a length of zero
- // E_FAIL ... file does not exist.
- static void SetArtPath(const char* szArtwork);
- static HRESULT getFile( const char* name,
- const char* extension,
- OUT char* artwork,
- bool downloadF,
- bool createF);
- // Writes a blob to disk; returns true iff successful
- static bool SaveFile( const char * szFilename,
- const void *pData,
- unsigned cLen,
- OUT char * szErrorMsg,
- bool bCreateAsTemp);
- static bool AppendFile(const char * szFileName, const void * data, unsigned bytes);
- static int SearchAndReplace(char * szDest, const char * szSource, const char * szNewWord, const char * szOldWord);
- static void SetUrlRoot(const char * szUrlRoot);
- //Like the stock strdup() except uses new [] and handles NULL
- static char* strdup(const char* s);
- //set allocated on demand strings, file names or names
- static void putFileName(char* name, const char* newVal);
- static void putName(char* name, const char* newVal);
- static const char* artworkPath(void)
- {
- return s_artworkPath;
- }
- static LONG GetPathFromReg(IN HKEY hkey,
- IN const char * szSubKey,
- OUT char * szPath);
- // converts char * of hex to int. Assumes uppercase for 'A' to 'F'.
- static int hextoi(const char * pHex);
- private:
- static char s_artworkPath[MAX_PATH];
- static char s_szUrlRoot[MAX_PATH];
- };
- class BytePercentage
- {
- public:
- enum
- {
- Divisor = 240 //Use 240 since it has so many nice factors (2, 3, 4, 5, 10, etc.)
- };
- BytePercentage(void)
- {
- }
- BytePercentage(const BytePercentage& p)
- :
- m_percentage(p.m_percentage)
- {
- }
- BytePercentage(float f)
- :
- m_percentage((unsigned char)(f * (float)Divisor + 0.5f))
- {
- assert ((f * (float)Divisor + 0.5f) >= 0.0f);
- assert ((f * (float)Divisor + 0.5f) < (float)(Divisor + 1));
- }
- unsigned char GetChar(void) const
- {
- return m_percentage;
- }
- void SetChar(unsigned char p)
- {
- m_percentage = p;
- }
- BytePercentage& operator = (float f)
- {
- assert ((f * (float)Divisor + 0.5f) >= 0.0f);
- assert ((f * (float)Divisor + 0.5f) < (float)(Divisor + 1));
- m_percentage = (unsigned char)(f * (float)Divisor + 0.5f);
- return *this;
- }
- operator float (void) const
- {
- return ((float)m_percentage) / ((float)Divisor);
- }
- private:
- unsigned char m_percentage;
- };
- extern const Rotation c_rotationZero;
- #include "utility.hxx"
- #undef _exposed
- // safe strcpy
- static char * Strcpy(char * szDst, const char * szSrc)
- {
- assert(szDst);
- return lstrcpyA(szDst, szSrc ? szSrc : "");
- }
-
- // safe strncpy
- static char * Strncpy(char * szDst, const char * szSrc, size_t cb)
- {
- assert(szDst);
- return strncpy(szDst, szSrc ? szSrc : "", cb);
- }
-
- // safe strcmp
- static int Strcmp(const char * szDst, const char * szSrc)
- {
- return lstrcmpA(szDst ? szDst : "", szSrc ? szSrc : "");
- }
- #define IMPLIES(x, y) (!(x) || (y))
- #define IFF(x, y) (!!(x) == !!(y))
- #include "listwrappers.h"
- // Class for temporary dll function use
- template <class Func> // signature of function to get, so that Proc can be used without casting
- class CTempFuncDll
- {
- public:
- CTempFuncDll(LPSTR szDLL, LPSTR szFunc)
- {
- hmod = LoadLibrary(szDLL);
- pfunc = (Func) ((hmod) ? GetProcAddress(hmod, szFunc) : 0);
- }
- ~CTempFuncDll()
- {
- FreeLibrary(hmod);
- }
- Func Call()
- {
- assert(pfunc);
- assert(!IsBadCodePtr((FARPROC)pfunc));
- return pfunc;
- }
- private:
- HMODULE hmod;
- Func pfunc;
- };
- class CTempTimer_OptimizedOut // timers do nothing in optimized builds
- {
- public:
- CTempTimer_OptimizedOut(const char * szName, float dtWarning) {}
- void Start() {}
- bool Stop(const char* format = NULL, ...) {return false;}
- DWORD LastInterval() {return 0;}
- };
- class CTimer
- {
- public:
- CTimer(const char * szName, float dtWarning) :
- m_szname(szName),
- m_time(0),
- m_dtWarning((DWORD)(1000.0f * dtWarning)),
- m_dtimemax(0),
- m_dtTotal(0)
- {
- }
- void Start()
- {
- m_time = Time::Now();
- }
- bool Stop(const char* format = NULL, ...) // returns whether this previous interval was a new record
- {
- m_dtimelast = Time::Now().clock() - m_time.clock();
- m_dtTotal += m_dtimelast;
- bool fExtra = false;
- bool fRecord = false;
- if (m_dtimelast > m_dtimemax)
- {
- debugf("Timer: %fs spent %s, %fs total (longest so far)\n", (float) m_dtimelast / 1000.f, m_szname, (float)m_dtTotal / 1000.f);
- m_dtimemax = m_dtimelast;
- fRecord = true;
- fExtra = true;
- }
- else if (m_dtimelast >= m_dtWarning)
- {
- debugf("Timer: %fs spent %s, %fs total\n", (float) m_dtimelast / 1000.0f, m_szname, (float)m_dtTotal / 1000.f);
- fExtra = true;
- }
- if (fExtra && format)
- {
- const size_t size = 256;
- char bfr[size];
- va_list vl;
- va_start(vl, format);
- _vsnprintf(bfr, size, format, vl);
- va_end(vl);
- debugf("^--%s\n", bfr);
- }
- return fRecord;
- }
- DWORD LastInterval() // in seconds
- {
- return m_dtimelast;
- }
- private:
- const char * m_szname;
- Time m_time;
- DWORD m_dtimelast;
- DWORD m_dtimemax;
- DWORD m_dtWarning;
- DWORD m_dtTotal;
- };
- #ifdef NDEBUG
- #define CTempTimer CTempTimer_OptimizedOut
- #else
- #define CTempTimer CTimer
- #endif
- #endif
|