Author Topic: Rotation help.  (Read 1187 times)

How can I compare two player's rotation to effectively tell whether or not player1 is in player2's field of view, vice versa.

Example:




                   player1 is looking      ^^^^^^^
                          \ \ \ \ \ \ \ \ \  |||||||||||
                           \ \ \ \ \ \ \ \ \ |||||||||||
                            \ \ \ \ \ \vvvv|||||||||||
                              v v v v v player2 is looking

Notice player1's view contains player 2 in some of it, hope someone get's that little picture lol.
« Last Edit: November 14, 2011, 12:34:54 PM by Superb »

You can find the angle between the forward vector of a player and the two positions of the players.  If the angle is large, then the other person is not in the field of view.

Here is a snippet that might help

Code: [Select]

function lookat(%posb)
{
%posa = serverconnection.getcontrolobject().getposition();
%xa = getword(%posb, 0) - getword(%posa, 0);
%ya = getword(%posb, 1) - getword(%posa, 1);
%za = getword(%posb, 2) - getword(%posa, 2) - getword(serverconnection.getcontrolobject().getdatablock().boundingbox, 2)/5 + $iamcrouching*1.5;
%la = msqrt(mpow(%xa, 2) + mpow(%ya, 2) + mpow(%za, 2));
%pitcha = macos(%za/%la);
%yawa = matan(%xa, %ya);

%v = serverconnection.getcontrolobject().getmuzzlevector(0);
%xb = getword(%v, 0);
%yb = getword(%v, 1);
%zb = getword(%v, 2);
%pitchb = macos(%zb);
%yawb = matan(%xb, %yb);

%pitch = %pitcha - %pitchb;
%yaw = %yawa - %yawb;

$mvpitch = %pitch;
$mvyaw = %yaw;
}

Not sure if this is what you're looking for, but Destiny wrote this up awhile ago.
Code: [Select]
function Player::objectInView(%player,%object)
{
if(!isObject(%object))
return 0;


//The eye point is the position of the players camera
%eye = %player.getEyePoint();
//The position of the object
%to = posFromTransform(%object.getTransform());

if(vectorDist(%eye,%to) < %range)
return 0;

//Cast a raycast to try and collide with the object
%ray = containerRaycast(%eye,%to,$TypeMasks::StaticShapeObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::PlayerObjectType | $TypeMasks::FxBrickObjectType | $TypeMasks::InteriorObjectType,%player);
%col = getWord(%ray,0);
if(isObject(%col) && %col == %object)
{
//The position of the collision
%pos = posFromRaycast(%ray);

//Super Maths C skills go B)
%resultant = vectorSub(%pos,%eye);
%normal = vectorNormalize(%resultant);

//Find the yaw from the resultant
%resultRadians = mAtan(getWord(%normal,1),getWord(%normal,0));

//Find the yaw from the eye vector
%eyeVec = %player.getEyeVector();
%eyeRadians = mAtan(getWord(%eyeVec,1),getWord(%eyeVec,0));

//Convert both of them to degrees for easier understanding
%resultDegrees = mRadToDeg(%resultRadians);
%eyeDegrees = mRadToDeg(%eyeRadians);

//Now the tricky part. In order for the object to be in sight, lets say that the object needs to be within 90 degrees of the players view
//Change 90 to something smaller if you don't like how wide the view is
if(%resultDegrees >= %eyeDegrees - 90 && %resultDegrees <= %eyeDegrees + 90)
return 1;
}
//No object hit, or not the target object, return 0/false
return 0;
}

This is some stuff that Quark figured out the math for and I scripted quite recently:

Code: [Select]
// x = eye position
// y = eye vector
// z = object position

function calculateCenterDistance( %x, %y, %z )
{
%s = vectorScale( %y, vectorLen( mAbs( vectorSub( %x, %z ) ) ) );
%b = mAbs( vectorDist( %z, vectorAdd( %x, %s)) );
%a = mAbs( vectorSub(%x, %z ) );
%l = vectorLen( %a );
%r = %b / ( 2 * %l );
if( %r > 1 )
%r = 1;
if( %r < -1 )
%r = -1;
return 2 * mAsin( %r );
}

if( mAbs( mRadToDeg( calculateCenterDistance( %obj1.getEyePoint(), %obj1.getEyeVector(), %obj2.getPosition() ) ) ) <= fov in degrees / 2 )

Please note that with this code, you'll also have to do a raycast as well to make sure that no objects are in the way.



This may or may not be better than what otto-san posted, but you should try both and see what works out best for you.
« Last Edit: November 15, 2011, 02:40:48 AM by Port »

The only problem with my script (I think) is that if there's a 1x1 brick in the it'll say that the object is out of view. Might be alright for a quick script, but if you want to be really crafty you can do some Depth of Field checks by finding the size of the collided object if it's not the player and then scaling the size by the distance from the eye point and if that size is over some threshold when compared to the target objects scale scaled by the position from the eye point then you can assume its covering it.