Dynamic Objects

The Dynamic Object component allows you to track the position and state of different game objects during a user session. These can be used to track things like controllers, AI characters, and interactive objects.

Step 1: Register the object

It is necessary to register each Dynamic Object only once when it first appears.

You should prefer to use RegisterObjectCustomId. Objects with a unique CustomId registered in this way will be aggregated between sessions.

  • Name: the name of this object and will be displayed on the Cognitive3D Dashboard.
  • MeshName: a name of a mesh which represents this object in SceneExplorer.
  • CustomId: the unique ID of an object. Used for aggregation.
  • InitialPosition: the initial position of an object.
  • InitialRotation: the initial rotation of an object.
  • InitialScale: is optional. It is the initial scale of the object. This is shown in the next example.
class RookGamePiece
{
    std::string Name = "Rook01";
    std::string MeshName = "rook_low_poly";

    //this should be unique to each instance
    std::string MyCustomId = "uniqueid1";

    void RookGamePiece::Initialize()
    {
        std::vector<float>initialPosition = { 0,0,0 };
        std::vector<float>initialRotation = { 0,0,0,1 };

        auto cog = cognitive::CognitiveVRAnalyticsCore::Instance();
        cog->GetDynamicObject()->RegisterObjectCustomId(Name, MeshName, MyCustomId, initialPosition, initialRotation);
    }
};

For objects that do not need to be aggregated, you can alternatively use RegisterObject as shown below. This will return an id that is not currently registered to an object. This example includes the optional InitialScale parameter, if the model view of your dynamic object is not {1,1,1} at its creation.

class PawnGamePiece
{
    std::string Name = "Pawn01";
    std::string MeshName = "pawn_low_poly";
    std::string MyGeneratedId = "0";

    void PawnGamePiece::Initialize()
    {
        std::vector<float>initialPosition = { 0,0,0 };
        std::vector<float>initialRotation = { 0,0,0,1 };
        std::vector<float>initialScale = { 0.5, 0.5, 0.5 };

        auto cog = cognitive::CognitiveVRAnalyticsCore::Instance();
        MyGeneratedId = cog->GetDynamicObject()->RegisterObject(Name, MeshName, initialPosition, initialRotation, initialScale);
    }
};

Step 2: Take an object snapshot

Create snapshots of Dynamic Objects when they move, rotate or scale. It is highly recommended that you only record snapshots after they move past a threshold instead of every frame.

    void RookGamePiece::Tick(float deltaTime)
    {
        std::vector<float>currentPosition = { 0,0,0 };
        std::vector<float>currentRotation = { 0,0,0,1 };
        std::vector<float>currentScale = { 1,1,1 };

        //highly recommended to have a minimum distance before writing a new snapshot of an object
        //if (Utility::SqrDistance(currentPosition,lastRecordedPosition)<sqrThreshold){return;}

        auto cog = cognitive::CognitiveVRAnalyticsCore::Instance();
        cog->GetDynamicObject()->RecordDynamic(MyCustomId, currentPosition, currentRotation);

        //including scale is optional! you only need to include scale if it has changed
        cog->GetDynamicObject()->RecordDynamic(MyCustomId, currentPosition, currentRotation, currentScale);
    }

Object Engagements

Custom Engagements allow you to record precise information about how a user manipulates objects in the scene. An Engagement could represent a state such as grabbing an object, proximity to an object, pointing to an object, etc. Generally we recommend calling the Engagement APIs when a user manipulates the object with their hand(s).

  • ObjectId: The Id of the object that is being engaged with.
  • EngagementType: The type of engagement that is happening. This is customizeable. For example: "Grab"
  • ParentId: The Id of the dynamic object which is engaging with this object. This is generally the controller that is grabbing the object. This is optional, but helps keep track of multiple similar engagements on the same object.

The example below shows how you could implement an Engagement onto a grab event:

    RookGamePiece::OnPlayerGrab(std::string controllerObjectId)
    {
        auto cog = cognitive::CognitiveVRAnalyticsCore::Instance();
        cog->GetDynamicObject()->BeginEngagement(MyCustomId, "Grab", controllerObjectId);
    }

To end an engagement:

    RookGamePiece::OnPlayerDrop(std::string controllerObjectId)
    {
        auto cog = cognitive::CognitiveVRAnalyticsCore::Instance();
        cog->GetDynamicObject()->EndEngagement(MyCustomId, "Grab", controllerObjectId);
    }