Actually I just figured it out! Since my program already breaks the move commands down to small increments between points, I simply commented out the heading property of the setView command and issued an incremental lookRight command so that by the time it completes turn it is heading in the right direction. I did the same thing with a moveUp command so I could have the drone change height while still moving along a plane parallel to the surface. It is a really smooth transition. I don’t know if mathematically I’m off in my heading but it looks pretty good and is good enough in my book! LOL. Paste this into SanCastle and have a look for yourself.
var viewer = new Cesium.Viewer(‘cesiumContainer’);
var VirtualTour = function(positions){
this.tourArray = ;
this.load = function(positions){
for (var i = 0; i < positions.cameraPositions.length; i++){
positions[i] = positions.cameraPositions[i];
positions[i].destination = Cesium.Cartesian3.fromDegrees(positions[i].longitude, positions[i].latitude, positions[i].height);
positions[i].heading = Cesium.Math.toRadians(positions[i].heading);
positions[i].pitch = Cesium.Math.toRadians(positions[i].pitch);
this.tourArray[positions[i].id] = positions[i];
}
}
this.load(positions);
this.tourExecuting = false;
this.nextPosition=1;
this.moveIncrement = 1;
this.timeInterval=10;
this.flyToWait = 6000;
this.setSpeedFactor = function(num){
this.moveIncrement = num*this.moveIncrement;
}
this.flyToRest = function(){
this.nextPosition++;
var thisTour = this;
setTimeout(function(){thisTour.flyToNext();},this.flyToWait);
}
this.flyToNext= function(){
var camera = viewer.scene.camera;
var heightInc = 0;
var lookInc = 0;
var geodesic = new Cesium.EllipsoidGeodesic();
var cart1 = Cesium.Cartographic.fromDegrees(this.tourArray[this.nextPosition-1].longitude,this.tourArray[this.nextPosition-1].latitude,this.tourArray[this.nextPosition-1].height);
var cart2 = Cesium.Cartographic.fromDegrees(this.tourArray[this.nextPosition].longitude,this.tourArray[this.nextPosition].latitude,this.tourArray[this.nextPosition].height);
geodesic.setEndPoints(cart1, cart2);
camera.setView({
heading : geodesic.startHeading,
});
var incGeodesic = new Cesium.EllipsoidGeodesic();
var distanceCovered = 0;
var thisTour = this;
this.flightListener = function() {
if (geodesic.surfaceDistance - distanceCovered < 1){
thisTour.nextPosition++;
if (thisTour.nextPosition === thisTour.tourArray.length){
thisTour.end();
}else{
cart1 = Cesium.Cartographic.fromDegrees(thisTour.tourArray[thisTour.nextPosition-1].longitude,thisTour.tourArray[thisTour.nextPosition-1].latitude,thisTour.tourArray[thisTour.nextPosition-1].height);
cart2 = Cesium.Cartographic.fromDegrees(thisTour.tourArray[thisTour.nextPosition].longitude,thisTour.tourArray[thisTour.nextPosition].latitude,thisTour.tourArray[thisTour.nextPosition].height);
geodesic.setEndPoints(cart1, cart2);
var amount = geodesic.startHeading-camera.heading;
lookInc = amount/geodesic.surfaceDistance*thisTour.moveIncrement;
camera.setView({
//heading : geodesic.startHeading,
pitch : thisTour.tourArray[thisTour.nextPosition].pitch,
roll : thisTour.tourArray[thisTour.nextPosition].roll,
});
distanceCovered = 0;
heightInc = (thisTour.tourArray[thisTour.nextPosition].height - thisTour.tourArray[thisTour.nextPosition-1].height)/geodesic.surfaceDistance*thisTour.moveIncrement
}
}else {
var currentPos = camera.positionCartographic;
incGeodesic.setEndPoints(currentPos, cart2);
camera.lookRight(lookInc);
camera.setView({
//heading : incGeodesic.startHeading,
pitch : thisTour.tourArray[thisTour.nextPosition].pitch,
roll : thisTour.tourArray[thisTour.nextPosition].roll,
});
if(0)
{camera.moveForward(thisTour.moveIncrement);}
else
{
//remove vertical component from camera.direction
var CC3=Cesium.Cartesian3;
var nadir = new CC3();var temp= new CC3();
Cesium.Ellipsoid.WGS84.geodeticSurfaceNormalCartographic(currentPos, nadir);
CC3.negate(nadir,nadir); //zenith to nadir
var scalar = CC3.dot(camera.direction,nadir);
CC3.multiplyByScalar(nadir,scalar,temp);
CC3.subtract(camera.direction,temp,temp); //remove downward component
viewer.scene.camera.move(temp,thisTour.moveIncrement);
}
camera.moveUp(heightInc);
distanceCovered = distanceCovered+thisTour.moveIncrement;
}
}
viewer.clock.onTick.addEventListener(thisTour.flightListener);
};
this.start = function(){
try {
if (this.tourExecuting) return;
this.tourExecuting = true;
this.nextPosition=1;
this.startPosition = {};
this.startPosition.destination = Cesium.Cartesian3.clone(viewer.scene.camera.positionWC);
this.startPosition.heading = viewer.scene.camera.heading;
this.startPosition.pitch = viewer.scene.camera.pitch;
this.startPosition.roll = viewer.scene.camera.roll;
viewer.scene.camera.flyTo({
destination : this.tourArray[this.nextPosition].destination,
duration : 5,
complete : this.flyToRest.call(this),
orientation : {
heading: this.tourArray[this.nextPosition].heading,
pitch: this.tourArray[this.nextPosition].pitch,
roll: this.tourArray[this.nextPosition].roll,
}
});
}catch(err) {
this.tourExecuting = false;
}
};
this.end = function(){
try {
this.nextPosition=0;
this.tourExecuting=false;
viewer.clock.onTick.removeEventListener(this.flightListener);
viewer.scene.camera.flyTo({
destination : this.startPosition.destination,
duration : 5,
orientation : {
heading: this.startPosition.heading,
pitch: this.startPosition.pitch,
roll: this.startPosition.roll,
}
});
}catch(err) {
this.tourExecuting = false;
}
}
}
function tourExecuting(){
return sanMarcosTour.tourExecuting;
}
var positions = {“cameraPositions”:[{“id”:1,“name”:"",“longitude”:-117.3506784,“latitude”:33.1773947,“height”:20.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:2,“name”:"",“longitude”:-117.34990600000002,“latitude”:33.1778617,“height”:30.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:3,“name”:"",“longitude”:-117.34814640000002,“latitude”:33.1789033,“height”:40.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:4,“name”:"",“longitude”:-117.3465586,“latitude”:33.1798372,“height”:50.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:5,“name”:"",“longitude”:-117.3457861,“latitude”:33.1801964,“height”:60.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:6,“name”:"",“longitude”:-117.34492780000001,“latitude”:33.1805556,“height”:70.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:7,“name”:"",“longitude”:-117.3441124,“latitude”:33.1808429,“height”:80.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:8,“name”:"",“longitude”:-117.34342580000002,“latitude”:33.1810225,“height”:90.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:9,“name”:"",“longitude”:-117.34273909999999,“latitude”:33.1810584,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:10,“name”:"",“longitude”:-117.3418379,“latitude”:33.1810584,“height”:90.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:11,“name”:"",“longitude”:-117.32986449999999,“latitude”:33.1812021,“height”:80.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:12,“name”:"",“longitude”:-117.3293066,“latitude”:33.1812021,“height”:70.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:13,“name”:"",“longitude”:-117.32883449999999,“latitude”:33.1813099,“height”:60.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:14,“name”:"",“longitude”:-117.32836250000001,“latitude”:33.1813458,“height”:50.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:15,“name”:"",“longitude”:-117.3279333,“latitude”:33.1814535,“height”:40.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:16,“name”:"",“longitude”:-117.32741830000002,“latitude”:33.1815254,“height”:30.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:17,“name”:"",“longitude”:-117.3252296,“latitude”:33.1820282,“height”:20.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:18,“name”:"",“longitude”:-117.3244143,“latitude”:33.1822078,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:19,“name”:"",“longitude”:-117.3238134,“latitude”:33.1822437,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:20,“name”:"",“longitude”:-117.32325550000002,“latitude”:33.1822796,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:21,“name”:"",“longitude”:-117.32274060000002,“latitude”:33.1822437,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:22,“name”:"",“longitude”:-117.3223114,“latitude”:33.1821719,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:23,“name”:"",“longitude”:-117.32188220000002,“latitude”:33.1821,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:24,“name”:"",“longitude”:-117.321496,“latitude”:33.1819923,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:25,“name”:"",“longitude”:-117.31677529999999,“latitude”:33.1806274,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:26,“name”:"",“longitude”:-117.31634620000001,“latitude”:33.1805556,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:27,“name”:"",“longitude”:-117.31595989999998,“latitude”:33.1805197,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:28,“name”:"",“longitude”:-117.31553079999999,“latitude”:33.1804478,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:29,“name”:"",“longitude”:-117.3109388,“latitude”:33.1798013,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:30,“name”:"",“longitude”:-117.31038090000001,“latitude”:33.1797295,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:31,“name”:"",“longitude”:-117.30986600000001,“latitude”:33.1797295,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:32,“name”:"",“longitude”:-117.309351,“latitude”:33.1797295,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:33,“name”:"",“longitude”:-117.3088789,“latitude”:33.1798731,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:34,“name”:"",“longitude”:-117.3084068,“latitude”:33.1799091,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},{“id”:35,“name”:"",“longitude”:-117.30780600000001,“latitude”:33.1800527,“height”:100.0,“heading”:0.0,“pitch”:-15.0,“roll”:0.0},]};
var sanMarcosTour = new VirtualTour(positions);
/*
var sanMarcosTour = {};
jQuery.getJSON( “resources/SanMarcosTour.json”, function( positions ) {
sanMarcosTour = new VirtualTour(positions);
});
*/
function SanMarcosTour(){
if (tourExecuting()) return;
sanMarcosTour.setSpeedFactor(2);
sanMarcosTour.start();
}
SanMarcosTour();