Modifying Celestia to allow orbiting while a script runs

The place to discuss creating, porting and modifying Celestia's source code.
Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Modifying Celestia to allow orbiting while a script runs

Post #1by JGL » 04.03.2009, 14:18

Hey All,

I am currently modifying Celestia to create an interactive installation.

The idea is to allow a person to walk into the installation, and as they move from left to right, have the viewpoint they see on the projection screen update - a pseudo VR effect.

I am using Openframeworks (http://www.openframeworks.cc) to take input from a camera, and send the position to Celestia via OSC (http://opensoundcontrol.org/).

I have sucessfully modified the Celestia source to allow OSC input.

I am using a Celxscript for the installation, running constantly.

Code: Select all

-- Title: Travel to Randomly Picked Stars with a look

timeToTravel = 30
timeToLook = 1
keepGoing = true

obs = celestia:getobserver()

while keepGoing do
    nstars = celestia:getstarcount()
    index = math.floor(nstars * math.random())
    star = celestia:getstar(index)
    celestia:select(star)
   obs:center(star, timeToLook)
   wait(timeToLook)
    obs:goto(star, timeToTravel)
    wait(timeToTravel)
   timeToTravel = timeToTravel/2
   
   if timeToTravel < 2 then
      timeToLook = 0.5
   end   
   
   if timeToTravel < 1 then
      timeToLook = 0.2
   end

   if timeToTravel < 0.2 then
      timeToLook = 0.1
   end   
   
   if timeToTravel < 0.001 then
      keepGoing = false
   end
end


To move from random star to random star in the universe, at an ever increasing rate, before finally stopping.

What I want to be able to do, while the script is running, is to change the viewpoint of the observer, so that they orbit around the target that is currently being moved towards.

At the end of the CelestiaCore::tick method I have added the following lines, in the place where I process OSC messages:

Code: Select all

   
Quatf q(1.0f);
float coarseness = ComputeRotationCoarseness(*sim);
   
q = q * Quatf::yrotation((float) (dt * -KeyRotationAccel * coarseness * numberOfMessagesThisTick));
sim->orbit(q);


As I am trying to get this to work, numberOfMessagesThisTick is an int, representing how many OSC messages have been received this tick.

If a script isn't running, then everything works as expected - the camera orbits.

If a script is running, then I don't see any results. Is there a way that anyone could suggest to allow me to orbit while the script is running? I want to feel like someone is being taken on a random journey across the universe, with their movement in the real world updating the simulation.

In addition, I need to be able to start and stop the script from within the CelestiaCore::tick, so that the installation can activate when the user enters the room. Should I use:

Code: Select all

luaHook->loadScript(<#std #>, <#const std streamname#>)


Is the luaHook object the thing to use?

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 4 months
Location: NY, USA

Re: Modifying Celestia to allow orbiting while a script runs

Post #2by selden » 04.03.2009, 16:05

Your symptoms are consistent with wait not being called by your CelX script.
Have you included wait(0.01) statements at appropriate places?
(wait() is supposed to work, too, but doesn't seem to be effective under Windows.)

Wait returns control to Celestia so it can compute screen updates.
Without wait statements, Celestia can never evaluate the new positions and can't change the viewpoint. Celestia is supposed to terminate CelX scripts which run for more than 5 seconds without calling wait(). I don't know if your edits might have changed that.

I've found luahook to be annoyingly obscure, so I use Lua modules invoked by ScriptedOrbit.
Selden

Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Re: Modifying Celestia to allow orbiting while a script runs

Post #3by JGL » 04.03.2009, 16:37

Hi Selden,

Thanks for your quick reply.

If you see my CelX script, I call wait() after each center or goto command:

Code: Select all

   obs:center(star, timeToLook)
   wait(timeToLook)
    obs:goto(star, timeToTravel)
    wait(timeToTravel)


Where should I put my wait(0.01) calls?

Once I have told Celestia to goto the star in question, I want it to keep going, but with the angle of orbit being changed by the movement of the person in the installation.

Cheers,

JGL

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 4 months
Location: NY, USA

Re: Modifying Celestia to allow orbiting while a script runs

Post #4by selden » 04.03.2009, 17:10

JGL wrote:Where should I put my wait(0.01) calls?

It has to be called whenever the screen needs to be updated, i.e. whenever the viewpoint is likely to have changed. Think of it as a "draw screen" command.
Selden

Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Re: Modifying Celestia to allow orbiting while a script runs

Post #5by JGL » 04.03.2009, 17:35

Hey Selden,

Would this be a sensible approach (PSEUDO CODE)

Code: Select all

obs:center(star, timeToLook)
DO MULTIPLE CALLS OF wait(0.01) HERE, TO ALLOW THE ORBIT TO ADJUST, UNTIL WE HAVE WAITED A TOTAL OF timeToLook
obs:goto(star, timeToTravel)
DO MULTIPLE CALLS OF wait(0.01) HERE, TO ALLOW THE ORBIT TO ADJUST, UNTIL WE HAVE WAITED A TOTAL OF timeToTravel


Cheers,

JGL

Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Re: Modifying Celestia to allow orbiting while a script runs

Post #6by JGL » 04.03.2009, 17:57

In addition, if I want to load a LUA script from C++ is:

Code: Select all

int loadScriptStatus = luaHook->loadScript("/Users/joel/Library/Application Support/CelestiaResources/scripts/randstar.celx");


The correct approach?

Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Re: Modifying Celestia to allow orbiting while a script runs

Post #7by JGL » 04.03.2009, 18:02

Aha, I realised that luahook isn't what I want, a call to runScript(fileName) worked perfectly.

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 4 months
Location: NY, USA

Re: Modifying Celestia to allow orbiting while a script runs

Post #8by selden » 04.03.2009, 18:37

JGL wrote:Hey Selden,

Would this be a sensible approach (PSEUDO CODE)

Code: Select all

obs:center(star, timeToLook)
DO MULTIPLE CALLS OF wait(0.01) HERE, TO ALLOW THE ORBIT TO ADJUST, UNTIL WE HAVE WAITED A TOTAL OF timeToLook
obs:goto(star, timeToTravel)
DO MULTIPLE CALLS OF wait(0.01) HERE, TO ALLOW THE ORBIT TO ADJUST, UNTIL WE HAVE WAITED A TOTAL OF timeToTravel


Cheers,

JGL

I would have expected something like

Code: Select all

while true do
  get observer's position in room
  convert observer's position in room to viewpoint's position in Celestia
  observer:goto (position)
  wait (0.01)
end


This would cause Celestia to respond in realtime to the viewer's activity instead of lagging behind.
Selden

Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Re: Modifying Celestia to allow orbiting while a script runs

Post #9by JGL » 04.03.2009, 19:20

Hey Selden,

Thanks for your response.

I think there is some confusion - all I am doing within the LUA Celx script, is picking a random star and travelling to it. All the user interaction is coming from the C++ side. I can only get information about the position of the user from within C++, not on the Lua side. There are several pieces of functionality that I can only access through C++ - the sky colour and relative brightness of stars for example.

I am loading the random Star script below from within C++ when a user enters the room. While this script is playing, I want to allow the user to shift their viewpoint - while remaining centred on the star being travelled to. Is that clearer? I am making calls to orbit to accomplish this, but while travelling to another star, calls to orbit seem to have little effect. The desired final effect is portal into space, that you can alter by moving from side to side in the real world.

Code: Select all

-- Title: Travel to Randomly Picked Stars with a look and pauses

timeToTravel = 20
timeToLook = 1
keepGoing = true

obs = celestia:getobserver()

while keepGoing do
    nstars = celestia:getstarcount()
    index = math.floor(nstars * math.random())
    star = celestia:getstar(index)
    celestia:select(star)
   --v = celestia:newvector(0, 1, 0)   
   --obs:lookat(star:getposition(), v)
   obs:center(star, timeToLook)
   numberOfLookWaits = timeToLook * 100
   while numberOfLookWaits > 0 do
      wait(0.01)
      numberOfLookWaits = numberOfLookWaits - 1
   end
      
    obs:goto(star, timeToTravel)
   numberOfTravelWaits = timeToTravel *100
   while numberOfTravelWaits > 0 do
      wait(0.01)
      numberOfTravelWaits = numberOfTravelWaits - 1
   end
   
   timeToTravel = timeToTravel/2
   
   if timeToTravel < 2 then
      timeToLook = 0.5
   end   
   
   if timeToTravel < 1 then
      timeToLook = 0.2
   end

   if timeToTravel < 0.2 then
      timeToLook = 0.1
   end   
   
   if timeToTravel < 0.001 then
      keepGoing = false
   end
end


Should I attempt direct OpenGL calls? I'd really rather use "pure" Celestia calls if possible.

Is that clearer?

Best,

JGL

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 4 months
Location: NY, USA

Re: Modifying Celestia to allow orbiting while a script runs

Post #10by selden » 04.03.2009, 19:37

Somehow the viewer's (or otherwise desired) position has to get into Celestia.

If I understand you now, you are using the command-line method:
Your C++ program writes a .celx file containing the desired commands and tells Celestia to run that script. My current guess is that the C++ program is not waiting.

Celestia runs only one CelX script at a time.
If a new one is started, then the previous CelX script is immediately aborted.

Your C++ program needs to wait until Celestia has finished its previous script before it creates a new one. Either it has to be done by dead reckoning (e.g. always wait 5 seconds before creating a new script) or by having Celestia clear a busy flag. (e.g. have the C++ program create a lock file which the Celestia CelX script deletes when it's finished.)

I think dead-reckoning is the most robust. There are too many possible problems which might cause Celestia to never delete the lock file.

Does this help?
Selden

Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Re: Modifying Celestia to allow orbiting while a script runs

Post #11by JGL » 04.03.2009, 19:47

Hey Selden,

I am not using the command line method, everything is happening within Celestia. I have modified Celestia to receive the position of the person within its main loop - i.e. within CelestiaCore::tick()).

I have the CelX script that I described previously, it is not generated - it is a static file that is never changed.

What I want to be able to do from within the CelestiaCore::tick() method is to be able to shift the camera position from left to right while still looking at the star that is being travelled to, and still have the CELX script continue.

Code: Select all

   Quatf q(1.0f);
   float coarseness = ComputeRotationCoarseness(*sim);
   
   q = q * Quatf::yrotation((float) (dt * -KeyRotationAccel * coarseness * numberOfMessagesThisTick));
   sim->orbit(q);


Above is the C++ code that I am attempting to use, but it doesn't work while the Camera is "travelling".

Is this clearer?

JGL

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 4 months
Location: NY, USA

Re: Modifying Celestia to allow orbiting while a script runs

Post #12by selden » 04.03.2009, 20:17

Sorry: I think you've exceeded my knowledge of how Celestia is coded.

My understanding is that during a tick (i.e. during a wait()) is when Celestia draws the next screen, first processing command tables which were set up before the tick, including stepping toward previously specified destination coordinates. In other words, your code shouldn't be changing the destination coordinates during a tick. I don't know what Celestia would do. It would entirely depend on what code you've modified.

Personally, I think I would have used the "externally generated script" technique in order to minimize the changes to Celestia. From what you've said, the coordinates change slowly enough (i.e. you're willing to wait several seconds for Celestia to get to its destination) that the time needed to create the files and for Celestia to process them are a small fraction of the total.

Sorry, I don't think I can help much more.
Selden

Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Re: Modifying Celestia to allow orbiting while a script runs

Post #13by JGL » 04.03.2009, 20:43

Thanks for all your help Selden, does anyone else have any ideas about how to change the orbit of the camera in C++ while a CelX script is running?

Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Re: Modifying Celestia to allow orbiting while a script runs

Post #14by JGL » 04.03.2009, 21:04

Specifially, I am issuing C++ orbit commands:

Code: Select all

   Quatf q(1.0f);
   float coarseness = ComputeRotationCoarseness(*sim);
   
   q = q * Quatf::yrotation((float) (dt * -KeyRotationAccel * coarseness * numberOfMessagesThisTick));
   sim->orbit(q);
   


while the script isn't running a obs:goto lua command. When it "going to", it seems not to respond to orbit commands at all...

Topic author
JGL
Posts: 10
Joined: 04.03.2009
With us: 15 years 10 months

Re: Modifying Celestia to allow orbiting while a script runs

Post #15by JGL » 04.03.2009, 21:17

I believe that that problem is that orbit() calls in C++ have no effect when the Observer is in "Travelling" mode.

Code: Select all

void Observer::update(double dt, double timeScale)


Does anyone else have any advice on how to alter this to allow orbiting while the camera is moving?


Return to “Development”