You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
5.3 KiB
C++
225 lines
5.3 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program 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 Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include "std3d.h"
|
|
|
|
#include <cstdio>
|
|
#include <iostream>
|
|
|
|
#include "nel/3d/zone_search.h"
|
|
|
|
using namespace std;
|
|
|
|
|
|
namespace NL3D
|
|
{
|
|
|
|
|
|
/**
|
|
* Constructor : Initialize some privates members
|
|
*/
|
|
CZoneSearch::CZoneSearch()
|
|
{
|
|
/// Size X is named of AA to ZZ, current size is IB = 26 * 8 + 2 (AA is zone number 1, AZ zone number 26, BA zone number 27...)
|
|
// TMP fix for level designer (nico ...)
|
|
_NbZoneX = 26 * ('Z'-'A') + ('Z'-'A');
|
|
|
|
/// Number zones on Y axis of landscape
|
|
_NbZoneY = 297;
|
|
|
|
/// Size X of one zone (in meters)
|
|
_SizeZoneX = 160;
|
|
|
|
/// Size X of one zone (in meters)
|
|
_SizeZoneY = 160;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the zone name corresponding to coordinate
|
|
* \param x is axis X coordinate (in meters)
|
|
* \param y is axis Y coordinate (in meters)
|
|
* \param cx is axis X coordinate of center area (in meters)
|
|
* \param cy is axis Y coordinate of center area (in meters)
|
|
* \return a pair of the zone name and square distance between zone and center area (in zone unit)
|
|
*/
|
|
pair<string, uint32> CZoneSearch::getZoneName(uint x, uint y, uint cx, uint cy)
|
|
{
|
|
char name[13];
|
|
|
|
uint zoneY = y / _SizeZoneY + 1;
|
|
uint zoneX = x / _SizeZoneX;
|
|
|
|
uint zoneCenterY = cy / _SizeZoneY + 1;
|
|
uint zoneCenterX = cx / _SizeZoneX;
|
|
|
|
uint32 distance = (zoneX - zoneCenterX) * (zoneX - zoneCenterX) + (zoneY - zoneCenterY) * (zoneY - zoneCenterY);
|
|
|
|
char firstLetter = zoneX / 26 + 'A';
|
|
char secondLetter = zoneX % 26 + 'A';
|
|
|
|
sprintf(name, "%d_%c%c.zonel", zoneY, firstLetter, secondLetter);
|
|
|
|
return make_pair<string, uint32>(string(name), distance);
|
|
}
|
|
|
|
|
|
/*
|
|
* Get a list of zone name around a position
|
|
* \param x is axis X ccordinate (in meter)
|
|
* \param y is axis Y coordinate (in meter)
|
|
* \param sizeArea is area of zone research (in meter)
|
|
* \param l is a reference to a list of pair of string and uint32
|
|
* \return a liste contained name of all zone around indicated position and and square distance between zone and center area (in zone unit)
|
|
*/
|
|
void CZoneSearch::getListZoneName(uint x, uint y, uint sizeArea, list<pair<string, uint32> >& l)
|
|
{
|
|
sint startPosX, startPosY;
|
|
uint lastPosX, lastPosY, sizeAreaX, sizeAreaY;
|
|
|
|
startPosX = x - sizeArea;
|
|
startPosY = y - sizeArea;
|
|
|
|
sizeArea += sizeArea;
|
|
sizeAreaX = sizeAreaY = sizeArea;
|
|
|
|
if(startPosX < 0)
|
|
{
|
|
sizeAreaX += startPosX;
|
|
startPosX = 0;
|
|
}
|
|
|
|
lastPosX = startPosX + sizeAreaX;
|
|
if(lastPosX >= (_NbZoneX * _SizeZoneX))
|
|
{
|
|
sizeAreaX -= _NbZoneX * _SizeZoneX - lastPosX;
|
|
lastPosX = _NbZoneX * _SizeZoneX - 1;
|
|
}
|
|
|
|
if(startPosY < 0)
|
|
{
|
|
sizeAreaY += startPosY;
|
|
startPosY = 0;
|
|
}
|
|
|
|
lastPosY = startPosY + sizeAreaY;
|
|
if(lastPosY >= (_NbZoneY * _SizeZoneY))
|
|
{
|
|
sizeAreaY -= _NbZoneY * _SizeZoneY - lastPosY;
|
|
lastPosY = _NbZoneY * _SizeZoneY - 1;
|
|
}
|
|
|
|
l.clear();
|
|
|
|
for(uint i = startPosY; i <= lastPosY; i += _SizeZoneY)
|
|
{
|
|
for(uint j = startPosX; j <= lastPosX; j += _SizeZoneX)
|
|
{
|
|
l.push_back(getZoneName(j, i, x, y));
|
|
}
|
|
}
|
|
}
|
|
|
|
uint16 CZoneSearch::getZoneId (uint x, uint y) const
|
|
{
|
|
uint zoneY = y / _SizeZoneY;
|
|
uint zoneX = x / _SizeZoneX;
|
|
|
|
return (zoneX&255)+(zoneY<<8);
|
|
}
|
|
|
|
void CZoneSearch::getZonePos (uint16 zoneId, uint &x, uint &y) const
|
|
{
|
|
x = _SizeZoneY*(zoneId&255);
|
|
y = _SizeZoneY*(zoneId>>8);
|
|
}
|
|
|
|
void CZoneSearch::getListZoneId (uint x, uint y, uint sizeArea, vector<uint16> &l, const std::vector<uint16> *validZoneIds)
|
|
{
|
|
sint startPosX, startPosY;
|
|
uint lastPosX, lastPosY, sizeAreaX, sizeAreaY;
|
|
|
|
startPosX = x - sizeArea;
|
|
startPosY = y - sizeArea;
|
|
|
|
sizeArea += sizeArea;
|
|
sizeAreaX = sizeAreaY = sizeArea;
|
|
|
|
if(startPosX < 0)
|
|
{
|
|
sizeAreaX += startPosX;
|
|
startPosX = 0;
|
|
}
|
|
|
|
lastPosX = startPosX + sizeAreaX;
|
|
if(lastPosX >= (_NbZoneX * _SizeZoneX))
|
|
{
|
|
sizeAreaX -= _NbZoneX * _SizeZoneX - lastPosX;
|
|
lastPosX = _NbZoneX * _SizeZoneX - 1;
|
|
}
|
|
|
|
if(startPosY < 0)
|
|
{
|
|
sizeAreaY += startPosY;
|
|
startPosY = 0;
|
|
}
|
|
|
|
lastPosY = startPosY + sizeAreaY;
|
|
if(lastPosY >= (_NbZoneY * _SizeZoneY))
|
|
{
|
|
sizeAreaY -= _NbZoneY * _SizeZoneY - lastPosY;
|
|
lastPosY = _NbZoneY * _SizeZoneY - 1;
|
|
}
|
|
|
|
l.clear();
|
|
|
|
for(uint i = startPosY; i <= lastPosY; i += _SizeZoneY)
|
|
{
|
|
for(uint j = startPosX; j <= lastPosX; j += _SizeZoneX)
|
|
{
|
|
uint16 zoneId = getZoneId(j, i);
|
|
if (validZoneIds)
|
|
{
|
|
bool found = false;
|
|
for(uint k = 0; k < validZoneIds->size(); ++k)
|
|
{
|
|
if (zoneId == (*validZoneIds)[k])
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) continue;
|
|
}
|
|
l.push_back(zoneId);
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string CZoneSearch::getZoneNameFromId (uint16 zoneid)
|
|
{
|
|
char name[16];
|
|
|
|
sint x = zoneid & 255;
|
|
sint y = zoneid >> 8;
|
|
sprintf (name, "%d_%c%c.zonel", y+1, (char)('A'+(x/26)), (char)('A'+(x%26)));
|
|
return string(name);
|
|
}
|
|
|
|
|
|
} // NL3D
|
|
|