Frustum Geometry Orientation

I am trying to display frustums based on different origin and HPR. When I tried using the Frustum Geometry, its orientation doesn’t seem right. Here’s a code snippet:

const origin = Cesium.Cartesian3.fromDegrees(lon, lat, height);
const rotation = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const orientation = Cesium.Quaternion.fromHeadingPitchRoll(rotation);

let frustum = new Cesium.PerspectiveFrustum();
frustum.fov = Cesium.Math.toRadians(fov);
frustum.aspectRatio = aspectWidth / aspectHeight;
frustum.near = 1.0;
frustum.far = 30.0;

const frustumGeometry = new Cesium.FrustumOutlineGeometry({

const frustumOutlineGeometryInstance = new Cesium.GeometryInstance({
  geometry: frustumGeometry,
    attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 1.0))

But when I checked using the Camera, its debug frustum is correct.

const orientation = {
  destination: origin,

Here’s a screenshot. Black one is the Frustum Geometry. Blue one is from the debug frustum planes.

Why is it different even if I am using the same HPR values? I need the Frustum to be the same orientation as the debug frustum plane.

Thank you for the help!

I also tried using Cesium.Transforms.headingPitchRollQuaternion but still getting different orientation.

let orientation = Cesium.Transforms.headingPitchRollQuaternion(origin, rotation);
1 Like

Bump! I read in another post that I need to transform relative heading-pitch-roll to absolute rotation Quaternion. Here’s my code:

let localQ = Cesium.Quaternion.fromHeadingPitchRoll(rotation);

let enu = Cesium.Transforms.eastNorthUpToFixedFrame(origin);
let transform3 = new Cesium.Matrix3();
Cesium.Matrix4.getMatrix3(enu, transform3);
let transformQ = Cesium.Quaternion.fromRotationMatrix(transform3);

let orientation = new Cesium.Quaternion();
Cesium.Quaternion.multiply(localQ, transformQ, orientation);

But still, I am getting a different orientation compared to the camera. I need it to be the same as the camera since based on my image, that is the correct orientation.

Would really appreciate it if someone can help. I already tried 3 different solutions but still getting incorrect orientation.

@omar or anyone else. Would really appreciate any help. 1 week since my first post. Thanks

1 Like

@john1 if you haven’t already seen it, I would look at how the DebugCameraPrimitive creates the frustum geometry and make sure you’re doing the same computation:

Let me know if that works. It would be great to have a code example that makes this easier perhaps. Can you tell us about your use case for this?

1 Like

@omar I already checked that one before, but DebugCameraPrimitive is based from its directionWC, upWC and rightWC. Is there a way to get those from HPR?

Can you tell us about your use case for this?

I am trying to visualize the FOV of images taken from certain origins and orientations.

This should work
Transforms.headingPitchRollToFixedFrame(origin, heading, pitch, roll, ellipsoid, result)
“Computes a 4x4 transformation matrix from a reference frame with axes computed from the heading-pitch-roll angles centered at the provided origin to the provided ellipsoid’s fixed reference frame.”
Assumes heading pitch roll are in terms of the local ENU frame.

1 Like

@Hyper_Sonic But that one will result to a Matrix4. If you can see from my comment, I actually tried using the Cesium.Transforms.headingPitchRollQuaternion. The same as that one but will result to a Quaternion which is the one needed for the Frustum. But still, I got a different orientation.

You’ve mentioned that you needed directionWC, upWC and rightWC from HPR (presumably HPR relative to the local ENU frame.) You should be able to get those directly from the Matrix4 (which is Matrix3 rotation coupled with a Cartesian3 position.)

right = new Cesium.Cartesian3(mat[0],mat[1],mat[2]);
direction = new Cesium.Cartesian3(mat[4],mat[5],mat[6]);
up = new Cesium.Cartesian3(mat[8],mat[9],mat[10]);

Can convert rotation portion of Matrix4 to Quaternion

var mat3 = new Cesium.Matrix3();
var quat = new Cesium.Quaternion();

Just tried it out, the Mat4 it produces is in terms of Earth’s fixed frame (WC), I was thinking that it might be in terms of the local ENU frame and would have to be transformed, but it’s not so it doesn’t. Can use just the 1st 2 parameters pos and HPR, and just have it use defaults for the rest.

1 Like

I see. Sure I’ll try that one. Thanks! I’ll update once tested