source: GTP/trunk/App/Demos/Illum/Ogre/src/Common/src/FPSPlayer.cpp @ 2443

Revision 2443, 16.7 KB checked in by szirmay, 17 years ago (diff)
Line 
1#include "fpsplayer.h"
2
3FPSPlayer* FPSPlayer::thePlayer = NULL;
4unsigned int PlayerCharacter::frameListenerPriority = 1;
5
6class MyTrigger : public Trigger
7{
8public:
9        MyTrigger(const NxString& meshIdentifier, Scene* scene, ShapeDescription* shape, const NxOgre::Pose& pose, ActorParams params = ""):
10          Trigger(meshIdentifier, scene, shape, pose, params)
11          {
12          }
13
14         void onEnter(Actor* a)
15         {
16                int ize = 0;
17         }
18};
19
20class MyCharMoveController : public CharacterMovementVectorController
21{
22public:
23        MyCharMoveController(float speed = 1.5){movespeed = speed;}
24        float movespeed;
25        void move(NxVec3 &out, NxVec3 &moveVector, NxQuat &direction, NxVec3 &g, float t, Character*)
26        {
27                NxVec3 dir = direction.rot(moveVector);
28                out = ((dir * movespeed) + g) * t;             
29        }
30};
31
32PlayerCharacter::PlayerCharacter(String name, Scene* scene, SceneManager* sceneManager, Vector3 dimensions, Vector3 startPosition, bool debug)
33{
34        mName = name;
35        mPlayerDimensions = dimensions;
36        mDebug = debug;
37        mSceneManager = sceneManager;
38        mScene = scene;
39        CharacterParams cp;
40        cp.setToDefault();
41        cp.mDimensions = NxVec3(dimensions.x, dimensions.y, dimensions.z);
42        cp.mType = CharacterParams::CT_Box;
43        mPlayerCharacter = mScene->createCharacter(mName, startPosition, cp);
44        mPlayerCharacter->createNode();
45        mPlayerNode = mPlayerCharacter->getNode();
46       
47        mCharacterController = 0;
48        mCharacterController = new MyCharMoveController(2.0);
49        mPlayerCharacter->setMovementVectorController(mCharacterController);
50
51        if(mDebug)
52        {
53                mPlayerBoundDebugNode = mPlayerNode->createChildSceneNode(mName + "_BoundDebugNode");
54                mPlayerBoundDebugNode->setScale(dimensions);
55                mPlayerBoundDebugNode->attachObject(mSceneManager->createEntity(mName + "_BoundDebug", "cube.mesh"));
56        }
57
58        mCharacterMesh_AnimState = 0;
59        mForceAnimChange = false;
60        mWeapon = 0;
61        mWeaponBound = 0;
62        mWeaponBoundDebugNode = 0;
63        mCharacterMeshEntity = 0;
64        mWeaponEntity = 0;
65        mWeaponAttachBone = 0;
66    mWeaponNode = 0;
67        mWeaponBoundNode = 0;
68        mWeaponBoundDebugNode = 0;
69        mPlayerBoundDebugNode = 0;
70        mWeaponBound = 0;
71        mWeaponNode2 = 0;
72               
73        this->setPriority(frameListenerPriority++);
74        Root::getSingleton().addFrameListener(this);
75
76        //mPlayerCharacter->setCharacterCollisionGroup(NX_CHARACTER_COL_GROUP_CHARACTER);
77        //mScene->getNxScene()->setGroupCollisionFlag(NX_CHARACTER_COL_GROUP_CHARACTER, NX_CHARACTER_COL_GROUP_NON_COLLIDABLE,false);
78}
79
80FPSPlayer::FPSPlayer(Scene* scene, SceneManager* sceneManager, Vector3 dimensions, Vector3 startPosition, float cameraHeight, Camera* cam, bool debug)
81: PlayerCharacter("FPSPlayerCharacter", scene, sceneManager, dimensions, startPosition, debug)
82{
83        mCameraHeight = cameraHeight - dimensions.y / 2.0;
84        mCamera = cam;
85        mPlayerNode->attachObject(cam);
86       
87        thePlayer = this;
88}
89
90FPSPlayer::~FPSPlayer(void)
91{
92}
93
94void PlayerCharacter::addPlayerMesh(String meshname, float meshscale, bool rotateModel)
95{
96        mCharacterMeshEntity = mSceneManager->createEntity(mName, meshname);
97        mCharacterMeshEntity->setCastShadows(false);
98        mMeshScale = meshscale;
99        mCurrentAnimState = PLAYERANIMSTATE_STAND;
100        mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_STAND));
101        mCharacterMesh_AnimState->setEnabled(true);
102        mCharacterMesh_AnimState->setLoop(true);
103        SceneNode* meshNode = mPlayerNode->createChildSceneNode(mName + "_MeshNode");
104        meshNode->attachObject(mCharacterMeshEntity);
105        meshNode->setPosition(0 ,-mPlayerDimensions.y / 2.0, 0);
106        meshNode->setScale(meshscale, meshscale, meshscale);
107        if(rotateModel)
108        meshNode->rotate(Vector3::UNIT_Y, Degree(180.0));       
109}
110
111void FPSPlayer::addPlayerMesh(String meshname, float meshscale, bool rotateModel)
112{
113        mCharacterMeshEntity = mSceneManager->createEntity(mName, meshname);
114        mCharacterMeshEntity->setCastShadows(false);
115        mMeshScale = meshscale;
116        mCurrentAnimState = PLAYERANIMSTATE_STAND;
117        mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_STAND));
118        mCharacterMesh_AnimState->setEnabled(true);
119        mCharacterMesh_AnimState->setLoop(true);
120        SceneNode* FPSArmNode = mPlayerNode->createChildSceneNode(mName+"_ArmNode");
121        FPSArmNode->attachObject(mCharacterMeshEntity);
122        FPSArmNode->setPosition(0,mCameraHeight,0);
123        FPSArmNode->setScale(meshscale, meshscale, meshscale);
124        if(rotateModel)
125        FPSArmNode->rotate(Vector3::UNIT_Y, Degree(180.0));
126}
127
128void PlayerCharacter::addWeaponModel(String meshname, String attachBoneName)
129{
130       
131        mWeaponEntity = mSceneManager->createEntity(mName + "_Weapon", meshname);
132        mWeaponAttachBone = mCharacterMeshEntity->getSkeleton()->getBone(attachBoneName);
133        mWeaponNode = mCharacterMeshEntity->getParentSceneNode()->createChildSceneNode(mName + "_WeaponNode"); 
134        mWeaponNode->attachObject(mWeaponEntity);
135
136        AxisAlignedBox bb = mWeaponEntity->getBoundingBox();
137
138        Vector3 max = bb.getMaximum();
139        //max.z *= 2.0;
140        Vector3 min = bb.getMinimum();
141        Vector3 center = (min + max) / 2.0;
142        //center.z = max.z;
143
144        mWeaponBoundNode = mWeaponNode->createChildSceneNode(mName + "_WeaponBoundNode");
145        mWeaponBoundNode->setPosition(center);
146/*
147        SceneNode* ArmNode2 = mPlayerNode->createChildSceneNode();
148        ArmNode2->setPosition(0,mCameraHeight , -mPlayerDimensions.z);
149        ArmNode2->rotate(Vector3::UNIT_Y, Degree(180.0));
150        mWeaponNode2 = ArmNode2->createChildSceneNode();
151        mWeaponBoundNode = mWeaponNode2->createChildSceneNode();
152        mWeaponBoundNode->setPosition(center * mMeshScale );
153*/     
154
155        max *= mMeshScale;
156        min *= mMeshScale;
157        float dimX = max.x-min.x;
158        float dimY = max.y-min.y;
159        float dimZ = max.z-min.z;
160        Vector3 dim(dimX, dimY, dimZ);
161
162        mWeaponBound = new MyTrigger(mName + "_WeaponTrigger", mScene, new CubeShape(dimX, dimY, dimZ, "trigger: yes"), Vector3(0,0,0), "mass: 0, density: 0");
163        mScene->addTrigger((Trigger*)mWeaponBound);
164               
165        if(mDebug)
166        {
167                mWeaponBoundDebugNode = mSceneManager->getRootSceneNode()->createChildSceneNode(mName+"_WeaponBoundDebugNode");
168                mWeaponBoundDebugNode->setScale(dim);
169                mWeaponBoundDebugNode->attachObject(mSceneManager->createEntity(mName+"_WeaponBoundDebug", "cube.mesh"));
170        }
171
172        //mWeaponBound->setCharacterCollisionGroup(NX_CHARACTER_COL_GROUP_NON_COLLIDABLE);     
173}
174
175void FPSPlayer::addWeaponModel(String meshname, String attachBoneName)
176{
177       
178        mWeaponEntity = mSceneManager->createEntity(mName + "_Weapon", meshname);
179        mWeaponEntity->setCastShadows(false);
180        mWeaponAttachBone = mCharacterMeshEntity->getSkeleton()->getBone(attachBoneName);
181        mWeaponNode = mCharacterMeshEntity->getParentSceneNode()->createChildSceneNode(mName+"_WeaponNode");   
182        mWeaponNode->attachObject(mWeaponEntity);
183
184        AxisAlignedBox bb = mWeaponEntity->getBoundingBox();
185
186        Vector3 max = bb.getMaximum();
187        //max.z *= 2.0;
188        Vector3 min = bb.getMinimum();
189        Vector3 center = (min + max) / 2.0;
190        //center.z = max.z;
191
192        //mWeaponBoundNode = mWeaponNode->createChildSceneNode();
193        //mWeaponBoundNode->setPosition(center);
194
195        SceneNode* ArmNode2 = mPlayerNode->createChildSceneNode(mName+"_ArmNode2");
196        ArmNode2->setPosition(0,mCameraHeight , -mPlayerDimensions.z);
197        ArmNode2->rotate(Vector3::UNIT_Y, Degree(180.0));
198        mWeaponNode2 = ArmNode2->createChildSceneNode();
199        mWeaponBoundNode = mWeaponNode2->createChildSceneNode(mName+"_WeaponBoundNode");
200        mWeaponBoundNode->setPosition(center * mMeshScale );
201       
202
203        max *= mMeshScale;
204        min *= mMeshScale;
205        float dimX = max.x-min.x;
206        float dimY = max.y-min.y;
207        dimY *=3;
208        float dimZ = max.z-min.z;
209        Vector3 dim(dimX, dimY, dimZ);
210
211//      mWeaponBound = mScene->createActor("FPSPlayerWeapon", new CubeShape(dimX, dimY, dimZ), Vector3(0,0,0), "kinematic: yes, mass: 10");
212        mWeaponBound = new MyTrigger(mName + "_WeaponTrigger", mScene, new CubeShape(dimX, dimY, dimZ, "trigger: yes"), Vector3(0,0,0), "mass: 0, density: 0");
213        mScene->addTrigger((Trigger*)mWeaponBound);
214       
215        if(mDebug)
216        {
217                mWeaponBoundDebugNode = mSceneManager->getRootSceneNode()->createChildSceneNode(mName+"_WeaponBoundDebugNode");
218                mWeaponBoundDebugNode->setScale(dim);
219                mWeaponBoundDebugNode->attachObject(mSceneManager->createEntity(mName+"_WeaponBoundDebug", "cube.mesh"));
220        }
221
222        mWeaponBound->setCharacterCollisionGroup(NX_CHARACTER_COL_GROUP_NON_COLLIDABLE);       
223}
224
225void PlayerCharacter::doAction(float dt)
226{
227        FPSPlayer* thePlayer = FPSPlayer::getPlayer();
228
229        if(thePlayer)
230        {
231                Vector3 playerPos = thePlayer->getPosition();
232                Vector3 myPos = mPlayerNode->getWorldPosition();
233                Vector3 dir = playerPos - myPos;
234                dir.y = 0;
235                //if( dir.length() > 1.0)
236                //{
237                        dir.normalise();
238                        Vector3 right = -dir.crossProduct(Vector3::UNIT_Y);
239                        Quaternion q;                   
240                        q.FromAxes(right,Vector3::UNIT_Y,dir);
241                        //mPlayerCharacter->setDirection(q);
242                        if(mCharacterController )
243                        ((MyCharMoveController*)mCharacterController)->movespeed = 1.5;
244                        //mPlayerCharacter->addMovement(Character::DR_StepRight);
245                //}
246
247        }
248        //if(mCharacterMeshEntity)
249        //setAnimState(PLAYERANIMSTATE_WALK);
250}
251
252bool PlayerCharacter::frameStarted(const FrameEvent& evt)
253{
254//      LogManager::getSingleton().logMessage("CHARACTERPLAYER_FRAMESTARTED");
255        doAction(evt.timeSinceLastFrame);
256
257        float dt = evt.timeSinceLastFrame;
258               
259        if(mCharacterMesh_AnimState)
260        {
261                float animspeed = 1.2;
262                if(mCurrentAnimState == PLAYERANIMSTATE_WALK && !mRunning)
263                        animspeed /= 2;
264
265                mCharacterMesh_AnimState->addTime(dt*animspeed);       
266        }
267
268        return true;
269}
270
271void FPSPlayer::processKeyInputs(InputReader* inputDevice)
272{               
273                mMoving = false;
274                if (inputDevice->isKeyDown(KC_W))
275                {
276                        mPlayerCharacter->addMovement(Character::DR_StepLeft);
277                        mMoving = true;
278                }       
279                if (inputDevice->isKeyDown(KC_S))
280                {
281                        mPlayerCharacter->addMovement(Character::DR_StepRight);
282                        mMoving = true;
283                }
284                if (inputDevice->isKeyDown(KC_A))
285                {
286                        mPlayerCharacter->addMovement(Character::DR_Forward);
287                        mMoving = true;
288                }
289                if (inputDevice->isKeyDown(KC_D))
290                {
291                        mPlayerCharacter->addMovement(Character::DR_Backward);
292                        mMoving = true;
293                }
294
295                if (inputDevice->isKeyDown(KC_1))
296                {
297                        mWeapon = 0;
298                        mForceAnimChange = true;
299                }
300                if (inputDevice->isKeyDown(KC_2))
301                {
302                        mWeapon = 1;
303                        mForceAnimChange = true;
304                }
305
306                if (inputDevice->isKeyDown(KC_LSHIFT))
307                {
308                        if(mCharacterController)
309                        ((MyCharMoveController*)mCharacterController)->movespeed = 4.0;
310                        mRunning = true;
311                }
312                else
313                {
314                        if(mCharacterController)
315                        ((MyCharMoveController*)mCharacterController)->movespeed = 2.0;
316                        mRunning = false;
317                }
318}
319
320void FPSPlayer::processMouseInputs(InputReader* inputDevice)
321{
322        if( inputDevice->getMouseButton( 0 ) )//attack
323                setAnimState(PLAYERANIMSTATE_ATTACK);
324               
325        else if( inputDevice->getMouseButton( 1 ) )//block
326                setAnimState(PLAYERANIMSTATE_BLOCK);
327
328        Quaternion q;
329        q.FromAngleAxis( Radian(Degree(-inputDevice->getMouseRelX() * 0.13)), Vector3::UNIT_Y );
330        q = mPlayerCharacter->getGlobalOrientation() * q;
331        mPlayerCharacter->setDirection(q);
332
333        mCamera->pitch(Radian(Degree(-inputDevice->getMouseRelY() * 0.13)));           
334}
335
336bool FPSPlayer::frameStarted(const FrameEvent& evt)
337{
338//      LogManager::getSingleton().logMessage("FPSPLAYER_FRAMESTARTED");
339
340        float dt = evt.timeSinceLastFrame;
341               
342        if(mCharacterMesh_AnimState)
343        {
344                float animspeed = 1.2;
345                if(mCurrentAnimState == PLAYERANIMSTATE_WALK && mRunning)
346                        animspeed *= 1.5;
347                if(mCurrentAnimState == PLAYERANIMSTATE_ATTACK)
348                        animspeed *= 2.0;
349
350                mCharacterMesh_AnimState->addTime(dt*animspeed);       
351        }
352
353        static float moveTime=0;
354       
355        float movecameraup = 0;
356        if(mDebug)movecameraup = 20.0;
357
358        if(mMoving)
359        {
360                setAnimState(PLAYERANIMSTATE_WALK);
361
362                moveTime += dt;
363                mCamera->setPosition(Vector3(0,mCameraHeight + movecameraup,0) + Vector3(0,0.009 * pow(sin(moveTime*5.0), 2),0));
364        }
365        else
366        {
367                if(Math::UnitRandom() > 0.98)
368                        setAnimState(PLAYERANIMSTATE_IDLE);
369                else
370                        setAnimState(PLAYERANIMSTATE_STAND);
371
372                moveTime = 0;
373                mCamera->setPosition(Vector3(0,mCameraHeight + movecameraup,0));
374        }
375
376        if(mCharacterMeshEntity)
377        this->mCharacterMeshEntity->_updateAnimation();
378
379        if(mWeaponEntity)
380        {
381                mWeaponNode->setPosition(mWeaponAttachBone->getWorldPosition());
382                mWeaponNode->setOrientation(mWeaponAttachBone->getWorldOrientation());
383
384                mWeaponNode2->setPosition(mWeaponAttachBone->getWorldPosition() * mMeshScale);
385                mWeaponNode2->setOrientation(mWeaponAttachBone->getWorldOrientation());
386
387                Vector3 translation = mWeaponBoundNode->getWorldPosition();
388                Quaternion orientation = mWeaponBoundNode->getWorldOrientation();
389               
390                mWeaponBound->setGlobalOrientation(orientation);               
391                mWeaponBound->setGlobalPosition(translation);
392
393                //mWeaponBound->setGlobalPosition(translation);         
394                //mWeaponBound->setGlobalOrientation(orientation);
395
396                if(mDebug)
397                {
398                        mWeaponBoundDebugNode->setPosition(translation);
399                        mWeaponBoundDebugNode->setOrientation(orientation);
400                }
401        }
402
403        return true;
404}
405
406String FPSPlayer::getAnimStateName(PlayerAnimState as, int option)
407{
408        switch (as)
409        {
410                case PLAYERANIMSTATE_IDLE:
411                {
412                        if(mWeapon < 1)
413                                return "sword_idle";
414                        else
415                                return "magic_idle";
416                }
417                case PLAYERANIMSTATE_STAND:
418                {
419                        if(mWeapon < 1)
420                                return "sword_stand";
421                        else
422                                return "magic_stand";
423                }
424                case PLAYERANIMSTATE_BLOCK:
425                {
426                                return "block";                 
427                }
428                case PLAYERANIMSTATE_WALK:
429                {
430                                return "walk";                 
431                }
432                case PLAYERANIMSTATE_ATTACK:
433                {
434                        if(option)
435                        {
436                                if(mWeapon < 1)
437                                        return "attack1";
438                                else
439                                        return "magic_attack";
440                        }
441                        else
442                        {
443                                if(mWeapon < 1)
444                                        return "attack2";
445                                else
446                                        return "magic_attack";
447                        }
448                }
449        }
450        return "";
451}
452
453void FPSPlayer::setAnimState(PlayerAnimState as)
454{
455        if(!mCharacterMeshEntity)
456                return;
457
458        switch(as)     
459        {
460                case PLAYERANIMSTATE_STAND:
461                {
462                        if(mCurrentAnimState != PLAYERANIMSTATE_STAND || mForceAnimChange)
463                        {
464                                //wait until anim finishes
465                                if(mCharacterMesh_AnimState->getTimePosition() >=
466                                        mCharacterMesh_AnimState->getLength() || mCharacterMesh_AnimState->getLoop())
467                                {
468                                        mCurrentAnimState = PLAYERANIMSTATE_STAND;
469                                        mCharacterMesh_AnimState->setEnabled(false);
470                                        mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_STAND));
471                                        mCharacterMesh_AnimState->setLoop(true);
472                                        mCharacterMesh_AnimState->setEnabled(true);
473                                }
474                        }
475                        break;
476                }
477                case PLAYERANIMSTATE_IDLE:
478                {
479                        if(mCurrentAnimState != PLAYERANIMSTATE_IDLE || mForceAnimChange)
480                        {
481                                //wait until anim finishes
482                                if(mCharacterMesh_AnimState->getTimePosition() >=
483                                        mCharacterMesh_AnimState->getLength() || mCharacterMesh_AnimState->getLoop() || mCurrentAnimState == PLAYERANIMSTATE_IDLE)
484                                {
485                                        mCurrentAnimState = PLAYERANIMSTATE_IDLE;
486                                        mCharacterMesh_AnimState->setEnabled(false);
487                                        mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_IDLE));
488                                        mCharacterMesh_AnimState->setTimePosition(0);
489                                        mCharacterMesh_AnimState->setLoop(false);
490                                        mCharacterMesh_AnimState->setEnabled(true);
491                                }
492                        }
493                        break;
494                }
495                case PLAYERANIMSTATE_WALK:
496                {
497                        if(mCurrentAnimState != PLAYERANIMSTATE_WALK)
498                        {
499                                if(mCurrentAnimState == PLAYERANIMSTATE_IDLE || mCurrentAnimState == PLAYERANIMSTATE_STAND)
500                                {
501                                        mCurrentAnimState = PLAYERANIMSTATE_WALK;
502                                        mCharacterMesh_AnimState->setEnabled(false);
503                                        mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_WALK));
504                                        mCharacterMesh_AnimState->setLoop(true);
505                                        mCharacterMesh_AnimState->setEnabled(true);
506                                }
507                        }
508                        break;
509                }
510                case PLAYERANIMSTATE_ATTACK:
511                {
512                        if(mCharacterMesh_AnimState->getTimePosition() >=
513                                        mCharacterMesh_AnimState->getLength() || mCharacterMesh_AnimState->getLoop() || mCurrentAnimState == PLAYERANIMSTATE_IDLE)
514                        {
515                            int attackType = 0;
516                                if(Math::UnitRandom() > 0.5)
517                                         attackType = 1;
518
519                                mCurrentAnimState = PLAYERANIMSTATE_ATTACK;
520                                mCharacterMesh_AnimState->setEnabled(false);
521                                mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_ATTACK, attackType));
522                                mCharacterMesh_AnimState->setTimePosition(0);
523                                mCharacterMesh_AnimState->setLoop(false);
524                                mCharacterMesh_AnimState->setEnabled(true);
525                        }
526                        break;
527                }               
528                case PLAYERANIMSTATE_BLOCK:
529                {
530                        if(mCharacterMesh_AnimState->getTimePosition() >=
531                                        mCharacterMesh_AnimState->getLength() || mCharacterMesh_AnimState->getLoop() || mCurrentAnimState == PLAYERANIMSTATE_IDLE)
532                        {
533                                mCurrentAnimState = PLAYERANIMSTATE_BLOCK;
534                                mCharacterMesh_AnimState->setEnabled(false);
535                                mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_BLOCK));
536                                mCharacterMesh_AnimState->setTimePosition(0);
537                                mCharacterMesh_AnimState->setLoop(false);
538                                mCharacterMesh_AnimState->setEnabled(true);
539                        }
540                        break;
541                }
542        }
543
544        if(mForceAnimChange)
545                mForceAnimChange = false;
546}
Note: See TracBrowser for help on using the repository browser.