About Store Forum Documentation Contact



Post Reply 
Object Parameters problems
Author Message
AndrewBGS Offline
Member

Post: #1
Object Parameters problems
I managed to reduce a lot of my problems to one issue;

Accessing the parameters used to create an object;
I want to store those parameters in order to use them later on to create an identical copy of the object.
Normally, I did this:

Game.ObjParamsPtr params;
void create(Game.ObjParams &obj)
{ params=&obj;
....

And this used to work. However, when the object is created from the code, not from the world, those parameters aren't correct anymore. Why? Where is the difference?
How should always get the correct parameters to re-create the object?
03-22-2014 07:01 PM
Find all posts by this user Quote this message in a reply
Pixel Perfect Offline
Member

Post: #2
RE: Object Parameters problems
Hi Andrew, when you say the parameters are not correct any more what exactly do you mean? Are the values corrupted or something?

I'm not exactly using the engine as its designed to be used so I'm not sure how helpful this might be but for what it is worth here is the code I use to spawn my NPCs when requested by the external AI engine.

I store the UIDs for my Model Objects against a type name and retrieve those at run time from my configuration manager. Ignore the EKI One commands as they are just interfacing with the external AI Engine as a data conduit, the Esenthel code starts from:

// Get the model UID and set the NPC object Type UID

Code:
void createEntityFromEKIMessage(const EKI_One::SystemMessage& message,
                                bool createAsAgent)
{
    // Read requested entity configuration from message
    const std::string& name = message.GetProperty<const std::string&>
            (EKI_One::MessageTypes::CreateAgentProps::NAME.ID);
    const std::string& type = message.GetProperty<const std::string&>
            (EKI_One::MessageTypes::CreateAgentProps::TYPE.ID);
    const EKI_One::Vector3d position = message.GetProperty<EKI_One::Vector3d>
            (EKI_One::MessageTypes::CreateAgentProps::POSITION.ID);
    const EKI_One::Vector3d facing = message.HasProperty
                (EKI_One::Strings::HardcodedProperties::FACING) ?
                message.GetProperty<EKI_One::Vector3d>
                (EKI_One::Strings::HardcodedProperties::FACING) :
                EKI_One::Vector3d::UNIT_X;

    // Even pure AI entities are created via this mechanism so that the
    // external application is in control of every entity created
    // The isShared flag signals if this is a conventional or pure AI
    // entity
    const bool createGameEntity = message.GetProperty<bool>
        (EKI_One::MessageTypes::CreateAgentProps::IS_SHARED.ID);

    EKIDataSynchronizationChannel* newSyncCh = nullptr;

    // Create a new game entity
    if (createGameEntity)
    {
        // Get the model UID and set the NPC object Type UID
        UID modelUID = configManager.getUIDData("npcModelList", type);

        // Check we have a valid UID for the model
        if(!modelUID.valid())
        {
            EKI_LOG("VS", EKI_One::Logger::INFO,
                "createEntityFromEKIMessage: Unable to find the
                 model type " << type << " for NPC name: "
                 << name,);

            return;
        }

        // Get a pointer to the NPC model
        Game::ObjParamsPtr obj=Game::Objs.ptrRequire(modelUID);

        EKI_LOG("VS", EKI_One::Logger::INFO,
            "createEntityFromEKIMessage: Creating NPC: " << name,);

        // Create the new NPC object and return a pointer to it (This
        // also adds it to the npcObjs collection
        // by virtue of its type).  Note the transformation of the z
        // axis here    
        Game::Obj* myObj = Game::World.objCreateNear(*obj,
                   Matrix(obj->scale(), Vec(position.x,
                   position.y+1,-position.z)));  

        // We can cast the game object pointer to an npc pointer
        m_pNPC = (npc*) myObj;

        // Save the name
        m_pNPC->setName(name);

        // Create the AI engine data synchronization channel and add it
        // to the sharedDataManager
        newSyncCh = new EKIDataSynchronizationChannel(name, position,
                facing , m_pNPC);
        mSharedDataManager.Add(newSyncCh);

        // Add the newly created NPC pointer to a map collection
        m_mapNPCList.insert(std::pair<std::string,npc*>(name,m_pNPC));
      
    }

    // else the nullptr is passed which is exactly the necessary signal that
    // this is an unshared, virtual entity
    if (createAsAgent)
        mAIEngine->CreateAgent(name, type, newSyncCh);
    else
        mAIEngine->CreateObject(name, type, newSyncCh);
      
}
03-22-2014 09:51 PM
Find all posts by this user Quote this message in a reply
AndrewBGS Offline
Member

Post: #3
RE: Object Parameters problems
I'm sorry, I think that might be a little too advanced for me, I don't seem able to understand too much :|.
I'm only using Esenthel, with c++. And all I wanted was an easy way to create another copy of an object; Why can't Greg give up that "no_copy_constructor" in his code...? :|
03-22-2014 10:36 PM
Find all posts by this user Quote this message in a reply
Rubeus Offline
Member

Post: #4
RE: Object Parameters problems
The reason for the "no_copy_constructor" is so you can take advantage of the enhance memory management features of the engine and it's containers, which I am finding very useful and under-appreciated.

You will have to post more code for anyone to be able to pinpoint the problem. It's very possible you are creating a pointer and it is getting deleted and you lose your data. Check your scopes and memory management. Also, remember some EE containers will change the memory addresses of the elements.
03-23-2014 12:15 AM
Find all posts by this user Quote this message in a reply
Pixel Perfect Offline
Member

Post: #5
RE: Object Parameters problems
I tend to agree with Rubeus on this one. We probably need to see more of your code.

However, if I understand what you've posted so far I suspect

Code:
Game.ObjParamsPtr params;
void create(Game.ObjParams &obj)
{ params=&obj;
....

implies you are copying the object params in the Create proc of your object class, which if this is the case will be updated for every instance of the object type placed in the level so you will end up with just a copy of the last one created and any parameters that were set against it.

What's more, if this objects has been subsequently deleted, you've maybe picked it up for example and added it to your inventory, then this pointer is probably no longer valid.

I'd have thought you would be better creating new objects in code from the original parent object as defined in the Editor.

i.e.

Code:
Game::ObjParamsPtr params=Game::Objs.ptrRequire(modelUID);
03-23-2014 01:38 AM
Find all posts by this user Quote this message in a reply
AndrewBGS Offline
Member

Post: #6
RE: Object Parameters problems
Rubeus, I still don't see why we aren't free to chose ourselves what to use; I found the EE memory containers very useful in most situations too, but in this particular one they impose too many constraints for it to be useful for me.

Pixel, I am in over my head with this issue already, and it boggles me how it only reproduces for manually created objects; However that last line of code sounds like what I'm looking for, but how can I get the model UID from within the model?

In the meantime, I'll try once again to adapt my code to using the esenthel containers and look more like the Tutorials..
03-23-2014 03:31 AM
Find all posts by this user Quote this message in a reply
Pixel Perfect Offline
Member

Post: #7
RE: Object Parameters problems
(03-23-2014 03:31 AM)AndrewBGS Wrote:  ...
Pixel, I am in over my head with this issue already, and it boggles me how it only reproduces for manually created objects; However that last line of code sounds like what I'm looking for, but how can I get the model UID from within the model?
...
Go to your model object in the editor and right click and choose Properties. Click on the copy button next to the UID and paste into your code. This is a static ID which will never change.

I use a configuration system to pass all the critical UIDs for objects I want to create in code (along with lots of other configurable data) which I simply retrieve via a single call anywhere in my code but hard coding it in is quite acceptable!

Look at the tutorial:

14 Game Basics / 07 Dynamically Creating Objects

This will work if you already know what object type you are wanting to create. I can think of occasions where you might want to duplicate an object dynamically without knowing what it is beforehand so in this case you would have to know how to get the UID from an already existing instance. I seem to remember you can get the UID from the objectParams struct using the type() function. But again, this would only work if you have a valid objectParams struct at the time.
03-23-2014 09:44 AM
Find all posts by this user Quote this message in a reply
Post Reply