Celestia/Celx Scripting/CELX Lua Methods/CEL command gotoloc

From Wikibooks, open books for an open world
Jump to navigation Jump to search

gotoloc[edit | edit source]

gotoloc { time <duration> position <vector> xrot <xrot> yrot <yrot> zrot <zrot> }

-- OR --

gotoloc { time <duration> x <xbase64> y <ybase64> z <zbase64> ow <ownumber> ox <oxnumber> oy <oynumber> oz <oznumber> }

Move the camera to the currently selected object, taking <duration> seconds, traveling to the specified position (or the Base64 values x, y, and z from a Cell://URL), using the orientation specified via xrot, yrot, and zrot (or ow, ox, oy, and oz).

Arguments:

time <duration>
Number of seconds to take centering the object. Default is 1.0 second.
position <vector>
Defines a point in the current Coordinate System specified in units of kilometers. Default is [0 1 0].
For all but the universal Coordinate System, a position of [ 0 0 0 ] is the center of the object
The kilometer value you specify must include the radius of the object.
  • The 1st value <xnumber> represents the camera location, in kilometers, along the X axis.
  • The 2nd value <ynumber> represents the camera location, in kilometers, along the Y axis.
  • The 3rd value <znumber> represents the camera location, in kilometers, along the Z axis.
xrot <xrot>
The "Eular Angle" or "Angle-Axis" representation of the camera's orientation in degrees. Default is 0.
Think of it as Pitch in aviation.
yrot <yrot>
The "Eular Angle" or "Angle-Axis" representation of the camera's orientation in degrees. Default is 0.
Think of it as Yaw in aviation.
zrot <zrot>
The "Eular Angle" or "Angle-Axis" representation of the camera's orientation in degrees. Default is 0.
Think of it as Roll in aviation.

-- OR --

Arguments:

time <duration>
Number of seconds to take centering the object. No default.
x <xbase64>
This value represents the X position as stored by a CelURL. No default.
The value can be obtained from the CelURL value after: ?x=
y <ybase64>
This value represents the Y position as stored by a CelURL. No default.
The value can be obtained from the CelURL value after: &y=
z <zbase64>
This value represents the Z position as stored by a CelURL. No default.
The value can be obtained from the CelURL value after: &z=
ow <ownumber>
This value represents the OW orientation as stored by a CelURL. No default.
The value can be obtained from the CelURL value after: &ow=
ox <oxnumber>
This value represents the OW orientation as stored by a CelURL. No default.
The value can be obtained from the CelURL value after: &ox=
oy <oynumber>
This value represents the OW orientation as stored by a CelURL. No default.
The value can be obtained from the CelURL value after: &oy=
oz <oznumber>
This value represents the OW orientation as stored by a CelURL. No default.
The value can be obtained from the CelURL value after: &oz=


CELX equivalent-1:

Based on Parameter list-1 and the observer:setorientation() and observer:gotolocation() methods.

Note: The disadvantage of this combination of methods is the sequential execution of these methods and the new observer orientation is set at once instead of smoothly during the goto.

  • Create new position object from <xnumber>, <ynumber> and <znumber> and store in "pos".
    The units of the components of a position object are millionths of a light-year, so you have to convert km to millionths of a light year, using the "uly_to_km" constant.
uly_to_km = 9460730.4725808
pos = celestia:newposition( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/uly_to_km )
  • Specify and create the axis of this rotation [ <xrot> , <yrot> , <zrot> ] and store it in "vec".
    <xrot> , <yrot> and <zrot> are the "Eular Angle" or "Angle-Axis" representation of the camera's orientation in degrees.
    Think of them as Pitch, Yaw, and Roll in aviation.
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
  • Create new rotation (i.e. a quaternion) about the specified axis and store in "rot".
    "angle" = math.pi / 180 (= 3.14159265 / 180), to obtain radians out of degrees.
angle = math.pi/180
rot = celestia:newrotation(vec, angle)
  • Get observer instance of the active view instance and rotate the observer according the created new rotation "rot".
obs = celestia:getobserver()
obs:setorientation(rot)
  • Go to target position "pos" in <duration> seconds.
obs:gotolocation(pos, <duration> )
  • Wait <duration> seconds.
wait( <duration> )

Summarized:

uly_to_km = 9460730.4725808
pos = celestia:newposition( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/uly_to_km )
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
angle = math.pi/180
rot = celestia:newrotation(vec, angle)
obs = celestia:getobserver()
obs:setorientation(rot)
obs:gotolocation(pos, <duration> )
wait( <duration> )


CELX equivalent-2:

Based on Parameter list-2 and the observer:setorientation() and observer:gotolocation() methods.

Note: The disadvantage of this combination of methods is the sequential execution of these methods and the new observer orientation is set at once instead of smoothly during the goto.

  • Create new position object from URL-style Base64-encoded values and store in "pos".
    <xbase64>: The X-component of the new vector, as a string-value taken from a cel-style URL ?x=.
    <ybase64>: The Y-component of the new vector, as a string-value taken from a cel-style URL &y=.
    <zbase64>: The Z-component of the new vector, as a string-value taken from a cel-style URL &z=.
pos = celestia:newposition( <xbase64>, <ybase64>, <zbase64> )
  • Create new rotation (i.e. a quaternion) from four scalar values (the values used in a CEL://URL), and store in "rot".
    <ownumber>: The OW-component of the new rotation, as a number-value taken from a cel-style URL &ow=.
    <oxnumber>: The OX-component of the new rotation, as a number-value taken from a cel-style URL &ox=.
    <oynumber>: The OY-component of the new rotation, as a number-value taken from a cel-style URL &oy=.
    <oznumber>: The OZ-component of the new rotation, as a number-value taken from a cel-style URL &oz=.
rot = celestia:newrotation( <ownumber>, <oxnumber>, <oynumber>, <oznumber> )
  • Get observer instance of the active view and rotate the observer according the created new rotation "rot".
obs = celestia:getobserver()
obs:setorientation(rot)
  • Go to target position “pos” in <duration> seconds.
obs:gotolocation(pos, <duration> )
  • Wait <duration> seconds.
wait( <duration> )

Summarized:

pos = celestia:newposition( <xbase64>, <ybase64>, <zbase64> )
rot = celestia:newrotation( <ownumber>, <oxnumber>, <oynumber>, <oznumber> )
obs = celestia:getobserver()
obs:setorientation(rot)
obs:gotolocation(pos, <duration> )
wait( <duration> )


CELX equivalent-3:

Based on the observer:goto(table) method.

Using this method, many different types of gotos can be performed. The strength of this method is that the observer orientation can be programmed and interpolated, so the orientation of the observer can be changed during the goto.

This method uses position objects to goto and rotation objects to set the observer orientation. Both positions and rotations can be extracted from Parameter list-1 and Parameter list-2 arguments. The parameters for the goto must be given in the table:

    • parameters.duration: duration (number)
    • parameters.from: source position
    • parameters.to: target position
    • parameters.initialOrientation: source orientation
    • parameters.finalOrientation: target orientation
    • parameters.startInterpolation:
    • parameters.endInterpolation:
    • parameters.accelTime:


  • Get observer instance of the active view and store in "obs".
obs = celestia:getobserver()
  • Define and initialize the parameter table as follows:
    • Determine the number of seconds the goto should take.
    • Obtain the current position of the observer.
    • Create new position object. There are 2 possibilities regarding the originally used CEL parameterlist:
      • from <xnumber>, <ynumber> and <znumber> and store in "parameters.to". The units of the components of a position object are millionths of a light-year, so you have to convert km to millionths of a light year, using “uly_to_km”.
        Note: The given positions are expected to be relative to the universal frame-of-reference, while the non table-based goto uses positions relative to the current frame-of-reference. So depending on the used frame of reference, you have to convert the position first to universal!
      • from URL-style Base64-encoded values and store in "parameters.to":
        <xbase64>: The X-component of the new vector, as a string-values taken from a cel-style URL ?x=.
        <ybase64>: The Y-component of the new vector, as a string-values taken from a cel-style URL &y=.
        <zbase64>: The Z-component of the new vector, as a string-values taken from a cel-style URL &z=.
    • Obtain the current orientation of the observer.
    • Create new rotation object. There are 2 possibilities regarding the originally used CEL parameterlist:
      • Specify and create the axis of the observer rotation [<xrot> , <yrot> , <zrot> ] and store it in "vec". <xrot> , <yrot> and <zrot> are the "Eular Angle" or "Angle-Axis" representation of the observer orientation in degrees. Think of them as Pitch, Yaw, and Roll in aviation. Then create new rotation (i.e. a quaternion) about the specified axis and use "angle" = math.pi/180 (= 3.14159265 / 180), to obtain radians out of degrees. Store this new rotation in "parameters.finalOrientation".
      • from four scalar values (the values used in a CEL://URL), and store in "parameters.finalOrientation".
        <ownumber>: The OW-component of the new rotation, as a number-value taken from a cel-style URL &ow=.
        <oxnumber>: The OX-component of the new rotation, as a number-value taken from a cel-style URL &ox=.
        <oynumber>: The OY-component of the new rotation, as a number-value taken from a cel-style URL &oy=.
        <oznumber>: The OZ-component of the new rotation, as a number-value taken from a cel-style URL &oz=.
    • Start adjusting the observer orientation after 20 percent of the time to goto.
    • End adjusting the observer orientation after 80 percent of the time to goto.
    • Spend 10% of the time for accelerating and decelerating
parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
uly_to_km = 9460730.4725808
parameters.to = celestia:newposition( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/uly_to_km )
parameters.initialOrientation = obs:getorientation()
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
angle = math.pi/180
parameters.finalOrientation = celestia:newrotation(vec, angle)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters. accelTime = 0.1

-- OR --

parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
parameters.to = celestia:newposition( <xbase64>, <ybase64>, <zbase64> )
parameters.initialOrientation = obs:getorientation()
parameters.finalOrientation = celestia:newrotation( <ownumber>, <oxnumber>, <oynumber>, <oznumber> )
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters. accelTime = 0.1
  • Goto target position with target orientation in <duration> seconds.
obs:goto(parameters)
  • Wait <duration> seconds.
wait(parameters.duration)


Summarized:

-- Use the following block of code for target positions
-- relative to the universal frame-of-reference:
obs = celestia:getobserver()
parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
uly_to_km = 9460730.4725808
parameters.to = celestia:newposition( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/uly_to_km )
parameters.initialOrientation = obs:getorientation()
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
angle = math.pi/180
parameters.finalOrientation = celestia:newrotation(vec, angle)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
obs:goto(parameters)
wait(parameters.duration)

-- OR --

–- Use the following block of code for target positions
-- relative to the ecliptic (follow) frame of reference,
-- with "objectname" as reference object.
obs = celestia:getobserver()
objectname = celestia:find( <string> )
obs:follow(objectname)
parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
uly_to_km = 9460730.4725808
vector = celestia:newvector( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/ uly_to_km )
objectpos = objectname:getposition()
parameters.to = objectpos + vector
parameters.initialOrientation = obs:getorientation()
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
angle = math.pi/180
parameters.finalOrientation = celestia:newrotation(vec, angle)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
obs:goto(parameters)
wait(parameters.duration)

-- OR --

obs = celestia:getobserver()
parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
parameters.to = celestia:newposition( <xbase64>, <ybase64>, <zbase64> )
parameters.initialOrientation = obs:getorientation()
parameters.finalOrientation = celestia:newrotation( <ownumber>, <oxnumber>,  <oynumber>, <oznumber> )
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
obs:goto(parameters)
wait(parameters.duration)

Example:
The next example demonstrates both gotoloc methods. It travels to the Earth, setting a position so you can see the night lights over the USA, view the Sun in the upper left hand corner of the display, and the Moon in the upper right hand corner.

Note: The lines of code starting with "#" (CEL) and "--" (CELX) are comment lines for further explanation:

Note: The CelURL values in this example are compatible with Celestia version 1.6.0.

CEL:

# Pause time and set the date and time to 2003 Aug 23 04:37:24 UTC
  timerate  { rate 0 }
  time      { jd 2452874.692638889 }
# Activate markers, clear all existing markers and
# place a blue square marker around the Moon...
  renderflags { set "markers" }
  unmarkall { }
  mark      { object "Sol/Earth/Moon" size 20.0 color [0 0 1] symbol "square" }
# Set the Field Of View value to 47.0 degrees...
  set       { name "FOV" value 47.0 }
# Select, follow and center Earth (so the coordinate system
# of the frame of reference is set to ecliptic).
  select    { object "Sol/Earth" }
  follow    { }
  center    { }
  wait      { duration 1 }
# Goto location: X = +7000km, Y = +9000km, Z = +11000km.
# Pitch Up +13 degrees (down = -), Yaw Left -32 degrees (right = +),
# Roll 0 degrees (left = - , right = +)
  gotoloc   { time 5 position [7000 9000 11000] xrot 13 yrot -32 zrot 0 }
  wait      { duration 5 }
  print     { text "Blue square is the Moon ---" duration 4 row -24 column 32 }
  wait      { duration 6 }
  print { text "First result done." duration 3 row -3 column 2 }
  wait { duration 3 }
  cancel { }
# Goto location using URL-style Base64-encoded values.
  gotoloc { time 5 x "AAAAbtdBM3XLDA" y "aG/b0Q34Pw" z "AABiyVOKuxUI"
            ow 0.703773 ox 0.068516 oy -0.703786 oz 0.068514 }
  wait { duration 5 }
  print { text "Second result done." duration 4  row -3 column 2 }
  wait { duration 4 }

CELX-1 with observer:gotolocation() method:

-- Pause time and set the date and time to 2003 Aug 23 04:37:24 UTC.
-- First convert UTC to TDB date/time:
--    UTC is used in the Celestia's Set Time dialog and it's also
--    the time displayed in the upper right of the screen.
--    TDB = Barycentric Dynamical Time.
--    When using scripts for Celestia, the time scale is TDB !!!
celestia:settimescale(0)
dt=celestia:utctotdb(2003, 08, 23, 04, 37, 24)
celestia:settime(dt)
-- Activate markers, clear all existing markers and
-- place a blue square marker around the Moon...
celestia:setrenderflags{markers=true}
celestia:unmarkall()
moon = celestia:find("Sol/Earth/Moon")
moon:mark("blue", "square", 20.0)
-- Set the Field Of View value to 47.0 degrees.
-- In CELX, angles are stored in radians, instead of degrees, so you have to convert
-- degrees to radians by multiplying degrees with math.pi (= 3.14159265) and divide
-- by 180. The LUA "math.rad()" function can also be used for this.
obs = celestia:getobserver()
obs:setfov(47*math.pi/180)
-- Select, follow and center Earth (so the coordinate system
-- of the frame of reference is set to ecliptic).
earth = celestia:find("Sol/Earth")
celestia:select(earth)
obs:follow(earth)
obs:center(earth, 1.0)
wait(1.0)
-- Goto location: X = +7000km, Y = +9000km, Z = +11000km.
-- Pitch Up +13 degrees (down = -),
-- Yaw Left -32 degrees (right = +),
-- Roll 0 degrees (left = - , right = +)
obs = celestia:getobserver()
-- In CELX, angles are stored in radians, instead of degrees, so you have to convert
-- degrees to radians by multiplying degrees with math.pi (= 3.14159265) and divide
-- by 180. The LUA "math.rad()" function can also be used for this.
vec = celestia:newvector(13, -32, 0)
angle = math.pi/180
-- Set the observer orientation:
rot = celestia:newrotation(vec, angle)
obs:setorientation(rot)
-- In CELX, positions are stored in millionths of a light year,
-- so you have to convert km to millionths of a light year, using "uly_to_km".
uly_to_km = 9460730.4725808
pos = celestia:newposition(7000/uly_to_km, 9000/uly_to_km, 11000/uly_to_km)
-- Goto target position.
obs:gotolocation(pos, 5.0 )
wait(5.0)
celestia:print("Blue square is the Moon ---" , 4.0, -1, -1, 32, 24)
wait(6.0)
celestia:print("First result done.", 3.0, -1, -1, 2, 3)
wait(3.0)
-- Cancel GOTO and TRACK commands, and reset the Coordinate System to universal.
obs:cancelgoto()
obs:track(nil)
obs:setframe(celestia:newframe("universal"))
-- Goto target position, using URL-style Base64-encoded values.
obs = celestia:getobserver()
rot = celestia:newrotation(0.703773, 0.068516, -0.703786, 0.068514)
obs:setorientation(rot)
pos = celestia:newposition("AAAAbtdBM3XLDA", "aG/b0Q34Pw", "AABiyVOKuxUI")
obs:gotolocation(pos, 5.0 )
wait(5.0)
celestia:print("Second result done.", 4.0, -1, -1, 2, 3)
wait(4.0)

CELX-2 with observer:goto(table) method:

-- Pause time and set the date and time to 2003 Aug 23 04:37:24 UTC.
-- First convert UTC to TDB date/time:
--    UTC is used in the Celestia's Set Time dialog and it's also
--    the time displayed in the upper right of the screen.
--    TDB = Barycentric Dynamical Time.
--    When using scripts for Celestia, the time scale is TDB !!!
celestia:settimescale(0)
dt=celestia:utctotdb(2003, 08, 23, 04, 37, 24)
celestia:settime(dt)
-- Activate markers, clear all existing markers and
-- place a blue square marker around the Moon...
celestia:setrenderflags{markers=true}
celestia:unmarkall()
moon = celestia:find("Sol/Earth/Moon")
moon:mark("blue", "square", 20.0)
-- Set the Field Of View value to 47.0 degrees.
-- In CELX, angles are stored in radians, instead of degrees, so you have to convert
-- degrees to radians by multiplying degrees with math.pi (= 3.14159265) and divide
-- by 180. The LUA "math.rad()" function can also be used for this.
obs = celestia:getobserver()
obs:setfov(47*math.pi/180)
-- Select, follow and center Earth (so the coordinate system
-- of the frame of reference is set to ecliptic).
earth = celestia:find("Sol/Earth")
celestia:select(earth)
obs:follow(earth)
obs:center(earth, 1.0)
wait(1.0)
-- Goto location: X = +7000km, Y = +9000km, Z = +11000km, relative to Earth !!!!
-- Pitch Up +13 degrees (down = -),
-- Yaw Left -32 degrees (right = +),
-- Roll 0 degrees (left = - , right = +)
obs = celestia:getobserver()
parameters={}
parameters.duration = 5.0
parameters.from = obs:getposition()
-- In CELX, positions are stored in millionths of a light year,
-- so you have to convert km to millionths of a light year, using "uly_to_km".
uly_to_km = 9460730.4725808
vec = celestia:newvector(7000/uly_to_km, 9000/uly_to_km, 11000/uly_to_km)
earthpos = earth:getposition()
parameters.to = earthpos + vec
parameters.initialOrientation = obs:getorientation()
-- In CELX, angles are stored in radians, instead of degrees, so you have to convert
-- degrees to radians by multiplying degrees with math.pi (= 3.14159265) and divide
-- by 180. The LUA "math.rad()" function can also be used for this.
vec = celestia:newvector(13, -32, 0)
angle = math.pi/180
-- Set the observer orientation:
parameters.finalOrientation = celestia:newrotation(vec, angle)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
-- Goto target position.
obs:goto(parameters)
wait(parameters.duration)
celestia:print("Blue square is the Moon ---" , 4.0, -1, -1, 32, 24)
wait(6.0)
celestia:print("First result done.", 3.0, -1, -1, 2, 3)
wait(3.0)
-- Cancel GOTO and TRACK commands, and reset the Coordinate System to universal.
obs:cancelgoto()
obs:track(nil)
obs:setframe(celestia:newframe("universal"))
-- Goto target position, using URL-style Base64-encoded values.
parameters={}
parameters.duration = 5.0
parameters.from = obs:getposition()
parameters.to = celestia:newposition("AAAAbtdBM3XLDA", "aG/b0Q34Pw", "AABiyVOKuxUI")
parameters.initialOrientation = obs:getorientation()
parameters.finalOrientation = celestia:newrotation(0.703773, 0.068516, -0.703786, 0.068514)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
-- Goto target position.
obs:goto(parameters)
wait(parameters.duration)
celestia:print("Second result done.", 4.0, -1, -1, 2, 3)
wait(4.0)


Back to CEL command index