Before you read this.
While re-reading this post, I noticed an oversight in handling the movement controls. I shall address this in a subsequent post.
Abstracted control
Following from the last devlog I created the LookControlInterface
, MoveControlInterface
, ButtonControlInterface
and the GameContolHub
class.
The XboxController
class implemented the three control interfaces and a new instance of it was created in the activities onCreate method, which was then passed to the GameControlHub
instance as each of the interfaces.
The GameControlHub
instance was then passed to the VrRenderer
instance via the VrGlSurfaceView
to allow the renderer to process game controls.
The XboxController
class
This class was based on the Android handling controller actions guide with the following exceptions:
- I did not implement the code to check if there was a game controller connected as the class would just return identity matrices if there was no controller, this is an area of possible future improvement
- I worked out which
MotionEvent
axis equated to the left and right joystick's up/down and left/right axis and hard coded these, I am assuming all xbox controllers use the same control scheme so this should be fine.
Processing the stick inputs
This code only updates the Android device when a stick has changed position, if the stick is kept in the same position then there will be no updates via the onGenericMotionEvent
function, to make this usable, I kept a local copy of the last reported position of the sticks as mTranslationMatrix
for both the left stick axis and mPitchDelta
for the right stick's up/down axis and mYawDelta
for the right stick's left/right axis.
Whenever the getLatestTranslationMatrix
function is called, I simply return a copy of mTranslationMatrix
.
Whenever the getLatestRotationMatrix
function is called, the current mPitchAngle
is adjusted by mPitchDelta
, making sure it is capped at looking directly up or directly down and mYawAngle
is adjusted by mYawDelta
, making sure to wrap the angle from 360° to 0° for incrementing angles or 0° to 360° for decrementing angles.
These new values of mPitchAngle
and mYawAngle
are used to generate the rotation matrix which is returned.
When calculating the rotation matrix, the mPitchAngle
is rotated first, as the pitch won't be skewed by a subsequent yaw rotation but a yaw rotation would be skewed by a subsequent pitch rotation.
Doing something with this control input
Now that we have a method of receiving control input from the player, what are we going to do with it?
Initially we are going to move the camera position and look direction.
To do this we need to add a function to the GameCamera
class to allow adjustments to the position and we need to finish off the setCameraRotation
method.
The adjustPosition
function is pretty simple and just adds the passed x, y and z delta's to the current x, y and z positions.
The setCameraRotation
method creates a forward
matrix which represents a translation of 1 unit forward and an up
matrix which represents a translation of 1 unit up.
Each of these matrices are multiplied by the passed rotation matrix rotMat
and the 12th, 13th and 14th elements are extracted from the matrices to set the mLookDirectionX
, mLookDirectionY
, mLookDirectionZ
, mUpDirectionX
, mUpDirectionY
and mUpDirectionZ
values.
Once all this was implemented I added a few extra triangles to the scene so I could get a better sense of how I was moving around.
The Source code at this point of the process has been captured in pre-release B1.3 on Github.
The next steps
Next, I plan on implementing a skybox/cubemap to add a bit of background to the scene, this is not something I have done before but sounds pretty straight forward, I also plan on adding some more complex models and some lighting effects to the opengl shaders.
Top comments (0)