# Calculating a vector normal?

Fayetteville, NC, USA
I need to figure out how to calculate a normal of a vector for a 3D calculation I am performing on some AI on my engine. I need to do this to see if any other NPCs or players are within the specified NPC's FOV. Here's a basic example of what I have, that is not working.
[code]
float CoreDot(const FVector &vA, const FVector &vB)
{
return ((vA.X * vB.X) + (vA.Y * vB.Y) + (vA.Z * vB.Z));
}

FVector CoreNormal(FVector vVect)
{
float fMagnitude;

fMagnitude = sqrt((vVect.X * vVect.X) + (vVect.Y * vVect.Y) + (vVect.Z * vVect.Z));
fMagnitude = abs(fMagnitude);
vVect.X = abs(vVect.X / fMagnitude);
vVect.Y = abs(vVect.Y / fMagnitude);
vVect.Z = abs(vVect.Z / fMagnitude);

return vVect;
}

bool NPCInFOV(APawn *pTarget)
{
FVector vX, vY, vZ, vD;

if((FOV <= 0) || (FOV >= 180))
return true;

CoreGetAxes(CoreNormalize(Controller->Pawn->GetViewRotation()), vX, vY, vZ);
vD = (pTarget->Location - Controller->Pawn->Location);

return (CoreDot(CoreNormal(vD), CoreNormal(vX)) > cos(FOV * Pi / 180));
}
[/code]
Any ideas?

-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]

• Hello Sephiroth,

Try the following.

[code]
FVector CoreNormal(FVector vVect)
{
float m = vVect.x * vVect.x + vVect.y * vVect.y + vVect.z * vVect.z;
// If the magnitude of the vector is zero we can't normalize it.
if (m == 0) return vVect;
// Only do the division once. 'sqrt' only accepts and returns positive values so no need for 'abs'.
m = 1 / sqrt(m);
// 'm' is now 1/m so we can multiply the vector components by the new 'm' instead of dividing which takes longer.
vVect.x *= m;
vVect.y *= m;
vVect.z *= m;
return vVect;
}

bool NPCInFOV(APawn *pTarget)
{
FVector player_direction; // Set to the current players normalized direction.
FVector direction_to_pTarget= CoreNormal(pTarget->Location - Controller->Pawn->Location);
// Get angle between the player direction and the direction to pTarget.
float angle = CoreDot(player_direction,direction_to_pTarget);
// If 'angle' < 0 than pTarget is behind the player.
if (angle < 0 || angle > cos(FOV * Pi / 180)) return false;
return true;
}
[/code]

I hope this works OK for you. I haven't tested it but it should work fine.

Cheers,
Michael Gallagher
asmosprog@hotmail.com
• Hello Sephiroth,

I made a bit of a mistake in the last bit of code.

[code]
if (angle < 0 || angle > cos(FOV * Pi / 180)) return false;
[/code]

should be changed to

[code]
if (angle < cos(FOV * Pi / 180)) return false;
[/code]

Sorry about that . I think that should work for you now without any trouble.

Cheers,
Michael Gallagher
asmosprog@hotmail.com
Cheers,
Michael Gallagher
asmosprog@hotmail.com

• Fayetteville, NC, USA
I know I didn't reply right away, but yeah I was barking up that tree myself, and I had made the same mistake you made in your first post. With your correction it works 100% and things are starting to run very smoothly, so thanks.

-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]