Change Encyclo button name and macros icon
[ryzomcore.git] / nel / src / 3d / camera.cpp
blob012402b745875914199e91ad77f1d38d0e4e7ec9
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "std3d.h"
19 #include "nel/3d/camera.h"
20 #include "nel/3d/scene.h"
22 #ifdef DEBUG_NEW
23 #define new DEBUG_NEW
24 #endif
26 namespace NL3D
30 // ***************************************************************************
31 void CCamera::registerBasic()
33 CScene::registerModel(CameraId, TransformId, CCamera::creator);
37 // ***************************************************************************
38 CCamera::CCamera()
40 setFrustum(1.0f, 1.0f, 0.01f, 1.0f);
42 // IAnimatable.
43 IAnimatable::resize(AnimValueLast);
45 _FovAnimationEnabled= false;
46 _TargetAnimationEnabled= false;
47 _FovAnimationAspectRatio= 4.0f/3.0f;
49 // Default Anims.
50 _Fov.Value= (float)NLMISC::Pi/2;
51 _Target.Value= CVector::Null;
52 _Roll.Value= 0;
54 // ***************************************************************************
55 void CCamera::setFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective)
57 _Frustum.init( left, right,bottom, top, znear, zfar, perspective);
59 // ***************************************************************************
60 void CCamera::setFrustum(float width, float height, float znear, float zfar, bool perspective)
62 _Frustum.init(width, height, znear, zfar, perspective);
64 // ***************************************************************************
65 void CCamera::setPerspective(float fov, float aspectRatio, float znear, float zfar)
67 _Frustum.initPerspective(fov, aspectRatio, znear, zfar);
69 // ***************************************************************************
70 void CCamera::getFrustum(float &left, float &right, float &bottom, float &top, float &znear, float &zfar) const
72 left= _Frustum.Left;
73 right= _Frustum.Right;
74 bottom= _Frustum.Bottom;
75 top= _Frustum.Top;
76 znear= _Frustum.Near;
77 zfar= _Frustum.Far;
79 // ***************************************************************************
80 bool CCamera::isOrtho() const
82 return !_Frustum.Perspective;
84 // ***************************************************************************
85 bool CCamera::isPerspective() const
87 return _Frustum.Perspective;
91 // ***************************************************************************
92 // ***************************************************************************
93 // Anims.
94 // ***************************************************************************
95 // ***************************************************************************
99 // ***************************************************************************
100 IAnimatedValue* CCamera::getValue (uint valueId)
102 // what value ?
103 switch (valueId)
105 case FovValue: return &_Fov;
106 case TargetValue: return &_Target;
107 case RollValue: return &_Roll;
110 return CTransform::getValue(valueId);
112 // ***************************************************************************
113 const char *CCamera::getValueName (uint valueId) const
115 // what value ?
116 switch (valueId)
118 case FovValue: return getFovValueName();
119 case TargetValue: return getTargetValueName();
120 case RollValue: return getRollValueName();
123 return CTransform::getValueName(valueId);
126 // ***************************************************************************
127 CTrackDefaultFloat CCamera::DefaultFov( (float)NLMISC::Pi/2 );
128 CTrackDefaultFloat CCamera::DefaultRoll( 0 );
131 ITrack* CCamera::getDefaultTrack (uint valueId)
133 // what value ?
134 switch (valueId)
136 case PosValue: return &_DefaultPos;
137 case FovValue: return &DefaultFov;
138 case TargetValue: return &_DefaultTargetPos;
139 case RollValue: return &DefaultRoll;
142 return CTransform::getDefaultTrack(valueId);
144 // ***************************************************************************
145 void CCamera::registerToChannelMixer(CChannelMixer *chanMixer, const std::string &prefix)
147 // For CCamera, channels are not detailled.
148 addValue(chanMixer, FovValue, OwnerBit, prefix, false);
149 addValue(chanMixer, TargetValue, OwnerBit, prefix, false);
150 addValue(chanMixer, RollValue, OwnerBit, prefix, false);
152 CTransform::registerToChannelMixer(chanMixer, prefix);
157 // ***************************************************************************
158 void CCamera::update()
160 // test animations
161 if(IAnimatable::isTouched(OwnerBit) || IAnimatable::isTouched(ITransformable::OwnerBit))
163 // FOV.
164 if( _FovAnimationEnabled && IAnimatable::isTouched(FovValue))
166 // keep the same near/far.
167 setPerspective(_Fov.Value, _FovAnimationAspectRatio, _Frustum.Near, _Frustum.Far);
168 IAnimatable::clearFlag(FovValue);
171 // Target / Roll.
172 // If target/Roll is animated, compute our own quaternion.
173 if( _TargetAnimationEnabled && (IAnimatable::isTouched(TargetValue) || IAnimatable::isTouched(RollValue) || IAnimatable::isTouched(PosValue)) )
175 lookAt (getPos (), _Target.Value, -_Roll.Value);
177 IAnimatable::clearFlag(TargetValue);
178 IAnimatable::clearFlag(RollValue);
182 CTransform::update();
184 // We are OK!
185 IAnimatable::clearFlag(OwnerBit);
189 // ***************************************************************************
190 void CCamera::build (const CCameraInfo &cameraInfo)
192 // Target ?
193 enableTargetAnimation(cameraInfo.TargetMode);
194 enableFovAnimation(cameraInfo.UseFov);
195 if (cameraInfo.TargetMode)
197 // Set the rot model
198 setTransformMode (ITransformable::RotQuat);
199 setTargetPos (cameraInfo.TargetPos);
200 _DefaultTargetPos.setDefaultValue (cameraInfo.TargetPos);
201 setRoll (cameraInfo.Roll);
203 if (cameraInfo.UseFov)
205 setFov (cameraInfo.Fov);
207 setPos (cameraInfo.Pos);
208 _DefaultPos.setDefaultValue (cameraInfo.Pos);
212 // ***************************************************************************
213 CCameraInfo::CCameraInfo ()
215 Roll = 0;
216 Fov = 0;
217 TargetMode = false;
218 UseFov = false;
222 // ***************************************************************************
223 void CCameraInfo::serial (NLMISC::IStream &s)
225 s.serialVersion (0);
227 s.serial (Pos);
228 s.serial (TargetPos);
229 s.serial (Roll);
230 s.serial (Fov);
231 s.serial (TargetMode);
232 s.serial (UseFov);
236 // ***************************************************************************
237 void CCamera::buildCameraPyramid(std::vector<CPlane> &pyramid, bool useWorldMatrix)
239 pyramid.resize(6);
241 // Compute pyramid in view basis.
242 CVector pfoc(0,0,0);
243 CVector lb(_Frustum.Left, _Frustum.Near, _Frustum.Bottom );
244 CVector lt(_Frustum.Left, _Frustum.Near, _Frustum.Top );
245 CVector rb(_Frustum.Right, _Frustum.Near, _Frustum.Bottom );
246 CVector rt(_Frustum.Right, _Frustum.Near, _Frustum.Top );
248 CVector lbFar(_Frustum.Left, _Frustum.Far, _Frustum.Bottom);
249 CVector ltFar(_Frustum.Left, _Frustum.Far, _Frustum.Top );
250 CVector rbFar(_Frustum.Right, _Frustum.Far, _Frustum.Bottom);
251 CVector rtFar(_Frustum.Right, _Frustum.Far, _Frustum.Top );
253 // near
254 pyramid[0].make(lt, lb, rt);
255 // far
256 pyramid[1].make(lbFar, ltFar, rtFar);
258 if(_Frustum.Perspective)
260 // left
261 pyramid[2].make(pfoc, lt, lb);
262 // top
263 pyramid[3].make(pfoc, rt, lt);
264 // right
265 pyramid[4].make(pfoc, rb, rt);
266 // bottom
267 pyramid[5].make(pfoc, lb, rb);
269 else
271 // left
272 pyramid[2].make(lt, ltFar, lbFar);
273 // top
274 pyramid[3].make(lt, rtFar, ltFar);
275 // right
276 pyramid[4].make(rt, rbFar, rtFar);
277 // bottom
278 pyramid[5].make(lb, lbFar, rbFar);
281 // get invCamMatrix
282 CMatrix invCamMatrix;
283 if(useWorldMatrix)
284 invCamMatrix= getWorldMatrix();
285 else
286 invCamMatrix= getMatrix();
287 invCamMatrix.invert();
289 // Compute pyramid in World basis.
290 // The vector transformation M of a plane p is computed as p*M-1.
291 for (uint i = 0; i < 6; i++)
293 pyramid[i]= pyramid[i]*invCamMatrix;
297 // ***************************************************************************
298 void CCamera::buildCameraPyramidCorners(std::vector<NLMISC::CVector> &pyramidCorners, bool useWorldMatrix)
300 pyramidCorners.resize(8);
301 pyramidCorners[0].set(_Frustum.Left, _Frustum.Near, _Frustum.Bottom );
302 pyramidCorners[1].set(_Frustum.Left, _Frustum.Near, _Frustum.Top );
303 pyramidCorners[2].set(_Frustum.Right, _Frustum.Near, _Frustum.Bottom );
304 pyramidCorners[3].set(_Frustum.Right, _Frustum.Near, _Frustum.Top );
305 float f = _Frustum.Perspective ? (_Frustum.Far / _Frustum.Near) : 1.f;
306 pyramidCorners[4].set(f * _Frustum.Left, _Frustum.Far, f * _Frustum.Bottom);
307 pyramidCorners[5].set(f * _Frustum.Left, _Frustum.Far, f * _Frustum.Top );
308 pyramidCorners[6].set(f * _Frustum.Right, _Frustum.Far, f * _Frustum.Bottom);
309 pyramidCorners[7].set(f * _Frustum.Right, _Frustum.Far, f * _Frustum.Top );
311 const CMatrix &camMatrix = useWorldMatrix ? getWorldMatrix() : getMatrix();
312 for(uint k = 0; k < 8; ++k)
314 pyramidCorners[k] = camMatrix * pyramidCorners[k];