Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / tools / 3d / cluster_viewer / view_cs.cpp
blob04251c46ecb09dcb8a63eb7efc4033b4b4811906
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) 2014-2019 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 // ---------------------------------------------------------------------------
22 // Includes
23 // ---------------------------------------------------------------------------
26 #include "nel/misc/types_nl.h"
28 #include "nel/misc/file.h"
29 #include "nel/misc/path.h"
30 #include "nel/misc/bitmap.h"
31 #include "nel/misc/events.h"
32 #include "nel/misc/time_nl.h"
33 #include "nel/misc/event_server.h"
34 #include "nel/misc/event_listener.h"
36 #include "nel/3d/nelu.h"
37 #include "nel/3d/driver.h"
38 #include "nel/3d/scene_group.h"
39 #include "nel/3d/text_context.h"
40 #include "nel/3d/transform_shape.h"
41 #include "nel/3d/event_mouse_listener.h"
43 #ifdef NL_OS_WINDOWS
44 # ifndef NL_COMP_MINGW
45 # define NOMINMAX
46 # endif
47 # include <windows.h>
48 #endif // NL_OS_WINDOWS
50 #ifndef CV_DIR
51 # define CV_DIR "."
52 #endif
54 using namespace std;
55 using namespace NL3D;
56 using namespace NLMISC;
59 // ---------------------------------------------------------------------------
60 struct SDispCS
62 string Name;
63 CInstanceGroup *pIG;
67 // ---------------------------------------------------------------------------
68 // ---------------------------------------------------------------------------
69 char *readLine (char*out, char*in)
71 out[0] = 0;
73 while ((*in != '\r') && (*in != '\n') && (*in != 0))
75 *out = *in;
76 ++out;
77 ++in;
78 *out = 0;
81 while ((*in == '\r') || (*in == '\n'))
82 ++in;
83 return in;
87 // ---------------------------------------------------------------------------
88 // ---------------------------------------------------------------------------
89 CInstanceGroup* LoadInstanceGroup(const char* sFilename)
91 CIFile file;
92 CInstanceGroup *newIG = new CInstanceGroup;
94 if( file.open( CPath::lookup( string(sFilename) ) ) )
96 try
98 // Serial the skeleton
99 newIG->serial (file);
100 // All is good
102 catch (const Exception &)
104 // Cannot save the file
105 delete newIG;
106 return NULL;
109 return newIG;
112 // ---------------------------------------------------------------------------
113 // ---------------------------------------------------------------------------
114 void LoadSceneScript (const char *ScriptName, CScene* pScene, vector<SDispCS> &DispCS, CVector &CameraStart)
116 char nameIG[256];
117 float posx, posy, posz;
118 float roti, rotj, rotk;
120 FILE *f = fopen (ScriptName,"rb");
121 fseek (f, 0, SEEK_END);
122 uint file_size = ftell (f);
123 fseek (f, 0, SEEK_SET);
124 char *file_buf = (char*)malloc(file_size+1);
125 if (fread (file_buf, 1, file_size, f) != file_size)
126 nlwarning("Can't read %d elements", file_size);
128 file_buf[file_size] = 0;
129 ++file_size;
130 fclose (f);
131 char *buf_ptr = file_buf;
132 sint nLastNbPlus = 0;
133 vector<CInstanceGroup*> pile;
134 pile.clear ();
138 char Line[256], *line_ptr;
139 sint nNbPlus = 0;
140 line_ptr = &Line[0];
141 buf_ptr = readLine (line_ptr, buf_ptr);
143 while ((*line_ptr == '\t') || (*line_ptr == ' ') || (*line_ptr == '+'))
145 if (*line_ptr == '+')
146 ++nNbPlus;
147 ++line_ptr;
150 if (strlen (line_ptr) == 0)
151 break;
153 if (*line_ptr == '/')
154 continue;
156 posx = posy = posz = roti = rotj = rotk = 0.0f;
157 sscanf (line_ptr, "%s %f %f %f %f %f %f", nameIG, &posx, &posy, &posz, &roti, &rotj, &rotk);
159 if (stricmp (nameIG, "CAMERA_START") == 0)
161 CameraStart = CVector(posx, posy, posz);
163 else
165 if (nLastNbPlus >= nNbPlus)
166 for (int i = 0; i < ((nLastNbPlus-nNbPlus)+1); ++i)
167 if (!pile.empty())
168 pile.pop_back();
170 nLastNbPlus = nNbPlus;
172 CInstanceGroup *father = pScene->getGlobalInstanceGroup();
174 if (!pile.empty())
175 father = pile.back();
177 CInstanceGroup *ITemp = LoadInstanceGroup (nameIG);
178 if (ITemp != NULL)
180 SDispCS dcsTemp;
181 for (sint32 i = 0; i < (1+nNbPlus); ++i)
182 dcsTemp.Name += " ";
183 dcsTemp.Name += nameIG;
184 dcsTemp.pIG = ITemp;
185 DispCS.push_back (dcsTemp);
187 ITemp->createRoot (*pScene);
188 ITemp->setPos (CVector(posx, posy, posz));
189 ITemp->setRotQuat (ITemp->getRotQuat() * CQuat(CVector::I, roti));
190 ITemp->setRotQuat (ITemp->getRotQuat() * CQuat(CVector::J, rotj));
191 ITemp->setRotQuat (ITemp->getRotQuat() * CQuat(CVector::K, rotk));
192 ITemp->setClusterSystemForInstances (father);
193 ITemp->addToScene (*pScene);
195 pile.push_back (ITemp);
198 while (strlen(buf_ptr) > 0);
199 free (file_buf);
203 // ---------------------------------------------------------------------------
204 // Main
205 // ---------------------------------------------------------------------------
206 #ifdef NL_OS_WINDOWS
207 int APIENTRY nltWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
208 #else // NL_OS_WINDOWS
209 int nltmain(int argc, NLMISC::tchar **argv)
210 #endif // NL_OS_WINDOWS
212 double rGlobalTime = 0;
213 double rOldGlobalTime = 0;
214 double rDeltaTime = 0;
216 vector<SDispCS> DispCS;
218 bool bAutoDetect = true;
219 bool bDisplay = true;
220 sint32 nSelected = 0;
222 SDispCS dcsTemp;
225 CNELU::init (800, 600, CViewport(), 32, true);
227 CNELU::Scene->enableLightingSystem(true);
228 CNELU::Scene->setAmbientGlobal(CRGBA(128,128,128));
230 CPath::addSearchPath(CV_DIR);
231 CPath::addSearchPath(CV_DIR"/shapes");
232 CPath::addSearchPath(CV_DIR"/groups");
233 CPath::addSearchPath(CV_DIR"/fonts");
235 CFontManager FontManager;
236 CTextContext TextContext;
238 TextContext.init (CNELU::Driver, &FontManager);
239 TextContext.setFontGenerator (NLMISC::CPath::lookup("n019003l.pfb"));
240 TextContext.setHotSpot (CComputedString::TopLeft);
241 TextContext.setColor (CRGBA(255,255,255));
242 TextContext.setFontSize (20);
244 CEvent3dMouseListener MouseListener;
245 MouseListener.addToServer (CNELU::EventServer);
246 MouseListener.setFrustrum (CNELU::Camera->getFrustum());
247 MouseListener.setMouseMode (CEvent3dMouseListener::firstPerson);
249 CNELU::Camera->setTransformMode (ITransformable::DirectMatrix);
250 // Force to automatically find the cluster system
251 CNELU::Camera->setClusterSystem ((CInstanceGroup*)-1);
253 CClipTrav *pClipTrav = &CNELU::Scene->getClipTrav();
254 dcsTemp.Name = "Root";
255 dcsTemp.pIG = NULL;
256 DispCS.push_back (dcsTemp);
258 // Add all instance that create the scene
259 // --------------------------------------
260 // Beginning of script reading
261 CVector CameraStart;
263 LoadSceneScript ("view_cs.txt", CNELU::Scene, DispCS, CameraStart);
265 CMatrix m = MouseListener.getViewMatrix();
266 m.setPos (CameraStart);
267 MouseListener.setMatrix (m);
268 // End of script reading
270 // Main loop
273 rGlobalTime = CTime::ticksToSecond(CTime::getPerformanceTime());
274 rDeltaTime = rGlobalTime - rOldGlobalTime;
275 rOldGlobalTime = rGlobalTime;
278 CNELU::Scene->animate ((float)rGlobalTime);
280 CNELU::EventServer.pump();
282 CNELU::clearBuffers (CRGBA(0,0,0));
284 CNELU::Scene->render ();
286 // -----------------------------------------------------
287 // -----------------------------------------------------
288 if (bDisplay)
290 vector<CCluster*> vCluster;
291 DispCS[0].pIG = pClipTrav->RootCluster->Group;
292 TextContext.setColor (CRGBA(255,255,255,255));
293 if (bAutoDetect)
295 TextContext.printfAt (0, 1, "AutoDetect : ON");
297 pClipTrav->fullSearch (vCluster, pClipTrav->CamPos);
299 for (uint32 i = 0; i < DispCS.size(); ++i)
301 TextContext.setColor (CRGBA(255,255,255,255));
302 for( uint32 j = 0; j < vCluster.size(); ++j)
304 if (DispCS[i].pIG == vCluster[j]->Group)
306 TextContext.setColor (CRGBA(255,0,0,255));
307 break;
311 TextContext.printfAt (0, 1-(i+2)*0.028f, DispCS[i].Name.c_str());
315 else
317 TextContext.printfAt (0, 1, "AutoDetect : OFF");
319 CInstanceGroup *pCurIG = CNELU::Camera->getClusterSystem();
320 for (uint32 i = 0; i < DispCS.size(); ++i)
322 if (DispCS[i].pIG == pCurIG)
323 TextContext.setColor (CRGBA(255,0,0,255));
324 else
325 TextContext.setColor (CRGBA(255,255,255,255));
327 TextContext.printfAt (0, 1-(i+2)*0.028f, DispCS[i].Name.c_str());
330 TextContext.setColor (CRGBA(255,255,255,255));
332 pClipTrav->Accel.select (pClipTrav->CamPos, pClipTrav->CamPos);
333 CQuadGrid<CCluster*>::CIterator itAcc = pClipTrav->Accel.begin();
334 while (itAcc != pClipTrav->Accel.end())
336 CCluster *pCluster = *itAcc;
337 if (pCluster->Group == pClipTrav->Camera->getClusterSystem())
338 if (pCluster->isIn (pClipTrav->CamPos))
340 vCluster.push_back (pCluster);
342 ++itAcc;
344 if (vCluster.empty() && (DispCS[0].pIG == pCurIG))
346 vCluster.push_back (pClipTrav->RootCluster);
351 TextContext.setColor (CRGBA(255,255,255,255));
353 string sAllClusters;
354 for( uint32 j = 0; j < vCluster.size(); ++j)
356 sAllClusters += vCluster[j]->Name;
357 if (j < (vCluster.size()-1))
358 sAllClusters += ", ";
360 TextContext.printfAt (0, 1-0.028f, sAllClusters.c_str());
363 // -----------------------------------------------------
364 // -----------------------------------------------------
366 CNELU::Driver->swapBuffers ();
368 // Keys management
369 // ---------------
371 if (CNELU::AsyncListener.isKeyDown (KeySHIFT))
372 MouseListener.setSpeed (50.0f);
373 else
374 MouseListener.setSpeed (10.0f);
376 CNELU::Camera->setMatrix (MouseListener.getViewMatrix());
378 if (CNELU::AsyncListener.isKeyPushed(KeyL))
380 CNELU::Driver->setPolygonMode (IDriver::Line);
383 if (CNELU::AsyncListener.isKeyPushed (KeyP))
385 CNELU::Driver->setPolygonMode (IDriver::Filled);
388 if (CNELU::AsyncListener.isKeyPushed (KeyTAB))
389 bDisplay = !bDisplay;
391 if (CNELU::AsyncListener.isKeyPushed (KeyA))
393 if (bAutoDetect)
395 bAutoDetect = false;
396 CNELU::Camera->setClusterSystem (NULL);
397 nSelected = 0;
399 else
401 bAutoDetect = true;
402 CNELU::Camera->setClusterSystem ((CInstanceGroup*)-1);
406 if (!bAutoDetect)
408 if (CNELU::AsyncListener.isKeyPushed (KeyZ))
410 nSelected--;
411 if(nSelected == -1)
412 nSelected = (sint32)DispCS.size()-1;
414 if (CNELU::AsyncListener.isKeyPushed (KeyS))
416 nSelected++;
417 if(nSelected == (sint32)DispCS.size())
418 nSelected = 0;
420 CNELU::Camera->setClusterSystem (DispCS[nSelected].pIG);
424 while ((!CNELU::AsyncListener.isKeyPushed(KeyESCAPE)) && CNELU::Driver->isActive());
426 return EXIT_SUCCESS;