-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCamera.cpp
executable file
·136 lines (112 loc) · 2.98 KB
/
Camera.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <stdio.h>
#include <stdlib.h>
#include "Miro.h"
#include "Camera.h"
#include "Image.h"
#include "Scene.h"
#include "Console.h"
#include "OpenGL.h"
Camera * g_camera = 0;
static bool firstRayTrace = true;
Camera::Camera() :
m_bgColor(0,0,0),
m_renderer(RENDER_OPENGL),
m_eye(0,0,0),
m_viewDir(0,0,-1),
m_up(0,1,0),
m_lookAt(FLT_MAX, FLT_MAX, FLT_MAX),
m_fov(45),
m_distance(0.038627416998),
m_focal_distance(0.04),
m_lens_size(0.03),
m_lens(false)
{
calcLookAt();
}
Camera::~Camera()
{
}
void
Camera::click(Scene* pScene, Image* pImage)
{
calcLookAt();
static bool firstRayTrace = false;
if (m_renderer == RENDER_OPENGL)
{
glDrawBuffer(GL_BACK);
pScene->openGL(this);
firstRayTrace = true;
}
else if (m_renderer == RENDER_RAYTRACE)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDrawBuffer(GL_FRONT);
if (firstRayTrace)
{
pImage->clear(bgColor());
pScene->raytraceImage(this, g_image);
firstRayTrace = false;
}
g_image->draw();
}
}
void
Camera::calcLookAt()
{
// this is true when a "lookat" is not used in the config file
if (m_lookAt.x != FLT_MAX)
{
setLookAt(m_lookAt);
m_lookAt.set(FLT_MAX, FLT_MAX, FLT_MAX);
}
}
void
Camera::drawGL()
{
// set up the screen with our camera parameters
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov(), g_image->width() / (float)g_image->height(), 0.01, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Vector3 vCenter = eye() + viewDir();
gluLookAt(eye().x, eye().y, eye().z,
vCenter.x, vCenter.y, vCenter.z,
up().x, up().y, up().z);
}
Ray
Camera::eyeRay(int x, int y, int imageWidth, int imageHeight)
{
// first compute the camera coordinate system
// ------------------------------------------
const Vector3 wDir = Vector3(-m_viewDir).normalize();
const Vector3 uDir = cross(m_up, wDir).normalize();
const Vector3 vDir = cross(wDir, uDir);
// next compute the pixel location in the world coordinate system using the camera coordinate system
// --------------------------------------------------------
const float aspectRatio = (float)imageWidth / (float)imageHeight;
const float imPlaneUPos = -((x + 0.5f) / (float)imageWidth - 0.5f);
const float imPlaneVPos = -((y + 0.5f) / (float)imageHeight - 0.5f);
const Vector3 pixelPos = m_eye + (aspectRatio * FILM_SIZE * imPlaneUPos) * uDir + (FILM_SIZE * imPlaneVPos) * vDir + m_distance * wDir;
return Ray(pixelPos, (m_eye - pixelPos).normalize());
}
Vector3
Camera::randLensPoint()
{
// first compute the camera coordinate system
// ------------------------------------------
const Vector3 wDir = Vector3(-m_viewDir).normalize();
const Vector3 uDir = cross(m_up, wDir).normalize();
const Vector3 vDir = cross(wDir, uDir);
float x = 1.0;
float y = 1.0;
while (x*x + y*y > 1.0)
{
x = (2.0 * drand48() - 1.0)*m_lens_size;
y = (2.0 * drand48() - 1.0)*m_lens_size;
}
return m_eye + x * uDir + y * vDir;
}