Shard Posted January 4, 2010 Share Posted January 4, 2010 I've been watching the Raycasting tutorial video and looking over the article and its lead to me a critical question: how do you trace back the entity to a programmer created class? For example, my player controller is inside my Player class, which has his health, jump height, shields, etc in it. When I do a raycast it will give me an entity pointer. Using this, how would I check to see if the entity pointer is my player class or just a random crate? One possible solution would be to compare all my player objects pointers with the pointer result from the raycast to see if they point to the same block of memory but this seems like an awful lot of processing to do. Is there another way? 1 1 Quote Programmer/Engineer/Student www.reikumar.com 2.6 GHz Intel Core Duo - nVidia GeForce 8600 GT - Windows 7 64-bit - 4 Gigs RAM C++ - Visual Studio Express - Dark GDK - Leadwerks SDK Link to comment Share on other sites More sharing options...
Josh Posted January 4, 2010 Share Posted January 4, 2010 Entity user data. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
TylerH Posted January 4, 2010 Share Posted January 4, 2010 Will the user data safely hold a pointer t a C++ structure and cast back? Quote nVidia 530M Intel Core i7 - 2.3Ghz 8GB DDR3 RAM Windows 7 Ultimate (64x)----- Visual Studio 2010 Ultimate Google Chrome Creative Suite 5 FL Studio 10 Office 15 ----- Expert Professional Expert BMX Programmer ----- Link to comment Share on other sites More sharing options...
Rick Posted January 4, 2010 Share Posted January 4, 2010 I've done it before and it seemed to work. I generally wrap Leadwerk data inside classes and need to make a pointer of that class the entity data so I can get that class instance when things get picked. Quote Link to comment Share on other sites More sharing options...
Laurens Posted January 4, 2010 Share Posted January 4, 2010 Wait -- so you instantiate a class, and you then call SetKey(pointerToClass) on the Leadwerks structure? I should have though of that before, lol. Quote Link to comment Share on other sites More sharing options...
Rick Posted January 4, 2010 Share Posted January 4, 2010 Close but not exactly. SetKey() only takes a string. You have to use SetEntityUserData() and pass in your pointer to your class. You have to cast it though. 1 Quote Link to comment Share on other sites More sharing options...
Laurens Posted January 4, 2010 Share Posted January 4, 2010 Ah I see. Well that's the first thing om my list of stuff to change in my code. Right now I'm looping through the array of objects in a scene, checking if the pointers match. Thanks! Good thread Quote Link to comment Share on other sites More sharing options...
Rick Posted January 4, 2010 Share Posted January 4, 2010 Ouch. Yeah you'll be better off using the entity user data. Quote Link to comment Share on other sites More sharing options...
Shard Posted January 4, 2010 Author Share Posted January 4, 2010 Close but not exactly. SetKey() only takes a string. You have to use SetEntityUserData() and pass in your pointer to your class. You have to cast it though. I'm new to casting (never done it before). Could you give some example code please? Quote Programmer/Engineer/Student www.reikumar.com 2.6 GHz Intel Core Duo - nVidia GeForce 8600 GT - Windows 7 64-bit - 4 Gigs RAM C++ - Visual Studio Express - Dark GDK - Leadwerks SDK Link to comment Share on other sites More sharing options...
L B Posted January 4, 2010 Share Posted January 4, 2010 I'm new to casting (never done it before). Could you give some example code please? TBody foo = (TBody)GetEntityUserData(bar); 1 1 Quote Link to comment Share on other sites More sharing options...
DaDonik Posted January 7, 2010 Share Posted January 7, 2010 Some of you don't use the entity's user data It's such an awesome feature!! Maybe this example will help you It's an example i pasted together from my code, so don't expect it to work via copy&paste. In the ProccessScene function you can call CPlayer* NewPlayer = new CPlayer (_Entity, _RootEntity); assuming that _Entity is the currently processed entity and _RootEntity is some global entity for message handling. After executing that line, the player has a pointer to it's own CPlayer class instance as it's entity user data. It can access that user data (CPlayer class) on every callback. Actually this is why i love Leadwerks ///////////////////////////////////////////////////////////////////////////// /// This class represents the user data (UD) of the player. ///////////////////////////////////////////////////////////////////////////// class CPlayer { public: ///////////////////////////////////////////////////////////////////////// /// Do everything needed to get the entity ready. /// /// \param _Entity The entity the user data corresponds to /// \param _RootEntity The main entity of the game ///////////////////////////////////////////////////////////////////////// CPlayer (TEntity _Entity, TEntity _RootEntity) { this->Init (); // Remember the entity, this class belongs to this->m_Entity = _Entity; // Remember the game global root entity this->m_RootEntity = _RootEntity; // Set this class as the user data of the entity SetEntityUserData (this->m_Entity, (byte*)this); // Enable callbacks, which will further control the entity and it's // behaviour. ENTITYCALLBACK_FREE should always be used, to free // dynamically allocated memory. Just comment out he ones not needed, or // leave them as they are. // Called when the entity is freed for some reason. SetEntityCallback (this->m_Entity, (byte*)GECPlayer::CBFree, ENTITYCALLBACK_FREE); // Called once per frame. SetEntityCallback (this->m_Entity, (byte*)GECPlayer::CBUpdate, ENTITYCALLBACK_UPDATE); // Called whenever the entity moves or rotates. SetEntityCallback (this->m_Entity, (byte*)GECPlayer::CBUpdateMatrix, ENTITYCALLBACK_UPDATEMATRIX); // Called 60 times per second, independent of the framerate. SetEntityCallback (this->m_Entity, (byte*)GECPlayer::CBUpdatePhysics, ENTITYCALLBACK_UPDATEPHYSICS); // Called whenever a collision occurs. SetEntityCallback (this->m_Entity, (byte*)GECPlayer::CBCollision, ENTITYCALLBACK_COLLISION); // Called when the entity Receives a message. SetEntityCallback (this->m_Entity, (byte*)GECPlayer::CBMessageReceive, ENTITYCALLBACK_MESSAGERECEIVE); // Do whatever needed to initialize } ///////////////////////////////////////////////////////////////////////// /// Standard destructor. ///////////////////////////////////////////////////////////////////////// ~CPlayer (); private: ///////////////////////////////////////////////////////////////////////// /// Called when the entity is freed for some reason. ///////////////////////////////////////////////////////////////////////// static void _stdcall CBFree (TEntity entity) { GECPlayer* pUD = (GECPlayer*)GetEntityUserData (entity); if (NULL != pUD) { delete pUD; } } ///////////////////////////////////////////////////////////////////////// /// Called once per frame. ///////////////////////////////////////////////////////////////////////// static void _stdcall CBUpdate (TEntity entity) { CPlayer* pUD = (CPlayer*)GetEntityUserData (entity); if (NULL != pUD) { } } ///////////////////////////////////////////////////////////////////////// /// Called whenever the entity moves or rotates. ///////////////////////////////////////////////////////////////////////// static void _stdcall CBUpdateMatrix (TEntity entity) { CPlayer* pUD = (CPlayer*)GetEntityUserData (entity); if (NULL != pUD) { } } ///////////////////////////////////////////////////////////////////////// /// Called 60 times per second, independent of the framerate. ///////////////////////////////////////////////////////////////////////// static void _stdcall CBUpdatePhysics (TEntity entity) { CPlayer* pUD = (CPlayer*)GetEntityUserData (entity); if (NULL != pUD) { } } ///////////////////////////////////////////////////////////////////////// /// Called whenever a colision occurs. ///////////////////////////////////////////////////////////////////////// static void _stdcall CBCollision ( TEntity entity0, TEntity entity1, byte* position, byte* normal, byte* force, flt speed ) { CPlayer* pUD = (CPlayer*)GetEntityUserData (entity0); if (NULL != pUD) { TVec3 VecPosition; memcpy (&VecPosition, position, sizeof (TVec3)); TVec3 VecForce; memcpy (&VecForce, force, sizeof (TVec3)); TVec3 VecNormal; memcpy (&VecNormal, normal, sizeof (TVec3)); } } ///////////////////////////////////////////////////////////////////////// /// Called when the entity Receives a message. ///////////////////////////////////////////////////////////////////////// static void _stdcall CBMessageReceive ( TEntity entity, char* message, byte* extra) { CPlayer* pUD = (CPlayer*)GetEntityUserData (entity); if (NULL != pUD) { } } ///////////////////////////////////////////////////////////////////////// /// Initializes all member variables with default values. ///////////////////////////////////////////////////////////////////////// void Init (); /// The entity this user data class belongs to. TEntity m_Entity; /// The game global root entity. TEntity m_RootEntity; }; Quote (Win7 64bit) && (i7 3770K @ 3,5ghz) && (16gb DDR3 @ 1600mhz) && (Geforce660TI) Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.