Simplifying surface feature placement
Posted: 06.06.2008, 23:48
It is quite a chore to correctly place and orient objects on the surface of a planet in Celestia. The difficulties are evident if you read this thread:
viewtopic.php?f=6&p=104425#p104425
A long discussion follows; if you'd rather skip it, the point is that it would be nice to place objects on the surface of planets using SSC definitions like this:
Positioning the object correctly isn't too hard if you use the LongLat property, but there are some catches:
The function of LongLat can be more elegantly handled with a BodyFixed frame and a FixedPosition trajectory. These both place an object on the surface of the Earth:
However, as is apparent from the code above, the elegance of the frame based approach is only conceptual and not syntactic. It's considerably harder to use FixedPosition and OrbitFrame, largely because the add-on creator must manually convert longitude, latitude, and altitude into rectangular coordinates for use with FixedPosition. So, the first addition I want to propose is a spherical coordinate version of FixedPosition. For lack of better ideas, it could be called SurfacePosition and have three values: longitude, latitude, and altitude (in kilometers). The simplified definition looks like this:
That's better, but it's still not as simple as using LongLat. The problem is that we have to explicitly set the frame. But what if we added a new object type with a different default frame? Add-on creators could use the new object type to place an object on the surface of a planet without ever being aware that they were dealing with frames. It might look like this:
This is as simple as LongLat. Explicitly declaring that the body is a surface object is a nice documentation bonus. But, the real payoff comes when we try and orient the object. Doing this right now is difficult because the parameters for orienting an object in space aren't intuitive for orienting an object on the surface of a planet. In Google Earth's KML files, the orientation parameters are heading, tilt, and roll. Heading is the angle reckoned from the local north direction. Tilt is equivalent to pitch or horizon angle. These angles give the orientation of an object in a frame where one axis points straight up toward the sky, and another axis points north. In Celestia 1.5.0, you can set up a frame, but there's a lot of typing involved. Here's an example from Selden's very cool Sidereal Clock add-on"
Just as we made a BodyFixed frame the default orbit frame for the new SurfaceObject type, we can make this complicated TwoVector frame the default body frame. We can now position one of the Mars rovers on the surface with this definition:
By default, the rover will face north and have its wheels on the ground. A new type of FixedRotation--let's call it SurfaceFixedRotation--would let us adjust the orientation of the rover in an intuitive way. To make it face east, we'd add this line to definition:
SurfaceFixedRotation { Heading 90 }
If it happens to be inclined a few degrees because it's climbing a hill, we might have this:
SurfaceFixedRotation { Heading 90 Tilt 5 }
All of this can be implemented by modifying just the solar system parser in Celestia--there's no need to change the 'guts' of the program. If people think that it is important and useful, it could even make it into Celestia 1.6.0.
--Chris
viewtopic.php?f=6&p=104425#p104425
A long discussion follows; if you'd rather skip it, the point is that it would be nice to place objects on the surface of planets using SSC definitions like this:
Code: Select all
SurfaceObject "Lunar Rover" "Sol/Earth/Moon"
{
Mesh "lunar.3ds"
Radius 0.002
SurfacePosition [ 56 -12 0.21 ]
SurfaceFixedRotation { Heading 65 }
}
Positioning the object correctly isn't too hard if you use the LongLat property, but there are some catches:
- LongLat doesn't help to properly orient the object
- LongLat cannot be used for objects that move relative to the surface of a planet.
- LongLat is a huge hack. I don't expect anyone outside the dev team to care too much, but there are problems with it. For one thing, it doesn't interact properly with reference frames.
The function of LongLat can be more elegantly handled with a BodyFixed frame and a FixedPosition trajectory. These both place an object on the surface of the Earth:
Code: Select all
"Fixed - LongLat" "Sol/Earth"
{
LongLat [ -122 47.5 0.1 ]
}
"Fixed - Frame" "Sol/Earth"
{
OrbitFrame { BodyFixed { Center "Sol/Earth" } }
FixedPosition [ -2283.448 -3654.281 4702.502 ]
}
However, as is apparent from the code above, the elegance of the frame based approach is only conceptual and not syntactic. It's considerably harder to use FixedPosition and OrbitFrame, largely because the add-on creator must manually convert longitude, latitude, and altitude into rectangular coordinates for use with FixedPosition. So, the first addition I want to propose is a spherical coordinate version of FixedPosition. For lack of better ideas, it could be called SurfacePosition and have three values: longitude, latitude, and altitude (in kilometers). The simplified definition looks like this:
Code: Select all
"Fixed - Frame" "Sol/Earth"
{
OrbitFrame { BodyFixed { Center "Sol/Earth" } }
SurfacePosition [ -122 47.5 0.1 ]
}
That's better, but it's still not as simple as using LongLat. The problem is that we have to explicitly set the frame. But what if we added a new object type with a different default frame? Add-on creators could use the new object type to place an object on the surface of a planet without ever being aware that they were dealing with frames. It might look like this:
Code: Select all
SurfaceObject "Fixed" "Sol/Earth"
{
SurfacePosition [ -122 47.5 0.1 ]
}
This is as simple as LongLat. Explicitly declaring that the body is a surface object is a nice documentation bonus. But, the real payoff comes when we try and orient the object. Doing this right now is difficult because the parameters for orienting an object in space aren't intuitive for orienting an object on the surface of a planet. In Google Earth's KML files, the orientation parameters are heading, tilt, and roll. Heading is the angle reckoned from the local north direction. Tilt is equivalent to pitch or horizon angle. These angles give the orientation of an object in a frame where one axis points straight up toward the sky, and another axis points north. In Celestia 1.5.0, you can set up a frame, but there's a lot of typing involved. Here's an example from Selden's very cool Sidereal Clock add-on"
Code: Select all
TwoVector
{
Center "Sol/Earth/Sidereal_Clock"
Primary
{
Axis "-y"
RelativePosition {Target "Sol/Earth"}
}
Secondary
{
Axis "z"
ConstantVector
{
Vector [ 0 0 1]
Frame { BodyFixed { Center "Sol/Earth" } }
}
}
}
Just as we made a BodyFixed frame the default orbit frame for the new SurfaceObject type, we can make this complicated TwoVector frame the default body frame. We can now position one of the Mars rovers on the surface with this definition:
Code: Select all
SurfaceObject "MER-A (Spirit) Rover" "Sol/Mars"
{
Class "spacecraft"
Mesh "spirit.3ds"
Beginning "2004 01 04"
Radius 0.0009 # 1.8m diameter *roughly*
SurfacePosition [175.4785 -14.5718 0.0009]
}
By default, the rover will face north and have its wheels on the ground. A new type of FixedRotation--let's call it SurfaceFixedRotation--would let us adjust the orientation of the rover in an intuitive way. To make it face east, we'd add this line to definition:
SurfaceFixedRotation { Heading 90 }
If it happens to be inclined a few degrees because it's climbing a hill, we might have this:
SurfaceFixedRotation { Heading 90 Tilt 5 }
All of this can be implemented by modifying just the solar system parser in Celestia--there's no need to change the 'guts' of the program. If people think that it is important and useful, it could even make it into Celestia 1.6.0.
--Chris