Rev 178 | Blame | Compare with Previous | Last modification | View Log | RSS feed
// bdl, jab, feb 2005
// Inspired by Nate Robins Obj loader
#include <CGLA/Vec3f.h>
#include <stdio.h>
#include <iostream>
#include "TriMesh.h"
using namespace std;
using namespace CGLA;
namespace Geometry
{
int TriMesh::find_material(const string& name) const
{
for(size_t i=0;i<materials.size(); ++i)
{
if(materials[i].name == name)
return i;
}
return 0;
}
void TriMesh::compute_normals()
{
// By default the normal faces are the same as the geometry faces
// and there are just as many normals as vertices, so we simply
// copy.
normals = geometry;
const int NV = normals.no_vertices();
// The normals are initialized to zero.
int i;
for(i=0;i<NV; ++i)
normals.vertex_rw(i) = Vec3f(0);
// For each face
int NF = geometry.no_faces();
for(i=0;i<NF; ++i)
{
// Compute the normal
const Vec3i& f = geometry.face(i);
const Vec3f p0 = geometry.vertex(f[0]);
const Vec3f a = geometry.vertex(f[1]) - p0;
const Vec3f b = geometry.vertex(f[2]) - p0;
Vec3f face_normal = cross(a,b);
float l = sqr_length(face_normal);
if(l > 0.0f)
face_normal /= sqrt(l);
// Add the angle weighted normal to each vertex
for(int j=0;j<3; ++j)
{
const Vec3f p0 = geometry.vertex(f[j]);
const Vec3f a = normalize(geometry.vertex(f[(j+1)%3]) - p0);
const Vec3f b = normalize(geometry.vertex(f[(j+2)%3]) - p0);
float d = max(-1.0f, min(1.0f, dot(a,b)));
normals.vertex_rw(f[j]) += face_normal * acos(d);
}
}
// Normalize all normals
for(i=0;i<NV; ++i)
{
normals.vertex_rw(i).normalize();
}
}
void TriMesh::get_bbox(CGLA::Vec3f& p0, CGLA::Vec3f& p7) const
{
int i;
p0 = geometry.vertex(0);
p7 = geometry.vertex(0);
for(i=1;i<geometry.no_vertices();i++)
{
p0 = v_min(geometry.vertex(i), p0);
p7 = v_max(geometry.vertex(i), p7);
}
}
void TriMesh::get_bsphere(CGLA::Vec3f& c, float& r) const
{
Vec3f p0,p7;
get_bbox(p0, p7);
Vec3f rad = (p7 - p0)/2.0;
c = p0 + rad;
r = rad.length();
}
}