About the Visualizing the camera path while animating Sample
[C#]
VisualizeCameraPath.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.GlobeCore;
using ESRI.ArcGIS.Animation;
using ESRI.ArcGIS.Analyst3D;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesGDB;
namespace VisualizeCameraPath
{
public class VisualizeCameraPath : ESRI.ArcGIS.Desktop.AddIns.Button
{
#region Member Variables
private ESRI.ArcGIS.GlobeCore.IGlobe globe;
private ESRI.ArcGIS.GlobeCore.IGlobeDisplay globeDisplay;
private ESRI.ArcGIS.Carto.IGraphicsContainer graphicsLayer;
private ESRI.ArcGIS.GlobeCore.IGlobeCamera globeCamera;
private ESRI.ArcGIS.Animation.IAGAnimationTracks animationTracks;
private ESRI.ArcGIS.Animation.IAGAnimationTrack animationTrack;
private VisualizeCameraPathForm theCamForm;
private ESRI.ArcGIS.Animation.IAGAnimationUtils animUtils;
private ESRI.ArcGIS.Animation.IAnimationEvents_Event animEvent;
private ESRI.ArcGIS.Animation.IAGAnimationEnvironment animEnv;
private ESRI.ArcGIS.Animation.IAGAnimationPlayer animPlayer;
private ESRI.ArcGIS.GlobeCore.IGlobeDisplayEvents_Event globeDispEvent;
private bool toolIsInitialized = false;
private double animationDuration = 0;
#endregion
#region DLLImportFunction
[DllImport("gdi32.dll")]
static extern bool DeleteObject(IntPtr hObject);
[DllImport("user32.dll")]
static extern int ShowWindow(int hwnd, int nCmdShow);
#endregion
public VisualizeCameraPath()
{
globe = ArcGlobe.Globe;
globeDisplay = globe.GlobeDisplay;
globeCamera = globeDisplay.ActiveViewer.Camera as IGlobeCamera;
}
~VisualizeCameraPath()
{
if (theCamForm != null)
{
theCamForm.Dispose();
}
}
protected override void OnClick()
{
//The first time button is clicked
if(toolIsInitialized == false)
{
theCamForm = new VisualizeCameraPathForm();
//Add event handlers for form's button click events
theCamForm.playButton.Click+= new System.EventHandler(formPlayButtonClickEventHandler);
theCamForm.stopButton.Click+= new System.EventHandler(formStopButtonClickEventHandler);
theCamForm.generatePathButton.Click+= new System.EventHandler(formGeneratePathButtonClickEventHandler);
theCamForm.generateCamPathCheckBox.CheckedChanged += new EventHandler(formCheckbox1CheckedChanged);
theCamForm.Closing += new CancelEventHandler(theCamForm_Closing);
animEnv = new AGAnimationEnvironmentClass();
//True = Button has been already clicked
toolIsInitialized = true;
}
//If the main form is already open - do not open another one
else if (toolIsInitialized == true)
{
//Clear the list of animation tracks
theCamForm.animTracksListBox.Items.Clear();
}
//Get the list of animation tracks
this.getCameraAnimationTracksFromGlobe();
theCamForm.Show();
}
protected override void OnUpdate()
{
Enabled = ArcGlobe.Application != null;
}
#region Custom Functions and Event Handlers
//function for getting camera animation tracks
public void getCameraAnimationTracksFromGlobe()
{
ESRI.ArcGIS.Animation.IAGAnimationType animationType = new AnimationTypeGlobeCameraClass();
animationTracks = (ESRI.ArcGIS.Animation.IAGAnimationTracks)globe;
int animCounter = 0;
while (animCounter < animationTracks.AGTracks.Count)
{
animationTrack = (ESRI.ArcGIS.Animation.IAGAnimationTrack)animationTracks.AGTracks.get_Element(animCounter);
if (animationTrack.AnimationType == animationType)
{
theCamForm.animTracksListBox.Items.Add(animationTrack.Name);
}
animCounter = animCounter + 1;
}
}
//function for enabling selected animation track
public void enableSelectedTrack()
{
if (theCamForm.animTracksListBox.SelectedItem != null)
{
string selectedTrack = theCamForm.animTracksListBox.SelectedItem.ToString();
int animCounter = 0;
while (animCounter < animationTracks.AGTracks.Count)
{
animationTrack = (IAGAnimationTrack)animationTracks.AGTracks.get_Element(animCounter);
if (animationTrack.Name != selectedTrack)
{
IAGAnimationTrack trackToDisable;
animationTracks.FindTrack(animationTrack.Name, out trackToDisable);
trackToDisable.IsEnabled = false;
}
else if (animationTrack.Name == selectedTrack)
{
animationTrack.IsEnabled = true;
}
animCounter = animCounter + 1;
}
}
else if (theCamForm.animTracksListBox.SelectedItem == null)
{
MessageBox.Show("No Track Selected - All enabled tracks will be played");
}
}
//function for playing animation
public void playAnimation()
{
animUtils = new AGAnimationUtilsClass();
//register/unregister events for tracing camera path based on selection
animEvent = (IAnimationEvents_Event)animUtils;
//set animation duration
if (theCamForm.animDurationTextBox.Text != "" & theCamForm.animDurationTextBox.Text != "Optional")
{
animEnv.AnimationDuration = Convert.ToDouble(theCamForm.animDurationTextBox.Text);
}
else
{
MessageBox.Show("Please enter animation duration", "Error");
return;
}
//register animation event handler
animEvent.StateChanged += new IAnimationEvents_StateChangedEventHandler(myAnimationEventHandler);
//enable/disable other buttons
theCamForm.stopButton.Enabled = true;
theCamForm.generatePathButton.Enabled = false;
theCamForm.playButton.Enabled = false;
animPlayer = (IAGAnimationPlayer)animUtils;
animationDuration = animEnv.AnimationDuration;
animPlayer.PlayAnimation(animationTracks, animEnv, null);
}
//function for creating specified number of graphics per second
public void generatePathPerSecond()
{
//set animation duration
if (theCamForm.animDurationTextBox.Text != "" & theCamForm.animDurationTextBox.Text != "Optional")
{
animEnv.AnimationDuration = Convert.ToDouble(theCamForm.animDurationTextBox.Text);
}
else
{
MessageBox.Show("Please enter animation duration", "Error");
return;
}
animationDuration = animEnv.AnimationDuration;
int numPtsPerSecond = 0;
if (theCamForm.numPtsPerSecTextBox.Text != "")
{
numPtsPerSecond = Convert.ToInt32(theCamForm.numPtsPerSecTextBox.Text);
}
addGraphicLayer();
string selectedTrack = theCamForm.animTracksListBox.SelectedItem.ToString();
animationTracks.FindTrack(selectedTrack, out animationTrack);
IAGAnimationTrackKeyframes kFrames = (IAGAnimationTrackKeyframes)animationTrack;
int kFrameCount = kFrames.KeyframeCount;
//total number of points to be created
int totalPts = (int)(numPtsPerSecond * animationDuration);
//this is the from point for the lines connecting the interpolated point graphics
IPoint previousPt = new PointClass();
IZAware prevPtZAware = (IZAware)previousPt;
prevPtZAware.ZAware = true;
previousPt.PutCoords(0, 0);
//this is the line connecting the interpolated camera positions
IPolyline connectingLine = new PolylineClass();
IZAware lineZAware = (IZAware)connectingLine;
lineZAware.ZAware = true;
//disable all buttons
theCamForm.playButton.Enabled = false;
theCamForm.stopButton.Enabled = false;
theCamForm.generatePathButton.Enabled = false;
//loop over the keyframes in the selected camera track
for (int i = 0; i < kFrameCount; i++)
{
IAGKeyframe currentKeyframe = kFrames.get_Keyframe(i);
IAGKeyframe prevKeyframe;
IAGKeyframe nextKeyframe;
IAGKeyframe afterNextKeyframe;
//if else statements to determine the keyframe arguments to the interpolate method
//this is needed because the first, second-last and the last keyframes should be handled differently
//than the middle keyframes
if (i > 0)
{
prevKeyframe = kFrames.get_Keyframe(i - 1);
}
else
{
prevKeyframe = kFrames.get_Keyframe(i);
}
if (i < kFrameCount - 1)
{
nextKeyframe = kFrames.get_Keyframe(i + 1);
}
else
{
nextKeyframe = kFrames.get_Keyframe(i);
}
if (i < kFrameCount - 2)
{
afterNextKeyframe = kFrames.get_Keyframe(i + 2);
}
else
{
//this should be equal to the nextKeyFrame for the last keyframe
afterNextKeyframe = nextKeyframe;//kFrames.get_Keyframe(i);
}
double origCamLat, origCamLong, origCamAlt;
double interLat, interLong, interAlt;
double tarLat, tarLong, tarAlt;
double interTarLat, interTarLong, interTarAlt;
globeCamera.GetObserverLatLonAlt(out origCamLat, out origCamLong, out origCamAlt);
globeCamera.GetTargetLatLonAlt(out tarLat, out tarLong, out tarAlt);
IAGAnimationContainer pAnimContainer = animationTracks.AnimationObjectContainer;
object objToInterpolate = (object)globeCamera;
double timeDiff = nextKeyframe.TimeStamp - currentKeyframe.TimeStamp;
int numPtsToInterpolateNow;
numPtsToInterpolateNow = Convert.ToInt32((timeDiff * totalPts));
//interpolate positions between keyframes and draw the graphics
//for 0 to n-1 keyframes
if (i < kFrameCount - 1)
{
for (int j = 0; j < numPtsToInterpolateNow; j++)
{
double timeToInterpolate;
timeToInterpolate = currentKeyframe.TimeStamp + j * (timeDiff / (numPtsToInterpolateNow));
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 1, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 2, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 3, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 4, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 5, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 6, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
//get observer and target lat, long, alt after interpolation
globeCamera.GetObserverLatLonAlt(out interLat, out interLong, out interAlt);
globeCamera.GetTargetLatLonAlt(out interTarLat, out interTarLong, out interTarAlt);
//set observer and target lat, long, alt to original values before interpolation
globeCamera.SetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt);
globeCamera.SetTargetLatLonAlt(tarLat, tarLong, tarAlt);
IPoint pObs = new PointClass();
IZAware obsZAware = (IZAware)pObs;
obsZAware.ZAware = true;
pObs.X = interLong;
pObs.Y = interLat;
pObs.Z = interAlt * 1000;
double symbolSize = 10000;
//change the symbol size based on distance to ground
if (pObs.Z >= 10000) symbolSize = 10000 + pObs.Z / 10;
else symbolSize = pObs.Z;
//add graphics - keyframes (j=0) are colored differently
if (j == 0) addPointGraphicElements(pObs, 2552550, symbolSize);
else addPointGraphicElements(pObs, 16732415, symbolSize);
connectingLine.FromPoint = previousPt;
connectingLine.ToPoint = pObs;
//barring the first keyframe, create the line connecting the interpolated points
if (i == 0 & j == 0) { }
else
{
addLineGraphicElements(connectingLine, 150150150);
}
//update the previous point
previousPt.PutCoords(pObs.X, pObs.Y);
previousPt.Z = pObs.Z;
//add camera to target direction
if (theCamForm.camToTargetDirectionCheckBox.Checked == true)
{
cameraToTargetDirection(interLat, interLong, interAlt, interTarLat, interTarLong, interTarAlt);
}
globeDisplay.RefreshViewers();
}
}
//for last keyframe
if (i == kFrameCount - 1)
{
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 4, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 5, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 6, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 1, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 2, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 3, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
globeCamera.GetObserverLatLonAlt(out interLat, out interLong, out interAlt);
globeCamera.GetTargetLatLonAlt(out interTarLat, out interTarLong, out interTarAlt);
globeCamera.SetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt);
globeCamera.SetTargetLatLonAlt(tarLat, tarLong, tarAlt);
IPoint pObs = new PointClass();
IZAware obsZAware = (IZAware)pObs;
obsZAware.ZAware = true;
pObs.X = interLong;
pObs.Y = interLat;
pObs.Z = interAlt * 1000;
double symbolSize = 10000;
if (pObs.Z >= 10000) symbolSize = 10000 + pObs.Z / 10;
else symbolSize = pObs.Z;
connectingLine.FromPoint = previousPt;
connectingLine.ToPoint = pObs;
addPointGraphicElements(pObs, 2552550, symbolSize);
addLineGraphicElements(connectingLine, 150150150);
//add camera to target orientation
if (theCamForm.camToTargetDirectionCheckBox.Checked == true)
{
cameraToTargetDirection(interLat, interLong, interAlt, interTarLat, interTarLong, interTarAlt);
}
globeDisplay.RefreshViewers();
}
}
//enable buttons
theCamForm.playButton.Enabled = true;
theCamForm.generatePathButton.Enabled = true;
}
//function for creating specified number of graphics between keyframe positions
public void generatePathBtwnKFrames()
{
int numPtsBtwnKFrames = 0;
//this is the from point for the lines connecting the interpolated point graphics
IPoint previousPt = new PointClass();
IZAware prevPtZAware = (IZAware)previousPt;
prevPtZAware.ZAware = true;
previousPt.PutCoords(0, 0);
//this is the line connecting the interpolated camera positions
IPolyline connectingLine = new PolylineClass();
IZAware lineZAware = (IZAware)connectingLine;
lineZAware.ZAware = true;
if (theCamForm.ptsBtwnKframeTextBox.Text != "")
{
numPtsBtwnKFrames = Convert.ToInt32(theCamForm.ptsBtwnKframeTextBox.Text);
}
else
{
MessageBox.Show("Please enter the number of points to be created");
return;
}
theCamForm.playButton.Enabled = false;
theCamForm.stopButton.Enabled = false;
theCamForm.generatePathButton.Enabled = false;
addGraphicLayer();
string selectedTrack = theCamForm.animTracksListBox.SelectedItem.ToString();
animationTracks.FindTrack(selectedTrack, out animationTrack);
IAGAnimationTrackKeyframes kFrames = (IAGAnimationTrackKeyframes)animationTrack;
int kFrameCount = kFrames.KeyframeCount;
//loop over the keyframes in the selected camera track
for (int i = 0; i < kFrameCount; i++)
{
IAGKeyframe currentKeyframe = kFrames.get_Keyframe(i);
IAGKeyframe prevKeyframe;
IAGKeyframe nextKeyframe;
IAGKeyframe afterNextKeyframe;
//if else statements to determine the keyframe arguments to the interpolate method
//this is needed because the first and the last keyframes should be handled differently
//than the middle keyframes
if (i > 0)
{
prevKeyframe = kFrames.get_Keyframe(i - 1);
}
else
{
prevKeyframe = kFrames.get_Keyframe(i);
}
if (i < kFrameCount - 1)
{
nextKeyframe = kFrames.get_Keyframe(i + 1);
}
else
{
nextKeyframe = kFrames.get_Keyframe(i);
}
if (i < kFrameCount - 2)
{
afterNextKeyframe = kFrames.get_Keyframe(i + 2);
}
else
{
//this should be equal to the nextKeyFrame for the last keyframe
afterNextKeyframe = nextKeyframe;//kFrames.get_Keyframe(i);
}
double origCamLat, origCamLong, origCamAlt;
double interLat, interLong, interAlt;
double tarLat, tarLong, tarAlt;
double interTarLat, interTarLong, interTarAlt;
globeCamera.GetObserverLatLonAlt(out origCamLat, out origCamLong, out origCamAlt);
globeCamera.GetTargetLatLonAlt(out tarLat, out tarLong, out tarAlt);
IAGAnimationContainer pAnimContainer = animationTracks.AnimationObjectContainer;
object objToInterpolate = (object)globeCamera;
double timeDiff = nextKeyframe.TimeStamp - currentKeyframe.TimeStamp;
//interpolate positions between keyframes and draw the graphics
for (int j = 0; j < numPtsBtwnKFrames + 1; j++)
{
double timeToInterpolate = currentKeyframe.TimeStamp + j * (timeDiff / (numPtsBtwnKFrames + 1));
//for 0 to n-1 keyframes
if (i >= 0 & i < kFrameCount - 1)
{
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 4, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 5, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 6, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 1, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 2, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 3, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe);
globeCamera.GetObserverLatLonAlt(out interLat, out interLong, out interAlt);
globeCamera.GetTargetLatLonAlt(out interTarLat, out interTarLong, out interTarAlt);
globeCamera.SetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt);
globeCamera.SetTargetLatLonAlt(tarLat, tarLong, tarAlt);
IPoint pObs = new PointClass();
IZAware obsZAware = (IZAware)pObs;
obsZAware.ZAware = true;
pObs.X = interLong;
pObs.Y = interLat;
pObs.Z = interAlt * 1000;
double symbolSize = 10000;
if (pObs.Z >= 10000) symbolSize = 10000 + pObs.Z / 10;
else symbolSize = pObs.Z;
if (j == 0) addPointGraphicElements(pObs, 2552550, symbolSize);
else addPointGraphicElements(pObs, 16732415, symbolSize);
connectingLine.FromPoint = previousPt;
connectingLine.ToPoint = pObs;
if (i == 0 & j == 0) { }
else
{
addLineGraphicElements(connectingLine, 150150150);
}
previousPt.PutCoords(pObs.X, pObs.Y);
previousPt.Z = pObs.Z;
//add camera to target orientation
if (theCamForm.camToTargetDirectionCheckBox.Checked == true)
{
cameraToTargetDirection(interLat, interLong, interAlt, interTarLat, interTarLong, interTarAlt);
}
globeDisplay.RefreshViewers();
}
//for last keyframe
else if (i == kFrameCount - 1)
{
if (j == 0)
{
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 4, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 5, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 6, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 1, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 2, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 3, 1, nextKeyframe, prevKeyframe, afterNextKeyframe);
globeCamera.GetObserverLatLonAlt(out interLat, out interLong, out interAlt);
globeCamera.GetTargetLatLonAlt(out interTarLat, out interTarLong, out interTarAlt);
globeCamera.SetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt);
globeCamera.SetTargetLatLonAlt(tarLat, tarLong, tarAlt);
IPoint pObs = new PointClass();
IZAware obsZAware = (IZAware)pObs;
obsZAware.ZAware = true;
pObs.X = interLong;
pObs.Y = interLat;
pObs.Z = interAlt * 1000;
double symbolSize = 10000;
if (pObs.Z >= 10000) symbolSize = 10000 + pObs.Z / 10;
else symbolSize = pObs.Z;
connectingLine.FromPoint = previousPt;
connectingLine.ToPoint = pObs;
addPointGraphicElements(pObs, 2552550, symbolSize);
addLineGraphicElements(connectingLine, 150150150);
//add camera to target orientation
if (theCamForm.camToTargetDirectionCheckBox.Checked == true)
{
cameraToTargetDirection(interLat, interLong, interAlt, interTarLat, interTarLong, interTarAlt);
}
globeDisplay.RefreshViewers();
}
}
}
}
//enable buttons
theCamForm.playButton.Enabled = true;
theCamForm.generatePathButton.Enabled = true;
}
//function for generating camera to target direction
public void cameraToTargetDirection(double camLat, double camLong, double camAlt, double tarLat, double tarLong, double tarAlt)
{
IPoint camPosition = new PointClass();
IPoint targetPosition = new PointClass();
ICamera pCamera = (ICamera)globeCamera;
IZAware obsZAware = (IZAware)camPosition;
obsZAware.ZAware = true;
camPosition.PutCoords(camLong, camLat);
camPosition.Z = camAlt * 1000;
IZAware targetZAware = (IZAware)targetPosition;
targetZAware.ZAware = true;
targetPosition.PutCoords(tarLong, tarLat);
targetPosition.Z = tarAlt;
IPolyline directionLine = new PolylineClass();
IZAware zAwareLine = (IZAware)directionLine;
zAwareLine.ZAware = true;
directionLine.FromPoint = camPosition;
directionLine.ToPoint = targetPosition;
addLineGraphicElements(directionLine, 255);
}
//function for adding a graphics layer
public void addGraphicLayer()
{
graphicsLayer = new GlobeGraphicsLayerClass();
ILayer pLayer;
pLayer = (ILayer)graphicsLayer;
pLayer.Name = "CameraPathGraphicsLayer";
globe.AddLayerType(pLayer, esriGlobeLayerType.esriGlobeLayerTypeDraped, true);
}
//function for adding point markers
public void addPointGraphicElements(ESRI.ArcGIS.Geometry.IPoint inPoint, int symbolColor, double symbolSize)
{
IElement pElement = new MarkerElementClass();
ISimpleMarker3DSymbol symbol3d = new SimpleMarker3DSymbolClass();
string markerStyle = "";
if (theCamForm.symbolTypeListBox.SelectedItem != null)
{
markerStyle = theCamForm.symbolTypeListBox.SelectedItem.ToString();
}
if (markerStyle == "Cone") symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSCone;
else if (markerStyle == "Sphere") symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSSphere;
else if (markerStyle == "Cylinder") symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSCylinder;
else if (markerStyle == "Cube") symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSCube;
else if (markerStyle == "Diamond") symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSDiamond;
else if (markerStyle == "Tetrahedron") symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSTetra;
else symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSCone;
symbol3d.ResolutionQuality = 1;
IColor pColor = new RgbColorClass();
pColor.RGB = symbolColor; //16732415;
IMarkerSymbol pMarkerSymbol;
pMarkerSymbol = (IMarkerSymbol)symbol3d;
pMarkerSymbol.Color = pColor;
if (symbolSize < 0) symbolSize = Math.Abs(symbolSize);
if (symbolSize == 0) symbolSize = 5000;
pMarkerSymbol.Size = symbolSize;
pElement.Geometry = inPoint;
IMarkerElement pMarkerElement;
pMarkerElement = (IMarkerElement)pElement;
pMarkerElement.Symbol = pMarkerSymbol;
graphicsLayer.AddElement(pElement, 1);
}
//function for adding line graphics elements
public void addLineGraphicElements(ESRI.ArcGIS.Geometry.IPolyline inLine, int symbolColor)
{
IElement pElement = new LineElementClass();// MarkerElementClass();
ISimpleLine3DSymbol symbol3d = new SimpleLine3DSymbolClass();
string markerStyle = "";
if (theCamForm.symbolTypeListBox.SelectedItem != null)
{
markerStyle = theCamForm.symbolTypeListBox.SelectedItem.ToString();
}
if (markerStyle == "Strip") symbol3d.Style = esriSimple3DLineStyle.esriS3DLSStrip;
else if (markerStyle == "Wall") symbol3d.Style = esriSimple3DLineStyle.esriS3DLSWall;
else symbol3d.Style = esriSimple3DLineStyle.esriS3DLSTube;
symbol3d.ResolutionQuality = 1;
IColor pColor = new RgbColorClass();
pColor.RGB = symbolColor;
ILineSymbol pLineSymbol;
pLineSymbol = (ILineSymbol)symbol3d;
pLineSymbol.Color = pColor;
pLineSymbol.Width = 1;
pElement.Geometry = inLine;
ILineElement pLineElement;
pLineElement = (ILineElement)pElement;
pLineElement.Symbol = pLineSymbol;
graphicsLayer.AddElement(pElement, 1);
}
//event handlers
public void formPlayButtonClickEventHandler(object sender, System.EventArgs e)
{
if (theCamForm.animTracksListBox.SelectedItem != null)
{
enableSelectedTrack();
//play the animation
this.playAnimation();
}
else
{
MessageBox.Show("Please select a camera track", "Error");
}
}
public void formStopButtonClickEventHandler(object sender, System.EventArgs e)
{
animPlayer.StopAnimation();
theCamForm.stopButton.Enabled = false;
if (theCamForm.generateCamPathCheckBox.Checked == true) theCamForm.generatePathButton.Enabled = true;
}
public void formGeneratePathButtonClickEventHandler(object sender, System.EventArgs e)
{
if (theCamForm.animTracksListBox.SelectedItem != null)
{
if (theCamForm.ptsPerSecRadioButton.Checked == true)
{
if (theCamForm.numPtsPerSecTextBox.Text == "")
{
MessageBox.Show("Please enter number of points to be created per second", "Error");
return;
}
generatePathPerSecond();
}
else if (theCamForm.ptsBtwnKframeRadioButton.Checked == true)
{
if (theCamForm.ptsBtwnKframeTextBox.Text == "")
{
MessageBox.Show("Please enter number of points to be created between keyframes", "Error");
return;
}
generatePathBtwnKFrames();
}
}
else
{
MessageBox.Show("Please select a camera track");
}
}
public void formCheckbox1CheckedChanged(object sender, System.EventArgs e)
{
if (theCamForm.generateCamPathCheckBox.Checked == true) theCamForm.generatePathButton.Enabled = true;
else theCamForm.generatePathButton.Enabled = false;
}
private void theCamForm_Closing(object sender, CancelEventArgs e)
{
theCamForm.animTracksListBox.Items.Clear();
toolIsInitialized = false;
}
public void myAnimationEventHandler(esriAnimationState animState)
{
globeDispEvent = (IGlobeDisplayEvents_Event)globeDisplay;
if (animState == esriAnimationState.esriAnimationStopped)
{
theCamForm.playButton.Enabled = true;
theCamForm.generatePathButton.Enabled = true;
theCamForm.stopButton.Enabled = false;
}
}
#endregion
}
}
[Visual Basic .NET]
VisualizeCameraPath.vb
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.ADF.BaseClasses
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.GlobeCore
Imports ESRI.ArcGIS.Animation
Imports ESRI.ArcGIS.Analyst3D
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.Display
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Controls
Imports ESRI.ArcGIS.DataSourcesGDB
Namespace VisualizeCameraPath
Public Class VisualizeCameraPath : Inherits ESRI.ArcGIS.Desktop.AddIns.Button
#Region "Member Variables"
Private globe As ESRI.ArcGIS.GlobeCore.IGlobe
Private globeDisplay As ESRI.ArcGIS.GlobeCore.IGlobeDisplay
Private graphicsLayer As ESRI.ArcGIS.Carto.IGraphicsContainer
Private globeCamera As ESRI.ArcGIS.GlobeCore.IGlobeCamera
Private animationTracks As ESRI.ArcGIS.Animation.IAGAnimationTracks
Private animationTrack As ESRI.ArcGIS.Animation.IAGAnimationTrack
Private theCamForm As VisualizeCameraPathForm
Private animUtils As ESRI.ArcGIS.Animation.IAGAnimationUtils
Private animEvent As ESRI.ArcGIS.Animation.IAnimationEvents_Event
Private animEnv As ESRI.ArcGIS.Animation.IAGAnimationEnvironment
Private animPlayer As ESRI.ArcGIS.Animation.IAGAnimationPlayer
Private globeDispEvent As ESRI.ArcGIS.GlobeCore.IGlobeDisplayEvents_Event
Private toolIsInitialized As Boolean = False
Private animationDuration As Double = 0
#End Region
#Region "DLLImportFunction"
<DllImport("gdi32.dll")> _
Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
End Function
<DllImport("user32.dll")> _
Shared Function ShowWindow(ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Integer
End Function
#End Region
Public Sub New()
globe = ArcGlobe.Globe
globeDisplay = globe.GlobeDisplay
globeCamera = TryCast(globeDisplay.ActiveViewer.Camera, IGlobeCamera)
End Sub
Protected Overrides Sub Finalize()
If Not theCamForm Is Nothing Then
theCamForm.Dispose()
End If
End Sub
Protected Overrides Sub OnClick()
'The first time button is clicked
If toolIsInitialized = False Then
theCamForm = New VisualizeCameraPathForm()
'Add event handlers for form's button click events
AddHandler theCamForm.playButton.Click, AddressOf formPlayButtonClickEventHandler
AddHandler theCamForm.stopButton.Click, AddressOf formStopButtonClickEventHandler
AddHandler theCamForm.generatePathButton.Click, AddressOf formGeneratePathButtonClickEventHandler
AddHandler theCamForm.generateCamPathCheckBox.CheckedChanged, AddressOf formCheckbox1CheckedChanged
AddHandler theCamForm.Closing, AddressOf theCamForm_Closing
animEnv = New AGAnimationEnvironmentClass()
'True = Button has been already clicked
toolIsInitialized = True
'If the main form is already open - do not open another one
ElseIf toolIsInitialized = True Then
'Clear the list of animation tracks
theCamForm.animTracksListBox.Items.Clear()
End If
'Get the list of animation tracks
Me.getCameraAnimationTracksFromGlobe()
theCamForm.Show()
End Sub
Protected Overrides Sub OnUpdate()
Enabled = Not ArcGlobe.Application Is Nothing
End Sub
#Region "Custom Functions and Event Handlers"
'function for getting camera animation tracks
Public Sub getCameraAnimationTracksFromGlobe()
Dim animationType As ESRI.ArcGIS.Animation.IAGAnimationType = New AnimationTypeGlobeCameraClass()
animationTracks = CType(globe, ESRI.ArcGIS.Animation.IAGAnimationTracks)
Dim animCounter As Integer = 0
Do While animCounter < animationTracks.AGTracks.Count
animationTrack = CType(animationTracks.AGTracks.Element(animCounter), ESRI.ArcGIS.Animation.IAGAnimationTrack)
If animationTrack.AnimationType Is animationType Then
theCamForm.animTracksListBox.Items.Add(animationTrack.Name)
End If
animCounter = animCounter + 1
Loop
End Sub
'function for enabling selected animation track
Public Sub enableSelectedTrack()
If Not theCamForm.animTracksListBox.SelectedItem Is Nothing Then
Dim selectedTrack As String = theCamForm.animTracksListBox.SelectedItem.ToString()
Dim animCounter As Integer = 0
Do While animCounter < animationTracks.AGTracks.Count
animationTrack = CType(animationTracks.AGTracks.Element(animCounter), IAGAnimationTrack)
If animationTrack.Name <> selectedTrack Then
Dim trackToDisable As IAGAnimationTrack
trackToDisable = Nothing
animationTracks.FindTrack(animationTrack.Name, trackToDisable)
trackToDisable.IsEnabled = False
ElseIf animationTrack.Name = selectedTrack Then
animationTrack.IsEnabled = True
End If
animCounter = animCounter + 1
Loop
ElseIf theCamForm.animTracksListBox.SelectedItem Is Nothing Then
MessageBox.Show("No Track Selected - All enabled tracks will be played")
End If
End Sub
'function for playing animation
Public Sub playAnimation()
animUtils = New AGAnimationUtilsClass()
'register/unregister events for tracing camera path based on selection
animEvent = CType(animUtils, IAnimationEvents_Event)
'set animation duration
If theCamForm.animDurationTextBox.Text <> "" And theCamForm.animDurationTextBox.Text <> "Optional" Then
animEnv.AnimationDuration = Convert.ToDouble(theCamForm.animDurationTextBox.Text)
Else
MessageBox.Show("Please enter animation duration", "Error")
Return
End If
'register animation event handler
AddHandler animEvent.StateChanged, AddressOf myAnimationEventHandler
'enable/disable other buttons
theCamForm.stopButton.Enabled = True
theCamForm.generatePathButton.Enabled = False
theCamForm.playButton.Enabled = False
animPlayer = CType(animUtils, IAGAnimationPlayer)
animationDuration = animEnv.AnimationDuration
animPlayer.PlayAnimation(animationTracks, animEnv, Nothing)
End Sub
'function for creating specified number of graphics per second
Public Sub generatePathPerSecond()
'set animation duration
If theCamForm.animDurationTextBox.Text <> "" And theCamForm.animDurationTextBox.Text <> "Optional" Then
animEnv.AnimationDuration = Convert.ToDouble(theCamForm.animDurationTextBox.Text)
Else
MessageBox.Show("Please enter animation duration", "Error")
Return
End If
animationDuration = animEnv.AnimationDuration
Dim numPtsPerSecond As Integer = 0
If theCamForm.numPtsPerSecTextBox.Text <> "" Then
numPtsPerSecond = Convert.ToInt32(theCamForm.numPtsPerSecTextBox.Text)
End If
addGraphicLayer()
Dim selectedTrack As String = theCamForm.animTracksListBox.SelectedItem.ToString()
animationTracks.FindTrack(selectedTrack, animationTrack)
Dim kFrames As IAGAnimationTrackKeyframes = CType(animationTrack, IAGAnimationTrackKeyframes)
Dim kFrameCount As Integer = kFrames.KeyframeCount
'total number of points to be created
Dim totalPts As Integer = CInt(numPtsPerSecond * animationDuration)
'this is the from point for the lines connecting the interpolated point graphics
Dim previousPt As IPoint = New PointClass()
Dim prevPtZAware As IZAware = CType(previousPt, IZAware)
prevPtZAware.ZAware = True
previousPt.PutCoords(0, 0)
'this is the line connecting the interpolated camera positions
Dim connectingLine As IPolyline = New PolylineClass()
Dim lineZAware As IZAware = CType(connectingLine, IZAware)
lineZAware.ZAware = True
'disable all buttons
theCamForm.playButton.Enabled = False
theCamForm.stopButton.Enabled = False
theCamForm.generatePathButton.Enabled = False
'loop over the keyframes in the selected camera track
Dim i As Integer = 0
Do While i < kFrameCount
Dim currentKeyframe As IAGKeyframe = CType(kFrames.Keyframe(i), ESRI.ArcGIS.Animation.IAGKeyframe)
Dim prevKeyframe As IAGKeyframe
Dim nextKeyframe As IAGKeyframe
Dim afterNextKeyframe As IAGKeyframe
'if else statements to determine the keyframe arguments to the interpolate method
'this is needed because the first, second-last and the last keyframes should be handled differently
'than the middle keyframes
If i > 0 Then
prevKeyframe = CType(kFrames.Keyframe(i - 1), ESRI.ArcGIS.Animation.IAGKeyframe)
Else
prevKeyframe = CType(kFrames.Keyframe(i), ESRI.ArcGIS.Animation.IAGKeyframe)
End If
If i < kFrameCount - 1 Then
nextKeyframe = CType(kFrames.Keyframe(i + 1), ESRI.ArcGIS.Animation.IAGKeyframe)
Else
nextKeyframe = CType(kFrames.Keyframe(i), ESRI.ArcGIS.Animation.IAGKeyframe)
End If
If i < kFrameCount - 2 Then
afterNextKeyframe = CType(kFrames.Keyframe(i + 2), ESRI.ArcGIS.Animation.IAGKeyframe)
Else
'this should be equal to the nextKeyFrame for the last keyframe
afterNextKeyframe = nextKeyframe 'kFrames.Keyframe(i);
End If
Dim origCamLat, origCamLong, origCamAlt As Double
Dim interLat, interLong, interAlt As Double
Dim tarLat, tarLong, tarAlt As Double
Dim interTarLat, interTarLong, interTarAlt As Double
globeCamera.GetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt)
globeCamera.GetTargetLatLonAlt(tarLat, tarLong, tarAlt)
Dim pAnimContainer As IAGAnimationContainer = animationTracks.AnimationObjectContainer
Dim objToInterpolate As Object = CObj(globeCamera)
Dim timeDiff As Double = nextKeyframe.TimeStamp - currentKeyframe.TimeStamp
Dim numPtsToInterpolateNow As Integer
numPtsToInterpolateNow = Convert.ToInt32((timeDiff * totalPts))
'interpolate positions between keyframes and draw the graphics
'for 0 to n-1 keyframes
If i < kFrameCount - 1 Then
Dim j As Integer = 0
Do While j < numPtsToInterpolateNow
Dim timeToInterpolate As Double
timeToInterpolate = currentKeyframe.TimeStamp + j * (timeDiff / (numPtsToInterpolateNow))
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 1, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 2, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 3, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 4, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 5, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 6, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
'get observer and target lat, long, alt after interpolation
globeCamera.GetObserverLatLonAlt(interLat, interLong, interAlt)
globeCamera.GetTargetLatLonAlt(interTarLat, interTarLong, interTarAlt)
'set observer and target lat, long, alt to original values before interpolation
globeCamera.SetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt)
globeCamera.SetTargetLatLonAlt(tarLat, tarLong, tarAlt)
Dim pObs As IPoint = New PointClass()
Dim obsZAware As IZAware = CType(pObs, IZAware)
obsZAware.ZAware = True
pObs.X = interLong
pObs.Y = interLat
pObs.Z = interAlt * 1000
Dim symbolSize As Double = 10000
'change the symbol size based on distance to ground
If pObs.Z >= 10000 Then
symbolSize = 10000 + pObs.Z / 10
Else
symbolSize = pObs.Z
End If
'add graphics - keyframes (j=0) are colored differently
If j = 0 Then
addPointGraphicElements(pObs, 2552550, symbolSize)
Else
addPointGraphicElements(pObs, 16732415, symbolSize)
End If
connectingLine.FromPoint = previousPt
connectingLine.ToPoint = pObs
'barring the first keyframe, create the line connecting the interpolated points
If i = 0 And j = 0 Then
Else
addLineGraphicElements(connectingLine, 150150150)
End If
'update the previous point
previousPt.PutCoords(pObs.X, pObs.Y)
previousPt.Z = pObs.Z
'add camera to target direction
If theCamForm.camToTargetDirectionCheckBox.Checked = True Then
cameraToTargetDirection(interLat, interLong, interAlt, interTarLat, interTarLong, interTarAlt)
End If
globeDisplay.RefreshViewers()
j += 1
Loop
End If
'for last keyframe
If i = kFrameCount - 1 Then
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 4, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 5, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 6, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 1, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 2, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 3, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
globeCamera.GetObserverLatLonAlt(interLat, interLong, interAlt)
globeCamera.GetTargetLatLonAlt(interTarLat, interTarLong, interTarAlt)
globeCamera.SetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt)
globeCamera.SetTargetLatLonAlt(tarLat, tarLong, tarAlt)
Dim pObs As IPoint = New PointClass()
Dim obsZAware As IZAware = CType(pObs, IZAware)
obsZAware.ZAware = True
pObs.X = interLong
pObs.Y = interLat
pObs.Z = interAlt * 1000
Dim symbolSize As Double = 10000
If pObs.Z >= 10000 Then
symbolSize = 10000 + pObs.Z / 10
Else
symbolSize = pObs.Z
End If
connectingLine.FromPoint = previousPt
connectingLine.ToPoint = pObs
addPointGraphicElements(pObs, 2552550, symbolSize)
addLineGraphicElements(connectingLine, 150150150)
'add camera to target orientation
If theCamForm.camToTargetDirectionCheckBox.Checked = True Then
cameraToTargetDirection(interLat, interLong, interAlt, interTarLat, interTarLong, interTarAlt)
End If
globeDisplay.RefreshViewers()
End If
i += 1
Loop
'enable buttons
theCamForm.playButton.Enabled = True
theCamForm.generatePathButton.Enabled = True
End Sub
'function for creating specified number of graphics between keyframe positions
Public Sub generatePathBtwnKFrames()
Dim numPtsBtwnKFrames As Integer = 0
'this is the from point for the lines connecting the interpolated point graphics
Dim previousPt As IPoint = New PointClass()
Dim prevPtZAware As IZAware = CType(previousPt, IZAware)
prevPtZAware.ZAware = True
previousPt.PutCoords(0, 0)
'this is the line connecting the interpolated camera positions
Dim connectingLine As IPolyline = New PolylineClass()
Dim lineZAware As IZAware = CType(connectingLine, IZAware)
lineZAware.ZAware = True
If theCamForm.ptsBtwnKframeTextBox.Text <> "" Then
numPtsBtwnKFrames = Convert.ToInt32(theCamForm.ptsBtwnKframeTextBox.Text)
Else
MessageBox.Show("Please enter the number of points to be created")
Return
End If
theCamForm.playButton.Enabled = False
theCamForm.stopButton.Enabled = False
theCamForm.generatePathButton.Enabled = False
addGraphicLayer()
Dim selectedTrack As String = theCamForm.animTracksListBox.SelectedItem.ToString()
animationTracks.FindTrack(selectedTrack, animationTrack)
Dim kFrames As IAGAnimationTrackKeyframes = CType(animationTrack, IAGAnimationTrackKeyframes)
Dim kFrameCount As Integer = kFrames.KeyframeCount
'loop over the keyframes in the selected camera track
Dim i As Integer = 0
Do While i < kFrameCount
Dim currentKeyframe As IAGKeyframe = CType(kFrames.Keyframe(i), ESRI.ArcGIS.Animation.IAGKeyframe)
Dim prevKeyframe As IAGKeyframe
Dim nextKeyframe As IAGKeyframe
Dim afterNextKeyframe As IAGKeyframe
'if else statements to determine the keyframe arguments to the interpolate method
'this is needed because the first and the last keyframes should be handled differently
'than the middle keyframes
If i > 0 Then
prevKeyframe = CType(kFrames.Keyframe(i - 1), ESRI.ArcGIS.Animation.IAGKeyframe)
Else
prevKeyframe = CType(kFrames.Keyframe(i), ESRI.ArcGIS.Animation.IAGKeyframe)
End If
If i < kFrameCount - 1 Then
nextKeyframe = CType(kFrames.Keyframe(i + 1), ESRI.ArcGIS.Animation.IAGKeyframe)
Else
nextKeyframe = CType(kFrames.Keyframe(i), ESRI.ArcGIS.Animation.IAGKeyframe)
End If
If i < kFrameCount - 2 Then
afterNextKeyframe = CType(kFrames.Keyframe(i + 2), ESRI.ArcGIS.Animation.IAGKeyframe)
Else
'this should be equal to the nextKeyFrame for the last keyframe
afterNextKeyframe = nextKeyframe 'kFrames.Keyframe(i);
End If
Dim origCamLat, origCamLong, origCamAlt As Double
Dim interLat, interLong, interAlt As Double
Dim tarLat, tarLong, tarAlt As Double
Dim interTarLat, interTarLong, interTarAlt As Double
globeCamera.GetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt)
globeCamera.GetTargetLatLonAlt(tarLat, tarLong, tarAlt)
Dim pAnimContainer As IAGAnimationContainer = animationTracks.AnimationObjectContainer
Dim objToInterpolate As Object = CObj(globeCamera)
Dim timeDiff As Double = nextKeyframe.TimeStamp - currentKeyframe.TimeStamp
'interpolate positions between keyframes and draw the graphics
Dim j As Integer = 0
Do While j < numPtsBtwnKFrames + 1
Dim timeToInterpolate As Double = currentKeyframe.TimeStamp + j * (timeDiff / (numPtsBtwnKFrames + 1))
'for 0 to n-1 keyframes
If i >= 0 And i < kFrameCount - 1 Then
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 4, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 5, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 6, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 1, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 2, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 3, timeToInterpolate, nextKeyframe, prevKeyframe, afterNextKeyframe)
globeCamera.GetObserverLatLonAlt(interLat, interLong, interAlt)
globeCamera.GetTargetLatLonAlt(interTarLat, interTarLong, interTarAlt)
globeCamera.SetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt)
globeCamera.SetTargetLatLonAlt(tarLat, tarLong, tarAlt)
Dim pObs As IPoint = New PointClass()
Dim obsZAware As IZAware = CType(pObs, IZAware)
obsZAware.ZAware = True
pObs.X = interLong
pObs.Y = interLat
pObs.Z = interAlt * 1000
Dim symbolSize As Double = 10000
If pObs.Z >= 10000 Then
symbolSize = 10000 + pObs.Z / 10
Else
symbolSize = pObs.Z
End If
If j = 0 Then
addPointGraphicElements(pObs, 2552550, symbolSize)
Else
addPointGraphicElements(pObs, 16732415, symbolSize)
End If
connectingLine.FromPoint = previousPt
connectingLine.ToPoint = pObs
If i = 0 And j = 0 Then
Else
addLineGraphicElements(connectingLine, 150150150)
End If
previousPt.PutCoords(pObs.X, pObs.Y)
previousPt.Z = pObs.Z
'add camera to target orientation
If theCamForm.camToTargetDirectionCheckBox.Checked = True Then
cameraToTargetDirection(interLat, interLong, interAlt, interTarLat, interTarLong, interTarAlt)
End If
globeDisplay.RefreshViewers()
'for last keyframe
ElseIf i = kFrameCount - 1 Then
If j = 0 Then
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 4, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 5, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 6, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 1, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 2, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
currentKeyframe.Interpolate(animationTrack, pAnimContainer, objToInterpolate, 3, 1, nextKeyframe, prevKeyframe, afterNextKeyframe)
globeCamera.GetObserverLatLonAlt(interLat, interLong, interAlt)
globeCamera.GetTargetLatLonAlt(interTarLat, interTarLong, interTarAlt)
globeCamera.SetObserverLatLonAlt(origCamLat, origCamLong, origCamAlt)
globeCamera.SetTargetLatLonAlt(tarLat, tarLong, tarAlt)
Dim pObs As IPoint = New PointClass()
Dim obsZAware As IZAware = CType(pObs, IZAware)
obsZAware.ZAware = True
pObs.X = interLong
pObs.Y = interLat
pObs.Z = interAlt * 1000
Dim symbolSize As Double = 10000
If pObs.Z >= 10000 Then
symbolSize = 10000 + pObs.Z / 10
Else
symbolSize = pObs.Z
End If
connectingLine.FromPoint = previousPt
connectingLine.ToPoint = pObs
addPointGraphicElements(pObs, 2552550, symbolSize)
addLineGraphicElements(connectingLine, 150150150)
'add camera to target orientation
If theCamForm.camToTargetDirectionCheckBox.Checked = True Then
cameraToTargetDirection(interLat, interLong, interAlt, interTarLat, interTarLong, interTarAlt)
End If
globeDisplay.RefreshViewers()
End If
End If
j += 1
Loop
i += 1
Loop
'enable buttons
theCamForm.playButton.Enabled = True
theCamForm.generatePathButton.Enabled = True
End Sub
'function for generating camera to target direction
Public Sub cameraToTargetDirection(ByVal camLat As Double, ByVal camLong As Double, ByVal camAlt As Double, ByVal tarLat As Double, ByVal tarLong As Double, ByVal tarAlt As Double)
Dim camPosition As IPoint = New PointClass()
Dim targetPosition As IPoint = New PointClass()
Dim pCamera As ICamera = CType(globeCamera, ICamera)
Dim obsZAware As IZAware = CType(camPosition, IZAware)
obsZAware.ZAware = True
camPosition.PutCoords(camLong, camLat)
camPosition.Z = camAlt * 1000
Dim targetZAware As IZAware = CType(targetPosition, IZAware)
targetZAware.ZAware = True
targetPosition.PutCoords(tarLong, tarLat)
targetPosition.Z = tarAlt
Dim directionLine As IPolyline = New PolylineClass()
Dim zAwareLine As IZAware = CType(directionLine, IZAware)
zAwareLine.ZAware = True
directionLine.FromPoint = camPosition
directionLine.ToPoint = targetPosition
addLineGraphicElements(directionLine, 255)
End Sub
'function for adding a graphics layer
Public Sub addGraphicLayer()
graphicsLayer = New GlobeGraphicsLayerClass()
Dim pLayer As ILayer
pLayer = CType(graphicsLayer, ILayer)
pLayer.Name = "CameraPathGraphicsLayer"
globe.AddLayerType(pLayer, esriGlobeLayerType.esriGlobeLayerTypeDraped, True)
End Sub
'function for adding point markers
Public Sub addPointGraphicElements(ByVal inPoint As ESRI.ArcGIS.Geometry.IPoint, ByVal symbolColor As Integer, ByVal symbolSize As Double)
Dim pElement As IElement = New MarkerElementClass()
Dim symbol3d As ISimpleMarker3DSymbol = New SimpleMarker3DSymbolClass()
Dim markerStyle As String = ""
If Not theCamForm.symbolTypeListBox.SelectedItem Is Nothing Then
markerStyle = theCamForm.symbolTypeListBox.SelectedItem.ToString()
End If
If markerStyle = "Cone" Then
symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSCone
ElseIf markerStyle = "Sphere" Then
symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSSphere
ElseIf markerStyle = "Cylinder" Then
symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSCylinder
ElseIf markerStyle = "Cube" Then
symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSCube
ElseIf markerStyle = "Diamond" Then
symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSDiamond
ElseIf markerStyle = "Tetrahedron" Then
symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSTetra
Else
symbol3d.Style = esriSimple3DMarkerStyle.esriS3DMSCone
End If
symbol3d.ResolutionQuality = 1
Dim pColor As IColor = New RgbColorClass()
pColor.RGB = symbolColor '16732415;
Dim pMarkerSymbol As IMarkerSymbol
pMarkerSymbol = CType(symbol3d, IMarkerSymbol)
pMarkerSymbol.Color = pColor
If symbolSize < 0 Then
symbolSize = Math.Abs(symbolSize)
End If
If symbolSize = 0 Then
symbolSize = 5000
End If
pMarkerSymbol.Size = symbolSize
pElement.Geometry = inPoint
Dim pMarkerElement As IMarkerElement
pMarkerElement = CType(pElement, IMarkerElement)
pMarkerElement.Symbol = pMarkerSymbol
graphicsLayer.AddElement(pElement, 1)
End Sub
'function for adding line graphics elements
Public Sub addLineGraphicElements(ByVal inLine As ESRI.ArcGIS.Geometry.IPolyline, ByVal symbolColor As Integer)
Dim pElement As IElement = New LineElementClass() ' MarkerElementClass();
Dim symbol3d As ISimpleLine3DSymbol = New SimpleLine3DSymbolClass()
Dim markerStyle As String = ""
If Not theCamForm.symbolTypeListBox.SelectedItem Is Nothing Then
markerStyle = theCamForm.symbolTypeListBox.SelectedItem.ToString()
End If
If markerStyle = "Strip" Then
symbol3d.Style = esriSimple3DLineStyle.esriS3DLSStrip
ElseIf markerStyle = "Wall" Then
symbol3d.Style = esriSimple3DLineStyle.esriS3DLSWall
Else
symbol3d.Style = esriSimple3DLineStyle.esriS3DLSTube
End If
symbol3d.ResolutionQuality = 1
Dim pColor As IColor = New RgbColorClass()
pColor.RGB = symbolColor
Dim pLineSymbol As ILineSymbol
pLineSymbol = CType(symbol3d, ILineSymbol)
pLineSymbol.Color = pColor
pLineSymbol.Width = 1
pElement.Geometry = inLine
Dim pLineElement As ILineElement
pLineElement = CType(pElement, ILineElement)
pLineElement.Symbol = pLineSymbol
graphicsLayer.AddElement(pElement, 1)
End Sub
'event handlers
Public Sub formPlayButtonClickEventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
If Not theCamForm.animTracksListBox.SelectedItem Is Nothing Then
enableSelectedTrack()
'play the animation
Me.playAnimation()
Else
MessageBox.Show("Please select a camera track", "Error")
End If
End Sub
Public Sub formStopButtonClickEventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
animPlayer.StopAnimation()
theCamForm.stopButton.Enabled = False
If theCamForm.generateCamPathCheckBox.Checked = True Then
theCamForm.generatePathButton.Enabled = True
End If
End Sub
Public Sub formGeneratePathButtonClickEventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
If Not theCamForm.animTracksListBox.SelectedItem Is Nothing Then
If theCamForm.ptsPerSecRadioButton.Checked = True Then
If theCamForm.numPtsPerSecTextBox.Text = "" Then
MessageBox.Show("Please enter number of points to be created per second", "Error")
Return
End If
generatePathPerSecond()
ElseIf theCamForm.ptsBtwnKframeRadioButton.Checked = True Then
If theCamForm.ptsBtwnKframeTextBox.Text = "" Then
MessageBox.Show("Please enter number of points to be created between keyframes", "Error")
Return
End If
generatePathBtwnKFrames()
End If
Else
MessageBox.Show("Please select a camera track")
End If
End Sub
Public Sub formCheckbox1CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs)
If theCamForm.generateCamPathCheckBox.Checked = True Then
theCamForm.generatePathButton.Enabled = True
Else
theCamForm.generatePathButton.Enabled = False
End If
End Sub
Private Sub theCamForm_Closing(ByVal sender As Object, ByVal e As CancelEventArgs)
theCamForm.animTracksListBox.Items.Clear()
toolIsInitialized = False
End Sub
Public Sub myAnimationEventHandler(ByVal animState As esriAnimationState)
globeDispEvent = CType(globeDisplay, IGlobeDisplayEvents_Event)
If animState = esriAnimationState.esriAnimationStopped Then
theCamForm.playButton.Enabled = True
theCamForm.generatePathButton.Enabled = True
theCamForm.stopButton.Enabled = False
End If
End Sub
#End Region
End Class
End Namespace