Game Development Community

Angle of the ground where a RayCast intersects

by Chris · in Torque 3D Professional · 05/20/2010 (10:24 am) · 6 replies

Could someone give me some guidance on how to find the angle of a surface I ray cast into from something like Src{0, 0, 100} --> Dst{0, 0, -100} having landscape between those two points that has a 20degree slope. How do I use rInfo to find the angle is 20 degrees at point of intersection?


#1
05/20/2010 (10:44 am)
Curious do you really want the slope or do you really want the gradiant?

if you just want the angle at an area I might suggest just doing two raycasts and using rise over run to find slope from that.
#2
05/20/2010 (11:09 am)
The rayInfo stores the normal vector of the surface hit - rInfo.normal.
If you do a dot product of the normal with the vector {0,0,1} (which is up), the result will be the cosine of the angle between them.

So, in the engine, you could do this with the results of the ray cast:

// get the dot product of the normal and the up vectors
F32 dot = mDot(rInfo.normal, Point3F(0.f, 0.f, 1.f));
// cos 20 degrees
F32 cos20 = mCos(mDegToRad(20.0f));
// compare them
if(dot == cos20)
   doStuff();

or in script:
// do the raycast - change this to something real
%rayinfo = containerRayCast(blah, blah, blah, blah);
// the normal vector is held in the last 3 words
%normal = getWords(%rayInfo, 4, 6);
// work out the dot product
%dot = VectorDot(%normal, "0 0 1");
// and cos 20 degrees
%cos20 = mCos(mDegToRad(20));
// compare them
if(%dot == %cos20)
   doStuff();
#3
05/20/2010 (11:18 am)
@Jacob : I want to find out how flat the surface is that the entity is standing on no matter which direction they are facing

@Guy : This sounds right, I will give it a try
#4
05/20/2010 (11:58 am)
This is really close to working

if(gClientContainer.castRay(ctrlpos + Point3F(0, 0, 5), ctrlpos + Point3F(0, 0, -5), EnvironmentObjectType | TerrainObjectType | InteriorObjectType | WaterObjectType | StaticObjectType, &rInfo))
	  {
		F32 dot = mDot(rInfo.normal, Point3F(0.f, 0.f, 1.f));
		SurfaceAngle = mRadToDeg(dot);
	  }

On flat ground I end up with about 60 and that number gets smaller as I go up steep hills down to about 40.

Is dot value not in rad when I get it?
#5
05/20/2010 (12:15 pm)
The dot is the consine of the angle, not the angle.
#6
05/20/2010 (12:35 pm)
Ok I see that, looks like it works great and thanks for the help everyone.

incase someone searches for this

float SurfaceAngle = 0;
	  RayInfo rInfo;
	  if(gClientContainer.castRay(ctrlpos + Point3F(0, 0, 50), ctrlpos + Point3F(0, 0, -5), EnvironmentObjectType | TerrainObjectType | InteriorObjectType | WaterObjectType | StaticObjectType, &rInfo))
	  {
		F32 dot = mDot(rInfo.normal, Point3F(0.f, 0.f, 1.f));
		SurfaceAngle = mRadToDeg(mAcos(dot));
	  }

this seems to produce the correct result