Problem with a function called in OnRender()
by Anthony Rosenbaum · in Torque Game Engine · 05/25/2003 (4:04 pm) · 18 replies
I am working on the homing missile code that is available at Luigi Rossi's site. The bug I am working is in the rendering of the "locking" icon. If you are the host the rendering works great, but if you are the client you can't see the lock, although it DOES lock. Intially it always rendered on the host's computer. I was able to stop that by surrounding the call "renderTagetHud" by the if(isClient())
So knowing it works for the host let me show you how the renderTargetHUD works
void ShapeBase::renderObject(SceneState* state, SceneRenderImage* image)
.....
ShapeImageRenderImage* shiri = dynamic_cast<ShapeImageRenderImage*>(image);
if (shiri != NULL)
{
renderMountedImage(state, shiri);
MountedImage* mimage = getImageStruct(shiri->mIndex);
if((bool)mimage->lockTarget)
{
if(isClientObject())
{
renderTargetHUD(state, mimage);
}
}
}So knowing it works for the host let me show you how the renderTargetHUD works
void ShapeBase::renderTargetHUD(SceneState* state, MountedImage* image)
{
GameConnection* conn = GameConnection::getServerConnection();
if(conn->getControlObject() != this)
return;As you can see this code gets the Server connection and renders on it. Logically I tried get LocalClientConnection() but that just broke the lock for the host. Does anyone have any ideas?About the author
#2
For the client to display the locking icon you need to tell the client of this information. You can probably do this via script or by using packupdate.
05/25/2003 (10:37 pm)
The lock seems to be handled on the server.For the client to display the locking icon you need to tell the client of this information. You can probably do this via script or by using packupdate.
#3
05/26/2003 (6:09 am)
I can't figure this thing out, after some review I noticed that the function only gets called by ther host. Where can I put this function so it behaives correcly HELP!!!
#4
05/27/2003 (5:53 am)
Daniel: The locking code does get sent via packupdate, my concern is where to put the rendering code so it renders on the client too.
#5
Stefan.
05/27/2003 (6:21 am)
I had a similar problem with a bool in the render function, too. It got sent via packupdate, too, after it was set by a script, however, it seemed that it somehow didn't reach the render function on the client. It turned out, that the action of setting the bool wasn't noticed and thus wasn't sent. So I changed this by setting an appropriate bit in the bit mask. Like that the bool was set, setBitMask told the engine to transmit the change and pack/unpackupdate did the rest. Maybe this helps. Does it render if you replace (bool)mimage->lockTarget with a hardcoded true, just to check that?Stefan.
#6
05/27/2003 (11:48 am)
Hard coding true causes it to lock up the game. I noticed once that after you mount a seekerprojectile weapon then change weapons to something non seeker the code expect the new weapon to have reticules I hacked a fix by making reticules all transparent for the other weapons. But I belive that might be a releated issue to what you were describing. HELP HELP HELP HELP
#7
if((bool)mimage->lockTarget)
05/31/2003 (9:46 am)
Well it isn't that the host is calling the objectRender it just never gets pastif((bool)mimage->lockTarget)
#8
If you take a closer look in ShapeImage.cc in the function "ShapeBase::updateImageState" in the "if (imageData.isSeeker) { " part, there's the differentiation between the server and the client call. There the server part actually does the lock on the target and set's the target to be transfered to the client. And in the client part there is the if(...) statement to check if an actual target was set by the server. I think we have to search there a bit more...
Hope we find it soon... :-)
Martin
05/31/2003 (1:05 pm)
Yepp, that's right. And what I found out so far is that this is because the "mimage->lockTarget" variable is not correctly transfered from the server to the client when the lock is done.If you take a closer look in ShapeImage.cc in the function "ShapeBase::updateImageState" in the "if (imageData.isSeeker) { " part, there's the differentiation between the server and the client call. There the server part actually does the lock on the target and set's the target to be transfered to the client. And in the client part there is the if(...) statement to check if an actual target was set by the server. I think we have to search there a bit more...
Hope we find it soon... :-)
Martin
#9
Here is the whole bit the way it came and then I'll take about particular parts
from ShapeBase::updateImageState
This bit is the powerhouse and does work for both client and host to lock on to. I bolded the area where target is used and are having problems with. Mainly the ever last test in the isClientObject() area.
Things to note
if I change the if (target), within the getControllingClient() block, to if(image.locked) It will display the "locked" hud only, and render only on the host. But all clients will echo correctly. When they have a lock and when they don't. But because the target won't work in this area it never gets set so we can't test to see if the rendering code is alright. Right now I am stumped. Only thing I can thing of is adding another variable to the image structure to hold potential targets or something.
06/08/2003 (3:22 pm)
After some more poking around I can assure you, you are correct. As I can see it the target variable, used for possible shapebase targets on the target set itterator, is not being set. Here is the whole bit the way it came and then I'll take about particular parts
from ShapeBase::updateImageState
//Luigi's Missiles
// Seeker management
if (imageData.isSeeker) {
MatrixF muzTrans;
Point3F pos, spos;
getEyeTransform(&muzTrans);
// the actual muzzle transform is inconsitent on the server and client
// due to players not being animated on the server, eye transform is
// much safer, and easier to aim
muzTrans.getColumn(3, &pos);
Point3F muzZ;
muzTrans.getColumn( 1, &muzZ );
[b] ShapeBase* target = NULL; [/b]
F32 closestAngle = (imageData.maxSeekAngle*M_PI/180);
F32 dot;
SimSetIterator itr(Sim::getServerTargetSet());
if(!isServerObject())
itr = SimSetIterator(Sim::getClientTargetSet());
for (; *itr; ++itr) {
if ((*itr)->getType() & imageData.lockObjectType) {
//Con::printf("target type found ");
[b] ShapeBase* shape = static_cast<ShapeBase*>(*itr);[/b]
spos = shape->getPosition();
spos.z += (shape->getObjBox().len_z()/2);
Point3F dir = spos - pos;
F32 len = dir.len();
if(len <= imageData.seekRadius && shape->getHeat() >=
imageData.minSeekHeat)
{
// Con::printf("target's heat is %d",shape->getHeat());
// check los
static U32 losMask = STATIC_COLLISION_MASK;
RayInfo info;
bool los;
if(isServerObject())
los = !gServerContainer.castRay(pos, spos, losMask, &info);
else
//if(isClientObject())
los = !gClientContainer.castRay(pos, spos, losMask, &info);
if(los)
{
dot = mDot(dir,muzZ);
F32 lc = muzZ.len();
dot = mAcos((dot/lc)/len);
if(dot <= closestAngle)
{
[b]target = shape; [/b]
closestAngle = dot;
}
}
}
}
}
if(isServerObject())
{
[b] if(target)[/b] //works
{
if(!image.lockTarget || target != image.lockTarget)
{
if(image.locked)
setMaskBits(ImageMaskN << imageSlot);
image.seekStart = Sim::getCurrentTime();
image.locked = false;
}
else
if( (Sim::getCurrentTime() - image.seekStart) >= image.dataBlock->seekTime)
{
if(!image.locked)
setMaskBits(ImageMaskN << imageSlot);
image.locked = true;
}
else
{
image.locked = false;
}
[b] image.lockTarget = target;[/b]
}
else
{
if(image.locked)
setMaskBits(ImageMaskN << imageSlot);
image.lockTarget = NULL;
image.locked = false;
}
}
else{
// client, only gets the target, server decides lock
if(isClientObject());
{
if(getControllingClient())
{
[b]if(target)[/b]//not working for clients other than the host
{
Con::printf("TARGET LOCKED");
[b]image.lockTarget = target;[/b]
}
else
{
Con::printf("NO TARGET LOCKED");
image.lockTarget = NULL;
}
//Con::printf("A CLIENT SCRIPT CAN BE CALLED HERE");
//scriptOnAdd();
}
}
//old code
// if(target)
// {
//image.lockTarget = target;
// }
// else
// {
// image.lockTarget = NULL;
// }
}
}This bit is the powerhouse and does work for both client and host to lock on to. I bolded the area where target is used and are having problems with. Mainly the ever last test in the isClientObject() area.
Things to note
if I change the if (target), within the getControllingClient() block, to if(image.locked) It will display the "locked" hud only, and render only on the host. But all clients will echo correctly. When they have a lock and when they don't. But because the target won't work in this area it never gets set so we can't test to see if the rendering code is alright. Right now I am stumped. Only thing I can thing of is adding another variable to the image structure to hold potential targets or something.
#10
I added an additional variable which works fine for the host but again does not get picked up by the clients.
06/08/2003 (6:24 pm)
UPDATE I added an additional variable which works fine for the host but again does not get picked up by the clients.
#11
06/09/2003 (5:31 pm)
UPDATE After restoring code to its origial state I noticed that the rendering works fine for the clients, but it the fact that it renders on the Host I think teh problems lie withing renderTargetingHUD() itself
#12
06/10/2003 (9:03 am)
Update I noticed that the clients' hud gets rendered on the Host's computer if the the Client is locking on to someone AND the host has a "line of sight" on the client locking something.
#13
Why would this code
This must be part of the problems cause a recticle won't show unless the Host positions themself to have a LOS on the client, who is the one that is targeting some one else
06/11/2003 (7:12 am)
UpdatedWhy would this code
if(isServerObject())
los = !gServerContainer.castRay(pos, spos, losMask, &info);
else
los = !gClientContainer.castRay(pos, spos, losMask, &info);
if(los)
{
dot = mDot(dir,muzZ);
F32 lc = muzZ.len();
dot = mAcos((dot/lc)/len);
if(dot <= closestAngle)
{
target = shape;
closestAngle = dot;
}
}and this if(target)
{
image.lockTarget = target;
}
else
{
image.lockTarget = NULL;
}Only set on the server?This must be part of the problems cause a recticle won't show unless the Host positions themself to have a LOS on the client, who is the one that is targeting some one else
#14
here is the Whole renderTargetHud function
If you notice 2 viewports are called, now my Open GL is beginner to intermediate at best. But the variable viewport2 seems to hold the client's screen but, dglSetViewPort(viewport2) never gets called.
06/11/2003 (1:45 pm)
OK under the assumtion that maybe the GL code might be off let me post some possibilities.here is the Whole renderTargetHud function
void ShapeBase::renderTargetHUD(SceneState* state, MountedImage* image)
{
// Con::printf("IN RENDER HUD");
GameConnection* conn = GameConnection::getServerConnection();
if(conn->getControlObject() == image->lockTarget)
{
//Con::printf("LOCKED TO SELF ");
return;
}
glDisable(GL_LIGHTING);
Point3F targetPos = image->lockTarget->getPosition();
targetPos.z += (image->lockTarget->getObjBox().len_z()/2);
[b]RectI viewport;
dglGetViewport(&viewport); [/b]
glMatrixMode(GL_PROJECTION);
glPushMatrix();
state->setupObjectProjection(this);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
state->setupObjectProjection(this);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
if(!image->dataBlock->lockReticleTexture.getName())
glDisable(GL_TEXTURE_2D);
else
glEnable(GL_TEXTURE_2D);
glDepthMask(GL_FALSE);
//-----------------------
//
// render targeter
//
Point3F screenPoint;
if( dglPointToScreen( targetPos, screenPoint ))
{
MatrixF camTrans;
F32 fov;
conn->getControlCameraTransform(0, &camTrans);
conn->getControlCameraFov(&fov);
Point3F camPos = camTrans.getPosition();
Point3F camZ;
camTrans.getColumn( 1, &camZ );
Point3F v = targetPos - camPos;
F32 dot = mDot(v,camZ);
if(dot > 0.0f)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// set ortho mode [b]
RectI viewport2;
dglGetViewport(&viewport2);
dglSetClipRect( viewport2 );[/b]
if(image->locked)
{
if((bool)image->dataBlock->lockReticleTexture.getName())
glBindTexture(GL_TEXTURE_2D,
image->dataBlock->lockReticleTexture.getGLName());
}
else
{
if((bool)image->dataBlock->seekReticleTexture.getName())
glBindTexture(GL_TEXTURE_2D,
image->dataBlock->seekReticleTexture.getGLName());
}
F32 size = 30;
dglDraw2DSquare( Point2F( screenPoint.x, screenPoint.y ), size, 0 );
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glDisable(GL_BLEND);
}
}
//-----------------------
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDepthMask(GL_TRUE);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
[b]dglSetViewport(viewport);[/b]
glEnable(GL_LIGHTING);
}If you notice 2 viewports are called, now my Open GL is beginner to intermediate at best. But the variable viewport2 seems to hold the client's screen but, dglSetViewPort(viewport2) never gets called.
#15
Well after some talk with KillerBunny , I realized that these thing are SUPPOST to be GUI elements so right now I hacked a starting point. I made a copy of the health gui element and made it change colors depending on if there is a lock or not. I will be back when I have something more to tell you. But I can tell you so far it works!!!
06/11/2003 (8:09 pm)
UPDATEWell after some talk with KillerBunny , I realized that these thing are SUPPOST to be GUI elements so right now I hacked a starting point. I made a copy of the health gui element and made it change colors depending on if there is a lock or not. I will be back when I have something more to tell you. But I can tell you so far it works!!!
#16
Anthony Rosenbaum
06/14/2003 (3:52 pm)
After working with Luigi he was able to fix my code, I'm not sure what I missed, but in case others are having problems I am posting the player.cc, shapebase.cc and shapeimage.cc file in zip format, here Warning this code has ConformToGround code from the resource posted by BraveTree for their game Think Tanks. I was so stranded that. I hope this helps anyone trying to impliment this code. I especially want to say Thank You to Luigi Rosso, for helping me with this code, I'm sure we will see some great stuff from this up an comming game developer.Anthony Rosenbaum
#17
01/27/2005 (7:11 pm)
I meet the same question.@Anthony,could you post your fix code?thanks.
#18
01/28/2005 (5:30 am)
Sorry all that code got rewritten, and is IP which I can't release, there is a homing missile resource search the resources to find it
Associate Anthony Rosenbaum