mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Tango: Added Settings/Optimized Mesh/Sketchfab Upload
This commit is contained in:
1
app/android/.gitignore
vendored
Normal file
1
app/android/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/bin/
|
||||
@@ -2,7 +2,7 @@
|
||||
<!-- BEGIN_INCLUDE(manifest) -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.introlab.rtabmap"
|
||||
android:versionCode="30"
|
||||
android:versionCode="31"
|
||||
android:versionName="@RTABMAP_VERSION@">
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
@@ -10,10 +10,12 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
|
||||
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
|
||||
<!-- This is the platform API where NativeActivity was introduced. -->
|
||||
<uses-sdk android:minSdkVersion="17" />
|
||||
<uses-sdk android:minSdkVersion="19" />
|
||||
|
||||
<!-- This .apk has no Java code itself, so set hasCode to false. -->
|
||||
<application
|
||||
@@ -36,6 +38,8 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="SettingsActivity" android:label="@string/settings"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -32,6 +32,11 @@ configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/ant.properties.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/ant.properties"
|
||||
@ONLY)
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/custom_rules.xml"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/custom_rules.xml"
|
||||
COPYONLY)
|
||||
|
||||
add_custom_target(NativeRTABMap-ant-configure ALL
|
||||
COMMAND "${ANDROID_EXECUTABLE}"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
builddir=@CMAKE_CURRENT_BINARY_DIR@
|
||||
srcdir=@CMAKE_CURRENT_SOURCE_DIR@
|
||||
android.abi=@ANDROID_ABI@
|
||||
|
||||
source.dir=${srcdir}/src
|
||||
gen.dir=${builddir}/gen
|
||||
|
||||
10
app/android/custom_rules.xml
Normal file
10
app/android/custom_rules.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<project>
|
||||
<target name="-pre-build">
|
||||
<copy todir="${jar.libs.dir}">
|
||||
<fileset dir="${srcdir}/libs" includes="**/*.jar" excludes="**/*sources.jar, **/*javadoc.jar" />
|
||||
</copy>
|
||||
<copy todir="${native.libs.dir}/${android.abi}">
|
||||
<fileset dir="${srcdir}/libs-c" includes="**/*.so"/>
|
||||
</copy>
|
||||
</target>
|
||||
</project>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <rtabmap/utilite/UEventsHandler.h>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <pcl/pcl_base.h>
|
||||
#include <pcl/TextureMesh.h>
|
||||
|
||||
// RTABMapApp handles the application lifecycle and resources.
|
||||
class RTABMapApp : public UEventsHandler {
|
||||
@@ -113,6 +114,8 @@ class RTABMapApp : public UEventsHandler {
|
||||
void setMapCloudShown(bool shown);
|
||||
void setOdomCloudShown(bool shown);
|
||||
void setMeshRendering(bool enabled, bool withTexture);
|
||||
void setPointSize(float value);
|
||||
void setLighting(bool enabled);
|
||||
void setLocalizationMode(bool enabled);
|
||||
void setTrajectoryMode(bool enabled);
|
||||
void setGraphOptimization(bool enabled);
|
||||
@@ -132,7 +135,22 @@ class RTABMapApp : public UEventsHandler {
|
||||
|
||||
void resetMapping();
|
||||
void save(const std::string & databasePath);
|
||||
bool exportMesh(const std::string & filePath);
|
||||
cv::Mat mergeTextures(pcl::TextureMesh & mesh, int textureSize) const;
|
||||
bool exportMesh(
|
||||
const std::string & filePath,
|
||||
float cloudVoxelSize,
|
||||
bool meshing,
|
||||
int textureSize,
|
||||
int normalK,
|
||||
bool optimized,
|
||||
float optimizedVoxelSize,
|
||||
int optimizedDepth,
|
||||
float optimizedDecimationFactor,
|
||||
float optimizedColorRadius,
|
||||
bool optimizedCleanWhitePolygons,
|
||||
bool optimizedColorWhitePolygons,
|
||||
bool blockRendering);
|
||||
bool postExportation(bool visualize);
|
||||
int postProcessing(int approach);
|
||||
|
||||
protected:
|
||||
@@ -176,6 +194,11 @@ class RTABMapApp : public UEventsHandler {
|
||||
int lastDrawnCloudsCount_;
|
||||
float renderingTime_;
|
||||
|
||||
bool visualizingMesh_;
|
||||
bool exportedMeshUpdated_;
|
||||
pcl::TextureMesh::Ptr exportedMesh_;
|
||||
cv::Mat exportedTexture_;
|
||||
|
||||
// main_scene_ includes all drawable object for visualizing Tango device's
|
||||
// movement and point cloud.
|
||||
Scene main_scene_;
|
||||
|
||||
@@ -145,6 +145,18 @@ Java_com_introlab_rtabmap_RTABMapLib_setMeshRendering(
|
||||
return app.setMeshRendering(enabled, withTexture);
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setPointSize(
|
||||
JNIEnv*, jobject, float value)
|
||||
{
|
||||
return app.setPointSize(value);
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setLighting(
|
||||
JNIEnv*, jobject, bool enabled)
|
||||
{
|
||||
return app.setLighting(enabled);
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setLocalizationMode(
|
||||
JNIEnv*, jobject, bool enabled)
|
||||
{
|
||||
@@ -262,11 +274,44 @@ Java_com_introlab_rtabmap_RTABMapLib_save(
|
||||
|
||||
JNIEXPORT bool JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_exportMesh(
|
||||
JNIEnv* env, jobject, jstring filePath)
|
||||
JNIEnv* env, jobject,
|
||||
jstring filePath,
|
||||
float cloudVoxelSize,
|
||||
bool meshing,
|
||||
int textureSize,
|
||||
int normalK,
|
||||
bool optimized,
|
||||
float optimizedVoxelSize,
|
||||
int optimizedDepth,
|
||||
float optimizedDecimationFactor,
|
||||
float optimizedColorRadius,
|
||||
bool optimizedCleanWhitePolygons,
|
||||
bool optimizedColorWhitePolygons,
|
||||
bool blockRendering)
|
||||
{
|
||||
std::string filePathC;
|
||||
GetJStringContent(env,filePath,filePathC);
|
||||
return app.exportMesh(filePathC);
|
||||
return app.exportMesh(
|
||||
filePathC,
|
||||
cloudVoxelSize,
|
||||
meshing,
|
||||
textureSize,
|
||||
normalK,
|
||||
optimized,
|
||||
optimizedVoxelSize,
|
||||
optimizedDepth,
|
||||
optimizedDecimationFactor,
|
||||
optimizedColorRadius,
|
||||
optimizedCleanWhitePolygons,
|
||||
optimizedColorWhitePolygons,
|
||||
blockRendering);
|
||||
}
|
||||
|
||||
JNIEXPORT bool JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_postExportation(
|
||||
JNIEnv* env, jobject, bool visualize)
|
||||
{
|
||||
return app.postExportation(visualize);
|
||||
}
|
||||
|
||||
JNIEXPORT int JNICALL
|
||||
|
||||
@@ -46,6 +46,7 @@ PointCloudDrawable::PointCloudDrawable(
|
||||
nPoints_(0),
|
||||
pose_(1.0f),
|
||||
visible_(true),
|
||||
hasNormals_(false),
|
||||
cloud_shader_program_(cloudShaderProgram),
|
||||
texture_shader_program_(textureShaderProgram),
|
||||
gain_(1.0f)
|
||||
@@ -63,6 +64,7 @@ PointCloudDrawable::PointCloudDrawable(
|
||||
nPoints_(0),
|
||||
pose_(1.0f),
|
||||
visible_(true),
|
||||
hasNormals_(false),
|
||||
cloud_shader_program_(cloudShaderProgram),
|
||||
texture_shader_program_(textureShaderProgram),
|
||||
gain_(1.0f)
|
||||
@@ -90,19 +92,20 @@ PointCloudDrawable::~PointCloudDrawable()
|
||||
|
||||
void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polygons)
|
||||
{
|
||||
LOGD("Update polygons");
|
||||
polygons_.clear();
|
||||
if(polygons.size() && organizedToDenseIndices_.size())
|
||||
{
|
||||
int polygonSize = polygons[0].vertices.size();
|
||||
unsigned int polygonSize = polygons[0].vertices.size();
|
||||
UASSERT(polygonSize == 3);
|
||||
polygons_.resize(polygons.size() * polygonSize);
|
||||
int oi = 0;
|
||||
for(unsigned int i=0; i<polygons.size(); ++i)
|
||||
{
|
||||
UASSERT((int)polygons[i].vertices.size() == polygonSize);
|
||||
for(int j=0; j<polygonSize; ++j)
|
||||
UASSERT(polygons[i].vertices.size() == polygonSize);
|
||||
for(unsigned int j=0; j<polygonSize; ++j)
|
||||
{
|
||||
polygons_[oi++] = organizedToDenseIndices_.at((unsigned short)polygons[i].vertices[j]);
|
||||
polygons_[oi++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +113,7 @@ void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polyg
|
||||
|
||||
void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::IndicesPtr & indices, float gain)
|
||||
{
|
||||
UASSERT(cloud.get() && !cloud->empty() && indices.get() && !indices->empty());
|
||||
UASSERT(cloud.get() && !cloud->empty());
|
||||
nPoints_ = 0;
|
||||
polygons_.clear();
|
||||
gain_ = gain;
|
||||
@@ -137,13 +140,31 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
|
||||
}
|
||||
|
||||
LOGI("Creating cloud buffer %d", vertex_buffers_);
|
||||
std::vector<float> vertices(indices->size()*4);
|
||||
for(unsigned int i=0; i<indices->size(); ++i)
|
||||
std::vector<float> vertices;
|
||||
int totalPoints = 0;
|
||||
if(indices.get() && indices->size())
|
||||
{
|
||||
vertices[i*4] = cloud->at(indices->at(i)).x;
|
||||
vertices[i*4+1] = cloud->at(indices->at(i)).y;
|
||||
vertices[i*4+2] = cloud->at(indices->at(i)).z;
|
||||
vertices[i*4+3] = cloud->at(indices->at(i)).rgb;
|
||||
totalPoints = indices->size();
|
||||
vertices.resize(indices->size()*4);
|
||||
for(unsigned int i=0; i<indices->size(); ++i)
|
||||
{
|
||||
vertices[i*4] = cloud->at(indices->at(i)).x;
|
||||
vertices[i*4+1] = cloud->at(indices->at(i)).y;
|
||||
vertices[i*4+2] = cloud->at(indices->at(i)).z;
|
||||
vertices[i*4+3] = cloud->at(indices->at(i)).rgb;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
totalPoints = cloud->size();
|
||||
vertices.resize(cloud->size()*4);
|
||||
for(unsigned int i=0; i<cloud->size(); ++i)
|
||||
{
|
||||
vertices[i*4] = cloud->at(i).x;
|
||||
vertices[i*4+1] = cloud->at(i).y;
|
||||
vertices[i*4+2] = cloud->at(i).z;
|
||||
vertices[i*4+3] = cloud->at(i).rgb;
|
||||
}
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
|
||||
@@ -158,12 +179,12 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
|
||||
return;
|
||||
}
|
||||
|
||||
nPoints_ = indices->size();
|
||||
nPoints_ = totalPoints;
|
||||
}
|
||||
|
||||
void PointCloudDrawable::updateMesh(const Mesh & mesh, const cv::Mat & texture)
|
||||
{
|
||||
UASSERT(mesh.cloud.get() && !mesh.cloud->empty() && mesh.indices.get() && !mesh.indices->empty());
|
||||
UASSERT(mesh.cloud.get() && !mesh.cloud->empty());
|
||||
nPoints_ = 0;
|
||||
|
||||
if (vertex_buffers_)
|
||||
@@ -196,7 +217,6 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, const cv::Mat & texture)
|
||||
|
||||
if(textureUpdate)
|
||||
{
|
||||
UASSERT(!mesh.cloud->is_dense);
|
||||
glGenTextures(1, &textures_);
|
||||
if(!textures_)
|
||||
{
|
||||
@@ -206,39 +226,155 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, const cv::Mat & texture)
|
||||
}
|
||||
}
|
||||
|
||||
LOGI("Creating cloud buffer %d", vertex_buffers_);
|
||||
LOGD("Creating cloud buffer %d", vertex_buffers_);
|
||||
std::vector<float> vertices;
|
||||
organizedToDenseIndices_ = std::vector<int>(mesh.cloud->width*mesh.cloud->height, -1);
|
||||
if(textures_)
|
||||
int totalPoints = 0;
|
||||
std::vector<pcl::Vertices> polygons = mesh.polygons;
|
||||
hasNormals_ = mesh.normals.get() && mesh.normals->size() == mesh.cloud->size();
|
||||
UASSERT(!hasNormals_ || mesh.cloud->size() == mesh.normals->size());
|
||||
if(mesh.cloud->isOrganized()) // assume organized mesh
|
||||
{
|
||||
vertices = std::vector<float>(mesh.indices->size()*6);
|
||||
for(unsigned int i=0; i<mesh.indices->size(); ++i)
|
||||
organizedToDenseIndices_ = std::vector<unsigned int>(mesh.cloud->width*mesh.cloud->height, -1);
|
||||
totalPoints = mesh.indices->size();
|
||||
if(textures_ && polygons.size())
|
||||
{
|
||||
vertices[i*6] = mesh.cloud->at(mesh.indices->at(i)).x;
|
||||
vertices[i*6+1] = mesh.cloud->at(mesh.indices->at(i)).y;
|
||||
vertices[i*6+2] = mesh.cloud->at(mesh.indices->at(i)).z;
|
||||
LOGD("Organized mesh with texture");
|
||||
int items = hasNormals_?9:6;
|
||||
vertices = std::vector<float>(mesh.indices->size()*9);
|
||||
for(unsigned int i=0; i<mesh.indices->size(); ++i)
|
||||
{
|
||||
vertices[i*items] = mesh.cloud->at(mesh.indices->at(i)).x;
|
||||
vertices[i*items+1] = mesh.cloud->at(mesh.indices->at(i)).y;
|
||||
vertices[i*items+2] = mesh.cloud->at(mesh.indices->at(i)).z;
|
||||
|
||||
// rgb
|
||||
vertices[i*6+3] = mesh.cloud->at(mesh.indices->at(i)).rgb;
|
||||
// rgb
|
||||
vertices[i*items+3] = mesh.cloud->at(mesh.indices->at(i)).rgb;
|
||||
|
||||
// texture uv
|
||||
int index = mesh.indices->at(i);
|
||||
vertices[i*6+4] = float(index % mesh.cloud->width)/float(mesh.cloud->width); //u
|
||||
vertices[i*6+5] = float(index / mesh.cloud->width)/float(mesh.cloud->height); //v
|
||||
// texture uv
|
||||
int index = mesh.indices->at(i);
|
||||
vertices[i*items+4] = float(index % mesh.cloud->width)/float(mesh.cloud->width); //u
|
||||
vertices[i*items+5] = float(index / mesh.cloud->width)/float(mesh.cloud->height); //v
|
||||
|
||||
organizedToDenseIndices_[mesh.indices->at(i)] = i;
|
||||
if(hasNormals_)
|
||||
{
|
||||
// normal
|
||||
vertices[i*items+6] = mesh.normals->at(mesh.indices->at(i)).normal_x;
|
||||
vertices[i*items+7] = mesh.normals->at(mesh.indices->at(i)).normal_y;
|
||||
vertices[i*items+8] = mesh.normals->at(mesh.indices->at(i)).normal_z;
|
||||
}
|
||||
|
||||
organizedToDenseIndices_[mesh.indices->at(i)] = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGD("Organized mesh");
|
||||
int items = hasNormals_?7:4;
|
||||
vertices = std::vector<float>(mesh.indices->size()*items);
|
||||
for(unsigned int i=0; i<mesh.indices->size(); ++i)
|
||||
{
|
||||
vertices[i*items] = mesh.cloud->at(mesh.indices->at(i)).x;
|
||||
vertices[i*items+1] = mesh.cloud->at(mesh.indices->at(i)).y;
|
||||
vertices[i*items+2] = mesh.cloud->at(mesh.indices->at(i)).z;
|
||||
vertices[i*items+3] = mesh.cloud->at(mesh.indices->at(i)).rgb;
|
||||
|
||||
if(hasNormals_)
|
||||
{
|
||||
// normal
|
||||
vertices[i*items+4] = mesh.normals->at(mesh.indices->at(i)).normal_x;
|
||||
vertices[i*items+5] = mesh.normals->at(mesh.indices->at(i)).normal_y;
|
||||
vertices[i*items+6] = mesh.normals->at(mesh.indices->at(i)).normal_z;
|
||||
}
|
||||
|
||||
organizedToDenseIndices_[mesh.indices->at(i)] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else // assume dense mesh with texCoords set to polygons
|
||||
{
|
||||
vertices = std::vector<float>(mesh.indices->size()*4);
|
||||
for(unsigned int i=0; i<mesh.indices->size(); ++i)
|
||||
totalPoints = mesh.cloud->size();
|
||||
if(textures_ && polygons.size() && mesh.normals->size())
|
||||
{
|
||||
vertices[i*4] = mesh.cloud->at(mesh.indices->at(i)).x;
|
||||
vertices[i*4+1] = mesh.cloud->at(mesh.indices->at(i)).y;
|
||||
vertices[i*4+2] = mesh.cloud->at(mesh.indices->at(i)).z;
|
||||
vertices[i*4+3] = mesh.cloud->at(mesh.indices->at(i)).rgb;
|
||||
organizedToDenseIndices_[mesh.indices->at(i)] = i;
|
||||
LOGD("Dense mesh with texture (%d texCoords %d points %d polygons %dx%d)",
|
||||
(int)mesh.texCoords.size(), (int)mesh.cloud->size(), (int)mesh.polygons.size(), texture.cols, texture.rows);
|
||||
|
||||
// Texturing issue:
|
||||
// tex_coordinates should be linked to points, not
|
||||
// polygon vertices. Points linked to multiple different texCoords (different textures) should
|
||||
// be duplicated.
|
||||
vertices = std::vector<float>(mesh.texCoords.size()*9);
|
||||
organizedToDenseIndices_ = std::vector<unsigned int>(mesh.texCoords.size(), -1);
|
||||
|
||||
UASSERT_MSG(mesh.texCoords.size() == polygons[0].vertices.size()*polygons.size(),
|
||||
uFormat("%d vs %d x %d", (int)mesh.texCoords.size(), (int)polygons[0].vertices.size(), (int)polygons.size()).c_str());
|
||||
|
||||
int items = hasNormals_?9:6;
|
||||
unsigned int oi=0;
|
||||
for(unsigned int i=0; i<polygons.size(); ++i)
|
||||
{
|
||||
pcl::Vertices & v = polygons[i];
|
||||
for(unsigned int j=0; j<v.vertices.size(); ++j)
|
||||
{
|
||||
UASSERT(oi < mesh.texCoords.size());
|
||||
UASSERT(v.vertices[j] < mesh.cloud->size());
|
||||
|
||||
vertices[oi*items] = mesh.cloud->at(v.vertices[j]).x;
|
||||
vertices[oi*items+1] = mesh.cloud->at(v.vertices[j]).y;
|
||||
vertices[oi*items+2] = mesh.cloud->at(v.vertices[j]).z;
|
||||
|
||||
// rgb
|
||||
vertices[oi*items+3] = mesh.cloud->at(v.vertices[j]).rgb;
|
||||
|
||||
// texture uv
|
||||
if(mesh.texCoords[oi][0]>=0.0f)
|
||||
{
|
||||
vertices[oi*items+4] = mesh.texCoords[oi][0]; //u
|
||||
vertices[oi*items+5] = 1.0f-mesh.texCoords[oi][1]; //v
|
||||
}
|
||||
else
|
||||
{
|
||||
vertices[oi*items+4] = vertices[oi*items+5] = -1.0f;
|
||||
}
|
||||
|
||||
if(hasNormals_)
|
||||
{
|
||||
// normal
|
||||
vertices[oi*items+6] = mesh.normals->at(v.vertices[j]).normal_x;
|
||||
vertices[oi*items+7] = mesh.normals->at(v.vertices[j]).normal_y;
|
||||
vertices[oi*items+8] = mesh.normals->at(v.vertices[j]).normal_z;
|
||||
}
|
||||
|
||||
v.vertices[j] = (int)oi; // new vertex index
|
||||
|
||||
UASSERT(oi < organizedToDenseIndices_.size());
|
||||
organizedToDenseIndices_[oi] = oi;
|
||||
|
||||
++oi;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGD("Dense mesh");
|
||||
int items = hasNormals_?7:4;
|
||||
organizedToDenseIndices_ = std::vector<unsigned int>(mesh.cloud->size(), -1);
|
||||
vertices = std::vector<float>(mesh.cloud->size()*items);
|
||||
for(unsigned int i=0; i<mesh.cloud->size(); ++i)
|
||||
{
|
||||
vertices[i*items] = mesh.cloud->at(i).x;
|
||||
vertices[i*items+1] = mesh.cloud->at(i).y;
|
||||
vertices[i*items+2] = mesh.cloud->at(i).z;
|
||||
vertices[i*items+3] = mesh.cloud->at(i).rgb;
|
||||
|
||||
if(hasNormals_)
|
||||
{
|
||||
vertices[i*items+4] = mesh.normals->at(i).normal_x;
|
||||
vertices[i*items+5] = mesh.normals->at(i).normal_y;
|
||||
vertices[i*items+6] = mesh.normals->at(i).normal_z;
|
||||
}
|
||||
|
||||
organizedToDenseIndices_[i] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +392,10 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, const cv::Mat & texture)
|
||||
|
||||
if(textures_ && textureUpdate)
|
||||
{
|
||||
GLint maxTextureSize = 0;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
LOGI("maxTextureSize=%d", maxTextureSize);
|
||||
|
||||
// gen texture from image
|
||||
glBindTexture(GL_TEXTURE_2D, textures_);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
@@ -276,11 +416,11 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, const cv::Mat & texture)
|
||||
}
|
||||
}
|
||||
|
||||
nPoints_ = mesh.indices->size();
|
||||
nPoints_ = totalPoints;
|
||||
|
||||
if(polygons_.size() != mesh.polygons.size())
|
||||
if(polygons_.size() != polygons.size())
|
||||
{
|
||||
updatePolygons(mesh.polygons);
|
||||
updatePolygons(polygons);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +431,12 @@ void PointCloudDrawable::setPose(const rtabmap::Transform & pose)
|
||||
pose_ = glmFromTransform(pose);
|
||||
}
|
||||
|
||||
void PointCloudDrawable::Render(const glm::mat4 & projectionMatrix, const glm::mat4 & viewMatrix, bool meshRendering, float pointSize, bool textureRendering) {
|
||||
void PointCloudDrawable::Render(const glm::mat4 & projectionMatrix,
|
||||
const glm::mat4 & viewMatrix,
|
||||
bool meshRendering,
|
||||
float pointSize,
|
||||
bool textureRendering,
|
||||
bool lighting) {
|
||||
|
||||
if(vertex_buffers_ && nPoints_ && visible_)
|
||||
{
|
||||
@@ -299,65 +444,144 @@ void PointCloudDrawable::Render(const glm::mat4 & projectionMatrix, const glm::m
|
||||
{
|
||||
glUseProgram(texture_shader_program_);
|
||||
|
||||
GLuint mvp_handle_ = glGetUniformLocation(texture_shader_program_, "mvp");
|
||||
glm::mat4 mvp_mat = projectionMatrix * viewMatrix * pose_;
|
||||
glUniformMatrix4fv(mvp_handle_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
GLuint mvp_handle = glGetUniformLocation(texture_shader_program_, "uMVP");
|
||||
glm::mat4 mv_mat = viewMatrix * pose_;
|
||||
glm::mat4 mvp_mat = projectionMatrix * mv_mat;
|
||||
glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
|
||||
GLuint n_handle = glGetUniformLocation(texture_shader_program_, "uN");
|
||||
glm::mat3 normalMatrix(mv_mat);
|
||||
normalMatrix = glm::inverse(normalMatrix);
|
||||
normalMatrix = glm::transpose(normalMatrix);
|
||||
glUniformMatrix3fv(n_handle, 1, GL_FALSE, glm::value_ptr(normalMatrix));
|
||||
|
||||
if(!hasNormals_)
|
||||
{
|
||||
lighting = false;
|
||||
}
|
||||
|
||||
//lighting
|
||||
GLuint lighting_handle = glGetUniformLocation(texture_shader_program_, "uUseLighting");
|
||||
glUniform1i(lighting_handle, lighting?1:0);
|
||||
|
||||
if(lighting)
|
||||
{
|
||||
GLuint ambiant_handle = glGetUniformLocation(texture_shader_program_, "uAmbientColor");
|
||||
glUniform3f(ambiant_handle,0.6,0.6,0.6);
|
||||
|
||||
GLuint lightingDirection_handle = glGetUniformLocation(texture_shader_program_, "uLightingDirection");
|
||||
glUniform3f(lightingDirection_handle, 0.0, 0.0, 1.0); // from the camera
|
||||
}
|
||||
|
||||
// Texture activate unit 0
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
// Bind the texture to this unit.
|
||||
glBindTexture(GL_TEXTURE_2D, textures_);
|
||||
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
|
||||
GLuint texture_handle = glGetUniformLocation(texture_shader_program_, "u_Texture");
|
||||
GLuint texture_handle = glGetUniformLocation(texture_shader_program_, "uTexture");
|
||||
glUniform1i(texture_handle, 0);
|
||||
|
||||
GLuint gain_handle = glGetUniformLocation(texture_shader_program_, "u_gain");
|
||||
GLuint gain_handle = glGetUniformLocation(texture_shader_program_, "uGain");
|
||||
glUniform1f(gain_handle, gain_);
|
||||
|
||||
GLint attribute_vertex = glGetAttribLocation(texture_shader_program_, "vertex");
|
||||
GLint attribute_texture = glGetAttribLocation(texture_shader_program_, "a_TexCoordinate");
|
||||
GLint attribute_vertex = glGetAttribLocation(texture_shader_program_, "aVertex");
|
||||
GLint attribute_texture = glGetAttribLocation(texture_shader_program_, "aTexCoord");
|
||||
GLint attribute_normal=0;
|
||||
if(hasNormals_)
|
||||
{
|
||||
attribute_normal = glGetAttribLocation(texture_shader_program_, "aNormal");
|
||||
}
|
||||
|
||||
glEnableVertexAttribArray(attribute_vertex);
|
||||
glEnableVertexAttribArray(attribute_texture);
|
||||
if(hasNormals_)
|
||||
{
|
||||
glEnableVertexAttribArray(attribute_normal);
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
|
||||
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), 0);
|
||||
glVertexAttribPointer(attribute_texture, 2, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (GLvoid*) (4 * sizeof(GLfloat)));
|
||||
|
||||
glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_SHORT, polygons_.data());
|
||||
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, (hasNormals_?9:6)*sizeof(GLfloat), 0);
|
||||
glVertexAttribPointer(attribute_texture, 2, GL_FLOAT, GL_FALSE, (hasNormals_?9:6)*sizeof(GLfloat), (GLvoid*) (4 * sizeof(GLfloat)));
|
||||
if(hasNormals_)
|
||||
{
|
||||
glVertexAttribPointer(attribute_normal, 3, GL_FLOAT, GL_FALSE, 9*sizeof(GLfloat), (GLvoid*) (6 * sizeof(GLfloat)));
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_INT, polygons_.data());
|
||||
}
|
||||
else // point cloud or colored mesh
|
||||
{
|
||||
glUseProgram(cloud_shader_program_);
|
||||
|
||||
GLuint mvp_handle_ = glGetUniformLocation(cloud_shader_program_, "mvp");
|
||||
glm::mat4 mvp_mat = projectionMatrix * viewMatrix * pose_;
|
||||
GLuint mvp_handle_ = glGetUniformLocation(cloud_shader_program_, "uMVP");
|
||||
glm::mat4 mv_mat = viewMatrix * pose_;
|
||||
glm::mat4 mvp_mat = projectionMatrix * mv_mat;
|
||||
glUniformMatrix4fv(mvp_handle_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
|
||||
GLuint point_size_handle_ = glGetUniformLocation(cloud_shader_program_, "point_size");
|
||||
GLuint n_handle = glGetUniformLocation(texture_shader_program_, "uN");
|
||||
glm::mat3 normalMatrix(mv_mat);
|
||||
normalMatrix = glm::inverse(normalMatrix);
|
||||
normalMatrix = glm::transpose(normalMatrix);
|
||||
glUniformMatrix3fv(n_handle, 1, GL_FALSE, glm::value_ptr(normalMatrix));
|
||||
|
||||
if(!hasNormals_)
|
||||
{
|
||||
lighting = false;
|
||||
}
|
||||
|
||||
//lighting
|
||||
GLuint lighting_handle = glGetUniformLocation(texture_shader_program_, "uUseLighting");
|
||||
glUniform1i(lighting_handle, lighting?1:0);
|
||||
|
||||
if(lighting)
|
||||
{
|
||||
GLuint ambiant_handle = glGetUniformLocation(texture_shader_program_, "uAmbientColor");
|
||||
glUniform3f(ambiant_handle,0.6,0.6,0.6);
|
||||
|
||||
GLuint lightingDirection_handle = glGetUniformLocation(texture_shader_program_, "uLightingDirection");
|
||||
glUniform3f(lightingDirection_handle, 0.0, 0.0, 1.0); // from the camera
|
||||
}
|
||||
|
||||
GLuint point_size_handle_ = glGetUniformLocation(cloud_shader_program_, "uPointSize");
|
||||
glUniform1f(point_size_handle_, pointSize);
|
||||
|
||||
GLuint gain_handle = glGetUniformLocation(cloud_shader_program_, "u_gain");
|
||||
GLuint gain_handle = glGetUniformLocation(cloud_shader_program_, "uGain");
|
||||
glUniform1f(gain_handle, gain_);
|
||||
|
||||
GLint attribute_vertex = glGetAttribLocation(cloud_shader_program_, "vertex");
|
||||
GLint attribute_color = glGetAttribLocation(cloud_shader_program_, "color");
|
||||
GLint attribute_vertex = glGetAttribLocation(cloud_shader_program_, "aVertex");
|
||||
GLint attribute_color = glGetAttribLocation(cloud_shader_program_, "aColor");
|
||||
GLint attribute_normal=0;
|
||||
if(hasNormals_)
|
||||
{
|
||||
attribute_normal = glGetAttribLocation(cloud_shader_program_, "aNormal");
|
||||
}
|
||||
|
||||
glEnableVertexAttribArray(attribute_vertex);
|
||||
glEnableVertexAttribArray(attribute_color);
|
||||
if(hasNormals_)
|
||||
{
|
||||
glEnableVertexAttribArray(attribute_normal);
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
|
||||
if(textures_)
|
||||
{
|
||||
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), 0);
|
||||
glVertexAttribPointer(attribute_color, 3, GL_UNSIGNED_BYTE, GL_TRUE, 6*sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
|
||||
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, (hasNormals_?9:6)*sizeof(GLfloat), 0);
|
||||
glVertexAttribPointer(attribute_color, 3, GL_UNSIGNED_BYTE, GL_TRUE, (hasNormals_?9:6)*sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
|
||||
if(hasNormals_)
|
||||
{
|
||||
glVertexAttribPointer(attribute_normal, 3, GL_FLOAT, GL_FALSE, 9*sizeof(GLfloat), (GLvoid*) (6 * sizeof(GLfloat)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0);
|
||||
glVertexAttribPointer(attribute_color, 3, GL_UNSIGNED_BYTE, GL_TRUE, 4*sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
|
||||
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, (hasNormals_?7:4)*sizeof(GLfloat), 0);
|
||||
glVertexAttribPointer(attribute_color, 3, GL_UNSIGNED_BYTE, GL_TRUE, (hasNormals_?7:4)*sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
|
||||
if(hasNormals_)
|
||||
{
|
||||
glVertexAttribPointer(attribute_normal, 3, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), (GLvoid*) (4 * sizeof(GLfloat)));
|
||||
}
|
||||
}
|
||||
if(meshRendering && polygons_.size())
|
||||
{
|
||||
glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_SHORT, polygons_.data());
|
||||
glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_INT, polygons_.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -61,6 +61,7 @@ class PointCloudDrawable {
|
||||
void setVisible(bool visible) {visible_=visible;}
|
||||
rtabmap::Transform getPose() const {return glmToTransform(pose_);}
|
||||
bool isVisible() const {return visible_;}
|
||||
bool hasMesh() const {return polygons_.size()!=0;}
|
||||
bool hasTexture() const {return textures_ != 0;}
|
||||
|
||||
// Update current point cloud data.
|
||||
@@ -69,17 +70,23 @@ class PointCloudDrawable {
|
||||
// @param view_mat: view matrix from current render camera.
|
||||
// @param model_mat: model matrix for this point cloud frame.
|
||||
// @param vertices: all vertices in this point cloud frame.
|
||||
void Render(const glm::mat4 & projectionMatrix, const glm::mat4 & viewMatrix, bool meshRendering = true, float pointSize = 3.0f, bool textureRendering = false);
|
||||
void Render(const glm::mat4 & projectionMatrix,
|
||||
const glm::mat4 & viewMatrix,
|
||||
bool meshRendering = true,
|
||||
float pointSize = 3.0f,
|
||||
bool textureRendering = false,
|
||||
bool lighting = true);
|
||||
|
||||
private:
|
||||
// Vertex buffer of the point cloud geometry.
|
||||
GLuint vertex_buffers_;
|
||||
GLuint textures_;
|
||||
std::vector<GLushort> polygons_;
|
||||
std::vector<GLuint> polygons_;
|
||||
int nPoints_;
|
||||
glm::mat4 pose_;
|
||||
bool visible_;
|
||||
std::vector<int> organizedToDenseIndices_;
|
||||
bool hasNormals_;
|
||||
std::vector<unsigned int> organizedToDenseIndices_;
|
||||
|
||||
GLuint cloud_shader_program_;
|
||||
GLuint texture_shader_program_;
|
||||
|
||||
@@ -42,47 +42,87 @@ const glm::vec3 kFrustumScale = glm::vec3(0.4f, 0.3f, 0.5f);
|
||||
const std::string kPointCloudVertexShader =
|
||||
"precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"attribute vec3 vertex;\n"
|
||||
"attribute vec3 color;\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"uniform float point_size;\n"
|
||||
"varying vec3 v_color;\n"
|
||||
"attribute vec3 aVertex;\n"
|
||||
"attribute vec3 aNormal;\n"
|
||||
"attribute vec3 aColor;\n"
|
||||
|
||||
"uniform mat4 uMVP;\n"
|
||||
"uniform mat3 uN;\n"
|
||||
"uniform vec3 uAmbientColor;\n"
|
||||
"uniform vec3 uLightingDirection;\n"
|
||||
"uniform bool uUseLighting;\n"
|
||||
|
||||
"uniform float uPointSize;\n"
|
||||
"varying vec3 vColor;\n"
|
||||
"varying float vLightWeighting;\n"
|
||||
|
||||
"void main() {\n"
|
||||
" gl_Position = mvp*vec4(vertex.x, vertex.y, vertex.z, 1.0);\n"
|
||||
" gl_PointSize = point_size;\n"
|
||||
" v_color = color;\n"
|
||||
" gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n"
|
||||
" gl_PointSize = uPointSize;\n"
|
||||
" if (!uUseLighting) {\n"
|
||||
" vLightWeighting = vec3(1.0, 1.0, 1.0);\n"
|
||||
" } else {\n"
|
||||
" vec3 transformedNormal = uN * aNormal;\n"
|
||||
" vLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);\n"
|
||||
" if(vLightWeighting<0.1) vLightWeighting=0.1;\n"
|
||||
" }\n"
|
||||
" vColor = aColor;\n"
|
||||
"}\n";
|
||||
const std::string kPointCloudFragmentShader =
|
||||
"precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"uniform float u_gain;\n"
|
||||
"varying vec3 v_color;\n"
|
||||
"uniform float uGain;\n"
|
||||
"varying vec3 vColor;\n"
|
||||
"varying float vLightWeighting;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = vec4(v_color.z*u_gain, v_color.y*u_gain, v_color.x*u_gain, 1.0);\n"
|
||||
" vec4 textureColor = vec4(vColor.z*uGain, vColor.y*uGain, vColor.x*uGain, 1.0);\n"
|
||||
" gl_FragColor = vec4(textureColor.rgb * uGain * vLightWeighting, textureColor.a);\n"
|
||||
"}\n";
|
||||
|
||||
const std::string kTextureMeshVertexShader =
|
||||
"precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"attribute vec3 vertex;\n"
|
||||
"attribute vec2 a_TexCoordinate;\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"varying vec2 v_TexCoordinate;\n"
|
||||
"attribute vec3 aVertex;\n"
|
||||
"attribute vec3 aNormal;\n"
|
||||
"attribute vec2 aTexCoord;\n"
|
||||
|
||||
"uniform mat4 uMVP;\n"
|
||||
"uniform mat3 uN;\n"
|
||||
"uniform vec3 uAmbientColor;\n"
|
||||
"uniform vec3 uLightingDirection;\n"
|
||||
"uniform bool uUseLighting;\n"
|
||||
|
||||
"varying vec2 vTexCoord;\n"
|
||||
"varying float vLightWeighting;\n"
|
||||
|
||||
"void main() {\n"
|
||||
" gl_Position = mvp*vec4(vertex.x, vertex.y, vertex.z, 1.0);\n"
|
||||
" v_TexCoordinate = a_TexCoordinate;\n"
|
||||
" gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n"
|
||||
|
||||
" if(aTexCoord.x < 0.0) {\n"
|
||||
" vTexCoord.x = 1.0;\n"
|
||||
" vTexCoord.y = 1.0;\n" // bottom right corner
|
||||
" } else {\n"
|
||||
" vTexCoord = aTexCoord;\n"
|
||||
" }\n"
|
||||
|
||||
" if (!uUseLighting) {\n"
|
||||
" vLightWeighting = vec3(1.0, 1.0, 1.0);\n"
|
||||
" } else {\n"
|
||||
" vec3 transformedNormal = uN * aNormal;\n"
|
||||
" vLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);\n"
|
||||
" if(vLightWeighting<0.1) vLightWeighting=0.1;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
const std::string kTextureMeshFragmentShader =
|
||||
"precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"uniform sampler2D u_Texture;\n"
|
||||
"uniform float u_gain;\n"
|
||||
"varying vec2 v_TexCoordinate;\n"
|
||||
"uniform sampler2D uTexture;\n"
|
||||
"uniform float uGain;\n"
|
||||
"varying vec2 vTexCoord;\n"
|
||||
"varying float vLightWeighting;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = texture2D(u_Texture, v_TexCoordinate);\n"
|
||||
" gl_FragColor.x *= u_gain;\n"
|
||||
" gl_FragColor.y *= u_gain;\n"
|
||||
" gl_FragColor.z *= u_gain;\n"
|
||||
" vec4 textureColor = texture2D(uTexture, vTexCoord);\n"
|
||||
" gl_FragColor = vec4(textureColor.rgb * uGain * vLightWeighting, textureColor.a);\n"
|
||||
"}\n";
|
||||
|
||||
const std::string kGraphVertexShader =
|
||||
@@ -123,21 +163,31 @@ Scene::Scene() :
|
||||
mapRendering_(true),
|
||||
meshRendering_(true),
|
||||
meshRenderingTexture_(true),
|
||||
pointSize_(3.0f) {}
|
||||
pointSize_(5.0f),
|
||||
frustumCulling_(true),
|
||||
lighting_(true)
|
||||
{
|
||||
gesture_camera_ = new tango_gl::GestureCamera();
|
||||
gesture_camera_->SetCameraType(
|
||||
tango_gl::GestureCamera::kFirstPerson);
|
||||
}
|
||||
|
||||
Scene::~Scene() {DeleteResources();}
|
||||
Scene::~Scene() {
|
||||
DeleteResources();
|
||||
delete gesture_camera_;
|
||||
}
|
||||
|
||||
//Should only be called in OpenGL thread!
|
||||
void Scene::InitGLContent()
|
||||
{
|
||||
if(gesture_camera_ != 0)
|
||||
if(axis_ != 0)
|
||||
{
|
||||
DeleteResources();
|
||||
}
|
||||
|
||||
UASSERT(gesture_camera_ == 0);
|
||||
UASSERT(axis_ == 0);
|
||||
|
||||
|
||||
gesture_camera_ = new tango_gl::GestureCamera();
|
||||
axis_ = new tango_gl::Axis();
|
||||
frustum_ = new tango_gl::Frustum();
|
||||
trace_ = new tango_gl::Trace();
|
||||
@@ -151,8 +201,6 @@ void Scene::InitGLContent()
|
||||
trace_->SetColor(kTraceColor);
|
||||
grid_->SetColor(kGridColor);
|
||||
grid_->SetPosition(-kHeightOffset);
|
||||
gesture_camera_->SetCameraType(
|
||||
tango_gl::GestureCamera::kFirstPerson);
|
||||
|
||||
if(cloud_shader_program_ == 0)
|
||||
{
|
||||
@@ -175,15 +223,14 @@ void Scene::InitGLContent()
|
||||
void Scene::DeleteResources() {
|
||||
|
||||
LOGI("Scene::DeleteResources()");
|
||||
if(gesture_camera_)
|
||||
if(axis_)
|
||||
{
|
||||
delete gesture_camera_;
|
||||
delete axis_;
|
||||
axis_ = 0;
|
||||
delete frustum_;
|
||||
delete trace_;
|
||||
delete grid_;
|
||||
delete currentPose_;
|
||||
gesture_camera_ = 0;
|
||||
}
|
||||
|
||||
if (cloud_shader_program_) {
|
||||
@@ -288,9 +335,8 @@ int Scene::Render() {
|
||||
gesture_camera_->GetViewMatrix());
|
||||
}
|
||||
|
||||
bool frustumCulling = true;
|
||||
int cloudDrawn=0;
|
||||
if(mapRendering_ && frustumCulling)
|
||||
if(mapRendering_ && frustumCulling_)
|
||||
{
|
||||
//Use camera frustum to cull nodes that don't need to be drawn
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
@@ -336,7 +382,7 @@ int Scene::Render() {
|
||||
for(unsigned int i=0; i<indices->size(); ++i)
|
||||
{
|
||||
++cloudDrawn;
|
||||
pointClouds_.find(ids[indices->at(i)])->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_);
|
||||
pointClouds_.find(ids[indices->at(i)])->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_, lighting_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,7 +393,7 @@ int Scene::Render() {
|
||||
if((mapRendering_ || iter->first < 0) && iter->second->isVisible())
|
||||
{
|
||||
++cloudDrawn;
|
||||
iter->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_);
|
||||
iter->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_, lighting_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,7 +472,7 @@ void Scene::addCloud(
|
||||
const pcl::IndicesPtr & indices,
|
||||
const rtabmap::Transform & pose)
|
||||
{
|
||||
LOGI("add cloud %d", id);
|
||||
LOGI("add cloud %d (%d points %d indices)", id, (int)cloud->size(), indices.get()?(int)indices->size():0);
|
||||
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
|
||||
if(iter != pointClouds_.end())
|
||||
{
|
||||
@@ -496,6 +542,11 @@ bool Scene::hasCloud(int id) const
|
||||
return pointClouds_.find(id) != pointClouds_.end();
|
||||
}
|
||||
|
||||
bool Scene::hasMesh(int id) const
|
||||
{
|
||||
return pointClouds_.find(id) != pointClouds_.end() && pointClouds_.at(id)->hasMesh();
|
||||
}
|
||||
|
||||
bool Scene::hasTexture(int id) const
|
||||
{
|
||||
return pointClouds_.find(id) != pointClouds_.end() && pointClouds_.at(id)->hasTexture();
|
||||
|
||||
@@ -111,6 +111,7 @@ class Scene {
|
||||
void setCloudPose(int id, const rtabmap::Transform & pose);
|
||||
void setCloudVisible(int id, bool visible);
|
||||
bool hasCloud(int id) const;
|
||||
bool hasMesh(int id) const;
|
||||
bool hasTexture(int id) const;
|
||||
std::set<int> getAddedClouds() const;
|
||||
void updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons);
|
||||
@@ -119,9 +120,14 @@ class Scene {
|
||||
void setMapRendering(bool enabled) {mapRendering_ = enabled;}
|
||||
void setMeshRendering(bool enabled, bool withTexture) {meshRendering_ = enabled; meshRenderingTexture_ = withTexture;}
|
||||
void setPointSize(float size) {pointSize_ = size;}
|
||||
void setFrustumCulling(bool enabled) {frustumCulling_ = enabled;}
|
||||
void setLighting(bool enabled) {lighting_ = enabled;}
|
||||
|
||||
bool isMeshRendering() const {return meshRendering_;}
|
||||
bool isMeshTexturing() const {return meshRendering_ && meshRenderingTexture_;}
|
||||
float getPointSize() const {return pointSize_;}
|
||||
bool isFrustumCulling() const {return frustumCulling_;}
|
||||
bool isLighting() const {return lighting_;}
|
||||
|
||||
private:
|
||||
// Camera object that allows user to use touch input to interact with.
|
||||
@@ -156,6 +162,8 @@ class Scene {
|
||||
bool meshRendering_;
|
||||
bool meshRenderingTexture_;
|
||||
float pointSize_;
|
||||
bool frustumCulling_;
|
||||
bool lighting_;
|
||||
};
|
||||
|
||||
#endif // TANGO_POINT_CLOUD_SCENE_H_
|
||||
|
||||
@@ -143,15 +143,26 @@ inline rtabmap::Transform glmToTransform(const glm::mat4 & mat)
|
||||
return transform;
|
||||
}
|
||||
|
||||
struct Mesh
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
Mesh() :
|
||||
cloud(new pcl::PointCloud<pcl::PointXYZRGB>),
|
||||
normals(new pcl::PointCloud<pcl::Normal>),
|
||||
indices(new std::vector<int>),
|
||||
visible(true),
|
||||
gain(1.0f)
|
||||
{}
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud; // organized cloud
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals;
|
||||
pcl::IndicesPtr indices;
|
||||
std::vector<pcl::Vertices> polygons;
|
||||
rtabmap::Transform pose; // in rtabmap coordinates
|
||||
bool visible;
|
||||
rtabmap::CameraModel cameraModel;
|
||||
float gain;
|
||||
std::vector<Eigen::Vector2f> texCoords;
|
||||
};
|
||||
|
||||
#endif /* UTIL_H_ */
|
||||
|
||||
BIN
app/android/libs/TangoSDK_Caporales_Java.jar
Normal file
BIN
app/android/libs/TangoSDK_Caporales_Java.jar
Normal file
Binary file not shown.
BIN
app/android/libs/android-support-v4.jar
Normal file
BIN
app/android/libs/android-support-v4.jar
Normal file
Binary file not shown.
@@ -22,13 +22,13 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_gravity="top" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/debug_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="5dp" >
|
||||
|
||||
@@ -203,6 +203,7 @@
|
||||
android:id="@+id/inliers"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
@@ -237,7 +238,20 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
<ToggleButton
|
||||
android:id="@+id/light_button"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/first_person_button"
|
||||
android:layout_alignLeft="@+id/first_person_button"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:textOff="@string/light_off"
|
||||
android:textOn="@string/light_on" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/first_person_button"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -247,19 +261,10 @@
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:text="@string/first_person" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/top_down_button"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:text="@string/top_down" />
|
||||
|
||||
<Button
|
||||
android:textOff="@string/first_person"
|
||||
android:textOn="@string/first_person" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/third_person_button"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -268,6 +273,29 @@
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:text="@string/third_person" />
|
||||
android:textOff="@string/third_person"
|
||||
android:textOn="@string/third_person" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/top_down_button"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:paddingRight="5dp"
|
||||
android:textOff="@string/top_down"
|
||||
android:textOn="@string/top_down" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/pause_button"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/first_person_button"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginTop="61dp"
|
||||
android:paddingRight="5dp"
|
||||
android:textOff="@string/pause"
|
||||
android:textOn="@string/resume" />
|
||||
|
||||
</RelativeLayout>
|
||||
195
app/android/res/layout/activity_settings.xml
Normal file
195
app/android/res/layout/activity_settings.xml
Normal file
@@ -0,0 +1,195 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_title_rendering">
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_decimation"
|
||||
android:title="@string/pref_title_decimation"
|
||||
android:summary="@string/pref_summary_decimation"
|
||||
android:entries="@array/pref_decimation_keys"
|
||||
android:entryValues="@array/pref_decimation_values"
|
||||
android:defaultValue="@string/pref_default_decimation"/>
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_depth"
|
||||
android:title="@string/pref_title_depth"
|
||||
android:summary="@string/pref_summary_depth"
|
||||
android:entries="@array/pref_depth_keys"
|
||||
android:entryValues="@array/pref_depth_values"
|
||||
android:defaultValue="@string/pref_default_depth"/>
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_point_size"
|
||||
android:title="@string/pref_title_point_size"
|
||||
android:summary="@string/pref_summary_point_size"
|
||||
android:entries="@array/pref_point_size_values"
|
||||
android:entryValues="@array/pref_point_size_values"
|
||||
android:defaultValue="@string/pref_default_point_size"/>
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_angle"
|
||||
android:title="@string/pref_title_angle"
|
||||
android:summary="@string/pref_summary_angle"
|
||||
android:entries="@array/pref_angle_keys"
|
||||
android:entryValues="@array/pref_angle_values"
|
||||
android:defaultValue="@string/pref_default_angle"/>
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_triangle"
|
||||
android:title="@string/pref_title_triangle"
|
||||
android:summary="@string/pref_summary_triangle"
|
||||
android:entries="@array/pref_triangle_keys"
|
||||
android:entryValues="@array/pref_triangle_values"
|
||||
android:defaultValue="@string/pref_default_triangle"/>
|
||||
<SwitchPreference
|
||||
android:key="@string/pref_key_nodes_filtering"
|
||||
android:title="@string/pref_title_nodes_filtering"
|
||||
android:summary="@string/pref_summary_nodes_filtering"
|
||||
android:defaultValue="@string/pref_default_nodes_filtering"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_title_mapping">
|
||||
<PreferenceScreen
|
||||
android:key="pref_button_mapping"
|
||||
android:title="@string/pref_title_mapping"
|
||||
android:summary="@string/pref_summary_mapping"
|
||||
android:persistent="false">
|
||||
|
||||
<SwitchPreference
|
||||
android:key="@string/pref_key_append"
|
||||
android:title="@string/pref_title_append"
|
||||
android:summary="@string/pref_summary_append"
|
||||
android:defaultValue="@string/pref_default_append"/>
|
||||
<SwitchPreference
|
||||
android:key="@string/pref_key_drift_correction"
|
||||
android:title="@string/pref_title_drift_correction"
|
||||
android:summary="@string/pref_summary_drift_correction"
|
||||
android:defaultValue="@string/pref_default_drift_correction"/>
|
||||
<SwitchPreference
|
||||
android:key="@string/pref_key_auto_exposure"
|
||||
android:title="@string/pref_title_auto_exposure"
|
||||
android:summary="@string/pref_summary_auto_exposure"
|
||||
android:defaultValue="@string/pref_default_auto_exposure"/>
|
||||
<SwitchPreference
|
||||
android:key="@string/pref_key_resolution"
|
||||
android:title="@string/pref_title_resolution"
|
||||
android:summary="@string/pref_summary_resolution"
|
||||
android:defaultValue="@string/pref_default_resolution"/>
|
||||
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_update_rate"
|
||||
android:title="@string/pref_title_update_rate"
|
||||
android:summary="@string/pref_summary_update_rate"
|
||||
android:entries="@array/pref_update_rate_keys"
|
||||
android:entryValues="@array/pref_update_rate_values"
|
||||
android:defaultValue="@string/pref_default_update_rate"/>
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_time_thr"
|
||||
android:title="@string/pref_title_time_thr"
|
||||
android:summary="@string/pref_summary_time_thr"
|
||||
android:entries="@array/pref_time_thr_keys"
|
||||
android:entryValues="@array/pref_time_thr_values"
|
||||
android:defaultValue="@string/pref_default_time_thr"/>
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_loop_thr"
|
||||
android:title="@string/pref_title_loop_thr"
|
||||
android:summary="@string/pref_summary_loop_thr"
|
||||
android:entries="@array/pref_loop_thr_keys"
|
||||
android:entryValues="@array/pref_loop_thr_values"
|
||||
android:defaultValue="@string/pref_default_loop_thr"/>
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_opt_error"
|
||||
android:title="@string/pref_title_opt_error"
|
||||
android:summary="@string/pref_summary_opt_error"
|
||||
android:entries="@array/pref_opt_error_keys"
|
||||
android:entryValues="@array/pref_opt_error_values"
|
||||
android:defaultValue="@string/pref_default_opt_error"/>
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_features"
|
||||
android:title="@string/pref_title_features"
|
||||
android:summary="@string/pref_summary_features"
|
||||
android:entries="@array/pref_features_keys"
|
||||
android:entryValues="@array/pref_features_values"
|
||||
android:defaultValue="@string/pref_default_features"/>
|
||||
</PreferenceScreen>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_title_export">
|
||||
<PreferenceScreen
|
||||
android:key="pref_button_export"
|
||||
android:title="@string/pref_title_export"
|
||||
android:summary="@string/pref_summary_export"
|
||||
android:persistent="false">
|
||||
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_cloud_voxel"
|
||||
android:title="@string/pref_title_cloud_voxel"
|
||||
android:summary="@string/pref_summary_cloud_voxel"
|
||||
android:entries="@array/pref_cloud_voxel_keys"
|
||||
android:entryValues="@array/pref_cloud_voxel_values"
|
||||
android:defaultValue="@string/pref_default_cloud_voxel"/>
|
||||
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_texture_size"
|
||||
android:title="@string/pref_title_texture_size"
|
||||
android:summary="@string/pref_summary_texture_size"
|
||||
android:entries="@array/pref_texture_size_keys"
|
||||
android:entryValues="@array/pref_texture_size_values"
|
||||
android:defaultValue="@string/pref_default_texture_size"/>
|
||||
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_normal_k"
|
||||
android:title="@string/pref_title_normal_k"
|
||||
android:summary="@string/pref_summary_normal_k"
|
||||
android:entries="@array/pref_normal_k_values"
|
||||
android:entryValues="@array/pref_normal_k_values"
|
||||
android:defaultValue="@string/pref_default_normal_k"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="@string/pref_key_block_render"
|
||||
android:title="@string/pref_title_block_render"
|
||||
android:summary="@string/pref_summary_block_render"
|
||||
android:defaultValue="@string/pref_default_block_render"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_title_optimized">
|
||||
|
||||
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_opt_depth"
|
||||
android:title="@string/pref_title_opt_depth"
|
||||
android:summary="@string/pref_summary_opt_depth"
|
||||
android:entries="@array/pref_opt_depth_values"
|
||||
android:entryValues="@array/pref_opt_depth_values"
|
||||
android:defaultValue="@string/pref_default_opt_depth"/>
|
||||
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_opt_decimation_factor"
|
||||
android:title="@string/pref_title_opt_decimation_factor"
|
||||
android:summary="@string/pref_summary_opt_decimation_factor"
|
||||
android:entries="@array/pref_opt_decimation_factor_keys"
|
||||
android:entryValues="@array/pref_opt_decimation_factor_values"
|
||||
android:defaultValue="@string/pref_default_opt_decimation_factor"/>
|
||||
|
||||
<ListPreference
|
||||
android:key="@string/pref_key_opt_color_radius"
|
||||
android:title="@string/pref_title_opt_color_radius"
|
||||
android:summary="@string/pref_summary_opt_color_radius"
|
||||
android:entries="@array/pref_opt_color_radius_keys"
|
||||
android:entryValues="@array/pref_opt_color_radius_values"
|
||||
android:defaultValue="@string/pref_default_opt_color_radius"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="@string/pref_key_opt_clean_white"
|
||||
android:title="@string/pref_title_opt_clean_white"
|
||||
android:summary="@string/pref_summary_opt_clean_white"
|
||||
android:defaultValue="@string/pref_default_opt_clean_white"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_title_general">
|
||||
<Preference android:title="@string/pref_title_reset_button"
|
||||
android:key="@string/pref_key_reset_button"/>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
11
app/android/res/layout/auth_dialog.xml
Normal file
11
app/android/res/layout/auth_dialog.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
<WebView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/webv"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,12 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<group android:id="@+id/group_pause" android:checkableBehavior="all">
|
||||
<item android:id="@+id/pause" android:checked="false" android:title="Pause"/>
|
||||
</group>
|
||||
|
||||
|
||||
<group android:id="@+id/group_actions">
|
||||
<item android:id="@+id/post_processing" android:title="Post-Processing...">
|
||||
<group android:checkableBehavior="single">
|
||||
<item android:id="@+id/point_cloud" android:title="Point Cloud" />
|
||||
<item android:id="@+id/mesh" android:title="Mesh" />
|
||||
<item android:id="@+id/texture_mesh" android:checked="true" android:title="Texture Mesh" />
|
||||
</group>
|
||||
<item android:id="@+id/save" android:title="Save" android:showAsAction="ifRoom"/>
|
||||
<item android:id="@+id/post_processing" android:title="Optimize" android:showAsAction="ifRoom">
|
||||
<menu>
|
||||
<item android:id="@+id/post_processing_standard" android:title="Standard Optimization" />
|
||||
<item android:id="@+id/post_processing_advanced" android:title="Advanced..." >
|
||||
@@ -23,35 +25,30 @@
|
||||
</item>
|
||||
</menu>
|
||||
</item>
|
||||
<item android:id="@+id/open" android:title="Open"/>
|
||||
<item android:id="@+id/export" android:title="Export...">
|
||||
<item android:id="@+id/export" android:showAsAction="ifRoom" android:title="Export">
|
||||
<menu>
|
||||
<group android:id="@+id/group_export">
|
||||
<item android:id="@+id/export_ply" android:title="Mesh (.ply)" />
|
||||
<item android:id="@+id/export_obj" android:title="Mesh with texture (*.obj)" />
|
||||
</group>
|
||||
<item android:id="@+id/export_point_cloud" android:title="Point Cloud (*.ply)" />
|
||||
<item android:id="@+id/export_mesh_menu" android:title="Raw Mesh..." >
|
||||
<menu>
|
||||
<item android:id="@+id/export_mesh" android:title="Colored Mesh (*.ply)" />
|
||||
<item android:id="@+id/export_mesh_texture" android:title="Textured Mesh (*.obj)" />
|
||||
</menu>
|
||||
</item>
|
||||
<item android:id="@+id/export_optimized_mesh_menu" android:title="Optimized Mesh..." >
|
||||
<menu>
|
||||
<item android:id="@+id/export_optimized_mesh" android:title="Colored Mesh (*.ply)" />
|
||||
<item android:id="@+id/export_optimized_mesh_texture" android:title="Textured Mesh (*.obj)" />
|
||||
</menu>
|
||||
</item>
|
||||
</menu>
|
||||
</item>
|
||||
<item android:id="@+id/save" android:title="Save"/>
|
||||
<item android:id="@+id/reset" android:title="Reset"/>
|
||||
|
||||
<item android:id="@+id/menu_rendering_settings" android:title="Rendering Options...">
|
||||
<item android:id="@+id/open" android:title="Open" android:showAsAction="ifRoom"/>
|
||||
|
||||
<item android:id="@+id/menu_rendering_settings" android:title="Visibility...">
|
||||
<menu >
|
||||
<group android:id="@+id/group_rendering_visibility" android:checkableBehavior="all">
|
||||
<item android:id="@+id/debug" android:checked="false" android:title="Debug" />
|
||||
<item android:id="@+id/menu_rendering" android:checkable="false" android:title="Mesh Rendering..." >
|
||||
<menu>
|
||||
<group android:checkableBehavior="single">
|
||||
<item android:id="@+id/point_cloud" android:title="Point Cloud" />
|
||||
<item android:id="@+id/mesh" android:title="Mesh" />
|
||||
<item android:id="@+id/texture_mesh" android:checked="true" android:title="Texture Mesh" />
|
||||
</group>
|
||||
<item android:id="@+id/mesh_decimation" android:checkable="false" android:title="Mesh Decimation..." />
|
||||
<item android:id="@+id/mesh_angle_tolerance" android:checkable="false" android:title="Mesh Angle Tolerance..." />
|
||||
<item android:id="@+id/mesh_triangle_size" android:checkable="false" android:title="Mesh Triangle Size..." />
|
||||
<item android:id="@+id/max_depth" android:checkable="false" android:title="Max Depth..." />
|
||||
</menu>
|
||||
</item>
|
||||
<item android:id="@+id/map_shown" android:checked="true" android:title="Map Visible" />
|
||||
<item android:id="@+id/odom_shown" android:checked="true" android:title="Odom Visible" />
|
||||
<item android:id="@+id/graph_visible" android:checked="true" android:title="Graph Visible" />
|
||||
@@ -60,30 +57,17 @@
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
<item android:id="@+id/menu_mapping_settings" android:title="Mapping Options...">
|
||||
<item android:id="@+id/modes" android:title="Modes...">
|
||||
<menu >
|
||||
<group android:id="@+id/group_mapping_visibility" android:checkableBehavior="all">
|
||||
<item android:id="@+id/localization_mode" android:checked="false" android:title="Localization Mode" />
|
||||
<item android:id="@+id/trajectory_mode" android:checked="false" android:title="Trajectory Mode" />
|
||||
<item android:id="@+id/append" android:checked="true" android:title="Append Mode" />
|
||||
<item android:id="@+id/nodes_filtering" android:checked="false" android:title="Nodes Filtering" />
|
||||
<item android:id="@+id/drift_correction" android:checked="false" android:title="Drift Correction" />
|
||||
<item android:id="@+id/auto_exposure" android:checked="true" android:title="Auto Exposure" />
|
||||
<item android:id="@+id/resolution" android:checked="false" android:title="HD Mode" />
|
||||
<item android:id="@+id/data_recorder" android:checked="false" android:title="Data Recorder Mode" />
|
||||
<item android:id="@+id/menu_param_settings" android:checkable="false" android:title="Parameters...">
|
||||
<menu >
|
||||
<item android:id="@+id/update_rate" android:title="Map Update Rate..." />
|
||||
<item android:id="@+id/time_threshold" android:title="Time Threshold..." />
|
||||
<item android:id="@+id/loop_threshold" android:title="Loop Closure Threshold..." />
|
||||
<item android:id="@+id/optimize_error" android:title="Max Optimization Error..." />
|
||||
<item android:id="@+id/features" android:title="Max Features Extracted..." />
|
||||
</menu>
|
||||
</item>
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item android:id="@+id/settings" android:title="Settings"/>
|
||||
<item android:id="@+id/reset" android:title="Reset"/>
|
||||
<item android:id="@+id/about" android:title="About"/>
|
||||
</group>
|
||||
</menu>
|
||||
@@ -3,11 +3,17 @@
|
||||
<string name="app_name">RTAB-Map</string>
|
||||
<string name="sys_name">RTAB-Map</string>
|
||||
<string name="menu_name">Real-Time Appearance-Based Mapping</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="dropbox">Dropbox</string>
|
||||
<string name="status">"Status: "</string>
|
||||
<string name="words">"Words: "</string>
|
||||
<string name="first_person">First</string>
|
||||
<string name="third_person">Third</string>
|
||||
<string name="top_down">Top</string>
|
||||
<string name="pause">Pause</string>
|
||||
<string name="resume">Paused</string>
|
||||
<string name="light_on">Lighting</string>
|
||||
<string name="light_off">Lighting</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="nodes">"Nodes (WM): "</string>
|
||||
<string name="points">"Number of points: "</string>
|
||||
@@ -21,5 +27,392 @@
|
||||
<string name="memory">"Memory (MB): "</string>
|
||||
<string name="hypothesis">"Hypothesis: "</string>
|
||||
<string name="fps">"FPS (rendering): "</string>
|
||||
|
||||
<!-- Preference keys: BEGIN -->
|
||||
<string name="pref_key_rendering">pref_key_rendering</string><string name="pref_default_rendering">2</string>
|
||||
<string name="pref_key_reset_button">pref_key_reset_button</string>
|
||||
|
||||
<string name="pref_key_decimation">pref_key_decimation</string> <string name="pref_default_decimation">0</string>
|
||||
<string name="pref_key_depth">pref_key_depth</string> <string name="pref_default_depth">0</string>
|
||||
<string name="pref_key_point_size">pref_key_point_size</string> <string name="pref_default_point_size">5</string>
|
||||
<string name="pref_key_angle">pref_key_angle</string> <string name="pref_default_angle">15</string>
|
||||
<string name="pref_key_triangle">pref_key_triangle</string> <string name="pref_default_triangle">2</string>
|
||||
<string name="pref_key_nodes_filtering">pref_key_nodes_filtering</string> <string name="pref_default_nodes_filtering">false</string>
|
||||
|
||||
<string name="pref_key_append">pref_key_append</string> <string name="pref_default_append">true</string>
|
||||
<string name="pref_key_drift_correction">pref_key_drift_correction</string> <string name="pref_default_drift_correction">false</string>
|
||||
<string name="pref_key_auto_exposure">pref_key_auto_exposure</string> <string name="pref_default_auto_exposure">true</string>
|
||||
<string name="pref_key_resolution">pref_key_resolution</string> <string name="pref_default_resolution">false</string>
|
||||
<string name="pref_key_update_rate">pref_key_update_rate</string> <string name="pref_default_update_rate">1</string>
|
||||
<string name="pref_key_time_thr">pref_key_time_thr</string> <string name="pref_default_time_thr">800</string>
|
||||
<string name="pref_key_loop_thr">pref_key_loop_thr</string> <string name="pref_default_loop_thr">0.11</string>
|
||||
<string name="pref_key_opt_error">pref_key_opt_error</string> <string name="pref_default_opt_error">0.1</string>
|
||||
<string name="pref_key_features">pref_key_features</string> <string name="pref_default_features">200</string>
|
||||
|
||||
<string name="pref_key_cloud_voxel">pref_key_cloud_voxel</string> <string name="pref_default_cloud_voxel">0</string>
|
||||
<string name="pref_key_texture_size">pref_key_texture_size</string> <string name="pref_default_texture_size">4096</string>
|
||||
<string name="pref_key_normal_k">pref_key_normal_k</string> <string name="pref_default_normal_k">6</string>
|
||||
<string name="pref_key_block_render">pref_key_block_render</string> <string name="pref_default_block_render">false</string>
|
||||
<string name="pref_key_opt_depth">pref_key_opt_depth</string> <string name="pref_default_opt_depth">8</string>
|
||||
<string name="pref_key_opt_decimation_factor">pref_key_opt_decimation_factor</string><string name="pref_default_opt_decimation_factor">80</string>
|
||||
<string name="pref_key_opt_color_radius">pref_key_opt_color_radius</string> <string name="pref_default_opt_color_radius">0.0</string>
|
||||
<string name="pref_key_opt_clean_white">pref_key_opt_clean_white</string> <string name="pref_default_opt_clean_white">true</string>
|
||||
<!-- Preference keys: END-->
|
||||
|
||||
<string name="pref_title_rendering">Rendering</string>
|
||||
|
||||
<string name="pref_title_decimation">Mesh Decimation</string>
|
||||
<string name="pref_summary_decimation">Decimate the cloud size to reduce rendering time and memory.</string>
|
||||
<string name="pref_title_angle">Mesh Angle Tolerance</string>
|
||||
<string name="pref_summary_angle">Minimum polygon angle.</string>
|
||||
<string name="pref_title_triangle">Mesh Triangle Size</string>
|
||||
<string name="pref_summary_triangle">Size in pixels of the polygons created from the depth image.</string>
|
||||
<string name="pref_title_depth">Max Depth</string>
|
||||
<string name="pref_summary_depth">Points over the maximum depth are not rendered.</string>
|
||||
<string name="pref_title_point_size">Point Size</string>
|
||||
<string name="pref_summary_point_size">Size of the points when rendering only the point cloud.</string>
|
||||
<string name="pref_title_nodes_filtering">Nodes Filtering</string>
|
||||
<string name="pref_summary_nodes_filtering">Hide close point clouds from rendering.</string>
|
||||
|
||||
<string-array name="pref_decimation_keys">
|
||||
<item>"High"</item>
|
||||
<item>"Medium"</item>
|
||||
<item>"Disabled"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_decimation_values">
|
||||
<item>"2"</item>
|
||||
<item>"1"</item>
|
||||
<item>"0"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_depth_keys">
|
||||
<item>"No Limit"</item>
|
||||
<item>"5"</item>
|
||||
<item>"4"</item>
|
||||
<item>"3"</item>
|
||||
<item>"2"</item>
|
||||
<item>"1"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_depth_values">
|
||||
<item>"0"</item>
|
||||
<item>"5"</item>
|
||||
<item>"4"</item>
|
||||
<item>"3"</item>
|
||||
<item>"2"</item>
|
||||
<item>"1"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_point_size_values">
|
||||
<item>"50"</item>
|
||||
<item>"30"</item>
|
||||
<item>"25"</item>
|
||||
<item>"15"</item>
|
||||
<item>"5"</item>
|
||||
<item>"1"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_angle_keys">
|
||||
<item>"30 deg"</item>
|
||||
<item>"25 deg"</item>
|
||||
<item>"20 deg"</item>
|
||||
<item>"15 deg"</item>
|
||||
<item>"10 deg"</item>
|
||||
<item>"5 deg"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_angle_values">
|
||||
<item>"30"</item>
|
||||
<item>"25"</item>
|
||||
<item>"20"</item>
|
||||
<item>"15"</item>
|
||||
<item>"10"</item>
|
||||
<item>"5"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_triangle_keys">
|
||||
<item>"6 pix"</item>
|
||||
<item>"5 pix"</item>
|
||||
<item>"4 pix"</item>
|
||||
<item>"3 pix"</item>
|
||||
<item>"2 pix"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_triangle_values">
|
||||
<item>"6"</item>
|
||||
<item>"5"</item>
|
||||
<item>"4"</item>
|
||||
<item>"3"</item>
|
||||
<item>"2"</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_title_mapping">Mapping</string>
|
||||
<string name="pref_summary_mapping">Advanced mapping parameters for fine tuning.</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_title_drift_correction">Drift Correction</string>
|
||||
<string name="pref_summary_drift_correction">Iterative-closest-point (ICP) is done to refine geometrically the links in the map. Use only when environment is highly geometric. Camera should move slowly.</string>
|
||||
<string name="pref_title_auto_exposure">Auto Exposure</string>
|
||||
<string name="pref_summary_auto_exposure">Adjust camera exposure depending on the lighting to get always maximum contrast. This may change texture color between scanned images. Color correction option in Post-Processing can help to uniformize colors. May not work on some devices.</string>
|
||||
<string name="pref_title_resolution">HD Mode</string>
|
||||
<string name="pref_summary_resolution">Save HD images if you want very detailed textures. More memory will be required.</string>
|
||||
|
||||
<string name="pref_title_update_rate">Update Rate</string>
|
||||
<string name="pref_summary_update_rate">Rate at which a new node is added to map.</string>
|
||||
<string name="pref_title_time_thr">Time Limit</string>
|
||||
<string name="pref_summary_time_thr">Maximum time allowed for map updates. If time to add a new node is above this theshold, some old parts of the map are temporarly forgotten to reduce time of next updates.</string>
|
||||
<string name="pref_title_loop_thr">Loop Closure Threshold</string>
|
||||
<string name="pref_summary_loop_thr">Threshold at which loop closure hypotheses are accepted. Higher means more robust to false loop closures while rejecting more good loop closures.</string>
|
||||
<string name="pref_title_opt_error">Max Optimization Error</string>
|
||||
<string name="pref_summary_opt_error">Reject any loop closures causing error corrections in the map higher than this threshold.</string>
|
||||
<string name="pref_title_features">Max Features Extracted</string>
|
||||
<string name="pref_summary_features">Extracting more features per image would result in better loop closure detection but more processing time required.</string>
|
||||
|
||||
<string-array name="pref_update_rate_keys">
|
||||
<item>"Max"</item>
|
||||
<item>"5 Hz"</item>
|
||||
<item>"4 Hz"</item>
|
||||
<item>"3 Hz"</item>
|
||||
<item>"2 Hz"</item>
|
||||
<item>"1 Hz"</item>
|
||||
<item>"0.5 Hz"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_update_rate_values">
|
||||
<item>"0"</item>
|
||||
<item>"5"</item>
|
||||
<item>"4"</item>
|
||||
<item>"3"</item>
|
||||
<item>"2"</item>
|
||||
<item>"1"</item>
|
||||
<item>"0.5"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_time_thr_keys">
|
||||
<item>"No Limit"</item>
|
||||
<item>"1500 ms"</item>
|
||||
<item>"1400 ms"</item>
|
||||
<item>"1300 ms"</item>
|
||||
<item>"1200 ms"</item>
|
||||
<item>"1100 ms"</item>
|
||||
<item>"1000 ms"</item>
|
||||
<item>"900 ms"</item>
|
||||
<item>"800 ms"</item>
|
||||
<item>"700 ms"</item>
|
||||
<item>"600 ms"</item>
|
||||
<item>"500 ms"</item>
|
||||
<item>"400"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_time_thr_values">
|
||||
<item>"0"</item>
|
||||
<item>"1500"</item>
|
||||
<item>"1400"</item>
|
||||
<item>"1300"</item>
|
||||
<item>"1200"</item>
|
||||
<item>"1100"</item>
|
||||
<item>"1000"</item>
|
||||
<item>"900"</item>
|
||||
<item>"800"</item>
|
||||
<item>"700"</item>
|
||||
<item>"600"</item>
|
||||
<item>"500"</item>
|
||||
<item>"400"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_loop_thr_keys">
|
||||
<item>"0.90"</item>
|
||||
<item>"0.80"</item>
|
||||
<item>"0.70"</item>
|
||||
<item>"0.60"</item>
|
||||
<item>"0.50"</item>
|
||||
<item>"0.40"</item>
|
||||
<item>"0.30"</item>
|
||||
<item>"0.20"</item>
|
||||
<item>"0.11"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_loop_thr_values">
|
||||
<item>"0.90"</item>
|
||||
<item>"0.80"</item>
|
||||
<item>"0.70"</item>
|
||||
<item>"0.60"</item>
|
||||
<item>"0.50"</item>
|
||||
<item>"0.40"</item>
|
||||
<item>"0.30"</item>
|
||||
<item>"0.20"</item>
|
||||
<item>"0.11"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_opt_error_keys">
|
||||
<item>"1.0 m"</item>
|
||||
<item>"0.5 m"</item>
|
||||
<item>"0.35 m"</item>
|
||||
<item>"0.2 m"</item>
|
||||
<item>"0.1 m"</item>
|
||||
<item>"0.05 m"</item>
|
||||
<item>"0.025 m"</item>
|
||||
<item>"0.01 m"</item>
|
||||
<item>"Disabled"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_opt_error_values">
|
||||
<item>"1.0"</item>
|
||||
<item>"0.5"</item>
|
||||
<item>"0.35"</item>
|
||||
<item>"0.2"</item>
|
||||
<item>"0.1"</item>
|
||||
<item>"0.05"</item>
|
||||
<item>"0.025"</item>
|
||||
<item>"0.01"</item>
|
||||
<item>"0"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_features_keys">
|
||||
<item>"No Limit"</item>
|
||||
<item>"1000"</item>
|
||||
<item>"900"</item>
|
||||
<item>"800"</item>
|
||||
<item>"700"</item>
|
||||
<item>"600"</item>
|
||||
<item>"500"</item>
|
||||
<item>"400"</item>
|
||||
<item>"300"</item>
|
||||
<item>"200"</item>
|
||||
<item>"100"</item>
|
||||
<item>"Disabled"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_features_values">
|
||||
<item>"0"</item>
|
||||
<item>"1000"</item>
|
||||
<item>"900"</item>
|
||||
<item>"800"</item>
|
||||
<item>"700"</item>
|
||||
<item>"600"</item>
|
||||
<item>"500"</item>
|
||||
<item>"400"</item>
|
||||
<item>"300"</item>
|
||||
<item>"200"</item>
|
||||
<item>"100"</item>
|
||||
<item>"-1"</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_title_export">Exporting</string>
|
||||
<string name="pref_summary_export">Advanced parameters used when exporting the map.</string>
|
||||
|
||||
<string name="pref_title_cloud_voxel">Voxel Size</string>
|
||||
<string name="pref_summary_cloud_voxel">If you don\'t need a very precise point cloud, you can set this to reduce the output point cloud size. This is also used for optimized mesh.</string>
|
||||
<string name="pref_title_texture_size">Texture Size</string>
|
||||
<string name="pref_summary_texture_size">If the map is large, you may want to increase this to maximize the texture resolution.</string>
|
||||
<string name="pref_title_normal_k">Normal K</string>
|
||||
<string name="pref_summary_normal_k">K-nearest neighbors used for normal computation when a mesh is created.</string>
|
||||
<string name="pref_title_block_render">Block Rendering Thread While Exporting</string>
|
||||
<string name="pref_summary_block_render">This decreases exporting time, but freezes rendering while exporting.</string>
|
||||
|
||||
<string-array name="pref_cloud_voxel_keys">
|
||||
<item>"0.2 m"</item>
|
||||
<item>"0.1 m"</item>
|
||||
<item>"0.05 m"</item>
|
||||
<item>"0.02 m"</item>
|
||||
<item>"0.01 m"</item>
|
||||
<item>"Disabled"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_cloud_voxel_values">
|
||||
<item>"0.2"</item>
|
||||
<item>"0.1"</item>
|
||||
<item>"0.05"</item>
|
||||
<item>"0.02"</item>
|
||||
<item>"0.01"</item>
|
||||
<item>"0"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_texture_size_keys">
|
||||
<item>"16384x16384"</item>
|
||||
<item>"8192x8192"</item>
|
||||
<item>"4096x4096"</item>
|
||||
<item>"2048x2048"</item>
|
||||
<item>"1024x1024"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_texture_size_values">
|
||||
<item>"16384"</item>
|
||||
<item>"8192"</item>
|
||||
<item>"4096"</item>
|
||||
<item>"2048"</item>
|
||||
<item>"1024"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_normal_k_values">
|
||||
<item>"30"</item>
|
||||
<item>"24"</item>
|
||||
<item>"18"</item>
|
||||
<item>"12"</item>
|
||||
<item>"6"</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_title_optimized">Optimized</string>
|
||||
|
||||
<string name="pref_title_opt_voxel">Voxel Size</string>
|
||||
<string name="pref_summary_opt_voxel">Increasing this can reduce reconstruction time at the cost of less geometry precision.</string>
|
||||
<string name="pref_title_opt_depth">Reconstruction Depth</string>
|
||||
<string name="pref_summary_opt_depth">Lowering this parameter decreases reconstruction time, but geometry precision is lower.</string>
|
||||
<string name="pref_title_opt_decimation_factor">Mesh Decimation Factor</string>
|
||||
<string name="pref_summary_opt_decimation_factor">Reduce the number of the output polygons on plane areas by this factor. This also reduces texture projection time.</string>
|
||||
<string name="pref_title_opt_color_radius">Color Radius</string>
|
||||
<string name="pref_summary_opt_color_radius">Radius used to transfer nearest color from the point cloud to reconstructed mesh.</string>
|
||||
<string name="pref_title_opt_clean_white">Clean Mesh</string>
|
||||
<string name="pref_summary_opt_clean_white">Clean mesh from textureless or colorless reconstructed polygons.</string>
|
||||
|
||||
<string-array name="pref_opt_depth_values">
|
||||
<item>"12"</item>
|
||||
<item>"11"</item>
|
||||
<item>"10"</item>
|
||||
<item>"9"</item>
|
||||
<item>"8"</item>
|
||||
<item>"7"</item>
|
||||
<item>"6"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_opt_decimation_factor_keys">
|
||||
<item>"90%"</item>
|
||||
<item>"80%"</item>
|
||||
<item>"70%"</item>
|
||||
<item>"60%"</item>
|
||||
<item>"50%"</item>
|
||||
<item>"40%"</item>
|
||||
<item>"30%"</item>
|
||||
<item>"20%"</item>
|
||||
<item>"10%"</item>
|
||||
<item>"Disabled"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_opt_decimation_factor_values">
|
||||
<item>"90"</item>
|
||||
<item>"80"</item>
|
||||
<item>"70"</item>
|
||||
<item>"60"</item>
|
||||
<item>"50"</item>
|
||||
<item>"40"</item>
|
||||
<item>"30"</item>
|
||||
<item>"20"</item>
|
||||
<item>"20"</item>
|
||||
<item>"0"</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_opt_color_radius_keys">
|
||||
<item>"Nearest"</item>
|
||||
<item>"2 m"</item>
|
||||
<item>"1 m"</item>
|
||||
<item>"0.5 m"</item>
|
||||
<item>"0.2 m"</item>
|
||||
<item>"0.05 m"</item>
|
||||
<item>"0.01 m"</item>
|
||||
<item>"Disabled"</item>
|
||||
</string-array>
|
||||
<string-array name="pref_opt_color_radius_values">
|
||||
<item>"0"</item>
|
||||
<item>"2"</item>
|
||||
<item>"1"</item>
|
||||
<item>"0.5"</item>
|
||||
<item>"0.2"</item>
|
||||
<item>"0.05"</item>
|
||||
<item>"0.01"</item>
|
||||
<item>"-1"</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_title_general">General</string>
|
||||
<string name="pref_title_reset_button">Restore All Default Settings</string>
|
||||
|
||||
</resources>
|
||||
|
||||
148
app/android/src/com/introlab/rtabmap/MultipartUtility.java
Normal file
148
app/android/src/com/introlab/rtabmap/MultipartUtility.java
Normal file
@@ -0,0 +1,148 @@
|
||||
package com.introlab.rtabmap;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This utility class provides an abstraction layer for sending multipart HTTP
|
||||
* POST requests to a web server.
|
||||
* @author www.codejava.net
|
||||
* http://www.codejava.net/java-se/networking/upload-files-by-sending-multipart-request-programmatically
|
||||
*
|
||||
*/
|
||||
public class MultipartUtility {
|
||||
private final String boundary;
|
||||
private static final String LINE_FEED = "\r\n";
|
||||
private HttpURLConnection httpConn;
|
||||
private String charset;
|
||||
private OutputStream outputStream;
|
||||
private PrintWriter writer;
|
||||
|
||||
/**
|
||||
* This constructor initializes a new HTTP POST request with content type
|
||||
* is set to multipart/form-data
|
||||
* @param requestURL
|
||||
* @param charset
|
||||
* @throws IOException
|
||||
*/
|
||||
public MultipartUtility(String requestURL, String token, String charset)
|
||||
throws IOException {
|
||||
this.charset = charset;
|
||||
|
||||
// creates a unique boundary based on time stamp
|
||||
boundary = "===" + System.currentTimeMillis() + "===";
|
||||
|
||||
URL url = new URL(requestURL);
|
||||
httpConn = (HttpURLConnection) url.openConnection();
|
||||
httpConn.setUseCaches(false);
|
||||
httpConn.setDoOutput(true); // indicates POST method
|
||||
httpConn.setDoInput(true);
|
||||
httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||
httpConn.setRequestProperty("Authorization", "Bearer " + token);
|
||||
outputStream = httpConn.getOutputStream();
|
||||
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a form field to the request
|
||||
* @param name field name
|
||||
* @param value field value
|
||||
*/
|
||||
public void addFormField(String name, String value) {
|
||||
writer.append("--" + boundary).append(LINE_FEED);
|
||||
writer.append("Content-Disposition: form-data; name=\"" + name + "\"").append(LINE_FEED);
|
||||
writer.append("Content-Type: text/plain; charset=" + charset).append(LINE_FEED);
|
||||
writer.append(LINE_FEED);
|
||||
writer.append(value).append(LINE_FEED);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a upload file section to the request
|
||||
* @param fieldName name attribute in <input type="file" name="..." />
|
||||
* @param uploadFile a File to be uploaded
|
||||
* @throws IOException
|
||||
*/
|
||||
public void addFilePart(String fieldName, File uploadFile)
|
||||
throws IOException {
|
||||
String fileName = uploadFile.getName();
|
||||
writer.append("--" + boundary).append(LINE_FEED);
|
||||
writer.append(
|
||||
"Content-Disposition: form-data; name=\"" + fieldName
|
||||
+ "\"; filename=\"" + fileName + "\"")
|
||||
.append(LINE_FEED);
|
||||
writer.append(
|
||||
"Content-Type: "
|
||||
+ URLConnection.guessContentTypeFromName(fileName))
|
||||
.append(LINE_FEED);
|
||||
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
|
||||
writer.append(LINE_FEED);
|
||||
writer.flush();
|
||||
|
||||
FileInputStream inputStream = new FileInputStream(uploadFile);
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead = -1;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
outputStream.flush();
|
||||
inputStream.close();
|
||||
|
||||
writer.append(LINE_FEED);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a header field to the request.
|
||||
* @param name - name of the header field
|
||||
* @param value - value of the header field
|
||||
*/
|
||||
public void addHeaderField(String name, String value) {
|
||||
writer.append(name + ": " + value).append(LINE_FEED);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Completes the request and receives response from the server.
|
||||
* @return a list of Strings as response in case the server returned
|
||||
* status OK, otherwise an exception is thrown.
|
||||
* @throws IOException
|
||||
*/
|
||||
public List<String> finish() throws IOException {
|
||||
List<String> response = new ArrayList<String>();
|
||||
|
||||
writer.append(LINE_FEED).flush();
|
||||
writer.append("--" + boundary + "--").append(LINE_FEED);
|
||||
writer.close();
|
||||
|
||||
// checks server's status code first
|
||||
int status = httpConn.getResponseCode();
|
||||
if (status == 201) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||
httpConn.getInputStream()));
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.add(line);
|
||||
}
|
||||
reader.close();
|
||||
httpConn.disconnect();
|
||||
} else {
|
||||
throw new IOException("Server returned non-OK status: " + status + ", msg: " + httpConn.getResponseMessage());
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -72,6 +72,8 @@ public class RTABMapLib
|
||||
public static native void setAppendMode(boolean enabled);
|
||||
public static native void setDataRecorderMode(boolean enabled);
|
||||
public static native void setMaxCloudDepth(float value);
|
||||
public static native void setPointSize(float value);
|
||||
public static native void setLighting(boolean enabled);
|
||||
public static native void setMeshDecimation(int value);
|
||||
public static native void setMeshAngleTolerance(float value);
|
||||
public static native void setMeshTriangleSize(int value);
|
||||
@@ -79,7 +81,21 @@ public class RTABMapLib
|
||||
|
||||
public static native void resetMapping();
|
||||
public static native void save(String outputDatabasePath);
|
||||
public static native boolean exportMesh(String filePath);
|
||||
public static native boolean exportMesh(
|
||||
String filePath,
|
||||
float cloudVoxelSize,
|
||||
boolean meshing,
|
||||
int textureSize,
|
||||
int normalK,
|
||||
boolean optimized,
|
||||
float optimizedVoxelSize,
|
||||
int optimizedDepth,
|
||||
float optimizedDecimationFactor,
|
||||
float optimizedColorRadius,
|
||||
boolean optimizedCleanWhitePolygons,
|
||||
boolean optimizedColorWhitePolygons,
|
||||
boolean blockRendering);
|
||||
public static native boolean postExportation(boolean visualize);
|
||||
public static native int postProcessing(int approach);
|
||||
|
||||
public static native String getStatus();
|
||||
|
||||
95
app/android/src/com/introlab/rtabmap/SettingsActivity.java
Normal file
95
app/android/src/com/introlab/rtabmap/SettingsActivity.java
Normal file
@@ -0,0 +1,95 @@
|
||||
package com.introlab.rtabmap;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.os.Bundle;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.layout.activity_settings);
|
||||
|
||||
Preference button = findPreference(getString(R.string.pref_key_reset_button));
|
||||
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
getPreferenceScreen().getSharedPreferences().edit().clear().commit();
|
||||
|
||||
recreate();
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
((Preference)findPreference(getString(R.string.pref_key_decimation))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_decimation))).getEntry() + ") "+getString(R.string.pref_summary_decimation));
|
||||
((Preference)findPreference(getString(R.string.pref_key_depth))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_depth))).getEntry() + ") "+getString(R.string.pref_summary_depth));
|
||||
((Preference)findPreference(getString(R.string.pref_key_point_size))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_point_size))).getEntry() + ") "+getString(R.string.pref_summary_point_size));
|
||||
((Preference)findPreference(getString(R.string.pref_key_angle))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_angle))).getEntry() + ") "+getString(R.string.pref_summary_angle));
|
||||
((Preference)findPreference(getString(R.string.pref_key_triangle))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_triangle))).getEntry() + ") "+getString(R.string.pref_summary_triangle));
|
||||
|
||||
((Preference)findPreference(getString(R.string.pref_key_update_rate))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_update_rate))).getEntry() + ") "+getString(R.string.pref_summary_update_rate));
|
||||
((Preference)findPreference(getString(R.string.pref_key_time_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_time_thr))).getEntry() + ") "+getString(R.string.pref_summary_time_thr));
|
||||
((Preference)findPreference(getString(R.string.pref_key_loop_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_loop_thr))).getEntry() + ") "+getString(R.string.pref_summary_loop_thr));
|
||||
((Preference)findPreference(getString(R.string.pref_key_opt_error))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_error))).getEntry() + ") "+getString(R.string.pref_summary_opt_error));
|
||||
((Preference)findPreference(getString(R.string.pref_key_features))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_features))).getEntry() + ") "+getString(R.string.pref_summary_features));
|
||||
|
||||
((Preference)findPreference(getString(R.string.pref_key_cloud_voxel))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_cloud_voxel))).getEntry() + ") "+getString(R.string.pref_summary_cloud_voxel));
|
||||
((Preference)findPreference(getString(R.string.pref_key_texture_size))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_texture_size))).getEntry() + ") "+getString(R.string.pref_summary_texture_size));
|
||||
((Preference)findPreference(getString(R.string.pref_key_normal_k))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_normal_k))).getEntry() + ") "+getString(R.string.pref_summary_normal_k));
|
||||
|
||||
((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_decimation_factor))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_decimation_factor))).getValue() + "%%) "+getString(R.string.pref_summary_opt_decimation_factor));
|
||||
((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));
|
||||
|
||||
}
|
||||
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
Preference pref = findPreference(key);
|
||||
|
||||
if (pref instanceof ListPreference) {
|
||||
if(key.compareTo(getString(R.string.pref_key_decimation))==0) pref.setSummary("("+ ((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_decimation));
|
||||
if(key.compareTo(getString(R.string.pref_key_depth))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_depth));
|
||||
if(key.compareTo(getString(R.string.pref_key_point_size))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_point_size));
|
||||
if(key.compareTo(getString(R.string.pref_key_angle))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_angle));
|
||||
if(key.compareTo(getString(R.string.pref_key_triangle))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_triangle));
|
||||
|
||||
if(key.compareTo(getString(R.string.pref_key_update_rate))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_update_rate));
|
||||
if(key.compareTo(getString(R.string.pref_key_time_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_time_thr));
|
||||
if(key.compareTo(getString(R.string.pref_key_loop_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_loop_thr));
|
||||
if(key.compareTo(getString(R.string.pref_key_opt_error))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_error));
|
||||
if(key.compareTo(getString(R.string.pref_key_features))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_features));
|
||||
|
||||
if(key.compareTo(getString(R.string.pref_key_cloud_voxel))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_cloud_voxel));
|
||||
if(key.compareTo(getString(R.string.pref_key_texture_size))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_texture_size));
|
||||
if(key.compareTo(getString(R.string.pref_key_normal_k))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_normal_k));
|
||||
|
||||
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_decimation_factor))==0) pref.setSummary("("+((ListPreference)pref).getValue() + "%%) "+getString(R.string.pref_summary_opt_decimation_factor));
|
||||
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));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// Set up a listener whenever a key changes
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
// Unregister the listener whenever a key changes
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user