Fly through
Normal 3D views
You can do view manipulation manually on "ViewAttributes" objects, but, alternatively, you can use the built in function EvalCubicSpline to smoothly interpolate many view control points. This section shows how to use the interpolation functions to interpolate normal View3DAttributes objects. If you want to actually move the camera to locations of your choosing then see the next section.
Here's how:
- Find views that you like interactively in the GUI.
- Have the CLI running and enter:
>>> v = GetView3D() >>> v # gives the current view viewNormal = (0, 0, 1) focus = (0, 0, 0) viewUp = (0, 1, 0) viewAngle = 30 parallelScale = 0.5 nearPlane = -0.5 farPlane = 0.5 imagePan = (0, 0) imageZoom = 1 perspective = 1 eyeAngle = 2 centerOfRotationSet = 0 centerOfRotation = (0, 0, 0)
- You must have at least four views because cubic functions require at least 4 coefficients. (The one below has six.)
- Then employ a function like fly() to animat the view:
def fly():
# Do a pseudocolor plot of u.
OpenDatabase('../../data/globe.silo')
AddPlot('Pseudocolor', 'u')
DrawPlots()
# Create the control points for the views.
c0 = View3DAttributes()
c0.viewNormal = (0, 0, 1)
c0.focus = (0, 0, 0)
c0.viewUp = (0, 1, 0)
c0.viewAngle = 30
c0.parallelScale = 17.3205
c0.nearPlane = 17.3205
c0.farPlane = 81.9615
c0.perspective = 1
c1 = View3DAttributes()
c1.viewNormal = (-0.499159, 0.475135, 0.724629)
c1.focus = (0, 0, 0)
c1.viewUp = (0.196284, 0.876524, -0.439521)
c1.viewAngle = 30
c1.parallelScale = 14.0932
c1.nearPlane = 15.276
c1.farPlane = 69.917
c1.perspective = 1
c2 = View3DAttributes()
c2.viewNormal = (-0.522881, 0.831168, -0.189092)
c2.focus = (0, 0, 0)
c2.viewUp = (0.783763, 0.556011, 0.27671)
c2.viewAngle = 30
c2.parallelScale = 11.3107
c2.nearPlane = 14.8914
c2.farPlane = 59.5324
c2.perspective = 1
c3 = View3DAttributes()
c3.viewNormal = (-0.438771, 0.523661, -0.730246)
c3.focus = (0, 0, 0)
c3.viewUp = (-0.0199911, 0.80676, 0.590541)
c3.viewAngle = 30
c3.parallelScale = 8.28257
c3.nearPlane = 3.5905
c3.farPlane = 48.2315
c3.perspective = 1
c4 = View3DAttributes()
c4.viewNormal = (0.286142, -0.342802, -0.894768)
c4.focus = (0, 0, 0)
c4.viewUp = (-0.0382056, 0.928989, -0.36813)
c4.viewAngle = 30
c4.parallelScale = 10.4152
c4.nearPlane = 1.5495
c4.farPlane = 56.1905
c4.perspective = 1
c5 = View3DAttributes()
c5.viewNormal = (0.974296, -0.223599, -0.0274086)
c5.focus = (0, 0, 0)
c5.viewUp = (0.222245, 0.97394, -0.0452541)
c5.viewAngle = 30
c5.parallelScale = 1.1052
c5.nearPlane = 24.1248
c5.farPlane = 58.7658
c5.perspective = 1
c6 = c0
# Create a tuple of camera values and x values. The x values are weights
# that help to determine where in [0,1] the control points occur.
cpts = (c0, c1, c2, c3, c4, c5, c6)
x=[]
for i in range(7):
x = x + [float(i) / float(6.)]
# Animate the camera. Note that we use the new built-in EvalCubicSpline
# function which takes a t value from [0,1] a tuple of t values and a tuple
# of control points. In this case, the control points are View3DAttributes
# objects that we are using to animate the camera but they can be any object
# that supports +, * operators.
nsteps = 100
for i in range(nsteps):
t = float(i) / float(nsteps - 1)
c = EvalCubicSpline(t, x, cpts)
c.nearPlane = -34.461
c.farPlane = 34.461
SetView3D(c)
Setting the camera position
With normal 3D views, VisIt takes care of setting the camera position based on some distance and orientation from the plots being viewed. You can override this behavior by turning on Flythrough interaction in the Options->Interactors window. When the flythrough interaction method is used, you must provide the camera location, up vector, and view direction that will be used.
Here is a script that shows how to use the EvalCubicBezier function to build up a smooth camera path, consisting of: camera position, camera up vector, and camera direction (or focus). You can model your camera, thinking of these parameters and then set them into the View3DAttributes object such that VisIt will use them for the view.
import math
#
# Vector functions
#
def vec_magnitude(vec):
return math.sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2])
def vec_normalize(vec):
R = vec_magnitude(vec)
return (vec[0] / R, vec[1] / R, vec[2] / R)
def vec_add(a, b):
return (a[0] + b[0], a[1] + b[1], a[2] + b[2])
def vec_mult_float(vec, f):
return (vec[0] * f, vec[1] * f, vec[2] * f)
def vec_cross(a, b):
return (a[1]*b[2] - a[2]*b[1],
a[2]*b[0] - a[0]*b[2],
a[0]*b[1] - a[1]*b[0])
def setup():
OpenDatabase("globe.silo")
AddPlot("Pseudocolor", "u")
DrawPlots()
ia = GetInteractorAttributes()
ia.navigationMode = ia.Flythrough
SetInteractorAttributes(ia)
def animate(nts):
# Here is where the control points for the camera position and up vector are determined.
positions = ((0,0,30), (0,0,15), (-8,0,10), (-11,0,0), (-7.7,0,-7.77), (0,0,-11), (7.77, 0, -7.77), (11,0,0))
up = ((0,1,0), (-0.2, 0.7, 0.2), (-.707,0,0.707), (-1, 0, 0), (-0.707, 0, -0.707), (0,0,-1), (0.707, 0, -0.707), (1,0,0))
x=[]
px = []
py = []
pz = []
ux = []
uy = []
uz = []
for i in range(len(positions)):
x = x + [float(i) / float(len(positions)-1)]
px = px + [positions[i][0]]
py = py + [positions[i][1]]
pz = pz + [positions[i][2]]
ux = ux + [up[i][0]]
uy = uy + [up[i][1]]
uz = uz + [up[i][2]]
smooth_positions = []
for i in xrange(nts+1):
t = float(i) / float(nts)
print t
sx = EvalCubicSpline(t, x, px)
sy = EvalCubicSpline(t, x, py)
sz = EvalCubicSpline(t, x, pz)
smooth_positions = smooth_positions + [(sx,sy,sz)]
# Let's write the positions of these paths to files that we can plot in VisIt
f1 = open("pos.lines", "wt")
f2 = open("up.lines", "wt")
f3 = open("right.lines", "wt")
v = GetView3D()
for i in xrange(nts):
t = float(i) / float(nts)
# Make the camera position be the values that we already made.
camera_position = smooth_positions[i]
# Make the camera view along the path that we're following.
# We could be looking at anything, however.
dx = smooth_positions[i+1][0] - smooth_positions[i][0]
dy = smooth_positions[i+1][1] - smooth_positions[i][1]
dz = smooth_positions[i+1][2] - smooth_positions[i][2]
camera_direction = vec_normalize((dx, dy, dz))
# Make a smooth up vector
sux = EvalCubicSpline(t, x, ux)
suy = EvalCubicSpline(t, x, uy)
suz = EvalCubicSpline(t, x, uz)
camera_up = vec_normalize((sux,suy,suz))
# Now, map the camera into VisIt's flythrough view
v.viewNormal = camera_direction
v.focus = camera_position
v.viewUp = camera_up
v.parallelScale = 1
v.nearPlane = -50
v.farPlane = 50
SetView3D(v)
SaveWindow()
# Write out the position, etc for debugging.
f1.write("%g, %g, %g\n" % camera_position)
f2.write("%g, %g, %g\n" % (camera_position[0] + camera_up[0], camera_position[1] + camera_up[1], camera_position[2] + camera_up[2]))
right = vec_normalize(vec_cross(camera_direction, camera_up))
f3.write("%g, %g, %g\n" % (camera_position[0] + right[0], camera_position[1] + right[1], camera_position[2] + right[2]))
f1.close()
f2.close()
f3.close()
def main():
setup()
animate(50)
main()