Subversion Repositories gelsvn

Rev

Rev 78 | Rev 132 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 78 Rev 79
1
// bdl, jab, feb 2005
1
// bdl, jab, feb 2005
2
// Inspired by Nate Robins Obj loader
2
// Inspired by Nate Robins Obj loader
3
 
3
 
4
#include "TriMesh.h"
4
#include "TriMesh.h"
5
#ifdef WIN32
5
#ifdef WIN32
6
#include <windows.h>
6
#include <windows.h>
7
#endif
7
#endif
8
#include <GL/gl.h>
8
#include <GL/gl.h>
9
#include <GL/glu.h>
9
#include <GL/glu.h>
10
 
10
 
11
#include <CGLA/Vec3f.h>
11
#include <CGLA/Vec3f.h>
12
#include <stdio.h>
12
#include <stdio.h>
13
#include <iostream>
13
#include <iostream>
14
 
14
 
15
using namespace std;
15
using namespace std;
16
using namespace CGLA;
16
using namespace CGLA;
17
 
17
 
18
namespace Mesh 
18
namespace Geometry 
19
{
19
{
20
	int TriMesh::find_material(const string& name) const
20
	int TriMesh::find_material(const string& name) const
21
	{
21
	{
22
		for(int i=0;i<materials.size(); ++i)
22
		for(int i=0;i<materials.size(); ++i)
23
			{
23
			{
24
				if(materials[i].name == name)
24
				if(materials[i].name == name)
25
					return i;
25
					return i;
26
			}
26
			}
27
		return 0;
27
		return 0;
28
	}
28
	}
29
 
29
 
30
	int TriMesh::find_texmap(const string& name) const
30
	int TriMesh::find_texmap(const string& name) const
31
	{
31
	{
32
		for(int i=0;i<texmaps.size(); ++i)
32
		for(int i=0;i<texmaps.size(); ++i)
33
			{
33
			{
34
				if(texmaps[i].get_name() == name)
34
				if(texmaps[i].get_name() == name)
35
					return i;
35
					return i;
36
			}
36
			}
37
		return -1;
37
		return -1;
38
	}
38
	}
39
 
39
 
40
	void TriMesh::compute_normals()
40
	void TriMesh::compute_normals()
41
	{		
41
	{		
42
		// By default the normal faces are the same as the geometry faces
42
		// By default the normal faces are the same as the geometry faces
43
		// and there are just as many normals as vertices, so we simply
43
		// and there are just as many normals as vertices, so we simply
44
		// copy.
44
		// copy.
45
		normals = geometry;
45
		normals = geometry;
46
 
46
 
47
		const int NV = normals.no_vertices();
47
		const int NV = normals.no_vertices();
48
		// The normals are initialized to zero.
48
		// The normals are initialized to zero.
49
		int i;
49
		int i;
50
		for(i=0;i<NV; ++i)
50
		for(i=0;i<NV; ++i)
51
			normals.vertex_rw(i) = Vec3f(0);
51
			normals.vertex_rw(i) = Vec3f(0);
52
 
52
 
53
		// For each face
53
		// For each face
54
		int NF = geometry.no_faces();
54
		int NF = geometry.no_faces();
55
		for(i=0;i<NF; ++i)
55
		for(i=0;i<NF; ++i)
56
      {
56
      {
57
				// Compute the normal
57
				// Compute the normal
58
				const Vec3i& f  = geometry.face(i);
58
				const Vec3i& f  = geometry.face(i);
59
				const Vec3f p0 = geometry.vertex(f[0]);
59
				const Vec3f p0 = geometry.vertex(f[0]);
60
				const Vec3f a  = geometry.vertex(f[1]) - p0;
60
				const Vec3f a  = geometry.vertex(f[1]) - p0;
61
				const Vec3f b  = geometry.vertex(f[2]) - p0;
61
				const Vec3f b  = geometry.vertex(f[2]) - p0;
62
				Vec3f face_normal = cross(a,b);
62
				Vec3f face_normal = cross(a,b);
63
				float l = sqr_length(face_normal);
63
				float l = sqr_length(face_normal);
64
				if(l > 0.0f)
64
				if(l > 0.0f)
65
					face_normal /= sqrt(l);
65
					face_normal /= sqrt(l);
66
				
66
				
67
				// Add the angle weighted normal to each vertex
67
				// Add the angle weighted normal to each vertex
68
				for(int j=0;j<3; ++j)
68
				for(int j=0;j<3; ++j)
69
					{
69
					{
70
						const Vec3f p0 = geometry.vertex(f[j]);
70
						const Vec3f p0 = geometry.vertex(f[j]);
71
						const Vec3f a = normalize(geometry.vertex(f[(j+1)%3]) - p0);
71
						const Vec3f a = normalize(geometry.vertex(f[(j+1)%3]) - p0);
72
						const Vec3f b = normalize(geometry.vertex(f[(j+2)%3]) - p0);
72
						const Vec3f b = normalize(geometry.vertex(f[(j+2)%3]) - p0);
73
						float d = max(-1.0f, min(1.0f, dot(a,b)));
73
						float d = max(-1.0f, min(1.0f, dot(a,b)));
74
						normals.vertex_rw(f[j]) += face_normal * acos(d);
74
						normals.vertex_rw(f[j]) += face_normal * acos(d);
75
					}
75
					}
76
      }
76
      }
77
 
77
 
78
		// Normalize all normals
78
		// Normalize all normals
79
    for(i=0;i<NV; ++i)
79
    for(i=0;i<NV; ++i)
80
			{
80
			{
81
				normals.vertex_rw(i).normalize();
81
				normals.vertex_rw(i).normalize();
82
			}
82
			}
83
	}
83
	}
84
 
84
 
85
	void TriMesh::gl_init_textures()
85
	void TriMesh::gl_init_textures()
86
	{
86
	{
87
		for(int i=0;i<texmaps.size();++i)
87
		for(int i=0;i<texmaps.size();++i)
88
			texmaps[i].gl_init();
88
			texmaps[i].gl_init();
89
	}
89
	}
90
 
90
 
91
 
91
 
92
	void TriMesh::gl_set_material(int idx)
92
	void TriMesh::gl_set_material(int idx)
93
	{
93
	{
94
		assert(idx<materials.size());
94
		assert(idx<materials.size());
95
		Material& material = materials[idx];
95
		Material& material = materials[idx];
96
		if(material.tex_id >=0)
96
		if(material.tex_id >=0)
97
			{
97
			{
98
				glEnable(GL_TEXTURE_2D);
98
				glEnable(GL_TEXTURE_2D);
99
				texmaps[material.tex_id].gl_bind();
99
				texmaps[material.tex_id].gl_bind();
100
				glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
100
				glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
101
			}
101
			}
102
		else
102
		else
103
			glDisable(GL_TEXTURE_2D);
103
			glDisable(GL_TEXTURE_2D);
104
			
104
			
105
		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material.ambient);
105
		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material.ambient);
106
		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material.diffuse);
106
		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material.diffuse);
107
		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material.specular);
107
		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material.specular);
108
		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.shininess);
108
		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.shininess);
109
	}
109
	}
110
 
110
 
111
	void TriMesh::gl_draw()
111
	void TriMesh::gl_draw()
112
	{
112
	{
113
		int old_mat_idx = -1;
113
		int old_mat_idx = -1;
114
		glBegin(GL_TRIANGLES);
114
		glBegin(GL_TRIANGLES);
115
		for(int i=0;i<geometry.no_faces();i++) 
115
		for(int i=0;i<geometry.no_faces();i++) 
116
			{
116
			{
117
				if(mat_idx[i] != old_mat_idx)
117
				if(mat_idx[i] != old_mat_idx)
118
					{
118
					{
119
						glEnd();
119
						glEnd();
120
						gl_set_material(mat_idx[i]);
120
						gl_set_material(mat_idx[i]);
121
						glBegin(GL_TRIANGLES);
121
						glBegin(GL_TRIANGLES);
122
						old_mat_idx = mat_idx[i];
122
						old_mat_idx = mat_idx[i];
123
					}
123
					}
124
				Vec3i n_face = normals.face(i);
124
				Vec3i n_face = normals.face(i);
125
				Vec3i g_face = geometry.face(i);
125
				Vec3i g_face = geometry.face(i);
126
				Vec3i t_face = texcoords.face(i);
126
				Vec3i t_face = texcoords.face(i);
127
				for(int j=0;j<3;j++) 
127
				for(int j=0;j<3;j++) 
128
					{
128
					{
129
						if(n_face != NULL_FACE)
129
						if(n_face != NULL_FACE)
130
							{
130
							{
131
								Vec3f norm = normals.vertex(n_face[j]);
131
								Vec3f norm = normals.vertex(n_face[j]);
132
								glNormal3fv(norm.get());
132
								glNormal3fv(norm.get());
133
							}
133
							}
134
						if(t_face != NULL_FACE)
134
						if(t_face != NULL_FACE)
135
							{
135
							{
136
								Vec3f texc = texcoords.vertex(t_face[j]);
136
								Vec3f texc = texcoords.vertex(t_face[j]);
137
								glTexCoord2fv(texc.get());
137
								glTexCoord2fv(texc.get());
138
							}
138
							}
139
						Vec3f vert = geometry.vertex(g_face[j]);
139
						Vec3f vert = geometry.vertex(g_face[j]);
140
						glVertex3fv(vert.get());
140
						glVertex3fv(vert.get());
141
					}
141
					}
142
		}
142
		}
143
		glEnd();
143
		glEnd();
144
		glDisable(GL_TEXTURE_2D);
144
		glDisable(GL_TEXTURE_2D);
145
	}
145
	}
146
 
146
 
147
  void TriMesh::get_bbox(CGLA::Vec3f& p0, CGLA::Vec3f& p7) const
147
  void TriMesh::get_bbox(CGLA::Vec3f& p0, CGLA::Vec3f& p7) const
148
  {
148
  {
149
    int i;
149
    int i;
150
    p0 = geometry.vertex(0);
150
    p0 = geometry.vertex(0);
151
    p7 = geometry.vertex(0);
151
    p7 = geometry.vertex(0);
152
    for(i=1;i<geometry.no_vertices();i++) 
152
    for(i=1;i<geometry.no_vertices();i++) 
153
      {
153
      {
154
				p0 = v_min(geometry.vertex(i), p0);
154
				p0 = v_min(geometry.vertex(i), p0);
155
				p7 = v_max(geometry.vertex(i), p7);
155
				p7 = v_max(geometry.vertex(i), p7);
156
      }
156
      }
157
  }
157
  }
158
 
158
 
159
  void TriMesh::get_bsphere(CGLA::Vec3f& c, float& r) const
159
  void TriMesh::get_bsphere(CGLA::Vec3f& c, float& r) const
160
  {
160
  {
161
    Vec3f p0,p7;
161
    Vec3f p0,p7;
162
    get_bbox(p0, p7);
162
    get_bbox(p0, p7);
163
    Vec3f rad = (p7 - p0)/2.0;
163
    Vec3f rad = (p7 - p0)/2.0;
164
    c = p0 + rad;
164
    c = p0 + rad;
165
    r = rad.length();
165
    r = rad.length();
166
  }
166
  }
167
 
167
 
168
 
168
 
169
}
169
}
170
 
170