diff --git a/engine/openxr.cpp b/engine/openxr.cpp index 30b84aa..feb3ffb 100644 --- a/engine/openxr.cpp +++ b/engine/openxr.cpp @@ -51,6 +51,7 @@ struct OpenXRAction XrAction m_action; XrActionType m_eType; XrSpace m_space; + EXRInputType_t m_eUserInputType; }; class COpenXRController: public IXRController @@ -68,7 +69,7 @@ public: EXRControllerType_t m_type; EXRControllerSide_t m_side; CUtlVector m_actions; - XrActionSet m_actionSet; + XrActionSet m_actionSet = XR_NULL_HANDLE; XRInputCallbackFn m_callback = NULL; }; @@ -97,9 +98,9 @@ public: XrSession m_session; XrSpace m_space; - CUtlVector m_eyeSwapchains; - CUtlVector m_projviews; - CUtlVector m_views; + CUtlVector m_eyeSwapchains = {}; + CUtlVector m_projviews = {}; + CUtlVector m_views = {}; float m_fPredictedTime; COpenXRController *m_pLeftHand; @@ -177,7 +178,11 @@ void COpenXRController::Frame() XrActionStateBoolean b = {}; b.type = XR_TYPE_ACTION_STATE_BOOLEAN; xrGetActionStateBoolean(m_pHeadset->m_session, &gi, &b); - V_printf("%s %b\n", a.m_szName.GetString(), b.currentState); + EXRInputValue_t v; + v.type = k_EXRValue_Bool; + v.b.value = b.currentState; + if (m_callback) + m_callback( this, a.m_eUserInputType, NULL, k_EXRInputAction_Value, v ); break; } case XR_ACTION_TYPE_FLOAT_INPUT: @@ -188,7 +193,11 @@ void COpenXRController::Frame() XrActionStateFloat f32 = {}; f32.type = XR_TYPE_ACTION_STATE_FLOAT; xrGetActionStateFloat(m_pHeadset->m_session, &gi, &f32); - V_printf("%s %f\n", a.m_szName.GetString(), f32.currentState); + EXRInputValue_t v; + v.type = k_EXRValue_Float; + v.f32.value = f32.currentState; + if (m_callback) + m_callback( this, a.m_eUserInputType, NULL, k_EXRInputAction_Value, v ); break; } case XR_ACTION_TYPE_POSE_INPUT: @@ -208,8 +217,9 @@ void COpenXRController::Frame() EXRInputValue_t v; v.type = k_EXRValue_Pose; v.pose.pos = {s.pose.position.x, s.pose.position.y, s.pose.position.z}; + v.pose.rot = {s.pose.orientation.x, s.pose.orientation.y, s.pose.orientation.z, s.pose.orientation.w}; if (m_callback) - m_callback( this, k_EXRInput_Grip, NULL, k_EXRInputAction_Pose, v ); + m_callback( this, a.m_eUserInputType, NULL, k_EXRInputAction_Pose, v ); } break; } @@ -247,6 +257,82 @@ void COpenXRController::ConfigureActionSets( const char *szDevice, const char *s { IJSONValue *pInput = (*pInputs)[i]; CUtlString szInputName = (*pInput)["name"]->GetStringValue(); + EXRInputType_t eInputType = k_EXRInput_FromString; + if (szInputName == "trackpad") + eInputType = k_EXRInput_Trackpad; + if (szInputName == "thumbstick") + eInputType = k_EXRInput_Thumbstick; + if (szInputName == "joystick") + eInputType = k_EXRInput_Joystick; + if (szInputName == "trigger") + eInputType = k_EXRInput_Trigger; + if (szInputName == "throttle") + eInputType = k_EXRInput_Throttle; + if (szInputName == "trackball") + eInputType = k_EXRInput_Trackball; + if (szInputName == "pedal") + eInputType = k_EXRInput_Pedal; + if (szInputName == "system") + eInputType = k_EXRInput_System; + if (szInputName == "dpad_up") + eInputType = k_EXRInput_Dpad_Up; + if (szInputName == "dpad_down") + eInputType = k_EXRInput_Dpad_Down; + if (szInputName == "dpad_left") + eInputType = k_EXRInput_Dpad_Left; + if (szInputName == "dpad_right") + eInputType = k_EXRInput_Dpad_Right; + if (szInputName == "diamond_up") + eInputType = k_EXRInput_Diamond_Up; + if (szInputName == "diamond_down") + eInputType = k_EXRInput_Diamond_Down; + if (szInputName == "diamond_left") + eInputType = k_EXRInput_Diamond_Left; + if (szInputName == "diamond_right") + eInputType = k_EXRInput_Diamond_Right; + if (szInputName == "a") + eInputType = k_EXRInput_A; + if (szInputName == "b") + eInputType = k_EXRInput_B; + if (szInputName == "x") + eInputType = k_EXRInput_X; + if (szInputName == "y") + eInputType = k_EXRInput_Y; + if (szInputName == "start") + eInputType = k_EXRInput_Start; + if (szInputName == "home") + eInputType = k_EXRInput_Home; + if (szInputName == "end") + eInputType = k_EXRInput_End; + if (szInputName == "select") + eInputType = k_EXRInput_Select; + if (szInputName == "volume_up") + eInputType = k_EXRInput_Volume_Up; + if (szInputName == "volume_down") + eInputType = k_EXRInput_Volume_Down; + if (szInputName == "mute_mic") + eInputType = k_EXRInput_Mute_Mic; + if (szInputName == "play_pause") + eInputType = k_EXRInput_Play_Pause; + if (szInputName == "menu") + eInputType = k_EXRInput_Menu; + if (szInputName == "view") + eInputType = k_EXRInput_View; + if (szInputName == "back") + eInputType = k_EXRInput_Back; + if (szInputName == "thumbrest") + eInputType = k_EXRInput_ThumbRest; + if (szInputName == "shoulder") + eInputType = k_EXRInput_Shoulder; + if (szInputName == "squeeze") + eInputType = k_EXRInput_Squeeze; + if (szInputName == "wheel") + eInputType = k_EXRInput_Wheel; + if (szInputName == "grip") + eInputType = k_EXRInput_Grip; + if (szInputName == "aim") + eInputType = k_EXRInput_Aim; + IJSONValue *pActions = (*pInput)["actions"]; for (uint32_t y = 0; y < pActions->GetArray()->GetCount(); y++ ) @@ -284,6 +370,7 @@ void COpenXRController::ConfigureActionSets( const char *szDevice, const char *s action.m_szName = szName; action.m_action = a; action.m_eType = eType; + action.m_eUserInputType = eInputType; if (eType == XR_ACTION_TYPE_POSE_INPUT) { XrActionSpaceCreateInfo asci = {}; @@ -666,7 +753,7 @@ formatPicked: if (!V_strcmp(c, "/user/hand/right")) { m_pRightHand = new COpenXRController; - m_pRightHand->m_side = k_EXRController_Left; + m_pRightHand->m_side = k_EXRController_Right; m_pRightHand->m_pHeadset = this; for ( auto &p: s_interactionProfiles ) if (s == p.m_szName) diff --git a/funnyassets/meshes/hand.fmesh_c b/funnyassets/meshes/hand.fmesh_c new file mode 100644 index 0000000..24bb162 Binary files /dev/null and b/funnyassets/meshes/hand.fmesh_c differ diff --git a/funnyassets/models/hand.fmdl b/funnyassets/models/hand.fmdl new file mode 100644 index 0000000..44095d4 --- /dev/null +++ b/funnyassets/models/hand.fmdl @@ -0,0 +1,5 @@ +{ + "Mesh": "game/core/meshes/hand.fmesh_c", + "Material": "game/core/materials/cube.fmat", + "Physics": "game/core/physics/sphere.fpx" +} diff --git a/game/client/assetmgr.cpp b/game/client/assetmgr.cpp index a2369fb..c2b3d05 100644 --- a/game/client/assetmgr.cpp +++ b/game/client/assetmgr.cpp @@ -40,9 +40,9 @@ public: return u; } } - for ( auto &m: m_objects) + for ( uint32_t u = 1; u < nCount; u++ ) { - if (m.m_pObject == NULL) + if (m_objects[u].m_pObject == NULL) break; uFoundIndex++; } @@ -57,6 +57,8 @@ public: { if (uIndex >= nCount) return 0; + if (uIndex == 0) + return 0; return m_objects[uIndex].m_pObject; } void UnrefObject( uint32_t uIndex ) @@ -135,6 +137,7 @@ FunnyMesh_t *CAssetManager::GetMeshByIndex( uint32_t uIndex ) uint32_t CAssetManager::LoadModel( const char *szName ) { + V_printf("LOADING %s\n", szName); bool bHasBeenCreated = false; HFunnyModel hModel = m_models.GetOrCreateObject(szName, &bHasBeenCreated); if (!bHasBeenCreated) @@ -170,7 +173,6 @@ uint32_t CAssetManager::LoadModel( const char *szName ) IJSONValue *pMesh = pMainObject->GetValue("Mesh"); IJSONValue *pMaterial = pMainObject->GetValue("Material"); IJSONValue *pPhysics = pMainObject->GetValue("Physics"); - V_printf("%s\n", pMaterial->GetStringValue()); if (pMesh) pModel->m_hMesh = LoadMesh(pMesh->GetStringValue()); if (pMaterial) @@ -294,7 +296,7 @@ void CAssetManager::UnrefMaterial( uint32_t uIndex ) HFunnyMesh CAssetManager::LoadMesh( const char *szName ) { - + V_printf("LOADING %s\n", szName); bool bHasBeenCreated = false; HFunnyMesh hAsset = m_meshes.GetOrCreateObject(szName, &bHasBeenCreated); if (!bHasBeenCreated) @@ -308,6 +310,7 @@ HFunnyMesh CAssetManager::LoadMesh( const char *szName ) m_meshes.UnrefObject(hAsset); return 0; } + V_printf("V_LOADING %s %llu\n", szName, filesystem->Size(hMesh)); IVertexBuffer *pVertexBuffer = g_pRenderContext->CreateVertexBuffer(filesystem->Size(hMesh)); pVertexBuffer->Lock(); diff --git a/game/client/entitysystem.cpp b/game/client/entitysystem.cpp index a7f16a9..159819e 100644 --- a/game/client/entitysystem.cpp +++ b/game/client/entitysystem.cpp @@ -325,6 +325,13 @@ C_BaseEntity **CEntitySystem::GetEntities() return m_pEntities; }; +C_BaseEntity *CEntitySystem::GetEntityByIndex( int idx ) +{ + if (idx < 0 || idx >= MAX_EDICTS) + return NULL; + return m_pEntities[idx]; +} + C_BaseEntity *UTIL_GetLocalPlayer() { return s_pLocalEntity; diff --git a/game/client/entitysystem.h b/game/client/entitysystem.h index a6da98b..ef6a910 100644 --- a/game/client/entitysystem.h +++ b/game/client/entitysystem.h @@ -14,6 +14,7 @@ class IEntityFactory; class C_BaseEntity; #define MAX_EDICTS 8192 +#define EDICT_INDEX_UNDEFINED (-1U) class CEntitySystem { @@ -35,6 +36,8 @@ public: virtual void NetSendThink( INetworkBase *pBase ); virtual C_BaseEntity **GetEntities(); + + virtual C_BaseEntity *GetEntityByIndex( int idx ); private: C_BaseEntity *m_pEntities[MAX_EDICTS]; int m_nEntityCount; diff --git a/game/client/game.cpp b/game/client/game.cpp index ac48fb9..3fa23cb 100644 --- a/game/client/game.cpp +++ b/game/client/game.cpp @@ -108,6 +108,7 @@ void CFunnyGameBridge::Init() for ( uint32_t i = 0; i < pHeadSet->GetControllerCount(); i++ ) { pHeadSet->GetController(i)->SetInputCallback(XRInputCallback); + V_printf("callback set on %p\n", pHeadSet->GetController(i)); } } @@ -161,7 +162,6 @@ void CFunnyGameBridge::Frame( float fDelta ) if (pHeadSet) { XRRenderSurface_t s = pHeadSet->GetSurface(0); g_pWorldRenderer->SetCameraPosition(s.m_vPosition); - V_printf("%f\n", s.m_vPosition.y); g_pWorldRenderer->SetCameraRotation(s.m_vRotation); } diff --git a/game/client/milmoba/player.cpp b/game/client/milmoba/player.cpp index a0e67f7..8d653e9 100644 --- a/game/client/milmoba/player.cpp +++ b/game/client/milmoba/player.cpp @@ -26,10 +26,9 @@ void C_MOBAPlayer::Think( float fDelta ) if (pPlayerEntity == this) { } - m_pLeftHand = (C_MOBAPlayerHandController*)EntitySystem()->GetEntities()[m_leftHandId]; - m_pRightHand = (C_MOBAPlayerHandController*)EntitySystem()->GetEntities()[m_rightHandId]; + m_pLeftHand = (C_MOBAPlayerHandController*)EntitySystem()->GetEntityByIndex(m_leftHandId); + m_pRightHand = (C_MOBAPlayerHandController*)EntitySystem()->GetEntityByIndex(m_rightHandId); BaseClass::Think(fDelta); - V_printf("device: %p %p\n", m_pLeftHand, m_pRightHand ); }; LINK_ENTITY_TO_CLASS(player, C_MOBAPlayer) @@ -161,6 +160,14 @@ void Game_OnGameAxisDiff( EInputDeviceType eDevice, EInputAxis eAxis, float fVal void C_MOBAPlayerHandController::Precache() { + + m_hNormal = g_pAssetManager->LoadModel("game/core/models/hand.fmdl"); + m_pNormalModel = g_pAssetManager->GetModelByIndex(m_hNormal); + m_hSqueezed = g_pAssetManager->LoadModel("game/core/models/sphere.fmdl"); + m_pSqueezedModel = g_pAssetManager->GetModelByIndex(m_hSqueezed); + m_pModel = m_pNormalModel; + m_pMesh = g_pAssetManager->GetMeshByIndex(m_pModel->m_hMesh)->m_pMesh; + m_pInstance = g_pWorldRenderer->CreateInstance(m_pMesh); } @@ -172,10 +179,45 @@ void C_MOBAPlayerHandController::Spawn() void C_MOBAPlayerHandController::Think( float fDelta ) { - V_printf("controller: %p %f %f %f\n", this, m_vDesiredHandPosition.x, m_vDesiredHandPosition.y, m_vDesiredHandPosition.z ); - SetAbsOrigin(m_vDesiredHandPosition); - BaseClass::Think(fDelta); -}; + if (m_fSqueeze != m_fPreviousSqueeze) + { + if (m_fSqueeze > 0.5 && m_fPreviousSqueeze > 0.5) + goto draw; + if (m_fSqueeze <= 0.5 && m_fPreviousSqueeze <= 0.5) + goto draw; + + if (m_pInstance) + g_pWorldRenderer->DestroyMeshInstance(m_pMesh, m_pInstance); + + if (m_fSqueeze > 0.5) + m_pModel = m_pSqueezedModel; + else + m_pModel = m_pNormalModel; + m_pMesh = g_pAssetManager->GetMeshByIndex(m_pModel->m_hMesh)->m_pMesh; + m_pInstance = g_pWorldRenderer->CreateInstance(m_pMesh); + } + +draw: + if (m_pInstance) + { + CBaseMaterial *pMat = g_pAssetManager->GetMaterialByIndex(m_pModel->m_hMaterial)->m_pLayout; + m_pInstance->SetPosition(m_vDesiredHandPosition); + m_pInstance->SetRotation(m_vDesiredHandRotation); + m_pInstance->SetScale({0.025, 0.025, 0.025}); + m_pInstance->SetMaterial(pMat); + + } + + m_fPreviousSqueeze = m_fSqueeze; +} +C_MOBAPlayerHandController::~C_MOBAPlayerHandController() +{ + if (m_pInstance) + g_pWorldRenderer->DestroyMeshInstance(m_pMesh, m_pInstance); + g_pAssetManager->UnrefModel(m_hNormal); + g_pAssetManager->UnrefModel(m_hSqueezed); + +} LINK_ENTITY_TO_CLASS(player_hand_controller, C_MOBAPlayerHandController) @@ -208,11 +250,19 @@ void XRInputCallback( IXRController *pController, EXRInputType_t eType, const ch if (pCon == NULL) return; - switch (action) - { - case k_EXRInputAction_Pose: - pCon->m_vDesiredHandPosition = value.pose.pos; - V_printf("callback: %p %f %f %f\n", pCon, pCon->m_vDesiredHandPosition.x, pCon->m_vDesiredHandPosition.y, pCon->m_vDesiredHandPosition.z ); + switch (eType) { + case k_EXRInput_Grip: + if (action == k_EXRInputAction_Pose) + { + pCon->m_vDesiredHandPosition = value.pose.pos; + pCon->m_vDesiredHandRotation = value.pose.rot; + } + break; + case k_EXRInput_Squeeze: + if (action == k_EXRInputAction_Value) + { + pCon->m_fSqueeze = value.f32.value; + } break; default: break; diff --git a/game/client/milmoba/player.h b/game/client/milmoba/player.h index 710e92e..0cb2384 100644 --- a/game/client/milmoba/player.h +++ b/game/client/milmoba/player.h @@ -3,19 +3,32 @@ #define MILMOBA_PLAYER_H #include "basemodelentity.h" -class C_MOBAPlayerHandController: public C_BaseModelEntity +class C_MOBAPlayerHandController: public C_BaseEntity { public: - DECLARE_CLASS(C_MOBAPlayerHandController, C_BaseModelEntity); + DECLARE_CLASS(C_MOBAPlayerHandController, C_BaseEntity); DECLARE_DATADESC(); DECLARE_CLIENTCLASS(); virtual void Precache ( void ) override; virtual void Spawn( void ) override; void Think( float fDelta ); + virtual ~C_MOBAPlayerHandController() override; Vector m_vDesiredHandPosition = {}; Quat m_vDesiredHandRotation = {}; + float m_fPreviousSqueeze = 0; + float m_fSqueeze = 0; + + HFunnyModel m_hNormal = NULL; + FunnyModel_t *m_pNormalModel = NULL; + HFunnyModel m_hSqueezed = NULL; + FunnyModel_t *m_pSqueezedModel = NULL; + + FunnyModel_t *m_pModel = NULL; + IMesh *m_pMesh = NULL; + IMeshInstance *m_pInstance = NULL; + }; class C_MOBAPlayer: public C_BaseModelEntity @@ -45,10 +58,10 @@ public: Vector m_vLocalMovementVector; Vector vCameraPos; - C_MOBAPlayerHandController *m_pLeftHand; - int m_leftHandId = 0; - C_MOBAPlayerHandController *m_pRightHand; - int m_rightHandId = 0; + C_MOBAPlayerHandController *m_pLeftHand = NULL; + int m_leftHandId = EDICT_INDEX_UNDEFINED; + C_MOBAPlayerHandController *m_pRightHand = NULL; + int m_rightHandId = EDICT_INDEX_UNDEFINED; }; diff --git a/game/client/worldrender.cpp b/game/client/worldrender.cpp index 0eb3813..8ecdd37 100644 --- a/game/client/worldrender.cpp +++ b/game/client/worldrender.cpp @@ -105,13 +105,6 @@ void CFunnyMeshInstance::Frame() v[2] = m_vScale.z; glm_scale_make(m, v); glm_mat4_mul(m_data.m_matTranslation, m, m_data.m_matTranslation); - - /* - V_printf("AAAAA %f %f %f %f\n", m_data.m_matTranslation[0][0], m_data.m_matTranslation[0][1], m_data.m_matTranslation[0][2], m_data.m_matTranslation[0][3]); - V_printf("AAAAA %f %f %f %f\n", m_data.m_matTranslation[1][0], m_data.m_matTranslation[1][1], m_data.m_matTranslation[1][2], m_data.m_matTranslation[1][3]); - V_printf("AAAAA %f %f %f %f\n", m_data.m_matTranslation[2][0], m_data.m_matTranslation[2][1], m_data.m_matTranslation[2][2], m_data.m_matTranslation[2][3]); - V_printf("AAAAA %f %f %f %f\n", m_data.m_matTranslation[3][0], m_data.m_matTranslation[3][1], m_data.m_matTranslation[3][2], m_data.m_matTranslation[3][3]); - */ } void CFunnyMeshInstance::SetMaterial( CBaseMaterial *pMaterial ) diff --git a/game/server/assetmgr.cpp b/game/server/assetmgr.cpp index 8a79117..a7a4612 100644 --- a/game/server/assetmgr.cpp +++ b/game/server/assetmgr.cpp @@ -39,9 +39,9 @@ public: return u; } } - for ( auto &m: m_objects) + for ( uint32_t u = 1; u < nCount; u++ ) { - if (m.m_pObject == NULL) + if (m_objects[u].m_pObject == NULL) break; uFoundIndex++; } @@ -179,9 +179,6 @@ void CAssetManager::UnrefMaterial( uint32_t uIndex ) HFunnyMesh CAssetManager::LoadMesh( const char *szName ) { - - - bool bHasBeenCreated = false; HFunnyMesh hAsset = m_meshes.GetOrCreateObject(szName, &bHasBeenCreated); if (!bHasBeenCreated) diff --git a/game/server/milmoba/player.cpp b/game/server/milmoba/player.cpp index c728529..749d83c 100644 --- a/game/server/milmoba/player.cpp +++ b/game/server/milmoba/player.cpp @@ -6,8 +6,6 @@ CMOBAPlayer::CMOBAPlayer() { m_hCuboid = g_pPhysics->CreateCube({1,1,1}); - m_pLeftHand = EntitySystem()->CreateByClassname("player_hand_controller", &m_leftHandId); - m_pRightHand = EntitySystem()->CreateByClassname("player_hand_controller", &m_rightHandId); } CMOBAPlayer::~CMOBAPlayer() @@ -22,6 +20,8 @@ void CMOBAPlayer::Spawn() SetAbsOrigin({0,-11.5, 0}); SetThink(Think); + m_pLeftHand = EntitySystem()->CreateByClassname("player_hand_controller", &m_leftHandId); + m_pRightHand = EntitySystem()->CreateByClassname("player_hand_controller", &m_rightHandId); m_pLeftHand->Spawn(); m_pRightHand->Spawn(); }; @@ -71,7 +71,6 @@ CMOBAPlayerHandController::CMOBAPlayerHandController() void CMOBAPlayerHandController::Spawn() { CBaseEntity::Spawn(); - SetModel("game/core/models/sphere.fmdl"); SetScale(0.03); SetThink(Think); } diff --git a/game/server/milmoba/player.h b/game/server/milmoba/player.h index 0d0cec8..b1fc12f 100644 --- a/game/server/milmoba/player.h +++ b/game/server/milmoba/player.h @@ -27,10 +27,10 @@ private: int m_rightHandId; }; -class CMOBAPlayerHandController: public CBaseModelEntity +class CMOBAPlayerHandController: public CBaseEntity { public: - DECLARE_CLASS(CMOBAPlayerHandController, CBaseModelEntity); + DECLARE_CLASS(CMOBAPlayerHandController, CBaseEntity); DECLARE_DATADESC(); DECLARE_SERVERCLASS() CMOBAPlayerHandController(); diff --git a/public/ixr.h b/public/ixr.h index 90ae9a0..539733c 100644 --- a/public/ixr.h +++ b/public/ixr.h @@ -35,6 +35,7 @@ enum EXRInputType_t k_EXRInput_Thumbstick, k_EXRInput_Joystick, k_EXRInput_Trigger, + k_EXRInput_Throttle , k_EXRInput_Trackball, k_EXRInput_Pedal, k_EXRInput_System,