unity 网格编辑

19 篇文章 0 订阅

用代码直接创建unity mesh 网格。

示例为可以不断拉长的曲形的面片。网格完成后会进行平滑插值,让曲形更加平滑。 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeshPlan : MonoBehaviour {
    // Use this for initialization
    //坐标顶点
    private List<Vector3> OrignPos;


    private MeshFilter meshFilter;


    public Transform StartPlan;
    public Transform EndPlan;

    //重新绘制的间隔距离
    public float Mid = 0.005f;


    //
    private List<Vector3> LeftPos;
    private List<Vector3> RightPos;


    public void Init()
    {
        //记录的初始位置赋值
        CurrentPos_L = EndPlan.GetChild(0).position;
        OldPos_L = CurrentPos_L;

        CurrentPos_R = EndPlan.GetChild(1).position;
        OldPos_R = CurrentPos_R;
   
        meshFilter = GetComponent<MeshFilter>();
        //初始化坐标顶点的集合
        OrignPos = new List<Vector3>();
        LeftPos = new List<Vector3>();
        RightPos = new List<Vector3>();
        for(int i = 0; i < 2; i++)
        {
            OrignPos.Add(StartPlan.GetChild(i).position);
            // print(StartPlan.GetChild(i).position);
        }
        for(int i = 0; i < 2; i++)
        {
            OrignPos.Add(EndPlan.GetChild(i).position);
            //print(EndPlan.GetChild(i).position);
        }

        GetLeftAndRightPos();
    }
    // Use this for initialization
    void Start()
    {
        Init();
       // EditorMesh();
    }
    //编辑
    public void EditorMesh()
    {
        int count = OrignPos.Count;
        int CubeNum = count / 2 - 1;
        Vector3[] newVertices = new Vector3[count];
        Vector3[] newNormals = new Vector3[count];
        int[] newTriangles = new int[CubeNum * 4 * 3];


        for(int i = 0; i < count; i++)
        {
            newVertices[i] = OrignPos[i];
        }

        #region  三角面构建
        int currentCount = 0;
        for(int i = 0; i < CubeNum; i = i + 1)
        {
            newTriangles[currentCount++] = i * 2;
            newTriangles[currentCount++] = i * 2 + 2;
            newTriangles[currentCount++] = i * 2 + 3;

            newTriangles[currentCount++] = i * 2;
            newTriangles[currentCount++] = i * 2 + 3;
            newTriangles[currentCount++] = i * 2 + 1;

            newTriangles[currentCount++] = i * 2 + 1;
            newTriangles[currentCount++] = i * 2 + 3;
            newTriangles[currentCount++] = i * 2 + 2;

            newTriangles[currentCount++] = i * 2 + 1;
            newTriangles[currentCount++] = i * 2 + 2;
            newTriangles[currentCount++] = i * 2 + 0;
        }
        #endregion
        //normal
        for(int i = 0; i < count; i++)
        {
            newNormals[i] = new Vector3(0, 1, 0);
        }

        //UV
        List<Vector2> NewUv = new List<Vector2>();
        NewUv.Add(new Vector2(0, 0));
        NewUv.Add(new Vector2(0, 1));
        for(int i = 0; i < CubeNum; i++)
        {
            NewUv.Add(new Vector2(1, 1));
            NewUv.Add(new Vector2(1, 0));
        }

        //创建网格
        Mesh mesh = new Mesh();
        meshFilter.mesh = mesh;
        mesh.vertices = newVertices;
        mesh.triangles = newTriangles;
        mesh.uv = NewUv.ToArray();
        mesh.normals = newNormals;
        //   mesh.RecalculateNormals();
    }
    void AddNewPoint()
    {
        for(int i = 0; i < 2; i++)
        {
            OrignPos.Add(EndPlan.GetChild(i).position);
        }


    }

    //偏移位置
    private Vector3 OldPos_L;
    private Vector3 CurrentPos_L;

    private Vector3 OldPos_R;
    private Vector3 CurrentPos_R;


    private void FixedUpdate()
    {
        CurrentPos_L = EndPlan.GetChild(0).position;
        CurrentPos_R = EndPlan.GetChild(1).position;

        if(Vector3.Distance(CurrentPos_L, OldPos_L) > Mid || Vector3.Distance(CurrentPos_R, OldPos_R) > Mid)
        {
            AddNewPoint();
            EditorMesh();

        }
  

        OldPos_L = CurrentPos_L;
        OldPos_R = CurrentPos_R;

    }
    private void GetLeftAndRightPos()
    {
        if(LeftPos.Count > 0)
        {
            LeftPos.Clear();
            RightPos.Clear();
        }
        for(int i = 0; i < OrignPos.Count; i++)
        {
            if(i % 2 == 0)
            {
                LeftPos.Add(OrignPos[i]);
            }
            else
            {
                RightPos.Add(OrignPos[i]);
            }

        //    print(OrignPos[i]);
        }
    }

    private void  GetAllPoint()
    {
        OrignPos.Clear();
        int count = LeftPos.Count + RightPos.Count;
      //  print("coun="+ count);
        for(int i = 0; i < count; i++)
        {
            if(i % 2 == 0)
            {
                OrignPos.Add(LeftPos[i/2]);
            }
            else
            {
               OrignPos.Add(RightPos[(i-1) / 2]);
            }
        }
      //  print("OrignPos=" + OrignPos.Count);
    }

    public void SetLerpVertices()
    {
       
        GetLeftAndRightPos();

        List<Vector3> L = LeftPos;
        List<Vector3> R = RightPos;
        int span;
        if(LeftPos.Count > 10)
            span = 10;
        else
            span = 3;
        LeftPos = SmoothPos.SmoothPoint(L, span);
        RightPos = SmoothPos.SmoothPoint(R, span);
        GetAllPoint();
        EditorMesh();
    }
    public void CutLerpVertices()
    {

        GetLeftAndRightPos();
   
        LeftPos = CutLerp(LeftPos);
        RightPos = CutLerp(RightPos);

        GetAllPoint();
        EditorMesh();
    }




    //简化删值
    private List<Vector3> CutLerp(List<Vector3> PosList)
    {
          Vector3 OldDirec;
          Vector3 CurrentDirec;
          List<Vector3> list = new List<Vector3>();
        int count = PosList.Count;
        if(count < 3)
            return PosList;
        OldDirec = PosList[1]-PosList[0];
        CurrentDirec = OldDirec;

       
        list.Add(PosList[0]);
        for(int i = 1; i < count-1; i++)
        {
            CurrentDirec = PosList[i+1] - PosList[i];
            if(Vector3.Angle(CurrentDirec, OldDirec) > 0.1f)
            {
                list.Add(PosList[i]);
               
            }
            OldDirec = CurrentDirec;
        }
        list.Add(PosList[count - 1]);
      //  print("S="+count+"  N="+list.Count);
        return list;
    }

}

  SmoothPos代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class SmoothPos : MonoBehaviour {
	// Use this for initialization
	void Start () {
    }
    public static List<Vector3> SmoothPoint(List<Vector3> list, int s)
    {
        List<Vector3> reslist = new List<Vector3>();
        int Count = list.Count;
        double[] x = new double[Count];
        double[] y = new double[Count];
        double[] z = new double[Count];

        double[] X = new double[Count];
        double[] Y = new double[Count];
        double[] Z = new double[Count];

        for(int i = 0; i < Count; i++)
        {
            x[i] = list[i].x;
            y[i] = list[i].y;
            z[i] = list[i].z;
        }
        X = MovingAverage(x, s);
        Y = MovingAverage(y, s);
        Z = MovingAverage(z, s);


        for(int i = 0; i < Count; i++)
        {
            Vector3 V = new Vector3((float)X[i],(float)Y[i],(float)Z[i]);
            reslist.Add(V);
        }

        return reslist;
    }







    public static double[] MovingAverage(double[] data, int span)
    {
        int b = 0;
        if(span % 2 == 1)
            b = (span - 1) / 2;
        else
        {
            span -= 1;
            b = (span - 1) / 2;
        }


        double[] smoothArray = new double[data.Length];
        if(data.Length > span)
        {
            for(int i = 0; i < data.Length; i++)
            {
                if(i < b)
                {
                    smoothArray[i] = 0;
                    for(int j = -i; j < i + 1; j++)
                    {
                        smoothArray[i] += data[i + j];
                    }
                    smoothArray[i] /= (2 * i + 1);
                }
                else if(i >= b && (data.Length - i) > b)
                {
                    smoothArray[i] = 0;
                    for(int j = -b; j < b + 1; j++)
                    {
                        smoothArray[i] += data[i + j];
                    }
                    smoothArray[i] /= span;
                }
                else
                {
                    smoothArray[i] = 0;
                    int c = data.Length - i - 1;
                    for(int j = -c; j < c + 1; j++)
                    {
                        smoothArray[i] += data[i + j];
                    }
                    smoothArray[i] /= (2 * c + 1);

                }
            }
        }
        else
        {
            throw new ArgumentException("span is bigger than data's count");
        }

        return smoothArray;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值