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) 2014-2019 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/>.
21 // ---------------------------------------------------------------------------
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"
44 # ifndef NL_COMP_MINGW
48 #endif // NL_OS_WINDOWS
56 using namespace NLMISC
;
59 // ---------------------------------------------------------------------------
67 // ---------------------------------------------------------------------------
68 // ---------------------------------------------------------------------------
69 char *readLine (char*out
, char*in
)
73 while ((*in
!= '\r') && (*in
!= '\n') && (*in
!= 0))
81 while ((*in
== '\r') || (*in
== '\n'))
87 // ---------------------------------------------------------------------------
88 // ---------------------------------------------------------------------------
89 CInstanceGroup
* LoadInstanceGroup(const char* sFilename
)
92 CInstanceGroup
*newIG
= new CInstanceGroup
;
94 if( file
.open( CPath::lookup( string(sFilename
) ) ) )
98 // Serial the skeleton
102 catch (const Exception
&)
104 // Cannot save the file
112 // ---------------------------------------------------------------------------
113 // ---------------------------------------------------------------------------
114 void LoadSceneScript (const char *ScriptName
, CScene
* pScene
, vector
<SDispCS
> &DispCS
, CVector
&CameraStart
)
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;
131 char *buf_ptr
= file_buf
;
132 sint nLastNbPlus
= 0;
133 vector
<CInstanceGroup
*> pile
;
138 char Line
[256], *line_ptr
;
141 buf_ptr
= readLine (line_ptr
, buf_ptr
);
143 while ((*line_ptr
== '\t') || (*line_ptr
== ' ') || (*line_ptr
== '+'))
145 if (*line_ptr
== '+')
150 if (strlen (line_ptr
) == 0)
153 if (*line_ptr
== '/')
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
);
165 if (nLastNbPlus
>= nNbPlus
)
166 for (int i
= 0; i
< ((nLastNbPlus
-nNbPlus
)+1); ++i
)
170 nLastNbPlus
= nNbPlus
;
172 CInstanceGroup
*father
= pScene
->getGlobalInstanceGroup();
175 father
= pile
.back();
177 CInstanceGroup
*ITemp
= LoadInstanceGroup (nameIG
);
181 for (sint32 i
= 0; i
< (1+nNbPlus
); ++i
)
183 dcsTemp
.Name
+= nameIG
;
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);
203 // ---------------------------------------------------------------------------
205 // ---------------------------------------------------------------------------
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;
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";
256 DispCS
.push_back (dcsTemp
);
258 // Add all instance that create the scene
259 // --------------------------------------
260 // Beginning of script reading
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
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 // -----------------------------------------------------
290 vector
<CCluster
*> vCluster
;
291 DispCS
[0].pIG
= pClipTrav
->RootCluster
->Group
;
292 TextContext
.setColor (CRGBA(255,255,255,255));
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));
311 TextContext
.printfAt (0, 1-(i
+2)*0.028f
, DispCS
[i
].Name
.c_str());
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));
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
);
344 if (vCluster
.empty() && (DispCS
[0].pIG
== pCurIG
))
346 vCluster
.push_back (pClipTrav
->RootCluster
);
351 TextContext
.setColor (CRGBA(255,255,255,255));
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 ();
371 if (CNELU::AsyncListener
.isKeyDown (KeySHIFT
))
372 MouseListener
.setSpeed (50.0f
);
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
))
396 CNELU::Camera
->setClusterSystem (NULL
);
402 CNELU::Camera
->setClusterSystem ((CInstanceGroup
*)-1);
408 if (CNELU::AsyncListener
.isKeyPushed (KeyZ
))
412 nSelected
= (sint32
)DispCS
.size()-1;
414 if (CNELU::AsyncListener
.isKeyPushed (KeyS
))
417 if(nSelected
== (sint32
)DispCS
.size())
420 CNELU::Camera
->setClusterSystem (DispCS
[nSelected
].pIG
);
424 while ((!CNELU::AsyncListener
.isKeyPushed(KeyESCAPE
)) && CNELU::Driver
->isActive());