Page 1 of 4

New script: a flight over Mars

Posted: 07.07.2004, 17:51
by Toti
Hello,

this script features a short voyage over Mars' surface.
Two remarks:
1) A B-Spline is used to move the viewer and his viewing direction separately, with the result of a quite fluid movement.
2) It is extremely easy to create new "journeys", because of the way paths are defined:
    *) Path points are selected by placing the cursor over an interesting texture map's point (a crater, for example) and reading its coordinates as displayed by a simple image editor.
    *) The script automatically determines how long the user will stay above a certain place, based on its associated description text's length.

This means that no cel/celx programming skills are needed to create simple but enjoyable planetary excursions.

You need to copy the code below and paste it on your text editor. Then save it as anyname.celx in your current Celestia folder.
(In order to run it, you will need a recent 1.3.2 prerelease)

Code: Select all

--***************************************************************************
--***************************************************************************
--          An non-uniform B-Spline approximation algorithm
--            Applied to Mars touring
--
--               Coded by Toti   
--         
--***************************************************************************
--***************************************************************************

--***************************************************************************
--               Constants
--***************************************************************************
DELAY      = 5
SEC_LETTER   = 0.1               -- user takes this time to read a single letter (increase if you find the text's
                     -- speed too fast)

KM_MLY   = 9466411.842
KM_AU      = 149597870.7

BODY      = "Sol/Mars"

ZERO      = celestia:newposition (0, 0, 0)
OBS      = celestia:getobserver()

ORDER      = 3                  -- order of the curve. Increase for additional smoothness
                        
IM_WIDTH   = 1024               -- texture dimensions used as input for the Control Points
IM_HEIGHT   = 512   

-- control points, given as:
--   1] flight path (x,y) as pixel positions in BODY's texture map; z as altitude (a BODY's radius multiplier)
--   2] lookat positions (x,y) as pixel positions in BODY's texture map; z as altitude (a BODY's radius multiplier)
--   3] info field (with descriptive text):

FEATURES   = {   { 180, 50,   15,    134, 205,    1,     "Here we are, enjoying an impressive view above the fourth planet from Sol:"},
         { 180, 50,   12,    134, 205,    1,     "Mars, named after the Roman god of war.\nLet's head towards Tharsis Regio..."},

         {  0, 150,    3,    134, 205,    1,     "...a very conspicuous highland, full of outstanding features."},

         { 90, 220,  1.1,    131, 204,    1,     "Now we are over Olympus Mons, a huge shield volcano, probably the largest one in the Solar System."},   
         {141, 236,  1.1,    131, 204,    1,     "Its summit is 24 km. above the surrounding plains."},
         {163, 180,  1.1,    131, 204,    1,     "Note the deep scarp (up to 6 km. high) that frames it."},
         {163, 180,  1.1,    131, 204,    1,     "There are several other volcanoes with a similar structure:..."},

         {247, 148,  1.2,    214, 224,    1,     "...very prominent is this almost colinear set: Ascraeus,..."},      
         {174, 250,  1.3,    193, 254,    1,     "...Pavonis,..."},
         {165, 298,  1.2,    169, 283,    1,     "...and Arsia."},
         {165, 298,  1.5,    169, 283,    1,     "Each one of this three shield volcanoes is about 15 km. above the nearby area."},

         {172, 285,  1.2,    200, 275, 1.01,     "The intense tensions associated with the Tharsis bulge formation cracked the lithosphere,..."},
         {185, 275,  1.1,    205, 275, 1.01,     "...creating these intrincated patterns that we are flying over, which received the name of Noctis Labyrinthus."},

         {238, 274, 1.05,    255, 274, 1.01,     "Now we are entering Valles Marineris, a system of canyons about 4000 km. long..."},
         {292, 276, 1.05,    310, 286, 1.01,     "...probably originated by a mixture of collapses and fluvial sculpture. Its walls reach 10 km. high."},
         {340, 294, 1.05,    360, 300, 1.01,     "Note that the overall structure is quite complex, with various crests and parallel channels."},
         {355, 294, 1.05,    360, 300, 1.01,     "Let's climb a bit so we can have the whole picture."},

         {365, 294,  1.8,    300, 274,    1,     "A quite impressive postcard, indeed."},
         {365, 294,  1.8,    270, 274,    1,     "Now let's change direction, let's fly towards South..."},
         {361, 302,  1.8,    361, 320, 1.01,     "...which is heavily cratered, and full of smaller features."},

         {365, 375, 1.75,    391, 400,    1,     "We are reaching Argyre Planitia, a highly preserved impact basin."},
         {412, 398, 1.75,    391, 400,    1,     "Note the rugged patterns. Specially interesting are the radial ones..."},
         {412, 398,  1.1,    375, 381,    1,     "...here..."},
         {412, 398,  1.1,    375, 381,    1,     "...(Probably a drainage of the hypothetical lake that once filled the basin)..."},
         {412, 398,  1.1,    412, 414,    1,     "...and here."},
         {391, 400,  1.1,    412, 414,    1,     "This formation probably conducted flows into this basin's lake."},
         {400, 415,  1.1,    412, 414,    1,     "We are near the South Pole. Let's move closer to it."},

         {330, 470, 1.01,    256, 510,    1,     "The ice formations here are notably smaller than the North Pole ones."},
         {270, 475, 1.05,    256, 510,    1,     "This cap is composed of water ice and carbon dioxide (dry) ice..."},
         {210, 480,  1.1,    256, 510,    1,     "...arranged in a multilayered disposition with dark dust bands in between."},
         {150, 485,  1.1,    256, 510,    1,     "Both the northern and southern Mars poles dramatically recede on a seasonal basis."},
         { 90, 490,  1.1,    256, 510,    1,     "As temperature increases, the carbon dioxide sublimates..."},
         { 30, 495,  1.1,    256, 510,    1,       "...ie. it passes from solid to gaseous state without getting liquid."},
         {992, 500,  1.1,    256, 510,    1,       "This huge gaseous mass produces substantial changes in martian atmospheric pressure."},
         {932, 500,  1.1,    256, 510,    1,       "In addition to these annual oscillations, there is also evidence that this cap is slowly dwindling..."},
         {872, 500,    2,    256, 510,    1,       "...possibly due to a progressive climate change."},

         {791, 408, 1.75,    700, 375,    1,       "The Hellas Planitia was the result of a giant asteroid impact."},
         {732, 305,    2,    700, 375,    1,       "Extending 2300 km. across, the central basin is about nine kilometers deep (the deepest point on Mars)."},
         {603, 356,  2.5,    700, 375,    1,       "A ring of material (almost surely thrown out by the impact itself)..."},
         {705, 428,    3,    700, 375,    1,       "...covers all this almost circular surface up to a diameter of nearly 4000 km."},
         {705, 428,  3.2,    700, 375,    1,       "Finally, we will move to Elysium Planitia, the second largest volcanic zone of the planet..."},
         {897, 351,    4,    940, 194,    1,       "...quite far from our previous position."},

         {952, 237,  1.1,    940, 194,    1,       "There are three massive volcanoes here:"},
         {910, 208,  1.1,    940, 202,    1,       "Albor,...                                                         "},
         {960, 195,  1.1,    935, 190, 1.03,       "...Elysium (the largest one in the area),...                      "},
         {929, 158,  1.1,    945, 164,    1,       "...and Hecates.                                                   "},
         {977, 143,  1.2,    913, 173,    1,       "This plain is really a huge dome of about 2400 by 1700 km..."},
         {997, 180,  1.5,    913, 173,    1,       "...crossed by several radial fractures that evidence crust stress during bulge development."},
         {999, 200,  1.8,    913, 173,    1,       "Those cracks are specially noticeable in this region's western slopes..."},
         {973, 215,    2,    913, 173,    1,       "The rest of the place is notably smooth with the exception of some wrinkles and a few craters: an even terrain..."},
         {953, 233,  2.2,    913, 173,    1,       "...like the already visited Tharsis."},

         {600, 230,  3.4,    700, 190,    1,     "This concludes our very brief voyage."},
         {398, 255,    6,    134, 205,    1,     "I hope it was interesting."}   }


-- *********************************************************
--            Touring functions
-- *********************************************************
function buildControlPts (L, bRad, oAmb)
-- builds a table of UCS control points where the flightpath & 'look at' positions will pass through
   local size   = table.getn (L)
   local P   = {}
   local i
   for i = 1, size do
      -- adapt to Celestia's Prime Meridian conventions:
      local long   = ( L[i][1] / IM_WIDTH * 360 ) - 180
      local lat   = 90 - ( L[i][2] / IM_HEIGHT * 180 )
      local r   = bRad * L[i][3]
      local pos   = sphe2cart (r, long, lat)

      long   = ( L[i][4] / IM_WIDTH * 360 ) - 180
      lat   = 90 - ( L[i][5] / IM_HEIGHT * 180 )
      r   = bRad * L[i][6]
      local view   = sphe2cart (r, long, lat)

      -- include ambient light curve directly in the BSpline (this is done so all features are shown, including those
      -- in the planet's dark side:
      if i==1 or i==size then   
         P[i]   = {pos.x, pos.y, pos.z, view.x, view.y, view.z, i, oAmb}       
      else
         P[i]   = {pos.x, pos.y, pos.z, view.x, view.y, view.z, i, 1}
      end
   end
   -- add a blank point so there is room at the end of the fitting scheme (so next-to-last point shows up):
   L[size+1]   = {L[size][1], L[size][2], L[size][3], L[size][4], L[size][5], L[size][6], ""}
   P[size+1]   = {P[size][1], P[size][2], P[size][3], P[size][4], P[size][5], P[size][6], size+1, oAmb}
   return P
end

-- *********************************************************
--            B-Spline functions
-- *********************************************************
function getDuration (L, size)
-- returns total time of the tour, based on info field in table L
   local j
   local length   = 0
   for j = 1, size do
      length   = length + string.len ( L[j][7] )
   end
   return (length * SEC_LETTER)
end

function buildKnots (L, ord, size, dur)
-- builds a table of non-uniform knots as a function of L info field length
   local j
   local K   = {}
   local kn   = size + ord

   local plength    = 0
   for j = 1, kn do
      if j <= ord then
         K[j]   = 0
      elseif j > size then
         K[j]   =  dur+1
      else
         plength   = plength + string.len( L[j-ord][7] )
         K[j]      = plength * SEC_LETTER
      end
   end
   return K
end

function N (K, i, ord, curr)
-- returns the blending factor for 'curr' position along the curve, using 'K' as knot vector. Uses recursion
   local blend
   if ord == 1 then                              -- definition 1st case
      if K[i] <= curr and curr < K[i+1] then
         blend   = 1
      else
         blend   = 0
      end
   else
      local k1   = i+ord-1
      local k2   = i+ord
      if  K[k1] == K[i] and K[k2] == K[i+1] then            -- be careful with 'division by zero' errors at the extremes
         blend   = 0
      elseif K[k1] == K[i] then
         blend   = (K[k2] - curr)  / (K[k2] - K[i+1]) * N(K, i+1, ord-1, curr)
      elseif K[k2] == K[i+1] then
         blend   = (curr - K[i]) / (K[k1] - K[i]) * N(K, i, ord-1, curr)
      else                                 -- definition 2nd case
         blend   = (curr - K[i]) / (K[k1] - K[i]) * N(K, i, ord-1, curr) + (K[k2] - curr) / (K[k2] - K[i+1]) *  N(K, i+1, ord-1, curr)
      end
   end
   return blend
end

function buildSpline (K, CP, rows, cols, ord, curr)
-- returns the B-Spline value for 'curr' knot position
   local i, j
   local S   = {}
   for j = 1, cols do
      S[j]   = 0
   end   
   for i = 1, rows do
      local w   = N(K, i, ord, curr)
      for j = 1, cols do
         S[j]   = CP[i][j] * w + S[j]
      end
   end
   return S
end

--***************************************************************************
--               Other functions
--***************************************************************************
function sphe2cart (rad, rho, phi)
-- converts from spherical to cartesian coordinates. Returns a POSITION
   local   r   = rad / KM_MLY
   local x   = - r * math.cos (math.rad (rho)) * math.cos (math.rad (phi))
   local y   = r * math.sin (math.rad (phi))
   local z   = r * math.sin (math.rad (rho)) * math.cos (math.rad (phi))
   return celestia:newposition (x,y,z)
end

function celestia_cleanup_callback()
-- restores user's preferred settings
   celestia:setambient (oldAmb)
end


--***************************************************************************
--               Main routine
--***************************************************************************
oldAmb    = celestia:getambient()

body      = celestia:find(BODY)
bodyRad   = body:radius()
bodyFrame   = celestia:newframe("planetographic", body)

TOUR      = buildControlPts (FEATURES, bodyRad, oldAmb)

celestia:select (body)

tableSize   = table.getn (TOUR)
datumSize   = table.getn (TOUR[1])

duration   = getDuration (FEATURES, tableSize)
Knots      = buildKnots (FEATURES, ORDER, tableSize, duration)

t0      = celestia:getscripttime()
t1      = 0

repeat

   pos      = buildSpline (Knots, TOUR, tableSize, datumSize, ORDER, t1)

   obsPos   = bodyFrame:from (celestia:newposition (pos[1], pos[2], pos[3]))   -- body is rotating, so UCS won't work OK
   lookAtPos   = bodyFrame:from (celestia:newposition (pos[4], pos[5], pos[6]))   -- same here
   normalVect   = obsPos-body:getposition()

   OBS:setposition (obsPos)
   OBS:lookat (lookAtPos, normalVect)

   celestia:setambient (pos[8])

   celestia:flash (string.format("%s", FEATURES[math.floor(pos[7])][7]), DELAY)

   wait()

   t1      = celestia:getscripttime() - t0   -- put this here so old computers (like mine) can run the code fine

until t1 > duration

Posted: 07.07.2004, 21:35
by Harry
Wow, just great! :D

Harald

Posted: 08.07.2004, 01:45
by jestr
Wow awesome script Toti,like your camerawork (so to speak) Jestr

Posted: 08.07.2004, 06:01
by chris
Really great work Toti! I think that Celestia could use a library of standard script functions written in Lua--your B-spline camera paths would certainly be candidates. The Lua libraries wouldn't be loaded by default, but could via a new command. Something like:

require bspline

. . . at the beginning of a program.

--Chris

Re: New script: a flight over Mars

Posted: 08.07.2004, 16:24
by danielj
I copied and past in the Wordpad and didn?t work.First,it said "invalid command".Then,it says that was a problem with a }.
I am using Celestia 1.3.2 pre 7

Re: New script: a flight over Mars

Posted: 08.07.2004, 17:29
by Pliskin
danielj wrote:I copied and past in the Wordpad and didn?t work.First,it said "invalid command".Then,it says that was a problem with a }.
I am using Celestia 1.3.2 pre 7


Did you copy all of it exactly? Also, did you use the extention ".celx" and save it under "all files instead of "text document"?

Re: New script: a flight over Mars

Posted: 08.07.2004, 17:33
by t00fri
danielj wrote:I copied and past in the Wordpad and didn?t work.First,it said "invalid command".Then,it says that was a problem with a }.
I am using Celestia 1.3.2 pre 7


...and again things don't work for you!!

Apparently (see above), Toti's script worked at least for

-- Toti
-- Harry
-- jestr
-- Chris
(-- myself )

now this fact makes it highly unplausible that there was a typo connected to a '}' involved in Toti's script. So instead of rushing to write another of your countless "does'nt work for me" posts, you might just as well have spent a moment thinking, instead.

What could come to mind? What do you guess?

a) You might have copied the script incompletely in some way with your mouse...Solution: try it again carefully.

b) You introduced an extra return somewhere into a line accidentally. Then a single command appears chopped into two incomplete ones for the Lua interpreter. Result: error.
Solution: try to copy the script again carefully

c) something might be wrong with your Lua installation and you might have forgotten to name your script with ending .celx.
Solution: check your Lua installation with other .celx scripts first.

Bye Fridger

Posted: 08.07.2004, 21:39
by selden
Toti,

A suggestion: include a time-of-day specification.

The tour would be more dramatic if the locations were visited near sunrise or sunset when the shadows and highlights enhance the mountains and valleys.

p.s. I also have no problem running the script. My guess is that Daniel accidentally named it .CEL instead of .CELX.

Re: New script: a flight over Mars

Posted: 08.07.2004, 22:35
by danielj
The following error appeared :
Fatal error
[string "C:\Arquivos de Programa\Softwares de Astronomia\Celestia\Marsf..."]:1:unexpected symbol near ?{'

There isn?t an option to save in All files,only in text files.
I using Wordpad,because Notepad dissapeared(some virus?!)

Re: New script: a flight over Mars

Posted: 08.07.2004, 22:35
by danielj
The following error appeared :
Fatal error
[string "C:\Arquivos de Programa\Softwares de Astronomia\Celestia\Marsf..."]:1:unexpected symbol near ?{'

There isn?t an option to save in All files,only in text files.
I using Wordpad,because Notepad dissapeared(some virus?!)

Posted: 08.07.2004, 23:14
by Toti
Harald, Jestr and Chris,

Thank you very much for your comments.
I am glad that you liked the script :D

Chris wrote:I think that Celestia could use a library of standard script functions written in Lua--your B-spline camera paths would certainly be candidates. The Lua libraries wouldn't be loaded by default, but could via a new command. Something like:

require bspline

. . . at the beginning of a program.


These are good news! And what about adding a small C library with very fast Spline/B-Spline/NURBS support to Celestia? It will find several uses:
-faster and better orbit trajectory drawing
-animation keyframes interpolation
-touring and flights
-volumetric rendering (nebulae?)

among other data fitting/interpolating tasks. (Fridger referred to this in the recent past)


Daniel,

Surely you are saving the file with .celx extension but in MS-Word format. You must save it as "text only", ie. with no format. You can select this option in the "save as" dialog.


Bye

Posted: 09.07.2004, 02:43
by Toti
Selden,

Thanks for your suggestion.

My TNT2 video card can't handle bump/normal mapping, so I use Praesepe's excellent 8K shaded Mars (converted to VT).
I deliberately raised Ambient Light to its maximum, with the purpose of showing features in Mars' night side.

As a result, I can see "shaded" mountains anywhere on the planet's surface.

How does maximum Ambient Light affect bump mapping? Are you seeing a flat image?

Re: New script: a flight over Mars

Posted: 09.07.2004, 07:21
by Bob Hegwood
danielj wrote:There isn?t an option to save in All files,only in text files.
I using Wordpad,because Notepad dissapeared(some virus?!)

Daniel,

1. Highlight and Copy the script from Toti's original message.
2. Open Wordpad and click on the "Edit" button at the top of the screen.
3. Click on the "Paste Special" option with your cursor.
4. Click on the "Unformatted Text" option.
5. Click on "Okay" to paste the code into the document.
6. Click on the "File" option on the menu.
7. Click on "Save As" then highlight the "Unicode Text Document" option.
8. Type in the filename manually. Try TotiMars.celx
9. Click on the "Save" button.
10. Click on "Yes" when you see the warning message about losing formatting.

I have done all of this on my Brain-Dead system, and the script works fine.
Very nice too, Toti. A note though... The Tour Messages will not show up unless I have pressed the "V" key in Celestia to enable info text.

Hope this helps Daniel...

Take care, Bob

Posted: 09.07.2004, 07:32
by Bob Hegwood
Toti,

One additional note about your script... I am also using Praesepe's Mars textures,
and I can use the alternate surfaces option to run the tour using my 8k VT's. This
really creates a spectacular tour on my limited machine. Just thought you might
like to know that. Can't really do that with my cel scripts because of the delays
involved. For some reason, the delays are *much* less noticeable
using the CELX scripts. <shrug>

At any rate, thanks *very* much for the script. Cool Tour.

Take care, Bob

Posted: 09.07.2004, 10:20
by maxim
Toti wrote:How does maximum Ambient Light affect bump mapping? Are you seeing a flat image?

Yes. Using DBradys Mars texture, there are only flat colorpatterns left to watch.

A really nice script - specially the camera movements. Unfortunately my system seems to be too slow for it (sniff :cry:).
With my preshaded 16k hires texure I can't avoid stop-and-go interrupts (sniff sniff :cry:) - it doesn't even load from cache fast enought - this makes you think of a system with 2GB main memory ;)

If you think it's worthwhile Toti, you might adapt seldens suggestion, and combine camera movement with fast planet rotation to keep viewpoints near a terminator - perhaps this helps reducing those inverse flipovers on preshaded maps I watched from time to time when lighting and shading weren't aligned.

Thanks for that script. :)

maxim

Posted: 09.07.2004, 16:49
by Toti
Bob and Maxim,

you are quite welcome.
In order to reduce the delays and interruptions you can run the script twice. The second time, most VTs will be already loaded into memory, so it will be notably faster.
I will modify the code as Selden suggested (bumpmapping removal was entirely an unwanted sideeffect). In the meantime, you can comment out the line:

Code: Select all

celestia:setambient (pos[8])

near the end of the code. Just add "--" at the beginning of the line:

Code: Select all

--celestia:setambient (pos[8])

It will turn off light setup, so you can adjust Ambient Light by hand with { and }. It's far from a solution, however, but at least some bumpmapping will show up.

Again, many thanks.

Bye

Posted: 09.07.2004, 17:04
by Guest
Hi toti, Howard here.

I just this moment found this thread and have not had an opportunity to try your script, but I have a few questions.

I was gearing up to build (with help from a programmer, I am not one) a comprehensive production/editing environment for Celestia. Goal is to create content in a cinemagraphic way with precise control over the cameras special and temporal orientation. This tool should also have an editing timeline which can “splice” together different splines or add transitions, add keyframes, add audio etc. One of the key components was to be able to draw splines or Bezier curves which can be precisely manipulated as the “track for the camera. On top of that would be precise control over camera pitch, roll and yaw as well as FOV. Ideally, in one window, one could see this path in 3D, with all objects drawn as wireframes, and be able to fly up to the camera to adjust it as well as the spline. In another window would be the real-time view in Celestia, and a third window would be the editing timeline.

From the sounds of it you are able to do the spline. Does the spline get drawn? If so, is it something that can be manipulated?

Posted: 09.07.2004, 17:50
by howard
Sorry, That last post was me. Guess I wasn't logged in :oops:

An edit: I am on a powerbook G4 MAC so I currently can't run the 1.3.2 pre. and I don't have access to a windoz box at the moment. This means I really can't tell what the script does so if you can fill me in...

thanks
hc

Posted: 10.07.2004, 01:35
by Toti
Howard wrote:This tool should also have an editing timeline which can splice together different splines or add transitions, add keyframes, add audio etc.
One of the key components was to be able to draw splines or Bezier curves which can be precisely manipulated as the track for the camera. On top of that would be precise control over camera pitch, roll and yaw as well as FOV.
In this script, the "up" vector is always perpendicular to the surface, so there is no roll control. Its is easy to add support for this.

Howard wrote:Ideally, in one window, one could see this path in 3D, with all objects drawn as wireframes, and be able to fly up to the camera to adjust it as well as the spline. In another window would be the real-time view in Celestia, and a third window would be the editing timeline.
Blender (Open Source) provides almost all this functionality. It gives you a very sophisticated non linear editing environment. You can edit your wireframe curves, adjust keyframing functions, synchronize audio and do NLA, each one in a separated window.
Now it depends on your needs, but Blender is scriptable (using Phyton, an extremely easy-to-use, yet powerful programming language).
A priori you could write scripts to import Celestia's ssc files into Blender and (via VSOP 87 routines, etc.) automatically keyframe the objects they describe, in order to match Celestia bodies' trajectories. Once done, you could save the scene (in Blender's own format) and work with it like any usual animation, doing wireframe or GL-shaded, real-time previsualizations. (Blender was used in Spiderman 2 with this same purpose)
Once finished, your spline points could be exported (again, Phyton) to Celestia for final use.
Of course, you must first study the detailed feasibility of all this.
http://www.blender.org/

Howard wrote:From the sounds of it you are able to do the spline. Does the spline get drawn? If so, is it something that can be manipulated

No, the spline doesn't get drawn. The workflow for "tour creation" is as follows:
    a) open the planet's texture map in any image editor.
    b) put your pointer near crater1. The image editor will show the pixel coordinates of the point you are over. Write down these coordinates. This will be your camera position.
    c) put your pointer over crater1. Write down the pixel coordinates. This will be your camera "look at" position.
    d) add a height value (in planet's radii) to b) (eg: 3, we want to be at some altitude) and another height value for c) (eg: 1, because we want to look at a point in the surface)
    e) add some text (eg: "We are over crater1")

Now you have your first bspline "datum". You are near crater1, at 3 times the planet's radius, looking at crater1.
You can repeat the process for other surface features. (It is fast)
Finally, the spline routines will create a soft trajectory between them. You can run the script to check the results, then you can tweak the points to improve the movements. There is little "interactive editing", as you see ;)

Posted: 10.07.2004, 06:31
by maxim
Toti wrote:In order to reduce the delays and interruptions you can run the script twice. The second time, most VTs will be already loaded into memory, so it will be notably faster.

I thought that too, but not in this case - most VTs gets swapped into disk cache and are reloaded even slower than from original place (ok, I WILL have to do a defragmentation run ;) ). So the second run is even more worse (sniff :cry:).

Completely used/displayed planet VTs seems to be a real load stress.

maxim