Horde3D

Next-Generation Graphics Engine
It is currently 25.04.2024, 04:51

All times are UTC + 1 hour




Post new topic Reply to topic  [ 27 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: 20.11.2008, 21:52 
Offline

Joined: 19.11.2007, 19:35
Posts: 218
Thus far I've got everything built fine, and I was fairly certain I had a good idea of how everything operates, but...

I've encountered this issue, checked it out, hardcoded a parameter for "Doserwerfen.scn" and fed it in where anticipated in the Coconut_Shy.exe sample application, and still had the issue.

Also, so far I haven't been able to identify where the plugins are being registered, whether it's by the GameEngineCore.dll, I saw some code that looked like a config file setup, or the application itself (albiet I haven't searched too exhaustively).


Top
 Profile  
Reply with quote  
PostPosted: 20.11.2008, 22:34 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
Well the Coconut_shy example application requires a file as command line parameter as argument. You can use the Dosenwerfen\Dosenwerfen.scn for that. It initializes Horde3D based on the path settings in this file and loads the scene defined in the SceneGraph node.

The plugins are loaded from the plugin.cfg for the release version and from the plugin_debug.cfg in the debug version. These files are located in the bin directory where all binaries and plugin DLLs will be placed in. So by default the working directory should be the one where the executable and plugins are located and the command line parameter should be the path to the Dosenwerfen.scn

I just realized that another sample application (TutorialApp) was uploaded by Nikolaus,... not sure what this will contain, but perhaps he will post some comment on that in the future.


Top
 Profile  
Reply with quote  
PostPosted: 20.11.2008, 23:09 
Offline

Joined: 19.11.2007, 19:35
Posts: 218
Alright, I've got all of that working now, plugins loading, but Horde seems to be freaking on me (unable to initialize, probably some coded project setting). I think I'll figure out how things work by just whipping up my own sample application and playing around.

EDIT:

Alright, it's the loadscene that was giving me problems.

Using app->init("Dosenwerfen\Dosenwerfen.scn"); Refused to work (not sure why), but using GameEngine::loadScene("Dosenwerfen/Dosenwerfen.scn") worked fine.

Got to see a pyramid of cans and a bright green ball with unsmooth normals fall onto the ground, made my day, oddly.

What I've checked out of the internal engine code looks really good.


Top
 Profile  
Reply with quote  
PostPosted: 21.11.2008, 08:48 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
AcidFaucet wrote:
EDIT:
Alright, it's the loadscene that was giving me problems.
Using app->init("Dosenwerfen\Dosenwerfen.scn"); Refused to work (not sure why), but using GameEngine::loadScene("Dosenwerfen/Dosenwerfen.scn") worked fine.

Strange, couldn't reproduce that on my system. What Compiler setup are you using? VS2005?
I just realized, that I forgot to add the plugin.cfg and plugin_debug.cfg files to the bin directory, and also to add the Horde3D libraries to the solution file, but after that, all runs fine on my system after a new checkout.

There is also a separate GameEngineLog.htm placed into the directory where the GameEngineCore.dll lives. That might also help to debug the application.

AcidFaucet wrote:
Got to see a pyramid of cans and a bright green ball with unsmooth normals fall onto the ground, made my day, oddly.

:P I'm sorry for that! :wink: I created that scene for an application, we wanted to realize at the university some day, but never finished it. We had the idea to use an eye tracker for targeting and a Wiimote for throwing the green ball onto the pyramid.
AcidFaucet wrote:
What I've checked out of the internal engine code looks really good.

Thanks,... the messaging and property storing could certainly be improved (see also the TODO section in the documentation) but the current system at least works and new components can be realized as separate plugins without affecting the rest of the engine's code what was the most important thing I wanted to realize, especially for student projects :-)


Top
 Profile  
Reply with quote  
PostPosted: 22.11.2008, 21:33 
Offline

Joined: 19.11.2007, 19:35
Posts: 218
Quote:
Strange, couldn't reproduce that on my system. What Compiler setup are you using? VS2005?

Yeah, VS2005 Pro. I'll check for updates, and do a clean rebuild though, I've noticed some std::cin (use them so I actually get time to read console messages) commands that aren't present in the code remaining in the obj files and then compiling.

Quote:
There is also a separate GameEngineLog.htm placed into the directory where the GameEngineCore.dll lives. That might also help to debug the application.

Saw that, helped quite a bit to narrow my range issues.

I was wondering about the plugin.cfg files, I just looked at the config code to see what it did and whipped a file that worked with it.

I'll work away on some art assets for a racing demo the rest of this weekend. Probably do something F-Zero like, as I don't want to be both tweaking a physical car and learning the guts of GaBaCo at the same time.


Top
 Profile  
Reply with quote  
PostPosted: 23.11.2008, 09:43 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
I tried some car physics based on the bullet vehicle example some times ago. I used the terrain example for testing, but I ended up with a vehicle that always overbalanced if there was only a small slope. I guess the most important thing is the configuration of the various bullet vehicle parameters and a balanced choice for masses and geometry scales. So maybe you should start with a very simple racing course that don't have steep hills.
If I can find the source of those quick hacks I will post them here in the forums, but I guess, I have lost them on my old computer in the university. But they were ugly and not very sophisticated anyway. I think starting based on the link in my post here, it may be much simpler now, since there are the various configuration parameters described already. Unfortunately I haven't found this article earlier and now I don't have the time anymore.


Top
 Profile  
Reply with quote  
PostPosted: 24.11.2008, 02:56 
Offline

Joined: 19.11.2007, 19:35
Posts: 218
Yeah, it looks like it wouldn't be too difficult basing off of that vehicle wrapper. I don't think the track parts I've modeled thus far are prohibitive from a texture switch to be suitable for a car thankfully.

I've spent more time writing a simple overlay GUI system than on art (that still needs to be UV'ed and textured), as all the current Horde demos are really simple and just launch into the scene, so I figured it would be pretty helpful to provide an example of a simple intro, main menu, options menu, and two different tracks that can be loaded.


Top
 Profile  
Reply with quote  
PostPosted: 03.12.2008, 03:21 
Offline

Joined: 19.11.2007, 19:35
Posts: 218
Alright, so far everything is going well and I think I've got a pretty solid understanding of what's going on. I think I'm about ready to move on from violently smashing that green ball into those cans, but I've got a couple of questions/notes:

I've noticed that if the listener leaves the range of a sound source, it won't resume when the listener enters the range later. This makes sense for nonlooping sounds, but it doesn't make sense for sounds that loop.

I've been wondering what you were up to with SAPI and the visimes and phonemes?

I haven't spotted anything pertaining to spatial querying (like within a range from a point, or within an AABB) or of raycasting against primitives for stuff like surface normals or even just identifying what a raycast met other than doing it the Horde3D::castRay() way.

Were there any planned components that just didn't make it in? It could be helpful to know what the general vision was.


Top
 Profile  
Reply with quote  
PostPosted: 03.12.2008, 08:09 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
Quote:
I've noticed that if the listener leaves the range of a sound source, it won't resume when the listener enters the range later. This makes sense for nonlooping sounds, but it doesn't make sense for sounds that loop

That listener thing may be a bug. It should be re-enabled when the listener is within range again. The main reason for disabling sounds that are not in range was that only a limited number of sounds can be activated at the same time. I will have a look at it.

Quote:
I've been wondering what you were up to with SAPI and the visimes and phonemes?

We had several projects with talking characters at the lab. While the Microsoft voices sound really horrible, there are some very good ones from Loquendo we used in some projects. The visimes, phonemes were used to control the morph targets of the virtual characters. You can see them in action on the site referenced above, although the character is not very well visible in the video. Felix Kistler is also working on some phoneme editor for the Horde3D editor. If I understood it correctly, it allows the synchronisation of audio files with morph targets of a character. But I didn't see it in action yet so I can't tell you more details.

Quote:
I haven't spotted anything pertaining to spatial querying (like within a range from a point, or within an AABB) or of raycasting against primitives for stuff like surface normals or even just identifying what a raycast met other than doing it the Horde3D::castRay() way.

No nothing like that is currently available. We used Horde3D's raycast method for creating a visibility graph in one project and used a separate collision detection component that won't be published in another one. But this collision detection may be replaced by the one from bullet. We only used it because we wanted to detect collisions that are not influenced by the physics and hadn't the time to figure out how this could be realized with bullet.


Top
 Profile  
Reply with quote  
PostPosted: 04.12.2008, 23:45 
Offline

Joined: 19.11.2007, 19:35
Posts: 218
Quote:
That listener thing may be a bug. It should be re-enabled when the listener is within range again. The main reason for disabling sounds that are not in range was that only a limited number of sounds can be activated at the same time. I will have a look at it.

I had looked through the update loop, I could see where the sound was being disabled and the source freed, but after that everything started to get fairly esoteric without keeping the OpenAL reference open.

Quote:
But this collision detection may be replaced by the one from bullet. We only used it because we wanted to detect collisions that are not influenced by the physics and hadn't the time to figure out how this could be realized with bullet.

I added static="bool" and solid="bool" attribute checks in loadFromXml(), with static assigning the object as physically static or not and solid setting btCollision::CF_NO_CONTACT_RESPONSE so the object reports contacts but doesn't influence or receive physical forces (also forces kinematic status of the object so it doesn't just fall through the world). Bullets raycasting looks interesting, but I haven't gotten that far.

A "ComponentTemplate" would be handy in the core though with an additional loadFromTemplate() function in each component, any xml component's that have a "store='string'" attribute (or something else) would be saved to a core manager as a template that could be applied to a component instead of always having to parse an xml string. Would also make it possible to have a reference library of templates defined in another file and then just use something like "<Physics ref='green_ball' />" instead of duplicating data in xml.

The only other question I've got is how would complicated situations like jointed objects be realized? I could see a physics function that links two physics components by a joint or removes a joint linking them, but defining two entities each with scenegraph representations and their physics components then linking them in xml?

Still pondering about properties.


Top
 Profile  
Reply with quote  
PostPosted: 05.12.2008, 00:15 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
AcidFaucet wrote:
I added static="bool" and solid="bool" attribute checks in loadFromXml(), with static assigning the object as physically static or not and solid setting btCollision::CF_NO_CONTACT_RESPONSE so the object reports contacts but doesn't influence or receive physical forces (also forces kinematic status of the object so it doesn't just fall through the world). Bullets raycasting looks interesting, but I haven't gotten that far.

Sounds interesting, the CF_NO_CONTACT_RESPONSE was nothing I've known before.

AcidFaucet wrote:
A "ComponentTemplate" would be handy in the core though with an additional loadFromTemplate() function in each component, any xml component's that have a "store='string'" attribute (or something else) would be saved to a core manager as a template that could be applied to a component instead of always having to parse an xml string. Would also make it possible to have a reference library of templates defined in another file and then just use something like "<Physics ref='green_ball' />" instead of duplicating data in xml.

Not sure if I understood that right,... you want to have a global storage for a string in the entity that can be used as a template for a component that does not contain a configuration for that component but only the name of the component itself?

AcidFaucet wrote:
The only other question I've got is how would complicated situations like jointed objects be realized? I could see a physics function that links two physics components by a joint or removes a joint linking them, but defining two entities each with scenegraph representations and their physics components then linking them in xml?

I think if you intend to have objects that can interact with other components you have to create entities for it. If you create something that can only interact with data within the component than you don't have to create an entity. So I guess you have to care about the complexity of the exported component. For example to create something like a character controller, one could create a component that controls it's joints but interacts with other entities only as a complete character.
AcidFaucet wrote:
Still pondering about properties.

As already mentioned that was something I wanted to add myself, since I don't like the distributed storage of core data, like the transformation. But I found no gold standard solution while I was working on the engine and now I don't have the time anymore.

But feel free to add your ideas to the engine. In case of bigger changes you may create a branch for it, since the students at the university may have some projects that depend on the current functionality.


Top
 Profile  
Reply with quote  
PostPosted: 05.12.2008, 02:10 
Offline

Joined: 19.11.2007, 19:35
Posts: 218
Quote:
AcidFaucet wrote:
A "ComponentTemplate" would be handy in the core though with an additional loadFromTemplate() function in each component, any xml component's that have a "store='string'" attribute (or something else) would be saved to a core manager as a template that could be applied to a component instead of always having to parse an xml string. Would also make it possible to have a reference library of templates defined in another file and then just use something like "<Physics ref='green_ball' />" instead of duplicating data in xml.

Not sure if I understood that right,... you want to have a global storage for a string in the entity that can be used as a template for a component that does not contain a configuration for that component but only the name of the component itself?

Something like:

Code:
class componentTemplate
{
public:
     virtual string getType();
}

class physicsComponentTemplate : public componentTemplate
{
    string getType() { return "Physics"; };
    // begin data
    // store positions as offsets
}

physicsComponent::loadFromTemplate(componentTemplate* data)
{
    if(data->getType() == "Physics)
    {
            physicsComponentTemplate* dataStore = static_cast<physicsComponentTemplate*>(data);
            //set data to match stored data
    }
}
So during loadFromXml if there's a "store" attribute than a componentTemplate will be created and added to the collection. If there's a "ref" attribute then it will lookup the named component in the registry. The purpose being to make programmatic creation of common entities easier.
Code:
GameEngine::setComponentData(entityID, "Physics", GameEngine::templateLookup("Physics","TinCan"))
Though an actual componentTemplate class template wouldn't be necessary really, the xml string itself could just be stored and the template lookup would return the string for that component. Using a class would just get rid of xml parsing as an optimization. An xml string would make using transforms as offsets more difficult. Basically a convenience.

-------------------

Could probably get away with something like map<string, pair< dataTypeEnum, void*> > for property storage and using overloaded setProperty(string name, value) functions that would create the property if it doesn't already or just set the value (assuming datatypes match), and some getPropertyFloat(string), getPropertyBool(), getPropertyString(), getPropertyVec3f(), etc, and etc. Whenever a property is set then you just throw an E_SET_PROPERTY event and pass the name of the property and possibly the value in the event data. Could turn into some hyrbrid of Game Programming Gems II articles 1.7 and 1.18 ("A Property Class for Generic C++ Member Access" and "A Generic Tweaker").

If the properties can't be destroyed without toasting the entity too, then the components could just keep pointers to the variables, then instead of passing value E_SET_PROPERTY would pass the pointer, it's compared to the addresses the component has, if they're the same then update, and do what needs to be done.

Could also be done as a seperate component using the E_SET_PROPERTY and E_GET_PROPERTY events to handle things. Would be cumbersome though.


Top
 Profile  
Reply with quote  
PostPosted: 05.12.2008, 03:15 
Offline

Joined: 19.11.2007, 19:35
Posts: 218
Scroll all the way to the bottom for the header defines. This patch does what I described in the post before. The void* returned by each set function gives a pointer to the datatype to either make reading the variable simpler or so it can be edited discretely without tripping an event, should that be desired.

NOTE: I just noticed that the default return values of the "get" functions need to be moved to outside the first "if" test.

Code:
Index: GameEntity.cpp
===================================================================
--- GameEntity.cpp   (revision 110)
+++ GameEntity.cpp   (working copy)
@@ -108,6 +108,13 @@
 GameEntity::~GameEntity()
 {
    delete m_privateData;
+   std::map< std::string, std::pair<PropertyType,void*> >::iterator t = m_properties.begin();
+   while(t != m_properties.end())
+   {
+      delete t->second.second;
+      t++;
+   }
+   m_properties.clear();
 }
 
 void GameEntity::addListener( GameEvent::EventID eventType, GameComponent* listener )
@@ -208,3 +215,225 @@
    }
 }
 
+
+
+void* GameEntity::setProperty(std::string name, int value, GameComponent* editor)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::INTEGER)
+      {
+         int* val = static_cast<int*>(t->second.second);
+         *val = value;
+         throwPropertyEvent(name,PropertyType::INTEGER,t->second.second,editor);
+         return t->second.second;
+      }
+      return 0x0;
+   }
+   else
+   {
+      m_properties[name] = std::make_pair(PropertyType::INTEGER, new int(value));
+      throwPropertyEvent(name,PropertyType::INTEGER, m_properties[name].second,editor);
+      return m_properties[name].second;
+   }
+}
+void* GameEntity::setProperty(std::string name, unsigned int value, GameComponent* editor)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::UNSIGNED)
+      {
+         unsigned int* val = static_cast<unsigned int*>(t->second.second);
+         *val = value;
+         throwPropertyEvent(name,PropertyType::UNSIGNED,t->second.second,editor);
+         return t->second.second;
+      }
+      return 0x0;
+   }
+   else
+   {
+      m_properties[name] = std::make_pair(PropertyType::UNSIGNED, new unsigned int(value));
+      throwPropertyEvent(name,PropertyType::UNSIGNED,m_properties[name].second,editor);
+      return m_properties[name].second;
+   }
+}
+void* GameEntity::setProperty(std::string name, float value, GameComponent* editor)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::FLOAT)
+      {
+         float* val = static_cast<float*>(t->second.second);
+         *val = value;
+         throwPropertyEvent(name,PropertyType::FLOAT,t->second.second,editor);
+         return t->second.second;
+      }
+      return 0x0;
+   }
+   else
+   {
+      m_properties[name] = std::make_pair(PropertyType::FLOAT, new float(value));
+      throwPropertyEvent(name,PropertyType::FLOAT,m_properties[name].second,editor);
+      return m_properties[name].second;
+   }
+}
+void* GameEntity::setProperty(std::string name, double value, GameComponent* editor)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::DOUBLE)
+      {
+         double* val = static_cast<double*>(t->second.second);
+         *val = value;
+         throwPropertyEvent(name,PropertyType::DOUBLE,t->second.second,editor);
+         return t->second.second;
+      }
+      return 0x0;
+   }
+   else
+   {
+      m_properties[name] = std::make_pair(PropertyType::DOUBLE, new double(value));
+      throwPropertyEvent(name,PropertyType::DOUBLE,m_properties[name].second,editor);
+      return m_properties[name].second;
+   }
+}
+void* GameEntity::setProperty(std::string name, std::string value, GameComponent* editor)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::STRING)
+      {
+         std::string* val = static_cast<std::string*>(t->second.second);
+         *val = value;
+         throwPropertyEvent(name,PropertyType::STRING,t->second.second,editor);
+         return t->second.second;
+      }
+      return 0x0;
+   }
+   else
+   {
+      m_properties[name] = std::make_pair(PropertyType::STRING, new std::string(value));
+      throwPropertyEvent(name,PropertyType::STRING,m_properties[name].second,editor);
+      return m_properties[name].second;
+   }
+}
+void* GameEntity::setProperty(std::string name, Vec3f value, GameComponent* editor)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::VEC)
+      {
+         Vec3f* val = static_cast<Vec3f*>(t->second.second);
+         *val = value;
+         throwPropertyEvent(name,PropertyType::VEC,t->second.second,editor);
+         return t->second.second;
+      }
+      return 0x0;
+   }
+   else
+   {
+      m_properties[name] = std::make_pair(PropertyType::VEC, new Vec3f(value));
+      throwPropertyEvent(name,PropertyType::VEC,m_properties[name].second,editor);
+      return m_properties[name].second;
+   }
+}
+
+int GameEntity::getPropertyInteger(std::string name)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::INTEGER)
+      {
+         return *(static_cast<int*>(t->second.second));
+      }
+      return 0;
+   }
+}
+unsigned int GameEntity::getPropertyUnsigned(std::string name)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::UNSIGNED)
+      {
+         return *(static_cast<unsigned int*>(t->second.second));
+      }
+      return 0;
+   }
+}
+float GameEntity::getPropertyFloat(std::string name)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::FLOAT)
+      {
+         return *(static_cast<float*>(t->second.second));
+      }
+      return 0.0f;
+   }
+}
+double GameEntity::getPropertyDouble(std::string name)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::DOUBLE)
+      {
+         return *(static_cast<double*>(t->second.second));
+      }
+      return 0.0;
+   }
+}
+std::string GameEntity::getPropertyString(std::string name)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::STRING)
+      {
+         return *(static_cast<std::string*>(t->second.second));
+      }
+      return "";
+   }
+}
+Vec3f GameEntity::getPropertyVec3f(std::string name)
+{
+   std::map< std::string, std::pair< PropertyType, void*> >::iterator t;
+   t = m_properties.find(name);
+   if(t != m_properties.end())
+   {
+      if(t->second.first == PropertyType::VEC)
+      {
+         return *(static_cast<Vec3f*>(t->second.second));
+      }
+      return Vec3f(0.0f,0.0f,0.0f);
+   }
+}
+void GameEntity::throwPropertyEvent(std::string name, PropertyType type, void* value, GameComponent* editor)
+{
+   std::pair<std::string , std::pair<PropertyType,void*> > data;
+   data.first = name;
+   data.second.first = type;
+   data.second.second = value;
+   GameEvent event(GameEvent::E_SET_PROPERTY,&GameEventData(static_cast<void*>(&data)),editor);
+   checkEvent(&event);
+}
\ No newline at end of file
Index: GameEntity.h
===================================================================
--- GameEntity.h   (revision 110)
+++ GameEntity.h   (working copy)
@@ -36,6 +36,8 @@
 #define GAMEENTITY_H_
 
 #include <string>
+#include <map>
+#include <GameEngine/utMath.h>
 
 #include "GameComponent.h"
 
@@ -64,6 +66,30 @@
    friend struct DeleteEntity;
 
 public:
+   enum PropertyType
+   {
+      INVALID = 0,
+      INTEGER,
+      UNSIGNED,
+      FLOAT,
+      DOUBLE,
+      STRING,
+      VEC,
+      COUNT
+   };
+   void* setProperty(std::string name, int value, GameComponent* editor = 0);
+   void* setProperty(std::string name, unsigned int value, GameComponent* editor = 0);
+   void* setProperty(std::string name, float value, GameComponent* editor = 0);
+   void* setProperty(std::string name, double value, GameComponent* editor = 0);
+   void* setProperty(std::string name, std::string value, GameComponent* editor = 0);
+   void* setProperty(std::string name, Vec3f value, GameComponent* editor = 0);
+
+   int getPropertyInteger(std::string name);
+   unsigned int getPropertyUnsigned(std::string name);
+   float getPropertyFloat(std::string name);
+   double getPropertyDouble(std::string name);
+   std::string getPropertyString(std::string name);
+   Vec3f getPropertyVec3f(std::string name);
    
    /**
     * \brief A unique id (string) of the entity within the GameWorld
@@ -184,7 +210,9 @@
 
    /// Index for the entity within the GameWorld
    unsigned int            m_worldId;
-   
+
+   std::map< std::string, std::pair< PropertyType, void* > > m_properties;
+   void throwPropertyEvent(std::string name, PropertyType type, void* value, GameComponent* editor);
 };
 
 /*! @}*/


Attachments:
PropertyMapping.zip [1.5 KiB]
Downloaded 741 times
Top
 Profile  
Reply with quote  
PostPosted: 05.12.2008, 20:32 
Offline

Joined: 22.11.2007, 17:05
Posts: 707
Location: Boston, MA
AcidFaucet wrote:
Could probably get away with something like map<string, pair< dataTypeEnum, void*> > for property storage and using overloaded setProperty(string name, value) functions that would create the property if it doesn't already or just set the value (assuming datatypes match), and some getPropertyFloat(string), getPropertyBool(), getPropertyString(), getPropertyVec3f(), etc, and etc. Whenever a property is set then you just throw an E_SET_PROPERTY event and pass the name of the property and possibly the value in the event data. Could turn into some hyrbrid of Game Programming Gems II articles 1.7 and 1.18 ("A Property Class for Generic C++ Member Access" and "A Generic Tweaker").
Something along the lines of boost::any might be preferable to managing void pointers there.

_________________
Tristam MacDonald - [swiftcoding]


Top
 Profile  
Reply with quote  
PostPosted: 05.12.2008, 20:44 
Offline

Joined: 19.11.2007, 19:35
Posts: 218
It definitely would, but I wanted to avoid another dependency. Realistically an "anyType" class would be preferable with derived classes and a getType() function, would get rid of the nested std::pairs. Was more concerned about a draft of method rather than the internal guts.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 27 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 25 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group