曲面绘制Mesh

在 3d模型上边绘制mesh是很平常的操作,如车轮压过的轨迹等等。

在场景中建一个空的gameobject, 然后添加meshfilter 和meshrender组件,
传入参数,把返回值赋值给meshfile.mesh对象就能在屏幕上看见了,代码如下:
有中间点的mesh绘制代码


    public static Mesh CreateCurveMesh(MeshFilter meshFilter, Vector3 startPos, Vector3 endPos, float width, float step)
    {
        Mesh mesh = new Mesh();

        List<Vector3> listMidVertex = new List<Vector3>();
        List<Vector3> listLeftVertex = new List<Vector3>();
        List<Vector3> listRightVertex = new List<Vector3>();

        List<Vector3> listNormal = new List<Vector3>();

        Vector3 curveDir = endPos - startPos;
        float pathLen = curveDir.magnitude;

        curveDir = curveDir / pathLen;
        int count = (int)(pathLen / step);

        Ray ray;
        float heightOff = 5f;
        RaycastHit hitInfo;
        float rayLength = 20;
        int layerMask = -1;

        for (int i = 0; i < count; ++i)
        {
            ray = new Ray(startPos + i * step * curveDir + Vector3.up * heightOff, -Vector3.up);

            if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
            {
                listMidVertex.Add(hitInfo.point);
                listNormal.Add(hitInfo.normal);
            }
        }


        Vector3 averageNormal = Vector3.zero;
        Vector3 origin = (startPos + endPos) / 2;
        Vector3 originOffUp = origin + Vector3.up * 5;

        for (int i = 0; i < count; ++i)
        {
            averageNormal = (averageNormal * i + listNormal[i]) / (i + 1);

            listNormal[i] = averageNormal;
            Vector3 dir = Vector3.Cross(listNormal[i], curveDir).normalized;
            Vector3 leftPos = listMidVertex[i] - dir * width;
            Vector3 rightPos = listMidVertex[i] + dir * width;

            ray = new Ray(originOffUp, leftPos - originOffUp);
            if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
            {
                listLeftVertex.Add(hitInfo.point);
            }
            else
            {
                break;
            }

            ray = new Ray(originOffUp, rightPos - originOffUp);
            if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
            {
                listRightVertex.Add(hitInfo.point);
            }
            else
            {
                break;
            }
        }

        int totalPointCount = Mathf.Min(listLeftVertex.Count, listRightVertex.Count);

        if(totalPointCount < 1)
        {
            return mesh;
        }

        Vector3[] vertices = new Vector3[totalPointCount * 3];
        Vector3[] normals = new Vector3[totalPointCount * 3];

        Vector2[] UVS = new Vector2[totalPointCount * 3];

        int[] triangles = new int[(totalPointCount - 1) * 12];

        Vector3 curveMidPos = (listMidVertex[0] + listMidVertex[listMidVertex.Count - 1]) / 2;
        meshFilter.transform.position = curveMidPos;

        //UV: 在0,1之间表示放大了图片(0.2, tmp)(0.8,tmp), 小于0, 大于1表示缩小了图片(-0.8,tmp) (1,8,tmp);
        for (int i = 0; i < totalPointCount * 3; i += 3)
        {
            vertices[i] = listMidVertex[i / 3] - curveMidPos;
            vertices[i + 1] = listLeftVertex[i / 3] - curveMidPos;
            vertices[i + 2] = listRightVertex[i / 3] - curveMidPos;

            normals[i + 2] = normals[i + 1] = normals[i] = listNormal[i / 3];

            float temp = 1 - (float)(i / 3) / (float)(totalPointCount - 1);
            UVS[i] = new Vector2(0.5f, temp);

            UVS[i + 1] = new Vector2(0, temp);
            UVS[i + 2] = new Vector2(1, temp);
        }

        //按逆时针设置三角形中的顶点缩影,否则,就会显示在反面
        for (int i = 0; i < (totalPointCount - 1) * 12; i += 12)
        {
            triangles[i] = i / 4;
            triangles[i + 1] = triangles[i] + 4;
            triangles[i + 2] = triangles[i] + 3;

            triangles[i + 3] = triangles[i];
            triangles[i + 4] = triangles[i] + 1;
            triangles[i + 5] = triangles[i] + 4;

            triangles[i + 6] = triangles[i];
            triangles[i + 7] = triangles[i] + 5;
            triangles[i + 8] = triangles[i] + 2;

            triangles[i + 9] = triangles[i];
            triangles[i + 10] = triangles[i] + 3;
            triangles[i + 11] = triangles[i] + 5;
        }

        mesh.vertices = vertices;
        mesh.normals = normals;
        mesh.uv = UVS;
        mesh.triangles = triangles;
        return mesh;
    }

没有中间点,只存在左右点的mesh绘制代码

  public static Mesh CreateRoughCurveMesh(MeshFilter meshFilter, Vector3 startPos, Vector3 endPos, float width, float step)
    {
        Mesh mesh = new Mesh();

        List<Vector3> listMidVertex = new List<Vector3>();
        List<Vector3> listLeftVertex = new List<Vector3>();
        List<Vector3> listRightVertex = new List<Vector3>();

        List<Vector3> listNormal = new List<Vector3>();

        Vector3 curveDir = endPos - startPos;
        float pathLen = curveDir.magnitude;

        curveDir = curveDir / pathLen;
        int count = (int)(pathLen / step);

        Ray ray;
        float heightOff = 5f;
        RaycastHit hitInfo;
        float rayLength = 20;
        int layerMask = -1;

        for (int i = 0; i < count; ++i)
        {
            ray = new Ray(startPos + i * step * curveDir + Vector3.up * heightOff, -Vector3.up);

            if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
            {
                listMidVertex.Add(hitInfo.point);
                listNormal.Add(hitInfo.normal);
            }
        }

        Vector3 averageNormal = Vector3.zero;
        Vector3 origin = (startPos + endPos) / 2;
        Vector3 originOffUp = origin + Vector3.up * 5;

        for (int i = 0; i < count; ++i)
        {
            averageNormal = (averageNormal * i + listNormal[i]) / (i + 1);

            listNormal[i] = averageNormal;
            Vector3 dir = Vector3.Cross(listNormal[i], curveDir).normalized;
            Vector3 leftPos = listMidVertex[i] - dir * width;
            Vector3 rightPos = listMidVertex[i] + dir * width;

            ray = new Ray(originOffUp, leftPos - originOffUp);
            if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
            {
                listLeftVertex.Add(hitInfo.point);
            }
            else
            {
                break;
            }

            ray = new Ray(originOffUp, rightPos - originOffUp);
            if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
            {
                listRightVertex.Add(hitInfo.point);
            }
            else
            {
                break;
            }
        }

        int totalPointCount = Mathf.Min(listLeftVertex.Count, listRightVertex.Count);

        if (totalPointCount < 1)
        {
            return mesh;
        }

        Vector3[] vertices = new Vector3[totalPointCount * 2];
        Vector3[] normals = new Vector3[totalPointCount * 2];

        Vector2[] UVS = new Vector2[totalPointCount * 2];

        int[] triangles = new int[(totalPointCount - 1) * 6];

        Vector3 curveMidPos = (listMidVertex[0] + listMidVertex[listMidVertex.Count - 1]) / 2;
        meshFilter.transform.position = curveMidPos;

        //UV: 在0,1之间表示放大了图片(0.2, tmp)(0.8,tmp), 小于0, 大于1表示缩小了图片(-0.8,tmp) (1,8,tmp);
        for (int i = 0; i < totalPointCount * 2; i += 2)
        {
            vertices[i] = listLeftVertex[i / 2] - curveMidPos;
            vertices[i + 1] = listRightVertex[i / 2] - curveMidPos;

            normals[i + 1] = normals[i] = listNormal[i / 2];

            float temp = 1 - (float)(i / 2) / (float)(totalPointCount - 1);
            UVS[i] = new Vector2(0, temp);
            UVS[i + 1] = new Vector2(1, temp);
        }

        //按逆时针设置三角形中的顶点缩影,否则,就会显示在反面
        for (int i = 0; i < (totalPointCount - 1) * 6; i += 6)
        {
            triangles[i] = i / 3;
            triangles[i + 1] = triangles[i] + 2;
            triangles[i + 2] = triangles[i] + 3;

            triangles[i + 3] = triangles[i];
            triangles[i + 4] = triangles[i] + 3;
            triangles[i + 5] = triangles[i] + 1;
        }

        mesh.vertices = vertices;
        mesh.normals = normals;
        mesh.uv = UVS;
        mesh.triangles = triangles;
        return mesh;
    }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值