]> git.uio.no Git - private-olgabo.git/blob - projects/ogrebullet/Game.cpp
e852692deb2d97c0f49f3d3c676216e698c9bcca
[private-olgabo.git] / projects / ogrebullet / Game.cpp
1 #include <iostream>
2 #include <string>
3 #include "Game.h"
4 //#include "PredictedState.h"
5 #include <OgreMeshManager.h>
6 #include <Utils/OgreBulletCollisionsMeshToShapeConverter.h>
7
8 #define CG_PLAYERS 001
9 #define CM_PLAYERS 011
10 #define CAMERA_STEP 20
11 //-------------------------------------------------------------------------------------
12 Game::Game(void)
13 {
14     
15 }
16 //-------------------------------------------------------------------------------------
17 Game::~Game(void)
18 {
19     // OgreBullet physic delete - RigidBodies
20         std::deque<OgreBulletDynamics::RigidBody *>::iterator itBody = mBodies.begin();
21         while (mBodies.end() != itBody)
22         {   
23             delete *itBody; 
24             ++itBody;
25         }   
26         // OgreBullet physic delete - Shapes
27         std::deque<OgreBulletCollisions::CollisionShape *>::iterator itShape = mShapes.begin();
28         while (mShapes.end() != itShape)
29         {   
30             delete *itShape; 
31             ++itShape;
32         }
33         mBodies.clear();
34         mShapes.clear();
35         delete mWorld->getDebugDrawer();
36         mWorld->setDebugDrawer(0);
37         delete mWorld;
38        
39 }
40 //-------------------------------------------------------------------------------------
41 void Game::init()
42 {
43
44     mNumEntitiesInstanced = 0; // how many shapes are created
45        
46     // Start Bullet
47     Ogre::Vector3 gravityVector = Ogre::Vector3(0,-1500,0); // gravity vector for Bullet
48     mWorld = new OgreBulletDynamics::DynamicsWorld(mSceneMgr,  Ogre::AxisAlignedBox (Ogre::Vector3 (-10000, -10000, -10000),Ogre::Vector3 (10000,  10000,  10000)), gravityVector);
49     
50     // add Debug info display tool
51     debugDrawer = new OgreBulletCollisions::DebugDrawer();
52     debugDrawer->setDrawWireframe(true);    // we want to see the Bullet containers
53  
54     mWorld->setDebugDrawer(debugDrawer);
55     mWorld->setShowDebugShapes(true);       // enable it if you want to see the Bullet containers
56     Ogre::SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("debugDrawer", Ogre::Vector3::ZERO);
57     node->attachObject(static_cast <Ogre::SimpleRenderable *> (debugDrawer));
58      
59     btDynamicsWorld *bulletWorld = mWorld->getBulletDynamicsWorld();
60     btWorld = bulletWorld; 
61     btDispatcher *dispatcher = btWorld->getDispatcher();
62     int i;
63     for (i = 0; i < numPlayers; i++)
64     {
65         playersAlive[i] = 0;
66         RigidBodies[i] = 0;
67         updated[i] = false;
68     }
69         
70     connected = false;
71     activePlayers = 1;
72     myPlayerId = 9;
73
74     Client *clientobject = new Client("localhost");
75     client = clientobject;
76
77     
78     /*    
79     int res = client->connectToServer(5001);
80     if (res == 0)
81     {
82         connected = true;
83         if ((res = client->getId((char *)&myPlayerId)) < (sizeof(int)))
84         {
85             std::cout << "Failed to receive player id. Not connected.";
86             connected = false;
87         } 
88         std::cout << "\n\nPlayer id: " << myPlayerId << "\n\n";
89     }
90     */
91     pthread_mutexattr_init(&errorcheck);
92     pthread_mutexattr_settype(&errorcheck, PTHREAD_MUTEX_ERRORCHECK);
93
94     pthread_mutex_init(&po_mutex,&errorcheck);
95     pthread_mutex_init(&an_mutex,&errorcheck);
96   
97     pthread_mutex_init(&players_mutex,&errorcheck);
98     pthread_mutex_init(&log_mutex,&errorcheck);
99        
100     pthread_mutex_init(&send,NULL);
101     pthread_cond_init(&time2send,NULL);
102 }
103 /*//-------------------------------------------------------------------------------------
104 void Game::initPhysics()
105 {
106    // btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));
107    // m_collisionShapes.push_back(groundShape);
108     m_collisionConfiguration = new btDefaultCollisionConfiguration();
109     m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
110     btVector3 worldMin(-100000,-100000,-100000);
111     btVector3 worldMax(100000,100000,100000);
112     btAxisSweep3* sweepBP = new btAxisSweep3(worldMin,worldMax);
113     m_overlappingPairCache = sweepBP;
114
115     m_constraintSolver = new btSequentialImpulseConstraintSolver();
116     m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration);
117     m_dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration=0.0001f;
118     
119 #ifdef DYNAMIC_CHARACTER_CONTROLLER
120     m_character = new DynamicCharacterController ();
121 #else
122     
123     btTransform startTransform;
124     startTransform.setIdentity();
125     //startTransform.setOrigin (btVector3(0.0, 4.0, 0.0));
126     startTransform.setOrigin (btVector3(10.210098,-1.6433364,16.453260));
127
128
129     m_ghostObject = new btPairCachingGhostObject();
130     m_ghostObject->setWorldTransform(startTransform);
131     sweepBP->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
132     btScalar characterHeight=1.75;
133     btScalar characterWidth =1.75;
134     btConvexShape* capsule = new btCapsuleShape(characterWidth,characterHeight);
135     m_ghostObject->setCollisionShape (capsule);
136     m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT);
137
138     btScalar stepHeight = btScalar(0.35);
139     m_character = new btKinematicCharacterController (m_ghostObject,capsule,stepHeight);
140 #endif
141
142 }
143
144 */
145 void Game::createCamera(void)
146 {
147     // create the camera
148     mCamera = mSceneMgr->createCamera("PlayerCam");
149     // set its position, direction
150     mCamera->setPosition(Ogre::Vector3(0,300,-500));
151     mCamera->lookAt(Ogre::Vector3(0,0,0));
152     // set the near clip distance
153     mCamera->setNearClipDistance(5);
154
155 }
156  //-------------------------------------------------------------------------------------
157 void Game::createViewports(void)
158 {
159     // Create one viewport, entire window
160     Ogre::Viewport* vp = mWindow->addViewport(mCamera);
161     vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0));
162     // Alter the camera aspect ratio to match the viewport
163     mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
164 }
165 //-------------------------------------------------------------------------------------
166 void Game::createScene(void)
167 {
168     init();
169       
170     mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);
171     mSceneMgr->setShadowTextureSettings(1000, 2, Ogre::PF_FLOAT16_R);
172     mSceneMgr->setShadowTextureSelfShadow(true);      
173     mSceneMgr->setAmbientLight(Ogre::ColourValue(0.45f, 0.45f, 0.45f));
174
175     // create background 
176     Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);
177     Ogre::MeshManager::getSingleton().createPlane("ground", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
178         plane, 15000, 15000, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);
179
180     Ogre::Entity* entGround = mSceneMgr->createEntity("GroundEntity", "ground");
181     mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entGround);
182
183     entGround->setMaterialName("Examples/GrassFloor");
184     entGround->setMaterialLodBias(2.0, 5, 20);
185     entGround->setCastShadows(false);
186     mSceneMgr->setSkyDome(true, "Examples/CloudySky", 1, 10 );  
187
188     Ogre::ColourValue fadeColour(0.9, 0.9, 0.9);
189     mSceneMgr->setFog(Ogre::FOG_EXP, fadeColour, 0.000005);
190    
191     Ogre::Light* daylight = mSceneMgr->createLight("dayLight");
192     daylight->setType(Ogre::Light::LT_DIRECTIONAL);
193   
194     daylight->setDirection(0.1f, 0.9f, 0.9f);
195     daylight->setDiffuseColour(0.15f, 0.15f, 0.18f);
196     daylight->setSpecularColour(0, 0, 0);
197     daylight->setCastShadows(true);
198
199     Ogre::Light* sunlight = mSceneMgr->createLight("sunLight");
200     sunlight->setType(Ogre::Light::LT_DIRECTIONAL);
201     sunlight->setDirection(0.1f, 0.9f, 0.9f);
202     sunlight->setDiffuseColour(0.15f, 0.15f, 0.18f);
203     sunlight->setSpecularColour(0, 0, 0);
204     sunlight->setCastShadows(true);
205
206
207     // add collision detection to the ground
208     OgreBulletCollisions::CollisionShape *Shape;
209     Shape = new OgreBulletCollisions::StaticPlaneCollisionShape(Ogre::Vector3(0,1,0), 0); // (normal vector, distance)
210     // a body is needed for the shape
211     OgreBulletDynamics::RigidBody *defaultPlaneBody = new OgreBulletDynamics::RigidBody("BasePlane",
212                                                     mWorld);
213     defaultPlaneBody->setStaticShape(Shape, 0.1, 0.8);// (shape, restitution, friction)
214         // push the created objects to the deques
215     mShapes.push_back(Shape);
216     mBodies.push_back(defaultPlaneBody);
217
218
219     
220
221     // create Maya temple :)
222     Ogre::Entity *entTemple = mSceneMgr->createEntity("TempleEntity", "MayanTemple.mesh");
223     Ogre::SceneNode *nodeTemple = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(1000,0,0));
224     nodeTemple->attachObject(entTemple);
225     nodeTemple->scale(50,50,50);
226
227     Ogre::AxisAlignedBox templeB = entTemple->getWorldBoundingBox(true);
228     Ogre::Vector3 templeSize = templeB.getSize();
229     templeSize /= 2.0f;
230     templeSize *= 0.95f;
231     OgreBulletCollisions::BoxCollisionShape *templeBox = new OgreBulletCollisions::BoxCollisionShape(templeSize);
232
233     OgreBulletCollisions::StaticMeshToShapeConverter *stConverter = new OgreBulletCollisions::StaticMeshToShapeConverter(entTemple);
234     OgreBulletCollisions::TriangleMeshCollisionShape *templeShape = stConverter->createTrimesh();
235     OgreBulletDynamics::RigidBody *templeBody = new OgreBulletDynamics::RigidBody("Temple", mWorld);
236     templeBody->setStaticShape(templeBox, 0.1, 0.8);
237    /* templeBody->setShape(nodeTemple,
238                         templeBox,        
239                         100.0f,           // dynamic body restitution
240                         100.6f,           // dynamic body friction
241                         1.0f,           // dynamic bodymass
242                         Ogre::Vector3::ZERO,       // starting position of the box
243                         nodeTemple->getOrientation());// orientation of the box*/
244     mNumEntitiesInstanced++; 
245     Ogre::Vector3 move = Ogre::Vector3::ZERO;
246     move.z += 1000;
247     nodeTemple->translate(move);
248     btRigidBody *btTemple = templeBody->getBulletRigidBody();                
249     btTemple->clearForces();
250     mShapes.push_back(templeShape);
251     mShapes.push_back(templeBox);
252     mBodies.push_back(templeBody);
253
254
255
256     // create local player and attach camera to it
257    createPlayer(myPlayerId);
258     playerNodes[myPlayerId]->attachObject(daylight);
259     playerNodes[myPlayerId]->attachObject(sunlight);
260    
261
262     //predictionHandler = new PredictedState(localPlayer, collisionObjects);
263   
264   std::cout << "created players\n";
265     if (connected == 1)
266     {
267         pthread_cond_signal(&send_start);
268         pthread_cond_signal(&update_start);
269     }
270 }
271 //-------------------------------------------------------------------------------------
272 void Game::createFrameListener(void){
273   
274     mToggle = 0.0;    // The time left until next toggle
275     mRotate = 0.0;   // The rotate constant
276     mMove = 160;      // The movement constant
277     
278     BaseApplication::createFrameListener();
279    
280 }   
281 //-------------------------------------------------------------------------------------
282 bool Game::frameRenderingQueued(const Ogre::FrameEvent &evt)
283 {
284     // set idle animation immediately if stopped walking 
285     if (anStates[myPlayerId]->getAnimationName() == "walk")
286     {
287         if (!mKeyboard->isKeyDown(OIS::KC_J) && !mKeyboard->isKeyDown(OIS::KC_L) && !mKeyboard->isKeyDown(OIS::KC_I) && !mKeyboard->isKeyDown(OIS::KC_K))
288         {
289             pthread_mutex_lock(&an_mutex);
290             animation = 1;
291             pthread_mutex_unlock(&an_mutex);
292             pthread_cond_signal(&time2send);
293             animate("idle",&anStates[myPlayerId], players[myPlayerId]);
294         }    
295     }
296
297     else if (anStates[myPlayerId]->getAnimationName() == "handshake")
298     {
299         if (anStates[myPlayerId]->hasEnded())
300         {
301             animate("idle",&anStates[myPlayerId], players[myPlayerId]);
302             restoreCameraPosition();
303         }
304             
305         else if(anStates[myPlayerId]->getTimePosition() == 0)
306         {
307             cameraPos = mCamera->getPosition();
308             cameraOrient = mCamera->getOrientation();
309
310             Ogre::Vector3 moveCamera = cameraPos;
311             moveCamera.z += 480;
312             moveCamera.x -= 480;
313             mCamera->setPosition(moveCamera);
314             mCamera->lookAt(playerNodes[myPlayerId]->getPosition());
315         }
316     }
317    
318     // update animation states of all players 
319     anStates[myPlayerId]->addTime(evt.timeSinceLastFrame);
320   //  anStates[6]->addTime(evt.timeSinceLastFrame);
321     int i;
322    // std::cerr << "main thread taking the lock\n\n\n";
323     pthread_mutex_lock(&players_mutex);
324     // std::cerr << "main thread taken the lock\n\n\n";
325     for (i = 0; i < numPlayers; i++)
326     { 
327        
328         if (playersAlive[i] == 1)
329         {
330             anStates[i]->addTime(evt.timeSinceLastFrame);
331           // if (anStates[i]->getAnimationName() == "walk")
332             if (updated[i])
333
334             {   
335               //  predictionHandler->correct(orientationUpdate[i],positionUpdate[i],anStates[i]->getAnimationName(), playerNodes[i], evt);
336                // playerNodes[i]->setOrientation(orientationUpdate[i]);
337                // playerNodes[i]->setPosition(positionUpdate[i]);
338                 updated[i] = false;
339             }
340           //  else
341                // predictionHandler->predictNext(anStates[i]->getAnimationName(), playerNodes[i], evt);
342        
343         }
344          
345     } 
346     pthread_mutex_unlock(&players_mutex);
347    // std::cerr << "main thread released the lock\n\n\n";
348       
349             
350     if(!processUnbufferedInput(evt)) {
351   
352         std::cerr << "processUnbufferedInput == false\n";
353         return false;
354     }
355
356     // write my position and orientation to use by sending thread
357     pthread_mutex_lock(&po_mutex);
358     position = playerNodes[myPlayerId]->getPosition();
359     orientation = playerNodes[myPlayerId]->getOrientation();
360     pthread_mutex_unlock(&po_mutex);
361    
362     mWorld->stepSimulation(evt.timeSinceLastFrame); // update Bullet Physics animation
363
364     bool ret = BaseApplication::frameRenderingQueued(evt);
365     return ret;
366 }
367 //-------------------------------------------------------------------------------------
368 bool Game::keyPressed( const OIS::KeyEvent &arg )
369 {
370
371     if (arg.key == OIS::KC_ESCAPE)
372     {
373         int res = client->sendMessage("exit",4);
374         mShutDown = true;
375     }
376     else if (arg.key == OIS::KC_F1)
377     {
378         mWorld->setShowDebugShapes(true);
379     }
380     if (arg.key == OIS::KC_F2)
381     {
382         mWorld->setShowDebugShapes(false);
383     }
384      
385     
386
387 }
388 //-------------------------------------------------------------------------------------
389 bool Game::keyReleased( const OIS::KeyEvent &arg )
390 {
391     return true;
392 }
393 //-------------------------------------------------------------------------------------
394 bool Game::processUnbufferedInput(const Ogre::FrameEvent& evt)
395 {
396     mToggle -= evt.timeSinceLastFrame;
397     Ogre::Vector3 transVector = Ogre::Vector3::ZERO;
398
399     if (mKeyboard->isKeyDown(OIS::KC_K)) // Forward
400     {   
401         mToggle  = 0.1;
402         if (anStates[myPlayerId]->getAnimationName() != "walk" || !anStates[myPlayerId]->getEnabled())
403         {
404             pthread_mutex_lock(&an_mutex);
405             animation = 2;
406             pthread_mutex_unlock(&an_mutex);
407             pthread_cond_signal(&time2send);
408             animate("walk",&anStates[myPlayerId], players[myPlayerId]);
409         }
410            
411         transVector.z -= mMove;
412     }
413
414     if (mKeyboard->isKeyDown(OIS::KC_I)) // Backward
415     {   
416         mToggle  = 0.1;
417         if (anStates[myPlayerId]->getAnimationName() != "walk" || !anStates[myPlayerId]->getEnabled())
418         {
419             pthread_mutex_lock(&an_mutex);
420             animation = 2;
421             pthread_mutex_unlock(&an_mutex);
422             pthread_cond_signal(&time2send); 
423             animate("walk",&anStates[myPlayerId], players[myPlayerId]);        
424         }
425         transVector.z += mMove;
426         //transVector.y += mMove;
427
428
429        // MC_RBody->applyForce((MC_RBody->getCenterOfMassPosition() + transVector), MC_RBody->getCenterOfMassPosition());
430     }
431
432     if (mKeyboard->isKeyDown(OIS::KC_J)) // Left 
433     {
434         mToggle  = 0.1;
435         if (anStates[myPlayerId]->getAnimationName() != "walk" || !anStates[myPlayerId]->getEnabled())
436         {
437             pthread_mutex_lock(&an_mutex);
438             animation = 2;
439             pthread_mutex_unlock(&an_mutex);
440             pthread_cond_signal(&time2send);
441             animate("walk",&anStates[myPlayerId], players[myPlayerId]);
442         }
443         mRotate+=20;
444     }
445
446     if (mKeyboard->isKeyDown(OIS::KC_L)) // Right 
447     {
448         mToggle  = 0.1;
449         if (anStates[myPlayerId]->getAnimationName() != "walk" || !anStates[myPlayerId]->getEnabled())
450         {
451             pthread_mutex_lock(&an_mutex);
452             animation = 2;
453             pthread_mutex_unlock(&an_mutex);
454             pthread_cond_signal(&time2send);
455             animate("walk",&anStates[myPlayerId], players[myPlayerId]);
456         }
457         mRotate-=20;
458     }
459     
460     if (mToggle < 0.0f )
461     {
462         mToggle  = 0.1;
463         if (mKeyboard->isKeyDown(OIS::KC_1))
464         {
465             pthread_mutex_lock(&an_mutex);
466             animation = 3;
467             pthread_mutex_unlock(&an_mutex);
468             pthread_cond_signal(&time2send);
469             animate("wave",&anStates[myPlayerId], players[myPlayerId]);
470         }
471         else if (mKeyboard->isKeyDown(OIS::KC_N)) //nod
472         {
473             pthread_mutex_lock(&an_mutex);
474             animation = 4;
475             pthread_mutex_unlock(&an_mutex);
476             pthread_cond_signal(&time2send);
477             animate("nod",&anStates[myPlayerId], players[myPlayerId]);
478         }
479         else if (mKeyboard->isKeyDown(OIS::KC_P)) // punch
480         {
481             pthread_mutex_lock(&an_mutex);
482             animation = 5;
483             pthread_mutex_unlock(&an_mutex);
484             pthread_cond_signal(&time2send);
485             animate("punch",&anStates[myPlayerId], players[myPlayerId]);
486         }
487         else if (mKeyboard->isKeyDown(OIS::KC_Q)) // kick
488         {
489           //  kick = true;
490         }
491         else if (mKeyboard->isKeyDown(OIS::KC_3)) // headshake
492         {
493             
494             pthread_mutex_lock(&an_mutex);
495             animation = 6;
496             pthread_mutex_unlock(&an_mutex);
497             pthread_cond_signal(&time2send);
498             animate("headshake",&anStates[myPlayerId], players[myPlayerId]);
499         }
500         else if (mKeyboard->isKeyDown(OIS::KC_2)) // smth
501         {
502           //  animate("punch",&p2AnimationState, entP2);
503         }
504         else if (mKeyboard->isKeyDown(OIS::KC_H)) // smth
505         {
506           //  restoreCameraPosition();
507             if (anStates[myPlayerId]->getAnimationName() != "handshake")
508             {
509                  pthread_mutex_lock(&an_mutex);
510                 animation = 7;
511                 pthread_mutex_unlock(&an_mutex);
512                 pthread_cond_signal(&time2send);
513                 animate("handshake",&anStates[myPlayerId], players[myPlayerId]);
514                 animate("handshake",&anStates[6], players[6]);
515                 std::cout << playerNodes[myPlayerId]->getOrientation() << " me\n";
516                 std::cout << playerNodes[6]->getOrientation() << " other\n";
517
518                 //mCamera->yaw(Ogre::Degree(-20));
519             }           
520         }
521         else if(mKeyboard->isKeyDown(OIS::KC_Z)) 
522         {
523             createPlayer(6);
524             RigidBodies[6] = 1;
525         }
526         else if(mKeyboard->isKeyDown(OIS::KC_B)) 
527         {
528             Ogre::Vector3 size = Ogre::Vector3::ZERO;   // size of the box
529             // starting position of the box
530             Ogre::Vector3 position = (playerNodes[myPlayerId]->getPosition() + 10);
531             // starting orientation of the box 
532             Ogre::Quaternion orientation = (playerNodes[myPlayerId]->getOrientation());
533  
534             // create an ordinary, Ogre mesh with texture
535             Ogre::Entity *entity = mSceneMgr->createEntity(
536                     "Box" + Ogre::StringConverter::toString(mNumEntitiesInstanced),
537                     "cube.mesh");               
538             entity->setCastShadows(true);
539             // we need the bounding box of the box to be able to set the size of the Bullet-box
540             Ogre::AxisAlignedBox boundingB = entity->getBoundingBox();
541             size = boundingB.getSize(); size /= 2.0f; // only the half needed
542             size *= 0.95f;  // Bullet margin is a bit bigger so we need a smaller size
543                                     // (Bullet 2.76 Physics SDK Manual page 18)
544             entity->setMaterialName("Examples/Rockwall");
545             Ogre::SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
546             node->attachObject(entity);
547             node->scale(0.2f, 0.2f, 0.2f);   // the cube is too big for us
548             size *= 0.2f;                      // don't forget to scale down the Bullet-box too
549  
550             // after that create the Bullet shape with the calculated size
551             OgreBulletCollisions::BoxCollisionShape *sceneBoxShape = new OgreBulletCollisions::BoxCollisionShape(size);
552             // and the Bullet rigid body
553             OgreBulletDynamics::RigidBody *defaultBody = new OgreBulletDynamics::RigidBody(
554                     "defaultBoxRigid" + Ogre::StringConverter::toString(mNumEntitiesInstanced), 
555                     mWorld);
556             defaultBody->setShape(node,
557                         sceneBoxShape,
558                         0.0f,           // dynamic body restitution
559                         0.6f,           // dynamic body friction
560                         1.01f,           // dynamic bodymass
561                         position,       // staring position of the box
562                         playerNodes[myPlayerId]->convertLocalToWorldOrientation(orientation));// orientation of the box
563                 mNumEntitiesInstanced++;                
564  
565             defaultBody->setLinearVelocity(
566                         playerNodes[myPlayerId]->getPosition().normalisedCopy() * 7.0f ); // shooting speed
567             // push the created objects to the deque
568             mShapes.push_back(sceneBoxShape);
569             mBodies.push_back(defaultBody);             
570         }
571         else if (mKeyboard->isKeyDown(OIS::KC_PGUP))
572         {
573             cameraNode->pitch(Ogre::Degree(CAMERA_STEP*evt.timeSinceLastFrame), Ogre::Node::TS_LOCAL);
574         }
575         else if (mKeyboard->isKeyDown(OIS::KC_PGDOWN))
576         {
577             cameraNode->pitch(Ogre::Degree(-CAMERA_STEP*evt.timeSinceLastFrame), Ogre::Node::TS_LOCAL);
578         }   
579         else if (mKeyboard->isKeyDown(OIS::KC_RIGHT))
580         {
581             cameraNode->yaw(Ogre::Degree(-CAMERA_STEP*evt.timeSinceLastFrame), Ogre::Node::TS_LOCAL);
582         }   
583         else if (mKeyboard->isKeyDown(OIS::KC_LEFT))
584         {
585             cameraNode->yaw(Ogre::Degree(CAMERA_STEP*evt.timeSinceLastFrame), Ogre::Node::TS_LOCAL);
586         }  
587         else if (mKeyboard->isKeyDown(OIS::KC_UP))
588         {
589             transVector.z -= CAMERA_STEP;
590             cameraNode->translate(transVector * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);
591             transVector.z = 0;
592         }      
593         else if (mKeyboard->isKeyDown(OIS::KC_DOWN))
594         {
595             transVector.z += CAMERA_STEP;
596             cameraNode->translate(transVector * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);
597             transVector.z = 0;
598         }    
599     }    
600  
601    
602     playerNodes[myPlayerId]->translate(transVector * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);
603     playerNodes[myPlayerId]->yaw(Ogre::Degree(mRotate) * evt.timeSinceLastFrame);
604    //  CollisionCheck();
605     mRotate = 0;
606     
607     return true;
608 }
609 //-------------------------------------------------------------------------------------
610 void Game::animate(const Ogre::String &an, Ogre::AnimationState** anState, Ogre::Entity *ent)
611 {
612     (*anState)->setEnabled(false);
613     (*anState) = ent->getAnimationState(an);
614     (*anState)->setTimePosition(0);
615     (*anState)->setEnabled(true);
616     if (an == "walk")
617         (*anState)->setLoop(true);
618     else        
619         (*anState)->setLoop(false);
620 }
621 //-------------------------------------------------------------------------------------
622 void Game::sendUpdate()
623 {
624     int rc;
625     struct timespec ts;
626     struct timeval tp;
627     
628     while (connected)
629     {
630         rc = gettimeofday(&tp, NULL);
631
632         // Convert from timeval to timespec
633         if (ts.tv_nsec < WAIT_TIME_NSECONDS)
634         {
635             ts.tv_sec = tp.tv_sec;
636             ts.tv_nsec = tp.tv_usec * 1000;
637             ts.tv_nsec += WAIT_TIME_NSECONDS;    
638         }
639         else // if less a half second left until next second
640         {
641             ts.tv_sec = tp.tv_sec + 1;
642             ts.tv_nsec = tp.tv_usec * 1000;
643         }
644           
645         
646         int res = pthread_cond_timedwait(&time2send, &send, &ts); 
647       /*  if (res == ETIMEDOUT)  
648             std::cerr << "ETIMEDOUT\n"; 
649         else if(res == EINVAL)
650             std::cerr << "EINVAL: value is not correct";
651         else if(res == EPERM)
652             std::cerr << "EPERM: mutex not locked";
653         else if (res == 0)
654             std::cerr << "SIGNAL\n";   */ 
655         memset(sendbuffer, 0, BUFFERSIZE);
656         int size = 0;
657         pthread_mutex_lock(&po_mutex);
658         memcpy(&sendbuffer[size],(void*)&position, sizeof(Ogre::Vector3));
659         size += sizeof(Ogre::Vector3);
660         memcpy(&sendbuffer[size],(void*)&orientation, sizeof(Ogre::Quaternion));
661         pthread_mutex_unlock(&po_mutex);
662         size += sizeof(Ogre::Quaternion);
663
664         pthread_mutex_lock(&an_mutex);
665         memcpy(&sendbuffer[size],(void*)&animation, sizeof(int));
666         animation = 0;
667         pthread_mutex_unlock(&an_mutex);
668         size += sizeof(int);        
669         client->sendMessage(sendbuffer, size);
670         sleep(1);
671     }
672    
673 }
674 //-------------------------------------------------------------------------------------
675 void Game::update()
676 {
677     while(connected)
678     {
679         memset(recvbuffer, 0, BUFFERSIZE);
680         int bytesreceived = client->readMessage(recvbuffer);
681         
682         int pid;
683         Ogre::Vector3 pos;
684         Ogre::Quaternion orient;
685         int an;
686     
687         int sizeread = 0;
688         //memcpy(&activePlayers,&recvbuffer[sizeread], sizeof(int));
689        // sizeread += sizeof(int);
690     
691         //std::cout << "Active players: " << activePlayers << "\n";
692        
693         //if (activePlayers > 1)
694         //{
695             int nr = bytesreceived/36;
696             std::cout << "number of updates: " << nr << "\n";
697             int i;
698             for (i = 0; i < nr; i++)
699             {
700                 memcpy(&pid,&recvbuffer[sizeread], sizeof(int));
701                 sizeread += sizeof(int);
702                 if (pid > numPlayers)
703                 {
704                     std::cerr << "Bad player id. dropping update\n";
705                     break;
706                 }
707                 std::cout << "pid " << pid << "\n";
708                 if (pid == myPlayerId)
709                 {
710                     sizeread += ( sizeof(Ogre::Vector3) + sizeof(Ogre::Quaternion) + sizeof(int));
711                     continue;
712                 }
713
714                 std::cerr << "taking lock\n";
715                 pthread_mutex_lock(&players_mutex);
716                 std::cerr << "taken lock\n";
717                 if (playersAlive[pid] != 1)
718                 {
719                     std::cout << "new player \n\n\n";
720                     createPlayer(pid);
721                     playersAlive[pid] = 1;
722                 }
723                 
724
725                 memcpy(&pos, &recvbuffer[sizeread], sizeof(Ogre::Vector3));
726                 std::cout << pos << "\n";
727                 sizeread += sizeof(Ogre::Vector3);
728                 memcpy(&orient, &recvbuffer[sizeread], sizeof(Ogre::Quaternion));
729                 std::cout << orient << "\n";
730                 sizeread += sizeof(Ogre::Quaternion);
731                 memcpy(&an, &recvbuffer[sizeread], sizeof(int));
732                 sizeread += sizeof(int);
733                 std::cout << an << "\n";
734                
735                 positionUpdate[pid] = pos;
736                 orientationUpdate[pid] = orient;
737               //  predictionHandler->setLastUpdate(orient,pos); 
738                // position_log[pid].push_front(pos);
739                // orientation_log[pid].push_front(orient);
740                 updated[pid] = true;
741              
742                 
743                 if (an != 0)
744                 {
745                     switch (an)
746                     {
747                         case 1:
748                             std::cout << "idle\n";
749                             animate("idle", &anStates[pid], players[pid]);
750                             break;
751
752                         case 2:
753                             std::cout << "walk\n";
754                             animate("walk", &anStates[pid], players[pid]);
755                             break;
756
757                         case 3:
758                             std::cout << "wave\n";
759                             animate("wave", &anStates[pid], players[pid]);
760                             break;
761
762                         case 4:
763                             std::cout << "nod\n";
764                             animate("nod", &anStates[pid], players[pid]);
765                             break;
766
767                         case 5:
768                             std::cout << "punch\n";
769                             animate("punch", &anStates[pid], players[pid]);
770                             break;
771
772                         case 6:
773                             std::cout << "headshake\n";
774                             animate("headshake", &anStates[pid], players[pid]);
775                             break;
776
777                         case 7:
778                             std::cout << "handshake\n";
779                             animate("handshake", &anStates[pid], players[pid]);
780                             break;
781
782                         default:
783                             break;
784                     }
785                    
786                 }
787                 pthread_mutex_unlock(&players_mutex);
788                 std::cerr << "updating thread released the lock\n\n\n";  
789                 }
790         //}
791     }
792 }
793 //-------------------------------------------------------------------------------------
794 void Game::handlePlayers()
795 {
796     while(1)
797     {
798         
799     }
800 }
801 //-------------------------------------------------------------------------------------
802 void* Game::sendThread(void* empt)
803 {
804     pthread_cond_wait(&send_start,&send_mutex);
805   
806     Game* th = (Game *) empt;
807     th->sendUpdate();
808 }  
809 //-------------------------------------------------------------------------------------
810 void* Game::receiveThread(void* empt)
811 {
812     pthread_cond_wait(&update_start,&update_mutex);
813    
814     Game* th = (Game *) empt;
815     th->update();
816 }
817 //-------------------------------------------------------------------------------------
818 void Game::createPlayer(int id)
819 {
820     std::cout << "\n creating new player " << id << "\n";
821     playerNodes[id] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3( 0, 100.5, 0 ));
822     players[id] = mSceneMgr->createEntity("player" + Ogre::StringConverter::toString(id), "MCMesh.mesh");
823     players[id]->setCastShadows(true);
824     playerNodes[id]->attachObject(players[id]);
825     playerNodes[id]->setScale(30,30,30);
826     anStates[id] = players[id]->getAnimationState("idle");
827     anStates[id]->setEnabled(true);
828     anStates[id]->setLoop(true);
829
830     if (id == myPlayerId)
831     {
832         Ogre::SceneNode* cameraNode = playerNodes[myPlayerId]->createChildSceneNode();
833         cameraNode->attachObject(mCamera);
834     }
835
836     //create a converter to make containers for animated mesh
837     OgreBulletCollisions::AnimatedMeshToShapeConverter *cont = new OgreBulletCollisions::AnimatedMeshToShapeConverter(players[myPlayerId], *(players[myPlayerId]->_getBoneMatrices()));
838     Ogre::SkeletonInstance *skel = players[id]->getSkeleton();
839     Ogre::Bone *bone = skel->getBone("hip.R");
840     //OgreBulletCollisions::CapsuleCollisionShape *boneShape = cont->createOrientedCapsuleCollisionShape(bone->getHandle(), bone->convertLocalToWorldPosition(bone->getPosition()), bone->convertLocalToWorldOrientation(bone->getOrientation()));
841    
842     std::cout << "bone position (local): " << bone->getPosition() << "\n";
843     std::cout << "bone position (world): " << bone->convertLocalToWorldPosition(bone->getPosition()) << "\n";
844     std::cout << "handle: " << bone->getHandle() << "\n";
845     std::cout << "name: " << bone->getName() << "\n";
846    // int numBones = skel->getNumBones();    
847
848     // we need the bounding box of the box to be able to set the size getCenterOfMassPosition the Bullet-box
849     Ogre::AxisAlignedBox BoundingBox = players[id]->getWorldBoundingBox(true);
850     Ogre::Vector3 s = Ogre::Vector3::ZERO;   // size of the box
851     s = BoundingBox.getSize();
852     //adjust the size of the box to best fit manually
853     s.x /= 9;
854     s.y /= 2;
855     s.z *= 1.3;
856     BoundingBox.scale(s);
857  //   s *= 0.95f;  // Bullet margin is a bit bigger so we need a smaller size
858                                     // (Bullet 2.76 Physics SDK Manual page 18)
859   
860   
861     // after that create the Bullet shape with the calculated size
862     OgreBulletCollisions::BoxCollisionShape *boxShape = new OgreBulletCollisions::BoxCollisionShape(s);
863     Ogre::Real radius = 10;
864     Ogre::Real height = 50;
865   //  OgreBulletCollisions::CapsuleCollisionShape *charShape = new OgreBulletCollisions::CapsuleCollisionShape(radius,height,Ogre::Vector3::ZERO);
866
867     // create compound collision shape to attach all created shapes to
868    // btCompoundShape *bshape = new btCompoundShape();
869   //  OgreBulletCollisions::CompoundCollisionShape *cShape = new OgreBulletCollisions::CompoundCollisionShape(bshape);
870     
871    // cShape->addChildShape(boxShape);
872     //cShape->addChildShape(boneShape);
873
874     // create a rigid body for the player
875     //OgreBulletDynamics::RigidBody *RBody
876
877
878     RBodies[id] = new OgreBulletDynamics::RigidBody(
879                 "MCRigid" + Ogre::StringConverter::toString(mNumEntitiesInstanced), 
880                    mWorld, CG_PLAYERS, CM_PLAYERS);
881     RBodies[id]->setShape(playerNodes[id],
882                         boxShape,         // compound shapes containing all child shapes
883                         0.6f,           // dynamic body restitution
884                         0.6f,           // dynamic body friction
885                         100.0f,           // dynamic bodymass
886                         Ogre::Vector3::ZERO,       // starting position of the box
887                         playerNodes[id]->getOrientation());// orientation of the box
888     mNumEntitiesInstanced++;                
889     RBodies[id]->enableActiveState();   
890     RBodies[id]->disableDeactivation();   
891     // kinematic object setting allows to control the body manually
892     RBodies[id]->setKinematicObject(true);     
893     btRigidBodies[id] = RBodies[id]->getBulletRigidBody();
894
895     // push the created objects to the deque
896   //  mShapes.push_back(boneShape);
897     mShapes.push_back(boxShape);
898    // mShapes.push_back(cShape);
899     mBodies.push_back(RBodies[id]); 
900     
901     // for some reason, the entity appears at wrong position (too low), correct that manually  
902     Ogre::Vector3 lift = Ogre::Vector3::ZERO;
903     lift.y += 101.5;
904     playerNodes[id]->translate(lift);
905 /*
906     if (id == myPlayerId)
907     {
908         btVector3 worldMin(-100000,-100000,-100000);
909         btVector3 worldMax(100000,100000,100000);
910         btAxisSweep3* sweepBP = new btAxisSweep3(worldMin,worldMax);
911         //m_overlappingPairCache = sweepBP;
912     
913     
914         btTransform startTransform;
915         startTransform.setIdentity();
916     //startTransform.setOrigin (btVector3(0.0, 4.0, 0.0));
917         startTransform.setOrigin (btVector3(10.210098,-1.6433364,16.453260));
918 Coll
919
920         m_ghostObject = new btPairCachingGhostObject(); 
921         m_ghostObject->setWorldTransform(startTransform);
922         sweepBP->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
923         btScalar characterHeight=1.75;
924         btScalar characterWidth =1.75;
925         btConvexShape* capsule = new btCapsuleShape(characterWidth,characterHeight);
926         m_ghostObject->setCollisionShape (capsule);
927         m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT);
928     }*/
929 }
930 //-------------------------------------------------------------------------------------
931 void Game::predictNext(int id, const Ogre::FrameEvent &evt)
932 {
933
934     Ogre::Vector3 transVector = Ogre::Vector3::ZERO;
935     transVector.z += mMove;
936     if (anStates[id]->getAnimationName() == "walk")
937         playerNodes[id]->translate(transVector * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);
938    
939 }
940 //-------------------------------------------------------------------------------------
941 void Game::restoreCameraPosition()
942 {
943     mCamera->setOrientation(cameraOrient);
944     mCamera->setPosition(cameraPos);
945 }
946 //-------------------------------------------------------------------------------------
947 bool Game::CollisionCheck()
948 {
949     int numManifolds = btWorld->getDispatcher()->getNumManifolds();
950     btSimpleBroadphase *simplebp = new btSimpleBroadphase();
951     bool overlap = simplebp->testAabbOverlap(btRigidBodies[myPlayerId]->getBroadphaseProxy(), btRigidBodies[6]->getBroadphaseProxy()); 
952     if (overlap)
953         std::cout << "overlap\n";
954     for (int i = 0; i < numManifolds; i++)
955     {
956         btPersistentManifold* contactManifold =  btWorld->getDispatcher()->getManifoldByIndexInternal(i);
957         btRigidBody* obA = static_cast<btRigidBody*>(contactManifold->getBody0());
958         btRigidBody* obB = static_cast<btRigidBody*>(contactManifold->getBody1());
959         if (obA->isKinematicObject())
960        //     std::cout << "kinematic\n";
961
962         if (obA == btRigidBodies[myPlayerId])
963             std::cout << "me\n";
964
965         int numContacts = contactManifold->getNumContacts();
966         std::cout << numContacts << " numContacts\n";
967         for (int j=0;j<numContacts;j++)
968         {
969             btManifoldPoint& pt = contactManifold->getContactPoint(j);
970             if (pt.getDistance()<0.f)
971             {
972                 const btVector3& ptA = pt.getPositionWorldOnA();
973                 const btVector3& ptB = pt.getPositionWorldOnB();
974                 const btVector3& normalOnB = pt.m_normalWorldOnB;
975                 std::cout << "collision\n";
976                 std::cout << pt.getDistance() << "\n";
977                 pt.setDistance(50.0f);
978                // return true;
979
980             }   
981             else 
982                 std::cout << pt.getDistance() << "\n";
983         }
984
985            
986     }
987     return false;
988
989 }
990 /*void Game::createPlayer(int id)
991 {
992
993     Player* p;
994
995     SceneNode* playerNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3( 0, 100.5, id*100));
996     Entity* playerEnt = mSceneMgr->createEntity("player" + StringConverter::toString(id), "MCMesh.mesh");
997     std::string playerCaption = "Player " + StringConverter::toString(id);
998     if (id == myPlayerId)  // local player
999     {
1000         p = new Player(id, playerNode, playerEnt, mCamera);
1001         localPlayer = p;
1002         cameraNode = playerNode->createChildSceneNode();
1003         cameraNode->attachObject(mCamera);
1004         SceneNode* msgBoardNode = cameraNode->createChildSceneNode("MsgBoard",Vector3( -0.5, 2, -14.5));
1005         msgBoard = new MovableText("msgBoard", "  . ");
1006         msgBoard->setTextAlignment(MovableText::H_CENTER, MovableText::V_ABOVE); 
1007         msgBoard->setColor(ColourValue::White);
1008         msgBoard->setCharacterHeight(0.8);
1009         msgBoard->setFontName("BlueHighway-12");
1010         msgBoardNode->attachObject(msgBoard);
1011         SceneNode* scoreNode = cameraNode->createChildSceneNode(Vector3(-3.5, 21.4, -8.5));
1012         scoreBoard = new MovableText("scoreBoard", "H:+" + 
1013                 StringConverter::toString(localPlayer->HandshakesDone) + "-" +
1014                 StringConverter::toString(localPlayer->HandshakesReceived) + " R:+" +
1015                 StringConverter::toString(localPlayer->RPSDone) + "-" + 
1016                 StringConverter::toString(localPlayer->RPSReceived) + " P:+" +
1017                 StringConverter::toString(localPlayer->PunchesDone) + "-" +
1018                 StringConverter::toString(localPlayer->PunchesReceived) + " W:+" + 
1019                 StringConverter::toString(localPlayer->WavesDone) + "-" +
1020                 StringConverter::toString(localPlayer->WavesReceived));
1021
1022         scoreBoard->setTextAlignment(MovableText::H_LEFT, MovableText::V_ABOVE); 
1023         scoreBoard->setColor(ColourValue::Black);
1024         scoreBoard->setCharacterHeight(0.8);
1025         scoreBoard->showOnTop();
1026         scoreBoard->setFontName("BlueHighway-12");
1027         scoreNode->attachObject(scoreBoard);
1028
1029         SceneNode* stepsBoardNode = cameraNode->createChildSceneNode(Vector3( 11, 21.4, -8.5));
1030         stepsBoard = new MovableText("stepsBoard", " . " );
1031         stepsBoard->setTextAlignment(MovableText::H_LEFT, MovableText::V_ABOVE); 
1032         stepsBoard->setColor(ColourValue::Black);
1033         stepsBoard->setCharacterHeight(0.8);
1034         stepsBoard->showOnTop();
1035         stepsBoard->setFontName("BlueHighway-12");
1036         stepsBoardNode->attachObject(stepsBoard);
1037
1038         SceneNode* timeBoardNode = cameraNode->createChildSceneNode(Vector3( 5, 21.4, -8.5));
1039         timeBoard = new MovableText("timeBoard", " . " );
1040         timeBoard->setTextAlignment(MovableText::H_LEFT, MovableText::V_ABOVE); 
1041         timeBoard->setColor(ColourValue::Black);
1042         timeBoard->setCharacterHeight(0.8);
1043         timeBoard->showOnTop();
1044         timeBoard->setFontName("BlueHighway-12");
1045         timeBoardNode->attachObject(timeBoard);
1046        
1047        
1048         if (nickName.length() > 0)
1049             playerCaption = nickName;
1050         playerCaption += " (you)";
1051
1052         cameraPos = cameraNode->getPosition();
1053         cameraOrient = cameraNode->getOrientation();
1054         absoluteCameraPos = cameraNode->getPosition();
1055         absoluteCameraOrient = cameraNode->getOrientation();
1056         
1057     }
1058     else
1059     {
1060         Camera* playerCam = mSceneMgr->createCamera("PlayerCam" + StringConverter::toString(id));
1061         playerCam->setPosition(Vector3(0,650,-1100+id*100));
1062         playerCam->lookAt(Vector3(0,250,id*100));
1063         playerCam->setNearClipDistance(5);
1064         playerNode->createChildSceneNode()->attachObject(playerCam); 
1065        
1066         Player *last;
1067         for (last = localPlayer; last->next != NULL; last = last->next)
1068
1069         if (last == localPlayer)
1070             cout << "appending to local player\n";
1071         p = new Player(id, playerNode, playerEnt, playerCam);
1072         last->next = p;
1073
1074     }
1075    
1076     SceneNode* captionNode = playerNode->createChildSceneNode(Vector3(-0.5,3,0));
1077     p->idCaption = new MovableText("idCaption" + StringConverter::toString(id) , playerCaption);
1078     p->idCaption->setTextAlignment(MovableText::H_CENTER, MovableText::V_ABOVE); 
1079     p->idCaption->setColor(ColourValue::Black);
1080     p->idCaption->setCharacterHeight(0.6);
1081     captionNode->attachObject(p->idCaption);
1082   
1083 }
1084 //-------------------------------------------------------------------------------------
1085 */
1086
1087 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
1088 #define WIN32_LEAN_AND_MEAN
1089 #include "windows.h"
1090 #endif
1091
1092 #ifdef __cplusplus
1093         extern "C" {
1094 #endif
1095
1096 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
1097                 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
1098 #else
1099                 int main(int argc, char *argv[])
1100 #endif
1101                 {
1102                         // Create application object
1103                         Game app;
1104            
1105                         try {
1106                 pthread_mutex_init(&send_mutex, NULL);
1107                 pthread_mutex_init(&update_mutex, NULL);
1108                 pthread_cond_init(&send_start, NULL);
1109                 pthread_cond_init(&update_start, NULL);
1110                 pthread_t thread_id=0;
1111                 pthread_create(&thread_id,0,&Game::sendThread,(void*)&app);
1112                 pthread_detach(thread_id);
1113                 pthread_create(&thread_id,NULL,&Game::receiveThread,(void*)&app);
1114                 pthread_detach(thread_id);
1115
1116                                 app.go();
1117                 
1118             
1119            
1120             
1121                 
1122                         } catch( Ogre::Exception& e ) {
1123 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
1124                                 MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
1125 #else
1126                                 std::cerr << "An exception has occured: " <<
1127                                         e.getFullDescription().c_str() << std::endl;
1128 #endif
1129                         }
1130
1131                         return 0;
1132                 }
1133
1134 #ifdef __cplusplus
1135         }
1136 #endif
1137
1138
1139     /*
1140     - idle 1
1141     - walk 2
1142     - wave 3
1143     - nod 4
1144     - punch 5
1145     - headshake 6
1146     - handshake
1147     - waving
1148     - come here
1149     - kick
1150     - punch
1151     - nod
1152     - shake
1153     - saks, stein, papir
1154     */