camera roll with Celx

Post requests, images, descriptions and reports about work in progress here.
Topic author
foravalon
Posts: 50
Joined: 07.05.2005
With us: 19 years 6 months
Location: Santa Rosa, CA

camera roll with Celx

Post #1by foravalon » 28.07.2009, 06:23

I feel like I'm trying to do something very simple with a celx file that I'm creating, but I'm baffled in my attempts at finding a simple solution.

What I've got already is a simple gotolonglat command which, for the most part, works out great. It puts the viewer at the precise distance and facing in the direction I'm trying to place them in....

Code: Select all

    obs = celestia:getobserver()
    sol = celestia:find("Sol")
    obs:follow(sol)
    obs:gotolonglat(sol,  math.rad(0.0233), math.rad(29.8115), 27000000000000000)


...but the only problem is that roll angle of the camera is about 95 degrees off of what I'd like it to be.
Image

Manually this is fixed very simply by holding the down on the right arrow button for a bit until the orientation is correct...
Image

..... but what I'd like to figure out is how to achieve this automatically, and a lot more precisely, with the celx file. Can anyone help me out?
Foravalon's most common phrase: "So, yeah, um, how do you do this... ?"

Avatar
Marco Klunder
Posts: 181
Joined: 20.02.2008
Age: 62
With us: 16 years 9 months
Location: The Netherlands

Re: camera roll with Celx

Post #2by Marco Klunder » 02.11.2009, 20:23

Hellow foravalon,

Probably you can use the following CELX code to rotate the observer automatically and precisely AFTER your gotolonglat() command.
In this example you need to fill in the values between <...> yourself. They are the equivalent values of the CEL: rotate command.
The funtion "rotate_obs(rotangle, rotaxis, rottime)" needs to be placed somewhere at the start of your CELX script.

Code: Select all

function rotate_obs(rotangle, rotaxis, rottime)
   -- Rotangle is the angle to rotate the Observer view in degrees
   -- Rotaxis is the axis vector (x,y,z) for the rotation
   -- Rottime is the duration of the rotation in seconds
   local obs = celestia:getobserver()
   local rotsteps = 50 * rottime
   local rot = celestia:newrotation(rotaxis, math.rad(rotangle)/rotsteps)
   local rotsteptime = rottime/rotsteps
   for i = 1, rotsteps do
      obs:rotate(rot)
      wait(rotsteptime)
   end
end

< ... other CELX script code ...>
objectname = celestia:find( <string> )
celestia:select(objectname)
rotation_angle = <duration> * <rate>
axis_vector = celestia:newvector( <x> , <y> , <z> )
rotate_obs(rotation_angle, axis_vector, <duration> )
< ... other CELX script code ...>


There is also a possibility to rotate the observer smoothly during the goto command.
In that case you need to use the observer:goto(table: parameters) method.
Using this method, many different types of gotos can be performed.
The parameters for the goto must be given in a table:
parameters={}
parameters.duration = duration (number) seconds of the goto command
parameters.from = source position you start from, which can be obtained using the observer:getposition() method
parameters.to = target position to go to
parameters.initialOrientation = source orientation of the observer
parameters.finalOrientation = target orientation of the observer, including the rotation you wish
parameters.startInterpolation = The point in time during the goto (expressed as a percent number between 0 and 1), at which the observer should begin turning from the initial orientation to the final orientation.
parameters.endInterpolation = The point in time during the goto (expressed as a percent number between 0 and 1) at which the observer should finish turning from the initial orienation to the final orientation.
parameters.accelTime = Indicates (as a percentage number between 0 and 1) how much of the time during the goto should be spent accelerating away from the initial position. It also represents the amount of time that will be spent decelerating towards the final position. The remainder of the time during the goto is spend cruising.

example:

Code: Select all

obs = celestia:getobserver()
parameters = { }
parameters.duration = 4.0
parameters.from = obs:getposition()
parameters.to = celestia:newposition(-14.969302409159, 0.092810465260171, -6.8908004451794)
parameters.initialOrientation = obs:getorientation()
parameters.finalOrientation = celestia:newrotation(0.67196884005123, 0.71473804065804, -0.18559640882388, 0.056226188455065)
parameters.startInterpolation = 0
parameters.endInterpolation = 1
parameters.accelTime = 0
obs:goto(parameters)
wait(parameters.duration)


There are also alternatives for defining the newposition and newrotation, based on cel:-URL values (see the wiki books at http://en.wikibooks.org/wiki/Celestia/Celx_Scripting/CELX_Lua_Methods/Celx_celestia#newposition).
so when you go to your target position once, based on your gotolonglat() method and rotate the observer once by hand (or with the above obs_rotate() function, you then can press the [Ctrl] + [c] keys to capture the cel:-URL and copy that URL into a document or so, to extract the x=, y= and z= values for the newpostion and ow=, ox=, oy= and oz= values for the new rotation.

Good luck, Marco
Marco Klunder
email: marco.klunder@xs4all.nl
Windows10 PD 3.0 GHz, 2 GB of RAM, Nvidia GeForce 6700 XL
Celestia161 / SVN + Lua Edu Tools v1.2 Beta9, Celestia160-ED and Celestia1621


Return to “Add-on development”