• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
maikkk
博客园    首页    新随笔    联系   管理    订阅  订阅
3D网格寻路实现 lua 代码

最近主要是有个很迫切需求要实现能在3D网格里面实现自动寻路

其实之前一直思考如何去实现,也找了不少资料和代码,最近脑海里面才形成比较完整思路

首先要知道地图网格数据,里面包含了顶点坐标和三角形面 

把地图网格数据可以转成成ply文件格式,用meshlab打开

ply
format ascii 1.0
comment VCGLIB generated
element vertex (顶多数量)
property float x
property float y
property float z
element face (三角形面的数量)
property list uchar int vertex_indices
end_header

(顶多坐标定义)

(三角形面定义)

 

通过上面的截图看到,地图是通过三角形面进行连接的

那么我们要实现寻路,就必须要知道开始和结束坐标轴三角形哪个面

然后再根据网格直接关系进行遍历,其实是一个图的遍历算法来实现

下面是遍历查找三角形面序号的lua代码

function getnextmeshtris(ss,d,mesh)

    local retTrisList = {}
    if mesh.tris[ss].visit ~= nil and mesh.tris[ss].visit == true then
        return retTrisList
    end
    mesh.tris[ss].visit = true
    print("getnextmeshtris next="..ss)
    local sstr  = ""
    for k,v in pairs(mesh.tris[ss]) do
        if type(v) == "table" then
            sstr = sstr .. k.."={"
            for _,vv in pairs(v) do
                sstr = sstr ..vv..","
            end
            sstr = sstr.."},"
        elseif type(v) == "number" or type(v) == "string" then
            sstr = sstr .. k.."="..v..","
        end
    end
    print(sstr)
    
    
    local findend = false
    for k,v in pairs(mesh.tris[ss]) do
        
        if not findend and string.find(k,"connect") ~= nil then
            for _,c in pairs(v) do
                if c == d then
                    print("getnextmeshtris in findend")
                    table.insert(retTrisList,d)
                    findend = true
                else
                    print("getnextmeshtris next next"..c + 1)
                    local l = getnextmeshtris(c + 1,d,mesh)
                    
                    for kk,vv in pairs(l) do
                        print("getnextmeshtris insert "..vv)
                        table.insert(retTrisList,vv)
                    end
                    if table.getn(l) > 0 then
                        table.insert(retTrisList,ss)
                    end
                end
            end
        end
    end
    print("getnextmeshtris next return")
    return retTrisList
end
-- 得到三角形的连接面
function get_tris_connect_in_mesh(s,d,mesh)
    local retTrisIndexList = {}
    
    local sstr = ""
    for k,v in pairs(mesh.tris[s]) do
        if type(v) == "table" then
            sstr = sstr .. k.."={"
            for _,vv in pairs(v) do
                sstr = sstr ..vv..","
            end
            sstr = sstr.."},"
        else
            sstr = sstr .. k.."="..v..","
        end
    end
    print(sstr)
    sstr = ""
    for k,v in pairs(mesh.tris[s]) do
        if string.find(k,"tartVert") ~= nil then
            sstr = sstr..k.."=[".."x="..mesh.verts[v + 1].x..",y="..mesh.verts[v + 1].y..",z="..mesh.verts[v + 1].z.."],"
        end
    end
    print(sstr)
    sstr = ""
    for k,v in pairs(mesh.tris[d]) do
        if type(v) == "table" then
            sstr = sstr .. k.."={"
            for _,vv in pairs(v) do
                sstr = sstr ..vv..","
            end
            sstr = sstr.."},"
        else
            sstr = sstr .. k.."="..v..","
        end
    end
    print(sstr)
    
    sstr = ""
    for k,v in pairs(mesh.tris[d]) do
        if string.find(k,"tartVert") ~= nil then
            sstr = sstr..k.."=[".."x="..mesh.verts[v + 1].x..",y="..mesh.verts[v + 1].y..",z="..mesh.verts[v + 1].z.."],"
        end
    end
    print(sstr)
    local findend = false
    mesh.tris[s].visit = true
    for k,v in pairs(mesh.tris[s]) do
        
        if not findend and string.find(k,"connect") ~= nil then
            for _,c in pairs(v) do
                if c == d then
                    print("get_tris_connect_in_mesh once")
                    table.insert(retTrisIndexList,s)
                    table.insert(retTrisIndexList,d)
                    findend = true
                else
                    print("getnextmeshtris next start:"..c + 1)
                    local l = getnextmeshtris(c + 1,d,mesh)
                    
                    for kk,vv in pairs(l) do
                        print("get_tris_connect_in_mesh insert "..vv)
                        table.insert(retTrisIndexList,vv)
                    end
                    if table.getn(l) > 0 then
                        table.insert(retTrisIndexList,s)
                    else
                        print("getnextmeshtris return nil ")
                    end
                    mesh.tris[s].visit = true
                    
                end
            
            end
            
        end
    end
    for kkk,vvv in pairs(retTrisIndexList) do
        print(vvv)
    end
    print("get_tris_connect_in_mesh end")
    return retTrisIndexList
end

下面是求点到空间直线的垂线交点函数

-- 求点到空间直线的交点
function GetPointCoressLine(point,linepoints)

    -- 两点直线的空间向量
    local xline = {x=linepoints[1].x - linepoints[2].x,y=linepoints[1].y - linepoints[2].y,z=linepoints[1].z - linepoints[2].z} 
    
    -- 直线方程
    --local t = (x -linepoints[2].x)/xline.x = (y -linepoints[2].y)/xline.y = (z -linepoints[2].z)/xline.z
    
    -- 求过point 垂直直线的平面方程
    --xline.x * (x - point.x) + xline.y * (y - point.y) + xline.z * (z - point.z) = 0
    
    --把 直线方程和平面方程带入求出t
    
    --local x = t * xline.x + linepoints[2].x
    --local y = t * xline.y + linepoints[2].y
    --local z = t * xline.z + linepoints[2].z
    --xline.x * (t * xline.x + linepoints[2].x - point.x) + xline.y * (t * xline.y + linepoints[2].y - point.y) + xline.z * (t * xline.z + linepoints[2].z - point.z) = 0
    
    local t = -(xline.x * (linepoints[2].x - point.x) + xline.y * (linepoints[2].y - point.y) + xline.z * (linepoints[2].z - point.z))/(xline.x * xline.x + xline.y * xline.y + xline.z * xline.z)
    
    local x = t * xline.x + linepoints[2].x
    local y = t * xline.y + linepoints[2].y
    local z = t * xline.z + linepoints[2].z
    
    print(x..","..y..","..z)
    return {x,y,z}
    
end

 

下面是计算一个空间坐标点在哪个三角形面上(代码中家里....)

 

 

参考资料

http://course.zjnu.cn/wyh/show.asp?id=185

http://61.139.105.132/gdsx/dzja/6/5.htm

http://www.pathengine.com/index.php

http://www.pathengine.com/downloads.php

https://code.google.com/p/critterai/

搜索谷歌 "空间直线及其方程"

posted on 2012-05-29 13:25  maikkk  阅读(1283)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3