Game Development Community

Mounted Camera

by Robert Norris · in Torque Game Engine · 10/11/2006 (7:28 am) · 5 replies

I have a problem.

My project does not use a Player or a Vehicle, just Camera, PathCamera and a bunch of StaticShapes some of which are animated. These sequences animate one of the mount points that we have designated to be the mount point for the camera. Just before playing the thread, I mount a new Camera to this mount point and make it the controlling object for the client. The rest of the navigation involves flying between markers with the PathCamera when objects are selected.

What works?

After some tinkering with the engine, I have it so that the Camera is positioned at the initial mount point position. The sequence runs but the Camera does not get animated. I tested this with the 3D Torque Logo as a StaticShape mounted to the same mount point and it gets animated; the difference being that I did not change the object designated as the client control object.

Why does it not work?

The modifications I made to Camera are in processTick and interpolateTick; these test whether the Camera isMounted and adjust the transformation accordingly. Although interpolateTick is called (which would be required to have it move according to the sequence) the mount information is not moved from the server to the client as the object that it is attached to (a StaticShape) does not have a ghost id. This is strange as the very same object does have a ghost id when the 3D Torque Logo is mounted to it rather than the Camera.

What happens in NetConnection::getGhostIndex()?

The following test fails as the GhostInfo::Ghosting bit is set.

if(gptr->obj == obj && (gptr->flags & (GhostInfo::KillingGhost | GhostInfo::Ghosting | GhostInfo::NotYetGhosted | GhostInfo::KillGhost)) == 0)

The index is set to 3 which may or may not be the correct index.
The other bits set are GhostInfo::InScope and GhostInfo::ScopeLocalAlways which is just fine.

I understand from this that the object is in the process of being ghosted i.e. if I could wait a tick or two or synchronize the update of the Camera and the StaticShape, all will be ready. I thought I could solve this using processAfter but to no avail.

Has anyone tried anything similar or does anyone have any ideas?

Regards,
Rob

#1
10/11/2006 (7:38 am)
You are confusing a few terms here, so I am not sure what you are asking. For instance, a camera can not animate, as it has no body or sequences attached to it. It is just an object.

Are you saying that the camera does not update it's position according to the mountPoint?
StaticShape's should definatly have a ghost ID.

I would advice you to (if you have not already, that is!) take a look at shapeBase.h and mountInfo in particular.

/// Mounted objects
   struct MountInfo {
      ShapeBase* list;              ///< Objects mounted on this object
      ShapeBase* object;            ///< Object this object is mounted on.
      ShapeBase* link;              ///< Link to next object mounted to this object's mount
      U32 node;                     ///< Node point we are mounted to.
   } mMount;

What you can do is duplicating the code (if you need the functionallity for ShapeBase objects intact) and let it mount GameBase objects, or change the above to only accept GameBase objects and cast between different object types depending on their object type bit.

I think Peter Simard does the former in his equipment resource, though I could not find it.
#2
10/11/2006 (7:48 am)
@Stephan
The sequence animates the mount point and the cameras is mounted to that mount point.
I have just refreshed the post. The ghost index is not returned due to the Ghosting bit being set. Have I understood the Ghosting flag correctly?
#3
10/11/2006 (7:52 am)
@Stephan
Camera inherits from ShapeBase and is correctly added to the list of mounted objects. I think the problem lies with the ghosting.
#4
10/11/2006 (9:17 am)
@Robrett (I could not resist :D)
Sorry about that! I was under the impression Camera was inherited from GameBase.

I am not sure what the issue is here :/ I just know that it took some porting of code from other classes to get my collidable camera working, because in vanilla TGE it is not meant to be ghostable.
#5
10/11/2006 (9:38 am)
@Stephan
Thanks for your willing assistance. Although the bit about Robrett you will have to explain to me :-) sometime.

The problem was in Camera::packUpdate. The mask returned from Parent::packUpdate was ignored and 0 was returned in all cases. This must have lead to Ghosting not being resolved.

Here are my changes:

U32 Camera::packUpdate(NetConnection *con, U32 mask, BitStream *bstream)
{
U32 retMask = Parent::packUpdate(con,mask,bstream);

// The rest of the data is part of the control object packet update.
// If we're controlled by this client, we don't need to send it.
if(bstream->writeFlag(getControllingClient() == con && !(mask & InitialUpdateMask)))
return retMask;

if (bstream->writeFlag(mask & MoveMask)) {
Point3F pos;
mObjToWorld.getColumn(3,&pos);
bstream->write(pos.x);
bstream->write(pos.y);
bstream->write(pos.z);
bstream->write(mRot.x);
bstream->write(mRot.z);
}

return retMask;
}