1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013-2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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/>.
24 #include <nel/misc/types_nl.h>
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"
44 #include "mouse_listener.h"
52 using namespace NLMISC
;
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
;
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
;
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
)
104 deviceInfo
= &devices
[0];
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
)
117 if (hmdDeviceId
== it
->Serial
)
123 nlinfo("Create VR stereo display device");
124 StereoDisplay
= IStereoDisplay::createDevice(*deviceInfo
);
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(),
146 Camera
.lookAt (CVector(ConfigFile
->getVar("StartPoint").asFloat(0),
147 ConfigFile
->getVar("StartPoint").asFloat(1),
148 ConfigFile
->getVar("StartPoint").asFloat(2)),
151 CamCollisionEntity
= VisualCollisionManager
->createEntity();
152 CamCollisionEntity
->setCeilMode(true);
154 // Create the snowing particle system
155 Snow
= Scene
->createInstance("snow.ps");
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
);
179 SkyScene
->deleteInstance(Sky
);
180 Driver
->deleteScene(SkyScene
);
181 Scene
->deleteInstance(Snow
);
182 VisualCollisionManager
->deleteEntity(CamCollisionEntity
);
188 StereoDisplay
= NULL
;
190 delete StereoDisplay
;
191 StereoDisplay
= NULL
;
192 IStereoDisplay::releaseAllLibraries();
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)*/);
215 // -- -- or what the clouds have to do with the sky
217 SCloudScapeSetup css
;
218 Clouds
= Scene
->createCloudScape ();
220 Clouds
->setQuality (160);
221 Clouds
->setNbCloudToUpdateIn80ms (1);
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
239 CMatrix skyCameraMatrix
;
240 skyCameraMatrix
.identity();
242 skyCameraMatrix
= Camera
.getMatrix();
243 skyCameraMatrix
.setPos(CVector::Null
);
244 SkyCamera
.setMatrix(skyCameraMatrix
);
247 // Must clear ZBuffer For incoming rendering.
248 Driver
->clearZBuffer();
250 if (!StereoHMD
) // Cloudscape not supported (fix Viewport please)
254 } /* namespace SBCLIENT */