diff --git a/contrib/ar4dcops/app_android/README.md b/contrib/ar4dcops/app_android/README.md new file mode 100644 index 000000000..4f013b53d --- /dev/null +++ b/contrib/ar4dcops/app_android/README.md @@ -0,0 +1,13 @@ +# App-Android + +An Augmented Reality (AR) based app that runs on Android systems to aid data center maintenance and audit work. It obtains data from +the back-end server Flowgate, which integrates all the information related to a specific data +center, and displays necessary information onto real scenes" in the data center using AR +technology. + +Note: + +Some problems remain before our project period ends. The app might not be very stable because of compability issues (the packages we +use might have some conflicts with ARcore). It may run smoothly +on some Android devices but can crash frequently on some other types of devices. Also, its features are not as comprehensive as the +IOS version. We hope that future developers can try to improve the solution. diff --git a/contrib/ar4dcops/app_android/augmentedimage/.gitignore b/contrib/ar4dcops/app_android/augmentedimage/.gitignore new file mode 100644 index 000000000..863f89cd4 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/.gitignore @@ -0,0 +1,13 @@ +# Android Studio configuration. +*.iml +.idea/ +# +# # Gradle configuration. +.gradle/ +build/ +# +# # User configuration. +local.properties +# +# # OS configurations. +.DS_Store diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/.gitignore b/contrib/ar4dcops/app_android/augmentedimage/app/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/build.gradle b/contrib/ar4dcops/app_android/augmentedimage/app/build.gradle new file mode 100644 index 000000000..266d04375 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/build.gradle @@ -0,0 +1,79 @@ +/* + * Copyright 2018 Google LLC + * 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. + */ + apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "com.google.ar.sceneform.samples.augmentedimage" + + // Sceneform requires minSdkVersion >= 24. + minSdkVersion 24 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + } + // Sceneform libraries use language constructs from Java 8. + // Add these compile options if targeting minSdkVersion < 26. + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.0.0' + implementation 'com.google.android.material:material:1.0.0' + + // Use the Sceneform UX Package pre-built from Maven. + implementation "com.google.ar.sceneform.ux:sceneform-ux:1.15.0" + implementation 'com.google.mlkit:barcode-scanning:16.0.3' + implementation 'com.android.volley:volley:1.1.1' + + // Use the Sceneform UX Package built from the source files included in the sceneformux folder. + //api project(":sceneformux") +} + +apply plugin: 'com.google.ar.sceneform.plugin' + +sceneform.asset('sampledata/models/frame_lower_left.obj', + 'default', + 'sampledata/models/frame_lower_left.sfa', + 'src/main/assets/models/frame_lower_left') + +sceneform.asset('sampledata/models/frame_lower_right.obj', + 'default', + 'sampledata/models/frame_lower_right.sfa', + 'src/main/assets/models/frame_lower_right') + +sceneform.asset('sampledata/models/frame_upper_left.obj', + 'default', + 'sampledata/models/frame_upper_left.sfa', + 'src/main/assets/models/frame_upper_left') + +sceneform.asset('sampledata/models/frame_upper_right.obj', + 'default', + 'sampledata/models/frame_upper_right.sfa', + 'src/main/assets/models/frame_upper_right') diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/proguard-rules.pro b/contrib/ar4dcops/app_android/augmentedimage/app/proguard-rules.pro new file mode 100644 index 000000000..45dc58a59 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /opt/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_base.png b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_base.png new file mode 100644 index 000000000..5fcfa6ea3 Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_base.png differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_left.mtl b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_left.mtl new file mode 100644 index 000000000..27ca7b066 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_left.mtl @@ -0,0 +1,7 @@ +newmtl unlit_material +illum 2 +Kd 0.00 0.00 0.00 +Ka 0.00 0.00 0.00 +Tf 1.00 1.00 1.00 +map_Kd frame_base.png +Ni 1.00 diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_left.obj b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_left.obj new file mode 100644 index 000000000..d7856723e --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_left.obj @@ -0,0 +1,420 @@ +mtllib frame_lower_left.mtl +v 0.019500 0.001781 -0.019500 +v 0.019500 -0.000000 -0.019500 +v 0.009750 0.004591 -0.009750 +v 0.009027 0.005968 -0.009027 +v 0.007902 0.007060 -0.007902 +v 0.006484 0.007761 -0.006484 +v 0.003340 0.007761 -0.003340 +v 0.000000 0.000000 0.000000 +v 0.000000 0.009051 0.000000 +v 0.018467 0.001781 -0.018467 +v 0.014182 0.002906 -0.014182 +v 0.014636 0.002160 -0.014636 +v 0.010457 0.003749 -0.010457 +v 0.002438 0.009051 -0.002438 +v 0.011328 0.003131 -0.011328 +v 0.017860 0.002160 -0.017860 +v 0.016248 0.002488 -0.016248 +v 0.019500 -0.000000 -0.030469 +v 0.019500 0.001781 -0.030469 +v 0.018467 0.001781 -0.031502 +v 0.017860 0.002160 -0.032109 +v 0.016248 0.002488 -0.033721 +v 0.014636 0.002160 -0.035333 +v 0.014182 0.002906 -0.035787 +v 0.011328 0.003131 -0.038641 +v 0.010457 0.003749 -0.039512 +v 0.009750 0.004591 -0.040219 +v 0.009027 0.005968 -0.040942 +v 0.007902 0.007060 -0.042067 +v 0.006484 0.007761 -0.043485 +v 0.003340 0.007761 -0.046629 +v 0.002438 0.009051 -0.047530 +v -0.000000 0.009051 -0.049969 +v -0.000000 0.000000 -0.049969 +v 0.049969 0.000000 0.000000 +v 0.049969 0.009051 0.000000 +v 0.047530 0.009051 -0.002438 +v 0.046629 0.007761 -0.003340 +v 0.043485 0.007761 -0.006484 +v 0.042067 0.007060 -0.007902 +v 0.040941 0.005968 -0.009027 +v 0.040219 0.004591 -0.009750 +v 0.039512 0.003749 -0.010457 +v 0.038641 0.003131 -0.011328 +v 0.035787 0.002906 -0.014182 +v 0.035333 0.002160 -0.014636 +v 0.033721 0.002488 -0.016248 +v 0.032108 0.002160 -0.017860 +v 0.031502 0.001781 -0.018467 +v 0.030469 0.001781 -0.019500 +v 0.030469 -0.000000 -0.019500 +v 0.014182 0.000000 -0.035787 +v 0.009043 0.000000 -0.040926 +v 0.040925 0.000000 -0.009043 +v 0.035787 0.000000 -0.014182 +vt 0.145859 0.175636 +vt 0.155382 0.180635 +vt 0.155382 0.391434 +vt 0.145859 0.396434 +vt 0.138302 0.167849 +vt 0.138302 0.404220 +vt 0.128490 0.158038 +vt 0.128490 0.414032 +vt 0.106738 0.136285 +vt 0.106738 0.435784 +vt 0.212705 0.236748 +vt 0.215329 0.240946 +vt 0.215329 0.331125 +vt 0.212705 0.335323 +vt 0.201550 0.225593 +vt 0.201550 0.346477 +vt 0.190396 0.357632 +vt 0.190396 0.214438 +vt 0.177930 0.148151 +vt 0.398727 0.148152 +vt 0.393727 0.157675 +vt 0.182929 0.157674 +vt 0.170143 0.140594 +vt 0.406513 0.140594 +vt 0.160332 0.130782 +vt 0.416325 0.130783 +vt 0.138579 0.109030 +vt 0.438077 0.109030 +vt 0.250384 0.224766 +vt 0.326272 0.224766 +vt 0.326272 0.237088 +vt 0.250384 0.237088 +vt 0.132344 0.100107 +vt 0.444312 0.100107 +vt 0.363063 0.187527 +vt 0.213593 0.187527 +vt 0.187818 0.163503 +vt 0.388838 0.163504 +vt 0.382812 0.167778 +vt 0.193844 0.167778 +vt 0.239040 0.214997 +vt 0.337616 0.214997 +vt 0.333417 0.217621 +vt 0.243239 0.217621 +vt 0.227886 0.203842 +vt 0.348770 0.203843 +vt 0.216732 0.192688 +vt 0.359924 0.192688 +vt 0.115474 0.083237 +vt 0.461182 0.083237 +vt 0.115474 0.020617 +vt 0.461182 0.020617 +vt 0.080945 0.458889 +vt 0.018325 0.458889 +vt 0.018325 0.113180 +vt 0.080946 0.113180 +vt 0.097815 0.442019 +vt 0.097815 0.130050 +vt 0.161211 0.185524 +vt 0.161211 0.386545 +vt 0.165485 0.380519 +vt 0.165486 0.191551 +vt 0.185235 0.211300 +vt 0.185235 0.360770 +vt 0.222474 0.248091 +vt 0.222473 0.323980 +vt 0.234795 0.323980 +vt 0.234796 0.248091 +vt 0.247360 0.337045 +vt 0.250383 0.332209 +vt 0.264576 0.323980 +vt 0.244751 0.349895 +vt 0.264576 0.366359 +vt 0.247360 0.362743 +vt 0.241415 0.366359 +vt 0.264576 0.407313 +vt 0.239625 0.389107 +vt 0.234701 0.396049 +vt 0.227987 0.401681 +vt 0.217017 0.407440 +vt 0.208312 0.416409 +vt 0.202723 0.427711 +vt 0.202722 0.452768 +vt 0.264577 0.479383 +vt 0.192444 0.459951 +vt 0.192444 0.479383 +vt 0.250383 0.323980 +vt 0.462243 0.198405 +vt 0.481675 0.270537 +vt 0.455060 0.208683 +vt 0.409606 0.270537 +vt 0.430004 0.208683 +vt 0.418702 0.214272 +vt 0.409733 0.222978 +vt 0.403974 0.233947 +vt 0.398342 0.240662 +vt 0.391400 0.245586 +vt 0.368652 0.247375 +vt 0.368652 0.270537 +vt 0.365036 0.253321 +vt 0.352188 0.250711 +vt 0.326272 0.270537 +vt 0.339339 0.253321 +vt 0.334503 0.256343 +vt 0.326272 0.256343 +vt 0.481675 0.198405 +vn 0.766581 0.642148 0.000000 +vn 0.859115 0.511782 -0.000000 +vn 0.859116 0.511782 -0.000000 +vn 0.766582 0.642146 0.000000 +vn 0.517901 0.855441 -0.000000 +vn 0.517901 0.855441 -0.000000 +vn 0.061574 0.998103 -0.000000 +vn 0.061575 0.998103 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.240884 0.970554 0.000001 +vn 0.530016 0.847988 0.000002 +vn 0.530016 0.847988 0.000002 +vn 0.240885 0.970554 0.000001 +vn -0.113066 0.993588 -0.000000 +vn -0.113067 0.993587 -0.000000 +vn -0.199028 0.979994 -0.000000 +vn -0.199028 0.979994 -0.000000 +vn -0.000001 0.642157 -0.766573 +vn -0.000001 0.642157 -0.766573 +vn -0.000001 0.511787 -0.859112 +vn -0.000001 0.511787 -0.859113 +vn -0.000000 0.855445 -0.517893 +vn -0.000000 0.855445 -0.517893 +vn 0.000000 0.998102 -0.061576 +vn 0.000000 0.998102 -0.061576 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.572793 -0.819700 +vn 0.000000 0.572793 -0.819700 +vn 0.000000 0.572793 -0.819700 +vn 0.000000 0.572793 -0.819700 +vn -0.000001 0.694850 -0.719155 +vn -0.000001 0.694849 -0.719155 +vn -0.000000 0.930015 -0.367521 +vn -0.000000 0.930014 -0.367523 +vn -0.000000 0.996920 -0.078425 +vn -0.000000 0.996920 -0.078425 +vn -0.000001 0.970555 -0.240881 +vn -0.000001 0.970555 -0.240881 +vn -0.000002 0.847990 -0.530013 +vn -0.000002 0.847990 -0.530013 +vn 0.000000 0.993588 0.113065 +vn 0.000000 0.993588 0.113064 +vn 0.000000 0.979994 0.199028 +vn 0.000000 0.979994 0.199028 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +vn 0.000006 1.000000 -0.000006 +vn 0.000006 1.000000 -0.000006 +vn -0.000000 1.000000 -0.000012 +vn -0.000000 1.000000 -0.000012 +vn -0.000002 0.519613 -0.854402 +vn -0.000002 0.519613 -0.854402 +vn -0.000002 0.519613 -0.854402 +vn -0.000002 0.519613 -0.854402 +vn 0.000000 1.000000 -0.000006 +vn 0.000000 1.000000 -0.000006 +vn 0.000000 1.000000 -0.000006 +vn 0.000000 1.000000 -0.000006 +vn -1.000000 0.000000 0.000001 +vn -1.000000 0.000000 0.000001 +vn -1.000000 0.000000 0.000001 +vn -1.000000 0.000000 0.000001 +vn 0.000006 1.000000 -0.000000 +vn 0.000006 1.000000 -0.000000 +vn 0.000006 1.000000 -0.000000 +vn 0.000006 1.000000 -0.000000 +vn 0.819683 0.572818 -0.000001 +vn 0.819683 0.572818 -0.000001 +vn 0.819683 0.572818 -0.000001 +vn 0.819683 0.572818 -0.000001 +vn 0.719141 0.694865 -0.000000 +vn 0.719141 0.694864 -0.000000 +vn 0.367513 0.930019 -0.000000 +vn 0.367513 0.930019 -0.000000 +vn 0.078424 0.996920 0.000000 +vn 0.078424 0.996920 0.000000 +vn 0.854431 0.519565 0.000000 +vn 0.854431 0.519565 0.000000 +vn 0.854431 0.519565 0.000000 +vn 0.854431 0.519565 0.000000 +vn 0.000012 1.000000 0.000000 +vn 0.000012 1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.707093 -0.000030 -0.707121 +vn 0.707093 -0.000030 -0.707121 +vn 0.707093 -0.000030 -0.707121 +vn 0.707110 -0.000009 -0.707104 +vn 0.707110 -0.000009 -0.707104 +vn 0.707110 -0.000009 -0.707104 +vn 0.707110 -0.000009 -0.707104 +vn 0.707100 0.000014 -0.707113 +vn 0.707100 0.000014 -0.707113 +vn 0.707100 0.000014 -0.707113 +vn 0.707130 0.000000 -0.707083 +vn 0.707131 0.000000 -0.707083 +vn 0.707130 0.000000 -0.707083 +vn 0.707103 0.000007 -0.707111 +vn 0.707103 0.000007 -0.707111 +vn 0.707103 0.000007 -0.707111 +vn 0.707103 0.000007 -0.707111 +vn 0.707110 0.000004 -0.707103 +vn 0.707110 0.000004 -0.707103 +vn 0.707110 0.000004 -0.707104 +vn 0.707113 0.000004 -0.707101 +vn 0.707113 0.000004 -0.707101 +vn 0.707113 0.000004 -0.707101 +vn 0.707109 0.000004 -0.707105 +vn 0.707109 0.000004 -0.707105 +vn 0.707109 0.000004 -0.707105 +vn 0.707110 0.000004 -0.707103 +vn 0.707110 0.000004 -0.707103 +vn 0.707110 0.000004 -0.707103 +vn 0.707106 0.000003 -0.707108 +vn 0.707106 0.000003 -0.707108 +vn 0.707106 0.000003 -0.707108 +vn 0.707102 0.000002 -0.707111 +vn 0.707102 0.000002 -0.707111 +vn 0.707102 0.000002 -0.707111 +vn 0.707102 0.000002 -0.707111 +vn 0.707107 -0.000000 -0.707106 +vn 0.707107 -0.000000 -0.707106 +vn 0.707107 -0.000000 -0.707106 +vn 0.707107 0.000000 -0.707107 +vn 0.707107 0.000000 -0.707107 +vn 0.707107 0.000000 -0.707107 +vn 0.707126 0.000000 -0.707087 +vn 0.707126 0.000000 -0.707087 +vn 0.707126 0.000000 -0.707087 +vn 0.707115 0.000000 -0.707098 +vn 0.707115 0.000000 -0.707098 +vn 0.707115 0.000000 -0.707098 +vn 0.707092 -0.000015 -0.707121 +vn 0.707092 -0.000015 -0.707121 +vn 0.707092 -0.000015 -0.707121 +vn 0.707111 0.000002 -0.707102 +vn 0.707111 0.000002 -0.707102 +vn 0.707111 0.000002 -0.707103 +vn 0.707111 0.000002 -0.707103 +vn 0.707115 -0.000002 -0.707099 +vn 0.707114 -0.000002 -0.707099 +vn 0.707114 -0.000002 -0.707099 +vn 0.707117 -0.000003 -0.707097 +vn 0.707117 -0.000003 -0.707097 +vn 0.707117 -0.000003 -0.707097 +vn 0.707126 -0.000003 -0.707088 +vn 0.707126 -0.000003 -0.707088 +vn 0.707126 -0.000003 -0.707088 +vn 0.707112 -0.000007 -0.707102 +vn 0.707112 -0.000007 -0.707102 +vn 0.707112 -0.000007 -0.707102 +vn 0.707090 -0.000022 -0.707123 +vn 0.707090 -0.000022 -0.707124 +vn 0.707090 -0.000022 -0.707123 +vn 0.707112 0.000005 -0.707101 +vn 0.707112 0.000005 -0.707101 +vn 0.707112 0.000005 -0.707101 +vn 0.707112 0.000005 -0.707101 +vn 0.707126 0.000000 -0.707088 +vn 0.707126 0.000000 -0.707087 +vn 0.707126 0.000000 -0.707088 +vn 0.707107 -0.000014 -0.707107 +vn 0.707107 -0.000014 -0.707107 +vn 0.707107 -0.000014 -0.707107 +vn 0.707109 -0.000020 -0.707105 +vn 0.707109 -0.000020 -0.707105 +vn 0.707109 -0.000020 -0.707105 +vn 0.707109 -0.000020 -0.707105 +vn 0.707130 -0.000075 -0.707084 +vn 0.707130 -0.000075 -0.707083 +vn 0.707130 -0.000075 -0.707084 +vn 0.707067 0.000000 -0.707147 +vn 0.707067 0.000000 -0.707147 +vn 0.707067 0.000000 -0.707147 +s 1 +f 4/1/1 3/2/2 27/3/3 28/4/4 +f 5/5/5 4/1/1 28/4/4 29/6/6 +f 6/7/7 5/5/5 29/6/6 30/8/8 +f 6/7/7 30/8/8 31/10/9 7/9/10 +s 2 +f 16/11/11 10/12/12 20/13/13 21/14/14 +f 16/11/11 21/14/14 22/16/15 17/15/16 +f 17/15/16 22/16/15 23/17/17 12/18/18 +s 3 +f 4/19/19 41/20/20 42/21/21 3/22/22 +f 5/23/23 40/24/24 41/20/20 4/19/19 +f 6/25/25 39/26/26 40/24/24 5/23/23 +f 39/26/26 6/25/25 7/27/27 38/28/28 +s off +f 1/29/29 50/30/30 51/31/31 2/32/32 +f 14/33/33 37/34/34 38/28/35 7/27/36 +s 3 +f 13/37/37 43/38/38 44/39/39 15/40/40 +f 11/36/41 15/40/40 44/39/39 45/35/42 +s 4 +f 16/41/43 48/42/44 49/43/45 10/44/46 +f 48/42/44 16/41/43 17/45/47 47/46/48 +f 47/46/48 17/45/47 12/47/49 46/48/50 +s off +f 9/49/51 8/51/52 35/52/53 36/50/54 +s 3 +f 13/37/37 3/22/22 42/21/21 43/38/38 +s 5 +f 1/29/55 10/44/56 49/43/57 50/30/58 +s off +f 12/47/59 11/36/60 45/35/61 46/48/62 +f 37/34/63 14/33/64 9/49/65 36/50/66 +f 33/53/67 34/54/68 8/55/69 9/56/70 +f 14/58/71 32/57/72 33/53/73 9/56/74 +f 7/9/75 31/10/76 32/57/77 14/58/78 +s 1 +f 13/59/79 26/60/80 27/3/3 3/2/2 +f 25/61/81 26/60/80 13/59/79 15/62/82 +f 11/63/83 24/64/84 25/61/81 15/62/82 +s off +f 23/17/85 24/64/86 11/63/87 12/18/88 +s 5 +f 1/65/55 19/66/89 20/13/90 10/12/56 +s off +f 18/67/91 19/66/92 1/65/93 2/68/94 +f 21/69/95 20/70/96 18/71/97 +f 18/71/98 52/73/99 22/72/100 21/69/101 +f 52/73/102 23/74/103 22/72/104 +f 24/75/105 23/74/106 52/73/107 +f 53/76/108 25/77/109 24/75/110 52/73/111 +f 26/78/112 25/77/113 53/76/114 +f 27/79/115 26/78/116 53/76/117 +f 28/80/118 27/79/119 53/76/120 +f 29/81/121 28/80/122 53/76/123 +f 30/82/124 29/81/125 53/76/126 +f 53/76/127 34/84/128 31/83/129 30/82/130 +f 32/85/131 31/83/132 34/84/133 +f 34/84/134 33/86/135 32/85/136 +f 18/71/137 20/70/138 19/87/139 +f 35/89/140 37/88/141 36/106/142 +f 38/90/143 37/88/144 35/89/145 +f 54/91/146 39/92/147 38/90/148 35/89/149 +f 40/93/150 39/92/151 54/91/152 +f 41/94/153 40/93/154 54/91/155 +f 42/95/156 41/94/157 54/91/158 +f 43/96/159 42/95/160 54/91/161 +f 44/97/162 43/96/163 54/91/164 +f 54/91/165 55/99/166 45/98/167 44/97/168 +f 46/100/169 45/98/170 55/99/171 +f 55/99/172 47/101/173 46/100/174 +f 51/102/175 48/103/176 47/101/177 55/99/178 +f 49/104/179 48/103/180 51/102/181 +f 49/104/182 51/102/183 50/105/184 diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_left.sfa b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_left.sfa new file mode 100644 index 000000000..5b5086e65 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_left.sfa @@ -0,0 +1,50 @@ +{ + materials: [ + { + name: 'unlit_material', + parameters: [ + { + baseColor: 'frame_base', + }, + { + baseColorTint: [ + 1, + 1, + 1, + 1, + ], + }, + { + metallic: 1, + }, + { + roughness: 1, + }, + { + opacity: null, + }, + ], + source: 'build/sceneform_sdk/default_materials/obj_material.sfm', + }, + ], + model: { + attributes: [ + 'Position', + 'TexCoord', + 'Orientation', + ], + collision: {}, + file: 'sampledata/models/frame_lower_left.obj', + name: 'frame_lower_left', + recenter: 'root', + scale: 1.0006200000000001, + }, + samplers: [ + { + file: 'sampledata/models\\frame_base.png', + name: 'frame_base', + pipeline_name: 'frame_base.png', + }, + ], + version: '0.54:2', +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_right.mtl b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_right.mtl new file mode 100644 index 000000000..27ca7b066 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_right.mtl @@ -0,0 +1,7 @@ +newmtl unlit_material +illum 2 +Kd 0.00 0.00 0.00 +Ka 0.00 0.00 0.00 +Tf 1.00 1.00 1.00 +map_Kd frame_base.png +Ni 1.00 diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_right.obj b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_right.obj new file mode 100644 index 000000000..4be0c4a68 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_right.obj @@ -0,0 +1,420 @@ +mtllib frame_lower_right.mtl +v -0.019500 0.001781 -0.019500 +v -0.019500 -0.000000 -0.019500 +v -0.009750 0.004591 -0.009750 +v -0.009027 0.005968 -0.009027 +v -0.007902 0.007060 -0.007902 +v -0.006484 0.007761 -0.006484 +v -0.003340 0.007761 -0.003340 +v 0.000000 0.000000 0.000000 +v 0.000000 0.009051 0.000000 +v -0.018467 0.001781 -0.018467 +v -0.014182 0.002906 -0.014182 +v -0.014636 0.002160 -0.014636 +v -0.010457 0.003749 -0.010457 +v -0.002438 0.009051 -0.002438 +v -0.011328 0.003131 -0.011328 +v -0.017860 0.002160 -0.017860 +v -0.016248 0.002488 -0.016248 +v -0.030469 -0.000000 -0.019500 +v -0.030469 0.001781 -0.019500 +v -0.031502 0.001781 -0.018467 +v -0.032109 0.002160 -0.017860 +v -0.033721 0.002488 -0.016248 +v -0.035333 0.002160 -0.014636 +v -0.035787 0.002906 -0.014182 +v -0.038641 0.003131 -0.011328 +v -0.039512 0.003749 -0.010457 +v -0.040219 0.004591 -0.009750 +v -0.040942 0.005968 -0.009027 +v -0.042067 0.007060 -0.007902 +v -0.043485 0.007761 -0.006484 +v -0.046629 0.007761 -0.003340 +v -0.047530 0.009051 -0.002438 +v -0.049969 0.009051 0.000000 +v -0.049969 0.000000 0.000000 +v 0.000000 0.000000 -0.049969 +v 0.000000 0.009051 -0.049969 +v -0.002438 0.009051 -0.047530 +v -0.003340 0.007761 -0.046629 +v -0.006484 0.007761 -0.043485 +v -0.007902 0.007060 -0.042067 +v -0.009027 0.005968 -0.040941 +v -0.009750 0.004591 -0.040219 +v -0.010457 0.003749 -0.039512 +v -0.011328 0.003131 -0.038641 +v -0.014182 0.002906 -0.035787 +v -0.014636 0.002160 -0.035333 +v -0.016248 0.002488 -0.033721 +v -0.017860 0.002160 -0.032108 +v -0.018467 0.001781 -0.031502 +v -0.019500 0.001781 -0.030469 +v -0.019500 -0.000000 -0.030469 +v -0.035787 0.000000 -0.014182 +v -0.040926 0.000000 -0.009043 +v -0.009043 0.000000 -0.040925 +v -0.014182 0.000000 -0.035787 +vt 0.824364 0.145859 +vt 0.819365 0.155382 +vt 0.608566 0.155382 +vt 0.603566 0.145859 +vt 0.832151 0.138302 +vt 0.595780 0.138302 +vt 0.841962 0.128490 +vt 0.585968 0.128490 +vt 0.863714 0.106738 +vt 0.564216 0.106738 +vt 0.763252 0.212705 +vt 0.759054 0.215329 +vt 0.668875 0.215329 +vt 0.664677 0.212705 +vt 0.774407 0.201550 +vt 0.653523 0.201550 +vt 0.642368 0.190396 +vt 0.785562 0.190396 +vt 0.851849 0.177930 +vt 0.851848 0.398727 +vt 0.842325 0.393727 +vt 0.842326 0.182929 +vt 0.859406 0.170143 +vt 0.859406 0.406513 +vt 0.869218 0.160332 +vt 0.869217 0.416325 +vt 0.890970 0.138579 +vt 0.890970 0.438077 +vt 0.775234 0.250384 +vt 0.775234 0.326272 +vt 0.762912 0.326272 +vt 0.762912 0.250384 +vt 0.899893 0.132344 +vt 0.899893 0.444312 +vt 0.812473 0.363063 +vt 0.812473 0.213593 +vt 0.836497 0.187818 +vt 0.836496 0.388838 +vt 0.832222 0.382812 +vt 0.832222 0.193844 +vt 0.785003 0.239040 +vt 0.785003 0.337616 +vt 0.782379 0.333417 +vt 0.782379 0.243239 +vt 0.796158 0.227886 +vt 0.796157 0.348770 +vt 0.807312 0.216732 +vt 0.807312 0.359924 +vt 0.916763 0.115474 +vt 0.916763 0.461182 +vt 0.979383 0.115474 +vt 0.979383 0.461182 +vt 0.541111 0.080945 +vt 0.541111 0.018325 +vt 0.886820 0.018325 +vt 0.886820 0.080946 +vt 0.557981 0.097815 +vt 0.869950 0.097815 +vt 0.814476 0.161211 +vt 0.613455 0.161211 +vt 0.619481 0.165485 +vt 0.808449 0.165486 +vt 0.788700 0.185235 +vt 0.639230 0.185235 +vt 0.751909 0.222474 +vt 0.676020 0.222473 +vt 0.676020 0.234795 +vt 0.751909 0.234796 +vt 0.662955 0.247360 +vt 0.667791 0.250383 +vt 0.676020 0.264576 +vt 0.650105 0.244751 +vt 0.633641 0.264576 +vt 0.637257 0.247360 +vt 0.633641 0.241415 +vt 0.592687 0.264576 +vt 0.610893 0.239625 +vt 0.603951 0.234701 +vt 0.598319 0.227987 +vt 0.592560 0.217017 +vt 0.583591 0.208312 +vt 0.572289 0.202723 +vt 0.547232 0.202722 +vt 0.520617 0.264577 +vt 0.540049 0.192444 +vt 0.520617 0.192444 +vt 0.676020 0.250383 +vt 0.801595 0.462243 +vt 0.729463 0.481675 +vt 0.791317 0.455060 +vt 0.729463 0.409606 +vt 0.791317 0.430004 +vt 0.785728 0.418702 +vt 0.777022 0.409733 +vt 0.766053 0.403974 +vt 0.759338 0.398342 +vt 0.754414 0.391400 +vt 0.752625 0.368652 +vt 0.729463 0.368652 +vt 0.746679 0.365036 +vt 0.749289 0.352188 +vt 0.729463 0.326272 +vt 0.746679 0.339339 +vt 0.743657 0.334503 +vt 0.743657 0.326272 +vt 0.801595 0.481675 +vn 0.000000 0.642146 -0.766582 +vn 0.000000 0.511782 -0.859116 +vn 0.000000 0.511782 -0.859116 +vn 0.000000 0.642146 -0.766582 +vn -0.000000 0.855441 -0.517901 +vn -0.000000 0.855441 -0.517901 +vn -0.000000 0.998103 -0.061574 +vn -0.000000 0.998103 -0.061575 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn 0.000001 0.970554 -0.240884 +vn 0.000002 0.847989 -0.530014 +vn 0.000002 0.847989 -0.530014 +vn 0.000001 0.970554 -0.240884 +vn -0.000000 0.993588 0.113066 +vn -0.000000 0.993587 0.113067 +vn -0.000000 0.979994 0.199028 +vn -0.000000 0.979994 0.199028 +vn -0.766576 0.642154 0.000001 +vn -0.766577 0.642153 0.000001 +vn -0.859115 0.511782 0.000002 +vn -0.859116 0.511782 0.000002 +vn -0.517894 0.855445 0.000000 +vn -0.517893 0.855445 0.000000 +vn -0.061577 0.998102 -0.000000 +vn -0.061576 0.998102 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -0.819700 0.572793 -0.000000 +vn -0.819700 0.572793 -0.000000 +vn -0.819700 0.572793 -0.000000 +vn -0.819700 0.572793 -0.000000 +vn -0.719145 0.694860 0.000001 +vn -0.719146 0.694859 0.000001 +vn -0.367521 0.930015 0.000000 +vn -0.367523 0.930014 0.000000 +vn -0.078425 0.996920 0.000000 +vn -0.078425 0.996920 0.000000 +vn -0.240883 0.970554 0.000000 +vn -0.240885 0.970554 0.000000 +vn -0.529995 0.848001 0.000001 +vn -0.529995 0.848001 0.000001 +vn 0.113066 0.993588 -0.000000 +vn 0.113066 0.993587 -0.000000 +vn 0.199028 0.979994 -0.000000 +vn 0.199028 0.979994 -0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -0.000006 1.000000 -0.000006 +vn -0.000006 1.000000 -0.000006 +vn -0.000012 1.000000 0.000000 +vn -0.000012 1.000000 0.000000 +vn -0.854400 0.519615 0.000002 +vn -0.854400 0.519616 0.000002 +vn -0.854400 0.519616 0.000002 +vn -0.854400 0.519615 0.000002 +vn -0.000006 1.000000 -0.000000 +vn -0.000006 1.000000 -0.000000 +vn -0.000006 1.000000 -0.000000 +vn -0.000006 1.000000 -0.000000 +vn 0.000001 0.000000 1.000000 +vn 0.000001 0.000000 1.000000 +vn 0.000001 0.000000 1.000000 +vn 0.000001 0.000000 1.000000 +vn -0.000000 1.000000 -0.000006 +vn -0.000000 1.000000 -0.000006 +vn -0.000000 1.000000 -0.000006 +vn -0.000000 1.000000 -0.000006 +vn -0.000001 0.572818 -0.819683 +vn -0.000001 0.572818 -0.819683 +vn -0.000001 0.572818 -0.819683 +vn -0.000001 0.572818 -0.819683 +vn -0.000000 0.694864 -0.719141 +vn -0.000000 0.694864 -0.719141 +vn -0.000000 0.930019 -0.367513 +vn -0.000000 0.930019 -0.367513 +vn 0.000000 0.996920 -0.078424 +vn 0.000000 0.996920 -0.078424 +vn 0.000000 0.519565 -0.854431 +vn 0.000000 0.519565 -0.854431 +vn 0.000000 0.519565 -0.854431 +vn 0.000000 0.519565 -0.854431 +vn 0.000000 1.000000 -0.000012 +vn 0.000000 1.000000 -0.000012 +vn -0.000000 0.000000 -1.000000 +vn -0.000000 0.000000 -1.000000 +vn -0.000000 0.000000 -1.000000 +vn -0.000000 0.000000 -1.000000 +vn -0.707119 -0.000022 -0.707095 +vn -0.707119 -0.000022 -0.707095 +vn -0.707119 -0.000022 -0.707095 +vn -0.707104 -0.000009 -0.707110 +vn -0.707104 -0.000009 -0.707110 +vn -0.707104 -0.000009 -0.707110 +vn -0.707104 -0.000009 -0.707110 +vn -0.707115 0.000015 -0.707099 +vn -0.707115 0.000015 -0.707099 +vn -0.707115 0.000015 -0.707099 +vn -0.707081 0.000000 -0.707132 +vn -0.707081 0.000000 -0.707132 +vn -0.707081 0.000000 -0.707132 +vn -0.707111 0.000006 -0.707103 +vn -0.707111 0.000006 -0.707103 +vn -0.707111 0.000006 -0.707103 +vn -0.707111 0.000006 -0.707103 +vn -0.707105 0.000005 -0.707109 +vn -0.707105 0.000005 -0.707109 +vn -0.707105 0.000005 -0.707109 +vn -0.707105 0.000003 -0.707109 +vn -0.707105 0.000003 -0.707109 +vn -0.707105 0.000003 -0.707109 +vn -0.707104 0.000004 -0.707110 +vn -0.707104 0.000004 -0.707110 +vn -0.707104 0.000004 -0.707110 +vn -0.707104 0.000004 -0.707109 +vn -0.707104 0.000004 -0.707109 +vn -0.707104 0.000004 -0.707109 +vn -0.707106 0.000003 -0.707108 +vn -0.707106 0.000003 -0.707108 +vn -0.707106 0.000003 -0.707108 +vn -0.707111 0.000002 -0.707102 +vn -0.707111 0.000002 -0.707103 +vn -0.707111 0.000002 -0.707103 +vn -0.707111 0.000002 -0.707102 +vn -0.707106 0.000001 -0.707107 +vn -0.707106 0.000001 -0.707107 +vn -0.707106 0.000001 -0.707107 +vn -0.707107 0.000000 -0.707107 +vn -0.707107 0.000000 -0.707107 +vn -0.707107 0.000000 -0.707107 +vn -0.707087 0.000000 -0.707127 +vn -0.707087 0.000000 -0.707127 +vn -0.707087 0.000000 -0.707127 +vn -0.707098 0.000000 -0.707116 +vn -0.707098 0.000000 -0.707116 +vn -0.707098 0.000000 -0.707116 +vn -0.707123 -0.000013 -0.707090 +vn -0.707123 -0.000013 -0.707090 +vn -0.707123 -0.000013 -0.707090 +vn -0.707102 0.000002 -0.707111 +vn -0.707102 0.000002 -0.707111 +vn -0.707102 0.000002 -0.707111 +vn -0.707102 0.000002 -0.707111 +vn -0.707101 -0.000002 -0.707113 +vn -0.707101 -0.000002 -0.707113 +vn -0.707101 -0.000002 -0.707113 +vn -0.707098 -0.000003 -0.707116 +vn -0.707098 -0.000003 -0.707116 +vn -0.707098 -0.000003 -0.707116 +vn -0.707087 -0.000003 -0.707127 +vn -0.707087 -0.000003 -0.707127 +vn -0.707087 -0.000003 -0.707127 +vn -0.707102 -0.000007 -0.707111 +vn -0.707102 -0.000007 -0.707111 +vn -0.707102 -0.000007 -0.707111 +vn -0.707122 -0.000024 -0.707092 +vn -0.707122 -0.000024 -0.707092 +vn -0.707121 -0.000024 -0.707092 +vn -0.707102 0.000004 -0.707112 +vn -0.707102 0.000004 -0.707112 +vn -0.707102 0.000004 -0.707112 +vn -0.707102 0.000004 -0.707112 +vn -0.707086 0.000000 -0.707127 +vn -0.707086 0.000000 -0.707127 +vn -0.707086 0.000000 -0.707127 +vn -0.707107 -0.000008 -0.707106 +vn -0.707107 -0.000008 -0.707106 +vn -0.707107 -0.000008 -0.707106 +vn -0.707108 -0.000013 -0.707106 +vn -0.707108 -0.000013 -0.707106 +vn -0.707108 -0.000013 -0.707106 +vn -0.707108 -0.000013 -0.707106 +vn -0.707023 -0.000131 -0.707190 +vn -0.707023 -0.000131 -0.707190 +vn -0.707023 -0.000131 -0.707190 +vn -0.707147 0.000000 -0.707067 +vn -0.707147 0.000000 -0.707067 +vn -0.707147 0.000000 -0.707067 +s 1 +f 4/1/1 3/2/2 27/3/3 28/4/4 +f 5/5/5 4/1/1 28/4/4 29/6/6 +f 6/7/7 5/5/5 29/6/6 30/8/8 +f 6/7/7 30/8/8 31/10/9 7/9/10 +s 2 +f 16/11/11 10/12/12 20/13/13 21/14/14 +f 16/11/11 21/14/14 22/16/15 17/15/16 +f 17/15/16 22/16/15 23/17/17 12/18/18 +s 3 +f 4/19/19 41/20/20 42/21/21 3/22/22 +f 5/23/23 40/24/24 41/20/20 4/19/19 +f 6/25/25 39/26/26 40/24/24 5/23/23 +f 39/26/26 6/25/25 7/27/27 38/28/28 +s off +f 1/29/29 50/30/30 51/31/31 2/32/32 +f 14/33/33 37/34/34 38/28/35 7/27/36 +s 3 +f 13/37/37 43/38/38 44/39/39 15/40/40 +f 11/36/41 15/40/40 44/39/39 45/35/42 +s 4 +f 16/41/43 48/42/44 49/43/45 10/44/46 +f 48/42/44 16/41/43 17/45/47 47/46/48 +f 47/46/48 17/45/47 12/47/49 46/48/50 +s off +f 9/49/51 8/51/52 35/52/53 36/50/54 +s 3 +f 13/37/37 3/22/22 42/21/21 43/38/38 +s 5 +f 1/29/55 10/44/56 49/43/57 50/30/58 +s off +f 12/47/59 11/36/60 45/35/61 46/48/62 +f 37/34/63 14/33/64 9/49/65 36/50/66 +f 33/53/67 34/54/68 8/55/69 9/56/70 +f 14/58/71 32/57/72 33/53/73 9/56/74 +f 7/9/75 31/10/76 32/57/77 14/58/78 +s 1 +f 13/59/79 26/60/80 27/3/3 3/2/2 +f 25/61/81 26/60/80 13/59/79 15/62/82 +f 11/63/83 24/64/84 25/61/81 15/62/82 +s off +f 23/17/85 24/64/86 11/63/87 12/18/88 +s 5 +f 1/65/55 19/66/89 20/13/90 10/12/56 +s off +f 18/67/91 19/66/92 1/65/93 2/68/94 +f 21/69/95 20/70/96 18/71/97 +f 18/71/98 52/73/99 22/72/100 21/69/101 +f 52/73/102 23/74/103 22/72/104 +f 24/75/105 23/74/106 52/73/107 +f 53/76/108 25/77/109 24/75/110 52/73/111 +f 26/78/112 25/77/113 53/76/114 +f 27/79/115 26/78/116 53/76/117 +f 28/80/118 27/79/119 53/76/120 +f 29/81/121 28/80/122 53/76/123 +f 30/82/124 29/81/125 53/76/126 +f 53/76/127 34/84/128 31/83/129 30/82/130 +f 32/85/131 31/83/132 34/84/133 +f 34/84/134 33/86/135 32/85/136 +f 18/71/137 20/70/138 19/87/139 +f 35/89/140 37/88/141 36/106/142 +f 38/90/143 37/88/144 35/89/145 +f 54/91/146 39/92/147 38/90/148 35/89/149 +f 40/93/150 39/92/151 54/91/152 +f 41/94/153 40/93/154 54/91/155 +f 42/95/156 41/94/157 54/91/158 +f 43/96/159 42/95/160 54/91/161 +f 44/97/162 43/96/163 54/91/164 +f 54/91/165 55/99/166 45/98/167 44/97/168 +f 46/100/169 45/98/170 55/99/171 +f 55/99/172 47/101/173 46/100/174 +f 51/102/175 48/103/176 47/101/177 55/99/178 +f 49/104/179 48/103/180 51/102/181 +f 49/104/182 51/102/183 50/105/184 diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_right.sfa b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_right.sfa new file mode 100644 index 000000000..3a62bedd1 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_lower_right.sfa @@ -0,0 +1,50 @@ +{ + materials: [ + { + name: 'unlit_material', + parameters: [ + { + baseColor: 'frame_base', + }, + { + baseColorTint: [ + 1, + 1, + 1, + 1, + ], + }, + { + metallic: 1, + }, + { + roughness: 1, + }, + { + opacity: null, + }, + ], + source: 'build/sceneform_sdk/default_materials/obj_material.sfm', + }, + ], + model: { + attributes: [ + 'Position', + 'TexCoord', + 'Orientation', + ], + collision: {}, + file: 'sampledata/models/frame_lower_right.obj', + name: 'frame_lower_right', + recenter: 'root', + scale: 1.0006200000000001, + }, + samplers: [ + { + file: 'sampledata/models\\frame_base.png', + name: 'frame_base', + pipeline_name: 'frame_base.png', + }, + ], + version: '0.54:2', +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_left.mtl b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_left.mtl new file mode 100644 index 000000000..27ca7b066 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_left.mtl @@ -0,0 +1,7 @@ +newmtl unlit_material +illum 2 +Kd 0.00 0.00 0.00 +Ka 0.00 0.00 0.00 +Tf 1.00 1.00 1.00 +map_Kd frame_base.png +Ni 1.00 diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_left.obj b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_left.obj new file mode 100644 index 000000000..5303c9e13 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_left.obj @@ -0,0 +1,420 @@ +mtllib frame_upper_left.mtl +v 0.019500 0.001781 0.019500 +v 0.019500 -0.000000 0.019500 +v 0.009750 0.004591 0.009750 +v 0.009027 0.005968 0.009027 +v 0.007902 0.007060 0.007902 +v 0.006484 0.007761 0.006484 +v 0.003340 0.007761 0.003340 +v 0.000000 0.000000 0.000000 +v 0.000000 0.009051 0.000000 +v 0.018467 0.001781 0.018467 +v 0.014182 0.002906 0.014182 +v 0.014636 0.002160 0.014636 +v 0.010457 0.003749 0.010457 +v 0.002438 0.009051 0.002438 +v 0.011328 0.003131 0.011328 +v 0.017860 0.002160 0.017860 +v 0.016248 0.002488 0.016248 +v 0.030469 -0.000000 0.019500 +v 0.030469 0.001781 0.019500 +v 0.031502 0.001781 0.018467 +v 0.032109 0.002160 0.017860 +v 0.033721 0.002488 0.016248 +v 0.035333 0.002160 0.014636 +v 0.035787 0.002906 0.014182 +v 0.038641 0.003131 0.011328 +v 0.039512 0.003749 0.010457 +v 0.040219 0.004591 0.009750 +v 0.040942 0.005968 0.009027 +v 0.042067 0.007060 0.007902 +v 0.043485 0.007761 0.006484 +v 0.046629 0.007761 0.003340 +v 0.047530 0.009051 0.002438 +v 0.049969 0.009051 -0.000000 +v 0.049969 0.000000 -0.000000 +v 0.000000 0.000000 0.049969 +v 0.000000 0.009051 0.049969 +v 0.002438 0.009051 0.047530 +v 0.003340 0.007761 0.046629 +v 0.006484 0.007761 0.043485 +v 0.007902 0.007060 0.042067 +v 0.009027 0.005968 0.040941 +v 0.009750 0.004591 0.040219 +v 0.010457 0.003749 0.039512 +v 0.011328 0.003131 0.038641 +v 0.014182 0.002906 0.035787 +v 0.014636 0.002160 0.035333 +v 0.016248 0.002488 0.033721 +v 0.017860 0.002160 0.032108 +v 0.018467 0.001781 0.031502 +v 0.019500 0.001781 0.030469 +v 0.019500 -0.000000 0.030469 +v 0.035787 0.000000 0.014182 +v 0.040926 0.000000 0.009043 +v 0.009043 0.000000 0.040925 +v 0.014182 0.000000 0.035787 +vt 0.175636 0.854141 +vt 0.180635 0.844618 +vt 0.391434 0.844618 +vt 0.396434 0.854141 +vt 0.167849 0.861698 +vt 0.404220 0.861698 +vt 0.158038 0.871510 +vt 0.414032 0.871510 +vt 0.136286 0.893262 +vt 0.435784 0.893262 +vt 0.236747 0.787295 +vt 0.240946 0.784671 +vt 0.331125 0.784671 +vt 0.335323 0.787295 +vt 0.225593 0.798450 +vt 0.346477 0.798450 +vt 0.357632 0.809604 +vt 0.214438 0.809604 +vt 0.148151 0.822070 +vt 0.148152 0.601273 +vt 0.157675 0.606273 +vt 0.157674 0.817071 +vt 0.140594 0.829857 +vt 0.140594 0.593487 +vt 0.130782 0.839668 +vt 0.130783 0.583675 +vt 0.109030 0.861421 +vt 0.109030 0.561923 +vt 0.224766 0.749616 +vt 0.224766 0.673728 +vt 0.237088 0.673728 +vt 0.237088 0.749616 +vt 0.100107 0.867656 +vt 0.100107 0.555688 +vt 0.187527 0.636937 +vt 0.187527 0.786407 +vt 0.163503 0.812182 +vt 0.163504 0.611162 +vt 0.167778 0.617188 +vt 0.167778 0.806156 +vt 0.214997 0.760960 +vt 0.214997 0.662384 +vt 0.217621 0.666583 +vt 0.217621 0.756761 +vt 0.203842 0.772114 +vt 0.203843 0.651230 +vt 0.192688 0.783268 +vt 0.192688 0.640076 +vt 0.083237 0.884526 +vt 0.083237 0.538818 +vt 0.020617 0.884526 +vt 0.020617 0.538818 +vt 0.458889 0.919055 +vt 0.458889 0.981675 +vt 0.113180 0.981675 +vt 0.113180 0.919054 +vt 0.442019 0.902185 +vt 0.130050 0.902185 +vt 0.185524 0.838789 +vt 0.386545 0.838789 +vt 0.380519 0.834515 +vt 0.191551 0.834514 +vt 0.211300 0.814765 +vt 0.360770 0.814765 +vt 0.248091 0.777526 +vt 0.323980 0.777527 +vt 0.323980 0.765205 +vt 0.248091 0.765204 +vt 0.337045 0.752640 +vt 0.332209 0.749617 +vt 0.323980 0.735424 +vt 0.349895 0.755249 +vt 0.366359 0.735424 +vt 0.362743 0.752640 +vt 0.366359 0.758585 +vt 0.407313 0.735424 +vt 0.389107 0.760375 +vt 0.396049 0.765299 +vt 0.401681 0.772013 +vt 0.407440 0.782983 +vt 0.416409 0.791688 +vt 0.427711 0.797277 +vt 0.452768 0.797278 +vt 0.479383 0.735423 +vt 0.459951 0.807556 +vt 0.479383 0.807556 +vt 0.323980 0.749617 +vt 0.198405 0.537757 +vt 0.270537 0.518325 +vt 0.208683 0.544940 +vt 0.270537 0.590394 +vt 0.208683 0.569996 +vt 0.214272 0.581298 +vt 0.222978 0.590267 +vt 0.233947 0.596026 +vt 0.240662 0.601658 +vt 0.245586 0.608600 +vt 0.247375 0.631348 +vt 0.270537 0.631348 +vt 0.253321 0.634964 +vt 0.250711 0.647812 +vt 0.270537 0.673728 +vt 0.253321 0.660661 +vt 0.256343 0.665497 +vt 0.256343 0.673728 +vt 0.198405 0.518325 +vn 0.000000 0.642146 0.766582 +vn 0.000000 0.511782 0.859116 +vn 0.000000 0.511782 0.859116 +vn 0.000000 0.642146 0.766582 +vn 0.000000 0.855441 0.517901 +vn 0.000000 0.855441 0.517901 +vn 0.000000 0.998103 0.061574 +vn 0.000000 0.998103 0.061575 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.000001 0.970554 0.240884 +vn -0.000002 0.847989 0.530014 +vn -0.000002 0.847989 0.530014 +vn -0.000001 0.970554 0.240884 +vn 0.000000 0.993588 -0.113066 +vn 0.000000 0.993587 -0.113067 +vn 0.000000 0.979994 -0.199028 +vn 0.000000 0.979994 -0.199028 +vn 0.766576 0.642154 -0.000001 +vn 0.766577 0.642153 -0.000001 +vn 0.859115 0.511782 -0.000002 +vn 0.859116 0.511782 -0.000002 +vn 0.517894 0.855445 -0.000000 +vn 0.517893 0.855445 -0.000000 +vn 0.061577 0.998102 0.000000 +vn 0.061576 0.998102 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.819700 0.572793 0.000000 +vn 0.819700 0.572793 0.000000 +vn 0.819700 0.572793 0.000000 +vn 0.819700 0.572793 0.000000 +vn 0.719145 0.694860 -0.000001 +vn 0.719146 0.694859 -0.000001 +vn 0.367521 0.930015 -0.000000 +vn 0.367523 0.930014 -0.000000 +vn 0.078425 0.996920 -0.000000 +vn 0.078425 0.996920 -0.000000 +vn 0.240883 0.970554 -0.000000 +vn 0.240885 0.970554 -0.000000 +vn 0.529995 0.848001 -0.000001 +vn 0.529995 0.848001 -0.000001 +vn -0.113066 0.993588 0.000000 +vn -0.113066 0.993587 0.000000 +vn -0.199028 0.979994 0.000000 +vn -0.199028 0.979994 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000006 1.000000 0.000006 +vn 0.000006 1.000000 0.000006 +vn 0.000012 1.000000 -0.000000 +vn 0.000012 1.000000 -0.000000 +vn 0.854400 0.519615 -0.000002 +vn 0.854400 0.519616 -0.000002 +vn 0.854400 0.519616 -0.000002 +vn 0.854400 0.519615 -0.000002 +vn 0.000006 1.000000 0.000000 +vn 0.000006 1.000000 0.000000 +vn 0.000006 1.000000 0.000000 +vn 0.000006 1.000000 0.000000 +vn -0.000001 0.000000 -1.000000 +vn -0.000001 0.000000 -1.000000 +vn -0.000001 0.000000 -1.000000 +vn -0.000001 0.000000 -1.000000 +vn 0.000000 1.000000 0.000006 +vn 0.000000 1.000000 0.000006 +vn 0.000000 1.000000 0.000006 +vn 0.000000 1.000000 0.000006 +vn 0.000001 0.572818 0.819683 +vn 0.000001 0.572818 0.819683 +vn 0.000001 0.572818 0.819683 +vn 0.000001 0.572818 0.819683 +vn 0.000000 0.694864 0.719141 +vn 0.000000 0.694864 0.719141 +vn 0.000000 0.930019 0.367513 +vn 0.000000 0.930019 0.367513 +vn 0.000000 0.996920 0.078424 +vn 0.000000 0.996920 0.078424 +vn 0.000000 0.519565 0.854431 +vn 0.000000 0.519565 0.854431 +vn 0.000000 0.519565 0.854431 +vn 0.000000 0.519565 0.854431 +vn -0.000000 1.000000 0.000012 +vn -0.000000 1.000000 0.000012 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.707119 -0.000022 0.707095 +vn 0.707119 -0.000022 0.707095 +vn 0.707119 -0.000022 0.707095 +vn 0.707104 -0.000009 0.707110 +vn 0.707104 -0.000009 0.707110 +vn 0.707104 -0.000009 0.707110 +vn 0.707104 -0.000009 0.707110 +vn 0.707115 0.000015 0.707099 +vn 0.707115 0.000015 0.707099 +vn 0.707115 0.000015 0.707099 +vn 0.707081 0.000000 0.707132 +vn 0.707081 0.000000 0.707132 +vn 0.707081 0.000000 0.707132 +vn 0.707111 0.000006 0.707103 +vn 0.707111 0.000006 0.707103 +vn 0.707111 0.000006 0.707103 +vn 0.707111 0.000006 0.707103 +vn 0.707105 0.000005 0.707109 +vn 0.707105 0.000005 0.707109 +vn 0.707105 0.000005 0.707109 +vn 0.707105 0.000003 0.707109 +vn 0.707105 0.000003 0.707109 +vn 0.707105 0.000003 0.707109 +vn 0.707104 0.000004 0.707110 +vn 0.707104 0.000004 0.707110 +vn 0.707104 0.000004 0.707110 +vn 0.707104 0.000004 0.707109 +vn 0.707104 0.000004 0.707109 +vn 0.707104 0.000004 0.707109 +vn 0.707106 0.000003 0.707108 +vn 0.707106 0.000003 0.707108 +vn 0.707106 0.000003 0.707108 +vn 0.707111 0.000002 0.707102 +vn 0.707111 0.000002 0.707103 +vn 0.707111 0.000002 0.707103 +vn 0.707111 0.000002 0.707102 +vn 0.707106 0.000001 0.707107 +vn 0.707106 0.000001 0.707107 +vn 0.707106 0.000001 0.707107 +vn 0.707107 0.000000 0.707107 +vn 0.707107 0.000000 0.707107 +vn 0.707107 0.000000 0.707107 +vn 0.707087 0.000000 0.707127 +vn 0.707087 0.000000 0.707127 +vn 0.707087 0.000000 0.707127 +vn 0.707098 0.000000 0.707116 +vn 0.707098 0.000000 0.707116 +vn 0.707098 0.000000 0.707116 +vn 0.707123 -0.000013 0.707090 +vn 0.707123 -0.000013 0.707090 +vn 0.707123 -0.000013 0.707090 +vn 0.707102 0.000002 0.707111 +vn 0.707102 0.000002 0.707111 +vn 0.707102 0.000002 0.707111 +vn 0.707102 0.000002 0.707111 +vn 0.707101 -0.000002 0.707113 +vn 0.707101 -0.000002 0.707113 +vn 0.707101 -0.000002 0.707113 +vn 0.707098 -0.000003 0.707116 +vn 0.707098 -0.000003 0.707116 +vn 0.707098 -0.000003 0.707116 +vn 0.707087 -0.000003 0.707127 +vn 0.707087 -0.000003 0.707127 +vn 0.707087 -0.000003 0.707127 +vn 0.707102 -0.000007 0.707111 +vn 0.707102 -0.000007 0.707111 +vn 0.707102 -0.000007 0.707111 +vn 0.707122 -0.000024 0.707092 +vn 0.707122 -0.000024 0.707092 +vn 0.707121 -0.000024 0.707092 +vn 0.707102 0.000004 0.707112 +vn 0.707102 0.000004 0.707112 +vn 0.707102 0.000004 0.707112 +vn 0.707102 0.000004 0.707112 +vn 0.707086 0.000000 0.707127 +vn 0.707086 0.000000 0.707127 +vn 0.707086 0.000000 0.707127 +vn 0.707107 -0.000008 0.707106 +vn 0.707107 -0.000008 0.707106 +vn 0.707107 -0.000008 0.707106 +vn 0.707108 -0.000013 0.707106 +vn 0.707108 -0.000013 0.707106 +vn 0.707108 -0.000013 0.707106 +vn 0.707108 -0.000013 0.707106 +vn 0.707023 -0.000131 0.707190 +vn 0.707023 -0.000131 0.707190 +vn 0.707023 -0.000131 0.707190 +vn 0.707147 0.000000 0.707067 +vn 0.707147 0.000000 0.707067 +vn 0.707147 0.000000 0.707067 +s 1 +f 4/1/1 3/2/2 27/3/3 28/4/4 +f 5/5/5 4/1/1 28/4/4 29/6/6 +f 6/7/7 5/5/5 29/6/6 30/8/8 +f 6/7/7 30/8/8 31/10/9 7/9/10 +s 2 +f 16/11/11 10/12/12 20/13/13 21/14/14 +f 16/11/11 21/14/14 22/16/15 17/15/16 +f 17/15/16 22/16/15 23/17/17 12/18/18 +s 3 +f 4/19/19 41/20/20 42/21/21 3/22/22 +f 5/23/23 40/24/24 41/20/20 4/19/19 +f 6/25/25 39/26/26 40/24/24 5/23/23 +f 39/26/26 6/25/25 7/27/27 38/28/28 +s off +f 1/29/29 50/30/30 51/31/31 2/32/32 +f 14/33/33 37/34/34 38/28/35 7/27/36 +s 3 +f 13/37/37 43/38/38 44/39/39 15/40/40 +f 11/36/41 15/40/40 44/39/39 45/35/42 +s 4 +f 16/41/43 48/42/44 49/43/45 10/44/46 +f 48/42/44 16/41/43 17/45/47 47/46/48 +f 47/46/48 17/45/47 12/47/49 46/48/50 +s off +f 9/49/51 8/51/52 35/52/53 36/50/54 +s 3 +f 13/37/37 3/22/22 42/21/21 43/38/38 +s 5 +f 1/29/55 10/44/56 49/43/57 50/30/58 +s off +f 12/47/59 11/36/60 45/35/61 46/48/62 +f 37/34/63 14/33/64 9/49/65 36/50/66 +f 33/53/67 34/54/68 8/55/69 9/56/70 +f 14/58/71 32/57/72 33/53/73 9/56/74 +f 7/9/75 31/10/76 32/57/77 14/58/78 +s 1 +f 13/59/79 26/60/80 27/3/3 3/2/2 +f 25/61/81 26/60/80 13/59/79 15/62/82 +f 11/63/83 24/64/84 25/61/81 15/62/82 +s off +f 23/17/85 24/64/86 11/63/87 12/18/88 +s 5 +f 1/65/55 19/66/89 20/13/90 10/12/56 +s off +f 18/67/91 19/66/92 1/65/93 2/68/94 +f 21/69/95 20/70/96 18/71/97 +f 18/71/98 52/73/99 22/72/100 21/69/101 +f 52/73/102 23/74/103 22/72/104 +f 24/75/105 23/74/106 52/73/107 +f 53/76/108 25/77/109 24/75/110 52/73/111 +f 26/78/112 25/77/113 53/76/114 +f 27/79/115 26/78/116 53/76/117 +f 28/80/118 27/79/119 53/76/120 +f 29/81/121 28/80/122 53/76/123 +f 30/82/124 29/81/125 53/76/126 +f 53/76/127 34/84/128 31/83/129 30/82/130 +f 32/85/131 31/83/132 34/84/133 +f 34/84/134 33/86/135 32/85/136 +f 18/71/137 20/70/138 19/87/139 +f 35/89/140 37/88/141 36/106/142 +f 38/90/143 37/88/144 35/89/145 +f 54/91/146 39/92/147 38/90/148 35/89/149 +f 40/93/150 39/92/151 54/91/152 +f 41/94/153 40/93/154 54/91/155 +f 42/95/156 41/94/157 54/91/158 +f 43/96/159 42/95/160 54/91/161 +f 44/97/162 43/96/163 54/91/164 +f 54/91/165 55/99/166 45/98/167 44/97/168 +f 46/100/169 45/98/170 55/99/171 +f 55/99/172 47/101/173 46/100/174 +f 51/102/175 48/103/176 47/101/177 55/99/178 +f 49/104/179 48/103/180 51/102/181 +f 49/104/182 51/102/183 50/105/184 diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_left.sfa b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_left.sfa new file mode 100644 index 000000000..b3d85cfc1 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_left.sfa @@ -0,0 +1,50 @@ +{ + materials: [ + { + name: 'unlit_material', + parameters: [ + { + baseColor: 'frame_base', + }, + { + baseColorTint: [ + 1, + 1, + 1, + 1, + ], + }, + { + metallic: 1, + }, + { + roughness: 1, + }, + { + opacity: null, + }, + ], + source: 'build/sceneform_sdk/default_materials/obj_material.sfm', + }, + ], + model: { + attributes: [ + 'Position', + 'TexCoord', + 'Orientation', + ], + collision: {}, + file: 'sampledata/models/frame_upper_left.obj', + name: 'frame_upper_left', + recenter: 'root', + scale: 1.0006200000000001, + }, + samplers: [ + { + file: 'sampledata/models\\frame_base.png', + name: 'frame_base', + pipeline_name: 'frame_base.png', + }, + ], + version: '0.54:2', +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_right.mtl b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_right.mtl new file mode 100644 index 000000000..27ca7b066 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_right.mtl @@ -0,0 +1,7 @@ +newmtl unlit_material +illum 2 +Kd 0.00 0.00 0.00 +Ka 0.00 0.00 0.00 +Tf 1.00 1.00 1.00 +map_Kd frame_base.png +Ni 1.00 diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_right.obj b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_right.obj new file mode 100644 index 000000000..3b4863c4c --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_right.obj @@ -0,0 +1,420 @@ +mtllib frame_upper_right.mtl +v -0.019500 0.001781 0.019500 +v -0.019500 -0.000000 0.019500 +v -0.009750 0.004591 0.009750 +v -0.009027 0.005968 0.009027 +v -0.007902 0.007060 0.007902 +v -0.006484 0.007761 0.006484 +v -0.003340 0.007761 0.003340 +v 0.000000 0.000000 0.000000 +v 0.000000 0.009051 0.000000 +v -0.018467 0.001781 0.018467 +v -0.014182 0.002906 0.014182 +v -0.014636 0.002160 0.014636 +v -0.010457 0.003749 0.010457 +v -0.002438 0.009051 0.002438 +v -0.011328 0.003131 0.011328 +v -0.017860 0.002160 0.017860 +v -0.016248 0.002488 0.016248 +v -0.019500 -0.000000 0.030469 +v -0.019500 0.001781 0.030469 +v -0.018467 0.001781 0.031502 +v -0.017860 0.002160 0.032109 +v -0.016248 0.002488 0.033721 +v -0.014636 0.002160 0.035333 +v -0.014182 0.002906 0.035787 +v -0.011328 0.003131 0.038641 +v -0.010457 0.003749 0.039512 +v -0.009750 0.004591 0.040219 +v -0.009027 0.005968 0.040942 +v -0.007902 0.007060 0.042067 +v -0.006484 0.007761 0.043485 +v -0.003340 0.007761 0.046629 +v -0.002438 0.009051 0.047530 +v 0.000000 0.009051 0.049969 +v 0.000000 0.000000 0.049969 +v -0.049969 0.000000 0.000000 +v -0.049969 0.009051 0.000000 +v -0.047530 0.009051 0.002438 +v -0.046629 0.007761 0.003340 +v -0.043485 0.007761 0.006484 +v -0.042067 0.007060 0.007902 +v -0.040941 0.005968 0.009027 +v -0.040219 0.004591 0.009750 +v -0.039512 0.003749 0.010457 +v -0.038641 0.003131 0.011328 +v -0.035787 0.002906 0.014182 +v -0.035333 0.002160 0.014636 +v -0.033721 0.002488 0.016248 +v -0.032108 0.002160 0.017860 +v -0.031502 0.001781 0.018467 +v -0.030469 0.001781 0.019500 +v -0.030469 -0.000000 0.019500 +v -0.014182 0.000000 0.035787 +v -0.009043 0.000000 0.040926 +v -0.040925 0.000000 0.009043 +v -0.035787 0.000000 0.014182 +vt 0.854141 0.824364 +vt 0.844618 0.819365 +vt 0.844618 0.608566 +vt 0.854141 0.603566 +vt 0.861698 0.832151 +vt 0.861698 0.595780 +vt 0.871510 0.841962 +vt 0.871510 0.585968 +vt 0.893262 0.863714 +vt 0.893262 0.564216 +vt 0.787295 0.763252 +vt 0.784671 0.759054 +vt 0.784671 0.668875 +vt 0.787295 0.664677 +vt 0.798450 0.774407 +vt 0.798450 0.653523 +vt 0.809604 0.642368 +vt 0.809604 0.785562 +vt 0.822070 0.851849 +vt 0.601273 0.851848 +vt 0.606273 0.842325 +vt 0.817071 0.842326 +vt 0.829857 0.859406 +vt 0.593487 0.859406 +vt 0.839668 0.869218 +vt 0.583675 0.869217 +vt 0.861421 0.890970 +vt 0.561923 0.890970 +vt 0.749616 0.775234 +vt 0.673728 0.775234 +vt 0.673728 0.762912 +vt 0.749616 0.762912 +vt 0.867656 0.899893 +vt 0.555688 0.899893 +vt 0.636937 0.812473 +vt 0.786407 0.812473 +vt 0.812182 0.836497 +vt 0.611162 0.836496 +vt 0.617188 0.832222 +vt 0.806156 0.832222 +vt 0.760960 0.785003 +vt 0.662384 0.785003 +vt 0.666583 0.782379 +vt 0.756761 0.782379 +vt 0.772114 0.796158 +vt 0.651230 0.796157 +vt 0.783268 0.807312 +vt 0.640076 0.807312 +vt 0.884526 0.916763 +vt 0.538818 0.916763 +vt 0.884526 0.979383 +vt 0.538818 0.979383 +vt 0.919055 0.541111 +vt 0.981675 0.541111 +vt 0.981675 0.886820 +vt 0.919054 0.886820 +vt 0.902185 0.557981 +vt 0.902185 0.869950 +vt 0.838789 0.814476 +vt 0.838789 0.613455 +vt 0.834515 0.619481 +vt 0.834514 0.808449 +vt 0.814765 0.788700 +vt 0.814765 0.639230 +vt 0.777526 0.751909 +vt 0.777527 0.676020 +vt 0.765205 0.676020 +vt 0.765204 0.751909 +vt 0.752640 0.662955 +vt 0.749617 0.667791 +vt 0.735424 0.676020 +vt 0.755249 0.650105 +vt 0.735424 0.633641 +vt 0.752640 0.637257 +vt 0.758585 0.633641 +vt 0.735424 0.592687 +vt 0.760375 0.610893 +vt 0.765299 0.603951 +vt 0.772013 0.598319 +vt 0.782983 0.592560 +vt 0.791688 0.583591 +vt 0.797277 0.572289 +vt 0.797278 0.547232 +vt 0.735423 0.520617 +vt 0.807556 0.540049 +vt 0.807556 0.520617 +vt 0.749617 0.676020 +vt 0.537757 0.801595 +vt 0.518325 0.729463 +vt 0.544940 0.791317 +vt 0.590394 0.729463 +vt 0.569996 0.791317 +vt 0.581298 0.785728 +vt 0.590267 0.777022 +vt 0.596026 0.766053 +vt 0.601658 0.759338 +vt 0.608600 0.754414 +vt 0.631348 0.752625 +vt 0.631348 0.729463 +vt 0.634964 0.746679 +vt 0.647812 0.749289 +vt 0.673728 0.729463 +vt 0.660661 0.746679 +vt 0.665497 0.743657 +vt 0.673728 0.743657 +vt 0.518325 0.801595 +vn -0.766579 0.642150 0.000000 +vn -0.859113 0.511787 0.000001 +vn -0.859112 0.511787 0.000001 +vn -0.766579 0.642150 0.000000 +vn -0.517895 0.855444 0.000001 +vn -0.517895 0.855444 0.000001 +vn -0.061575 0.998103 0.000000 +vn -0.061576 0.998102 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.240884 0.970554 -0.000001 +vn -0.530016 0.847988 -0.000002 +vn -0.530016 0.847988 -0.000002 +vn -0.240885 0.970554 -0.000001 +vn 0.113066 0.993588 0.000000 +vn 0.113067 0.993587 0.000000 +vn 0.199028 0.979994 0.000000 +vn 0.199028 0.979994 0.000000 +vn 0.000001 0.642156 0.766574 +vn 0.000001 0.642153 0.766576 +vn 0.000002 0.511782 0.859115 +vn 0.000002 0.511782 0.859115 +vn 0.000000 0.855445 0.517893 +vn 0.000000 0.855445 0.517893 +vn -0.000000 0.998102 0.061576 +vn -0.000000 0.998102 0.061576 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 1.000000 +vn -0.000000 0.572793 0.819700 +vn -0.000000 0.572793 0.819700 +vn -0.000000 0.572793 0.819700 +vn -0.000000 0.572793 0.819700 +vn 0.000001 0.694861 0.719144 +vn 0.000001 0.694860 0.719145 +vn 0.000000 0.930015 0.367521 +vn 0.000000 0.930014 0.367523 +vn 0.000000 0.996920 0.078425 +vn 0.000000 0.996920 0.078425 +vn 0.000000 0.970554 0.240883 +vn 0.000000 0.970554 0.240885 +vn 0.000001 0.848001 0.529995 +vn 0.000001 0.848001 0.529995 +vn -0.000000 0.993588 -0.113066 +vn -0.000000 0.993587 -0.113066 +vn -0.000000 0.979994 -0.199028 +vn -0.000000 0.979994 -0.199028 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 -1.000000 +vn -0.000006 1.000000 0.000006 +vn -0.000006 1.000000 0.000006 +vn 0.000000 1.000000 0.000012 +vn 0.000000 1.000000 0.000012 +vn 0.000002 0.519613 0.854402 +vn 0.000002 0.519613 0.854402 +vn 0.000002 0.519613 0.854402 +vn 0.000002 0.519613 0.854402 +vn -0.000000 1.000000 0.000006 +vn -0.000000 1.000000 0.000006 +vn -0.000000 1.000000 0.000006 +vn -0.000000 1.000000 0.000006 +vn 1.000000 0.000000 -0.000001 +vn 1.000000 0.000000 -0.000001 +vn 1.000000 0.000000 -0.000001 +vn 1.000000 0.000000 -0.000001 +vn -0.000006 1.000000 0.000000 +vn -0.000006 1.000000 0.000000 +vn -0.000006 1.000000 0.000000 +vn -0.000006 1.000000 0.000000 +vn -0.819683 0.572818 0.000001 +vn -0.819683 0.572818 0.000001 +vn -0.819683 0.572818 0.000001 +vn -0.819683 0.572818 0.000001 +vn -0.719151 0.694854 0.000001 +vn -0.719151 0.694854 0.000001 +vn -0.367513 0.930019 0.000000 +vn -0.367513 0.930019 0.000000 +vn -0.078424 0.996920 0.000000 +vn -0.078424 0.996920 0.000000 +vn -0.854431 0.519565 0.000000 +vn -0.854431 0.519565 0.000000 +vn -0.854431 0.519565 0.000000 +vn -0.854431 0.519565 0.000000 +vn -0.000012 1.000000 -0.000000 +vn -0.000012 1.000000 -0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -1.000000 0.000000 0.000000 +vn -0.707093 -0.000030 0.707121 +vn -0.707093 -0.000030 0.707121 +vn -0.707093 -0.000030 0.707121 +vn -0.707110 -0.000009 0.707104 +vn -0.707110 -0.000009 0.707104 +vn -0.707110 -0.000009 0.707104 +vn -0.707110 -0.000009 0.707104 +vn -0.707100 0.000014 0.707113 +vn -0.707100 0.000014 0.707113 +vn -0.707100 0.000014 0.707113 +vn -0.707130 0.000000 0.707083 +vn -0.707131 0.000000 0.707083 +vn -0.707130 0.000000 0.707083 +vn -0.707103 0.000007 0.707111 +vn -0.707103 0.000007 0.707111 +vn -0.707103 0.000007 0.707111 +vn -0.707103 0.000007 0.707111 +vn -0.707110 0.000004 0.707103 +vn -0.707110 0.000004 0.707103 +vn -0.707110 0.000004 0.707104 +vn -0.707113 0.000004 0.707101 +vn -0.707113 0.000004 0.707101 +vn -0.707113 0.000004 0.707101 +vn -0.707109 0.000004 0.707105 +vn -0.707109 0.000004 0.707105 +vn -0.707109 0.000004 0.707105 +vn -0.707110 0.000004 0.707103 +vn -0.707110 0.000004 0.707103 +vn -0.707110 0.000004 0.707103 +vn -0.707090 -0.000002 0.707124 +vn -0.707090 -0.000002 0.707124 +vn -0.707090 -0.000002 0.707124 +vn -0.707104 0.000004 0.707110 +vn -0.707104 0.000004 0.707110 +vn -0.707104 0.000004 0.707110 +vn -0.707104 0.000004 0.707110 +vn -0.707107 -0.000000 0.707106 +vn -0.707107 -0.000000 0.707106 +vn -0.707107 -0.000000 0.707106 +vn -0.707107 0.000000 0.707107 +vn -0.707107 0.000000 0.707107 +vn -0.707107 0.000000 0.707107 +vn -0.707126 0.000000 0.707087 +vn -0.707126 0.000000 0.707087 +vn -0.707126 0.000000 0.707087 +vn -0.707115 -0.000000 0.707098 +vn -0.707115 -0.000000 0.707098 +vn -0.707115 -0.000000 0.707098 +vn -0.707092 -0.000015 0.707121 +vn -0.707092 -0.000015 0.707121 +vn -0.707092 -0.000015 0.707121 +vn -0.707110 0.000001 0.707103 +vn -0.707110 0.000001 0.707103 +vn -0.707110 0.000001 0.707103 +vn -0.707110 0.000001 0.707103 +vn -0.707115 -0.000006 0.707098 +vn -0.707115 -0.000006 0.707098 +vn -0.707115 -0.000006 0.707098 +vn -0.707118 -0.000007 0.707095 +vn -0.707118 -0.000007 0.707095 +vn -0.707118 -0.000007 0.707095 +vn -0.707129 -0.000007 0.707084 +vn -0.707129 -0.000007 0.707084 +vn -0.707129 -0.000007 0.707084 +vn -0.707114 -0.000012 0.707100 +vn -0.707114 -0.000012 0.707100 +vn -0.707114 -0.000012 0.707100 +vn -0.707092 -0.000027 0.707122 +vn -0.707092 -0.000027 0.707122 +vn -0.707092 -0.000027 0.707122 +vn -0.707113 0.000003 0.707100 +vn -0.707114 0.000003 0.707100 +vn -0.707113 0.000003 0.707100 +vn -0.707113 0.000003 0.707100 +vn -0.707126 0.000000 0.707088 +vn -0.707126 0.000000 0.707087 +vn -0.707126 0.000000 0.707088 +vn -0.707107 -0.000014 0.707107 +vn -0.707107 -0.000014 0.707107 +vn -0.707107 -0.000014 0.707107 +vn -0.707105 -0.000013 0.707108 +vn -0.707105 -0.000013 0.707108 +vn -0.707105 -0.000013 0.707108 +vn -0.707105 -0.000013 0.707108 +vn -0.707186 -0.000134 0.707028 +vn -0.707186 -0.000134 0.707027 +vn -0.707186 -0.000134 0.707027 +vn -0.707067 0.000000 0.707147 +vn -0.707067 0.000000 0.707147 +vn -0.707067 0.000000 0.707147 +s 1 +f 4/1/1 3/2/2 27/3/3 28/4/4 +f 5/5/5 4/1/1 28/4/4 29/6/6 +f 6/7/7 5/5/5 29/6/6 30/8/8 +f 6/7/7 30/8/8 31/10/9 7/9/10 +s 2 +f 16/11/11 10/12/12 20/13/13 21/14/14 +f 16/11/11 21/14/14 22/16/15 17/15/16 +f 17/15/16 22/16/15 23/17/17 12/18/18 +s 3 +f 4/19/19 41/20/20 42/21/21 3/22/22 +f 5/23/23 40/24/24 41/20/20 4/19/19 +f 6/25/25 39/26/26 40/24/24 5/23/23 +f 39/26/26 6/25/25 7/27/27 38/28/28 +s off +f 1/29/29 50/30/30 51/31/31 2/32/32 +f 14/33/33 37/34/34 38/28/35 7/27/36 +s 3 +f 13/37/37 43/38/38 44/39/39 15/40/40 +f 11/36/41 15/40/40 44/39/39 45/35/42 +s 4 +f 16/41/43 48/42/44 49/43/45 10/44/46 +f 48/42/44 16/41/43 17/45/47 47/46/48 +f 47/46/48 17/45/47 12/47/49 46/48/50 +s off +f 9/49/51 8/51/52 35/52/53 36/50/54 +s 3 +f 13/37/37 3/22/22 42/21/21 43/38/38 +s 5 +f 1/29/55 10/44/56 49/43/57 50/30/58 +s off +f 12/47/59 11/36/60 45/35/61 46/48/62 +f 37/34/63 14/33/64 9/49/65 36/50/66 +f 33/53/67 34/54/68 8/55/69 9/56/70 +f 14/58/71 32/57/72 33/53/73 9/56/74 +f 7/9/75 31/10/76 32/57/77 14/58/78 +s 1 +f 13/59/79 26/60/80 27/3/3 3/2/2 +f 25/61/81 26/60/80 13/59/79 15/62/82 +f 11/63/83 24/64/84 25/61/81 15/62/82 +s off +f 23/17/85 24/64/86 11/63/87 12/18/88 +s 5 +f 1/65/55 19/66/89 20/13/90 10/12/56 +s off +f 18/67/91 19/66/92 1/65/93 2/68/94 +f 21/69/95 20/70/96 18/71/97 +f 18/71/98 52/73/99 22/72/100 21/69/101 +f 52/73/102 23/74/103 22/72/104 +f 24/75/105 23/74/106 52/73/107 +f 53/76/108 25/77/109 24/75/110 52/73/111 +f 26/78/112 25/77/113 53/76/114 +f 27/79/115 26/78/116 53/76/117 +f 28/80/118 27/79/119 53/76/120 +f 29/81/121 28/80/122 53/76/123 +f 30/82/124 29/81/125 53/76/126 +f 53/76/127 34/84/128 31/83/129 30/82/130 +f 32/85/131 31/83/132 34/84/133 +f 34/84/134 33/86/135 32/85/136 +f 18/71/137 20/70/138 19/87/139 +f 35/89/140 37/88/141 36/106/142 +f 38/90/143 37/88/144 35/89/145 +f 54/91/146 39/92/147 38/90/148 35/89/149 +f 40/93/150 39/92/151 54/91/152 +f 41/94/153 40/93/154 54/91/155 +f 42/95/156 41/94/157 54/91/158 +f 43/96/159 42/95/160 54/91/161 +f 44/97/162 43/96/163 54/91/164 +f 54/91/165 55/99/166 45/98/167 44/97/168 +f 46/100/169 45/98/170 55/99/171 +f 55/99/172 47/101/173 46/100/174 +f 51/102/175 48/103/176 47/101/177 55/99/178 +f 49/104/179 48/103/180 51/102/181 +f 49/104/182 51/102/183 50/105/184 diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_right.sfa b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_right.sfa new file mode 100644 index 000000000..b94b93469 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/sampledata/models/frame_upper_right.sfa @@ -0,0 +1,50 @@ +{ + materials: [ + { + name: 'unlit_material', + parameters: [ + { + baseColor: 'frame_base', + }, + { + baseColorTint: [ + 1, + 1, + 1, + 1, + ], + }, + { + metallic: 1, + }, + { + roughness: 1, + }, + { + opacity: null, + }, + ], + source: 'build/sceneform_sdk/default_materials/obj_material.sfm', + }, + ], + model: { + attributes: [ + 'Position', + 'TexCoord', + 'Orientation', + ], + collision: {}, + file: 'sampledata/models/frame_upper_right.obj', + name: 'frame_upper_right', + recenter: 'root', + scale: 1.0006200000000001, + }, + samplers: [ + { + file: 'sampledata/models\\frame_base.png', + name: 'frame_base', + pipeline_name: 'frame_base.png', + }, + ], + version: '0.54:2', +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/AndroidManifest.xml b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..199fb3cba --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/AndroidManifest.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/default.jpg b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/default.jpg new file mode 100644 index 000000000..d3241668f Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/default.jpg differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_lower_left.sfb b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_lower_left.sfb new file mode 100644 index 000000000..5120d5950 Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_lower_left.sfb differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_lower_right.sfb b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_lower_right.sfb new file mode 100644 index 000000000..a40662459 Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_lower_right.sfb differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_upper_left.sfb b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_upper_left.sfb new file mode 100644 index 000000000..9b6e2e4ad Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_upper_left.sfb differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_upper_right.sfb b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_upper_right.sfb new file mode 100644 index 000000000..e65a5ac6a Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/models/frame_upper_right.sfb differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/sample_database.imgdb b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/sample_database.imgdb new file mode 100644 index 000000000..dba77b428 Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/sample_database.imgdb differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/server.jpg b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/server.jpg new file mode 100644 index 000000000..a9fec5fda Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/server.jpg differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/test.jpg b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/test.jpg new file mode 100644 index 000000000..5158148ae Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/assets/test.jpg differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageActivity.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageActivity.java new file mode 100644 index 000000000..2d8b1b2b3 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageActivity.java @@ -0,0 +1,249 @@ +/* + * Copyright 2018 Google LLC + * + * 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. + */ + +package com.google.ar.sceneform.samples.augmentedimage; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.ImageFormat; +import android.media.Image; +import android.os.Bundle; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.FragmentTransaction; + +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import com.google.ar.core.Anchor; +import com.google.ar.core.AugmentedImage; +import com.google.ar.core.Frame; +import com.google.ar.core.Pose; +import com.google.ar.core.Session; +import com.google.ar.core.TrackingState; +import com.google.ar.core.exceptions.NotYetAvailableException; +import com.google.ar.sceneform.AnchorNode; +import com.google.ar.sceneform.FrameTime; +import com.google.ar.sceneform.rendering.ViewRenderable; +import com.google.ar.sceneform.samples.augmentedimage.flowgate.flowgateClient; +import com.google.ar.sceneform.ux.ArFragment; +import com.google.mlkit.vision.common.InputImage; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + + +/** + * This application demonstrates using augmented images to place anchor nodes. app to include image + * tracking functionality. + * + *

In this example, we assume all images are static or moving slowly with a large occupation of + * the screen. If the target is actively moving, we recommend to check + * ArAugmentedImage_getTrackingMethod() and render only when the tracking method equals to + * AR_AUGMENTED_IMAGE_TRACKING_METHOD_FULL_TRACKING. See details in Recognize and Augment + * Images. + */ +public class AugmentedImageActivity extends AppCompatActivity implements AugmentedImageFragment.OnCompleteListener { + private ArFragment arFragment; + private TextView serverTextview; + private ViewRenderable serverRenderable; + private AnchorNode serverNode; + private Boolean isScanSuccess = false; + private Boolean isPause = true; + + flowgateClient fc = new flowgateClient("202.121.180.32", "admin", "Ar_InDataCenter_450"); + + // Augmented image and its associated center pose anchor, keyed by the augmented image in + // the database. + private Map augmentedImageMap = new HashMap<>(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + // Create new fragment and transaction + arFragment = new AugmentedImageFragment(); + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + + // Replace whatever is in the fragment_container view with this fragment, + // and add the transaction to the back stack + transaction.replace(R.id.ux_fragment, arFragment); + transaction.addToBackStack(null); + // Commit the transaction + transaction.commit(); + + // arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment); + + Button reset = findViewById(R.id.button1); + // Reset the app status. + reset.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + isScanSuccess = false; + serverNode = null; + if (serverTextview != null){ + serverTextview.setText(""); + } + TextView dialog = findViewById(R.id.disp1); + String text = "Resetting"; + dialog.setText(text); + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + transaction.detach(arFragment); + transaction.attach(arFragment); + transaction.commit(); + } + }); + + Button pause = findViewById(R.id.button2); + // Pause/continue the current session. + pause.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String text; + if (isPause){ + onPause(); + text = "Continue"; + } else { + onResume(); + text = "Pause"; + } + isPause = !isPause; + pause.setText(text); + } + }); + } + + @Override + public void onComplete() { + TextView dialog = findViewById(R.id.disp1); + String text = "Detecting"; + dialog.setText(text); + // Build the 2D renderable for text views of server. + ViewRenderable.builder() + .setView(this, R.layout.server_view) + .build() + .thenAccept(renderable -> serverRenderable = renderable); + + arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame); + } + + /** + * Registered with the Sceneform Scene object, this method is called at the start of each frame. + * + * @param frameTime - time since last frame. + */ + private void onUpdateFrame(FrameTime frameTime) { + Frame frame = arFragment.getArSceneView().getArFrame(); + Session session = arFragment.getArSceneView().getSession(); + + if (session == null || frame == null) { + return; + } + + // Let the fragment update its state first. + arFragment.onUpdate(frameTime); + + // If ARCore is not tracking yet, then don't process anything. + if (frame.getCamera().getTrackingState() != TrackingState.TRACKING) { + return; + } + + serverTextview = (TextView) serverRenderable.getView(); + + // Scan once; and once the information is obtained, no scanning before reset. + if (!isScanSuccess) { + /*if (this.serverNode != null) { + serverNode.getAnchor().detach(); + serverNode.setParent(null); + serverNode.setRenderable(null); + serverNode = null; + augmentedImageMap.forEach((image, node) -> { + arFragment.getArSceneView().getScene().removeChild(node); + node = null; + }); + augmentedImageMap.clear(); + }*/ + // Send frame image and scan barcode. + try (final Image image = arFragment.getArSceneView().getArFrame().acquireCameraImage()) { + if (image.getFormat() == ImageFormat.YUV_420_888) { + Bitmap bitmapImage = YUV420toBitmap.getBitmap(image); + BarcodeScan barScanning = new BarcodeScan(); + InputImage inputImage = InputImage.fromBitmap(bitmapImage, 0); + + Context context = this.getApplicationContext(); + + TextView dialog = findViewById(R.id.disp1); + barScanning.scanBarcodes(inputImage, fc, context, serverTextview, dialog); + image.close(); + } + } catch (NotYetAvailableException e) { + Log.e("NYA", "Not yet available"); + e.printStackTrace(); + } + } + + isScanSuccess = (serverTextview.getText().toString().length() != 0); + + // Image recognition after barcode scanning. + if (isScanSuccess) { + Collection updatedAugmentedImages = + frame.getUpdatedTrackables(AugmentedImage.class); + for (AugmentedImage augmentedImage : updatedAugmentedImages) { + TextView dialog = findViewById(R.id.disp1); + String text; + switch (augmentedImage.getTrackingState()) { + case PAUSED: + // When an image is in PAUSED state, but the camera is not PAUSED, it has been detected, + // but not yet tracked. + text = "Detected the paused Image " + augmentedImage.getIndex(); + dialog.setText(text); + break; + + case TRACKING: + // Create a new anchor for newly found images. + if (!augmentedImageMap.containsKey(augmentedImage)) { + AugmentedImageNode node = new AugmentedImageNode(); + node.setImage(augmentedImage, this); + augmentedImageMap.put(augmentedImage, node); + arFragment.getArSceneView().getScene().addChild(node); + text = "Device detected and frame drawn"; + dialog.setText(text); + + // Put the server's information near the cabinet. + if (this.serverNode == null) { + float[] pos = {augmentedImage.getCenterPose().tx() + augmentedImage.getExtentX(), augmentedImage.getCenterPose().ty(), augmentedImage.getCenterPose().tz()}; + float[] rotation = {0, 0, 0, 90}; + Anchor anchor = session.createAnchor(new Pose(pos, rotation)); + serverNode = new AnchorNode(anchor); + serverNode.setRenderable(serverRenderable); + serverNode.setParent(arFragment.getArSceneView().getScene()); + } + } + break; + + case STOPPED: + augmentedImageMap.remove(augmentedImage); + break; + } + } + } + } +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageFragment.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageFragment.java new file mode 100644 index 000000000..ca4f4ac5c --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageFragment.java @@ -0,0 +1,172 @@ +/* + * Copyright 2018 Google LLC + * + * 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. + */ + +package com.google.ar.sceneform.samples.augmentedimage; + +import android.app.ActivityManager; +import android.content.Context; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Build; +import android.os.Bundle; +import androidx.annotation.Nullable; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import com.google.ar.core.AugmentedImageDatabase; +import com.google.ar.core.Config; +import com.google.ar.core.Session; +import com.google.ar.sceneform.samples.common.helpers.SnackbarHelper; +import com.google.ar.sceneform.ux.ArFragment; +import java.io.IOException; +import java.io.InputStream; + +/** + * Extend the ArFragment to customize the ARCore session configuration to include Augmented Images. + */ +public class AugmentedImageFragment extends ArFragment { + private static final String TAG = "AugmentedImageFragment"; + + // This is the name of the image in the sample database. A copy of the image is in the assets + // directory. Opening this image on your computer is a good quick way to test the augmented image + // matching. + private static final String DEFAULT_IMAGE_NAME = "test.jpg"; + + // This is a pre-created database containing the sample image. + private static final String SAMPLE_IMAGE_DATABASE = "sample_database.imgdb"; + + // Augmented image configuration and rendering. + // Load a single image (true) or a pre-generated image database (false). + private static final boolean USE_SINGLE_IMAGE = true; + + // Do a runtime check for the OpenGL level available at runtime to avoid Sceneform crashing the + // application. + private static final double MIN_OPENGL_VERSION = 3.0; + + private OnCompleteListener mListener; + + public static interface OnCompleteListener { + public abstract void onComplete(); + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + + // Check for Sceneform being supported on this device. This check will be integrated into + // Sceneform eventually. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + Log.e(TAG, "Sceneform requires Android N or later"); + SnackbarHelper.getInstance() + .showError(getActivity(), "Sceneform requires Android N or later"); + } + + String openGlVersionString = + ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)) + .getDeviceConfigurationInfo() + .getGlEsVersion(); + if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) { + Log.e(TAG, "Sceneform requires OpenGL ES 3.0 or later"); + SnackbarHelper.getInstance() + .showError(getActivity(), "Sceneform requires OpenGL ES 3.0 or later"); + } + + try { + this.mListener = (OnCompleteListener)context; + } + catch (final ClassCastException e) { + throw new ClassCastException(context.toString() + " must implement OnCompleteListener"); + } + } + + @Override + public View onCreateView( + LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + + // Turn off the plane discovery since we're only looking for images + getPlaneDiscoveryController().hide(); + getPlaneDiscoveryController().setInstructionView(null); + getArSceneView().getPlaneRenderer().setEnabled(false); + return view; + } + + @Override + protected Config getSessionConfiguration(Session session) { + Config config = super.getSessionConfiguration(session); + if (!setupAugmentedImageDatabase(config, session)) { + SnackbarHelper.getInstance() + .showError(getActivity(), "Could not setup augmented image database"); + } + // Set Auto focus of the camera. + config.setFocusMode(Config.FocusMode.AUTO); + mListener.onComplete(); + return config; + } + + private boolean setupAugmentedImageDatabase(Config config, Session session) { + AugmentedImageDatabase augmentedImageDatabase; + + AssetManager assetManager = getContext() != null ? getContext().getAssets() : null; + if (assetManager == null) { + Log.e(TAG, "Context is null, cannot intitialize image database."); + return false; + } + + // There are two ways to configure an AugmentedImageDatabase: + // 1. Add Bitmap to DB directly + // 2. Load a pre-built AugmentedImageDatabase + // Option 2) has + // * shorter setup time + // * doesn't require images to be packaged in apk. + if (USE_SINGLE_IMAGE) { + Bitmap augmentedImageBitmap = loadAugmentedImageBitmap(assetManager); + if (augmentedImageBitmap == null) { + return false; + } + + augmentedImageDatabase = new AugmentedImageDatabase(session); + augmentedImageDatabase.addImage(DEFAULT_IMAGE_NAME, augmentedImageBitmap, (float) 0.076); + // If the physical size of the image is known, you can instead use: + // augmentedImageDatabase.addImage("image_name", augmentedImageBitmap, widthInMeters); + // This will improve the initial detection speed. ARCore will still actively estimate the + // physical size of the image as it is viewed from multiple viewpoints. + } else { + // This is an alternative way to initialize an AugmentedImageDatabase instance, + // load a pre-existing augmented image database. + try (InputStream is = getContext().getAssets().open(SAMPLE_IMAGE_DATABASE)) { + augmentedImageDatabase = AugmentedImageDatabase.deserialize(session, is); + } catch (IOException e) { + Log.e(TAG, "IO exception loading augmented image database.", e); + return false; + } + } + + config.setAugmentedImageDatabase(augmentedImageDatabase); + return true; + } + + private Bitmap loadAugmentedImageBitmap(AssetManager assetManager) { + try (InputStream is = assetManager.open(DEFAULT_IMAGE_NAME)) { + return BitmapFactory.decodeStream(is); + } catch (IOException e) { + Log.e(TAG, "IO exception loading augmented image bitmap.", e); + } + return null; + } +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageNode.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageNode.java new file mode 100644 index 000000000..dc6521d19 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/AugmentedImageNode.java @@ -0,0 +1,265 @@ +/* + * Copyright 2018 Google LLC + * + * 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. + */ + +package com.google.ar.sceneform.samples.augmentedimage; + +import android.content.Context; +import android.net.Uri; +import android.util.Log; + +import androidx.annotation.Nullable; + +import com.google.ar.core.AugmentedImage; +import com.google.ar.sceneform.AnchorNode; +import com.google.ar.sceneform.Node; +import com.google.ar.sceneform.collision.Box; +import com.google.ar.sceneform.math.Vector3; +import com.google.ar.sceneform.rendering.Color; +import com.google.ar.sceneform.rendering.Material; +import com.google.ar.sceneform.rendering.MaterialFactory; +import com.google.ar.sceneform.rendering.ModelRenderable; +import com.google.ar.sceneform.rendering.Renderable; +import com.google.ar.sceneform.rendering.RenderableDefinition; +import com.google.ar.sceneform.rendering.ShapeFactory; +import com.google.ar.sceneform.rendering.Vertex; +import com.google.ar.sceneform.utilities.AndroidPreconditions; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +/** + * Node for rendering an augmented image. The image is framed by placing the virtual picture frame + * at the corners of the augmented image trackable. + */ +@SuppressWarnings({"AndroidApiChecker"}) +public class AugmentedImageNode extends AnchorNode { + + private static final String TAG = "AugmentedImageNode"; + + // The augmented image represented by this node. + private AugmentedImage image; + + // Two kinds of bars: one vertical, one horizontal; + // two vertical bars & two horizontal bars form a frame + private static ModelRenderable[] bar = new ModelRenderable[2]; + private static ModelRenderable[] dividerBar = new ModelRenderable[1]; + + public AugmentedImageNode() { + // Do nothing upon construction + } + + /** + * Called when the AugmentedImage is detected and should be rendered. A Sceneform node tree is + * created based on an Anchor created from the image. The corners are then positioned based on the + * extents of the image. There is no need to worry about world coordinates since everything is + * relative to the center of the image, which is the parent node of the corners. + */ + @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"}) + public void setImage(AugmentedImage image, Context context) { + this.image = image; + + Log.d(TAG, "setImage begins"); + + setAnchor(image.createAnchor(image.getCenterPose())); + + // width of frame bar + float frameWidth = image.getExtentX()/20; + ArrayList triangleIndices = getTriangleIndices(); + // position of vertices of bars + ArrayList[] vertices= new ArrayList[2]; + vertices[0] = getCubeVertices(new Vector3(image.getExtentX() + 2 * frameWidth, 0.0f, frameWidth), new Vector3(0.0f, 0.0f, 0.0f)); + vertices[1] = getCubeVertices(new Vector3(frameWidth, 0.0f, image.getExtentZ() + 2 * frameWidth), new Vector3(0.0f, 0.0f, 0.0f)); + ArrayList dividerVertices = getCubeVertices(new Vector3(image.getExtentX(), 0.0f, frameWidth/5), new Vector3(0.0f, 0.0f, 0.0f)); + // color of frame + Color c = new Color(android.graphics.Color.BLUE); + MaterialFactory.makeTransparentWithColor(context, c).thenAccept( + // get the bars + material -> { + Log.d(TAG, "materials set"); + + RenderableDefinition.Submesh submesh = + RenderableDefinition.Submesh.builder().setTriangleIndices(triangleIndices).setMaterial(material).build(); + + RenderableDefinition[] renderableDefinition = new RenderableDefinition[2]; + renderableDefinition[0] = + RenderableDefinition.builder() + .setVertices(vertices[0]) + .setSubmeshes(Arrays.asList(submesh)) + .build(); + renderableDefinition[1] = + RenderableDefinition.builder() + .setVertices(vertices[1]) + .setSubmeshes(Arrays.asList(submesh)) + .build(); + RenderableDefinition[] dividerRenderableDefinition = new RenderableDefinition[1]; + dividerRenderableDefinition[0] = + RenderableDefinition.builder() + .setVertices(dividerVertices) + .setSubmeshes(Arrays.asList(submesh)) + .build(); + + try { + + bar[0] = ModelRenderable.builder().setSource(renderableDefinition[0]).build().get(); + bar[1] = ModelRenderable.builder().setSource(renderableDefinition[1]).build().get(); + dividerBar[0] = ModelRenderable.builder().setSource(dividerRenderableDefinition[0]).build().get(); + } catch (ExecutionException e) { + Log.e(TAG, "ExecutionException when set image"); + e.printStackTrace(); + } catch (InterruptedException e) { + Log.e(TAG, "InterruptedException when set image"); + e.printStackTrace(); + } + + // draw the frame + Vector3 localPosition = new Vector3(); + Node cornerNode; + + localPosition.set(0, 0.0f, 0.5f * image.getExtentZ()); + cornerNode = new Node(); + cornerNode.setParent(this); + cornerNode.setLocalPosition(localPosition); + cornerNode.setRenderable(bar[0]); + + localPosition.set(0, 0.0f, -0.5f * image.getExtentZ()); + cornerNode = new Node(); + cornerNode.setParent(this); + cornerNode.setLocalPosition(localPosition); + cornerNode.setRenderable(bar[0]); + + localPosition.set(0.5f * image.getExtentX(), 0.0f, 0); + cornerNode = new Node(); + cornerNode.setParent(this); + cornerNode.setLocalPosition(localPosition); + cornerNode.setRenderable(bar[1]); + + localPosition.set(-0.5f * image.getExtentX(), 0.0f, 0); + cornerNode = new Node(); + cornerNode.setParent(this); + cornerNode.setLocalPosition(localPosition); + cornerNode.setRenderable(bar[1]); + + + float intervalNum = 14; + float interval = image.getExtentZ()/intervalNum; + float bottom = -0.5f * image.getExtentZ() + interval; + + for(int i = 1; i < intervalNum; i++){ + localPosition.set(0, 0.0f, bottom + i * interval); + cornerNode = new Node(); + cornerNode.setParent(this); + cornerNode.setLocalPosition(localPosition); + cornerNode.setRenderable(dividerBar[0]); + } + + }); + } + + public AugmentedImage getImage() { + return image; + } + + // copy from ShapeFactory + // get eight vertices of the cube according to its size and center + private static ArrayList getCubeVertices(Vector3 size, Vector3 center){ + AndroidPreconditions.checkMinAndroidApiLevel(); + + Vector3 extents = size.scaled(0.5f); + + Vector3 p0 = Vector3.add(center, new Vector3(-extents.x, -extents.y, extents.z)); + Vector3 p1 = Vector3.add(center, new Vector3(extents.x, -extents.y, extents.z)); + Vector3 p2 = Vector3.add(center, new Vector3(extents.x, -extents.y, -extents.z)); + Vector3 p3 = Vector3.add(center, new Vector3(-extents.x, -extents.y, -extents.z)); + Vector3 p4 = Vector3.add(center, new Vector3(-extents.x, extents.y, extents.z)); + Vector3 p5 = Vector3.add(center, new Vector3(extents.x, extents.y, extents.z)); + Vector3 p6 = Vector3.add(center, new Vector3(extents.x, extents.y, -extents.z)); + Vector3 p7 = Vector3.add(center, new Vector3(-extents.x, extents.y, -extents.z)); + + Vector3 up = Vector3.up(); + Vector3 down = Vector3.down(); + Vector3 front = Vector3.forward(); + Vector3 back = Vector3.back(); + Vector3 left = Vector3.left(); + Vector3 right = Vector3.right(); + + Vertex.UvCoordinate uv00 = new Vertex.UvCoordinate(0.0f, 0.0f); + Vertex.UvCoordinate uv10 = new Vertex.UvCoordinate(1.0f, 0.0f); + Vertex.UvCoordinate uv01 = new Vertex.UvCoordinate(0.0f, 1.0f); + Vertex.UvCoordinate uv11 = new Vertex.UvCoordinate(1.0f, 1.0f); + + ArrayList vertices = + new ArrayList<>( + Arrays.asList( + // Bottom + Vertex.builder().setPosition(p0).setNormal(down).setUvCoordinate(uv01).build(), + Vertex.builder().setPosition(p1).setNormal(down).setUvCoordinate(uv11).build(), + Vertex.builder().setPosition(p2).setNormal(down).setUvCoordinate(uv10).build(), + Vertex.builder().setPosition(p3).setNormal(down).setUvCoordinate(uv00).build(), + // Left + Vertex.builder().setPosition(p7).setNormal(left).setUvCoordinate(uv01).build(), + Vertex.builder().setPosition(p4).setNormal(left).setUvCoordinate(uv11).build(), + Vertex.builder().setPosition(p0).setNormal(left).setUvCoordinate(uv10).build(), + Vertex.builder().setPosition(p3).setNormal(left).setUvCoordinate(uv00).build(), + // Front + Vertex.builder().setPosition(p4).setNormal(front).setUvCoordinate(uv01).build(), + Vertex.builder().setPosition(p5).setNormal(front).setUvCoordinate(uv11).build(), + Vertex.builder().setPosition(p1).setNormal(front).setUvCoordinate(uv10).build(), + Vertex.builder().setPosition(p0).setNormal(front).setUvCoordinate(uv00).build(), + // Back + Vertex.builder().setPosition(p6).setNormal(back).setUvCoordinate(uv01).build(), + Vertex.builder().setPosition(p7).setNormal(back).setUvCoordinate(uv11).build(), + Vertex.builder().setPosition(p3).setNormal(back).setUvCoordinate(uv10).build(), + Vertex.builder().setPosition(p2).setNormal(back).setUvCoordinate(uv00).build(), + // Right + Vertex.builder().setPosition(p5).setNormal(right).setUvCoordinate(uv01).build(), + Vertex.builder().setPosition(p6).setNormal(right).setUvCoordinate(uv11).build(), + Vertex.builder().setPosition(p2).setNormal(right).setUvCoordinate(uv10).build(), + Vertex.builder().setPosition(p1).setNormal(right).setUvCoordinate(uv00).build(), + // Top + Vertex.builder().setPosition(p7).setNormal(up).setUvCoordinate(uv01).build(), + Vertex.builder().setPosition(p6).setNormal(up).setUvCoordinate(uv11).build(), + Vertex.builder().setPosition(p5).setNormal(up).setUvCoordinate(uv10).build(), + Vertex.builder().setPosition(p4).setNormal(up).setUvCoordinate(uv00).build())); + + return vertices; + } + + // copy from ShapeFactory + private static ArrayList getTriangleIndices(){ + final int COORDS_PER_TRIANGLE = 3; + final int numSides = 6; + final int verticesPerSide = 4; + final int trianglesPerSide = 2; + + ArrayList triangleIndices = + new ArrayList<>(numSides * trianglesPerSide * COORDS_PER_TRIANGLE); + for (int i = 0; i < numSides; i++) { + // First triangle for this side. + triangleIndices.add(3 + verticesPerSide * i); + triangleIndices.add(1 + verticesPerSide * i); + triangleIndices.add(0 + verticesPerSide * i); + + // Second triangle for this side. + triangleIndices.add(3 + verticesPerSide * i); + triangleIndices.add(2 + verticesPerSide * i); + triangleIndices.add(1 + verticesPerSide * i); + } + return triangleIndices; + } + +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/BarcodeScan.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/BarcodeScan.java new file mode 100644 index 000000000..c911f0fc2 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/BarcodeScan.java @@ -0,0 +1,73 @@ +package com.google.ar.sceneform.samples.augmentedimage; + +import android.app.Activity; +import android.content.Context; +import android.util.Log; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.android.gms.tasks.Task; +import com.google.mlkit.vision.barcode.Barcode; +import com.google.mlkit.vision.barcode.BarcodeScanner; +import com.google.mlkit.vision.barcode.BarcodeScannerOptions; +import com.google.mlkit.vision.barcode.BarcodeScanning; +import com.google.mlkit.vision.common.InputImage; + +import java.util.List; + +import com.google.ar.sceneform.samples.augmentedimage.flowgate.flowgateClient; + +public class BarcodeScan { + private static final String TAG = "Barcode Detect"; + public void scanBarcodes(InputImage image, flowgateClient fc, Context context, TextView textView, TextView dialog) { + BarcodeScannerOptions options = + new BarcodeScannerOptions.Builder() + .setBarcodeFormats(Barcode.FORMAT_CODE_128) + .build(); + + BarcodeScanner scanner = BarcodeScanning.getClient(); + // Or, to specify the formats to recognize: + Log.d(TAG, "set options"); +// BarcodeScanner scanner = BarcodeScanning.getClient(options); + + Log.d(TAG, "getClient"); + Task> result = scanner.process(image) + .addOnSuccessListener(new OnSuccessListener>() { + @Override + public void onSuccess(List barcodes) { + // Task completed successfully + // [START_EXCLUDE] + // [START get_barcodes] + for (Barcode barcode: barcodes) { + String rawValue = barcode.getRawValue(); + Log.d(TAG, "The id is: " + rawValue); + String text = "Barcode detected"; + dialog.setText(text); + + Thread t = new Thread(){ + @Override + public void run(){ + fc.getAssetByIdOnScreen(context, rawValue, textView); + } + }; + t.start(); + try{ + t.join(); + } + catch (Exception e){ + e.printStackTrace(); + } + } + } + }) + .addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + Log.d(TAG, "Failure"); + } + }); + } +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/YUV420toBitmap.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/YUV420toBitmap.java new file mode 100644 index 000000000..1298ef9e9 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/YUV420toBitmap.java @@ -0,0 +1,65 @@ +package com.google.ar.sceneform.samples.augmentedimage; + +import android.content.ContentValues; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.ImageFormat; +import android.graphics.Rect; +import android.graphics.YuvImage; +import android.media.Image; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.MediaStore; +import android.util.Log; +import android.widget.Toast; + +import com.google.ar.core.exceptions.NotYetAvailableException; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * Convert the YUV420 image captured by acquireCameraImage() into bitmap + */ +public class YUV420toBitmap { + public static Bitmap getBitmap(Image image) { + byte[] byteArray; + byteArray = NV21toJPEG(YUV420toNV21(image), image.getWidth(), image.getHeight()); + // return byteArray; + return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); + } + + private static byte[] NV21toJPEG(byte[] nv21, int width, int height) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + YuvImage yuv = new YuvImage(nv21, ImageFormat.NV21, width, height, null); + yuv.compressToJpeg(new Rect(0, 0, width, height), 100, out); + return out.toByteArray(); + } + + private static byte[] YUV420toNV21(Image image) { + byte[] nv21; + // Get the three planes. + ByteBuffer yBuffer = image.getPlanes()[0].getBuffer(); + ByteBuffer uBuffer = image.getPlanes()[1].getBuffer(); + ByteBuffer vBuffer = image.getPlanes()[2].getBuffer(); + + int ySize = yBuffer.remaining(); + int uSize = uBuffer.remaining(); + int vSize = vBuffer.remaining(); + + nv21 = new byte[ySize + uSize + vSize]; + + // U and V are swapped + yBuffer.get(nv21, 0, ySize); + vBuffer.get(nv21, ySize, vSize); + uBuffer.get(nv21, ySize + vSize, uSize); + + return nv21; + } +} \ No newline at end of file diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/MySingleton.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/MySingleton.java new file mode 100644 index 000000000..80e6ab7e3 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/MySingleton.java @@ -0,0 +1,68 @@ +package com.google.ar.sceneform.samples.augmentedimage.flowgate; + +import android.content.Context; +import android.graphics.Bitmap; +import android.util.LruCache; + +// add volley in build.gradle +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.toolbox.ImageLoader; +import com.android.volley.toolbox.Volley; + +/* +* https://developer.android.com/training/volley/requestqueue +* This class is for network request for asset info +*/ + +public class MySingleton { + private static MySingleton instance; + private RequestQueue requestQueue; + private ImageLoader imageLoader; + private static Context ctx; + + private MySingleton(Context context) { + ctx = context; + requestQueue = getRequestQueue(); + + imageLoader = new ImageLoader(requestQueue, + new ImageLoader.ImageCache() { + private final LruCache + cache = new LruCache(20); + + @Override + public Bitmap getBitmap(String url) { + return cache.get(url); + } + + @Override + public void putBitmap(String url, Bitmap bitmap) { + cache.put(url, bitmap); + } + }); + } + + public static synchronized MySingleton getInstance(Context context) { + if (instance == null) { + instance = new MySingleton(context); + } + return instance; + } + + public RequestQueue getRequestQueue() { + if (requestQueue == null) { + // getApplicationContext() is key, it keeps you from leaking the + // Activity or BroadcastReceiver if someone passes one in. + requestQueue = Volley.newRequestQueue(ctx.getApplicationContext()); + } + return requestQueue; + } + + public void addToRequestQueue(Request req) { + getRequestQueue().add(req); + } + + public ImageLoader getImageLoader() { + return imageLoader; + } +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/flowgateClient.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/flowgateClient.java new file mode 100644 index 000000000..9b72cde6c --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/flowgateClient.java @@ -0,0 +1,194 @@ +package com.google.ar.sceneform.samples.augmentedimage.flowgate; + +import android.content.Context; +import android.util.Log; +import android.widget.TextView; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.URL; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +public class flowgateClient { + private static final String TAG = "flowgateClient"; + + private String host; + private String userName; + private String password; + + private final String assetString = "/apiservice/v1/assets/"; + + private JSONObject token = null; + + public flowgateClient(String host, String userName, String password){ + this.host = host; + this.userName = userName; + this.password = password; + } + + public void setHost(String newHost){ + this.host = newHost; + } + + public void setUserName(String newUserName){ + this.userName = newUserName; + } + + public void setPassword(String newPassword){ + this.password = newPassword; + } + + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + + // Read `response` from `connection` after 200 OK + private StringBuilder readResponse(HttpsURLConnection connection) throws IOException { + InputStreamReader isr = new InputStreamReader(connection.getInputStream()); + BufferedReader br = new BufferedReader(isr); + StringBuilder response = new StringBuilder(); + String responseLine; + while((responseLine = br.readLine()) != null){ + response.append(responseLine.trim()); + } + return response; + } + + // Get token + public String getAuthToken() { + try{ + /* + * Existed token not expired + */ + if(this.token != null){ + long expiresTime = Long.parseLong(token.getString("expires_in")); + long currentTime = System.currentTimeMillis(); // unix time in milliseconds + Log.d("flowgateClient", expiresTime + " " + currentTime); + if(expiresTime - currentTime > 600000){ + return token.getString("access_token"); + } + } + + /* + * Acquire new token + */ + // install all-trusting trust manager TODO because our server has no certificate + try{ + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + } + catch (Exception e){} + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession sslSession) { + return true; + } + }); + + // set up connection + String authString = "/apiservice/v1/auth/token"; + URL tokenUrl = new URL("https://" + host + authString); + HttpsURLConnection tokenHttpCon = (HttpsURLConnection)(tokenUrl.openConnection()); + tokenHttpCon.setRequestMethod("POST"); + tokenHttpCon.setDoOutput(true); + tokenHttpCon.setRequestProperty("Content-Type", "application/json"); + tokenHttpCon.setRequestProperty("Accept", "application/json"); + + Log.d(TAG, "connect"); + + // send authentication info + String jsonUser = "{\"userName\": \""+(this.userName)+"\", " + + "\"password\": \""+this.password+"\"}"; + byte[] inputUser = jsonUser.getBytes(); // StandardCharsets.UTF_8 + OutputStream os = tokenHttpCon.getOutputStream(); + os.write(inputUser, 0, inputUser.length); + + Log.d(TAG, "auth"); + + // receive and set this.token and return string if success + tokenHttpCon.connect(); + int responseStatus = tokenHttpCon.getResponseCode(); + if(responseStatus == 200){ + StringBuilder response = this.readResponse(tokenHttpCon); + this.token = new JSONObject(response.toString()); + return token.getString("access_token"); + } + + + Log.d(TAG, "return"); + + return null; + } + catch (IOException e){ + Log.w("flowgateClient", "getAuthToken: IO exception when asking for token"); + e.printStackTrace(); + return null; + } + catch (JSONException e){ + Log.w("flowgateClient", "getAuthToken: JSON exception when asking for token"); + return null; + } + } + + // Let flowgateClientWorker get asset information from `urlString` and display on `textView` + public void getAssetInfoOnScreen(Context context, String urlString, TextView textView) throws Exception { + class NullTokenException extends Exception{ + public NullTokenException(){ + super("flowgateClient: NullTokenException in getAssetInfo"); + } + } + String receivedToken = getAuthToken(); + if(receivedToken == null){ + Log.w("flowgateClient", "getAssetInfo: null token"); + throw new NullTokenException(); + } + + flowgateClientWorker worker = new flowgateClientWorker(urlString); + worker.displayAssetInfoOnScreen(context, receivedToken, textView); + } + + // Get asset information by `name` and display on `textView` + public void getAssetByNameOnScreen(Context context, String name, TextView textView){ + try { + getAssetInfoOnScreen(context, "https://" + this.host + this.assetString + "name/" + name, textView); + } + catch (Exception e){ + e.printStackTrace(); + } + } + + // Get asset information by `id` and display on `textView` + public void getAssetByIdOnScreen(Context context, String id, TextView textView){ + try { + Log.d(TAG, "here"); + getAssetInfoOnScreen(context, "https://" + this.host + this.assetString + id, textView); + } + catch (Exception e){ + Log.d(TAG, e.getMessage()); + e.printStackTrace(); + } + } + +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/flowgateClientActor.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/flowgateClientActor.java new file mode 100644 index 000000000..542e88d56 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/flowgateClientActor.java @@ -0,0 +1,11 @@ +package com.google.ar.sceneform.samples.augmentedimage.flowgate; + +import org.json.JSONException; +import org.json.JSONObject; + +/* + * An interface used to determine what to do when receiving asset info + */ +public interface flowgateClientActor { + public void act(JSONObject response) throws JSONException; +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/flowgateClientWorker.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/flowgateClientWorker.java new file mode 100644 index 000000000..645272eb0 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/augmentedimage/flowgate/flowgateClientWorker.java @@ -0,0 +1,102 @@ +package com.google.ar.sceneform.samples.augmentedimage.flowgate; + +import android.content.Context; +import android.util.Log; +import android.widget.TextView; + +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonObjectRequest; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +/* + * This class is for sending *one* request to *one* url to get asset information and perform corresponding action + * Similar functions as `displayAssetInfoOnScreen` can be written: + * add arguments (e.g. location of barcode) & + * define a new actor to determine what to do when receiving response (e.g. display with AR) + */ +public class flowgateClientWorker { + String urlString; // `urlString` is the string of url to be requested + + public flowgateClientWorker(String urlString){ + this.urlString = urlString; + } + + /* + * `context` is the class of MainActivity, + * `receivedToken` is the received token used for authorization + * `actor` is used to determine what to do when receiving response + * EFFECTS: obtain asset info by sending GET request to `this.urlString`, + * and `actor` acts + */ + public void getAssetInfo(Context context, String receivedToken, flowgateClientActor actor) { + JsonObjectRequest jsonObjectRequest = new JsonObjectRequest + (Request.Method.GET, urlString, null, new Response.Listener() { + + @Override + public void onResponse(JSONObject response) { + try { + actor.act(response); + } catch (JSONException e) { + e.printStackTrace(); + } + // Log.d("flowgateClientWorker", "setAssetInfo: " + response.toString()); + } + }, new Response.ErrorListener() { + + @Override + public void onErrorResponse(VolleyError error) { + // TODO: Handle error maybe throw exception/display message on screen + Log.w("flowgateClientWorker", + "setAssetInfo: response error - " + error.toString()); + } + }) + { + @Override + public Map getHeaders() { + Map params = new HashMap(); + params.put("Content-Type","application/json"); + params.put("Authorization", "Bearer " + receivedToken); + params.put("Accept", "application/json"); + return params; + } + }; + MySingleton.getInstance(context).addToRequestQueue(jsonObjectRequest); + } + + /* + * EFFECTS: obtain asset info by sending GET request to `this.urlString`, + * and display received info on `textView` + */ + public void displayAssetInfoOnScreen(Context context, String receivedToken, TextView textView){ + flowgateClientActor actor = new flowgateClientActor() { + @Override + public void act(JSONObject response) throws JSONException { + String assetNumber = response.getString("assetNumber"); + String assetName = response.getString("assetName"); + String category = response.getString("category"); + String manufacturer = response.getString("manufacturer"); + String model = response.getString("model"); + String mountingSide = response.getString("mountingSide"); + + String disp = + assetName + "\n" + + "Asset Number: " + assetNumber + "\n" + + "Category: " + category + "\n" + + "Manufacturer: " + manufacturer + "\n" + + "Model: " + model + "\n" + + "Mounting side: " + mountingSide; + + textView.setText(disp); + } + }; + getAssetInfo(context, receivedToken, actor); + } + +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/common/helpers/SnackbarHelper.java b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/common/helpers/SnackbarHelper.java new file mode 100644 index 000000000..58ec82006 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/java/com/google/ar/sceneform/samples/common/helpers/SnackbarHelper.java @@ -0,0 +1,116 @@ +/* + * Copyright 2017 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. + */ +package com.google.ar.sceneform.samples.common.helpers; + +import android.app.Activity; +import com.google.android.material.snackbar.BaseTransientBottomBar; +import com.google.android.material.snackbar.Snackbar; +import android.view.View; + +/** + * Helper to manage the sample snackbar. Hides the Android boilerplate code, and exposes simpler + * methods. + */ +public final class SnackbarHelper { + private static final int BACKGROUND_COLOR = 0xbf323232; + private static final SnackbarHelper THE_INSTANCE = new SnackbarHelper(); + private Snackbar messageSnackbar; + + private enum DismissBehavior { + HIDE, + SHOW, + FINISH + }; + + public static SnackbarHelper getInstance() { + return THE_INSTANCE; + } + + public boolean isShowing() { + return messageSnackbar != null; + } + + /** Shows a snackbar with a given message. */ + public void showMessage(Activity activity, String message) { + show(activity, message, DismissBehavior.HIDE); + } + + /** Shows a snackbar with a given message, and a dismiss button. */ + public void showMessageWithDismiss(Activity activity, String message) { + show(activity, message, DismissBehavior.SHOW); + } + + /** + * Shows a snackbar with a given error message. When dismissed, will finish the activity. Useful + * for notifying errors, where no further interaction with the activity is possible. + */ + public void showError(Activity activity, String errorMessage) { + show(activity, errorMessage, DismissBehavior.FINISH); + } + + /** + * Hides the currently showing snackbar, if there is one. Safe to call from any thread. Safe to + * call even if snackbar is not shown. + */ + public void hide(Activity activity) { + activity.runOnUiThread( + new Runnable() { + @Override + public void run() { + if (messageSnackbar != null) { + messageSnackbar.dismiss(); + } + messageSnackbar = null; + } + }); + } + + private void show( + final Activity activity, final String message, final DismissBehavior dismissBehavior) { + activity.runOnUiThread( + new Runnable() { + @Override + public void run() { + messageSnackbar = + Snackbar.make( + activity.findViewById(android.R.id.content), + message, + Snackbar.LENGTH_INDEFINITE); + messageSnackbar.getView().setBackgroundColor(BACKGROUND_COLOR); + if (dismissBehavior != DismissBehavior.HIDE) { + messageSnackbar.setAction( + "Dismiss", + new View.OnClickListener() { + @Override + public void onClick(View v) { + messageSnackbar.dismiss(); + } + }); + if (dismissBehavior == DismissBehavior.FINISH) { + messageSnackbar.addCallback( + new BaseTransientBottomBar.BaseCallback() { + @Override + public void onDismissed(Snackbar transientBottomBar, int event) { + super.onDismissed(transientBottomBar, event); + activity.finish(); + } + }); + } + } + messageSnackbar.show(); + } + }); + } +} diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/drawable-xxhdpi/fit_to_scan.png b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/drawable-xxhdpi/fit_to_scan.png new file mode 100644 index 000000000..0613db35f Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/drawable-xxhdpi/fit_to_scan.png differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..fcf0dc09d Binary files /dev/null and b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/drawable/rounded_bg.xml b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/drawable/rounded_bg.xml new file mode 100644 index 000000000..2e72fa117 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/drawable/rounded_bg.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/layout/activity_main.xml b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..d3bc8c195 --- /dev/null +++ b/contrib/ar4dcops/app_android/augmentedimage/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/Library/ProjectLibrary/Contents.json b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/Library/ProjectLibrary/Contents.json new file mode 100644 index 000000000..c44dc44f3 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/Library/ProjectLibrary/Contents.json @@ -0,0 +1,3 @@ +[ + +] \ No newline at end of file diff --git a/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/Library/ProjectLibrary/Version.json b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/Library/ProjectLibrary/Version.json new file mode 100644 index 000000000..ea86f98e8 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/Library/ProjectLibrary/Version.json @@ -0,0 +1,4 @@ +{ + "LibraryID" : "BBB5EDD2-CBE1-49E5-931D-2C81F724D19D", + "Version" : "1.0" +} \ No newline at end of file diff --git a/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/SceneThumbnails/F9610871-0955-494F-A5C3-51D1A281BAB3 b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/SceneThumbnails/F9610871-0955-494F-A5C3-51D1A281BAB3 new file mode 100644 index 000000000..69378c280 Binary files /dev/null and b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/SceneThumbnails/F9610871-0955-494F-A5C3-51D1A281BAB3 differ diff --git a/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/SceneThumbnails/F9610871-0955-494F-A5C3-51D1A281BAB3.thumbnails/square b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/SceneThumbnails/F9610871-0955-494F-A5C3-51D1A281BAB3.thumbnails/square new file mode 100644 index 000000000..a69f880f4 Binary files /dev/null and b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/SceneThumbnails/F9610871-0955-494F-A5C3-51D1A281BAB3.thumbnails/square differ diff --git a/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/SceneThumbnails/F9610871-0955-494F-A5C3-51D1A281BAB3.thumbnails/wide b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/SceneThumbnails/F9610871-0955-494F-A5C3-51D1A281BAB3.thumbnails/wide new file mode 100644 index 000000000..51516d229 Binary files /dev/null and b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/SceneThumbnails/F9610871-0955-494F-A5C3-51D1A281BAB3.thumbnails/wide differ diff --git a/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/com.apple.RCFoundation.Project b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/com.apple.RCFoundation.Project new file mode 100644 index 000000000..b47d290c9 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/Experience.rcproject/com.apple.RCFoundation.Project @@ -0,0 +1,155 @@ +{ + "__version" : 1, + "__content" : [ + { + "tags" : { + "__version" : 1, + "__content" : [ + { + "tagsStore" : { + + } + } + ] + }, + "scenes" : [ + { + "__version" : 2, + "__content" : [ + { + "hasGroundPlane" : true, + "gravity" : [ + 0, + -9.8000001907348633, + 0 + ], + "arAnchorSpecification" : { + "name" : "surface", + "classification" : 0, + "alignment" : 1 + }, + "title" : "Box", + "material" : "concrete", + "layoutData" : { + "version" : 1, + "constraints" : [ + + ] + }, + "identifier" : "F9610871-0955-494F-A5C3-51D1A281BAB3", + "behaviors" : [ + + ], + "overrides" : { + "factory" : null, + "children" : { + "4A213441-135C-450E-8EF8-1A4EAB267C1D" : { + "overrides" : { + "factory" : { + "version" : "1.0", + "identifier" : "com.apple.rc.af.CoreAssetFactories.PrimitiveShapeAssetFactory" + }, + "arguments" : [ + [ + "material", + { + "value" : "steel", + "typeName" : "String" + } + ], + [ + "type", + { + "value" : "box", + "typeName" : "String" + } + ] + ], + "runtimeAttributes" : [ + [ + "RuntimeIdentifier", + { + "value" : "3788A5B5-0388-488A-8304-7B90FEBA6FAC", + "typeName" : "UUID" + } + ], + [ + "entityName", + { + "value" : "Steel Box", + "typeName" : "String" + } + ] + ] + }, + "transform" : { + "matrix" : [ + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0.05000000074505806, + 0, + 1 + ] + } + }, + "B91C7CA3-4AB1-4253-9A84-07383168A8A8" : null, + "7F5F1ADC-E5E4-4EF5-A5B5-FC43B071FFA5" : null, + "632E476F-1E55-4E30-9723-1C51DD2E8B89" : null + } + }, + "viewTransform" : { + "sceneTransform" : [ + 1, + 0, + 0, + 0, + 0, + 0.99999994039535522, + 0, + 0, + 0, + 0, + 0.99999994039535522, + 0, + 0, + 0, + 0, + 1 + ], + "cameraTransform" : [ + 0.99999994039535522, + 0, + 0, + 0, + 0, + 0.80754852294921875, + -0.58980101346969604, + 0, + 0, + 0.58980101346969604, + 0.80754852294921875, + 0, + 0, + 1.135667085647583, + 1.5549418926239014, + 1 + ] + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/contrib/ar4dcops/app_ios/FlowAR/FlowgateClient.swift b/contrib/ar4dcops/app_ios/FlowAR/FlowgateClient.swift new file mode 100644 index 000000000..5bf33dfe1 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/FlowgateClient.swift @@ -0,0 +1,232 @@ +// +// FlowgateClient.swift +// FlowAR +// +// Created by 周舒意 on 2020/11/8. +// Copyright © 2020 周舒意. All rights reserved. +// + +import Foundation +import UIKit +import ARKit +extension ViewController{ + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + + } + + + func getFlowgateToken() -> [String: Any]{ + if (!self.current_token.isEmpty){ + let current_time = Int(round(Date().timeIntervalSince1970 * 1000)) + guard let expire_time = self.current_token["expires_in"]! as? Int else {return ["fail token":0]} + if (expire_time - current_time > 600000){ + return self.current_token + } + } + + let config = URLSessionConfiguration.default + let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) + let token_url = URL(string: self.host + "/apiservice/v1/auth/token") + var request = URLRequest(url: token_url!) + // header + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + // body dump to json + if let theJSONData = try? JSONSerialization.data( + withJSONObject: ["userName": self.username, "password": self.password], + options: []) { + request.httpBody = theJSONData + request.httpMethod = "POST" + let task = session.dataTask(with: request, completionHandler: {(data, response, error) in + if (error != nil){print(error.debugDescription)} + guard let data = data, error == nil else { + print(error?.localizedDescription ?? "get nothing") + return + } + if let httpResponse = response as? HTTPURLResponse{ + if httpResponse.statusCode==200{ + do { + self.current_token = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any] + }catch _ { + print("JSONSerialization error:", error as Any) + } + } + } + }) + task.resume() + } + return current_token + } + + func getAssetByName(name: String) { + let _token = self.getFlowgateToken() + let config = URLSessionConfiguration.default + let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) + let token_url = URL(string: self.host + "/apiservice/v1/assets/name/" + name + "/") + var request = URLRequest(url: token_url!) + // header + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + guard let acc_token = _token["access_token"] as? String else { + return + } + print(acc_token) + request.addValue(("Bearer " + acc_token), forHTTPHeaderField: "Authorization") + request.httpMethod = "GET" + print("getAssetByName") + let task = session.dataTask(with: request, completionHandler: {(data, response, error) in + if (error != nil){print(error.debugDescription)} + print(2) + guard let data = data, error == nil else { + print(error?.localizedDescription ?? "get nothing") + return + } + if let httpResponse = response as? HTTPURLResponse{ + if httpResponse.statusCode==200{ + do{ + self.fetch_result = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any] + self.cabinet_b = true + }catch _{ print("JSONSerialization error:", error as Any)} + } + } + }) + task.resume() + } + + func getAssetByID(ID:String){ +// DispatchQueue.main.async { +// self.statusViewController.cancelAllScheduledMessages() +// self.statusViewController.showMessage("getAssetByID") +// } + print("getAssetById") + let _token = self.getFlowgateToken() + let config = URLSessionConfiguration.default + let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) + let token_url = URL(string: self.host + "/apiservice/v1/assets/" + ID + "/") + var request = URLRequest(url: token_url!) + // header + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + guard let acc_token = _token["access_token"] as? String else { + return + } + request.addValue(("Bearer " + acc_token), forHTTPHeaderField: "Authorization") + request.httpMethod = "GET" + let task = session.dataTask(with: request, completionHandler: {(data, response, error) in + if (error != nil){print(error.debugDescription)} + print(2) + guard let data = data, error == nil else { + print(error?.localizedDescription ?? "get nothing") + return + } + if let httpResponse = response as? HTTPURLResponse{ + if httpResponse.statusCode==200{ + do{ +// DispatchQueue.main.async { +// self.statusViewController.cancelAllScheduledMessages() +// self.statusViewController.showMessage("Internet") +// } + let info = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] + self.detectedDataResult[ID] = info + print("getAssetByIdonline") + self.sceneView.session.add(anchor: self.detectedDataAnchor[ID]!!) + + }catch _{ print("JSONSerialization error:", error as Any)} + } + } + }) + task.resume() + } + + func getAssetByIDNAnchor(ID: String){ + + let _token = self.getFlowgateToken() + let config = URLSessionConfiguration.default + let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) + let token_url = URL(string: self.host + "/apiservice/v1/assets/" + ID + "/") + var request = URLRequest(url: token_url!) + // header + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + guard let acc_token = _token["access_token"] as? String else { + return + } + request.addValue(("Bearer " + acc_token), forHTTPHeaderField: "Authorization") + request.httpMethod = "GET" + let task = session.dataTask(with: request, completionHandler: {(data, response, error) in + if (error != nil){print(error.debugDescription)} + print(2) + guard let data = data, error == nil else { + print(error?.localizedDescription ?? "get nothing") + return + } + if let httpResponse = response as? HTTPURLResponse{ + if httpResponse.statusCode==200{ + do{ + let info = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] + self.detectedDataResult[ID] = info +// self.lastAddedAnchor = self.detectedDataAnchor[ID] as? ARAnchor + + self.statusViewController.showPause() + self.statusViewController.unhidePause() + self.cabinet = info?["cabinetName"] as? String + DispatchQueue.main.async { + guard let _ = self.cabinet else { + return + }} + DispatchQueue.main.async { + self.statusViewController.cancelAllScheduledMessages() + self.statusViewController.showMessage("Work around to detect the rack" + self.cabinet) + } + guard let _ = self.cabinet else { + self.statusViewController.cancelAllScheduledMessages() + self.statusViewController.showMessage("Not in cabinet") + return + } + print("getAssetByIDNAnchor") + self.getAssetByName(name: self.cabinet) + + }catch _{ print("JSONSerialization error:", error as Any)} + } + } + }) + task.resume() + } + + func strFormat(content: [String: Any]) -> [String: String]{ +// let content = self.detectedDataResult[ID]! as [String: Any] + var result: [String: String] = ["type":"", "content":"", "title":""] + for item in items{ + if item == "assetName" { + result["title"] = content[item] as? String + continue + } + if item.contains("."){ + let item_l = item.split(separator: ".") // "xxx.aa/bb" get [xx, aa/bb] + let left = String(item_l[0]) // left = xx + guard let temp_o = content[left] as? [String: Any] else {return ["error":"no a list"]} // temp_o = content[xx] + let item_i = item_l[1].split(separator: "/") // [aa, bb] + result["type"]! += left + "\n" + result["content"]! += "\n" + for item_in in item_i{ // aa + result["type"]! += "\t" + item_in + "\n" + if let temp = temp_o[String(item_in)] as? String { + result["content"]! += temp + "\n" + } else if let temp = temp_o[String(item_in)] as? Int { + result["content"]! += String(format: "%d", temp) + "\n" + } + } + } + else { + if let temp = content[item] as? String { + result["type"]! += item + "\n" + result["content"]! += temp + "\n" + } else if let temp = content[item] as? Int { + result["type"]! += item + "\n" + result["content"]! += String(format: "%d", temp) + "\n" + } + } + } + return result + } + + +} diff --git a/contrib/ar4dcops/app_ios/FlowAR/Info.plist b/contrib/ar4dcops/app_ios/FlowAR/Info.plist new file mode 100644 index 000000000..d3b409d30 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/Info.plist @@ -0,0 +1,63 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + DatA CenteR + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + NSCameraUsageDescription + The camera is used for augmenting reality + NSLocationWhenInUseUsageDescription + The location is used for augmenting reality + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + arkit + + UIRequiresFullScreen + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/contrib/ar4dcops/app_ios/FlowAR/RoundedButton.swift b/contrib/ar4dcops/app_ios/FlowAR/RoundedButton.swift new file mode 100644 index 000000000..b7f93a13f --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/RoundedButton.swift @@ -0,0 +1,36 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +A custom button that stands out over the camera view. +*/ + +import UIKit + +@IBDesignable +class RoundedButton: UIButton { + + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + func setup() { + backgroundColor = tintColor + layer.cornerRadius = 8 + clipsToBounds = true + setTitleColor(.white, for: []) + titleLabel?.font = UIFont.boldSystemFont(ofSize: 17) + } + + override var isEnabled: Bool { + didSet { + backgroundColor = isEnabled ? tintColor : .gray + } + } +} diff --git a/contrib/ar4dcops/app_ios/FlowAR/StartViewController.swift b/contrib/ar4dcops/app_ios/FlowAR/StartViewController.swift new file mode 100644 index 000000000..769c1e1d7 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/StartViewController.swift @@ -0,0 +1,15 @@ +// +// StartViewController.swift +// FlowAR +// +// Created by 周舒意 on 2020/11/11. +// Copyright © 2020 周舒意. All rights reserved. +// + +import Foundation +import UIKit + +class StartViewController: UIViewController{ + + +} diff --git a/contrib/ar4dcops/app_ios/FlowAR/ViewController+ARSessionDelegate.swift b/contrib/ar4dcops/app_ios/FlowAR/ViewController+ARSessionDelegate.swift new file mode 100644 index 000000000..7d3b0a548 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/ViewController+ARSessionDelegate.swift @@ -0,0 +1,96 @@ +// +// ViewController+ARSessionDelegate.swift +// FlowAR +// +// Created by 周舒意 on 2020/11/11. +// Copyright © 2020 周舒意. All rights reserved. +// + +import ARKit + +extension ViewController { + + // MARK: - ARSessionDelegate + + func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) { + statusViewController.showTrackingQualityInfo(for: camera.trackingState, autoHide: true) + + switch camera.trackingState { + case .notAvailable, .limited: + statusViewController.escalateFeedback(for: camera.trackingState, inSeconds: 3.0) + case .normal: + statusViewController.cancelScheduledMessage(for: .trackingStateEscalation) + } + } + + func session(_ session: ARSession, didFailWithError error: Error) { + guard error is ARError else { return } + + let errorWithInfo = error as NSError + let messages = [ + errorWithInfo.localizedDescription, + errorWithInfo.localizedFailureReason, + errorWithInfo.localizedRecoverySuggestion + ] + + // Use `flatMap(_:)` to remove optional error messages. + let errorMessage = messages.compactMap({ $0 }).joined(separator: "\n") + + DispatchQueue.main.async { + self.displayErrorMessage(title: "The AR session failed.", message: errorMessage) + } + } + + func sessionWasInterrupted(_ session: ARSession) { + blurView.isHidden = false + statusViewController.showMessage(""" + SESSION INTERRUPTED + The session will be reset after the interruption has ended. + """, autoHide: false) + } + + func sessionInterruptionEnded(_ session: ARSession) { + blurView.isHidden = true + statusViewController.showMessage("RESETTING SESSION") + + restartExperience() + } + + func sessionShouldAttemptRelocalization(_ session: ARSession) -> Bool { + return true + } + + // MARK: - Error handling + + func displayErrorMessage(title: String, message: String) { + // Blur the background. + blurView.isHidden = false + + // Present an alert informing about the error that has occurred. + let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) + let restartAction = UIAlertAction(title: "Restart Session", style: .default) { _ in + alertController.dismiss(animated: true, completion: nil) + self.blurView.isHidden = true + self.resetTracking() + } + alertController.addAction(restartAction) + present(alertController, animated: true, completion: nil) + } + + // MARK: - Interface Actions + + func restartExperience() { + guard isRestartAvailable else { return } + isRestartAvailable = false + + statusViewController.cancelAllScheduledMessages() + + resetTracking() + + // Disable restart for a while in order to give the session time to restart. + DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { + self.isRestartAvailable = true + } + } + +} diff --git a/contrib/ar4dcops/app_ios/FlowAR/ViewController.swift b/contrib/ar4dcops/app_ios/FlowAR/ViewController.swift new file mode 100644 index 000000000..337bd659c --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/ViewController.swift @@ -0,0 +1,632 @@ +// +// ViewController.swift +// FlowAR +// +// Created by 周舒意 on 2020/10/20. +// Copyright © 2020 周舒意. All rights reserved. +// + +import UIKit +import SceneKit +import ARKit +import Vision +import ClassKit + +class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate, URLSessionDelegate { + + @IBOutlet var sceneView: ARSCNView! + + @IBOutlet weak var blurView: UIVisualEffectView! + + var temperatures = [25.5, 25.8, 28, 26.9] + + var qrRequests = [VNRequest]() + var detectedDataAnchor: [String: ARAnchor?] = [:] // QR location + var message: String! // QR Message === ID + var detectedDataResult: [String: [String: Any]] = [:] // [ID: ["AssetId":"sfsdf", "AssetName": "sfdsfd"]] + var cabinet: String! // cabinet name -> getAssetByName + var cabitnetNode: SCNNode? + + var paused = false + + var chartNode: SCNNode? + var addPlane: SCNNode? + + /// The view controller that displays the status and "restart experience" UI. + lazy var statusViewController: StatusViewController = { + return children.lazy.compactMap({ $0 as? StatusViewController }).first! + }() + /// A serial queue for thread safety when modifying the SceneKit node graph. + let updateQueue = DispatchQueue(label: Bundle.main.bundleIdentifier! + + ".serialSceneKitQueue") + + /// Convenience accessor for the session owneASd by ARSCNView. + var session: ARSession { + return sceneView.session + } + + var lastAddedAnchor: ARAnchor? // 最近添加的QRcode的anchor + var processing = false // QR code image process + + + let host = "https://202.121.180.32/" // FLOWGATE_HOST + var password = "QWxv_3arJ70gl" // FLOWGATE_PASSWORD + var username = "API" + var current_token: [String: Any] = [:] + let items = [ + "assetName", + "assetNumber", + "assetSource", + "category", + "subCategory", + "manufacturer", + "model", + "tag", + "cabinetName"] // 看情况加 + var fetch_result: [String: Any] = [:] // data for one cabinet + + lazy var cabinet_b = false {// is cabinet detected + didSet{ + if(cabinet_b) {self.startFigure()} + } + } + var cabinet_show = false; + // MARK: - View Controller Life Cycle + override func viewDidLoad() { + super.viewDidLoad() + Swift.print(getFlowgateToken()) + // Set the view's delegate + sceneView.delegate = self + sceneView.session.delegate=self +// sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin] + + // Hook up status view controller callback(s). + statusViewController.restartExperienceHandler = { [unowned self] in + self.restartExperience() + } + startQrCodeDetection() + statusViewController.pauseSessionHandler = {[unowned self] in + if(paused){ + self.paused = false + let configuration = ARWorldTrackingConfiguration() + session.run(configuration, options: []) + statusViewController.showPause() + }else{ + self.paused = true + session.pause() + statusViewController.showContinue() + }} + + } +// override func viewWillAppear(_ animated: Bool) { +// super.viewWillAppear(animated) +// print("heihei") +// +// } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + // Prevent the screen from being dimmed to avoid interuppting the AR experience. + UIApplication.shared.isIdleTimerDisabled = true + + // Start the AR experience + resetTracking() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + session.pause() + } + + // MARK: - Session management (Image detection setup) + + /// Prevents restarting the session while a restart is in progress. + var isRestartAvailable = true + + /// Creates a new AR configuration to run on the `session`. + /// - Tag: ARReferenceImage-Loading + func startFigure(){ + guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else { + fatalError("Missing expected asset catalog resources.") + } + let configuration = ARWorldTrackingConfiguration() + configuration.detectionImages = referenceImages + session.run(configuration) + } + + func stopFigure(){ + let configuration = ARWorldTrackingConfiguration() + session.run(configuration) + } + func resetTracking() { + +// guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else { +// fatalError("Missing expected asset catalog resources.") +// } +// + statusViewController.hidePause() + statusViewController.showPause() + let configuration = ARWorldTrackingConfiguration() + session.run(configuration, options: [.resetTracking, .removeExistingAnchors]) + + statusViewController.scheduleMessage("Look around to detect server", inSeconds: 7.5, messageType: .contentPlacement) + cabinet_b = false; + cabinet_show = false; + } + + + func startQrCodeDetection() { + + // Create a Barcode Detection Request + let request = VNDetectBarcodesRequest(completionHandler: self.requestHandler) + // Set it to recognize QR code only + request.symbologies = [.Aztec, .Code39, .Code39Checksum, .Code39FullASCII, .Code39FullASCIIChecksum, .Code93, .Code93i, .Code128, .DataMatrix, .EAN8, + .EAN13, .I2of5, .I2of5Checksum, .ITF14, .PDF417, .UPCE] + self.qrRequests = [request] + } + + func requestHandler(request: VNRequest, error: Error?) { + // Get the first result out of the results, if there are any + if let results = request.results, let result = results.first as? VNBarcodeObservation { + guard let message=result.payloadStringValue else {return} + self.message = message + Swift.print(self.message ?? "No message.") + DispatchQueue.main.async { + self.statusViewController.cancelAllScheduledMessages() + self.statusViewController.showMessage("Detected a bar code") + } + // Get the bounding box for the bar code and find the center + var rect = result.boundingBox + // TODO: Draw it + // Flip coordinates + rect = rect.applying(CGAffineTransform(scaleX: 1, y: -1)) + rect = rect.applying(CGAffineTransform(translationX: 0, y: 1)) + // Get center + let center = CGPoint(x: rect.midX, y: rect.midY) + if(cabinet_show) + { + DispatchQueue.main.async { + self.statusViewController.cancelAllScheduledMessages() + self.statusViewController.showMessage("Loading information") + } + DispatchQueue.main.async { + self.hitTestQrCode(center: center, message: message) + self.processing = false + } + }else{ + getAssetByIDNAnchor(ID: message) + self.hitTestQrCodeFirst(center: center, message: message) + self.processing = false + } + } else { + self.processing = false + } + } + + func hitTestQrCode(center: CGPoint, message: String) { +// print(detectedDataResult) + if let hitTestResults = sceneView?.hitTest(center, types: [.featurePoint] ), + let hitTestResult = hitTestResults.first { + if let detectedDataAnchor = self.detectedDataAnchor[message], // ID的anchor + let node = self.sceneView.node(for: detectedDataAnchor!) { + node.transform = SCNMatrix4(hitTestResult.worldTransform) + node.rotation = self.cabitnetNode?.rotation ?? node.rotation + } else { + // Create an anchor. The node will be created in delegate methods +// self.detectedDataAnchor[message] = hitTestResult.anchor + self.detectedDataAnchor[message] = ARAnchor(transform: hitTestResult.worldTransform) + self.lastAddedAnchor = self.detectedDataAnchor[message] as? ARAnchor + self.getAssetByID(ID: message) + } + } + } + + func hitTestQrCodeFirst(center: CGPoint, message: String) { +// print(detectedDataResult) + if let hitTestResults = sceneView?.hitTest(center, types: [.featurePoint] ), + let hitTestResult = hitTestResults.first { + // Create an anchor. The node will be created in delegate methods +// self.detectedDataAnchor[message] = hitTestResult.anchor + self.detectedDataAnchor[message] = ARAnchor(transform: hitTestResult.worldTransform) + self.lastAddedAnchor = self.detectedDataAnchor[message] as? ARAnchor + } + } + + public func session(_ session: ARSession, didUpdate frame: ARFrame) { + DispatchQueue.global(qos: .userInitiated).async { + do { + if self.processing { + return + } + self.processing = true + // Create a request handler using the captured image from the ARFrame + let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: frame.capturedImage, + options: [:]) + // Process the request + try imageRequestHandler.perform(self.qrRequests) + } catch { + + } + } + } + + // Anchor(定位) ->Node(Anchor) object -> node加进你要的返回的node + // Geometry _^ + + // MARK: - ARSCNViewDelegate + + + // Override to create and configure nodes for anchors added to the view's session. + func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? { + if self.lastAddedAnchor?.identifier == anchor.identifier { + +// DispatchQueue.main.async { +// self.statusViewController.cancelAllScheduledMessages() +// self.statusViewController.showMessage("add this anchor") +// } + let node = SCNNode() + guard let ID = self.message else { return node } + let result = strFormat(content: detectedDataResult[ID]! as [String: Any]) + let left_message = textNode(text: result["type"]!, position: SCNVector3(-0.11, 0.05, 0.01)) + let right_message = textNode(text: result["content"]!, position: SCNVector3(0, 0.05, 0.01)) + let title_message = textNode(text: result["title"]!, position: SCNVector3(-0.11, 0.09, 0.01), bold: true, size: 2) + left_message.eulerAngles.x = 0 + right_message.eulerAngles.x = 0 + title_message.eulerAngles.x = 0 + + left_message.opacity = 0 + right_message.opacity = 0 + title_message.opacity = 0 + node.addChildNode(left_message) + node.addChildNode(right_message) + node.addChildNode(title_message) + + + let plane = SCNPlane(width: 0.25, height: 0.2) + let planeNode = SCNNode(geometry: plane) + planeNode.eulerAngles.x = 0 + planeNode.opacity = 0 // for fadein + node.addChildNode(planeNode) + + let underLine = SCNPlane(width: 0.25, height: 0.002) + underLine.firstMaterial?.diffuse.contents = UIColor.cyan + let underLineNode = SCNNode(geometry: underLine) + underLineNode.eulerAngles.x = 0 + underLineNode.opacity = 0 // for fadein + underLineNode.position = SCNVector3Make(0, 0.06, 0.001) + node.addChildNode(underLineNode) + + planeNode.scale = SCNVector3Zero + planeNode.runAction(self.imageAppearAction) + underLineNode.scale = SCNVector3Zero + underLineNode.runAction(self.imageAppearAction) + + + title_message.runAction(self.textAppearAction) + left_message.runAction(self.textAppearAction) + right_message.runAction(self.textAppearAction) + + + + return node + + } else if let imageAnchor = anchor as? ARImageAnchor{ + let referenceImage = imageAnchor.referenceImage + let node = SCNNode() + updateQueue.async { + guard let path = Bundle.main.path(forResource: "wireframe_shader", ofType: "metal", inDirectory: "art.scnassets"), + let shader = try? String(contentsOfFile: path, encoding: .utf8) else { + print(Bundle.main.path(forResource: "wireframe_shader", ofType: "metal", inDirectory: "Assets.xcassets") ?? "nothing") + print("faile to open") + return + } + // Create a plane to visualize the initial position of the detected image. + let wireFrame = SCNNode() + let box = SCNBox(width: referenceImage.physicalSize.width, height: 0, length: referenceImage.physicalSize.height, chamferRadius: 0) + box.firstMaterial?.diffuse.contents = UIColor.red + box.firstMaterial?.isDoubleSided = true + box.firstMaterial?.shaderModifiers = [.surface: shader] + wireFrame.geometry = box + node.addChildNode(wireFrame) + self.cabitnetNode = wireFrame + + // add lines + + var start_y = -referenceImage.physicalSize.height/2 + let end_y = referenceImage.physicalSize.height/2 - (referenceImage.physicalSize.height/42) * 3 + let part = (referenceImage.physicalSize.height/42) * 3 // every 3 units + let text_pos = part/2 + var iter = 40 + + + while(start_y SCNNode { + let mesages = SCNText(string: text, extrusionDepth: 0) // SCN开头的geometry + if(bold) {mesages.font = UIFont(name:"HelveticaNeue-Bold", size: 12)} + else {mesages.font = UIFont(name:"HelveticaNeue", size: 12)} + let material = SCNMaterial() + material.diffuse.contents = color + mesages.materials = [material] + + let messageNode = SCNNode(geometry: mesages) + messageNode.scale = SCNVector3Make( 0.001*size, 0.001*size, 0.001*size) + // 锚点 + // set pivot of left top point + var minVec = SCNVector3Zero + var maxVec = SCNVector3Zero + (minVec, maxVec) = messageNode.boundingBox + if(center){ + messageNode.pivot = SCNMatrix4MakeTranslation( + (minVec.x + maxVec.x)/2, + maxVec.y, + minVec.z + ) + messageNode.position = messageNode.position + position + } + else {messageNode.pivot = SCNMatrix4MakeTranslation( + minVec.x, + maxVec.y, + minVec.z + ) + messageNode.eulerAngles.x = -.pi/2 + messageNode.position = messageNode.position + position + } + + return messageNode + } + + func lineNode(color: UIColor, height: CGFloat, position: SCNVector3, angle: Float) -> SCNNode{ + // Add vertical line + let LineConnect = SCNCylinder() + LineConnect.radius = 0.001 + LineConnect.height = height + LineConnect.radialSegmentCount = 5 + LineConnect.firstMaterial!.diffuse.contents = color + let LineNode = SCNNode(geometry: LineConnect) + LineNode.pivot = SCNMatrix4MakeTranslation( + 0, + -Float(height/2), + 0 + ) + LineNode.position = position + LineNode.eulerAngles.x = -.pi/2 + LineNode.eulerAngles.y = -.pi/2+angle + + return LineNode + } + + func ballNode(color: UIColor, position: SCNVector3, radius: CGFloat) -> SCNNode{ + let ballGeo = SCNSphere() + ballGeo.radius = radius + ballGeo.firstMaterial!.diffuse.contents = color + let ballNode = SCNNode(geometry: ballGeo) + ballNode.position = position + return ballNode + } + + func planeNode(width: CGFloat, height: CGFloat, opacity: CGFloat, position: SCNVector3, conor: CGFloat = 0)->SCNNode{ + let plane = SCNPlane(width: width, height: height) + plane.cornerRadius = conor + let planeNode = SCNNode(geometry: plane) + planeNode.eulerAngles.x = -.pi/2 + planeNode.opacity = opacity + planeNode.position = position + return planeNode + } + + func see_chart_button() -> SCNNode{ + let node = SCNNode() + node.addChildNode(textNode(text: "Show Temperature Plots", position: SCNVector3(0, 0, 0), color: .brown)) + node.addChildNode(lineNode(color: .cyan, height: 0.1/cos(.pi/2), position: SCNVector3(0, 0, 0), angle: -.pi/4)) + node.addChildNode(lineNode(color: .cyan, height: 0.1/cos(.pi/2), position: SCNVector3(0, 0, 0), angle: .pi/4)) + return node + } + + + @IBAction func tap_add_chart(_ sender: UITapGestureRecognizer) { + let currentTouchLocation = sender.location(in: sceneView) + print(currentTouchLocation) + guard let hitTestResultNode = self.sceneView.hitTest(currentTouchLocation, options: nil).first?.node else { return } + guard let name = hitTestResultNode.name else{ return } + print("name") + if(name=="temp"){ + // TODO + print("here") + self.chartNode?.isHidden = false + self.addPlane?.runAction(self.imageAppearAction) + } + + } + + func add_chart() -> SCNNode{ + let date = Date() + let calendar = Calendar.current + let hour = calendar.component(.hour, from: date) + let minutes = calendar.component(.minute, from: date) + let node = SCNNode() + node.addChildNode(lineNode(color: .darkGray, height: 0.1, position: SCNVector3(0, 0, 0), angle: .pi/2)) + node.addChildNode(lineNode(color: .darkGray, height: 0.2, position: SCNVector3(0, 0, 0), angle: 0)) + let height = temperatures.max()! - temperatures.min()! + let length = 0.18/Double(temperatures.count-1) + var now_height = 0.005 + for i in 0...(temperatures.count-2){ + let height = (temperatures[i+1] - temperatures[i])/height * 0.09 + let angle = atan(height/length) + node.addChildNode(lineNode(color: .cyan, height: CGFloat(length/cos(angle)), position: SCNVector3(0.01 + length * Double(i), 0, -now_height), angle: Float(angle))) + node.addChildNode(ballNode(color: .cyan, position: SCNVector3(0.01 + length * Double(i), 0, -now_height), radius: 0.001)) + node.addChildNode(textNode(text: String(temperatures[i]), position: SCNVector3Make(Float(0.01 + length * Double(i)), 0, -Float(now_height)), bold: false, size: 1, color: .darkGray)) + node.addChildNode(textNode(text: String(hour) + ":" + String(minutes - temperatures.count + 1 + i), position: SCNVector3(Float(0.01 + length * Double(i)), 0, 0.01), bold: false, size: 1, color: .darkGray)) + now_height += height + } + let i = temperatures.count - 1 + node.addChildNode(textNode(text: String(temperatures[i]), position: SCNVector3(Float(0.01 + length * Double(i)), 0, -Float(now_height)), bold: false, size: 1, color: .darkGray)) + node.addChildNode(textNode(text: String(hour) + ":" + String(minutes), position: SCNVector3(Float(0.01 + length * Double(i)), 0, 0.01), bold: false, size: 1, color: .darkGray)) + node.addChildNode(textNode(text: "time: ", position: SCNVector3(-0.02, 0, 0.01), bold: false, size: 1, color: .darkGray)) + return node + } + +} + +extension SCNVector3 { + static func + (left: SCNVector3, right: SCNVector3) -> SCNVector3 { + return SCNVector3Make(left.x + right.x, left.y + right.y, left.z + right.z) + } +} diff --git a/contrib/ar4dcops/app_ios/FlowAR/art.scnassets/wireframe_shader.metal b/contrib/ar4dcops/app_ios/FlowAR/art.scnassets/wireframe_shader.metal new file mode 100644 index 000000000..68ea78beb --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowAR/art.scnassets/wireframe_shader.metal @@ -0,0 +1,49 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +SceneKit shader modifier to render bounding box edges with distance-based fade. +*/ +#pragma transparent +#pragma body + +float3 modelPosition = scn_node.modelTransform[3].xyz; +float3 viewPosition = scn_frame.inverseViewTransform[3].xyz; +float distance = length(modelPosition - viewPosition); + +float3 bBoxMin = scn_node.boundingBox[0]; +float3 bBoxMax = scn_node.boundingBox[1]; +float3 size = bBoxMax - bBoxMin; +float bBoxDiag = length(size); + +//////////////////////////////////////////////////////////////// +// Compute per-pixel transparency based on distance from camera +//////////////////////////////////////////////////////////////// +float closest = distance - bBoxDiag / 2.0; +float furthest = distance + bBoxDiag / 2.0; +float distFromPointOfView = length(_surface.position); +float normalizedDistance = 1 - ((distFromPointOfView - closest) / (furthest - closest)); +_surface.transparent.a = clamp(normalizedDistance, 0.0, 1.0); + +//////////////////////////////////////////////////////////////// +// Render only a wireframe +//////////////////////////////////////////////////////////////// +float lineThickness = 0.01; +float u = _surface.diffuseTexcoord.x; +float v = _surface.diffuseTexcoord.y; + +// Compute scaling of line thickness based on bounding box size +float2 scale; +if (abs((scn_node.inverseModelViewTransform * float4(_surface.normal, 0.0)).x) > 0.5) { + scale = size.zy; +} else if (abs((scn_node.inverseModelViewTransform * float4(_surface.normal, 0.0)).y) > 0.5) { + scale = size.xz; +} else { + scale = size.xy; +} + +// Compute threshold for discarding rendering +float2 thresh = float2(lineThickness) / scale; +if (u > thresh[0] && u < (1.0 - thresh[0]) && v > thresh[1] && v < (1.0 - thresh[1])) { + discard_fragment(); +} diff --git a/contrib/ar4dcops/app_ios/FlowARTests/FlowARTests.swift b/contrib/ar4dcops/app_ios/FlowARTests/FlowARTests.swift new file mode 100644 index 000000000..38113271d --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowARTests/FlowARTests.swift @@ -0,0 +1,34 @@ +// +// FlowARTests.swift +// FlowARTests +// +// Created by 周舒意 on 2020/10/20. +// Copyright © 2020 周舒意. All rights reserved. +// + +import XCTest +@testable import FlowAR + +class FlowARTests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/contrib/ar4dcops/app_ios/FlowARTests/Info.plist b/contrib/ar4dcops/app_ios/FlowARTests/Info.plist new file mode 100644 index 000000000..64d65ca49 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowARTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/contrib/ar4dcops/app_ios/FlowARUITests/FlowARUITests.swift b/contrib/ar4dcops/app_ios/FlowARUITests/FlowARUITests.swift new file mode 100644 index 000000000..ea4994f19 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowARUITests/FlowARUITests.swift @@ -0,0 +1,43 @@ +// +// FlowARUITests.swift +// FlowARUITests +// +// Created by 周舒意 on 2020/10/20. +// Copyright © 2020 周舒意. All rights reserved. +// + +import XCTest + +class FlowARUITests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) { + XCUIApplication().launch() + } + } + } +} diff --git a/contrib/ar4dcops/app_ios/FlowARUITests/Info.plist b/contrib/ar4dcops/app_ios/FlowARUITests/Info.plist new file mode 100644 index 000000000..64d65ca49 --- /dev/null +++ b/contrib/ar4dcops/app_ios/FlowARUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/contrib/ar4dcops/app_ios/README.md b/contrib/ar4dcops/app_ios/README.md new file mode 100644 index 000000000..19ec58c57 --- /dev/null +++ b/contrib/ar4dcops/app_ios/README.md @@ -0,0 +1,6 @@ +# App-IOS + +An Augmented Reality (AR) based app that runs on iOS systems to aid data center maintenance and audit work. It obtains data from +the back-end server Flowgate, which integrates all the information related to a specific data +center, and displays necessary information onto real scenes" in the data center using AR +technology. \ No newline at end of file