Schmidt's Solar system tour v1.1

All about writing scripts for Celestia in Lua and the .cel system
Topic author
raylier
Posts: 4
Joined: 26.04.2020
With us: 4 years

Schmidt's Solar system tour v1.1

Post #1by raylier » 25.07.2020, 13:33

Hello,

I have downloaded the solarsytemtour v1.1.celx made by H Schmidt. I have a question...
I want to display only the planets and not the moons. I changed the code so that moons are not
preloaded. But.. after Pluto the script continues with the moons. Any suggestions? Thanks.

onetwothree
Site Admin
Posts: 704
Joined: 22.09.2018
With us: 5 years 7 months

Post #2by onetwothree » 25.07.2020, 17:24

where did you downloaded it? what changes did you make?

Janus
Posts: 537
Joined: 13.08.2016
With us: 7 years 8 months

Post #3by Janus » 25.07.2020, 18:00

For anyone who is interested.

V1.1
Some versions show base_Inertia{line 29} @ 0.7 instead of 0.3 as this does.
Spoiler

Code: Select all

-- Example script for Lua support in celestia
--
-- Solar system tour Version II, v1.1
--
-- (c) 2003 Harald Schmidt
-- http://www.h-schmidt.net/celestia/
--
-- comments, bugreports to: celestia ( at ) h-schmidt.net
--
-- You are free to use, copy, modify, redistribute this script,
-- but keep a credit to the original author
--
-- Bugs: script needs cleanup. It has become more complex than anticipated,
-- and some things are just a dirty hack.
-- 2003-12-14: Test with 1.3.1rc:
--  There are some workarounds needed for Windows -
--  the assumption that a simple wait(0) forces a rendering phase
--  seems is wrong.
--  table.getn() seems to not work on win (or works differently).
--  Replaced by old explicit length-counting until further investigation.

-- temporary workaround against a bug on windows:
wait(0.1)
celestia:flash("")
wait(0.5)

-- base_inertia is (very!) roughly how much of the current direction
-- will be retained in a second.
base_inertia = 0.3

-- base_speed_timestep is the amount of time we would (at current speed)
-- need to reach next target:
-- Don't set this too small, or we will miss targets
base_speed_timestep = 1

-- CONSTANT, do not change
KM_PER_MLY=9466411.842

-- keep camera locked within this distance to target:
CAMLOCKD = 0.03

-- up-vector for observer
UP = celestia:newvector(0,1,0)

INTRO = "Solarsystem Tour (v1.1) by Harald Schmidt\nplease report bugs to celestia (at) h-schmidt.net\n\n"
-- return vector with same direction and length == 1
function normalize(v)
    local x = v:getx()
    local y = v:gety()
    local z = v:getz()
    local d = math.sqrt(x*x + y*y + z*z)
    if d > 0.0000001 then
        d = 1/d
    else
        --celestia:flash("underflow",2)
        d = 1
    end
    return celestia:newvector(d*x, d*y, d*z)
end

-- return length of v
function length(v)
    local x = v:getx()
    local y = v:gety()
    local z = v:getz()
    local d = math.sqrt(x*x + y*y + z*z)
    return d
end

-- INITIALIZATION

pos_table = {}
pos_table.len = 0

-- fill pos_table with solar-system objects
-- we currently avoid moons, they probably need further tweaking
-- (extreme changes in speed necessary, for example when
-- moving from mars to jupiter (very fast) and then to a jupiter moon (slow))
function filltable(obj, depth)
    pos_table[pos_table.len] = obj
    pos_table.len = pos_table.len + 1
    local i, v
    local children = obj:getchildren()
    for i, v in ipairs(children) do
        if v:radius() < 1 or v:name() == "Galileo" then
            --celestia:flash("ignoring: " .. v:name())
            --wait(2)
        else
            --if depth <= 2 then
            --    filltable(v, depth+1)
            --end
            pos_table[pos_table.len] = v
            pos_table.len = pos_table.len + 1
            preload(v)
        end
    end
end

-- preload textures
function preload(obj)
    if obj:type() == "planet" or obj:type() == "moon" then
        if obj:radius() < 100 then
           return
        end
        celestia:print(INTRO.."Preloading texture for " .. obj:name(), 10, 0, 0, -20, 0)       
        local p = obj:getposition()
        local r = obj:radius()
        local v = celestia:newvector(1,0,0)
        v = (4 * r) / KM_PER_MLY * v
        celestia:getobserver():setposition(p + v)
        celestia:getobserver():lookat(p, UP)
        wait(0.1)
        if obj:type() == "planet" then
           local children = obj:getchildren()
           for i, c in ipairs(children) do
              preload(c)
           end
        end
    end
end

side_toggle_a = 1
side_toggle_b = 1
function getposfromobject(source, target)
   local displacement = nil
   if source == nil then
      displacement = celestia:newvector(0.001, 0, 0)
   else
      local src2target = source:getposition():vectorto(target:getposition())
      displacement = (src2target ^ UP):normalize()
      displacement = side_toggle_a  * 3*target:radius()/KM_PER_MLY * displacement
      displacement = displacement + 1.0*target:radius()/KM_PER_MLY * src2target:normalize()
      side_toggle_a = -1 * side_toggle_a
      side_toggle_b = side_toggle_a * side_toggle_b
   end
   return target:getposition() + displacement
end

function getcameratarget(sourcepos, targetpos, obspos, part)
   src2target = sourcepos:vectorto(targetpos)
   local lgth = length(src2target)
   local part2 = (part - CAMLOCKD) / (1 - 2*CAMLOCKD)
   part2 = math.min(1,math.max(0,part2))
   local disp = lgth * 0.05 * side_toggle_b * math.pow(math.sin(math.pi*part2),2)
   local vec = nil
   if part2 < 0.5 then
        vec = obspos:vectorto(sourcepos)
   else
        vec = obspos:vectorto(targetpos)
   end
   local factor1 = math.abs(part2 - 0.5)
   local displacement =  disp * (sourcepos:vectorto(targetpos) ^ UP):normalize()
   return obspos + factor1 * vec + displacement
end

offset = celestia:newvector(0.1,0,0)

sol = celestia:find("Sol")
filltable(sol,1)
o = celestia:getobserver()
t = 1
date = celestia:gettime()
pos = pos_table[t-1]:getposition():addvector(offset)
o:setposition(pos)
velocity = celestia:newvector(1e-5,0,0)
-- count frames
counter = 0
-- starting speed: 2mly / step
min_speed = 2
-- distance to/from target where we maintain constant speed
-- this is the starting value, to get away from sun
const_speed_distance = pos_table[t-1]:radius()*1

time = celestia:getscripttime()

last_target_pos = pos

-- must show this long, because sun is to bright to read this at first:
celestia:print(INTRO .. "", 5, 0, 0, -20, 0)

celestia:select(pos_table[0])
-- walk the position-table:
while t < pos_table.len do   
  next_target = pos_table[t]
 
  past_midpoint = false
 
  -- get position where we should be heading and distance to target
  -- next_target_pos = next_target:getposition():addvector(offset)
  next_target_pos = getposfromobject(pos_table[t-1], pos_table[t])
  -- overall distance
  dist = pos:distanceto(next_target_pos)
 
  -- :TODO: convert this from dist (we need this in microly instead of km)
  dist_mly = length(pos:vectorto(next_target_pos))
 
  -- select next target when within dist_trigger to planet
  radius = math.max(10, next_target:radius())
  dist_trigger = radius*5
 
  -- emergency trigger if first trigger fails (could happen if we blast by too fast - current parameters should avoid this)
  dist_emergency_trigger = dist / 3
  last_dist = dist
 
  -- current distance to target
  d = dist
 
  -- INNER LOOP: approach to next target, exit loop when there
  while d > dist_trigger do
      local time2 = celestia:getscripttime()
      local dt = math.max(0.005, math.min(0.2, time2 - time))
      time = time2
     
      -- use this to correct for moving bodies while in flight
      celestia:settime(date)
      -- next_target_pos = next_target:getposition():addvector(offset)
     
      -- distance to target (in "dist"-units, i.e. should vary between ~1 and 0)
      a = d / dist

      -- now compute velocity envelope: go slow when near planet, go really fast between
     
      -- speed is a funcion of distance to/from target, and
      -- distance is computed as:
      if a > 0.5 then
        -- distance from previous target:
        ref_distance_km = dist - d
      else
        if not past_midpoint then
          -- this is executed once between src and target
          celestia:select(next_target)
          past_midpoint = true
        end
        -- distance to next target:
        ref_distance_km = d
      end
     
      -- reset const_speed_distance when approaching next target
      -- leave intact while going away from last target (avoid instantaneous velocity boost)
      if a < 0.5 then
        const_speed_distance = dist_trigger*2
      end
     
      -- compute distance to target (when approaching) or
      -- from last target
      ref_distance_km = math.max(const_speed_distance, ref_distance_km)
      ref_distance_mly = ref_distance_km / KM_PER_MLY
       
      -- speed is computed as:
      -- speed = distance_to_target / time_to_reach_target
      -- distance_to_target is of couse
      speed = ref_distance_mly / base_speed_timestep
     
      -- inertia controls how quick the direction of view changes.
      --
      -- To make the script behave mostly identical for different FPS, we
      -- must change inertia depending on the time between two frames.
      -- inertia doesn't have a linear influence, but this first-order
      -- approximation should suffice.
      --
      -- if dt == 0, inertia = 1, for dt >= 0.1, inertia = 0.1*base_inertia
      inertia = 1 - (math.min(0.1, dt)*(1-base_inertia))
      -- camera must change quicker when getting near target, otherwise we could miss the target,
      -- therefore adjust proportionally to distance to target (but don't set to >= 1)
      inertia = math.max(0.5, math.min(a,1)*inertia)
     
      direction = pos:vectorto(next_target_pos)     
      -- normalized direction
      dir_norm = normalize(direction)
     
      -- normalized velocity
      -- cant use vector:normalize because length may be to small
      vel_norm = normalize(velocity)

      -- This is the most important part:
      -- compute the new velocity, by choosing a direction
      -- between the former velocity and the direction we have to go.
     
      new_velocity_direction = (inertia * vel_norm + (1-inertia)*dir_norm)
     
      velocity = speed * dt * new_velocity_direction:normalize()
     
      newpos = pos + velocity
     
      -- look in direction of movement     
      o:setposition(pos)
      o:lookat(getcameratarget(last_target_pos, next_target:getposition(), pos, 1-a), UP)     
     
      pos = newpos
      d = pos:distanceto(next_target_pos)
     
      -- check emergency trigger?
      if d < dist_emergency_trigger then
        -- real check: are we going away again?
        if d > last_dist then
            -- this is an error, print message
            celestia:flash("Ah, I just missed my target - continuing with next target!")
            --wait(2)
            break
        end
      end
      last_dist = d
      counter = counter + 1
      wait(0.01)
  end
 
  last_target_pos = next_target:getposition()
  t = t + 1
end
o:follow(pos_table[pos_table.len-1])
celestia:flash("This is the end, after " .. math.floor(celestia:getscripttime()) .. " seconds and " .. counter .. " steps. Thanks for watching.",10)



V1.2
Spoiler

Code: Select all

function tourspecifiedsystems()
-- NOMINATE SYSTEMS TO TOUR AND OBJECT TYPES TO VIEW
-- SYSTEMS MAY BE SOLAR SYSTEMS WITH PLANETS OR PLANETARY SYSTEMS WITH MOONS
-- Syntax is
--    tour("systemcentre_name","object_types_to_view")
--
-- Valid object_types_to_view are:
--    "planets"
--    "asteroids"
--    "comets"
--    "planets&moons" or "planet&moons"
--    "asteroids&comets"
--    "all"
-- Add as many systems as you would like to tour below this line.
-- To tour examples given, remove -- at beginning of line.

-- ****** USER-EDITABLE SECTION BELOW THIS LINE ******
--tour("Sol","all")
tour("Sol","planets")
--tour("Sol/Mars","planet&moons")
--tour("Sol/Jupiter","planet&moons")
--tour("Sol/Saturn","planet&moons")
--tour("Sol/Uranus","planet&moons")
--tour("Sol/Neptune","planet&moons")
--tour("Sol/Pluto","planet&moons")
--tour("Sol","comets")
--tour("UPS And","all")
--tour("51 Peg","all")
--tour("61 Cyg A","all")
--tour("Katalina","planets&moons")
-- ****** END OF USER-EDITABLE SECTION SPECIFYING SYSTEMS TO TOUR ******
return
end

function resetusersrenderflags()
-- ****** EDIT LINES BELOW TO RESTORE RENDER SETTINGS TO YOUR PREFERENCES ******
--   celestia:show("planets", "comettails", "stars")
--   celestia:hide("ringshadows", "grid", "boundaries", "constellations", "galaxies", "automag")
--   celestia:showlabel()
--   celestia:hidelabel("spacecraft", "asteroids", "comets", "constellations", "stars", "galaxies")
--   celestia:show("planets", "cloudmaps", "nightmaps", "atmospheres", "eclipseshadows", "comettails", "stars")
--   celestia:hide("orbits", "ringshadows", "markers", "grid", "boundaries", "constellations", "galaxies", "automag")
--   celestia:showlabel()
--   celestia:hidelabel("planets", "moons", "spacecraft", "asteroids", "comets", "constellations", "stars", "galaxies")
-- ****** END OF EDITABLE SECTION SPECIFYING YOUR PREFERED RENDER SETTINGS ******
return
end


-- *******************************************************************
-- ************* CREDITS, GENERAL INFO ABOUT PROGRAM *****************
-- *******************************************************************
-- SolarSystemTour v1.2 by Tim McMahon
-- Based on Harald Schmidt's script SolarSystemTour_v1.1.celx
-- This modified script allows specification and touring of multiple
-- solar systems or planetary systems and their objects.
-- Comments, bugreports to: tim.mcmahon@tiscali.co.uk
-- (c) 9 March 2004
--
-- Based on Solar system tour Version II, v1.1
-- (c) 2003 Harald Schmidt
-- http://www.h-schmidt.net/celestia/
--
-- You are free to use, copy, modify, redistribute this script,
-- but keep a credit to the original author
--
-- *******************************************************************
-- MODIFY THE CODE AT THE TOP OF THE SCRIPT TO SPECIFY SYSTEMS TO TOUR
-- *******************************************************************
--
-- There are some workarounds needed for Windows -
-- the assumption that a simple wait(0) forces a rendering phase
-- seems is wrong.
-- table.getn() seems to not work on win (or works differently).
-- Replaced by old explicit length-counting until further investigation.

function workaroundwindowsbug()
-- temporary workaround against a bug on windows:
   wait(0.1)
   celestia:flash("")
   wait(0.5)
return
end

-- *************** MORE FUNCTION DEFINITIONS **************

function setrenderflags()
   celestia:show("planets", "cloudmaps", "nightmaps", "atmospheres", "eclipseshadows", "comettails", "stars")
   celestia:hide("orbits", "ringshadows", "markers", "grid", "boundaries", "constellations", "galaxies", "automag")
   celestia:hidelabel("planets", "moons", "spacecraft", "asteroids", "comets", "constellations", "stars", "galaxies")
end

-- INITIALIZATION & CONSTANT DEFINITION
function initializemainprogram()
   -- intro screen
   INTRO = "SolarSystemTour v1.2 by Tim McMahon\nBased on SolarSystemTour v1.1 by Harald Schmidt\n"
   --Please report bugs to tim.mcmahon@tiscali.co.uk\n\n"

   -- base_inertia is (very!) roughly how much of the current direction
   -- will be retained in a second.
   base_inertia = 0.3

   -- base_speed_timestep is the amount of time we would (at current speed)
   -- need to reach next target:
   -- Don't set this too small, or we will miss targets
   base_speed_timestep = 1.333

   -- CONSTANT, do not change
   KM_PER_MLY=9466411.842

   -- keep camera locked within this distance to target:
   CAMLOCKD = 0.03

   -- up-vector for observer
   UP = celestia:newvector(0,1,0)

   -- initialize touring time
   touringtime = 0

   return
end

function openingflash(systemcentre,objectstovisit)
   -- OPENING FLASH SCREEN
   celestia:print(INTRO .. "",10, 0, 0, -20, 0)
   wait(2)
   celestia:flash("Touring " .. systemcentre:name() .. " system - " .. objectstovisit,5)
   wait(5)
   celestia:flash("Compiling list of objects to tour...",2)
   wait(2)
   return
end

function specify(objectstovisit)
   viewplanetsonly        = false
   viewasteroidsonly      = false
   viewcometsonly         = false
   viewplanetsandmoons    = false
   viewasteroidsandcomets = false
   viewall                = false
   if objectstovisit == "planets" then
      viewplanetsonly = true
   end
   if objectstovisit == "asteroids" then
      viewasteroidsonly = true
   end
   if objectstovisit == "comets" then
      viewcometsonly = true
   end
   if objectstovisit == "planets&moons" or objectstovisit == "planet&moons" then
      viewplanetsandmoons = true
   end
   if objectstovisit == "asteroids&comets" then
      viewasteroidsandcomets = true
   end
   if objectstovisit == "all" then
      viewall = true
   end
   return
end

function notspecifiedtype(obj)
   wrongtype = true
   if viewplanetsonly and obj:type() == "planet" then
      wrongtype = false
   end
   if viewasteroidsonly and obj:type() == "asteroid" then
      wrongtype = false
   end
   if viewcometsonly and obj:type() == "comet" then
      wrongtype = false
   end
   if viewplanetsandmoons and (obj:type() == "planet" or obj:type() == "moon") then
      wrongtype = false
   end
   if viewasteroidsandcomets and (obj:type() == "asteroid" or obj:type() == "comet") then
      wrongtype = false
   end
   if viewall and not (obj:type() == "invisible" or obj:type() == "spacecraft") then
      wrongtype = false
   end
   return wrongtype
end


function loadchildren(parent,depth)
         local i, v
         local children = parent:getchildren()
         for i, v in ipairs(children) do
            if notspecifiedtype(v) then
               celestia:flash("Ignoring : " .. v:name())
               wait(0.2)
            else 
               preload(v)
               celestia:flash("Including: " .. v:name())
               wait(0.2)
               pos_table[pos_table.len] = v
               pos_table.len = pos_table.len + 1
               if depth <= 2 then
                  loadchildren(v, depth+1)
               end
            end
         end
         return
end

pos_table = {}
pos_table.len = 0
-- fill pos_table with specified system objects
function filltable(obj, depth)
   if obj:type() == "star" then
      preload(obj)
      pos_table[pos_table.len] = obj
      pos_table.len = pos_table.len + 1
      local i, v
      local children = obj:getchildren()
      for i, v in ipairs(children) do
         if notspecifiedtype(v) then
            celestia:flash("Ignoring : " .. v:name())
            wait(0.2)
         else 
            preload(v)
            celestia:flash("Including: " .. v:name())
            wait(0.2)
            pos_table[pos_table.len] = v
            pos_table.len = pos_table.len + 1
            if depth <= 2  then
               loadchildren(v, depth+1)
            end
         end
      end
   else
      if notspecifiedtype(obj) then
         celestia:flash("Ignoring : " .. obj:name())
         wait(0.2)
      else 
         preload(obj)
         pos_table[pos_table.len] = obj
         pos_table.len = pos_table.len + 1
         local i, v
         local children = obj:getchildren()
         for i, v in ipairs(children) do
            if notspecifiedtype(v) then
               celestia:flash("Ignoring : " .. v:name())
               wait(0.2)
            else 
               preload(v)
               celestia:flash("Including: " .. v:name())
               wait(0.2)
               pos_table[pos_table.len] = v
               pos_table.len = pos_table.len + 1
               if depth <= 2  then
                  loadchildren(v, depth+1)
               end
            end
         end
      end
   end
end

-- preload textures
function preload(obj)
   celestia:print("Preloading texture for " .. obj:name(), 10, 0, 0, -20, 0)       
   local p = obj:getposition()
   local r = obj:radius()
   local v = celestia:newvector(1,0,0)
   v = (4 * r) / KM_PER_MLY * v
   celestia:getobserver():setposition(p + v)
   celestia:getobserver():lookat(p, UP)
   wait(0.1)
end

-- return vector with same direction and length == 1
function normalize(v)
    local x = v:getx()
    local y = v:gety()
    local z = v:getz()
    local d = math.sqrt(x*x + y*y + z*z)
    if d > 0.0000001 then
        d = 1/d
    else
        --celestia:flash("underflow",2)
        d = 1
    end
    return celestia:newvector(d*x, d*y, d*z)
end

-- return length of v
function length(v)
    local x = v:getx()
    local y = v:gety()
    local z = v:getz()
    local d = math.sqrt(x*x + y*y + z*z)
    return d
end

side_toggle_a = 1
side_toggle_b = 1
function getposfromobject(source, target)
   local displacement = nil
   if source == nil then
      displacement = celestia:newvector(0.001, 0, 0)
   else
      local src2target = source:getposition():vectorto(target:getposition())
      displacement = (src2target ^ UP):normalize()
      displacement = side_toggle_a  * 3*target:radius()/KM_PER_MLY * displacement
      displacement = displacement + 1.0*target:radius()/KM_PER_MLY * src2target:normalize()
      side_toggle_a = -1 * side_toggle_a
      side_toggle_b = side_toggle_a * side_toggle_b
   end
   return target:getposition() + displacement
end

function getcameratarget(sourcepos, targetpos, obspos, part)
   src2target = sourcepos:vectorto(targetpos)
   local lgth = length(src2target)
   local part2 = (part - CAMLOCKD) / (1 - 2*CAMLOCKD)
   part2 = math.min(1,math.max(0,part2))
   local disp = lgth * 0.05 * side_toggle_b * math.pow(math.sin(math.pi*part2),2)
   local vec = nil
   if part2 < 0.5 then
        vec = obspos:vectorto(sourcepos)
   else
        vec = obspos:vectorto(targetpos)
   end
   local factor1 = math.abs(part2 - 0.5)
   local displacement =  disp * (sourcepos:vectorto(targetpos) ^ UP):normalize()
   return obspos + factor1 * vec + displacement
end

function visit(system,objecttypes)
   specify(objecttypes)
   openingflash(system,objecttypes)

   -- GET OBJECTS TO VISIT
   pos_table = {}
   pos_table.len = 0
   side_toggle_a = 1
   side_toggle_b = 1
   counter = 0
   --preload(system)
   filltable(system,1)
   num_objects = (pos_table.len - 1)

   -- VISIT OBJECTS!
   -- begin tour with intro on screen
   if num_objects == 1 then
      celestia:print(INTRO .. "\n\nTouring " .. num_objects .. " object in " .. system:name() .. " system", 7, 0, 0, -20, 0)
   else
      celestia:print(INTRO .. "\n\nTouring " .. num_objects .. " objects in " .. system:name() .. " system", 7, 0, 0, -20, 0)
   end

   t = 1
   date = celestia:gettime()

   offset = celestia:newvector(8e-7*system:radius(),0,0)
   pos = pos_table[t-1]:getposition():addvector(offset)
   velocity = celestia:newvector(1e-5,0,0)

   o = celestia:getobserver()
   o:setposition(pos)

   -- starting speed: 2mly / step
   min_speed = 2

   -- distance to/from target where we maintain constant speed
   -- this is the starting value, to get away from sun
   const_speed_distance = pos_table[t-1]:radius()*1

   time = celestia:getscripttime()

   last_target_pos = pos

   celestia:select(pos_table[0])
   -- walk the position-table:
   while t < pos_table.len do   
      next_target = pos_table[t]
 
      past_midpoint = false
 
      -- get position where we should be heading and distance to target
      -- next_target_pos = next_target:getposition():addvector(offset)
      next_target_pos = getposfromobject(pos_table[t-1], pos_table[t])
      offset = celestia:newvector(8e-7*pos_table[t]:radius(),0,0)

      -- overall distance
      dist = pos:distanceto(next_target_pos)
 
      -- :TODO: convert this from dist (we need this in microly instead of km)
      dist_mly = length(pos:vectorto(next_target_pos))
 
      -- select next target when within dist_trigger to planet
      radius = math.max(10, next_target:radius())
      dist_trigger = radius*5
 
      -- emergency trigger if first trigger fails
      -- (could happen if we blast by too fast - current parameters should avoid this)
      dist_emergency_trigger = dist / 3
      last_dist = dist
 
      -- current distance to target
      d = dist
 
      -- INNER LOOP: approach to next target, exit loop when there
      while d > dist_trigger do
         local time2 = celestia:getscripttime()
         local dt = math.max(0.005, math.min(0.2, time2 - time))
         time = time2
     
         -- use this to correct for moving bodies while in flight
         celestia:settime(date)
         -- next_target_pos = next_target:getposition():addvector(offset)
     
         -- distance to target (in "dist"-units, i.e. should vary between ~1 and 0)
         a = d / dist

         -- now compute velocity envelope: go slow when near planet, go really fast between
     
         -- speed is a funcion of distance to/from target, and
         -- distance is computed as:
         if a > 0.5 then
            -- distance from previous target:
            ref_distance_km = dist - d
         else
            if not past_midpoint then
               -- this is executed once between src and target
               celestia:select(next_target)
               past_midpoint = true
               celestia:print("Object " .. counter+1 .." of " .. num_objects .. ": ".. next_target:name(), 7, 0, 0, -20, -10)
            end
            -- distance to next target:
            ref_distance_km = d
         end
     
         -- reset const_speed_distance when approaching next target
         -- leave intact while going away from last target
         -- (avoid instantaneous velocity boost)
         if a < 0.5 then
            const_speed_distance = dist_trigger*2
         end
     
         -- compute distance to target (when approaching) or
         -- from last target
         ref_distance_km = math.max(const_speed_distance, ref_distance_km)
         ref_distance_mly = ref_distance_km / KM_PER_MLY
       
         -- speed is computed as:
         -- speed = distance_to_target / time_to_reach_target
         -- distance_to_target is of couse
         speed = ref_distance_mly / base_speed_timestep
     
         -- inertia controls how quick the direction of view changes.
         --
         -- To make the script behave mostly identical for different FPS, we
         -- must change inertia depending on the time between two frames.
         -- inertia doesn't have a linear influence, but this first-order
         -- approximation should suffice.
         --
         -- if dt == 0, inertia = 1, for dt >= 0.1, inertia = 0.1*base_inertia
         inertia = 1 - (math.min(0.1, dt)*(1-base_inertia))
         -- camera must change quicker when getting near target,
         -- otherwise we could miss the target,
         -- therefore adjust proportionally to distance to target
         -- (but don't set to >= 1)
         inertia = math.max(0.5, math.min(a,1)*inertia)
     
         direction = pos:vectorto(next_target_pos)     
         -- normalized direction
         dir_norm = normalize(direction)
     
         -- normalized velocity
         -- cant use vector:normalize because length may be to small
         vel_norm = normalize(velocity)

         -- This is the most important part:
         -- compute the new velocity, by choosing a direction
         -- between the former velocity and the direction we have to go.
     
         new_velocity_direction = (inertia * vel_norm + (1-inertia)*dir_norm)
     
         velocity = speed * dt * new_velocity_direction:normalize()
     
         newpos = pos + velocity
     
         -- look in direction of movement     
         o:setposition(pos)
         o:lookat(getcameratarget(last_target_pos, next_target:getposition(), pos, 1-a), UP)     
     
         pos = newpos
         d = pos:distanceto(next_target_pos)
     
         -- check emergency trigger?
         if d < dist_emergency_trigger then
            -- real check: are we going away again?
            if d > last_dist then
               -- this is an error, print message
               celestia:flash("Ah, I just missed my target - continuing with next target!",2)
               --counter = counter - 1
               wait(2)
               break
            end
         end
         last_dist = d
         wait(0.01)
      end
 
      last_target_pos = next_target:getposition()
      t = t + 1
      counter = counter + 1
   end

   o:follow(pos_table[pos_table.len-1])
   
   touringtime = celestia:getscripttime() - touringtime

   if num_objects == 1 then
      celestia:flash("Completed touring " .. counter .. " object in " .. system:name() .. " system in about 1 minute",10)
   else
      if math.floor(touringtime/60) <= 1 then
         celestia:flash("Completed touring " .. counter .. " objects in " .. system:name() .. " system in about 1 minute",10)
   else
         celestia:flash("Completed touring " .. counter .. " objects in " .. system:name() .. " system in " .. math.floor(touringtime/60) .. " minutes",10)
      end
   end
   wait(10)

   touringtime = celestia:getscripttime()

   return
end

function tour(systemcentrename,objecttypestoview)
   systemcentre = celestia:find(systemcentrename)
   if systemcentre:name() == "?" then
      celestia:flash(systemcentrename .. " system NOT FOUND")
      wait(2.0)
   else
      visit(systemcentre,objecttypestoview)
   end
   return
end


-- *************** MAIN PROGRAM **************

workaroundwindowsbug()
--get_users_orig_renderflags()
setrenderflags()
initializemainprogram()
tourspecifiedsystems()
resetusersrenderflags()
celestia:flash("ALL TOURS COMPLETE",15)
wait(2.0)

--EOP


I hope this helps as a reference.


Janus.

Topic author
raylier
Posts: 4
Joined: 26.04.2020
With us: 4 years

Post #4by raylier » 25.07.2020, 22:13

Downloaded from motherlode..

My change:

Code: Select all

function preload(obj)
    if obj:type() == "planet" then
        if obj:radius() < 1 then
           return
        end
        celestia:print("Preloading en dergelijke " .. obj:name(), 10, 0, 0, -20, 0)
        local p = obj:getposition()
        local r = obj:radius()
        local v = celestia:newvector(1,0,0)
        v = (4 * r) / KM_PER_MLY * v
        celestia:getobserver():setposition(p + v)
        celestia:getobserver():lookat(p, UP)
        wait(0.1)
        if obj:type() == "planet" then
         
         --  local children = obj:getchildren()
         --  for i, c in ipairs(children) do
         --     preload(c)
        --   end
        end
    end
end


Added after 26 minutes 57 seconds:
Janus,

Thanks. I'll take a closer look at v1.2.

Greetz
Ray

Janus
Posts: 537
Joined: 13.08.2016
With us: 7 years 8 months

Post #5by Janus » 26.07.2020, 02:13

@raylier

Try something like this.
I didn't run it, this is off the cuff.
The problem is that because of the unitized nature of object storage, SOL, the planets, the moons, dwarfplanets, minormoons and such are all in one list, which is cycled through.
In order to only see the planets, you have to filter for them when making the table to cycle through.
I think you will understand easily.
Keep the child test in preload() turned off to make the script run faster.
However, not loading the moon textures might cause stutters depending on the moon's visibility when you pass close or by the planet.

{I may be in minority, but Pluto will always be a planet to me.}

Code: Select all

function filltable(obj, depth)
    pos_table[pos_table.len] = obj
    pos_table.len = pos_table.len + 1
    local i, v
    local children = obj:getchildren()
    for i, v in ipairs(children) do
        if v:radius() < 1 or v:name() == "Galileo" then
            --celestia:flash("ignoring: " .. v:name())
            --wait(2)
        else
            --if depth <= 2 then
            --    filltable(v, depth+1)
            --end
         if v:type() == "planet" or v:type() == "dwarfplanet" then
            pos_table[pos_table.len] = v
            pos_table.len = pos_table.len + 1
            preload(v)
         end
        end
    end
end


I hope this helps.


Janus.

Topic author
raylier
Posts: 4
Joined: 26.04.2020
With us: 4 years

Post #6by raylier » 26.07.2020, 13:23

Janus.. the function filltable you adjusted works great. Thanks.

BTW: the v1.2 stops after preloading Neptune. Some bug?

Grtz
Ray

Janus
Posts: 537
Joined: 13.08.2016
With us: 7 years 8 months

Post #7by Janus » 26.07.2020, 14:39

Does it display any of the planets, or just stop at the preload?
Either way, I would start the troubleshooting in the notspecifiedtype() routine.

The scripts were written pre new horizons, before some people I disagree with decided pluto was not a planet.
I think they are wrong and in this specific case, potentially id 10 ts.
Even if it were just honorary, it should have stayed, and in my mind, it is and always will be.

The reason I bring it up is the same the other script.

From: notspecifiedtype

Code: Select all

if viewplanetsonly and obj:type() == "planet" then
    wrongtype = false
end


I would start by adding

Code: Select all

if viewplanetsonly and obj:type() == "dwarfplanet" then
    wrongtype = false
end


Then see if it runs.
I don't have time to test right now, I am swamped with this whole shutdown thing, and a snapshot just rendered.
Customers who have always refused to give me time find hte actual problems instead of just make it work, are all screaming "We're shutdown now, fix it for real, fix it for real now."
I'm gonna need a vacation before this is done.


Janus.

Topic author
raylier
Posts: 4
Joined: 26.04.2020
With us: 4 years

Post #8by raylier » 26.07.2020, 14:59

Janus...

I found out that after the Neptune preload it takes some time to run.
So it works. Thanks again.

Greetz
Ray

Duglis
Posts: 42
Joined: 13.10.2020
Age: 60
With us: 3 years 6 months
Location: Southern California

Post #9by Duglis » 14.10.2020, 22:01

where can this be downloaded at this time? the latest tour? :)


Return to “Scripting”