Can clients do ContainerRayCasts?
by Drew Parker · in Torque Game Engine · 04/08/2004 (10:21 am) · 16 replies
I posted this in the MOD forum yesterday, but moved it here because I need to talk about C++ code. (I always have trouble deciding where to post script questions that correlate to C++). Sorry about the confusion.
Anyway, I'm trying to do a ContainerRayCast on the client side only, to save some bandwidth and server processing time. I've modified the Object Selection resource to do raycasts to see what's under the mouse cursor not only on a mouseclick, but at anytime, basically, a mouseover. The problem I'm having is when I do a client side raycast, I always get the same ID number returned, no matter where the mouse is on the screen. If I click, however (thus calling the Object Selection resources code) I get the right object ID. It should be noted I'm using the exact same code, only running the ContainerRayCast from the client, in PlayGui.cs.
Has anybody else run up against this?
Anyway, I'm trying to do a ContainerRayCast on the client side only, to save some bandwidth and server processing time. I've modified the Object Selection resource to do raycasts to see what's under the mouse cursor not only on a mouseclick, but at anytime, basically, a mouseover. The problem I'm having is when I do a client side raycast, I always get the same ID number returned, no matter where the mouse is on the screen. If I click, however (thus calling the Object Selection resources code) I get the right object ID. It should be noted I'm using the exact same code, only running the ContainerRayCast from the client, in PlayGui.cs.
Has anybody else run up against this?
About the author
#2
Sounds like it only performs a raycast on the server-set. So (entering into dark territory here) I changed that variable to be gClientContainer, since I figured that might be the client-side equivalent.
I've spent a good 1 1/2 to 2 weeks on this problem, and read everything I can find on the client side radars and such. I've debugged all the mouse-click and mouse-over raycasts, as well as the mouse pointer locations, and the results from my mouse-over function matches exactly with the Object Selection resource results. With the little I know about ghosting, it seems that their should still be objects existing on client in ghosted form, correct? So shouldn't I at least be able to find those objects with some sort of raycast?
04/08/2004 (10:46 am)
Last night I did some more looking, and decided to look into the ContainerRayCast function itself. Something noteworthy I found was the C++ raycast call from the object gServerContainer. ConsoleFunction( containerRayCast, const char*, 4, 5, "( Point3F start, Point3F end, bitset mask, SceneObject exempt=NULL )"
"Cast a ray from start to end,.......)
{
char *returnBuffer = Con::getReturnBuffer(256);
Point3F start, end;
dSscanf(argv[1], "%f %f %f", &start.x, &start.y, &start.z);
dSscanf(argv[2], "%f %f %f", &end.x, &end.y, &end.z);
U32 mask = dAtoi(argv[3]);
SceneObject* pExempt = NULL;
if (argc > 4) {
U32 exemptId = dAtoi(argv[4]);
Sim::findObject(exemptId, pExempt);
}
if (pExempt)
pExempt->disableCollision();
RayInfo rinfo;
S32 ret = 0;
[b] if (gServerContainer.castRay(start, end, mask, &rinfo) == true)[/b]
ret = rinfo.object->getId();
[i]// more code....[/i]Sounds like it only performs a raycast on the server-set. So (entering into dark territory here) I changed that variable to be gClientContainer, since I figured that might be the client-side equivalent.
I've spent a good 1 1/2 to 2 weeks on this problem, and read everything I can find on the client side radars and such. I've debugged all the mouse-click and mouse-over raycasts, as well as the mouse pointer locations, and the results from my mouse-over function matches exactly with the Object Selection resource results. With the little I know about ghosting, it seems that their should still be objects existing on client in ghosted form, correct? So shouldn't I at least be able to find those objects with some sort of raycast?
#3
This is the call from script:
playGui.cs
The last argument is what to exempt from the search, right? If I called the above line correctly, then perhaps the way I derive the %player var is wrong? I've been having a lot of trouble figuring out how to get references to the player and client objects clientside. In another resource I found this and implemented it:
client/scripts/serverConnection.cs
So I'm assuming I've disabled the collision with the player's ghost. Unless I am doing something wrong getting a reference to the player object on the client?
04/08/2004 (10:53 am)
Hi Ben,This is the call from script:
playGui.cs
%player = $localPlayer;
if ($firstPerson)
%scanTarg = ContainerRayCast (%cameraPoint, %rangeEnd, %searchMasks, %player);The last argument is what to exempt from the search, right? If I called the above line correctly, then perhaps the way I derive the %player var is wrong? I've been having a lot of trouble figuring out how to get references to the player and client objects clientside. In another resource I found this and implemented it:
client/scripts/serverConnection.cs
function GameConnection::onConnectionAccepted(%this)
{
// Called on the new connection object after connect() succeeds.
[b]$localPlayer = %this; // store the local player reference [/b]
LagIcon.setVisible(false);
}So I'm assuming I've disabled the collision with the player's ghost. Unless I am doing something wrong getting a reference to the player object on the client?
#4
If I ever figure this out, I'll allow myself to think of it as an accomplishment. :)
Ben:
I saw your post in my e-mail box the other day, from when my post was in the old thread, "1476 is probably a ghost of 1448. Have you tried calling dump on it?" Sorry, I forgot to refresh my browser and had deleted the thread, so I never got your post. I haven't tried calling dump on it yet, but I'll try and see what happens.
04/09/2004 (8:13 am)
I did a test last night with a dedicated server and client on the same machine. Before I said when I did the client-side raycast, I was always getting a specific ID, like 1476. This time, I always got 0. So it looks like the raycast isn't finding anything, not even the player's ghost. Strange when running a single-player game I get 1476, and when running a dedicated server and client I get 0.If I ever figure this out, I'll allow myself to think of it as an accomplishment. :)
Ben:
I saw your post in my e-mail box the other day, from when my post was in the old thread, "1476 is probably a ghost of 1448. Have you tried calling dump on it?" Sorry, I forgot to refresh my browser and had deleted the thread, so I never got your post. I haven't tried calling dump on it yet, but I'll try and see what happens.
#5
Although I'd suggest making a clientCastContainerRay or somesuch so that you know which container you're casting in.
04/09/2004 (8:21 am)
If you changed gServerContainer to gClientContainer in that code snippet, I'd also suggest stepping through the code and seeing what's going on there. This is a problem that really shouldn't take you that long to knock down. ;)Although I'd suggest making a clientCastContainerRay or somesuch so that you know which container you're casting in.
#6
04/09/2004 (8:46 am)
Thanks for the encouragement, Ben, I'll see what I can do. :) I already made a seperate console function clientRayCast, now I'll try debugging it to see what I come up with. I was trying not to re-invent the wheel in case there was a 'proper' way to go about this that I didn't know of. But if not, hey, I'm not at all against rolling up my sleeves and getting my hands dirty with Torque! I'll keep everyone posted on how it goes...
#7
Basically, the IDs I was using to reference the local client and local player on the client machine were all wrong, so the raycast wasn't working. My idea of ghosting and ghosted IDs was all wrong. I thought there were just 2 sets of numbers, the servers and the clients. But there are 3 sets, the servers, the clients, and the ghosted indexes that connect the two. After I realized that, things slowly fell into place. To summarize really quick, this is what I had to do to fix my original problem:
- Write a function in C++ code called clientContainerRayCast, make it accessible by script
- Have the server send the client their clientID and playerID after the player is created on the server, use a schedule command to wait a bit so the player can finish ghosting to the client
- Send the clientID and playerID with getGhostIndex()
- The client receives the 2 values and runs resolveGhost() on them, giving the client the correct IDs for their local system
- Do the clientContainerRayCast, find what you are looking for on the client, yeah!
If anyone needs a more detailed breakdown let me know. It was quite a process and a few pieces (besides what's listed here), but I finally got the client-side mouse-overs to work.
Ben, thanks for all the help! You were right on both counts also, the player was blocking the raycasts in first person mode (since I had the wrong reference to the player, the exempt wasn't working)
04/14/2004 (6:48 am)
Ok, I got it working. I did have the wrong ID reference to the client's player object.Basically, the IDs I was using to reference the local client and local player on the client machine were all wrong, so the raycast wasn't working. My idea of ghosting and ghosted IDs was all wrong. I thought there were just 2 sets of numbers, the servers and the clients. But there are 3 sets, the servers, the clients, and the ghosted indexes that connect the two. After I realized that, things slowly fell into place. To summarize really quick, this is what I had to do to fix my original problem:
- Write a function in C++ code called clientContainerRayCast, make it accessible by script
- Have the server send the client their clientID and playerID after the player is created on the server, use a schedule command to wait a bit so the player can finish ghosting to the client
- Send the clientID and playerID with getGhostIndex()
- The client receives the 2 values and runs resolveGhost() on them, giving the client the correct IDs for their local system
- Do the clientContainerRayCast, find what you are looking for on the client, yeah!
If anyone needs a more detailed breakdown let me know. It was quite a process and a few pieces (besides what's listed here), but I finally got the client-side mouse-overs to work.
Ben, thanks for all the help! You were right on both counts also, the player was blocking the raycasts in first person mode (since I had the wrong reference to the player, the exempt wasn't working)
#8
Would you mind posting your changes please? (or if it is too long, just a link to your modified files)
I was trying to do exactly the same, and it'd be nice to see how you did it (^_^)
Thanks,
Isi
08/05/2004 (1:41 pm)
Hi Drew,Would you mind posting your changes please? (or if it is too long, just a link to your modified files)
I was trying to do exactly the same, and it'd be nice to see how you did it (^_^)
Thanks,
Isi
#9
08/10/2004 (11:03 am)
Isi - you are trying to get mouse-overs to work, or a client version of ContainerRayCast?
#10
I currently have a mouse-over based on the Object Selection resource, but it is server side.
I tried your method, but I am stuck at the end. clientContainerRayCast() sends me the ID of the object it found, ok, but I am not too sure what to do with it actually. Maybe this local ID has nothing to do with the server's one's and I don't really know how to convert one into the other. Unless I got it all wrong :D
(I have to say I didn't investigate very long... (^^;) )
Isi
08/10/2004 (1:27 pm)
Hi Drew,I currently have a mouse-over based on the Object Selection resource, but it is server side.
I tried your method, but I am stuck at the end. clientContainerRayCast() sends me the ID of the object it found, ok, but I am not too sure what to do with it actually. Maybe this local ID has nothing to do with the server's one's and I don't really know how to convert one into the other. Unless I got it all wrong :D
(I have to say I didn't investigate very long... (^^;) )
Isi
#11
First off, clientContainerRayCast() doesn't actually exist in the engine, I had to write that one myself. It just takes some small modification of containerRayCast to look in the client container instead of the server container (just in case you didn't know about that one already :)
Once you use some kind of client ray cast to find the client object you are looking at, you need to pass it to the server. How do you pass it? You work with getGhostIndex() and ResolveGhost(). What that does is allow the server to know what object the client is talking about.
For instance, if the server has an object, like a healthkit, it's assigned a number. Lets say the number is 20. On the client, the number will be different, like maybe 34. So if you mouse over the health kit on the client and send that ID to the sever (which is 34), the server won't know what you are talking about, since on the server the healthkit is ID 20. So you have to change that 34 to a 20 through the ghost commands.
Do a search on GG, there should be a number of threads and probably a few resources about it.
Good luck!
09/01/2004 (9:57 am)
Hi Isi,First off, clientContainerRayCast() doesn't actually exist in the engine, I had to write that one myself. It just takes some small modification of containerRayCast to look in the client container instead of the server container (just in case you didn't know about that one already :)
Once you use some kind of client ray cast to find the client object you are looking at, you need to pass it to the server. How do you pass it? You work with getGhostIndex() and ResolveGhost(). What that does is allow the server to know what object the client is talking about.
For instance, if the server has an object, like a healthkit, it's assigned a number. Lets say the number is 20. On the client, the number will be different, like maybe 34. So if you mouse over the health kit on the client and send that ID to the sever (which is 34), the server won't know what you are talking about, since on the server the healthkit is ID 20. So you have to change that 34 to a 20 through the ghost commands.
Do a search on GG, there should be a number of threads and probably a few resources about it.
Good luck!
#12
I had another different bug anyway (an invisible GUI item capturing the mouse-over. a bit strange... ). This having been fixed, and with your extra info on the ghosting, it should be ok now!
Thanks!
Isi
09/01/2004 (10:39 am)
Ok, I think I get it :)I had another different bug anyway (an invisible GUI item capturing the mouse-over. a bit strange... ). This having been fixed, and with your extra info on the ghosting, it should be ok now!
Thanks!
Isi
#13
how did you fix it ?
see my comment down towards the tail of:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=2173
09/01/2004 (11:47 am)
Isi - i'm having that exact problem!how did you fix it ?
see my comment down towards the tail of:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=2173
#14
I am not sure whether it will solve things for you, but to solve this,
I modified starter.fps/client/ui/chatHud.gui:
Around line 82 (in the definition of "MainChatHud") I just resized the first GuiControl object.
changing
to
I think it is an invisible area anyway, but it was catching the mouse-down event (or the mouse-over, I can't remember) when the mouse was too close from the chat-hud.
Don't know if it helps ^^;
Isi
09/01/2004 (2:12 pm)
Hi Orion!I am not sure whether it will solve things for you, but to solve this,
I modified starter.fps/client/ui/chatHud.gui:
Around line 82 (in the definition of "MainChatHud") I just resized the first GuiControl object.
changing
extent = "400 300";
to
extent = "400 142";
I think it is an invisible area anyway, but it was catching the mouse-down event (or the mouse-over, I can't remember) when the mouse was too close from the chat-hud.
Don't know if it helps ^^;
Isi
#15
Ideally i'd like that gui element
not to catch mouse clicks, but
shrinking it down to the size
of the actual chatr window is better
than a floating invisible element!
If you're using the stock starter.fps demo,
you can shrink that element even further:
extent = "272 72";
09/03/2004 (1:37 pm)
Isi - yes, that's it, thanks.Ideally i'd like that gui element
not to catch mouse clicks, but
shrinking it down to the size
of the actual chatr window is better
than a floating invisible element!
If you're using the stock starter.fps demo,
you can shrink that element even further:
extent = "272 72";
#16
Anyway, thanks for the hint ;)
Isi
09/04/2004 (10:04 am)
Glad it helped :). What you'd like could be changed in the code I suppose , if you really need it. Not sure if it's worth though. Anyway, thanks for the hint ;)
Isi
Associate Kyle Carter