From 4d1619ddfbc781585106dc108ea9b58e56ecb4f6 Mon Sep 17 00:00:00 2001 From: "adam.b" Date: Wed, 10 Aug 2016 19:05:27 +0100 Subject: [PATCH] VR: Gyro support, math corrections for gearvr, Dali desktop gyroscope support through proxy server Change-Id: I753632660e7b65e77bd7f078aaeefa0f9cda9435 --- .../test-application.cpp | 1 + dali/integration-api/core.cpp | 5 +- dali/integration-api/core.h | 2 + dali/integration-api/file.list | 1 + dali/integration-api/gyroscope-sensor.h | 47 +++++++ dali/internal/common/core-impl.cpp | 6 +- dali/internal/common/core-impl.h | 2 + .../event/actors/camera-actor-impl.cpp | 32 +++++ .../internal/event/actors/camera-actor-impl.h | 19 +++ dali/internal/event/common/stage-impl.cpp | 117 ++++++++++++++++-- dali/internal/event/common/stage-impl.h | 22 ++++ .../internal/render/common/render-manager.cpp | 30 +++-- dali/internal/render/common/renderer-vr.h | 16 ++- .../update/manager/update-manager.cpp | 13 +- dali/internal/update/manager/update-manager.h | 6 +- .../render-tasks/scene-graph-camera.cpp | 26 ++-- dali/public-api/actors/camera-actor.h | 1 + 17 files changed, 311 insertions(+), 35 deletions(-) create mode 100644 dali/integration-api/gyroscope-sensor.h diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp index f2e3cd739..ce23d856c 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp @@ -68,6 +68,7 @@ void TestApplication::Initialize() mGlAbstraction, mGlSyncAbstraction, mGestureManager, + NULL, mDataRetentionPolicy); mCore->ContextCreated(); diff --git a/dali/integration-api/core.cpp b/dali/integration-api/core.cpp index dc08bb917..5e2dd3485 100644 --- a/dali/integration-api/core.cpp +++ b/dali/integration-api/core.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include namespace Dali @@ -31,10 +32,10 @@ namespace Integration { Core* Core::New(RenderController& renderController, PlatformAbstraction& platformAbstraction, - GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction, GestureManager& gestureManager, ResourcePolicy::DataRetention policy ) + GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction, GestureManager& gestureManager, GyroscopeSensor* gyroscopeSensor, ResourcePolicy::DataRetention policy ) { Core* instance = new Core; - instance->mImpl = new Internal::Core( renderController, platformAbstraction, glAbstraction, glSyncAbstraction, gestureManager, policy ); + instance->mImpl = new Internal::Core( renderController, platformAbstraction, glAbstraction, glSyncAbstraction, gestureManager, gyroscopeSensor, policy ); return instance; } diff --git a/dali/integration-api/core.h b/dali/integration-api/core.h index c99258b85..90a0e3d6e 100644 --- a/dali/integration-api/core.h +++ b/dali/integration-api/core.h @@ -42,6 +42,7 @@ class GlSyncAbstraction; class PlatformAbstraction; class RenderController; class SystemOverlay; +class GyroscopeSensor; struct Event; struct TouchData; @@ -204,6 +205,7 @@ public: GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction, GestureManager& gestureManager, + GyroscopeSensor* gyroscopeSensor, ResourcePolicy::DataRetention policy); /** diff --git a/dali/integration-api/file.list b/dali/integration-api/file.list index 79d4f959f..37ca0b4e0 100644 --- a/dali/integration-api/file.list +++ b/dali/integration-api/file.list @@ -37,6 +37,7 @@ platform_abstraction_header_files = \ $(platform_abstraction_src_dir)/resource-cache.h \ $(platform_abstraction_src_dir)/resource-declarations.h \ $(platform_abstraction_src_dir)/gl-abstraction.h \ + $(platform_abstraction_src_dir)/gyroscope-sensor.h \ $(platform_abstraction_src_dir)/gl-defines.h \ $(platform_abstraction_src_dir)/gl-sync-abstraction.h \ $(platform_abstraction_src_dir)/gesture-manager.h \ diff --git a/dali/integration-api/gyroscope-sensor.h b/dali/integration-api/gyroscope-sensor.h new file mode 100644 index 000000000..438ed628e --- /dev/null +++ b/dali/integration-api/gyroscope-sensor.h @@ -0,0 +1,47 @@ +#ifndef __DALI_GYROSCOPE_SENSOR_H__ +#define __DALI_GYROSCOPE_SENSOR_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +namespace Dali +{ +class Vector4; + +namespace Integration +{ + +// EXTERNAL INCLUDES +class GyroscopeSensor +{ +public: + + GyroscopeSensor() {} + virtual ~GyroscopeSensor() {} + + virtual void Enable() = 0; + virtual void Disable() = 0; + virtual void Read( Dali::Vector4& data ) = 0; + virtual void ReadPackets( Dali::Vector4* data, int count ) = 0; + virtual bool IsEnabled() = 0; + virtual bool IsSupported() = 0; +}; + +} // Integration +} // Dali + +#endif diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index b4154824c..207421634 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -83,10 +83,11 @@ using Integration::GlAbstraction; using Integration::Event; using Integration::UpdateStatus; using Integration::RenderStatus; +using Integration::GyroscopeSensor; Core::Core( RenderController& renderController, PlatformAbstraction& platform, GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction, - GestureManager& gestureManager, ResourcePolicy::DataRetention dataRetentionPolicy) + GestureManager& gestureManager, GyroscopeSensor* gyroscopeSensor, ResourcePolicy::DataRetention dataRetentionPolicy) : mRenderController( renderController ), mPlatform(platform), mGestureEventProcessor(NULL), @@ -160,7 +161,7 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) ); mStage->Initialize(); - + mStage->SetGyroscopeSensor( gyroscopeSensor ); mResourceClient = new ResourceClient( *mResourceManager, *mStage ); mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController); @@ -169,6 +170,7 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, mImageFactory = new ImageFactory( *mResourceClient ); mShaderFactory = new ShaderFactory(); mUpdateManager->SetShaderSaver( *mShaderFactory ); + mUpdateManager->SetGyroscopeSensor( *gyroscopeSensor ); mShaderFactory->LoadDefaultShaders(); GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions(); diff --git a/dali/internal/common/core-impl.h b/dali/internal/common/core-impl.h index d40f827ed..0f342305e 100644 --- a/dali/internal/common/core-impl.h +++ b/dali/internal/common/core-impl.h @@ -41,6 +41,7 @@ class GlSyncAbstraction; class SystemOverlay; class UpdateStatus; class RenderStatus; +class GyroscopeSensor; struct Event; struct TouchData; } @@ -84,6 +85,7 @@ public: Integration::GlAbstraction& glAbstraction, Integration::GlSyncAbstraction& glSyncAbstraction, Integration::GestureManager& gestureManager, + Integration::GyroscopeSensor* gyroscopeSensor, ResourcePolicy::DataRetention dataRetentionPolicy ); /** diff --git a/dali/internal/event/actors/camera-actor-impl.cpp b/dali/internal/event/actors/camera-actor-impl.cpp index 032855ccb..60def8806 100644 --- a/dali/internal/event/actors/camera-actor-impl.cpp +++ b/dali/internal/event/actors/camera-actor-impl.cpp @@ -360,6 +360,38 @@ bool CameraActor::GetInvertYAxis() const return mInvertYAxis; } + +void CameraActor::SetFrustum( float left, float right, float bottom, float top, float near, float far, float eyePosBias ) +{ + Matrix result; + float a = (right + left)/(right-left); + float b = (top+bottom)/(top-bottom); + float c = -(far+near)/(far-near); + float d = -(2*far*near)/(far-near); + float e = - (2*near)/(right-left); + float f = (2*near)/(top-bottom); + + float mat[16] = + { + e, 0, a, 0, + 0, f, b, 0, + 0, 0, c, d, + 0, 0,-1, 0 + }; + + std::copy( mat, mat+16, result.AsFloat() ); +} + +void CameraActor::SetPerspectiveProjectionFovY( float fovY, float aspect, float near, float far, const Vector2& stereoBias ) +{ + SetAspectRatio( aspect ); + SetNearClippingPlane( near ); + SetFarClippingPlane( far ); + SetFieldOfView( fovY ); + SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION); + SetStereoBiasMessage( GetEventThreadServices(), *mSceneObject, stereoBias ); +} + void CameraActor::SetPerspectiveProjection( const Size& size, const Vector2& stereoBias /* = Vector2::ZERO */ ) { float width = size.width; diff --git a/dali/internal/event/actors/camera-actor-impl.h b/dali/internal/event/actors/camera-actor-impl.h index 056945dfe..7ae50534e 100644 --- a/dali/internal/event/actors/camera-actor-impl.h +++ b/dali/internal/event/actors/camera-actor-impl.h @@ -158,6 +158,25 @@ public: */ void SetPerspectiveProjection( const Size& size, const Vector2& stereoBias = Vector2::ZERO ); + /** + * @brief SetPerspectiveProjectionFovY + * @param fovY + * @param size + * @param stereoBias + */ + void SetPerspectiveProjectionFovY( float fovY, float aspect, float near, float far, const Vector2& stereoBias ); + /** + * @brief SetFrustum + * @param left + * @param right + * @param bottom + * @param top + * @param near + * @param far + */ + void SetFrustum( float left, float right, float bottom, float top, float near, float far, float eyePosOffset = 0.0f ); + + /** * @copydoc Dali::CameraActor::SetOrthographicProjection(const Vector2& size); */ diff --git a/dali/internal/event/common/stage-impl.cpp b/dali/internal/event/common/stage-impl.cpp index fd8416bf8..1b098b56c 100644 --- a/dali/internal/event/common/stage-impl.cpp +++ b/dali/internal/event/common/stage-impl.cpp @@ -59,6 +59,49 @@ enum Eye RIGHT }; +//TODOVR: Gyroscope constraints +struct GyroEyeConstraint +{ + GyroEyeConstraint( Dali::Internal::Stage* stage ) + : stage( stage ) + { + pitch = Radian(Degree(0.0f)); + yaw = Radian(Degree(180.0f)); + roll = Radian(Degree(0.0f)); + } + + void operator()( Quaternion& current, const PropertyInputContainer& inputs ) + { + // TODO: get gyro data, update rotation + // get data from gyroscope + Dali::Integration::GyroscopeSensor* sensor( stage->GetGyroscopeSensor() ); + if( !sensor->IsEnabled() ) + { + sensor->Enable(); + current.SetEuler( Radian((pitch)), Radian((yaw)), Radian((roll)) ); + } + else + { + const int packets = 16; + Dali::Vector4 accumulated; + sensor->ReadPackets( &accumulated, packets ); + pitch = -accumulated.y; + yaw = accumulated.x; + roll = accumulated.z; + Quaternion rot; + rot.SetEuler( Radian((Degree(pitch))), Radian(Degree(yaw)), Radian(Degree(roll)) ); + current *= rot; + } + //current = Dali::Quaternion() + + } + Dali::Internal::Stage* stage; + + float pitch; + float yaw; + float roll; +}; + //TODOVR const float DEFAULT_STEREO_BASE( 10.0f ); //const float DEFAULT_STEREO_BASE( 15.0f ); @@ -366,6 +409,7 @@ void Stage::UpdateCameras() case VR: { const float pixelAspect = GetDpi().y / GetDpi().x; + float stereoBase( 0.05f ); if( mSize.width > mSize.height ) { @@ -390,35 +434,90 @@ void Stage::UpdateCameras() } else { + +#if 0 // Portrait aspect - default to VR on device. // Precalculations: const float sizeY = mSize.x * pixelAspect; const float viewPortHeight = mSize.y / 2.0f; const float cameraAspect = pixelAspect * ( sizeY / viewPortHeight ); - + const float near = 100.0f; + const float far = 5000.0f; // TODOVR: Base this off actual FoV values (EG. 96 degrees for GearVR) // Recalculate fov based on viewport size. - const float fov = std::atan( viewPortHeight / ( 2.0f * mSize.width ) ); + const float fov = Radian( Degree(60) );//std::atan( viewPortHeight / ( 2.0f * mSize.width ) ); - mStereoInfo[LEFT].camera->SetPerspectiveProjection( Size( mSize.width, sizeY ), Vector2::ZERO ); - //mStereoInfo[LEFT].camera->SetPerspectiveProjection( Size( mSize.width, sizeY ), Vector2( 0.0f, stereoBase ) ); + mStereoInfo[LEFT].camera->SetPerspectiveProjectionFovY( fov, cameraAspect, near, far, Vector2::ZERO ); mStereoInfo[LEFT].camera->SetAspectRatio( cameraAspect ); mStereoInfo[LEFT].camera->SetOrientation( -Dali::ANGLE_90, Vector3::ZAXIS ); mStereoInfo[LEFT].camera->SetFieldOfView( fov ); mStereoInfo[LEFT].renderTask.SetViewport( Viewport( 0, viewPortHeight, mSize.width, viewPortHeight ) ); - mStereoInfo[RIGHT].camera->SetPerspectiveProjection( Size( mSize.width, sizeY ), Vector2::ZERO ); - //mStereoInfo[RIGHT].camera->SetPerspectiveProjection( Size( mSize.width, sizeY ), Vector2( 0.0, -stereoBase ) ); + mStereoInfo[RIGHT].camera->SetPerspectiveProjectionFovY( fov, cameraAspect, near, far, Vector2::ZERO ); mStereoInfo[RIGHT].camera->SetAspectRatio( cameraAspect ); mStereoInfo[RIGHT].camera->SetOrientation( -Dali::ANGLE_90, Vector3::ZAXIS ); mStereoInfo[RIGHT].camera->SetFieldOfView( fov ); mStereoInfo[RIGHT].renderTask.SetViewport( Viewport( 0, 0, mSize.width, viewPortHeight ) ); + + mDefaultCamera->SetPosition( 0.0f, 100.0f ); +#endif + + // Portrait aspect - default to VR on device. + // Precalculations: + const float sizeY = mSize.x * pixelAspect; + const float viewPortHeight = mSize.y / 2.0f; + const float cameraAspect = pixelAspect * ( sizeY / viewPortHeight ); + + // TODOVR: Base this off actual FoV values (EG. 96 degrees for GearVR) + // Recalculate fov based on viewport size. + float fov = std::atan( viewPortHeight / ( 2.0f * mSize.width ) ); + const float far = 300.0f; + float IPD = 0.0635f; + stereoBase = -IPD*0.5f; + const float near = IPD+0.1f; + //stereoBase = 0.0f; + fov = Radian( Degree(106) ); + mStereoInfo[LEFT].camera->SetPerspectiveProjectionFovY( fov, cameraAspect, near, far, Vector2( 0.0f, +stereoBase ) ); + //mStereoInfo[LEFT].camera->SetPerspectiveProjection( Size( mSize.width, sizeY ), Vector2::ZERO ); + //mStereoInfo[LEFT].camera->SetPerspectiveProjection( Size( mSize.width, sizeY ), Vector2( 0.0f, stereoBase ) ); + //mStereoInfo[LEFT].camera->SetAspectRatio( cameraAspect ); + //mStereoInfo[LEFT].camera->SetOrientation( -Dali::ANGLE_90, Vector3::ZAXIS ); + //mStereoInfo[LEFT].camera->SetFieldOfView( fov ); + mStereoInfo[LEFT].renderTask.SetViewport( Viewport( 0, viewPortHeight, mSize.width, viewPortHeight ) ); + + //mStereoInfo[RIGHT].camera->SetPerspectiveProjection( Size( mSize.width, sizeY ), Vector2::ZERO ); + //mStereoInfo[RIGHT].camera->SetPerspectiveProjection( Size( mSize.width, sizeY ), Vector2( 0.0, -stereoBase ) ); + mStereoInfo[RIGHT].camera->SetPerspectiveProjectionFovY( fov, cameraAspect, near, far, Vector2( 0.0f, -stereoBase ) ); + //mStereoInfo[RIGHT].camera->SetAspectRatio( cameraAspect ); + //mStereoInfo[RIGHT].camera->SetOrientation( -Dali::ANGLE_90, Vector3::ZAXIS ); + //mStereoInfo[RIGHT].camera->SetFieldOfView( fov ); + mStereoInfo[RIGHT].renderTask.SetViewport( Viewport( 0, 0, mSize.width, viewPortHeight ) ); + } + // VR camera will be feed from gyroscope input, for now using constraints + // Camera needs to check gyroscope state every update, simple constraint will + // solve the problem, however we need to keep that 'fake' update running, so that + // there's 'infinite' animation running. This way we are able to hit the constraint + // every frame and update orientation. + mVRGyroEyeConstraint = Constraint::New( mDefaultCamera.Get(), + Dali::Actor::Property::ORIENTATION, + GyroEyeConstraint( this )); + mVRGyroEyeConstraint.Apply(); + Dali::Actor actor( mDefaultCamera.Get() ); + Quaternion quaternion( Radian(Degree(0)), Vector3( 0.0f, 0.0f, 0.0f )); + mVRDefaultCameraAnimation = Dali::Animation::New( 1.0f ); + mVRDefaultCameraAnimation.AnimateBy( Property( actor, Dali::Actor::Property::ORIENTATION ), quaternion, AlphaFunction::LINEAR ); + mVRDefaultCameraAnimation.SetLooping( true ); + mVRDefaultCameraAnimation.Play(); + + mStereoInfo[LEFT].camera->SetType( Camera::FREE_LOOK ); + mStereoInfo[RIGHT].camera->SetType( Camera::FREE_LOOK ); + //mDefaultCamera->SetType( Camera::VIRTUAL_REALITY ); // Same settings regardless of orientation: - const float stereoBase( ( ( mStereoBase / 25.4f ) * GetDpi().y ) * 0.5f ); - mStereoInfo[LEFT].camera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) ); - mStereoInfo[RIGHT].camera->SetPosition( Vector3( -stereoBase, 0.0f, 0.0f ) ); + //stereoBase = 0; + mStereoInfo[LEFT].camera->SetPosition( Vector3( 0.0f, -stereoBase, 0.0f ) ); + mStereoInfo[RIGHT].camera->SetPosition( Vector3( 0.f, +stereoBase, 0.0f ) ); break; } diff --git a/dali/internal/event/common/stage-impl.h b/dali/internal/event/common/stage-impl.h index 7e469eb27..c36fc7529 100644 --- a/dali/internal/event/common/stage-impl.h +++ b/dali/internal/event/common/stage-impl.h @@ -35,6 +35,9 @@ #include #include #include +#include + +#include namespace Dali { @@ -44,6 +47,7 @@ struct Vector2; namespace Integration { class SystemOverlay; +class GyroscopeSensor; } namespace Internal @@ -425,6 +429,19 @@ public: // Implementation of EventThreadServices */ virtual BufferIndex GetEventBufferIndex() const; +public: + + // VR + void SetGyroscopeSensor( Dali::Integration::GyroscopeSensor* sensor ) + { + mGyroscopeSensor = sensor; + } + + Dali::Integration::GyroscopeSensor* GetGyroscopeSensor() + { + return mGyroscopeSensor; + } + private: /** @@ -482,6 +499,7 @@ private: // The list of render-tasks IntrusivePtr mRenderTaskList; + Dali::Integration::GyroscopeSensor* mGyroscopeSensor; //TODOVR struct StereoInfo @@ -510,6 +528,10 @@ private: Dali::Stage::ContextStatusSignal mContextRegainedSignal; Dali::Stage::SceneCreatedSignalType mSceneCreatedSignal; + + //VR + Constraint mVRGyroEyeConstraint; + Dali::Animation mVRDefaultCameraAnimation; /// To keep camera update running and keep hitting constraint }; } // namespace Internal diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index d2bfa042c..0494ce067 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -813,6 +813,7 @@ inline void Orthographic(Matrix& result, float left, float right, float bottom, m[15] = 1.0f; } +/* void LookAt(Matrix& result, const Vector3& eye, const Vector3& target, const Vector3& up) { Vector3 vZ = target - eye; @@ -826,7 +827,7 @@ void LookAt(Matrix& result, const Vector3& eye, const Vector3& target, const Vec result.SetInverseTransformComponents(vX, vY, vZ, eye); } - +*/ } void RenderManager::SetupVRMode() @@ -845,8 +846,8 @@ void RenderManager::SetupVRMode() mImpl->defaultSurfaceRect.width, mImpl->defaultSurfaceRect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 ) ); - GL( ctx.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ) ); - GL( ctx.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ) ); + GL( ctx.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) ); + GL( ctx.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) ); GL( ctx.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, vr.mainFrameBufferAttachments[0], 0 ) ); // depth/stencil attachment @@ -886,7 +887,9 @@ void RenderManager::SetupVRMode() " vec3 pos = aPosition;\n" //" pos.y -= 1.0;\n" " gl_Position = mvp * vec4( pos, 1.0 );\n" - " vTexCoord = aTexCoord;\n" + " mediump vec2 uvs = vec2( aTexCoord );\n" +// " uvs.r = 1.0 - uvs.r;\n" + " vTexCoord = uvs;\n" "}\n\0", // fragment shader @@ -896,9 +899,13 @@ void RenderManager::SetupVRMode() "void main()\n" "{ \n" #ifdef DEBUG_DISABLE_BARREL_DISTORTION +#ifdef DEBUG_VR_TINT_EACH_EYE " mediump vec4 mulcol = vec4( 1.0, 0.0, 0.0, 1.0 );\n" " if( vTexCoord.y < 0.5 ) { mulcol = vec4( 0.0, 1.0, 0.0, 1.0 ); }\n" " gl_FragColor = texture2D( texSampler, vTexCoord ) * mulcol;\n" +#else + " gl_FragColor = texture2D( texSampler, vTexCoord );\n" +#endif #else " gl_FragColor = texture2D( texSampler, vTexCoord );\n" #endif @@ -964,7 +971,11 @@ void RenderManager::SetupVRMode() // mvp Matrix proj, view; - Orthographic( proj, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, false ); + + //float asp = (float)mImpl->defaultSurfaceRect.height / (float)mImpl->defaultSurfaceRect.width; + + float shift = 0.016f; + Orthographic( proj, -1.0f, 1.0f, 1.0f+shift, -1.0f+shift, -1.0f, 1.0f, false ); //LookAt( view, Vector3( 0.0f, 0.0f, 0.0f ), Vector3( 0.0f, 0.0f, 1.0f ), Vector3( 0.0f, 1.0f, 0.0f ) ); //mat.SetTranslation( Vector3(0.0f, 0.0f, 1.0f ) ); Matrix::Multiply( vr.MVP, view, proj ); @@ -982,9 +993,13 @@ void RenderManager::RenderVR() Integration::GlAbstraction& gl = ctx.GetAbstraction(); GL( ctx.BindFramebuffer( GL_FRAMEBUFFER, 0 ) ); gl.Viewport( 0, 0, mImpl->defaultSurfaceRect.width, mImpl->defaultSurfaceRect.height ); - //gl.Disable( GL_SCISSOR_TEST ); + ctx.Scissor( 0, 0, mImpl->defaultSurfaceRect.width, mImpl->defaultSurfaceRect.height ); + //DALI_LOG_ERROR("VR: %d, %d\n", (int) mImpl->defaultSurfaceRect.width, (int) mImpl->defaultSurfaceRect.height); + + gl.Disable( GL_SCISSOR_TEST ); //gl.Disable( GL_DEPTH_TEST ); - //gl.ClearColor( 0.0f, f, 0.0f, 1.0f ); + gl.ClearColor( 1.0f, 0.0f, 0.0f, 1.0f ); + //gl.Clear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); f -= 0.2f; if( f < 0 ) f = 1.0f; @@ -1019,6 +1034,7 @@ void RenderManager::RenderVR() GL( gl.DrawArrays( GL_TRIANGLES, 0, 6 ) ); #else GL( gl.DrawElements( GL_TRIANGLES, vr.indicesCount, GL_UNSIGNED_SHORT, 0 ) ); + #endif if( program ) diff --git a/dali/internal/render/common/renderer-vr.h b/dali/internal/render/common/renderer-vr.h index e82db6bf7..f1f10f728 100644 --- a/dali/internal/render/common/renderer-vr.h +++ b/dali/internal/render/common/renderer-vr.h @@ -462,36 +462,44 @@ inline void GenerateGridVertexBuffer( std::vector& vertexBuffer ) std::copy( gridVertices, gridVertices+N, vertexBuffer.data() ); std::copy( gridVertices, gridVertices+N, vertexBuffer.data()+N ); + const float eyeseparation = 0.0f;//0.05f; + + float scale = 1.0f; // Process data for both eyes for( size_t i = 0; i < N; i += 5 ) { float* co = &vertexBuffer[i]; float* uv = &vertexBuffer[i+3]; - #ifdef DEBUG_USE_HORIZONTAL_GEOMETRY co[0] *= 0.5f; co[0] -= 0.5f; uv[0] *= 0.5f; #else - co[1] -= 1.0f; co[1] *= 0.5f; + co[0] *= scale; + co[1] *= scale; + co[1] -= 0.5f; uv[1] *= 0.5f; #endif + co[1] -= eyeseparation; } for( size_t i = N; i < N*2; i += 5 ) { float* co = &vertexBuffer[i]; float* uv = &vertexBuffer[i+3]; - #ifdef DEBUG_USE_HORIZONTAL_GEOMETRY co[0] *= 0.5f; co[0] += 0.5f; uv[0] *= 0.5f; #else - co[1] += 1.0f; + co[1] *= -1.0f; co[1] *= 0.5f; + co[0] *= scale; + co[1] *= scale; + co[1] += 0.5f; uv[1] += 1.0f; + uv[1] = 1.0f - uv[1]; uv[1] *= 0.5f; #endif } diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index ee790398f..fade246b7 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -67,6 +68,8 @@ #include #include +#include + // Un-comment to enable node tree debug logging //#define NODE_TREE_LOGGING 1 @@ -160,7 +163,8 @@ struct UpdateManager::Impl previousUpdateScene( false ), frameCounter( 0 ), renderSortingHelper(), - renderTaskWaiting( false ) + renderTaskWaiting( false ), + gyroscopeSensor( NULL ) { sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue ); @@ -272,6 +276,8 @@ struct UpdateManager::Impl GestureContainer gestures; ///< A container of owned gesture detectors bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered + + GyroscopeSensor* gyroscopeSensor; }; UpdateManager::UpdateManager( NotificationManager& notificationManager, @@ -628,6 +634,11 @@ void UpdateManager::RemoveGesture( PanGesture* gesture ) DALI_ASSERT_DEBUG(false); } +void UpdateManager::SetGyroscopeSensor( Dali::Integration::GyroscopeSensor& sensor ) +{ + mImpl->gyroscopeSensor = &sensor; +} + void UpdateManager::AddTextureSet( TextureSet* textureSet ) { DALI_ASSERT_DEBUG( NULL != textureSet ); diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 7f1556347..117bef604 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -46,7 +46,7 @@ namespace Integration { class GlSyncAbstraction; class RenderController; - +class GyroscopeSensor; } // namespace Integration namespace Internal @@ -333,6 +333,10 @@ public: */ void RemoveGesture( PanGesture* gesture ); + // Sensors + + void SetGyroscopeSensor( Dali::Integration::GyroscopeSensor& sensor ); + // Message queue handling /** diff --git a/dali/internal/update/render-tasks/scene-graph-camera.cpp b/dali/internal/update/render-tasks/scene-graph-camera.cpp index c9e4b7ada..d1d60dbe8 100644 --- a/dali/internal/update/render-tasks/scene-graph-camera.cpp +++ b/dali/internal/update/render-tasks/scene-graph-camera.cpp @@ -286,20 +286,27 @@ const PropertyInputImpl* Camera::GetViewMatrix() const void Camera::Update( BufferIndex updateBufferIndex, const Node& owningNode ) { - // if owning node has changes in world position we need to update camera for next 2 frames - if( owningNode.IsLocalMatrixDirty() ) + if( mType == Dali::Camera::VIRTUAL_REALITY ) { mUpdateViewFlag = UPDATE_COUNT; + } - if( owningNode.GetDirtyFlags() & VisibleFlag ) + else { - // If the visibility changes, the projection matrix needs to be re-calculated. - // It may happen the first time an actor is rendered it's rendered only once and becomes invisible, - // in the following update the node will be skipped leaving the projection matrix (double buffered) - // with the Identity. - mUpdateProjectionFlag = UPDATE_COUNT; + // if owning node has changes in world position we need to update camera for next 2 frames + if( owningNode.IsLocalMatrixDirty() ) + { + mUpdateViewFlag = UPDATE_COUNT; + } + if( owningNode.GetDirtyFlags() & VisibleFlag ) + { + // If the visibility changes, the projection matrix needs to be re-calculated. + // It may happen the first time an actor is rendered it's rendered only once and becomes invisible, + // in the following update the node will be skipped leaving the projection matrix (double buffered) + // with the Identity. + mUpdateProjectionFlag = UPDATE_COUNT; + } } - // if either matrix changed, we need to recalculate the inverse matrix for hit testing to work unsigned int viewUpdateCount = UpdateViewMatrix( updateBufferIndex, owningNode ); unsigned int projectionUpdateCount = UpdateProjection( updateBufferIndex ); @@ -344,6 +351,7 @@ unsigned int Camera::UpdateViewMatrix( BufferIndex updateBufferIndex, const Node { // camera orientation taken from node - i.e. look in abitrary, unconstrained direction case Dali::Camera::FREE_LOOK: + case Dali::Camera::VIRTUAL_REALITY: { Matrix& viewMatrix = mViewMatrix.Get( updateBufferIndex ); viewMatrix = owningNode.GetWorldMatrix( updateBufferIndex ); diff --git a/dali/public-api/actors/camera-actor.h b/dali/public-api/actors/camera-actor.h index 0c44da0eb..66464b9f3 100644 --- a/dali/public-api/actors/camera-actor.h +++ b/dali/public-api/actors/camera-actor.h @@ -46,6 +46,7 @@ enum Type { FREE_LOOK, ///< Camera orientation is taken from CameraActor @SINCE_1_0.0 LOOK_AT_TARGET, ///< Camera is oriented to always look at a target @SINCE_1_0.0 + VIRTUAL_REALITY ///< Camera uses senseors in order to maintain the orientation }; /** -- 2.34.1