@@ -40,11 +40,14 @@ struct NativeContext {
4040 bool arcoreEnabled = false ;
4141 ArSession *arSession = nullptr ;
4242 ArFrame *arFrame = nullptr ;
43+ ArAnchor *arFloorAnchor = nullptr ;
4344 GLuint arTexture = 0 ;
4445
4546 AlvrQuat lastOrientation = {0 .f , 0 .f , 0 .f , 0 .f };
4647 float lastPosition[3 ] = {0 .f , 0 .f , 0 .f };
4748
49+ float currentMagnetometerValues[4 ] = {0 .f , 0 .f , 0 .f , 0 .f };
50+
4851 int screenWidth = 0 ;
4952 int screenHeight = 0 ;
5053 int screenRotation = 0 ;
@@ -163,13 +166,100 @@ AlvrPose getPose(uint64_t timestampNs) {
163166
164167 ArPose *arPose = nullptr ;
165168 ArPose_create (CTX.arSession , nullptr , &arPose);
166- ArCamera_getPose (CTX.arSession , arCamera, arPose);
169+ ArCamera_getDisplayOrientedPose (CTX.arSession , arCamera, arPose);
167170 // ArPose_getPoseRaw() returns a pose in {qx, qy, qz, qw, tx, ty, tz} format.
168171 float arRawPose[7 ] = {0 .f , 0 .f , 0 .f , 0 .f , 0 .f , 0 .f , 0 .f };
169172 ArPose_getPoseRaw (CTX.arSession , arPose, arRawPose);
170173
174+
175+ /* We use an anchor here for two things:
176+ *
177+ * 1. To determine floor position by finding the lowest detected plane. We do this by
178+ * placing an anchor in the center position of the plane, and if it's lower than the
179+ * currently placed anchor (CTX.floorAnchor), we replace it.
180+ *
181+ * (By default, ARCore's "world coordinates" space begins wherever the device is, but this
182+ * can desync over time. Anchor position adapts to world space movement.)
183+ *
184+ * ~~2. To determine the rotation of world space. This allows us to improve tracking.~~
185+ * nevermind, that doesn't seem to work, orientation is stuck :(
186+ */
187+ ArTrackableList *trackables = nullptr ;
188+ ArTrackableList_create (CTX.arSession , &trackables);
189+ ArFrame_getUpdatedTrackables (CTX.arSession , CTX.arFrame , AR_TRACKABLE_PLANE, trackables);
190+ int32_t detectedPlaneCount;
191+ ArTrackableList_getSize (CTX.arSession , trackables, &detectedPlaneCount);
192+
193+ for (int i = 0 ; i < detectedPlaneCount; i++) {
194+ ArTrackable* arTrackable = nullptr ;
195+ ArTrackableList_acquireItem (CTX.arSession , trackables, i,
196+ &arTrackable);
197+ const ArPlane *plane = ArAsPlane (arTrackable);
198+ ArTrackingState planeTrackingState;
199+ ArTrackable_getTrackingState (CTX.arSession , arTrackable, &planeTrackingState);
200+ ArPlaneType planeType;
201+ ArPlane_getType (CTX.arSession , plane, &planeType);
202+ if (planeTrackingState == AR_TRACKING_STATE_TRACKING &&
203+ planeType == AR_PLANE_HORIZONTAL_UPWARD_FACING) {
204+ ArPose *planePose = nullptr ;
205+ ArPose_create (CTX.arSession , nullptr , &planePose);
206+ ArPlane_getCenterPose (CTX.arSession , plane, planePose);
207+
208+ bool reanchor = false ;
209+ if (CTX.arFloorAnchor == nullptr ) {
210+ reanchor = true ;
211+ } else {
212+ ArPose *currentFloorPose = nullptr ;
213+ ArPose_create (CTX.arSession , nullptr , ¤tFloorPose);
214+
215+ ArAnchor_getPose (CTX.arSession , CTX.arFloorAnchor , currentFloorPose);
216+ float currentFloorPoseRaw[7 ] = {0 .f , 0 .f , 0 .f , 0 .f , 0 .f , 0 .f , 0 .f };
217+ ArPose_getPoseRaw (CTX.arSession , currentFloorPose, currentFloorPoseRaw);
218+
219+ float planePoseRaw[7 ] = {0 .f , 0 .f , 0 .f , 0 .f , 0 .f , 0 .f , 0 .f };
220+ ArPose_getPoseRaw (CTX.arSession , planePose, planePoseRaw);
221+
222+ if (planePoseRaw[5 ] < currentFloorPoseRaw[5 ]) {
223+ info (" Found new plane lower than pose (current %f vs new %f), reanchoring" ,
224+ currentFloorPoseRaw[5 ], planePoseRaw[5 ]);
225+ reanchor = true ;
226+ }
227+ }
228+
229+ if (reanchor) {
230+ if (CTX.arFloorAnchor != nullptr ) {
231+ ArAnchor_detach (CTX.arSession , CTX.arFloorAnchor );
232+ ArAnchor_release (CTX.arFloorAnchor );
233+ }
234+
235+ ArPose *planePoseNoRotation = ArPose_extractTranslation (CTX.arSession ,
236+ planePose);
237+ ArTrackable_acquireNewAnchor (CTX.arSession , arTrackable, planePoseNoRotation,
238+ &CTX.arFloorAnchor );
239+ ArPose_destroy (planePoseNoRotation);
240+ }
241+
242+ ArPose_destroy (planePose);
243+ }
244+ }
245+
246+ ArTrackableList_destroy (trackables);
247+
248+ float anchorRawPose[7 ] = {0 .f , 0 .f , 0 .f , 0 .f , 0 .f , 0 .f , 0 .f };
249+ if (CTX.arFloorAnchor != nullptr ) {
250+ ArPose *anchorPose = nullptr ;
251+ ArPose_create (CTX.arSession , nullptr , &anchorPose);
252+ ArAnchor_getPose (CTX.arSession , CTX.arFloorAnchor , anchorPose);
253+ ArPose_getPoseRaw (CTX.arSession , anchorPose, anchorRawPose);
254+ info (" anchor pose %f %f %f %f %f %f %f" , anchorRawPose[0 ], anchorRawPose[1 ], anchorRawPose[2 ], anchorRawPose[3 ], anchorRawPose[4 ], anchorRawPose[5 ], anchorRawPose[6 ]);
255+ }
256+
257+
258+ pose.position [0 ] = arRawPose[4 ];
259+ pose.position [1 ] = arRawPose[5 ] - anchorRawPose[5 ];
260+ pose.position [2 ] = arRawPose[6 ];
261+
171262 for (int i = 0 ; i < 3 ; i++) {
172- pose.position [i] = arRawPose[i + 4 ];
173263 CTX.lastPosition [i] = arRawPose[i + 4 ];
174264 }
175265
@@ -345,6 +435,7 @@ extern "C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_initia
345435 ArConfig_setDepthMode (CTX.arSession , arConfig, AR_DEPTH_MODE_DISABLED);
346436 ArConfig_setLightEstimationMode (CTX.arSession , arConfig, AR_LIGHT_ESTIMATION_MODE_DISABLED);
347437 ArConfig_setPlaneFindingMode (CTX.arSession , arConfig, AR_PLANE_FINDING_MODE_HORIZONTAL_AND_VERTICAL);
438+ ArConfig_setCloudAnchorMode (CTX.arSession , arConfig, AR_CLOUD_ANCHOR_MODE_DISABLED);
348439
349440 // Set "latest camera image" update mode (ArSession_update returns immediately without blocking)
350441 ArConfig_setUpdateMode (CTX.arSession , arConfig, AR_UPDATE_MODE_LATEST_CAMERA_IMAGE);
0 commit comments