/
main.cpp
287 lines (222 loc) · 9.25 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#include <irrlicht.h>
#include "driverChoice.h"
#include "polar.h"
#define IDFlag_IsNotPickable 0
#define IDFlag_IsPickable 1
using namespace irr;
IrrlichtDevice* device;
/*
To receive events like mouse and keyboard input, or GUI events like "the OK
button has been clicked", we need an object which is derived from the
irr::IEventReceiver object. There is only one method to override:
irr::IEventReceiver::OnEvent(). This method will be called by the engine once
when an event happens. What we really want to know is whether a key is being
held down, and so we will remember the current state of each key.
*/
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
if( event.EventType == irr::EET_MOUSE_INPUT_EVENT)
{
MousePosition.X = event.MouseInput.X;
MousePosition.Y = event.MouseInput.Y;
}
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
virtual core::position2di GetMousePosition()
{
return MousePosition;
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
core::position2di MousePosition;
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
/*
The event receiver for keeping the pressed keys is ready, the actual responses
will be made inside the render loop, right before drawing the scene. So lets
just create an irr::IrrlichtDevice and the scene node we want to move. We also
create some other additional scene nodes, to show that there are also some
different possibilities to move and animate scene nodes.
*/
int main()
{
//core::vector2df* cameraLocation = new core::vector2df( 180, 180 );
//f32 cameraZoom = 12.0;
Polar* cameraLocation = new Polar( 180.0, 0.0, 12.0 );
f32 cameraUpVctDst = (cameraLocation->Radius * cameraLocation->Radius) * 2;
// ask user for driver
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9; // DIRECT3D9; // driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device
MyEventReceiver receiver;
IrrlichtDevice* tmpDevice = createDevice( video::EDT_NULL );
device = createDevice(driverType, core::dimension2d<u32>(800, 600), 32, false, false, false, &receiver);
//device = createDevice(driverType, tmpDevice->getVideoModeList()->getDesktopResolution(), tmpDevice->getVideoModeList()->getDesktopDepth(), true, false, false, &receiver);
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
video::ITexture* bkgTexture = driver->getTexture("background.png");
smgr->setAmbientLight( irr::video::SColorf( 0.3, 0.3, 0.3 ) );
scene::ISceneNode* indicatorNode = smgr->addSphereSceneNode(0.4, 32,0, IDFlag_IsNotPickable);
if (indicatorNode)
{
indicatorNode->setMaterialTexture(0, driver->getTexture("background.png"));
indicatorNode->setMaterialFlag(video::EMF_LIGHTING, true);
}
scene::IAnimatedMesh* worldMesh = smgr->addSphereMesh( L"WorldMesh", 5.0, 64, 64 );
scene::ISceneNode * node = smgr->addAnimatedMeshSceneNode( worldMesh, 0, IDFlag_IsPickable ); // smgr->addSphereSceneNode(5.0, 128,0, IDFlag_IsPickable);
scene::ITriangleSelector* nodeTS;
if (node)
{
node->setMaterialTexture(0, driver->getTexture("earth_day.jpg"));
node->setMaterialFlag(video::EMF_LIGHTING, true);
nodeTS = smgr->createTriangleSelector( worldMesh, node );
node->setTriangleSelector( nodeTS );
}
scene::ISceneNode* ln = smgr->addLightSceneNode( 0, core::vector3df(0, 0, 0), video::SColorf(1.0, 1.0, 1.0), 500.0, IDFlag_IsNotPickable );
scene::ISceneNodeAnimator* anim =
smgr->createFlyCircleAnimator(core::vector3df(0,0,0), 150.0f);
if (anim)
{
ln->addAnimator(anim);
anim->drop();
}
/*
To be able to look at and move around in this scene, we create a first
person shooter style camera and make the mouse cursor invisible.
*/
scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
cam->setID( IDFlag_IsNotPickable );
device->getCursorControl()->setVisible(true);
/*
We have done everything, so lets draw it. We also write the current
frames per second and the name of the driver to the caption of the
window.
*/
int lastFPS = -1;
// In order to do framerate independent movement, we have to know
// how long it was since the last frame
u32 then = device->getTimer()->getTime();
// This is the movemen speed in units per second.
const f32 MOVEMENT_SPEED = 60.0f;
const f32 ZOOM_SPEED = 3.0f;
while(device->run())
{
// Work out a frame delta time.
const u32 now = device->getTimer()->getTime();
const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
then = now;
/* Check if keys W, S, A or D are being held down, and move the
sphere node around respectively. */
core::vector3df nodePosition = node->getPosition();
if(receiver.IsKeyDown(irr::KEY_KEY_W))
{
//nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime;
//r.rotateXYBy( 0.8, node->getPosition() );
cameraLocation->Latitude += MOVEMENT_SPEED * frameDeltaTime;
}
else if(receiver.IsKeyDown(irr::KEY_KEY_S))
{
//nodePosition.Y -= MOVEMENT_SPEED * frameDeltaTime;
//r.rotateXYBy( 0.8, node->getPosition() );
cameraLocation->Latitude -= MOVEMENT_SPEED * frameDeltaTime;
}
if(receiver.IsKeyDown(irr::KEY_KEY_A))
{
//nodePosition.X -= MOVEMENT_SPEED * frameDeltaTime;
//r.rotateXZBy( 0.8, node->getPosition() );
cameraLocation->Longitude -= MOVEMENT_SPEED * frameDeltaTime;
}
else if(receiver.IsKeyDown(irr::KEY_KEY_D))
{
//nodePosition.X += MOVEMENT_SPEED * frameDeltaTime;
//r.rotateXZBy( -0.8, node->getPosition() );
cameraLocation->Longitude += MOVEMENT_SPEED * frameDeltaTime;
}
else if(receiver.IsKeyDown(irr::KEY_KEY_E))
{
cameraLocation->Radius += ZOOM_SPEED * frameDeltaTime;
if( cameraLocation->Radius > 12.0 )
cameraLocation->Radius = 12.0;
cameraUpVctDst = (cameraLocation->Radius * cameraLocation->Radius) * 2;
}
else if(receiver.IsKeyDown(irr::KEY_KEY_Q))
{
cameraLocation->Radius -= ZOOM_SPEED * frameDeltaTime;
if( cameraLocation->Radius < 6.0 )
cameraLocation->Radius = 6.0;
cameraUpVctDst = (cameraLocation->Radius * cameraLocation->Radius) * 2;
}
//core::vector3df* nodeLocalPos = new core::vector3df( node->getPosition().X, node->getPosition().Y, node->getPosition().Z );
if( cameraLocation->Latitude < 0 )
cameraLocation->Latitude += 360;
if( cameraLocation->Longitude < 0 )
cameraLocation->Longitude += 360;
if( cameraLocation->Latitude >= 360 )
cameraLocation->Latitude -= 360;
if( cameraLocation->Longitude >= 360 )
cameraLocation->Longitude -= 360;
cam->setPosition( cameraLocation->ToCartesian() ); // *GetLongitudeLatitudeOffset( nodeLocalPos, cameraLocation, cameraZoom ) );
cam->setTarget( node->getPosition() );
driver->beginScene(true, true, video::SColor(255,113,113,133));
driver->draw2DImage( bkgTexture, core::rect<s32>(0,0, driver->getScreenSize().Width, driver->getScreenSize().Height), core::rect<s32>(0,0, bkgTexture->getSize().Width, bkgTexture->getSize().Height) );
smgr->drawAll(); // draw the 3d scene
device->getGUIEnvironment()->drawAll(); // draw the gui environment (the logo)
Polar* camUpRot = new Polar( cameraLocation->Longitude, cameraLocation->Latitude - 45, cameraUpVctDst );
core::vector3df camUp = camUpRot->ToCartesian();
camUp = cam->getPosition() - camUp;
cam->setUpVector( camUp.normalize() );
core::vector3df camInv = cam->getRotation();
camInv = camInv.invert().normalize();
core::vector3df mousePosition;
core::triangle3df collisionTiangle;
scene::ISceneNode* hitCheck = 0;
scene::ISceneCollisionManager* cmgr = smgr->getSceneCollisionManager();
core::line3df ray = cmgr->getRayFromScreenCoordinates(receiver.GetMousePosition(), cam);
hitCheck = cmgr->getSceneNodeAndCollisionPointFromRay( ray, mousePosition, collisionTiangle, IDFlag_IsPickable, 0 );
if( hitCheck == node )
{
indicatorNode->setPosition( mousePosition );
}
Polar* polarMouse = new Polar( cameraLocation->ToCartesian(), cameraLocation->Radius );
printf( "Cam:Lon/Lat: %f, %f\t%f, %f\n", cameraLocation->Longitude, cameraLocation->Latitude , polarMouse->Longitude, polarMouse->Latitude );
indicatorNode->setRotation( cam->getRotation() );
driver->endScene();
int fps = driver->getFPS();
/*
if (lastFPS != fps)
{
core::stringw tmp(L"Movement Example - Irrlicht Engine [");
tmp += driver->getName();
tmp += L"] fps: ";
tmp += fps;
device->setWindowCaption(tmp.c_str());
lastFPS = fps;
}
*/
}
/*
In the end, delete the Irrlicht device.
*/
device->drop();
return 0;
}