Subversion Repositories gelsvn

Rev

Rev 350 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
346 awk 1
#include <Geometry/BSPTree.h>
2
 
353 awk 3
#include "scene.h"
4
#include "mesh.h"
346 awk 5
 
6
using namespace Geometry;
7
using namespace CGLA;
8
 
9
scene::scene(void) : cam_(0)
10
{
349 awk 11
    accel_ = new BSPTree;
346 awk 12
}
13
 
14
scene::~scene(void)
15
{
349 awk 16
    delete accel_;
346 awk 17
}
18
 
19
void scene::insert(const luminaire* obj)
20
{
349 awk 21
    objs_.push_back(obj);
346 awk 22
}
23
 
24
size_t scene::luminaires(void) const
25
{
349 awk 26
    return objs_.size();
346 awk 27
}
28
 
29
const luminaire* scene::get_luminaire(size_t i) const
30
{
349 awk 31
    return objs_.at(i);
346 awk 32
}
33
 
34
bool scene::intersect(const ray& r)
35
{
349 awk 36
    Ray s;
37
    s.direction = r.direction;
38
    s.origin = r.origin;
39
    s.dist = r.distance;
40
    s.trace_depth = r.depth;
346 awk 41
 
349 awk 42
    return accel_->intersect(s);
346 awk 43
}
44
 
45
bool scene::intersect(const ray& r, hit_info& hi)
46
{
349 awk 47
    Ray s;
48
    s.direction = r.direction;
49
    s.origin = r.origin;
50
    s.trace_depth = r.depth;
51
    s.dist = r.distance;
346 awk 52
 
349 awk 53
    bool hit = accel_->intersect(s);
346 awk 54
 
349 awk 55
    if (hit)
56
    {
57
        //find the mesh which was hit
58
        const mesh& msh = dynamic_cast<const mesh&>(*objs_[s.id]);
346 awk 59
 
349 awk 60
        //set hit position and normals
61
        hi.distance = s.dist;
62
        hi.position = s.hit_pos;
63
        hi.shading_normal = s.hit_normal;
346 awk 64
 
349 awk 65
        const IndexedFaceSet& geometry = msh.get_trimesh().geometry;
66
        const Vec3i& f  = geometry.face(s.hit_face_id);
67
        const Vec3f p0 = geometry.vertex(f[0]);
68
        const Vec3f a  = geometry.vertex(f[1]) - p0;
69
        const Vec3f b  = geometry.vertex(f[2]) - p0;
70
        Vec3f face_normal = cross(a,b);
71
        float l = sqr_length(face_normal);
72
        if(l > 0.0f)
73
            face_normal /= sqrt(l);
346 awk 74
 
349 awk 75
        hi.geometric_normal = msh.transform().mul_3D_vector(face_normal);
76
        //hi.geometric_normal = msh.triangle_normal(s.hit_face_id);
346 awk 77
 
349 awk 78
        hi.inside = dot(hi.geometric_normal, -s.direction) < 0.f;
79
        if (hi.inside)
80
        {
81
            hi.geometric_normal = -hi.geometric_normal;
82
            hi.shading_normal = -hi.shading_normal;
83
        }
346 awk 84
 
349 awk 85
        bool has_texcoords = msh.get_trimesh().texcoords.no_faces() > 0;
346 awk 86
 
349 awk 87
        if (has_texcoords)
88
        {
89
            //compute texture coords..
90
            const IndexedFaceSet& texcoords = msh.get_trimesh().texcoords;
91
            const Vec3i& t = texcoords.face(s.hit_face_id);
92
            Vec3f uv0 = texcoords.vertex(t[0]);
93
            Vec3f uv1 = texcoords.vertex(t[1]);
94
            Vec3f uv2 = texcoords.vertex(t[2]);
95
            hi.texcoords(0) = (1.f-s.u-s.v)*uv0(0) + s.u*uv1(0) + s.v*uv2(0);
96
            hi.texcoords(1) = (1.f-s.u-s.v)*uv0(1) + s.u*uv1(1) + s.v*uv2(1);
346 awk 97
 
349 awk 98
            //compute tangent vectors..
346 awk 99
 
349 awk 100
 
101
        }
102
        else
103
        {
104
            //hmm.. no uvs. not good!
105
            hi.texcoords = Vec2f(0.f);
106
            //orthogonal(hi.shading_normal, hi.tangent, hi.bitangent);
107
        }
108
 
109
        //sample material to get bsdf
110
        const material* mat = msh.get_material();
111
        if (mat)
112
            mat->sample(r, hi);
113
 
114
        //convert from radiant exitance to radiance
115
        if (!hi.inside)
116
            hi.emitted = msh.exitance() / float(M_PI);
117
    }
118
 
119
    return hit;
346 awk 120
}
121
 
122
const camera* scene::get_camera(void) const
123
{
349 awk 124
    return cam_;
346 awk 125
}
126
 
127
void scene::set_camera(const camera* c)
128
{
349 awk 129
    cam_ = c;
346 awk 130
}
131
 
132
void scene::initialize(int mo, int md)
133
{
349 awk 134
    assert(cam_);
135
    assert(!objs_.empty());
346 awk 136
 
349 awk 137
    std::vector<const TriMesh*> msh;
138
    std::vector<Mat4x4f> trs;
346 awk 139
 
349 awk 140
    std::vector<const luminaire*>::iterator it;
141
    for (it=objs_.begin(); it!=objs_.end(); ++it)
142
    {
143
        const luminaire* obj = *it;
346 awk 144
 
349 awk 145
        const mesh* mxx = dynamic_cast<const mesh*>(obj);
146
        if (!mxx)
147
            continue;
346 awk 148
 
349 awk 149
        msh.push_back(&mxx->get_trimesh());
150
        trs.push_back(mxx->transform());
151
    }
152
 
153
    accel_->init(msh, trs, mo, md);
154
    accel_->build();
346 awk 155
}
156
 
157
//02566 framework, Anders Wang Kristensen, awk@imm.dtu.dk, 2007