PDA

View Full Version : Rotation issues



primo
24-12-2015, 16:33
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

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

Petr Schreiber
25-12-2015, 11:09
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:


TBGL_m15LoadModel ModelFile, "Textures\", 1, 1, %TBGL_NORMAL_PRECISE


#2: TBGL has dedicated TBGL_ResetKeyState to reset the keys before reading them


Petr

Petr Schreiber
25-12-2015, 11:25
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


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

primo
25-12-2015, 15:44
Thank you Petr for the suggestions and the new code