int EngineMain(string worldFile) { int returnValue = Quit_Completely; //-------------------------- // CrowdDynamics Setup //-------------------------- GSceneManager* crowdEngine = GSceneManager::GetInstance(worldFile); worldBlueprint = crowdEngine->GetWorldBlueprint(); // Create a 3D engine (using TLX engine here) and open a window for it I3DEngine* gameEngine = New3DEngine(kTLX); gameEngine->StartWindowed(); // Add default folder for meshes and other media gameEngine->AddMediaFolder(".\\Media"); IFont* mousePosFont = gameEngine->LoadFont("Font1.bmp"); IMesh* floorTileMesh = gameEngine->LoadMesh("FloorTile.x"); IMesh* vectorMesh = gameEngine->LoadMesh("Vector.x"); IMesh* influenceTileMesh = gameEngine->LoadMesh("InfluenceTile.x"); IMesh* SkyboxMesh = gameEngine->LoadMesh("Skybox.x"); //////////////////////// // Obstacles //////////////////////// std::map<string, float> obstacleMeshList = crowdEngine->GetObstacleMeshes(); std::map<string, IMesh*> obstacleTLMeshes; for (auto mesh : obstacleMeshList) //Load the TL Meshes { obstacleTLMeshes.emplace(make_pair(mesh.first, gameEngine->LoadMesh(mesh.first))); } vector<UID> obstacleUIDs = crowdEngine->GetObstacleUIDs(); //Get a list of all the obstacles in the scene map<UID, IModel*> obstacleModels; for (auto id : obstacleUIDs) //Construct a TL model for each obstacle { string thisMeshName; if (crowdEngine->GetObstacleMesh(id, thisMeshName)) { obstacleModels.emplace(id, obstacleTLMeshes[thisMeshName]->CreateModel()); } } //////////////////////// // Agents //////////////////////// std::map<string, float> agentMeshScales = crowdEngine->GetAgentMeshes(); std::map<string, IMesh*> agentTLMeshes; for (auto mesh : agentMeshScales) { agentTLMeshes.emplace(make_pair(mesh.first, gameEngine->LoadMesh(mesh.first))); } map<UID, IModel*> Agents; map<UID, IModel*> DestinationVectors; map<UID, IModel*> MovementVectors; vector<UID> AgentIDs = crowdEngine->GetAgentUIDs(); for (auto id : AgentIDs) { //Use the Y Column as the height (0 column), CrowdDynamics uses X and Y as this will use X and Z //Where the model spawns is irrelevant as it's matrix is built from the CrowdDynamics matrix string thisMeshName; if (crowdEngine->GetAgentMeshFile(id, thisMeshName)) { Agents.emplace(make_pair(id, agentTLMeshes[thisMeshName]->CreateModel())); Agents[id]->ScaleY(agentMeshScales[thisMeshName]); #ifdef DirectionVisualiserEnabled DestinationVectors.insert(make_pair(id, vectorMesh->CreateModel())); MovementVectors.insert(make_pair(id, vectorMesh->CreateModel())); #endif } } #ifdef DirectionVisualiserEnabled for (auto item : MovementVectors) { item.second->SetSkin("vectortex2.jpg"); } #endif IModel** FloorTiles; IModel* SkyBox = SkyboxMesh->CreateModel(); SkyBox->ScaleX((worldBlueprint.WorldSize.x + 2000.0f) / 2000.0f); //worldBlueprint.WorldSize.x / 200.0f); SkyBox->ScaleZ((worldBlueprint.WorldSize.y + 2000.0f) / 2000.0f); //worldBlueprint.WorldSize.y / 200.0f); SkyBox->SetPosition(worldBlueprint.WorldSize.x / 2.0f, -1000.0f, worldBlueprint.WorldSize.y / 2.0f); FloorTiles = new IModel*[worldBlueprint.subdivisions.x * worldBlueprint.subdivisions.y]; for (int i = 0; i < worldBlueprint.subdivisions.x; i++) { for (int j = 0; j < worldBlueprint.subdivisions.y; j++) { FloorTiles[i * worldBlueprint.subdivisions.x + j] = floorTileMesh->CreateModel(i * (worldBlueprint.WorldSize.x / worldBlueprint.subdivisions.x), 0.0f, j * (worldBlueprint.WorldSize.y / worldBlueprint.subdivisions.y)); FloorTiles[i * worldBlueprint.subdivisions.x + j]->ScaleX(worldBlueprint.WorldSize.x / worldBlueprint.subdivisions.x); FloorTiles[i * worldBlueprint.subdivisions.x + j]->ScaleZ(worldBlueprint.WorldSize.y / worldBlueprint.subdivisions.y); FloorTiles[i * worldBlueprint.subdivisions.x + j]->Scale(1.0f); } } #ifdef InfluenceVisualiserEnabled IModel** InfluenceTiles; InfluenceTiles = new IModel*[worldBlueprint.influenceSubdivisions.x * worldBlueprint.influenceSubdivisions.y]; for (int i = 0; i < worldBlueprint.influenceSubdivisions.x; i++) { for (int j = 0; j < worldBlueprint.influenceSubdivisions.y; j++) { InfluenceTiles[i * worldBlueprint.influenceSubdivisions.x + j] = influenceTileMesh->CreateModel(static_cast<float>(i) / worldBlueprint.influenceSquaresPerUnit, 0.5f, (static_cast<float>(j) + 1) / worldBlueprint.influenceSquaresPerUnit); InfluenceTiles[i * worldBlueprint.influenceSubdivisions.x + j]->RotateX(180.0f); InfluenceTiles[i * worldBlueprint.influenceSubdivisions.x + j]->ScaleX((1.0f / worldBlueprint.influenceSquaresPerUnit) * 0.75f); InfluenceTiles[i * worldBlueprint.influenceSubdivisions.x + j]->ScaleZ((1.0f / worldBlueprint.influenceSquaresPerUnit) * 0.75f); } } #endif ICamera* cameras[Camera_Size]; ECameraState currentCameraState = Camera_TopDown; cameras[Camera_FirstPerson]= gameEngine->CreateCamera(kFPS, worldBlueprint.WorldSize.x / 2.0f, (worldBlueprint.WorldSize.x + worldBlueprint.WorldSize.y) / 2, worldBlueprint.WorldSize.y / 2.0f); cameras[Camera_FirstPerson]->SetMovementSpeed(100.0f); cameras[Camera_FirstPerson]->SetRotationSpeed(25.0f); cameras[Camera_FirstPerson]->RotateX(90.0f); cameras[Camera_TopDown] = gameEngine->CreateCamera(kManual, worldBlueprint.WorldSize.x / 2.0f, 220.0f, worldBlueprint.WorldSize.y / 2.0f); cameras[Camera_TopDown]->RotateX(90.0f); float frameRate; stringstream frameStream; gen::CMatrix3x3 tempAgentMat; string tempString; //Assign the simulation matrices to the model matrices - first time UpdateAgentsFromCrowdData(crowdEngine, Agents, agentMeshScales,agentTLMeshes, DestinationVectors, MovementVectors); UpdateObstaclesFromCrowdData(crowdEngine, obstacleModels); UID holding = -1; crowdEngine->SetPaused(true); // The main game loop, repeat until engine is stopped while (gameEngine->IsRunning()) { if (gameEngine->KeyHit(Key_Escape)) { returnValue = Quit_Completely; gameEngine->Stop(); } if (gameEngine->KeyHit(Key_Delete)) { returnValue = Quit_LoadNewMap; gameEngine->Stop(); } frameTime = gameEngine->Timer(); // Draw the scene gameEngine->DrawScene(cameras[currentCameraState]); //Check if the active camera is to change CameraSwitcher(gameEngine, cameras, currentCameraState); DrawPointingPosition(gameEngine, cameras[currentCameraState], mousePosFont, frameStream); frameRate = 1 / frameTime; frameStream << setprecision(4) << (frameRate); gameEngine->SetWindowCaption(frameStream.str()); frameStream.str(""); CameraControls(gameEngine, cameras[currentCameraState]); /**** Update your scene each frame here ****/ crowdEngine->Update(frameTime); //Update the CrowdDynamics simulation //Update the influence representation from the crowd engine #ifdef InfluenceVisualiserEnabled UpdateInfluenceFromCrowdData(crowdEngine, InfluenceTiles); #endif //Assign the simulation matrices to the model matrices UpdateAgentsFromCrowdData(crowdEngine, Agents, agentMeshScales, agentTLMeshes, DestinationVectors, MovementVectors); UpdateObstaclesFromCrowdData(crowdEngine, obstacleModels); if (gameEngine->KeyHit(pauseKey)) { crowdEngine->SetPaused(!crowdEngine->GetIsPaused()); //Toggle paused } if (gameEngine->KeyHeld(Key_T) && crowdEngine->GetIsPaused()) { crowdEngine->PerformOneTimeStep(); //Update the CrowdDynamics simulation //Assign the simulation matrices to the model matrices UpdateAgentsFromCrowdData(crowdEngine, Agents, agentMeshScales, agentTLMeshes, DestinationVectors, MovementVectors); UpdateObstaclesFromCrowdData(crowdEngine, obstacleModels); } if (gameEngine->KeyHit(Key_N)) { CVector3 tempPos = WorldPosFromPixel(gameEngine, cameras[currentCameraState]); CVector2 mousePosition = CVector2(tempPos.x, tempPos.z); #ifdef _DEBUG crowdEngine->GetSquareString(mousePosition, tempString); cout << tempString; #endif } if (gameEngine->KeyHeld(Mouse_LButton)) { if (holding == -1) //If not holding anything, pick the nearest item up { UID tempHold; if (FindNearestAgent(Agents, crowdEngine, tempHold, gameEngine, cameras[currentCameraState])) { holding = tempHold; string agentString; #ifdef _DEBUG if (crowdEngine->GetAgentString(holding, agentString)) { cout << "Picked up: " << endl; cout << agentString << endl; } #endif try //Find the id 'holding' and set the holding skin { Agents.at(holding)->SetSkin("tiles3.jpg"); } catch (std::out_of_range err) { cout << err.what(); } } } if (holding != -1) { CVector3 tempPos = WorldPosFromPixel(gameEngine, cameras[currentCameraState]); crowdEngine->SetAgentPosition(holding, CVector2(tempPos.x, tempPos.z)); UpdateAgentFromCrowdData(holding, crowdEngine, Agents, agentMeshScales, agentTLMeshes, DestinationVectors, MovementVectors); } } else //Release the held item if there is a held item { if (holding != -1) { #ifdef _DEBUG string agentString; if (crowdEngine->GetAgentString(holding, agentString)) { cout << "Dropped: " << endl; cout << agentString << endl; } #endif try { if (crowdEngine->GetAgentWatched(holding)) { Agents.at(holding)->SetSkin("tiles2.jpg"); } else { Agents.at(holding)->SetSkin("tiles1.jpg"); } } catch (std::out_of_range err) { cout << err.what(); } holding = -1; } } if (gameEngine->KeyHit(Mouse_RButton)) { UID foundNearest; if (FindNearestAgent(Agents, crowdEngine, foundNearest, gameEngine, cameras[currentCameraState])) { bool isWatched = crowdEngine->GetAgentWatched(foundNearest); if (crowdEngine->SetAgentWatched(foundNearest, !crowdEngine->GetAgentWatched(foundNearest))) { cout << "Agent: " << foundNearest << " Is "; if (isWatched) //Was being watched before change, is now not being watched { try { Agents.at(foundNearest)->SetSkin("tiles1.jpg"); } catch (std::out_of_range err) { cout << endl << err.what() << endl; } cout << "Not "; } else { try { Agents.at(foundNearest)->SetSkin("tiles2.jpg"); } catch (std::out_of_range err) { cout << endl << err.what() << endl; } } cout << "Being Watched" << endl; } } } if (gameEngine->KeyHit(Key_Space)) { CVector3 tempPos = WorldPosFromPixel(gameEngine, cameras[currentCameraState]); string thisBlueprint = "AgentBlueprint1.xml"; UID newID = crowdEngine->AddAgent(thisBlueprint, true, CVector2(tempPos.x, tempPos.z)); if (agentMeshScales.count(thisBlueprint) == 0) //This blueprint does not already exist on the TL side { float scale; if (crowdEngine->GetAgentMeshScale(thisBlueprint, scale)) { agentTLMeshes.emplace(thisBlueprint, gameEngine->LoadMesh(thisBlueprint)); agentMeshScales[thisBlueprint] = scale; } } Agents.insert(make_pair(newID, agentTLMeshes[thisBlueprint]->CreateModel(tempPos.x, 0.0f, tempPos.z))); #ifdef DirectionVisualiserEnabled DestinationVectors.insert(make_pair(newID, vectorMesh->CreateModel(tempPos.x, 10.0f, tempPos.z))); MovementVectors.insert(make_pair(newID, vectorMesh->CreateModel(tempPos.x, 11.0f, tempPos.z))); MovementVectors.at(newID)->SetSkin("vectortex2.jpg"); #endif } } // Delete the 3D engine now we are finished with it gameEngine->Delete(); delete[] FloorTiles; #ifdef InfluenceVisualiserEnabled delete[] InfluenceTiles; #endif delete crowdEngine; return returnValue; }
void UpdateAgentFromCrowdData(UID agentID, GSceneManager* crowdEngine, map<UID, IModel*>& agentModels, map<string, float> meshScales, map<string, IMesh*> meshList, map<UID, IModel*>& DestinationVectors, map<UID, IModel*>& MovementVectors) { gen::CMatrix3x3 tempAgentMat; if (crowdEngine->GetAgentMatrix(agentID, tempAgentMat)) { try //Find the id 'holding' and set the holding skin { float tempModelMat[16]; IModel* thisAgentModel; thisAgentModel = agentModels.at(agentID); float thisScale = meshScales[FindStringFromMesh(thisAgentModel->GetMesh(), meshList)]; thisAgentModel->GetMatrix(tempModelMat); tempModelMat[0] = tempAgentMat.e00 * thisScale; tempModelMat[2] = tempAgentMat.e01 * thisScale; tempModelMat[8] = tempAgentMat.e10 * thisScale; tempModelMat[10] = tempAgentMat.e11 * thisScale; tempModelMat[12] = tempAgentMat.e20; tempModelMat[14] = tempAgentMat.e21; thisAgentModel->SetMatrix(tempModelMat); } catch (std::out_of_range err) { cout << err.what(); } } #ifdef DirectionVisualiserEnabled gen::CVector2 tempDestination; if (crowdEngine->GetAgentDestination(agentID, tempDestination)) { IModel* thisVectorModel; IModel* thisAgentModel; thisAgentModel = agentModels.at(agentID); thisVectorModel = DestinationVectors.at(agentID); //Set the vector model to the id model's position thisVectorModel->SetPosition(thisAgentModel->GetX(), thisAgentModel->GetY() + 10.0f, thisAgentModel->GetZ()); thisVectorModel->LookAt(tempDestination.x, 10.0f, tempDestination.y); CVector2 vectorToEnd = tempDestination - CVector2(thisAgentModel->GetX(), thisAgentModel->GetZ()); thisVectorModel->ScaleZ(vectorToEnd.Length()); } if (crowdEngine->GetAgentDesiredVector(agentID, tempDestination)) { IModel* thisVectorModel; IModel* thisAgentModel; thisAgentModel = agentModels.at(agentID); thisVectorModel = MovementVectors.at(agentID); //Set the vector model to the id model's position thisVectorModel->SetPosition(thisAgentModel->GetX(), thisAgentModel->GetY() + 10.0f, thisAgentModel->GetZ()); thisVectorModel->LookAt(tempDestination.x + thisAgentModel->GetX(), 10.0f, tempDestination.y + thisAgentModel->GetZ()); thisVectorModel->ScaleZ(tempDestination.Length()); } #endif }