Possible issue with BoundingFrustum

Hi all,

I am try to put AAA gunner AI into my engine, but having a problem.

I use an entity component system, so I created a AAAGunFOFComponent to hold the valid fields of fire for each weapon.

Weapons can have multiple fields of fire, you don’t want to shoot the tail off your own aircraft, or the bridge of your ship.

The component is defined as heading, max pitch, min pitch, max yaw and min yaw, (range is defined by the weapon)

From this I calculate the four corners in object space and then average them to get the far point of the view volume.

I then calculate a perspective matrix from the pitch and yaw ranges, and a view matrix from the position and target.

These two give me a BoundingFrustum I can use to check for valid targets.

It almost works.

The bounding frustum is rubbish, I am not sure why.

An image can show what I mean better than a lot of words

The white line is the guns forward vector.
The red line is the target vector
The yellow the bounding frustum.

The component has the following values

ShipGunFOFComponent_1
ShipGunFOFComponent
1
ShipGunComponent#GunSights#ShipGunComponent_1:Gun
0
5
YawMin Float -45
YawMax Float 45
PitchMin Float -10
PitchMax Float 75
BaseHeading Float 90
ShipGunComponent_1
ShipGunComponent
2
Root#Root#HMSIllustriousCV:GameComponents
ShipStateComponent#Guns#ShipStateComponent_1:Ship
1
GunSights#ShipGunFOFComponent_1:Gun,
5
Hook String ShellStart_51
GunType String AAA\Oerlikon20mm
RoundType Int 0
Mesh String Head50_x
AmmoType String AAA\aa20mm

The pitch range is 10 degrees below horizontal to 75 degrees above, you can clearly see that does not match the display.

Here is the relevant code

                float x_range = sf.YawMax - sf.YawMin;
                float y_range = sf.PitchMax - sf.PitchMin;
                float aspect_ratio = x_range / y_range;

                Matrix p = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(x_range), aspect_ratio, near, far);
                Matrix l = Matrix.CreateLookAt(start, start + target, Vector3.Up);
                frustrum = new BoundingFrustum(l * p);

Any ideas guys?

Cheers
Paul

What’s wrong with the frustum ?
Seems to have the correct fov and aspect ratio and is looking along the target vector.

Your bounding frustrum is oriented towards the target because your lookat matrix is looking at the target. You want the frustrum to be looking at the center point between YawMin/YawMax and PitchMin/PitchMax.

float lookatYaw = (YawMin + YawMax) / 2;
float lookatPitch =  (PitchMin + PitchMax) / 2;

You then need to convert this to a vector and use that in your lookat matrix instead of target. Do you need help with that?

Another small problem is the aspect ratio. Aspect ratio is length / width, you can’t use the angles directly. aspect_ratio = tan(x_range / 2) / tan(y_range / 2)

It should go from below horizontal, it starts above the horizontal, to just below vertical, it goes past vertical.

Hi markus,

yes the aspect_ratio does look wrong thinking about it.

I already calculate the target point based on the yaw and pitch values… hmmm I will try calculating the target based on the average of the yaw and pitch and see if it is different.

Cheers
Paul

With PitchMin=-10 and PitchMax=75 your lookat vector needs to have a pitch angle of 32.5 degrees. If it doesn’t have that, you know it’s wrong. It looks much steeper to me.

Thanks guys got it working, was a number of face palms all over the code.

Teach me to try and fit in some work while in a skype meeting…

The working code is

                    Vector3 end = new Vector3(0, 0, far);

                    float mid_yaw = MathHelper.ToRadians((sf.YawMax + sf.YawMin) / 2);
                    float mid_pitch = MathHelper.ToRadians((sf.PitchMax + sf.PitchMin) / 2);
                    Matrix tm = Matrix.CreateFromYawPitchRoll(mid_yaw, -mid_pitch, 0);
                    Vector3 target = Vector3.Transform(end, tm);
                    target = Vector3.Transform(target, mat);

                    float x_range = MathHelper.ToRadians(sf.YawMax - sf.YawMin);
                    float y_range = MathHelper.ToRadians(sf.PitchMax - sf.PitchMin);
                    float aspect_ratio = x_range / y_range;

                    Matrix p = Matrix.CreatePerspectiveFieldOfView(x_range, aspect_ratio, near, far);
                    Matrix l = Matrix.CreateLookAt(start, start + target, Vector3.Up);
                    frustrum = new BoundingFrustum(l * p);
                    state = GunState.Scanning;

You will notice a sprinkling of MathHelper.ToRadians in there that I kinda missed… idiot

I also realised that by forcing the end of the target vector to the max range of the weapon I was effectively flattening the vector, hence the rotation matrix instead of Math.Tan

Thanks guys