Subversion Repositories gelsvn

Rev

Rev 346 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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