00001 #include "PhCirclingCamera.hpp" 00002 #include "sim/area/Area.hpp" 00003 #include "../area/NavMeshArea.hpp" 00004 #include "sim/physics/PhysicsComponent.hpp" 00005 00006 using namespace se_basic; 00007 using namespace se_client; 00008 using namespace se_core; 00009 00010 namespace se_basic { 00011 00012 const PhCirclingCamera physicsCirclingCamera; 00013 00014 00015 void PhCirclingCamera 00016 ::calcNext(const PhysicsComponent& physics 00017 , const Pos& pos 00018 , Pos& nextPos 00019 , const Move& move 00020 , Move& nextMove 00021 ) const { 00022 00023 // If the camera is not inside an area, physics are meaningless 00024 if(!pos.hasArea()) { 00025 return; 00026 } 00027 00028 if(!nextPos.hasParent()) { 00029 return; 00030 } 00031 00032 // Player has already been updated, because it is set as 00033 // the parent by the "T" option in the data/logic/start/start.txt 00034 PosComponent::Ptr target(*nextPos.parent()); 00035 const Pos& targetPos = target->nextPos(); 00036 00037 // As this camera dangles behind the player, the player should 00038 // be inside an area as well 00039 if(!targetPos.hasArea()) { 00040 return; 00041 } 00042 00043 // If they are on the same position, move camera 00044 // to the players spawn coordinate 0 00045 //SpawnComponent::Ptr targetSpawn(*target); 00046 //ViewPoint lookAt(*playerSpawn->spawnPoint(4)); 00047 //lookAt.add(playerPos.world_); 00048 ViewPoint lookAt(targetPos.world_); 00049 00050 // Keep the camera inside the same area as the player. 00051 // (This camera cannot collide, so it doesn't matter if the 00052 // camera coordinate is outside area bounds.) 00053 PosComponent* a = target->nextPos().area(); 00054 if(a != 0 && a != nextPos.area()) { 00055 nextPos.setArea(*a); 00056 } 00057 00058 NavMeshArea::Ptr area(ClientSchema::player->nextPos().area()); 00059 Point3 dest(0, 6 * COOR_RES, 0); 00060 Vector3 tmp; 00061 tmp.sub(lookAt.coor_, pos.worldCoor()); 00062 tmp.y_ = 0; 00063 coor_t dist = tmp.length(); 00064 bray_t yaw = BrayT::invert(pos.worldFace().yaw_); 00065 yaw = BrayT::invert(tmp.yaw()); 00066 00067 coor_t MAX_TRAIL_DISTANCE = 16 * COOR_RES; 00068 coor_t MIN_TRAIL_DISTANCE = 1 * COOR_RES; 00069 coor_t MOVE_SPEED = 0.3f; 00070 coor_t TRAIL_DISTANCE = dist + MOVE_SPEED; 00071 if(MOVE_SPEED < 0) 00072 MOVE_SPEED = 1; 00073 00074 if(TRAIL_DISTANCE > MAX_TRAIL_DISTANCE) { 00075 TRAIL_DISTANCE = MAX_TRAIL_DISTANCE; 00076 } 00077 coor_t legalDist = area->farthestLineOfSight(targetPos, yaw, TRAIL_DISTANCE, 1 * COOR_RES, dest); 00078 if(dist > legalDist || dist < MIN_TRAIL_DISTANCE || true) { 00079 if(TRAIL_DISTANCE > legalDist) { 00080 TRAIL_DISTANCE -= 2 * MOVE_SPEED; 00081 if(TRAIL_DISTANCE < legalDist) { 00082 TRAIL_DISTANCE = legalDist; 00083 } 00084 } 00085 //dest.add(areaPos->nextPos().worldCoor()); 00086 dest.setForward(TRAIL_DISTANCE, yaw); 00087 dest.add(lookAt.coor_); 00088 dest.y_ = 6 + 2 * (1 - (TRAIL_DISTANCE / MAX_TRAIL_DISTANCE)); 00089 00090 nextPos.worldCoor().set(dest); 00091 } 00092 nextPos.worldCoor().eulerTowards(lookAt.coor_, nextPos.worldFace()); 00093 //nextPos.worldFace().yaw_ = BrayT::towards(pos.worldFace().yaw_, targetPos.worldFace().yaw_, BRAY_RES >> 2); 00094 00095 // Look at the player 00096 nextPos.updateLocalViewPoint(); 00097 } 00098 00099 00100 void PhCirclingCamera 00101 ::affect(PhysicsComponent& physics) const { 00102 if(!PosComponent::Ptr(physics)->nextPos().hasArea()) { 00103 // Camera has left all areas - which means 00104 // it should be destroyed 00105 //physics.owner()->scheduleForDestruction(); 00106 } 00107 } 00108 00109 }
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:03 2007 by Doxygen version 1.3.9.1.