Game Development Community

Resolving Ghost ID From Ray Cast (C++)

by Chad Hall · in Torque 3D Beginner · 03/20/2013 (2:22 pm) · 3 replies

Hey everyone, finally returning to Torque after a long time and I've been really enjoying working with it again. However, I've been stumped on an issue for a few days now. I've written a basic GUI in source that will cast a ray to check for items and return the item's ID through a callback function. This works fine but so far I can only return the ghost ID and can't seem to figure out how to resolve it properly.

In my code I have a game connection and control:

GameConnection* connection = GameConnection::getConnectionToServer();
ShapeBase* control = dynamic_cast<ShapeBase*>(connection->getControlObject());

After getting camera info and checking various things the ray gets cast and I get the object info:

RayInfo info;  

  if (gClientContainer.castRay(camPos, endPos, losMask, &info))  
 {  
   if (ShapeBase* obj = dynamic_cast<ShapeBase*>(info.object))   
  { 
   mTargetId = obj->getNetIndex();
  }
 }

At this point I can get the correct ghost ID from getNetIndex(), but I can't seem to find a way to get the server ID. I've looked through various other files and tried lots of different things but nothing appears to give me what I'm looking for. I can get the server ID properly by resolving it in script by using %clientId.resolveObjectFromGhostIndex(%ghost) but can't seem to do the same using connection->resolveGhost() in C++. I'd just prefer to handle it in source so it looks cleaner, and would also like to know what I'm doing wrong.

Also, I've tried following code from other functions that return IDs, trying methods like the below but they seem return a totally different ID (in this case 4309 when I expect 4276 and the net index returns 11).

NetObject* pObject = connection->resolveGhost(obj->getNetIndex());
Con::printf("ID: %s", (S32)pObject->getId());

#1
03/21/2013 (1:58 pm)
Well, seems I figured it out... haha. I never needed to deal with ghost IDs anyway. All I needed to do was use 'obj->getServerObject()->getId()' to get the ID I wanted from source. I'm learning, slowly!
#2
04/01/2013 (10:51 pm)
That will not work in a client/server mode, it will only work in singleplayer.

If you are trying to get the server id from a remote client, you have to send the ghostid to the server, have it look up the simobject id and then have the server send the simobject id back to the client.

If your doing it on the server and you are passed a ghostid then.

DefineEngineMethod(NetConnection, GetGhostIndex, S32, (NetObject* obj),,
                   "Returns the ghost-index for an object.\n\n"
                   "@ingroup AFX")
{
  if (obj)
    return object->getGhostIndex(obj);
  return 0;
}

DefineEngineMethod(NetConnection, ResolveGhost, S32, (int ghostIndex),,
                   "Resolves a ghost-index into an object ID.\n\n"
                   "@ingroup AFX")
{
  if (ghostIndex != -1)
  {
    NetObject* pObject = NULL;
    if( object->isGhostingTo())
      pObject = object->resolveGhost(ghostIndex);
    else if( object->isGhostingFrom())
      pObject = object->resolveObjectFromGhostIndex(ghostIndex);
    if (pObject)
      return pObject->getId();
  } 
  return 0;
}

I didn't write these, but I don't remember where I snaged them from.
#3
04/01/2013 (11:32 pm)
Thanks a ton, Vince. My project happens to be strictly single-player only so that would be why I had no issues, I suppose. I've implemented the following code and it seems to work properly (though I've only lightly tested it).

if (gClientContainer.castRay(camPos, endPos, losMask, &info))  
{
  if (ShapeBase* obj = dynamic_cast<ShapeBase*>(info.object))   
 {
  NetObject* pObject = NULL;
  U32 netIndex = obj->getNetIndex();

  if (connection->isGhostingTo())
   pObject = connection->resolveGhost(netIndex);
  else if (connection->isGhostingFrom())
   pObject = connection->resolveObjectFromGhostIndex(netIndex);

  if (pObject)
   Con::printf("Object ID is: %i", (U32)pObject->getServerObject()->getId());
 }
}

Connection again being: GameConnection* connection = GameConnection::getConnectionToServer();

Hopefully I'm doing this properly now. Even though I could have used the previous method I'm very glad to know how to do this. Thanks again.