CSC8503_Advanced_Game_Technologies / CSC8503 / CSC8503Common / GameWorld.cpp
GameWorld.cpp
Raw
#include "GameWorld.h"
#include "GameObject.h"
#include "Constraint.h"
#include "CollisionDetection.h"
#include "../../Common/Camera.h"
#include <algorithm>

using namespace NCL;
using namespace NCL::CSC8503;

GameWorld::GameWorld()	{
	mainCamera = new Camera();

	shuffleConstraints	= false;
	shuffleObjects		= false;
	worldIDCounter		= 0;

	// Layers
	std::vector<Layer> layerConfig0;
	const Layer layer0;
	layerConfig0.emplace_back(layer0);
	std::vector<Layer> layerConfig1;
	Layer layer1;
	layer1.SetLayerID(1);
	layerConfig0.emplace_back(layer1);
	worldLayers.emplace_back(layerConfig0);
	worldLayers.emplace_back(layerConfig1);
}

GameWorld::~GameWorld()	{
}

void GameWorld::Clear() {
	gameObjects.clear();
	constraints.clear();
}

void GameWorld::ClearAndErase() {
	for (auto& i : gameObjects) {
		delete i;
	}
	for (auto& i : constraints) {
		delete i;
	}
	Clear();
}

void GameWorld::AddGameObject(GameObject* o) {
	gameObjects.emplace_back(o);
	o->SetWorldID(worldIDCounter++);
}

void GameWorld::RemoveGameObject(GameObject* o, bool andDelete) {
	gameObjects.erase(std::remove(gameObjects.begin(), gameObjects.end(), o), gameObjects.end());
	if (andDelete) {
		delete o;
	}
}

void GameWorld::GetObjectIterators(
	GameObjectIterator& first,
	GameObjectIterator& last) const {

	first	= gameObjects.begin();
	last	= gameObjects.end();
}

void GameWorld::OperateOnContents(GameObjectFunc f) {
	for (GameObject* g : gameObjects) {
		f(g);
	}
}

void GameWorld::UpdateWorld(float dt) {
	if (shuffleObjects) {
		std::random_shuffle(gameObjects.begin(), gameObjects.end());
	}

	if (shuffleConstraints) {
		std::random_shuffle(constraints.begin(), constraints.end());
	}
}

bool GameWorld::Raycast(Ray& r, RayCollision& closestCollision, bool closestObject) const {
	//The simplest raycast just goes through each object and sees if there's a collision
	RayCollision collision;

	for (auto& i : gameObjects) {
		if (!i->GetBoundingVolume()) { 
			continue;
		}
	//for (auto& i : gameObjects)
	//{
	//	if (!i->GetBoundingVolume())  //objects might not be collideable etc...
	//		continue;

	//	const unsigned layerID = i->GetLayer().GetConstLayerID();
	//	bool found = false;
	//	for (unsigned i = 0; i < worldLayers[layerID].size(); i++)  // 28.11.19 - if object is on a layer that can't be raycasted against, then continue... (raycast layer is 0)
	//	{
	//		if (worldLayers[layerID][i].GetConstLayerID() == RAYCAST_LAYER_ID)
	//		{
	//			found = true;
	//			break;
	//		}
	//	}
	//	if (!found)
	//		continue;

		RayCollision thisCollision;
		if (CollisionDetection::RayIntersection(r, *i, thisCollision)) {
				
			if (!closestObject) {	
				closestCollision		= collision;
				closestCollision.node = i;
				return true;
			}
			else {
				if (thisCollision.rayDistance < collision.rayDistance) {
					thisCollision.node = i;
					collision = thisCollision;
				}
			}
		}
	}
	if (collision.node) {
		closestCollision		= collision;
		closestCollision.node	= collision.node;
		return true;
	}
	return false;
}


/*
Constraint Tutorial Stuff
*/

void GameWorld::AddConstraint(Constraint* c) {
	constraints.emplace_back(c);
}

void GameWorld::RemoveConstraint(Constraint* c, bool andDelete) {
	constraints.erase(std::remove(constraints.begin(), constraints.end(), c), constraints.end());
	if (andDelete) {
		delete c;
	}
}

void GameWorld::GetConstraintIterators(
	std::vector<Constraint*>::const_iterator& first,
	std::vector<Constraint*>::const_iterator& last) const {
	first	= constraints.begin();
	last	= constraints.end();
}

unsigned GameWorld::UpdateWorldLayers(unsigned layerIndex, const std::vector<Layer>& newConfig) {
	if (!(worldLayers.size() > layerIndex))
	{
		// layer index doesn't exist yet, create it at the next available index
		worldLayers.emplace_back(newConfig);
		return (worldLayers.size() - 1);
	}
	worldLayers[layerIndex].clear();
	worldLayers[layerIndex] = newConfig;
	return layerIndex;
}