Skip to content

Commit a5a5412

Browse files
committed
altitude works \o/ (code needs cleanups...)
1 parent aba5513 commit a5a5412

File tree

2 files changed

+112
-2
lines changed

2 files changed

+112
-2
lines changed

code/mobile/android/PhoneVR/app/src/main/cpp/alvr_main.cpp

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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, &currentFloorPose);
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);

code/mobile/android/PhoneVR/app/src/main/cpp/utils.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define PHONEVR_UTILS_H
33

44
#include "alvr_client_core.h"
5+
#include "arcore_c_api.h"
56
#include <GLES3/gl3.h>
67
#include <android/log.h>
78
#include <string>
@@ -87,4 +88,22 @@ static const char *GlErrorString(GLenum error) {
8788
func; \
8889
GLCheckErrors(__FILE__, __LINE__)
8990

91+
/* Returns a pose having the translation of this pose but no rotation.
92+
* The caller is responsible for freeing the original pose and the output pose.
93+
* (C++ port of Pose.extractTranslation.) */
94+
static ArPose *ArPose_extractTranslation(ArSession *session, ArPose *in_pose) {
95+
float raw_pose[7] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
96+
ArPose_getPoseRaw(session, in_pose, raw_pose);
97+
98+
raw_pose[0] = 0.f;
99+
raw_pose[1] = 0.f;
100+
raw_pose[2] = 0.f;
101+
raw_pose[3] = 0.f;
102+
103+
ArPose *out_pose = nullptr;
104+
ArPose_create(session, raw_pose, &out_pose);
105+
106+
return out_pose;
107+
}
108+
90109
#endif // PHONEVR_UTILS_H

0 commit comments

Comments
 (0)