Game Development Community

how to get distance raycast to render onscreen?

by deepscratch · in Torque 3D Professional · 05/30/2009 (4:32 am) · 17 replies

hiya,
I'm playing with binoculars, and would like to have a distance meter displayed on the binocular guiHud that I am using, that constantly updates to show the view distance at the centre point of where you are looking,
I think you know the effect I'm after,
but I have no idea at all how to implement this.
help?

#1
05/30/2009 (6:48 am)
Well basically, you'd want to make a custom gui for this, grab the player's control object's camera transform (getControlCameraTransform), cast a ray along the forward vector, find what you hit, and then calculate the distance from there.

Was there a specific step that you're not sure how to get started? I'd strongly suggest taking a look at the crosshair gui code included, since it is a very small amount of code to wade though, and had the code to 1) get the camera, 2) Calculate the point in front of it, and 3) Cast the ray... all you've gotta do now is display the distance. (Hint: RayInfo.distance)
#2
05/30/2009 (7:13 am)
@Tim,
I got as far as this
// Get control camera info
   MatrixF cam;
   Point3F camPos;
   conn->getControlCameraTransform(0,&cam);
   cam.getColumn(3, &camPos);

   // Extend the camera vector to create an endpoint for our ray
   Point3F endPos;
   cam.getColumn(1, &endPos);
   endPos *= gClientSceneGraph->getVisibleDistance();
   endPos += camPos;
and got stuck on the displaying part
mDistance = WHAT GOES HERE TO DISPLAY THE DISTANCE?.len());
	if(mDistance > mMaxDistance)
		mDistance = mMaxDistance;
I think I got the rest of the code correct, so I didnt post it all
#3
05/30/2009 (7:44 am)
Perhaps the simplest way would be to have your range gui extend guiTextCtrl, then you can simply use setText()
#4
05/31/2009 (6:54 am)
I got a bit furher with this, and thefunction seems to be correct, but instead of giving me a raycast distance to the point the crosshair points, it gives me a distance moved.
heres the code, anyone know why its not working?
// Use the eye transform to orient the camera
Point3F dir;
MatrixF mat;
mat.getColumn(1, &dir);
F32 rayDistance = 999;

// Use the camera node's pos.

Point3F startPos = conn->getControlObject()->getRenderPosition();
Point3F endPos;

// Make sure we don't extend the camera into anything solid
   conn->getControlObject()->disableCollision();
RayInfo collision;
U32 mask = TerrainObjectType |
           InteriorObjectType |
           WaterObjectType |
           StaticShapeObjectType |
           PlayerObjectType |
           ItemObjectType |
           VehicleObjectType;

endPos = startPos + dir * rayDistance;
Container* pContainer = conn->getControlObject()->isServerObject() ? &gServerContainer : &gClientContainer;
if (!pContainer->castRay(startPos, endPos, mask, &collision))
{
	Point3F distTemp;
	distTemp = collision.point - startPos;
	mDistance = distTemp.len();
}

where mDistance should be the raycast distance.
thanks
#5
05/31/2009 (7:00 am)
Delete line 27 and 28, line 29 should read mDistance = collision.distance;

Edit: Upon further looking at your code, the code at the top to get the direction is all wrong.
#6
05/31/2009 (7:07 am)
Totally untested, but it should look something like this:
MatrixF cam;
   Point3F dir;

   Point3F startPos;
   Point3F endPos;

   // Get control camera info
   conn->getControlCameraTransform(0,&cam);
   cam.getColumn(3, &startPos);
   cam.getColumn(1, &dir);
   endPos = startPos + dir * rayDistance;

	// Make sure we don't extend the camera into anything solid
	conn->getControlObject()->disableCollision();
	RayInfo collision;
	U32 mask = TerrainObjectType |
			   InteriorObjectType |
			   WaterObjectType |
			   StaticShapeObjectType |
			   PlayerObjectType |
			   ItemObjectType |
			   VehicleObjectType;
	
	Container* pContainer = conn->getControlObject()->isServerObject() ? &gServerContainer : &gClientContainer;

	if (pContainer->castRay(startPos, endPos, mask, &collision))
		mDistance = collision.distance;
#7
05/31/2009 (7:10 am)
Additionally, are you really trying to run this same code on server && client? I'd guess that a range finder gui would only be useful on the client, and you shouldn't even be calling this code on the server.
#8
05/31/2009 (7:27 am)
the problem is that I need the ".len();" to render the distance.

// Convert distance to char so we can work with it
	char distanceBuff[8];
	dSprintf(distanceBuff, 7, "%.0f", mDistance);
	S32 len = dStrlen(distanceBuff);

	if(len < maxLen)
		for(int val = maxLen - 1; val >= 0; val--)
		{
			if(val <= len - 1)
			{
				distanceBuff[val + (maxLen - len)] = distanceBuff[val];
				distanceBuff[val] = '0';
			}
		}
#9
05/31/2009 (8:45 am)
I believe collision.distance = is the length
#10
05/31/2009 (10:26 am)
I'm sure it may be, I dropped your snippet straight in, and it renders the position you are in, when you move, it adds, or subtracts from your position, reletive to your move direction,
is there a way to feed "collision.distance" to len?
#11
05/31/2009 (2:58 pm)
@deepscratch - If you want to email me your entire file, I'll drop it into T3D here and take a look at what's going on, I'm thinking it's most likely something really simple but it's hard to remote debug.
#12
05/31/2009 (9:49 pm)
I would be extremely interested in how this turns out. Working on something quite similar a bit down the road.
#13
05/31/2009 (10:48 pm)
@Tim,
thanks for the offer, mailed it.

this is what the rangefiner will look like

img188.imageshack.us/img188/3631/rangef.jpg
#14
06/01/2009 (6:18 am)
@Tim,
the email in your profile is no longer valid??
I got a delivery failed report.
#15
06/01/2009 (8:06 am)
@deepscratch - I've been working on that this morning. I've got 31k new emails at tim@cantanogames.com, and it's kinda crashing the software. Try sending it to timd at the same domain.
#16
06/01/2009 (8:32 am)
great Tim, sent it.
thanks