zoukankan      html  css  js  c++  java
  • 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/

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

  • 相关阅读:
    屏蔽/捕获并输出错误
    物理机转Hyper-V虚拟机
    Windows Server 2012无法安装 .NET3.5-安装角色或功能失败,找不到源文件
    IDRAC 固件升级操:
    网卡启动安装dell服务器OS
    服务器指定网卡进行备份数据避免影响业务口
    【转载】用户通过WEB方式更改AD域帐户密码
    Windows运维之Windows8.1-KB2999226-x64安装提示 此更新不适用你的计算机
    Exchange 退信550 5.1.11 RESOLVER.ADR.ExRecipNotFound
    优酷kux视频转MP4
  • 原文地址:https://www.cnblogs.com/maikkk/p/2523819.html
Copyright © 2011-2022 走看看