Fix crash
[ryzomcore.git] / snowballs2 / client / src / camera.cpp
blobfb5d12ea23c6543accb5ee7a418bda3f14de3756
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013-2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 // Includes
24 #include <nel/misc/types_nl.h>
26 #include <cmath>
27 #include <sstream>
28 #include <nel/misc/vectord.h>
29 #include <nel/misc/config_file.h>
30 #include <nel/3d/u_camera.h>
31 #include <nel/3d/u_driver.h>
32 #include <nel/3d/u_scene.h>
33 #include <nel/3d/u_instance.h>
34 #include <nel/3d/u_skeleton.h>
35 #include <nel/3d/u_visual_collision_entity.h>
36 #include <nel/3d/u_visual_collision_manager.h>
37 #include <nel/3d/u_cloud_scape.h>
38 #include <nel/3d/viewport.h>
40 #include <nel/3d/stereo_hmd.h>
42 #include "snowballs_client.h"
43 #include "entities.h"
44 #include "mouse_listener.h"
45 #include "pacs.h"
48 // Namespaces
51 using namespace std;
52 using namespace NLMISC;
53 using namespace NL3D;
55 namespace SBCLIENT {
58 // Variables
61 // The camera for the whole scene
62 UCamera Camera = NULL;
63 // The collision entity use to snap the camera on the ground
64 UVisualCollisionEntity *CamCollisionEntity = NULL;
66 // The particle system for the snowing effect
67 static UInstance Snow = NULL;
69 // The sky 3D objects
70 UScene *SkyScene = NULL;
71 UCamera SkyCamera = NULL;
72 static UInstance Sky = NULL;
74 static UCloudScape *Clouds = NULL;
76 IStereoDisplay *StereoDisplay = NULL;
77 IStereoHMD *StereoHMD = NULL;
80 // Functions
83 void initCamera()
85 if (ConfigFile->getVar("HMDEnable").asBool())
87 std::vector<NL3D::CStereoDeviceInfo> devices;
88 IStereoDisplay::listDevices(devices);
89 for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
91 std::stringstream name;
92 name << std::string("[") << it->Serial << "] [" << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName << "]";
93 nlinfo("Stereo Display: %s", name.str().c_str());
95 CStereoDeviceInfo *deviceInfo = NULL;
96 std::string hmdDeviceCfg = ConfigFile->getVar("HMDDevice").asString();
97 if (hmdDeviceCfg == std::string("Auto")
98 && devices.begin() != devices.end())
100 for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
102 if (it->AllowAuto)
104 deviceInfo = &devices[0];
108 else
110 std::string hmdDeviceId = ConfigFile->getVar("HMDDeviceId").asString();
111 for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
113 std::stringstream name;
114 name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName;
115 if (name.str() == hmdDeviceCfg)
116 deviceInfo = &(*it);
117 if (hmdDeviceId == it->Serial)
118 break;
121 if (deviceInfo)
123 nlinfo("Create VR stereo display device");
124 StereoDisplay = IStereoDisplay::createDevice(*deviceInfo);
125 if (StereoDisplay)
127 if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD)
129 nlinfo("Stereo display device is a HMD");
130 StereoHMD = static_cast<IStereoHMD *>(StereoDisplay);
131 StereoHMD->setScale(3.0f); // snowballs is about 4 units per meter
133 StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation
134 StereoDisplay->attachToDisplay();
138 IStereoDisplay::releaseUnusedLibraries();
140 // Set up directly the camera
141 Camera = Scene->getCam();
142 Camera.setTransformMode (UTransformable::DirectMatrix);
143 Camera.setPerspective((float)Pi/2.f,
144 ConfigFile->getVar("ScreenWidth").asFloat() / ConfigFile->getVar("ScreenHeight").asFloat(),
145 0.1f, 1000.f);
146 Camera.lookAt (CVector(ConfigFile->getVar("StartPoint").asFloat(0),
147 ConfigFile->getVar("StartPoint").asFloat(1),
148 ConfigFile->getVar("StartPoint").asFloat(2)),
149 CVectorD (0,0,0));
151 CamCollisionEntity = VisualCollisionManager->createEntity();
152 CamCollisionEntity->setCeilMode(true);
154 // Create the snowing particle system
155 Snow = Scene->createInstance("snow.ps");
156 // And setup it
157 Snow.setTransformMode (UTransformable::DirectMatrix);
160 // Setup the sky scene
163 // -- -- not sure what the sky has to do with the camera
165 SkyScene = Driver->createScene(false);
167 SkyCamera = SkyScene->getCam ();
168 SkyCamera.setTransformMode (UTransformable::DirectMatrix);
169 // Set the very same frustum as the main camera
170 SkyCamera.setFrustum (Camera.getFrustum ());
172 Sky = SkyScene->createInstance("sky.shape");
173 Sky.setTransformMode (UTransformable::DirectMatrix);
174 Sky.setMatrix(CMatrix::Identity);
177 void releaseCamera()
179 SkyScene->deleteInstance(Sky);
180 Driver->deleteScene(SkyScene);
181 Scene->deleteInstance(Snow);
182 VisualCollisionManager->deleteEntity(CamCollisionEntity);
184 if (StereoHMD)
186 delete StereoHMD;
187 StereoHMD = NULL;
188 StereoDisplay = NULL;
190 delete StereoDisplay;
191 StereoDisplay = NULL;
192 IStereoDisplay::releaseAllLibraries();
195 void updateCamera()
197 if (StereoHMD)
199 NLMISC::CQuat hmdOrient = StereoHMD->getOrientation();
200 NLMISC::CMatrix camMatrix = Camera.getMatrix();
201 NLMISC::CMatrix hmdMatrix;
202 hmdMatrix.setRot(hmdOrient);
203 NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future
204 posMatrix.translate(StereoHMD->getEyePosition());
205 Camera.setMatrix((camMatrix * hmdMatrix) * posMatrix);
207 // Set the new position of the snow emitter
208 CMatrix mat = CMatrix::Identity;
209 mat.setPos (Camera.getMatrix().getPos()/*+CVector (0.0f, 0.0f, -10.0f)*/);
210 Snow.setMatrix(mat);
213 void initSky()
215 // -- -- or what the clouds have to do with the sky
217 SCloudScapeSetup css;
218 Clouds = Scene->createCloudScape ();
219 Clouds->init (&css);
220 Clouds->setQuality (160);
221 Clouds->setNbCloudToUpdateIn80ms (1);
224 void releaseSky()
226 Scene->deleteCloudScape(Clouds);
229 // -- -- random note: update and render makes more sense than animate and update
230 void animateSky(double dt)
232 if (!StereoHMD) Clouds->anim(dt);
233 SkyScene->animate(AnimationTime);
236 // this is actually render
237 void updateSky()
239 CMatrix skyCameraMatrix;
240 skyCameraMatrix.identity();
242 skyCameraMatrix= Camera.getMatrix();
243 skyCameraMatrix.setPos(CVector::Null);
244 SkyCamera.setMatrix(skyCameraMatrix);
246 SkyScene->render();
247 // Must clear ZBuffer For incoming rendering.
248 Driver->clearZBuffer();
250 if (!StereoHMD) // Cloudscape not supported (fix Viewport please)
251 Clouds->render();
254 } /* namespace SBCLIENT */
256 /* end of file */