Player.cpp
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 Filename    :   Player.cpp
00004 Content     :   Player location and hit-testing logic source
00005 Created     :   October 4, 2012
00006 
00007 Copyright   :   Copyright 2012 Oculus, Inc. All Rights reserved.
00008 
00009 Licensed under the Apache License, Version 2.0 (the "License");
00010 you may not use this file except in compliance with the License.
00011 You may obtain a copy of the License at
00012 
00013 http://www.apache.org/licenses/LICENSE-2.0
00014 
00015 Unless required by applicable law or agreed to in writing, software
00016 distributed under the License is distributed on an "AS IS" BASIS,
00017 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018 See the License for the specific language governing permissions and
00019 limitations under the License.
00020 
00021 *************************************************************************************/
00022 
00023 #include "Player.h"
00024 #include <Kernel/OVR_Alg.h>
00025 
00026 Player::Player(void)
00027         : EyeHeight(1.8f),
00028           EyePos(7.7f, 1.8f, -1.0f),
00029       EyeYaw(YawInitial), EyePitch(0), EyeRoll(0),
00030       LastSensorYaw(0)
00031 {
00032         MoveForward = MoveBack = MoveLeft = MoveRight = 0;
00033     GamepadMove = Vector3f(0);
00034     GamepadRotate = Vector3f(0);
00035 }
00036 
00037 
00038 Player::~Player(void)
00039 {
00040 }
00041 
00042 void Player::HandleCollision(double dt, Array<Ptr<CollisionModel> >* collisionModels,
00043                                  Array<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown)
00044 {
00045         if(MoveForward || MoveBack || MoveLeft || MoveRight || GamepadMove.LengthSq() > 0)
00046     {
00047         Vector3f orientationVector;
00048         // Handle keyboard movement.
00049         // This translates EyePos based on Yaw vector direction and keys pressed.
00050         // Note that Pitch and Roll do not affect movement (they only affect view).
00051         if(MoveForward || MoveBack || MoveLeft || MoveRight)
00052         {
00053             Vector3f localMoveVector(0, 0, 0);
00054             Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw);
00055             
00056             if (MoveForward)
00057             {
00058                 localMoveVector = ForwardVector;
00059             }
00060             else if (MoveBack)
00061             {
00062                 localMoveVector = -ForwardVector;
00063             }
00064 
00065             if (MoveRight)
00066             {
00067                 localMoveVector += RightVector;
00068             }
00069             else if (MoveLeft)
00070             {
00071                 localMoveVector -= RightVector;
00072             }
00073 
00074             // Normalize vector so we don't move faster diagonally.
00075             localMoveVector.Normalize();
00076             orientationVector = yawRotate.Transform(localMoveVector);
00077         }
00078         else if (GamepadMove.LengthSq() > 0)
00079         {
00080             Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw);
00081             GamepadMove.Normalize();
00082             orientationVector = yawRotate.Transform(GamepadMove);
00083         }
00084 
00085         float moveLength = OVR::Alg::Min<float>(MoveSpeed * (float)dt * (shiftDown ? 3.0f : 1.0f), 1.0f);
00086 
00087         float   checkLengthForward = moveLength;
00088         Planef  collisionPlaneForward;
00089         float   checkLengthLeft = moveLength;
00090         Planef  collisionPlaneLeft;
00091         float   checkLengthRight = moveLength;
00092         Planef  collisionPlaneRight;
00093         bool    gotCollision = false;
00094         bool    gotCollisionLeft = false;
00095         bool    gotCollisionRight = false;
00096 
00097         for(unsigned int i = 0; i < collisionModels->GetSize(); ++i)
00098         {
00099             // Checks for collisions at eye level, which should prevent us from
00100                         // slipping under walls
00101             if (collisionModels->At(i)->TestRay(EyePos, orientationVector, checkLengthForward,
00102                                                                 &collisionPlaneForward))
00103             {
00104                 gotCollision = true;
00105             }
00106 
00107             Matrix4f leftRotation = Matrix4f::RotationY(45 * (Math<float>::Pi / 180.0f));
00108             Vector3f leftVector   = leftRotation.Transform(orientationVector);
00109             if (collisionModels->At(i)->TestRay(EyePos, leftVector, checkLengthLeft,
00110                                                                 &collisionPlaneLeft))
00111             {
00112                 gotCollisionLeft = true;
00113             }
00114             Matrix4f rightRotation = Matrix4f::RotationY(-45 * (Math<float>::Pi / 180.0f));
00115             Vector3f rightVector   = rightRotation.Transform(orientationVector);
00116             if (collisionModels->At(i)->TestRay(EyePos, rightVector, checkLengthRight,
00117                                                                 &collisionPlaneRight))
00118             {
00119                 gotCollisionRight = true;
00120             }
00121         }
00122 
00123         if (gotCollision)
00124         {
00125             // Project orientationVector onto the plane
00126             Vector3f slideVector = orientationVector - collisionPlaneForward.N
00127                                 * (orientationVector * collisionPlaneForward.N);
00128 
00129             // Make sure we aren't in a corner
00130             for(unsigned int j = 0; j < collisionModels->GetSize(); ++j)
00131             {
00132                 if (collisionModels->At(j)->TestPoint(EyePos - Vector3f(0.0f, RailHeight, 0.0f) +
00133                                                                           (slideVector * (moveLength))) )
00134                 {
00135                     moveLength = 0;
00136                 }
00137             }
00138             if (moveLength != 0)
00139             {
00140                 orientationVector = slideVector;
00141             }
00142         }
00143         // Checks for collisions at foot level, which allows us to follow terrain
00144         orientationVector *= moveLength;
00145         EyePos += orientationVector;
00146 
00147         Planef collisionPlaneDown;
00148         float finalDistanceDown = 10;
00149 
00150         for(unsigned int i = 0; i < groundCollisionModels->GetSize(); ++i)
00151         {
00152             float checkLengthDown = 10;
00153             if (groundCollisionModels->At(i)->TestRay(EyePos, Vector3f(0.0f, -1.0f, 0.0f),
00154                                                                       checkLengthDown, &collisionPlaneDown))
00155             {
00156                 finalDistanceDown = Alg::Min(finalDistanceDown, checkLengthDown);
00157             }
00158         }
00159 
00160         // Maintain the minimum camera height
00161         if (EyeHeight - finalDistanceDown < 1.0f)
00162         {
00163             EyePos.y += EyeHeight - finalDistanceDown;
00164         }
00165     }
00166 }


oculus_sdk
Author(s):
autogenerated on Mon Oct 6 2014 03:01:19