~gimaker/peekabot/coord-sys-default

« back to all changes in this revision

Viewing changes to src/renderer/entities/Camera.cc

  • Committer: Staffan Gimåker
  • Date: 2009-06-29 10:09:26 UTC
  • mfrom: (665.1.39 renderer-redux)
  • Revision ID: staffan@gimaker.se-20090629100926-ju5kx8jwzy422rwu
Merged the renderer-redux branch.

This represents a major overhaul to the rendering engine, with a less contrived
design and better performance. Both memory and CPU utilization should be 
better in general.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
 
2
 * Copyright Staffan Gimåker 2006-2009.
 
3
 *
 
4
 * ---
 
5
 *
2
6
 * This file is part of peekabot.
3
7
 *
4
8
 * peekabot is free software; you can redistribute it and/or modify
17
21
 
18
22
#include <cmath>
19
23
#include <GL/glew.h>
 
24
 
20
25
#include "Camera.hh"
21
26
#include "../BoundingVolumes.hh"
22
 
#include "../SceneNode.hh"
23
27
#include "../Frustum.hh"
24
28
#include "../RenderContext.hh"
 
29
#include "../PrepareRenderContext.hh"
25
30
 
26
31
using namespace peekabot;
27
32
using namespace peekabot::renderer;
28
 
using namespace peekabot::renderer::primitives;
29
 
 
30
 
 
31
 
static const real32 DEG_TO_RAD = M_PI/180.0f;
 
33
 
 
34
 
 
35
static const float DEG_TO_RAD = M_PI/180.0f;
32
36
 
33
37
 
34
38
Camera::Camera(bool is_ortho,
35
 
               real32 fov,
36
 
               real32 near,
37
 
               real32 far,
 
39
               float fov,
 
40
               float near,
 
41
               float far,
38
42
               float zoom_distance) throw()
39
43
    : m_fov(fov),
40
44
      m_fov_rad(m_fov * DEG_TO_RAD),
45
49
      m_x(0), m_y(0),
46
50
      m_w(100), m_h(100)
47
51
{
 
52
    calculate_bvs();
 
53
    calculate_viewer_mtow();
48
54
    get_state().set(new statelets::Lighting(false));
49
55
}
50
56
 
61
67
}
62
68
 
63
69
 
64
 
void Camera::get_renderables(
65
 
    Camera *camera, EnumerationCallback callback) throw()
 
70
void Camera::get_renderables(PrepareRenderContext &context) const
66
71
{
67
 
    if( camera != this )
 
72
    if( context.get_camera() != this )
68
73
    {
69
 
        callback(this);
 
74
        context.prepare(this);
70
75
    }
71
76
}
72
77
 
98
103
}
99
104
 
100
105
 
101
 
void Camera::set_fov(real32 fov) throw()
 
106
void Camera::set_fov(float fov) throw()
102
107
{
103
108
    if( fov != m_fov )
104
109
    {
111
116
}
112
117
 
113
118
 
114
 
real32 Camera::get_fov() const throw()
 
119
float Camera::get_fov() const throw()
115
120
{
116
121
    return m_fov;
117
122
}
118
123
 
119
124
 
120
 
void Camera::set_near_plane(real32 y_distance) throw()
 
125
void Camera::set_near_plane(float y_distance) throw()
121
126
{
122
127
    if( y_distance != m_near )
123
128
    {
124
129
        m_near = y_distance;
125
130
 
126
131
        invalidate_cached_frustums();
 
132
        calculate_bvs();
127
133
    }
128
134
}
129
135
 
130
136
 
131
 
void Camera::set_far_plane(real32 y_distance) throw()
 
137
void Camera::set_far_plane(float y_distance) throw()
132
138
{
133
139
    if( y_distance != m_far )
134
140
    {
148
154
 
149
155
        invalidate_cached_frustums();
150
156
        calculate_bvs();
 
157
        calculate_viewer_mtow();
151
158
    }
152
159
}
153
160
 
165
172
        m_is_ortho = is_ortho;
166
173
 
167
174
        invalidate_cached_frustums();
 
175
        calculate_bvs();
168
176
    }
169
177
}
170
178
 
181
189
 
182
190
    if( is_orthographic() )
183
191
    {
184
 
        real32 d = m_zoom_distance;
185
 
        real32 aspect = static_cast<real32>(m_w)/m_h;
186
 
        real32 half_h = d*tanf(m_fov_rad/2);
187
 
        real32 half_w = half_h*aspect;
 
192
        float d = m_zoom_distance;
 
193
        float aspect = static_cast<float>(m_w)/m_h;
 
194
        float half_h = d*tanf(m_fov_rad/2);
 
195
        float half_w = half_h*aspect;
188
196
 
189
197
        glOrtho(-half_w, half_w, -half_h, half_h, m_near, m_far);
190
198
    }
191
199
    else
192
200
    {
193
 
        gluPerspective(m_fov, static_cast<real32>(m_w)/m_h, m_near, m_far);
 
201
        gluPerspective(m_fov, static_cast<float>(m_w)/m_h, m_near, m_far);
194
202
    }
195
203
 
196
204
    glMatrixMode(GL_MODELVIEW);
199
207
 
200
208
void Camera::calculate_bvs() throw()
201
209
{
202
 
    // 1. Calculate object BVs
203
 
    const Matrix4r &vmtow = get_viewer_mtow();
204
 
 
 
210
    // Calculate BVs
 
211
    //
205
212
    // The point furthest away from the center of the BV must either
206
213
    // lie in the corner of the frustum of at the edge of the slope
207
214
    // on the arrow.
210
217
    // that yields the greatest distance is (always) the tip of the arrow.
211
218
    // Thus, we need only consider two cases - the distance to the corner
212
219
    // and arrow tip respectively.
213
 
   
 
220
 
214
221
    BoundingSphere bsphere;
215
222
 
216
223
    float base = (m_near * tanf(m_fov_rad/2));
220
227
    if( std::max(arrowtipdist, cornerdist) > m_zoom_distance/2 )
221
228
    {
222
229
        bsphere.set_radius(std::max(arrowtipdist, cornerdist));
223
 
        bsphere.set_pos( vmtow(3) + get_view_vector()*m_near/2 );
 
230
        bsphere.set_pos(Vector3f(-m_near/2, 0, 0));
224
231
    }
225
232
    else
226
233
    {
227
234
        bsphere.set_radius(m_zoom_distance/2);
228
 
        bsphere.set_pos( vmtow(3) + get_view_vector()*m_zoom_distance/2 );
 
235
        bsphere.set_pos(Vector3f(-m_zoom_distance/2, 0, 0));
229
236
    }
230
237
 
231
238
    set_bounding_sphere(bsphere);
232
 
    
233
 
 
234
 
    // 2. Frustum BVs - If BVs are invalid then frustum BVs must also be...
235
 
    invalidate_cached_frustums();
236
 
}
237
 
 
238
 
 
239
 
 
240
 
const Vector4r &Camera::get_view_vector() const throw()
241
 
{
242
 
    return get_parent()->get_mtow()(0);
243
 
}
244
 
 
245
 
 
246
 
const Vector4r &Camera::get_up_vector() const throw()
247
 
{
248
 
    return get_parent()->get_mtow()(2);
249
 
}
250
 
 
251
 
 
252
 
Matrix4r Camera::get_viewer_mtow() const throw()
253
 
{
254
 
    return get_parent()->get_mtow() * Matrix4r::translate(
255
 
        -m_zoom_distance, 0, 0);
256
 
}
257
 
 
258
 
 
259
 
Vector4r Camera::get_viewer_world_pos() const throw()
260
 
{
261
 
    return get_viewer_mtow()(3);
262
239
}
263
240
 
264
241
 
287
264
}
288
265
 
289
266
 
290
 
void Camera::render(RenderContext &context) throw()
 
267
void Camera::render(RenderContext &context) const
291
268
{
292
269
    float offset = -m_zoom_distance;
293
270
 
294
271
    // Half the base width/height
295
 
    real32 base = (m_near * tanf(m_fov_rad/2));
 
272
    float base = (m_near * tanf(m_fov_rad/2));
296
273
 
297
274
    glBegin(GL_LINE_LOOP);
298
275
    glVertex3f(m_near+offset, -base,  base);
371
348
    glPopAttrib();
372
349
}
373
350
 
 
351
 
 
352
void Camera::on_transformation_set()
 
353
{
 
354
    calculate_bvs();
 
355
    invalidate_cached_frustums();
 
356
    calculate_viewer_mtow();
 
357
    CullableEntity::on_transformation_set();
 
358
}
 
359
 
 
360
 
 
361
void Camera::calculate_viewer_mtow()
 
362
{
 
363
    m_viewer_mtow =  get_transformation() * Matrix4f::translate(
 
364
        -m_zoom_distance, 0, 0);
 
365
}
 
366