Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Calculating a vector normal?

SephirothSephiroth Fayetteville, NC, USAMember Posts: 1,035
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]

Comments

  • asmosprogasmosprog Member Posts: 54
    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
  • asmosprogasmosprog Member Posts: 54
    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

  • SephirothSephiroth Fayetteville, NC, USAMember Posts: 1,035
    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]

Sign In or Register to comment.