Browse Source

SPGrid removed, grid system is now part of raycast mesh, grids no longer have a precision issue and cpu usage is down heavily

Image 2 years ago
parent
commit
80add76130

+ 4 - 4
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -46,7 +46,6 @@ along with EQ2Emulator.  If not, see <http://www.gnu.org/licenses/>.
 #include "../RaceTypes/RaceTypes.h"
 #include "../classes.h"
 #include "../Transmute.h"
-#include "../Zone/SPGrid.h"
 #include "../Bots/Bot.h"
 
 extern WorldDatabase database;
@@ -5844,7 +5843,6 @@ void Commands::Command_StopFollow(Client* client, Seperator* sep)
 	}
 }
 
-#include "../Zone/SPGrid.h"
 /* 
 	Function: Command_Grid()
 	Purpose	: Show player's current Grid ID
@@ -5857,8 +5855,10 @@ void Commands::Command_Grid(Client* client)
 	client->Message(CHANNEL_COLOR_YELLOW, "Your Grid ID is %u", client->GetPlayer()->appearance.pos.grid_id);
 
 	if (client->GetPlayer()->GetMap() != nullptr) {
-		int32 grid = client->GetPlayer()->GetMap()->GetGrid()->GetGridID(client->GetPlayer());
-		client->Message(CHANNEL_COLOR_YELLOW, "SPGrid result is %u", grid);
+			auto loc = glm::vec3(client->GetPlayer()->GetX(), client->GetPlayer()->GetZ(), client->GetPlayer()->GetY());
+			uint32 GridID = 0;
+			float new_z = client->GetPlayer()->GetMap()->FindBestZ(loc, nullptr, &GridID);
+			client->Message(CHANNEL_COLOR_YELLOW, "Grid result is %u, at EQ2 Y coordinate %f", GridID, new_z);
 	}
 }
 

+ 47 - 18
EQ2/source/WorldServer/Spawn.cpp

@@ -30,7 +30,6 @@
 #include "Rules/Rules.h"
 #include "World.h"
 #include "LuaInterface.h"
-#include "Zone/SPGrid.h"
 #include "Bots/Bot.h"
 #include "Zone/raycast_mesh.h"
 
@@ -2026,11 +2025,22 @@ void Spawn::InitializePosPacketData(Player* player, PacketStruct* packet, bool b
 		std::map<int32,TimedGridData>::iterator itr = established_grid_id.find(version);
 		if ( itr == established_grid_id.end() || itr->second.timestamp <= (Timer::GetCurrentTime2()))
 		{
-			new_grid_id = player->GetMap()->GetGrid()->GetGridIDByLocation(GetX(),GetY(),GetZ());
-			TimedGridData data;
-			data.grid_id = new_grid_id;
-			data.timestamp = Timer::GetCurrentTime2()+100;
-			established_grid_id.insert(make_pair(packet->GetVersion(), data));
+			if(itr != established_grid_id.end() && itr->second.x == GetX() && itr->second.z == GetZ() && !itr->second.npc_save) {
+				itr->second.timestamp = Timer::GetCurrentTime2()+100;
+				itr->second.npc_save = false;
+			}
+			else {
+				auto loc = glm::vec3(GetX(), GetZ(), GetY());
+				float new_z = player->GetMap()->FindBestZ(loc, nullptr, &new_grid_id);
+				TimedGridData data;
+				data.grid_id = new_grid_id;
+				data.x = GetX();
+				data.y = GetY();
+				data.z = GetZ();
+				data.npc_save = false;
+				data.timestamp = Timer::GetCurrentTime2()+100;
+				established_grid_id.insert(make_pair(packet->GetVersion(), data));
+			}
 		}
 		else
 			new_grid_id = itr->second.grid_id;
@@ -2752,11 +2762,6 @@ void Spawn::ProcessMovement(bool isSpawnListLocked){
 	if (forceMapCheck && GetZone() != nullptr && GetMap() != nullptr && GetMap()->IsMapLoaded())
 	{
 		FixZ(true);
-
-		int32 newGrid = GetMap()->GetGrid()->GetGridID(this);
-		if ((IsTransportSpawn() || !IsFlyingCreature()) && newGrid != 0 && newGrid != appearance.pos.grid_id)
-			SetPos(&(appearance.pos.grid_id), newGrid);
-
 		forceMapCheck = false;
 	}
 
@@ -3245,11 +3250,22 @@ bool Spawn::CalculateChange(){
 			std::map<int32,TimedGridData>::iterator itr = established_grid_id.begin();
 			if ( itr == established_grid_id.end() || itr->second.timestamp <= (Timer::GetCurrentTime2()))
 			{
-				newGrid = GetMap()->GetGrid()->GetGridIDByLocation(GetX(),GetY(),GetZ());
-				TimedGridData data;
-				data.grid_id = newGrid;
-				data.timestamp = Timer::GetCurrentTime2()+1000;
-				established_grid_id.insert(make_pair(0, data));
+				if(itr != established_grid_id.end() && itr->second.x == GetX() && itr->second.z == GetZ()) {
+					itr->second.timestamp = Timer::GetCurrentTime2()+1000;
+					itr->second.npc_save = true;
+				}
+				else {
+					auto loc = glm::vec3(GetX(), GetZ(), GetY());
+					float new_z = GetMap()->FindBestZ(loc, nullptr, &newGrid);
+					TimedGridData data;
+					data.grid_id = newGrid;
+					data.x = GetX();
+					data.y = GetY();
+					data.z = GetZ();
+					data.npc_save = true;
+					data.timestamp = Timer::GetCurrentTime2()+1000;
+					established_grid_id.insert(make_pair(0, data));
+				}
 			}
 			else
 				newGrid = itr->second.grid_id;
@@ -3779,7 +3795,7 @@ float Spawn::GetFixedZ(const glm::vec3& destination, int32 z_find_offset) {
 
 
 void Spawn::FixZ(bool forceUpdate) {
-	if (IsPlayer() || IsFlyingCreature() || !GetZone() || IsObject()) {
+	if (!GetZone()) {
 		return;
 	}
 	/*
@@ -3793,7 +3809,20 @@ void Spawn::FixZ(bool forceUpdate) {
 	
 	// we do the inwater check here manually to avoid double calling for a Z coordinate
 	glm::vec3 current_loc(GetX(), GetZ(), GetY());
-	float new_z = GetFixedZ(current_loc, 1);
+
+	uint32 GridID = 0;
+	float new_z = GetZ();
+	if(GetMap() != nullptr) {
+		float new_z = GetMap()->FindBestZ(current_loc, nullptr, &GridID);
+
+		if ((IsTransportSpawn() || !IsFlyingCreature()) && GridID != 0 && GridID != appearance.pos.grid_id)
+			SetPos(&(appearance.pos.grid_id), GridID);
+	}
+
+	// no need to go any further for players, flying creatures or objects, just needed the grid id set
+	if (IsPlayer() || IsFlyingCreature() || IsObject()) {
+		return;
+	}
 	
 	if ( region_map != nullptr )
 	{

+ 4 - 0
EQ2/source/WorldServer/Spawn.h

@@ -242,6 +242,10 @@ struct SpawnData {
 struct TimedGridData {
 	int32 timestamp;
 	int32 grid_id;
+	float x;
+	float y;
+	float z;
+	bool npc_save;
 };
 
 class Spawn {

+ 4 - 2
EQ2/source/WorldServer/WorldDatabase.cpp

@@ -7259,8 +7259,10 @@ void WorldDatabase::GetHouseSpawnInstanceData(ZoneServer* zone, Spawn* spawn)
 
 		if (spawn->GetZone() != nullptr && spawn->GetMap() != nullptr && spawn->GetMap()->IsMapLoaded())
 		{
-			int32 newGrid = spawn->GetMap()->GetGrid()->GetGridID(spawn);
-			spawn->SetPos(&(spawn->appearance.pos.grid_id), newGrid);
+			auto loc = glm::vec3(spawn->GetX(),spawn->GetZ(),spawn->GetY());
+			uint32 GridID = 0;
+			float new_z = spawn->GetMap()->FindBestZ(loc, nullptr, &GridID);
+			spawn->SetPos(&(spawn->appearance.pos.grid_id), GridID);
 		}
 	}
 }

+ 0 - 667
EQ2/source/WorldServer/Zone/SPGrid.cpp

@@ -1,667 +0,0 @@
-/*
-EQ2Emulator:  Everquest II Server Emulator
-Copyright (C) 2007  EQ2EMulator Development Team (http://www.eq2emulator.net)
-
-This file is part of EQ2Emulator.
-EQ2Emulator is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-EQ2Emulator is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with EQ2Emulator.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "SPGrid.h"
-#include "../../common/Log.h"
-
-SPGrid::SPGrid(string file, int32 cellSize) {
-	m_ZoneFile = file;
-	m_MinX = 0;
-	m_MinZ = 0;
-	m_MaxX = 0;
-	m_MaxZ = 0;
-	m_NumCellsX = 0;
-	m_NumCellsZ = 0;
-	m_NumFaceCellsX = 0;
-	m_NumFaceCellsZ = 0;
-}
-
-SPGrid::~SPGrid() {
-	vector<FaceCell>::iterator CellItr;
-	map<int32, vector<Face*> >::iterator MapItr;
-	vector<Face*>::iterator FaceItr;
-
-	map<Face*, bool> deadPtrs;
-	
-	// Loop through the vector of cells
-	for (CellItr = m_FaceCells.begin(); CellItr != m_FaceCells.end(); CellItr++) {
-		// Loop through the map of vertices on this cell
-		for (MapItr = (*CellItr).FaceList.begin(); MapItr != (*CellItr).FaceList.end(); MapItr++) {
-			// Loop through the vector of faces in the map and delete the pointers
-			for (FaceItr = (*MapItr).second.begin(); FaceItr != (*MapItr).second.end(); FaceItr++) {
-				if(deadPtrs.count((*FaceItr)) == 0)
-				{
-					deadPtrs.insert(make_pair((*FaceItr), true));
-					safe_delete((*FaceItr));
-				}
-			}
-		}
-	}
-}
-
-bool SPGrid::Init() {
-	// Make sure we have a zone file
-	if (m_ZoneFile.empty()) {
-		LogWrite(ZONE__ERROR, 0, "SPGrid", "SPGrid::Init() m_ZoneFile is empty.");
-		return false;
-	}
-
-	// Open the map file for this zone
-	string filePath = "Maps/" + m_ZoneFile + ".EQ2Map";
-	FILE* file = fopen(filePath.c_str(), "rb");
-	if (file == nullptr) {
-		LogWrite(ZONE__WARNING, 0, "SPGrid", "SPGrid::Init() unable to open the map file for %s. (zoneserver will continue to run fine without it)", m_ZoneFile.c_str());
-		return false;
-	}
-
-	// Read the string for the zone file name this was created for
-	int8 strSize;
-	char name[256];
-	fread(&strSize, sizeof(int8), 1, file);
-	LogWrite(ZONE__DEBUG, 0, "SPGrid", "strSize = %u", strSize);
-
-	size_t len = fread(&name, sizeof(char), strSize, file);
-	name[len] = '\0';
-	LogWrite(ZONE__DEBUG, 0, "SPGrid", "name = %s", name);
-
-	string fileName(name);
-	std::size_t found = fileName.find(m_ZoneFile);
-	// Make sure file contents are for the correct zone
-	if (found == std::string::npos) {
-		fclose(file);
-		LogWrite(ZONE__ERROR, 0, "SPGrid", "SPGrid::Init() map contents (%s) do not match its name (%s).", &name, m_ZoneFile.c_str());
-		return false;
-	}
-
-	// Read the min bounds
-	fread(&m_MinX, sizeof(float), 1, file);
-	fread(&m_MinZ, sizeof(float), 1, file);
-	LogWrite(ZONE__DEBUG, 0, "SPGrid", "minx = %f, minz = %f", m_MinX, m_MinZ);
-
-	// Read the max bounds
-	fread(&m_MaxX, sizeof(float), 1, file);
-	fread(&m_MaxZ, sizeof(float), 1, file);
-	LogWrite(ZONE__DEBUG, 0, "SPGrid", "maxx = %f, maxz = %f", m_MaxX, m_MaxZ);
-
-	// Calculate how many cells we need
-	// in both the X and Z direction
-	float width = m_MaxX - m_MinX;
-	float height = m_MaxZ - m_MinZ;
-
-	m_NumFaceCellsX = ceil(width / CELLSIZEDEFAULT);
-	m_NumFaceCellsZ = ceil(height / CELLSIZEDEFAULT);
-	m_FaceCells.resize(m_NumFaceCellsX * m_NumFaceCellsZ);
-
-	// Read the number of grids
-	int32 NumGrids;
-	fread(&NumGrids, sizeof(int32), 1, file);
-	LogWrite(ZONE__DEBUG, 0, "SPGrid", "NumGrids = %u", NumGrids);
-
-	// Loop through the grids loading the face list
-	for (int32 i = 0; i < NumGrids; i++) {
-		// Read the grid id
-		int32 GridID;
-		fread(&GridID, sizeof(int32), 1, file);
-		LogWrite(ZONE__DEBUG, 0, "SPGrid", "GridID = %u", GridID);
-
-		// Read the number of vertices
-		int32 NumFaces;
-		fread(&NumFaces, sizeof(int32), 1, file);
-		LogWrite(ZONE__DEBUG, 0, "SPGrid", "NumFaces = %u", NumFaces);
-
-		// Loop through the vertices list reading
-		// 3 at a time to creat a triangle (face)
-		for (int32 y = 0; y < NumFaces; ) {
-
-			// Each vertex need an x,y,z coordinate and 
-			// we will be reading 3 to create the face
-			float x1, x2, x3;
-			float y1, y2, y3;
-			float z1, z2, z3;
-
-			// Read the first vertex
-			fread(&x1, sizeof(float), 1, file);
-			fread(&y1, sizeof(float), 1, file);
-			fread(&z1, sizeof(float), 1, file);
-			y++;
-
-			// Read the second vertex
-			fread(&x2, sizeof(float), 1, file);
-			fread(&y2, sizeof(float), 1, file);
-			fread(&z2, sizeof(float), 1, file);
-			y++;
-
-			// Read the third (final) vertex
-			fread(&x3, sizeof(float), 1, file);
-			fread(&y3, sizeof(float), 1, file);
-			fread(&z3, sizeof(float), 1, file);
-			y++;
-			
-			// Create the face and add it to the grid
-			Face* face = new Face;
-			face->Vertex1[0] = x1;
-			face->Vertex1[1] = y1;
-			face->Vertex1[2] = z1;
-
-			face->Vertex2[0] = x2;
-			face->Vertex2[1] = y2;
-			face->Vertex2[2] = z2;
-
-			face->Vertex3[0] = x3;
-			face->Vertex3[1] = y3;
-			face->Vertex3[2] = z3;
-
-			AddFace(face, GridID);
-		}
-	}
-
-	fclose(file);
-
-	return true;
-}
-
-FaceCell* SPGrid::GetFaceCell(int32 x, int32 z) {
-	if (x >= m_NumFaceCellsX)
-		x = m_NumFaceCellsX - 1;
-
-	if (z >= m_NumFaceCellsZ)
-		z = m_NumFaceCellsZ - 1;
-
-	return &m_FaceCells[z * m_NumFaceCellsX + x];
-}
-
-FaceCell* SPGrid::GetFaceCell(float x, float z) {
-	// As cell grid coordinates are all positive we need to
-	// modify the coordinates by subtracting the min bounds
-	float newX = x - m_MinX;
-	float newZ = z - m_MinZ;
-
-	// Get the cell coordinates by doing int division
-	// with the modified coordinates and the cell size
-	int32 CellX = (int32)(newX / CELLSIZEDEFAULT);
-	int32 CellZ = (int32)(newZ / CELLSIZEDEFAULT);
-
-	return GetFaceCell(CellX, CellZ);
-}
-
-void SPGrid::AddFace(Face* face, int32 grid) {
-	// As each face has three vertices we will need to check the cell
-	// for all of them and add the face to each cell that it is within
-	face->grid_id = grid;
-	// Get the cell at the first vertex position (X and Z, Y is vertical in EQ2)
-	// as this is the first check we will add it to this cell and compare it 
-	// to the other two cells we get for the other two verticies
-	FaceCell* cell = GetFaceCell(face->Vertex1[0], face->Vertex1[2]);
-	cell->FaceList[grid].push_back(face);
-
-	// Get the cells for the other two verticies and compare
-	FaceCell* cell2 = GetFaceCell(face->Vertex2[0], face->Vertex2[2]);
-	FaceCell* cell3 = GetFaceCell(face->Vertex3[0], face->Vertex3[2]);
-
-	// If cell 2 is not the same cell as the original cell then add the face to cell2
-	if (cell2 != cell)
-		cell2->FaceList[grid].push_back(face);
-
-	// If cell 3 is not the same as the original cell AND not the same as cell 2 then add the face to cell 3
-	if (cell3 != cell && cell3 != cell2)
-		cell3->FaceList[grid].push_back(face);
-}
-
-float rayIntersectsTriangle(float *p, float *d, float *v0, float *v1, float *v2);
-
-int32 SPGrid::GetGridID(Spawn * spawn) {
-	FaceCell* cell = GetFaceCell(spawn->GetX(), spawn->GetZ());
-	
-
-	/*if (cell->GridBounds.size() == 1)
-		return cell->FaceList.begin()->first;*/
-
-	// Create the starting point for the trace
-	float point[3];
-	point[0] = spawn->GetX();
-	point[1] = spawn->GetY() + (float)(spawn->GetSize()/6.0f); // Small bump to make sure we are above ground when we do the trace
-	point[2] = spawn->GetZ();
-
-	// Create the direction for the trace, as we want what
-	// is below it will just be -1 in the y direction
-	float direction[3];
-	direction[0] = 0.0f;
-	direction[1] = -1.0f;
-	direction[2] = 0.0f;
-
-	float MinDistance = 0.0f;
-	int32 Grid = 0;
-
-	/*map<int32, GridBounds*>::iterator itr;
-	for (itr = cell->GridBounds.begin(); itr != cell->GridBounds.end(); itr++) {
-		GridBounds* bounds = (*itr).second;
-
-		if (point[0] >= bounds->MinBounds[0] && point[1] >= bounds->MinBounds[1] && point[2] >= bounds->MinBounds[2]
-			&& point[0] <= bounds->MaxBounds[0] && point[1] <= bounds->MaxBounds[1] && point[2] <= bounds->MaxBounds[2]) {
-
-			vector<Face*>::iterator itr2;
-			for (itr2 = cell->FaceList[(*itr).first].begin(); itr2 != cell->FaceList[(*itr).first].end(); itr2++) {
-				Face* face = *itr2;
-				float distance;
-				if ((distance = rayIntersectsTriangle(point, direction, face->Vertex1, face->Vertex2, face->Vertex3)) != 0) {
-					if (MinDistance == 0.0f || distance < MinDistance) {
-						MinDistance = distance;
-						Grid = (*itr).first;
-					}
-				}
-			}
-		}
-	}*/
-	map<int32, vector<Face*> >::iterator mapitr;
-	for (mapitr = cell->FaceList.begin(); mapitr != cell->FaceList.end(); mapitr++) {
-		vector<Face*>::iterator itr;
-		for (itr = (*mapitr).second.begin(); itr != (*mapitr).second.end(); itr++) {
-			Face* face = *itr;
-			float distance;
-			if ((distance = rayIntersectsTriangle(point, direction, face->Vertex1, face->Vertex2, face->Vertex3)) != 0) {
-				if (MinDistance == 0.0f || distance < MinDistance) {
-					MinDistance = distance;
-					Grid = (*mapitr).first;
-				}
-			}
-		}
-	}
-
-	return Grid;
-}
-
-int32 SPGrid::GetGridIDByLocation(float x, float y, float z) {
-	FaceCell* cell = GetFaceCell(x, z);
-	
-
-	/*if (cell->GridBounds.size() == 1)
-		return cell->FaceList.begin()->first;*/
-
-	// Create the starting point for the trace
-	float point[3];
-	point[0] = x;
-	point[1] = y + 3.0f; // Small bump to make sure we are above ground when we do the trace
-	point[2] = z;
-
-	// Create the direction for the trace, as we want what
-	// is below it will just be -1 in the y direction
-	float direction[3];
-	direction[0] = 0.0f;
-	direction[1] = -1.0f;
-	direction[2] = 0.0f;
-
-	float MinDistance = 0.0f;
-	int32 Grid = 0;
-
-	/*map<int32, GridBounds*>::iterator itr;
-	for (itr = cell->GridBounds.begin(); itr != cell->GridBounds.end(); itr++) {
-		GridBounds* bounds = (*itr).second;
-
-		if (point[0] >= bounds->MinBounds[0] && point[1] >= bounds->MinBounds[1] && point[2] >= bounds->MinBounds[2]
-			&& point[0] <= bounds->MaxBounds[0] && point[1] <= bounds->MaxBounds[1] && point[2] <= bounds->MaxBounds[2]) {
-
-			vector<Face*>::iterator itr2;
-			for (itr2 = cell->FaceList[(*itr).first].begin(); itr2 != cell->FaceList[(*itr).first].end(); itr2++) {
-				Face* face = *itr2;
-				float distance;
-				if ((distance = rayIntersectsTriangle(point, direction, face->Vertex1, face->Vertex2, face->Vertex3)) != 0) {
-					if (MinDistance == 0.0f || distance < MinDistance) {
-						MinDistance = distance;
-						Grid = (*itr).first;
-					}
-				}
-			}
-		}
-	}*/
-	map<int32, vector<Face*> >::iterator mapitr;
-	for (mapitr = cell->FaceList.begin(); mapitr != cell->FaceList.end(); mapitr++) {
-		vector<Face*>::iterator itr;
-		for (itr = (*mapitr).second.begin(); itr != (*mapitr).second.end(); itr++) {
-			Face* face = *itr;
-			float distance;
-			if ((distance = rayIntersectsTriangle(point, direction, face->Vertex1, face->Vertex2, face->Vertex3)) != 0) {
-				if (MinDistance == 0.0f || distance < MinDistance) {
-					MinDistance = distance;
-					Grid = (*mapitr).first;
-				}
-			}
-		}
-	}
-
-	return Grid;
-}
-
-float SPGrid::GetBestY(float x, float y, float z)
-{
-	float temp_y = 0;
-	float best_y = 999999.0f;
-	FaceCell* startCell = GetFaceCell(x, z);
-
-	float tmpY = y + 0.5f;
-
-	float point[3];
-	point[0] = x;
-	point[1] = tmpY; // Small bump to make sure we are above ground when we do the trace
-	point[2] = z;
-
-	float MinDistance = 0.0f;
-
-	// Create the direction for the trace, as we want what
-	// is below it will just be -1 in the y direction
-	float direction[3];
-	direction[0] = 0.0f;
-	direction[1] = -1.0f;
-	direction[2] = 0.0f;
-
-	Face* lastFace = 0;
-	int32 Grid = 0;
-	float BestZ = -999999.0f;
-	map<int32, vector<Face*> >::iterator mapitr;
-	for (mapitr = startCell->FaceList.begin(); mapitr != startCell->FaceList.end(); mapitr++) {
-		vector<Face*>::iterator itr;
-		for (itr = (*mapitr).second.begin(); itr != (*mapitr).second.end(); itr++) {
-			Face* face = *itr;
-			float distance;
-			if ((distance = rayIntersectsTriangle(point, direction, face->Vertex1, face->Vertex2, face->Vertex3)) != 0) {
-				if (MinDistance == 0.0f || distance < MinDistance) {
-					BestZ = face->Vertex2[1];
-					MinDistance = distance;
-					lastFace = face;
-					Grid = (*mapitr).first;
-				}
-			}
-		}
-	}
-
-	printf("GridID: %i, BestZ: %f yIn:% f\n", Grid, BestZ, y);
-
-	float endY = 999999.0f;
-
-	if (lastFace)
-	{
-/*		for (int i = 0; i < 3; i++)
-		{
-			for (int z = 0; z < 3; z++)
-			{
-				if (i == 0)
-					printf("Face%i-%i: %f\n", i, z, lastFace->Vertex1[z]);
-				else if (i == 1)
-					printf("Face%i-%i: %f\n", i, z, lastFace->Vertex2[z]);
-				else if (i == 2)
-					printf("Face%i-%i: %f\n", i, z, lastFace->Vertex3[z]);
-			}
-		}*/
-		endY = lastFace->Vertex2[1];
-	}
-
-	return endY;
-}
-
-Face* SPGrid::GetClosestFace(float x, float y, float z)
-{
-	float temp_y = 0;
-	float best_y = 999999.0f;
-	FaceCell* startCell = GetFaceCell(x, z);
-
-	float tmpY = y + 0.5f;
-
-	float point[3];
-	point[0] = x;
-	point[1] = tmpY; // Small bump to make sure we are above ground when we do the trace
-	point[2] = z;
-
-	float MinDistance = 0.0f;
-
-	// Create the direction for the trace, as we want what
-	// is below it will just be -1 in the y direction
-	float direction[3];
-	direction[0] = 0.0f;
-	direction[1] = -1.0f;
-	direction[2] = 0.0f;
-
-	Face* lastFace = 0;
-	int32 Grid = 0;
-	float BestZ = -999999.0f;
-	map<int32, vector<Face*> >::iterator mapitr;
-	for (mapitr = startCell->FaceList.begin(); mapitr != startCell->FaceList.end(); mapitr++) {
-		vector<Face*>::iterator itr;
-		for (itr = (*mapitr).second.begin(); itr != (*mapitr).second.end(); itr++) {
-			Face* face = *itr;
-			float distance;
-			if ((distance = rayIntersectsTriangle(point, direction, face->Vertex1, face->Vertex2, face->Vertex3)) != 0) {
-				if (MinDistance == 0.0f || distance < MinDistance) {
-					BestZ = face->Vertex2[1];
-					MinDistance = distance;
-					lastFace = face;
-					Grid = (*mapitr).first;
-				}
-			}
-		}
-	}
-
-	return lastFace;
-}
-
-Face* SPGrid::FindPath(float x, float y, float z, float targX, float targY, float targZ, bool forceEndCell)
-{
-	float MinDistance = 0.0f;
-	float MinDistanceEnd = 999999.0f;
-	// Create the starting point for the trace
-	float point[3];
-	point[0] = x;
-	point[1] = y + 1.0f; // Small bump to make sure we are above ground when we do the trace
-	point[2] = z;
-
-	float pointEnd[3];
-	pointEnd[0] = targX;
-	pointEnd[1] = y + 1.0f; // Small bump to make sure we are above ground when we do the trace
-	pointEnd[2] = targZ;
-
-	// Create the direction for the trace, as we want what
-	// is below it will just be -1 in the y direction
-	float direction[3];
-
-	if (!forceEndCell)
-	{
-		if (targX > x)
-			direction[0] = -0.5f;
-		else
-			direction[0] = 0.5f;
-	}
-	else
-	{
-		if (targX > x)
-			direction[0] = 1.0f;
-		else// if (targZ < z)
-			direction[0] = -1.0f;
-	}
-
-	//if (targY < y)
-		direction[1] = -1.0f;
-	//else
-	//	direction[1] = .5f;
-
-	//direction[1] = -1.0f;
-
-	if (forceEndCell)
-	{
-		if (targZ > z)
-			direction[2] = -0.5f;
-		else
-			direction[2] = 0.5f;
-	}
-	else
-	{
-		if (targZ > z)
-			direction[2] = 1.0f;
-		else// if ( targX < x )
-			direction[2] = -1.0f;
-	}
-
-	FaceCell* startCell = GetFaceCell(x, z);
-	FaceCell* endCell = GetFaceCell(x, z);
-
-	Face* startFace = GetClosestFace(x, y, z);
-	if (startFace == NULL)
-		return 0;
-
-	//float tmpDistance = rayIntersectsTriangle(pointEnd, direction, startFace->Vertex1, startFace->Vertex2, startFace->Vertex3);
-	//if (tmpDistance != 0.0f && tmpDistance < 15.0f)
-	//	return 0;
-
-	Face* nextFace = 0;
-
-	Face* endFace = GetClosestFace(targX, targY, targZ);
-
-	float distBetweenEachOther = 999999.0f;
-	map<int32, vector<Face*> >::iterator mapitr;
-	if (endFace != NULL && startCell->FaceList.count(endFace->grid_id))
-		mapitr = startCell->FaceList.find(endFace->grid_id);
-	else if (startFace != NULL)
-		mapitr = startCell->FaceList.find(startFace->grid_id);
-	else
-		return 0;
-
-	//FILE* pFile;
-	//pFile = fopen("vertices.txt", "a+");
-	char msg[256];
-	//_snprintf(msg, 256, "%f %f %f - %f %f %f\n", x,y,z,targX,targY,targZ);
-	//fwrite(msg, 1, strnlen(msg, 256), pFile);
-	for (; mapitr != startCell->FaceList.end(); mapitr++) {
-		vector<Face*>::iterator itr;
-		for (itr = (*mapitr).second.begin(); itr != (*mapitr).second.end(); itr++) {
-			Face* face = *itr;
-			float distance;
-			float distanceend;
-			distance = rayIntersectsTriangle(point, direction, face->Vertex1, face->Vertex2, face->Vertex3);
-			//distanceend = rayIntersectsTriangle(pointEnd, direction, face->Vertex1, face->Vertex2, face->Vertex3);
-
-			float tmpx1 = face->Vertex1[0] - pointEnd[0];
-			float tmpy1 = face->Vertex1[1] - pointEnd[1];
-			float tmpz1 = face->Vertex1[2] - pointEnd[2];
-			float tmpDistBetweenEachOther = sqrt(tmpx1 * tmpx1 + tmpy1 * tmpy1 + tmpz1 * tmpz1);
-			snprintf(msg, 256, "%f (%f): Face: %f %f %f\n", tmpDistBetweenEachOther, distance, face->Vertex1[0], face->Vertex1[1], face->Vertex1[2]);
-
-			if (face == startFace)
-			{
-				printf("Hit Start Cell..%s\n",msg);
-				break;
-			}
-			else if (face == endFace)
-			{
-				printf("Hit End Cell..%s\n",msg);
-				//continue;
-			}
-			//fwrite(msg, 1, strnlen(msg,256), pFile);
-			//printf("%f: Face: %f %f %f... distance: %f..\n", tmpDistBetweenEachOther, face->Vertex1[0], face->Vertex1[1], face->Vertex1[2],distance);
-			if (distance > 0.0f && ((MinDistance == 0.0f || distance < MinDistance) || (tmpDistBetweenEachOther < distBetweenEachOther))) {
-				printf("%f (%f): !HIT! Face: %f %f %f\n", tmpDistBetweenEachOther, distance, face->Vertex1[0], face->Vertex1[1], face->Vertex1[2]);
-				distBetweenEachOther = tmpDistBetweenEachOther;
-				nextFace = face;
-				MinDistance = distance;
-			}
-		}
-	}
-	/*
-	fwrite("\n", sizeof(char), 1, pFile);
-	if (forceEndCell)
-		fwrite("Y", sizeof(char), 1, pFile);
-	fwrite("\n\n", sizeof(char), 2, pFile);
-	fclose(pFile);*/
-
-	Face* anotherAttempt = 0;
-	if (!forceEndCell)
-	{
-		printf("ForceEndCellSet:\n");
-		anotherAttempt = FindPath(x, y, z, targX, targY, targZ, true);
-	}
-	if (!nextFace)
-	{
-		if (anotherAttempt)
-			nextFace = anotherAttempt;
-		else
-			nextFace = endFace;
-		/*if (!forceEndCell)
-			return FindPath(x, y, z, targX, targY, targZ, true);
-		nextFace = endFace;*/
-	}
-
-	return nextFace;
-}
-
-/**********************************************************************
- 
- Math functions/macros to test a ray intersection in 3D space
-
-**********************************************************************/
-
-/* a = b - c */
-#define vector(a,b,c) \
-	(a)[0] = (b)[0] - (c)[0];	\
-	(a)[1] = (b)[1] - (c)[1];	\
-	(a)[2] = (b)[2] - (c)[2];
-
-#define crossProduct(a,b,c) \
-	(a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2]; \
-	(a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0]; \
-	(a)[2] = (b)[0] * (c)[1] - (c)[0] * (b)[1];
-
-#define innerProduct(v,q) \
-	((v)[0] * (q)[0] + \
-	(v)[1] * (q)[1] + \
-	(v)[2] * (q)[2])
-
-// all parameters should be vectors (float[3])
-float rayIntersectsTriangle(float *p, float *d, float *v0, float *v1, float *v2) {
-
-	float e1[3], e2[3], h[3], s[3], q[3];
-	float a, f, u, v;
-	vector(e1, v1, v0);
-	vector(e2, v2, v0);
-
-	crossProduct(h, d, e2);
-	a = innerProduct(e1, h);
-
-	if (a > -0.00001 && a < 0.00001)
-		return 0;
-
-	f = 1 / a;
-	vector(s, p, v0);
-	u = f * (innerProduct(s, h));
-
-	if (u < 0.0 || u > 1.0)
-		return 0;
-
-	crossProduct(q, s, e1);
-	v = f * innerProduct(d, q);
-
-	if (v < 0.0 || u + v > 1.0)
-		return 0;
-
-	// at this stage we can compute t to find out where
-	// the intersection point is on the line
-	float t = f * innerProduct(e2, q);
-
-	if (t > 0.00001) // ray intersection
-		return t;
-
-	else // this means that there is a line intersection
-		 // but not a ray intersection
-		return 0;
-}

+ 0 - 111
EQ2/source/WorldServer/Zone/SPGrid.h

@@ -1,111 +0,0 @@
-/*
-EQ2Emulator:  Everquest II Server Emulator
-Copyright (C) 2007  EQ2EMulator Development Team (http://www.eq2emulator.net)
-
-This file is part of EQ2Emulator.
-EQ2Emulator is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-EQ2Emulator is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with EQ2Emulator.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include <vector>
-#include <map>
-#include "../../common/types.h"
-#include <cmath>
-
-class Spawn;
-
-#define CELLSIZEDEFAULT 30
-#define FACECELLSIZEDEFAULT 15
-
-struct Face {
-	float Vertex1[3];
-	float Vertex2[3];
-	float Vertex3[3];
-	int32 grid_id;
-};
-
-/*struct GridBounds {
-	int32 Grid;
-	float MinBounds[3];
-	float MaxBounds[3];
-};*/
-
-struct Cell {
-	std::vector<Spawn*> SpawnList;
-	//std::map<int32, vector<Face*> > FaceList;
-	//std::map<int32, GridBounds*> GridBounds;
-};
-
-struct FaceCell {
-	std::map<int32, vector<Face*> > FaceList;
-};
-
-class SPGrid {
-public:
-	SPGrid(string file, int32 cellSize);
-	~SPGrid();
-
-	// Sets up the spacial partioning grid
-	bool Init();
-
-	// Adds a face to the cells it needs to be in and sets its GridID
-	void AddFace(Face* face, int32 grid);
-
-	// Checks the faces below the given spawn to determine the GridID
-	int32 GetGridID(Spawn* spawn);
-	int32 GetGridIDByLocation(float x, float y, float z);
-
-	// Get cell based on cell coordinates
-	FaceCell* GetFaceCell(int32 x, int32 z);
-
-	// Get cell based on world coordinates
-	FaceCell* GetFaceCell(float x, float z);
-
-	float GetBestY(float x, float y, float z);
-	Face* GetClosestFace(float x, float y, float z);
-	Face* FindPath(float x, float y, float z, float targX, float targY, float targZ, bool forceEndCell=false);
-
-	void InitValues(float minX, float maxX, float minZ, float maxZ, int32 numCellsX, int32 numCellsZ)
-	{
-		m_MinX = minX;
-		m_MaxX = maxX;
-		m_MinZ = minZ;
-		m_MaxZ = maxZ;
-		m_NumCellsX = numCellsX;
-		m_NumCellsZ = numCellsZ;
-
-		float width = m_MaxX - m_MinX;
-		float height = m_MaxZ - m_MinZ;
-
-		m_NumFaceCellsX = ceil(width / CELLSIZEDEFAULT);
-		m_NumFaceCellsZ = ceil(height / CELLSIZEDEFAULT);
-		m_FaceCells.resize(m_NumFaceCellsX * m_NumFaceCellsZ);
-	}
-private:
-	std::vector<FaceCell> m_FaceCells;
-
-	string m_ZoneFile;
-
-	float m_MinX;
-	float m_MinZ;
-	float m_MaxX;
-	float m_MaxZ;
-
-	int32 m_NumCellsX;
-	int32 m_NumCellsZ;
-
-	int32 m_NumFaceCellsX;
-	int32 m_NumFaceCellsZ;
-};

+ 19 - 59
EQ2/source/WorldServer/Zone/map.cpp

@@ -60,14 +60,12 @@ ThreadReturnType LoadMapAsync(void* mapToLoad)
 	THREAD_RETURN(NULL);
 }
 
-Map::Map(string zonename, string file, SPGrid* grid) {
+Map::Map(string zonename, string file) {
 	CheckMapMutex.SetName(file + "MapMutex");
 	SetMapLoaded(false);
 	m_ZoneName = zonename;
 	m_ZoneFile = file;
 	imp = nullptr;
-	mGrid = grid;
-	m_CellSize = CELLSIZEDEFAULT;
 }
 
 Map::~Map() {
@@ -76,10 +74,9 @@ Map::~Map() {
 		imp->rm->release();
 		safe_delete(imp);
 	}
-	safe_delete(mGrid);
 }
 
-float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result)
+float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result, uint32* GridID)
 {
 	if (!IsMapLoaded())
 		return BEST_Z_INVALID;
@@ -96,7 +93,7 @@ float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result)
 	float hit_distance;
 	bool hit = false;
 
-	hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
+	hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance, (RmUint32*)GridID);
 	if(hit) {
 		return result->z;
 	}
@@ -104,7 +101,7 @@ float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result)
 	// Find nearest Z above us
 	
 	to.z = -BEST_Z_INVALID;
-	hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
+	hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance, (RmUint32*)GridID);
 	if (hit)
 	{
 		return result->z;
@@ -131,9 +128,9 @@ float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result) {
 	glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
 	float hit_distance;
 	bool hit = false;
-	
+	uint32 grid_id = 0;
 	// first check is below us
-	hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
+	hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance, (RmUint32*)grid_id);
 	if (hit) {
 		ClosestZ = result->z;
 		
@@ -141,7 +138,7 @@ float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result) {
 	
 	// Find nearest Z above us
 	to.z = -BEST_Z_INVALID;
-	hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
+	hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance, (RmUint32*)grid_id);
 	if (hit) {
 		if (std::abs(from.z - result->z) < std::abs(ClosestZ - from.z))
 			return result->z;
@@ -155,7 +152,7 @@ bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::ve
 		return false;
 	if(!imp)
 		return false;
-	return imp->rm->raycast((const RmReal*)&start, (const RmReal*)&end, (RmReal*)result, nullptr, nullptr);
+	return imp->rm->raycast((const RmReal*)&start, (const RmReal*)&end, (RmReal*)result, nullptr, nullptr, nullptr);
 }
 
 bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) {
@@ -252,7 +249,7 @@ bool Map::CheckLoS(glm::vec3 myloc, glm::vec3 oloc)
 	if(!imp)
 		return false;
 
-	return !imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, nullptr, nullptr);
+	return !imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, nullptr, nullptr, nullptr);
 }
 
 // returns true if a collision happens
@@ -262,10 +259,10 @@ bool Map::DoCollisionCheck(glm::vec3 myloc, glm::vec3 oloc, glm::vec3 &outnorm,
 	if(!imp)
 		return false;
 
-	return imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, (RmReal *)&outnorm, (RmReal *)&distance);
+	return imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, (RmReal *)&outnorm, (RmReal *)&distance, nullptr);
 }
 
-Map *Map::LoadMapFile(std::string zonename, std::string file, SPGrid* grid) {
+Map *Map::LoadMapFile(std::string zonename, std::string file) {
 
 	std::string filename = "Maps/";
 	filename += file;
@@ -279,7 +276,7 @@ Map *Map::LoadMapFile(std::string zonename, std::string file, SPGrid* grid) {
 
 	LogWrite(MAP__INFO, 7, "Map", "Attempting to load Map File [{%s}]", filename.c_str());
 
-	auto m = new Map(zonename, file, grid);
+	auto m = new Map(zonename, file);
 	m->SetMapLoading(true);
 	m->SetFileName(filename);
 #ifdef WIN32
@@ -371,15 +368,13 @@ bool Map::LoadV2(FILE* f) {
 	m_NumCellsX = ceil(width / m_CellSize);
 	m_NumCellsZ = ceil(height / m_CellSize);
 
-	if (mGrid != nullptr)
-		mGrid->InitValues(m_MinX, m_MaxX, m_MinZ, m_MaxZ, m_NumCellsX, m_NumCellsZ);
-
 	// Read the number of grids
 	int32 NumGrids;
 	fread(&NumGrids, sizeof(int32), 1, f);
 
 	std::vector<glm::vec3> verts;
 	std::vector<uint32> indices;
+	std::vector<uint32> grids;
 
 	uint32 face_count = 0;
 	// Loop through the grids loading the face list
@@ -434,23 +429,7 @@ bool Map::LoadV2(FILE* f) {
 			verts.push_back(c);
 			indices.push_back((uint32)sz + 2);
 
-			if (mGrid != nullptr)
-			{
-				Face* face = new Face;
-				face->Vertex1[0] = x1;
-				face->Vertex1[1] = y1;
-				face->Vertex1[2] = z1;
-
-				face->Vertex2[0] = x2;
-				face->Vertex2[1] = y2;
-				face->Vertex2[2] = z2;
-
-				face->Vertex3[0] = x3;
-				face->Vertex3[1] = y3;
-				face->Vertex3[2] = z3;
-
-				mGrid->AddFace(face, GridID);
-			}
+			grids.push_back((uint32)GridID);
 		}
 	}
 	face_count = face_count / 3;
@@ -463,7 +442,7 @@ bool Map::LoadV2(FILE* f) {
 		imp = new impl;
 	}
 
-	imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]);
+	imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0], &grids[0]);
 
 	if (!imp->rm) {
 		delete imp;
@@ -527,9 +506,6 @@ bool Map::LoadV2Deflated(FILE* f) {
 	m_NumCellsX = ceil(width / m_CellSize);
 	m_NumCellsZ = ceil(height / m_CellSize);
 
-	if (mGrid != nullptr)
-		mGrid->InitValues(m_MinX, m_MaxX, m_MinZ, m_MaxZ, m_NumCellsX, m_NumCellsZ);
-
 	// Read the number of grids
 	int32 NumGrids;
 	srcbuf->sgetn(buf,sizeof(int32));
@@ -537,6 +513,7 @@ bool Map::LoadV2Deflated(FILE* f) {
 
 	std::vector<glm::vec3> verts;
 	std::vector<uint32> indices;
+	std::vector<uint32> grids;
 
 	uint32 face_count = 0;
 	// Loop through the grids loading the face list
@@ -596,23 +573,7 @@ bool Map::LoadV2Deflated(FILE* f) {
 			verts.push_back(c);
 			indices.push_back((uint32)sz + 2);
 
-			if (mGrid != nullptr)
-			{
-				Face* face = new Face;
-				face->Vertex1[0] = x1;
-				face->Vertex1[1] = y1;
-				face->Vertex1[2] = z1;
-
-				face->Vertex2[0] = x2;
-				face->Vertex2[1] = y2;
-				face->Vertex2[2] = z2;
-
-				face->Vertex3[0] = x3;
-				face->Vertex3[1] = y3;
-				face->Vertex3[2] = z3;
-
-				mGrid->AddFace(face, GridID);
-			}
+			grids.push_back(GridID);
 		}
 	}
 	face_count = face_count / 3;
@@ -625,7 +586,7 @@ bool Map::LoadV2Deflated(FILE* f) {
 		imp = new impl;
 	}
 
-	imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]);
+	imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0], &grids[0]);
 
 	file.close();
 	safe_delete_array(buf);
@@ -699,8 +660,7 @@ void MapRange::AddVersionRange(std::string zoneName) {
 		std::string baseMatch3(base_sub_match3.str().c_str());
         LogWrite(MAP__INFO, 0, "Map", "Map To Load: %s, size: %i, string: %s, min: %s, max: %s\n", i.string().c_str(), base_match.size(), baseMatch.c_str(), baseMatch2.c_str(), baseMatch3.c_str());
 
-        SPGrid * Grid = new SPGrid(base_sub_match.str().c_str(), 0);
-        Map * zonemap = Map::LoadMapFile(zoneName, base_sub_match.str().c_str(), Grid);
+        Map * zonemap = Map::LoadMapFile(zoneName, base_sub_match.str().c_str());
 
         int32 min_version = 0, max_version = 0;
         if (strlen(base_sub_match2.str().c_str()) > 0)

+ 3 - 7
EQ2/source/WorldServer/Zone/map.h

@@ -27,17 +27,16 @@
 #include "../../common/Mutex.h"
 #include "position.h"
 #include <stdio.h>
-#include "SPGrid.h"
 
 #define BEST_Z_INVALID -99999
 
 class Map
 {
 public:
-	Map(string zonename, string filename, SPGrid* grid=nullptr);
+	Map(string zonename, string filename);
 	~Map();
 
-	float FindBestZ(glm::vec3 &start, glm::vec3 *result);
+	float FindBestZ(glm::vec3 &start, glm::vec3 *result, uint32 *GridID = 0);
 	float FindClosestZ(glm::vec3 &start, glm::vec3 *result);
 	bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result);
 	bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result);
@@ -46,7 +45,7 @@ public:
 
 	bool Load(const std::string& filename);
 
-	static Map *LoadMapFile(std::string zonename, std::string file, SPGrid* grid=nullptr);
+	static Map *LoadMapFile(std::string zonename, std::string file);
 
 	std::string GetFileName() { return m_ZoneFile; }
 	void SetMapLoaded(bool val) {
@@ -80,8 +79,6 @@ public:
 	float GetMaxZ() { return m_MaxZ; }
 
 	void SetFileName(std::string newfile) { m_FileName = string(newfile); }
-	
-	SPGrid* GetGrid() { return mGrid; }
 private:
 	void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
 	void ScaleVertex(glm::vec3 &v, float sx, float sy, float sz);
@@ -110,7 +107,6 @@ private:
 	bool mapLoaded;
 	bool mapLoading;
 	Mutex CheckMapMutex;
-	SPGrid* mGrid;
 };
 
 class MapRange {

+ 22 - 9
EQ2/source/WorldServer/Zone/raycast_mesh.cpp

@@ -650,8 +650,10 @@ public:
 							RmReal *hitLocation,
 							RmReal *hitNormal,
 							RmReal *hitDistance,
+							RmUint32 *GridID,
 							const RmReal *vertices,
 							const RmUint32 *indices,
+							const RmUint32 *grids,
 							RmReal &nearestDistance,
 							NodeInterface *callback,
 							RmUint32 *raycastTriangles,
@@ -708,6 +710,9 @@ public:
 								{
 									*hitDistance = t;
 								}
+								if(GridID) {
+									*GridID = grids[tri];
+								}
 								nearestTriIndex = tri;
 								hit = true;
 							}
@@ -719,11 +724,11 @@ public:
 			{
 				if ( mLeft )
 				{
-					mLeft->raycast(hit,from,to,dir,hitLocation,hitNormal,hitDistance,vertices,indices,nearestDistance,callback,raycastTriangles,raycastFrame,leafTriangles,nearestTriIndex);
+					mLeft->raycast(hit,from,to,dir,hitLocation,hitNormal,hitDistance,GridID,vertices,indices,grids,nearestDistance,callback,raycastTriangles,raycastFrame,leafTriangles,nearestTriIndex);
 				}
 				if ( mRight )
 				{
-					mRight->raycast(hit,from,to,dir,hitLocation,hitNormal,hitDistance,vertices,indices,nearestDistance,callback,raycastTriangles,raycastFrame,leafTriangles,nearestTriIndex);
+					mRight->raycast(hit,from,to,dir,hitLocation,hitNormal,hitDistance,GridID,vertices,indices,grids,nearestDistance,callback,raycastTriangles,raycastFrame,leafTriangles,nearestTriIndex);
 				}
 			}
 		}
@@ -738,7 +743,7 @@ class MyRaycastMesh : public RaycastMesh, public NodeInterface
 {
 public:
 
-	MyRaycastMesh(RmUint32 vcount,const RmReal *vertices,RmUint32 tcount,const RmUint32 *indices,RmUint32 maxDepth,RmUint32 minLeafSize,RmReal minAxisSize)
+	MyRaycastMesh(RmUint32 vcount,const RmReal *vertices,RmUint32 tcount,const RmUint32 *indices,const RmUint32 *grids,RmUint32 maxDepth,RmUint32 minLeafSize,RmReal minAxisSize)
 	{
 		mRaycastFrame = 0;
 		if ( maxDepth < 2 )
@@ -765,6 +770,8 @@ public:
 		memcpy(mIndices,indices,sizeof(RmUint32)*tcount*3);
 		mRaycastTriangles = (RmUint32 *)::malloc(tcount*sizeof(RmUint32));
 		memset(mRaycastTriangles,0,tcount*sizeof(RmUint32));
+		mGrids = (RmUint32 *)::malloc(sizeof(RmUint32)*tcount);
+		memcpy(mGrids,grids,sizeof(RmUint32)*tcount);
 		mRoot = getNode();
 		mFaceNormals = NULL;
 		new ( mRoot ) NodeAABB(mVcount,mVertices,mTcount,mIndices,maxDepth,minLeafSize,minAxisSize,this,mLeafTriangles);
@@ -777,9 +784,10 @@ public:
 		::free(mIndices);
 		::free(mFaceNormals);
 		::free(mRaycastTriangles);
+		::free(mGrids);
 	}
 
-	virtual bool raycast(const RmReal *from,const RmReal *to,RmReal *hitLocation,RmReal *hitNormal,RmReal *hitDistance)
+	virtual bool raycast(const RmReal *from,const RmReal *to,RmReal *hitLocation,RmReal *hitNormal,RmReal *hitDistance,RmUint32 *GridID)
 	{
 		bool ret = false;
 
@@ -795,7 +803,7 @@ public:
 		dir[2]*=recipDistance;
 		mRaycastFrame++;
 		RmUint32 nearestTriIndex=TRI_EOF;
-		mRoot->raycast(ret,from,to,dir,hitLocation,hitNormal,hitDistance,mVertices,mIndices,distance,this,mRaycastTriangles,mRaycastFrame,mLeafTriangles,nearestTriIndex);
+		mRoot->raycast(ret,from,to,dir,hitLocation,hitNormal,hitDistance,GridID,mVertices,mIndices,mGrids,distance,this,mRaycastTriangles,mRaycastFrame,mLeafTriangles,nearestTriIndex);
 		return ret;
 	}
 
@@ -844,7 +852,7 @@ public:
 		faceNormal[2] = src[2];
 	}
 
-	virtual bool bruteForceRaycast(const RmReal *from,const RmReal *to,RmReal *hitLocation,RmReal *hitNormal,RmReal *hitDistance)
+	virtual bool bruteForceRaycast(const RmReal *from,const RmReal *to,RmReal *hitLocation,RmReal *hitNormal,RmReal *hitDistance,RmUint32 *GridID)
 	{
 		bool ret = false;
 
@@ -896,6 +904,10 @@ public:
 					{
 						*hitDistance = t;
 					}
+
+					if(GridID) {
+						*GridID = mGrids[tri];
+					}
 					ret = true;
 				}
 			}
@@ -915,6 +927,7 @@ public:
 	RmUint32		mMaxNodeCount;
 	NodeAABB		*mNodes;
 	TriVector		mLeafTriangles;
+	RmUint32		*mGrids;
 };
 
 };
@@ -928,11 +941,11 @@ RaycastMesh * createRaycastMesh(RmUint32 vcount,		// The number of vertices in t
 								const RmReal *vertices,		// The array of vertex positions in the format x1,y1,z1..x2,y2,z2.. etc.
 								RmUint32 tcount,		// The number of triangles in the source triangle mesh
 								const RmUint32 *indices, // The triangle indices in the format of i1,i2,i3 ... i4,i5,i6, ...
+								const RmUint32 *grids,
 								RmUint32 maxDepth,	// Maximum recursion depth for the triangle mesh.
 								RmUint32 minLeafSize,	// minimum triangles to treat as a 'leaf' node.
-								RmReal	minAxisSize	// once a particular axis is less than this size, stop sub-dividing.
-								)
+								RmReal	minAxisSize )	// once a particular axis is less than this size, stop sub-dividing.
 {
-	auto m = new MyRaycastMesh(vcount, vertices, tcount, indices, maxDepth, minLeafSize, minAxisSize);
+	auto m = new MyRaycastMesh(vcount, vertices, tcount, indices, grids, maxDepth, minLeafSize, minAxisSize);
 	return static_cast< RaycastMesh * >(m);
 }

+ 3 - 2
EQ2/source/WorldServer/Zone/raycast_mesh.h

@@ -36,8 +36,8 @@ typedef unsigned int RmUint32;
 class RaycastMesh
 {
 public:
-	virtual bool raycast(const RmReal *from,const RmReal *to,RmReal *hitLocation,RmReal *hitNormal,RmReal *hitDistance) = 0;
-	virtual bool bruteForceRaycast(const RmReal *from,const RmReal *to,RmReal *hitLocation,RmReal *hitNormal,RmReal *hitDistance) = 0;
+	virtual bool raycast(const RmReal *from,const RmReal *to,RmReal *hitLocation,RmReal *hitNormal,RmReal *hitDistance, RmUint32 *GridID) = 0;
+	virtual bool bruteForceRaycast(const RmReal *from,const RmReal *to,RmReal *hitLocation,RmReal *hitNormal,RmReal *hitDistance, RmUint32 *GridID) = 0;
 
 	virtual const RmReal * getBoundMin(void) const = 0; // return the minimum bounding box
 	virtual const RmReal * getBoundMax(void) const = 0; // return the maximum bounding box.
@@ -51,6 +51,7 @@ RaycastMesh * createRaycastMesh(RmUint32 vcount,		// The number of vertices in t
 								const RmReal *vertices,		// The array of vertex positions in the format x1,y1,z1..x2,y2,z2.. etc.
 								RmUint32 tcount,		// The number of triangles in the source triangle mesh
 								const RmUint32 *indices, // The triangle indices in the format of i1,i2,i3 ... i4,i5,i6, ...
+								const RmUint32 *grids,
 								RmUint32 maxDepth=15,	// Maximum recursion depth for the triangle mesh.
 								RmUint32 minLeafSize=4,	// minimum triangles to treat as a 'leaf' node.
 								RmReal	minAxisSize=0.01f	// once a particular axis is less than this size, stop sub-dividing.

+ 2 - 1
EQ2/source/WorldServer/Zone/region_map_v1.cpp

@@ -196,7 +196,8 @@ void RegionMapV1::IdentifyRegionsInGrid(Client *client, const glm::vec3 &locatio
 	int32 grid = 0;
 	if (client->GetPlayer()->GetMap() != nullptr && client->GetPlayer()->GetMap()->IsMapLoaded())
 	{
-		grid = client->GetPlayer()->GetMap()->GetGrid()->GetGridIDByLocation(location.x, location.y, location.z);
+		auto loc = glm::vec3(location.x, location.z, location.y);
+		float new_z = client->GetPlayer()->GetMap()->FindBestZ(loc, nullptr, &grid);
 	}
 	else
 		client->SimpleMessage(CHANNEL_COLOR_RED, "No map to establish grid id, using grid id 0 (attempt match all).");

+ 0 - 1
EQ2/source/WorldServer/makefile.a64

@@ -140,7 +140,6 @@ SRC= ../common/Condition.o \
 	Widget.o \
 	World.o \
 	WorldDatabase.o \
-	Zone/SPGrid.o \
 	Zone/ChestTraps.o \
 	zoneserver.o
 

+ 0 - 1
EQ2/source/WorldServer/zoneserver.cpp

@@ -83,7 +83,6 @@ extern int errno;
 #include <algorithm>
 #include <random>
 
-#include "Zone/SPGrid.h"
 #include "Bots/Bot.h"
 
 #ifdef WIN32

+ 0 - 2
EQ2/source/WorldServer/zoneserver.h

@@ -257,8 +257,6 @@ struct ZoneInfoSlideStruct {
 	vector<ZoneInfoSlideStructTransitionInfo*> slide_transition_info;
 };
 
-class SPGrid;
-
 // need to attempt to clean this up and add xml comments, remove unused code, find a logical way to sort the functions maybe by get/set/process/add etc...
 class ZoneServer {
 public: