mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-03 01:50:24 +08:00
android: added occlusion detection using arcore depth api (for FPS view). Added depth from motion option in Mapping options.
This commit is contained in:
@@ -37,14 +37,16 @@ namespace rtabmap {
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// CameraARCore
|
// CameraARCore
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
CameraARCore::CameraARCore(void* env, void* context, void* activity, bool smoothing):
|
CameraARCore::CameraARCore(void* env, void* context, void* activity, bool depthFromMotion, bool smoothing):
|
||||||
CameraMobile(smoothing),
|
CameraMobile(smoothing),
|
||||||
env_(env),
|
env_(env),
|
||||||
context_(context),
|
context_(context),
|
||||||
activity_(activity),
|
activity_(activity),
|
||||||
arInstallRequested_(false),
|
arInstallRequested_(false),
|
||||||
textureId_(9999),
|
textureId_(9999),
|
||||||
uvs_initialized_(false)
|
uvs_initialized_(false),
|
||||||
|
updateOcclusionImage_(false),
|
||||||
|
depthFromMotion_(depthFromMotion)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,8 +164,8 @@ bool CameraARCore::init(const std::string & calibrationFolder, const std::string
|
|||||||
UASSERT(ArSession_create(env_, context_, &arSession_) == AR_SUCCESS);
|
UASSERT(ArSession_create(env_, context_, &arSession_) == AR_SUCCESS);
|
||||||
UASSERT(arSession_);
|
UASSERT(arSession_);
|
||||||
|
|
||||||
int32_t is_depth_supported = 0; // Disabled by default, depth is not super accurate for mapping
|
int32_t is_depth_supported = 0;
|
||||||
//ArSession_isDepthModeSupported(arSession_, AR_DEPTH_MODE_AUTOMATIC, &is_depth_supported);
|
ArSession_isDepthModeSupported(arSession_, AR_DEPTH_MODE_AUTOMATIC, &is_depth_supported);
|
||||||
|
|
||||||
ArConfig_create(arSession_, &arConfig_);
|
ArConfig_create(arSession_, &arConfig_);
|
||||||
UASSERT(arConfig_);
|
UASSERT(arConfig_);
|
||||||
@@ -277,6 +279,7 @@ void CameraARCore::close()
|
|||||||
arPose_ = nullptr;
|
arPose_ = nullptr;
|
||||||
|
|
||||||
CameraMobile::close();
|
CameraMobile::close();
|
||||||
|
occlusionImage_ = cv::Mat();
|
||||||
}
|
}
|
||||||
|
|
||||||
LaserScan CameraARCore::scanFromPointCloudData(
|
LaserScan CameraARCore::scanFromPointCloudData(
|
||||||
@@ -429,8 +432,7 @@ SensorData CameraARCore::captureImage(CameraInfo * info)
|
|||||||
ArStatus status = ArFrame_acquireCameraImage(arSession_, arFrame_, &image);
|
ArStatus status = ArFrame_acquireCameraImage(arSession_, arFrame_, &image);
|
||||||
if(status == AR_SUCCESS)
|
if(status == AR_SUCCESS)
|
||||||
{
|
{
|
||||||
cv::Mat outputDepth;
|
if(is_depth_supported && (updateOcclusionImage_||depthFromMotion_))
|
||||||
if(is_depth_supported)
|
|
||||||
{
|
{
|
||||||
LOGD("Acquire depth image!");
|
LOGD("Acquire depth image!");
|
||||||
ArImage * depthImage = nullptr;
|
ArImage * depthImage = nullptr;
|
||||||
@@ -444,36 +446,24 @@ SensorData CameraARCore::captureImage(CameraInfo * info)
|
|||||||
int planeCount;
|
int planeCount;
|
||||||
ArImage_getNumberOfPlanes(arSession_, depthImage, &planeCount);
|
ArImage_getNumberOfPlanes(arSession_, depthImage, &planeCount);
|
||||||
LOGD("planeCount=%d", planeCount);
|
LOGD("planeCount=%d", planeCount);
|
||||||
UASSERT_MSG(planeCount == 1,
|
UASSERT_MSG(planeCount == 1, uFormat("Error: getNumberOfPlanes() planceCount = %d", planeCount).c_str());
|
||||||
uFormat("Error: getNumberOfPlanes() planceCount = %d", planeCount).c_str());
|
|
||||||
const uint8_t *data = nullptr;
|
const uint8_t *data = nullptr;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int stride;
|
int stride;
|
||||||
int width;
|
int depth_width;
|
||||||
int height;
|
int depth_height;
|
||||||
ArImage_getWidth(arSession_, depthImage, &width);
|
ArImage_getWidth(arSession_, depthImage, &depth_width);
|
||||||
ArImage_getHeight(arSession_, depthImage, &height);
|
ArImage_getHeight(arSession_, depthImage, &depth_height);
|
||||||
ArImage_getPlaneRowStride(arSession_, depthImage, 0, &stride);
|
ArImage_getPlaneRowStride(arSession_, depthImage, 0, &stride);
|
||||||
ArImage_getPlaneData(arSession_, depthImage, 0, &data, &len);
|
ArImage_getPlaneData(arSession_, depthImage, 0, &data, &len);
|
||||||
|
|
||||||
LOGD("width=%d, height=%d, bytes=%d stride=%d", width, height, len, stride);
|
LOGD("width=%d, height=%d, bytes=%d stride=%d", depth_width, depth_height, len, stride);
|
||||||
|
|
||||||
outputDepth = cv::Mat(height, width, CV_16UC1);
|
occlusionImage_ = cv::Mat(depth_height, depth_width, CV_16UC1, (void*)data).clone();
|
||||||
uint16_t *dataShort = (uint16_t *)data;
|
|
||||||
uint16_t max=0x0;
|
float scaleX = (float)depth_width / (float)width;
|
||||||
for (int y = 0; y < outputDepth.rows; ++y)
|
float scaleY = (float)depth_height / (float)height;
|
||||||
{
|
occlusionModel_ = CameraModel(fx*scaleX, fy*scaleY, cx*scaleX, cy*scaleY, pose*deviceTColorCamera_, 0, cv::Size(depth_width, depth_height));
|
||||||
for (int x = 0; x < outputDepth.cols; ++x)
|
|
||||||
{
|
|
||||||
uint16_t depthSample = dataShort[y*outputDepth.cols + x];
|
|
||||||
uint16_t depthRange = (depthSample & 0x1FFF); // first 3 bits are confidence
|
|
||||||
outputDepth.at<uint16_t>(y,x) = depthRange;
|
|
||||||
if(depthRange > max)
|
|
||||||
{
|
|
||||||
max = depthRange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ArImage_release(depthImage);
|
ArImage_release(depthImage);
|
||||||
}
|
}
|
||||||
@@ -545,7 +535,7 @@ SensorData CameraARCore::captureImage(CameraInfo * info)
|
|||||||
LOGI("pointCloud empty");
|
LOGI("pointCloud empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
data = SensorData(scan, rgb, outputDepth, model, 0, stamp);
|
data = SensorData(scan, rgb, depthFromMotion_?occlusionImage_:cv::Mat(), model, 0, stamp);
|
||||||
data.setFeatures(kpts, kpts3, cv::Mat());
|
data.setFeatures(kpts, kpts3, cv::Mat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -619,11 +609,6 @@ void CameraARCore::capturePoseOnly()
|
|||||||
uvs_initialized_ = true;
|
uvs_initialized_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ArImage* ar_image = nullptr;
|
|
||||||
ArStatus status =
|
|
||||||
ArFrame_acquireCameraImage(arSession_, arFrame_, &ar_image);
|
|
||||||
ArImage_release(ar_image);
|
|
||||||
*/
|
|
||||||
ArCamera* ar_camera;
|
ArCamera* ar_camera;
|
||||||
ArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
|
ArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
|
||||||
|
|
||||||
@@ -649,6 +634,52 @@ void CameraARCore::capturePoseOnly()
|
|||||||
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
||||||
this->poseReceived(pose);
|
this->poseReceived(pose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t is_depth_supported = 0;
|
||||||
|
ArSession_isDepthModeSupported(arSession_, AR_DEPTH_MODE_AUTOMATIC, &is_depth_supported);
|
||||||
|
|
||||||
|
if(is_depth_supported && updateOcclusionImage_)
|
||||||
|
{
|
||||||
|
LOGD("Acquire depth image!");
|
||||||
|
ArImage * depthImage = nullptr;
|
||||||
|
ArFrame_acquireDepthImage(arSession_, arFrame_, &depthImage);
|
||||||
|
|
||||||
|
ArImageFormat format;
|
||||||
|
ArImage_getFormat(arSession_, depthImage, &format);
|
||||||
|
if(format == AR_IMAGE_FORMAT_DEPTH16)
|
||||||
|
{
|
||||||
|
LOGD("Depth format detected!");
|
||||||
|
int planeCount;
|
||||||
|
ArImage_getNumberOfPlanes(arSession_, depthImage, &planeCount);
|
||||||
|
LOGD("planeCount=%d", planeCount);
|
||||||
|
UASSERT_MSG(planeCount == 1, uFormat("Error: getNumberOfPlanes() planceCount = %d", planeCount).c_str());
|
||||||
|
const uint8_t *data = nullptr;
|
||||||
|
int len = 0;
|
||||||
|
int stride;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
ArImage_getWidth(arSession_, depthImage, &width);
|
||||||
|
ArImage_getHeight(arSession_, depthImage, &height);
|
||||||
|
ArImage_getPlaneRowStride(arSession_, depthImage, 0, &stride);
|
||||||
|
ArImage_getPlaneData(arSession_, depthImage, 0, &data, &len);
|
||||||
|
|
||||||
|
LOGD("width=%d, height=%d, bytes=%d stride=%d", width, height, len, stride);
|
||||||
|
|
||||||
|
occlusionImage_ = cv::Mat(height, width, CV_16UC1, (void*)data).clone();
|
||||||
|
|
||||||
|
float fx,fy, cx, cy;
|
||||||
|
int32_t rgb_width, rgb_height;
|
||||||
|
ArCamera_getImageIntrinsics(arSession_, ar_camera, arCameraIntrinsics_);
|
||||||
|
ArCameraIntrinsics_getFocalLength(arSession_, arCameraIntrinsics_, &fx, &fy);
|
||||||
|
ArCameraIntrinsics_getPrincipalPoint(arSession_, arCameraIntrinsics_, &cx, &cy);
|
||||||
|
ArCameraIntrinsics_getImageDimensions(arSession_, arCameraIntrinsics_, &rgb_width, &rgb_height);
|
||||||
|
|
||||||
|
float scaleX = (float)width / (float)rgb_width;
|
||||||
|
float scaleY = (float)height / (float)rgb_height;
|
||||||
|
occlusionModel_ = CameraModel(fx*scaleX, fy*scaleY, cx*scaleX, cy*scaleY, pose*deviceTColorCamera_, 0, cv::Size(width, height));
|
||||||
|
}
|
||||||
|
ArImage_release(depthImage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArCamera_release(ar_camera);
|
ArCamera_release(ar_camera);
|
||||||
|
|||||||
@@ -60,13 +60,16 @@ public:
|
|||||||
std::vector<cv::Point3f> * kpts3D = 0);
|
std::vector<cv::Point3f> * kpts3D = 0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CameraARCore(void* env, void* context, void* activity, bool smoothing = false);
|
CameraARCore(void* env, void* context, void* activity, bool depthFromMotion = false, bool smoothing = false);
|
||||||
virtual ~CameraARCore();
|
virtual ~CameraARCore();
|
||||||
|
|
||||||
bool uvsInitialized() const {return uvs_initialized_;}
|
bool uvsInitialized() const {return uvs_initialized_;}
|
||||||
const float* uvsTransformed() const {return transformed_uvs_;}
|
const float* uvsTransformed() const {return transformed_uvs_;}
|
||||||
void getVPMatrices(glm::mat4 & view, glm::mat4 & projection) const {view=viewMatrix_; projection=projectionMatrix_;}
|
void getVPMatrices(glm::mat4 & view, glm::mat4 & projection) const {view=viewMatrix_; projection=projectionMatrix_;}
|
||||||
|
|
||||||
|
void updateOcclusionImage(bool enabled) {updateOcclusionImage_ = enabled;}
|
||||||
|
const cv::Mat & getOcclusionImage(CameraModel * model=0) const {if(model)*model=occlusionModel_; return occlusionImage_; }
|
||||||
|
|
||||||
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height);
|
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height);
|
||||||
|
|
||||||
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
||||||
@@ -101,6 +104,11 @@ private:
|
|||||||
bool uvs_initialized_ = false;
|
bool uvs_initialized_ = false;
|
||||||
glm::mat4 viewMatrix_;
|
glm::mat4 viewMatrix_;
|
||||||
glm::mat4 projectionMatrix_;
|
glm::mat4 projectionMatrix_;
|
||||||
|
|
||||||
|
bool updateOcclusionImage_;
|
||||||
|
cv::Mat occlusionImage_;
|
||||||
|
CameraModel occlusionModel_;
|
||||||
|
bool depthFromMotion_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace rtabmap */
|
} /* namespace rtabmap */
|
||||||
|
|||||||
@@ -690,7 +690,7 @@ bool RTABMapApp::startCamera(JNIEnv* env, jobject iBinder, jobject context, jobj
|
|||||||
else if(cameraDriver_ == 1)
|
else if(cameraDriver_ == 1)
|
||||||
{
|
{
|
||||||
#ifdef RTABMAP_ARCORE
|
#ifdef RTABMAP_ARCORE
|
||||||
camera_ = new rtabmap::CameraARCore(env, context, activity, smoothing_);
|
camera_ = new rtabmap::CameraARCore(env, context, activity, depthFromMotion_, smoothing_);
|
||||||
#else
|
#else
|
||||||
UERROR("RTAB-Map is not built with ARCore support!");
|
UERROR("RTAB-Map is not built with ARCore support!");
|
||||||
#endif
|
#endif
|
||||||
@@ -1113,15 +1113,24 @@ int RTABMapApp::Render()
|
|||||||
const float* uvsTransformed = 0;
|
const float* uvsTransformed = 0;
|
||||||
glm::mat4 arProjectionMatrix(0);
|
glm::mat4 arProjectionMatrix(0);
|
||||||
glm::mat4 arViewMatrix(0);
|
glm::mat4 arViewMatrix(0);
|
||||||
|
rtabmap::Mesh occlusionMesh;
|
||||||
if((cameraDriver_ == 1 || cameraDriver_ == 2) && camera_!=0)
|
if((cameraDriver_ == 1 || cameraDriver_ == 2) && camera_!=0)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(cameraMutex_);
|
boost::mutex::scoped_lock lock(cameraMutex_);
|
||||||
if(camera_!=0)
|
if(camera_!=0)
|
||||||
{
|
{
|
||||||
camera_->spinOnce();
|
#ifdef RTABMAP_ARCORE
|
||||||
if(cameraDriver_ == 1)
|
if(cameraDriver_ == 1)
|
||||||
{
|
{
|
||||||
|
((rtabmap::CameraARCore*)camera_)->updateOcclusionImage(!visualizingMesh_ && main_scene_.GetCameraType() == tango_gl::GestureCamera::kFirstPerson);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
camera_->spinOnce();
|
||||||
|
|
||||||
#ifdef RTABMAP_ARCORE
|
#ifdef RTABMAP_ARCORE
|
||||||
|
if(cameraDriver_ == 1)
|
||||||
|
{
|
||||||
if(main_scene_.background_renderer_ == 0)
|
if(main_scene_.background_renderer_ == 0)
|
||||||
{
|
{
|
||||||
main_scene_.background_renderer_ = new BackgroundRenderer();
|
main_scene_.background_renderer_ = new BackgroundRenderer();
|
||||||
@@ -1131,12 +1140,31 @@ int RTABMapApp::Render()
|
|||||||
{
|
{
|
||||||
uvsTransformed = ((rtabmap::CameraARCore*)camera_)->uvsTransformed();
|
uvsTransformed = ((rtabmap::CameraARCore*)camera_)->uvsTransformed();
|
||||||
((rtabmap::CameraARCore*)camera_)->getVPMatrices(arViewMatrix, arProjectionMatrix);
|
((rtabmap::CameraARCore*)camera_)->getVPMatrices(arViewMatrix, arProjectionMatrix);
|
||||||
//main_scene_.background_renderer_->Draw(uvsTransformed);
|
}
|
||||||
|
if(!visualizingMesh_ && main_scene_.GetCameraType() == tango_gl::GestureCamera::kFirstPerson)
|
||||||
|
{
|
||||||
|
rtabmap::CameraModel occlusionModel;
|
||||||
|
cv::Mat occlusionImage = ((rtabmap::CameraARCore*)camera_)->getOcclusionImage(&occlusionModel);
|
||||||
|
|
||||||
|
if(occlusionModel.isValidForProjection())
|
||||||
|
{
|
||||||
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
|
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = rtabmap::util3d::cloudFromDepth(occlusionImage, occlusionModel, 1, 0, 0, indices.get());
|
||||||
|
cloud = rtabmap::util3d::transformPointCloud(cloud, rtabmap::opengl_world_T_rtabmap_world*occlusionModel.localTransform());
|
||||||
|
occlusionMesh.cloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>());
|
||||||
|
pcl::copyPointCloud(*cloud, *occlusionMesh.cloud);
|
||||||
|
occlusionMesh.indices = indices;
|
||||||
|
occlusionMesh.polygons = rtabmap::util3d::organizedFastMesh(cloud, 1.0*M_PI/180.0, false, meshTrianglePix_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UERROR("invalid occlusionModel: %f %f %f %f %dx%d", occlusionModel.fx(), occlusionModel.fy(), occlusionModel.cx(), occlusionModel.cy(), occlusionModel.imageWidth(), occlusionModel.imageHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// process only pose events in visualization mode
|
// process only pose events in visualization mode
|
||||||
rtabmap::Transform pose;
|
rtabmap::Transform pose;
|
||||||
@@ -1820,7 +1848,7 @@ int RTABMapApp::Render()
|
|||||||
|
|
||||||
fpsTime.restart();
|
fpsTime.restart();
|
||||||
main_scene_.setFrustumVisible(camera_!=0);
|
main_scene_.setFrustumVisible(camera_!=0);
|
||||||
lastDrawnCloudsCount_ = main_scene_.Render(uvsTransformed, arViewMatrix, arProjectionMatrix);
|
lastDrawnCloudsCount_ = main_scene_.Render(uvsTransformed, arViewMatrix, arProjectionMatrix, occlusionMesh);
|
||||||
if(renderingTime_ < fpsTime.elapsed())
|
if(renderingTime_ < fpsTime.elapsed())
|
||||||
{
|
{
|
||||||
renderingTime_ = fpsTime.elapsed();
|
renderingTime_ = fpsTime.elapsed();
|
||||||
@@ -2106,6 +2134,14 @@ void RTABMapApp::setSmoothing(bool enabled)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RTABMapApp::setDepthFromMotion(bool enabled)
|
||||||
|
{
|
||||||
|
if(depthFromMotion_ != enabled)
|
||||||
|
{
|
||||||
|
depthFromMotion_ = enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RTABMapApp::setAppendMode(bool enabled)
|
void RTABMapApp::setAppendMode(bool enabled)
|
||||||
{
|
{
|
||||||
if(appendMode_ != enabled)
|
if(appendMode_ != enabled)
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
void setCameraColor(bool enabled);
|
void setCameraColor(bool enabled);
|
||||||
void setFullResolution(bool enabled);
|
void setFullResolution(bool enabled);
|
||||||
void setSmoothing(bool enabled);
|
void setSmoothing(bool enabled);
|
||||||
|
void setDepthFromMotion(bool enabled);
|
||||||
void setAppendMode(bool enabled);
|
void setAppendMode(bool enabled);
|
||||||
void setDataRecorderMode(bool enabled);
|
void setDataRecorderMode(bool enabled);
|
||||||
void setMaxCloudDepth(float value);
|
void setMaxCloudDepth(float value);
|
||||||
@@ -183,6 +184,7 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
bool trajectoryMode_;
|
bool trajectoryMode_;
|
||||||
bool rawScanSaved_;
|
bool rawScanSaved_;
|
||||||
bool smoothing_;
|
bool smoothing_;
|
||||||
|
bool depthFromMotion_;
|
||||||
bool cameraColor_;
|
bool cameraColor_;
|
||||||
bool fullResolution_;
|
bool fullResolution_;
|
||||||
bool appendMode_;
|
bool appendMode_;
|
||||||
|
|||||||
@@ -512,6 +512,19 @@ Java_com_introlab_rtabmap_RTABMapLib_setSmoothing(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
|
Java_com_introlab_rtabmap_RTABMapLib_setDepthFromMotion(
|
||||||
|
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||||
|
{
|
||||||
|
if(native_application)
|
||||||
|
{
|
||||||
|
return native(native_application)->setDepthFromMotion(enabled);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UERROR("native_application is null!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
Java_com_introlab_rtabmap_RTABMapLib_setCameraColor(
|
Java_com_introlab_rtabmap_RTABMapLib_setCameraColor(
|
||||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ bool intersectFrustumAABB(
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Should only be called in OpenGL thread!
|
//Should only be called in OpenGL thread!
|
||||||
int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat4 arProjectionMatrix) {
|
int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat4 arProjectionMatrix, const rtabmap::Mesh & occlusionMesh) {
|
||||||
UASSERT(gesture_camera_ != 0);
|
UASSERT(gesture_camera_ != 0);
|
||||||
|
|
||||||
if(currentPose_ == 0)
|
if(currentPose_ == 0)
|
||||||
@@ -458,7 +458,7 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
|
|||||||
|
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
|
|
||||||
bool onlineBlending = blending_ && gesture_camera_->GetCameraType()!=tango_gl::GestureCamera::kTopOrtho && mapRendering_ && meshRendering_ && cloudsToDraw.size()>1;
|
bool onlineBlending = (renderBackgroundCamera && occlusionMesh.cloud.get() && occlusionMesh.cloud->size()) || (blending_ && gesture_camera_->GetCameraType()!=tango_gl::GestureCamera::kTopOrtho && mapRendering_ && meshRendering_ && cloudsToDraw.size()>1);
|
||||||
if(onlineBlending && fboId_)
|
if(onlineBlending && fboId_)
|
||||||
{
|
{
|
||||||
// set the rendering destination to FBO
|
// set the rendering destination to FBO
|
||||||
@@ -468,12 +468,20 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
|
|||||||
glClearColor(1, 1, 1, 1);
|
glClearColor(1, 1, 1, 1);
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
if(renderBackgroundCamera)
|
||||||
|
{
|
||||||
|
PointCloudDrawable drawable(occlusionMesh);
|
||||||
|
drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 999.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Draw scene
|
// Draw scene
|
||||||
for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
|
for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
|
||||||
{
|
{
|
||||||
// set large distance to cam to use low res polygons for fast processing
|
// set large distance to cam to use low res polygons for fast processing
|
||||||
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, 999.0f);
|
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, 999.0f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// back to normal window-system-provided framebuffer
|
// back to normal window-system-provided framebuffer
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind
|
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind
|
||||||
@@ -512,6 +520,10 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
|
|||||||
if(renderBackgroundCamera)
|
if(renderBackgroundCamera)
|
||||||
{
|
{
|
||||||
background_renderer_->Draw(uvsTransformed);
|
background_renderer_->Draw(uvsTransformed);
|
||||||
|
|
||||||
|
//To debug occlusion image:
|
||||||
|
//PointCloudDrawable drawable(occlusionMesh);
|
||||||
|
//drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 999.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!currentPose_->isNull())
|
if(!currentPose_->isNull())
|
||||||
|
|||||||
@@ -72,13 +72,14 @@ class Scene {
|
|||||||
// frame's timestamp.
|
// frame's timestamp.
|
||||||
// @param: point_cloud_vertices, point cloud's vertices of the current point
|
// @param: point_cloud_vertices, point cloud's vertices of the current point
|
||||||
// frame.
|
// frame.
|
||||||
int Render(const float * uvsTransformed = 0, glm::mat4 arViewMatrix = glm::mat4(0), glm::mat4 arProjectionMatrix=glm::mat4(0));
|
int Render(const float * uvsTransformed = 0, glm::mat4 arViewMatrix = glm::mat4(0), glm::mat4 arProjectionMatrix=glm::mat4(0), const rtabmap::Mesh & occlusionMesh=rtabmap::Mesh());
|
||||||
|
|
||||||
// Set render camera's viewing angle, first person, third person or top down.
|
// Set render camera's viewing angle, first person, third person or top down.
|
||||||
//
|
//
|
||||||
// @param: camera_type, camera type includes first person, third person and
|
// @param: camera_type, camera type includes first person, third person and
|
||||||
// top down
|
// top down
|
||||||
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type);
|
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type);
|
||||||
|
tango_gl::GestureCamera::CameraType GetCameraType() const {return gesture_camera_->GetCameraType();}
|
||||||
|
|
||||||
void SetCameraPose(const rtabmap::Transform & pose); // opengl camera
|
void SetCameraPose(const rtabmap::Transform & pose); // opengl camera
|
||||||
rtabmap::Transform GetCameraPose() const {return currentPose_!=0?*currentPose_:rtabmap::Transform();}
|
rtabmap::Transform GetCameraPose() const {return currentPose_!=0?*currentPose_:rtabmap::Transform();}
|
||||||
|
|||||||
@@ -98,6 +98,11 @@
|
|||||||
android:summary="@string/pref_summary_resolution"
|
android:summary="@string/pref_summary_resolution"
|
||||||
android:defaultValue="@string/pref_default_resolution"/>
|
android:defaultValue="@string/pref_default_resolution"/>
|
||||||
<com.introlab.rtabmap.CustomSwitchPreference
|
<com.introlab.rtabmap.CustomSwitchPreference
|
||||||
|
android:key="@string/pref_key_depth_from_motion"
|
||||||
|
android:title="@string/pref_title_depth_from_motion"
|
||||||
|
android:summary="@string/pref_summary_depth_from_motion"
|
||||||
|
android:defaultValue="@string/pref_default_depth_from_motion"/>
|
||||||
|
<com.introlab.rtabmap.CustomSwitchPreference
|
||||||
android:key="@string/pref_key_smoothing"
|
android:key="@string/pref_key_smoothing"
|
||||||
android:title="@string/pref_title_smoothing"
|
android:title="@string/pref_title_smoothing"
|
||||||
android:summary="@string/pref_summary_smoothing"
|
android:summary="@string/pref_summary_smoothing"
|
||||||
|
|||||||
@@ -81,6 +81,8 @@
|
|||||||
|
|
||||||
<string name="pref_key_camera_driver">pref_key_camera_driver</string>
|
<string name="pref_key_camera_driver">pref_key_camera_driver</string>
|
||||||
<string name="pref_default_camera_driver">0</string>
|
<string name="pref_default_camera_driver">0</string>
|
||||||
|
<string name="pref_key_depth_from_motion">pref_key_depth_from_motion</string>
|
||||||
|
<string name="pref_default_depth_from_motion">false</string>
|
||||||
<string name="pref_key_update_rate">pref_key_update_rate</string>
|
<string name="pref_key_update_rate">pref_key_update_rate</string>
|
||||||
<string name="pref_default_update_rate">1</string>
|
<string name="pref_default_update_rate">1</string>
|
||||||
<string name="pref_key_max_speed">pref_key_max_speed</string>
|
<string name="pref_key_max_speed">pref_key_max_speed</string>
|
||||||
@@ -323,6 +325,8 @@
|
|||||||
<string name="pref_title_mapping_database">Database</string>
|
<string name="pref_title_mapping_database">Database</string>
|
||||||
<string name="pref_title_camera_driver">Camera Driver</string>
|
<string name="pref_title_camera_driver">Camera Driver</string>
|
||||||
<string name="pref_summary_camera_driver">AR sdk use for capturing 6DoF poses and images. A TOF camera is required to record a 3D model.</string>
|
<string name="pref_summary_camera_driver">AR sdk use for capturing 6DoF poses and images. A TOF camera is required to record a 3D model.</string>
|
||||||
|
<string name="pref_title_depth_from_motion">Depth From Motion</string>
|
||||||
|
<string name="pref_summary_depth_from_motion">Use ARCore\'s depth API to compute depth image from motion. If the phone has a TOF camera and is supported by ARCore, results should be better. Currently supported only with ARCore NDK driver.</string>
|
||||||
<string name="pref_title_append">Append Mode</string>
|
<string name="pref_title_append">Append Mode</string>
|
||||||
<string name="pref_summary_append">When resuming mapping, wait for a relocalization on the current map before starting a new map.</string>
|
<string name="pref_summary_append">When resuming mapping, wait for a relocalization on the current map before starting a new map.</string>
|
||||||
<string name="pref_title_resolution">HD Mode</string>
|
<string name="pref_title_resolution">HD Mode</string>
|
||||||
|
|||||||
@@ -992,6 +992,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
|
|||||||
RTABMapLib.setRawScanSaved(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_raw_scan_saved), Boolean.parseBoolean(getString(R.string.pref_default_raw_scan_saved))));
|
RTABMapLib.setRawScanSaved(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_raw_scan_saved), Boolean.parseBoolean(getString(R.string.pref_default_raw_scan_saved))));
|
||||||
RTABMapLib.setFullResolution(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_resolution), Boolean.parseBoolean(getString(R.string.pref_default_resolution))));
|
RTABMapLib.setFullResolution(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_resolution), Boolean.parseBoolean(getString(R.string.pref_default_resolution))));
|
||||||
RTABMapLib.setSmoothing(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_smoothing), Boolean.parseBoolean(getString(R.string.pref_default_smoothing))));
|
RTABMapLib.setSmoothing(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_smoothing), Boolean.parseBoolean(getString(R.string.pref_default_smoothing))));
|
||||||
|
RTABMapLib.setDepthFromMotion(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_depth_from_motion), Boolean.parseBoolean(getString(R.string.pref_default_depth_from_motion))));
|
||||||
RTABMapLib.setCameraColor(nativeApplication, !sharedPref.getBoolean(getString(R.string.pref_key_fisheye), Boolean.parseBoolean(getString(R.string.pref_default_fisheye))));
|
RTABMapLib.setCameraColor(nativeApplication, !sharedPref.getBoolean(getString(R.string.pref_key_fisheye), Boolean.parseBoolean(getString(R.string.pref_default_fisheye))));
|
||||||
RTABMapLib.setAppendMode(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_append), Boolean.parseBoolean(getString(R.string.pref_default_append))));
|
RTABMapLib.setAppendMode(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_append), Boolean.parseBoolean(getString(R.string.pref_default_append))));
|
||||||
RTABMapLib.setMappingParameter(nativeApplication, "Rtabmap/DetectionRate", mUpdateRate);
|
RTABMapLib.setMappingParameter(nativeApplication, "Rtabmap/DetectionRate", mUpdateRate);
|
||||||
@@ -1162,6 +1163,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
|
|||||||
|
|
||||||
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
String cameraDriverStr = sharedPref.getString(getString(R.string.pref_key_camera_driver), getString(R.string.pref_default_camera_driver));
|
String cameraDriverStr = sharedPref.getString(getString(R.string.pref_key_camera_driver), getString(R.string.pref_default_camera_driver));
|
||||||
|
final boolean depthFromMotion = sharedPref.getBoolean(getString(R.string.pref_key_depth_from_motion), Boolean.parseBoolean(getString(R.string.pref_default_depth_from_motion)));
|
||||||
mCameraDriver = Integer.parseInt(cameraDriverStr);
|
mCameraDriver = Integer.parseInt(cameraDriverStr);
|
||||||
|
|
||||||
if(!DISABLE_LOG) Log.i(TAG, String.format("startCamera() driver=%d", mCameraDriver));
|
if(!DISABLE_LOG) Log.i(TAG, String.format("startCamera() driver=%d", mCameraDriver));
|
||||||
@@ -1218,7 +1220,8 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
|
|||||||
}
|
}
|
||||||
Thread bindThread = new Thread(new Runnable() {
|
Thread bindThread = new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if(mCameraDriver==1)
|
|
||||||
|
if(mCameraDriver==1 && !depthFromMotion)
|
||||||
{
|
{
|
||||||
RTABMapLib.setMeshRendering(
|
RTABMapLib.setMeshRendering(
|
||||||
nativeApplication,
|
nativeApplication,
|
||||||
@@ -1263,7 +1266,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if((mState==State.STATE_IDLE || mState==State.STATE_WELCOME) && mCameraDriver == 1)
|
if((mState==State.STATE_IDLE || mState==State.STATE_WELCOME) && mCameraDriver == 1 && !depthFromMotion)
|
||||||
{
|
{
|
||||||
mToast.makeText(getApplicationContext(), "Currently ARCore NDK driver doesn't support depth, only poses, RGB images and 3d features can be recorded.", mToast.LENGTH_LONG).show();
|
mToast.makeText(getApplicationContext(), "Currently ARCore NDK driver doesn't support depth, only poses, RGB images and 3d features can be recorded.", mToast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ public class RTABMapLib
|
|||||||
public static native void setRawScanSaved(long nativeApplication, boolean enabled);
|
public static native void setRawScanSaved(long nativeApplication, boolean enabled);
|
||||||
public static native void setFullResolution(long nativeApplication, boolean enabled);
|
public static native void setFullResolution(long nativeApplication, boolean enabled);
|
||||||
public static native void setSmoothing(long nativeApplication, boolean enabled);
|
public static native void setSmoothing(long nativeApplication, boolean enabled);
|
||||||
|
public static native void setDepthFromMotion(long nativeApplication, boolean enabled);
|
||||||
public static native void setCameraColor(long nativeApplication, boolean enabled);
|
public static native void setCameraColor(long nativeApplication, boolean enabled);
|
||||||
public static native void setAppendMode(long nativeApplication, boolean enabled);
|
public static native void setAppendMode(long nativeApplication, boolean enabled);
|
||||||
public static native void setDataRecorderMode(long nativeApplication, boolean enabled);
|
public static native void setDataRecorderMode(long nativeApplication, boolean enabled);
|
||||||
|
|||||||
Reference in New Issue
Block a user