aboutsummaryrefslogtreecommitdiffstats
path: root/Samples/SensorBox/SensorBoxTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Samples/SensorBox/SensorBoxTest.cpp')
-rw-r--r--Samples/SensorBox/SensorBoxTest.cpp506
1 files changed, 506 insertions, 0 deletions
diff --git a/Samples/SensorBox/SensorBoxTest.cpp b/Samples/SensorBox/SensorBoxTest.cpp
new file mode 100644
index 0000000..637f235
--- /dev/null
+++ b/Samples/SensorBox/SensorBoxTest.cpp
@@ -0,0 +1,506 @@
+/************************************************************************************
+
+Filename : SensorBoxTest.h
+Content : Visual orientaion sensor test app; renders a rotating box over axes.
+Created : October 1, 2012
+Authors : Michael Antonov
+
+Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
+
+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.
+
+*************************************************************************************/
+
+#include "OVR.h"
+#include "Kernel/OVR_String.h"
+
+#include "../CommonSrc/Platform/Platform_Default.h"
+#include "../CommonSrc/Render/Render_Device.h"
+#include "../CommonSrc/Platform/Gamepad.h"
+
+using namespace OVR;
+using namespace OVR::Platform;
+using namespace OVR::Render;
+
+//-------------------------------------------------------------------------------------
+// ***** SensorBoxTest Description
+
+// This application renders an axes-colored box that rotates with sensor input. App allows
+// user to toggle views for debugging purposes by pressing F1, F2, F3 keys.
+// Application further allows running multiple sensors at once to compare sensor quality.
+//
+// The Right-handed coordinate system is defines as follows (as seen in perspective view):
+// Y - Up (colored red)
+// Z - Back (Out from screen, colored blue)
+// X - Right (green)
+// All cameras are looking at the origin.
+
+// Camera view types.
+enum ViewType
+{
+ View_Perspective,
+ View_XZ_UpY,
+ View_XY_DownZ,
+ View_Count
+};
+
+
+//-------------------------------------------------------------------------------------
+
+class InputTestApp : public Application
+{
+ RenderDevice* pRender;
+
+ Ptr<DeviceManager> pManager;
+ Ptr<HMDDevice> pHMD;
+ Ptr<SensorDevice> pSensor;
+ Ptr<SensorDevice> pSensor2;
+
+ SensorFusion SFusion;
+ SensorFusion SFusion2;
+
+ double LastUpdate;
+ ViewType CurrentView;
+
+ double LastTitleUpdate;
+
+ Matrix4f Proj;
+ Matrix4f View;
+ Scene Sc;
+ Ptr<Model> pAxes; // Model of the coordinate system
+ Ptr<Container> pBox; // Rendered box
+ Ptr<Container> pBox2; // Second model (right now just lines)
+
+ // Applies specified projection/lookAt direction to the scene.
+ void SetView(ViewType view);
+
+public:
+
+ InputTestApp();
+ ~InputTestApp();
+
+ virtual int OnStartup(int argc, const char** argv);
+ virtual void OnIdle();
+
+ virtual void OnMouseMove(int x, int y, int modifiers);
+ virtual void OnKey(KeyCode key, int chr, bool down, int modifiers);
+};
+
+InputTestApp::InputTestApp()
+ : pRender(0), CurrentView(View_Perspective),
+ LastUpdate(0), LastTitleUpdate(0), pAxes(0), pBox(0)
+{
+
+}
+
+
+/*
+void UseCase()
+{
+ using namespace OVR;
+
+ OVR::System::Init();
+
+ Ptr<DeviceManager> pManager = 0;
+ Ptr<HMDDevice> pHMD = 0;
+ Ptr<SensorDevice> pSensor = 0;
+ SensorFusion FusionResult;
+
+
+ // *** Initialization - Create the first available HMD Device
+ pManager = *DeviceManager::Create();
+ pHMD = *pManager->EnumerateDevices<HMDDevice>().CreateDevice();
+ if (!pHMD)
+ return;
+ pSensor = *pHMD->GetSensor();
+
+ // Get DisplayDeviceName, ScreenWidth/Height, etc..
+ HMDInfo hmdInfo;
+ pHMD->GetDeviceInfo(&hmdInfo);
+
+ if (pSensor)
+ FusionResult.AttachToSensor(pSensor);
+
+ // *** Per Frame
+ // Get orientation quaternion to control view
+ Quatf q = FusionResult.GetOrientation();
+
+ // Create a matrix from quaternion,
+ // where elements [0][0] through [3][3] contain rotation.
+ Matrix4f bodyFrameMatrix(q);
+
+ // Get Euler angles from quaternion, in specified axis rotation order.
+ float yaw, pitch, roll;
+ q.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch, &roll);
+
+ // *** Shutdown
+ pSensor.Clear();
+ pHMD.Clear();
+ pManager.Clear();
+
+ OVR::System::Destroy();
+}
+*/
+
+InputTestApp::~InputTestApp()
+{
+ pSensor.Clear();
+ pManager.Clear();
+
+}
+
+
+int InputTestApp::OnStartup(int argc, const char** argv)
+{
+ if (!pPlatform->SetupWindow(1200,800))
+ return 1;
+
+
+ pManager = *DeviceManager::Create();
+
+ // This initialization logic supports running two sensors at the same time.
+
+ DeviceEnumerator<SensorDevice> isensor = pManager->EnumerateDevices<SensorDevice>();
+ DeviceEnumerator<SensorDevice> oculusSensor;
+ DeviceEnumerator<SensorDevice> oculusSensor2;
+
+ while(isensor)
+ {
+ DeviceInfo di;
+ if (isensor.GetDeviceInfo(&di))
+ {
+ if (strstr(di.ProductName, "Tracker"))
+ {
+ if (!oculusSensor)
+ oculusSensor = isensor;
+ else if (!oculusSensor2)
+ oculusSensor2 = isensor;
+ }
+ }
+
+ isensor.Next();
+ }
+
+ if (oculusSensor)
+ {
+ pSensor = *oculusSensor.CreateDevice();
+
+ if (pSensor)
+ pSensor->SetRange(SensorRange(4 * 9.81f, 8 * Math<float>::Pi, 1.0f), true);
+
+ if (oculusSensor2)
+ {
+ // Second Oculus sensor, useful for comparing firmware behavior & settings.
+ pSensor2 = *oculusSensor2.CreateDevice();
+
+ if (pSensor2)
+ pSensor2->SetRange(SensorRange(4 * 9.81f, 8 * Math<float>::Pi, 1.0f), true);
+ }
+ }
+
+ oculusSensor.Clear();
+ oculusSensor2.Clear();
+
+
+ /*
+ DeviceHandle hHMD = pManager->EnumerateDevices<HMDDevice>();
+ HMDInfo hmdInfo;
+ if (hHMD)
+ {
+ hHMD.GetDeviceInfo(&hmdInfo);
+ }
+ */
+
+ if (pSensor)
+ SFusion.AttachToSensor(pSensor);
+ if (pSensor2)
+ SFusion2.AttachToSensor(pSensor2);
+
+ /*
+ // Test rotation: This give rotations clockwise (CW) while looking from
+ // origin in the direction of the axis.
+
+ Vector3f xV(1,0,0);
+ Vector3f zV(0,0,1);
+
+ Vector3f rxV = Matrix4f::RotationZ(DegreeToRad(10.0f)).Transform(xV);
+ Vector3f ryV = Matrix4f::RotationY(DegreeToRad(10.0f)).Transform(xV);
+ Vector3f rzV = Matrix4f::RotationX(DegreeToRad(10.0f)).Transform(zV);
+ */
+
+ // Report relative mouse motion (not absolute position)
+ // pPlatform->SetMouseMode(Mouse_Relative);
+
+ const char* graphics = "d3d10";
+ for (int i = 1; i < argc; i++)
+ if (!strcmp(argv[i], "-r") && i < argc-1)
+ graphics = argv[i+1];
+
+ pRender = pPlatform->SetupGraphics(OVR_DEFAULT_RENDER_DEVICE_SET, graphics,
+ RendererParams());
+
+ //WireframeFill = pRender->CreateSimpleFill(Fill::F_Wireframe);
+
+
+
+ // *** Rotating Box
+
+ pBox = *new Container;
+ pBox->Add(Ptr<Model>(
+ *Model::CreateAxisFaceColorBox(-2.0f, 2.0f, Color(0, 0xAA, 0), // x = green
+ -1.0f, 1.0f, Color(0xAA,0, 0), // y = red
+ -1.0f, 1.0f, Color(0, 0, 0xAA)) )); // z = blue
+ // Drop-down line from box, to make it easier to see differences in angle.
+ Ptr<Model> downLine = *new Model(Prim_Lines);
+ downLine->AddLine(Vertex(0.0f,-4.5f, 0.0f, 0xFFE0B0B0),
+ Vertex(0.0f, 0.0f, 0.0f, 0xFFE0B0B0));
+ pBox->Add(downLine);
+ Sc.World.Add(pBox);
+
+
+ // Secondary rotating coordinate object, if we have two values.
+ if (pSensor2)
+ {
+ pBox2 = *new Container;
+
+ // Drop-down line from box, to make it easier to see differences in angle.
+ Ptr<Model> lines = *new Model(Prim_Lines);
+ lines->AddLine(Vertex( 0.0f,-4.0f, 0.0f, 0xFFA07070), // -Y
+ Vertex( 0.0f, 0.0f, 0.0f, 0xFFA07070));
+ lines->AddLine(Vertex(-4.0f, 0.0f, 0.0f, 0xFF70A070), // -X
+ Vertex( 0.0f, 0.0f, 0.0f, 0xFF70A070));
+ lines->AddLine(Vertex( 0.0f, 0.0f,-4.0f, 0xFF7070A0), // -Z
+ Vertex( 0.0f, 0.0f, 0.0f, 0xFF7070A0));
+ pBox2->Add(lines);
+ Sc.World.Add(pBox2);
+ }
+
+
+ // *** World axis X,Y,Z rendering.
+
+ pAxes = *new Model(Prim_Lines);
+ pAxes->AddLine(Vertex(-8.0f, 0.0f, 0.0f, 0xFF40FF40),
+ Vertex( 8.0f, 0.0f, 0.0f, 0xFF40FF40)); // X
+ pAxes->AddLine(Vertex( 7.6f, 0.4f, 0.4f, 0xFF40FF40),
+ Vertex( 8.0f, 0.0f, 0.0f, 0xFF40FF40)); // X - arrow
+ pAxes->AddLine(Vertex( 7.6f,-0.4f,-0.4f, 0xFF40FF40),
+ Vertex( 8.0f, 0.0f, 0.0f, 0xFF40FF40)); // X - arrow
+
+ pAxes->AddLine(Vertex( 0.0f,-8.0f, 0.0f, 0xFFFF4040),
+ Vertex( 0.0f, 8.0f, 0.0f, 0xFFFF4040)); // Y
+ pAxes->AddLine(Vertex( 0.4f, 7.6f, 0.0f, 0xFFFF4040),
+ Vertex( 0.0f, 8.0f, 0.0f, 0xFFFF4040)); // Y - arrow
+ pAxes->AddLine(Vertex(-0.4f, 7.6f, 0.0f, 0xFFFF4040),
+ Vertex( 0.0f, 8.0f, 0.0f, 0xFFFF4040)); // Y
+
+ pAxes->AddLine(Vertex( 0.0f, 0.0f,-8.0f, 0xFF4040FF),
+ Vertex( 0.0f, 0.0f, 8.0f, 0xFF4040FF)); // Z
+ pAxes->AddLine(Vertex( 0.4f, 0.0f, 7.6f, 0xFF4040FF),
+ Vertex( 0.0f, 0.0f, 8.0f, 0xFF4040FF)); // Z - arrow
+ pAxes->AddLine(Vertex(-0.4f, 0.0f, 7.6f, 0xFF4040FF),
+ Vertex( 0.0f, 0.0f, 8.0f, 0xFF4040FF)); // Z - arrow
+ Sc.World.Add(pAxes);
+
+
+ SetView(CurrentView);
+
+
+ LastUpdate = pPlatform->GetAppTime();
+ return 0;
+}
+
+void InputTestApp::SetView(ViewType type)
+{
+ switch(type)
+ {
+ case View_Perspective:
+ View = Matrix4f::LookAtRH(Vector3f(5.0f, 4.0f, 10.0f), // eye
+ Vector3f(0.0f, 1.5f, 0.0f), // at
+ Vector3f(0.0f, 1.0f, 0.0f));
+ break;
+
+ case View_XY_DownZ: // F2
+ View = Matrix4f::LookAtRH(Vector3f(0.0f, 0.0f, 10.0f), // eye
+ Vector3f(0.0f, 0.0f, 0.0f), // at
+ Vector3f(0.0f, 1.0f, 0.0f));
+ break;
+
+ case View_XZ_UpY:
+ View = Matrix4f::LookAtRH(Vector3f(0.0f,-10.0f, 0.0f), // eye
+ Vector3f(0.0f, 0.0f, 0.0f), // at
+ Vector3f(0.0f, 0.0f, 1.0f));
+
+ break;
+ default:
+ break;
+ }
+
+ Proj = Matrix4f::PerspectiveRH(DegreeToRad(70.0f), 1280 / (float)800,
+ 0.3f, 1000.0f); // LH
+}
+
+
+void InputTestApp::OnMouseMove(int x, int y, int modifiers)
+{
+ OVR_UNUSED3(x, y, modifiers);
+}
+
+
+static float CalcDownAngleDegrees(Quatf q)
+{
+ Vector3f downVector(0.0f, -1.0f, 0.0f);
+ Vector3f val= q.Rotate(downVector);
+ return RadToDegree(downVector.Angle(val));
+}
+
+void InputTestApp::OnKey(KeyCode key, int chr, bool down, int modifiers)
+{
+ OVR_UNUSED2(chr, modifiers);
+
+ switch (key)
+ {
+ case Key_Q:
+ if (!down)
+ pPlatform->Exit(0);
+ break;
+
+ case Key_F1:
+ CurrentView = View_Perspective;
+ SetView(CurrentView);
+ //UpdateWindowTitle();
+ break;
+ case Key_F2:
+ CurrentView = View_XY_DownZ;
+ SetView(CurrentView);
+ break;
+ case Key_F3:
+ CurrentView = View_XZ_UpY;
+ SetView(CurrentView);
+ break;
+
+ case Key_R:
+ if (down)
+ {
+ SFusion.Reset();
+ SFusion2.Reset();
+ }
+ break;
+
+ case Key_H:
+ if (down && pSensor)
+ {
+ SensorDevice::CoordinateFrame coord = pSensor->GetCoordinateFrame();
+ pSensor->SetCoordinateFrame(
+ (coord == SensorDevice::Coord_Sensor) ?
+ SensorDevice::Coord_HMD : SensorDevice::Coord_Sensor);
+ SFusion.Reset();
+ SFusion2.Reset();
+ }
+ break;
+
+ case Key_G:
+ if (down)
+ {
+ SFusion.SetGravityEnabled(!SFusion.IsGravityEnabled());
+ SFusion2.SetGravityEnabled(SFusion.IsGravityEnabled());
+ }
+ break;
+
+ case Key_A:
+
+ if (down)
+ {
+ if (!pSensor2)
+ {
+ LogText("Angle: %2.3f\n", CalcDownAngleDegrees(SFusion.GetOrientation()));
+ }
+ else
+ {
+ LogText("Angle: %2.3f Secondary Sensor Angle: %2.3f\n",
+ CalcDownAngleDegrees(SFusion.GetOrientation()),
+ CalcDownAngleDegrees(SFusion2.GetOrientation()));
+ }
+ }
+ break;
+
+ /*
+ case Key_End:
+ if (!down)
+ {
+ OriAdjust = OriSensor.Conj();
+ Sc.ViewPoint.SetOrientation(Quatf());
+ }
+ break; */
+ default:
+ break;
+ }
+}
+
+void InputTestApp::OnIdle()
+{
+ double curtime = pPlatform->GetAppTime();
+ // float dt = float(LastUpdate - curtime);
+ LastUpdate = curtime;
+
+ if (pBox)
+ {
+ Quatf q = SFusion.GetOrientation();
+ pBox->SetOrientation(q);
+
+ // Test Euler conversion, alternative to the above:
+ // Vector3f euler;
+ // SFusion.GetOrientation().GetEulerABC<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&euler.y, &euler.x, &euler.z);
+ // Matrix4f mat = Matrix4f::RotationY(euler.y) * Matrix4f::RotationX(euler.x) * Matrix4f::RotationZ(euler.z);
+ // pBox->SetMatrix(mat);
+
+ // Update titlebar every 20th of a second.
+ if ((curtime - LastTitleUpdate) > 0.05f)
+ {
+ char titleBuffer[512];
+ SensorDevice::CoordinateFrame coord = SensorDevice::Coord_Sensor;
+ if (pSensor)
+ coord = pSensor->GetCoordinateFrame();
+
+ OVR_sprintf(titleBuffer, 512, "OVR SensorBox %s %s Ang: %0.3f",
+ (SFusion.IsGravityEnabled() ? "" : "[Grav Off]"),
+ (coord == SensorDevice::Coord_HMD) ? "[HMD Coord]" : "",
+ CalcDownAngleDegrees(q));
+ pPlatform->SetWindowTitle(titleBuffer);
+ LastTitleUpdate = curtime;
+ }
+ }
+
+ if (pBox2)
+ {
+ pBox2->SetOrientation(SFusion2.GetOrientation());
+ }
+
+ // Render
+ int w, h;
+ pPlatform->GetWindowSize(&w, &h);
+
+ pRender->SetViewport(0, 0, w, h);
+
+ pRender->Clear();
+ pRender->BeginScene();
+
+ pRender->SetProjection(Proj);
+ pRender->SetDepthMode(1,1);
+
+ Sc.Render(pRender, View);
+
+ pRender->Present();
+
+}
+
+OVR_PLATFORM_APP(InputTestApp);