⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmapmanager.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
                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 + -