' ________________________________________________________________________ ' TrueVision3D (web: http://www.truevision3d.com) ' ???????????????????????????????????? ' Tutorial 4 : Keyboard/Mouse input. ' ????? ' Description : In this 4th tutorial, we will take everything from the ' ?????? 3rd tutorial and add keyboard input to move and turn ' the teapot. Mouse input is also added, and this ' kind of mouse input can be easily adapted for a model viewer.
' Force explicit declarations Option Explicit
' We declare TVEngine. Private TV3D As TVEngine
' You know how do do this, we declare the teapot. Private Teapot As TVMesh
' We the clare the scene Private Scene As TVScene
' To check if we pressed a key on the keyboard or clicked on a mouse ' button, we have to use the TrueVision3D input object. Private InputEngine As TVInputEngine
' The loop. Private DoLoop As Boolean
' We need some variables to hold the vector (position) of the teapot as ' well as the teapot angles (for rotation). Never forget that for ' positions and angles, we need to declare the variables as single. Private sngAngleX As Single Private sngAngleY As Single Private sngAngleZ As Single Private sngPositionX As Single Private sngPositionY As Single Private sngPositionZ As Single
Private Sub cmdQuit_Click()
' We have clicked on the "Quit" button, so we change the DoLoop. DoLoop = False
End Sub
Private Sub Form_Load()
' We have to create the TV3D object before anything else. Set TV3D = New TVEngine
'We set the debug file in the app directory TV3D.SetDebugFile App.Path + "\debugfile.txt" ' Set the search directory of the objects, textures, ... TV3D.SetSearchDirectory App.Path ' We initialize TV3D in the picture box of the form. TV3D.Init3DWindowedMode Picture1.hWnd
' We want to see the FPS. TV3D.DisplayFPS = True 'We set the AngleSystem TV3D.SetAngleSystem TV_ANGLE_DEGREE
' To use the TVInputEngine, we have to create an object, just like ' the TV3D and the scene. '定义输入引擎 Set InputEngine = New TVInputEngine ' We create the scene (the world). Set Scene = New TVScene
' We load the texture Scene.LoadTexture "..\..\..\Media\texture.bmp", , , "TeapotTexture"
' We create the 3D teapot object. Set Teapot = New TVMesh ' We tell the scene that it will have to take the teapot object and ' create a mesh with it. Set Teapot = Scene.CreateMeshBuilder ' We load the teapot mesh. Teapot.CreateTeapot ' Assign the texture to the teapot mesh. Teapot.SetTexture GetTex("TeapotTexture") ' Set texture as chrome. Teapot.EnableSphereMapping True ' We set the teapot position. sngPositionX = 0 sngPositionY = 0 sngPositionZ = 10 Teapot.SetPosition sngPositionX, sngPositionY, sngPositionZ ' Set the teapot initial rotation. sngAngleX = 0 sngAngleY = 0 sngAngleZ = 0 Teapot.SetRotation sngAngleX, sngAngleY, sngAngleZ
' We pop the form over everything else. Form1.Show ' We start the main loop. DoLoop = True Main_Loop
End Sub
Private Sub Form_Unload(Cancel As Integer)
' The user asked to quit but clicked on the 'X' button at up right. DoLoop = False ' And ask to quit. Main_Quit
End Sub
Private Sub Main_Loop()
' The main loop Do ' Let us the capacity to use buttons of the form. DoEvents ' New : the project check if we have pressed a key of the ' keyboard, moved the mouse or clicked on a button. We have to ' look for each input key : if the key is pressed, we get a ' return value of True, if not, we get a return value of False. ' Check if we pressed the UP arrow key, if so, move ' the teapot higher. '如果输入引擎中按下上下键,则Y坐标相应变换 If InputEngine.IsKeyPressed(TV_KEY_UP) = True Then sngPositionY = sngPositionY + (TV3D.TimeElapsed / 100) End If ' Check if we pressed the DOWN arrow key, if so, move ' the teapot lower. If InputEngine.IsKeyPressed(TV_KEY_DOWN) = True Then sngPositionY = sngPositionY - (TV3D.TimeElapsed / 100) End If ' Check if we pressed the LEFT arrow key, if so, move ' the teapot to the left. '如果按下左右键,则X坐标相应变换 If InputEngine.IsKeyPressed(TV_KEY_LEFT) = True Then sngPositionX = sngPositionX - (TV3D.TimeElapsed / 100) End If ' Check if we pressed the RIGHT arrow key, if so, move ' the teapot to the right. If InputEngine.IsKeyPressed(TV_KEY_RIGHT) = True Then sngPositionX = sngPositionX + (TV3D.TimeElapsed / 100) End If ' Check if we pressed the SUBSTRACT key, if so, move the ' teapot away from us. '如果按下加减键,则Z坐标相应变换 If InputEngine.IsKeyPressed(TV_KEY_SUBTRACT) = True Then sngPositionZ = sngPositionZ + (TV3D.TimeElapsed / 100) End If ' Check if we pressed the ADD key, if so, move the teapot ' in our direction. If InputEngine.IsKeyPressed(TV_KEY_ADD) = True Then sngPositionZ = sngPositionZ - (TV3D.TimeElapsed / 100) End If
' Now, for the mouse input, we have to declare variables ' where to store temporaly the value of the mouse movement ' and mouse buttons press value. If a mouse button is pressed, ' we don't get a True value but something else than 0 value. ' 定义鼠标临时坐标及按钮 Dim tmpMouseX As Long, tmpMouseY As Long Dim tmpMouseB1 As Integer, tmpMouseB2 As Integer, tmpMouseB3 As Integer ' We also need to declare two variables for the mouse scroller : ' we need the old value and the new value, so we can compare them. Dim tmpMouseScrollOld As Long, tmpMouseScrollNew As Long ' We pass the actual value of the mouse scroller to the variable ' that holds the old mouse scroller value. tmpMouseScrollOld = tmpMouseScrollNew ' By using GetMouseState, we get the movement of the mouse ' with the speed of the movement. The fastest the mouse movement ' will be, the higher will be the return. InputEngine.GetMouseState tmpMouseX, tmpMouseY, tmpMouseB1, tmpMouseB2, tmpMouseB3, tmpMouseScrollNew ' We update the teapot angles only if we are pressing the ' mouse button1. Else, we turn the teapot automaticaly. If tmpMouseB1 <> 0 Then ' From the mouse return values, we update the teapot angles ' by adding or substracting the mouse return value. sngAngleX = sngAngleX - (tmpMouseY * TV3D.TimeElapsed / 3) sngAngleY = sngAngleY - (tmpMouseX * TV3D.TimeElapsed / 3) Else ' Turn that teapot sngAngleY = sngAngleY + (TV3D.TimeElapsed / 100) End If ' We also add the same feature as the keyboard arrows keypress, ' but we add this feature using the mouse button2. If tmpMouseB2 <> 0 Then ' From the mouse return values, we update the teapot positions ' by adding or substracting the mouse return value. sngPositionX = sngPositionX + (tmpMouseX * TV3D.TimeElapsed / 100) sngPositionY = sngPositionY - (tmpMouseY * TV3D.TimeElapsed / 100) End If ' We check the mouse scroller value. If the newest value of the ' scroller is lower than the old value, then we move the teapot ' away from us. Guess what we are going to do if the newest ' value is higher than the old value... '判断鼠标滚动过程 Select Case tmpMouseScrollNew Case Is > tmpMouseScrollOld '如果新值大于旧值,Z轴变小 ' Take the difference between the new and old value and move ' the teapot according to that difference. sngPositionZ = sngPositionZ - ((tmpMouseScrollNew - tmpMouseScrollOld) / 100) Case Is < tmpMouseScrollOld '如果新值小于旧值,Z轴变大 ' Take the difference between the new and old value and move ' the teapot according to that difference. sngPositionZ = sngPositionZ - ((tmpMouseScrollNew - tmpMouseScrollOld) / 100) End Select ' We update the teapot position and rotation according to the ' position and angle variables that we just updated above. '根据设定的位置角度进行相关设置 Teapot.SetPosition sngPositionX, sngPositionY, sngPositionZ Teapot.SetRotation sngAngleX, sngAngleY, sngAngleZ ' Clear the the last frame. TV3D.Clear ' We render all the 3D objects contained in the scene. '渲染所有模型 Scene.RenderAllMeshes ' We display everything that we have rendered '渲染至屏幕 TV3D.RenderToScreen 'We loop all of this until the DoLoop isn't True. Loop Until DoLoop = False ' We ask to quit. Main_Quit
End Sub
Private Sub Main_Quit() ' We want to quit the project, so we destroy the teapot object. Set Teapot = Nothing ' Don't forget to destroy the inputengine object... Set InputEngine = Nothing ' Then, we destroy the scene object. Set Scene = Nothing ' We finish the frenetic destroy with the TV3D object. Set TV3D = Nothing ' We end the application. End
End Sub
|