<commit_before>#include "ServerPickingSystem.h"
#include "Transform.h"
#include <AglMatrix.h>
#include <AglQuaternion.h>
#include "PhysicsSystem.h"
#include <PhysicsController.h>
#include "RayPacket.h"
#include "PhysicsBody.h"
#include "ShipManagerSystem.h"
#include "EntityCreationPacket.h"
#include "EntityType.h"
#include "NetworkSynced.h"
#include "ShipModule.h"
#include "ShipManagerSystem.h"

float getT(AglVector3 p_o, AglVector3 p_d, AglVector3 p_c, float p_r)
{
	//Sphere Info
	AglVector3 C = p_c;
	float radius = p_r;

	//Sphere collision algorithm
	float b = AglVector3::dotProduct(p_d, p_o - C);
	float c = AglVector3::dotProduct(p_o - C, p_o - C) - radius*radius;
	if (b*b - c >= 0)
	{
		float t1 = -b - sqrt(b*b-c);
		float t2 = -b + sqrt(b*b-c);
		return t1;
		/*if (t2 > 0 && t1 * t1 < AglVector3::lengthSquared(p_lineSegment.p2-p_lineSegment.p1))
		{
			return true;
		}*/
	}
	return -1;
}

ServerPickingSystem::ServerPickingSystem(TcpServer* p_server)
	: EntitySystem(SystemType::ServerPickingSystem, 1, ComponentType::ShipModule)
{
	m_server = p_server;
	mrota = 0;
}


ServerPickingSystem::~ServerPickingSystem()
{
}

void ServerPickingSystem::initialize()
{
}

void ServerPickingSystem::processEntities(const vector<Entity*>& p_entities)
{
	float dt = m_world->getDelta();
	mrota += dt;
	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_latestPick >= 0)
		{
			project(m_world->getEntity(m_pickComponents[i].m_latestPick), m_pickComponents[i]);
		}
		else
		{
			if (m_pickComponents[i].m_active)
				handleRay(m_pickComponents[i], p_entities);
			else if (m_pickComponents[i].m_selection >= 0)
			{
				Entity* SelectionSphere = m_world->getEntity(m_pickComponents[i].m_selection);
				Transform* SelectionSphereTransform = static_cast<Transform*>
					(SelectionSphere->getComponent(ComponentType::Transform));
				SelectionSphereTransform->setScale(AglVector3(0, 0, 0));
			}
		}
		if (m_pickComponents[i].m_selection < 0)
		{
			//Create the selection highlighter sphere
			Entity* entity = m_world->createEntity();

			Transform* t = new Transform(AglVector3(0, 0, 0), AglQuaternion::identity(), 
				AglVector3(1, 1, 1));
			entity->addComponent( ComponentType::Transform, t);
			m_world->addEntity(entity);
			m_pickComponents[i].m_selection = entity->getIndex();

			EntityCreationPacket data;
			data.entityType		= static_cast<char>(EntityType::SelectionSphere);
			data.owner			= -1;
			data.networkIdentity = entity->getIndex();
			data.translation	= t->getTranslation();
			data.rotation		= t->getRotation();
			data.scale			= t->getScale();
			data.meshInfo		= 1;

			entity->addComponent(ComponentType::NetworkSynced, 
				new NetworkSynced( entity->getIndex(), -1, EntityType::SelectionSphere));

			m_server->broadcastPacket(data.pack());
		}
	}
}
void ServerPickingSystem::setRay(int p_index, AglVector3 p_o, AglVector3 p_d)
{
	PhysicsSystem* physX = static_cast<PhysicsSystem*>(m_world->getSystem(
		SystemType::PhysicsSystem));

	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_clientIndex == p_index)
		{
			physX->getController()->SetRay(p_o, p_d, m_pickComponents[i].m_rayIndex);
			return;
		}
	}

	//Create the ray
	PickComponent pc;
	pc.m_rayIndex = physX->getController()->AddRay(p_o, p_d);
	pc.m_clientIndex = p_index;
	m_pickComponents.push_back(pc);
}
void ServerPickingSystem::setEnabled(int p_index, bool p_value)
{
	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_clientIndex == p_index)
		{
			m_pickComponents[i].m_active = p_value;
			if (!p_value)
			{
				attemptConnect(m_pickComponents[i]);
				m_pickComponents[i].m_latestPick = -1;
			}
			return;
		}
	}
}
void ServerPickingSystem::setReleased(int p_index)
{
	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_clientIndex == p_index)
		{
			//Release the picked module
			m_pickComponents[i].m_latestPick = -1;
			m_pickComponents[i].m_active = false;
			return;
		}
	}
}
void ServerPickingSystem::handleRay(PickComponent& p_pc, const vector<Entity*>& p_entities)
{
	if (p_pc.m_active)
	{
		PhysicsSystem* physX = static_cast<PhysicsSystem*>(m_world->getSystem(
			SystemType::PhysicsSystem));

		vector<LineCollisionData> cols = physX->getPhysicsController()->LineSortedCollisions(p_pc.m_rayIndex);
		if (cols.size() > 0)
		{
			//Find closest module
			int col = -1;
			for (unsigned int i = 0; i < cols.size(); i++)
			{
				Entity* e = physX->getEntity(cols[i].bodyID);
				if (e && e->getComponent(ComponentType::ShipModule))
				{
					col = cols[i].bodyID;
					break;
				}
			}

			if (col < 0)
				return;

			for (unsigned int i = 0; i < p_entities.size(); i++)
			{
				PhysicsBody* pb = static_cast<PhysicsBody*>(p_entities[i]->getComponent(
					ComponentType::PhysicsBody));
				if (pb && pb->m_id == col)
				{
					//Found a pick
					p_pc.m_latestPick = p_entities[i]->getIndex();

					//Attempt a detach if the entity is already connected
					if (attemptDetach(p_pc))
					{
						AglVector3 origin;
						AglVector3 dir;
						physX->getController()->GetRay(p_pc.m_rayIndex, origin, dir);

						AglVector3 d = physX->getController()->getBody(col)->GetWorld().GetTranslation()-origin;<commit_msg>Unable to pick far away objects<commit_after>#include "ServerPickingSystem.h"
#include "Transform.h"
#include <AglMatrix.h>
#include <AglQuaternion.h>
#include "PhysicsSystem.h"
#include <PhysicsController.h>
#include "RayPacket.h"
#include "PhysicsBody.h"
#include "ShipManagerSystem.h"
#include "EntityCreationPacket.h"
#include "EntityType.h"
#include "NetworkSynced.h"
#include "ShipModule.h"
#include "ShipManagerSystem.h"

float getT(AglVector3 p_o, AglVector3 p_d, AglVector3 p_c, float p_r)
{
	//Sphere Info
	AglVector3 C = p_c;
	float radius = p_r;

	//Sphere collision algorithm
	float b = AglVector3::dotProduct(p_d, p_o - C);
	float c = AglVector3::dotProduct(p_o - C, p_o - C) - radius*radius;
	if (b*b - c >= 0)
	{
		float t1 = -b - sqrt(b*b-c);
		float t2 = -b + sqrt(b*b-c);
		return t1;
		/*if (t2 > 0 && t1 * t1 < AglVector3::lengthSquared(p_lineSegment.p2-p_lineSegment.p1))
		{
			return true;
		}*/
	}
	return -1;
}

ServerPickingSystem::ServerPickingSystem(TcpServer* p_server)
	: EntitySystem(SystemType::ServerPickingSystem, 1, ComponentType::ShipModule)
{
	m_server = p_server;
	mrota = 0;
}


ServerPickingSystem::~ServerPickingSystem()
{
}

void ServerPickingSystem::initialize()
{
}

void ServerPickingSystem::processEntities(const vector<Entity*>& p_entities)
{
	float dt = m_world->getDelta();
	mrota += dt;
	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_latestPick >= 0)
		{
			project(m_world->getEntity(m_pickComponents[i].m_latestPick), m_pickComponents[i]);
		}
		else
		{
			if (m_pickComponents[i].m_active)
				handleRay(m_pickComponents[i], p_entities);
			else if (m_pickComponents[i].m_selection >= 0)
			{
				Entity* SelectionSphere = m_world->getEntity(m_pickComponents[i].m_selection);
				Transform* SelectionSphereTransform = static_cast<Transform*>
					(SelectionSphere->getComponent(ComponentType::Transform));
				SelectionSphereTransform->setScale(AglVector3(0, 0, 0));
			}
		}
		if (m_pickComponents[i].m_selection < 0)
		{
			//Create the selection highlighter sphere
			Entity* entity = m_world->createEntity();

			Transform* t = new Transform(AglVector3(0, 0, 0), AglQuaternion::identity(), 
				AglVector3(1, 1, 1));
			entity->addComponent( ComponentType::Transform, t);
			m_world->addEntity(entity);
			m_pickComponents[i].m_selection = entity->getIndex();

			EntityCreationPacket data;
			data.entityType		= static_cast<char>(EntityType::SelectionSphere);
			data.owner			= -1;
			data.networkIdentity = entity->getIndex();
			data.translation	= t->getTranslation();
			data.rotation		= t->getRotation();
			data.scale			= t->getScale();
			data.meshInfo		= 1;

			entity->addComponent(ComponentType::NetworkSynced, 
				new NetworkSynced( entity->getIndex(), -1, EntityType::SelectionSphere));

			m_server->broadcastPacket(data.pack());
		}
	}
}
void ServerPickingSystem::setRay(int p_index, AglVector3 p_o, AglVector3 p_d)
{
	PhysicsSystem* physX = static_cast<PhysicsSystem*>(m_world->getSystem(
		SystemType::PhysicsSystem));

	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_clientIndex == p_index)
		{
			physX->getController()->SetRay(p_o, p_d, m_pickComponents[i].m_rayIndex);
			return;
		}
	}

	//Create the ray
	PickComponent pc;
	pc.m_rayIndex = physX->getController()->AddRay(p_o, p_d);
	pc.m_clientIndex = p_index;
	m_pickComponents.push_back(pc);
}
void ServerPickingSystem::setEnabled(int p_index, bool p_value)
{
	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_clientIndex == p_index)
		{
			m_pickComponents[i].m_active = p_value;
			if (!p_value)
			{
				attemptConnect(m_pickComponents[i]);
				m_pickComponents[i].m_latestPick = -1;
			}
			return;
		}
	}
}
void ServerPickingSystem::setReleased(int p_index)
{
	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_clientIndex == p_index)
		{
			//Release the picked module
			m_pickComponents[i].m_latestPick = -1;
			m_pickComponents[i].m_active = false;
			return;
		}
	}
}
void ServerPickingSystem::handleRay(PickComponent& p_pc, const vector<Entity*>& p_entities)
{
	if (p_pc.m_active)
	{
		PhysicsSystem* physX = static_cast<PhysicsSystem*>(m_world->getSystem(
			SystemType::PhysicsSystem));

		vector<LineCollisionData> cols = physX->getPhysicsController()->LineSortedCollisions(p_pc.m_rayIndex);
		if (cols.size() > 0)
		{
			//Find closest module
			int col = -1;
			for (unsigned int i = 0; i < cols.size(); i++)
			{
				Entity* e = physX->getEntity(cols[i].bodyID);
				if (e && e->getComponent(ComponentType::ShipModule))
				{
					col = cols[i].bodyID;
					break;
				}
			}

			if (col < 0)
				return;

			for (unsigned int i = 0; i < p_entities.size(); i++)
			{
				PhysicsBody* pb = static_cast<PhysicsBody*>(p_entities[i]->getComponent(
					ComponentType::PhysicsBody));
				if (pb && pb->m_id == col)
				{
					//Found a pick

					//Verify that the pick is not already picked
					for (unsigned int pcs = 0; pcs < m_pickComponents.size(); pcs++)
					{
						if (m_pickComponents[pcs].m_latestPick == p_entities[i]->getIndex())
							return;
					}

					//Only allow picking a certain distance
					ShipManagerSystem* sms = static_cast<ShipManagerSystem*>(m_world->getSystem(SystemType::ShipManagerSystem));
					Entity* rayShip = sms->findShip(p_pc.m_clientIndex);
					
					Transform* t1 = static_cast<Transform*>(p_entities[i]->getComponent(ComponentType::Transform));
					Transform* t2 = static_cast<Transform*>(rayShip->getComponent(ComponentType::Transform));
					if ((t1->getTranslation()-t2->getTranslation()).lengthSquared() > 1600)
						return;


					p_pc.m_latestPick = p_entities[i]->getIndex();

					//Attempt a detach if the entity is already connected
					if (attemptDetach(p_pc))
					{
						AglVector3 origin;
						AglVector3 dir;
						physX->getController()->GetRay(p_pc.m_rayIndex, origin, dir);

						AglVector3 d = physX->getController()->getBody(col)->GetWorld().GetTranslation()-origin;
{'fraction_non_alphanumeric': 0.14513570673246387, 'fraction_numerical': 0.010310186817060274, 'mean_word_length': 4.3256687001407785, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 114, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2880712', 'n_tokens_mistral': 4713, 'n_tokens_neox': 4137, 'n_words': 762}