From 5855198b5f7b866e6bef9b076c48b9e7b5716479 Mon Sep 17 00:00:00 2001 From: matlabbe Date: Mon, 24 Jul 2017 20:24:16 -0400 Subject: [PATCH] Tango: swipe down to show hud, added notification sound after saving or exporting, added polygon cluster filtering export option, action and status bars are transparent --- app/android/AndroidManifest.xml.in | 5 +- app/android/jni/RTABMapApp.cpp | 4 +- app/android/jni/RTABMapApp.h | 2 +- app/android/jni/jni_interface.cpp | 4 +- app/android/res/layout/activity_settings.xml | 13 ++ app/android/res/values/strings.xml | 22 ++- app/android/res/values/styles.xml | 10 ++ .../com/introlab/rtabmap/RTABMapActivity.java | 127 +++++++++++++----- .../src/com/introlab/rtabmap/RTABMapLib.java | 2 +- .../introlab/rtabmap/SettingsActivity.java | 4 +- 10 files changed, 146 insertions(+), 47 deletions(-) create mode 100644 app/android/res/values/styles.xml diff --git a/app/android/AndroidManifest.xml.in b/app/android/AndroidManifest.xml.in index db297899..b5296ca9 100644 --- a/app/android/AndroidManifest.xml.in +++ b/app/android/AndroidManifest.xml.in @@ -2,7 +2,7 @@ @@ -31,7 +31,8 @@ android:label="@string/app_name" android:launchMode="singleTask" android:screenOrientation="fullSensor" - android:configChanges="orientation|screenSize|keyboardHidden"> + android:configChanges="orientation|screenSize|keyboardHidden" + android:theme="@style/ThemeApp"> diff --git a/app/android/jni/RTABMapApp.cpp b/app/android/jni/RTABMapApp.cpp index 0844e1b7..1de180bc 100644 --- a/app/android/jni/RTABMapApp.cpp +++ b/app/android/jni/RTABMapApp.cpp @@ -2051,7 +2051,7 @@ bool RTABMapApp::exportMesh( int optimizedMaxPolygons, float optimizedColorRadius, bool optimizedCleanWhitePolygons, - bool optimizedColorWhitePolygons, // not yet used + int optimizedMinClusterSize, float optimizedMaxTextureDistance, int optimizedMinTextureClusterSize, bool blockRendering) @@ -2341,7 +2341,7 @@ bool RTABMapApp::exportMesh( optimizedColorRadius, textureSize == 0, optimizedCleanWhitePolygons, - 0); + optimizedMinClusterSize); if(textureSize>0) { diff --git a/app/android/jni/RTABMapApp.h b/app/android/jni/RTABMapApp.h index 3d462217..4c511eab 100644 --- a/app/android/jni/RTABMapApp.h +++ b/app/android/jni/RTABMapApp.h @@ -164,7 +164,7 @@ class RTABMapApp : public UEventsHandler { int optimizedMaxPolygons, float optimizedColorRadius, bool optimizedCleanWhitePolygons, - bool optimizedColorWhitePolygons, + int optimizedMinClusterSize, float optimizedMaxTextureDistance, int optimizedMinTextureClusterSize, bool blockRendering); diff --git a/app/android/jni/jni_interface.cpp b/app/android/jni/jni_interface.cpp index fecf5cbf..6ba10fe6 100644 --- a/app/android/jni/jni_interface.cpp +++ b/app/android/jni/jni_interface.cpp @@ -377,7 +377,7 @@ Java_com_introlab_rtabmap_RTABMapLib_exportMesh( int optimizedMaxPolygons, float optimizedColorRadius, bool optimizedCleanWhitePolygons, - bool optimizedColorWhitePolygons, + int optimizedMinClusterSize, float optimizedMaxTextureDistance, int optimizedMinTextureClusterSize, bool blockRendering) @@ -395,7 +395,7 @@ Java_com_introlab_rtabmap_RTABMapLib_exportMesh( optimizedMaxPolygons, optimizedColorRadius, optimizedCleanWhitePolygons, - optimizedColorWhitePolygons, + optimizedMinClusterSize, optimizedMaxTextureDistance, optimizedMinTextureClusterSize, blockRendering); diff --git a/app/android/res/layout/activity_settings.xml b/app/android/res/layout/activity_settings.xml index a8554229..923c68cf 100644 --- a/app/android/res/layout/activity_settings.xml +++ b/app/android/res/layout/activity_settings.xml @@ -292,6 +292,14 @@ android:summary="@string/pref_summary_opt_clean_white" android:defaultValue="@string/pref_default_opt_clean_white"/> + + + diff --git a/app/android/res/values/strings.xml b/app/android/res/values/strings.xml index ba8432ec..1aeb4f88 100644 --- a/app/android/res/values/strings.xml +++ b/app/android/res/values/strings.xml @@ -124,10 +124,14 @@ 0.05 pref_key_opt_clean_white true + pref_key_opt_min_cluster_size + 0 pref_key_gain_max_radius 0.02 pref_key_cluster_ratio 0.05 + pref_key_notification_sound + true Rendering @@ -657,22 +661,22 @@ "2" - "Disabled" "1000" "500" "200" "100" "50" "10" + "Disabled" - "0" "1000" "500" "200" "100" "50" "10" + "0" Optimized @@ -684,7 +688,9 @@ Radius used to transfer nearest color from the point cloud to reconstructed mesh. When exporting with texture, if Clean Mesh is also enabled, this will limit the number of polygons textured in holes. Clean Mesh Clean mesh from textureless or colorless reconstructed polygons. - + This can be used to filter polygons before texturing. + Polygon Filtering + "Auto" "12" @@ -733,12 +739,22 @@ "0.01" "-1" + + "Only biggest cluster kept" + "Keep all polygons" + + + "-1" + "0" + General Color Correction Radius Radius used to find pixel correspondences for Adjust Colors optimization. Noise Filtering Ratio Polygon clusters with size smaller than this ratio of the largest cluster are removed by the Noise Filtering optimization. + Notification Sound + After saving database or preparing data to export, a notification sound is played. "0.3 m" diff --git a/app/android/res/values/styles.xml b/app/android/res/values/styles.xml new file mode 100644 index 00000000..b1849901 --- /dev/null +++ b/app/android/res/values/styles.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/android/src/com/introlab/rtabmap/RTABMapActivity.java b/app/android/src/com/introlab/rtabmap/RTABMapActivity.java index 385e3097..c71d2765 100644 --- a/app/android/src/com/introlab/rtabmap/RTABMapActivity.java +++ b/app/android/src/com/introlab/rtabmap/RTABMapActivity.java @@ -257,6 +257,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem display.getSize(mScreenSize); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // Setting content view of this activity. setContentView(R.layout.activity_rtabmap); @@ -367,7 +368,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem @Override public boolean onTouch(View v, MotionEvent event) { - resetNoTouchTimer(); + resetNoTouchTimer(getActionBar().isShowing() && mHudVisible == false); mGesDetect.onTouchEvent(event); @@ -728,7 +729,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem } TangoInitializationHelper.bindTangoService(getActivity(), mTangoServiceConnection); - resetNoTouchTimer(); + resetNoTouchTimer(true); } private void setCamera(int type) @@ -822,11 +823,31 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem @Override public boolean onDoubleTap(MotionEvent event) { + if(!DISABLE_LOG) Log.i(TAG, "onDoubleTap"); float normalizedX = event.getX(0) / mScreenSize.x; float normalizedY = event.getY(0) / mScreenSize.y; RTABMapLib.onTouchEvent(3, event.getActionMasked(), normalizedX, normalizedY, 0.0f, 0.0f); return true; } + @Override + public boolean onFling( + MotionEvent e1, + MotionEvent e2, + float velocityX, + float velocityY) { + if(!DISABLE_LOG) Log.i(TAG, String.format("onFling velocityY=%f", velocityY)); + if(velocityY < -1000) + { + notouchHandler.removeCallbacks(notouchCallback); + notouchHandler.postDelayed(notouchCallback, 0); + } + else if(velocityY > 1000) + { + resetNoTouchTimer(true); + } + + return true; + } } @Override @@ -1364,14 +1385,20 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem }; public void resetNoTouchTimer(){ - if(!mHudVisible) + resetNoTouchTimer(false); + } + + public void resetNoTouchTimer(boolean showHud){ + if(showHud) { - setNavVisibility(true); mHudVisible = true; - updateState(mState); + setNavVisibility(true); + if(mItemSave != null) + { + updateState(mState); + } } - mHudVisible = true; - + notouchHandler.removeCallbacks(notouchCallback); notouchHandler.postDelayed(notouchCallback, NOTOUCH_TIMEOUT); } @@ -1387,6 +1414,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem mToast.makeText(getActivity(), String.format("Re-adding %d online clouds, this may take some time...", mMapNodes), mToast.LENGTH_LONG).show(); } mState = state; + if(!DISABLE_LOG) Log.i(TAG, String.format("updateState() state=%s hud=%d", state.toString(), mHudVisible?1:0)); switch(state) { case STATE_PROCESSING: @@ -1744,6 +1772,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); + resetNoTouchTimer(true); } }) .show(); @@ -2010,7 +2039,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem final int optimizedDepth = Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_opt_depth), getString(R.string.pref_default_opt_depth))); final float optimizedColorRadius = Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_opt_color_radius), getString(R.string.pref_default_opt_color_radius))); final boolean optimizedCleanWhitePolygons = sharedPref.getBoolean(getString(R.string.pref_key_opt_clean_white), Boolean.parseBoolean(getString(R.string.pref_default_opt_clean_white))); - final boolean optimizedColorWhitePolygons = false;//sharedPref.getBoolean("pref_key_opt_color_white", false); // not used + final int optimizedMinClusterSize = Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_opt_min_cluster_size), getString(R.string.pref_default_opt_min_cluster_size))); final boolean blockRendering = sharedPref.getBoolean(getString(R.string.pref_key_block_render), Boolean.parseBoolean(getString(R.string.pref_default_block_render))); @@ -2041,22 +2070,41 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem optimizedMaxPolygons, optimizedColorRadius, optimizedCleanWhitePolygons, - optimizedColorWhitePolygons, + optimizedMinClusterSize, maxTextureDistance, minTextureClusterSize, blockRendering); runOnUiThread(new Runnable() { public void run() { if(mExportProgressDialog.isShowing()) - { + { if(success) - { + { if(!meshing && cloudVoxelSize>0.0f) { mToast.makeText(getActivity(), String.format("Cloud assembled and voxelized at %s m.", cloudVoxelSizeStr), mToast.LENGTH_LONG).show(); } final long endTime = System.currentTimeMillis()/1000; + + if(endTime-startTime > 10) + { + // build notification + // the addAction re-use the same intent to keep the example short + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity()); + boolean notifySound = sharedPref.getBoolean(getString(R.string.pref_key_notification_sound), Boolean.parseBoolean(getString(R.string.pref_default_notification_sound))); + Notification n = new Notification.Builder(getActivity()) + .setContentTitle(getString(R.string.app_name)) + .setContentText("Data generated and ready to be exported!") + .setSmallIcon(R.drawable.ic_launcher) + .setDefaults(notifySound?Notification.DEFAULT_SOUND:0) + .setAutoCancel(true).build(); + + NotificationManager notificationManager = + (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + + notificationManager.notify(0, n); + } // Visualize the result? AlertDialog d = new AlertDialog.Builder(getActivity()) @@ -2065,7 +2113,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem .setMessage(Html.fromHtml("Do you want visualize the result before saving to file or sharing to Sketchfab?")) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { - resetNoTouchTimer(); + resetNoTouchTimer(true); mSavedRenderingType = mItemRenderingPointCloud.isChecked()?0:mItemRenderingMesh.isChecked()?1:2; if(!meshing) { @@ -2113,6 +2161,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem }) .setNeutralButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + resetNoTouchTimer(true); } }) .create(); @@ -2166,33 +2215,38 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem RTABMapLib.save(newDatabasePath); // save runOnUiThread(new Runnable() { public void run() { + String msg; if(mOpenedDatabasePath.equals(newDatabasePath)) { - mToast.makeText(getActivity(), String.format("Database \"%s\" updated.", newDatabasePathHuman), mToast.LENGTH_LONG).show(); + msg = String.format("Database \"%s\" updated.", newDatabasePathHuman); } else { - mToast.makeText(getActivity(), String.format("Database saved to \"%s\".", newDatabasePathHuman), mToast.LENGTH_LONG).show(); - - Intent intent = new Intent(getActivity(), RTABMapActivity.class); - // use System.currentTimeMillis() to have a unique ID for the pending intent - PendingIntent pIntent = PendingIntent.getActivity(getActivity(), (int) System.currentTimeMillis(), intent, 0); - - // build notification - // the addAction re-use the same intent to keep the example short - Notification n = new Notification.Builder(getActivity()) - .setContentTitle(getString(R.string.app_name)) - .setContentText(newDatabasePathHuman + " saved!") - .setSmallIcon(R.drawable.ic_launcher) - .setContentIntent(pIntent) - .setAutoCancel(true).build(); - - - NotificationManager notificationManager = - (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - - notificationManager.notify(0, n); + msg = String.format("Database saved to \"%s\".", newDatabasePathHuman); } + + mToast.makeText(getActivity(), msg, mToast.LENGTH_LONG).show(); + + // build notification + Intent intent = new Intent(getActivity(), RTABMapActivity.class); + // use System.currentTimeMillis() to have a unique ID for the pending intent + PendingIntent pIntent = PendingIntent.getActivity(getActivity(), (int) System.currentTimeMillis(), intent, 0); + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity()); + boolean notifySound = sharedPref.getBoolean(getString(R.string.pref_key_notification_sound), Boolean.parseBoolean(getString(R.string.pref_default_notification_sound))); + Notification n = new Notification.Builder(getActivity()) + .setContentTitle(getString(R.string.app_name)) + .setContentText(msg) + .setSmallIcon(R.drawable.ic_launcher) + .setContentIntent(pIntent) + .setDefaults(notifySound?Notification.DEFAULT_SOUND:0) + .setAutoCancel(true).build(); + + NotificationManager notificationManager = + (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + + notificationManager.notify(0, n); + + resetNoTouchTimer(true); if(!mItemDataRecorderMode.isChecked()) { mOpenedDatabasePath = newDatabasePath; @@ -2233,6 +2287,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); + resetNoTouchTimer(true); } }); builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @@ -2357,11 +2412,12 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem .setContentIntent(pIntent) .setAutoCancel(true).build(); - NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); notificationManager.notify(0, n); + + resetNoTouchTimer(true); } }); } @@ -2371,6 +2427,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem public void run() { mProgressDialog.dismiss(); mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! No files found in tmp directory!? Last export may have failed or have been canceled.", pathHuman), mToast.LENGTH_LONG).show(); + resetNoTouchTimer(true); } }); } @@ -2453,7 +2510,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem if(status >= 1 && status<=3) { mProgressDialog.dismiss(); - resetNoTouchTimer(); + resetNoTouchTimer(true); updateState(State.STATE_VISUALIZING); mToast.makeText(getActivity(), String.format("Database loaded!"), mToast.LENGTH_LONG).show(); } diff --git a/app/android/src/com/introlab/rtabmap/RTABMapLib.java b/app/android/src/com/introlab/rtabmap/RTABMapLib.java index b0889893..a52b225d 100644 --- a/app/android/src/com/introlab/rtabmap/RTABMapLib.java +++ b/app/android/src/com/introlab/rtabmap/RTABMapLib.java @@ -109,7 +109,7 @@ public class RTABMapLib int optimizedMaxPolygons, float optimizedColorRadius, boolean optimizedCleanWhitePolygons, - boolean optimizedColorWhitePolygons, + int optimizedMinClusterSize, float optimizedMaxTextureDistance, int optimizedMinTextureClusterSize, boolean blockRendering); diff --git a/app/android/src/com/introlab/rtabmap/SettingsActivity.java b/app/android/src/com/introlab/rtabmap/SettingsActivity.java index 3e425f7f..c15a72c0 100644 --- a/app/android/src/com/introlab/rtabmap/SettingsActivity.java +++ b/app/android/src/com/introlab/rtabmap/SettingsActivity.java @@ -215,7 +215,8 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref ((Preference)findPreference(getString(R.string.pref_key_opt_depth))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_depth))).getEntry() + ") "+getString(R.string.pref_summary_opt_depth)); ((Preference)findPreference(getString(R.string.pref_key_opt_color_radius))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_color_radius))).getEntry() + ") "+getString(R.string.pref_summary_opt_color_radius)); - + ((Preference)findPreference(getString(R.string.pref_key_opt_min_cluster_size))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_min_cluster_size))).getEntry() + ") "+getString(R.string.pref_summary_opt_min_cluster_size)); + ((Preference)findPreference(getString(R.string.pref_key_cluster_ratio))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_cluster_ratio))).getEntry() + ") "+getString(R.string.pref_summary_cluster_ratio)); ((Preference)findPreference(getString(R.string.pref_key_gain_max_radius))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_gain_max_radius))).getEntry() + ") "+getString(R.string.pref_summary_gain_max_radius)); } @@ -272,6 +273,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref if(key.compareTo(getString(R.string.pref_key_opt_depth))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_depth)); if(key.compareTo(getString(R.string.pref_key_opt_color_radius))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_color_radius)); + if(key.compareTo(getString(R.string.pref_key_opt_min_cluster_size))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_min_cluster_size)); if(key.compareTo(getString(R.string.pref_key_cluster_ratio))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_cluster_ratio)); if(key.compareTo(getString(R.string.pref_key_gain_max_radius))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_gain_max_radius));