diff --git a/libraries/include/arcore_c_api.h b/libraries/include/arcore_c_api.h
index 19ff3bf1b..abbadd815 100644
--- a/libraries/include/arcore_c_api.h
+++ b/libraries/include/arcore_c_api.h
@@ -110,6 +110,9 @@
/// @defgroup config Configuration
/// Session configuration.
+/// @defgroup cameraconfig CameraConfig
+/// Camera configuration.
+
/// @defgroup frame Frame
/// Per-frame state.
@@ -158,10 +161,31 @@ typedef struct ArConfig_ ArConfig;
/// @}
+// CameraConfig objects and list.
+
+/// @addtogroup cameraconfig
+/// @{
+
+/// A camera config struct that contains the config supported by
+/// the physical camera obtained from the low level device profiles.
+/// (@ref ownership "value type").
+///
+/// Allocate with ArCameraConfig_create()
+/// Release with ArCameraConfig_destroy()
+typedef struct ArCameraConfig_ ArCameraConfig;
+
+/// A list of camera config (@ref ownership "value type").
+///
+/// Allocate with ArCameraConfigList_create()
+/// Release with ArCameraConfigList_destroy()
+typedef struct ArCameraConfigList_ ArCameraConfigList;
+
+/// @}
+
/// @addtogroup session
/// @{
-/// The ArCore session (@ref ownership "value type").
+/// The ARCore session (@ref ownership "value type").
///
/// Create with ArSession_create()
/// Release with ArSession_destroy()
@@ -443,7 +467,7 @@ inline ArPoint *ArAsPoint(ArTrackable *trackable) {
inline ArAugmentedImage *ArAsAugmentedImage(ArTrackable *trackable) {
return reinterpret_cast(trackable);
}
-#endif
+#endif // __cplusplus
/// @}
// If compiling for C++11, use the 'enum underlying type' feature to enforce
@@ -568,6 +592,13 @@ AR_DEFINE_ENUM(ArStatus){
/// of the SDK.
AR_ERROR_DATA_UNSUPPORTED_VERSION = -19,
+ /// A function has been invoked at an illegal or inappropriate time. A
+ /// message will be printed to logcat with additional details for the
+ /// developer. For example, ArSession_resume() will return this status if
+ /// the camera configuration was changed and there are any unreleased
+ /// images.
+ AR_ERROR_ILLEGAL_STATE = -20,
+
/// The ARCore APK is not installed on this device.
AR_UNAVAILABLE_ARCORE_NOT_INSTALLED = -100,
@@ -755,6 +786,24 @@ AR_DEFINE_ENUM(ArUpdateMode){
/// ::ArFrame object.
AR_UPDATE_MODE_LATEST_CAMERA_IMAGE = 1};
+/// @ingroup config
+/// Selects the desired behavior of the camera focus subsystem. Currently, the
+/// default focus mode is AR_FOCUS_MODE_FIXED, but the default might change in
+/// the future.
+///
+/// For optimal AR tracking performance, use the focus mode provided by the
+/// default session config. While capturing pictures or video, use
+/// AR_FOCUS_MODE_AUTO. For optimal AR tracking, revert to the default focus
+/// mode once auto focus behavior is no longer needed. If your app requires
+/// fixed focus camera, call ArConfig_setFocusMode(…, …, AR_FOCUS_MODE_FIXED)
+/// before enabling the AR session. This will ensure that your app always uses
+/// fixed focus, even if the default camera config focus mode changes in a
+/// future release.
+AR_DEFINE_ENUM(ArFocusMode){/// Focus is fixed.
+ AR_FOCUS_MODE_FIXED = 0,
+ /// Auto-focus is enabled.
+ AR_FOCUS_MODE_AUTO = 1};
+
/// @ingroup plane
/// Simple summary of the normal vector of a plane, for filtering purposes.
AR_DEFINE_ENUM(ArPlaneType){
@@ -794,8 +843,6 @@ AR_DEFINE_ENUM(ArCloudAnchorMode){
/// will require that the application have the Android INTERNET permission.
AR_CLOUD_ANCHOR_MODE_ENABLED = 1};
-#undef AR_DEFINE_ENUM
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -1035,6 +1082,74 @@ void ArConfig_getAugmentedImageDatabase(
const ArConfig *config,
ArAugmentedImageDatabase *out_augmented_image_database);
+/// Sets the focus mode that should be used. See ::ArFocusMode for available
+/// options.
+void ArConfig_setFocusMode(const ArSession *session,
+ ArConfig *config,
+ ArFocusMode focus_mode);
+
+/// Stores the currently configured focus mode into @c *focus_mode.
+void ArConfig_getFocusMode(const ArSession *session,
+ ArConfig *config,
+ ArFocusMode *focus_mode);
+
+/// @}
+
+// === ArCameraConfigList and ArCameraConfig methods ===
+
+/// @addtogroup cameraconfig
+/// @{
+
+// === ArCameraConfigList methods ===
+
+/// Creates a camera config list object.
+///
+/// @param[in] session The ARCore session
+/// @param[out] out_list A pointer to an @c ArCameraConfigList* to receive
+/// the address of the newly allocated ArCameraConfigList.
+void ArCameraConfigList_create(const ArSession *session,
+ ArCameraConfigList **out_list);
+
+/// Releases the memory used by a camera config list object,
+/// along with all the camera config references it holds.
+void ArCameraConfigList_destroy(ArCameraConfigList *list);
+
+/// Retrieves the number of camera configs in this list.
+void ArCameraConfigList_getSize(const ArSession *session,
+ const ArCameraConfigList *list,
+ int32_t *out_size);
+
+/// Retrieves the specific camera config based on the position in this list.
+void ArCameraConfigList_getItem(const ArSession *session,
+ const ArCameraConfigList *list,
+ int32_t index,
+ ArCameraConfig *out_camera_config);
+
+// === ArCameraConfig methods ===
+
+/// Creates a camera config object.
+///
+/// @param[in] session The ARCore session
+/// @param[out] out_camera_config A pointer to an @c ArCameraConfig* to receive
+/// the address of the newly allocated ArCameraConfig.
+void ArCameraConfig_create(const ArSession *session,
+ ArCameraConfig **out_camera_config);
+
+/// Releases the memory used by a camera config object.
+void ArCameraConfig_destroy(ArCameraConfig *camera_config);
+
+/// Obtains the camera image dimensions for the given camera config.
+void ArCameraConfig_getImageDimensions(const ArSession *session,
+ const ArCameraConfig *camera_config,
+ int32_t *out_width,
+ int32_t *out_height);
+
+/// Obtains the texture dimensions for the given camera config.
+void ArCameraConfig_getTextureDimensions(const ArSession *session,
+ const ArCameraConfig *camera_config,
+ int32_t *out_width,
+ int32_t *out_height);
+
/// @}
// === ArSession methods ===
@@ -1043,6 +1158,10 @@ void ArConfig_getAugmentedImageDatabase(
/// @{
/// Releases resources used by an ARCore session.
+/// This method will take several seconds to complete. To prevent blocking
+/// the main thread, call ArSession_pause() on the main thread, and then call
+/// ArSession_destroy() on a background thread.
+///
void ArSession_destroy(ArSession *session);
/// Before release 1.2.0: Checks if the provided configuration is usable on the
@@ -1088,10 +1207,18 @@ void ArSession_getConfig(ArSession *session, ArConfig *out_config);
/// href="https://developer.android.com/reference/android/app/Activity.html#onResume()"
/// >Activity.onResume().
///
+/// Note that if the camera configuration has been changed by
+/// ArSession_setCameraConfig() since the last call to ArSession_resume(), all
+/// images previously acquired using ArFrame_acquireCameraImage() must be
+/// released by calling ArImage_release() before calling ArSession_resume(). If
+/// there are open images, ArSession_resume will return AR_ERROR_ILLEGAL_STATE
+/// and the session will not resume.
+///
/// @returns #AR_SUCCESS or any of:
/// - #AR_ERROR_FATAL
/// - #AR_ERROR_CAMERA_PERMISSION_NOT_GRANTED
/// - #AR_ERROR_CAMERA_NOT_AVAILABLE
+/// - #AR_ERROR_ILLEGAL_STATE
ArStatus ArSession_resume(ArSession *session);
/// Pause the current session. This method will stop the camera feed and release
@@ -1101,6 +1228,9 @@ ArStatus ArSession_resume(ArSession *session);
/// href="https://developer.android.com/reference/android/app/Activity.html#onPause()"
/// >Activity.onPause().
///
+/// Note that ARCore might continue consuming substantial computing resources
+/// for up to 10 seconds after calling this method.
+///
/// @returns #AR_SUCCESS or any of:
/// - #AR_ERROR_FATAL
ArStatus ArSession_pause(ArSession *session);
@@ -1248,6 +1378,57 @@ ArStatus ArSession_resolveAndAcquireNewCloudAnchor(ArSession *session,
const char *cloud_anchor_id,
ArAnchor **out_cloud_anchor);
+/// Enumerates the list of supported camera configs on the device.
+/// Can be called at any time. The supported camera configs will be filled in
+/// the provided list after clearing it.
+///
+/// The list will always return 3 camera configs. The GPU texture resolutions
+/// are the same in all three configs. Currently, most devices provide GPU
+/// texture resolution of 1920 x 1080, but devices might provide higher or lower
+/// resolution textures, depending on device capabilities. The CPU image
+/// resolutions returned are VGA, 720p, and a resolution matching the GPU
+/// texture.
+///
+/// @param[in] session The ARCore session
+/// @param[inout] list The list to fill. This list must have already
+/// been allocated with ArCameraConfigList_create(). The list is cleared
+/// to remove any existing elements. Once it is no longer needed, the list
+/// must be destroyed using ArCameraConfigList_destroy to release allocated
+/// memory.
+void ArSession_getSupportedCameraConfigs(const ArSession *session,
+ ArCameraConfigList *list);
+
+/// Sets the ArCameraConfig that the ArSession should use. Can only be called
+/// while the session is paused. The provided ArCameraConfig must be one of the
+/// configs returned by ArSession_getSupportedCameraConfigs.
+///
+/// The camera config will be applied once the session is resumed.
+/// All previously acquired frame images must be released via ArImage_release
+/// before calling resume(). Failure to do so will cause resume() to return
+/// AR_ERROR_ILLEGAL_STATE error.
+///
+/// @param[in] session The ARCore session
+/// @param[in] camera_config The provided ArCameraConfig must be from a
+/// list returned by ArSession_getSupportedCameraConfigs.
+/// @return #AR_SUCCESS or any of:
+/// - #AR_ERROR_INVALID_ARGUMENT
+/// - #AR_ERROR_SESSION_NOT_PAUSED
+ArStatus ArSession_setCameraConfig(const ArSession *session,
+ const ArCameraConfig *camera_config);
+
+/// Gets the ArCameraConfig that the ArSession is currently using. If the
+/// camera config was not explicitly set then it returns the default
+/// camera config. Use ArCameraConfig_destroy to release memory associated with
+/// the returned camera config once it is no longer needed.
+///
+/// @param[in] session The ARCore session
+/// @param[inout] out_camera_config The camera config object to fill. This
+/// object must have already been allocated with ArCameraConfig_create().
+/// Use ArCameraConfig_destroy to release memory associated with
+/// out_camera_config once it is no longer needed.
+void ArSession_getCameraConfig(const ArSession *session,
+ ArCameraConfig *out_camera_config);
+
/// @}
// === ArPose methods ===
@@ -1526,6 +1707,24 @@ void ArFrame_hitTest(const ArSession *session,
float pixel_y,
ArHitResultList *hit_result_list);
+/// Similar to ArFrame_hitTest, but takes an arbitrary ray in world space
+/// coordinates instead of a screen space point.
+///
+/// @param[in] session The ARCore session.
+/// @param[in] frame The current frame.
+/// @param[in] ray_origin_3 A pointer to float[3] array containing ray
+/// origin in world space coordinates.
+/// @param[in] ray_direction_3 A pointer to float[3] array containing ray
+/// direction in world space coordinates. Does not have to be normalized.
+/// @param[inout] hit_result_list The list to fill. This list must have been
+/// previously allocated using ArHitResultList_create(). If the list has
+/// been previously used, it will first be cleared.
+void ArFrame_hitTestRay(const ArSession *session,
+ const ArFrame *frame,
+ const float *ray_origin_3,
+ const float *ray_direction_3,
+ ArHitResultList *hit_result_list);
+
/// Gets the current ambient light estimate, if light estimation was enabled.
///
/// @param[in] session The ARCore session.
@@ -1577,6 +1776,22 @@ ArStatus ArFrame_acquireImageMetadata(const ArSession *session,
const ArFrame *frame,
ArImageMetadata **out_metadata);
+/// Gets the image of the tracking camera relative to the input session and
+/// frame. Caller is responsible for later releasing the image with @c
+/// ArImage_release.
+/// Return values:
+/// @returns #AR_SUCCESS or any of:
+/// - #AR_ERROR_INVALID_ARGUMENT - one more input arguments are invalid.
+/// - #AR_ERROR_DEADLINE_EXCEEDED - the input frame is not the current frame.
+/// - #AR_ERROR_RESOURCE_EXHAUSTED - the caller app has exceeded maximum number
+/// of images that it can hold without releasing.
+/// - #AR_ERROR_NOT_YET_AVAILABLE - image with the timestamp of the input frame
+/// was not found within a bounded amount of time, or the camera failed to
+/// produce the image
+ArStatus ArFrame_acquireCameraImage(ArSession *session,
+ ArFrame *frame,
+ ArImage **out_image);
+
/// Gets the set of anchors that were changed by the ArSession_update() that
/// produced this Frame.
///
@@ -1670,23 +1885,8 @@ void ArImageMetadata_getNdkCameraMetadata(
/// This method may safely be called with @c nullptr - it will do nothing.
void ArImageMetadata_release(ArImageMetadata *metadata);
-// === CPU Image Access types and methods ===
-/// Gets the image of the tracking camera relative to the input session and
-/// frame.
-/// Return values:
-/// @returns #AR_SUCCESS or any of:
-/// - #AR_ERROR_INVALID_ARGUMENT - one more input arguments are invalid.
-/// - #AR_ERROR_DEADLINE_EXCEEDED - the input frame is not the current frame.
-/// - #AR_ERROR_RESOURCE_EXHAUSTED - the caller app has exceeded maximum number
-/// of images that it can hold without releasing.
-/// - #AR_ERROR_NOT_YET_AVAILABLE - image with the timestamp of the input frame
-/// was not found within a bounded amount of time, or the camera failed to
-/// produce the image
-ArStatus ArFrame_acquireCameraImage(ArSession *session,
- ArFrame *frame,
- ArImage **out_image);
-
-/// Converts an ArImage object to an Android NDK AImage object.
+/// Converts an ArImage object to an Android NDK AImage object. The
+/// converted image object format is AIMAGE_FORMAT_YUV_420_888.
void ArImage_getNdkImage(const ArImage *image, const AImage **out_ndk_image);
/// Releases an instance of ArImage returned by ArFrame_acquireCameraImage().
@@ -2025,7 +2225,7 @@ void ArPoint_getPose(const ArSession *session,
/// Returns the OrientationMode of the point. For @c Point objects created by
/// ArFrame_hitTest().
/// If OrientationMode is ESTIMATED_SURFACE_NORMAL, then normal of the surface
-/// centered around the ArPoint was estimated succesfully.
+/// centered around the ArPoint was estimated successfully.
///
/// @param[in] session The ARCore session.
/// @param[in] point The point to retrieve the pose of.
@@ -2340,6 +2540,8 @@ void ArString_release(char *str);
/// Releases a byte array created using an ARCore API function.
void ArByteArray_release(uint8_t *byte_array);
+#undef AR_DEFINE_ENUM
+
#ifdef __cplusplus
}
#endif
diff --git a/samples/augmented_image_c/app/build.gradle b/samples/augmented_image_c/app/build.gradle
index 43cc8df0e..ce50fb089 100644
--- a/samples/augmented_image_c/app/build.gradle
+++ b/samples/augmented_image_c/app/build.gradle
@@ -32,6 +32,10 @@ android {
abiFilters "arm64-v8a", "x86"
}
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
buildTypes {
release {
minifyEnabled false
@@ -47,8 +51,8 @@ android {
dependencies {
// ARCore library
- implementation 'com.google.ar:core:1.3.0'
- natives 'com.google.ar:core:1.3.0'
+ implementation 'com.google.ar:core:1.4.0'
+ natives 'com.google.ar:core:1.4.0'
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support:design:27.0.2'
diff --git a/samples/augmented_image_c/app/src/main/assets/models/andy.png b/samples/augmented_image_c/app/src/main/assets/models/andy.png
index f88b1d6b4..6aa50ec2b 100644
Binary files a/samples/augmented_image_c/app/src/main/assets/models/andy.png and b/samples/augmented_image_c/app/src/main/assets/models/andy.png differ
diff --git a/samples/augmented_image_c/gradle/wrapper/gradle-wrapper.jar b/samples/augmented_image_c/gradle/wrapper/gradle-wrapper.jar
index c44b679ac..758de960e 100644
Binary files a/samples/augmented_image_c/gradle/wrapper/gradle-wrapper.jar and b/samples/augmented_image_c/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/augmented_image_c/gradlew.bat b/samples/augmented_image_c/gradlew.bat
index f9553162f..e95643d6a 100644
--- a/samples/augmented_image_c/gradlew.bat
+++ b/samples/augmented_image_c/gradlew.bat
@@ -1,84 +1,84 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/augmented_image_java/app/build.gradle b/samples/augmented_image_java/app/build.gradle
index d79b429a0..f48d6751e 100644
--- a/samples/augmented_image_java/app/build.gradle
+++ b/samples/augmented_image_java/app/build.gradle
@@ -11,7 +11,10 @@ android {
versionCode 1
versionName "1.0"
}
-
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
buildTypes {
release {
minifyEnabled false
@@ -22,7 +25,7 @@ android {
dependencies {
// ARCore library
- implementation 'com.google.ar:core:1.3.0'
+ implementation 'com.google.ar:core:1.4.0'
// Obj - a simple Wavefront OBJ file loader
// https://github.com/javagl/Obj
diff --git a/samples/augmented_image_java/app/src/main/assets/models/andy.png b/samples/augmented_image_java/app/src/main/assets/models/andy.png
index f88b1d6b4..6aa50ec2b 100644
Binary files a/samples/augmented_image_java/app/src/main/assets/models/andy.png and b/samples/augmented_image_java/app/src/main/assets/models/andy.png differ
diff --git a/samples/augmented_image_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java b/samples/augmented_image_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
index d84573788..87dc77daa 100644
--- a/samples/augmented_image_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
+++ b/samples/augmented_image_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
@@ -123,7 +123,7 @@ public void update(PointCloud cloud) {
}
/**
- * Renders the point cloud. ArCore point cloud is given in world space.
+ * Renders the point cloud. ARCore point cloud is given in world space.
*
* @param cameraView the camera view matrix for this frame, typically from {@link
* com.google.ar.core.Camera#getViewMatrix(float[], int)}.
diff --git a/samples/augmented_image_java/gradle/wrapper/gradle-wrapper.jar b/samples/augmented_image_java/gradle/wrapper/gradle-wrapper.jar
index c44b679ac..758de960e 100644
Binary files a/samples/augmented_image_java/gradle/wrapper/gradle-wrapper.jar and b/samples/augmented_image_java/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/augmented_image_java/gradlew.bat b/samples/augmented_image_java/gradlew.bat
index f9553162f..e95643d6a 100644
--- a/samples/augmented_image_java/gradlew.bat
+++ b/samples/augmented_image_java/gradlew.bat
@@ -1,84 +1,84 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/cloud_anchor_c/app/build.gradle b/samples/cloud_anchor_c/app/build.gradle
index 05275a5c8..2f10d08af 100644
--- a/samples/cloud_anchor_c/app/build.gradle
+++ b/samples/cloud_anchor_c/app/build.gradle
@@ -32,6 +32,10 @@ android {
abiFilters "arm64-v8a", "x86"
}
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
buildTypes {
release {
minifyEnabled false
@@ -51,8 +55,8 @@ android {
dependencies {
// ARCore library
- implementation 'com.google.ar:core:1.3.0'
- natives 'com.google.ar:core:1.3.0'
+ implementation 'com.google.ar:core:1.4.0'
+ natives 'com.google.ar:core:1.4.0'
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support:design:27.0.2'
diff --git a/samples/cloud_anchor_c/app/src/main/assets/models/andy.png b/samples/cloud_anchor_c/app/src/main/assets/models/andy.png
index f88b1d6b4..6aa50ec2b 100644
Binary files a/samples/cloud_anchor_c/app/src/main/assets/models/andy.png and b/samples/cloud_anchor_c/app/src/main/assets/models/andy.png differ
diff --git a/samples/cloud_anchor_c/app/src/main/cpp/cloud_anchor_manager.cc b/samples/cloud_anchor_c/app/src/main/cpp/cloud_anchor_manager.cc
index ba597dcf4..148e610a6 100644
--- a/samples/cloud_anchor_c/app/src/main/cpp/cloud_anchor_manager.cc
+++ b/samples/cloud_anchor_c/app/src/main/cpp/cloud_anchor_manager.cc
@@ -4,6 +4,36 @@
#include "util.h"
namespace cloud_anchor {
+namespace {
+
+#define CASE_VALUE_RETURN_STRING(_value) \
+ case _value: \
+ return #_value;
+
+std::string CloudAnchorStateString(ArCloudAnchorState cloud_state) {
+ switch (cloud_state) {
+ CASE_VALUE_RETURN_STRING(AR_CLOUD_ANCHOR_STATE_SUCCESS);
+ CASE_VALUE_RETURN_STRING(AR_CLOUD_ANCHOR_STATE_ERROR_INTERNAL);
+ CASE_VALUE_RETURN_STRING(AR_CLOUD_ANCHOR_STATE_TASK_IN_PROGRESS);
+ CASE_VALUE_RETURN_STRING(
+ AR_CLOUD_ANCHOR_STATE_ERROR_HOSTING_DATASET_PROCESSING_FAILED);
+ CASE_VALUE_RETURN_STRING(AR_CLOUD_ANCHOR_STATE_ERROR_SERVICE_UNAVAILABLE);
+ CASE_VALUE_RETURN_STRING(AR_CLOUD_ANCHOR_STATE_ERROR_RESOURCE_EXHAUSTED);
+ CASE_VALUE_RETURN_STRING(AR_CLOUD_ANCHOR_STATE_ERROR_CLOUD_ID_NOT_FOUND);
+ CASE_VALUE_RETURN_STRING(AR_CLOUD_ANCHOR_STATE_ERROR_NOT_AUTHORIZED);
+ CASE_VALUE_RETURN_STRING(
+ AR_CLOUD_ANCHOR_STATE_ERROR_RESOLVING_LOCALIZATION_NO_MATCH);
+ CASE_VALUE_RETURN_STRING(
+ AR_CLOUD_ANCHOR_STATE_ERROR_RESOLVING_SDK_VERSION_TOO_NEW);
+ CASE_VALUE_RETURN_STRING(
+ AR_CLOUD_ANCHOR_STATE_ERROR_RESOLVING_SDK_VERSION_TOO_OLD);
+ CASE_VALUE_RETURN_STRING(AR_CLOUD_ANCHOR_STATE_NONE);
+ }
+}
+
+#undef CASE_VALUE_RETURN_STRING
+
+} // namespace
CloudAnchorManager::CloudAnchorManager()
: host_resolve_mode_(HostResolveMode::NONE) {}
@@ -53,22 +83,9 @@ void CloudAnchorManager::SetTrackedCloudAnchor(ArAnchor* anchor) {
ArAnchor_release(ar_cloud_anchor_);
}
ar_cloud_anchor_ = anchor;
-
pending_anchor_ = nullptr;
}
-bool CloudAnchorManager::PromotePendingAnchorToCloudAnchor() {
- // Note: This function is private and it is assumed the write lock is held.
- if (!pending_anchor_) {
- return false;
- }
- if (AnchorInReturnableState(pending_anchor_)) {
- SetTrackedCloudAnchor(pending_anchor_);
- return true;
- }
- return false;
-}
-
void CloudAnchorManager::OnHostButtonPress() {
std::lock_guard lock(mutex_);
CHECK(host_resolve_mode_ == HostResolveMode::NONE ||
@@ -85,7 +102,7 @@ void CloudAnchorManager::OnHostButtonPress() {
case HostResolveMode::HOSTING:
// When the host button is pressed in hosting state, it cancels.
SetTrackedCloudAnchor(nullptr);
- host_resolve_mode_ = HostResolveMode::NONE,
+ host_resolve_mode_ = HostResolveMode::NONE;
util::SetHostAndResolveButtonVisibility(
util::HostResolveVisibilityEnum::ALL);
util::UpdateFirebaseRoomCode(false, 0);
@@ -168,9 +185,21 @@ void CloudAnchorManager::OnUpdate(const ArFrame* ar_frame) {
CHECK(ar_session_);
CHECK(ar_frame);
- if (PromotePendingAnchorToCloudAnchor()) {
+ if (pending_anchor_ == nullptr || !AnchorInReturnableState(pending_anchor_)) {
+ return;
+ }
+
+ ArCloudAnchorState cloud_state;
+ ArAnchor_getCloudAnchorState(ar_session_, pending_anchor_, &cloud_state);
+ if (cloud_state == AR_CLOUD_ANCHOR_STATE_SUCCESS) {
+ SetTrackedCloudAnchor(pending_anchor_);
util::MaybeUpdateFirebase(GetCloudAnchorId());
+ } else {
+ SetTrackedCloudAnchor(nullptr);
+ util::DisplayMessageOnLowerSnackbar("Error while hosting anchor: " +
+ CloudAnchorStateString(cloud_state));
}
+ host_resolve_mode_ = HostResolveMode::NONE;
}
const ArAnchor* CloudAnchorManager::GetCloudAnchor() const {
diff --git a/samples/cloud_anchor_c/app/src/main/cpp/cloud_anchor_manager.h b/samples/cloud_anchor_c/app/src/main/cpp/cloud_anchor_manager.h
index 1d97d5613..277eeba91 100644
--- a/samples/cloud_anchor_c/app/src/main/cpp/cloud_anchor_manager.h
+++ b/samples/cloud_anchor_c/app/src/main/cpp/cloud_anchor_manager.h
@@ -63,12 +63,6 @@ class CloudAnchorManager {
// anchor will become unset.
void SetTrackedCloudAnchor(ArAnchor* anchor);
- // If there is a pending anchor and it has reached a valid tracking state then
- // the current cloud anchor will be updated and this will return true. If
- // this function returns false there either was no anchor pending or the
- // anchor is not in a tracking state.
- bool PromotePendingAnchorToCloudAnchor();
-
// This pointer is owned by the application context.
ArSession* ar_session_ = nullptr;
diff --git a/samples/cloud_anchor_c/gradle/wrapper/gradle-wrapper.jar b/samples/cloud_anchor_c/gradle/wrapper/gradle-wrapper.jar
index c44b679ac..758de960e 100644
Binary files a/samples/cloud_anchor_c/gradle/wrapper/gradle-wrapper.jar and b/samples/cloud_anchor_c/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/cloud_anchor_c/gradlew.bat b/samples/cloud_anchor_c/gradlew.bat
index f9553162f..e95643d6a 100644
--- a/samples/cloud_anchor_c/gradlew.bat
+++ b/samples/cloud_anchor_c/gradlew.bat
@@ -1,84 +1,84 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/cloud_anchor_java/app/build.gradle b/samples/cloud_anchor_java/app/build.gradle
index 7e16879b5..e5cd5fab6 100644
--- a/samples/cloud_anchor_java/app/build.gradle
+++ b/samples/cloud_anchor_java/app/build.gradle
@@ -25,7 +25,7 @@ android {
dependencies {
// ARCore library
- implementation 'com.google.ar:core:1.3.0'
+ implementation 'com.google.ar:core:1.4.0'
// Obj - a simple Wavefront OBJ file loader
// https://github.com/javagl/Obj
diff --git a/samples/cloud_anchor_java/app/src/main/assets/models/andy.png b/samples/cloud_anchor_java/app/src/main/assets/models/andy.png
index f88b1d6b4..6aa50ec2b 100644
Binary files a/samples/cloud_anchor_java/app/src/main/assets/models/andy.png and b/samples/cloud_anchor_java/app/src/main/assets/models/andy.png differ
diff --git a/samples/cloud_anchor_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java b/samples/cloud_anchor_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
index d84573788..87dc77daa 100644
--- a/samples/cloud_anchor_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
+++ b/samples/cloud_anchor_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
@@ -123,7 +123,7 @@ public void update(PointCloud cloud) {
}
/**
- * Renders the point cloud. ArCore point cloud is given in world space.
+ * Renders the point cloud. ARCore point cloud is given in world space.
*
* @param cameraView the camera view matrix for this frame, typically from {@link
* com.google.ar.core.Camera#getViewMatrix(float[], int)}.
diff --git a/samples/cloud_anchor_java/gradle/wrapper/gradle-wrapper.jar b/samples/cloud_anchor_java/gradle/wrapper/gradle-wrapper.jar
index c44b679ac..758de960e 100644
Binary files a/samples/cloud_anchor_java/gradle/wrapper/gradle-wrapper.jar and b/samples/cloud_anchor_java/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/cloud_anchor_java/gradlew.bat b/samples/cloud_anchor_java/gradlew.bat
index f9553162f..e95643d6a 100644
--- a/samples/cloud_anchor_java/gradlew.bat
+++ b/samples/cloud_anchor_java/gradlew.bat
@@ -1,84 +1,84 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/computervision_c/app/build.gradle b/samples/computervision_c/app/build.gradle
index 31de9157c..e065fc90e 100644
--- a/samples/computervision_c/app/build.gradle
+++ b/samples/computervision_c/app/build.gradle
@@ -32,6 +32,10 @@ android {
abiFilters "arm64-v8a", "x86"
}
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
buildTypes {
release {
minifyEnabled false
@@ -47,8 +51,8 @@ android {
dependencies {
// ARCore library
- implementation 'com.google.ar:core:1.3.0'
- natives 'com.google.ar:core:1.3.0'
+ implementation 'com.google.ar:core:1.4.0'
+ natives 'com.google.ar:core:1.4.0'
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support:design:27.0.2'
diff --git a/samples/computervision_c/app/src/main/cpp/computer_vision_application.cc b/samples/computervision_c/app/src/main/cpp/computer_vision_application.cc
index 8477adf6d..a086d86b1 100644
--- a/samples/computervision_c/app/src/main/cpp/computer_vision_application.cc
+++ b/samples/computervision_c/app/src/main/cpp/computer_vision_application.cc
@@ -18,6 +18,8 @@
#include
#include
#include
+#include
+#include
#include "util.h"
@@ -51,9 +53,17 @@ ComputerVisionApplication::ComputerVisionApplication(
: asset_manager_(asset_manager) {}
ComputerVisionApplication::~ComputerVisionApplication() {
- ArSession_destroy(ar_session_);
- ArFrame_destroy(ar_frame_);
- ArCameraIntrinsics_destroy(ar_camera_intrinsics_);
+ if (ar_session_ != nullptr) {
+ destroyCameraConfigs();
+ ArSession_destroy(ar_session_);
+ ArConfig_destroy(ar_config_);
+ }
+ if (ar_frame_ != nullptr) {
+ ArFrame_destroy(ar_frame_);
+ }
+ if (ar_camera_intrinsics_ != nullptr) {
+ ArCameraIntrinsics_destroy(ar_camera_intrinsics_);
+ }
}
void ComputerVisionApplication::OnPause() {
@@ -96,9 +106,14 @@ void ComputerVisionApplication::OnResume(void* env, void* context,
CHECK(ArSession_create(env, context, &ar_session_) == AR_SUCCESS);
CHECK(ar_session_);
+ ArConfig_create(ar_session_, &ar_config_);
+ CHECK(ar_config_);
+
ArFrame_create(ar_session_, &ar_frame_);
CHECK(ar_frame_);
+ obtainCameraConfigs();
+
ArCameraIntrinsics_create(ar_session_, &ar_camera_intrinsics_);
CHECK(ar_camera_intrinsics_);
@@ -158,21 +173,172 @@ void ComputerVisionApplication::OnDrawFrame(float split_position) {
"ComputerVisionApplication::OnDrawFrame acquire camera image not "
"ready.");
}
+
cpu_image_renderer_.Draw(ar_session_, ar_frame_, ndk_image, aspect_ratio_,
camera_to_display_rotation_, split_position);
}
+std::string ComputerVisionApplication::getCameraConfigLabel(
+ bool is_low_resolution) {
+ if (is_low_resolution && cpu_low_resolution_camera_config_ptr_ != nullptr) {
+ return "Low Resolution" +
+ cpu_low_resolution_camera_config_ptr_->config_label;
+ } else if (!is_low_resolution &&
+ cpu_high_resolution_camera_config_ptr_ != nullptr) {
+ return "High Resolution" +
+ cpu_high_resolution_camera_config_ptr_->config_label;
+ } else {
+ return "";
+ }
+}
+
+ArStatus ComputerVisionApplication::setCameraConfig(bool is_low_resolution) {
+ // To change the AR camera config - first we pause the AR session, set the
+ // desired camera config and then resume the AR session.
+ CHECK(ar_session_)
+
+ ArSession_pause(ar_session_);
+
+ if (is_low_resolution) {
+ ArSession_setCameraConfig(ar_session_,
+ cpu_low_resolution_camera_config_ptr_->config);
+ } else {
+ ArSession_setCameraConfig(ar_session_,
+ cpu_high_resolution_camera_config_ptr_->config);
+ }
+
+ ArStatus status = ArSession_resume(ar_session_);
+ if (status != ArStatus::AR_SUCCESS) {
+ // In a rare case (such as another camera app launching) the camera may be
+ // given to a different app and so may not be available to this app. Handle
+ // this properly and recreate the session at the next iteration.
+ ArSession_destroy(ar_session_);
+ ArConfig_destroy(ar_config_);
+ ArFrame_destroy(ar_frame_);
+ }
+
+ return status;
+}
+
+void ComputerVisionApplication::SetFocusMode(bool enable_auto_focus) {
+ CHECK(ar_session_);
+ CHECK(ar_config_);
+
+ ArConfig_setFocusMode(
+ ar_session_, ar_config_,
+ enable_auto_focus ? AR_FOCUS_MODE_AUTO : AR_FOCUS_MODE_FIXED);
+
+ CHECK(ArSession_configure(ar_session_, ar_config_) == AR_SUCCESS);
+}
+
+bool ComputerVisionApplication::GetFocusMode() {
+ CHECK(ar_session_);
+ CHECK(ar_config_);
+
+ ArFocusMode focus_mode;
+ ArConfig_getFocusMode(ar_session_, ar_config_, &focus_mode);
+
+ return (focus_mode == AR_FOCUS_MODE_AUTO);
+}
+
+void ComputerVisionApplication::obtainCameraConfigs() {
+ // Retrieve supported camera configs.
+ ArCameraConfigList* all_camera_configs = nullptr;
+ int32_t num_configs = 0;
+ ArCameraConfigList_create(ar_session_, &all_camera_configs);
+ ArSession_getSupportedCameraConfigs(ar_session_, all_camera_configs);
+ ArCameraConfigList_getSize(ar_session_, all_camera_configs, &num_configs);
+
+ if (num_configs < 1) {
+ LOGE("No camera config found");
+ return;
+ }
+
+ camera_configs_.resize(num_configs);
+ for (int i = 0; i < num_configs; ++i) {
+ copyCameraConfig(ar_session_, all_camera_configs, i, num_configs,
+ &camera_configs_[i]);
+ }
+
+ // Determine the highest and lowest CPU resolutions.
+ cpu_low_resolution_camera_config_ptr_ = nullptr;
+ cpu_high_resolution_camera_config_ptr_ = nullptr;
+ getCameraConfigLowestAndHighestResolutions(
+ &cpu_low_resolution_camera_config_ptr_,
+ &cpu_high_resolution_camera_config_ptr_);
+
+ // Cleanup the list obtained as it is safe to destroy the list as camera
+ // config instances were explicitly created and copied. Refer to the
+ // previous comment.
+ ArCameraConfigList_destroy(all_camera_configs);
+}
+
+void ComputerVisionApplication::getCameraConfigLowestAndHighestResolutions(
+ CameraConfig** lowest_resolution_config,
+ CameraConfig** highest_resolution_config) {
+ if (camera_configs_.empty()) {
+ return;
+ }
+
+ int low_resolution_config_idx = 0;
+ int high_resolution_config_idx = 0;
+ int32_t smallest_height = camera_configs_[0].height;
+ int32_t largest_height = camera_configs_[0].height;
+
+ for (int i = 1; i < camera_configs_.size(); ++i) {
+ int32_t image_height = camera_configs_[i].height;
+ if (image_height < smallest_height) {
+ smallest_height = image_height;
+ low_resolution_config_idx = i;
+ } else if (image_height > largest_height) {
+ largest_height = image_height;
+ high_resolution_config_idx = i;
+ }
+ }
+
+ if (low_resolution_config_idx == high_resolution_config_idx) {
+ *lowest_resolution_config = &camera_configs_[low_resolution_config_idx];
+ } else {
+ *lowest_resolution_config = &camera_configs_[low_resolution_config_idx];
+ *highest_resolution_config = &camera_configs_[high_resolution_config_idx];
+ }
+}
+
+void ComputerVisionApplication::copyCameraConfig(
+ const ArSession* ar_session, const ArCameraConfigList* all_configs,
+ int index, int num_configs, CameraConfig* camera_config) {
+ if (camera_config != nullptr && index >= 0 && index < num_configs) {
+ ArCameraConfig_create(ar_session, &camera_config->config);
+ ArCameraConfigList_getItem(ar_session, all_configs, index,
+ camera_config->config);
+ ArCameraConfig_getImageDimensions(ar_session, camera_config->config,
+ &camera_config->width,
+ &camera_config->height);
+ camera_config->config_label = "(" + std::to_string(camera_config->width) +
+ "x" + std::to_string(camera_config->height) +
+ ")";
+ }
+}
+
+void ComputerVisionApplication::destroyCameraConfigs() {
+ for (int i = 0; i < camera_configs_.size(); ++i) {
+ if (camera_configs_[i].config != nullptr) {
+ ArCameraConfig_destroy(camera_configs_[i].config);
+ }
+ }
+}
+
std::string ComputerVisionApplication::GetCameraIntrinsicsText(
- bool show_cpu_intrinsics) {
+ bool for_gpu_texture) {
if (ar_session_ == nullptr) return "";
ArCamera* ar_camera;
ArFrame_acquireCamera(ar_session_, ar_frame_, &ar_camera);
- if (show_cpu_intrinsics) {
- ArCamera_getImageIntrinsics(ar_session_, ar_camera, ar_camera_intrinsics_);
- } else {
+ if (for_gpu_texture) {
ArCamera_getTextureIntrinsics(ar_session_, ar_camera,
ar_camera_intrinsics_);
+ } else {
+ ArCamera_getImageIntrinsics(ar_session_, ar_camera, ar_camera_intrinsics_);
}
float fx;
@@ -196,15 +362,17 @@ std::string ComputerVisionApplication::GetCameraIntrinsicsText(
fov_x *= kRadiansToDegrees;
fov_y *= kRadiansToDegrees;
- std::string intrinsics_type_label(show_cpu_intrinsics ? "Image" : "Texture");
-
- return "Unrotated Camera " + intrinsics_type_label +
- " Intrinsics:\n\tFocal Length: (" + std::to_string(fx) + ", " +
- std::to_string(fy) + ")\n\tPrincipal Point: (" + std::to_string(cx) +
- ", " + std::to_string(cy) + ")\n\tImage Dimensions: (" +
- std::to_string(image_width) + ", " + std::to_string(image_height) +
- ")\n\tUnrotated Field of View: (" + std::to_string(fov_x) + "º, " +
- std::to_string(fov_y) + "º)";
+ std::ostringstream intrinsics_text;
+ intrinsics_text << std::fixed << std::setprecision(2) << "Unrotated Camera "
+ << (for_gpu_texture ? "GPU Texture" : "CPU Image")
+ << " Intrinsics:\n\tFocal Length: (" << fx << ", " << fy
+ << ")\n\tPrincipal Point: (" << cx << ", " << cy << ")\n\t"
+ << (for_gpu_texture ? "GPU" : "CPU") << " Image Dimensions: ("
+ << image_width << ", " << image_height
+ << ")\n\tUnrotated Field of View: (" << fov_x << "º, "
+ << fov_y << "º)";
+
+ return intrinsics_text.str();
}
} // namespace computer_vision
diff --git a/samples/computervision_c/app/src/main/cpp/computer_vision_application.h b/samples/computervision_c/app/src/main/cpp/computer_vision_application.h
index 57ccb1531..3a1e85ea1 100644
--- a/samples/computervision_c/app/src/main/cpp/computer_vision_application.h
+++ b/samples/computervision_c/app/src/main/cpp/computer_vision_application.h
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include "arcore_c_api.h"
#include "cpu_image_renderer.h"
@@ -62,11 +63,22 @@ class ComputerVisionApplication {
// OnDrawFrame is called on the OpenGL thread to render the next frame.
void OnDrawFrame(float split_position);
+ // Get the text label of a camera config.
+ // Return an empty string if the camera config is not available.
+ std::string getCameraConfigLabel(bool is_low_resolution);
+
+ // Set camera config with low or high resolution.
+ ArStatus setCameraConfig(bool is_low_resolution);
+
+ void SetFocusMode(bool enable_auto_focus);
+ bool GetFocusMode();
+
// Get the text logs for the camera intrinsics.
- std::string GetCameraIntrinsicsText(bool show_cpu_intrinsics);
+ std::string GetCameraIntrinsicsText(bool for_gpu_texture);
private:
ArSession* ar_session_ = nullptr;
+ ArConfig* ar_config_ = nullptr;
ArFrame* ar_frame_ = nullptr;
ArCameraIntrinsics* ar_camera_intrinsics_ = nullptr;
@@ -80,6 +92,35 @@ class ComputerVisionApplication {
AAssetManager* const asset_manager_;
CpuImageRenderer cpu_image_renderer_;
+
+ struct CameraConfig {
+ int32_t width = 0;
+ int32_t height = 0;
+ std::string config_label;
+ ArCameraConfig* config = nullptr;
+ };
+
+ std::vector camera_configs_;
+ CameraConfig* cpu_low_resolution_camera_config_ptr_ = nullptr;
+ CameraConfig* cpu_high_resolution_camera_config_ptr_ = nullptr;
+
+ // Obtain all camera configs (and update camera_configs_) and sort out the
+ // configs with lowest and highest image resolutions.
+ void obtainCameraConfigs();
+
+ // Copy one camera config from ArCameraConfigList to a CameraConfig.
+ void copyCameraConfig(const ArSession* ar_session,
+ const ArCameraConfigList* all_configs, int index,
+ int num_configs, CameraConfig* camera_config);
+
+ // Release memory in camera_configs_.
+ void destroyCameraConfigs();
+
+ // Help function (called by obtainCameraConfigs()) to return pointers to
+ // camera_configs_ the lowest and highest resolutions configs.
+ void getCameraConfigLowestAndHighestResolutions(
+ CameraConfig** lowest_resolution_config,
+ CameraConfig** highest_resolution_config);
};
} // namespace computer_vision
diff --git a/samples/computervision_c/app/src/main/cpp/cpu_image_renderer.cc b/samples/computervision_c/app/src/main/cpp/cpu_image_renderer.cc
index 6e2a59195..0af29b542 100644
--- a/samples/computervision_c/app/src/main/cpp/cpu_image_renderer.cc
+++ b/samples/computervision_c/app/src/main/cpp/cpu_image_renderer.cc
@@ -96,14 +96,14 @@ bool DetectEdge(const AImage* ndk_image, int32_t width, int32_t height,
int offset = (j * stride) + i;
// Neighbour pixels around the pixel at [i, j].
- int a00 = input_pixels[offset - width - 1];
- int a01 = input_pixels[offset - width];
- int a02 = input_pixels[offset - width + 1];
+ int a00 = input_pixels[offset - stride - 1];
+ int a01 = input_pixels[offset - stride];
+ int a02 = input_pixels[offset - stride + 1];
int a10 = input_pixels[offset - 1];
int a12 = input_pixels[offset + 1];
- int a20 = input_pixels[offset + width - 1];
- int a21 = input_pixels[offset + width];
- int a22 = input_pixels[offset + width + 1];
+ int a20 = input_pixels[offset + stride - 1];
+ int a21 = input_pixels[offset + stride];
+ int a22 = input_pixels[offset + stride + 1];
// Sobel X filter:
// -1, 0, 1,
diff --git a/samples/computervision_c/app/src/main/cpp/jni_interface.cc b/samples/computervision_c/app/src/main/cpp/jni_interface.cc
index 6a7b5f872..89137ca6f 100644
--- a/samples/computervision_c/app/src/main/cpp/jni_interface.cc
+++ b/samples/computervision_c/app/src/main/cpp/jni_interface.cc
@@ -27,7 +27,7 @@
extern "C" {
namespace {
-// maintain a reference to the JVM so we can use it later.
+// Maintain a reference to the JVM so we can use it later.
static JavaVM *g_vm = nullptr;
inline jlong jptr(computer_vision::ComputerVisionApplication
@@ -97,12 +97,35 @@ jclass FindClass(const char *classname) {
return env->FindClass(classname);
}
+JNI_METHOD(jstring, getCameraConfigLabel)
+(JNIEnv *env, jclass, jlong native_application, jboolean is_low_resolution) {
+ auto label =
+ native(native_application)->getCameraConfigLabel(is_low_resolution);
+ return env->NewStringUTF(label.c_str());
+}
+
+JNI_METHOD(jint, setCameraConfig)
+(JNIEnv *env, jclass, jlong native_application, jboolean is_low_resolution) {
+ ArStatus status =
+ native(native_application)->setCameraConfig(is_low_resolution);
+ return static_cast(status);
+}
+
JNI_METHOD(jstring, getCameraIntrinsicsText)
-(JNIEnv *env, jclass, jlong native_application, jboolean show_cpu_intrinsics) {
+(JNIEnv *env, jclass, jlong native_application, jboolean for_gpu_texture) {
auto label =
- native(native_application)
- ->GetCameraIntrinsicsText(static_cast(show_cpu_intrinsics));
+ native(native_application)->GetCameraIntrinsicsText(for_gpu_texture);
return env->NewStringUTF(label.c_str());
}
+JNI_METHOD(void, setFocusMode)
+(JNIEnv *, jclass, jlong native_application, jboolean enable_auto_focus) {
+ native(native_application)->SetFocusMode(enable_auto_focus);
+}
+
+JNI_METHOD(jboolean, getFocusMode)
+(JNIEnv *, jclass, jlong native_application) {
+ return native(native_application)->GetFocusMode();
+}
+
} // extern "C"
diff --git a/samples/computervision_c/app/src/main/java/com/google/ar/core/examples/c/computervision/ComputerVisionActivity.java b/samples/computervision_c/app/src/main/java/com/google/ar/core/examples/c/computervision/ComputerVisionActivity.java
index 5e93f8276..9689b7b1e 100644
--- a/samples/computervision_c/app/src/main/java/com/google/ar/core/examples/c/computervision/ComputerVisionActivity.java
+++ b/samples/computervision_c/app/src/main/java/com/google/ar/core/examples/c/computervision/ComputerVisionActivity.java
@@ -27,6 +27,10 @@
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
+import android.widget.CompoundButton;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import javax.microedition.khronos.egl.EGLConfig;
@@ -48,29 +52,32 @@ public class ComputerVisionActivity extends AppCompatActivity
private int viewportHeight;
// Using float value to set the splitter position in shader in native code.
private float splitterPosition = 0.0f;
+ private boolean isLowResolutionSelected = true;
// Camera intrinsics text elements.
private TextView cameraIntrinsicsTextView;
- private boolean isShowingCpuIntrinsics = true;
+
+ private Switch focusModeSwitch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cameraIntrinsicsTextView = findViewById(R.id.camera_intrinsics_view);
+ focusModeSwitch = (Switch) findViewById(R.id.switch_focus_mode);
+ focusModeSwitch.setOnCheckedChangeListener(this::onFocusModeChanged);
surfaceView = findViewById(R.id.surfaceview);
surfaceView.setOnTouchListener(
- new View.OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
- isShowingCpuIntrinsics = (splitterPosition > 0.5f);
- splitterPosition = isShowingCpuIntrinsics ? 0.0f : 1.0f;
- }
-
- return true;
+ (View view, MotionEvent motionEvent) -> {
+ if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
+ splitterPosition = (splitterPosition < 0.5f) ? 1.0f : 0.0f;
+
+ // Turn off the CPU resolution radio buttons if CPU image is not displayed.
+ showCameraConfigMenu(splitterPosition < 0.5f);
}
+
+ return true;
});
// Set up renderer.
@@ -96,6 +103,24 @@ protected void onResume() {
JniInterface.onResume(nativeApplication, getApplicationContext(), this);
surfaceView.onResume();
+ // Update the radio buttons with the resolution info.
+ String lowResLabel = JniInterface.getCameraConfigLabel(nativeApplication, true);
+ String highResLabel = JniInterface.getCameraConfigLabel(nativeApplication, false);
+ RadioButton lowResolutionRadioButton = (RadioButton) findViewById(R.id.radio_low_res);
+ RadioButton highResolutionRadioButton = (RadioButton) findViewById(R.id.radio_high_res);
+ if (!lowResLabel.isEmpty()) {
+ lowResolutionRadioButton.setText(lowResLabel);
+ } else {
+ lowResolutionRadioButton.setVisibility(View.INVISIBLE);
+ }
+ if (!highResLabel.isEmpty()) {
+ highResolutionRadioButton.setText(highResLabel);
+ } else {
+ highResolutionRadioButton.setVisibility(View.INVISIBLE);
+ }
+
+ focusModeSwitch.setChecked(JniInterface.getFocusMode(nativeApplication));
+
// Listen to display changed events to detect 180° rotation, which does not cause a config
// change or view resize.
getSystemService(DisplayManager.class).registerDisplayListener(this, null);
@@ -219,16 +244,13 @@ public void onDrawFrame(GL10 gl) {
viewportHeight);
viewportChanged = false;
}
+
JniInterface.onGlSurfaceDrawFrame(nativeApplication, splitterPosition);
final String cameraIntrinsicsText =
- JniInterface.getCameraIntrinsicsText(nativeApplication, isShowingCpuIntrinsics);
- runOnUiThread(
- new Runnable() {
- @Override
- public void run() {
- cameraIntrinsicsTextView.setText(cameraIntrinsicsText);
- }
- });
+ JniInterface.getCameraIntrinsicsText(
+ nativeApplication, /*forGpuTexture=*/ (splitterPosition > 0.5f));
+
+ runOnUiThread(() -> cameraIntrinsicsTextView.setText(cameraIntrinsicsText));
}
}
@@ -256,4 +278,42 @@ public void onDisplayRemoved(int displayId) {}
public void onDisplayChanged(int displayId) {
viewportChanged = true;
}
+
+ public void onLowResolutionRadioButtonClicked(View view) {
+ boolean checked = ((RadioButton) view).isChecked();
+ if (checked && !isLowResolutionSelected) {
+ // Display low resolution.
+ isLowResolutionSelected = true;
+ String label = (String) ((RadioButton) view).getText();
+ onCameraConfigChanged(isLowResolutionSelected, label);
+ }
+ }
+
+ public void onHighResolutionRadioButtonClicked(View view) {
+ boolean checked = ((RadioButton) view).isChecked();
+ if (checked && isLowResolutionSelected) {
+ // Display high resolution
+ isLowResolutionSelected = false;
+ String label = (String) ((RadioButton) view).getText();
+ onCameraConfigChanged(isLowResolutionSelected, label);
+ }
+ }
+
+ private void onFocusModeChanged(CompoundButton unusedButton, boolean isChecked) {
+ JniInterface.setFocusMode(nativeApplication, isChecked);
+ }
+
+ private void onCameraConfigChanged(boolean isLowResolution, String label) {
+ int status = JniInterface.setCameraConfig(nativeApplication, isLowResolution);
+ if (status == 0) {
+ // Let the user know that the camera config is set.
+ String message = "Set the camera config with " + label;
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void showCameraConfigMenu(boolean show) {
+ RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radio_camera_configs);
+ radioGroup.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+ }
}
diff --git a/samples/computervision_c/app/src/main/java/com/google/ar/core/examples/c/computervision/JniInterface.java b/samples/computervision_c/app/src/main/java/com/google/ar/core/examples/c/computervision/JniInterface.java
index 191bb124b..1b6fd7408 100644
--- a/samples/computervision_c/app/src/main/java/com/google/ar/core/examples/c/computervision/JniInterface.java
+++ b/samples/computervision_c/app/src/main/java/com/google/ar/core/examples/c/computervision/JniInterface.java
@@ -58,12 +58,20 @@ static native void onDisplayGeometryChanged(
*/
static native void onGlSurfaceDrawFrame(long nativeApplication, float splitPosition);
+ static native String getCameraConfigLabel(
+ long nativeApplication, boolean isLowResolutionSelected);
+
+ static native int setCameraConfig(long nativeApplication, boolean isLowResolutionSelected);
+
/**
* Retrieves the text for the intrinsic values of the current camera configuration.
*
* @param nativeApplication the native application handle.
- * @param showCpuIntrinsics if true, retrieves the text for the CPU image's intrinsics. Otherwise,
- * retrieves the text for the GPU texture's intrinsics.
+ * @param forGpuTexture is the intrinsic text required for GPU texture or for CPU image.
*/
- static native String getCameraIntrinsicsText(long nativeApplication, boolean showCpuIntrinsics);
+ static native String getCameraIntrinsicsText(long nativeApplication, boolean forGpuTexture);
+
+ static native void setFocusMode(long nativeApplication, boolean isFixedFocus);
+
+ static native boolean getFocusMode(long nativeApplication);
}
diff --git a/samples/computervision_c/app/src/main/res/layout/activity_main.xml b/samples/computervision_c/app/src/main/res/layout/activity_main.xml
index 74a1a521e..02c0181fc 100644
--- a/samples/computervision_c/app/src/main/res/layout/activity_main.xml
+++ b/samples/computervision_c/app/src/main/res/layout/activity_main.xml
@@ -25,13 +25,46 @@
android:layout_height="match_parent"
android:layout_gravity="top"/>
-
+ android:layout_marginTop="10dp"
+ android:layout_marginLeft="10dp"
+ android:checkedButton="@+id/radio_low_res"
+ android:orientation="vertical">
+
+
+
+
+
+
+
+
+
diff --git a/samples/computervision_c/app/src/main/res/values/strings.xml b/samples/computervision_c/app/src/main/res/values/strings.xml
index b65c992c7..b553abb66 100644
--- a/samples/computervision_c/app/src/main/res/values/strings.xml
+++ b/samples/computervision_c/app/src/main/res/values/strings.xml
@@ -16,4 +16,9 @@
-->
CV C
+
+
+ Low Resolution
+ High Resolution
+ Auto Focus
diff --git a/samples/computervision_c/gradle/wrapper/gradle-wrapper.jar b/samples/computervision_c/gradle/wrapper/gradle-wrapper.jar
index c44b679ac..758de960e 100644
Binary files a/samples/computervision_c/gradle/wrapper/gradle-wrapper.jar and b/samples/computervision_c/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/computervision_c/gradlew.bat b/samples/computervision_c/gradlew.bat
index f9553162f..e95643d6a 100644
--- a/samples/computervision_c/gradlew.bat
+++ b/samples/computervision_c/gradlew.bat
@@ -1,84 +1,84 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/computervision_java/app/build.gradle b/samples/computervision_java/app/build.gradle
index 2c87ab4ae..805b56274 100644
--- a/samples/computervision_java/app/build.gradle
+++ b/samples/computervision_java/app/build.gradle
@@ -11,7 +11,10 @@ android {
versionCode 1
versionName "1.0"
}
-
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
buildTypes {
release {
minifyEnabled false
@@ -22,7 +25,7 @@ android {
dependencies {
// ARCore library
- implementation 'com.google.ar:core:1.3.0'
+ implementation 'com.google.ar:core:1.4.0'
// Obj - a simple Wavefront OBJ file loader
// https://github.com/javagl/Obj
diff --git a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
index d84573788..87dc77daa 100644
--- a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
+++ b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
@@ -123,7 +123,7 @@ public void update(PointCloud cloud) {
}
/**
- * Renders the point cloud. ArCore point cloud is given in world space.
+ * Renders the point cloud. ARCore point cloud is given in world space.
*
* @param cameraView the camera view matrix for this frame, typically from {@link
* com.google.ar.core.Camera#getViewMatrix(float[], int)}.
diff --git a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/ComputerVisionActivity.java b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/ComputerVisionActivity.java
index f20b742eb..9399d0d99 100644
--- a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/ComputerVisionActivity.java
+++ b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/ComputerVisionActivity.java
@@ -23,11 +23,18 @@
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
+import android.util.Size;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.RadioButton;
+import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.google.ar.core.ArCoreApk;
import com.google.ar.core.Camera;
+import com.google.ar.core.CameraConfig;
import com.google.ar.core.CameraIntrinsics;
+import com.google.ar.core.Config;
import com.google.ar.core.Frame;
import com.google.ar.core.Session;
import com.google.ar.core.examples.java.common.helpers.CameraPermissionHelper;
@@ -41,6 +48,7 @@
import com.google.ar.core.exceptions.UnavailableUserDeclinedInstallationException;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.util.List;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
@@ -48,8 +56,10 @@
public class ComputerVisionActivity extends AppCompatActivity implements GLSurfaceView.Renderer {
private static final String TAG = ComputerVisionActivity.class.getSimpleName();
private static final String CAMERA_INTRINSICS_TEXT_FORMAT =
- "Unrotated Camera %s Intrinsics:\n\tFocal Length: (%.2f, %.2f)\n\tPrincipal Point: "
- + "(%.2f, %.2f)\n\tImage Dimensions: (%d, %d)\n\tUnrotated Field of View: (%.2fº, %.2fº)";
+ "Unrotated Camera %s %s Intrinsics:\n\tFocal Length: (%.2f, %.2f)"
+ + "\n\tPrincipal Point: (%.2f, %.2f)"
+ + "\n\t%s Image Dimensions: (%d, %d)"
+ + "\n\tUnrotated Field of View: (%.2fº, %.2fº)";
private static final float RADIANS_TO_DEGREES = (float) (180 / Math.PI);
// This app demonstrates two approaches to obtaining image data accessible on CPU:
@@ -68,6 +78,7 @@ private enum ImageAcquisitionPath {
// Session management and rendering.
private GLSurfaceView surfaceView;
private Session session;
+ private Config config;
private boolean installRequested;
private final SnackbarHelper messageSnackbarHelper = new SnackbarHelper();
private CpuImageDisplayRotationHelper cpuImageDisplayRotationHelper;
@@ -90,14 +101,25 @@ private enum ImageAcquisitionPath {
private static final int IMAGE_WIDTH = 1280;
private static final int IMAGE_HEIGHT = 720;
+ // For Camera Configuration APIs usage.
+ private boolean isLowResolutionSelected;
+ private CameraConfig cpuLowResolutionCameraConfig;
+ private CameraConfig cpuHighResolutionCameraConfig;
+
+ private Switch focusModeSwitch;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ surfaceView = findViewById(R.id.surfaceview);
cameraIntrinsicsTextView = findViewById(R.id.camera_intrinsics_view);
surfaceView = findViewById(R.id.surfaceview);
+ focusModeSwitch = (Switch) findViewById(R.id.switch_focus_mode);
+ focusModeSwitch.setOnCheckedChangeListener(this::onFocusModeChanged);
+
cpuImageDisplayRotationHelper = new CpuImageDisplayRotationHelper(/*context=*/ this);
- cpuImageTouchListener = new CpuImageTouchListener(cpuImageRenderer);
+ cpuImageTouchListener = new CpuImageTouchListener(cpuImageRenderer, /*context=*/ this);
// Setup a touch listener to control the texture splitter position.
surfaceView.setOnTouchListener(cpuImageTouchListener);
@@ -136,6 +158,7 @@ protected void onResume() {
}
session = new Session(/* context= */ this);
+ config = new Config(session);
} catch (UnavailableArcoreNotInstalledException
| UnavailableUserDeclinedInstallationException e) {
message = "Please install ARCore";
@@ -158,6 +181,10 @@ protected void onResume() {
}
}
+ obtainCameraConfigs();
+
+ focusModeSwitch.setChecked(config.getFocusMode() != Config.FocusMode.FIXED);
+
// Note that order matters - see the note in onPause(), the reverse applies here.
try {
session.resume();
@@ -259,13 +286,7 @@ public void onDrawFrame(GL10 gl) {
}
// Update the camera intrinsics' text.
- runOnUiThread(
- new Runnable() {
- @Override
- public void run() {
- cameraIntrinsicsTextView.setText(getCameraIntrinsicsText(frame));
- }
- });
+ runOnUiThread(() -> cameraIntrinsicsTextView.setText(getCameraIntrinsicsText(frame)));
} catch (Exception t) {
// Avoid crashing the application due to unhandled exceptions.
Log.e(TAG, "Exception on the OpenGL thread", t);
@@ -337,13 +358,112 @@ private void renderProcessedImageGpuDownload(Frame frame) {
textureReader.submitFrame(cpuImageRenderer.getTextureId(), TEXTURE_WIDTH, TEXTURE_HEIGHT);
}
+ public void onLowResolutionRadioButtonClicked(View view) {
+ boolean checked = ((RadioButton) view).isChecked();
+ if (checked && !isLowResolutionSelected) {
+ // Display low resolution
+ onCameraConfigChanged(cpuLowResolutionCameraConfig);
+ isLowResolutionSelected = true;
+ }
+ }
+
+ public void onHighResolutionRadioButtonClicked(View view) {
+ boolean checked = ((RadioButton) view).isChecked();
+ if (checked && isLowResolutionSelected) {
+ // Display high resolution
+ onCameraConfigChanged(cpuHighResolutionCameraConfig);
+ isLowResolutionSelected = false;
+ }
+ }
+
+ private void onFocusModeChanged(CompoundButton unusedButton, boolean isChecked) {
+ config.setFocusMode(isChecked ? Config.FocusMode.AUTO : Config.FocusMode.FIXED);
+ session.configure(config);
+ }
+
+ private void onCameraConfigChanged(CameraConfig cameraConfig) {
+ // To change the AR camera config - first we pause the AR session, set the desired camera
+ // config and then resume the AR session.
+ if (session != null) {
+ session.pause();
+ session.setCameraConfig(cameraConfig);
+ try {
+ session.resume();
+ } catch (CameraNotAvailableException ex) {
+ // In a rare case (such as another camera app launching) the camera may be given to a
+ // different app and so may not be available to this app. Handle this properly by showing a
+ // message and recreate the session at the next iteration.
+ messageSnackbarHelper.showError(this, "Camera not available. Please restart the app.");
+ session = null;
+ return;
+ }
+
+ // Let the user know that the camera config is set.
+ String toastMessage =
+ "Set the camera config with CPU image resolution of "
+ + cameraConfig.getImageSize().getWidth()
+ + "x"
+ + cameraConfig.getImageSize().getHeight()
+ + ".";
+ Toast.makeText(this, toastMessage, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ // Obtains the supported camera configs and build the list of radio button one for each camera
+ // config.
+ private void obtainCameraConfigs() {
+ // First obtain the session handle before getting the list of various camera configs.
+ if (session != null) {
+ List cameraConfigs = session.getSupportedCameraConfigs();
+
+ // Determine the highest and lowest CPU resolutions.
+ cpuLowResolutionCameraConfig =
+ getCameraConfigWithLowestOrHighestResolution(cameraConfigs, true);
+ cpuHighResolutionCameraConfig =
+ getCameraConfigWithLowestOrHighestResolution(cameraConfigs, false);
+
+ // Update the radio buttons with the resolution info.
+ updateRadioButtonText(
+ R.id.radio_low_res, cpuLowResolutionCameraConfig, getString(R.string.label_low_res));
+ updateRadioButtonText(
+ R.id.radio_high_res, cpuHighResolutionCameraConfig, getString(R.string.label_high_res));
+ isLowResolutionSelected = true;
+ }
+ }
+
+ private void updateRadioButtonText(int id, CameraConfig cameraConfig, String prefix) {
+ RadioButton radioButton = (RadioButton) findViewById(id);
+ Size resolution = cameraConfig.getImageSize();
+ radioButton.setText(prefix + " (" + resolution.getWidth() + "x" + resolution.getHeight() + ")");
+ }
+
+ private CameraConfig getCameraConfigWithLowestOrHighestResolution(
+ List cameraConfigs, boolean lowest) {
+ CameraConfig cameraConfig = cameraConfigs.get(0);
+ for (int index = 1; index < cameraConfigs.size(); index++) {
+ if (lowest) {
+ if (cameraConfigs.get(index).getImageSize().getHeight()
+ < cameraConfig.getImageSize().getHeight()) {
+ cameraConfig = cameraConfigs.get(index);
+ }
+ } else {
+ if (cameraConfigs.get(index).getImageSize().getHeight()
+ > cameraConfig.getImageSize().getHeight()) {
+ cameraConfig = cameraConfigs.get(index);
+ }
+ }
+ }
+ return cameraConfig;
+ }
+
private String getCameraIntrinsicsText(Frame frame) {
Camera camera = frame.getCamera();
- boolean shouldShowCpuIntrinsics = (cpuImageRenderer.getSplitterPosition() < 0.5f);
+ boolean forGpuTexture = (cpuImageRenderer.getSplitterPosition() > 0.5f);
CameraIntrinsics intrinsics =
- shouldShowCpuIntrinsics ? camera.getImageIntrinsics() : camera.getTextureIntrinsics();
- String intrinsicsLabel = shouldShowCpuIntrinsics ? "Image" : "Texture";
+ forGpuTexture ? camera.getTextureIntrinsics() : camera.getImageIntrinsics();
+ String intrinsicsLabel = forGpuTexture ? "Texture" : "Image";
+ String imageType = forGpuTexture ? "GPU" : "CPU";
float[] focalLength = intrinsics.getFocalLength();
float[] principalPoint = intrinsics.getPrincipalPoint();
@@ -356,11 +476,13 @@ private String getCameraIntrinsicsText(Frame frame) {
return String.format(
CAMERA_INTRINSICS_TEXT_FORMAT,
+ imageType,
intrinsicsLabel,
focalLength[0],
focalLength[1],
principalPoint[0],
principalPoint[1],
+ imageType,
imageSize[0],
imageSize[1],
fovX,
diff --git a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/CpuImageRenderer.java b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/CpuImageRenderer.java
index a9b14b9b0..66c8c527c 100644
--- a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/CpuImageRenderer.java
+++ b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/CpuImageRenderer.java
@@ -292,7 +292,7 @@ private void updateTextureCoordinates(
}
// Crop the CPU image to fit the screen aspect ratio.
- float imageAspectRatio = (float) (imageWidth) / imageHeight;
+ float imageAspectRatio = (float) imageWidth / imageHeight;
float croppedWidth = 0.f;
float croppedHeight = 0.f;
if (screenAspectRatio < imageAspectRatio) {
diff --git a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/CpuImageTouchListener.java b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/CpuImageTouchListener.java
index 4ff814345..a18b5de38 100644
--- a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/CpuImageTouchListener.java
+++ b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/CpuImageTouchListener.java
@@ -1,7 +1,10 @@
package com.google.ar.core.examples.java.computervision;
+import android.app.Activity;
+import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
+import android.widget.RadioGroup;
/**
* Tracks the touches to the rendering view and updates the splitter position in {@link
@@ -10,9 +13,11 @@
class CpuImageTouchListener implements View.OnTouchListener {
private final CpuImageRenderer cpuImageRenderer;
+ private final Context context;
- public CpuImageTouchListener(CpuImageRenderer cpuImageRenderer) {
+ public CpuImageTouchListener(CpuImageRenderer cpuImageRenderer, Context context) {
this.cpuImageRenderer = cpuImageRenderer;
+ this.context = context;
}
@Override
@@ -20,6 +25,12 @@ public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
float newPosition = (cpuImageRenderer.getSplitterPosition() < 0.5f) ? 1.0f : 0.0f;
cpuImageRenderer.setSplitterPosition(newPosition);
+
+ // Display the CPU resolution related UI only when CPU image is being displayed.
+ boolean show = (newPosition < 0.5f);
+ RadioGroup radioGroup =
+ (RadioGroup) ((Activity) context).findViewById(R.id.radio_camera_configs);
+ radioGroup.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
}
return true;
diff --git a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/EdgeDetector.java b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/EdgeDetector.java
index bdd82b457..66ec104f5 100644
--- a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/EdgeDetector.java
+++ b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/EdgeDetector.java
@@ -34,7 +34,7 @@ public class EdgeDetector {
*/
public synchronized ByteBuffer detect(int width, int height, int stride, ByteBuffer input) {
// Reallocate input byte array if its size is different from the required size.
- if (stride * height != inputPixels.length) {
+ if (stride * height > inputPixels.length) {
inputPixels = new byte[stride * height];
}
@@ -44,7 +44,12 @@ public synchronized ByteBuffer detect(int width, int height, int stride, ByteBuf
// Copy input buffer into a java array for ease of access. This is not the most optimal
// way to process an image, but used here for simplicity.
input.position(0);
- input.get(inputPixels);
+
+ // Note: On certain devices with specific resolution where the stride is not equal to the width.
+ // In such situation the memory allocated for the frame may not be exact multiple of stride x
+ // height hence the capacity of the ByteBuffer could be less. To handle such situations it will
+ // be better to transfer the exact amount of image bytes to the destination bytes.
+ input.get(inputPixels, 0, input.capacity());
// Detect edges.
for (int j = 1; j < height - 1; j++) {
@@ -53,14 +58,14 @@ public synchronized ByteBuffer detect(int width, int height, int stride, ByteBuf
int offset = (j * stride) + i;
// Neighbour pixels around the pixel at [i, j].
- int a00 = inputPixels[offset - width - 1];
- int a01 = inputPixels[offset - width];
- int a02 = inputPixels[offset - width + 1];
+ int a00 = inputPixels[offset - stride - 1];
+ int a01 = inputPixels[offset - stride];
+ int a02 = inputPixels[offset - stride + 1];
int a10 = inputPixels[offset - 1];
int a12 = inputPixels[offset + 1];
- int a20 = inputPixels[offset + width - 1];
- int a21 = inputPixels[offset + width];
- int a22 = inputPixels[offset + width + 1];
+ int a20 = inputPixels[offset + stride - 1];
+ int a21 = inputPixels[offset + stride];
+ int a22 = inputPixels[offset + stride + 1];
// Sobel X filter:
// -1, 0, 1,
diff --git a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/TextureReader.java b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/TextureReader.java
index 7313ef200..1814adbd6 100644
--- a/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/TextureReader.java
+++ b/samples/computervision_java/app/src/main/java/com/google/ar/core/examples/java/computervision/TextureReader.java
@@ -412,8 +412,8 @@ private void drawTexture(int textureId, int textureWidth, int textureHeight) {
if (keepAspectRatio) {
int renderWidth = 0;
int renderHeight = 0;
- float textureAspectRatio = (float) (textureWidth) / textureHeight;
- float imageAspectRatio = (float) (imageWidth) / imageHeight;
+ float textureAspectRatio = (float) textureWidth / textureHeight;
+ float imageAspectRatio = (float) imageWidth / imageHeight;
if (textureAspectRatio < imageAspectRatio) {
renderWidth = imageWidth;
renderHeight = textureHeight * imageWidth / textureWidth;
diff --git a/samples/computervision_java/app/src/main/res/layout/activity_main.xml b/samples/computervision_java/app/src/main/res/layout/activity_main.xml
index 0f7a603e4..aeab644c6 100644
--- a/samples/computervision_java/app/src/main/res/layout/activity_main.xml
+++ b/samples/computervision_java/app/src/main/res/layout/activity_main.xml
@@ -25,6 +25,35 @@
android:layout_height="fill_parent"
android:layout_gravity="top"/>
+
+
+
+
+
+
+
CV Java
+ Low Resolution
+ High Resolution
+ Auto Focus
diff --git a/samples/computervision_java/gradle/wrapper/gradle-wrapper.jar b/samples/computervision_java/gradle/wrapper/gradle-wrapper.jar
index c44b679ac..758de960e 100644
Binary files a/samples/computervision_java/gradle/wrapper/gradle-wrapper.jar and b/samples/computervision_java/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/computervision_java/gradlew.bat b/samples/computervision_java/gradlew.bat
index f9553162f..e95643d6a 100644
--- a/samples/computervision_java/gradlew.bat
+++ b/samples/computervision_java/gradlew.bat
@@ -1,84 +1,84 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/hello_ar_c/app/build.gradle b/samples/hello_ar_c/app/build.gradle
index 1abd337d4..d98a13a3e 100644
--- a/samples/hello_ar_c/app/build.gradle
+++ b/samples/hello_ar_c/app/build.gradle
@@ -32,6 +32,10 @@ android {
abiFilters "arm64-v8a", "x86"
}
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
buildTypes {
release {
minifyEnabled false
@@ -47,8 +51,8 @@ android {
dependencies {
// ARCore library
- implementation 'com.google.ar:core:1.3.0'
- natives 'com.google.ar:core:1.3.0'
+ implementation 'com.google.ar:core:1.4.0'
+ natives 'com.google.ar:core:1.4.0'
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support:design:27.0.2'
diff --git a/samples/hello_ar_c/app/src/main/assets/models/andy.png b/samples/hello_ar_c/app/src/main/assets/models/andy.png
index f88b1d6b4..6aa50ec2b 100644
Binary files a/samples/hello_ar_c/app/src/main/assets/models/andy.png and b/samples/hello_ar_c/app/src/main/assets/models/andy.png differ
diff --git a/samples/hello_ar_c/app/src/main/java/com/google/ar/core/examples/c/helloar/HelloArActivity.java b/samples/hello_ar_c/app/src/main/java/com/google/ar/core/examples/c/helloar/HelloArActivity.java
index e0c1c47c4..693d16eb0 100644
--- a/samples/hello_ar_c/app/src/main/java/com/google/ar/core/examples/c/helloar/HelloArActivity.java
+++ b/samples/hello_ar_c/app/src/main/java/com/google/ar/core/examples/c/helloar/HelloArActivity.java
@@ -88,12 +88,7 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public boolean onSingleTapUp(final MotionEvent e) {
surfaceView.queueEvent(
- new Runnable() {
- @Override
- public void run() {
- JniInterface.onTouched(nativeApplication, e.getX(), e.getY());
- }
- });
+ () -> JniInterface.onTouched(nativeApplication, e.getX(), e.getY()));
return true;
}
@@ -104,12 +99,7 @@ public boolean onDown(MotionEvent e) {
});
surfaceView.setOnTouchListener(
- new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return gestureDetector.onTouchEvent(event);
- }
- });
+ (View v, MotionEvent event) -> gestureDetector.onTouchEvent(event));
// Set up renderer.
surfaceView.setPreserveEGLContextOnPause(true);
diff --git a/samples/hello_ar_c/gradle/wrapper/gradle-wrapper.jar b/samples/hello_ar_c/gradle/wrapper/gradle-wrapper.jar
index c44b679ac..758de960e 100644
Binary files a/samples/hello_ar_c/gradle/wrapper/gradle-wrapper.jar and b/samples/hello_ar_c/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/hello_ar_c/gradlew.bat b/samples/hello_ar_c/gradlew.bat
index f9553162f..e95643d6a 100644
--- a/samples/hello_ar_c/gradlew.bat
+++ b/samples/hello_ar_c/gradlew.bat
@@ -1,84 +1,84 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/hello_ar_java/app/build.gradle b/samples/hello_ar_java/app/build.gradle
index 1567b5f1e..e84e2cf4b 100644
--- a/samples/hello_ar_java/app/build.gradle
+++ b/samples/hello_ar_java/app/build.gradle
@@ -11,7 +11,10 @@ android {
versionCode 1
versionName "1.0"
}
-
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
buildTypes {
release {
minifyEnabled false
@@ -22,7 +25,7 @@ android {
dependencies {
// ARCore library
- implementation 'com.google.ar:core:1.3.0'
+ implementation 'com.google.ar:core:1.4.0'
// Obj - a simple Wavefront OBJ file loader
// https://github.com/javagl/Obj
diff --git a/samples/hello_ar_java/app/src/main/assets/models/andy.png b/samples/hello_ar_java/app/src/main/assets/models/andy.png
index f88b1d6b4..6aa50ec2b 100644
Binary files a/samples/hello_ar_java/app/src/main/assets/models/andy.png and b/samples/hello_ar_java/app/src/main/assets/models/andy.png differ
diff --git a/samples/hello_ar_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java b/samples/hello_ar_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
index d84573788..87dc77daa 100644
--- a/samples/hello_ar_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
+++ b/samples/hello_ar_java/app/src/main/java/com/google/ar/core/examples/java/common/rendering/PointCloudRenderer.java
@@ -123,7 +123,7 @@ public void update(PointCloud cloud) {
}
/**
- * Renders the point cloud. ArCore point cloud is given in world space.
+ * Renders the point cloud. ARCore point cloud is given in world space.
*
* @param cameraView the camera view matrix for this frame, typically from {@link
* com.google.ar.core.Camera#getViewMatrix(float[], int)}.
diff --git a/samples/hello_ar_java/gradle/wrapper/gradle-wrapper.jar b/samples/hello_ar_java/gradle/wrapper/gradle-wrapper.jar
index c44b679ac..758de960e 100644
Binary files a/samples/hello_ar_java/gradle/wrapper/gradle-wrapper.jar and b/samples/hello_ar_java/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/hello_ar_java/gradlew.bat b/samples/hello_ar_java/gradlew.bat
index f9553162f..e95643d6a 100644
--- a/samples/hello_ar_java/gradlew.bat
+++ b/samples/hello_ar_java/gradlew.bat
@@ -1,84 +1,84 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega