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 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/common.h"
30 #include "nel/misc/path.h"
31 #include "nel/misc/bitmap.h"
32 #include "nel/misc/events.h"
33 #include "nel/misc/time_nl.h"
34 #include "nel/misc/event_server.h"
35 #include "nel/misc/event_listener.h"
37 #include "nel/3d/nelu.h"
38 #include "nel/3d/driver.h"
39 #include "nel/3d/scene_group.h"
40 #include "nel/3d/text_context.h"
41 #include "nel/3d/transform_shape.h"
42 #include "nel/3d/event_mouse_listener.h"
45 # ifndef NL_COMP_MINGW
49 #endif // NL_OS_WINDOWS
57 using namespace NLMISC
;
60 // ---------------------------------------------------------------------------
68 // ---------------------------------------------------------------------------
69 // ---------------------------------------------------------------------------
70 char *readLine (char*out
, char*in
)
74 while ((*in
!= '\r') && (*in
!= '\n') && (*in
!= 0))
82 while ((*in
== '\r') || (*in
== '\n'))
88 // ---------------------------------------------------------------------------
89 // ---------------------------------------------------------------------------
90 CInstanceGroup
* LoadInstanceGroup(const char* sFilename
)
93 CInstanceGroup
*newIG
= new CInstanceGroup
;
95 if( file
.open( CPath::lookup( string(sFilename
) ) ) )
99 // Serial the skeleton
100 newIG
->serial (file
);
103 catch (const Exception
&)
105 // Cannot save the file
113 // ---------------------------------------------------------------------------
114 // ---------------------------------------------------------------------------
115 void LoadSceneScript (const char *ScriptName
, CScene
* pScene
, vector
<SDispCS
> &DispCS
, CVector
&CameraStart
,
116 vector
<CInstanceGroup
*> &vIGs
)
119 float posx
, posy
, posz
;
120 float roti
, rotj
, rotk
;
122 FILE *f
= nlfopen (CPath::lookup(ScriptName
), "rb");
123 fseek (f
, 0, SEEK_END
);
124 uint file_size
= ftell (f
);
125 fseek (f
, 0, SEEK_SET
);
126 char *file_buf
= (char*)malloc(file_size
+1);
127 if (fread (file_buf
, 1, file_size
, f
) != file_size
)
128 nlwarning("Can't read %d elements", file_size
);
130 file_buf
[file_size
] = 0;
133 char *buf_ptr
= file_buf
;
134 sint nLastNbPlus
= 0;
135 vector
<CInstanceGroup
*> pile
;
137 pile
.push_back (pScene
->getGlobalInstanceGroup());
138 pile
.push_back (pScene
->getGlobalInstanceGroup());
142 char Line
[256], *line_ptr
;
145 buf_ptr
= readLine (line_ptr
, buf_ptr
);
147 while ((*line_ptr
== '\t') || (*line_ptr
== ' ') || (*line_ptr
== '+'))
149 if (*line_ptr
== '+')
154 if (strlen (line_ptr
) == 0)
157 if (*line_ptr
== '/')
160 posx
= posy
= posz
= roti
= rotj
= rotk
= 0.0f
;
161 sscanf (line_ptr
, "%s %f %f %f %f %f %f", nameIG
, &posx
, &posy
, &posz
, &roti
, &rotj
, &rotk
);
163 if (stricmp (nameIG
, "CAMERA_START") == 0)
165 CameraStart
= CVector(posx
, posy
, posz
);
169 if (nLastNbPlus
>= nNbPlus
)
170 for (int i
= 0; i
< ((nLastNbPlus
-nNbPlus
)+1); ++i
)
173 nLastNbPlus
= nNbPlus
;
175 CInstanceGroup
*father
= pile
.back();
177 CInstanceGroup
*ITemp
= LoadInstanceGroup (nameIG
);
182 for (sint32 i
= 0; i
< (1+nNbPlus
); ++i
)
184 dcsTemp
.Name
+= nameIG
;
186 DispCS
.push_back (dcsTemp
);
188 ITemp
->createRoot (*pScene
);
189 ITemp
->setPos (CVector(posx
, posy
, posz
));
190 ITemp
->setRotQuat (ITemp
->getRotQuat() * CQuat(CVector::I
, roti
));
191 ITemp
->setRotQuat (ITemp
->getRotQuat() * CQuat(CVector::J
, rotj
));
192 ITemp
->setRotQuat (ITemp
->getRotQuat() * CQuat(CVector::K
, rotk
));
193 ITemp
->setClusterSystemForInstances (father
);
194 ITemp
->addToScene (*pScene
);
195 vIGs
.push_back (ITemp
);
197 pile
.push_back (ITemp
);
200 //while (strlen(buf_ptr) > 0);
201 while (buf_ptr
< (file_buf
+file_size
-1));
206 // ---------------------------------------------------------------------------
208 // ---------------------------------------------------------------------------
210 int WINAPI
WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpCmdLine
, int nCmdShow
)
215 double rGlobalTime
= 0;
216 double rOldGlobalTime
= 0;
217 double rDeltaTime
= 0;
219 vector
<SDispCS
> DispCS
;
221 bool bAutoDetect
= true;
222 bool bDisplay
= true;
223 sint32 nSelected
= 0;
227 vector
<CInstanceGroup
*> vAllIGs
;
228 // 2 dynamics objects
229 CTransformShape
*pDynObj_InRoot
;
230 CTransformShape
*pDynObj_InCS
;
232 CNELU::init (800, 600, CViewport(), 32, true);
234 CNELU::Scene
->enableLightingSystem(true);
235 CNELU::Scene
->setAmbientGlobal(CRGBA(128,128,128));
237 CPath::addSearchPath(CV_DIR
);
238 CPath::addSearchPath(CV_DIR
"/shapes");
239 CPath::addSearchPath(CV_DIR
"/groups");
240 CPath::addSearchPath(CV_DIR
"/fonts");
242 CFontManager FontManager
;
243 CTextContext TextContext
;
245 TextContext
.init (CNELU::Driver
, &FontManager
);
246 TextContext
.setFontGenerator (NLMISC::CPath::lookup("n019003l.pfb"));
247 TextContext
.setHotSpot (CComputedString::TopLeft
);
248 TextContext
.setColor (CRGBA(255,255,255));
249 TextContext
.setFontSize (20);
251 CEvent3dMouseListener MouseListener
;
252 MouseListener
.addToServer (CNELU::EventServer
);
253 MouseListener
.setFrustrum (CNELU::Camera
->getFrustum());
254 MouseListener
.setMouseMode (CEvent3dMouseListener::firstPerson
);
256 CNELU::Camera
->setTransformMode (ITransformable::DirectMatrix
);
257 // Force to automatically find the cluster system
258 CNELU::Camera
->setClusterSystem ((CInstanceGroup
*)-1);
260 CClipTrav
*pClipTrav
= (CClipTrav
*)&(CNELU::Scene
->getClipTrav());
261 dcsTemp
.Name
= "Root";
263 DispCS
.push_back (dcsTemp
);
265 // Add all instance that create the scene
266 // --------------------------------------
267 // Beginning of script reading
270 LoadSceneScript ("main.cvs", CNELU::Scene
, DispCS
, CameraStart
, vAllIGs
);
272 CMatrix m
= MouseListener
.getViewMatrix();
273 m
.setPos (CameraStart
);
274 MouseListener
.setMatrix (m
);
275 // End of script reading
277 // Put a dynamic object in the root
278 pDynObj_InRoot
= CNELU::Scene
->createInstance ("sphere01.shape");
279 pDynObj_InRoot
->setPos (0.0f
, 0.0f
, 0.0f
);
280 // Put a dynamic object inside
281 pDynObj_InCS
= CNELU::Scene
->createInstance ("sphere01.shape");
282 pDynObj_InCS
->setPos (50.0f
, 50.0f
, 25.0f
);
283 // No automatic detection for moving objects - setup in street
284 pDynObj_InCS
->setClusterSystem (vAllIGs
[0]);
290 rGlobalTime
= CTime::ticksToSecond(CTime::getPerformanceTime());
291 rDeltaTime
= rGlobalTime
- rOldGlobalTime
;
292 rOldGlobalTime
= rGlobalTime
;
294 pDynObj_InRoot
->setPos (-20.0f
+20.0f
*sinf((float)rGlobalTime
),
295 -20.0f
+20.0f
*cosf((float)rGlobalTime
*1.2f
),
296 20.0f
*sinf((float)rGlobalTime
*1.1f
+0.5f
));
298 pDynObj_InCS
->setPos (25.0f
+5.0f
*sinf((float)rGlobalTime
*1.4f
),
299 -25.0f
+5.0f
*cosf((float)rGlobalTime
*1.3f
),
300 25.0f
+2.0f
*sinf((float)rGlobalTime
*1.2f
+0.7f
));
303 CNELU::Scene
->animate ((float)rGlobalTime
);
305 CNELU::EventServer
.pump();
307 CNELU::clearBuffers (CRGBA(0,0,0));
309 CNELU::Scene
->render ();
311 // -----------------------------------------------------
312 // -----------------------------------------------------
315 vector
<CCluster
*> vCluster
;
316 DispCS
[0].pIG
= pClipTrav
->RootCluster
->Group
;
317 TextContext
.setColor (CRGBA(255,255,255,255));
320 TextContext
.printfAt (0, 1, "AutoDetect : ON");
322 pClipTrav
->fullSearch (vCluster
, pClipTrav
->CamPos
);
324 for (uint32 i
= 0; i
< DispCS
.size(); ++i
)
326 TextContext
.setColor (CRGBA(255,255,255,255));
327 for( uint32 j
= 0; j
< vCluster
.size(); ++j
)
329 if (DispCS
[i
].pIG
== vCluster
[j
]->Group
)
331 TextContext
.setColor (CRGBA(255,0,0,255));
336 TextContext
.printfAt (0, 1-(i
+2)*0.028f
, DispCS
[i
].Name
.c_str());
342 TextContext
.printfAt (0, 1, "AutoDetect : OFF");
344 CInstanceGroup
*pCurIG
= CNELU::Camera
->getClusterSystem();
345 for (uint32 i
= 0; i
< DispCS
.size(); ++i
)
347 if (DispCS
[i
].pIG
== pCurIG
)
348 TextContext
.setColor (CRGBA(255,0,0,255));
350 TextContext
.setColor (CRGBA(255,255,255,255));
352 TextContext
.printfAt (0, 1-(i
+2)*0.028f
, DispCS
[i
].Name
.c_str());
355 TextContext
.setColor (CRGBA(255,255,255,255));
357 pClipTrav
->Accel
.select (pClipTrav
->CamPos
, pClipTrav
->CamPos
);
358 CQuadGrid
<CCluster
*>::CIterator itAcc
= pClipTrav
->Accel
.begin();
359 while (itAcc
!= pClipTrav
->Accel
.end())
361 CCluster
*pCluster
= *itAcc
;
362 if (pCluster
->Group
== pClipTrav
->Camera
->getClusterSystem())
363 if (pCluster
->isIn (pClipTrav
->CamPos
))
365 vCluster
.push_back (pCluster
);
369 if (vCluster
.empty() && (DispCS
[0].pIG
== pCurIG
))
371 vCluster
.push_back (pClipTrav
->RootCluster
);
376 TextContext
.setColor (CRGBA(255,255,255,255));
378 string sAllClusters
= "";
379 for( uint32 j
= 0; j
< vCluster
.size(); ++j
)
381 sAllClusters
+= vCluster
[j
]->Name
;
382 if (j
< (vCluster
.size()-1))
383 sAllClusters
+= ", ";
385 TextContext
.printfAt (0, 1-0.028f
, sAllClusters
.c_str());
388 // -----------------------------------------------------
389 // -----------------------------------------------------
391 CNELU::Driver
->swapBuffers ();
396 if (CNELU::AsyncListener
.isKeyDown (KeySHIFT
))
397 MouseListener
.setSpeed (50.0f
);
399 MouseListener
.setSpeed (10.0f
);
401 CNELU::Camera
->setMatrix (MouseListener
.getViewMatrix());
403 if (CNELU::AsyncListener
.isKeyPushed(KeyL
))
405 CNELU::Driver
->setPolygonMode (IDriver::Line
);
408 if (CNELU::AsyncListener
.isKeyPushed (KeyP
))
410 CNELU::Driver
->setPolygonMode (IDriver::Filled
);
413 if (CNELU::AsyncListener
.isKeyPushed (KeyTAB
))
414 bDisplay
= !bDisplay
;
416 if (CNELU::AsyncListener
.isKeyPushed (KeyA
))
421 CNELU::Camera
->setClusterSystem (NULL
);
427 CNELU::Camera
->setClusterSystem ((CInstanceGroup
*)-1);
433 if (CNELU::AsyncListener
.isKeyPushed (KeyZ
))
437 nSelected
= (sint32
)DispCS
.size()-1;
439 if (CNELU::AsyncListener
.isKeyPushed (KeyS
))
442 if(nSelected
== (sint32
)DispCS
.size())
445 CNELU::Camera
->setClusterSystem (DispCS
[nSelected
].pIG
);
449 while ((!CNELU::AsyncListener
.isKeyPushed(KeyESCAPE
)) && CNELU::Driver
->isActive());