PATHcHT1.sml

  Download

More scripts: Advanced

Syntax Highlighing:

comments, key words, predefined symbols, class members & methods, functions & classes
            
######################
#
# PATHcHT1.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 flight path at constant height above the
# surface.  View center moves on the surface.  
# Both paths are partitioned into equal segments to set 
# positions for capturing frames (to produce smoother motion).
#
# Input flight line and center line vector objects are shown in
# the overhead (2D) view but hidden in the 3D view.
#
# 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 (seconds)
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;
# Add layers to group
GroupQuickAddRasterVar(group,Surface,1);
GroupQuickAddRasterVar(group,RastDrape,0);
class GRE_LAYER_VECTOR vclayer;
class GRE_LAYER_VECTOR fplayer;
vclayer = GroupQuickAddVectorVar(group,ViewCenterVec);
fplayer = GroupQuickAddVectorVar(group,FlightPathVec);
# Hide vector layers in 3D view
LayerHide(vclayer,view3d);
LayerHide(fplayer,view3d);
# Open 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$ = "Muddy Mountains, NV";
# Font size for annotation in frame
numeric fontsize;
fontsize = 16;
# Define color for text annotation in frame
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 from frame and activate it");
ActivateGC(FrameCreateGC(frame));
DrawTextSetHeightPixels(fontsize);
DrawUseStyleObject(styleFilename$,styleObjectname$);
######## Set some more movie parameters
# Initialize 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 to hold vertex coordinates for input flight path line
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
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 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];
	} 
# Set height of flight path above surface and compute array of
# z-values for path
numeric heightAboveSurf;
heightAboveSurf = 1000;
for i = 1 to numflight {
	zarrayf[i] = zarrayf[i] + heightAboveSurf;
}
# Compute length of 3D flight path and movement increment
numeric dx;
numeric dy;
numeric dz;
numeric dl;
numeric lengthf;		# flight path 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];
	dz = zarrayf[i+1] - zarrayf[i];
	dl = sqrt( dx*dx + dy*dy + dz*dz );
	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] = zarrayf[1];
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];
	dz = zarrayf[indexf+1] - zarrayf[indexf];
	dl = sqrt( dx*dx + dy*dy + dz*dz );
	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] = zarrayf[indexf] + coef * dz;
		}
	indexf = indexf + 1;
	}
xarrayf_eq[numFrames] = xarrayf[numflight];
yarrayf_eq[numFrames] = yarrayf[numflight];
zarrayf_eq[numFrames] = zarrayf[numflight];
##### Compute view center path from 2D vector line
# Create arrays to hold vertex 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 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 2d 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 main processing loop
# Stop and Exit movie
MovieStop(movie);
MovieExit(movie);
# Close dialogs
DialogClose(dialog2d);
DialogClose(dialog3d);
print("END");