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

📄 routemap.cpp.svn-base

📁 坦克大战游戏完整全套源代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
#pragma warning(disable: 4996)

#include <string>
#include <cassert>
#include <vector>
#include <map>
#include <algorithm>

#include "map.h"
#include "mapObj.h"
#include "staticMapObj.h"
#include "common/entityManager.h"
#include "common/graphicEntity.h"
#include "delaunay.h"

using std::vector;
using std::map;
using std::find;
using std::swap;
using std::sort;

void RouteMapObjSpace::addEntity(size_t dataId, DataType dataType, const Rectf &box)
{
    RouteMapObjSpace *qs = this;
    while(qs->child)
    {
        size_t cid = qs->getChildId(box);
        if (cid == size_t(-1))
            break;
        else
            qs = &qs->getChild(cid);
    }
    Node n;
    n.dataType = dataType;
    n.dataId = dataId;
    n.boundingBox = box;
    qs->entities.push_back(n);
}

size_t RouteMapObjSpace::getClosestEntity(const Point2f &point, float &minDistance, unsigned short filter) const
{
    size_t entityId = size_t(-1);
    minDistance = FLT_MAX;
    for (size_t i = 0; i < entities.size(); i++)
    {
        if ((filter & entities[i].dataType) == 0)
            continue;

        float distance = entities[i].boundingBox.distance(point);
        if (distance < minDistance)
        {
            minDistance = distance;

            entityId = entities[i].dataId;
        }
    }
    if (child)
    {
        for (size_t i = 0; i < NumSubSpaces; i++)
        {
            float distance = getChild(i).getRange().distance(point);
            if (distance < minDistance)
            {
                size_t eid = getChild(i).getClosestEntity(point, distance, filter);
                if (distance < minDistance)
                {
                    minDistance = distance;
                    entityId = eid;
                }
            }
        }
    }
    return entityId;
}

class DistanceCompare
{
public:
    DistanceCompare() : minDistance(FLT_MAX)
    {
    }
    
    virtual bool filter(DataType dt) const = 0;
    virtual bool operator () (const Point2f &point, size_t id) = 0;
    float getMinDistance() const
    {
        return minDistance;
    }
    void resetDistance()
    {
        minDistance = FLT_MAX;
    }
protected:
    float minDistance;
};

size_t RouteMapObjSpace::getClosestEntity(const Point2f &point, DistanceCompare &cmp) const
{
    size_t entityId = size_t(-1);
    for (size_t i = 0; i < entities.size(); i++)
    {
        if (!cmp.filter(entities[i].dataType))
            continue;

        float distance = entities[i].boundingBox.distance(point);
        if (distance < cmp.getMinDistance() && cmp(point, entities[i].dataId))
        {
            entityId = entities[i].dataId;
        }
    }
    if (child)
    {
        for (size_t i = 0; i < NumSubSpaces; i++)
        {
            float distance = getChild(i).getRange().distance(point);
            if (distance < cmp.getMinDistance())
            {
                size_t eid = getChild(i).getClosestEntity(point, cmp);
                if (eid != size_t(-1))
                    entityId = eid;
            }
        }
    }
    return entityId;
}

class RouteMapTriangleDistanceCompare : public DistanceCompare
{
public:
    RouteMapTriangleDistanceCompare(const RouteMap &_rmap) : rmap(_rmap)
    {
    }
    virtual bool filter(DataType dt) const
    {
        return (filterDataType & dt) != 0;
    }
    virtual bool operator () (const Point2f &point, size_t id)
    {
        assert(id < rmap.triangles.size());
        const Point2f &center = rmap.getCenter(rmap.triangles[id]);
        float len = (center - point).Length();
        if (len < minDistance)
        {
            minDistance = len;
            return true;
        }
        return false;
    }
    unsigned short filterDataType;
protected:
    const RouteMap &rmap;
};

void RouteMap::renderDebug() const
{
    float alpha = 128;
    vector<size_t> objects;
    MapObjCuller culler(objects);
    culler.viewer = RenderQueue::getSingleton().getWindowViewer();
    culler.dataType = DT_Triangle;
    space.cull(culler);

#define ROUTEMAP_RENDERDEBUG_INTERSECT_POINTS       0
#define ROUTEMAP_RENDERDEBUG_TRIANGLE_EDGES         1
#define ROUTEMAP_RENDERDEBUG_BLOCK_TRIANGLE_EDGES   1
#define ROUTEMAP_RENDERDEBUG_FILL_BLOCK_AREA        1

    for (size_t i = 0; i < objects.size(); i++)
    {
        size_t tid = objects[i];
        assert(tid < triangles.size());
        const Triangle &tri = triangles[tid];
        const Point2f center = getCenter(tri);
        //if (!tri.block)

        const Point2f &pa = verticesBuffer[tri.v[Triangle::PointA]];
        const Point2f &pb = verticesBuffer[tri.v[Triangle::PointB]];
        const Point2f &pc = verticesBuffer[tri.v[Triangle::PointC]];
        const Point2f &da = (pa - center).Normalize();
        const Point2f &db = (pb - center).Normalize();
        const Point2f &dc = (pc - center).Normalize();
#if ROUTEMAP_RENDERDEBUG_INTERSECT_POINTS
        if (tri.va >= numOriginalVertices)
        {
            RenderQueue::getSingleton().render(pa - Point2f(3, 0), pa + Point2f(2, 0), ARGB(255, 0, 0, 255));
            RenderQueue::getSingleton().render(pa - Point2f(0, 3), pa + Point2f(0, 2), ARGB(255, 0, 0, 255));
        }
        if (tri.vb >= numOriginalVertices)
        {
            RenderQueue::getSingleton().render(pb - Point2f(3, 0), pb + Point2f(2, 0), ARGB(255, 0, 0, 255));
            RenderQueue::getSingleton().render(pb - Point2f(0, 3), pb + Point2f(0, 2), ARGB(255, 0, 0, 255));
        }
        if (tri.vc >= numOriginalVertices)
        {
            RenderQueue::getSingleton().render(pc - Point2f(3, 0), pc + Point2f(2, 0), ARGB(255, 0, 0, 255));
            RenderQueue::getSingleton().render(pc - Point2f(0, 3), pc + Point2f(0, 2), ARGB(255, 0, 0, 255));
        }
#endif
#if ROUTEMAP_RENDERDEBUG_TRIANGLE_EDGES
#if ROUTEMAP_RENDERDEBUG_BLOCK_TRIANGLE_EDGES
        if (!tri.block)
#endif
        {
            // 宁可画2遍,也不愿意做一次检测...
            DWORD c1 = ARGB(alpha, 128, 255, 128);
            DWORD c2 = ARGB(alpha, 255, 255, 0);
            DWORD c3 = ARGB(alpha, 255, 0, 255);
            size_t eid = tri.e[Triangle::EdgeAB];
            DWORD c = c1;
            if (eid < edges.size())
            {
                if (edges[eid].bBad)
                    c = c2;
                else if (edges[eid].failedToTurn)
                    c = c3;
            }
            RenderQueue::getSingleton().render(pa, pb, c);
            eid = tri.e[Triangle::EdgeBC];
            c = c1;
            if (eid < edges.size())
            {
                if (edges[eid].bBad)
                    c = c2;
                else if (edges[eid].failedToTurn)
                    c = c3;
            }
            RenderQueue::getSingleton().render(pc, pb, c);
            eid = tri.e[Triangle::EdgeAC];
            c = c1;
            if (eid < edges.size())
            {
                if (edges[eid].bBad)
                    c = c2;
                else if (edges[eid].failedToTurn)
                    c = c3;
            }
            RenderQueue::getSingleton().render(pa, pc, c);
        }
#endif

#if 0
        const Point2f p2[3] = {pa + da * -3, pb + db * -3, pc + dc * -3, };
        for (int i = 0; i < 3; i++)
        {
            //if (tri.t[i] == size_t(-1))
            {
                RenderQueue::getSingleton().render(p2[(i + 2) % 3], p2[(i + 1) % 3], ARGB(alpha, 255, 128, 255));
            }
            /*
            else
            {
                assert(tri.t[i] < triangles.size());
                const Triangle &tOther = triangles[tri.t[i]];
                const Point2f &cOther = getCenter(tOther);
                RenderQueue::getSingleton().render(center, cOther , ARGB(64, 0, 0, 128));
            }
            */
        }
#endif
        if (!tri.block)
        {

        }
#if ROUTEMAP_RENDERDEBUG_FILL_BLOCK_AREA
        else
        {
            // 障碍物,填充红色
            hgeTriple t;
            t.v[0].x = pa.x;
            t.v[0].y = pa.y;
            t.v[0].z = 0;
            t.v[0].col = ARGB(48, 255, 0, 0);
            t.v[0].tx = t.v[0].ty = 0;
            t.v[1].x = pb.x;
            t.v[1].y = pb.y;
            t.v[1].z = 0;
            t.v[1].col = ARGB(48, 255, 0, 0);
            t.v[1].tx = t.v[1].ty = 0;
            t.v[2].x = pc.x;
            t.v[2].y = pc.y;
            t.v[2].z = 0;
            t.v[2].col = ARGB(48, 255, 0, 0);
            t.v[2].tx = t.v[2].ty = 0;
            t.tex = 0;
            t.blend = BLEND_DEFAULT;
            RenderQueue::getSingleton().render(Point2f(), t);
        }
#endif
    }
    objects.clear();
    culler.dataType = DT_Edge;
    polySpace.cull(culler);

    HGE *hge = hgeCreate(HGE_VERSION);
    Point2f mousePos;
    hge->Input_GetMousePos(&mousePos.x, &mousePos.y);
    hge->Release();
    RenderQueue::getSingleton().screenToGame(mousePos);
    vector<size_t> picked;
    MapObjCuller pickCuller(picked);
    pickCuller.viewer.leftTop = mousePos + Point2f(-10, -10);
    pickCuller.viewer.rightBottom = mousePos + Point2f(10, 10);
    pickCuller.dataType = DT_Edge;
    space.cull(pickCuller);

    RenderQueue::getSingleton().render(pickCuller.viewer.leftTop, pickCuller.viewer.rightBottom, ARGB(255, 255, 0, 255));

    for (size_t p = 0; p < picked.size(); p++)
    {
        size_t peid = picked[p];
        assert(peid < edges.size());
        const Edge &pe = edges[peid];
        const Point2f &pea = verticesBuffer[pe.va];
        const Point2f &peb = verticesBuffer[pe.vb];
        RenderQueue::getSingleton().render(pea, peb, ARGB(255, 255, 128, 128));
        Point2f crossPoint0;
        if (::LineCrossPoint(pea, peb, pickCuller.viewer.leftTop, pickCuller.viewer.rightBottom, crossPoint0))
        {
            for (size_t i = 0; i < objects.size(); i++)
            {
                size_t eid = objects[i];
                assert(eid < polyEdges.size());
                const Edge &e = polyEdges[eid];

                const Point2f &pa = verticesBuffer[e.va];
                const Point2f &pb = verticesBuffer[e.vb];

                Point2f crossPoint;
                if (LineCrossPoint(e, pe, crossPoint)) // 求交点

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -