From: <leo...@us...> - 2010-07-23 23:31:00
|
Revision: 4076 http://cel.svn.sourceforge.net/cel/?rev=4076&view=rev Author: leonardord Date: 2010-07-23 23:30:54 +0000 (Fri, 23 Jul 2010) Log Message: ----------- pc mover: -Added a smooth property to iPcMover. If smooth is set (default behaviour), this class will behave just like it did before. However, if it is not set, the turns used during movement will be sudden and instant, causing the movement to happen only in straight lines. The smooth parameter can be accessed using iPcMover::IsSmoothMovement() and iPcMover::SetSmoothMovement(). demo app: -Fixed the path following code. Now the agent will walk without deviating from the path. -Fixed the navmesh and path debug rendering code. -Added keybinds for switching debug rendering on and off. '1' controls navigation meshes rendering, '2' controls destination rendering and '3' controls path rendering. Modified Paths: -------------- cel/branches/soc2010/navmesh/apps/pathfindingtest/BehaviourLayer.cpp cel/branches/soc2010/navmesh/apps/pathfindingtest/BehaviourLayer.h cel/branches/soc2010/navmesh/apps/pathfindingtest/MainApp.cpp cel/branches/soc2010/navmesh/apps/pathfindingtest/MainApp.h cel/branches/soc2010/navmesh/include/propclass/mover.h cel/branches/soc2010/navmesh/plugins/propclass/mover/moverfact.cpp cel/branches/soc2010/navmesh/plugins/propclass/mover/moverfact.h Modified: cel/branches/soc2010/navmesh/apps/pathfindingtest/BehaviourLayer.cpp =================================================================== --- cel/branches/soc2010/navmesh/apps/pathfindingtest/BehaviourLayer.cpp 2010-07-21 23:31:31 UTC (rev 4075) +++ cel/branches/soc2010/navmesh/apps/pathfindingtest/BehaviourLayer.cpp 2010-07-23 23:30:54 UTC (rev 4076) @@ -56,8 +56,18 @@ return navStruct; } +void BehaviourLayer::SetPath (iCelHPath* path) +{ + this->path = path; +} +iCelHPath* BehaviourLayer::GetPath () const +{ + return path; +} + + /* * BehaviourCommon */ @@ -242,7 +252,11 @@ if (msg_id == id_pccommandinput_forward1) { - pcActorMove->Forward(true); + //pcActorMove->Forward(true); + csRef<iPcCamera> pcCamera = CEL_QUERY_PROPCLASS_ENT(entity, iPcCamera); + csRef<iCamera> camera = pcCamera->GetCamera(); + camera->MoveWorld(csVector3(0, 0, 0.5)); + pcCamera->UpdateCamera(); } else if (msg_id == id_pccommandinput_forward0) { @@ -311,9 +325,10 @@ csRef<iSector> destinationSector = sectorList->Get(0); path = navStruct->ShortestPath(origin, originSector, destination, destinationSector); + behaviourLayer->SetPath(path); GetMover(); csRef<iMapNode> node = path->Next(); - pcMover->MoveTo(node->GetSector(), node->GetPosition(), 0.1f); + pcMover->MoveTo(node->GetSector(), node->GetPosition(), 0.005f); } } else if (msg_id == id_pcinventory_addchild) @@ -334,9 +349,9 @@ { if (path->HasNext()) { - GetMover(); + GetMover(); csRef<iMapNode> node = path->Next(); - pcMover->MoveTo(node->GetSector(), node->GetPosition(), 1.0f); + pcMover->MoveTo(node->GetSector(), node->GetPosition(), 0.005f); } } } Modified: cel/branches/soc2010/navmesh/apps/pathfindingtest/BehaviourLayer.h =================================================================== --- cel/branches/soc2010/navmesh/apps/pathfindingtest/BehaviourLayer.h 2010-07-21 23:31:31 UTC (rev 4075) +++ cel/branches/soc2010/navmesh/apps/pathfindingtest/BehaviourLayer.h 2010-07-23 23:30:54 UTC (rev 4076) @@ -21,8 +21,9 @@ csRef<iCelPlLayer> physicalLayer; csRef<iObjectRegistry> objectRegistry; - // Tranference region + // Members used to transfer data between the behaviour layer and the application csRef<iCelHNavStruct> navStruct; + csRef<iCelHPath> path; public: BehaviourLayer (iCelPlLayer* physicalLayer, iObjectRegistry* objectRegistry); @@ -32,6 +33,8 @@ virtual iCelBehaviour* CreateBehaviour (iCelEntity* entity, const char* name); void SetNavStruct (iCelHNavStruct* navStruct); iCelHNavStruct* GetNavStruct () const; + void SetPath (iCelHPath* path); + iCelHPath* GetPath () const; }; class BehaviourCommon : public scfImplementation1<BehaviourCommon, iCelBehaviour> Modified: cel/branches/soc2010/navmesh/apps/pathfindingtest/MainApp.cpp =================================================================== --- cel/branches/soc2010/navmesh/apps/pathfindingtest/MainApp.cpp 2010-07-21 23:31:31 UTC (rev 4075) +++ cel/branches/soc2010/navmesh/apps/pathfindingtest/MainApp.cpp 2010-07-23 23:30:54 UTC (rev 4076) @@ -5,13 +5,15 @@ SetApplicationName("Navigation Mesh Test"); originSet = false; destinationSet = false; + renderNavMesh = true; + renderDestination = true; + renderPath = true; } MainApp::~MainApp () { } -// TODO ver o que precisa ficar na classe mesmo bool MainApp::LoadLevel () { levelEntity = physicalLayer->CreateEntity("level", behaviourLayer, "levelBehaviour", @@ -28,8 +30,6 @@ zone->LinkRegion(region); mapfile = region->CreateMapFile(); - //mapfile->SetPath("/cellib/lev"); - //mapfile->SetFile("walktut_world"); mapfile->SetPath("/lev/castle"); mapfile->SetFile("world"); vfs->ChDir("/lev/castle"); @@ -48,9 +48,14 @@ } // Get the iPcCamera interface so that we can set the camera. - csRef<iPcCamera> pcCamera = CEL_QUERY_PROPCLASS_ENT(playerEntity, iPcCamera); + pcCamera = CEL_QUERY_PROPCLASS_ENT(playerEntity, iPcCamera); camera = pcCamera->GetCamera(); + // Since we want to be able to see the navigation meshes and paths, we have to turn AutoDraw off + // and Draw the camera manually in the Frame method, along with the navmeshes and in the right + // order. + pcCamera->SetAutoDraw(false); + // Get the zone manager from the level entity which should have been created by now. csRef<iPcZoneManager> pcZoneMgr = CEL_QUERY_PROPCLASS_ENT(levelEntity, iPcZoneManager); pcCamera->SetZoneManager(pcZoneMgr, true, "main", "Camera"); @@ -69,21 +74,27 @@ // Get height before scaling the model, and then scale it. // At the time this demo application was created, the model's bounding box was not updated // after scaling it, so this is the safest way to get the height. + float x = objectModel->GetObjectBoundingBox().MaxY() - objectModel->GetObjectBoundingBox().MinY(); float y = objectModel->GetObjectBoundingBox().MaxY() - objectModel->GetObjectBoundingBox().MinY(); + float z = objectModel->GetObjectBoundingBox().MaxY() - objectModel->GetObjectBoundingBox().MinY(); - // Scale model - float scaleFactor = 0.5f; + // Scale model. A tiny model will be used, since her bounding box is big and the map has + // a lot of closed spaces. + float scaleFactor = 0.25f; csRef<iSpriteCal3DFactoryState> cal3dSprite = scfQueryInterface<iSpriteCal3DFactoryState> (mesh->GetFactory()->GetMeshObjectFactory()); cal3dSprite->RescaleFactory(scaleFactor); - // Calculate approximate height and radius - agentHeight = y * scaleFactor; - // If we use the bounding box to calculate an approximate radius, it will give a high value, - // probably because it takes the arms into account. Lets just say The agent radius is about - // one fourth of it's height - agentRadius = agentHeight / 4.0f; + // Scale bounding box + x *= scaleFactor; + y *= scaleFactor; + z *= scaleFactor; + // Calculate approximate height and radius. Height will be the height of the bounding box, and + // radius will be half of the diagonal lenght of the bounding box, in the xz plane. + agentHeight = y; + agentRadius = csQsqrt(csSquare(x) + csSquare(z)) * 0.5f; + if (pcZoneMgr->PointMesh("player", "main", "Camera")) { return ReportError("Can't find region or start position in region!"); @@ -92,13 +103,20 @@ // Get iPcLinearMovement so we can setup the movement system. csRef<iPcLinearMovement> pcLinMove = CEL_QUERY_PROPCLASS_ENT(playerEntity, iPcLinearMovement); pcLinMove->InitCD(csVector3(0.5f,0.8f,0.5f), csVector3(0.5f,0.4f,0.5f), csVector3(0,0,0)); + pcLinMove->SetFullPosition(pcLinMove->GetPosition(), PI, pcLinMove->GetSector()); // Get the iPcActorMove interface so that we can set movement speed. csRef<iPcActorMove> pcActorMove = CEL_QUERY_PROPCLASS_ENT (playerEntity, iPcActorMove); - pcActorMove->SetMovementSpeed(3.0f); - pcActorMove->SetRunningSpeed(5.0f); + pcActorMove->SetMovementSpeed(1.5f); + pcActorMove->SetRunningSpeed(2.5f); pcActorMove->SetRotationSpeed(1.75f); + pcActorMove->ToggleCameraMode(); + // Remove the smooth behaviour from iPcMover (it causes our actor to walk where we + // don't want it to go). + csRef<iPcMover> pcMover = CEL_QUERY_PROPCLASS_ENT (playerEntity, iPcMover); + pcMover->SetSmoothMovement(false); + // Get iPcCommandInput so we can do key bindings. The behaviour layer will interprete the // commands so the actor can move. csRef<iPcCommandInput> pcInput = CEL_QUERY_PROPCLASS_ENT(playerEntity, iPcCommandInput); @@ -115,25 +133,22 @@ return true; } -// TODO not working. Rendering before the rest? void MainApp::Frame () { - if (navStruct) + pcCamera->Draw(); + + if (renderNavMesh && navStruct) { navStruct->DebugRender(); } - if (originSet && navStruct) + if (renderDestination && destinationSet && navStruct) { - navStruct->DebugRenderAgent(origin, 70, 140, 255, 150); - } - - if (destinationSet && navStruct) - { navStruct->DebugRenderAgent(destination, 50, 255, 120, 150); } - if (path) + path = behaviourLayer->GetPath(); + if (renderPath && path) { path->DebugRender(); } @@ -143,7 +158,7 @@ { // We got a keyboard event. csKeyEventType eventType = csKeyEventHelper::GetEventType(&ev); - if (eventType == csKeyEventTypeDown) + if (eventType == csKeyEventTypeUp) { // The user pressed a key (as opposed to releasing it). utf32_char code = csKeyEventHelper::GetCookedCode(&ev); @@ -167,6 +182,9 @@ { params.AttachNew(navStructBuilder->GetNavMeshParams()->Clone()); params->SetSuggestedValues(agentHeight, agentRadius, 45.0f); + // Our agent is tiny and the map has stairs, so lets change agentMaxClimb so she can + // go everywhere + params->SetAgentMaxClimb(agentHeight); //params->SetSuggestedValues(1.0f, 0.2f, 45.0f); navStructBuilder->SetNavMeshParams(params); } @@ -199,7 +217,20 @@ path.Invalidate(); originSet = false; destinationSet = false; + behaviourLayer->SetPath(0); } + else if (code == '1') // Switch navmesh rendering + { + renderNavMesh = !renderNavMesh; + } + else if (code == '2') // Switch destination rendering + { + renderDestination = !renderDestination; + } + else if (code == '3') // Switch path rendering + { + renderPath = !renderPath; + } } return false; } @@ -224,6 +255,11 @@ // left void MainApp::MouseClick1Handler (iEvent& ev) { + if (!navStruct) + { + return; + } + csVector2 screenPoint; screenPoint.x = csMouseEventHelper::GetX(&ev); screenPoint.y = csMouseEventHelper::GetY(&ev); Modified: cel/branches/soc2010/navmesh/apps/pathfindingtest/MainApp.h =================================================================== --- cel/branches/soc2010/navmesh/apps/pathfindingtest/MainApp.h 2010-07-21 23:31:31 UTC (rev 4075) +++ cel/branches/soc2010/navmesh/apps/pathfindingtest/MainApp.h 2010-07-23 23:30:54 UTC (rev 4076) @@ -51,11 +51,15 @@ bool destinationSet; csRef<iCamera> camera; + csRef<iPcCamera> pcCamera; csRef<iCelZone> zone; csRef<iCelRegion> region; csRef<iCelMapFile> mapfile; csRef<iCelEntity> levelEntity; // iCelEntity csRef<iCelEntity> playerEntity; // iCelEntity + bool renderNavMesh; + bool renderDestination; + bool renderPath; void Frame (); bool LoadLevel (); Modified: cel/branches/soc2010/navmesh/include/propclass/mover.h =================================================================== --- cel/branches/soc2010/navmesh/include/propclass/mover.h 2010-07-21 23:31:31 UTC (rev 4075) +++ cel/branches/soc2010/navmesh/include/propclass/mover.h 2010-07-23 23:30:54 UTC (rev 4076) @@ -53,7 +53,7 @@ */ struct iPcMover : public virtual iBase { - SCF_INTERFACE (iPcMover, 1, 0, 0); + SCF_INTERFACE (iPcMover, 1, 1, 0); /** * Start moving. When you call this function this property class will @@ -129,6 +129,18 @@ * Return true if currently moving. */ virtual bool IsMoving () const = 0; + + /** + * Return true if the rotations used during the movement will be smooth and + * false if they will be sudden. + */ + virtual bool IsSmoothMovement () const = 0; + + /** + * Define if the movement will have sudden of smooth turns. Having sudden turns will + * ensure the movement is done in straight lines. + */ + virtual void SetSmoothMovement (bool smooth) = 0; }; #endif // __CEL_PF_MOVER__ Modified: cel/branches/soc2010/navmesh/plugins/propclass/mover/moverfact.cpp =================================================================== --- cel/branches/soc2010/navmesh/plugins/propclass/mover/moverfact.cpp 2010-07-21 23:31:31 UTC (rev 4075) +++ cel/branches/soc2010/navmesh/plugins/propclass/mover/moverfact.cpp 2010-07-23 23:30:54 UTC (rev 4076) @@ -88,6 +88,8 @@ is_moving = false; up = csVector3(0,1,0); + + smooth = true; } celPcMover::~celPcMover () @@ -145,6 +147,23 @@ return angle; } +static float GetAngle2 (const csVector3& vector) +{ + float length = vector.Norm(); + float angle = acos(vector.z / length); + + if (vector.x > 0) + { + angle = - angle; + } + angle = PI - angle; + if (angle >= (2 * PI)) + { + angle = angle - (2 * PI); + } + return angle; +} + #define DELAY_RECHECK 20 bool celPcMover::Start (iSector* sector, const csVector3& position, @@ -205,10 +224,18 @@ return false; } } - - csVector3 vec (0,0,1); - float yrot = GetAngle (position-cur_position, vec); - pcactormove->RotateTo (yrot); + + if (smooth) + { + csVector3 vec (0,0,1); + float yrot = GetAngle (position-cur_position, vec); + pcactormove->RotateTo (yrot); + } + else + { + float yrot = GetAngle2 (position - cur_position); + pclinmove->SetFullPosition (pclinmove->GetPosition(), yrot, pclinmove->GetSector()); + } pcactormove->Forward (true); pl->CallbackOnce ((iCelTimerListener*)this, DELAY_RECHECK, CEL_EVENT_PRE); @@ -293,10 +320,18 @@ dispatcher_arrived); return; } - - csVector3 vec (0,0,1); - float yrot = GetAngle (position-cur_position, vec); - pcactormove->RotateTo (yrot); + + if (smooth) + { + csVector3 vec (0,0,1); + float yrot = GetAngle (position-cur_position, vec); + pcactormove->RotateTo (yrot); + } + else + { + float yrot = GetAngle2 (position - cur_position); + pclinmove->SetFullPosition (pclinmove->GetPosition(), yrot, pclinmove->GetSector()); + } pl->CallbackOnce ((iCelTimerListener*)this, DELAY_RECHECK, CEL_EVENT_PRE); } Modified: cel/branches/soc2010/navmesh/plugins/propclass/mover/moverfact.h =================================================================== --- cel/branches/soc2010/navmesh/plugins/propclass/mover/moverfact.h 2010-07-21 23:31:31 UTC (rev 4075) +++ cel/branches/soc2010/navmesh/plugins/propclass/mover/moverfact.h 2010-07-23 23:30:54 UTC (rev 4076) @@ -88,6 +88,7 @@ csVector3 up; float sqradius; bool is_moving; + bool smooth; void FindSiblingPropertyClasses (); void SendMessage (const char* msgold, @@ -118,6 +119,8 @@ virtual bool PerformActionIndexed (int idx, iCelParameterBlock* params, celData& ret); virtual void TickOnce (); + virtual bool IsSmoothMovement () const { return smooth; } + virtual void SetSmoothMovement (bool smooth) { this->smooth = smooth; } }; #endif // __CEL_PF_MOVERFACT__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |