VR: Gyro support, math corrections for gearvr, Dali desktop gyroscope support through... 40/84640/1
authoradam.b <adam.b@samsung.com>
Wed, 10 Aug 2016 18:05:27 +0000 (19:05 +0100)
committeradam.b <adam.b@samsung.com>
Fri, 19 Aug 2016 16:05:03 +0000 (17:05 +0100)
Change-Id: I753632660e7b65e77bd7f078aaeefa0f9cda9435

17 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-application.cpp
dali/integration-api/core.cpp
dali/integration-api/core.h
dali/integration-api/file.list
dali/integration-api/gyroscope-sensor.h [new file with mode: 0644]
dali/internal/common/core-impl.cpp
dali/internal/common/core-impl.h
dali/internal/event/actors/camera-actor-impl.cpp
dali/internal/event/actors/camera-actor-impl.h
dali/internal/event/common/stage-impl.cpp
dali/internal/event/common/stage-impl.h
dali/internal/render/common/render-manager.cpp
dali/internal/render/common/renderer-vr.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/render-tasks/scene-graph-camera.cpp
dali/public-api/actors/camera-actor.h

index f2e3cd7..ce23d85 100644 (file)
@@ -68,6 +68,7 @@ void TestApplication::Initialize()
     mGlAbstraction,
     mGlSyncAbstraction,
     mGestureManager,
+    NULL,
     mDataRetentionPolicy);
 
   mCore->ContextCreated();
index dc08bb9..5e2dd34 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/common/dali-common.h>
 #include <dali/integration-api/events/event.h>
 #include <dali/integration-api/gl-sync-abstraction.h>
+#include <dali/integration-api/gyroscope-sensor.h>
 #include <dali/internal/common/core-impl.h>
 
 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;
 }
index c99258b..90a0e3d 100644 (file)
@@ -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);
 
   /**
index 79d4f95..37ca0b4 100644 (file)
@@ -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 (file)
index 0000000..438ed62
--- /dev/null
@@ -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
index b415482..2074216 100644 (file)
@@ -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();
index d40f827..0f34230 100644 (file)
@@ -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 );
 
   /**
index 032855c..60def88 100644 (file)
@@ -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;
index 056945d..7ae5053 100644 (file)
@@ -159,6 +159,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);
    */
   void SetOrthographicProjection( const Vector2& size );
index fd8416b..1b098b5 100644 (file)
@@ -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<Quaternion>( 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;
     }
 
index 7e469eb..c36fc75 100644 (file)
@@ -35,6 +35,9 @@
 #include <dali/public-api/math/vector3.h>
 #include <dali/public-api/math/vector4.h>
 #include <dali/public-api/render-tasks/render-task.h>
+#include <dali/public-api/animation/animation.h>
+
+#include <dali/integration-api/gyroscope-sensor.h>
 
 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<RenderTaskList> 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
index d2bfa04..0494ce0 100644 (file)
@@ -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,12 +899,16 @@ 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
     "}\n\0",
   };
 
@@ -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 )
index e82db6b..f1f10f7 100644 (file)
@@ -462,36 +462,44 @@ inline void GenerateGridVertexBuffer( std::vector<float>& 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
   }
index ee79039..fade246 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <dali/integration-api/core.h>
 #include <dali/integration-api/render-controller.h>
+#include <dali/integration-api/gyroscope-sensor.h>
 #include <dali/internal/common/shader-data.h>
 #include <dali/integration-api/debug.h>
 
@@ -67,6 +68,8 @@
 #include <dali/internal/render/gl-resources/texture-cache.h>
 #include <dali/internal/render/shaders/scene-graph-shader.h>
 
+#include <cstdio>
+
 // 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 );
index 7f15563..117bef6 100644 (file)
@@ -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
 
   /**
index c9e4b7a..d1d60db 100644 (file)
@@ -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 );
index 0c44da0..66464b9 100644 (file)
@@ -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
 };
 
 /**