2014-04-16 19:51:25 -07:00
/*
* Copyright 2013 Dario Manesku . All rights reserved .
2016-01-01 00:11:04 -08:00
* License : https : //github.com/bkaradzic/bgfx#license-bsd-2-clause
2014-04-16 19:51:25 -07:00
*/
# include <bx/timer.h>
2014-05-26 19:31:37 -07:00
# include <bx/fpumath.h>
2014-04-16 19:51:25 -07:00
# include "camera.h"
2015-11-01 17:28:23 -08:00
# include "entry/entry.h"
2014-04-16 19:51:25 -07:00
# include "entry/cmd.h"
# include "entry/input.h"
2015-11-01 17:28:23 -08:00
# include <bx/allocator.h>
2014-04-16 19:51:25 -07:00
int cmdMove ( CmdContext * /*_context*/ , void * /*_userData*/ , int _argc , char const * const * _argv )
{
if ( _argc > 1 )
{
if ( 0 = = strcmp ( _argv [ 1 ] , " forward " ) )
{
2014-12-15 20:59:22 -08:00
cameraSetKeyState ( CAMERA_KEY_FORWARD , true ) ;
2014-04-16 19:51:25 -07:00
return 0 ;
}
else if ( 0 = = strcmp ( _argv [ 1 ] , " left " ) )
{
cameraSetKeyState ( CAMERA_KEY_LEFT , true ) ;
return 0 ;
}
else if ( 0 = = strcmp ( _argv [ 1 ] , " right " ) )
{
cameraSetKeyState ( CAMERA_KEY_RIGHT , true ) ;
return 0 ;
}
else if ( 0 = = strcmp ( _argv [ 1 ] , " backward " ) )
2014-12-15 20:59:22 -08:00
{
cameraSetKeyState ( CAMERA_KEY_BACKWARD , true ) ;
return 0 ;
}
else if ( 0 = = strcmp ( _argv [ 1 ] , " up " ) )
{
cameraSetKeyState ( CAMERA_KEY_UP , true ) ;
return 0 ;
}
else if ( 0 = = strcmp ( _argv [ 1 ] , " down " ) )
2014-04-16 19:51:25 -07:00
{
cameraSetKeyState ( CAMERA_KEY_DOWN , true ) ;
return 0 ;
}
}
return 1 ;
}
static void cmd ( const void * _userData )
{
cmdExec ( ( const char * ) _userData ) ;
}
2015-08-21 22:52:37 -07:00
static const InputBinding s_camBindings [ ] =
2014-04-16 19:51:25 -07:00
{
2014-12-15 20:59:22 -08:00
{ entry : : Key : : KeyW , entry : : Modifier : : None , 0 , cmd , " move forward " } ,
{ entry : : Key : : GamepadUp , entry : : Modifier : : None , 0 , cmd , " move forward " } ,
{ entry : : Key : : KeyA , entry : : Modifier : : None , 0 , cmd , " move left " } ,
{ entry : : Key : : GamepadLeft , entry : : Modifier : : None , 0 , cmd , " move left " } ,
{ entry : : Key : : KeyS , entry : : Modifier : : None , 0 , cmd , " move backward " } ,
{ entry : : Key : : GamepadDown , entry : : Modifier : : None , 0 , cmd , " move backward " } ,
{ entry : : Key : : KeyD , entry : : Modifier : : None , 0 , cmd , " move right " } ,
{ entry : : Key : : GamepadRight , entry : : Modifier : : None , 0 , cmd , " move right " } ,
2015-11-01 17:28:23 -08:00
{ entry : : Key : : KeyQ , entry : : Modifier : : None , 0 , cmd , " move down " } ,
2014-12-15 20:59:22 -08:00
{ entry : : Key : : GamepadShoulderL , entry : : Modifier : : None , 0 , cmd , " move down " } ,
2015-11-01 17:28:23 -08:00
{ entry : : Key : : KeyE , entry : : Modifier : : None , 0 , cmd , " move up " } ,
2014-12-15 20:59:22 -08:00
{ entry : : Key : : GamepadShoulderR , entry : : Modifier : : None , 0 , cmd , " move up " } ,
2014-04-16 19:51:25 -07:00
INPUT_BINDING_END
} ;
struct Camera
{
struct MouseCoords
{
int32_t m_mx ;
int32_t m_my ;
} ;
Camera ( )
{
reset ( ) ;
2014-12-15 20:59:22 -08:00
entry : : MouseState mouseState ;
update ( 0.0f , mouseState ) ;
2014-04-16 19:51:25 -07:00
cmdAdd ( " move " , cmdMove ) ;
inputAddBindings ( " camBindings " , s_camBindings ) ;
}
~ Camera ( )
{
inputRemoveBindings ( " camBindings " ) ;
}
void reset ( )
{
2014-12-15 20:59:22 -08:00
m_mouseNow . m_mx = 0 ;
m_mouseNow . m_my = 0 ;
2014-04-16 19:51:25 -07:00
m_mouseLast . m_mx = 0 ;
m_mouseLast . m_my = 0 ;
2014-12-15 20:59:22 -08:00
m_eye [ 0 ] = 0.0f ;
m_eye [ 1 ] = 0.0f ;
2014-04-16 19:51:25 -07:00
m_eye [ 2 ] = - 35.0f ;
2014-12-15 20:59:22 -08:00
m_at [ 0 ] = 0.0f ;
m_at [ 1 ] = 0.0f ;
m_at [ 2 ] = - 1.0f ;
m_up [ 0 ] = 0.0f ;
m_up [ 1 ] = 1.0f ;
m_up [ 2 ] = 0.0f ;
2014-04-16 19:51:25 -07:00
m_horizontalAngle = 0.01f ;
m_verticalAngle = 0.0f ;
m_mouseSpeed = 0.0020f ;
2014-12-15 20:59:22 -08:00
m_gamepadSpeed = 0.04f ;
2014-04-16 19:51:25 -07:00
m_moveSpeed = 30.0f ;
m_keys = 0 ;
m_mouseDown = false ;
}
void setKeyState ( uint8_t _key , bool _down )
{
m_keys & = ~ _key ;
m_keys | = _down ? _key : 0 ;
}
2014-12-15 20:59:22 -08:00
void update ( float _deltaTime , const entry : : MouseState & _mouseState )
2014-04-16 19:51:25 -07:00
{
if ( ! m_mouseDown )
{
2014-12-15 20:59:22 -08:00
m_mouseLast . m_mx = _mouseState . m_mx ;
m_mouseLast . m_my = _mouseState . m_my ;
2014-04-16 19:51:25 -07:00
}
2014-12-15 20:59:22 -08:00
m_mouseDown = ! ! _mouseState . m_buttons [ entry : : MouseButton : : Right ] ;
2014-04-16 19:51:25 -07:00
2014-12-15 20:59:22 -08:00
if ( m_mouseDown )
2014-04-16 19:51:25 -07:00
{
2014-12-15 20:59:22 -08:00
m_mouseNow . m_mx = _mouseState . m_mx ;
m_mouseNow . m_my = _mouseState . m_my ;
2014-04-16 19:51:25 -07:00
}
if ( m_mouseDown )
{
int32_t deltaX = m_mouseNow . m_mx - m_mouseLast . m_mx ;
int32_t deltaY = m_mouseNow . m_my - m_mouseLast . m_my ;
m_horizontalAngle + = m_mouseSpeed * float ( deltaX ) ;
m_verticalAngle - = m_mouseSpeed * float ( deltaY ) ;
m_mouseLast . m_mx = m_mouseNow . m_mx ;
m_mouseLast . m_my = m_mouseNow . m_my ;
}
2014-12-15 20:59:22 -08:00
entry : : GamepadHandle handle = { 0 } ;
m_horizontalAngle + = m_gamepadSpeed * inputGetGamepadAxis ( handle , entry : : GamepadAxis : : RightX ) / 32768.0f ;
m_verticalAngle - = m_gamepadSpeed * inputGetGamepadAxis ( handle , entry : : GamepadAxis : : RightY ) / 32768.0f ;
const int32_t gpx = inputGetGamepadAxis ( handle , entry : : GamepadAxis : : LeftX ) ;
const int32_t gpy = inputGetGamepadAxis ( handle , entry : : GamepadAxis : : LeftY ) ;
m_keys | = gpx < - 16834 ? CAMERA_KEY_LEFT : 0 ;
m_keys | = gpx > 16834 ? CAMERA_KEY_RIGHT : 0 ;
m_keys | = gpy < - 16834 ? CAMERA_KEY_FORWARD : 0 ;
m_keys | = gpy > 16834 ? CAMERA_KEY_BACKWARD : 0 ;
2014-04-16 19:51:25 -07:00
float direction [ 3 ] =
{
cosf ( m_verticalAngle ) * sinf ( m_horizontalAngle ) ,
sinf ( m_verticalAngle ) ,
cosf ( m_verticalAngle ) * cosf ( m_horizontalAngle ) ,
} ;
float right [ 3 ] =
{
2014-10-23 21:10:44 -07:00
sinf ( m_horizontalAngle - bx : : piHalf ) ,
2014-04-16 19:51:25 -07:00
0 ,
2014-10-23 21:10:44 -07:00
cosf ( m_horizontalAngle - bx : : piHalf ) ,
2014-04-16 19:51:25 -07:00
} ;
2014-12-15 20:59:22 -08:00
float up [ 3 ] ;
bx : : vec3Cross ( up , right , direction ) ;
if ( m_keys & CAMERA_KEY_FORWARD )
2014-04-16 19:51:25 -07:00
{
2014-12-15 20:59:22 -08:00
float pos [ 3 ] ;
bx : : vec3Move ( pos , m_eye ) ;
float tmp [ 3 ] ;
bx : : vec3Mul ( tmp , direction , _deltaTime * m_moveSpeed ) ;
bx : : vec3Add ( m_eye , pos , tmp ) ;
setKeyState ( CAMERA_KEY_FORWARD , false ) ;
2014-04-16 19:51:25 -07:00
}
2014-12-15 20:59:22 -08:00
if ( m_keys & CAMERA_KEY_BACKWARD )
2014-04-16 19:51:25 -07:00
{
2014-12-15 20:59:22 -08:00
float pos [ 3 ] ;
bx : : vec3Move ( pos , m_eye ) ;
float tmp [ 3 ] ;
bx : : vec3Mul ( tmp , direction , _deltaTime * m_moveSpeed ) ;
bx : : vec3Sub ( m_eye , pos , tmp ) ;
setKeyState ( CAMERA_KEY_BACKWARD , false ) ;
2014-04-16 19:51:25 -07:00
}
if ( m_keys & CAMERA_KEY_LEFT )
{
2014-12-15 20:59:22 -08:00
float pos [ 3 ] ;
bx : : vec3Move ( pos , m_eye ) ;
float tmp [ 3 ] ;
bx : : vec3Mul ( tmp , right , _deltaTime * m_moveSpeed ) ;
bx : : vec3Add ( m_eye , pos , tmp ) ;
2014-04-16 19:51:25 -07:00
setKeyState ( CAMERA_KEY_LEFT , false ) ;
}
if ( m_keys & CAMERA_KEY_RIGHT )
{
2014-12-15 20:59:22 -08:00
float pos [ 3 ] ;
bx : : vec3Move ( pos , m_eye ) ;
float tmp [ 3 ] ;
bx : : vec3Mul ( tmp , right , _deltaTime * m_moveSpeed ) ;
bx : : vec3Sub ( m_eye , pos , tmp ) ;
2014-04-16 19:51:25 -07:00
setKeyState ( CAMERA_KEY_RIGHT , false ) ;
}
2014-12-15 20:59:22 -08:00
if ( m_keys & CAMERA_KEY_UP )
{
float pos [ 3 ] ;
bx : : vec3Move ( pos , m_eye ) ;
float tmp [ 3 ] ;
bx : : vec3Mul ( tmp , up , _deltaTime * m_moveSpeed ) ;
bx : : vec3Add ( m_eye , pos , tmp ) ;
setKeyState ( CAMERA_KEY_UP , false ) ;
}
if ( m_keys & CAMERA_KEY_DOWN )
{
float pos [ 3 ] ;
bx : : vec3Move ( pos , m_eye ) ;
float tmp [ 3 ] ;
bx : : vec3Mul ( tmp , up , _deltaTime * m_moveSpeed ) ;
bx : : vec3Sub ( m_eye , pos , tmp ) ;
setKeyState ( CAMERA_KEY_DOWN , false ) ;
}
2014-05-26 19:31:37 -07:00
bx : : vec3Add ( m_at , m_eye , direction ) ;
bx : : vec3Cross ( m_up , right , direction ) ;
2014-04-16 19:51:25 -07:00
}
void getViewMtx ( float * _viewMtx )
{
2014-05-26 19:31:37 -07:00
bx : : mtxLookAt ( _viewMtx , m_eye , m_at , m_up ) ;
2014-04-16 19:51:25 -07:00
}
2015-08-21 22:52:37 -07:00
void setPosition ( const float * _pos )
2014-04-16 19:51:25 -07:00
{
memcpy ( m_eye , _pos , sizeof ( float ) * 3 ) ;
}
void setVerticalAngle ( float _verticalAngle )
{
m_verticalAngle = _verticalAngle ;
}
2015-08-21 22:52:37 -07:00
2014-04-16 19:51:25 -07:00
void setHorizontalAngle ( float _horizontalAngle )
{
m_horizontalAngle = _horizontalAngle ;
}
2014-12-15 20:59:22 -08:00
MouseCoords m_mouseNow ;
MouseCoords m_mouseLast ;
2014-04-16 19:51:25 -07:00
float m_eye [ 3 ] ;
float m_at [ 3 ] ;
float m_up [ 3 ] ;
float m_horizontalAngle ;
float m_verticalAngle ;
2014-12-15 20:59:22 -08:00
2014-04-16 19:51:25 -07:00
float m_mouseSpeed ;
2014-12-15 20:59:22 -08:00
float m_gamepadSpeed ;
2014-04-16 19:51:25 -07:00
float m_moveSpeed ;
2014-12-15 20:59:22 -08:00
2014-04-16 19:51:25 -07:00
uint8_t m_keys ;
bool m_mouseDown ;
} ;
static Camera * s_camera = NULL ;
void cameraCreate ( )
{
2015-11-01 17:28:23 -08:00
s_camera = BX_NEW ( entry : : getAllocator ( ) , Camera ) ;
2014-04-16 19:51:25 -07:00
}
void cameraDestroy ( )
{
2015-11-01 17:28:23 -08:00
BX_DELETE ( entry : : getAllocator ( ) , s_camera ) ;
2014-04-16 19:51:25 -07:00
s_camera = NULL ;
}
2015-08-21 22:52:37 -07:00
void cameraSetPosition ( const float * _pos )
2014-04-16 19:51:25 -07:00
{
s_camera - > setPosition ( _pos ) ;
}
void cameraSetHorizontalAngle ( float _horizontalAngle )
{
s_camera - > setHorizontalAngle ( _horizontalAngle ) ;
}
void cameraSetVerticalAngle ( float _verticalAngle )
{
s_camera - > setVerticalAngle ( _verticalAngle ) ;
}
void cameraSetKeyState ( uint8_t _key , bool _down )
{
s_camera - > setKeyState ( _key , _down ) ;
}
void cameraGetViewMtx ( float * _viewMtx )
{
s_camera - > getViewMtx ( _viewMtx ) ;
}
void cameraGetPosition ( float * _pos )
{
2015-07-16 20:28:43 -07:00
memcpy ( _pos , s_camera - > m_eye , 3 * sizeof ( float ) ) ;
2014-04-16 19:51:25 -07:00
}
void cameraGetAt ( float * _at )
{
2015-07-16 20:28:43 -07:00
memcpy ( _at , s_camera - > m_at , 3 * sizeof ( float ) ) ;
2014-04-16 19:51:25 -07:00
}
2014-12-15 20:59:22 -08:00
void cameraUpdate ( float _deltaTime , const entry : : MouseState & _mouseState )
2014-04-16 19:51:25 -07:00
{
2014-12-15 20:59:22 -08:00
s_camera - > update ( _deltaTime , _mouseState ) ;
2014-04-16 19:51:25 -07:00
}