PDA

View Full Version : Sun, Earth, Moon simulation with Entity System



primo
08-10-2017, 16:47
demo using Entity System, it is almost impossible or very hard to do this in basic opengl, but Entity System makes simulations much easier

demo: sun, earth, moon system
tilted earth by 23, make a fake ball (MoonGuide) and position it on earth center and tilted it by 5.5 then rotate it
attach the moon to the MoonGuide
position a light on the center of the sun and make it look at the earth
https://en.wikipedia.org/wiki/Earth%27s_orbit#/media/File:North_season.jpg


'depending on example "TBGL_CustomSphereEntity" by Petr Schreiber, 2009 =
'===============================================================================

Uses "TBGL" , "Math"

BEGIN CONST
' -- Scene IDs
%sScene = 1
%texOne = 1
' -- Entity IDs
%eCamera = 1
%eLight

%eSun
%tSun
%eEarth
%eMoonGuide
%eMoon
END CONST

FUNCTION TBMAIN()
LOCAL hWnd As DWORD
Global FrameRate As Long
Global ang, earthX, earthZ, OrbitRadius As Single
Global flag, wireframe As Long
flag = 1
OrbitRadius = 7.5

' -- Create and show window
hWnd = TBGL_CreateWindowEx("press Space to toggle the camera position , 'W' to toggle wire/solid frame ", 800, 600, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow

' -- Create scene
TBGL_SceneCreate(%sScene)

'TBGL_LoadTexture APP_Path+"SampleScripts\TBGL\GBuffers\Textures\Bricks.bmp", %texOne, %TBGL_TEX_MIPMAP
' -- Create basic entities
' -- Create camera to look from 0, 2, 7 to 0, 0, 0
TBGL_EntityCreateCamera(%sScene, %eCamera)
TBGL_EntitySetPos(%sScene, %eCamera, 0, 0, -21)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)

' -- Create point light
TBGL_EntityCreateLight(%sScene, %eLight)
TBGL_EntitySetPos(%sScene, %eLight, 0, 0, 0)

' -- Create something to look at

TBGL_EntityCreateFuncSlot(%sScene, %eSun, 0, "Sun_Render")

TBGL_EntityCreateFuncSlot(%sScene, %eEarth, 0, "Earth_Render")
TBGL_EntityTurn(%sScene, %eEarth, 0, 0, 23)

TBGL_EntityCreateFuncSlot(%sScene, %eMoonGuide, 0, "MoonGuide_Render")
TBGL_EntityTurn(%sScene, %eMoonGuide, 0, 0, 5.5)
TBGL_EntitySetPos(%sScene, %eMoonGuide, 0, 0, 0)


TBGL_EntityCreateFuncSlot(%sScene, %eMoon, 0, "Moon_Render")
'attach the moon to the blue ball inside the earth
TBGL_EntityAttach(%sScene, %eMoon, %eMoonGuide, %TBGL_DEFAULT)

' -- Resets status of all keys
TBGL_ResetKeyState()

TBGL_EntitySetTexture(%sScene, %eEarth, %texOne )
TBGL_LoadTexture APP_Path+"SampleScripts\TBGL\EntityBased\Textures\alien2.bmp", %texOne, %TBGL_TEX_MIPMAP
'TBGL_LoadTexture APP_Path+"SampleScripts\TBGL\GBuffers\Textures\Bricks.bmp", %texOne, %TBGL_TEX_MIPMAP
TBGL_EntitySetColor(%sScene, %eEarth, 255, 255, 255)

TBGL_PolygonLook %GL_FILL

' -- Main loop
While TBGL_IsWindow(hWnd)
FrameRate = TBGL_GetFrameRate
TBGL_SetWindowTitle( hWnd, "FPS =" +Str$(FrameRate)+" press 'Space' to toggle the camera position , 'W' to toggle wire/solid frame")

TBGL_ClearFrame
If TBGL_GetWindowKeyOnce( hWnd, %VK_SPACE) Then
If flag = 1 Then
TBGL_EntitySetPos(%sScene, %eCamera, 0, 30, -0.1)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)

flag * -1
Else
TBGL_EntitySetPos(%sScene, %eCamera, 0, 0, -21)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)
flag * -1
End If
End If

If TBGL_GetWindowKeyOnce( hWnd, %VK_W) Then
wireframe = Not wireframe
TBGL_PolygonLook IIf(wireframe, %GL_LINE, %GL_FILL)
End If

orbit()

TBGL_SceneRender(%sScene)

TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While

Wend

TBGL_DestroyWindow
END FUNCTION

Sub orbit()
ang + 0.4 ' determine the rotational speed
earthX = OrbitRadius * Sin(DegToRad(ang)) ' FORMULA For the circular motion
earthZ = OrbitRadius * Cos(DegToRad(ang)) ' FORMULA For the circular motion
TBGL_EntitySetPos(%sScene, %eEarth, earthX, 0, earthZ)
TBGL_EntitySetPos(%sScene, %eMoonGuide, earthX, 0, earthZ)
TBGL_EntitySetTargetPos(%sScene, %eLight, earthX, 0, earthZ)

End Sub

' -- Render procedure
Sub Earth_Render()
TBGL_EntitySetColor(%sScene, %eEarth, 0, 255, 0)
'TBGL_EntitySetTexture(%sScene, %eEarth, %texOne )
TBGL_EntitySetPos(%sScene, %eEarth, 0, 0, 0)
TBGL_EntityTurn(%sScene, %eEarth, 0, 100/FrameRate, 0)

' -- earth represented by a sphere
TBGL_Sphere 1.2
TBGL_Translate 0,-1.8,0
TBGL_Cylinder 0.2,0.2,4 'earth axis
End Sub

Sub Moon_Render()
TBGL_EntitySetRot(%sScene, %eMoon, 0, 0, 0 )
TBGL_EntityTurn(%sScene, %eMoon, 0, 100/FrameRate, 0)
TBGL_EntitySetColor(%sScene, %eMoon, 255, 255, 155)
TBGL_EntitySetPos(%sScene, %eMoon, 3, 0, 0)
TBGL_EntitySetScale(%sScene, %eMoon, 0.4, 0.4, 0.4)
' -- Moon represented by a sphere
TBGL_Sphere 1.2
TBGL_Translate 0,-3.6,0
TBGL_Cylinder 0.1,0.1,8 'moon axis
End Sub

Sub Sun_Render()

TBGL_EntitySetColor(%sScene, %eSun, 255, 255, 0)
'TBGL_EntitySetSpecular(%sScene, %eSun, 255, 0, 0 )
TBGL_EntitySetPos(%sScene, %eSun, 0, 0, 0)
TBGL_EntityTurn(%sScene, %eSun, 0, 40/FrameRate, 0)
' -- earth represented by a sphere
TBGL_UseLighting %FALSE
TBGL_Sphere 0.7
TBGL_UseLighting %TRUE
End Sub

Sub MoonGuide_Render()
TBGL_EntitySetColor(%sScene, %eMoonGuide, 255, 0, 255)
TBGL_EntityTurn(%sScene, %eMoonGuide, 0, 100/FrameRate, 0)
' -- MoonGuide represented by a sphere
TBGL_Sphere 0.6
End Sub


demo: Moon phases:
very rough, but it show the idea, in the future i will try to reflect the real dimensions (scaled down)
position the camera on earth center (it should be at earth surface)
make the camera (the observer) look at the moon by tracking its positions

'depending on example "TBGL_CustomSphereEntity" by Petr Schreiber, 2009 =
'===============================================================================

Uses "TBGL" , "Math"

BEGIN CONST
' -- Scene IDs
%sScene = 1
%texOne = 1
' -- Entity IDs
%eCamera = 1
%eLight

%eSun
%tSun
%eEarth
%eMoonGuide
%eMoon
END CONST

FUNCTION TBMAIN()
LOCAL hWnd As DWORD
Global FrameRate As Long
Global ang, earthX, earthZ, OrbitRadius, mX,mY,mZ As Single
Global flag, wireframe As Long
flag = 1
OrbitRadius = 7.5

' -- Create and show window
hWnd = TBGL_CreateWindowEx("Moon Phases from the viewpoint of observer on earth ", 800, 600, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow

' -- Create scene
TBGL_SceneCreate(%sScene)

'TBGL_LoadTexture APP_Path+"SampleScripts\TBGL\GBuffers\Textures\Bricks.bmp", %texOne, %TBGL_TEX_MIPMAP
' -- Create basic entities
' -- Create camera to look from 0, 2, 7 to 0, 0, 0
TBGL_EntityCreateCamera(%sScene, %eCamera)
TBGL_EntitySetPos(%sScene, %eCamera, 0, 0, -21)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)

' -- Create point light
TBGL_EntityCreateLight(%sScene, %eLight)
TBGL_EntitySetPos(%sScene, %eLight, 0, 0, 0)

' -- Create something to look at

TBGL_EntityCreateFuncSlot(%sScene, %eSun, 0, "Sun_Render")

TBGL_EntityCreateFuncSlot(%sScene, %eEarth, 0, "Earth_Render")
TBGL_EntityTurn(%sScene, %eEarth, 0, 0, 23)

TBGL_EntityCreateFuncSlot(%sScene, %eMoonGuide, 0, "MoonGuide_Render")
TBGL_EntityTurn(%sScene, %eMoonGuide, 0, 0, 5.5)
TBGL_EntitySetPos(%sScene, %eMoonGuide, 0, 0, 0)


TBGL_EntityCreateFuncSlot(%sScene, %eMoon, 0, "Moon_Render")
'attach the moon to the blue ball inside the earth
TBGL_EntityAttach(%sScene, %eMoon, %eMoonGuide, %TBGL_DEFAULT)

' -- Resets status of all keys
TBGL_ResetKeyState()

TBGL_EntitySetTexture(%sScene, %eEarth, %texOne )
TBGL_LoadTexture APP_Path+"SampleScripts\TBGL\EntityBased\Textures\alien2.bmp", %texOne, %TBGL_TEX_MIPMAP
'TBGL_LoadTexture APP_Path+"SampleScripts\TBGL\GBuffers\Textures\Bricks.bmp", %texOne, %TBGL_TEX_MIPMAP
TBGL_EntitySetColor(%sScene, %eEarth, 255, 255, 255)

TBGL_PolygonLook %GL_FILL

' -- Main loop
While TBGL_IsWindow(hWnd)
FrameRate = TBGL_GetFrameRate
TBGL_SetWindowTitle( hWnd, "FPS =" +Str$(FrameRate)+" Moon Phases from the viewpoint of observer on earth")

TBGL_ClearFrame

orbit()

TBGL_SceneRender(%sScene)

TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While

Wend

TBGL_DestroyWindow
END FUNCTION

Sub orbit()
ang + 0.4 ' determine the rotational speed
earthX = OrbitRadius * Sin(DegToRad(ang)) ' FORMULA For the circular motion
earthZ = OrbitRadius * Cos(DegToRad(ang)) ' FORMULA For the circular motion
TBGL_EntitySetPos(%sScene, %eEarth, earthX, 0, earthZ)
TBGL_EntitySetPos(%sScene, %eMoonGuide, earthX, 0, earthZ)
TBGL_EntitySetTargetPos(%sScene, %eLight, earthX, 0, earthZ)
TBGL_EntitySetPos(%sScene, %eCamera, earthX, 0.0, earthZ)
TBGL_EntityGetPos( %sScene, %eMoon, mx, my, mz, %TRUE)
TBGL_EntitySetTargetPos(%sScene, %eCamera, mX, mY, mZ)

End Sub

' -- Render procedure
Sub Earth_Render()
TBGL_EntitySetColor(%sScene, %eEarth, 0, 255, 0)
TBGL_EntitySetPos(%sScene, %eEarth, 0, 0, 0)
TBGL_EntityTurn(%sScene, %eEarth, 0, 100/FrameRate, 0)
' -- earth represented by a sphere
TBGL_Sphere 0.01

End Sub

Sub Moon_Render()
TBGL_EntitySetRot(%sScene, %eMoon, 0, 0, 0 )
TBGL_EntityTurn(%sScene, %eMoon, 0, 100/FrameRate, 0)
TBGL_EntitySetColor(%sScene, %eMoon, 255, 255, 155)
TBGL_EntitySetPos(%sScene, %eMoon, 3, 0, 0)
TBGL_EntitySetScale(%sScene, %eMoon, 0.4, 0.4, 0.4)
' -- Moon represented by a sphere
TBGL_Sphere 1.2
TBGL_Translate 0,-3.6,0
TBGL_Cylinder 0.1,0.1,8 'moon axis
End Sub

Sub Sun_Render()

TBGL_EntitySetColor(%sScene, %eSun, 255, 255, 0)
'TBGL_EntitySetSpecular(%sScene, %eSun, 255, 0, 0 )
TBGL_EntitySetPos(%sScene, %eSun, 0, 0, 0)
TBGL_EntityTurn(%sScene, %eSun, 0, 40/FrameRate, 0)
' -- earth represented by a sphere
TBGL_UseLighting %FALSE
TBGL_Sphere 0.09
TBGL_UseLighting %TRUE
End Sub

Sub MoonGuide_Render()
TBGL_EntitySetColor(%sScene, %eMoonGuide, 255, 0, 255)
TBGL_EntityTurn(%sScene, %eMoonGuide, 0, 50/FrameRate, 0)
' -- MoonGuide represented by a sphere
TBGL_Sphere 0.001
End Sub


a joke i read:
Which is more important, the sun or the moon, in giving us light?" A little boy asked his teacher.
"It must be the moon," the teacher answered.
Boy: Why?
Teacher: Because the moon shines at night, when it is dark.
ref : http://idv.sinica.edu.tw/jwang/

Petr Schreiber
08-10-2017, 21:51
Dear Primo,

you made my day. Excellent example, thanks for sharing! :eusaclap:


Petr

Petr Schreiber
09-10-2017, 17:36
Did you know?

You can improve the quality of the primitives by manipulating it this way:


tbgl_setprimitivequality 100


Use this parameter wisely, it leads to increased polycount :)


Petr

Petr Schreiber
09-10-2017, 17:41
How to ensure the animation will reach roughly the same speed on any PC?

Scale the movement/rotations by the frame rate.

For example, if you want something to turn 360° in one second, you can do:


tbgl_entityTurn(%scene, %something, 0, 360/FrameRate, 0)


If you perform PC performance dependant additions like:


angle + 0.4 ' equivalent of angle += 0.4, or angle = angle + 0.4


...it will result in varied performance on slower and faster PC.

If you approach it like:


angle + 360/FrameRate


... it will ensure angle will reach 360 in +/- one second on any PC.


Petr

primo
09-10-2017, 21:21
Thanks Petr for the tips, yes i have noticed the rough sphere in the moon phases example, this will help in the future more realistic moon phases demo, i have tried it like this:
TBGL_PushMatrix
TBGL_SetPrimitiveQuality 100
TBGL_Sphere 1.2
TBGL_PopMatrix
TBGL_SetPrimitiveQuality 24

Kuron
09-10-2017, 21:51
Really nice work, Primo.


And thanks to Petr for the awesome tips.