• Print view

ScriptedOrbit tutorial

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

Re: ScriptedOrbit tutorial

Cham wrote:ROFL !

Try this one !

Archive.zip

Celestia CARTOONS! Well, I think that there is all for black holes radiation. 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.
Never at rest.
Massimo

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

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 orbitend

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 :
$$r(\eta) = a (1 - e \cos \eta)$$
$$\omega t(\eta) = \eta - e \sin \eta$$
$$x(\eta) = a (\cos \eta - e)$$
$$y(\eta) = a \sqrt(1 - e^2) \sin \eta$$

However, I don't know of any analytical representation of the parametrisation $$\eta$$ 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 ?

$$\eta = \omega t + e \sin \eta = \omega t + e \sin(\omega t + e \sin(\omega t + e \sin(\omega t + ...)))$$

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 $$e$$.

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!"

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

Well, this topic doesn't seem to interest much people . 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 $$meters/sec^2$$), initial position and velocity (in $$meters/sec$$), etc). So this may also be interesting as a small physics simulator
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 ...). 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
Posts: 1780
Joined: 11.08.2003
With us: 15 years 11 months
Location: Switzerland

Re: ScriptedOrbit tutorial

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 orbitend

This is somewhat easier than writing out the transformation explicitly.

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

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!"

Topic author
Fenerit
Posts: 1880
Joined: 26.03.2007
Age: 12
With us: 12 years 3 months
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

Thanks ajtribick for partecipating here. 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
Never at rest.
Massimo

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

... 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!"

Topic author
Fenerit
Posts: 1880
Joined: 26.03.2007
Age: 12
With us: 12 years 3 months
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

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

Topic author
Fenerit
Posts: 1880
Joined: 26.03.2007
Age: 12
With us: 12 years 3 months
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

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.
Never at rest.
Massimo

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

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.

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!"

Topic author
Fenerit
Posts: 1880
Joined: 26.03.2007
Age: 12
With us: 12 years 3 months
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

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.

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!
Never at rest.
Massimo

Topic author
Fenerit
Posts: 1880
Joined: 26.03.2007
Age: 12
With us: 12 years 3 months
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

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

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

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!"

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

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!"

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

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

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

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!"

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

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 !

"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
Posts: 4211
Joined: 28.01.2002
With us: 17 years 5 months
Location: Seattle, Washington, USA

Re: ScriptedOrbit tutorial

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

Topic author
Fenerit
Posts: 1880
Joined: 26.03.2007
Age: 12
With us: 12 years 3 months
Location: Thyrrenian sea

Re: ScriptedOrbit tutorial

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...
Never at rest.
Massimo

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

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 orbitend

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 orbitend

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

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

where $$t_0 \in [0, T]$$ is a random delay and $$T$$ 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!"

Cham
Posts: 4325
Joined: 14.01.2004
Age: 54
With us: 15 years 6 months
Location: Montreal

Re: ScriptedOrbit tutorial

Chris,

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

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!"