diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d29fb73e4a..4c76e18ba9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3743,6 +3743,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se } renderArgs->_debugFlags = renderDebugFlags; _entities.render(renderArgs); + ViveControllerManager::getInstance().render(renderArgs); } // render the ambient occlusion effect if enabled diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index b3f9a590d9..28c17552c9 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -3,7 +3,7 @@ set(TARGET_NAME input-plugins) setup_hifi_library() # use setup_hifi_library macro to setup our project and link appropriate Qt modules -link_hifi_libraries(shared plugins) +link_hifi_libraries(shared plugins gpu render-utils) GroupSources("src/input-plugins") diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp index 93a873b7f7..f5ea59c35e 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp @@ -13,6 +13,10 @@ #include +#include "GeometryCache.h" +#include +#include +#include #include #include "NumericalConstants.h" #include "UserActivityLogger.h" @@ -40,6 +44,8 @@ const unsigned int GRIP_BUTTON = 1U << 2; const unsigned int TRACKPAD_BUTTON = 1U << 3; const unsigned int TRIGGER_BUTTON = 1U << 4; +const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b"; + ViveControllerManager& ViveControllerManager::getInstance() { static ViveControllerManager sharedInstance; return sharedInstance; @@ -48,7 +54,8 @@ ViveControllerManager& ViveControllerManager::getInstance() { ViveControllerManager::ViveControllerManager() : _isInitialized(false), _isEnabled(true), - _trackedControllers(0) + _trackedControllers(0), + _modelLoaded(false) { } @@ -98,9 +105,90 @@ void ViveControllerManager::activate() { Q_ASSERT(eError == vr::HmdError_None); } Q_ASSERT(_hmd); + + vr::RenderModel_t model; + if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING.toStdString().c_str(), &model)) { + qDebug("Unable to load render model %s\n", CONTROLLER_MODEL_STRING); + } else { + model::Mesh* mesh = new model::Mesh(); + model::MeshPointer meshPtr(mesh); + _modelGeometry.setMesh(meshPtr); + + auto indexBuffer = new gpu::Buffer(3 * model.unTriangleCount * sizeof(uint16_t), (gpu::Byte*)model.rIndexData); + auto indexBufferPtr = gpu::BufferPointer(indexBuffer); + auto indexBufferView = new gpu::BufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT16, gpu::RAW)); + mesh->setIndexBuffer(*indexBufferView); + + auto vertexBuffer = new gpu::Buffer(model.unVertexCount * sizeof(vr::RenderModel_Vertex_t), + (gpu::Byte*)model.rVertexData); + auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer); + auto vertexBufferView = new gpu::BufferView(vertexBufferPtr, + 0, + vertexBufferPtr->getSize() - sizeof(float) * 3, + sizeof(vr::RenderModel_Vertex_t), + gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)); + mesh->setVertexBuffer(*vertexBufferView); + mesh->addAttribute(gpu::Stream::NORMAL, + gpu::BufferView(vertexBufferPtr, + sizeof(float) * 3, + vertexBufferPtr->getSize() - sizeof(float) * 3, + sizeof(vr::RenderModel_Vertex_t), + gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW))); + //mesh->addAttribute(gpu::Stream::TEXCOORD, + // gpu::BufferView(vertexBufferPtr, + // 2 * sizeof(float) * 3, + // vertexBufferPtr->getSize() - sizeof(float) * 3, + // sizeof(vr::RenderModel_Vertex_t), + // gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW))); + + _modelLoaded = true; + } + _isInitialized = true; } +void ViveControllerManager::render(RenderArgs* args) { + PerformanceTimer perfTimer("ViveControllerManager::render"); + + if (_modelLoaded) { + UserInputMapper::PoseValue leftHand = _poseStateMap[makeInput(JointChannel::LEFT_HAND).getChannel()]; + UserInputMapper::PoseValue rightHand = _poseStateMap[makeInput(JointChannel::RIGHT_HAND).getChannel()]; + + gpu::Batch batch; + auto geometryCache = DependencyManager::get(); + geometryCache->useSimpleDrawPipeline(batch); + batch.setProjectionTransform(mat4()); + + if (leftHand.isValid()) { + renderHand(leftHand, batch); + } + if (rightHand.isValid()) { + renderHand(rightHand, batch); + } + + args->_context->syncCache(); + args->_context->render(batch); + } +} + +void ViveControllerManager::renderHand(UserInputMapper::PoseValue pose, gpu::Batch& batch) { + Transform transform; + transform.setTranslation(pose.getTranslation()); + transform.setRotation(pose.getRotation()); + + auto mesh = _modelGeometry.getMesh(); + DependencyManager::get()->bindSimpleProgram(batch); + batch.setModelTransform(transform); + batch.setInputFormat(mesh->getVertexFormat()); + batch.setInputBuffer(gpu::Stream::POSITION, mesh->getVertexBuffer()); + batch.setInputBuffer(gpu::Stream::NORMAL, + mesh->getVertexBuffer()._buffer, + sizeof(float) * 3, + mesh->getVertexBuffer()._stride); + batch.setIndexBuffer(gpu::UINT16, mesh->getIndexBuffer()._buffer, 0); + batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0); +} + void ViveControllerManager::update() { if (!_hmd) { return; @@ -108,7 +196,7 @@ void ViveControllerManager::update() { _buttonPressedMap.clear(); if (_isInitialized && _isEnabled) { - PerformanceTimer perfTimer("Vive Controllers"); + PerformanceTimer perfTimer("ViveControllerManager::update"); int numTrackedControllers = 0; diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h b/libraries/input-plugins/src/input-plugins/ViveControllerManager.h index 789e9cd391..7ec16f8ba8 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.h @@ -17,8 +17,10 @@ #include -#include "UserInputMapper.h" +#include #include "plugins/Plugin.h" +#include +#include "UserInputMapper.h" class ViveControllerManager : public Plugin { public: @@ -64,7 +66,8 @@ public: }; void focusOutEvent(); - + + void render(RenderArgs* args); void update(); static ViveControllerManager& getInstance(); @@ -89,6 +92,8 @@ public: private: ViveControllerManager(); ~ViveControllerManager(); + + void renderHand(UserInputMapper::PoseValue pose, gpu::Batch& batch); void handleButtonEvent(uint64_t buttons, int index); void handleAxisEvent(Axis axis, float x, float y, int index); @@ -98,6 +103,9 @@ private: bool _isEnabled; int _trackedControllers; + bool _modelLoaded; + model::Geometry _modelGeometry; + static const QString NAME; protected: