-
1 Attachment(s)
Rotation issues
some times our graphics rotate in an orbit instead of around itself. also some models do the same thing. there is a sub to adjust the object vertices so it will rotate correctly around itself (the sub is not mine). i will use a model from Petr utility thinEdge (simple house). by default it will rotate around the far end of its front yard, so the house will rotate in orbit, after centering it will rotate around its front door, and wherever we translate it it will still keep the correct rotations
so comment/uncomment line 025 GraphicsCentering() to see the difference.
note: the M15 models have a great and many functions to manipulate its vertices, and i have used some of them to get and then to set the new vertices xyz coordinates.
you need the house model and its textures zipped in the attached file
Code:
Uses "TBGL"
Uses "UI"
Uses "FILE"
DIM hWnd as dword
' We will initialize OpenGL and internal buffers
' Function also returns window handle
hWnd = TBGL_CreateWindowEx(" Graphics Centering - ESC to quit", 640, 480, 32, %TBGL_WS_WINDOWED )
TBGL_ShowWindow ' This will display the window on the screen
TBGL_GetAsyncKeyState(-1) ' Reset status of the all keys to prevent immediate quit
Dim ModelFile As String
ModelFile = "simple_house.m15"
TBGL_m15LoadModel ModelFile, "Textures\", 1, 1, 2
Dim LightX, LightY, LightZ As Single
LightY = 0 :LightZ = 0
TBGL_UseLighting 1
TBGL_UseLightSource %GL_LIGHT0, 1
TBGL_SetupLightSource %GL_LIGHT0, LightX, LightY, LightZ, 32,32,32,255
'===========================================================
GraphicsCentering()
'===========================================================
while TBGL_IsWindow(hWnd) ' While window exists, we will draw and check for ESCAPE
tbgl_ClearFrame ' This clears the frame and prepares it for drawing
TBGL_Camera 0,20,10,0,15,0 ' We will look from point 0,0,10 to 0,0,0 ( origin of coordinates )
TBGL_Translate 0,0,-30
TBGL_Rotate GetTickCount/10, 0, 1, 0
TBGL_m15DrawModel 1
tbgl_DrawFrame ' This will display the scene
' When ESCAPE is pressed, we will leave the main loop
IF TBGL_GetWindowKeyState( hWnd, %VK_ESCAPE ) THEN EXIT while
Wend
tbgl_DestroyWindow ' This will destroy the window
'******************************************
Sub GraphicsCentering()
Local i, vtx As Long
Local x,y,z As Single
vtx = TBGL_m15GetModelVertexcount(1)
Dim minx, miny, minz, maxx, maxy, maxz As Single
Dim corx, cory, corz As Single
minx = 99999
miny = 99999
minz = 99999
maxx = -99999
maxy = -99999
maxz = -99999
For i = 1 To vtx
'TBGL_m15GetVertexXYZ( ModelID, VertexIndex, varX, varY, varZ )
TBGL_m15GetVertexXYZ(1, i, x, y, z)
If x > maxx Then
maxx = x
End If
If x < minx Then
minx = x
End If
If y > maxy Then
maxy = y
End If
If y < miny Then
miny = y
End If
If z > maxz Then
maxz = z
End If
If z < minz Then
minz = z
End If
Next
corx = (-maxx - minx) /2.0
cory = (-maxy - miny) /2.0
corz = (-maxz - minz) /2.0
'MsgBox 0, str$(corx)+" " + str$(cory)+" " +str$(corz)
For i = 1 To vtx
x = TBGL_m15GetVertexX( 1, i )
y = TBGL_m15GetVertexY( 1, i )
z = TBGL_m15GetVertexZ( 1, i )
TBGL_m15SetVertexXYZ(1, i, x+corx, y+cory, z+corz)
Next
End Sub
-
Hi Primo,
thanks for the nice example. The pivot of rotation is responsibility of the artist (the one who makes the model).
Many times the models are not made centered, to fit a particular scenario (fitting top left corner of grid and such).
So it is not exactly an issue in TBGL itself, but something to be aware of when preparing art for the project.
Few hints for the code:
#1: It is better to specify the normal method via equate. For the case of house the PRECISE gives more pleasing results:
Code:
TBGL_m15LoadModel ModelFile, "Textures\", 1, 1, %TBGL_NORMAL_PRECISE
#2: TBGL has dedicated TBGL_ResetKeyState to reset the keys before reading them
Petr
-
I adjusted the code in a way it uses latest language features - you can see how to center the model without modifying the X, Y, Z of the vertices:
Note: Media files from original code needed
Code:
Uses "TBGL"
Function TBMain()
DWord hWnd = TBGL_CreateWindowEx("Graphics Centering - ESC to quit", 640, 480, 32, %TBGL_WS_WINDOWED)
TBGL_ShowWindow
String modelFile = "simple_house.m15"
TBGL_m15LoadModel ModelFile, "Textures\", 1, 1, %TBGL_NORMAL_PRECISE
Dim light As TBGL_TVECTOR3D
TBGL_UseLighting TRUE
TBGL_UseLightSource %GL_LIGHT0, TRUE
TBGL_SetupLightSource %GL_LIGHT0, light.x, light.y, light.z, 32, 32, 32, 255
Dim center As TBGL_TVECTOR3D
center = GetModelCenter(1)
TBGL_ResetKeyState()
While TBGL_IsWindow(hWnd)
TBGL_ClearFrame
TBGL_Camera 0, 20, 60,
0, 0, 0
TBGL_PushMatrix
TBGL_Rotate GetTickCount/10, 0, 1, 0 ' -- Turn model
TBGL_Translate -center.x, -center.y, -center.z ' -- Center the rotation
TBGL_m15DrawModel 1
TBGL_PopMatrix
TBGL_DrawFrame
If TBGL_GetWindowKeyState( hWnd, %VK_ESCAPE ) Then Exit While
Wend
TBGL_DestroyWindow
End Function
Function GetModelCenter( modelId As Long ) As String ' -- Hack to return TYPEs
Long i, vtx
Single x,y,z
vtx = TBGL_m15GetModelVertexcount(modelId)
Single minx, miny, minz = 99999
Single maxx, maxy, maxz = -99999
Dim center As TBGL_TVECTOR3D
For i = 1 To vtx
TBGL_m15GetVertexXYZ(modelId, i, x, y, z)
maxx = Max(x, maxx)
minx = Min(x, minx)
maxy = Max(y, maxy)
miny = Min(y, miny)
maxz = Max(z, maxz)
minz = Min(z, minz)
Next
center.x = minx + (maxx - minx) / 2.0
center.y = miny + (maxy - miny) / 2.0
center.z = minz + (maxz - minz) / 2.0
Return center
End Function
Petr
-
Thank you Petr for the suggestions and the new code