Problem with setCameraObject()
by Markus Nuebel · in Torque Game Engine · 08/11/2004 (10:14 pm) · 6 replies
I am doing some kind of special camera animation/movement, by spawning a ShapeBase derived object and setting this as the new camera object for the GameConnection.
The new camera object is created server side and ghosted to the client.
It is moved and animated on the client, which works quite well.
But the effect of the new camera object is only seen on the client, when you "tab away" from the game (in windowed mode) and "tab back" ???
I think this has something to do with network updates for the GameConnection, but don't know where to look.
Has anyone seen such a thing before?
Why is the change done by GameConection::setCameraObject(); not active immediately?
Here is what I did in detail:
On a server side object I am executing the following:
The MyCamera object is similar to the PathedCamera object.
In it's onAdd() function it directly inserts itself into the respecitve container using:
And it does not use: addToScene();
(Maybe this is the problem??)
There is an AdvancedCamera resource around, that mentions, you have to modify the function:
GameConnection::writePacket() and GameConnection::readPacket(), to have mCameraObject write itself to the stream: e.g. mCameraObject->writePacketData(this, bstream); and mCameraObject->readPacketData(this, bstream);
But this had no effects on my problem.
I still have to "tab-away and -back" from the application, to see the camera move along with my new camera object. After tabbing back to the application, the animation/movement of my special object has already started, so I guess, my new camera object is already ghosted to the client, but the switch from the old to the new camera object is not executed.
Any hints or ideas?
Thanks.
-- Markus
The new camera object is created server side and ghosted to the client.
It is moved and animated on the client, which works quite well.
But the effect of the new camera object is only seen on the client, when you "tab away" from the game (in windowed mode) and "tab back" ???
I think this has something to do with network updates for the GameConnection, but don't know where to look.
Has anyone seen such a thing before?
Why is the change done by GameConection::setCameraObject(); not active immediately?
Here is what I did in detail:
On a server side object I am executing the following:
// Create new camera object and add it to the simulation
MyCamera* pCam = new MyCamera();
pCam->setXYZ();
MyCameraData* pMyCamData = dynamic_cast<MyCameraData*>(Sim::findObject("MySpecialCam"));
pCam->onNewDataBlock( pMyCamData );
pCam->registerObject();
// Switch the camera object for the client connection
GameConnection::getLocalClientConnection()->setCameraObject(pCam); The MyCamera object is similar to the PathedCamera object.
In it's onAdd() function it directly inserts itself into the respecitve container using:
if(isClientObject())
gClientContainer.addObject(this);
else
gServerContainer.addObject(this);And it does not use: addToScene();
(Maybe this is the problem??)
There is an AdvancedCamera resource around, that mentions, you have to modify the function:
GameConnection::writePacket() and GameConnection::readPacket(), to have mCameraObject write itself to the stream: e.g. mCameraObject->writePacketData(this, bstream); and mCameraObject->readPacketData(this, bstream);
But this had no effects on my problem.
I still have to "tab-away and -back" from the application, to see the camera move along with my new camera object. After tabbing back to the application, the animation/movement of my special object has already started, so I guess, my new camera object is already ghosted to the client, but the switch from the old to the new camera object is not executed.
Any hints or ideas?
Thanks.
-- Markus
About the author
#2
The "tabbing" behavior might be explained by third person view, which is triggered by the tab key. On my system when you alt-tab in the demo, the orc often switches into 3rd person view.
Well written post, by the way. I appreciate you explaining your problem so thoroughly. :)
08/13/2004 (9:01 am)
I would try running a dedicated server and a dedicated client. It looks like you might be mixing your client and server semantics, and running two processes will help you clean things up. That will be the first step to fixing things...The "tabbing" behavior might be explained by third person view, which is triggered by the tab key. On my system when you alt-tab in the demo, the orc often switches into 3rd person view.
Well written post, by the way. I appreciate you explaining your problem so thoroughly. :)
#3
Although I debugged a thousand times into GameConnection::getCameraObject() I did not realize the mFirstPerson in the if-statement.
Regardless of the mCameraObject setting, you will get the control object, unless you set mFirstPerson to false.
So in my C++ code I am using:
Ben would it be a bad idea, to add some code to GameConnection::readPacket() to reset the mFirstPeson flag, in case a camera object is used?
E.g.
-- Markus
08/13/2004 (12:01 pm)
Ben, you are my hero ;)Although I debugged a thousand times into GameConnection::getCameraObject() I did not realize the mFirstPerson in the if-statement.
ShapeBase* GameConnection::getCameraObject()
{
// If there is no camera object, or if we're first person, return
// the control object.
if( !mControlObject.isNull() && (mCameraObject.isNull() || mFirstPerson))
return mControlObject;
return mCameraObject;
}Regardless of the mCameraObject setting, you will get the control object, unless you set mFirstPerson to false.
So in my C++ code I am using:
Con::setBoolVariable("firstPerson", false); since mFirstPerson is private to GameConnection, but this works fine for me.Ben would it be a bad idea, to add some code to GameConnection::readPacket() to reset the mFirstPeson flag, in case a camera object is used?
E.g.
void GameConnection::readPacket()
{
....
if (bstream->readFlag())
{
S32 gIndex = bstream->readInt(10);
ShapeBase* obj = static_cast<ShapeBase*>(resolveGhost(gIndex));
setCameraObject(obj);
// Remove the first person flag, in case we are using a camera object
mFirstPerson = false;
}
}-- Markus
#4
08/13/2004 (1:03 pm)
Hmm... Not a bad idea. I'll put it on my todo list.
#5
BTW, you did a great job bringing this problem to light. Well explained, with code citations... made it very easy to address this issue. Thanks, Markus.
08/17/2004 (2:18 pm)
Hey, looked over this with Rick, and we decided that there's not a really clear win in messing with it - it could potentially break people. Really, the whole situation is a bit odd, and one of our major upcoming Torque upgrades should do a lot to clean it up, so for now we're going to let sleeping dogs lie. The best workaround in this situation is either that line of code or to use commandToClient to set the $firstPerson variable.BTW, you did a great job bringing this problem to light. Well explained, with code citations... made it very easy to address this issue. Thanks, Markus.
#6
Yes, you are right. If this might break other code, it's not worth it.
You are talking about the RTS Pack right?
I suppose it deals a lot with camera issues.
-- Markus
08/17/2004 (10:15 pm)
Thanks, Ben.Yes, you are right. If this might break other code, it's not worth it.
You are talking about the RTS Pack right?
I suppose it deals a lot with camera issues.
-- Markus
Torque Owner Markus Nuebel
I am over a week on this little feature now .... :(
Did some additional debugging:
After I am calling: GameConnection::getLocalClientConnection()->setCameraObject(pCam); serverside,
the GameConnection sends this change to the client and handles it in GameConnection::readPacket(BitStream *bstream). Here the client resolves the ghost of the new camera object by index, and calls
clientside.
After the change to the new camera object has taken place: GameConnection::getControlCameraTransform()
is called a few times. (I wanted to see, what camera object is used by the engine, after the switch, so I placed a breakpoint in this function)
It is first called from:
and ShapeBase* obj = getCameraObject(); shows, that my new camera object is used here.
The second call to getControlCameraTransform() is initiated by:
clientProcess(U32 timeDelta) -->GameGetCameraTransform(&mat, &velocity) --> connection->getControlCameraTransform(0, mat)
The same as above: ShapeBase* obj = getCameraObject(); shows, that my new camera object is used here.
Since I am using a EditTSCtrl derived object as game-gui object, the third call to getControlCameraTransform() occurs in:
EditTSCtrl::processCameraQuery(CameraQuery * query)
!!!! Here !!!!
ShapeBase* obj = getCameraObject(); shows, that the default Camera object (not my new camera object) is used as the GameConnections camera object ???
What is going on here?
All the above calls are calling: getControlCameraTransform() on a GameConnection pointer retrieved by:
GameConnection::getServerConnection().
Why is the editTSCtrl any different?
After continuing to debug, I found out, that the camera object is not simple switched back. Following calls from the AmbientAudioManager and the clientProcess() function always use my new camera object, while the calls from EditTSCtrl are using the default camera.
This does not change, until I am "tabbing away and back" to the game (in windowed mode), then everything is fine???
Any tips, hints, ideas, suggestions or pointers?
Thanks
-- Markus