Solar System
This example is the same as the tutorial.
This example is the same as the tutorial.
-.-------------------------------------------------------------------------------------- Solar system This example is not very different from the rotating cubes example. It serves only to show that with the ( fairly basic ) integration of Direct X in CellSpeak, it is easy to build animated models. There is a lot of room to add sophistication to this program, both in its graphics and its behaviour, but -.-------------------------------------------------------------------------------------- use Math, Strings, Editor, Windows use D3D11, Camera, Light, Color, Material, Shape -- A sphere - based on the shared mesh shape (see shape.cellsrc in packages\d3dgraphics) design Sphere(float Radius, MeshClass cppMesh) like SharedMesh( cppMesh ) is -- originaly the sphere is positioned at the origin (see Shape.SharedMesh) -- A sphere has a simple world matrix WorldMatrix = [ Radius, 0, 0, Position.x, 0, Radius, 0, Position.y, 0, 0, Radius, Position.z, 0, 0, 0, 1 ] -- we create a function variable that will be used to calculate a new frame for the cube var function FrameAction (word Interval) to do -- when a new frame has to be calculated the camera sends the message NewFrame on NewFrame(word Interval) do -- ..just execute the frame action for the sphere FrameAction( Interval ) end -- Note that the camera also sends the message 'draw', but that message is handled by the -- ancestor design SharedMesh, because processing is the same for all mesh types( sphere, cube etc.) -- A message that sets the particular frame action for the sphere (in this case to advance along its orbit) on SetOrbit( xyz Axis, float AngularSpeed) do -- define the body for FrameAction body FrameAction with -- Calculate the rotation matrix to use (this is done now, at initialisation) matrix4 RotationMatrix =Rotate.Axis( Axis , AngularSpeed) end is -- Calculate the world matrix - this is done each time the function is called WorldMatrix = RotationMatrix * WorldMatrix end end end -.- The solar system A simple table with the basic parameters of each planet serves as the starting point for creating the planets. In this model the ratio's of the planet sizes and the orbit sizes are correct, but the size of the planets is not to scale wrt to the orbit, otherwise the small spheres would be far apart. The sun itself is set at 10% of its actual size compared to the planets, because otherwise the sun would be bigger then the orbits of the inner planets. -.- -- these are multipliers for distance, diameter and period that are based on the earth value. const float AU = 149.597871 * 3 -- astronomical unit is 149 597 871 km - x 3 to spread the planets out const float ER = 12.756 -- the earth radius is 12 756 km const float EY = 3.65 -- the duration of an earth year in seconds - 1 day = 10 msec design SolarSystemDesign is -- The name of the planets type PlanetEnum is [Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto] -- The mesh for a sphere (shared by all spheres, so we only create it once) Mesh.PolarSphere SphereMesh -- Mesh for a sphere -- The data for a planet type PlanetRecord is record cell Cell float Diameter -- in Earth diameters float Mass -- In Earth Masses float Distance -- From Sun, in AU = distance earth sun float Period -- in earth years Material.rgba Material -- material of the planet end -- The list of data for the planets (straight from Wikipedia - except for the material) PlanetRecord PlanetList[ PlanetEnum ] = [ -- cell Diameter Mass Distance Period Material [null, 0.382, 0.06, 0.39, 0.24, Material.White], -- Mercury [null, 0.949, 0.82, 0.72, 0.62, Material.White * 0.3], -- Venus [null, 1.0, 1.0, 1.0, 1.0, Material.Blue + Material.White*0.2], -- Earth [null, 0.532, 0.11, 1.52, 1.88, Material.Red], -- Mars [null, 11.209, 317.8, 5.2, 11.86, Material.Red*0.4 + Material.Green*0.25], -- Jupiter [null, 9.449, 95.2, 9.54, 29.46, Material.Red*0.2 + Material.Green*0.2], -- Saturn [null, 4.007, 14.6, 19.22, 84.01, Material.Aqua], -- Uranus [null, 3.883, 17.2, 30.06, 164.8, Material.Blue], -- Neptune [null, 0.1863, 0.00218,39.54, 248.25, Material.Fuschia] -- Pluto, rehabilitated ] -- There is only one record for the sun - we do not define a separate type var Sun is record cell Cell = null float Diameter = 109 float Mass = 333000 Material.rgba Stuff = Material.Yellow * 2.0 end -- Constructing the solar system constructor is -- Build a sphere mesh SphereMesh.Build(16,8) -- create the sun (at 10% of its relative size !) Sun.Cell = create Sphere( Sun.Diameter*ER/10, SphereMesh.cppMesh ) <- SetMaterial( Sun.Stuff ) for each Planet in PlanetList do -- create planet - set color, distance and orbit parameters -- 1 year is 360° in 3.65 second @ 25 fps Planet.Cell = create Sphere(Planet.Diameter*ER , SphereMesh.cppMesh) <- SetMaterial( Planet.Material ), MoveTo( [Planet.Distance*AU, 0, 0]), SetOrbit( [0,1,0], 2*pi_f / ( 25 * EY * Planet.Period) ) end end -- pass the messages to the children on ? => all <- (same) end -- SolarSystemDesign -- This is the design that we will instatiate to get the program going design HelloEarth is cell Camera -- We need a camera cell Light -- We need a light cell Window -- A text output window cell Timer -- we need a timer CanvasWindowClass CameraWindow -- The camera needs a window to display into Hwnd CameraWindowHandle -- The window handle RectangleType Rectangle -- The window rectangle cell SolarSystem -- Our scene constructor is -- The 'from' and 'to' vectors for the camera xyz From = [0,0,10*AU] xyz To = [0,0,0] -- We create the output window Window = create MenuWindow("The Solar System") -- set it also as stdout system <- stdout.Set( Window ) -- Create a camera that looks at the origin - we use a version with some more settings here then in the cubes example Camera = create FromTo(From,To, [0,1,0], 100*AU, 0.1, pi_f/4) -- The camera needs a window to display in - the rectangle defines the size of the window Rectangle = [500,0,2000,1000] -- Create the camera window class (calls a C++ method) CameraWindow = CameraWindow.Create("Camera",&Rectangle, 0, 0, null ) -- Tell the window about the camera - the window will send keyboard and mouse events to the camera -- CameraWindow is a C++ object, so SetCamera is a C++ object method call. CameraWindow.SetCamera(Camera) -- Create a light for the scene - to simulate the sun we use a pointlight in the center Light = create Point( Color.White, Color.White, Color.White, [10,10,10], 50*AU, 0.0) -- and build the solar system SolarSystem = create SolarSystemDesign -- Tell the camera about the window, the light and the scene (which starts at the world = self) Camera <- SetWindow(CameraWindow), SetLight(Light), SetScene(SolarSystem) -- Request a timer service from the system system <- Service.Get("Timer") -- We start the camera - we request a delivery notification for this message Camera <+- Roll -- and we print some feedback Window <- print("\nScene was created - Camera = [Camera] and Light = [Light] ") end -- The delivery notification from the camera - just for info on Roll.DN do Window <- print("\nReceived Delivery Notification from Camera [sender]") end -- The timer service on Service.Provider( ansi Name, cell Provider) do -- check that the service is for a timer Name is "Timer" ? Timer = Provider : yield -- every 3.65 seconds we will change the action ( 10msec is a day ) Timer <- Subscribe.Interval( (EY * 1000) ,"ReportYears") end int YearCount = 0 on ReportYears( word Time ) do system <- println("[YearCount += 1] earth years have passed") end end -- HelloEarth