Syntax Highlighing:
comments, key words, predefined symbols, class members & methods, functions & classes
######################
#
# PATHcALT.SML
#
# Demonstration of movie generation from 3D display using
# 2D vector objects to derive viewer position (flight) path
# and path of view center. Both 2D and 3D views are
# copied into each movie frame. Current viewer position and
# view center positions are shown in each 2D frame.
#
# Script uses input DEM for surface, an input raster drape layer, and
# two input vector objects, each with a single line, one defining the
# ground trace of the viewer position and the other defining the ground
# trace of the view center.
#
# Computes constant-altitude flight path a set height
# above the highest surface elevation beneath the flight
# path. View center moves on the surface.
#
# Both paths are partitioned into equal segments to set
# positions for capturing frames (to produce smoother motion).
# Symbols are drawn into each frame to mark current viewer and
# view center locations.
#
# Requires TNTmips Version 6.5
#
#####################
clear();
#### Set movie format, frame rate, and recording time
# Movie format (Possible values : "MPEG"(All platform) or "AVI"(Windows only)
string format$;
format$ = "AVI";
# Frame rate
# Possible values :
# "MOVIE_FRAMERATE_23_976" 23.976 (24000/1001) fps - NTSC encapsulated film rate
# "MOVIE_FRAMERATE_24" 24 fps - Standard international cinema film rate
# "MOVIE_FRAMERATE_25" 25 fps - PAL (625/50) video frame rate
# "MOVIE_FRAMERATE_29_970" 29.97 (30000/1001) fps - NTSC video frame rate
# "MOVIE_FRAMERATE_30" 30 fps - NTSC drop-frame (525/60) video frame rate
# "MOVIE_FRAMERATE_50" 50 fps - Double frame rate / progressive PAL
# "MOVIE_FRAMERATE_59_940" 59.94 (60000/1001) fps - Double frame rate NTSC
# "MOVIE_FRAMERATE_60" 60 fps - Double frame rate drop-frame NTSC
string framerate$;
framerate$ = "MOVIE_FRAMERATE_24";
# Recording time
numeric time;
time = 60;
####### Get RVC objects to load
raster Surface, RastDrape;
vector FlightPathVec, ViewCenterVec;
print("Select raster to use for surface");
GetInputRaster(Surface);
print("Select raster to use for drape layer");
GetInputRaster(RastDrape);
print("Select 3D vector to use for flight path");
GetInputVector(FlightPathVec);
print("Select vector to use for view center path");
GetInputVector(ViewCenterVec);
###### RVC style object to draw center point and viewer point
string styleFilename$;
string styleObjectname$;
GetInputObject("Style","Select style object for center and viewer point symbols:",
styleFilename$, styleObjectname$);
string viewer$;
viewer$ = "VIEWER";
string center$;
center$ = "CENTER";
######## Create display group with 2d and 3d views
print("START");
# Size of squared 2D view and 3D view
# Should be evenly divisible by 8
numeric size;
size = 320;
# Zoom out factor for 2D view
numeric zoomfactor;
zoomfactor = 1.0;
# Create group
print("Creating Group");
class GRE_GROUP group;
group = GroupCreate();
# Create flags to create view without iconbar, scrollbars, status line and scale/position line
# This is important to maintain fixed window size for movie generation
string flags$;
flags$ = "NoScalePosLine,NoIconBar,NoScrollbars,NoStatusLine";
# Create dialog and 2D view
print("Creating dialog and 2D view");
class XmForm dialog2d;
class GRE_VIEW view2d;
dialog2d = CreateFormDialog("VIEW 2D");
view2d = GroupCreateView(group,dialog2d,"",size,size,flags$);
view2d.BackgroundColor.red = 67;
view2d.BackgroundColor.green = 100;
view2d.BackgroundColor.blue = 100;
# Create dialog and 3D view
print("Creating dialog and 3D view");
class XmForm dialog3d;
class GRE_VIEW3D view3d;
dialog3d = CreateFormDialog("VIEW 3D");
view3d = GroupCreate3DView(group,dialog3d,"",size,size,flags$);
view3d.BackgroundColor.red = 67;
view3d.BackgroundColor.green = 100;
view3d.BackgroundColor.blue = 100;
# Adding layers to group
GroupQuickAddRasterVar(group,Surface,1);
GroupQuickAddRasterVar(group,RastDrape,0);
# Open of both views
DialogOpen(dialog2d);
DialogOpen(dialog3d);
# Full redraw of both views
ViewRedrawFull(view2d);
ViewRedrawFull(view3d);
ViewZoomOut(view2d,zoomfactor,1);
####### Set up parameters for movie frame
# Destination of each view in final frame for movie
numeric x2d, y2d, x3d, y3d, w, h;
x2d = 0;
y2d = 0;
x3d = size;
y3d = 0;
w = 2 * size;
h = size;
# Create text string for annotation in frame
string frameTitle$;
frameTitle$ = "Ray Mine, AZ";
# Font size for annotation in frame
numeric fontsize;
fontsize = 16;
# Define color for text annotation
class Color black;
black.red = 0;
black.green = 0;
black.blue = 0;
# Create frame
print("Creating frame for movie");
class Frame frame;
frame = FrameCreate(w,h);
# Create graphics context (GC) for frame
print("Creating GC for frame and activate it");
ActivateGC(FrameCreateGC(frame));
DrawTextSetHeightPixels(fontsize);
DrawUseStyleObject(styleFilename$,styleObjectname$);
######## Set some more movie parameters
# Initializing Movie
print("Initializing Movie");
class Movie movie;
movie = MovieInit();
# Check framerate and force it to "MOVIE_FRAMERATE_24" if it is invalid
numeric rate;
rate = 24;
if (framerate$ == "MOVIE_FRAMERATE_23_976") rate = 23.976;
if (framerate$ == "MOVIE_FRAMERATE_25") rate = 25.0;
if (framerate$ == "MOVIE_FRAMERATE_29_970") rate = 29.970;
if (framerate$ == "MOVIE_FRAMERATE_30") rate = 30.0;
if (framerate$ == "MOVIE_FRAMERATE_50") rate = 50.0;
if (framerate$ == "MOVIE_FRAMERATE_59_940") rate = 59.940;
if (framerate$ == "MOVIE_FRAMERATE_60") rate = 60.0;
if (rate == 24.0) framerate$ = "MOVIE_FRAMERATE_24";
# Set Movie Parameters
print("Setting Movie Parameters");
MovieSetFormat(movie,format$);
MovieSetFrameRate(movie,framerate$);
MovieSetFrameWidth(movie,w);
MovieSetFrameHeight(movie,h);
# Make Output File
string ext$;
ext$ = MovieGetFileExt(movie);
string filename$;
filename$ = GetOutputFileName("","Make filename for movie",ext$);
printf("Filename = %s\n",filename$);
# Check recording time
if (time <= 1.0) time = 1.0;
# Calculate number of frames
numeric numFrames = time * rate;
####### Get georeference parameters for layers and reset to group projection
####### (defined by raster drape layer)
# Georeference for surface layer
class Georef georefS;
georefS = GetLastUsedGeorefObject(Surface);
GeorefSetProjection(georefS,group.Projection);
# Georeference for flight path vector object
class Georef georefFlight;
georefFlight = GetLastUsedGeorefObject(FlightPathVec);
GeorefSetProjection(georefFlight,group.Projection);
# Georeference for view center path vector object
class Georef georefCent;
georefCent = GetLastUsedGeorefObject(ViewCenterVec);
GeorefSetProjection(georefCent,group.Projection);
####### Compute flight path from 2D vector line
# Create arrays of vertex coordinates for flight and center path lines
numeric numflight; # number of vertices in flight path line
array numeric xarrayf [1]; # array to hold x-coordinates of flight line vertices
array numeric yarrayf [1]; # array to hold y-coordinates of flight line vertices
# Get x and y coordinates of line vertices
numflight = GetVectorLinePointList(FlightPathVec,xarrayf,yarrayf,1);
# Transform vertex coordinates for flight path to map coordinates for group
# and find surface Z-value for each vertex and maximum z-value
array numeric zarrayf [numflight]; # array to hold z-coordinates of flight line vertices
numeric obj_x;
numeric obj_y;
numeric map_x;
numeric map_y;
numeric maxZ;
maxZ = 0;
numeric i;
for i = 1 to numflight {
obj_x = xarrayf[i];
obj_y = yarrayf[i];
ObjectToMap(FlightPathVec,obj_x,obj_y,georefFlight,map_x,map_y);
xarrayf[i] = map_x;
yarrayf[i] = map_y;
MapToObject(georefS,map_x,map_y,Surface,obj_x,obj_y);
zarrayf[i] = Surface[obj_y,obj_x];
if (zarrayf[i] > maxZ) then maxZ = zarrayf[i];
}
# Set desired altitude of flight path above maximum surface elevation
# on flight path
numeric clearance;
numeric altitude;
clearance = 1000;
altitude = maxZ + clearance;
# Compute length of level flight path and movement increment
numeric dx;
numeric dy;
numeric dl;
numeric lengthf; # flight path 2D length in meters
numeric incFlight; # movement increment along flight path
lengthf = 0;
for i = 1 to (numflight - 1) {
dx = xarrayf[i+1] - xarrayf[i];
dy = yarrayf[i+1] - yarrayf[i];
dl = sqrt( dx*dx + dy*dy );
lengthf = lengthf + dl;
}
incFlight = lengthf / (numFrames - 1);
# Recalculate equal-distance vertices for flight path
array numeric xarrayf_eq [numFrames]; # array to hold x-coordinates of flight line vertices
array numeric yarrayf_eq [numFrames]; # array to hold y-coordinates of flight line vertices
array numeric zarrayf_eq [numFrames]; # array to hold z-coordinates of flight line vertices
xarrayf_eq[1] = xarrayf[1];
yarrayf_eq[1] = yarrayf[1];
zarrayf_eq[1] = altitude;
numeric numvert_eq;
numeric indexf;
numeric coef;
numeric sum;
numeric rest;
numvert_eq = 1;
indexf = 1;
rest = 0.0;
while (numvert_eq < (numFrames - 1)) {
dx = xarrayf[indexf+1] - xarrayf[indexf];
dy = yarrayf[indexf+1] - yarrayf[indexf];
dl = sqrt( dx*dx + dy*dy );
rest = rest + dl;
sum = 0.0;
while ((rest > incFlight) and (numvert_eq < (numFrames - 1) ) ) {
rest = rest - incFlight;
sum = sum + incFlight;
numvert_eq = numvert_eq + 1;
coef = sum / dl;
xarrayf_eq[numvert_eq] = xarrayf[indexf] + coef * dx;
yarrayf_eq[numvert_eq] = yarrayf[indexf] + coef * dy;
zarrayf_eq[numvert_eq] = altitude;
}
indexf = indexf + 1;
}
xarrayf_eq[numFrames] = xarrayf[numflight];
yarrayf_eq[numFrames] = yarrayf[numflight];
zarrayf_eq[numFrames] = altitude;
##### Compute view center path from 2D vector line
# Create arrays to hold vertex x and y coordinates of view center line
# Arrays will be resized automatically by the GetVectorLinePointList function
numeric numcent; # number of vertices in view center line
array numeric xarrayc [1]; # array to hold x-coordinates of center line vertices
array numeric yarrayc [1]; # array to hold y-coordinates of center line vertices
# Get x and y coordinates of line vertices
numcent = GetVectorLinePointList(ViewCenterVec,xarrayc,yarrayc,1);
# Transform vertex coordinates for view center path to map coordinates for group
# and find surface Z-value for each vertex
array numeric zarrayc [numcent]; # array to hold z-coordinates of center line vertices
for i = 1 to numcent {
obj_x = xarrayc[i];
obj_y = yarrayc[i];
ObjectToMap(ViewCenterVec,obj_x,obj_y,georefCent,map_x,map_y);
xarrayc[i] = map_x;
yarrayc[i] = map_y;
MapToObject(georefS,map_x,map_y,Surface,obj_x,obj_y);
zarrayc[i] = Surface[obj_y,obj_x];
}
# Compute length of view center path and movement increment
numeric dz;
numeric lengthc; # view center path 3D length in map meters
numeric incCent; # movement increment along view center path
lengthc = 0;
for i = 1 to (numcent-1) {
dx = xarrayc[i+1] - xarrayc[i];
dy = yarrayc[i+1] - yarrayc[i];
dz = zarrayc[i+1] - zarrayc[i];
dl = sqrt( dx*dx + dy*dy + dz*dz );
lengthc = lengthc + dl;
}
incCent = lengthc / numFrames ;
# Recalculate equal-distance vertices for center path
array numeric xarrayc_eq [numFrames]; # array to hold x-coordinates of center line vertices
array numeric yarrayc_eq [numFrames]; # array to hold y-coordinates of center line vertices
array numeric zarrayc_eq [numFrames]; # array to hold z-coordinates of center line vertices
xarrayc_eq[1] = xarrayc[1]; # first vertex is the same for new path
yarrayc_eq[1] = yarrayc[1];
zarrayc_eq[1] = zarrayc[1];
numeric numcent_eq;
numeric indexc;
numcent_eq = 1;
indexc = 1;
rest = 0.0;
while (numcent_eq < (numFrames - 1)) {
dx = xarrayc[indexc+1] - xarrayc[indexc];
dy = yarrayc[indexc+1] - yarrayc[indexc];
dz = zarrayc[indexc+1] - zarrayc[indexc];
dl = sqrt( dx*dx + dy*dy + dz*dz );
rest = rest + dl;
sum = 0.0;
while ( (rest > incCent) and ( numcent_eq < (numFrames - 1) ) ) {
rest = rest - incCent;
sum = sum + incCent;
numcent_eq = numcent_eq + 1;
coef = sum / dl;
xarrayc_eq[numcent_eq] = xarrayc[indexc] + coef * dx;
yarrayc_eq[numcent_eq] = yarrayc[indexc] + coef * dy;
zarrayc_eq[numcent_eq] = zarrayc[indexc] + coef * dz;
}
indexc = indexc + 1;
}
xarrayc_eq[numFrames] = xarrayc[numcent]; # last vertex is the same also
yarrayc_eq[numFrames] = yarrayc[numcent];
zarrayc_eq[numFrames] = zarrayc[numcent];
##### Set up viewpoint and viewer position parameters
class VIEWPOINT3D vp;
vp = view3d.ViewPoint;
class POINT3D fpt; # flight path location
class POINT3D cpt; # center point location
class POINT2D point; # 2D point for location symbols
##### Start recording movie to file
MovieStart(movie,filename$);
# Loop for each frame
for i = 1 to numFrames {
SetStatusMessage(sprintf("Processing frame %d of %d",i,numFrames));
# Set viewer position and center position and redraw views
fpt.x = xarrayf_eq[i];
fpt.y = yarrayf_eq[i];
fpt.z = zarrayf_eq[i];
vp.SetViewerPosition(fpt);
cpt.x = xarrayc_eq[i];
cpt.y = yarrayc_eq[i];
cpt.z = zarrayc_eq[i];
vp.SetCenter(cpt);
# ViewRedrawDirect(view3d,"NoBlankScreen");
# This new function added after release of TNTmips 6.5
# can redraw the view without blanking it first. Use of
# this function eliminates "flashing" of the view as the
# movie is initially rendered. It has no effect on the
# output movie file. For 6.5 release version, use the
# function in the next statement.
ViewRedraw(view3d);
# Copy 2dd view and 3d view to destination frame
FrameCopyFromView(frame,view2d,0,0,size,size,x2d,y2d);
FrameCopyFromView(frame,view3d,0,0,size,size,x3d,y3d);
# Draw center point in 2d frame
point.x = vp.CenterPoint.x;
point.y = vp.CenterPoint.y;
point = TransPoint2D(point,ViewGetTransMapToView(view2d,group.Projection));
point = TransPoint2D(point,ViewGetTransViewToScreen(view2d));
DrawSetPointStyle(center$);
DrawPoint(point.x,point.y);
# Draw viewer position point in 2d frame
point.x = vp.ViewPos.x;
point.y = vp.ViewPos.y;
point = TransPoint2D(point,ViewGetTransMapToView(view2d,group.Projection));
point = TransPoint2D(point,ViewGetTransViewToScreen(view2d));
DrawSetPointStyle(viewer$);
DrawPoint(point.x,point.y);
# Draw text to top of frame
DrawTextSetColors(black);
DrawTextSimple(frameTitle$,2,fontsize);
# Add frame to movie
MovieAddFrame(movie,frame);
} # End of main processing loop
# Stop and Exit movie
MovieStop(movie);
MovieExit(movie);
# Close dialogs
DialogClose(dialog2d);
DialogClose(dialog3d);
print("END");