### Install GLM using Vcpkg Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/readme.md This command demonstrates how to install the GLM library using the vcpkg package manager. Vcpkg simplifies the process of acquiring and managing libraries for C++ projects. ```shell vcpkg install glm ``` -------------------------------- ### Example GLM Configuration Log Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md This is an example output generated when `GLM_FORCE_MESSAGES` is enabled, showing GLM's detected version, C++ standard, compiler, architecture, platform, and enabled/disabled features. ```plaintext GLM: version 0.9.9.1 GLM: C++ 17 with extensions GLM: Clang compiler detected GLM: x86 64 bits with AVX instruction set build target GLM: Linux platform detected GLM: GLM_FORCE_SWIZZLE is undefined. swizzling functions or operators are disabled. GLM: GLM_FORCE_SIZE_T_LENGTH is undefined. .length() returns a glm::length_t, a typedef of int following GLSL. GLM: GLM_FORCE_UNRESTRICTED_GENTYPE is undefined. Follows strictly GLSL on valid function genTypes. GLM: GLM_FORCE_DEPTH_ZERO_TO_ONE is undefined. Using negative one to one depth clip space. GLM: GLM_FORCE_LEFT_HANDED is undefined. Using right handed coordinate system. ``` -------------------------------- ### GLSL Swizzle Example Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Demonstrates GLSL swizzle expressions for selecting and arranging vector components, including assigning values between vectors. ```glsl vec4 A; vec2 B; B.yx = A.wy; B = A.xx; vec3 C = A.bgr; vec3 D = B.rsz; // Invalid, won't compile ``` -------------------------------- ### Setup AugmentedImageDatabase in ARCore Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt Configure ARCore to recognize physical images. Choose between adding a Bitmap at runtime or loading a pre-built binary database for faster initialization. ```java private boolean setupAugmentedImageDatabase(Config config) { AugmentedImageDatabase db; if (useSingleImage) { // Option A: add a Bitmap at runtime Bitmap bmp; try (InputStream is = getAssets().open("default.jpg")) { bmp = BitmapFactory.decodeStream(is); } catch (IOException e) { return false; } db = new AugmentedImageDatabase(session); db.addImage("my_image", bmp); // If the physical width is known, pass it for better scale accuracy: // db.addImage("my_image", bmp, /* widthInMeters= */ 0.2f); } else { // Option B: load a pre-built binary database (shorter setup time) try (InputStream is = getAssets().open("sample_database.imgdb")) { db = AugmentedImageDatabase.deserialize(session, is); } catch (IOException e) { return false; } } config.setAugmentedImageDatabase(db); return true; } ``` -------------------------------- ### Create and Configure ARCore Session Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt Initialize and configure the ARCore Session, handling potential exceptions for installation and compatibility issues. The session must be created on the UI thread. ```java Session session; try { session = new Session(/* context= */ this); } catch (UnavailableArcoreNotInstalledException e) { showError("Please install ARCore"); return; } catch (UnavailableApkTooOldException e) { showError("Please update ARCore"); return; } catch (UnavailableSdkTooOldException e) { showError("Please update the app"); return; } catch (UnavailableDeviceNotCompatibleException e) { showError("Device does not support AR"); return; } // Configure: enable Environmental HDR light estimation + automatic depth Config config = session.getConfig(); config.setLightEstimationMode(Config.LightEstimationMode.ENVIRONMENTAL_HDR); if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) { config.setDepthMode(Config.DepthMode.AUTOMATIC); } else { config.setDepthMode(Config.DepthMode.DISABLED); } config.setInstantPlacementMode(Config.InstantPlacementMode.LOCAL_Y_UP); session.configure(config); ``` -------------------------------- ### Check ARCore Availability and Request Install Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt Check if ARCore is available and prompt the user to install or update it if necessary. This should be called in Activity.onResume(). ```java ArCoreApk.Availability availability = ArCoreApk.getInstance().checkAvailability(this); if (availability != ArCoreApk.Availability.SUPPORTED_INSTALLED) { switch (ArCoreApk.getInstance().requestInstall(this, /* userRequestedInstall= */ true)) { case INSTALL_REQUESTED: // The system has launched the ARCore install dialog. // onResume() will be called again after the user returns. return; case INSTALLED: // ARCore is now installed; continue to create a Session below. break; } } // At this point ARCore is guaranteed to be installed and compatible. // Expected: either INSTALL_REQUESTED (activity pauses) or INSTALLED (fall through). ``` -------------------------------- ### GLM: Epsilon-based float equality comparison Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md This example shows how to compare two floats for equality within a custom epsilon tolerance using glm::equal. Include for this function. ```cpp #include "third_party/glm/latest/glm/ext/scalar_relational.hpp" bool epsilonEqual(float const a, float const b) { float const CustomEpsilon = 0.0001f; return glm::equal(a, b, CustomEpsilon); } ``` -------------------------------- ### Setup and Per-Frame Rendering for Augmented Faces Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt Configures the ARCore session for augmented face tracking using a front-facing camera and processes detected faces for rendering virtual objects. Requires `Config.AugmentedFaceMode.MESH3D`. ```java // Session setup for Augmented Faces Session session = new Session(this, EnumSet.noneOf(Session.Feature.class)); CameraConfigFilter filter = new CameraConfigFilter(session); filter.setFacingDirection(CameraConfig.FacingDirection.FRONT); List configs = session.getSupportedCameraConfigs(filter); if (!configs.isEmpty()) session.setCameraConfig(configs.get(0)); Config config = new Config(session); config.setAugmentedFaceMode(Config.AugmentedFaceMode.MESH3D); session.configure(config); // Per-frame rendering Collection faces = session.getAllTrackables(AugmentedFace.class); for (AugmentedFace face : faces) { if (face.getTrackingState() != TrackingState.TRACKING) continue; float[] modelMatrix = new float[16]; // Center pose of the whole face mesh face.getCenterPose().toMatrix(modelMatrix, 0); augmentedFaceRenderer.draw(projectionMatrix, viewMatrix, modelMatrix, colorCorrectionRgba, face); // Named region poses for 3-D accessories float[] noseMatrix = new float[16]; face.getRegionPose(AugmentedFace.RegionType.NOSE_TIP).toMatrix(noseMatrix, 0); noseObject.updateModelMatrix(noseMatrix, /* scale= */ 1.0f); noseObject.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, DEFAULT_COLOR); float[] rightEarMatrix = new float[16]; face.getRegionPose(AugmentedFace.RegionType.FOREHEAD_RIGHT).toMatrix(rightEarMatrix, 0); rightEarObject.updateModelMatrix(rightEarMatrix, 1.0f); rightEarObject.draw(viewMatrix, projectionMatrix, colorCorrectionRgba, DEFAULT_COLOR); } ``` -------------------------------- ### ArCoreApk - Check Availability and Request Installation Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt This snippet demonstrates how to check for ARCore availability on a device and prompt the user to install or update 'Google Play Services for AR' if necessary. It's typically called in the Activity's onResume() method. ```APIDOC ## ArCoreApk - Check Availability and Request Installation ### Description Checks if ARCore is available on the device and requests installation if it's not supported or installed. This is a crucial step before creating an ARCore Session. ### Method Static factory methods provided by `ArCoreApk` class. ### Usage Example (Java) ```java // In Activity.onResume() — check availability and request install if needed ArCoreApk.Availability availability = ArCoreApk.getInstance().checkAvailability(this); if (availability != ArCoreApk.Availability.SUPPORTED_INSTALLED) { switch (ArCoreApk.getInstance().requestInstall(this, /* userRequestedInstall= */ true)) { case INSTALL_REQUESTED: // The system has launched the ARCore install dialog. // onResume() will be called again after the user returns. return; case INSTALLED: // ARCore is now installed; continue to create a Session below. break; } } // At this point ARCore is guaranteed to be installed and compatible. // Expected: either INSTALL_REQUESTED (activity pauses) or INSTALLED (fall through). ``` ### Key Components - `ArCoreApk.getInstance()`: Gets the singleton instance of ArCoreApk. - `checkAvailability(Context context)`: Checks the ARCore availability status. - `requestInstall(Activity activity, boolean userRequestedInstall)`: Requests the installation or update of ARCore. ### Return Values for `requestInstall` - `INSTALL_REQUESTED`: The system has launched the ARCore install dialog. - `INSTALLED`: ARCore is now installed or already installed and compatible. ``` -------------------------------- ### GLM: Pack scalar types into uint64 Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md This example demonstrates packing multiple sized unsigned integer types (uint32, uint16, uint8) into a single uint64 using bit shifting. Include for related functionalities. ```cpp #include "third_party/glm/latest/glm/ext/scalar_common.hpp" glm::uint64 pack(glm::uint32 A, glm::uint16 B, glm::uint8 C, glm::uint8 D) { glm::uint64 ShiftA = 0; glm::uint64 ShiftB = sizeof(glm::uint32) * 8; glm::uint64 ShiftC = (sizeof(glm::uint32) + sizeof(glm::uint16)) * 8; glm::uint64 ShiftD = (sizeof(glm::uint32) + sizeof(glm::uint16) + sizeof(glm::uint8)) * 8; return (glm::uint64(A) << ShiftA) | (glm::uint64(B) << ShiftB) | (glm::uint64(C) << ShiftC) | (glm::uint64(D) << ShiftD); } ``` -------------------------------- ### Build GLM with CMake Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/readme.md This shell command demonstrates how to configure and build the GLM library using CMake. It disables tests, builds it as a static library, and then installs it. Passing `-DBUILD_SHARED_LIBS=ON` will build it as a shared library instead. ```shell cd /path/to/glm cmake \ -DGLM_BUILD_TESTS=OFF \ -DBUILD_SHARED_LIBS=OFF \ -B build . cmake --build build -- all cmake --build build -- install ``` -------------------------------- ### GLM C++ Code Style: Namespace and Class Definition Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Example of defining namespaces and classes in GLM, including the distinction between public 'glm' and implementation detail 'glm::detail' namespaces. ```cpp #define GLM_MY_DEFINE 76 class myClass {}; myClass const MyClass; namespace glm{ // glm namespace is for public code namespace detail // glm::detail namespace is for implementation detail { float myFunction(vec2 const& V) { return V.x + V.y; } float myFunction(vec2 const* const V) { return V->x + V->y; } }//namespace detail }//namespace glm ``` -------------------------------- ### ARCore C API Session Lifecycle Management Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt Handles the ARCore session lifecycle, including initialization, configuration, frame updates, and cleanup for NDK applications. Ensure ARCore is installed and configured before resuming the session. ```cpp #include "arcore_c_api.h" ArSession* ar_session = nullptr; ArFrame* ar_frame = nullptr; // --- Resume (called from JNI on Activity.onResume) --- void OnResume(JNIEnv* env, void* context, void* activity) { if (ar_session == nullptr) { ArInstallStatus install_status; ArCoreApk_requestInstall(env, activity, /*user_requested=*/true, &install_status); if (install_status == AR_INSTALL_STATUS_INSTALL_REQUESTED) return; ArSession_create(env, context, &ar_session); // Configure: enable depth if supported ArConfig* ar_config; ArConfig_create(ar_session, &ar_config); ArConfig_setDepthMode(ar_session, ar_config, AR_DEPTH_MODE_AUTOMATIC); ArSession_configure(ar_session, ar_config); ArConfig_destroy(ar_config); ArFrame_create(ar_session, &ar_frame); ArSession_setDisplayGeometry(ar_session, display_rotation, width, height); } ArSession_resume(ar_session); } // --- Per-frame draw --- void OnDrawFrame() { ArSession_setCameraTextureName(ar_session, background_texture_id); ArSession_update(ar_session, ar_frame); // advance one frame ArCamera* ar_camera; ArFrame_acquireCamera(ar_session, ar_frame, &ar_camera); ArTrackingState tracking_state; ArCamera_getTrackingState(ar_session, ar_camera, &tracking_state); float view_mat[16], proj_mat[16]; ArCamera_getViewMatrix(ar_session, ar_camera, view_mat); ArCamera_getProjectionMatrix(ar_session, ar_camera, 0.1f, 100.f, proj_mat); ArCamera_release(ar_camera); // MUST release each acquired reference if (tracking_state != AR_TRACKING_STATE_TRACKING) return; // Query all tracked planes ArTrackableList* plane_list; ArTrackableList_create(ar_session, &plane_list); ArSession_getAllTrackables(ar_session, AR_TRACKABLE_PLANE, plane_list); int32_t plane_count; ArTrackableList_getSize(ar_session, plane_list, &plane_count); for (int i = 0; i < plane_count; ++i) { ArTrackable* trackable; ArTrackableList_acquireItem(ar_session, plane_list, i, &trackable); // … render plane … ArTrackable_release(trackable); // release each item } ArTrackableList_destroy(plane_list); } // --- Pause / Destroy --- void OnPause() { ArSession_pause(ar_session); } void OnDestroy() { ArSession_destroy(ar_session); ArFrame_destroy(ar_frame); } ``` -------------------------------- ### Link GLM in CMakeLists.txt (Shared Library) Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/readme.md This CMakeLists.txt snippet shows how to find and link the GLM library as a shared library in your project. Ensure GLM is installed or available in your CMake include path. ```cmake find_package(glm CONFIG REQUIRED) target_link_libraries(main PRIVATE glm::glm) ``` -------------------------------- ### Include GLM Extensions and Matrix Transformations Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Demonstrates how to include GLM extensions and use matrix transformation functions. Ensure the necessary header files are included before use. ```cpp #include "third_party/glm/latest/glm/glm.hpp" #include "third_party/glm/latest/glm/gtc/matrix_transform.hpp" int foo() { glm::vec4 Position = glm::vec4(glm:: vec3(0.0f), 1.0f); glm::mat4 Model = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f)); glm::vec4 Transformed = Model * Position; ... return 0; } ``` -------------------------------- ### Configure Include Directories and Link Libraries Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/hardwarebuffer_java/app/CMakeLists.txt Configures private include directories for the application library and links it against necessary system and ARCore libraries. Ensure all listed libraries are available. ```cmake target_include_directories(hello_ar_hardwarebuffer_native PRIVATE src/main/cpp) target_link_libraries(hello_ar_hardwarebuffer_native android log EGL GLESv2 glm arcore) ``` -------------------------------- ### Camera Matrix Transformation with GLM Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/readme.md This C++ snippet demonstrates how to construct a camera matrix using GLM, incorporating perspective projection, translation, rotation, and scaling. It requires including various GLM headers for vector, matrix, and transformation functions. ```cpp #include "third_party/glm/latest/glm/vec3.hpp" #include "third_party/glm/latest/glm/vec4.hpp" #include "third_party/glm/latest/glm/mat4x4.hpp" #include "third_party/glm/latest/glm/ext/matrix_transform.hpp" #include "third_party/glm/latest/glm/ext/matrix_clip_space.hpp" #include "third_party/glm/latest/glm/ext/scalar_constants.hpp" glm::mat4 camera(float Translate, glm::vec2 const& Rotate) { glm::mat4 Projection = glm::perspective(glm::pi() * 0.25f, 4.0f / 3.0f, 0.1f, 100.f); glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Translate)); View = glm::rotate(View, Rotate.y, glm::vec3(-1.0f, 0.0f, 0.0f)); View = glm::rotate(View, Rotate.x, glm::vec3(0.0f, 1.0f, 0.0f)); glm::mat4 Model = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f)); return Projection * View * Model; } ``` -------------------------------- ### GLM_FORCE_DEFAULT_ALIGNED_GENTYPES: Default aligned types Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES to make GLM vector types aligned by default. This can affect structure padding and memory layout, as demonstrated by the sizeof examples. ```cpp #define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES #include "third_party/glm/latest/glm/glm.hpp" struct MyStruct { glm::vec4 a; float b; glm::vec3 c; }; void foo() { printf("MyStruct requires memory padding: %d bytes\n", sizeof(MyStruct)); } >>> MyStruct requires memory padding: 48 bytes ``` ```cpp #include "third_party/glm/latest/glm/glm.hpp" struct MyStruct { glm::vec4 a; float b; glm::vec3 c; }; void foo() { printf("MyStruct is tightly packed: %d bytes\n", sizeof(MyStruct)); } >>> MyStruct is tightly packed: 32 bytes ``` -------------------------------- ### GLM emulation of GLSL precision qualifiers Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Demonstrates how GLM emulates GLSL precision qualifiers using prefixes like 'highp_', 'mediump_', and 'lowp_'. This allows trading precision for performance. ```glsl // Using precision qualifier in GLSL: ivec3 foo(in vec4 v) { highp vec4 a = v; mediump vec4 b = a; lowp ivec3 c = ivec3(b); return c; } ``` ```cpp // Using precision qualifier in GLM: #include "third_party/glm/latest/glm/glm.hpp" ivec3 foo(const vec4 & v) { highp_vec4 a = v; medium_vec4 b = a; lowp_ivec3 c = glm::ivec3(b); return c; } ``` -------------------------------- ### Update Session and Get Frame in ARCore Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt Call session.update() within your GLSurfaceView.Renderer.onDrawFrame to retrieve the latest tracking state and camera image. Ensure camera texture names are set before updating. ```java @Override public void onDrawFrame(SampleRender render) { if (session == null) return; // Bind camera texture names once on the GL thread if (!hasSetTextureNames) { session.setCameraTextureNames( new int[]{ backgroundRenderer.getCameraColorTexture().getTextureId() }); hasSetTextureNames = true; } // Drive ARCore and get the current frame Frame frame; try { frame = session.update(); } catch (CameraNotAvailableException e) { Log.e(TAG, "Camera not available", e); return; } Camera camera = frame.getCamera(); TrackingState trackingState = camera.getTrackingState(); // Obtain projection and view matrices float[] projectionMatrix = new float[16]; float[] viewMatrix = new float[16]; camera.getProjectionMatrix(projectionMatrix, 0, 0.1f, 100f); camera.getViewMatrix(viewMatrix, 0); // Acquire and release a point cloud (try-with-resources handles release) try (PointCloud pointCloud = frame.acquirePointCloud()) { if (pointCloud.getTimestamp() > lastPointCloudTimestamp) { pointCloudVertexBuffer.set(pointCloud.getPoints()); lastPointCloudTimestamp = pointCloud.getTimestamp(); } } // Render background camera image backgroundRenderer.drawBackground(render); if (trackingState == TrackingState.PAUSED) return; // … render virtual objects using viewMatrix and projectionMatrix … } ``` -------------------------------- ### Session - Create, Configure, and Manage AR Session Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt This snippet outlines the process of creating, configuring, and managing the ARCore Session, which is the central object for AR functionality. It covers lifecycle management (resume, pause, close) and configuration for features like depth and light estimation. ```APIDOC ## Session - Create, Configure, and Manage AR Session ### Description The `Session` object is the core of ARCore, managing tracking state and AR features. This documentation covers its creation, configuration, and integration with the Android Activity lifecycle. ### Creation `Session` must be created on the UI thread after ARCore is installed and camera permission is granted. ```java Session session; try { session = new Session(/* context= */ this); } catch (UnavailableArcoreNotInstalledException e) { showError("Please install ARCore"); return; } catch (UnavailableApkTooOldException e) { showError("Please update ARCore"); return; } catch (UnavailableSdkTooOldException e) { showError("Please update the app"); return; } catch (UnavailableDeviceNotCompatibleException e) { showError("Device does not support AR"); return; } ``` ### Configuration Configure the session with a `Config` object to enable features like light estimation and depth sensing. ```java // Configure: enable Environmental HDR light estimation + automatic depth Config config = session.getConfig(); config.setLightEstimationMode(Config.LightEstimationMode.ENVIRONMENTAL_HDR); if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) { config.setDepthMode(Config.DepthMode.AUTOMATIC); } else { config.setDepthMode(Config.DepthMode.DISABLED); } config.setInstantPlacementMode(Config.InstantPlacementMode.LOCAL_Y_UP); session.configure(config); ``` ### Lifecycle Management Integrate `Session` methods with the Activity lifecycle callbacks (`onResume`, `onPause`, `onDestroy`). ```java // Lifecycle integration @Override protected void onResume() { super.onResume(); try { session.resume(); } catch (CameraNotAvailableException e) { session = null; } surfaceView.onResume(); } @Override public void onPause() { super.onPause(); surfaceView.onPause(); // pause GL before session session.pause(); } @Override protected void onDestroy() { if (session != null) { session.close(); session = null; } super.onDestroy(); } ``` ### Key Methods - `Session(Context context)`: Constructor to create a new Session. - `getConfig()`: Retrieves the current configuration. - `configure(Config config)`: Applies the given configuration. - `resume()`: Resumes the AR session. - `pause()`: Pauses the AR session. - `close()`: Closes and releases resources associated with the session. ``` -------------------------------- ### Include GLM Core and Extension Headers Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Include both core GLM features and extensions for additional functionality. Be mindful of potential build time increases. ```cpp // Include all GLM core / GLSL features #include "third_party/glm/latest/glm/glm.hpp" // vec2, vec3, mat4, radians // Include all GLM extensions #include "third_party/glm/latest/glm/ext.hpp" // perspective, translate, rotate glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, glm::vec3 const& Up) { glm::mat4 Proj = glm::perspective(glm::radians(45.f), 1.33f, 0.1f, 10.f); glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.f), Translate); glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Orientation.y, Up); glm::mat4 View = glm::rotate(ViewRotateX, Orientation.x, Up); glm::mat4 Model = glm::mat4(1.0f); return Proj * View * Model; } ``` -------------------------------- ### GLM_FORCE_ALIGNED_GENTYPES: Enable aligned types Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Use GLM_FORCE_ALIGNED_GENTYPES to ensure GLM types adhere to alignment requirements, which is crucial for SIMD optimizations. This example shows how to use aligned and packed vector types. ```cpp #define GLM_FORCE_ALIGNED_GENTYPES #include "third_party/glm/latest/glm/glm.hpp" #include "third_party/glm/latest/glm/gtc/type_aligned.hpp" typedef glm::aligned_vec4 vec4a; typedef glm::packed_vec4 vec4p; ``` -------------------------------- ### Measure float accuracy with GLM_EXT_scalar_ulp Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Include `` to use functions that measure accuracy in numeric calculations. This example demonstrates checking if two floats are a single ULP (Unit in the Last Place) apart. ```cpp #include "third_party/glm/latest/glm/ext/scalar_ulp.hpp" bool test_ulp(float x) { float const a = glm::next_float(x); // return a float a ULP away from the float argument. return float_distance(a, x) == 1; // check both float are a single ULP away. } ``` -------------------------------- ### Hit testing — placing anchors on detected surfaces Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt The `Frame.hitTest()` and `Frame.hitTestInstantPlacement()` methods cast a ray from a screen touch coordinate into the physical environment to find intersections with detected surfaces. They return a list of `HitResult` objects, each containing a `Trackable` and a pose that can be used to create an `Anchor`. ```APIDOC ## Frame.hitTest() and Frame.hitTestInstantPlacement() ### Description Casts a ray from a screen touch coordinate into the physical environment to detect intersections with surfaces. Returns a list of `HitResult` objects sorted by depth, allowing for the placement of anchors on detected planes, points, or instant placement points. ### Method ```java List hits = frame.hitTest(tap); // or List hits = frame.hitTestInstantPlacement(tap.getX(), tap.getY(), approximateDistanceMeters); ``` ### Parameters #### `hitTest(MotionEvent tap)` - **tap** (MotionEvent) - The screen touch event. #### `hitTestInstantPlacement(float x, float y, float approximateDistanceMeters)` - **x** (float) - The x-coordinate of the touch point. - **y** (float) - The y-coordinate of the touch point. - **approximateDistanceMeters** (float) - An estimated distance in meters for instant placement. ### Response - **List** - A list of `HitResult` objects representing detected intersections, sorted by depth. Each `HitResult` contains a `Trackable` and a pose. ``` -------------------------------- ### Configure Include Directories and Link Libraries Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/hello_ar_c/app/CMakeLists.txt Sets private include directories for the application's native code and links the necessary libraries, including Android NDK, OpenGL ES, GLM, and ARCore. This ensures all dependencies are resolved for building. ```cmake target_include_directories(hello_ar_native PRIVATE src/main/cpp) target_link_libraries(hello_ar_native android log GLESv2 glm arcore) ``` -------------------------------- ### Get Pointer to GLM Type Memory Layout Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Use glm::value_ptr to obtain a pointer to the memory layout of GLM vectors and matrices. This is useful for uploading data to matrices or copying data to buffer objects. Include . ```cpp #include "third_party/glm/latest/glm/glm.hpp" #include "third_party/glm/latest/glm/gtc/type_ptr.hpp" void foo() { glm::vec4 v(0.0f); glm::mat4 m(1.0f); ... glVertex3fv(glm::value_ptr(v)) glLoadMatrixfv(glm::value_ptr(m)); } ``` ```cpp #include "third_party/glm/latest/glm/glm.hpp" void foo() { glm::vec4 v(0.0f); glm::mat4 m(1.0f); ... glVertex3fv(&v[0]); glLoadMatrixfv(&m[0][0]); } ``` -------------------------------- ### Update Light Estimation for PBR Shaders Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt Feeds real-world lighting data into PBR shaders for realistic virtual object lighting. Requires `Frame.getLightEstimate()` and provides directional and ambient lighting information. ```java private void updateLightEstimation(LightEstimate lightEstimate, float[] viewMatrix) { if (lightEstimate.getState() != LightEstimate.State.VALID) { virtualObjectShader.setBool("u_LightEstimateIsValid", false); return; } virtualObjectShader.setBool("u_LightEstimateIsValid", true); // Main directional light: direction and RGB intensity float[] mainLightDirection = lightEstimate.getEnvironmentalHdrMainLightDirection(); float[] mainLightIntensity = lightEstimate.getEnvironmentalHdrMainLightIntensity(); float[] worldLightDir = { mainLightDirection[0], mainLightDirection[1], mainLightDirection[2], 0f }; float[] viewLightDir = new float[4]; Matrix.multiplyMV(viewLightDir, 0, viewMatrix, 0, worldLightDir, 0); virtualObjectShader.setVec4("u_ViewLightDirection", viewLightDir); virtualObjectShader.setVec3("u_LightIntensity", mainLightIntensity); // 9-band spherical harmonics for ambient diffuse lighting float[] shCoefficients = lightEstimate.getEnvironmentalHdrAmbientSphericalHarmonics(); // Pre-multiply coefficients by normalised SH basis × lambertian BRDF factor for (int i = 0; i < 9 * 3; ++i) { shCoefficients[i] *= sphericalHarmonicFactors[i / 3]; } virtualObjectShader.setVec3Array("u_SphericalHarmonicsCoefficients", shCoefficients); // HDR specular cubemap updated from the real-world environment cubemapFilter.update(lightEstimate.acquireEnvironmentalHdrCubeMap()); } ``` -------------------------------- ### Link Libraries and Include Directories Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/hardwarebuffer_c/app/CMakeLists.txt Configures include directories for the application's native code and links the necessary libraries, including Android system libraries, OpenGL ES, EGL, GLM, and ARCore. This ensures all dependencies are resolved during the build process. ```cmake target_include_directories(hello_ar_hardwarebuffer_native PRIVATE src/main/cpp) target_link_libraries(hello_ar_hardwarebuffer_native android log GLESv2 EGL glm arcore) ``` -------------------------------- ### Add GLM to CMake Project with FetchContent Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/readme.md This CMakeLists.txt snippet shows how to use CMake's FetchContent module to download and build GLM directly within your project. It specifies the Git repository and a commit hash for reproducibility. ```cmake cmake_minimum_required(VERSION 3.11) # FetchContent is new in version 3.11. include(FetchContent) FetchContent_Declare( glm GIT_REPOSITORY https://github.com/g-truc/glm.git GIT_TAG bf71a834948186f4097caa076cd2663c69a10e1e #refs/tags/1.0.1 ) FetchContent_MakeAvailable(glm) target_link_libraries(main PRIVATE glm::glm) ``` -------------------------------- ### Use GLM Core and Extension Headers Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Combine includes for GLM core features like vectors and matrices with specific extension headers for functionalities such as transformations and perspective projection. ```cpp // Include GLM core features #include "third_party/glm/latest/glm/vec2.hpp" #include "third_party/glm/latest/glm/vec3.hpp" #include "third_party/glm/latest/glm/mat4x4.hpp" #include "third_party/glm/latest/glm/trigonometric.hpp" // Include GLM extension #include "third_party/glm/latest/glm/ext/matrix_transform.hpp" #include "third_party/glm/latest/glm/ext/matrix_clip_space.hpp" glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, glm::vec3 const& Up) { glm::mat4 Proj = glm::perspective(glm::radians(45.f), 1.33f, 0.1f, 10.f); glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.f), Translate); glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Orientation.y, Up); glm::mat4 View = glm::rotate(ViewRotateX, Orientation.x, Up); glm::mat4 Model = glm::mat4(1.0f); return Proj * View * Model; } ``` -------------------------------- ### Import ARCore Library Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/hello_ar_c/app/CMakeLists.txt Imports the ARCore shared library and configures its properties, including the shared object location and include directories. This is crucial for AR functionality. ```cmake add_library(arcore SHARED IMPORTED) set_target_properties(arcore PROPERTIES IMPORTED_LOCATION ${ARCORE_LIBPATH}/${ANDROID_ABI}/libarcore_sdk_c.so INTERFACE_INCLUDE_DIRECTORIES ${ARCORE_INCLUDE} ) ``` -------------------------------- ### GLM Lighting Calculation Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Implements a basic lighting model considering diffuse and specular components, with support for shadows and random light vector perturbation. ```cpp #include "third_party/glm/latest/glm/glm.hpp" // vec3 normalize reflect dot pow #include "third_party/glm/latest/glm/gtc/random.hpp" // ballRand // vecRand3, generate a random and equiprobable normalized vec3 glm::vec3 lighting(intersection const& Intersection, material const& Material, light const& Light, glm::vec3 const& View) { glm::vec3 Color = glm::vec3(0.0f); glm::vec3 LightVertor = glm::normalize( Light.position() - Intersection.globalPosition() + glm::ballRand(0.0f, Light.inaccuracy())); if(!shadow(Intersection.globalPosition(), Light.position(), LightVertor)) { float Diffuse = glm::dot(Intersection.normal(), LightVector); if(Diffuse <= 0.0f) return Color; if(Material.isDiffuse()) Color += Light.color() * Material.diffuse() * Diffuse; if(Material.isSpecular()) { glm::vec3 Reflect = glm::reflect(-LightVector, Intersection.normal()); float Dot = glm::dot(Reflect, View); float Base = Dot > 0.0f ? Dot : 0.0f; float Specular = glm::pow(Base, Material.exponent()); Color += Material.specular() * Specular; } } return Color; } ``` -------------------------------- ### Define Main Application Library Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/hardwarebuffer_java/app/CMakeLists.txt Defines the main shared library for the application, listing its source files. This is the core native code for your AR application. ```cmake add_library(hello_ar_hardwarebuffer_native SHARED src/main/cpp/opengl_helper.cc src/main/cpp/jni_interface.cc src/main/cpp/util.cc) ``` -------------------------------- ### Define Main Application Library Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/hardwarebuffer_c/app/CMakeLists.txt Defines the main shared library for the application, listing all its source files. This compiles your native C++ code into a single library. ```cmake add_library(hello_ar_hardwarebuffer_native SHARED src/main/cpp/background_renderer.cc src/main/cpp/hello_ar_application.cc src/main/cpp/jni_interface.cc src/main/cpp/obj_renderer.cc src/main/cpp/plane_renderer.cc src/main/cpp/point_cloud_renderer.cc src/main/cpp/texture.cc src/main/cpp/util.cc) ``` -------------------------------- ### Checkout Master Branch Git Command Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Use this command to switch to the master branch before synchronizing your fork. Ensure you are on the master branch to create a new branch from the latest code. ```plaintext git checkout master ``` -------------------------------- ### Set Include Directories Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/augmented_image_c/app/CMakeLists.txt Specifies private include directories for the main application library. This allows source files to find header files within the specified path. ```cmake target_include_directories(augmented_image_native PRIVATE src/main/cpp) ``` -------------------------------- ### Include GLM Core Headers Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Include the main GLM header to access core GLSL mathematics functionality like vectors and matrices. ```cpp #include "third_party/glm/latest/glm/glm.hpp" ``` -------------------------------- ### Check VPS Availability with Geospatial API Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt Asynchronously check for Visual Positioning System (VPS) availability at a given latitude and longitude. A callback is provided to handle the availability status. ```java // 2. Check VPS availability at the user's current location VpsAvailabilityFuture future = session.checkVpsAvailabilityAsync(latitude, longitude, availability -> { if (availability != VpsAvailability.AVAILABLE) showVpsNotAvailableDialog(); }); ``` -------------------------------- ### Define Main Application Library Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/hello_ar_c/app/CMakeLists.txt Defines the main shared library for the application, listing all its source files. This compiles the native C++ code for the AR application. ```cmake add_library(hello_ar_native SHARED src/main/cpp/background_renderer.cc src/main/cpp/hello_ar_application.cc src/main/cpp/jni_interface.cc src/main/cpp/obj_renderer.cc src/main/cpp/plane_renderer.cc src/main/cpp/point_cloud_renderer.cc src/main/cpp/texture.cc src/main/cpp/util.cc) ``` -------------------------------- ### GLM project function for screen to object space Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Replaces gluProject for converting screen coordinates to object coordinates. Supports both float and double precision. ```cpp glm::vec3 project(glm::vec3 const& obj, glm::mat4 const& model, glm::mat4 const& proj, glm::ivec4 const& viewport); glM::dvec3 project(glm::dvec3 const& obj, glm::dmat4 const& model, glm::dmat4 const& proj, glm::ivec4 const& viewport); ``` -------------------------------- ### Enable GLM Build Messages Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Define GLM_FORCE_MESSAGES before including GLM headers to capture build configuration details for bug reporting. ```cpp #define GLM_FORCE_MESSAGES #include "third_party/glm/latest/glm/glm.hpp" ``` -------------------------------- ### Acquire and Process Depth Data with ARCore Source: https://context7.com/google-ar/arcore-android-sdk/llms.txt Acquires 16-bit depth and confidence images from the ARCore frame, then uses camera intrinsics to unproject depth pixels into a 3D point cloud. Matches points with RGB colors from the camera image and anchors the point cloud to the camera's pose. ```java // In onDrawFrame — acquire depth and reproject to a 3D point cloud public static DepthData create(Session session, Frame frame) { try (Image cameraImage = frame.acquireCameraImage(); Image depthImage = frame.acquireRawDepthImage16Bits(); // 16-bit mm values Image confidenceImage = frame.acquireRawDepthConfidenceImage()) { // 0-255 confidence final int maxPoints = 15000; // Use camera intrinsics to unproject 2-D depth pixels to 3-D world space CameraIntrinsics intrinsics = frame.getCamera().getTextureIntrinsics(); FloatBuffer points = PointCloudHelper.convertRawDepthImagesTo3dPointBuffer( depthImage, confidenceImage, intrinsics, maxPoints); // Match each 3-D point to an RGB colour from the co-located camera image FloatBuffer imageCoords = PointCloudHelper.getImageCoordinatesForFullTexture(frame); FloatBuffer colors = PointCloudHelper.convertImageToColorBuffer( cameraImage, depthImage, imageCoords, maxPoints); // Anchor at camera pose so the point cloud stays in world space after the camera moves Anchor cameraPoseAnchor = session.createAnchor(frame.getCamera().getPose()); return new DepthData(points, colors, depthImage.getTimestamp(), cameraPoseAnchor); } catch (NotYetAvailableException e) { // Depth not yet available for this frame — normal at session start } return null; } ``` -------------------------------- ### GLM Matrix Relational Comparison Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Compares two matrices for equality using an optional epsilon for floating-point tolerance. Requires including ``. ```cpp #include "third_party/glm/latest/glm/ext/vector_bool4.hpp" // bvec4 #include "third_party/glm/latest/glm/ext/matrix_float4x4.hpp" // mat4 #include "third_party/glm/latest/glm/ext/matrix_relational.hpp" // equal, all bool epsilonEqual(glm::mat4 const& A, glm::mat4 const& B) { float const CustomEpsilon = 0.0001f; glm::bvec4 const ColumnEqual = glm::equal(A, B, CustomEpsilon); // Evaluation per column return glm::all(ColumnEqual); } ``` -------------------------------- ### Import GLM Library Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/augmented_image_c/app/CMakeLists.txt Imports the GLM (OpenGL Mathematics) header files from the NDK. This is used for mathematical operations in graphics programming. ```cmake add_library( glm INTERFACE ) set_target_properties( glm PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${GLM_INCLUDE}) ``` -------------------------------- ### Find GLM with CMake and Link Target Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Use `find_package` to locate GLM and `target_link_libraries` to link your executable against the `glm::glm` target. This is the recommended way to integrate GLM. ```cmake set(glm_DIR /lib/cmake/glm) # if necessary find_package(glm REQUIRED) target_link_libraries( glm::glm) ``` -------------------------------- ### Configure Google Cloud Vision API Key in AndroidManifest.xml Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/ml_kotlin/app/README.md Add your Google Cloud Vision API key to the application's AndroidManifest.xml file. Ensure you have configured your Google Cloud project, enabled billing, and enabled the Vision API. ```xml ``` -------------------------------- ### Import GLM Library Source: https://github.com/google-ar/arcore-android-sdk/blob/main/samples/hello_ar_c/app/CMakeLists.txt Imports the GLM (OpenGL Mathematics) header files as an interface library. This is used for mathematical operations in graphics programming. ```cmake add_library( glm INTERFACE ) set_target_properties( glm PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${GLM_INCLUDE}) ``` -------------------------------- ### glm::project Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Converts object coordinates to window coordinates. This is equivalent to the GLU function `gluProject`. ```APIDOC ## glm::project ### Description Converts object coordinates to window coordinates. This is equivalent to the GLU function `gluProject`. ### Signature ```cpp glm::vec3 project(glm::vec3 const& obj, glm::mat4 const& model, glm::mat4 const& proj, glm::ivec4 const& viewport); glm::dvec3 project(glm::dvec3 const& obj, glm::dmat4 const& model, glm::dmat4 const& proj, glm::ivec4 const& viewport); ``` ### Header `` ``` -------------------------------- ### C++ Swizzle with Language Extensions (L-value Support) Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Using compiler-specific extensions, GLM enables GLSL-like swizzle syntax that supports both L-value and R-value operations. This requires `GLM_FORCE_SWIZZLE` and compiler support for anonymous structs in unions. ```cpp #define GLM_FORCE_SWIZZLE #include "third_party/glm/latest/glm/glm.hpp" // Only guaranteed to work with Visual C++! // Some compilers that support Microsoft extensions may compile this. void foo() { glm::vec4 ColorRGBA = glm::vec4(1.0f, 0.5f, 0.0f, 1.0f); // l-value: glm::vec4 ColorBGRA = ColorRGBA.bgra; // r-value: ColorRGBA.bgra = ColorRGBA; // Both l-value and r-value ColorRGBA.bgra = ColorRGBA.rgba; } ``` -------------------------------- ### GLM Perspective Projection Matrix Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Computes a perspective projection matrix for transforming scenes into clip space. Requires including ``. ```cpp #include "third_party/glm/latest/glm/ext/matrix_float4x4.hpp" // mat4x4 #include "third_party/glm/latest/glm/ext/matrix_clip_space.hpp" // perspective #include "third_party/glm/latest/glm/trigonometric.hpp" // radians glm::mat4 computeProjection(float Width, float Height) { return glm::perspective(glm::radians(45.0f), Width / Height, 0.1f, 100.f); } ``` -------------------------------- ### Include GLM Extension Headers for Vector and Matrix Operations Source: https://github.com/google-ar/arcore-android-sdk/blob/main/third_party/glm/manual.md Include specific GLM extension headers for vector and matrix operations, such as float vectors, 4x4 matrices, transformations, and clip space calculations, to optimize build times. ```cpp // Include GLM vector extensions: #include "third_party/glm/latest/glm/ext/vector_float2.hpp" #include "third_party/glm/latest/glm/ext/vector_float3.hpp" #include "third_party/glm/latest/glm/ext/vector_trigonometric.hpp" // Include GLM matrix extensions: #include "third_party/glm/latest/glm/ext/matrix_float4x4.hpp" #include "third_party/glm/latest/glm/ext/matrix_transform.hpp" #include "third_party/glm/latest/glm/ext/matrix_clip_space.hpp" glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, glm::vec3 const& Up) { glm::mat4 Proj = glm::perspective(glm::radians(45.f), 1.33f, 0.1f, 10.f); glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.f), Translate); glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Orientation.y, Up); glm::mat4 View = glm::rotate(ViewRotateX, Orientation.x, Up); glm::mat4 Model = glm::mat4(1.0f); return Proj * View * Model; } ```