Go to the documentation of this file.00001 #include <blort/TomGine/tgErrorMetric.h>
00002 #include <blort/TomGine/tgCollission.h>
00003
00004 using namespace TomGine;
00005
00006 vec3 tgErrorMetric::GetRandPointInTriangle(const vec3& v0, const vec3& v1, const vec3& v2, unsigned trials) const
00007 {
00008 vec3 e1 = v1 - v0;
00009 vec3 e2 = v2 - v0;
00010 vec3 p;
00011
00012 unsigned i=0;
00013
00014
00015
00016 do{
00017 float x = float(rand()) / RAND_MAX;
00018 float y = float(rand()) / RAND_MAX;
00019 p = v0 + e1*x + e2*y;
00020 i++;
00021 }while(!tgCollission::PointInTriangle(p,v0,v1,v2) && i<trials);
00022
00023 if(i==trials){
00024 printf("[tgErrorMetric::GetRandPointInTriangle] Warning: Number of trials exceeded, no point in triangle found.\n");
00025 p = vec3();
00026 }
00027
00028 return p;
00029 }
00030
00031 tgErrorMetric::tgErrorMetric(tgModel model, unsigned num_points)
00032 {
00033
00034
00035
00036
00037
00038 double Area = 0.0;
00039 double dArea = 0.0;
00040 for(unsigned f=0; f<model.m_faces.size(); f++){
00041 vec3 e1 = model.m_vertices[model.m_faces[f].v[1]].pos - model.m_vertices[model.m_faces[f].v[0]].pos;
00042 vec3 e2 = model.m_vertices[model.m_faces[f].v[2]].pos - model.m_vertices[model.m_faces[f].v[0]].pos;
00043 vec3 c;
00044 c.cross(e1,e2);
00045 Area += c.length() * 0.5;
00046 }
00047 dArea = 1.0/Area;
00048
00049
00050 unsigned points_used = 0;
00051 for(unsigned f=0; f<model.m_faces.size(); f++){
00052
00053 vec3 v0 = model.m_vertices[model.m_faces[f].v[0]].pos;
00054 vec3 v1 = model.m_vertices[model.m_faces[f].v[1]].pos;
00055 vec3 v2 = model.m_vertices[model.m_faces[f].v[2]].pos;
00056 vec3 e1 = v1 - v0;
00057 vec3 e2 = v2 - v0;
00058 vec3 c;
00059 vec3 p;
00060 c.cross(e1,e2);
00061 double area = c.length() * 0.5;
00062
00063
00064 unsigned n = 0;
00065 if(f==model.m_faces.size()-1)
00066 n = num_points - points_used;
00067 else{
00068 n = (unsigned)round(area * dArea * num_points);
00069 points_used += n;
00070 }
00071
00072
00073 if(model.m_faces[f].v.size() == 4){
00074 vec3 v3 = model.m_vertices[model.m_faces[f].v[3]].pos;
00075 unsigned m = n/2;
00076 for(unsigned i=0; i<m; i++){
00077 p = GetRandPointInTriangle(v0, v1, v3);
00078 pointlist.push_back(p);
00079 }
00080 for(unsigned i=0; i<(n-m); i++){
00081 p = GetRandPointInTriangle(v1, v2, v3);
00082 pointlist.push_back(p);
00083 }
00084 }else if(model.m_faces[f].v.size() == 3){
00085 for(unsigned i=0; i<n; i++){
00086 p = GetRandPointInTriangle(v0, v1, v2);
00087 pointlist.push_back(p);
00088 }
00089 }else{
00090 printf("[tgErrorMetric::tgErrorMetric] Warning face size not supported (only quads or triangles)\n");
00091 }
00092 }
00093 }
00094
00095 vec3 tgErrorMetric::Compare(const TomGine::tgPose &p1, const TomGine::tgPose &p2)
00096 {
00097 double err_x = 0.0;
00098 double err_y = 0.0;
00099 double err_z = 0.0;
00100 double dN = 1.0 / pointlist.size();
00101 for(unsigned i=0; i<pointlist.size(); i++){
00102 mat3 R1, R2;
00103 vec3 t1, t2;
00104
00105 p1.GetPose(R1,t1);
00106 p2.GetPose(R2,t2);
00107
00108 vec3 verr = (R1 * pointlist[i] + t1) - (R2 * pointlist[i] + t2);
00109
00110 err_x += double(fabs(verr.x)) * dN;
00111 err_y += double(fabs(verr.y)) * dN;
00112 err_z += double(fabs(verr.z)) * dN;
00113 }
00114 vec3 err = vec3(err_x, err_y, err_z);
00115 return err;
00116 }
00117