曲面绘制Mesh

来源:互联网 发布:种族灭绝政策 知乎 编辑:程序博客网 时间:2024/05/17 03:36

在 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;    }
原创粉丝点击