I used Toti's script from MARS FLUG in the scripts section in the motherlode, to create a nice trajectory arround the earth, it was not easy in the beginning , but finally I've got it!
I ceated new camera coordinates and the text I changed by spaces (because text length's is used as a factor of time between points of the trajectory).
Hope you like.
A.
Code: Select all
--This is a modified version of MarsFlug.celx for a nice trajectory over the Earth. by dimaVJ.
--Thanks Toti and Celestia team!
--I changed only the coordinates, and the text by spaces. and the selected object (Earth obviously)
--***************************************************************************
-- Rundflug ?ber den Mars (MarsFlug.celx)
--
-- Lauff?hig ab Celestia 1.3.2
-- Laufzeit: etwa 7 Minuten
--
--***************************************************************************
-- An non-uniform B-Spline approximation algorithm
-- Applied to Mars touring
--
-- Coded by Toti
-- Translated by Adirondack, 23. August 2004 (v1.0)
--
--***************************************************************************
--***************************************************************************
--***************************************************************************
-- 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/Earth"
ZERO = celestia:newposition (0, 0, 0)
OBS = celestia:getobserver()
ORDER = 3 -- order of the curve. Increase for additional smoothness
IM_WIDTH = 1000 -- texture dimensions used as input for the Control Points
IM_HEIGHT = 500
-- 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 = {
{ 450, 220, 8, 260, 80, 0.2, " "},
{ 130, 100, 1.6, 180, 120, 1.1, " "},
{ 900, 190, 1.5, 0, 160, 1, " "} ,
{ 700, 290, 2, 900, 260, 1, " "},
{ 650, 290, 8, 700, 200, 1, " "} ,
{ 630, 250, 18, 600, 190, 1, " "}
}
-- *********************************************************
-- 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, oldAmb}
else
P[i] = {pos.x, pos.y, pos.z, view.x, view.y, view.z, i, oldAmb}
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