aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp385
1 files changed, 385 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp
new file mode 100644
index 0000000..370b893
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp
@@ -0,0 +1,385 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CCameraSceneNode.h"
6#include "ISceneManager.h"
7#include "IVideoDriver.h"
8#include "os.h"
9
10namespace irr
11{
12namespace scene
13{
14
15
16//! constructor
17CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
18 const core::vector3df& position, const core::vector3df& lookat)
19 : ICameraSceneNode(parent, mgr, id, position),
20 Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f),
21 InputReceiverEnabled(true), TargetAndRotationAreBound(false)
22{
23 #ifdef _DEBUG
24 setDebugName("CCameraSceneNode");
25 #endif
26
27 // set default projection
28 Fovy = core::PI / 2.5f; // Field of view, in radians.
29
30 const video::IVideoDriver* const d = mgr?mgr->getVideoDriver():0;
31 if (d)
32 Aspect = (f32)d->getCurrentRenderTargetSize().Width /
33 (f32)d->getCurrentRenderTargetSize().Height;
34 else
35 Aspect = 4.0f / 3.0f; // Aspect ratio.
36
37 recalculateProjectionMatrix();
38 recalculateViewArea();
39}
40
41
42//! Disables or enables the camera to get key or mouse inputs.
43void CCameraSceneNode::setInputReceiverEnabled(bool enabled)
44{
45 InputReceiverEnabled = enabled;
46}
47
48
49//! Returns if the input receiver of the camera is currently enabled.
50bool CCameraSceneNode::isInputReceiverEnabled() const
51{
52 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
53 return InputReceiverEnabled;
54}
55
56
57//! Sets the projection matrix of the camera.
58/** The core::matrix4 class has some methods
59to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH
60\param projection: The new projection matrix of the camera. */
61void CCameraSceneNode::setProjectionMatrix(const core::matrix4& projection, bool isOrthogonal)
62{
63 IsOrthogonal = isOrthogonal;
64 ViewArea.getTransform ( video::ETS_PROJECTION ) = projection;
65}
66
67
68//! Gets the current projection matrix of the camera
69//! \return Returns the current projection matrix of the camera.
70const core::matrix4& CCameraSceneNode::getProjectionMatrix() const
71{
72 return ViewArea.getTransform ( video::ETS_PROJECTION );
73}
74
75
76//! Gets the current view matrix of the camera
77//! \return Returns the current view matrix of the camera.
78const core::matrix4& CCameraSceneNode::getViewMatrix() const
79{
80 return ViewArea.getTransform ( video::ETS_VIEW );
81}
82
83
84//! Sets a custom view matrix affector. The matrix passed here, will be
85//! multiplied with the view matrix when it gets updated.
86//! This allows for custom camera setups like, for example, a reflection camera.
87/** \param affector: The affector matrix. */
88void CCameraSceneNode::setViewMatrixAffector(const core::matrix4& affector)
89{
90 Affector = affector;
91}
92
93
94//! Gets the custom view matrix affector.
95const core::matrix4& CCameraSceneNode::getViewMatrixAffector() const
96{
97 return Affector;
98}
99
100
101//! It is possible to send mouse and key events to the camera. Most cameras
102//! may ignore this input, but camera scene nodes which are created for
103//! example with scene::ISceneManager::addMayaCameraSceneNode or
104//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input
105//! for changing their position, look at target or whatever.
106bool CCameraSceneNode::OnEvent(const SEvent& event)
107{
108 if (!InputReceiverEnabled)
109 return false;
110
111 // send events to event receiving animators
112
113 ISceneNodeAnimatorList::Iterator ait = Animators.begin();
114
115 for (; ait != Animators.end(); ++ait)
116 if ((*ait)->isEventReceiverEnabled() && (*ait)->OnEvent(event))
117 return true;
118
119 // if nobody processed the event, return false
120 return false;
121}
122
123
124//! sets the look at target of the camera
125//! \param pos: Look at target of the camera.
126void CCameraSceneNode::setTarget(const core::vector3df& pos)
127{
128 Target = pos;
129
130 if(TargetAndRotationAreBound)
131 {
132 const core::vector3df toTarget = Target - getAbsolutePosition();
133 ISceneNode::setRotation(toTarget.getHorizontalAngle());
134 }
135}
136
137
138//! Sets the rotation of the node.
139/** This only modifies the relative rotation of the node.
140If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
141then calling this will also change the camera's target to match the rotation.
142\param rotation New rotation of the node in degrees. */
143void CCameraSceneNode::setRotation(const core::vector3df& rotation)
144{
145 if(TargetAndRotationAreBound)
146 Target = getAbsolutePosition() + rotation.rotationToDirection();
147
148 ISceneNode::setRotation(rotation);
149}
150
151
152//! Gets the current look at target of the camera
153//! \return Returns the current look at target of the camera
154const core::vector3df& CCameraSceneNode::getTarget() const
155{
156 return Target;
157}
158
159
160//! sets the up vector of the camera
161//! \param pos: New upvector of the camera.
162void CCameraSceneNode::setUpVector(const core::vector3df& pos)
163{
164 UpVector = pos;
165}
166
167
168//! Gets the up vector of the camera.
169//! \return Returns the up vector of the camera.
170const core::vector3df& CCameraSceneNode::getUpVector() const
171{
172 return UpVector;
173}
174
175
176f32 CCameraSceneNode::getNearValue() const
177{
178 return ZNear;
179}
180
181
182f32 CCameraSceneNode::getFarValue() const
183{
184 return ZFar;
185}
186
187
188f32 CCameraSceneNode::getAspectRatio() const
189{
190 return Aspect;
191}
192
193
194f32 CCameraSceneNode::getFOV() const
195{
196 return Fovy;
197}
198
199
200void CCameraSceneNode::setNearValue(f32 f)
201{
202 ZNear = f;
203 recalculateProjectionMatrix();
204}
205
206
207void CCameraSceneNode::setFarValue(f32 f)
208{
209 ZFar = f;
210 recalculateProjectionMatrix();
211}
212
213
214void CCameraSceneNode::setAspectRatio(f32 f)
215{
216 Aspect = f;
217 recalculateProjectionMatrix();
218}
219
220
221void CCameraSceneNode::setFOV(f32 f)
222{
223 Fovy = f;
224 recalculateProjectionMatrix();
225}
226
227
228void CCameraSceneNode::recalculateProjectionMatrix()
229{
230 ViewArea.getTransform ( video::ETS_PROJECTION ).buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar);
231}
232
233
234//! prerender
235void CCameraSceneNode::OnRegisterSceneNode()
236{
237 if ( SceneManager->getActiveCamera () == this )
238 SceneManager->registerNodeForRendering(this, ESNRP_CAMERA);
239
240 ISceneNode::OnRegisterSceneNode();
241}
242
243
244//! render
245void CCameraSceneNode::render()
246{
247 core::vector3df pos = getAbsolutePosition();
248 core::vector3df tgtv = Target - pos;
249 tgtv.normalize();
250
251 // if upvector and vector to the target are the same, we have a
252 // problem. so solve this problem:
253 core::vector3df up = UpVector;
254 up.normalize();
255
256 f32 dp = tgtv.dotProduct(up);
257
258 if ( core::equals(core::abs_<f32>(dp), 1.f) )
259 {
260 up.X += 0.5f;
261 }
262
263 ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up);
264 ViewArea.getTransform(video::ETS_VIEW) *= Affector;
265 recalculateViewArea();
266
267 video::IVideoDriver* driver = SceneManager->getVideoDriver();
268 if ( driver)
269 {
270 driver->setTransform(video::ETS_PROJECTION, ViewArea.getTransform ( video::ETS_PROJECTION) );
271 driver->setTransform(video::ETS_VIEW, ViewArea.getTransform ( video::ETS_VIEW) );
272 }
273}
274
275
276//! returns the axis aligned bounding box of this node
277const core::aabbox3d<f32>& CCameraSceneNode::getBoundingBox() const
278{
279 return ViewArea.getBoundingBox();
280}
281
282
283//! returns the view frustum. needed sometimes by bsp or lod render nodes.
284const SViewFrustum* CCameraSceneNode::getViewFrustum() const
285{
286 return &ViewArea;
287}
288
289
290void CCameraSceneNode::recalculateViewArea()
291{
292 ViewArea.cameraPosition = getAbsolutePosition();
293
294 core::matrix4 m(core::matrix4::EM4CONST_NOTHING);
295 m.setbyproduct_nocheck(ViewArea.getTransform(video::ETS_PROJECTION),
296 ViewArea.getTransform(video::ETS_VIEW));
297 ViewArea.setFrom(m);
298}
299
300
301//! Writes attributes of the scene node.
302void CCameraSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
303{
304 ICameraSceneNode::serializeAttributes(out, options);
305
306 out->addVector3d("Target", Target);
307 out->addVector3d("UpVector", UpVector);
308 out->addFloat("Fovy", Fovy);
309 out->addFloat("Aspect", Aspect);
310 out->addFloat("ZNear", ZNear);
311 out->addFloat("ZFar", ZFar);
312 out->addBool("Binding", TargetAndRotationAreBound);
313 out->addBool("ReceiveInput", InputReceiverEnabled);
314}
315
316//! Reads attributes of the scene node.
317void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
318{
319 ICameraSceneNode::deserializeAttributes(in, options);
320
321 Target = in->getAttributeAsVector3d("Target");
322 UpVector = in->getAttributeAsVector3d("UpVector");
323 Fovy = in->getAttributeAsFloat("Fovy");
324 Aspect = in->getAttributeAsFloat("Aspect");
325 ZNear = in->getAttributeAsFloat("ZNear");
326 ZFar = in->getAttributeAsFloat("ZFar");
327 TargetAndRotationAreBound = in->getAttributeAsBool("Binding");
328 if ( in->findAttribute("ReceiveInput") )
329 InputReceiverEnabled = in->getAttributeAsBool("InputReceiverEnabled");
330
331 recalculateProjectionMatrix();
332 recalculateViewArea();
333}
334
335
336//! Set the binding between the camera's rotation adn target.
337void CCameraSceneNode::bindTargetAndRotation(bool bound)
338{
339 TargetAndRotationAreBound = bound;
340}
341
342
343//! Gets the binding between the camera's rotation and target.
344bool CCameraSceneNode::getTargetAndRotationBinding(void) const
345{
346 return TargetAndRotationAreBound;
347}
348
349
350//! Creates a clone of this scene node and its children.
351ISceneNode* CCameraSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
352{
353 ICameraSceneNode::clone(newParent, newManager);
354
355 if (!newParent)
356 newParent = Parent;
357 if (!newManager)
358 newManager = SceneManager;
359
360 CCameraSceneNode* nb = new CCameraSceneNode(newParent,
361 newManager, ID, RelativeTranslation, Target);
362
363 nb->ISceneNode::cloneMembers(this, newManager);
364 nb->ICameraSceneNode::cloneMembers(this);
365
366 nb->Target = Target;
367 nb->UpVector = UpVector;
368 nb->Fovy = Fovy;
369 nb->Aspect = Aspect;
370 nb->ZNear = ZNear;
371 nb->ZFar = ZFar;
372 nb->ViewArea = ViewArea;
373 nb->Affector = Affector;
374 nb->InputReceiverEnabled = InputReceiverEnabled;
375 nb->TargetAndRotationAreBound = TargetAndRotationAreBound;
376
377 if ( newParent )
378 nb->drop();
379 return nb;
380}
381
382
383} // end namespace
384} // end namespace
385