📄 vmapmanager.cpp.svn-base
字号:
c.fillTestVisCmd(pMapId,Vector3(x1,y1,z1),Vector3(x2,y2,z2),result);
iCommandLogger.appendCmd(c);
}
}
return(result);
}
//=========================================================
/**
get the hit position and return true if we hit something
otherwise the result pos will be the dest pos
*/
bool VMapManager::getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist)
{
bool result = false;
rx=x2;
ry=y2;
rz=z2;
if(isLineOfSightCalcEnabled())
{
if(iInstanceMapTrees.containsKey(pMapId))
{
Vector3 pos1 = convertPositionToInternalRep(x1,y1,z1);
Vector3 pos2 = convertPositionToInternalRep(x2,y2,z2);
Vector3 resultPos;
MapTree* mapTree = iInstanceMapTrees.get(pMapId);
result = mapTree->getObjectHitPos(pos1, pos2, resultPos, pModifyDist);
resultPos = convertPositionToMangosRep(resultPos.x,resultPos.y,resultPos.z);
rx = resultPos.x;
ry = resultPos.y;
rz = resultPos.z;
Command c = Command();
c.fillTestObjectHitCmd(pMapId, pos1, pos2, resultPos, result);
iCommandLogger.appendCmd(c);
}
}
return result;
}
//=========================================================
/**
get height or INVALID_HEIGHT if to hight was calculated
*/
//int gGetHeightCounter = 0;
float VMapManager::getHeight(unsigned int pMapId, float x, float y, float z)
{
float height = VMAP_INVALID_HEIGHT; //no height
if(isHeightCalcEnabled() && iInstanceMapTrees.containsKey(pMapId))
{
Vector3 pos = convertPositionToInternalRep(x,y,z);
MapTree* mapTree = iInstanceMapTrees.get(pMapId);
height = mapTree->getHeight(pos);
if(!(height < inf()))
{
height = VMAP_INVALID_HEIGHT; //no height
}
Command c = Command();
c.fillTestHeightCmd(pMapId,Vector3(x,y,z),height);
iCommandLogger.appendCmd(c);
}
return(height);
}
//=========================================================
/**
used for debugging
*/
bool VMapManager::processCommand(char *pCommand)
{
bool result = false;
std::string cmd = std::string(pCommand);
if(cmd == "startlog")
{
iCommandLogger.enableWriting(true);
result = true;
}
else if(cmd == "stoplog")
{
iCommandLogger.appendCmd(Command()); // Write stop command
iCommandLogger.enableWriting(false);
result = true;
}
else if(cmd.find_first_of("pos ") == 0)
{
float x,y,z;
sscanf(pCommand, "pos %f,%f,%f",&x,&y,&z);
Command c = Command();
c.fillSetPosCmd(convertPositionToInternalRep(x,y,z));
iCommandLogger.appendCmd(c);
iCommandLogger.enableWriting(false);
result = true;
}
return result;
}
//=========================================================
//=========================================================
//=========================================================
MapTree::MapTree(const char* pBaseDir)
{
iBasePath = std::string(pBaseDir);
if(iBasePath.length() > 0 && (iBasePath[iBasePath.length()-1] != '/' || iBasePath[iBasePath.length()-1] != '\\'))
{
iBasePath.append("/");
}
iTree = new AABSPTree<ModelContainer *>();
}
//=========================================================
MapTree::~MapTree()
{
Array<ModelContainer *> mcArray;
iTree->getMembers(mcArray);
int no = mcArray.size();
while(no >0)
{
--no;
delete mcArray[no];
}
delete iTree;
}
//=========================================================
// just for visual debugging with an external debug class
#ifdef _DEBUG_VMAPS
#ifndef gBoxArray
extern Vector3 p1,p2,p3,p4,p5,p6,p7;
extern Array<AABox>gBoxArray;
extern int gCount1, gCount2, gCount3, gCount4;
extern bool myfound;
#endif
#endif
typedef AABSPTree<ModelContainer*>::RayIntersectionIterator IT;
//=========================================================
/**
return dist to hit or inf() if no hit
*/
float MapTree::getIntersectionTime(const Ray& pRay, float pMaxDist, bool pStopAtFirstHit)
{
double firstDistance = inf();
const IT end = iTree->endRayIntersection();
IT obj = iTree->beginRayIntersection(pRay, pMaxDist);
for ( ;obj != end; ++obj) // (preincrement is *much* faster than postincrement!)
{
/*
Call your accurate intersection test here. It is guaranteed
that the ray hits the bounding box of obj. (*obj) has type T,
so you can call methods directly using the "->" operator.
*/
ModelContainer *model = (ModelContainer *) (*obj);
float t = model->getIntersectionTime(pRay, pStopAtFirstHit, pMaxDist);
// just for visual debugging with an external debug class
#ifdef _DEBUG_VMAPS
if(gCount3 == gCount1)
{
AABox testBox;
testBox = model->getAABoxBounds();
gBoxArray.append(testBox);
}
++gCount3;
#endif
if(t > 0 && t < inf())
{
obj.markBreakNode();
if(firstDistance > t && pMaxDist >= t)
{
firstDistance = t;
if(pStopAtFirstHit) break;
}
}
}
return firstDistance;
}
//=========================================================
bool MapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2)
{
bool result = true;
float maxDist = abs((pos2 - pos1).magnitude());
// direction with length of 1
Ray ray = Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist);
if(getIntersectionTime(ray, maxDist, true) < inf())
{
result = false;
}
return result;
}
//=========================================================
/**
When moving from pos1 to pos2 check if we hit an object. Return true and the position if we hit one
Return the hit pos or the original dest pos
*/
bool MapTree::getObjectHitPos(const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist)
{
bool result;
float maxDist = abs((pPos2 - pPos1).magnitude());
Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1
Ray ray = Ray::fromOriginAndDirection(pPos1, dir);
float dist = getIntersectionTime(ray, maxDist, false);
if(dist < inf())
{
pResultHitPos = pPos1 + dir * dist;
if(pModifyDist < 0)
{
if(abs((pResultHitPos - pPos1).magnitude()) > -pModifyDist)
{
pResultHitPos = pResultHitPos + dir*pModifyDist;
}
else
{
pResultHitPos = pPos1;
}
}
else
{
pResultHitPos = pResultHitPos + dir*pModifyDist;
}
result = true;
}
else
{
pResultHitPos = pPos2;
result = false;
}
return result;
}
//=========================================================
float MapTree::getHeight(const Vector3& pPos)
{
float height = inf();
Vector3 dir = Vector3(0,-1,0);
Ray ray = Ray::fromOriginAndDirection(pPos, dir); // direction with length of 1
float maxDist = VMapDefinitions::getMaxCanFallDistance();
float dist = getIntersectionTime(ray, maxDist, false);
if(dist < inf())
{
height = (pPos + dir * dist).y;
}
return(height);
}
//=========================================================
bool MapTree::loadMap(const std::string& pDirFileName, unsigned int pMapTileIdent)
{
bool result = true;
size_t len = iBasePath.length() + pDirFileName.length();
char *filenameBuffer = new char[len+1];
if(!hasDirFile(pDirFileName))
{
FilesInDir filesInDir;
result = false;
sprintf(filenameBuffer, "%s%s", iBasePath.c_str(), pDirFileName.c_str());
FILE* df = fopen(filenameBuffer, "rb");
if(df)
{
char lineBuffer[FILENAMEBUFFER_SIZE];
result = true;
bool newModelLoaded = false;
while(result && (fgets(lineBuffer, FILENAMEBUFFER_SIZE-1, df) != 0))
{
std::string name = std::string(lineBuffer);
chomp(name);
if(name.length() >1)
{
filesInDir.append(name);
ManagedModelContainer *mc;
if(!isAlreadyLoaded(name))
{
std::string fname = iBasePath;
fname.append(name);
mc = new ManagedModelContainer();
result = mc->readFile(fname.c_str());
if(result)
{
addModelConatiner(name, mc);
newModelLoaded = true;
}
}
else
{
mc = getModelContainer(name);
}
mc->incRefCount();
}
}
if(result && newModelLoaded)
{
iTree->balance();
}
if(result && ferror(df) != 0)
{
result = false;
}
fclose(df);
if(result)
{
filesInDir.incRefCount();
addDirFile(pDirFileName, filesInDir);
setLoadedMapTile(pMapTileIdent);
}
}
}
else
{
// Already loaded, so just inc. the ref count if mapTileIdent is new
if(!containsLoadedMapTile(pMapTileIdent))
{
setLoadedMapTile(pMapTileIdent);
FilesInDir& filesInDir = getDirFiles(pDirFileName);
filesInDir.incRefCount();
}
}
delete [] filenameBuffer;
return (result);
}
//=========================================================
void MapTree::unloadMap(const std::string& dirFileName, unsigned int pMapTileIdent, bool pForce)
{
if(hasDirFile(dirFileName) && (pForce || containsLoadedMapTile(pMapTileIdent)))
{
if(containsLoadedMapTile(pMapTileIdent))
removeLoadedMapTile(pMapTileIdent);
FilesInDir& filesInDir = getDirFiles(dirFileName);
filesInDir.decRefCount();
if(filesInDir.getRefCount() <= 0)
{
Array<std::string> fileNames = filesInDir.getFiles();
bool treeChanged = false;
for(int i=0; i<fileNames.size(); ++i)
{
std::string name = fileNames[i];
ManagedModelContainer* mc = getModelContainer(name);
mc->decRefCount();
if(mc->getRefCount() <= 0)
{
iLoadedModelContainer.remove(name);
iTree->remove(mc);
delete mc;
treeChanged = true;
}
}
iLoadedDirFiles.remove(dirFileName);
if(treeChanged)
{
iTree->balance();
}
}
}
}
//=========================================================
//=========================================================
void MapTree::addModelConatiner(const std::string& pName, ManagedModelContainer *pMc)
{
iLoadedModelContainer.set(pName, pMc);
iTree->insert(pMc);
}
//=========================================================
//=========================================================
//=========================================================
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -