util.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2014 Google Inc. All Rights Reserved.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "tango-gl/util.h"
00018 #include <rtabmap/utilite/ULogger.h>
00019 
00020 namespace tango_gl {
00021 
00022 void util::CheckGlError(const char* operation) {
00023   for (GLint error = glGetError(); error; error = glGetError()) {
00024     LOGE("after %s() glError (0x%x)\n", operation, error);
00025   }
00026 }
00027 
00028 // Convenience function used in CreateProgram below.
00029 static GLuint LoadShader(GLenum shader_type, const char* shader_source) {
00030   GLuint shader = glCreateShader(shader_type);
00031   if (shader) {
00032     glShaderSource(shader, 1, &shader_source, NULL);
00033     glCompileShader(shader);
00034     GLint compiled = 0;
00035     glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
00036     if (!compiled) {
00037       GLint info_len = 0;
00038       glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len);
00039       if (info_len) {
00040         char* buf = (char*) malloc(info_len);
00041         if (buf) {
00042           glGetShaderInfoLog(shader, info_len, NULL, buf);
00043           LOGE("Could not compile shader %d:\n%s\n", shader_type, buf);
00044           free(buf);
00045         }
00046         glDeleteShader(shader);
00047         shader = 0;
00048       }
00049     }
00050   }
00051   return shader;
00052 }
00053 
00054 GLuint util::CreateProgram(const char* vertex_source,
00055                              const char* fragment_source) {
00056   GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vertex_source);
00057   if (!vertexShader) {
00058     return 0;
00059   }
00060 
00061   GLuint fragment_shader = LoadShader(GL_FRAGMENT_SHADER, fragment_source);
00062   if (!fragment_shader) {
00063     return 0;
00064   }
00065 
00066   GLuint program = glCreateProgram();
00067   if (program) {
00068     glAttachShader(program, vertexShader);
00069     CheckGlError("glAttachShader");
00070     glAttachShader(program, fragment_shader);
00071     CheckGlError("glAttachShader");
00072     glLinkProgram(program);
00073     GLint link_status = GL_FALSE;
00074     glGetProgramiv(program, GL_LINK_STATUS, &link_status);
00075     if (link_status != GL_TRUE) {
00076       GLint buf_length = 0;
00077       glGetProgramiv(program, GL_INFO_LOG_LENGTH, &buf_length);
00078       if (buf_length) {
00079         char* buf = (char*) malloc(buf_length);
00080         if (buf) {
00081           glGetProgramInfoLog(program, buf_length, NULL, buf);
00082           LOGE("Could not link program:\n%s\n", buf);
00083           free(buf);
00084         }
00085       }
00086       glDeleteProgram(program);
00087       program = 0;
00088     }
00089   }
00090   CheckGlError("CreateProgram");
00091   return program;
00092 }
00093 
00094 void util::DecomposeMatrix (const glm::mat4& transform_mat,
00095                               glm::vec3& translation,
00096                               glm::quat& rotation,
00097                               glm::vec3& scale) {
00098   float scale_x = glm::length( glm::vec3( transform_mat[0][0], transform_mat[1][0], transform_mat[2][0] ) );
00099   float scale_y = glm::length( glm::vec3( transform_mat[0][1], transform_mat[1][1], transform_mat[2][1] ) );
00100   float scale_z = glm::length( glm::vec3( transform_mat[0][2], transform_mat[1][2], transform_mat[2][2] ) );
00101 
00102 
00103   float determinant = glm::determinant( transform_mat );
00104   if( determinant < 0.0 )
00105     scale_x = -scale_x;
00106 
00107   translation.x = transform_mat[3][0];
00108   translation.y = transform_mat[3][1];
00109   translation.z = transform_mat[3][2];
00110 
00111   float inverse_scale_x = 1.0 / scale_x;
00112   float inverse_scale_y = 1.0 / scale_y;
00113   float inverse_scale_z = 1.0 / scale_z;
00114 
00115   glm::mat4 transform_unscaled = transform_mat;
00116 
00117   transform_unscaled[0][0] *= inverse_scale_x;
00118   transform_unscaled[1][0] *= inverse_scale_x;
00119   transform_unscaled[2][0] *= inverse_scale_x;
00120 
00121   transform_unscaled[0][1] *= inverse_scale_y;
00122   transform_unscaled[1][1] *= inverse_scale_y;
00123   transform_unscaled[2][1] *= inverse_scale_y;
00124 
00125   transform_unscaled[0][2] *= inverse_scale_z;
00126   transform_unscaled[1][2] *= inverse_scale_z;
00127   transform_unscaled[2][2] *= inverse_scale_z;
00128 
00129   rotation = glm::quat_cast( transform_mat );
00130 
00131   scale.x = scale_x;
00132   scale.y = scale_y;
00133   scale.z = scale_z;
00134 }
00135 
00136 glm::vec3 util::GetColumnFromMatrix(const glm::mat4& mat, const int col) {
00137   return glm::vec3(mat[col][0], mat[col][1], mat[col][2]);
00138 }
00139 
00140 glm::vec3 util::GetTranslationFromMatrix(const glm::mat4& mat) {
00141   return glm::vec3(mat[3][0], mat[3][1], mat[3][2]);
00142 }
00143 
00144 float util::Clamp(float value, float min, float max) {
00145   return value < min ? min : (value > max ? max : value);
00146 }
00147 
00148 // Print out a column major matrix.
00149 void util::PrintMatrix(const glm::mat4& matrix) {
00150   int i;
00151   for (i = 0; i < 4; i++) {
00152     LOGI("[ %f, %f, %f, %f ]", matrix[0][i], matrix[1][i], matrix[2][i],
00153          matrix[3][i]);
00154   }
00155   LOGI(" ");
00156 }
00157 
00158 void util::PrintVector(const glm::vec3& vector) {
00159   LOGI("[ %f, %f, %f ]", vector[0], vector[1], vector[2]);
00160   LOGI(" ");
00161 }
00162 
00163 void util::PrintQuaternion(const glm::quat& quat) {
00164   LOGI("[ %f, %f, %f, %f ]", quat[0], quat[1], quat[2], quat[3]);
00165   LOGI(" ");
00166 }
00167 
00168 glm::vec3 util::LerpVector(const glm::vec3& x, const glm::vec3& y, float a) {
00169   return x * (1.0f - a) + y * a;
00170 }
00171 
00172 float util::DistanceSquared(const glm::vec3& v1, const glm::vec3& v2) {
00173   glm::vec3 delta = v2 - v1;
00174   return glm::dot(delta, delta);
00175 }
00176 
00177 bool util::SegmentAABBIntersect(const glm::vec3& aabb_min,
00178                             const glm::vec3& aabb_max,
00179                             const glm::vec3& start,
00180                             const glm::vec3& end) {
00181   float tmin, tmax, tymin, tymax, tzmin, tzmax;
00182   glm::vec3 direction = end - start;
00183   if (direction.x >= 0) {
00184     tmin = (aabb_min.x - start.x) / direction.x;
00185     tmax = (aabb_max.x - start.x) / direction.x;
00186   } else {
00187     tmin = (aabb_max.x - start.x) / direction.x;
00188     tmax = (aabb_min.x - start.x) / direction.x;
00189   }
00190   if (direction.y >= 0) {
00191     tymin = (aabb_min.y - start.y) / direction.y;
00192     tymax = (aabb_max.y - start.y) / direction.y;
00193   } else {
00194     tymin = (aabb_max.y - start.y) / direction.y;
00195     tymax = (aabb_min.y - start.y) / direction.y;
00196   }
00197   if ((tmin > tymax) || (tymin > tmax)) return false;
00198 
00199   if (tymin > tmin) tmin = tymin;
00200   if (tymax < tmax) tmax = tymax;
00201   if (direction.z >= 0) {
00202     tzmin = (aabb_min.z - start.z) / direction.z;
00203     tzmax = (aabb_max.z - start.z) / direction.z;
00204   } else {
00205     tzmin = (aabb_max.z - start.z) / direction.z;
00206     tzmax = (aabb_min.z - start.z) / direction.z;
00207   }
00208   if ((tmin > tzmax) || (tzmin > tmax)) return false;
00209 
00210   if (tzmin > tmin) tmin = tzmin;
00211   if (tzmax < tmax) tmax = tzmax;
00212   // Use the full length of the segment.
00213   return ((tmin < 1.0f) && (tmax > 0));
00214 }
00215 
00216 glm::vec3 util::ApplyTransform(const glm::mat4& mat, const glm::vec3& vec) {
00217   return glm::vec3(mat * glm::vec4(vec, 1.0f));
00218 }
00219 
00220 }  // namespace tango_gl


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sat Jul 23 2016 11:44:28