ScriptedOrbit tutorial

All tutorials about Celestia go in here. For Celestia itself, add-ons, textures, scripting, etc.
Avatar
Topic author
Fenerit M
Posts: 1880
Joined: 26.03.2007
Age: 17
With us: 17 years 1 month
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

Post #41by Fenerit » 14.10.2009, 00:05

Cham wrote:ROFL !

Try this one ! :lol:

Archive.zip

Celestia CARTOONS! :mrgreen: Well, I think that there is all for black holes radiation. :wink: Just curious whether this scripted O-R method and point sprites will always be slow than particles system (apart visual effects) because until now the motion of sprites weren't independent. :roll:
Never at rest.
Massimo

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #42by Cham » 15.10.2009, 21:12

I made a nice precessing elliptical orbit in the equatorial plane (currently, it is accurate up to the fourth order in the excentricity parameter. See below for an explanation) :

LUA CELXX file :

Code: Select all

function test_periodic(t)
   -- Create a new table
   local orbit = {};

   -- Save the parameter list
   orbit.params = t;

   -- Set the required fields boundingRadius and position; note that position is actually a function
   orbit.boundingRadius = t.SemiAxis

   -- The position function will be called whenever Celestia needs the position of the object
    function orbit:position(tjd)
   local t = tjd - 2451545.0

   --local PeriodicTime = t - math.floor(t);
   local Phi = 2 * math.pi * t / self.params.KeplerPeriod
   local exc = self.params.Excentricity;
   local Phase = Phi + exc * math.sin(Phi + exc * math.sin(Phi + exc * math.sin(Phi + exc * math.sin(Phi))));

   local x1 = (self.params.SemiAxis) * (math.cos(Phase) - exc);
   local y1 = (self.params.SemiAxis) * math.sqrt(1 - exc * exc) * math.sin(Phase);

   local Omega = 2 * math.pi * self.params.PrecessionRate * t

   local x = x1 * math.cos(Omega) - y1 * math.sin(Omega)
   local y = x1 * math.sin(Omega) + y1 * math.cos(Omega)
   local z = 0

   return x, y, z
    end

    return orbit
end


SSC file :

Code: Select all

"Test" "Sol/Earth"
{
   Class "spacecraft"
   Mesh "UFO.cmod"
   Orientation [90 1 0 0]
   Radius 10
   Albedo 0.6

   ScriptedOrbit {
      Module "test"
      Function "test_periodic"

      SemiAxis   24000   # in km
      KeplerPeriod      0.0004   # Revolution period in days
      Excentricity   0.7   # Must be < 1
      PrecessionRate   200   # Precession rate, in units of 2Pi/day
   }
}


I'm using the following parametric representation of the keplerian orbit :
[tex]r(\eta) = a (1 - e \cos \eta)[/tex]
[tex]\omega t(\eta) = \eta - e \sin \eta[/tex]
[tex]x(\eta) = a (\cos \eta - e)[/tex]
[tex]y(\eta) = a \sqrt(1 - e^2) \sin \eta[/tex]

However, I don't know of any analytical representation of the parametrisation [tex]\eta[/tex] defined as a function of time, so I had to do an approximation (to the fourth power in excentricity). Any better way to do this ? Chris ?

[tex]\eta = \omega t + e \sin \eta = \omega t + e \sin(\omega t + e \sin(\omega t + e \sin(\omega t + ...)))[/tex]

I may add more powers in excentricity for a better approximation, but I'm a bit afraid to have an impact on Celestia's performances. Currently, it's working very well in Celestia, at the fourth power in [tex]e[/tex].

I'm also interested to tilt the orbit... That should be next.
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #43by Cham » 20.10.2009, 14:42

Well, this topic doesn't seem to interest much people :x . I'll publish a last prototype. Maybe that this one would awake someone...

Here's an animated volcano prototype. 40 particles moving on a parabolic path, in a periodic way. It's working very well in Celestia. It just needs more particles, and the model would eventually be placed on Io. Take note that the SSC is using some "real" parameters : Gravity acceleration close to the surface (in [tex]meters/sec^2[/tex]), initial position and velocity (in [tex]meters/sec[/tex]), etc). So this may also be interesting as a small physics simulator :mrgreen:
Scripted-Volcano_prototype.zip


EDIT : While the above scripted orbit is currently working, there's a mistake in the time definition which makes it hard to adapt to other bodies (Io ...). :oops: This is related to the periodicity of the effect. Well, this is a prototype, anyway. I'll correct the mistake later.
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

ajtribick
Developer
Posts: 1855
Joined: 11.08.2003
With us: 20 years 9 months

Re: ScriptedOrbit tutorial

Post #44by ajtribick » 20.10.2009, 20:26

The precessing Keplerian code can be simplified a bit by using the built in vector and rotation (quaternion) datatypes.

Code: Select all

function test_periodic(t)
   -- Create a new table
   local orbit = {};

   -- Save the parameter list
   orbit.params = t;

   -- Set the required fields boundingRadius and position; note that position is actually a function
   orbit.boundingRadius = t.SemiAxis

   -- The position function will be called whenever Celestia needs the position of the object
   function orbit:position(tjd)
      local t = tjd - 2451545.0

      --local PeriodicTime = t - math.floor(t);
      local Phi = 2 * math.pi * t / self.params.KeplerPeriod
      local exc = self.params.Excentricity;
      local Phase = Phi + exc * math.sin(Phi + exc * math.sin(Phi + exc * math.sin(Phi + exc * math.sin(Phi))));

      -- position of the particle in canonical orbit orientation
      local canonical = celestia:newvector(
         (self.params.SemiAxis) * (math.cos(Phase) - exc),
         (self.params.SemiAxis) * math.sqrt(1 - exc * exc) * math.sin(Phase),
         0
      );

      -- rotation about the z axis
      local rot = celestia:newrotation(
         celestia:newvector(0,0,1),
         2 * math.pi * self.params.PrecessionRate * t
      );

      -- compute coordinates in rotated orbit
      local actual = rot:transform(canonical);

      return actual.x, actual.y, actual.z
   end
   
   return orbit
end

This is somewhat easier than writing out the transformation explicitly. :)

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #45by Cham » 23.10.2009, 00:00

Here's another cool experiment :

A cataclysmic binary of two stars orbiting each other, with an exponentially decaying orbit. The values used are all arbitrary, but this small addon could be usefull to show what happens to a close binary. Gravitational radiation alone isn't enough to give such a decay, so there must be some other mechanism in the game here (mass loss, mass transfer, friction, ...).

Cataclysmic_binary.zip


Just accelerate time by a factor of 500000, to see a nice evolution of the cataclysmic binary. The whole motion repeats itself after 200 days of real time.
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

Avatar
Topic author
Fenerit M
Posts: 1880
Joined: 26.03.2007
Age: 17
With us: 17 years 1 month
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

Post #46by Fenerit » 23.10.2009, 22:31

Thanks ajtribick for partecipating here. :wink: Now I'm involved in the minerals add-on which is a tedious compiling. I will check the volcano script later, otherwise it could distract me from minerals :P
Never at rest.
Massimo

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #47by Cham » 24.10.2009, 01:39

... and here's a better version of the Io volcano (permanent eruption, in this case, instead of a cyclic version). The effect is really spectacular with 400 particles, however the impact on the frame rate is severe. So I'm publishing a version with 150 particles instead. Adding more particles is really easy, though.

Io_volcano.zip
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

Avatar
Topic author
Fenerit M
Posts: 1880
Joined: 26.03.2007
Age: 17
With us: 17 years 1 month
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

Post #48by Fenerit » 24.10.2009, 10:22

183 kb for an erupting volcano! It's a record. :D
Never at rest.
Massimo

Avatar
Topic author
Fenerit M
Posts: 1880
Joined: 26.03.2007
Age: 17
With us: 17 years 1 month
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

Post #49by Fenerit » 24.10.2009, 12:56

Hey Cham, FYI I've changed local t = (tjd - 2451545.0) to local t = (tjd - 2451545.0) * 100 for fast real-time smooth flows and I've gained ONE fps. :o
Never at rest.
Massimo

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #50by Cham » 24.10.2009, 13:03

Fenerit wrote:Hey Cham, FYI I've changed local t = (tjd - 2451545.0) to local t = (tjd - 2451545.0) * 100 for fast real-time smooth flows and I've gained ONE fps. :o

This wont be realistic. The particles are really taking about 30 minutes to move on their trajectory, since gravity is weak on Io. The code is using some real data (gravity, ejection velocity, etc). The user just have to accelerate time by a factor of 100 to see the flow.
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

Avatar
Topic author
Fenerit M
Posts: 1880
Joined: 26.03.2007
Age: 17
With us: 17 years 1 month
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

Post #51by Fenerit » 24.10.2009, 13:35

Cham wrote:
Fenerit wrote:Hey Cham, FYI I've changed local t = (tjd - 2451545.0) to local t = (tjd - 2451545.0) * 100 for fast real-time smooth flows and I've gained ONE fps. :o

This wont be realistic. The particles are really taking about 30 minutes to move on their trajectory, since gravity is weak on Io. The code is using some real data (gravity, ejection velocity, etc). The user just have to accelerate time by a factor of 100 to see the flow.

Apart this, just for performances, with local t = (tjd - 2451545.0) * 128 the frame gain is TWO frames when Io is right toggled. Seems that all must be power of two, not just textures. Then I get 13.8 fps with 300 sprites at 32 pixel resized texture. As said, you want distract me from minerals! :lol:
Never at rest.
Massimo

Avatar
Topic author
Fenerit M
Posts: 1880
Joined: 26.03.2007
Age: 17
With us: 17 years 1 month
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

Post #52by Fenerit » 24.10.2009, 21:58

Well, I love this volcano. Is the color right? Sometime ago it should have the blue...
Never at rest.
Massimo

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #53by Cham » 25.10.2009, 00:30

Yes, the right color should be blue. I'm now using the following color for Io's volcano (to be used in the CMOD files) :

Code: Select all

  emissive 0.55 0.5 1
  diffuse  0.55 0.5 1


I used the yellow shades at first for a solar flare (mass dejection on the Sun). I also made several flakes models, for the flares...
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #54by Cham » 25.10.2009, 02:45

And now, a solar flare prototype :
Flares.zip


Very small addon! And it's very easy to add more random flares to the Sun, at any location (any longitude and latitude, any azimuth angle), any animation period, and any size (just examine the basic SSC file). Since the basic flare I'm publishing has only 25 "flare blobs", adding 3 or 4 more flares shouldn't affect much the frame rate :)

Adjust the cmod colors according to taste...
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #55by Cham » 27.10.2009, 02:22

Here's another application of the ScriptedOrbit method : animated relativistic jets on black holes (outgoing motion, which is totally new for Celestia) :

Image

The animation is also showing the deceleration caused by the jets interaction with the interstellar medium...
The spurting effect close to the BH is very good 8)

The only problem is the strong impact on the frame rate, if there's too much particles in the animation. :|
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #56by Cham » 27.10.2009, 13:40

Here's another version of the spurting jets (neutron star with an accreting disk). The animation is perfectly smooth in this case, with 400 particles ! 8)

Image
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 3 months
Location: Seattle, Washington, USA

Re: ScriptedOrbit tutorial

Post #57by chris » 27.10.2009, 22:26

Cham,

I've done some work with adding native particle system support to Celestia, which might eventually let you create these sorts of effects with tens of thousands of particles. What sort of motion do the particles have? As currently implemented, the motion of a particle in particle system must be expressible as a parametric quadratic curve. Is this adequate for your examples?

--Chris

Avatar
Topic author
Fenerit M
Posts: 1880
Joined: 26.03.2007
Age: 17
With us: 17 years 1 month
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

Post #58by Fenerit » 27.10.2009, 23:17

chris wrote:Cham,

I've done some work with adding native particle system support to Celestia, which might eventually let you create these sorts of effects with tens of thousands of particles. What sort of motion do the particles have? As currently implemented, the motion of a particle in particle system must be expressible as a parametric quadratic curve. Is this adequate for your examples?

--Chris

Please Cham, say yes to Chris... :mrgreen:
Never at rest.
Massimo

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #59by Cham » 28.10.2009, 01:14

chris wrote:As currently implemented, the motion of a particle in particle system must be expressible as a parametric quadratic curve. Is this adequate for your examples?

What do you mean by "quadratic curve" ? Do you mean a simple polynomial of degree 2 ? If yes, this is pretty limited. At least, the jets and volcano I made are quadratic :

The volcano CELXX code I'm using :

Code: Select all

function parabolic_motion(t)
   local orbit = {};
   orbit.params = t;
   orbit.boundingRadius = 2 * t.InitialRadius

   local RandomVelocity = t.MinVelocity + (t.MaxVelocity - t.MinVelocity) * math.random();
   local Delta = math.rad(t.MinDeclination + (t.MaxDeclination - t.MinDeclination) * math.random());
   local Phi = 2 * math.pi * math.random();

   local MaxTime = 2.1 * RandomVelocity * math.sin(Delta)/(86400 * t.Gravity);
   local RandomDelay = MaxTime * math.random();

    function orbit:position(tjd)
   local t = tjd - 2451545.0

   local Alpha = math.rad(self.params.Longitude);
   local Beta  = math.rad(self.params.Latitude);

   local CyclicTime = (t - RandomDelay) - MaxTime * math.floor((t - RandomDelay) / MaxTime)

   local acct  = 3732480 * self.params.Gravity * CyclicTime * CyclicTime;
   local v0xt  = 86.4 * RandomVelocity * math.cos(Delta) * math.cos(Phi) * CyclicTime;
   local v0yt  = 86.4 * RandomVelocity * math.cos(Delta) * math.sin(Phi) * CyclicTime;
   local v0zt  = 86.4 * RandomVelocity * math.sin(Delta) * CyclicTime;

   local x = (self.params.InitialRadius + v0zt - acct) * math.cos(Beta) * math.cos(Alpha) - v0xt * math.sin(Beta) * math.cos(Alpha) + v0yt * math.sin(Alpha)
   local y = (self.params.InitialRadius + v0zt - acct) * math.cos(Beta) * math.sin(Alpha) - v0xt * math.sin(Beta) * math.sin(Alpha) - v0yt * math.cos(Alpha)
   local z = (self.params.InitialRadius + v0zt - acct) * math.sin(Beta) + v0xt * math.cos(Beta)

   return x, y, z
    end

    return orbit
end


The jets code (a trivial variation of the previous one) :

Code: Select all

function jet_motion(t)
   local orbit = {};
   orbit.params = t;
   orbit.boundingRadius = 2 * t.InitialRadius

   local v0 = 86.4 * (t.MinVelocity + (t.MaxVelocity - t.MinVelocity) * math.random());
   local Delta = math.rad(t.MinDeclination + (t.MaxDeclination - t.MinDeclination) * math.random());
   local MaxTime = 0.9 * v0 * math.sin(Delta)/(7464960 * t.Deceleration);
   local RandomDelay = MaxTime * math.random();
   local Phi = 2 * math.pi * math.random();

    function orbit:position(tjd)
   local t = tjd - 2451545.0

   local PeriodicTime = (t - RandomDelay) - MaxTime * math.floor((t - RandomDelay) / MaxTime);

   local x = v0 * math.cos(Delta) * math.cos(Phi) * PeriodicTime
   local y = v0 * math.cos(Delta) * math.sin(Phi) * PeriodicTime
   local z = self.params.Pole * (self.params.InitialRadius + v0 * math.sin(Delta) * PeriodicTime - 3732480 * self.params.Deceleration * PeriodicTime * PeriodicTime)

   return x, y, z
    end

    return orbit
end


The curves in these two examples are just quadratic polynomials of the time variable (actually a periodic version of time, defined using the "floor" function), with several angles and velocity parameters as input :

equs.jpg

Here, [tex]\beta[/tex] and [tex]\alpha[/tex] are respectively the Latitude and Longitude of the source. The initial velocity ([tex]v_{0 x}[/tex], [tex]v_{0 y}[/tex] and [tex]v_{0 z}[/tex]) is a random vector which depend on [tex]v_{0}[/tex] (random modulus [tex]v_0 \in [v_{0 min}, v_{0 max} ][/tex]), the declination (random value [tex]\delta \in [\delta_{min}, \delta_{max}][/tex]) and the azimuth (random variable [tex]\phi \in [0, 2 \pi[[/tex]) :
[tex]v_{0 x} = v_{0} \cos\delta \cos\phi[/tex],
[tex]v_{0 y} = v_{0} \cos\delta \sin\phi[/tex],
[tex]v_{0 z} = v_{0} \sin\delta[/tex].

In the case of time, I made it cyclic, using the "floor" function :
[tex]CyclicTime = \tau(t) = t - t_0 - T floor(\frac{t - t_0}{T})[/tex],

where [tex]t_0 \in [0, T][/tex] is a random delay and [tex]T[/tex] is the period of the whole motion.


If Celestia could render **few thousands** of particles in real time for a volcano on Io or a pair of black hole jets, say, with a descent frame rate, it would be AWESOME !
Last edited by Cham on 28.10.2009, 14:49, edited 11 times in total.
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"

Avatar
Cham M
Posts: 4324
Joined: 14.01.2004
Age: 59
With us: 20 years 4 months
Location: Montreal

Re: ScriptedOrbit tutorial

Post #60by Cham » 28.10.2009, 10:15

Chris,

in the case of solar flares, we need more than quadratic functions. For example, a deformation of a circle :
[tex]x(t) =R + a \sin(\omega t + \phi)[/tex]
[tex]y(t) = b \cos(\omega t + \phi)[/tex]
[tex]z(t) = 0[/tex]

This would also be usefull to make accretion disks, with hopefully turbulence and/or differential rotation....
"Well! I've often seen a cat without a grin", thought Alice; "but a grin without a cat! It's the most curious thing I ever saw in all my life!"


Return to “Tutorials”