From 2bae0c340ea257d9ff323978ae6dea3ac59a517a Mon Sep 17 00:00:00 2001 From: lrz <lrz@lrzs-MacBook-Pro.local> Date: Thu, 5 Apr 2018 08:21:31 -0700 Subject: [PATCH] Early draft for Google Cardboard on IOS. --- GoogleCardboard/aux.cpp | 75 ++ GoogleCardboard/aux.h | 6 + .../NOMADgvrT/src/main/jni/.DS_Store | Bin 0 -> 6148 bytes .../src/main/jni/treasure_hunt_renderer.cc | 110 +-- GoogleCardboardIOS/NOMADVRSDK-Info.plist | 52 ++ .../NOMADVRSDK.xcodeproj/project.pbxproj | 529 ++++++++++++ .../contents.xcworkspacedata | 7 + .../UserInterfaceState.xcuserstate | Bin 0 -> 15721 bytes .../xcschemes/TreasureHuntNDK.xcscheme | 91 ++ .../xcschemes/xcschememanagement.plist | 22 + .../contents.xcworkspacedata | 10 + GoogleCardboardIOS/Podfile | 15 + GoogleCardboardIOS/Podfile.lock | 26 + GoogleCardboardIOS/TreasureHuntAppDelegate.h | 21 + GoogleCardboardIOS/TreasureHuntAppDelegate.m | 55 ++ .../contents.xcworkspacedata | 10 + .../UserInterfaceState.xcuserstate | Bin 0 -> 56027 bytes .../xcdebugger/Breakpoints_v2.xcbkptlist | 311 +++++++ .../TreasureHuntViewController.h | 21 + .../TreasureHuntViewController.mm | 125 +++ GoogleCardboardIOS/launch.xib | 35 + GoogleCardboardIOS/main.m | 23 + GoogleCardboardIOS/treasure_hunt_renderer.h | 155 ++++ GoogleCardboardIOS/treasure_hunt_renderer.mm | 800 ++++++++++++++++++ 24 files changed, 2391 insertions(+), 108 deletions(-) create mode 100644 GoogleCardboard/aux.cpp create mode 100644 GoogleCardboard/aux.h create mode 100644 GoogleCardboardAndroid/NOMADgvrT/src/main/jni/.DS_Store create mode 100644 GoogleCardboardIOS/NOMADVRSDK-Info.plist create mode 100644 GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.pbxproj create mode 100644 GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.xcworkspace/xcuserdata/lrz.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 GoogleCardboardIOS/NOMADVRSDK.xcodeproj/xcuserdata/lrz.xcuserdatad/xcschemes/TreasureHuntNDK.xcscheme create mode 100644 GoogleCardboardIOS/NOMADVRSDK.xcodeproj/xcuserdata/lrz.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 GoogleCardboardIOS/NOMADVRSDK.xcworkspace/contents.xcworkspacedata create mode 100644 GoogleCardboardIOS/Podfile create mode 100644 GoogleCardboardIOS/Podfile.lock create mode 100644 GoogleCardboardIOS/TreasureHuntAppDelegate.h create mode 100644 GoogleCardboardIOS/TreasureHuntAppDelegate.m create mode 100644 GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/contents.xcworkspacedata create mode 100644 GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/xcuserdata/lrz.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/xcuserdata/lrz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 GoogleCardboardIOS/TreasureHuntViewController.h create mode 100644 GoogleCardboardIOS/TreasureHuntViewController.mm create mode 100644 GoogleCardboardIOS/launch.xib create mode 100644 GoogleCardboardIOS/main.m create mode 100644 GoogleCardboardIOS/treasure_hunt_renderer.h create mode 100644 GoogleCardboardIOS/treasure_hunt_renderer.mm diff --git a/GoogleCardboard/aux.cpp b/GoogleCardboard/aux.cpp new file mode 100644 index 0000000..ed68904 --- /dev/null +++ b/GoogleCardboard/aux.cpp @@ -0,0 +1,75 @@ + + +#include "aux.h" + +float getCofactor(float m0, float m1, float m2, + float m3, float m4, float m5, + float m6, float m7, float m8) +{ + return m0 * (m4 * m8 - m5 * m7) - + m1 * (m3 * m8 - m5 * m6) + + m2 * (m3 * m7 - m4 * m6); +} + +//adapted from +//openvr-0.9.19\samples\shared\matrices.cpp +static gvr::Mat4f invert (const gvr::Mat4f& m) +{ + gvr::Mat4f r; + // get cofactors of minor matrices + float cofactor0 = getCofactor(m.m[1][1],m.m[1][2],m.m[1][3], m.m[2][1],m.m[2][2],m.m[2][3], m.m[3][1],m.m[3][2],m.m[3][3]); + float cofactor1 = getCofactor(m.m[1][0],m.m[1][2],m.m[1][3], m.m[2][0],m.m[2][2],m.m[2][3], m.m[3][0],m.m[3][2],m.m[3][3]); + float cofactor2 = getCofactor(m.m[1][0],m.m[1][1],m.m[1][3], m.m[2][0],m.m[2][1], m.m[2][3], m.m[3][0],m.m[3][1],m.m[3][3]); + float cofactor3 = getCofactor(m.m[1][0],m.m[1][1],m.m[1][2], m.m[2][0],m.m[2][1], m.m[2][2], m.m[3][0],m.m[3][1],m.m[3][2]); + + // get determinant + float determinant = m.m[0][0] * cofactor0 - m.m[0][1] * cofactor1 + m.m[0][2] * cofactor2 - m.m[0][3] * cofactor3; + + if(fabs(determinant) <= EPSILON) + { + for (int i=0;i<4;i++) + for (int j=0;j<4;j++) + r.m[i][j]=i==j; + return r; + } + + // get rest of cofactors for adj(M) + float cofactor4 = getCofactor(m.m[0][1],m.m[0][2],m.m[0][3], m.m[2][1],m.m[2][2],m.m[2][3], m.m[3][1],m.m[3][2],m.m[3][3]); + float cofactor5 = getCofactor(m.m[0][0],m.m[0][2],m.m[0][3], m.m[2][0],m.m[2][2],m.m[2][3], m.m[3][0],m.m[3][2],m.m[3][3]); + float cofactor6 = getCofactor(m.m[0][0],m.m[0][1],m.m[0][3], m.m[2][0],m.m[2][1], m.m[2][3], m.m[3][0],m.m[3][1],m.m[3][3]); + float cofactor7 = getCofactor(m.m[0][0],m.m[0][1],m.m[0][2], m.m[2][0],m.m[2][1], m.m[2][2], m.m[3][0],m.m[3][1],m.m[3][2]); + + float cofactor8 = getCofactor(m.m[0][1],m.m[0][2],m.m[0][3], m.m[1][1],m.m[1][2], m.m[1][3], m.m[3][1],m.m[3][2],m.m[3][3]); + float cofactor9 = getCofactor(m.m[0][0],m.m[0][2],m.m[0][3], m.m[1][0],m.m[1][2], m.m[1][3], m.m[3][0],m.m[3][2],m.m[3][3]); + float cofactor10= getCofactor(m.m[0][0],m.m[0][1],m.m[0][3], m.m[1][0],m.m[1][1], m.m[1][3], m.m[3][0],m.m[3][1],m.m[3][3]); + float cofactor11= getCofactor(m.m[0][0],m.m[0][1],m.m[0][2], m.m[1][0],m.m[1][1], m.m[1][2], m.m[3][0],m.m[3][1],m.m[3][2]); + + float cofactor12= getCofactor(m.m[0][1],m.m[0][2],m.m[0][3], m.m[1][1],m.m[1][2], m.m[1][3], m.m[2][1], m.m[2][2],m.m[2][3]); + float cofactor13= getCofactor(m.m[0][0],m.m[0][2],m.m[0][3], m.m[1][0],m.m[1][2], m.m[1][3], m.m[2][0], m.m[2][2],m.m[2][3]); + float cofactor14= getCofactor(m.m[0][0],m.m[0][1],m.m[0][3], m.m[1][0],m.m[1][1], m.m[1][3], m.m[2][0], m.m[2][1], m.m[2][3]); + float cofactor15= getCofactor(m.m[0][0],m.m[0][1],m.m[0][2], m.m[1][0],m.m[1][1], m.m[1][2], m.m[2][0], m.m[2][1], m.m[2][2]); + + // build inverse matrix = adj(M) / det(M) + // adjugate of M is the transpose of the cofactor matrix of M + float invDeterminant = 1.0f / determinant; + r.m[0][0] = invDeterminant * cofactor0; + r.m[0][1] = -invDeterminant * cofactor4; + r.m[0][2] = invDeterminant * cofactor8; + r.m[0][3] = -invDeterminant * cofactor12; + + r.m[1][0] = -invDeterminant * cofactor1; + r.m[1][1] = invDeterminant * cofactor5; + r.m[1][2] = -invDeterminant * cofactor9; + r.m[1][3] = invDeterminant * cofactor13; + + r.m[2][0] = invDeterminant * cofactor2; + r.m[2][1] = -invDeterminant * cofactor6; + r.m[2][2]= invDeterminant * cofactor10; + r.m[2][3]= -invDeterminant * cofactor14; + + r.m[3][0]= -invDeterminant * cofactor3; + r.m[3][1]= invDeterminant * cofactor7; + r.m[3][2]= -invDeterminant * cofactor11; + r.m[3][3]= invDeterminant * cofactor15; + return r; +} diff --git a/GoogleCardboard/aux.h b/GoogleCardboard/aux.h new file mode 100644 index 0000000..9f432f6 --- /dev/null +++ b/GoogleCardboard/aux.h @@ -0,0 +1,6 @@ +float getCofactor(float m0, float m1, float m2, + float m3, float m4, float m5, + float m6, float m7, float m8); + +static gvr::Mat4f invert (const gvr::Mat4f& m); + diff --git a/GoogleCardboardAndroid/NOMADgvrT/src/main/jni/.DS_Store b/GoogleCardboardAndroid/NOMADgvrT/src/main/jni/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..4280a71137333445c5bbc44bafb26ed43627cab7 GIT binary patch literal 6148 zcmeHKO-lno41HrO6uk7{p~pFT68r~CX$xNU2UNQiS}845_rCwUzBh^D;^Ij}B!T2* zGLy{ggPjimY1*uBfH8m(RhZ=Th{C;HXFgb%N{tsZIN}LQY<dd)#gNv1iPy5~M|@s? zgFWL*JQKILMveM*cc@pp!-_c~Y(c%E4o)XpVDfDp@v_I7R^E{nH{E*ajx|*8-0P`k zNH7o#1Ovf9F!0k1@XVHsE)2s41HnKr@WFughfEb#j;&$YI%sr#R{u~ap|7j4FgsR` zts#3T$x?}yn*528ES>S}<0{A2(9)60%&g-xzdv45nVs=mh9gymVS|BSpv%C(nq!^+ zbN({DkNj>*w1R<P;GZ#&hO_(Glpp11>zB{dS(~X3REfs5awzmWmjE`jk4#FZ^=J7U YS2?zZs-k#FC&opf5E3RB_yq>u0AM{TQ2+n{ literal 0 HcmV?d00001 diff --git a/GoogleCardboardAndroid/NOMADgvrT/src/main/jni/treasure_hunt_renderer.cc b/GoogleCardboardAndroid/NOMADgvrT/src/main/jni/treasure_hunt_renderer.cc index c3ed4bb..910f0b7 100644 --- a/GoogleCardboardAndroid/NOMADgvrT/src/main/jni/treasure_hunt_renderer.cc +++ b/GoogleCardboardAndroid/NOMADgvrT/src/main/jni/treasure_hunt_renderer.cc @@ -39,6 +39,8 @@ #include "NOMADVRLib/polyhedron.h" #include "NOMADVRLib/IsosurfacesGL.h" +#include "GoogleCardboard/aux.h" + #define LOG_TAG "NOMADgvrT" #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) @@ -50,7 +52,6 @@ } const char * configPath=0; -const float EPSILON = 0.00001f; void eprintf( const char *fmt, ... ) { @@ -71,41 +72,6 @@ void eprintf( const char *fmt, ... ) namespace { -gvr::Mat4f TranslationMatrix (float x, float y, float z) -{ -gvr::Mat4f mvs; -mvs.m[0][0]=1;mvs.m[0][1]=0;mvs.m[0][2]=0; mvs.m[0][3]=x; -mvs.m[1][0]=0;mvs.m[1][1]=1;mvs.m[1][2]=0;mvs.m[1][3]=y; -mvs.m[2][0]=0;mvs.m[2][1]=0;mvs.m[2][2]=1; mvs.m[2][3]=z; -mvs.m[3][0]=0;mvs.m[3][1]=0;mvs.m[3][2]=0; mvs.m[3][3]=1; -return mvs; -} - -gvr::Mat4f TranslationMatrix (float v[3]) -{ -return TranslationMatrix (v[0], v[1], v[2]); -} - -gvr::Mat4f ScalingMatrix (float x, float y, float z) -{ -gvr::Mat4f mvs; - -mvs.m[0][0]=x;mvs.m[0][1]=0;mvs.m[0][2]=0; mvs.m[0][3]=0; -mvs.m[1][0]=0;mvs.m[1][1]=y;mvs.m[1][2]=0;mvs.m[1][3]=0; -mvs.m[2][0]=0;mvs.m[2][1]=0;mvs.m[2][2]=z; mvs.m[2][3]=0; -mvs.m[3][0]=0;mvs.m[3][1]=0;mvs.m[3][2]=0; mvs.m[3][3]=1; -return mvs; -} - -gvr::Mat4f ScalingMatrix (float v[3]) -{ -return ScalingMatrix(v[0], v[1], v[2]); -} - -gvr::Mat4f ScalingMatrix (float s) -{ -return ScalingMatrix(s,s,s); -} //static const float kZNear = 1.0f; //static const float kZFar = 100.0f; @@ -117,78 +83,6 @@ static const int kCoordsPerVertex = 3; static const uint64_t kPredictionTimeWithoutVsyncNanos = 50000000; -float getCofactor(float m0, float m1, float m2, - float m3, float m4, float m5, - float m6, float m7, float m8) -{ - return m0 * (m4 * m8 - m5 * m7) - - m1 * (m3 * m8 - m5 * m6) + - m2 * (m3 * m7 - m4 * m6); -} - -//adapted from -//openvr-0.9.19\samples\shared\matrices.cpp -static gvr::Mat4f invert (const gvr::Mat4f& m) -{ -gvr::Mat4f r; - // get cofactors of minor matrices - float cofactor0 = getCofactor(m.m[1][1],m.m[1][2],m.m[1][3], m.m[2][1],m.m[2][2],m.m[2][3], m.m[3][1],m.m[3][2],m.m[3][3]); - float cofactor1 = getCofactor(m.m[1][0],m.m[1][2],m.m[1][3], m.m[2][0],m.m[2][2],m.m[2][3], m.m[3][0],m.m[3][2],m.m[3][3]); - float cofactor2 = getCofactor(m.m[1][0],m.m[1][1],m.m[1][3], m.m[2][0],m.m[2][1], m.m[2][3], m.m[3][0],m.m[3][1],m.m[3][3]); - float cofactor3 = getCofactor(m.m[1][0],m.m[1][1],m.m[1][2], m.m[2][0],m.m[2][1], m.m[2][2], m.m[3][0],m.m[3][1],m.m[3][2]); - - // get determinant - float determinant = m.m[0][0] * cofactor0 - m.m[0][1] * cofactor1 + m.m[0][2] * cofactor2 - m.m[0][3] * cofactor3; - - if(fabs(determinant) <= EPSILON) - { - for (int i=0;i<4;i++) - for (int j=0;j<4;j++) - r.m[i][j]=i==j; - return r; - } - - // get rest of cofactors for adj(M) - float cofactor4 = getCofactor(m.m[0][1],m.m[0][2],m.m[0][3], m.m[2][1],m.m[2][2],m.m[2][3], m.m[3][1],m.m[3][2],m.m[3][3]); - float cofactor5 = getCofactor(m.m[0][0],m.m[0][2],m.m[0][3], m.m[2][0],m.m[2][2],m.m[2][3], m.m[3][0],m.m[3][2],m.m[3][3]); - float cofactor6 = getCofactor(m.m[0][0],m.m[0][1],m.m[0][3], m.m[2][0],m.m[2][1], m.m[2][3], m.m[3][0],m.m[3][1],m.m[3][3]); - float cofactor7 = getCofactor(m.m[0][0],m.m[0][1],m.m[0][2], m.m[2][0],m.m[2][1], m.m[2][2], m.m[3][0],m.m[3][1],m.m[3][2]); - - float cofactor8 = getCofactor(m.m[0][1],m.m[0][2],m.m[0][3], m.m[1][1],m.m[1][2], m.m[1][3], m.m[3][1],m.m[3][2],m.m[3][3]); - float cofactor9 = getCofactor(m.m[0][0],m.m[0][2],m.m[0][3], m.m[1][0],m.m[1][2], m.m[1][3], m.m[3][0],m.m[3][2],m.m[3][3]); - float cofactor10= getCofactor(m.m[0][0],m.m[0][1],m.m[0][3], m.m[1][0],m.m[1][1], m.m[1][3], m.m[3][0],m.m[3][1],m.m[3][3]); - float cofactor11= getCofactor(m.m[0][0],m.m[0][1],m.m[0][2], m.m[1][0],m.m[1][1], m.m[1][2], m.m[3][0],m.m[3][1],m.m[3][2]); - - float cofactor12= getCofactor(m.m[0][1],m.m[0][2],m.m[0][3], m.m[1][1],m.m[1][2], m.m[1][3], m.m[2][1], m.m[2][2],m.m[2][3]); - float cofactor13= getCofactor(m.m[0][0],m.m[0][2],m.m[0][3], m.m[1][0],m.m[1][2], m.m[1][3], m.m[2][0], m.m[2][2],m.m[2][3]); - float cofactor14= getCofactor(m.m[0][0],m.m[0][1],m.m[0][3], m.m[1][0],m.m[1][1], m.m[1][3], m.m[2][0], m.m[2][1], m.m[2][3]); - float cofactor15= getCofactor(m.m[0][0],m.m[0][1],m.m[0][2], m.m[1][0],m.m[1][1], m.m[1][2], m.m[2][0], m.m[2][1], m.m[2][2]); - - // build inverse matrix = adj(M) / det(M) - // adjugate of M is the transpose of the cofactor matrix of M - float invDeterminant = 1.0f / determinant; - r.m[0][0] = invDeterminant * cofactor0; - r.m[0][1] = -invDeterminant * cofactor4; - r.m[0][2] = invDeterminant * cofactor8; - r.m[0][3] = -invDeterminant * cofactor12; - - r.m[1][0] = -invDeterminant * cofactor1; - r.m[1][1] = invDeterminant * cofactor5; - r.m[1][2] = -invDeterminant * cofactor9; - r.m[1][3] = invDeterminant * cofactor13; - - r.m[2][0] = invDeterminant * cofactor2; - r.m[2][1] = -invDeterminant * cofactor6; - r.m[2][2]= invDeterminant * cofactor10; - r.m[2][3]= -invDeterminant * cofactor14; - - r.m[3][0]= -invDeterminant * cofactor3; - r.m[3][1]= invDeterminant * cofactor7; - r.m[3][2]= -invDeterminant * cofactor11; - r.m[3][3]= invDeterminant * cofactor15; -return r; -} - static std::array<float, 16> MatrixToGLArray(const gvr::Mat4f& matrix) { // Note that this performs a *tranpose* to a column-major matrix array, as // expected by GL. diff --git a/GoogleCardboardIOS/NOMADVRSDK-Info.plist b/GoogleCardboardIOS/NOMADVRSDK-Info.plist new file mode 100644 index 0000000..a8be6a4 --- /dev/null +++ b/GoogleCardboardIOS/NOMADVRSDK-Info.plist @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>UIFileSharingEnabled</key> + <true/> + <key>UIRequiredDeviceCapabilities</key> + <array> + <string>magnetometer</string> + </array> + <key>CFBundleDisplayName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + <key>CFBundleIdentifier</key> + <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>2.1</string> + <key>CFBundleVersion</key> + <string>2.1</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>UILaunchStoryboardName</key> + <string>launch</string> + <key>UIStatusBarHidden</key> + <true/> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + <string>UIInterfaceOrientationPortraitUpsideDown</string> + </array> + <key>UISupportedInterfaceOrientations~ipad</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationPortraitUpsideDown</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> + <key>UIRequiresFullScreen</key> + <true/> + <key>NSCameraUsageDescription</key> + <string>Used to scan QR codes</string> +</dict> +</plist> diff --git a/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.pbxproj b/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.pbxproj new file mode 100644 index 0000000..71f38f8 --- /dev/null +++ b/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.pbxproj @@ -0,0 +1,529 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1278CED81CEBF98600D93A88 /* NOMADVRSDK-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1278CED71CEBF98600D93A88 /* NOMADVRSDK-Info.plist */; }; + 12BEE9C01C8F5426002F8361 /* TreasureHuntAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 12BEE9B91C8F5426002F8361 /* TreasureHuntAppDelegate.m */; }; + 12BEE9C31C8F5426002F8361 /* TreasureHuntViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 12BEE9BF1C8F5426002F8361 /* TreasureHuntViewController.mm */; }; + 12BEE9C81C8F546B002F8361 /* launch.xib in Resources */ = {isa = PBXBuildFile; fileRef = 12BEE9C61C8F546B002F8361 /* launch.xib */; }; + 12BEE9CB1C8F54B8002F8361 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 12BEE9CA1C8F54B8002F8361 /* main.m */; }; + 12C3DC8F1CEBBA9E00D39B85 /* treasure_hunt_renderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 12C3DC8C1CEBBA9E00D39B85 /* treasure_hunt_renderer.mm */; }; + 4D85FBEE2075203B008FD96D /* aux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D85FBEC2075203B008FD96D /* aux.cpp */; }; + 4DEE7BCE20629B0F00A0956C /* NOMADVRLib in Resources */ = {isa = PBXBuildFile; fileRef = 4DEE7BCD20629B0F00A0956C /* NOMADVRLib */; }; + 4DEE7BD22062A82000A0956C /* atoms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BD12062A82000A0956C /* atoms.cpp */; }; + 4DEE7BD52062A83800A0956C /* atomsGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BD32062A83800A0956C /* atomsGL.cpp */; }; + 4DEE7BDD2062AD8800A0956C /* rply.c in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BDA2062AD8800A0956C /* rply.c */; }; + 4DEE7BE12062ADCB00A0956C /* happyhttp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BDF2062ADCB00A0956C /* happyhttp.cpp */; }; + 4DEE7BE52062AE2200A0956C /* markerShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BE42062AE2200A0956C /* markerShaders.cpp */; }; + 4DEE7BE72062AE5200A0956C /* Grid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BE62062AE5200A0956C /* Grid.cpp */; }; + 4DEE7BE92062AE6D00A0956C /* ConfigFileAtoms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BE82062AE6D00A0956C /* ConfigFileAtoms.cpp */; }; + 4DEE7BEB2062AE9F00A0956C /* TessShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BEA2062AE9F00A0956C /* TessShaders.cpp */; }; + 4DEE7BED2062AEAB00A0956C /* UnitCellShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BEC2062AEAB00A0956C /* UnitCellShaders.cpp */; }; + 4DEE7BEF2062AECC00A0956C /* IsosurfacesGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BEE2062AECC00A0956C /* IsosurfacesGL.cpp */; }; + 4DEE7BF12062AED900A0956C /* ConfigFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BF02062AED900A0956C /* ConfigFile.cpp */; }; + 4DEE7BF32062B2EB00A0956C /* polyhedron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BF22062B2EB00A0956C /* polyhedron.cpp */; }; + 4DEE7BF52062B92100A0956C /* IsoShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BF42062B92100A0956C /* IsoShaders.cpp */; }; + 4DEE7BF72062BA3F00A0956C /* CompileGLShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE7BF62062BA3F00A0956C /* CompileGLShader.cpp */; }; + C99E7A8E024DA5FE8D83A5BB /* libPods-TreasureHuntNDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A4028450E1F4537A4DE358F /* libPods-TreasureHuntNDK.a */; }; + F27EE917D4C0E740BE5E6345 /* Pods_NOMADVRSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CAC7C8C2287795314AD5579A /* Pods_NOMADVRSDK.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1278CED71CEBF98600D93A88 /* NOMADVRSDK-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "NOMADVRSDK-Info.plist"; sourceTree = SOURCE_ROOT; }; + 12BEE99E1C8F53AB002F8361 /* NOMADVRSDK.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NOMADVRSDK.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 12BEE9B81C8F5426002F8361 /* TreasureHuntAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TreasureHuntAppDelegate.h; sourceTree = SOURCE_ROOT; }; + 12BEE9B91C8F5426002F8361 /* TreasureHuntAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TreasureHuntAppDelegate.m; sourceTree = SOURCE_ROOT; }; + 12BEE9BE1C8F5426002F8361 /* TreasureHuntViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TreasureHuntViewController.h; sourceTree = SOURCE_ROOT; }; + 12BEE9BF1C8F5426002F8361 /* TreasureHuntViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TreasureHuntViewController.mm; sourceTree = SOURCE_ROOT; }; + 12BEE9C61C8F546B002F8361 /* launch.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = launch.xib; sourceTree = SOURCE_ROOT; }; + 12BEE9CA1C8F54B8002F8361 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; + 12C3DC8C1CEBBA9E00D39B85 /* treasure_hunt_renderer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = treasure_hunt_renderer.mm; sourceTree = SOURCE_ROOT; }; + 12C3DC8D1CEBBA9E00D39B85 /* treasure_hunt_renderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = treasure_hunt_renderer.h; sourceTree = SOURCE_ROOT; }; + 3A4028450E1F4537A4DE358F /* libPods-TreasureHuntNDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-TreasureHuntNDK.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4D85FBEC2075203B008FD96D /* aux.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aux.cpp; sourceTree = "<group>"; }; + 4D85FBED2075203B008FD96D /* aux.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aux.h; sourceTree = "<group>"; }; + 4DEE7BCD20629B0F00A0956C /* NOMADVRLib */ = {isa = PBXFileReference; lastKnownFileType = folder; name = NOMADVRLib; path = "/Users/lrz/gvr-ios-sdk/Samples/TreasureHuntNDK/NOMADVRLib"; sourceTree = "<absolute>"; }; + 4DEE7BD12062A82000A0956C /* atoms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = atoms.cpp; path = NOMADVRLib/atoms.cpp; sourceTree = "<group>"; }; + 4DEE7BD32062A83800A0956C /* atomsGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = atomsGL.cpp; path = NOMADVRLib/atomsGL.cpp; sourceTree = "<group>"; }; + 4DEE7BDA2062AD8800A0956C /* rply.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rply.c; path = rply/rply.c; sourceTree = "<group>"; }; + 4DEE7BDB2062AD8800A0956C /* rply.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rply.h; path = rply/rply.h; sourceTree = "<group>"; }; + 4DEE7BDC2062AD8800A0956C /* rplyfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rplyfile.h; path = rply/rplyfile.h; sourceTree = "<group>"; }; + 4DEE7BDF2062ADCB00A0956C /* happyhttp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = happyhttp.cpp; sourceTree = "<group>"; }; + 4DEE7BE02062ADCB00A0956C /* happyhttp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = happyhttp.h; sourceTree = "<group>"; }; + 4DEE7BE42062AE2200A0956C /* markerShaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = markerShaders.cpp; path = NOMADVRLib/markerShaders.cpp; sourceTree = "<group>"; }; + 4DEE7BE62062AE5200A0956C /* Grid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Grid.cpp; path = NOMADVRLib/Grid.cpp; sourceTree = "<group>"; }; + 4DEE7BE82062AE6D00A0956C /* ConfigFileAtoms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConfigFileAtoms.cpp; path = NOMADVRLib/ConfigFileAtoms.cpp; sourceTree = "<group>"; }; + 4DEE7BEA2062AE9F00A0956C /* TessShaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TessShaders.cpp; path = NOMADVRLib/TessShaders.cpp; sourceTree = "<group>"; }; + 4DEE7BEC2062AEAB00A0956C /* UnitCellShaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnitCellShaders.cpp; path = NOMADVRLib/UnitCellShaders.cpp; sourceTree = "<group>"; }; + 4DEE7BEE2062AECC00A0956C /* IsosurfacesGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IsosurfacesGL.cpp; path = NOMADVRLib/IsosurfacesGL.cpp; sourceTree = "<group>"; }; + 4DEE7BF02062AED900A0956C /* ConfigFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConfigFile.cpp; path = NOMADVRLib/ConfigFile.cpp; sourceTree = "<group>"; }; + 4DEE7BF22062B2EB00A0956C /* polyhedron.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = polyhedron.cpp; path = NOMADVRLib/polyhedron.cpp; sourceTree = "<group>"; }; + 4DEE7BF42062B92100A0956C /* IsoShaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IsoShaders.cpp; path = NOMADVRLib/IsoShaders.cpp; sourceTree = "<group>"; }; + 4DEE7BF62062BA3F00A0956C /* CompileGLShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompileGLShader.cpp; path = NOMADVRLib/CompileGLShader.cpp; sourceTree = "<group>"; }; + 9FD381D5B2D35CE778ED88B3 /* Pods-NOMADVRSDK.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NOMADVRSDK.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NOMADVRSDK/Pods-NOMADVRSDK.debug.xcconfig"; sourceTree = "<group>"; }; + CAC7C8C2287795314AD5579A /* Pods_NOMADVRSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NOMADVRSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EB0170AE84675B1C851C3FA4 /* Pods-NOMADVRSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NOMADVRSDK.release.xcconfig"; path = "Pods/Target Support Files/Pods-NOMADVRSDK/Pods-NOMADVRSDK.release.xcconfig"; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 12BEE99B1C8F53AB002F8361 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C99E7A8E024DA5FE8D83A5BB /* libPods-TreasureHuntNDK.a in Frameworks */, + F27EE917D4C0E740BE5E6345 /* Pods_NOMADVRSDK.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 119687AEB1F830DBF8B32F90 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3A4028450E1F4537A4DE358F /* libPods-TreasureHuntNDK.a */, + CAC7C8C2287795314AD5579A /* Pods_NOMADVRSDK.framework */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; + 12BEE9951C8F53AB002F8361 = { + isa = PBXGroup; + children = ( + 12BEE9A01C8F53AB002F8361 /* TreasureHunt */, + 12BEE99F1C8F53AB002F8361 /* Products */, + 4DEE7BDE2062ADCB00A0956C /* happyhttp */, + 4DEE7BD92062AD5C00A0956C /* rply */, + 4D85FBEB2075203B008FD96D /* GoogleCardboard */, + 4DEE7BCF2062A33900A0956C /* NOMADVRLib */, + 119687AEB1F830DBF8B32F90 /* Frameworks */, + 2D97AF66D715451F210A5105 /* Pods */, + ); + sourceTree = "<group>"; + }; + 12BEE99F1C8F53AB002F8361 /* Products */ = { + isa = PBXGroup; + children = ( + 12BEE99E1C8F53AB002F8361 /* NOMADVRSDK.app */, + ); + name = Products; + sourceTree = "<group>"; + }; + 12BEE9A01C8F53AB002F8361 /* TreasureHunt */ = { + isa = PBXGroup; + children = ( + 12BEE9B81C8F5426002F8361 /* TreasureHuntAppDelegate.h */, + 12BEE9B91C8F5426002F8361 /* TreasureHuntAppDelegate.m */, + 12BEE9BE1C8F5426002F8361 /* TreasureHuntViewController.h */, + 12BEE9BF1C8F5426002F8361 /* TreasureHuntViewController.mm */, + 12C3DC8C1CEBBA9E00D39B85 /* treasure_hunt_renderer.mm */, + 12C3DC8D1CEBBA9E00D39B85 /* treasure_hunt_renderer.h */, + 1278CED71CEBF98600D93A88 /* NOMADVRSDK-Info.plist */, + 12BEE9C61C8F546B002F8361 /* launch.xib */, + 12BEE9A11C8F53AB002F8361 /* Supporting Files */, + ); + path = TreasureHunt; + sourceTree = "<group>"; + }; + 12BEE9A11C8F53AB002F8361 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 12BEE9CA1C8F54B8002F8361 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = "<group>"; + }; + 2D97AF66D715451F210A5105 /* Pods */ = { + isa = PBXGroup; + children = ( + 9FD381D5B2D35CE778ED88B3 /* Pods-NOMADVRSDK.debug.xcconfig */, + EB0170AE84675B1C851C3FA4 /* Pods-NOMADVRSDK.release.xcconfig */, + ); + name = Pods; + sourceTree = "<group>"; + }; + 4D85FBEB2075203B008FD96D /* GoogleCardboard */ = { + isa = PBXGroup; + children = ( + 4D85FBEC2075203B008FD96D /* aux.cpp */, + 4D85FBED2075203B008FD96D /* aux.h */, + ); + path = GoogleCardboard; + sourceTree = "<group>"; + }; + 4DEE7BCF2062A33900A0956C /* NOMADVRLib */ = { + isa = PBXGroup; + children = ( + 4DEE7BF62062BA3F00A0956C /* CompileGLShader.cpp */, + 4DEE7BF42062B92100A0956C /* IsoShaders.cpp */, + 4DEE7BF22062B2EB00A0956C /* polyhedron.cpp */, + 4DEE7BF02062AED900A0956C /* ConfigFile.cpp */, + 4DEE7BEE2062AECC00A0956C /* IsosurfacesGL.cpp */, + 4DEE7BEC2062AEAB00A0956C /* UnitCellShaders.cpp */, + 4DEE7BEA2062AE9F00A0956C /* TessShaders.cpp */, + 4DEE7BE82062AE6D00A0956C /* ConfigFileAtoms.cpp */, + 4DEE7BE62062AE5200A0956C /* Grid.cpp */, + 4DEE7BE42062AE2200A0956C /* markerShaders.cpp */, + 4DEE7BD32062A83800A0956C /* atomsGL.cpp */, + 4DEE7BD12062A82000A0956C /* atoms.cpp */, + ); + name = NOMADVRLib; + sourceTree = "<group>"; + }; + 4DEE7BD92062AD5C00A0956C /* rply */ = { + isa = PBXGroup; + children = ( + 4DEE7BDA2062AD8800A0956C /* rply.c */, + 4DEE7BDB2062AD8800A0956C /* rply.h */, + 4DEE7BDC2062AD8800A0956C /* rplyfile.h */, + ); + name = rply; + sourceTree = "<group>"; + }; + 4DEE7BDE2062ADCB00A0956C /* happyhttp */ = { + isa = PBXGroup; + children = ( + 4DEE7BDF2062ADCB00A0956C /* happyhttp.cpp */, + 4DEE7BE02062ADCB00A0956C /* happyhttp.h */, + ); + path = happyhttp; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 12BEE99D1C8F53AB002F8361 /* NOMADVRSDK */ = { + isa = PBXNativeTarget; + buildConfigurationList = 12BEE9B51C8F53AB002F8361 /* Build configuration list for PBXNativeTarget "NOMADVRSDK" */; + buildPhases = ( + ACFE6513C5D698691E7598BC /* [CP] Check Pods Manifest.lock */, + 12BEE99A1C8F53AB002F8361 /* Sources */, + 12BEE99B1C8F53AB002F8361 /* Frameworks */, + 12BEE99C1C8F53AB002F8361 /* Resources */, + 2EFF265D64E32C11F644E7C9 /* [CP] Embed Pods Frameworks */, + A352CE7013F07FFD6614613C /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NOMADVRSDK; + productName = TreasureHunt; + productReference = 12BEE99E1C8F53AB002F8361 /* NOMADVRSDK.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 12BEE9961C8F53AB002F8361 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0820; + TargetAttributes = { + 12BEE99D1C8F53AB002F8361 = { + CreatedOnToolsVersion = 7.2; + DevelopmentTeam = 6DYZG82AAG; + LastSwiftMigration = 0820; + }; + }; + }; + buildConfigurationList = 12BEE9991C8F53AB002F8361 /* Build configuration list for PBXProject "NOMADVRSDK" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 12BEE9951C8F53AB002F8361; + productRefGroup = 12BEE99F1C8F53AB002F8361 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 12BEE99D1C8F53AB002F8361 /* NOMADVRSDK */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 12BEE99C1C8F53AB002F8361 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DEE7BCE20629B0F00A0956C /* NOMADVRLib in Resources */, + 12BEE9C81C8F546B002F8361 /* launch.xib in Resources */, + 1278CED81CEBF98600D93A88 /* NOMADVRSDK-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 2EFF265D64E32C11F644E7C9 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-NOMADVRSDK/Pods-NOMADVRSDK-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/FileBrowser/FileBrowser.framework", + "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", + "${BUILT_PRODUCTS_DIR}/GoogleToolboxForMac/GoogleToolboxForMac.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FileBrowser.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleToolboxForMac.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NOMADVRSDK/Pods-NOMADVRSDK-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A352CE7013F07FFD6614613C /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-NOMADVRSDK/Pods-NOMADVRSDK-resources.sh", + "${PODS_ROOT}/GVRSDK/Resources/CardboardSDK.bundle", + "${PODS_ROOT}/GVRSDK/Resources/GoogleKitCore.bundle", + "${PODS_ROOT}/GVRSDK/Resources/GoogleKitDialogs.bundle", + "${PODS_ROOT}/GVRSDK/Resources/GoogleKitHUD.bundle", + "${PODS_ROOT}/GVRSDK/Resources/MaterialRobotoFontLoader.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/CardboardSDK.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleKitCore.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleKitDialogs.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleKitHUD.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialRobotoFontLoader.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NOMADVRSDK/Pods-NOMADVRSDK-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + ACFE6513C5D698691E7598BC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-NOMADVRSDK-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 12BEE99A1C8F53AB002F8361 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 12C3DC8F1CEBBA9E00D39B85 /* treasure_hunt_renderer.mm in Sources */, + 4DEE7BD52062A83800A0956C /* atomsGL.cpp in Sources */, + 4D85FBEE2075203B008FD96D /* aux.cpp in Sources */, + 4DEE7BF52062B92100A0956C /* IsoShaders.cpp in Sources */, + 4DEE7BE12062ADCB00A0956C /* happyhttp.cpp in Sources */, + 12BEE9CB1C8F54B8002F8361 /* main.m in Sources */, + 4DEE7BEB2062AE9F00A0956C /* TessShaders.cpp in Sources */, + 4DEE7BF12062AED900A0956C /* ConfigFile.cpp in Sources */, + 12BEE9C31C8F5426002F8361 /* TreasureHuntViewController.mm in Sources */, + 4DEE7BEF2062AECC00A0956C /* IsosurfacesGL.cpp in Sources */, + 12BEE9C01C8F5426002F8361 /* TreasureHuntAppDelegate.m in Sources */, + 4DEE7BE92062AE6D00A0956C /* ConfigFileAtoms.cpp in Sources */, + 4DEE7BE52062AE2200A0956C /* markerShaders.cpp in Sources */, + 4DEE7BF32062B2EB00A0956C /* polyhedron.cpp in Sources */, + 4DEE7BD22062A82000A0956C /* atoms.cpp in Sources */, + 4DEE7BED2062AEAB00A0956C /* UnitCellShaders.cpp in Sources */, + 4DEE7BDD2062AD8800A0956C /* rply.c in Sources */, + 4DEE7BE72062AE5200A0956C /* Grid.cpp in Sources */, + 4DEE7BF72062BA3F00A0956C /* CompileGLShader.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 12BEE9B31C8F53AB002F8361 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 12BEE9B41C8F53AB002F8361 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 12BEE9B61C8F53AB002F8361 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9FD381D5B2D35CE778ED88B3 /* Pods-NOMADVRSDK.debug.xcconfig */; + buildSettings = { + DEVELOPMENT_TEAM = 6DYZG82AAG; + ENABLE_BITCODE = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + INDICESGL32, + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/GTMSessionFetcher\"", + "\"${PODS_ROOT}/Headers/Public/GVRAudioSDK\"", + "\"${PODS_ROOT}/Headers/Public/GVRSDK\"", + "\"${PODS_ROOT}/Headers/Public/GoogleToolboxForMac\"", + "\"${PODS_ROOT}/..\"", + ); + INFOPLIST_FILE = "NOMADVRSDK-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.test.TreasureHunt; + PRODUCT_NAME = NOMADVRSDK; + SWIFT_VERSION = 4.0; + }; + name = Debug; + }; + 12BEE9B71C8F53AB002F8361 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EB0170AE84675B1C851C3FA4 /* Pods-NOMADVRSDK.release.xcconfig */; + buildSettings = { + DEVELOPMENT_TEAM = 6DYZG82AAG; + ENABLE_BITCODE = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + INDICESGL32, + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/GTMSessionFetcher\"", + "\"${PODS_ROOT}/Headers/Public/GVRAudioSDK\"", + "\"${PODS_ROOT}/Headers/Public/GVRSDK\"", + "\"${PODS_ROOT}/Headers/Public/GoogleToolboxForMac\"", + "\"${PODS_ROOT}/..\"", + ); + INFOPLIST_FILE = "NOMADVRSDK-Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.test.TreasureHunt; + PRODUCT_NAME = NOMADVRSDK; + SWIFT_VERSION = 4.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 12BEE9991C8F53AB002F8361 /* Build configuration list for PBXProject "NOMADVRSDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 12BEE9B31C8F53AB002F8361 /* Debug */, + 12BEE9B41C8F53AB002F8361 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 12BEE9B51C8F53AB002F8361 /* Build configuration list for PBXNativeTarget "NOMADVRSDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 12BEE9B61C8F53AB002F8361 /* Debug */, + 12BEE9B71C8F53AB002F8361 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 12BEE9961C8F53AB002F8361 /* Project object */; +} diff --git a/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "self:"> + </FileRef> +</Workspace> diff --git a/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.xcworkspace/xcuserdata/lrz.xcuserdatad/UserInterfaceState.xcuserstate b/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/project.xcworkspace/xcuserdata/lrz.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..faab40638f5e4675209d3e2037d5e52cccc4c61d GIT binary patch literal 15721 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 F{{RqwgV+E7 literal 0 HcmV?d00001 diff --git a/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/xcuserdata/lrz.xcuserdatad/xcschemes/TreasureHuntNDK.xcscheme b/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/xcuserdata/lrz.xcuserdatad/xcschemes/TreasureHuntNDK.xcscheme new file mode 100644 index 0000000..1854d68 --- /dev/null +++ b/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/xcuserdata/lrz.xcuserdatad/xcschemes/TreasureHuntNDK.xcscheme @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0820" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "12BEE99D1C8F53AB002F8361" + BuildableName = "NOMADVRSDK.app" + BlueprintName = "NOMADVRSDK" + ReferencedContainer = "container:NOMADVRSDK.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + </Testables> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "12BEE99D1C8F53AB002F8361" + BuildableName = "NOMADVRSDK.app" + BlueprintName = "NOMADVRSDK" + ReferencedContainer = "container:NOMADVRSDK.xcodeproj"> + </BuildableReference> + </MacroExpansion> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "12BEE99D1C8F53AB002F8361" + BuildableName = "NOMADVRSDK.app" + BlueprintName = "NOMADVRSDK" + ReferencedContainer = "container:NOMADVRSDK.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "12BEE99D1C8F53AB002F8361" + BuildableName = "NOMADVRSDK.app" + BlueprintName = "NOMADVRSDK" + ReferencedContainer = "container:NOMADVRSDK.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/xcuserdata/lrz.xcuserdatad/xcschemes/xcschememanagement.plist b/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/xcuserdata/lrz.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..a8bc326 --- /dev/null +++ b/GoogleCardboardIOS/NOMADVRSDK.xcodeproj/xcuserdata/lrz.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>SchemeUserState</key> + <dict> + <key>TreasureHuntNDK.xcscheme</key> + <dict> + <key>orderHint</key> + <integer>0</integer> + </dict> + </dict> + <key>SuppressBuildableAutocreation</key> + <dict> + <key>12BEE99D1C8F53AB002F8361</key> + <dict> + <key>primary</key> + <true/> + </dict> + </dict> +</dict> +</plist> diff --git a/GoogleCardboardIOS/NOMADVRSDK.xcworkspace/contents.xcworkspacedata b/GoogleCardboardIOS/NOMADVRSDK.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..defd941 --- /dev/null +++ b/GoogleCardboardIOS/NOMADVRSDK.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "group:NOMADVRSDK.xcodeproj"> + </FileRef> + <FileRef + location = "group:Pods/Pods.xcodeproj"> + </FileRef> +</Workspace> diff --git a/GoogleCardboardIOS/Podfile b/GoogleCardboardIOS/Podfile new file mode 100644 index 0000000..bc5ff22 --- /dev/null +++ b/GoogleCardboardIOS/Podfile @@ -0,0 +1,15 @@ +target 'NOMADVRSDK' do + pod 'GVRSDK' + pod 'GVRAudioSDK' + source 'https://github.com/CocoaPods/Specs.git' + pod 'FileBrowser', '~> 1.0' + use_frameworks! + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['SWIFT_VERSION'] = '3.0' + end + end +end +end diff --git a/GoogleCardboardIOS/Podfile.lock b/GoogleCardboardIOS/Podfile.lock new file mode 100644 index 0000000..2f4d07d --- /dev/null +++ b/GoogleCardboardIOS/Podfile.lock @@ -0,0 +1,26 @@ +PODS: + - FileBrowser (1.0.0) + - GoogleToolboxForMac/Defines (2.1.0) + - GoogleToolboxForMac/Logger (2.1.0): + - GoogleToolboxForMac/Defines (= 2.1.0) + - GTMSessionFetcher/Core (1.1.6) + - GVRAudioSDK (1.120.0) + - GVRSDK (1.120.0): + - GoogleToolboxForMac/Logger (= 2.1.0) + - GTMSessionFetcher/Core (= 1.1.6) + +DEPENDENCIES: + - FileBrowser (~> 1.0) + - GVRAudioSDK + - GVRSDK + +SPEC CHECKSUMS: + FileBrowser: 2ca91ff61c9ea09665eb3b8f9e64a7a77e66a0bf + GoogleToolboxForMac: 2b2596cbb7186865e98cadf2b1e262d851c2b168 + GTMSessionFetcher: 6aacd0ab48ddf0c3633ab2642d792abfcad1b08a + GVRAudioSDK: 302f0a8f190d855868ea07f246ce4f9b44c392ae + GVRSDK: 0cb9d0ce06a84d698e61e3db9509766022dcf815 + +PODFILE CHECKSUM: 99ba6b514157c57c4187c4110345b7c329fef13f + +COCOAPODS: 1.4.0 diff --git a/GoogleCardboardIOS/TreasureHuntAppDelegate.h b/GoogleCardboardIOS/TreasureHuntAppDelegate.h new file mode 100644 index 0000000..8573bc0 --- /dev/null +++ b/GoogleCardboardIOS/TreasureHuntAppDelegate.h @@ -0,0 +1,21 @@ +/* + * Copyright 2016 Google 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. + */ + +#import <UIKit/UIKit.h> + +@interface TreasureHuntAppDelegate : NSObject +@property(nonatomic, strong) UIWindow* window; +@end diff --git a/GoogleCardboardIOS/TreasureHuntAppDelegate.m b/GoogleCardboardIOS/TreasureHuntAppDelegate.m new file mode 100644 index 0000000..131f7d7 --- /dev/null +++ b/GoogleCardboardIOS/TreasureHuntAppDelegate.m @@ -0,0 +1,55 @@ +/* + * Copyright 2016 Google 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. + */ + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support. Compile with -fobjc-arc" +#endif + +#import "TreasureHuntAppDelegate.h" + +#import "TreasureHuntViewController.h" + +@interface TreasureHuntAppDelegate ()<UINavigationControllerDelegate> + +@end + +@implementation TreasureHuntAppDelegate + +#pragma mark - UIApplicationDelegate overrides + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + UINavigationController *navigationController = [[UINavigationController alloc] + initWithRootViewController:[[TreasureHuntViewController alloc] init]]; + navigationController.delegate = self; + navigationController.navigationBarHidden = YES; + + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.rootViewController = navigationController; + [self.window makeKeyAndVisible]; + return YES; +} + +#pragma mark - UINavigationControllerDelegate + +// Make the navigation controller defer the check of supported orientation to its topmost view +// controller. This allows |GVRCardboardViewController| to lock the orientation in VR mode. +- (UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations: + (UINavigationController *)navigationController { + return [navigationController.topViewController supportedInterfaceOrientations]; +} + +@end diff --git a/GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/contents.xcworkspacedata b/GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..312fdf3 --- /dev/null +++ b/GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "group:/Users/lrz/gvr-ios-sdk/Samples/TreasureHuntNDK/NOMADVRSDK.xcodeproj"> + </FileRef> + <FileRef + location = "group:Pods/Pods.xcodeproj"> + </FileRef> +</Workspace> diff --git a/GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/xcuserdata/lrz.xcuserdatad/UserInterfaceState.xcuserstate b/GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/xcuserdata/lrz.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..411be43fbe88ef337ca44c97eff976e1fa59a7ef GIT binary patch literal 56027 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 literal 0 HcmV?d00001 diff --git a/GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/xcuserdata/lrz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/xcuserdata/lrz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..daf0f59 --- /dev/null +++ b/GoogleCardboardIOS/TreasureHuntNDK.xcworkspace/xcuserdata/lrz.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,311 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Bucket + type = "0" + version = "2.0"> + <Breakpoints> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "220" + endingLineNumber = "220" + landmarkName = "TreasureHuntRenderer::TreasureHuntRenderer( gvr_context* gvr_context)" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "main.m" + timestampString = "544465671.0221111" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "21" + endingLineNumber = "21" + landmarkName = "main()" + landmarkType = "9"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "253" + endingLineNumber = "253" + landmarkName = "TreasureHuntRenderer::InitializeGl()" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "NOMADVRLib/atomsGL.cpp" + timestampString = "544465961.497296" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "58" + endingLineNumber = "58" + landmarkName = "atomTexture(GLuint t)" + landmarkType = "9"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "NOMADVRLib/atomsGL.cpp" + timestampString = "544526936.709954" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "60" + endingLineNumber = "60" + landmarkName = "atomTexture(GLuint t)" + landmarkType = "9"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "NOMADVRLib/atomsGL.cpp" + timestampString = "544526938.2828521" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "67" + endingLineNumber = "67" + landmarkName = "atomTexture(GLuint t)" + landmarkType = "9"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "NOMADVRLib/atomsGL.cpp" + timestampString = "544527787.9424599" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "72" + endingLineNumber = "72" + landmarkName = "atomTexture(GLuint t)" + landmarkType = "9"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "NOMADVRLib/atomsGL.cpp" + timestampString = "544527787.9424599" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "77" + endingLineNumber = "77" + landmarkName = "atomTexture(GLuint t)" + landmarkType = "9"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "NOMADVRLib/atomsGL.cpp" + timestampString = "544527787.9424599" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "70" + endingLineNumber = "70" + landmarkName = "atomTexture(GLuint t)" + landmarkType = "9"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "358" + endingLineNumber = "358" + landmarkName = "TreasureHuntRenderer::DrawFrame()" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "344" + endingLineNumber = "344" + landmarkName = "TreasureHuntRenderer::DrawFrame()" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "214" + endingLineNumber = "214" + landmarkName = "TreasureHuntRenderer::loadConfigFile(void)" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "296" + endingLineNumber = "296" + landmarkName = "TreasureHuntRenderer::InitializeGl()" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "176" + endingLineNumber = "176" + landmarkName = "TreasureHuntRenderer::loadConfigFile(void)" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "179" + endingLineNumber = "179" + landmarkName = "TreasureHuntRenderer::loadConfigFile(void)" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "180" + endingLineNumber = "180" + landmarkName = "TreasureHuntRenderer::loadConfigFile(void)" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "176" + endingLineNumber = "176" + landmarkName = "TreasureHuntRenderer::loadConfigFile(void)" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "170" + endingLineNumber = "170" + landmarkName = "TreasureHuntRenderer::loadConfigFile(void)" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "treasure_hunt_renderer.mm" + timestampString = "544628855.2832021" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "365" + endingLineNumber = "365" + landmarkName = "TreasureHuntRenderer::DrawFrame()" + landmarkType = "7"> + </BreakpointContent> + </BreakpointProxy> + </Breakpoints> +</Bucket> diff --git a/GoogleCardboardIOS/TreasureHuntViewController.h b/GoogleCardboardIOS/TreasureHuntViewController.h new file mode 100644 index 0000000..073f048 --- /dev/null +++ b/GoogleCardboardIOS/TreasureHuntViewController.h @@ -0,0 +1,21 @@ + /* + * Copyright 2016 Google 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. + */ + +#import <GLKit/GLKit.h> + +@interface TreasureHuntViewController : GLKViewController + +@end diff --git a/GoogleCardboardIOS/TreasureHuntViewController.mm b/GoogleCardboardIOS/TreasureHuntViewController.mm new file mode 100644 index 0000000..94f2a68 --- /dev/null +++ b/GoogleCardboardIOS/TreasureHuntViewController.mm @@ -0,0 +1,125 @@ +/* + * Copyright 2016 Google 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. + */ + +#import "TreasureHuntViewController.h" + +#import "GVROverlayView.h" +#import "treasure_hunt_renderer.h" + +@interface TreasureHuntViewController ()<GLKViewControllerDelegate, GVROverlayViewDelegate> { + gvr_context *_gvrContext; + std::unique_ptr<TreasureHuntRenderer> _renderer; +} +@end + +@implementation TreasureHuntViewController + +- (void)dealloc { + gvr_destroy(&_gvrContext); +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.delegate = self; + + // Create an overlay view on top of the GLKView. + GVROverlayView *overlayView = [[GVROverlayView alloc] initWithFrame:self.view.bounds]; + overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + overlayView.delegate = self; + [self.view addSubview:overlayView]; + + // Add a tap gesture to handle viewer trigger action. + UITapGestureRecognizer *tapGesture = + [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapGLView:)]; + [self.view addGestureRecognizer:tapGesture]; + + // Create an OpenGL ES context and assign it to the view loaded from storyboard + GLKView *glkView = (GLKView *)self.view; + glkView.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; + + // Set animation frame rate. + self.preferredFramesPerSecond = 60; + + // Set the GL context to initialize GVR. + [EAGLContext setCurrentContext:glkView.context]; + + // Make sure the glkView has bound its offscreen buffers before calling into gvr. + [glkView bindDrawable]; + + // Create GVR context. + _gvrContext = gvr_create(); + + // Initialize TreasureHuntRenderer. + _renderer.reset(new TreasureHuntRenderer(_gvrContext)); + _renderer->InitializeGl(); +} + +- (UIInterfaceOrientationMask)supportedInterfaceOrientations { + // GVR only supports landscape right orientation for inserting the phone in the viewer. + return UIInterfaceOrientationMaskLandscapeRight; +} + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { + _renderer->DrawFrame(); +} + +#pragma mark - GLKViewControllerDelegate + +- (void)glkViewControllerUpdate:(GLKViewController *)controller { + // Perform GL state update before drawing. +} + +- (void)glkViewController:(GLKViewController *)controller willPause:(BOOL)pause { + if (pause) { + _renderer->OnPause(); + } else { + _renderer->OnResume(); + } +} + +#pragma mark - Actions + +- (void)didTapGLView:(id)sender { + _renderer->OnTriggerEvent(); +} + +#pragma mark - GVROverlayViewDelegate + +- (void)didTapBackButton { + // User pressed the back button. Pop this view controller. + NSLog(@"User pressed back button"); +} + +- (UIViewController *)presentingViewControllerForSettingsDialog { + return self; +} + +- (void)didPresentSettingsDialog:(BOOL)presented { + // The overlay view is presenting the settings dialog. Pause our rendering while presented. + self.paused = presented; +} + +- (void)didChangeViewerProfile { + // Renderer's OnResume also refreshes viewer profile. + _renderer->OnResume(); +} + +- (void)shouldDisableIdleTimer:(BOOL)shouldDisable { + [UIApplication sharedApplication].idleTimerDisabled = shouldDisable; +} + +@end diff --git a/GoogleCardboardIOS/launch.xib b/GoogleCardboardIOS/launch.xib new file mode 100644 index 0000000..738fb7e --- /dev/null +++ b/GoogleCardboardIOS/launch.xib @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="13F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES"> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/> + </dependencies> + <objects> + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> + <view contentMode="scaleToFill" id="iN0-l3-epB"> + <rect key="frame" x="0.0" y="0.0" width="480" height="480"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye"> + <rect key="frame" x="20" y="439" width="441" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> + <nil key="highlightedColor"/> + <variation key="widthClass=compact"> + <fontDescription key="fontDescription" type="system" pointSize="11"/> + </variation> + </label> + </subviews> + <color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/> + <constraints> + <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/> + <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/> + <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/> + </constraints> + <nil key="simulatedStatusBarMetrics"/> + <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> + <point key="canvasLocation" x="404" y="445"/> + </view> + </objects> +</document> diff --git a/GoogleCardboardIOS/main.m b/GoogleCardboardIOS/main.m new file mode 100644 index 0000000..77e864d --- /dev/null +++ b/GoogleCardboardIOS/main.m @@ -0,0 +1,23 @@ +/* + * Copyright 2016 Google 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. + */ + +#import "TreasureHuntAppDelegate.h" + +int main(int argc, char *argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([TreasureHuntAppDelegate class])); + } +} diff --git a/GoogleCardboardIOS/treasure_hunt_renderer.h b/GoogleCardboardIOS/treasure_hunt_renderer.h new file mode 100644 index 0000000..466c976 --- /dev/null +++ b/GoogleCardboardIOS/treasure_hunt_renderer.h @@ -0,0 +1,155 @@ +/* Copyright 2016 Google 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. + */ + +#ifndef TREASUREHUNT_APP_SRC_MAIN_JNI_TREASUREHUNTRENDERER_H_ // NOLINT +#define TREASUREHUNT_APP_SRC_MAIN_JNI_TREASUREHUNTRENDERER_H_ // NOLINT + +#import <OpenGLES/EAGL.h> +#import <OpenGLES/ES3/gl.h> +#import <OpenGLES/ES3/glext.h> + +#include <memory> +#include <string> +#include <thread> // NOLINT +#include <vector> + +#include "vr/gvr/capi/include/gvr.h" +#include "vr/gvr/capi/include/gvr_types.h" + +#define ZLAYERS 2 + +class TreasureHuntRenderer { + public: + /** + * Create a TreasureHuntRenderer using a given |gvr_context|. + * + * @param gvr_api The (non-owned) gvr_context. + * @param gvr_audio_api The (owned) gvr::AudioApi context. + */ + TreasureHuntRenderer(gvr_context* gvr_context); + + /** + * Destructor. + */ + ~TreasureHuntRenderer(); + + /** + * Initialize any GL-related objects. This should be called on the rendering + * thread with a valid GL context. + */ + void InitializeGl(); + + /** + * Draw the TreasureHunt scene. This should be called on the rendering thread. + */ + void DrawFrame(); + + /** + * Hide the cube if it's being targeted. + */ + void OnTriggerEvent(); + + /** + * Pause head tracking. + */ + void OnPause(); + + /** + * Resume head tracking, refreshing viewer parameters if necessary. + */ + void OnResume(); + + private: + int CreateTexture(int width, int height, int textureFormat, int textureType); + + /** + * Converts a raw text file, saved as a resource, into an OpenGL ES shader. + * + * @param type The type of shader we will be creating. + * @param resId The resource ID of the raw text file. + * @return The shader object handler. + */ + int LoadGLShader(int type, const char** shadercode); + + /** + * Draws a frame for an eye. + * + * @param eye The eye to render. Includes all required transformations. + */ + void DrawEye(gvr::Eye eye, const gvr::Mat4f& view_matrix, + const gvr::BufferViewport& params); + + /** + * Draw the cube. + * + * We've set all of our transformation matrices. Now we simply pass them + * into the shader. + */ + void DrawCube(); + + + std::unique_ptr<gvr::GvrApi> gvr_api_; + std::unique_ptr<gvr::BufferViewportList> viewport_list_; + std::unique_ptr<gvr::SwapChain> swapchain_; + gvr::BufferViewport scratch_viewport_; + + gvr::Mat4f head_view_; + gvr::Mat4f model_cube_; + gvr::Mat4f camera_; + gvr::Mat4f view_; + gvr::Mat4f modelview_projection_cube_; + gvr::Mat4f modelview_; + gvr::Sizei render_size_; + + void loadConfigFile(void); + + GLuint textures[2]; // white, atoms + GLuint textDepthPeeling[ZLAYERS+2]; + GLuint peelingFramebuffer; + //if no tesselation is available, we still need the tess atoms for the trajectories! + GLuint *AtomTVAO=nullptr, *AtomTBuffer=nullptr, *AtomVAO=nullptr, *AtomBuffer=nullptr, *AtomIndices=nullptr,//[2], atoms, extraatoms + BondIndices, + UnitCellVAO, UnitCellBuffer, UnitCellIndexBuffer, + MarkerVAO, MarkerVertBuffer, MarkerIndexBuffer; + GLuint AtomsP, UnitCellP; // framework does not provide support for tesselation and provides many things we don't need. + GLint AtomMatrixLoc, UnitCellMatrixLoc, UnitCellColourLoc, totalatomsLocation; + GLuint TransP=0, BlendP=0; + GLint TransMatrixLoc=-1; + bool hasTess=true; + + GLuint *ISOVAO=nullptr/*[ISOS*TIMESTEPS]*/, *ISOBuffer=nullptr/*[ISOS*TIMESTEPS]*/, + *ISOIndices=nullptr/*[ISOS*TIMESTEPS]*/; + GLuint ISOP; + GLint ISOMatrixLoc; + GLuint BlendVAO=0, BlendBuffer=0, BlendIndices=0; + int *numISOIndices=nullptr/*[ISOS*TIMESTEPS]*/; + + int currentSet=0; + bool animateTimesteps=true; + bool animateMovement=false; + int currentIso; + + void RenderAtoms(const float *m); + void RenderMarker(const float *m); + void RenderUnitCell(const gvr::Mat4f eyeViewProjection); + void RenderAtomTrajectoriesUnitCell(); + void RenderAtomTrajectories(const gvr::Mat4f eyeViewProjection); + void RenderIsos(const gvr::Mat4f eyeViewProjection, int curDataPos); + float UserTranslation[3]={10,0,0}; + + int error=0; +}; + +#endif // TREASUREHUNT_APP_SRC_MAIN_JNI_TREASUREHUNTRENDERER_H_ // NOLINT diff --git a/GoogleCardboardIOS/treasure_hunt_renderer.mm b/GoogleCardboardIOS/treasure_hunt_renderer.mm new file mode 100644 index 0000000..83904a7 --- /dev/null +++ b/GoogleCardboardIOS/treasure_hunt_renderer.mm @@ -0,0 +1,800 @@ +/*# Copyright 2016-2018 The NOMAD Developers Group*/ +/* Copyright 2016 Google 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 "treasure_hunt_renderer.h" + +#include <assert.h> +#include <cmath> + +#include "NOMADVRLib/MyGL.h" + +#include "NOMADVRLib/atoms.hpp" +#include "NOMADVRLib/ConfigFile.h" +#include "NOMADVRLib/atomsGL.h" +#include "NOMADVRLib/UnitCellShaders.h" +#include "NOMADVRLib/TessShaders.h" +#include "NOMADVRLib/polyhedron.h" +#include "NOMADVRLib/IsosurfacesGL.h" +#include "NOMADVRLib/eprintf.h" + +#include "GoogleCardboard/aux.h" + +#define LOG_TAG "NOMADVRIOS" +#define LOGW(...) NSLog(@__VA_ARGS__) + +void eprintf( const char *fmt, ... ) +{ + va_list args; + char buffer[ 2048 ]; + + va_start( args, fmt ); + vsprintf( buffer, fmt, args ); + va_end( args ); + + LOGW("Message in NOMADgvrT"); + if (*fmt=='\0') + LOGW("Empty format"); + LOGW("<%s>", buffer); +} + +// TODO(sanjayc): Refactor this app to reuse treasure_hunt_renderer from: +// vr/gvr/demos/treasurehunt. http://b/28880883 + +namespace { +//static const int kTextureFormat = GL_RGB; +//static const int kTextureType = GL_UNSIGNED_BYTE; + +//static const float kZNear = 1.0f; +//static const float kZFar = 100.0f; +static const float kZNear = 0.01f; +static const float kZFar = 1000.0f; + +static const uint64_t kPredictionTimeWithoutVsyncNanos = 50000000; + +static std::array<float, 16> MatrixToGLArray(const gvr::Mat4f& matrix) { + // Note that this performs a *tranpose* to a column-major matrix array, as + // expected by GL. + std::array<float, 16> result; + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + result[j * 4 + i] = matrix.m[i][j]; + } + } + return result; +} + +static std::array<float, 4> MatrixVectorMul(const gvr::Mat4f& matrix, + const std::array<float, 4>& vec) { + std::array<float, 4> result; + for (int i = 0; i < 4; ++i) { + result[i] = 0; + for (int k = 0; k < 4; ++k) { + result[i] += matrix.m[i][k]*vec[k]; + } + } + return result; +} + +static gvr::Mat4f MatrixMul(const gvr::Mat4f& matrix1, + const gvr::Mat4f& matrix2) { + gvr::Mat4f result; + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + result.m[i][j] = 0.0f; + for (int k = 0; k < 4; ++k) { + result.m[i][j] += matrix1.m[i][k]*matrix2.m[k][j]; + } + } + } + return result; +} + +static gvr::Mat4f PerspectiveMatrixFromView(const gvr::Rectf& fov, float z_near, + float z_far) { + gvr::Mat4f result; + const float x_left = -std::tan(fov.left * M_PI / 180.0f) * z_near; + const float x_right = std::tan(fov.right * M_PI / 180.0f) * z_near; + const float y_bottom = -std::tan(fov.bottom * M_PI / 180.0f) * z_near; + const float y_top = std::tan(fov.top * M_PI / 180.0f) * z_near; + const float zero = 0.0f; + + assert(x_left < x_right && y_bottom < y_top && z_near < z_far && + z_near > zero && z_far > zero); + const float X = (2 * z_near) / (x_right - x_left); + const float Y = (2 * z_near) / (y_top - y_bottom); + const float A = (x_right + x_left) / (x_right - x_left); + const float B = (y_top + y_bottom) / (y_top - y_bottom); + const float C = (z_near + z_far) / (z_near - z_far); + const float D = (2 * z_near * z_far) / (z_near - z_far); + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + result.m[i][j] = 0.0f; + } + } + result.m[0][0] = X; + result.m[0][2] = A; + result.m[1][1] = Y; + result.m[1][2] = B; + result.m[2][2] = C; + result.m[2][3] = D; + result.m[3][2] = -1; + + return result; +} + +static gvr::Rectf ModulateRect(const gvr::Rectf& rect, float width, + float height) { + gvr::Rectf result = {rect.left * width, rect.right * width, + rect.bottom * height, rect.top * height}; + return result; +} + +static gvr::Recti CalculatePixelSpaceRect(const gvr::Sizei& texture_size, + const gvr::Rectf& texture_rect) { + float width = static_cast<float>(texture_size.width); + float height = static_cast<float>(texture_size.height); + gvr::Rectf rect = ModulateRect(texture_rect, width, height); + gvr::Recti result = { + static_cast<int>(rect.left), static_cast<int>(rect.right), + static_cast<int>(rect.bottom), static_cast<int>(rect.top)}; + return result; +} + +static void CheckGLError(const char* label) { + int gl_error = glGetError(); + if (gl_error != GL_NO_ERROR) { + LOGW("GL error @ %s: %d", label, gl_error); + } + assert(glGetError() == GL_NO_ERROR); +} + +} // namespace + +void TreasureHuntRenderer::loadConfigFile(void) +{ + //http://www.techotopia.com/index.php/Working_with_Directories_on_iPhone_OS#The_Application_Documents_Directory + NSArray *dirPaths; + NSString *docsDir; + + dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, + NSUserDomainMask, YES); + + docsDir = [dirPaths objectAtIndex:0]; + NSFileManager *filemgr = [NSFileManager defaultManager]; + + if ([filemgr changeCurrentDirectoryPath: docsDir] == NO) + NSLog(@"Cannot change current directory"); + + if ((error=::loadConfigFile("cytosine.ncfg"))<0) { + if (-100<error) { + eprintf(loadConfigFileErrors[-error]); + eprintf("Config file reading error"); + } else if (-200<error){ + eprintf(readAtomsXYZErrors[-error-100]); + eprintf("XYZ file reading error"); + } else if (-300<error) { + eprintf(readAtomsCubeErrors[-error-200]); + eprintf("Cube file reading error"); + } else { + eprintf(readAtomsJsonErrors[-error-300]); + eprintf("Json reading error"); + } + } + if (!solid) { + LOGW("No atom glyph specified, using Icosahedron"); + solid=new Solid(Solid::Type::Icosahedron); + } + + UserTranslation[0]=userpos[0]; //because of rotation in X to make Z vertical + UserTranslation[1]=-userpos[2]; + UserTranslation[2]=userpos[1]; + +} + + +TreasureHuntRenderer::TreasureHuntRenderer( + gvr_context* gvr_context) + : gvr_api_(gvr::GvrApi::WrapNonOwned(gvr_context)), + scratch_viewport_(gvr_api_->CreateBufferViewport()) +{ + loadConfigFile(); +} + +TreasureHuntRenderer::~TreasureHuntRenderer() {} + +void TreasureHuntRenderer::InitializeGl() { + gvr_api_->InitializeGl(); + + glGenTextures(2, textures); + glGenTextures(2+ZLAYERS, textDepthPeeling); + //white + unsigned char data2[4]={255,255,255,255}; //white texture for non-textured meshes + glBindTexture(GL_TEXTURE_2D, textures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2); + + // Create the programs + //Leave atoms until we check if android 7 has gles 3.2 or if we use the old icosahedron method with no tesselation + if (!PrepareUnitCellShader (&UnitCellP, &UnitCellMatrixLoc, &UnitCellColourLoc)) { + eprintf("OneTimeInit, failure compiling Unit Cell Shader"); + error=-401; + return ; + } + + //rgh: for now, we don't have any tess-ready phones + //if (!PrepareAtomShader(&AtomsP, &AtomMatrixLoc)) { + hasTess=false; + if (!PrepareAtomShaderNoTess(&AtomsP, &AtomMatrixLoc, &totalatomsLocation)) { + error=-402; + eprintf ("PrepareAtomShaderNoTess failed"); + } + //}; + + //atom texture + int e; + + e=atomTexture(textures[1]); + if (e!=GL_NO_ERROR) { + eprintf ("atomTexture error %d", e); + error=-403; + } + + e=SetupAtoms(&AtomTVAO, &AtomTBuffer, &BondIndices); + if (e!=GL_NO_ERROR) { + eprintf ("SetupAtoms error %d", e); + error=-404; + } + + if (!hasTess) + e=SetupAtomsNoTess(&AtomVAO, &AtomBuffer, &AtomIndices); + + if (e!=GL_NO_ERROR) { + eprintf ("SetupAtomsNoTess error %d, tess=%d", e, hasTess); + error=-405; + } + e=SetupUnitCell(&UnitCellVAO, &UnitCellBuffer, &UnitCellIndexBuffer); + if (e!=GL_NO_ERROR) { + eprintf ("SetupUnitCell error %d", e); + error=-406; + } + e=SetupMarkerNoTess(&MarkerVAO, &MarkerVertBuffer, &MarkerIndexBuffer); + if (e!=GL_NO_ERROR) { + eprintf ("SetupMarkerNoTess error %d", e); + error=-411; + } + + + std::vector<gvr::BufferSpec> specs; + specs.push_back(gvr_api_->CreateBufferSpec()); + render_size_ = specs[0].GetSize(); + swapchain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); + + viewport_list_.reset(new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); + +} + +void TreasureHuntRenderer::DrawFrame() { + viewport_list_->SetToRecommendedBufferViewports(); + + if (animateTimesteps) { + if (animationspeed>1) + currentSet+=animationspeed; + else { + static float current=0; + current+=animationspeed; + if (current>1) { + currentSet++; + current=0; + } + } + if (currentSet>TIMESTEPS-1) + currentSet=0; + } + gvr::Frame frame = swapchain_->AcquireFrame(); + + // A client app does its rendering here. + gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); + target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; + + head_view_ = gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); + gvr::Mat4f left_eye_view_pose = MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_LEFT_EYE), + head_view_); + gvr::Mat4f right_eye_view_pose = MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_RIGHT_EYE), + head_view_); + + if (animateMovement) { + const float speed=0.01; + gvr::Mat4f inv=invert(head_view_); + + std::array<float, 4> dir({0,0,1,0}); // {0,0,1,0} + std::array<float, 4> dir2=MatrixVectorMul(inv, dir); + + for (int i=0;i<3;i++) + UserTranslation[i]+=dir2[i]*speed*movementspeed; + + } + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_BLEND); + + frame.BindBuffer(0); + + if (error<0) { + //rgh: FIXME, add textures with messages here + if (-100<error) { //error with ncfg file + glClearColor(1.f, 0.f, 0.f, 1.f); + } else if (-200<error){//error loading xyz + glClearColor(0.f, 1.f, 0.f, 1.f); + } else if (-300<error) {//error loading gaussian + glClearColor(0.f, 0.f, 1.f, 1.f); + } else if (-400<error) {//error loading encyclopedia json + glClearColor(0.f, 1.f, 1.f, 1.f); + } else if (-500<error) {//error loading analytics json + glClearColor(1.f, 1.f, 0.f, 1.f); + } else { + glClearColor(1.f, 0.f, 1.f, 1.f); + } + } else { + glClearColor(BACKGROUND[0], BACKGROUND[1], BACKGROUND[2], 1.f); + } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + viewport_list_->GetBufferViewport(0, &scratch_viewport_); + DrawEye(GVR_LEFT_EYE, left_eye_view_pose, scratch_viewport_); + viewport_list_->GetBufferViewport(1, &scratch_viewport_); + DrawEye(GVR_RIGHT_EYE, right_eye_view_pose, scratch_viewport_); + + // Bind back to the default framebuffer. + frame.Unbind(); + frame.Submit(*viewport_list_, head_view_); + + CheckGLError("onDrawFrame"); +} + +void TreasureHuntRenderer::OnTriggerEvent() { + animateMovement=!animateMovement; +} + +void TreasureHuntRenderer::OnPause() { + gvr_api_->PauseTracking(); +} + +void TreasureHuntRenderer::OnResume() { + gvr_api_->RefreshViewerProfile(); + gvr_api_->ResumeTracking(); +} + +void TreasureHuntRenderer::RenderUnitCell(const gvr::Mat4f eyeViewProjection) +{ + //eprintf ("eyeViewProjection"); + //for (int i=0;i<4;i++) + // for (int j=0;j<4;j++) + // eprintf ("%d %d = %f", i, j, eyeViewProjection.m[i][j]); + //eprintf ("RenderUnitCell, has_abc=%d", has_abc); + if (!has_abc) + return; + if (UnitCellVAO==0) + eprintf ("Error, Unit Cell VAO not loaded"); + int e; + + int p[3]; + gvr::Mat4f sc=ScalingMatrix(scaling); + for (p[0]=0;p[0]<repetitions[0];(p[0])++) + for (p[1]=0;p[1]<repetitions[1];(p[1])++) + for (p[2]=0;p[2]<repetitions[2];(p[2])++) + { + float delta[3]; + GetDisplacement(p, delta); + /*gvr::Mat4f trans={1,0,0,delta[0]+UserTranslation[0], + 0,1,0,delta[1]+UserTranslation[1], + 0,0,1,delta[2]+UserTranslation[2], + 0,0,0,1};*/ + gvr::Mat4f trans=TranslationMatrix (delta[0]+UserTranslation[0]/scaling, delta[2]+UserTranslation[1]/scaling, + -delta[1]+UserTranslation[2]/scaling); + const gvr::Mat4f rot={.m={1,0,0,0, 0,0,1,0, 0,-1,0,0, 0,0,0,1}}; + //trans.translate(iPos).rotateX(-90).translate(UserPosition); + gvr::Mat4f transform = MatrixMul(eyeViewProjection, MatrixMul(sc, MatrixMul(trans,rot))); + + + + //gvr::Mat4f transform = MatrixMul(eyeViewProjection,trans); + //gvr::Mat4f transform=eyeViewProjection; + float t[16]; + for (int i=0;i<4;i++) + for (int j=0;j<4;j++) + t[j*4+i]=transform.m[i][j]; + glUseProgram(UnitCellP); + glUniformMatrix4fv(UnitCellMatrixLoc, 1, GL_FALSE, t); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after glUniform4fv 1 RenderUnitCell: %d\n", e); + if (displayunitcell) { + glUniform4fv(UnitCellColourLoc, 1, unitcellcolour); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after glUniform4fv 2 RenderUnitCell: %d\n", e); + glBindVertexArray(UnitCellVAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, UnitCellIndexBuffer); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("1 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + glBindBuffer(GL_ARRAY_BUFFER, UnitCellBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (const void *)(0)); + glEnableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glDisableVertexAttribArray(3); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after glBindVertexArray RenderUnitCell: %d\n", e); + glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0); + //glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after RenderUnitCell: %d\n", e); + } + //atom trajectories + RenderAtomTrajectoriesUnitCell(); + RenderAtoms(t); + RenderMarker(t); + } +} + +void TreasureHuntRenderer::RenderAtomTrajectoriesUnitCell() +{ + //now trajectories + if (!showTrajectories) + return; + + int e; + if (!AtomTVAO) { + LOGW("RenderAtomTrajectoriesUnitCell, no atoms"); + return; + } + glBindVertexArray(AtomTVAO[0]); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("1 Gl error RenderAtomTrajectoriesUnitCell: %d\n", e); + //glUseProgram(UnitCellP); + //glUniformMatrix4fv(m_nUnitCellMatrixLocation, 1, GL_FALSE, matrix); + glUniform4fv(UnitCellColourLoc, 1, atomtrajectorycolour); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after glUniform4fv 2 RenderAtomTrajectoriesUnitCell: %d\n", e); + //glEnableVertexAttribArray(0); + //glDisableVertexAttribArray(1); + + //LOG("atomtrajectories.size()=%d", atomtrajectories.size()); + //rgh FIXME, old code which does not work with large atom sets! + + glBindBuffer(GL_ARRAY_BUFFER, AtomTBuffer[0]); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("3 Gl error RenderAtomTrajectoriesUnitCell: %d\n", e); + + for (unsigned int i=0;i<atomtrajectories.size();i++) { + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float)*numAtoms[0], + (const void *)(0+4*sizeof(float)*atomtrajectories[i])); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("4 Gl error RenderAtomTrajectoriesUnitCell: %d\n", e); + + //LOG("atomtrajectoryrestarts[%d].size()=%d", i, atomtrajectoryrestarts[i].size()); + for (unsigned int j=1;j<atomtrajectoryrestarts[i].size();j++) { + int orig=atomtrajectoryrestarts[i][j-1]; + int count=atomtrajectoryrestarts[i][j]-atomtrajectoryrestarts[i][j-1]; + glDrawArrays(GL_LINE_STRIP, orig, count); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("5 Gl error RenderAtomTrajectoriesUnitCell: %d, orig=%d, count=%d\n", e, orig, count); + + } //j + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after Render Atom trajectories: %d\n", e); + } //i + +} //OvrApp::RenderAtomTrajectoriesUnitCell() + +void TreasureHuntRenderer::RenderAtoms(const float *m) //m[16] +{ + //eprintf ("RenderAtoms start numatoms %d, timestep %d", numAtoms[currentSet], currentSet); + //eprintf ("solid nfaces %d", solid->nFaces); + int e; + if (numAtoms==0) + return; + + if (hasTess) { + //FIXME, unimplemented + LOGW("FIXME, No Tess code for atoms yet!"); + return; + } else { //no tess + glBindVertexArray(AtomVAO[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, AtomIndices[0]); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("1 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + glBindBuffer(GL_ARRAY_BUFFER, AtomBuffer[0]); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("2 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7*sizeof(float), (const void *)0); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("3 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (const void *)(3*sizeof(float))); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("4 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + + glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (const void *)(6 * sizeof(float))); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("5 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + + glBindTexture(GL_TEXTURE_2D, textures[1]); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("6 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + + glUseProgram(AtomsP); + glUniform1f(totalatomsLocation, (float)getTotalAtomsInTexture()); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("7 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + + glUniformMatrix4fv(AtomMatrixLoc, 1, GL_FALSE, m); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("8 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + + if (currentSet==0) { + glDrawElements(GL_TRIANGLES, numAtoms[currentSet]* 3 * solid->nFaces, +#ifndef INDICESGL32 + GL_UNSIGNED_SHORT, +#else + GL_UNSIGNED_INT, +#endif + 0); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("9 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + + } else { + glDrawElements(GL_TRIANGLES, (numAtoms[currentSet]-numAtoms[currentSet-1]) * 3 * solid->nFaces, +#ifndef INDICESGL32 + GL_UNSIGNED_SHORT, (void*)(numAtoms[currentSet-1]*sizeof(unsigned short)*3*solid->nFaces) +#else + GL_UNSIGNED_INT, (void*)(numAtoms[currentSet-1]*sizeof(unsigned int)*3*solid->nFaces) +#endif + ); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("10 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + + } + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after Render Atom timestep =%d: %d\n", currentSet, e); + //now cloned atoms + if (numClonedAtoms!=0 && currentSet==0) { + glBindVertexArray(AtomVAO[1]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, AtomIndices[1]); + glBindBuffer(GL_ARRAY_BUFFER, AtomBuffer[1]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7*sizeof(float), (const void *)0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (const void *)(3*sizeof(float))); + glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (const void *)(6 * sizeof(float))); + + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("5 Gl error RenderAtom timestep =%d: %d\n", currentSet, e); + glDrawElements(GL_TRIANGLES, numClonedAtoms* 3 * solid->nFaces, +#ifndef INDICESGL32 + GL_UNSIGNED_SHORT, +#else + GL_UNSIGNED_INT, +#endif + 0); + + + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after Render cloned Atom timestep =%d: %d\n", currentSet, e); + } // painting cloned atoms + //now bonds + if (numBonds && displaybonds /*&& showAtoms*/) { + glLineWidth(bondThickness); + glBindVertexArray(AtomTVAO[2]); + glUseProgram(UnitCellP); + glUniformMatrix4fv(UnitCellMatrixLoc, 1, GL_FALSE, m); + glUniform4fv(UnitCellColourLoc, 1, bondscolours); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after Render Atom bonds uniform timestep =%d: %d\n", currentSet, e); + if (currentSet==0||fixedAtoms) + glDrawElements(GL_LINES, numBonds[0], GL_UNSIGNED_INT, (void*)0); + else + glDrawElements(GL_LINES, numBonds[currentSet]-numBonds[currentSet-1], GL_UNSIGNED_INT, + (void*)(sizeof(int)*numBonds[currentSet-1]) ); + glLineWidth(1.0f); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after Render Atom bonds timestep =%d: %d\n", currentSet, e); + glBindVertexArray(0); + } + } // no tess +} + +void TreasureHuntRenderer::RenderAtomTrajectories(const gvr::Mat4f eyeViewProjection) +{ + int e; + if (!numAtoms) + return; + gvr::Mat4f sc=ScalingMatrix(scaling); + gvr::Mat4f trans=TranslationMatrix (UserTranslation[0]/scaling, UserTranslation[1]/scaling, UserTranslation[2]/scaling); + const gvr::Mat4f rot={.m={1,0,0,0, 0,0,1,0, 0,-1,0,0, 0,0,0,1}}; + //trans.translate(iPos).rotateX(-90).translate(UserPosition); + gvr::Mat4f transform = MatrixMul(eyeViewProjection, MatrixMul(sc, MatrixMul(trans,rot))); + //gvr::Mat4f transform=eyeViewProjection; + float t[16]; + for (int i=0;i<4;i++) + for (int j=0;j<4;j++) + t[j*4+i]=transform.m[i][j]; + glUseProgram(UnitCellP); + glUniformMatrix4fv(UnitCellMatrixLoc, 1, GL_FALSE, t); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("Gl error after glUniform4fv 1 RenderAtomTrajectories: %d\n", e); + RenderAtomTrajectoriesUnitCell(); + RenderAtoms(t); + RenderMarker(t); +} + +void TreasureHuntRenderer::RenderIsos(const gvr::Mat4f eyeViewProjection, int curDataPos) +{ + GLenum e; + + gvr::Mat4f trans=TranslationMatrix (UserTranslation[0], UserTranslation[1], UserTranslation[2]); + const gvr::Mat4f rot={.m={1,0,0,0, 0,0,1,0, 0,-1,0,0, 0,0,0,1}}; + gvr::Mat4f transform = MatrixMul(eyeViewProjection, MatrixMul(trans,rot)); + + float t[16]; + for (int i=0;i<4;i++) + for (int j=0;j<4;j++) + t[j*4+i]=transform.m[i][j]; + + glUseProgram(ISOP); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("1 Gl error RenderIsos timestep =%d: %d\n", currentSet, e); + glUniformMatrix4fv(ISOMatrixLoc, 1, GL_FALSE, t); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("2 Gl error RenderIsos timestep =%d: %d\n", currentSet, e); + + if (curDataPos!=ISOS) { + glBindVertexArray(ISOVAO[currentSet*ISOS+curDataPos]); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("3 Gl error RenderIsos timestep =%d: %d\n", currentSet, e); + //eprintf ("Drawing %d vertices, isos", numISOIndices[currentSet*ISOS+curDataPos]); + glDrawElements(GL_TRIANGLES,numISOIndices[currentSet*ISOS+curDataPos] , GL_UNSIGNED_INT, 0); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("4 Gl error RenderIsos timestep =%d: %d\n", currentSet, e); + } else { + /*transparency*/ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glDepthMask(GL_FALSE); + for (int i=0;i<ISOS;i++) { + glBindVertexArray(ISOVAO[currentSet*ISOS+i]); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("5 Gl error RenderIsos timestep =%d: %d\n", currentSet, e); + //eprintf ("Drawing %d vertices, isos", numISOIndices[currentSet*ISOS+i]); + glDrawElements(GL_TRIANGLES,numISOIndices[currentSet*ISOS+i] , GL_UNSIGNED_INT, 0); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("6 Gl error RenderIsos timestep =%d: %d\n", currentSet, e); + } + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); + } //if (curDataPos!=ISOS) + //eprintf ("end of RenderIsos"); + glBindVertexArray(0); +} + + +void TreasureHuntRenderer::RenderMarker(const float *m) //m[16] +{ + int e; + if (!markers) + return; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindVertexArray(MarkerVAO); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("b %d", e); + glUseProgram(ISOP); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("c %d", e); + glUniformMatrix4fv(ISOMatrixLoc, 1, GL_FALSE, m); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("d %d, matrixloc=%d, program=%d", e, ISOMatrixLoc, ISOP); + glDrawElements(GL_TRIANGLES, 3*3*MARKERSOLID::nFaces, +#ifndef INDICESGL32 + GL_UNSIGNED_SHORT, (void*)(currentSet*sizeof(unsigned short)*3*3*MARKERSOLID::nFaces + ) +#else + GL_UNSIGNED_INT, (void*)(currentSet*sizeof(unsigned int)*3*3*MARKERSOLID::nFaces + ) +#endif + ); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("e %d", e); + glBindVertexArray(0); + if ((e = glGetError()) != GL_NO_ERROR) + eprintf("f %d", e); + + glDisable(GL_BLEND); +} + +/** + * Converts a raw text file, saved as a resource, into an OpenGL ES shader. + * + * @param type The type of shader we will be creating. + * @param resId The resource ID of the raw text file. + * @return The shader object handler. + */ +int TreasureHuntRenderer::LoadGLShader(int type, const char** shadercode) { + int shader = glCreateShader(type); + glShaderSource(shader, 1, shadercode, nullptr); + glCompileShader(shader); + + // Get the compilation status. + int* compileStatus = new int[1]; + glGetShaderiv(shader, GL_COMPILE_STATUS, compileStatus); + + // If the compilation failed, delete the shader. + if (compileStatus[0] == 0) { + glDeleteShader(shader); + shader = 0; + } + + return shader; +} + +/** + * Draws a frame for an eye. + * + * @param eye The eye to render. Includes all required transformations. + */ +void TreasureHuntRenderer::DrawEye(gvr::Eye eye, const gvr::Mat4f& view_matrix, + const gvr::BufferViewport& params) { + const gvr::Recti pixel_rect = + CalculatePixelSpaceRect(render_size_, params.GetSourceUv()); + + glViewport(pixel_rect.left, pixel_rect.bottom, + pixel_rect.right - pixel_rect.left, + pixel_rect.top - pixel_rect.bottom); + glScissor(pixel_rect.left, pixel_rect.bottom, + pixel_rect.right - pixel_rect.left, + pixel_rect.top - pixel_rect.bottom); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + CheckGLError("ColorParam"); + + // Set the position of the light + gvr::Mat4f perspective = + PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar); + + modelview_ = view_matrix; + modelview_projection_cube_ = MatrixMul(perspective, modelview_); + + //rgh, draw scene here + if(error) + return; + if (has_abc) { + RenderUnitCell(modelview_projection_cube_); + } else { + RenderAtomTrajectories(modelview_projection_cube_); + } + + if (ISOS) + RenderIsos(modelview_projection_cube_, currentIso); + +} + -- GitLab