# Celestia/1.6.0 Files

This page gives an explanation of some of the new features in Celestia 1.6.0. It is targeted at add-on creators who have some familiarity with making SSC files for earlier versions of Celestia. Each feature description is divided into two sections: background and 1.6.0 changes. The background section explains how a particular features of Celestia works in 1.5.0 and provides some motivation for why enhancements were made in 1.6.0. In all cases, backward compatibility with Celestia 1.5.0/1.5.1 has been maintained: add-ons written for 1.5.0 will work identically in 1.6.0.

# New Object Classes

## Background

A body in an SSC files may be assigned a class that determines how it is categorized in Celestia's solar system browser. In some cases, the body's class also controls certain aspects of its appearance. For example, cometary dust tails are only shown for objects marked as class comet. Here is a typical usage in Celestia 1.5.0:

"Ceres" "Sol"
{
Class "asteroid"
...
}

The available classes in Celestia 1.5.0 are:

* planet
* moon
* asteroid
* comet
* spacecraft
* invisible

## 1.6.0 Changes

The 1.5.0 object classes are unchanged, but Celestia 1.6.0 adds several new object classes.

### dwarfplanet

In 2006, the IAU passed a controversial resolution on the definition of a planet. Pluto was stripped of its planet status and reclassified as a member of the a new category of objects called dwarf planets. Ceres, the largest asteroid, and Eris, the largest known Kuiper belt object, were also designated dwarf planets. To date, these plus Makemake and Haumea are the only five objects recognized as dwarf planets by the IAU, but there are very likely to be more. A body may be marked as a dwarf planet by assigning it the class dwarfplanet:

"Ceres" "Sol"
{
Class "dwarfplanet"
...
}

In Celestia's 3D view window, dwarf planets are distinguished from planets with distinct orbit and label colors. Other than this, there is no difference between a dwarf planet and planet.

### minormoon

There are over a hundred known moons in the Solar System. Most of these moons are small rocks that orbit the outer planets. While it is interesting to be able to visualize the orbits of these moons, there are so many of them that turning on moon orbits results in a confusing "ball of string" around the outer planets. The new object class minor moon was introduced to address this problem. In the default Celestia solar system files, the small moons of outer planets are now designated as minor moons. Orbit and label display for minor moons may be toggled separately from the major moon labels and orbits. It is important to note that unlike dwarf planet, "minor moon" is not a term recognized by the IAU. The class was added to Celestia purely for the convenience of users. There's no hard and fast rule about what a minor moon is, but in general outer planet moons with a diameter less than 100 km are marked as minor.

Here's an example of using the minor moon class:

"Sinope" "Sol/Jupiter"
{
Class "minormoon"
...
}

### surfacefeature

Surface feature is a new class for objects that are fixed to the surface of another body, such as buildings and terrain features. Previously, there was simply no good classification for these objects. Lacking a better option, SSC creators tended to classify them as either asteroids or spacecraft. The surface feature class has one other useful property: surface features are not visible as points of light at a distance. While rendering very distant objects as points is a realistic effect for objects orbiting in space, it does not look good when applied to objects on the ground. In addition to this advantage, classifying appropriate objects means that they will be sensibly organized in the solar system browser.

Example:

"Space Needle" "Sol/Earth"
{
Class "surfacefeature"
Mesh "needle.cmod"
OrbitFrame { BodyFixed {} }
FixedPosition [ ... ]
...
}

### component

Objects with moving parts can be implemented in Celestia with multiple SSC objects. For example, a spacecraft with two movable solar panels could be defined as three objects: one for the main body of the spacecraft, and one object for each panel. Rather than defining all of the parts as spacecraft, only the main body should be a spacecraft and the other parts assigned the new class component. Like surface features, components are not rendered as points of light when they're far away from the viewer. This prevents the problem with multipart objects appearing overly bright at a distance. Using the class component appropriately also means that objects are better organized in the solar system browser.

Multi-part spacecraft example:

"Orbiter" "Sol/Mars"
{
Class "spacecraft"
Mesh "spacecraft-body.cmod"
...
}

"Solar Panel - Left" "Sol/Mars/Orbiter"
{
Class "component"
Mesh "spacecraft-leftpanel.cmod"
...
}

"Solar Panel - Right" "Sol/Mars/Orbiter"
{
Class "component"
Mesh "spacecraft-rightpanel.cmod"
...
}

### diffuse

Yet another set of objects that aren't good fits for any Celestia 1.5.0 class are dust clouds, accretion disks, volcanic plumes, and other extended, non-solid things. Celestia 1.6.0 adds a new class called diffuse for such objects. By default, diffuse objects cannot be clicked and selected by the user. They are never indicated with labels, nor are their trajectories shown when orbit paths are enabled. Lastly, they do not reflect light and result in "planetshine". This last point is important. Because diffuse objects are not solid, they may intersect other objects; under such circumstances, Celestia's reflected light calculation is not valid and will result in unrealistic lighting. Marking an object with class diffuse is the only way to tell Celestia that an object isn't solid and should be treated differently for the purpose of lighting.

Example:

"Loki Plume" "Sol/Jupiter/Io"
{
Class "diffuse"
Mesh "plume.cmod"
...
}

# Clickable property

## Background

A Celestia user can select an object by clicking on it in the 3D view. However, there are times when this is undesirable. An SSC author may define an extended, gaseous object such as an accretion disc with the idea that the viewer may move freely through it. When the camera is inside such an object, a click in any direction will select it—behavior that is likely confusing to users.

## 1.6.0 Changes

Celestia 1.6.0 offers a new boolean SSC property, Clickable. Specifying clickable false in an SSC body definition prevents that body from being selected when clicked. When a user click selects, an unclickable object is treated as if it weren't there at all; if there is a more distant object under the click point, that object will be selected instead.

Example:

"Accretion Disc" "Fomalhaut"
{
Mesh "disc.cmod"
Clickable false
...
}

Note that objects of class diffuse are not clickable by default. Thus, the above example is better written like this:

"Accretion Disc" "Fomalhaut"
{
Class "diffuse"
Mesh "disc.cmod"
...
}

If for some reason an SSC author wants to create a diffuse object that can be click selected, it is also possible to override the default unclickable status by setting the clickable property to true:

"Dust Cloud" "Sol"
{
Class "diffuse"
Mesh "cloud.cmod"
Clickable true
...
}

# Visible Property

## Background

When designing a dynamic Celestia body or when debugging a catalog file, it often is useful to have Celestia not draw an object.

## 1.6.0 Changes

The SSC directives

Visible true

and

Visible false

determine whether or not an object is drawn.

The default is

Visible true

For example:

"Dust Cloud" "Sol"
{
Class "diffuse"
Mesh "cloud.cmod"
Visible false
...
}

causes the cloud to be defined but not drawn.

The Visible property can be controlled in a CELX (Lua) script by calling the setvisible method:

local obj = celestia:find("Sol/Dust Cloud")
obj:setvisible(true)

# OrbitColor Property

## Background

Celestia allows users to toggle the display of orbit paths for planets, stars, moons, and other bodies. In version 1.5.0 of Celestia, new script commands were added for changing the color of the orbits shown for each class. But, there are situations where it is useful to have finer control over the colors of orbit paths. For example, a planetary system overview may be clearer if each planet is given a distinct orbit color.

## 1.6.0 Changes

The color of an SSC object's orbit can be modified by setting the OrbitColor property. In this example, we'll set the color of the Moon's orbit to yellow:

Modify "Moon" "Sol/Earth"
{
OrbitColor [ 1 1 0 ]
}

As with other color properties, the components of OrbitColor are values between 0 and 1, and are ordered red, green blue. The next example changes the orbit colors of all of the inner planets:

Modify "Mercury" "Sol"
{
OrbitColor [ 1 0.7 0.2 ]  # brown
}

Modify "Venus" "Sol"
{
OrbitColor [ 1 1 0.7 ]  # light yellow
}

Modify "Earth" "Sol"
{
OrbitColor [ 0.5 0.7 1 ]   # light blue
}

Modify "Mars" "Sol"
{
OrbitColor [ 1 0.6 0.6 ]   # light red
}

# Triaxial ellipsoids

## Background

Celestia has two ways to set the shape of an object:

• A 3D mesh file can be specified using the Mesh property, or...
• Celestia will assume that the object is an ellipsoid if the Mesh property is omitted

In Celestia 1.5.0, the size of the ellipsoid is controlled by the Radius property. The shape of the ellipsoid is given by the value of the oblateness property. Oblateness is the amount of flattening or stretching along the polar axis. The default value of oblateness is 0.0, indicating that the ellipsoid is a sphere. If the oblateness greater than zero, the planet will be appear squashed. This squashed sphere shape is called an oblate spheroid. Giant planets can be very noticeably non-spherical: fast rotation distorts them, causing a noticeable bulge at the equator. Even solid bodies such as Earth can be flattened to some extent, though less than giant planets.

Example of an oblate spheroid (oblateness < 1)

Oblateness is calculated as ${\displaystyle {\frac {a-b}{a}}}$, where a is the equatorial radius and b the polar radius. Saturn has the most extreme flattening of any planet in the Solar System, with an oblateness of 0.0980. Earth has an oblateness of about 0.00335--visually indistinguishable from a sphere when seen from space.

While most large Solar System bodies are accurately represented as oblate spheroids, there are a few that cannot be. Some moons of giant planets are noticeably stretched along the equatorial axis pointing toward the planet. Three axis lengths have to be given: the polar axis, and two different equatorial axes. The term 'triaxial ellipsoid' refers to an ellipsoid with three axes that are all different lengths.

## 1.6.0 Changes

The new SemiAxes property for SSC bodies is used to specify a triaxial ellipsoid. Images from the Cassini spacecraft show Saturn's moon Mimas to have a noticeably triaxial shape.

Its dimensions are 414.8×394.4×381.4 km. The first number is the length of the axis pointing toward Saturn, the second number is the axis along the orbit of Mimas, and the last number is the polar axis. In an SSC file, we'd write:

"Mimas" "Sol/Saturn"
{
SemiAxes [ 207.4 197.2 190.7 ]
...
}

Notice that since we're specifying the semiaxes not the axes, and thus the values are half the axis lengths. The relationship between axis and semiaxis is analogous to that between diameter and radius. The usage of the SemiAxes property is quite simple: you're essentially specifying three radii instead of just one. There are some subtleties in the interactions between the Radius, Oblateness, and SemiAxes properties:

• Radius is multiplied by the SemiAxes lengths if both properties are specified
• Oblateness is ignored if SemiAxes are given
• It is an error if neither SemiAxes nor Radius are specified

You can keep things simple and ignore these technicalities if you obey these guidelines:

• For spherical bodies, specify just the radius
• For oblate bodies, specify just the radius and oblateness
• For planets with triaxial ellipsoid shapes, specify just the semiaxes
• For irregular objects, specify just the mesh and radius

# Object timelines

Object timelines are a major new feature of Celestia 1.6.0. With a timeline, it is possible to describe the motion of an object over its entire lifetime, even when multiple trajectory types or reference frames are required. What used to require awkward SSC files with multiple definitions for the same object can now be done with a single object.

## Background

The motivation for adding Timeline to Celestia is best explained via an example. We'll consider the Cassini−Huygens mission to Saturn and Titan, which is included in the base Celestia package. The Huygens probe was attached to Cassini from launch until December 25, 2004. On that day, Huygens separated from Cassini and then orbited Saturn for three weeks on its own until descending into Titan's atmosphere on January 14, 2005. Now, how do we describe the trajectory of Huygens in an SSC file? For Cassini, we use a SampledTrajectory (xyz file) that covers the entire lifetime of the spacecraft. We could do something similar for Huygens: the xyz file would be identical up to the point of separation from Cassini. However, this is a lot of data duplication. It's also extra maintenance: if the Cassini trajectory is updated (after the separation time), we must also update the Huygens trajectory file. Finally, this technique only works if Cassini is not rotating, which in reality is not the case at all.

A more convenient and less wasteful approach would take advantage of the fact that Huygens and Cassini are joined together throughout their journey from Earth to Saturn. In Celestia 1.5.0, the only way to do this is to define two different versions of Huygens: one that's attached to Cassini, and another that's in orbit around Saturn. Here is the version that is attached to Cassini:

"Huygens (with Cassini)" "Sol/Cassini"
{
Class "spacecraft"
Mesh "huygens.3ds"

Beginning 2450736.893877314 # 1997 Oct 15 09:27:11
Ending    2453364.5847      # 2004 Dec 25 02:01:58

OrbitFrame { BodyFixed { Center "Sol/Cassini" } }
BodyFrame { BodyFixed { Center "Sol/Cassini" } }
FixedPosition [ -0.0013 0 -0.0002 ]
FixedRotation { }

}

The Ending property is set to the time of separation. At that point the version of "Huygens" attached to "Cassini" will disappear. Both the position and orientation of this "Huygens" is fixed relative to "Cassini": "Huygens" will follow every movement and rotation of the Cassini spacecraft. After separation "Huygens (with Cassini)" is replaced by this version:

"Huygens (free flight)" "Sol"
{
Class "spacecraft"
Mesh "huygens.3ds"

Beginning 2453364.5847 # 2004 Dec 25 02:01:58
Ending    2453384.8750 # 2005 Jan 14 09:00:00

SampledOrbit "huygens.xyz"

UniformRotation
{
Inclination 70
Period 0.01
}
}

Now, Huygens has its own trajectory and rotation. Its motion is defined relative to the Sun rather than to Cassini. But, there are drawbacks:

• We have to replicate all the data about Huygens not related to trajectory or orientation: the mesh, class, radius, infoURL, etc.
• A user is likely to be slightly confused by the fact that there are two instances of Huygens in the Solar System browser.
• Following Huygens as it separates from Cassini will not work; the camera will not track "Huygens (free flight)" after "Huygens (with Cassini)" disappears.

What we want is some way to give two different reference frames and trajectories for Huygens without creating to instances of the probe. This is exactly what object Timelines allow.

## 1.6.0 Changes

In Celestia 1.6.0, we can merge the two versions of Huygens into a single object.

"Huygens" "Sol/Cassini"
{
Class "spacecraft"
Mesh "huygens.3ds"

Timeline [
# Phase 1: With Cassini
{
Beginning "1997 19 15 09:27:11"
Ending    "2004 12 25 02:02:34"

OrbitFrame { BodyFixed { Center "Sol/Cassini" } }
BodyFrame { BodyFixed { Center "Sol/Cassini" } }
FixedPosition [ -0.0014 0 0.0002 ]
FixedRotation { Inclination 90 AscendingNode 90 }
}

# Phase 2: Free flight to Titan
{
Ending "2005 01 14 09:07:00"

OrbitFrame { EclipticJ2000 { Center "Sol/Saturn" } }
BodyFrame { EclipticJ2000 {} }

SampledTrajectory { Source "huygens.xyz" }
UniformRotation
{
Period 0.125            # 7.5 revolutions per minute
}
}
] # End Timeline
}

Observe the inside of the Timeline block, there are two sets of frames and trajectories. Each of these timeline sections is called a phase. The only things that are allowed in a phase are the beginning and ending time, trajectory, rotation model, body frame, and orbit frame. Timeline is not intended to be a general purpose system for animation, so there is no way to effect changes to the appearance of an object in a timeline phase by, say, putting a different model in each phase. Some other techniques will eventually be implemented to allow animation in Celestia.

### Beginning and Ending

The beginning and ending properties define the span covered by the phases of the timeline. Collectively, the phases cover a continuous span of time: no gaps are allowed. Continuity is guaranteed because for all phases but the first, the phase beginning time is automatically set to the ending time of the previous phase. The rules for beginning and ending times in timeline are summarized below:

First phase
Beginning may be specified, defaults to −infinity if it isn't
Ending must be specified if there is more than one phase
Last phase
Beginning must be specified if there is more than one phase
Ending may be specified, defaults to +infinity if it isn't
Other phases
Beginning is not allowed; it is automatically set to the Ending of the previous phase
Ending must be specified; there is no default value

A few examples will serve to illustrate various ways that a timeline can be divided into phases. In the first example, there is just a single infinite phase:

"Satellite1" "Sol/Earth"
{
Timeline [
{
EllipticalOrbit { ... }
}
]
}

Satellite1 is assigned an orbit that is valid over all time, because Beginning and Ending were omitted and have their defaults values of −infinity and +infinity. In this case, there's really no need to use a timeline at all. The object will behave identically to this simpler version:

"Satellite1" "Sol/Earth"
{
EllipticalOrbit { ... }
}

When there is just a single phase, there is no need to put the frames and trajectories in a timeline. A more useful timeline example is this definition of a lunar lander that is launched from Earth on 25 Feb 2010 and lands on the Moon on March 12th of the same year:

"Lunar Lander" "Sol/Earth"
{
Timeline [
# Phase 1: Launch and cruise
{
Beginning "2010 2 25 12:30"
Ending    "2010 3 12 15:30"
OrbitFrame { EquatorJ2000 { Center "Sol/Earth" } }
SampledTrajectory { Source "traj.xyzv" }
}

# Phase 2: Landed on the Moon
{
OrbitFrame { BodyFixed { Center "Sol/Earth/Moon" } }
FixedPosition [ ... ]
}
]
}

The landing time is defined in the first phase, so no beginning time is given (or allowed) in the second phase. Since there's no ending specified in the second phase, the lander will sit on the surface of the moon until the end of time.

# Position + Velocity Trajectories (xyzv files)

Using a new trajectory file format can simultaneously improve positioning accuracy and decrease memory usage.

## Background

Sampled trajectories are used when the trajectory of an object is not adequately described by an ellipse or one of Celestia's built-in orbit calculations. Typically, sampled trajectories are used for interplanetary spacecraft, but they can be useful for other objects as well. There are two ways to use sampled trajectories in an ssc or stc file. The old way uses SampledOrbit:

SampledOrbit "trajectory.xyz"

The new method added in 1.5.0 uses SampledTrajectory:

SampledTrajectory { Source "trajectory.xyz" }

SampledTrajectory should be preferred over SampledOrbit, as it offers options to control the precision (double or single) and the interpolation type (cubic or linear.) SampledOrbit always uses single precision positions, which is not adequate for serious spaceflight applications of Celestia.

A sampled trajectory file is a list of time and position records. Usually the files are generated from SPICE kernels or JPL's [[1]] system. Here's an excerpt from the trajectory file for Galileo:

2447818.615972 134114700.2612462193 64912642.6984842718 39861.799941
2447819.615972 133153386.7785827518 66969511.3118158504 237125.784089
2447820.615972 132137795.3581911474 69024279.8844281882 418499.867572
2447821.615972 131079666.1268854141 71061806.8872888833 596914.157647

The first value on each line is a Julian date, and that last three values are positions in kilometers. The reference frame for the positions is given in the ssc file. By default, Celestia uses a technique called cubic Hermite interpolation for smooth motion between points. For this discussion, the exact mathematics aren't important. What is relevant is that in order to interpolate between points, Celestia needs the velocity of the object as well as its position at each time. It's possible to estimate the velocity by looking at the difference in position between two successive points, but much improved accuracy is achievable saving velocities in the trajectory file.

## 1.6.0 Changes

Celestia 1.6.0 adds support for position and velocity trajectory files. These files have the extension xyzv, and can be used in exactly the same manner as xyz files in a SampledTrajectory:

SampledTrajectory { Source "trajectory.xyzv" }

The records in an xyzv file have the same layout as in an xyz file except that three velocity values are appended after each position. The units for velocity are kilometers per second. For a given file size, xyzv files give much more accurate positioning of objects. Thus, if it's possible to get velocities as well as positions for an object, an xyzv file should always be preferred over an xyz file. Celestia 1.6.0 will still support xyz files for backward compatibility and to cover situations where velocities are unavailable.

The web interface for HORIZONS can be used to produce trajectories with velocities as well as positions. There's also a new tool for Celestia called spice2xyzv that will generate an xyzv file from one or more SPICE kernels. Documentation on this tool is forthcoming.

# Multiple Names for SSC Objects

Objects defined in SSC files can now be assigned multiple aliases.

## Background

In Celestia 1.5.1, it is possible to assign more than one name to a star or deep sky object. This is important because there is often several commonly used designations for stars and galaxies. For example, the red giant Betelgeuse is often referred to by its Bayer designation Alpha Orionis. The Andromeda Galaxy is also as NGC 598 and by its Messier number M 33. The definition for Andromeda in a DSC file might look something like this:

"Andromeda Galaxy:M 33:NGC 598"
{
...
}

The names are delimited by colons.

## 1.6.0 Changes

1.6.0 simply adds the same multiname capability for SSC objects. As with stars and deep sky objects, names are delimited by colons. A common situation in which multiple names are useful is for minor planets. When first reported, a minor planet is assigned a provisional designation. After further observation it will get a minor planet number, and the IAU may eventually approve a proper name for the object as well. Thus, in an SSC file, you may have a definition like this:

Body "136199 Eris:Eris:2003 UB313" "Sol"
{
...
}

The first name in the list will be the one that appears in labels and in the solar system browser. All of the names will be shown in the upper left corner of the screen when the object is selected. Any of the names is valid in a path, so you could refer to Eris's moon Dysnomia as "Sol/136199 Eris/Dysnomia", "Sol/Eris/Dysnomia", or "Sol/2003 UB313/Dysnomia".

# Simplified Surface Placement

SurfaceObject "name" "path/parent" { ... }

Use of the SurfaceObject keyword invokes several useful defaults:

• The object's default OrbitFrame is the BodyFixed frame of the parent object
• The object's default BodyFrame is topocentric, with its Z axis pointing toward the zenith, its Y axis pointing toward the parent body's north pole, and its X axis pointing to the east.
• The object's default Class is "surfacefeature"

# Mesh placement and scaling

## Background

Celestia add-on creators face some difficulties when trying to place mesh objects precisely relative to each other. Celestia's "normalization" of mesh objects is the cause of some of these problems. When a mesh is normalized, it is scaled and centered so that its longest axis fits into a sphere with the specified radius of the object. The common workaround is to add identically sized invisible bounding box to objects that will be positioned close to each other. This ensures that the models will effectively share the same coordinate system.

While effective, creating these bounding boxes adds extra work for add-on creators. It also means that meshes end up getting incorrectly flagged as translucent for purposes of depth sorting.

## 1.6.0 Changes

Two new ssc properties solve the problem of mesh placement without resorting to adding bounding boxes:

# defaults to true for backward compatibility
NormalizeMesh <boolean>

# defaults to 1
MeshScale <number>

When an object has NormalizeMesh false specified, no automatic scaling and recentering of the mesh is done. The add-on creator must make sure to set the Radius of the object to a value large enough to contain it.

MeshScale converts the internal units of the model into kilometers as required by Celestia. For example, it is much more convenient to build a spacecraft in a system where the unit is one meter instead of one kilometer. For such a model, you would specify the MeshScale as 0.001.

Neither of these additions affect backward compatibility.