Subversion Repositories gelsvn

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
671 khor 1
#include "mesh.h"
2
#include "scene.h"
3
 
685 khor 4
#include <Geometry/obj_load.h>
671 khor 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 = gel_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(mt_random());
146
    float r2 = mt_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