A way to orient and place Frustum outline

In another thread someone asked how to orient (and place) Frustum outlines. I believe I got a fully working sandcastle example here:

const viewer = new Cesium.Viewer("cesiumContainer");
var myprim;

const onComplete = () => {
  return () => {
    viewer.scene.globe.depthTestAgainstTerrain = true;
    viewer.scene.debugShowFrustumPlanes = true;

      function() {
      }, 50);

//set us up
var heading = 90;
var pitch = -45;
var roll = -22;
const lon = 90;
const lat = 0;
const height = 66.5;
const origin = Cesium.Cartesian3.fromDegrees(lon, lat, height);
const zeroPt = new Cesium.Cartesian3(0,0,0);

// orientation for flyTo
const orientationCamera = {
  heading: Cesium.Math.toRadians(heading),
  pitch: Cesium.Math.toRadians(pitch),
  roll: Cesium.Math.toRadians(roll),

  destination: origin,
  orientation: orientationCamera,
  complete: onComplete(),

function doit()
  if(1) //method I wrote
    //deg to rad

    //declare shortcuts
    var til=pitch+(Math.PI/2);roll*=-1;
    var ch = Math.cos(heading);var sh = Math.sin(heading);
    var ct = Math.cos(til);var st = Math.sin(til);
    var cr = Math.cos(roll);var sr = Math.sin(roll);

    //calc rot mat in terms of local ENU frame
    var myrig=new Cesium.Cartesian3(ch*cr+sh*ct*sr,sh*cr*-1+ch*ct*sr,st*sr);
    var mydir=new Cesium.Cartesian3(sh*st,ch*st,ct*-1);
    var myup=new Cesium.Cartesian3(sh*ct*cr+ch*sr*-1,ch*ct*cr+sh*sr,st*cr);

    //transform rot mat to world coordinates
    var GD_transform = Cesium.Transforms.eastNorthUpToFixedFrame(origin, viewer.scene.globe.ellipsoid, new Cesium.Matrix4());//rot-tran
    var GD_rotmat = Cesium.Matrix4.getMatrix3(GD_transform, new Cesium.Matrix3());
    Cesium.Matrix3.multiplyByVector(GD_rotmat, myrig, myrig);
    Cesium.Matrix3.multiplyByVector(GD_rotmat, mydir, mydir);
    Cesium.Matrix3.multiplyByVector(GD_rotmat, myup, myup);
    var rot = [myrig.x,myrig.y,myrig.z,mydir.x,mydir.y,mydir.z,myup.x,myup.y,myup.z];
  else //using built in function (not working properly)
    const rotation4 = new Cesium.HeadingPitchRoll.fromDegrees(heading, pitch, roll);
    const mat = Cesium.Transforms.headingPitchRollToFixedFrame(origin, rotation4);
    var rot = new Cesium.Matrix3();

  //create frustum
  let frustum4 = new Cesium.PerspectiveFrustum();
  frustum4.fov = Cesium.Math.PI_OVER_TWO;
  frustum4.aspectRatio = 4 / 3;
  frustum4.near = 1.0;
  frustum4.far = 30.0;
  const frustumGeometry4 = new Cesium.FrustumOutlineGeometry({
    frustum: frustum4,
    origin: zeroPt,
    orientation: {x:0,y:0,z:0,w:1}, //same as HPR 0,0,0
  const frustumOutlineGeometryInstance4 = new Cesium.GeometryInstance({
    geometry: frustumGeometry4,
  //modelMatrix :[1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1], //identity
  modelMatrix :[1,0,0,0, 0,0,-1,0, 0,1,0,0, 0,0,0,1], //twist 90deg around x
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 1.0, 0.0, 1.0))
  myprim = viewer.scene.primitives.add(
    new Cesium.Primitive({
      geometryInstances: frustumOutlineGeometryInstance4,
      appearance: new Cesium.PerInstanceColorAppearance({
        closed: true,
        flat: true,

//place and orient primitive
    [rot[0],rot[1],rot[2],0, rot[3],rot[4],rot[5],0, rot[6],rot[7],rot[8],0,

I made the frustum creation as generic as possible, such as
orientation: {x:0,y:0,z:0,w:1}
origin: zeroPt

For geometry instance instead of the identity matrix I used one that rotates the face forward (it is created facing up.) Placement and orientation is only done once it is made into a primitive.

I used my own HPR to rot matrix calculations I wrote way back when I made 6DOF Google Earth. GE didn’t give the user access to Cartesian coordinates (only lat/lon/height & HPR) so for 6DOF movements I had to convert HPR->rot mat->HPR every frame.


I have an if/else statement, on the else portion I’ve tried using the
function instead, but could not get it to work. I wonder which is the case:
-I have a mis-conception of what it’s supposed to do.
-I’m not using it properly.
-It’s not working properly.

1 Like