Subversion Repositories gelsvn

Rev

Rev 348 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
346 awk 1
#include "mesh.hpp"
2
#include "scene.hpp"
3
 
4
#include <Geometry/obj_load.h>
5
 
6
using namespace CGLA;
7
using namespace Geometry;
8
 
9
extern scene* current;
10
 
11
mesh::mesh(void)
12
{
13
	msh_ = new TriMesh;
14
	tangents_ = new IndexedFaceSet;
15
	mat_ = 0;
16
	exitance_ = Vec3f(0.f);
17
}
18
 
19
mesh::mesh(const std::string& fn)
20
{
21
	msh_ = new TriMesh;
22
	tangents_ = new IndexedFaceSet;
23
	mat_ = 0;
24
	exitance_ = Vec3f(0.f);
25
 
26
	TriMesh msh;
27
	obj_load(fn, msh);
28
	set_trimesh(msh);
29
}
30
 
31
mesh::~mesh(void)
32
{
33
	delete tangents_;
34
	delete msh_;
35
}
36
 
37
const CGLA::Vec3f& mesh::triangle_normal(size_t i) const
38
{
39
	return triangle_normals_.at(i);
40
}
41
 
42
const TriMesh& mesh::get_trimesh(void) const
43
{
44
	return *msh_;
45
}
46
 
47
void mesh::set_trimesh(const TriMesh& tm)
48
{
49
	*msh_ = tm;
50
 
51
	msh_->compute_normals();
52
	//
53
	//int tris = msh_->geometry.no_faces();
54
 
55
	//std::vector<Vec3f> tan1;
56
	//tan1.resize(tris);
57
	//triangle_normals_.resize(tris);
58
 
59
	//for (int t=0; t<tris; t++)
60
	//{
61
	//	const Vec3i& f  = msh_->geometry.face(t);
62
	//	const Vec3f p0 = msh_->geometry.vertex(f[0]);
63
	//	const Vec3f a  = msh_->geometry.vertex(f[1]) - p0;
64
	//	const Vec3f b  = msh_->geometry.vertex(f[2]) - p0;
65
	//	Vec3f tri_normal = cross(a,b);
66
	//	float l = sqr_length(tri_normal);
67
	//	if(l > 0.0f)
68
	//		tri_normal /= sqrt(l);
69
	//	triangle_normals_[t] = trs_.mul_3D_vector(tri_normal);
70
 
71
	//}
72
#if 0
73
	if (msh_->texcoords.no_faces() == 0)
74
		return;
75
 
76
	for (long a = 0; a < triangleCount; a++)
77
	{
78
		long i1 = triangle->index[0];
79
		long i2 = triangle->index[1];
80
		long i3 = triangle->index[2];
81
 
82
		const Point3D& v1 = vertex[i1];
83
		const Point3D& v2 = vertex[i2];
84
		const Point3D& v3 = vertex[i3];
85
 
86
		const Point2D& w1 = texcoord[i1];
87
		const Point2D& w2 = texcoord[i2];
88
		const Point2D& w3 = texcoord[i3];
89
 
90
		float x1 = v2.x - v1.x;
91
		float x2 = v3.x - v1.x;
92
		float y1 = v2.y - v1.y;
93
		float y2 = v3.y - v1.y;
94
		float z1 = v2.z - v1.z;
95
		float z2 = v3.z - v1.z;
96
 
97
		float s1 = w2.x - w1.x;
98
		float s2 = w3.x - w1.x;
99
		float t1 = w2.y - w1.y;
100
		float t2 = w3.y - w1.y;
101
 
102
		float r = 1.0F / (s1 * t2 - s2 * t1);
103
		Vector3D sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
104
			(t2 * z1 - t1 * z2) * r);
105
		Vector3D tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
106
			(s1 * z2 - s2 * z1) * r);
107
 
108
		tan1[i1] += sdir;
109
		tan1[i2] += sdir;
110
		tan1[i3] += sdir;
111
 
112
		tan2[i1] += tdir;
113
		tan2[i2] += tdir;
114
		tan2[i3] += tdir;
115
 
116
		triangle++;
117
	}
118
#endif
119
}
120
 
121
const material* mesh::get_material(void) const
122
{
123
	return mat_;
124
}
125
 
126
void mesh::set_material(const material* m)
127
{
128
	mat_ = m;
129
}
130
 
131
bool mesh::sample(const ray& r, 
132
				  const hit_info& hi, 
133
				  Vec3f& Li, 
134
				  Vec3f& w) const
135
{
136
	//skip non-emitters
137
	if (intensity(exitance_) == 0.f)
138
		return false;
139
 
140
	//pick a random face
141
	int face = rand() % msh_->geometry.no_faces();
142
	float pface = 1.f / float(msh_->geometry.no_faces());
143
 
144
	//pick a random position in triangle
145
	float r1 = std::sqrt(random());
146
	float r2 = random();
147
	Vec3f barycentric(1.f - r1, (1.f - r2) * r1, r1 * r2);
148
 
149
	//find position
150
	Vec3i fidx = msh_->geometry.face(face);
151
	Vec3f vertices[3];
152
	Vec3f light_pos(0.f);
153
	for (int i=0; i<3; ++i)
154
	{
155
		vertices[i] = msh_->geometry.vertex(fidx[i]);
156
		light_pos += barycentric[i] * msh_->geometry.vertex(fidx[i]);
157
	}
158
 
159
	light_pos = trs_.mul_3D_point(light_pos);
160
 
161
	float parea = 2.f / length(cross(vertices[2]-vertices[1], 
162
		vertices[0]-vertices[1]));
163
 
164
	//find normal
165
	Vec3i nidx = msh_->normals.face(face);
166
	Vec3f light_normal(0.f);
167
	for (int i=0; i<3; ++i)
168
		light_normal += barycentric[i] * msh_->normals.vertex(nidx[i]);
169
	light_normal = trs_.mul_3D_vector(light_normal);
170
	light_normal.normalize();
171
 
172
	//find w
173
	w = normalize(light_pos - hi.position);
174
	//float costheta1 = dot(hi.shading_normal, w);
175
	//if (costheta1 < 0.f)
176
	//	return false;
177
 
178
	float costheta2 = dot(light_normal, -w);
179
	if (costheta2 < 0.f)
180
		return false;
181
 
182
	float d2 = sqr_length(light_pos - hi.position);
183
 
184
	//trace shadow feeler..
185
	ray s;
186
	s.origin = hi.position + epsilon * w;
187
	s.direction = w;
188
	s.distance = std::sqrt(d2) - 2.f * epsilon;
189
	s.depth = r.depth + 1;
190
	if (current->intersect(s))
191
		return false;
192
 
193
	//compute emitted
194
	Li = exitance_ / float(M_PI) * costheta2 / (d2 * pface * parea);
195
 
196
	return true;
197
}
198
 
199
Vec3f mesh::exitance(void) const
200
{
201
	return exitance_;
202
}
203
 
204
void mesh::set_exitance(const CGLA::Vec3f& E)
205
{
206
	exitance_ = E;
207
}
208
 
209
//02566 framework, Anders Wang Kristensen, awk@imm.dtu.dk, 2007