mirror of
https://github.com/lubosz/overte.git
synced 2025-04-15 19:47:38 +02:00
Merge branch 'android_new' into android
This commit is contained in:
commit
4d6538edf7
44 changed files with 1071 additions and 169 deletions
15
interface/resources/controllers/touchscreenvirtualpad.json
Normal file
15
interface/resources/controllers/touchscreenvirtualpad.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "TouchscreenVirtualPad to Actions",
|
||||
"channels": [
|
||||
{ "from": "TouchscreenVirtualPad.LY", "when": "Application.CameraFirstPerson", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Actions.TranslateZ" },
|
||||
{ "from": "TouchscreenVirtualPad.LX", "when": "Application.CameraFirstPerson", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Actions.TranslateX" },
|
||||
|
||||
|
||||
{ "from": "TouchscreenVirtualPad.RX", "when": "Application.CameraFirstPerson", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Actions.Yaw" },
|
||||
|
||||
{ "from": "TouchscreenVirtualPad.RY",
|
||||
"when": "Application.CameraFirstPerson",
|
||||
"to": "Actions.Pitch"
|
||||
}
|
||||
]
|
||||
}
|
BIN
interface/resources/images/analog_stick.png
Normal file
BIN
interface/resources/images/analog_stick.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
BIN
interface/resources/images/analog_stick_base.png
Normal file
BIN
interface/resources/images/analog_stick_base.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
|
@ -1,135 +0,0 @@
|
|||
name = being_of_light
|
||||
type = body+head
|
||||
scale = 1
|
||||
filename = being_of_light/being_of_light.fbx
|
||||
texdir = being_of_light/textures
|
||||
joint = jointRoot = Hips
|
||||
joint = jointLeftHand = LeftHand
|
||||
joint = jointHead = HeadTop_End
|
||||
joint = jointLean = Spine
|
||||
joint = jointEyeLeft = LeftEye
|
||||
joint = jointRightHand = RightHand
|
||||
joint = jointNeck = Head
|
||||
joint = jointEyeRight = RightEye
|
||||
freeJoint = LeftArm
|
||||
freeJoint = LeftForeArm
|
||||
freeJoint = RightArm
|
||||
freeJoint = RightForeArm
|
||||
bs = MouthFrown_L = Frown_Left = 1
|
||||
bs = MouthLeft = Midmouth_Left = 1
|
||||
bs = BrowsU_R = BrowsUp_Right = 1
|
||||
bs = ChinUpperRaise = UpperLipUp_Right = 0.5
|
||||
bs = ChinUpperRaise = UpperLipUp_Left = 0.5
|
||||
bs = MouthSmile_R = Smile_Right = 1
|
||||
bs = MouthDimple_L = Smile_Left = 0.25
|
||||
bs = EyeBlink_L = Blink_Left = 1
|
||||
bs = BrowsD_L = BrowsDown_Left = 1
|
||||
bs = MouthFrown_R = Frown_Right = 1
|
||||
bs = MouthDimple_R = Smile_Right = 0.25
|
||||
bs = Sneer = Squint_Right = 0.5
|
||||
bs = Sneer = Squint_Left = 0.5
|
||||
bs = Sneer = NoseScrunch_Right = 0.75
|
||||
bs = Sneer = NoseScrunch_Left = 0.75
|
||||
bs = EyeSquint_L = Squint_Left = 1
|
||||
bs = EyeBlink_R = Blink_Right = 1
|
||||
bs = JawLeft = JawRotateY_Left = 0.5
|
||||
bs = BrowsD_R = BrowsDown_Right = 1
|
||||
bs = EyeSquint_R = Squint_Right = 1
|
||||
bs = Puff = CheekPuff_Right = 1
|
||||
bs = Puff = CheekPuff_Left = 1
|
||||
bs = LipsUpperClose = UpperLipIn = 1
|
||||
bs = JawOpen = MouthOpen = 0.69999999999999996
|
||||
bs = LipsUpperUp = UpperLipUp_Right = 0.69999999999999996
|
||||
bs = LipsUpperUp = UpperLipUp_Left = 0.69999999999999996
|
||||
bs = LipsLowerDown = LowerLipDown_Right = 0.69999999999999996
|
||||
bs = LipsLowerDown = LowerLipDown_Left = 0.69999999999999996
|
||||
bs = LipsLowerOpen = LowerLipOut = 1
|
||||
bs = EyeOpen_L = EyesWide_Left = 1
|
||||
bs = LipsPucker = MouthNarrow_Right = 1
|
||||
bs = LipsPucker = MouthNarrow_Left = 1
|
||||
bs = EyeOpen_R = EyesWide_Right = 1
|
||||
bs = JawRight = Jaw_Right = 1
|
||||
bs = MouthRight = Midmouth_Right = 1
|
||||
bs = ChinLowerRaise = Jaw_Up = 1
|
||||
bs = LipsUpperOpen = UpperLipOut = 1
|
||||
bs = BrowsU_C = BrowsUp_Right = 1
|
||||
bs = BrowsU_C = BrowsUp_Left = 1
|
||||
bs = JawFwd = JawForeward = 1
|
||||
bs = BrowsU_L = BrowsUp_Left = 1
|
||||
bs = MouthSmile_L = Smile_Left = 1
|
||||
bs = LipsLowerClose = LowerLipIn = 1
|
||||
bs = LipsFunnel = TongueUp = 1
|
||||
bs = LipsFunnel = MouthWhistle_NarrowAdjust_Right = 0.5
|
||||
bs = LipsFunnel = MouthWhistle_NarrowAdjust_Left = 0.5
|
||||
bs = LipsFunnel = MouthNarrow_Right = 1
|
||||
bs = LipsFunnel = MouthNarrow_Left = 1
|
||||
bs = LipsFunnel = Jaw_Down = 0.35999999999999999
|
||||
bs = LipsFunnel = JawForeward = 0.39000000000000001
|
||||
jointIndex = LeftHandIndex1 = 50
|
||||
jointIndex = LeftHandIndex2 = 51
|
||||
jointIndex = LeftHandIndex3 = 52
|
||||
jointIndex = LeftHandIndex4 = 53
|
||||
jointIndex = Spine1 = 12
|
||||
jointIndex = Spine2 = 13
|
||||
jointIndex = RightHandThumb1 = 18
|
||||
jointIndex = RightHandThumb2 = 19
|
||||
jointIndex = RightHandThumb3 = 20
|
||||
jointIndex = RightHandThumb4 = 21
|
||||
jointIndex = LeftFoot = 8
|
||||
jointIndex = LeftForeArm = 40
|
||||
jointIndex = Neck = 62
|
||||
jointIndex = Head = 63
|
||||
jointIndex = Hips = 0
|
||||
jointIndex = RightHandPinky1 = 30
|
||||
jointIndex = RightHandPinky2 = 31
|
||||
jointIndex = RightHandPinky3 = 32
|
||||
jointIndex = RightHandPinky4 = 33
|
||||
jointIndex = RightLeg = 2
|
||||
jointIndex = RightForeArm = 16
|
||||
jointIndex = LeftHandRing1 = 46
|
||||
jointIndex = LeftHandRing2 = 47
|
||||
jointIndex = LeftHandRing3 = 48
|
||||
jointIndex = LeftHandRing4 = 49
|
||||
jointIndex = LeftHandThumb1 = 54
|
||||
jointIndex = LeftHandThumb2 = 55
|
||||
jointIndex = LeftHandThumb3 = 56
|
||||
jointIndex = LeftHandThumb4 = 57
|
||||
jointIndex = HeadTop_End = 66
|
||||
jointIndex = LeftUpLeg = 6
|
||||
jointIndex = LeftToeBase = 9
|
||||
jointIndex = LeftHandPinky1 = 42
|
||||
jointIndex = LeftHandPinky2 = 43
|
||||
jointIndex = LeftHandPinky3 = 44
|
||||
jointIndex = LeftHandPinky4 = 45
|
||||
jointIndex = LeftLeg = 7
|
||||
jointIndex = RightEye = 65
|
||||
jointIndex = RightHand = 17
|
||||
jointIndex = RightToeBase = 4
|
||||
jointIndex = RightUpLeg = 1
|
||||
jointIndex = RightArm = 15
|
||||
jointIndex = RightHandRing1 = 26
|
||||
jointIndex = RightHandRing2 = 27
|
||||
jointIndex = RightHandRing3 = 28
|
||||
jointIndex = RightHandRing4 = 29
|
||||
jointIndex = RightHandIndex1 = 22
|
||||
jointIndex = RightHandIndex2 = 23
|
||||
jointIndex = RightHandIndex3 = 24
|
||||
jointIndex = RightHandIndex4 = 25
|
||||
jointIndex = LeftToe_End = 10
|
||||
jointIndex = LeftHandMiddle1 = 58
|
||||
jointIndex = LeftHandMiddle2 = 59
|
||||
jointIndex = LeftHandMiddle3 = 60
|
||||
jointIndex = LeftShoulder = 38
|
||||
jointIndex = LeftHandMiddle4 = 61
|
||||
jointIndex = RightFoot = 3
|
||||
jointIndex = LeftHand = 41
|
||||
jointIndex = RightHandMiddle1 = 34
|
||||
jointIndex = RightHandMiddle2 = 35
|
||||
jointIndex = RightHandMiddle3 = 36
|
||||
jointIndex = RightShoulder = 14
|
||||
jointIndex = LeftEye = 64
|
||||
jointIndex = RightHandMiddle4 = 37
|
||||
jointIndex = Body = 67
|
||||
jointIndex = LeftArm = 39
|
||||
jointIndex = RightToe_End = 5
|
||||
jointIndex = Spine = 11
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 2.6 MiB |
Binary file not shown.
Before Width: | Height: | Size: 2.9 MiB |
Binary file not shown.
Before Width: | Height: | Size: 645 KiB |
BIN
interface/resources/meshes/mannequin/+gles/Eyes.ktx
Normal file
BIN
interface/resources/meshes/mannequin/+gles/Eyes.ktx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -69,6 +69,7 @@
|
|||
#include <AudioInjectorManager.h>
|
||||
#include <AvatarBookmarks.h>
|
||||
#include <CursorManager.h>
|
||||
#include <VirtualPadManager.h>
|
||||
#include <DebugDraw.h>
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <EntityScriptClient.h>
|
||||
|
@ -693,6 +694,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
|||
DependencyManager::set<PointerScriptingInterface>();
|
||||
DependencyManager::set<PickScriptingInterface>();
|
||||
DependencyManager::set<Cursor::Manager>();
|
||||
DependencyManager::set<VirtualPad::Manager>();
|
||||
DependencyManager::set<DesktopPreviewProvider>();
|
||||
DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp));
|
||||
DependencyManager::set<StatTracker>();
|
||||
|
@ -1429,12 +1431,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
return DependencyManager::get<OffscreenUi>()->navigationFocused() ? 1 : 0;
|
||||
});
|
||||
|
||||
// Setup the _keyboardMouseDevice, _touchscreenDevice and the user input mapper with the default bindings
|
||||
// Setup the _keyboardMouseDevice, _touchscreenDevice, _touchscreenVirtualPadDevice and the user input mapper with the default bindings
|
||||
userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice());
|
||||
// if the _touchscreenDevice is not supported it will not be registered
|
||||
if (_touchscreenDevice) {
|
||||
userInputMapper->registerDevice(_touchscreenDevice->getInputDevice());
|
||||
}
|
||||
if (_touchscreenVirtualPadDevice) {
|
||||
userInputMapper->registerDevice(_touchscreenVirtualPadDevice->getInputDevice());
|
||||
}
|
||||
|
||||
// force the model the look at the correct directory (weird order of operations issue)
|
||||
scriptEngines->setScriptsLocation(scriptEngines->getScriptsLocation());
|
||||
|
@ -2503,6 +2508,9 @@ void Application::initializeUi() {
|
|||
if (TouchscreenDevice::NAME == inputPlugin->getName()) {
|
||||
_touchscreenDevice = std::dynamic_pointer_cast<TouchscreenDevice>(inputPlugin);
|
||||
}
|
||||
if (TouchscreenVirtualPadDevice::NAME == inputPlugin->getName()) {
|
||||
_touchscreenVirtualPadDevice = std::dynamic_pointer_cast<TouchscreenVirtualPadDevice>(inputPlugin);
|
||||
}
|
||||
}
|
||||
_window->setMenuBar(new Menu());
|
||||
|
||||
|
@ -3591,6 +3599,9 @@ void Application::touchUpdateEvent(QTouchEvent* event) {
|
|||
if (_touchscreenDevice && _touchscreenDevice->isActive()) {
|
||||
_touchscreenDevice->touchUpdateEvent(event);
|
||||
}
|
||||
if (_touchscreenVirtualPadDevice && _touchscreenVirtualPadDevice->isActive()) {
|
||||
_touchscreenVirtualPadDevice->touchUpdateEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::touchBeginEvent(QTouchEvent* event) {
|
||||
|
@ -3612,6 +3623,9 @@ void Application::touchBeginEvent(QTouchEvent* event) {
|
|||
if (_touchscreenDevice && _touchscreenDevice->isActive()) {
|
||||
_touchscreenDevice->touchBeginEvent(event);
|
||||
}
|
||||
if (_touchscreenVirtualPadDevice && _touchscreenVirtualPadDevice->isActive()) {
|
||||
_touchscreenVirtualPadDevice->touchBeginEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -3632,7 +3646,9 @@ void Application::touchEndEvent(QTouchEvent* event) {
|
|||
if (_touchscreenDevice && _touchscreenDevice->isActive()) {
|
||||
_touchscreenDevice->touchEndEvent(event);
|
||||
}
|
||||
|
||||
if (_touchscreenVirtualPadDevice && _touchscreenVirtualPadDevice->isActive()) {
|
||||
_touchscreenVirtualPadDevice->touchEndEvent(event);
|
||||
}
|
||||
// put any application specific touch behavior below here..
|
||||
}
|
||||
|
||||
|
@ -3640,6 +3656,9 @@ void Application::touchGestureEvent(QGestureEvent* event) {
|
|||
if (_touchscreenDevice && _touchscreenDevice->isActive()) {
|
||||
_touchscreenDevice->touchGestureEvent(event);
|
||||
}
|
||||
if (_touchscreenVirtualPadDevice && _touchscreenVirtualPadDevice->isActive()) {
|
||||
_touchscreenVirtualPadDevice->touchGestureEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::wheelEvent(QWheelEvent* event) const {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <FileScriptingInterface.h>
|
||||
#include <input-plugins/KeyboardMouseDevice.h>
|
||||
#include <input-plugins/TouchscreenDevice.h>
|
||||
#include <input-plugins/TouchscreenVirtualPadDevice.h>
|
||||
#include <OctreeQuery.h>
|
||||
#include <PhysicalEntitySimulation.h>
|
||||
#include <PhysicsEngine.h>
|
||||
|
@ -545,6 +546,7 @@ private:
|
|||
std::shared_ptr<controller::StateController> _applicationStateDevice; // Default ApplicationDevice reflecting the state of different properties of the session
|
||||
std::shared_ptr<KeyboardMouseDevice> _keyboardMouseDevice; // Default input device, the good old keyboard mouse and maybe touchpad
|
||||
std::shared_ptr<TouchscreenDevice> _touchscreenDevice; // the good old touchscreen
|
||||
std::shared_ptr<TouchscreenVirtualPadDevice> _touchscreenVirtualPadDevice;
|
||||
SimpleMovingAverage _avatarSimsPerSecond {10};
|
||||
int _avatarSimsPerSecondReport {0};
|
||||
quint64 _lastAvatarSimsPerSecondUpdate {0};
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <plugins/PluginManager.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "VirtualPadManager.h"
|
||||
|
||||
bool ControllerScriptingInterface::isKeyCaptured(QKeyEvent* event) const {
|
||||
return isKeyCaptured(KeyEvent(*event));
|
||||
|
@ -83,6 +84,11 @@ QVariant ControllerScriptingInterface::getRecommendedHUDRect() const {
|
|||
return qRectToVariant(rect);
|
||||
}
|
||||
|
||||
void ControllerScriptingInterface::setVPadEnabled(const bool enable) {
|
||||
auto& virtualPadManager = VirtualPad::Manager::instance();
|
||||
virtualPadManager.enable(enable);
|
||||
}
|
||||
|
||||
void ControllerScriptingInterface::emitKeyPressEvent(QKeyEvent* event) { emit keyPressEvent(KeyEvent(*event)); }
|
||||
void ControllerScriptingInterface::emitKeyReleaseEvent(QKeyEvent* event) { emit keyReleaseEvent(KeyEvent(*event)); }
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ public slots:
|
|||
virtual glm::vec2 getViewportDimensions() const;
|
||||
virtual QVariant getRecommendedHUDRect() const;
|
||||
|
||||
virtual void setVPadEnabled(bool enable);
|
||||
|
||||
signals:
|
||||
void keyPressEvent(const KeyEvent& event);
|
||||
void keyReleaseEvent(const KeyEvent& event);
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "Basic2DWindowOpenGLDisplayPlugin.h"
|
||||
#include "CompositorHelper.h"
|
||||
#include "VirtualPadManager.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
|
@ -14,11 +16,60 @@
|
|||
#include <QtWidgets/QAction>
|
||||
|
||||
#include <ui-plugins/PluginContainer.h>
|
||||
#include <PathUtils.h>
|
||||
|
||||
const QString Basic2DWindowOpenGLDisplayPlugin::NAME("Desktop");
|
||||
|
||||
static const QString FULLSCREEN = "Fullscreen";
|
||||
|
||||
void Basic2DWindowOpenGLDisplayPlugin::customizeContext() {
|
||||
auto iconPath = PathUtils::resourcesPath() + "images/analog_stick.png";
|
||||
auto image = QImage(iconPath);
|
||||
if (image.format() != QImage::Format_ARGB32) {
|
||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
if ((image.width() > 0) && (image.height() > 0)) {
|
||||
|
||||
_virtualPadStickTexture = gpu::Texture::createStrict(
|
||||
gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA),
|
||||
image.width(), image.height(),
|
||||
gpu::Texture::MAX_NUM_MIPS,
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR));
|
||||
_virtualPadStickTexture->setSource("virtualPad stick");
|
||||
auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha();
|
||||
_virtualPadStickTexture->setUsage(usage.build());
|
||||
_virtualPadStickTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
_virtualPadStickTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
_virtualPadStickTexture->setAutoGenerateMips(true);
|
||||
}
|
||||
|
||||
iconPath = PathUtils::resourcesPath() + "images/analog_stick_base.png";
|
||||
image = QImage(iconPath);
|
||||
if (image.format() != QImage::Format_ARGB32) {
|
||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
if ((image.width() > 0) && (image.height() > 0)) {
|
||||
_virtualPadStickBaseTexture = gpu::Texture::createStrict(
|
||||
gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA),
|
||||
image.width(), image.height(),
|
||||
gpu::Texture::MAX_NUM_MIPS,
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR));
|
||||
_virtualPadStickBaseTexture->setSource("virtualPad base");
|
||||
auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha();
|
||||
_virtualPadStickBaseTexture->setUsage(usage.build());
|
||||
_virtualPadStickBaseTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
_virtualPadStickBaseTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
_virtualPadStickBaseTexture->setAutoGenerateMips(true);
|
||||
}
|
||||
|
||||
|
||||
Parent::customizeContext();
|
||||
}
|
||||
|
||||
void Basic2DWindowOpenGLDisplayPlugin::uncustomizeContext() {
|
||||
Parent::uncustomizeContext();
|
||||
}
|
||||
|
||||
bool Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
|
||||
_framerateActions.clear();
|
||||
_container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), FULLSCREEN,
|
||||
|
@ -33,6 +84,37 @@ bool Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
|
|||
return Parent::internalActivate();
|
||||
}
|
||||
|
||||
void Basic2DWindowOpenGLDisplayPlugin::compositeExtra() {
|
||||
auto& virtualPadManager = VirtualPad::Manager::instance();
|
||||
if(virtualPadManager.getLeftVirtualPad()->isBeingTouched()) {
|
||||
// render stick base
|
||||
auto stickBaseTransform = DependencyManager::get<CompositorHelper>()->getPoint2DTransform(virtualPadManager.getLeftVirtualPad()->getFirstTouch());
|
||||
render([&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setProjectionTransform(mat4());
|
||||
batch.setPipeline(_cursorPipeline);
|
||||
batch.setResourceTexture(0, _virtualPadStickBaseTexture);
|
||||
batch.resetViewTransform();
|
||||
batch.setModelTransform(stickBaseTransform);
|
||||
batch.setViewportTransform(ivec4(uvec2(0), getRecommendedRenderSize()));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
// render stick head
|
||||
auto stickTransform = DependencyManager::get<CompositorHelper>()->getPoint2DTransform(virtualPadManager.getLeftVirtualPad()->getCurrentTouch());
|
||||
render([&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setProjectionTransform(mat4());
|
||||
batch.setPipeline(_cursorPipeline);
|
||||
batch.setResourceTexture(0, _virtualPadStickTexture);
|
||||
batch.resetViewTransform();
|
||||
batch.setModelTransform(stickTransform);
|
||||
batch.setViewportTransform(ivec4(uvec2(0), getRecommendedRenderSize()));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
}
|
||||
Parent::compositeExtra();
|
||||
}
|
||||
|
||||
static const uint32_t MIN_THROTTLE_CHECK_FRAMES = 60;
|
||||
|
||||
bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const {
|
||||
|
|
|
@ -22,10 +22,15 @@ public:
|
|||
|
||||
virtual float getTargetFrameRate() const override { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; }
|
||||
|
||||
virtual void customizeContext() override;
|
||||
virtual void uncustomizeContext() override;
|
||||
|
||||
virtual bool internalActivate() override;
|
||||
|
||||
virtual bool isThrottled() const override;
|
||||
|
||||
virtual void compositeExtra() override;
|
||||
|
||||
protected:
|
||||
mutable bool _isThrottled = false;
|
||||
|
||||
|
@ -36,4 +41,7 @@ private:
|
|||
QAction* _vsyncAction { nullptr };
|
||||
uint32_t _framerateTarget { 0 };
|
||||
int _fullscreenTarget{ -1 };
|
||||
|
||||
gpu::TexturePointer _virtualPadStickTexture;
|
||||
gpu::TexturePointer _virtualPadStickBaseTexture;
|
||||
};
|
||||
|
|
|
@ -458,6 +458,22 @@ glm::mat4 CompositorHelper::getReticleTransform(const glm::mat4& eyePose, const
|
|||
return result;
|
||||
}
|
||||
|
||||
glm::mat4 CompositorHelper::getPoint2DTransform(const glm::vec2& point) const {
|
||||
glm::mat4 result;
|
||||
static const float PIXEL_SIZE = 512.0f;
|
||||
const auto canvasSize = vec2(toGlm(_renderingWidget->size()));;
|
||||
QPoint qPoint(point.x,point.y);
|
||||
vec2 position = toGlm(_renderingWidget->mapFromGlobal(qPoint));
|
||||
position /= canvasSize;
|
||||
position *= 2.0;
|
||||
position -= 1.0;
|
||||
position.y *= -1.0f;
|
||||
|
||||
vec2 size = PIXEL_SIZE / canvasSize;
|
||||
result = glm::scale(glm::translate(glm::mat4(), vec3(position, 0.0f)), vec3(size, 1.0f));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
QVariant ReticleInterface::getPosition() const {
|
||||
return vec2toVariant(_compositor->getReticlePosition());
|
||||
|
|
|
@ -92,6 +92,7 @@ public:
|
|||
glm::vec2 getReticleMaximumPosition() const;
|
||||
|
||||
glm::mat4 getReticleTransform(const glm::mat4& eyePose = glm::mat4(), const glm::vec3& headPosition = glm::vec3()) const;
|
||||
glm::mat4 getPoint2DTransform(const glm::vec2& point = glm::vec2()) const;
|
||||
|
||||
ReticleInterface* getReticleInterface() { return _reticleInterface; }
|
||||
|
||||
|
|
|
@ -14,9 +14,12 @@
|
|||
|
||||
#include <QDebug>
|
||||
|
||||
#include "GPULogging.h"
|
||||
|
||||
#if defined(NSIGHT_FOUND)
|
||||
#include "nvToolsExt.h"
|
||||
|
||||
|
||||
ProfileRangeBatch::ProfileRangeBatch(gpu::Batch& batch, const char *name) : _batch(batch) {
|
||||
_batch.pushProfileRange(name);
|
||||
}
|
||||
|
@ -30,6 +33,11 @@ ProfileRangeBatch::~ProfileRangeBatch() {
|
|||
|
||||
using namespace gpu;
|
||||
|
||||
// FIXME make these backend / pipeline dependent.
|
||||
static const int MAX_NUM_UNIFORM_BUFFERS = 12;
|
||||
static const int MAX_NUM_RESOURCE_BUFFERS = 16;
|
||||
static const int MAX_NUM_RESOURCE_TEXTURES = 16;
|
||||
|
||||
size_t Batch::_commandsMax { BATCH_PREALLOCATE_MIN };
|
||||
size_t Batch::_commandOffsetsMax { BATCH_PREALLOCATE_MIN };
|
||||
size_t Batch::_paramsMax { BATCH_PREALLOCATE_MIN };
|
||||
|
@ -281,7 +289,9 @@ void Batch::setStateScissorRect(const Vec4i& rect) {
|
|||
|
||||
void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) {
|
||||
ADD_COMMAND(setUniformBuffer);
|
||||
|
||||
if (slot >= MAX_NUM_UNIFORM_BUFFERS) {
|
||||
qCWarning(gpulogging) << "Slot" << slot << "exceeds max uniform buffer count of" << MAX_NUM_UNIFORM_BUFFERS;
|
||||
}
|
||||
_params.emplace_back(size);
|
||||
_params.emplace_back(offset);
|
||||
_params.emplace_back(_buffers.cache(buffer));
|
||||
|
@ -294,6 +304,9 @@ void Batch::setUniformBuffer(uint32 slot, const BufferView& view) {
|
|||
|
||||
void Batch::setResourceBuffer(uint32 slot, const BufferPointer& buffer) {
|
||||
ADD_COMMAND(setResourceBuffer);
|
||||
if (slot >= MAX_NUM_RESOURCE_BUFFERS) {
|
||||
qCWarning(gpulogging) << "Slot" << slot << "exceeds max resources buffer count of" << MAX_NUM_RESOURCE_BUFFERS;
|
||||
}
|
||||
|
||||
_params.emplace_back(_buffers.cache(buffer));
|
||||
_params.emplace_back(slot);
|
||||
|
@ -302,6 +315,10 @@ void Batch::setResourceBuffer(uint32 slot, const BufferPointer& buffer) {
|
|||
void Batch::setResourceTexture(uint32 slot, const TexturePointer& texture) {
|
||||
ADD_COMMAND(setResourceTexture);
|
||||
|
||||
if (slot >= MAX_NUM_RESOURCE_TEXTURES) {
|
||||
qCWarning(gpulogging) << "Slot" << slot << "exceeds max texture count of" << MAX_NUM_RESOURCE_TEXTURES;
|
||||
}
|
||||
|
||||
_params.emplace_back(_textures.cache(texture));
|
||||
_params.emplace_back(slot);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
set(TARGET_NAME input-plugins)
|
||||
setup_hifi_library()
|
||||
link_hifi_libraries(shared plugins ui-plugins controllers)
|
||||
link_hifi_libraries(shared plugins ui-plugins controllers ui)
|
||||
|
||||
GroupSources("src/input-plugins")
|
||||
|
|
|
@ -14,12 +14,16 @@
|
|||
|
||||
#include "KeyboardMouseDevice.h"
|
||||
#include "TouchscreenDevice.h"
|
||||
#include "TouchscreenVirtualPadDevice.h"
|
||||
|
||||
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class
|
||||
InputPluginList getInputPlugins() {
|
||||
InputPlugin* PLUGIN_POOL[] = {
|
||||
new KeyboardMouseDevice(),
|
||||
new TouchscreenDevice(),
|
||||
#if defined(Q_OS_ANDROID)
|
||||
new TouchscreenVirtualPadDevice(),
|
||||
#endif
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
//
|
||||
// TouchscreenVirtualPadDevice.cpp
|
||||
// input-plugins/src/input-plugins
|
||||
//
|
||||
// Created by Triplelexx on 01/31/16.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "TouchscreenVirtualPadDevice.h"
|
||||
#include "KeyboardMouseDevice.h"
|
||||
|
||||
#include <QtGui/QTouchEvent>
|
||||
#include <QGestureEvent>
|
||||
#include <QGuiApplication>
|
||||
#include <QWindow>
|
||||
#include <QScreen>
|
||||
|
||||
#include <controllers/UserInputMapper.h>
|
||||
#include <PathUtils.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include "VirtualPadManager.h"
|
||||
|
||||
const char* TouchscreenVirtualPadDevice::NAME = "TouchscreenVirtualPad";
|
||||
|
||||
bool TouchscreenVirtualPadDevice::isSupported() const {
|
||||
for (auto touchDevice : QTouchDevice::devices()) {
|
||||
if (touchDevice->type() == QTouchDevice::TouchScreen) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#if defined(Q_OS_ANDROID)
|
||||
// last chance, assume that if this is android, a touchscreen is indeed supported
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
float clip(float n, float lower, float upper) {
|
||||
return std::max(lower, std::min(n, upper));
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
userInputMapper->withLock([&, this]() {
|
||||
_inputDevice->update(deltaTime, inputCalibrationData);
|
||||
});
|
||||
|
||||
auto& virtualPadManager = VirtualPad::Manager::instance();
|
||||
if (_validTouchLeft) {
|
||||
float leftDistanceScaleX, leftDistanceScaleY;
|
||||
leftDistanceScaleX = (_currentTouchLeftPoint.x - _firstTouchLeftPoint.x) / _screenDPIScale.x;
|
||||
leftDistanceScaleY = (_currentTouchLeftPoint.y - _firstTouchLeftPoint.y) / _screenDPIScale.y;
|
||||
|
||||
leftDistanceScaleX = clip(leftDistanceScaleX, -STICK_RADIUS_INCHES, STICK_RADIUS_INCHES);
|
||||
leftDistanceScaleY = clip(leftDistanceScaleY, -STICK_RADIUS_INCHES, STICK_RADIUS_INCHES);
|
||||
|
||||
// NOW BETWEEN -1 1
|
||||
leftDistanceScaleX /= STICK_RADIUS_INCHES;
|
||||
leftDistanceScaleY /= STICK_RADIUS_INCHES;
|
||||
|
||||
_inputDevice->_axisStateMap[controller::LX] = leftDistanceScaleX;
|
||||
_inputDevice->_axisStateMap[controller::LY] = leftDistanceScaleY;
|
||||
|
||||
/* Shared variables for stick rendering (clipped to the stick radius)*/
|
||||
// Prevent this for being done when not in first person view
|
||||
virtualPadManager.getLeftVirtualPad()->setBeingTouched(true);
|
||||
virtualPadManager.getLeftVirtualPad()->setFirstTouch(_firstTouchLeftPoint);
|
||||
virtualPadManager.getLeftVirtualPad()->setCurrentTouch(
|
||||
glm::vec2(clip(_currentTouchLeftPoint.x, -STICK_RADIUS_INCHES * _screenDPIScale.x + _firstTouchLeftPoint.x, STICK_RADIUS_INCHES * _screenDPIScale.x + _firstTouchLeftPoint.x),
|
||||
clip(_currentTouchLeftPoint.y, -STICK_RADIUS_INCHES * _screenDPIScale.y + _firstTouchLeftPoint.y, STICK_RADIUS_INCHES * _screenDPIScale.y + _firstTouchLeftPoint.y))
|
||||
);
|
||||
} else {
|
||||
virtualPadManager.getLeftVirtualPad()->setBeingTouched(false);
|
||||
}
|
||||
|
||||
if (_validTouchRight) {
|
||||
float rightDistanceScaleX, rightDistanceScaleY;
|
||||
rightDistanceScaleX = (_currentTouchRightPoint.x - _firstTouchRightPoint.x) / _screenDPIScale.x;
|
||||
rightDistanceScaleY = (_currentTouchRightPoint.y - _firstTouchRightPoint.y) / _screenDPIScale.y;
|
||||
|
||||
rightDistanceScaleX = clip(rightDistanceScaleX, -STICK_RADIUS_INCHES, STICK_RADIUS_INCHES);
|
||||
rightDistanceScaleY = clip(rightDistanceScaleY, -STICK_RADIUS_INCHES, STICK_RADIUS_INCHES);
|
||||
|
||||
// NOW BETWEEN -1 1
|
||||
rightDistanceScaleX /= STICK_RADIUS_INCHES;
|
||||
rightDistanceScaleY /= STICK_RADIUS_INCHES;
|
||||
|
||||
_inputDevice->_axisStateMap[controller::RX] = rightDistanceScaleX;
|
||||
_inputDevice->_axisStateMap[controller::RY] = rightDistanceScaleY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||
_axisStateMap.clear();
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::InputDevice::focusOutEvent() {
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::debugPoints(const QTouchEvent* event, QString who) {
|
||||
// convert the touch points into an average
|
||||
const QList<QTouchEvent::TouchPoint>& tPoints = event->touchPoints();
|
||||
QVector<glm::vec2> points;
|
||||
int touchPoints = tPoints.count();
|
||||
for (int i = 0; i < touchPoints; ++i) {
|
||||
glm::vec2 thisPoint(tPoints[i].pos().x(), tPoints[i].pos().y());
|
||||
points << thisPoint;
|
||||
}
|
||||
QScreen* eventScreen = event->window()->screen();
|
||||
int midScreenX = eventScreen->size().width()/2;
|
||||
int lefties = 0;
|
||||
int righties = 0;
|
||||
vec2 currentPoint;
|
||||
for (int i = 0; i < points.length(); i++) {
|
||||
currentPoint = points.at(i);
|
||||
if (currentPoint.x < midScreenX) {
|
||||
lefties++;
|
||||
} else {
|
||||
righties++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchBeginEvent(const QTouchEvent* event) {
|
||||
// touch begin here is a big begin -> begins both pads? maybe it does nothing
|
||||
debugPoints(event, " BEGIN ++++++++++++++++");
|
||||
KeyboardMouseDevice::enableTouch(false);
|
||||
QScreen* eventScreen = event->window()->screen();
|
||||
_screenWidthCenter = eventScreen->size().width() / 2;
|
||||
if (_screenDPI != eventScreen->physicalDotsPerInch()) {
|
||||
_screenDPIScale.x = (float)eventScreen->physicalDotsPerInchX();
|
||||
_screenDPIScale.y = (float)eventScreen->physicalDotsPerInchY();
|
||||
_screenDPI = eventScreen->physicalDotsPerInch();
|
||||
}
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchEndEvent(const QTouchEvent* event) {
|
||||
// touch end here is a big reset -> resets both pads
|
||||
_touchPointCount = 0;
|
||||
KeyboardMouseDevice::enableTouch(true);
|
||||
debugPoints(event, " END ----------------");
|
||||
touchLeftEnd();
|
||||
touchRightEnd();
|
||||
_inputDevice->_axisStateMap.clear();
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchUpdateEvent(const QTouchEvent* event) {
|
||||
_touchPointCount = event->touchPoints().count();
|
||||
|
||||
const QList<QTouchEvent::TouchPoint>& tPoints = event->touchPoints();
|
||||
bool leftTouchFound = false;
|
||||
bool rightTouchFound = false;
|
||||
for (int i = 0; i < _touchPointCount; ++i) {
|
||||
glm::vec2 thisPoint(tPoints[i].pos().x(), tPoints[i].pos().y());
|
||||
if (thisPoint.x < _screenWidthCenter) {
|
||||
if (!leftTouchFound) {
|
||||
leftTouchFound = true;
|
||||
if (!_validTouchLeft) {
|
||||
touchLeftBegin(thisPoint);
|
||||
} else {
|
||||
touchLeftUpdate(thisPoint);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!rightTouchFound) {
|
||||
rightTouchFound = true;
|
||||
if (!_validTouchRight) {
|
||||
touchRightBegin(thisPoint);
|
||||
} else {
|
||||
touchRightUpdate(thisPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!leftTouchFound) {
|
||||
touchLeftEnd();
|
||||
}
|
||||
if (!rightTouchFound) {
|
||||
touchRightEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchLeftBegin(glm::vec2 touchPoint) {
|
||||
auto& virtualPadManager = VirtualPad::Manager::instance();
|
||||
if (virtualPadManager.isEnabled()) {
|
||||
_firstTouchLeftPoint = touchPoint;
|
||||
_validTouchLeft = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchLeftUpdate(glm::vec2 touchPoint) {
|
||||
_currentTouchLeftPoint = touchPoint;
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchLeftEnd() {
|
||||
if (_validTouchLeft) { // do stuff once
|
||||
_validTouchLeft = false;
|
||||
_inputDevice->_axisStateMap[controller::LX] = 0;
|
||||
_inputDevice->_axisStateMap[controller::LY] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchRightBegin(glm::vec2 touchPoint) {
|
||||
auto& virtualPadManager = VirtualPad::Manager::instance();
|
||||
if (virtualPadManager.isEnabled()) {
|
||||
_firstTouchRightPoint = touchPoint;
|
||||
_validTouchRight = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchRightUpdate(glm::vec2 touchPoint) {
|
||||
_currentTouchRightPoint = touchPoint;
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchRightEnd() {
|
||||
if (_validTouchRight) { // do stuff once
|
||||
_validTouchRight = false;
|
||||
_inputDevice->_axisStateMap[controller::RX] = 0;
|
||||
_inputDevice->_axisStateMap[controller::RY] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TouchscreenVirtualPadDevice::touchGestureEvent(const QGestureEvent* event) {
|
||||
if (QGesture* gesture = event->gesture(Qt::PinchGesture)) {
|
||||
QPinchGesture* pinch = static_cast<QPinchGesture*>(gesture);
|
||||
_pinchScale = pinch->totalScaleFactor();
|
||||
}
|
||||
}
|
||||
|
||||
controller::Input::NamedVector TouchscreenVirtualPadDevice::InputDevice::getAvailableInputs() const {
|
||||
using namespace controller;
|
||||
QVector<Input::NamedPair> availableInputs{
|
||||
makePair(LX, "LX"),
|
||||
makePair(LY, "LY"),
|
||||
makePair(RX, "RX"),
|
||||
makePair(RY, "RY")
|
||||
};
|
||||
return availableInputs;
|
||||
}
|
||||
|
||||
QString TouchscreenVirtualPadDevice::InputDevice::getDefaultMappingConfig() const {
|
||||
static const QString MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/touchscreenvirtualpad.json";
|
||||
return MAPPING_JSON;
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
//
|
||||
// TouchscreenVirtualPadDevice.h
|
||||
// input-plugins/src/input-plugins
|
||||
//
|
||||
// Created by Triplelexx on 1/31/16.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_TouchscreenVirtualPadDevice_h
|
||||
#define hifi_TouchscreenVirtualPadDevice_h
|
||||
|
||||
#include <controllers/InputDevice.h>
|
||||
#include "InputPlugin.h"
|
||||
#include <QtGui/qtouchdevice.h>
|
||||
|
||||
class QTouchEvent;
|
||||
class QGestureEvent;
|
||||
|
||||
const float STICK_RADIUS_INCHES = .3f;
|
||||
|
||||
class TouchscreenVirtualPadDevice : public InputPlugin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
// Plugin functions
|
||||
virtual bool isSupported() const override;
|
||||
virtual const QString getName() const override { return NAME; }
|
||||
|
||||
bool isHandController() const override { return false; }
|
||||
|
||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||
|
||||
void touchBeginEvent(const QTouchEvent* event);
|
||||
void touchEndEvent(const QTouchEvent* event);
|
||||
void touchUpdateEvent(const QTouchEvent* event);
|
||||
void touchGestureEvent(const QGestureEvent* event);
|
||||
|
||||
static const char* NAME;
|
||||
|
||||
protected:
|
||||
|
||||
class InputDevice : public controller::InputDevice {
|
||||
public:
|
||||
InputDevice() : controller::InputDevice("TouchscreenVirtualPad") {}
|
||||
private:
|
||||
// Device functions
|
||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
||||
virtual QString getDefaultMappingConfig() const override;
|
||||
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||
virtual void focusOutEvent() override;
|
||||
|
||||
friend class TouchscreenVirtualPadDevice;
|
||||
};
|
||||
|
||||
public:
|
||||
const std::shared_ptr<InputDevice>& getInputDevice() const { return _inputDevice; }
|
||||
|
||||
protected:
|
||||
qreal _lastPinchScale;
|
||||
qreal _pinchScale;
|
||||
qreal _screenDPI;
|
||||
glm::vec2 _screenDPIScale;
|
||||
bool _validTouchLeft;
|
||||
glm::vec2 _firstTouchLeftPoint;
|
||||
glm::vec2 _currentTouchLeftPoint;
|
||||
bool _validTouchRight;
|
||||
glm::vec2 _firstTouchRightPoint;
|
||||
glm::vec2 _currentTouchRightPoint;
|
||||
int _touchPointCount;
|
||||
int _screenWidthCenter;
|
||||
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>() };
|
||||
|
||||
void touchLeftBegin(glm::vec2 touchPoint);
|
||||
void touchLeftUpdate(glm::vec2 touchPoint);
|
||||
void touchLeftEnd();
|
||||
void touchRightBegin(glm::vec2 touchPoint);
|
||||
void touchRightUpdate(glm::vec2 touchPoint);
|
||||
void touchRightEnd();
|
||||
// just for debug
|
||||
private:
|
||||
void debugPoints(const QTouchEvent* event, QString who);
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_TouchscreenVirtualPadDevice_h
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#include <NumericalConstants.h>
|
||||
#include <shared/NsightHelpers.h>
|
||||
|
||||
#include <shared/FileUtils.h>
|
||||
#include <Finally.h>
|
||||
#include <Profile.h>
|
||||
|
||||
|
@ -50,10 +50,8 @@ Q_LOGGING_CATEGORY(trace_resource_parse_image, "trace.resource.parse.image")
|
|||
Q_LOGGING_CATEGORY(trace_resource_parse_image_raw, "trace.resource.parse.image.raw")
|
||||
Q_LOGGING_CATEGORY(trace_resource_parse_image_ktx, "trace.resource.parse.image.ktx")
|
||||
|
||||
#if !defined(DISABLE_KTX_CACHE)
|
||||
const std::string TextureCache::KTX_DIRNAME { "ktx_cache" };
|
||||
const std::string TextureCache::KTX_EXT { "ktx" };
|
||||
#endif
|
||||
|
||||
static const QString RESOURCE_SCHEME = "resource";
|
||||
static const QUrl SPECTATOR_CAMERA_FRAME_URL("resource://spectatorCameraFrame");
|
||||
|
@ -62,9 +60,12 @@ static const QUrl HMD_PREVIEW_FRAME_URL("resource://hmdPreviewFrame");
|
|||
static const float SKYBOX_LOAD_PRIORITY { 10.0f }; // Make sure skybox loads first
|
||||
static const float HIGH_MIPS_LOAD_PRIORITY { 9.0f }; // Make sure high mips loads after skybox but before models
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
TextureCache::TextureCache() {
|
||||
#if !defined(DISABLE_KTX_CACHE)
|
||||
_ktxCache->initialize();
|
||||
#if defined(DISABLE_KTX_CACHE)
|
||||
_ktxCache->wipe();
|
||||
#endif
|
||||
setUnusedResourceCacheSize(0);
|
||||
setObjectName("TextureCache");
|
||||
|
@ -294,6 +295,10 @@ _maxNumPixels(100)
|
|||
_loaded = true;
|
||||
}
|
||||
|
||||
static bool isLocalUrl(const QUrl& url) {
|
||||
auto scheme = url.scheme();
|
||||
return (scheme == URL_SCHEME_FILE || scheme == URL_SCHEME_QRC || scheme == RESOURCE_SCHEME);
|
||||
}
|
||||
|
||||
NetworkTexture::NetworkTexture(const QUrl& url, image::TextureUsage::Type type, const QByteArray& content, int maxNumPixels) :
|
||||
Resource(url),
|
||||
|
@ -387,6 +392,21 @@ void NetworkTexture::makeRequest() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (isLocalUrl(_url)) {
|
||||
auto self = _self;
|
||||
QtConcurrent::run(QThreadPool::globalInstance(), [self] {
|
||||
auto resource = self.lock();
|
||||
if (!resource) {
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkTexture* networkTexture = static_cast<NetworkTexture*>(resource.data());
|
||||
networkTexture->makeLocalRequest();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// We special-handle ktx requests to run 2 concurrent requests right off the bat
|
||||
PROFILE_ASYNC_BEGIN(resource, "Resource:" + getType(), QString::number(_requestID), { { "url", _url.toString() }, { "activeURL", _activeUrl.toString() } });
|
||||
|
||||
|
@ -435,6 +455,74 @@ void NetworkTexture::makeRequest() {
|
|||
|
||||
}
|
||||
|
||||
void NetworkTexture::makeLocalRequest() {
|
||||
const QString scheme = _url.scheme();
|
||||
QString path;
|
||||
if (scheme == URL_SCHEME_FILE) {
|
||||
path = _url.toLocalFile();
|
||||
} else {
|
||||
path = ":" + _url.path();
|
||||
}
|
||||
|
||||
path = FileUtils::selectFile(path);
|
||||
|
||||
auto storage = std::make_shared<storage::FileStorage>(path);
|
||||
std::unique_ptr<ktx::KTX> ktxFile;
|
||||
if (storage) {
|
||||
ktxFile = ktx::KTX::create(storage);
|
||||
}
|
||||
std::shared_ptr<ktx::KTXDescriptor> ktxDescriptor;
|
||||
if (ktxFile) {
|
||||
ktxDescriptor = std::make_shared<ktx::KTXDescriptor>(ktxFile->toDescriptor());
|
||||
}
|
||||
|
||||
gpu::TexturePointer texture;
|
||||
if (ktxDescriptor) {
|
||||
std::string hash;
|
||||
// Create bare ktx in memory
|
||||
auto found = std::find_if(ktxDescriptor->keyValues.begin(), ktxDescriptor->keyValues.end(), [](const ktx::KeyValue& val) -> bool {
|
||||
return val._key.compare(gpu::SOURCE_HASH_KEY) == 0;
|
||||
});
|
||||
|
||||
if (found == ktxDescriptor->keyValues.end() || found->_value.size() != gpu::SOURCE_HASH_BYTES) {
|
||||
hash = _url.toString().toLocal8Bit().toHex().toStdString();
|
||||
} else {
|
||||
// at this point the source hash is in binary 16-byte form
|
||||
// and we need it in a hexadecimal string
|
||||
auto binaryHash = QByteArray(reinterpret_cast<const char*>(found->_value.data()), gpu::SOURCE_HASH_BYTES);
|
||||
hash = binaryHash.toHex().toStdString();
|
||||
}
|
||||
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
texture = textureCache->getTextureByHash(hash);
|
||||
if (!texture) {
|
||||
texture = gpu::Texture::build(*ktxDescriptor);
|
||||
if (texture) {
|
||||
texture->setKtxBacking(path.toStdString());
|
||||
texture->setSource(path.toStdString());
|
||||
texture = textureCache->cacheTextureByHash(hash, texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!texture) {
|
||||
qCDebug(networking).noquote() << "Failed load local KTX from" << path;
|
||||
QMetaObject::invokeMethod(this, "setImage",
|
||||
Q_ARG(gpu::TexturePointer, nullptr),
|
||||
Q_ARG(int, 0),
|
||||
Q_ARG(int, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
_ktxResourceState = PENDING_MIP_REQUEST;
|
||||
_lowestKnownPopulatedMip = texture->minAvailableMipLevel();
|
||||
QMetaObject::invokeMethod(this, "setImage",
|
||||
Q_ARG(gpu::TexturePointer, texture),
|
||||
Q_ARG(int, texture->getWidth()),
|
||||
Q_ARG(int, texture->getHeight()));
|
||||
|
||||
}
|
||||
|
||||
bool NetworkTexture::handleFailedRequest(ResourceRequest::Result result) {
|
||||
if (!_sourceIsKTX && result == ResourceRequest::Result::RedirectFail) {
|
||||
auto newPath = _request->getRelativePathUrl();
|
||||
|
@ -750,7 +838,6 @@ void NetworkTexture::handleFinishedInitialLoad() {
|
|||
|
||||
gpu::TexturePointer texture = textureCache->getTextureByHash(hash);
|
||||
|
||||
#if !defined(DISABLE_KTX_CACHE)
|
||||
if (!texture) {
|
||||
auto ktxFile = textureCache->_ktxCache->getFile(hash);
|
||||
if (ktxFile) {
|
||||
|
@ -763,9 +850,8 @@ void NetworkTexture::handleFinishedInitialLoad() {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!texture) {
|
||||
|
||||
if (!texture) {
|
||||
auto memKtx = ktx::KTX::createBare(*header, keyValues);
|
||||
if (!memKtx) {
|
||||
qWarning() << " Ktx could not be created, bailing";
|
||||
|
@ -778,7 +864,6 @@ void NetworkTexture::handleFinishedInitialLoad() {
|
|||
|
||||
// Move ktx to file
|
||||
const char* data = reinterpret_cast<const char*>(memKtx->_storage->data());
|
||||
#if !defined(DISABLE_KTX_CACHE)
|
||||
size_t length = memKtx->_storage->size();
|
||||
cache::FilePointer file;
|
||||
auto& ktxCache = textureCache->_ktxCache;
|
||||
|
@ -790,14 +875,11 @@ void NetworkTexture::handleFinishedInitialLoad() {
|
|||
Q_ARG(int, 0));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto newKtxDescriptor = memKtx->toDescriptor();
|
||||
|
||||
texture = gpu::Texture::build(newKtxDescriptor);
|
||||
#if !defined(DISABLE_KTX_CACHE)
|
||||
texture->setKtxBacking(file);
|
||||
#endif
|
||||
texture->setSource(filename);
|
||||
|
||||
auto& images = originalKtxDescriptor->images;
|
||||
|
@ -940,7 +1022,6 @@ void ImageReader::read() {
|
|||
// If we already have a live texture with the same hash, use it
|
||||
auto texture = textureCache->getTextureByHash(hash);
|
||||
|
||||
#if !defined(DISABLE_KTX_CACHE)
|
||||
// If there is no live texture, check if there's an existing KTX file
|
||||
if (!texture) {
|
||||
auto ktxFile = textureCache->_ktxCache->getFile(hash);
|
||||
|
@ -953,7 +1034,6 @@ void ImageReader::read() {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we found the texture either because it's in use or via KTX deserialization,
|
||||
// set the image and return immediately.
|
||||
|
@ -989,7 +1069,6 @@ void ImageReader::read() {
|
|||
|
||||
// Save the image into a KTXFile
|
||||
if (texture && textureCache) {
|
||||
#if !defined(DISABLE_KTX_CACHE)
|
||||
auto memKtx = gpu::Texture::serialize(*texture);
|
||||
|
||||
// Move the texture into a memory mapped file
|
||||
|
@ -1006,7 +1085,7 @@ void ImageReader::read() {
|
|||
} else {
|
||||
qCWarning(modelnetworking) << "Unable to serialize texture to KTX " << _url;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We replace the texture with the one stored in the cache. This deals with the possible race condition of two different
|
||||
// images with the same hash being loaded concurrently. Only one of them will make it into the cache by hash first and will
|
||||
// be the winner
|
||||
|
|
|
@ -70,6 +70,7 @@ public slots:
|
|||
|
||||
protected:
|
||||
void makeRequest() override;
|
||||
void makeLocalRequest();
|
||||
|
||||
virtual bool isCacheable() const override { return _loaded; }
|
||||
|
||||
|
@ -194,12 +195,11 @@ private:
|
|||
TextureCache();
|
||||
virtual ~TextureCache();
|
||||
|
||||
#if !defined(DISABLE_KTX_CACHE)
|
||||
static const std::string KTX_DIRNAME;
|
||||
static const std::string KTX_EXT;
|
||||
|
||||
std::shared_ptr<cache::FileCache> _ktxCache { std::make_shared<KTXCache>(KTX_DIRNAME, KTX_EXT) };
|
||||
#endif
|
||||
|
||||
// Map from image hashes to texture weak pointers
|
||||
std::unordered_map<std::string, std::weak_ptr<gpu::Texture>> _texturesByHashes;
|
||||
std::mutex _texturesByHashesMutex;
|
||||
|
|
|
@ -104,11 +104,17 @@ QUrl AddressManager::currentFacingShareableAddress() const {
|
|||
}
|
||||
|
||||
void AddressManager::loadSettings(const QString& lookupString) {
|
||||
#if defined(USE_GLES) && defined(Q_OS_WIN)
|
||||
handleUrl(QUrl("hifi://127.0.0.0"), LookupTrigger::StartupFromSettings);
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
handleUrl(QUrl("hifi://dev-android"), LookupTrigger::StartupFromSettings);
|
||||
#else
|
||||
if (lookupString.isEmpty()) {
|
||||
handleUrl(currentAddressHandle.get(), LookupTrigger::StartupFromSettings);
|
||||
} else {
|
||||
handleUrl(lookupString, LookupTrigger::StartupFromSettings);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AddressManager::goBack() {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <StatTracker.h>
|
||||
#include <shared/FileUtils.h>
|
||||
|
||||
#include "NetworkLogging.h"
|
||||
#include "ResourceManager.h"
|
||||
|
||||
void FileResourceRequest::doSend() {
|
||||
|
@ -38,9 +39,15 @@ void FileResourceRequest::doSend() {
|
|||
|
||||
|
||||
// Allow platform specific versions of files loaded out of a resource cache via file://
|
||||
QFileSelector fileSelector;
|
||||
fileSelector.setExtraSelectors(FileUtils::getFileSelectors());
|
||||
filename = fileSelector.select(filename);
|
||||
{
|
||||
QString originalFilename = filename;
|
||||
QFileSelector fileSelector;
|
||||
fileSelector.setExtraSelectors(FileUtils::getFileSelectors());
|
||||
filename = fileSelector.select(filename);
|
||||
if (filename != originalFilename) {
|
||||
qCDebug(resourceLog) << "Using" << filename << "instead of" << originalFilename;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_byteRange.isValid()) {
|
||||
_result = ResourceRequest::InvalidByteRange;
|
||||
|
|
|
@ -187,6 +187,10 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
|
|||
}
|
||||
|
||||
bool Procedural::isReady() const {
|
||||
#if defined(USE_GLES)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!_enabled) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -34,8 +34,12 @@ render::ShapePipeline::BatchSetter FadeEffect::getBatchSetter() const {
|
|||
auto program = shapePipeline.pipeline->getProgram();
|
||||
auto maskMapLocation = program->getTextures().findLocation("fadeMaskMap");
|
||||
auto bufferLocation = program->getUniformBuffers().findLocation("fadeParametersBuffer");
|
||||
batch.setResourceTexture(maskMapLocation, _maskMap);
|
||||
batch.setUniformBuffer(bufferLocation, _configurations);
|
||||
if (maskMapLocation != -1) {
|
||||
batch.setResourceTexture(maskMapLocation, _maskMap);
|
||||
}
|
||||
if (bufferLocation != -1) {
|
||||
batch.setUniformBuffer(bufferLocation, _configurations);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -124,8 +124,6 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
color += ambientDiffuse;
|
||||
color += ambientSpecular;
|
||||
|
||||
|
||||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
|
||||
|
@ -136,6 +134,11 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
color += directionalDiffuse;
|
||||
color += directionalSpecular;
|
||||
|
||||
// Attenuate the light if haze effect selected
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
|
||||
color = computeHazeColorKeyLightAttenuation(color, lightDirection, position);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
@ -168,6 +171,7 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
|
|||
|
||||
|
||||
|
||||
<@include Haze.slh@>
|
||||
|
||||
<@func declareEvalGlobalLightingAlphaBlended()@>
|
||||
|
||||
|
@ -198,6 +202,46 @@ vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, fl
|
|||
return color;
|
||||
}
|
||||
|
||||
vec3 evalGlobalLightingAlphaBlendedWithHaze(
|
||||
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal,
|
||||
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity)
|
||||
{
|
||||
<$prepareGlobalLight()$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
|
||||
color += emissive * isEmissiveEnabled();
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
|
||||
color += ambientDiffuse;
|
||||
color += ambientSpecular / opacity;
|
||||
|
||||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
|
||||
color += directionalDiffuse;
|
||||
color += directionalSpecular / opacity;
|
||||
|
||||
// Haze
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
|
||||
vec4 colorV4 = computeHazeColor(
|
||||
vec4(color, 1.0), // fragment original color
|
||||
position, // fragment position in eye coordinates
|
||||
fragEyeVector, // fragment position in world coordinates
|
||||
invViewMat[3].y, // eye height in world coordinates
|
||||
lightDirection // keylight direction vector
|
||||
);
|
||||
|
||||
color = colorV4.rgb;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, SurfaceData surface) {
|
|||
float levels = getLightAmbientMapNumMips(ambient);
|
||||
float m = 12.0 / (1.0+11.0*surface.roughness);
|
||||
float lod = levels - m;
|
||||
lod = max(lod, 0);
|
||||
lod = max(lod, 0.0);
|
||||
specularLight = evalSkyboxLight(lightDir, lod).xyz;
|
||||
}
|
||||
<@endif@>
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "forward_model_normal_map_frag.h"
|
||||
#include "forward_model_normal_specular_map_frag.h"
|
||||
#include "forward_model_specular_map_frag.h"
|
||||
#include "forward_model_translucent_frag.h"
|
||||
|
||||
#include "model_lightmap_frag.h"
|
||||
#include "model_lightmap_normal_map_frag.h"
|
||||
|
@ -451,6 +452,7 @@ void initForwardPipelines(ShapePlumber& plumber, const render::ShapePipeline::Ba
|
|||
auto modelSpecularMapPixel = gpu::Shader::createPixel(std::string(forward_model_specular_map_frag));
|
||||
auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(forward_model_normal_specular_map_frag));
|
||||
auto modelNormalMapFadePixel = gpu::Shader::createPixel(std::string(model_normal_map_fade_frag));
|
||||
auto modelTranslucentPixel = gpu::Shader::createPixel(std::string(forward_model_translucent_frag));
|
||||
|
||||
using Key = render::ShapeKey;
|
||||
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3, _4, _5);
|
||||
|
@ -486,7 +488,25 @@ void initForwardPipelines(ShapePlumber& plumber, const render::ShapePipeline::Ba
|
|||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTangents().withFade(),
|
||||
skinModelNormalMapFadeVertex, modelNormalMapFadePixel, batchSetter, itemSetter, nullptr, nullptr);
|
||||
|
||||
// Translucents
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent(),
|
||||
modelVertex, modelTranslucentPixel, batchSetter, itemSetter, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withTangents(),
|
||||
modelNormalMapVertex, modelTranslucentPixel, batchSetter, itemSetter, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withSpecular(),
|
||||
modelVertex, modelTranslucentPixel, batchSetter, itemSetter, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withTangents().withSpecular(),
|
||||
modelNormalMapVertex, modelTranslucentPixel, batchSetter, itemSetter, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel, batchSetter, itemSetter, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent(),
|
||||
skinModelVertex, modelTranslucentPixel, batchSetter, itemSetter, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void addPlumberPipeline(ShapePlumber& plumber,
|
||||
|
|
|
@ -368,7 +368,9 @@ void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, c
|
|||
setupGPU();
|
||||
|
||||
batch.setPipeline(((*color).a < 1.0f || layered) ? _transparentPipeline : _pipeline);
|
||||
batch.setResourceTexture(_fontLoc, _texture);
|
||||
if (_fontLoc >= 0) {
|
||||
batch.setResourceTexture(_fontLoc, _texture);
|
||||
}
|
||||
if (_outlineLoc >= 0) {
|
||||
batch._glUniform1i(_outlineLoc, (effectType == OUTLINE_EFFECT));
|
||||
}
|
||||
|
|
|
@ -38,6 +38,16 @@ const QStringList& FileUtils::getFileSelectors() {
|
|||
|
||||
}
|
||||
|
||||
QString FileUtils::selectFile(const QString& path) {
|
||||
QFileSelector fileSelector;
|
||||
fileSelector.setExtraSelectors(FileUtils::getFileSelectors());
|
||||
QString result = fileSelector.select(path);
|
||||
if (path != result) {
|
||||
qDebug() << "Using" << result << "instead of" << path;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
QString FileUtils::readFile(const QString& filename) {
|
||||
QFile file(filename);
|
||||
|
@ -51,7 +61,7 @@ QStringList FileUtils::readLines(const QString& filename, QString::SplitBehavior
|
|||
return readFile(filename).split(QRegularExpression("[\\r\\n]"), QString::SkipEmptyParts);
|
||||
}
|
||||
|
||||
void FileUtils::locateFile(QString filePath) {
|
||||
void FileUtils::locateFile(const QString& filePath) {
|
||||
|
||||
// adapted from
|
||||
// http://stackoverflow.com/questions/3490336/how-to-reveal-in-finder-or-show-in-explorer-with-qt
|
||||
|
|
|
@ -18,7 +18,8 @@ class FileUtils {
|
|||
|
||||
public:
|
||||
static const QStringList& getFileSelectors();
|
||||
static void locateFile(QString fileName);
|
||||
static QString selectFile(const QString& fileName);
|
||||
static void locateFile(const QString& fileName);
|
||||
static QString standardPath(QString subfolder);
|
||||
static QString readFile(const QString& filename);
|
||||
static QStringList readLines(const QString& filename, QString::SplitBehavior splitBehavior = QString::KeepEmptyParts);
|
||||
|
|
58
libraries/ui/src/VirtualPadManager.cpp
Normal file
58
libraries/ui/src/VirtualPadManager.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// Created by Gabriel Calero & Cristian Duarte on 01/16/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "VirtualPadManager.h"
|
||||
|
||||
namespace VirtualPad {
|
||||
|
||||
bool Instance::isBeingTouched() {
|
||||
return _isBeingTouched;
|
||||
}
|
||||
|
||||
void Instance::setBeingTouched(bool touched) {
|
||||
_isBeingTouched = touched;
|
||||
}
|
||||
|
||||
void Instance::setFirstTouch(glm::vec2 point) {
|
||||
_firstTouch = point;
|
||||
}
|
||||
|
||||
glm::vec2 Instance::getFirstTouch() {
|
||||
return _firstTouch;
|
||||
}
|
||||
|
||||
void Instance::setCurrentTouch(glm::vec2 point) {
|
||||
_currentTouch = point;
|
||||
}
|
||||
|
||||
glm::vec2 Instance::getCurrentTouch() {
|
||||
return _currentTouch;
|
||||
}
|
||||
|
||||
Manager::Manager() {
|
||||
|
||||
}
|
||||
|
||||
Manager& Manager::instance() {
|
||||
static QSharedPointer<Manager> instance = DependencyManager::get<VirtualPad::Manager>();
|
||||
return *instance;
|
||||
}
|
||||
|
||||
void Manager::enable(bool enable) {
|
||||
_enabled = enable;
|
||||
}
|
||||
|
||||
bool Manager::isEnabled() {
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
Instance* Manager::getLeftVirtualPad() {
|
||||
return &_leftVPadInstance;
|
||||
}
|
||||
|
||||
}
|
46
libraries/ui/src/VirtualPadManager.h
Normal file
46
libraries/ui/src/VirtualPadManager.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// Created by Gabriel Calero & Cristian Duarte on 01/16/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
namespace VirtualPad {
|
||||
class Instance {
|
||||
public:
|
||||
virtual bool isBeingTouched();
|
||||
virtual void setBeingTouched(bool touched);
|
||||
virtual void setFirstTouch(glm::vec2 point);
|
||||
virtual glm::vec2 getFirstTouch();
|
||||
virtual void setCurrentTouch(glm::vec2 point);
|
||||
virtual glm::vec2 getCurrentTouch();
|
||||
private:
|
||||
bool _isBeingTouched;
|
||||
glm::vec2 _firstTouch;
|
||||
glm::vec2 _currentTouch;
|
||||
};
|
||||
|
||||
class Manager : public QObject, public Dependency {
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
Manager();
|
||||
Manager(const Manager& other) = delete;
|
||||
public:
|
||||
static Manager& instance();
|
||||
Instance* getLeftVirtualPad();
|
||||
bool isEnabled();
|
||||
void enable(bool enable);
|
||||
private:
|
||||
Instance _leftVPadInstance;
|
||||
bool _enabled;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -12,7 +12,8 @@
|
|||
//
|
||||
|
||||
var DEFAULT_SCRIPTS_COMBINED = [
|
||||
"system/progress.js"/*,
|
||||
"system/progress.js",
|
||||
"system/touchscreenvirtualpad.js"/*,
|
||||
"system/away.js",
|
||||
"system/controllers/controllerDisplayManager.js",
|
||||
"system/controllers/handControllerGrabAndroid.js",
|
||||
|
|
21
scripts/system/touchscreenvirtualpad.js
Normal file
21
scripts/system/touchscreenvirtualpad.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
"use strict";
|
||||
//
|
||||
// android.js
|
||||
// scripts/system/
|
||||
//
|
||||
// Created by Gabriel Calero & Cristian Duarte on Jan 16, 2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
|
||||
function init() {
|
||||
Controller.setVPadEnabled(true);
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
}()); // END LOCAL_SCOPE
|
|
@ -12,6 +12,9 @@ if (BUILD_TOOLS)
|
|||
add_subdirectory(ice-client)
|
||||
set_target_properties(ice-client PROPERTIES FOLDER "Tools")
|
||||
|
||||
add_subdirectory(ktx-tool)
|
||||
set_target_properties(ktx-tool PROPERTIES FOLDER "Tools")
|
||||
|
||||
add_subdirectory(ac-client)
|
||||
set_target_properties(ac-client PROPERTIES FOLDER "Tools")
|
||||
|
||||
|
|
14
tools/ktx-tool/CMakeLists.txt
Normal file
14
tools/ktx-tool/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
set(TARGET_NAME ktx-tool)
|
||||
|
||||
setup_hifi_project(Quick Gui Concurrent)
|
||||
|
||||
link_hifi_libraries(shared networking image gl gpu ktx)
|
||||
|
||||
target_gli()
|
||||
|
||||
setup_memory_debugger()
|
||||
|
||||
if (WIN32)
|
||||
package_libraries_for_deployment()
|
||||
endif()
|
||||
|
209
tools/ktx-tool/src/main.cpp
Normal file
209
tools/ktx-tool/src/main.cpp
Normal file
|
@ -0,0 +1,209 @@
|
|||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <cstdio>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <gli/gli.hpp>
|
||||
#include <gli/convert.hpp>
|
||||
#include <gli/generate_mipmaps.hpp>
|
||||
#include <gli/load.hpp>
|
||||
#include <gli/save.hpp>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QtCore/QTime>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QLoggingCategory>
|
||||
|
||||
#include <QtCore/QResource>
|
||||
|
||||
#include <QtGui/QResizeEvent>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QImage>
|
||||
|
||||
#include <gl/Config.h>
|
||||
|
||||
#include <gpu/Context.h>
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/Stream.h>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <PathUtils.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <PerfStat.h>
|
||||
#include <PathUtils.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include <gpu/Pipeline.h>
|
||||
#include <gpu/Context.h>
|
||||
#include <gpu/Texture.h>
|
||||
|
||||
#include <ktx/KTX.h>
|
||||
|
||||
|
||||
|
||||
|
||||
void stripKtxKeyValues(const std::string& sourceFile, const std::string& destFile) {
|
||||
auto sourceStorage = std::make_shared<storage::FileStorage>(sourceFile.c_str());
|
||||
auto ktx = ktx::KTX::create(sourceStorage);
|
||||
auto newStorageSize = ktx::KTX::evalStorageSize(ktx->_header, ktx->_images);
|
||||
storage::FileStorage::create(destFile.c_str(), newStorageSize, nullptr);
|
||||
storage::FileStorage destStorage(destFile.c_str());
|
||||
auto writtenSize = ktx::KTX::write(destStorage.mutableData(), newStorageSize, ktx->_header, ktx->_images);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const QDir SOURCE_FOLDER{ PathUtils::projectRootPath() + "/interface/resources/meshes/mannequin" };
|
||||
const QDir DEST_FOLDER{ PathUtils::projectRootPath() + "/interface/resources/meshes/mannequin/+gles" };
|
||||
const gli::gl GL(gli::gl::PROFILE_GL33);
|
||||
|
||||
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||
#ifdef Q_OS_WIN
|
||||
OutputDebugStringA(message.toStdString().c_str());
|
||||
OutputDebugStringA("\n");
|
||||
#endif
|
||||
std::cout << message.toStdString() << std::endl;
|
||||
}
|
||||
|
||||
static inline glm::uvec2 evalMipDimension(uint32_t mipLevel, const glm::uvec2& dims) {
|
||||
return glm::uvec2{
|
||||
std::max(dims.x >> mipLevel, 1U),
|
||||
std::max(dims.y >> mipLevel, 1U),
|
||||
};
|
||||
}
|
||||
|
||||
void processKtxFile(const QFileInfo& inputFileInfo) {
|
||||
const QString inputFileName = inputFileInfo.absoluteFilePath();
|
||||
const QString compressedFileName = DEST_FOLDER.absoluteFilePath(inputFileInfo.fileName());
|
||||
const QString finalFilename = compressedFileName + ".new.ktx";
|
||||
if (QFileInfo(finalFilename).exists()) {
|
||||
return;
|
||||
}
|
||||
qDebug() << inputFileName;
|
||||
qDebug() << compressedFileName;
|
||||
auto uncomrpessedKtx = ktx::KTX::create(std::make_shared<storage::FileStorage>(compressedFileName));
|
||||
if (!uncomrpessedKtx) {
|
||||
throw std::runtime_error("Unable to load texture using hifi::ktx");
|
||||
}
|
||||
|
||||
auto compressedKtx = ktx::KTX::create(std::make_shared<storage::FileStorage>(inputFileName));
|
||||
if (!compressedKtx) {
|
||||
throw std::runtime_error("Unable to load texture using hifi::ktx");
|
||||
}
|
||||
|
||||
|
||||
auto outputKtx = ktx::KTX::create(uncomrpessedKtx->getHeader(), uncomrpessedKtx->_images, compressedKtx->_keyValues);
|
||||
auto outputStorage = outputKtx->getStorage();
|
||||
|
||||
storage::FileStorage::create(finalFilename, outputStorage->size(), outputStorage->data());
|
||||
#if 0
|
||||
const auto& header = inputKtx->getHeader();
|
||||
|
||||
|
||||
detexTexture **input_textures;
|
||||
int nu_levels;
|
||||
if (!detexLoadTextureFileWithMipmaps(inputFileName.toStdString().c_str(), 32, &input_textures, &nu_levels)) {
|
||||
return;
|
||||
//throw std::runtime_error(detexGetErrorMessage());
|
||||
}
|
||||
|
||||
switch (header.glInternalFormat) {
|
||||
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
|
||||
case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
|
||||
outputHeader.glFormat = GL_RGBA;
|
||||
outputHeader.glInternalFormat = GL_RGBA8;
|
||||
break;
|
||||
|
||||
case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
|
||||
outputHeader.glFormat = GL_RG;
|
||||
outputHeader.glInternalFormat = GL_RG8;
|
||||
qWarning() << "Unsupported";
|
||||
return;
|
||||
break;
|
||||
|
||||
case GL_COMPRESSED_RED_RGTC1_EXT:
|
||||
outputHeader.glFormat = GL_RED;
|
||||
outputHeader.glInternalFormat = GL_R8;
|
||||
qWarning() << "Unsupported";
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
qWarning() << "Unsupported";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto outputKtx = ktx::KTX::createBare(outputHeader, ktx->_keyValues);
|
||||
auto outputDescriptor = outputKtx->toDescriptor();
|
||||
auto outputStorage = outputKtx->getStorage();
|
||||
auto outputPointer = outputStorage->mutableData();
|
||||
auto outputSize = outputStorage->size();
|
||||
|
||||
glm::uvec2 dimensions{ header.pixelWidth, header.pixelHeight };
|
||||
for (uint16_t mip = 0; mip < header.numberOfMipmapLevels; ++mip) {
|
||||
auto mipDimensions = evalMipDimension(mip, dimensions);
|
||||
|
||||
for (uint8_t face = 0; face < header.numberOfFaces; ++face) {
|
||||
auto faceSize = outputDescriptor.getMipFaceTexelsSize(mip, face);
|
||||
auto faceOffset = outputDescriptor.getMipFaceTexelsOffset(mip, face);
|
||||
assert(faceOffset + faceSize <= outputSize);
|
||||
auto mipFace = ktx->getMipFaceTexelsData(mip, face);
|
||||
auto outputMipFace = outputKtx->getMipFaceTexelsData();
|
||||
if (header.glInternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) {
|
||||
BlockDecompressImageDXT5(mipDimensions.x, mipDimensions.y, mipFace->data(), (unsigned long*)(outputPointer + faceOffset));
|
||||
} else if (header.glInternalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) {
|
||||
BlockDecompressImageDXT1(mipDimensions.x, mipDimensions.y, mipFace->data(), (unsigned long*)(outputPointer + faceOffset));
|
||||
} else {
|
||||
qWarning() << "Unsupported";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
storage::FileStorage::create(outputFileName, outputStorage->size(), outputStorage->data());
|
||||
#endif
|
||||
//if (gliTexture.empty()) {
|
||||
// throw std::runtime_error("Unable to load texture using GLI");
|
||||
//}
|
||||
//gli::texture2d gliTextureConverted = gli::convert(gliTexture, gli::FORMAT_RGBA8_UNORM_PACK8);
|
||||
}
|
||||
|
||||
void scanDir(const QDir& dir) {
|
||||
|
||||
auto entries = dir.entryInfoList();
|
||||
for (const auto& entry : entries) {
|
||||
if (entry.isDir()) {
|
||||
scanDir(QDir(entry.absoluteFilePath()));
|
||||
} else {
|
||||
qDebug() << entry.absoluteFilePath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
qInstallMessageHandler(messageHandler);
|
||||
{
|
||||
QDir destFolder(DEST_FOLDER);
|
||||
if (!destFolder.exists() && !destFolder.mkpath(".")) {
|
||||
throw std::runtime_error("failed to create output directory");
|
||||
}
|
||||
for (const auto ktxFile : SOURCE_FOLDER.entryInfoList(QStringList() << "*.ktx")) {
|
||||
processKtxFile(ktxFile);
|
||||
}
|
||||
qDebug() << "Done";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue