Implementing the Xbox Controller
Tags: android, vrgame, devlog, xboxcontroller
Published: 2020-05-03 15:11:00

#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 <code>LookControlInterface</code>, <code>MoveControlInterface</code>, <code>ButtonControlInterface</code> and the <code>GameContolHub</code> class.
The <code>XboxController</code> 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 <code>GameControlHub</code> instance as each of the interfaces.

![instantiation of new classes](https://dev-to-uploads.s3.amazonaws.com/i/5uesyc8zvbmmdxh60874.PNG)
The <code>GameControlHub</code> instance was then passed to the <code>VrRenderer</code> instance via the <code>VrGlSurfaceView</code> to allow the renderer to process game controls.
#The <code>XboxController</code> class
This class was based on the [Android handling controller actions guide](https://developer.android.com/training/game-controllers/controller-input) with the following exceptions:
<ul>
<li>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</li>
<li>I worked out which <code>MotionEvent</code> 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.</li>
</ul>
##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 <code>onGenericMotionEvent</code> function, to make this usable, I kept a local copy of the last reported position of the sticks as <code>mTranslationMatrix</code> for both the left stick axis and <code>mPitchDelta</code> for the right stick's up/down axis and <code>mYawDelta</code> for the right stick's left/right axis.
Whenever the <code>getLatestTranslationMatrix</code> function is called, I simply return a copy of <code>mTranslationMatrix</code>.
Whenever the <code>getLatestRotationMatrix</code> function is called, the current <code>mPitchAngle</code> is adjusted by <code>mPitchDelta</code>, making sure it is capped at looking directly up or directly down and <code>mYawAngle</code> is adjusted by <code>mYawDelta</code>, making sure to wrap the angle from 360° to 0° for incrementing angles or 0° to 360° for decrementing angles.
These new values of <code>mPitchAngle</code> and <code>mYawAngle</code> are used to generate the rotation matrix which is returned.
When calculating the rotation matrix, the <code>mPitchAngle</code> 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 <code>GameCamera</code> class to allow adjustments to the position and we need to finish off the <code>setCameraRotation</code> method.
The <code>adjustPosition</code> function is pretty simple and just adds the passed x, y and z delta's to the current x, y and z positions.
![Screen capture of adjustPosition method](https://dev-to-uploads.s3.amazonaws.com/i/4il5oda4eb5wbkrwab5u.PNG)
The <code>setCameraRotation</code> method creates a <code>forward</code> matrix which represents a translation of 1 unit forward and an <code>up</code> matrix which represents a translation of 1 unit up. 
![forward and up matrix creation](https://dev-to-uploads.s3.amazonaws.com/i/x96bnqi5qxprhgmmh1wi.PNG)
Each of these matrices are multiplied by the passed rotation matrix <code>rotMat</code> and the 12th, 13th and 14th elements are extracted from the matrices to set the <code>mLookDirectionX</code>, <code>mLookDirectionY</code>, <code>mLookDirectionZ</code>, <code>mUpDirectionX</code>, <code>mUpDirectionY</code> and <code>mUpDirectionZ</code> values.
![rotating the forward and up matrices and setting local variables](https://dev-to-uploads.s3.amazonaws.com/i/j8li9bg4t53pmeikjtmm.PNG)
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](https://github.com/longevity-software/AndroidVrGameDemo/releases/tag/B1.3).

#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.