PageSourceSearch

https://docs-vrgeo-version3.netlify.app/assets/js/62a93449.aa349bd6.js

js docs-vrgeo-version3.netlify.app collected 2026-10-03 10:41:29 UTC 95,305 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkvrgs_docs_v_3_1=globalThis.webpackChunkvrgs_docs_v_3_1||[]).push([[13569],{43124(e,t,n){n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>a,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"general/viewing-collaboration/flight-path-user-guide","title":"Flight Path User Guide","description":"Author cinematic camera fly-throughs of your outcrop in VRGS \u2014 mark points of interest and let VRGS generate the path, or capture viewpoints by hand, then fine-tune timing on the timeline editor, choreograph scene visibility, add spoken narration, and record a movie.","source":"@site/docs/general/viewing-collaboration/flight-path-user-guide.md","sourceDirName":"general/viewing-collaboration","slug":"/general/viewing-collaboration/flight-path-user-guide","permalink":"/docs/next/general/viewing-collaboration/flight-path-user-guide","draft":false,"unlisted":false,"editUrl":"https://github.com/vrgeoscience/vrgs_docs_v3/tree/master/docs/general/viewing-collaboration/flight-path-user-guide.md","tags":[],"version":"current","sidebarPosition":3,"frontMatter":{"id":"flight-path-user-guide","title":"Flight Path User Guide","sidebar_label":"Flight Paths","description":"Author cinematic camera fly-throughs of your outcrop in VRGS \u2014 mark points of interest and let VRGS generate the path, or capture viewpoints by hand, then fine-tune timing on the timeline editor, choreograph scene visibility, add spoken narration, and record a movie.","keywords":["flight path","camera animation","fly-through","movie","timeline","keyframe","viewpoint","point of interest","POI","auto generate","orbit","traverse","clearance","presentation","motion blur","narration","guided tour","virtual field trip","audio"],"sidebar_position":3},"sidebar":"docs","previous":{"title":"Billboards","permalink":"/docs/next/general/viewing-collaboration/billboards-guide"},"next":{"title":"Multiuser (VFT)","permalink":"/docs/next/general/viewing-collaboration/multiuser-vft"}}');var r=n(74848),s=n(28453);const o={id:"flight-path-user-guide",title:"Flight Path User Guide",sidebar_label:"Flight Paths",description:"Author cinematic camera fly-throughs of your outcrop in VRGS \u2014 mark points of interest and let VRGS generate the path, or capture viewpoints by hand, then fine-tune timing on the timeline editor, choreograph scene visibility, add spoken narration, and record a movie.",keywords:["flight path","camera animation","fly-through","movie","timeline","keyframe","viewpoint","point of interest","POI","auto generate","orbit","traverse","clearance","presentation","motion blur","narration","guided tour","virtual field trip","audio"],sidebar_position:3},a=void 0,h={},l=[{value:"Watch it done",id:"watch-it-done",level:2},{value:"Concepts",id:"concepts",level:2},{value:"Creating a flight path",id:"creating-a-flight-path",level:2},{value:"Two ways to get those viewpoints",id:"two-ways-to-get-those-viewpoints",level:3},{value:"Capturing viewpoints",id:"capturing-viewpoints",level:2},{value:"Viewpoint properties",id:"viewpoint-properties",level:3},{value:"Points of interest",id:"points-of-interest",level:2},{value:"Placing points of interest",id:"placing-points-of-interest",level:3},{value:"What each point tells the camera to do",id:"what-each-point-tells-the-camera-to-do",level:3},{value:"Point of interest properties",id:"point-of-interest-properties",level:3},{value:"Auto Generate",id:"auto-generate",level:2},{value:"Settings",id:"settings",level:3},{value:"Patterns",id:"patterns",level:3},{value:"Keeping the camera out of the rock",id:"keeping-the-camera-out-of-the-rock",level:3},{value:"Pressing Generate with nothing placed",id:"pressing-generate-with-nothing-placed",level:3},{value:"Building the path",id:"building-the-path",level:2},{value:"Interpolation method",id:"interpolation-method",level:3},{value:"Ease in and out",id:"ease-in-and-out",level:3},{value:"Smoothing",id:"smoothing",level:3},{value:"Check path clearance",id:"check-path-clearance",level:3},{value:"Playing back",id:"playing-back",level:2},{value:"Playback runs to the clock",id:"playback-runs-to-the-clock",level:3},{value:"Pause and look around",id:"pause-and-look-around",level:3},{value:"The timeline editor",id:"the-timeline-editor",level:2},{value:"Tracks",id:"tracks",level:3},{value:"Working in the timeline",id:"working-in-the-timeline",level:3},{value:"Timing and duration",id:"timing-and-duration",level:2},{value:"Pacing the camera",id:"pacing-the-camera",level:3},{value:"Reordering keyframes",id:"reordering-keyframes",level:3},{value:"Holding on a viewpoint",id:"holding-on-a-viewpoint",level:3},{value:"Scenes: visibility choreography",id:"scenes-visibility-choreography",level:2}
1,{value:"What a scene captures",id:"what-a-scene-captures",level:3},{value:"Editing scene timing on the timeline",id:"editing-scene-timing-on-the-timeline",level:3},{value:"Narration: guided tours",id:"narration-guided-tours",level:2},{value:"Adding narration",id:"adding-narration",level:3},{value:"How narration and the camera stay together",id:"how-narration-and-the-camera-stay-together",level:3},{value:"Timing narration",id:"timing-narration",level:3},{value:"Pinning commentary to a keyframe",id:"pinning-commentary-to-a-keyframe",level:4},{value:"On-screen captions",id:"on-screen-captions",level:4},{value:"Managing clips",id:"managing-clips",level:3},{value:"Stop and talk",id:"stop-and-talk",level:3},{value:"Playing a tour to a field trip",id:"playing-a-tour-to-a-field-trip",level:3},{value:"Presentation mode and slides",id:"presentation-mode-and-slides",level:2},{value:"Video and audio in the scene",id:"video-and-audio-in-the-scene",level:3},{value:"Motion blur",id:"motion-blur",level:2},{value:"Recording a movie",id:"recording-a-movie",level:2},{value:"Narration in the recorded movie",id:"narration-in-the-recorded-movie",level:3},{value:"Exporting",id:"exporting",level:2},{value:"Tips and troubleshooting",id:"tips-and-troubleshooting",level:2},{value:"See also",id:"see-also",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(t.p,{children:["A ",(0,r.jsx)(t.strong,{children:"flight path"})," is an animated camera fly-through of your scene. Mark the places you want to show \u2014 ",(0,r.jsx)(t.strong,{children:"points of interest"})," \u2014 and VRGS works out the camera positions for you; or capture each ",(0,r.jsx)(t.strong,{children:"viewpoint"})," (keyframe) by hand from the 3D view. Either way VRGS interpolates a smooth camera path between the keyframes, and you can then play it back, fine-tune the timing on a dedicated ",(0,r.jsx)(t.strong,{children:"timeline editor"}),", choreograph which objects are visible at each moment, add ",(0,r.jsx)(t.strong,{children:"spoken narration"}),", and record the result to a movie. Flight paths are ideal for presentations, virtual field trips, and rendering polished fly-over videos of an outcrop."]}),"\n",(0,r.jsx)(t.admonition,{title:"Works in both renderers",type:"info",children:(0,r.jsxs)(t.p,{children:["Flight paths run in both the ",(0,r.jsx)(t.strong,{children:"OpenGL"})," and ",(0,r.jsx)(t.strong,{children:"Vulkan"})," 3D views, but they are no longer equal. ",(0,r.jsx)(t.strong,{children:"Vulkan-only:"})," narration, guided tours, pause-and-look-around, the timeline transport strip, the ",(0,r.jsx)(t.strong,{children:"playback speed"})," buttons, ",(0,r.jsx)(t.strong,{children:"narration and holds in a recorded movie"}),", ",(0,r.jsx)(t.strong,{children:"Check Path"}),", and the ",(0,r.jsx)(t.strong,{children:"Keep the camera out of the outcrop"})," check inside Auto Generate. Everything else \u2014 capturing viewpoints, ",(0,r.jsx)(t.strong,{children:"placing points of interest"}),", ",(0,r.jsx)(t.strong,{children:"Auto Generate"})," itself, ",(0,r.jsx)(t.strong,{children:"Constant Speed"}),", building and re-timing the path, scenes, gamepad recording, motion blur and movie recording \u2014 works in both. The only thing still exclusive to ",(0,r.jsx)(t.strong,{children:"OpenGL"})," is the ",(0,r.jsx)(t.strong,{children:"presentation-mode controls"})," for stepping a slide deck. Individual features are called out below; if you are authoring guided tours, use the Vulkan renderer."]})}),"\n",(0,r.jsx)(t.h2,{id:"watch-it-done",children:"Watch it done"}),"\n","\n",(0,r.jsx)(t.p,{children:"A short tutorial that builds a narrated fly-through end to end: mark the outcrop\nwith points of interest, generate the path, check it clears the rock, pace it,\nrecord commentary over it, and export the result as an MP4."}),"\n",(0,r.jsxs)(t.p,{children:["For the two-minute version \u2014 just points of interest and Auto Generate \u2014 see the\n",(0,r.jsx)(t.a,{href:"/docs/next/tutorial/quick-tips/qt070-flight-paths",children:"Flight paths from points of interest"}),"\nquick tip."]}),"\n",(0,r.jsx)(t.h2,{id:"concepts",children:"Concepts"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Term"}),(0,r.jsx)(t.th,{children:"Meaning"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Point of interest"})," (POI)"]}),(0,r.jsxs)(t.td,{children:["A place on the ",(0,r.jsx)(t.em,{children:"outcrop"})," you want the tour to show. Unlike a viewpoint it is not a camera pose \u2014 it is the subject, and ",(0,r.jsx)(t.strong,{children:"Auto Generate"})," works out where to put the camera to see it (see ",(0,r.jsx)(t.a,{href:"#points-of-interest",children:"Points of interest"}),")."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Viewpoint"})," (control point / keyframe)"]}),(0,r.jsx)(t.td,{children:"A captured camera pose \u2014 position, orientation (pitch/roll/yaw), zoom and clip plane
1s. These are the keyframes you edit."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Interpolated path"})}),(0,r.jsxs)(t.td,{children:["The dense per-frame camera poses VRGS computes ",(0,r.jsx)(t.em,{children:"between"})," your viewpoints. This is what plays back and records; it is rebuilt automatically whenever you change a viewpoint."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Segment"})}),(0,r.jsxs)(t.td,{children:["The span between two consecutive viewpoints. Each viewpoint stores a ",(0,r.jsx)(t.strong,{children:"frame count"})," that sets how long the segment takes."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Scene"})}),(0,r.jsxs)(t.td,{children:["A saved snapshot of object visibility \u2014 including large geometry such as meshes and point clouds \u2014 that can be triggered along the path, so objects appear or disappear as the camera flies (see ",(0,r.jsx)(t.a,{href:"#scenes-visibility-choreography",children:"Scenes"}),")."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Narration clip"})}),(0,r.jsxs)(t.td,{children:["A piece of recorded or imported audio placed at a point on the path's timeline, so commentary plays as the camera reaches it (see ",(0,r.jsx)(t.a,{href:"#narration-guided-tours",children:"Narration"}),")."]})]})]})]}),"\n",(0,r.jsxs)(t.p,{children:["The camera uses the same ",(0,r.jsx)(t.strong,{children:"drone-style"})," convention as the rest of VRGS: pitch (look up/down), yaw (heading) and roll. Orientation values in the viewpoint properties are shown in ",(0,r.jsx)(t.strong,{children:"radians"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"creating-a-flight-path",children:"Creating a flight path"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["Open the ",(0,r.jsx)(t.strong,{children:"Interpretation"})," tree (the project tree that holds interpretation objects)."]}),"\n",(0,r.jsxs)(t.li,{children:["Right-click the ",(0,r.jsx)(t.strong,{children:"Flight Paths"})," branch and create a ",(0,r.jsx)(t.strong,{children:"new flight path"}),". It appears in the tree with empty ",(0,r.jsx)(t.strong,{children:"Viewpoints"}),", ",(0,r.jsx)(t.strong,{children:"Points of Interest"})," and ",(0,r.jsx)(t.strong,{children:"Scenes"})," sub-branches."]}),"\n",(0,r.jsxs)(t.li,{children:["Select the flight path. The ",(0,r.jsx)(t.strong,{children:"Flight Path"})," contextual tab appears on the ribbon, and the ",(0,r.jsx)(t.strong,{children:"Flight Path Timeline"})," panel auto-opens at the bottom of the window."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["A flight path needs at least ",(0,r.jsx)(t.strong,{children:"two viewpoints"})," before it can be interpolated."]}),"\n",(0,r.jsx)(t.h3,{id:"two-ways-to-get-those-viewpoints",children:"Two ways to get those viewpoints"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{}),(0,r.jsx)(t.th,{children:"How it works"}),(0,r.jsx)(t.th,{children:"Best for"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Mark the subject"})}),(0,r.jsxs)(t.td,{children:["Click the places on the outcrop you want shown, then press ",(0,r.jsx)(t.strong,{children:"Auto Generate"}),". VRGS works out where to stand the camera, which way to face and how long to take. See ",(0,r.jsx)(t.a,{href:"#points-of-interest",children:"Points of interest"}),"."]}),(0,r.jsx)(t.td,{children:"Getting a whole tour in a couple of minutes; orbiting a feature; tracking along a face."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Fly it yourself"})}),(0,r.jsxs)(t.td,{children:["Navigate to each shot and press ",(0,r.jsx)(t.strong,{children:"Add View"}),". See ",(0,r.jsx)(t.a,{href:"#capturing-viewpoints",children:"Capturing viewpoints"}),"."]}),(0,r.jsx)(t.td,{children:"Exact framing you have in mind, and fine-tuning whatever Auto Generate hands back."})]})]})]}),"\n",(0,r.jsx)(t.p,{children:"They are the same object underneath \u2014 generated keyframes are ordinary viewpoints, so you can generate a first pass and then adjust it by hand."}),"\n",(0,r.jsx)(t.h2,{id:"capturing-viewpoints",children:"Capturing viewpoints"}),"\n",(0,r.jsx)(t.p,{children:"Navigate the 3D view to the shot you want, then add a viewpoint:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["On the ",(0,r.jsx)(t.strong,{children:"Flight Path"})," ribbon tab, choose ",(0,r.jsx)(t.strong,{children:"Add Viewpoint"}),". The current camera pose (position, orientation, zoom and near/far clip plane
1s) is captured as a new keyframe and added to the path."]}),"\n",(0,r.jsxs)(t.li,{children:["Repeat for each shot. Viewpoints are listed under the flight path's ",(0,r.jsx)(t.strong,{children:"Viewpoints"})," branch and drawn as small camera glyphs in the 3D view."]}),"\n"]}),"\n",(0,r.jsxs)(t.admonition,{title:"Gamepad recording",type:"tip",children:[(0,r.jsxs)(t.p,{children:["Toggle ",(0,r.jsx)(t.strong,{children:"Record from Gamepad"})," to capture viewpoints automatically as you fly with a gamepad. A new viewpoint is dropped whenever the camera has moved more than a set distance ",(0,r.jsx)(t.strong,{children:"or"})," rotated more than a set angle since the last one. Tune ",(0,r.jsx)(t.strong,{children:"Record Distance (m)"})," and ",(0,r.jsx)(t.strong,{children:"Record Angle (deg)"})," in the flight path's properties under ",(0,r.jsx)(t.strong,{children:"Gamepad Recording"}),"."]}),(0,r.jsxs)(t.p,{children:["In the ",(0,r.jsx)(t.strong,{children:"Vulkan"})," view this rides the gamepad poll, so ",(0,r.jsx)(t.strong,{children:"Game Controller"})," mode has to be on for the camera to be read at all. In ",(0,r.jsx)(t.strong,{children:"OpenGL"})," it runs from that view's own game loop."]})]}),"\n",(0,r.jsx)(t.h3,{id:"viewpoint-properties",children:"Viewpoint properties"}),"\n",(0,r.jsx)(t.p,{children:"Select a viewpoint in the tree to edit it in the properties panel:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Property"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"View Position"})}),(0,r.jsx)(t.td,{children:"The camera's X/Y/Z location."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Direction/Yaw"}),", ",(0,r.jsx)(t.strong,{children:"Angle/Pitch"}),", ",(0,r.jsx)(t.strong,{children:"Rotation/Roll"})]}),(0,r.jsx)(t.td,{children:"Camera orientation, in radians."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Zoom Factor"})}),(0,r.jsx)(t.td,{children:"Lens zoom / field-of-view at this viewpoint."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Frames"})}),(0,r.jsxs)(t.td,{children:["How many frames the segment ",(0,r.jsx)(t.em,{children:"leaving"})," this viewpoint takes \u2014 the primary timing control."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"SmoothStep"})}),(0,r.jsxs)(t.td,{children:["Ease the camera in and out of this viewpoint (see ",(0,r.jsx)(t.a,{href:"#ease-in-and-out",children:"Ease in and out"}),")."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Hold Here"})}),(0,r.jsxs)(t.td,{children:["When ",(0,r.jsx)(t.strong,{children:"recording a movie"}),", stop on this viewpoint for the path's ",(0,r.jsx)(t.strong,{children:"Pause Frames"})," before carrying on (see ",(0,r.jsx)(t.a,{href:"#holding-on-a-viewpoint",children:"Holding on a viewpoint"}),")."]})]})]})]}),"\n",(0,r.jsxs)(t.p,{children:["You can also ",(0,r.jsx)(t.strong,{children:"update"})," a viewpoint to the current camera (right-click it, or use the timeline \u2014 see below), ",(0,r.jsx)(t.strong,{children:"reorder"})," it, ",(0,r.jsx)(t.strong,{children:"split the segment after it"}),", and ",(0,r.jsx)(t.strong,{children:"copy / paste / duplicate"})," viewpoints from the tree context menu (see ",(0,r.jsx)(t.a,{href:"#reordering-keyframes",children:"Reordering keyframes"}),")."]}),"\n",(0,r.jsx)(t.h2,{id:"points-of-interest",children:"Points of interest"}),"\n",(0,r.jsxs)(t.p,{children:["A ",(0,r.jsx)(t.strong,{children:"point of interest"})," marks a place ",(0,r.jsx)(t.em,{children:"on the outcrop"})," \u2014 the thing you want the audience to look at. It is not a camera position: ",(0,r.jsx)(t.strong,{children:"Auto Generate"})," decides where the camera goes, so that the subject is framed, the camera stands off the rock rather than inside it, and the tour visits everything in turn."]}),"\n",(0,r.jsxs)(t.p,{children:["This is the difference that makes the feature worth using on a real outcrop. Standing off a ",(0,r.jsx)(t.em,{children:"bounding box"})," would put the camera inside a re-entrant or swing it between opposite faces; VRGS instead fits a plane through your points to get the overall orientation of the face, bends the standoff towards each point's own ",(0,r.jsx)(t.strong,{children:"surface normal"})," so the camera follows bays and noses, and then checks the line of sight against the real geometry."]}),"\n",(0,r.jsx)(t.h3,{id:"placing-points-of-interest",children:"Placing points of interest"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["Select the flight path so it is ",(0,r.jsx)(t.strong,{children:"active"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["On the ",(0,r.jsx)(t.strong,{children:"Flight Path"})," ribbon tab, choose ",(0,r.jsx)(t.strong,{children:"Add POI"}),". The cursor arms for placement."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Click the outcrop"})," wherever you want the tour to stop. Each click drops a point, so you can place a whole set without re-arming."]}),"\n",(0,r.jsxs)(t.li,{children:["Press ",(0,r.jsx)(t.strong,{children:"Esc"})," to put the tool away."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Points appear under the flight path's ",(0,r.jsx)(t.strong,{children:"Points of Interest"})," branch in the Interpretation tree, and are drawn on the outcrop with a glyph that shows what each one does \u2014 so a glance tells you which will be orbited and which merely looked at. They are drawn whether or not the path has been generated yet."]}),"\n",(0,r.jsx)(t.admonition,{title:"Move one without re-placing it",type:"tip",children:(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.strong,{children:"Reposition"})," tool drags a point of interest exactly as it drags a waypoint or sample point. Delete or rename one from its right-click menu in the tree."]})}),"\n",(0,r.jsx)(t.admonition,{title:"The surface normal is recorded at the click",type:"note",children:(0,r.jsxs)(t.p,{children:["VRGS stores the orientation of the surface you clicked, and that is what lets the camera follow the shape of the face. A point placed where no triangle was available \u2014 on a bare point cloud, or in a project made before this feature \u2014 has no normal recorded, and simply falls back to the overall face direction. The ",(0,r.jsx)(t.strong,{children:"Surface \u2192 Normal"})," row in the properties shows it when there is one."]})}),"\n",(0,r.jsx)(t.h3,{id:"what-each-point-tells-the-camera-to-do",children:"What each point tells the camera to do"}),"\n",(0,r.jsxs)(t.p,{children:["Set ",(0,r.jsx)(t.strong,{children:"Type"})," in a point's properties:"]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"What the camera does"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Look At"})}),(0,r.jsx)(t.td,{children:"Stands off the point and faces it. The default, and the right answer for most stops."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Rotate Aroun
1d"})}),(0,r.jsx)(t.td,{children:"Circles the point, facing inwards the whole way \u2014 a turntable of a single feature."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Traverse Anchor"})}),(0,r.jsx)(t.td,{children:"Shapes a face-on traverse without getting a stop of its own: it steers the line the camera tracks along, but no viewpoint is generated at it."})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"point-of-interest-properties",children:"Point of interest properties"}),"\n",(0,r.jsxs)(t.p,{children:["Select a point in the tree to edit it. Every ",(0,r.jsx)(t.strong,{children:"0 means automatic"})," field falls back to the value in the Auto Generate dialog, and that in turn falls back to a fraction of the scene size \u2014 so a point placed with one click and never edited still generates a sensible camera."]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Property"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Name"})}),(0,r.jsx)(t.td,{children:"Used to label the keyframe the point generates."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Position"})}),(0,r.jsx)(t.td,{children:"Where the point sits, in project units."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Type"})}),(0,r.jsx)(t.td,{children:"Look At, Rotate Around or Traverse Anchor (above)."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Standoff"})}),(0,r.jsxs)(t.td,{children:["How far the camera stands off this point. ",(0,r.jsx)(t.strong,{children:"0 = automatic"})," from the scene size."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Dwell (seconds)"})}),(0,r.jsxs)(t.td,{children:["How long the camera holds here. ",(0,r.jsx)(t.strong,{children:"0 = do not stop."})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Pitch (degrees)"})}),(0,r.jsxs)(t.td,{children:["Downward tilt at this point, positive looking down. Leave at ",(0,r.jsx)(t.strong,{children:"0"})," to use the run's pitch."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Rotate Around \u2192 Radius"})}),(0,r.jsxs)(t.td,{children:["Orbit radius. ",(0,r.jsx)(t.strong,{children:"0 = use the standoff."})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Rotate Around \u2192 Sweep (degrees)"})}),(0,r.jsxs)(t.td,{children:["Arc swept around the point. ",(0,r.jsx)(t.strong,{children:"360"})," is a full turn."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Rotate Around \u2192 Keyframes"})}),(0,r.jsx)(t.td,{children:"How many viewpoints are generated around the arc."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Surface \u2192 Normal"})}),(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.em,{children:"Read-only."})," The orientation of the surface at the click (above)."]})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"auto-generate",children:"Auto Generate"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Auto Generate"})," on the ",(0,r.jsx)(t.strong,{children:"Flight Path"})," ribbon tab turns the active path's points of interest into its viewpoints. The dialog opens on a line telling you what the run will use \u2014 ",(0,r.jsx)(t.em,{children:'"Generating from 7 points of interest"'})," \u2014 so you never have to guess."]}),"\n",(0,r.jsx)(t.admonition,{title:"It replaces the viewpoints",type:"caution",children:(0,r.jsxs)(t.p,{children:["Auto Generate discards the path's existing keyframes and writes a new set. ",(0,r.jsx)(t.strong,{children:"Ctrl+Z"})," puts them back. If you have hand-tweaked a viewpoint since the last generate, the dialog says so before you commit \u2014 ",(0,r.jsx)(t.em,{children:'"Some viewpoints have been edited since they were generated; those edits will be lost."'}),' That comparison lasts as long as the session: reopen the project and there is nothing left to compare against, so treat the absence of the warning as "no edits seen", not "no edits made".']})}),"\n",(0,r.jsx)(t.h3,{id:"settings",children:"Settings"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Setting"}),(0,r.jsx)(t.th,{children:"What it does"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Pattern"})}),(0,r.jsx)(t.td,{children:"The overall shape of the tour \u2014 see below."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Standoff"})}),(0,r.jsxs)(t.td,{children:["Default camera distance from a point, for points that do not set the
1ir own. ",(0,r.jsx)(t.strong,{children:"0 = work it out from the scene size."})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Pitch"})}),(0,r.jsx)(t.td,{children:"Default downward tilt in degrees, positive looking down. Range \u221289 to 89."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Seconds per keyframe"})}),(0,r.jsx)(t.td,{children:"How long each generated segment takes, which is what sets the tour's overall length."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Surface blend"})}),(0,r.jsxs)(t.td,{children:["How far each point's own surface normal pulls the camera away from the overall face direction. ",(0,r.jsx)(t.strong,{children:"0"})," holds a rigid line across the whole face; ",(0,r.jsx)(t.strong,{children:"1"})," follows every local bend. The default ",(0,r.jsx)(t.strong,{children:"0.5"})," suits most outcrops."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Close the loop"})}),(0,r.jsx)(t.td,{children:"Return from the last point to the first, for a path that can play round and round."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Add an establishing shot"})}),(0,r.jsx)(t.td,{children:"Open on a wide view of the whole subject before the tour proper begins."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Keep the camera out of the outcrop"})}),(0,r.jsx)(t.td,{children:"Ray-cast each candidate camera position against the real geometry and move it when the rock is in the way."})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"patterns",children:"Patterns"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Pattern"}),(0,r.jsx)(t.th,{children:"Shape"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Waypoint tour"})}),(0,r.jsxs)(t.td,{children:["Visit each point in turn. Points set to ",(0,r.jsx)(t.strong,{children:"Rotate Around"})," still orbit as they are reached. The general-purpose choice."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Orbit every point"})}),(0,r.jsx)(t.td,{children:"Orbit every point regardless of its type \u2014 a survey of several features in turn."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Face-on traverse"})}),(0,r.jsxs)(t.td,{children:["Track along the face at a constant standoff, holding the outcrop side-on. This is where ",(0,r.jsx)(t.strong,{children:"Traverse Anchor"})," points earn their keep."]})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"keeping-the-camera-out-of-the-rock",children:"Keeping the camera out of the rock"}),"\n",(0,r.jsxs)(t.p,{children:["With ",(0,r.jsx)(t.strong,{children:"Keep the camera out of the outcrop"})," ticked, each candidate camera position is tested against the real geometry. When something is in the way, VRGS searches ",(0,r.jsx)(t.strong,{children:"around"})," the obstruction \u2014 sweeping sideways first, then looking over it \u2014 rather than simply backing further off, because retreating along the same line keeps a shoulder of rock exactly where it was."]}),"\n",(0,r.jsx)(t.admonition,{title:"Vulkan only",type:"note",children:(0,r.jsxs)(t.p,{children:["The line-of-sight check needs the ",(0,r.jsx)(t.strong,{children:"Vulkan"})," renderer. In an OpenGL view generation still runs and still produces a path, but the check is skipped and a warning is written to the messages panel \u2014 the tick box cannot do anything there. Either way, run ",(0,r.jsx)(t.a,{href:"#check-path-clearance",children:(0,r.jsx)(t.strong,{children:"Check Path"})})," afterwards: proving each ",(0,r.jsx)(t.em,{children:"keyframe"})," is clear does not prove the curve ",(0,r.jsx)(t.em,{children:"between"})," them is."]})}),"\n",(0,r.jsx)(t.h3,{id:"pressing-generate-with-nothing-placed",children:"Pressing Generate with nothing placed"}),"\n",(0,r.jsxs)(t.p,{children:["You get a path anyway. With no points of interest on it, VRGS lays out stand-ins from the ",(0,r.jsx)(t.strong,{children:"scene's own extent"})," and generates a serviceable establishing sweep of the whole model \u2014 spaced ",(0,r.jsx)(t.em,{children:"across"})," your view rather than along it, so the camera tracks past the outcrop instead of driving at it. An ",(0,r.jsx)(t.strong,{children:"Orbit every point"})," run instead gets a single turntable of the whole model."]}),"\n",(0,r.jsx)(t.p,{children:"The dialog says which of the two you are getting. It is a reasonable first look at a new project; for a path that actually follows the outcrop, place some points first."}),"\n",(0,r.jsx)(t.h2,{id:"building-the-path",children:"Building the path"}),"\n",(0,r.jsx)(t.p,{children:"Once you have two or more viewpoints, build the interpolated path from the ribbon:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Create Path"})," \u2014 an open path from the first viewpoint to the last."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Create Closed Path"})," \u2014 a loop that returns from the last viewpoint back to the first."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"interpolation-method",children:"Interpolation method"}),"\n",(0,r.jsxs)(t.p,{children:["The method is set in the flight path properties. ",(0,r.jsx)(t.strong,{children:"Smooth"})," (the default) is recommended for camera work:"]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Method"}),(0,r.jsx)(t.th,{children:"Behaviour"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Smooth"})}),(0,r.jsx)(t.td,{children:"A time-aware spline with continuous velocity and rotation across every keyframe. Best general-purpose choice; produces natural, glide-free motion."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Linear"})}),(0,r.jsx)(t.td,{children:"Straight-line constant-velocity segments."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Cosine"})}
1),(0,r.jsx)(t.td,{children:"Eased segments (slow in/out)."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Cubic"})," / ",(0,r.jsx)(t.strong,{children:"CatmullRom"})]}),(0,r.jsx)(t.td,{children:"Classic interpolating splines through the viewpoints."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Hermite"})}),(0,r.jsxs)(t.td,{children:["Spline with adjustable ",(0,r.jsx)(t.strong,{children:"Tension"})," and ",(0,r.jsx)(t.strong,{children:"Bias"})," (set in the properties) for tighter or looser curves."]})]})]})]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsx)(t.p,{children:"Orientation is always interpolated through quaternions, so the camera takes the shortest rotational path and never flips, even between widely separated headings."})}),"\n",(0,r.jsx)(t.h3,{id:"ease-in-and-out",children:"Ease in and out"}),"\n",(0,r.jsxs)(t.p,{children:["Tick ",(0,r.jsx)(t.strong,{children:"SmoothStep"})," on a viewpoint and the camera ",(0,r.jsx)(t.strong,{children:"eases out of it"})," as it leaves and ",(0,r.jsx)(t.strong,{children:"eases in to it"})," as it arrives \u2014 starting and stopping gently instead of at full speed. It is the natural finish for the first and last keyframes of a path, and for a viewpoint the tour dwells on."]}),"\n",(0,r.jsxs)(t.p,{children:["Easing changes only the ",(0,r.jsx)(t.em,{children:"rate"})," along the curve, never the curve itself, so it can never move a keyframe or bend the path. An un-eased keyframe keeps full speed, which is what lets an eased segment sit next to a plain one without jerking."]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["This is a deliberate change of speed, so a segment with one eased end and one plain end does not hold a constant velocity across the join \u2014 that ",(0,r.jsx)(t.em,{children:"is"})," what easing means. If you want even motion instead, use ",(0,r.jsx)(t.a,{href:"#pacing-the-camera",children:(0,r.jsx)(t.strong,{children:"Constant Speed"})}),"."]})}),"\n",(0,r.jsx)(t.h3,{id:"smoothing",children:"Smoothing"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.strong,{children:"Smooth Path"})," command runs an additional smoothing filter over the interpolated frames, damping out any residual jitter. The number of passes is set by ",(0,r.jsx)(t.strong,{children:"Smooth Iterations"})," in the properties."]}),"\n",(0,r.jsx)(t.h3,{id:"check-path-clearance",children:"Check path clearance"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Check Path"})," on the ribbon walks the whole flight and reports every stretch where the camera passes through the outcrop, or too close to it."]}),"\n",(0,r.jsxs)(t.p,{children:["This catches what Auto Generate cannot. Generation proves each ",(0,r.jsx)(t.strong,{children:"keyframe"})," stands clear of its subject; the path then runs a ",(0,r.jsx)(t.em,{children:"spline"})," between them, and on a concave face that curve will happily bulge through a nose or a buttress with both of its endpoints in open air. That is exactly the shape points of interest exist to describe, so it is exactly the case that bites \u2014 and hand-built paths have never had it checked at all."]}),"\n",(0,r.jsx)(t.p,{children:"What happens when you run it:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"VRGS walks the interpolated frames and groups consecutive bad ones into a single problem area, so one dive through a buttress reads as one problem rather than two hundred."}),"\n",(0,r.jsxs)(t.li,{children:["It reports what it found \u2014 how many places, over how many frames, how deep the worst incursion is, ",(0,r.jsx)(t.strong,{children:"and how many frames it actually examined"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["It ",(0,r.jsx)(t.strong,{children:"jumps the camera to the first problem"})," so you can see it before anything is changed."]}),"\n",(0,r.jsxs)(t.li,{children:["It then offers to ",(0,r.jsx)(t.strong,{children:"nudge the surrounding viewpoints clear"}),". Both keyframes bracketing a problem move, because the bulge belongs to the segment rather than to either end."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The nudge is a single ",(0,r.jsx)(t.strong,{children:"und
1o"})," step. One pass does not always resolve a deep pocket, so run ",(0,r.jsx)(t.strong,{children:"Check Path"})," again to confirm \u2014 the dialog says as much when it finishes."]}),"\n",(0,r.jsx)(t.admonition,{title:"Vulkan only, and it needs the outcrop loaded",type:"note",children:(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Check Path"})," requires the ",(0,r.jsx)(t.strong,{children:"Vulkan"})," renderer, a project with a computed extent, and loaded meshes to check against \u2014 it says which is missing rather than reporting a clean bill of health it has not earned. On a long path it samples every ",(0,r.jsx)(t.em,{children:"N"}),"th frame so a 20,000-frame movie does not take a minute to check, which is why the ",(0,r.jsx)(t.strong,{children:"number of frames checked"})," is reported: a stride can miss a very brief dive."]})}),"\n",(0,r.jsx)(t.p,{children:"If nothing can be moved automatically \u2014 the camera is buried too evenly for a way out to be worked out \u2014 move the viewpoints by hand, or place the points of interest further from the face and generate again."}),"\n",(0,r.jsx)(t.h2,{id:"playing-back",children:"Playing back"}),"\n",(0,r.jsxs)(t.p,{children:["Use the player on the ",(0,r.jsx)(t.strong,{children:"Flight Path"})," ribbon tab, or right-click the flight path in the tree and choose ",(0,r.jsx)(t.strong,{children:"Play"}),":"]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Control"}),(0,r.jsx)(t.th,{children:"Action"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Play"})}),(0,r.jsxs)(t.td,{children:["Start playback. The same button becomes ",(0,r.jsx)(t.strong,{children:"Pause"})," while playing, ",(0,r.jsx)(t.strong,{children:"Resume"})," while paused, and ",(0,r.jsx)(t.strong,{children:"Continue"})," while the tour is held at a stop-and-talk marker."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Esc"})}),(0,r.jsx)(t.td,{children:"Stop the tour and hand the camera back."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Start"})}),(0,r.jsx)(t.td,{children:"Jump to the first frame."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"End"})}),(0,r.jsx)(t.td,{children:"Jump to the last frame."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Step Forward / Back"})}),(0,r.jsx)(t.td,{children:"Advance or rewind one frame. A running tour pauses first, so stepping never fights the clock."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Stop"})}),(0,r.jsxs)(t.td,{children:["End the tour outright and keep the camera where the path left it. On the timeline's transport strip; ",(0,r.jsx)(t.strong,{children:"Esc"})," does the same."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"0.25x / 0.5x / 1x / 2x / 4x"})}),(0,r.jsxs)(t.td,{children:["Play the tour faster or slower than it was authored, without re-timing it. The buttons behave as a group, so exactly one rate is selected. ",(0,r.jsx)(t.strong,{children:"Vulkan only."})]})]})]})]}),"\n",(0,r.jsx)(t.admonition,{title:"Speed is for watching, not for authoring",type:"tip",children:(0,r.jsxs)(t.p,{children:["The speed buttons change only the rate of ",(0,r.jsx)(t.em,{children:"this"})," playback \u2014 nothing is written to the path, and the recorded movie is unaffected. Use ",(0,r.jsx)(t.strong,{children:"4x"})," to skim a long tour while you work on it, and ",(0,r.jsx)(t.strong,{children:"0.25x"})," to inspect a fast move. To change how long the tour actually runs, re-time it (see ",(0,r.jsx)(t.a,{href:"#timing-and-duration",children:"Timing and duration"}),")."]})}),"\n",(0,r.jsxs)(t.p,{children:["The same controls sit on a ",(0,r.jsx)(t.strong,{children:"transport strip along the top of the Flight Path Timeline"})," panel, with a running readout of the tour's position and total length. The readout is also where the tour tells you what it is doing \u2014 ",(0,r.jsx)(t.em,{children:"Paused"}),", ",(0,r.jsx)(t.em,{children:"Recording"}),", ",(0,r.jsx)(t.em,{children:"Stopped to talk \u2014 press Continue"})," \u2014 so you do not have to work it out from the buttons."]}),"\n",(0,r.jsxs)(t.p,{children:["Clicking in the 3D view ",(0,r.jsx)(t.strong,{children:"while the tour is playing"})," takes the camera back and ends the tour \u2014 useful when you want to break out and look at something. While the tour is ",(0,r.jsx)(t.strong,{children:"paused"}),", clicking navigates normally instead (see below)."]}),"\n",(0,r.jsx)(t.h3,{id:"playback-runs-to-the-clock",children:"Playback runs to the clock"}),"\n",(0,r.jsxs)(t.p,{children:["A path plays at its real duration, measured against the ",(0,r.jsx)(t.strong,{children:"project frame rate"})," \u2014 not at whatever speed the display happens to manage. On a heavy scene the picture skips frames and stays on time rather than sliding into slow motion, so a 60-second path takes 60 seconds on every machine. This is what lets narration stay in step with the picture, and what makes a preview a truthful rehearsal of the recorded movie."]}),"\n",(0,r.jsx)(t.h3,{id:"pause-and-look-around",children:"Pause and look around"}),"\n",(0,r.jsx)(t.p,{children:"Pausing is not the same as stopping: the tour stays open at its current position and the camera is handed back to you."}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["Press ",(0,r.jsx)(t.strong,{children:"Pause"})," (or the Play button, which becomes Pause during playback)."]}),"\n",(0,r.jsxs)(t.li,{children:["Navigate freely \u2014 orbit, zoom, pan, fly with ",(0,r.jsx)(t.strong,{children:"W A S D Q E"}),". The pivot is re-anchored on whatever you were looking at when you paused, so the first drag behaves the way it does anywhere else in VRGS."]}),"\n",(0,r.jsxs)(t.li,{children:["Press ",(0,r.jsx)(t.strong,{children:"Resume"}),". If you moved the camera, it eases smoothly back onto the path over about half a second rather than snapping, then playback continues from exactly where it stopped."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Press ",(0,r.jsx)(t.strong,{children:"Esc"})," at any point to abandon the tour and keep the camera where it is."]}
1),"\n",(0,r.jsx)(t.admonition,{title:"Stopping to discuss is the point",type:"tip",children:(0,r.jsx)(t.p,{children:"This is the core teaching interaction: fly to an outcrop, pause, talk about what is on screen while your audience looks around, then carry on. Scrubbing the timeline while paused works too \u2014 resume picks up from wherever you left the playhead."})}),"\n",(0,r.jsx)(t.admonition,{title:"Vulkan only",type:"note",children:(0,r.jsx)(t.p,{children:"Pause-and-look-around requires the Vulkan renderer. In the OpenGL view the Play button still stops rather than pauses."})}),"\n",(0,r.jsx)(t.h2,{id:"the-timeline-editor",children:"The timeline editor"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.strong,{children:"Flight Path Timeline"})," panel is the heart of flight-path editing. It shows the path as stacked time-vs-value tracks with a keyframe strip and a time axis along the bottom. It opens automatically when a flight path is active."]}),"\n",(0,r.jsx)(t.h3,{id:"tracks",children:"Tracks"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Track"}),(0,r.jsx)(t.th,{children:"Shows"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Speed"})}),(0,r.jsx)(t.td,{children:"Camera speed per frame (always shown). Spikes and dips reveal where the camera rushes or stalls."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Acceleration"})}),(0,r.jsx)(t.td,{children:"Change in speed \u2014 where the camera is speeding up (above the line) or slowing down (below). Toggle via right-click."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Orientation"})}),(0,r.jsx)(t.td,{children:"Pitch, roll and yaw curves. Toggle via right-click."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Scenes"})}),(0,r.jsxs)(t.td,{children:["One coloured bar per scene, showing when each is active (see ",(0,r.jsx)(t.a,{href:"#scenes-visibility-choreography",children:"Scenes"}),"). Shown when the path has scenes."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Narration"})}),(0,r.jsxs)(t.td,{children:["One bar per narration clip, spanning the time it plays, with its waveform and caption drawn inside it (see ",(0,r.jsx)(t.a,{href:"#narration-guided-tours",children:"Narration"}),"). A stop-and-talk clip is an orange ",(0,r.jsx)(t.strong,{children:"pin"})," instead, because it occupies no time. Shown when the path has narration."]})]})]})]}),"\n",(0,r.jsxs)(t.p,{children:["The left axis shows raw values; the right axis shows them in intuitive units (degrees for orientation, per-second for speed/acceleration) at the project frame rate. The bottom axis reads out ",(0,r.jsx)(t.strong,{children:"time in seconds"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"working-in-the-timeline",children:"Working in the timeline"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Interaction"}),(0,r.jsx)(t.th,{children:"Result"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Click"})," in the timeline area"]}),(0,r.jsxs)(t.td,{children:["Move the ",(0,r.jsx)(t.strong,{children:"playhead"})," to that frame and snap the camera there (scrubbing)."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Drag"})," in the timeline area"]}),(0,r.jsx)(t.td,{children:"Scrub continuously \u2014 the 3D view follows the playhead."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Click"})," a keyframe tick (bottom strip)"]}),(0,r.jsx)(t.td,{children:"Select it and snap the camera to that viewpoint."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Drag"})," a keyframe tick left/right"]}),(0,r.jsxs)(t.td,{children:["Change that segment's ",(0,r.jsx)(t.strong,{children:"duration"})," (its frame count). The path rebuilds live."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Mouse wheel"})}),(0,r.jsx)(t.td,{children:"Zoom the time axis, anchored under the cursor. Use the scrollbar to pan when zoomed in."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Drag a track boundary"})}),(0,r.jsx)(t.td,{children:"Resize the tracks to give a curve more room."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Right-click"})," the keyframe strip"]}),(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Add"}),", ",(0,r.jsx)(t.strong,{children:"Update from 3D view"}),", or ",(0,r.jsx)(t.strong,{children:"Delete"})," a keyframe at that point."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Right-click"})," a track"]}),(0,r.jsxs)(t.td,{children:["Toggle the Acceleration, Orientation, Scenes and Narration tracks, set the project frame rate, or add narration at that time. As the leader of a live field trip, also ",(0,r.jsx)(t.strong,{children:"share the path as a guided tour"}),"."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Drag"})," a narration clip"]}),(0,r.jsxs)(t.td,{children:["Move it to a different time. A clip ",(0,r.jsx)(t.strong,{children:"pinned"})," to a keyframe snaps from keyframe to keyframe instead, and stays pinned where it lands."]})]})]})]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["Right-clicking an empty part of the keyframe strip lets you ",(0,r.jsx)(t.strong,{children:"add a keyframe at that exact time"})," (capturing the current camera), and right-clicking an existing keyframe lets you ",(0,r.jsx)(t.strong,{children:"update it to the live camera"})," without leaving the timeline. The path, the 3D view and the tree all stay in sync."]})}),"\n",(0,r.jsxs)(t.p,{children:["Every timeline edit is a single ",(0,r.jsx)(t.strong,{children:"und
1o"})," step \u2014 press ",(0,r.jsx)(t.strong,{children:"Ctrl+Z"})," to revert a drag, add, delete or scene change."]}),"\n",(0,r.jsx)(t.h2,{id:"timing-and-duration",children:"Timing and duration"}),"\n",(0,r.jsxs)(t.p,{children:["A path's length is the sum of its per-segment ",(0,r.jsx)(t.strong,{children:"frame counts"}),", converted to seconds at the ",(0,r.jsx)(t.strong,{children:"project frame rate"})," (set in the project / display options). Several tree commands help you set timing in bulk:"]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Command"}),(0,r.jsx)(t.th,{children:"Effect"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Set Frames"})}),(0,r.jsx)(t.td,{children:"Set the frame count on the selected viewpoint(s)."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Set Frames per Metre"})}),(0,r.jsx)(t.td,{children:"Set frame counts proportional to each segment's length, for constant ground speed."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Set Duration"})}),(0,r.jsx)(t.td,{children:"Scale the whole path to a target total duration in seconds."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Set Duration (Selected)"})}),(0,r.jsx)(t.td,{children:"Distribute a duration across the selected viewpoints."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Scale Duration"})}),(0,r.jsx)(t.td,{children:"Multiply all frame counts by a factor to speed up or slow down the whole path."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Constant Speed"})}),(0,r.jsxs)(t.td,{children:["Re-pace the whole path so the camera covers the same distance every frame, ",(0,r.jsx)(t.strong,{children:"without changing the total duration"})," (see below)."]})]})]})]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["Durations are computed using the ",(0,r.jsx)(t.strong,{children:"project frame rate"}
1),", so a 60-second path really is 60 seconds in the recorded movie. Make sure the project frame rate matches your intended output."]})}),"\n",(0,r.jsx)(t.h3,{id:"pacing-the-camera",children:"Pacing the camera"}),"\n",(0,r.jsxs)(t.p,{children:["The path is timed in ",(0,r.jsx)(t.strong,{children:"frames"}),", so a segment's real speed is its length divided by its frame count. Two keyframes 5 m apart and the next pair 500 m apart with the same frame count means the camera crawls, then rockets \u2014 the single most common reason a fly-through looks wrong."]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Constant Speed"})," on the ",(0,r.jsx)(t.strong,{children:"Flight Path"})," ribbon tab fixes this in one press. It measures the ",(0,r.jsx)(t.strong,{children:"actual arc length"})," the camera flies along the interpolated path, then redistributes the path's existing frame budget in proportion to it."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The total duration does not change"}),", so a ",(0,r.jsx)(t.strong,{children:"Set Duration"})," you have already applied still holds, and narration timed against the path stays where you put it."]}),"\n",(0,r.jsxs)(t.li,{children:["It measures the curve that actually plays. ",(0,r.jsx)(t.strong,{children:"Set Frames per Metre"})," works from the straight-line distance between control points, which understates a curved segment badly on a tight turn \u2014 Constant Speed does not."]}),"\n",(0,r.jsxs)(t.li,{children:["Works in ",(0,r.jsx)(t.strong,{children:"both"})," renderers."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Check the result on the timeline's ",(0,r.jsx)(t.strong,{children:"Speed"})," track: after a Constant Speed pass it should read close to flat."]}),"\n",(0,r.jsx)(t.admonition,{title:"Pace first, then ease",type:"tip",children:(0,r.jsxs)(t.p,{children:["Run ",(0,r.jsx)(t.strong,{children:"Constant Speed"})," to get the body of the tour even, then tick ",(0,r.jsx)(t.a,{href:"#ease-in-and-out",children:(0,r.jsx)(t.strong,{children:"SmoothStep"})})," on the first and last keyframes so it still starts and stops gently."]})}),"\n",(0,r.jsx)(t.h3,{id:"reordering-keyframes",children:"Reordering keyframes"}),"\n",(0,r.jsxs)(t.p,{children:["Order matters most immediately after ",(0,r.jsx)(t.strong,{children:"Auto Generate"}),", which is exactly when it is a guess. Right-click a viewpoint in the tree and use the ",(0,r.jsx)(t.strong,{children:"Order"})," submenu:"]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Command"}),(0,r.jsx)(t.th,{children:"Effect"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Move Up"})}),(0,r.jsxs)(t.td,{children:["Move this viewpoint ",(0,r.jsx)(t.strong,{children:"earlier"})," in the flight. It carries its own frame count with it, so its timing follows it."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Move Down"})}),(0,r.jsxs)(t.td,{children:["Move it ",(0,r.jsx)(t.strong,{children:"later"}),", on the same terms."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Insert Viewpoint After"})}),(0,r.jsxs)(t.td,{children:["Add a new keyframe ",(0,r.jsx)(t.strong,{children:"midway to the next one"}),", to shape a corner."]})]})]})]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Reverse Path"}),", on the flight path's own right-click menu, flies the whole tour in the opposite direction."]}),"\n",(0,r.jsx)(t.admonition,{title:"Timing is preserved, not just the order",type:"note",children:(0,r.jsxs)(t.p,{children:["A frame count belongs to the ",(0,r.jsx)(t.em,{children:"segment leaving"})," a keyframe, not to the keyframe itself. Both commands account for that: ",(0,r.jsx)(t.strong,{children:"Insert Viewpoint After"})," splits the segment's frames between the old keyframe and the new one, so shaping a corner does not lengthen the path, and ",(0,r.jsx)(t.strong,{children:"Rever
1se Path"})," re-pairs the durations as well as reversing the order, so the movie keeps its timing instead of every segment inheriting its neighbour's. A reversed midpoint's orientation is interpolated the short way round, so a keyframe between headings of 170\xb0 and \u2212170\xb0 lands on 180\xb0 rather than swinging back through 0\xb0."]})}),"\n",(0,r.jsx)(t.h3,{id:"holding-on-a-viewpoint",children:"Holding on a viewpoint"}),"\n",(0,r.jsxs)(t.p,{children:["Tick ",(0,r.jsx)(t.strong,{children:"Hold Here"})," in a viewpoint's properties and the camera ",(0,r.jsx)(t.strong,{children:"stops on it"})," for the path's ",(0,r.jsx)(t.strong,{children:"Pause Frames"})," (set on the ribbon's Edit panel) before carrying on."]}),"\n",(0,r.jsxs)(t.p,{children:["The hold is applied when you ",(0,r.jsx)(t.strong,{children:"record a movie"}),", where it becomes real frames in the file. It is the simplest way to let a still shot land in a video, and needs no narration clip."]}),"\n",(0,r.jsx)(t.admonition,{title:"Which kind of stop do you want?",type:"tip",children:(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Hold Here"})," is a fixed-length pause built into the recording. A ",(0,r.jsx)(t.a,{href:"#stop-and-talk",children:(0,r.jsx)(t.strong,{children:"stop-and-talk"})})," narration clip instead parks the tour for exactly as long as its commentary lasts, and lets you look around while it plays. A point of interest's ",(0,r.jsx)(t.strong,{children:"Dwell (seconds)"})," sets a hold at generation time. A keyframe with both a hold and a narration stop gets both \u2014 they add up rather than one winning."]})}),"\n",(0,r.jsx)(t.h2,{id:"scenes-visibility-choreography",children:"Scenes: visibility choreography"}),"\n",(0,r.jsxs)(t.p,{children:["Scenes let you change ",(0,r.jsx)(t.em,{children:"what is visible"})," as the camera flies \u2014 for example, revealing an interpretation layer as you approach it, swapping a photorealistic mesh for an interpreted surface, or hiding clutter during a wide shot."]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Set up the object visibility you want in the 3D view."}),"\n",(0,r.jsxs)(t.li,{children:["On the ",(0,r.jsx)(t.strong,{children:"Flight Path"})," ribbon tab, choose ",(0,r.jsx)(t.strong,{children:"Add Scene"}),". The current visibility state is captured as a scene under the flight path's ",(0,r.jsx)(t.strong,{children:"Scenes"})," branch."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"what-a-scene-captures",children:"What a scene captures"}),"\n",(0,r.jsxs)(t.p,{children:["A scene records the on/off state of the objects in the 3D view at the moment you capture it, and restores exactly that set whenever it becomes active. This includes your ",(0,r.jsx)(t.strong,{children:"large geometry"})," \u2014 triangulated ",(0,r.jsx)(t.strong,{children:"meshes"}),", ",(0,r.jsx)(t.strong,{children:"point clouds"}),", ",(0,r.jsx)(t.strong,{children:"tiled meshes"})," and ",(0,r.jsx)(t.strong,{children:"Gaussian splats"})," \u2014 alongside interpretations, annotations, images and the other object types. There is no separate picker: whatever is switched on when you choose ",(0,r.jsx)(t.strong,{children:"Add Scene"})," is what the scene shows."]}),"\n",(0,r.jsx)(t.admonition,{title:"Loaded up front, so nothing pops in",type:"note",children:(0,r.jsxs)(t.p,{children:["Meshes and point clouds are streamed from disk, so when you ",(0,r.jsx)(t.strong,{children:"start playback"})," VRGS loads everything the path's scenes reference ",(0,r.jsx)(t.em,{children:"before"})," the camera moves. For a path that touches large clouds this can take a few seconds and shows a progress dialog \u2014 but it guarantees the data is resident before it is needed. This matters most when you are ",(0,r.jsx)(t.strong,{children:"recording a movie"}),", where a mesh fading in halfway through a shot would ruin the take."]})}),"\n",(0,r.jsx)(t.admonition,{title:"Scenes captured in an earlier version",type:"caution",children:(0,r.jsxs)(t.p,{children:["Earlier versions never switched meshes or point clouds off \u2014 they stayed on regardless of scenes. To keep those projects looking the same, a scene 
1captured before 3.4 leaves your large geometry alone until you ",(0,r.jsx)(t.strong,{children:"re-capture"})," it (right-click the scene \u2192 ",(0,r.jsx)(t.strong,{children:"Update"}),", or ",(0,r.jsx)(t.em,{children:"Update from 3D view"})," on the timeline). Re-recording brings the currently visible meshes and point clouds under that scene's control."]})}),"\n",(0,r.jsx)(t.p,{children:"A scene becomes active in one of two ways:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Spatial trigger (ROI)"})," \u2014 the scene activates whenever the camera comes within the scene's ",(0,r.jsx)(t.strong,{children:"Region of Interest"})," radius of the point where it was captured."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Temporal trigger"})," \u2014 the scene activates over an explicit ",(0,r.jsx)(t.strong,{children:"frame range"})," you set on the timeline."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"editing-scene-timing-on-the-timeline",children:"Editing scene timing on the timeline"}),"\n",(0,r.jsxs)(t.p,{children:["With the ",(0,r.jsx)(t.strong,{children:"Scenes"})," track visible, each scene is a coloured bar:"]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Interaction"}),(0,r.jsx)(t.th,{children:"Result"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Drag"})," a bar's edge"]}),(0,r.jsx)(t.td,{children:"Adjust the scene's start or end frame."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Drag"})," the bar body"]}),(0,r.jsx)(t.td,{children:"Move the whole active range."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Right-click"})," a scene"]}),(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Set start / end from playhead"}),", ",(0,r.jsx)(t.strong,{children:"convert to a spatial (ROI) trigger"}),", or ",(0,r.jsx)(t.strong,{children:"snap the range"})," to wherever the camera enters/leaves the ROI."]})]})]})]}),"\n",(0,r.jsx)(t.admonition,{title:"Triggers stay put when you re-time the path",type:"tip",children:(0,r.jsx)(t.p,{children:"If you drag a keyframe, add/delete a viewpoint, or toggle motion blur \u2014 anything that changes the path's length \u2014 temporal scene triggers are rescaled proportionally, so a scene keeps firing at the same point along the path rather than drifting off."})}),"\n",(0,r.jsx)(t.h2,{id:"narration-guided-tours",children:"Narration: guided tours"}),"\n",(0,r.jsxs)(t.p,{children:["A flight path can carry ",(0,r.jsx)(t.strong,{children:"spoken commentary"}),". Record it against the moving camera, or import audio you prepared elsewhere, and it plays in step with the picture \u2014 turning a fly-through into a self-guided virtual field trip a student can open and watch on their own."]}),"\n",(0,r.jsx)(t.admonition,{title:"Vulkan only",type:"note",children:(0,r.jsxs)(t.p,{children:["Narration requires the ",(0,r.jsx)(t.strong,{children:"Vulkan"})," renderer. Clips authored here are saved with the project either way, but the OpenGL view will not play them."]})}),"\n",(0,r.jsx)(t.h3,{id:"adding-narration",children:"Adding narration"}),"\n",(0,r.jsx)(t.p,{children:"Right-click anywhere on the timeline and choose:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Command"}),(0,r.jsx)(t.th,{children:"What it does"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Record while the tour plays\u2026"})}),(0,r.jsxs)(t.td,{children:["Starts the tour from the time you right-clicked and records as it flies, with ",(0,r.jsx)(t.strong,{children:"nothing covering the 3D view"})," \u2014 so you can describe what you are looking at. Stop with the same menu item, ",(0,r.jsx)(t.strong,{children:"Esc"}),", or by pausing."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Record here (tour paused)\u2026"})}),(0,r.jsxs)(t.td,{children:["Records with the tour parked at that moment. A small dialog shows elapsed time and a level meter; press ",(0,r.jsx)(t.strong,{children:"Cancel"})," to stop. Best for a ",(0,r.jsx)(t.strong,{children:"stop-and-talk"})," clip, where the camera is not moving anyway."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Import audio file\u2026"})}),(0,r.jsxs)(t.td,{children:["Brings in an existing ",(0,r.jsx)(t.strong,{children:"WAV"}),", ",(0,r.jsx)(t.strong,{children:"MP3"}),", ",(0,r.jsx)(t.strong,{children:"M4A"})," or ",(0,r.jsx)(t.strong,{children:"WMA"})," file, placed at the time you right-clicked."]})]})]})]}),"\n",(0,r.jsxs)(t.p,{children:["While recording over live playback the ",(0,r.jsx)(t.strong,{children:"Narration track shows \u25cf REC"}),", the\nelapsed time and a live level meter \u2014 check the level is moving before you commit\nto a long take. Any narration already on the path is muted for the duration, so\nthe microphone does not pick up your earlier commentary through the speakers."]}),"\n",(0,r.jsxs)(t.p,{children:["All three appear on the ",(0,r.jsx)(t.strong,{children:"Narration"})," track once the path has clips, and on the timeline's general right-click menu before that \u2014 the track only appears once there is something to show."]}),"\n",(0,r.jsxs)(t.p,{children:["Recordings are ",(0,r.jsx)(t.strong,{children:"normalised"})," when you stop, so a quiet microphone still gives usable narration. Imported files are left exactly as they are."]}),"\n",(0,r.jsxs)(t.p,{children:["Narration files are ",(0,r.jsx)(t.strong,{children:"copied into the project"}),", into an ",(0,r.jsx)(t.code,{children:"AUDIO"})," folder beside your other project data. A tour whose audio lives on one person's desktop would be silent for everyone else, so VRGS takes its own copy; the project folder is what backups, version control and cloud sync carry."]}),"\n",(0,r.jsx)(t.h3,{id:"how-narration-and-the-camera-stay-together",children:"How narration and the camera stay together"}),"\n",(0,r.jsxs)(t.p,{children:["While a clip is playing, ",(0,r.jsx)(t.strong,{children:"the audio leads and the picture follows"}),". If the display cannot keep up on a heavy scene, the camera skips frames to stay with the voice rather than letting the commentary drift out of step. Between clips the tour carries on at its normal rate, picking up exactly where the audio left off."]}),"\n",(0,r.jsx)(t.p,{children:"The practical consequence: what you hear in preview is what you get in the recorded movie, on any machine."}),"\n",(0,r.jsx)(t.h3,{id:"timing-narration",children:"Timing narration"}),"\n",(0,r.jsxs)(t.p,{children:["Clip positions are stored in ",(0,r.jsx)(t.strong,{children:"seconds"}),", not frames. Anything that rebuilds the interpolated path \u2014 toggling motion blur, changing the project frame rate \u2014 therefore leaves your commentary where you put it, instead of shifting it around."]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Drag a clip along the Narration track"})," to move it. Clips show a waveform, so you can line the start of a phrase up against a keyframe by eye rather than by guesswork. A clip's length comes from its audio file and cannot be trimmed here \u2014 record or edit a shorter take instead."]}),"\n",(0,r.jsx)(t.h4,{id:"pinning-commentary-to-a-keyframe",children:"Pinning commentary to a keyframe"}),"\n",(0,r.jsxs)(t.p,{children:["By default a clip sits at a fixed ",(0,r.jsx)(t.strong,{children:"time"}),". That is fine until you re-time the path \u2014 lengthen the approach to the outcrop, change the frame rate, drag a keyframe \u2014 and every piece of commentary after the change is suddenly describing the wrong thing."]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Pin the clip to its keyframe instead."})," Right-click the clip and choose ",(0,r.jsx)(t.strong,{children:"Pin to nearest keyframe"}),". The clip snaps onto that keyframe and gets a small white ",(0,r.jsx)(t.strong,{children:"tack"})," at its left edge, and from then on it travels with the keyframe: re-time the segment and the commentary moves with it."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Dragging a pinned clip snaps it from keyframe to keyframe and re-pins it where it lands, so it stays pinned."}),"\n",(0,r.jsxs)(t.li,{children:["Right-click and choose ",(0,r.jsxs)(t.strong,{children:["Pinned to keyframe ",(0,r.jsx)(t.em,{children:"N"})," (unpin)"]})," to release it back to a fixed time, where it is now."]}),"\n",(0,r.jsx)(t.li,{children:"If you delete the keyframe a clip is pinned to, the clip stays exactly where it is and quietly becomes unpinned \u2014 it is never moved somewhere you did not put it."}),"\n"]}),"\n",(0,r.jsx)(t.admonition,{title:"Pin the stops",type:"tip",children:(0,r.jsx)(t.p,{children:"Stop-and-talk clips are the ones that most want pinning: the whole point of a stop is that it belongs to a place, not to a moment."})}),"\n",(0,r.jsx)(t.h4,{id:"on-screen-captions",children:"On-screen captions"}),"\n",(0,r.jsx)(t.p,{children:"A clip can carry text that appears over the 3D view while it plays \u2014 a formation name, an age, a question for the group."}),"\n",(0,r.jsxs)(t.p,{children:["Right-click the clip and choose ",(0,r.jsx)(t.strong,{children:"Add on-screen caption\u2026"}),", and type the text. It can run to several lines. The caption appears centred along the bottom of the view while its clip is sounding, wrapped to fit, and disappears when the clip ends. It is also drawn inside the clip's bar on the timeline, so you can see at a glance which take carries which w
1ords."]}),"\n",(0,r.jsx)(t.p,{children:"Leave the box empty to remove a caption."}),"\n",(0,r.jsx)(t.h3,{id:"managing-clips",children:"Managing clips"}),"\n",(0,r.jsxs)(t.p,{children:["Right-click a clip on the ",(0,r.jsx)(t.strong,{children:"Narration"})," track:"]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Command"}),(0,r.jsx)(t.th,{children:"Effect"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Stop and talk"})}),(0,r.jsxs)(t.td,{children:["Turns the clip into a ",(0,r.jsx)(t.strong,{children:"stop"})," \u2014 the tour parks at that point while the commentary plays (see below)."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Wait for Continue"})}),(0,r.jsx)(t.td,{children:"For a stop: wait for you to press Continue instead of moving on when the clip ends."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Pin to nearest keyframe"})}),(0,r.jsxs)(t.td,{children:["Tie the clip to a keyframe so re-timing the path carries it along (see ",(0,r.jsx)(t.a,{href:"#pinning-commentary-to-a-keyframe",children:"above"}),"). Reads ",(0,r.jsxs)(t.strong,{children:["Pinned to keyframe ",(0,r.jsx)(t.em,{children:"N"})," (unpin)"]})," once it is pinned."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Add / Edit on-screen caption\u2026"})}),(0,r.jsx)(t.td,{children:"Text shown over the 3D view while this clip plays."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.strong,{children:"Volume"}),", ",(0,r.jsx)(t.strong,{children:"Fade in"}),", ",(0,r.jsx)(t.strong,{children:"Fade out"})]}),(0,r.jsx)(t.td,{children:"Level for this clip, and how it eases in and out."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"Delete narration clip"})}),(0,r.jsxs)(t.td,{children:["Removes the clip from the path. ",(0,r.jsx)(t.strong,{children:"Ctrl+Z"})," puts it back \u2014 the audio file survives until you next ",(0,r.jsx)(t.strong,{children:"save"}),", at which point a take nothing references is cleaned up."]})]})]})]}),"\n",(0,r.jsxs)(t.p,{children:["Every clip edit \u2014 moving, pinning, captioning, deleting, changing volume or fades \u2014 is a single ",(0,r.jsx)(t.strong,{children:"undo"})," step, so ",(0,r.jsx)(t.strong,{children:"Ctrl+Z"})," puts it back."]}),"\n",(0,r.jsxs)(t.p,{children:["A clip drawn ",(0,r.jsx)(t.strong,{children:"grey"})," has lost its audio file, usually because a project was copied without its ",(0,r.jsx)(t.code,{children:"AUDIO"})," folder. It keeps its place on the timeline so you can see what is missing, but it will not sound; re-import the audio to fix it."]}),"\n",(0,r.jsx)(t.h3,{id:"stop-and-talk",children:"Stop and talk"}),"\n",(0,r.jsxs)(t.p,{children:["Continuous voice-over is rarely what teaching sounds like. The real shape is ",(0,r.jsxs)(t.em,{children:["fly to the outcrop, ",(0,r.jsx)(t.strong,{children:"stop"}),", talk about it, carry on"]})," \u2014 and that is what a ",(0,r.jsx)(t.strong,{children:"stop-and-talk"})," clip does."]}),"\n",(0,r.jsxs)(t.p,{children:["Right-click a clip and choose ",(0,r.jsx)(t.strong,{children:"Stop and talk"}),". It changes from a bar to an ",(0,r.jsx)(t.strong,{children:"orange pin"}),", because a stop occupies no time on the timeline: the tour parks at that point for exactly as long as the commentary lasts, however long that turns out to be."]}),"\n",(0,r.jsx)(t.p,{children:"When the tour reaches the pin:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"The camera stops on that frame and the clip starts playing."}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"You can look around while it plays"})," \u2014 orbit, zoom, fly \u2014 exactly as when paused. The tour is holding its place, not frozen."]}),"\n",(0,r.jsxs)(t.li,{children:["If you leave it alone, the view ",(0,r.jsx)(t.strong,{children:"drifts slowly around the spot"})," rather than sitting dead still, so a long piece of commentary does not look like the application has hung. The moment you touch the camera the drift stops and it is yours."]}),"\n",(0,r.jsx)(t.li,{children:"When the clip finishes, the tour carries on by itself."}),"\n"]}),"\n",(0,r.jsx)(t.admonition,{title:"Re-record freely",type:"tip",children:(0,r.jsx)(t.p,{children:"Because a stop takes no timeline space, replacing its commentary with a longer or shorter take changes nothing else. The path does not need rebuilding and every clip after it stays exactly where you put it \u2014 which is not true of the old approach of padding a path with extra frames."})}),"\n",(0,r.jsx)(t.admonition,{title:"Waiting for you instead",type:"note",children:(0,r.jsxs)(t.p,{children:["A stop can wait for an explicit ",(0,r.jsx)(t.strong,{children:"Continue"})," rather than moving on by itself \u2014 useful when you want to take questions. Right-click the pin and tick ",(0,r.jsx)(t.strong,{children:"Wait for Continue"}),". The Play button becomes ",(0,r.jsx)(t.strong,{children:"Continue"})," while the tour is held."]})}),"\n",(0,r.jsx)(t.h3,{id:"playing-a-tour-to-a-field-trip",children:"Playing a tour to a field trip"}
1),"\n",(0,r.jsxs)(t.p,{children:["A narrated tour can be played to everyone in a ",(0,r.jsx)(t.strong,{children:"Virtual Field Trip"})," at once, with every participant's camera following the leader's."]}),"\n",(0,r.jsxs)(t.p,{children:["Only the ",(0,r.jsx)(t.strong,{children:"transport"})," is shared \u2014 play, pause, position. The narration itself plays from each person's own copy of the project, so nothing is streamed and the audio is as clean for the person on a hotel wifi as for the one next to the server."]}),"\n",(0,r.jsx)(t.admonition,{title:"Everyone needs the project",type:"info",children:(0,r.jsx)(t.p,{children:"Every participant must have the same project open locally. A guest who cannot open the project cannot join a tour \u2014 they would have no outcrop to look at either."})}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.strong,{children:"To lead a tour:"})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["Make sure the project is ",(0,r.jsx)(t.strong,{children:"saved"}),". A flight path only gets the shared identity other clients can resolve when it is saved, and an unsaved path will be refused."]}),"\n",(0,r.jsxs)(t.li,{children:["Right-click anywhere on the timeline and choose ",(0,r.jsx)(t.strong,{children:"Share as a guided tour for the field trip"}),". This appears only when you are the leader of a live trip."]}),"\n",(0,r.jsxs)(t.li,{children:["Everyone's copy of VRGS now loads the tour's geometry. The transport readout counts them in \u2014 ",(0,r.jsx)(t.em,{children:"Waiting for 3 of 9 to load\u2026"})]}),"\n",(0,r.jsxs)(t.li,{children:["When it says ",(0,r.jsx)(t.strong,{children:"Everyone is ready"}),", press ",(0,r.jsx)(t.strong,{children:"Play"}),". The tour starts on every machine at once."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The wait is not optional politeness \u2014 it is what stops three participants freezing mid-flight and then being yanked forward to catch up. If someone is wedged, the readout eventually offers ",(0,r.jsx)(t.strong,{children:"press Play to start anyway"}),", and the tour begins without them."]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"As a participant:"})," the tour simply starts, and your camera follows. Press ",(0,r.jsx)(t.strong,{children:"Play"})," at any point to ",(0,r.jsx)(t.strong,{children:"step out"})," and look around on your own; the tour carries on for everybody else. Your own stops, pauses and captions all behave exactly as they do in a solo tour."]}),"\n",(0,r.jsx)(t.admonition,{title:"Not yet in this release",type:"note",children:(0,r.jsx)(t.p,{children:'There is no roster display of who has stepped out, and no one-click "catch up" to re-join the group where they now are. Rejoin by restarting the tour on your machine.'})}),"\n",(0,r.jsx)(t.admonition,{title:"Movie export",type:"note",children:(0,r.jsxs)(t.p,{children:["A narrated tour ",(0,r.jsx)(t.strong,{children:"can"})," be exported as a video with its commentary \u2014 including its stops, which become real time in the file. See ",(0,r.jsx)(t.a,{href:"#recording-a-movie",children:"Recording a movie"}),". The one thing a video cannot do is ",(0,r.jsx)(t.em,{children:"wait"})," for you, so a stop set to ",(0,r.jsx)(t.strong,{children:"Wait for Continue"})," is held for the length of its clip instead."]})}),"\n",(0,r.jsx)(t.h2,{id:"presentation-mode-and-slides",children:"Presentation mode and slides"}),"\n",(0,r.jsxs)(t.p,{children:["A flight path can carry a ",(0,r.jsx)(t.strong,{children:"slide deck"})," (the ",(0,r.jsx)(t.strong,{children:"Slides"})," branch in the tree). Right-click ",(0,r.jsx)(t.strong,{children:"Slides \u2192 Add image"})," to add images to it, then link individual slides to viewpoints so that the relevant slide is shown as a billboard overlay as the camera reaches each viewpoint. Link either way round: ",(0,r.jsx)(t.strong,{children:"Link To Viewpoint"})," on a slide, or ",(0,r.jsx)(t.strong,{children:"Link To Slide"})," on a viewpoint. Step through viewpoints with ",(0,r.jsx)(t.strong,{children:"Next / Previous Viewpoint"}),", and toggle the overlay with the presentation controls. This is useful for guided, narrated tours."]}),"\n",(0,r.jsx)(t.admonition,{title:"Renderer differences",type:"note",children:(0,r.jsxs)(t.p,{children:["Slide ",(0,r.jsx)(t.strong,{children:"billboards are drawn in both renderers"})," \u2014 a Vulkan view shows the deck, and its multi-image slides have working prev/next/resize handles in the 3D view. The ",(0,r.jsx)(t.strong,{children:"presentation-mode controls"})," on the ribbon (Show Presentation, Minimise Presentation) are still ",(0,r.jsx)(t.strong,{children:"OpenGL-only"})," and are greyed out in a Vulkan view."]})}),"\n",(0,r.jsxs)(t.p,{children:["For a narrated tour, on-screen ",(0,r.jsx)(t.strong,{children:"captions"})," on the narration clips are usually the better tool \u2014 they need no images, travel with the commentary, and work in the Vulkan view where narration lives."]}),"\n",(0,r.jsx)(t.h3,{id:"video-and-audio-in-the-scene",children:"Video and audio in the scene"}),"\n",(0,r.jsxs)(t.p,{children:["A flight path's own ",(0,r.jsx)(t.strong,{children:"Slides"})," branch takes still images only. To put a ",(0,r.jsx)(t.strong,{children:"video\nclip with its soundtrack"})," into the outcrop itself, place a\n",(0,r.jsx)(t.a,{href:"/docs/next/trees/data/billboards",children:(0,r.jsx)(t.strong,{children:"billboard"})})," in the Data tree and add an\n",(0,r.jsx)(t.code,{children:".mp4"}),", ",(0,r.jsx)(t.code,{children:".avi"})," or ",(0,r.jsx)(t.code,{children:".mov"})," to it. The clip plays in the 3D scene, with sound,\ncomplete with a play/pause, rewind, repeat and scrub strip along the top of the\nboard \u2014 and the camera simply flies past it like anything else in the scene."]}),"\n",(0,r.jsxs)(t.p,{children:["Recording a movie handles this correctly: during an offline capture the clip is\ndriven by the ",(0,r.jsx)(t.strong,{children:"movie's own frame clock"})," rather than the wall clock, so it plays\nat natural speed in the finished video instead of racing through at render speed."]}),"\n",(0,r.jsx)(t.admonition,{title:"Which audio layer to use",type:"tip",children:(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Narration"})," is the commentary ",(0,r.jsx)(t.em,{children:"about"})," the tour \u2014 it belongs to the path, moves\nwith your keyframes, and can stop the camera while you talk. A ",(0,r.jsx)(t.strong,{children:"billboard video"}),"\nis a piece of media ",(0,r.jsx)(t.em,{children:"inside"})," the scene, fixed where you put it. A tour can carry\nboth \u2014 but they are separate sound sources with no ducking between them, so plan\na stop-and-talk around a billboard clip rather than talking over it."]})}),"\n",(0,r.jsx)(t.h2,{id:"motion-blur",children:"Motion blur"}),"\n",(0,r.jsxs)(t.p,{children:["Toggle ",(0,r.jsx)(t.strong,{children:"Motion Blur"})," on the ribbon for cinematic 180\xb0 shutter blur in the recorded movie. Turning it on or off ",(0,r.jsx)(t.strong,{children:"rebuilds the path"})," so the timeline and preview immediately reflect the change."]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["Motion blur adds sub-frames internally, which increases render time. It is ",(0,r.jsx)(t.strong,{children:"off by default"})," and only affects the recorded movie, not interactive preview."]})}),"\n",(0,r.jsx)(t.admonition,{title:"Narration keeps its timing",type:"tip",children:(0,r.jsxs)(t.p,{children:["Toggling motion blur rebuilds the interpolated path with many more frames in it, but the path still runs for the same number of ",(0,r.jsx)(t.strong,{children:"seconds"})," \u2014 so narration clips stay exactly where you placed them, and playback still takes the same time."]})}),"\n",(0,r.jsx)(t.h2,{id:"recording-a-movie",children:"Recording a movie"}),"\n",(0,r.jsxs)(t.p,{children:["With the flight path active, choose ",(0,r.jsx)(t.strong,{children:"Record Movie"}),", pick an output file, and set the resolution, frame rate, motion blur and render qual
1ity in the settings dialog. VRGS then renders ",(0,r.jsx)(t.strong,{children:"every frame of the path off-screen"})," and writes an ",(0,r.jsx)(t.strong,{children:"MP4"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Recording is offline, not a screen capture: each frame is rendered to completion however long it takes, so the video is smooth even where interactive preview would struggle. A progress dialog shows the frame count and has a ",(0,r.jsx)(t.strong,{children:"Cancel"})," button \u2014 cancelling still finalises a playable file containing everything captured up to that point."]}),"\n",(0,r.jsx)(t.admonition,{title:"Render quality",type:"tip",children:(0,r.jsxs)(t.p,{children:["Offline capture can ",(0,r.jsx)(t.strong,{children:"supersample"})," \u2014 render larger than the video size and downsample \u2014 which is the only thing that removes the shimmer on finely textured outcrops. It costs render time proportional to the square of the factor, so try a short path first."]})}),"\n",(0,r.jsx)(t.h3,{id:"narration-in-the-recorded-movie",children:"Narration in the recorded movie"}),"\n",(0,r.jsxs)(t.p,{children:["A guided tour records ",(0,r.jsx)(t.strong,{children:"with its commentary"}),", so a field guide you author in VRGS can be handed over as a single video file to someone who does not have VRGS at all."]}),"\n",(0,r.jsx)(t.p,{children:"Two things happen when you press Record:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The stops become real time."})," A ",(0,r.jsx)(t.a,{href:"#stop-and-talk",children:"stop-and-talk"})," clip costs the tour no time while the app plays it \u2014 the clock simply parks. A video has to actually sit there, so each stop is expanded into however many frames its commentary lasts, and everything after it shifts along. Keyframes ticked ",(0,r.jsx)(t.a,{href:"#holding-on-a-viewpoint",children:(0,r.jsx)(t.strong,{children:"Hold Here"})})," are expanded the same way, and a keyframe carrying both gets both."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The clips are mixed down"})," into one soundtrack, each at its own volume with its fade in and out, and laid into the MP4 in step with the picture."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Nothing on the path is altered by recording: the expansion happens on the interpolated frames, which are rebuilt from your keyframes when the capture finishes. Recording the same tour twice does not compound the stops."}),"\n",(0,r.jsx)(t.admonition,{title:"Vulkan only",type:"note",children:(0,r.jsxs)(t.p,{children:["Narration and holds are written into the movie by the ",(0,r.jsx)(t.strong,{children:"Vulkan"})," view. The OpenGL view records the picture with its own older pipeline and no tour audio \u2014 record narrated tours in Vulkan."]})}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["Movie recording itself works in ",(0,r.jsx)(t.strong,{children:"both"})," renderers. The Vulkan view writes MP4 as described above; the OpenGL view records with its own older pipeline."]})}),"\n",(0,r.jsx)(t.h2,{id:"exporting",children:"Exporting"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Export"})," on the flight path's tree context menu writes its viewpoints to a\n",(0,r.jsx)(t.strong,{children:"CSV"})," file \u2014 ",(0,r.jsx)(t.code,{children:"Name, X, Y, Z, Yaw, Pitch, Roll, Near, Far, Frames"}),", one row per\nviewpoint, positions in project units and orientations in radians \u2014 for use in\nexternal tools."]}),"\n",(0,r.jsxs)(t.admonition,{title:"Merging and splitting whole paths",type:"note",children:[(0,r.jsxs)(t.p,{children:["Merging two paths into one, and splitting a path in two at its middle viewpoint,\nexist in the application but are ",(0,r.jsx)(t.strong,{children:"not currently on any menu or ribbon"}),", so\nthere is no way to reach them in this release. To join two paths by hand, copy\nand paste the viewpoints (",(0,r.jsx)(t.strong,{children:"Selection \u2192 Copy / Paste Viewpoint Values"})," on a\nviewpoint) into a single path."]}),(0,r.jsxs)(t.p,{children:["This is not the same as ",(0,r.jsx)(t.a,{href:"#reordering-keyframes",children:(0,r.jsx)(t.strong,{children:"Insert Viewpoint After"})}),",\nwhich splits a ",(0,r.jsx)(t.em,{children:"segment"})," within one path and is on the viewpoint's ",(0,r.jsx)(t.strong,{children:"Order"}),"\nmenu."]})]}),"\n",(0,r.jsx)(t.h2,{id:"tips-and-troubleshooting",children:"Tips and troubleshooting"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:'Path won\'t build / "At least 2 view points needed".'})," Capture at least two viewpoints before using Create Path."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Motion looks jerky."})," Use the ",(0,r.jsx)(t.strong,{children:"Smooth"})," interpolation method, run ",(0,r.jsx)(t.strong,{children:"Smooth Path"})," a few times, and check the ",(0,r.jsx)(t.strong,{children:"Speed"})," track for sudden spikes \u2014 or just press ",(0,r.jsx)(t.strong,{children:"Constant Speed"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The camera rushes one segment and crawls another."})," Press ",(0,r.jsx)(t.strong,{children:"Constant Speed"}
1)," \u2014 it re-paces the whole path from the distance actually flown and leaves the total duration alone. ",(0,r.jsx)(t.strong,{children:"Set Frames per Metre"})," and dragging keyframes on the timeline are the manual alternatives."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The camera flies through the outcrop."})," Run ",(0,r.jsx)(t.strong,{children:"Check Path"})," (Vulkan), which finds the stretches that pass through rock and offers to nudge the surrounding viewpoints clear. Run it again afterwards \u2014 one pass does not always clear a deep pocket. Auto Generate's own check only proves the ",(0,r.jsx)(t.em,{children:"keyframes"})," are clear, not the curve between them."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Auto Generate put the camera behind the outcrop."}),' The generator picks which side of the face is "outside" from where your camera already is, so navigate to roughly the side you want to film from ',(0,r.jsx)(t.em,{children:"before"})," generating. On a strongly re-entrant face, raise ",(0,r.jsx)(t.strong,{children:"Surface blend"})," so each point follows its own local surface more closely."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:'"Generating from the scene extent"'})," in the Auto Generate dialog means the path has ",(0,r.jsx)(t.strong,{children:"no points of interest"})," \u2014 you will get a generic sweep of the whole model. Place some with ",(0,r.jsx)(t.strong,{children:"Add POI"})," for a path that follows the outcrop."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A generated viewpoint I edited by hand disappeared."})," Auto Generate replaces the keyframes; the dialog warns when it can see hand edits. ",(0,r.jsx)(t.strong,{children:"Ctrl+Z"})," restores them."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:'The "Keep the camera out of the outcrop" tick appears to do nothing.'})," That check needs the ",(0,r.jsx)(t.strong,{children:"Vulkan"})," renderer. In an OpenGL view generation runs without it and says so in the messages panel."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A scene isn't appearing when expected."})," Check whether it uses a spatial (ROI) or temporal trigger; on the ",(0,r.jsx)(t.strong,{children:"Scenes"})," track, right-click and ",(0,r.jsx)(t.strong,{children:"snap the range from the ROI sweep"}),", or set the start/end from the playhead."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The recorded movie is the wrong length."})," The duration is computed at the ",(0,r.jsx)(t.strong,{children:"project frame rate"})," \u2014 confirm it matches the frame rate you are recording at."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:'Nothing was recorded / "check that the microphone is not muted".'})," Another application may hold the microphone exclusively, or Windows may be blocking microphone access for VRGS (",(0,r.jsx)(t.strong,{children:"Settings \u2192 Privacy \u2192 Microphone"}),"). The level meter in the recording dialog is the quickest check: if it never moves, VRGS is not hearing anything."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A narration clip is grey and silent."})," Its audio file is missing \u2014 usually a project copied without its ",(0,r.jsx)(t.code,{children:"AUDIO"})," folder. Re-import the audio and delete the grey clip."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:'The tour does not stop at a "stop and talk" marker.'})," Check the clip is actually marked (it draws as an orange pin, not a bar), and that you are in the ",(0,r.jsx)(t.strong,{children:"Vulkan"})," renderer."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The recorded movie has no commentary."})," Tour audio is written by the ",(0,r.jsx)(t.strong,{children:"Vulkan"})," view only \u2014 the OpenGL view records the picture without it."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A feature is greyed out or missing."})," ",(0,r.jsx)(t.strong,{children:"Narration"}),", ",(0,r.jsx)(t.strong,{children:"guided tours"}),", ",(0,r.jsx)(t.strong,{children:"pause-and-look-around"}),", the ",(0,r.jsx)(t.strong,{children:"transport strip"}),", the ",(0,r.jsx)(t.strong,{children:"playback speed"})," buttons, ",(0,r.jsx)(t.strong,{children:"Check Path"})," and ",(0,r.jsx)(t.strong,{children:"narration in a recorded movie"})," need the ",(0,r.jsx)(t.strong,{children:"Vulkan"})," renderer; the ribbon's ",(0,r.jsx)(t.strong,{children:"presentation-mode controls"})," need ",(0,r.jsx)(t.strong,{children:"OpenGL"}),". Everything else works in both. Check which renderer the view is using."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"see-also",children:"See also"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/docs/next/general/viewing-collaboration/vr-user-guide",children:"VR / Headset User Guide"})," \u2014 explore and present outcrops in virtual reality."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/docs/next/general/viewing-collaboration/display-properties",children:"Display Properties"})," \u2014 control how objects are drawn in the 3D view."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/docs/next/general/viewing-collaboration/virtual-field-trips",children:"Building and Delivering a Virtual Field Trip"})," \u2014 how a flight path fits into a whole trip."]}),"\n"]})]})}function c(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453(e,t,n){n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const r={},s=i.createContext(r);function o(e){const t=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.