Unity模型加面算法实验

通常项目中为了游戏运行的顺畅会对模型进行相应的减面操作,但也有特例。这次就研究下给模型加面,尤其是给模型水平方向加面,类似于水平切割模型。 一般的加面算法,是在三角形内部取各条线的中点连接成新三角进行加面。
如下图:
在这里插入图片描述
项目中实现如下:
在这里插入图片描述
但项目中需要始终水平切割三角面的线,此种加面方法不太可行,只能另找方法。
在这里插入图片描述
主要思路是考虑切割线与三角形的位置关系,先获取某一面的所有三角形,然后通过切割线进行位置比较最后再进行切割三角形。
首先几种情况下无需进行分割:
在这里插入图片描述
需要进行切割的情况如下:
在这里插入图片描述
逐个分析下,第一种是切割线过三角形的某一点并且和另两点所成线段相交。 第二种是切割线不经过任一点且与三角形两条边相交。
第一种:原本的三角形序列为 abc,经过切割线切割后得到bda 和 dca两个三角形。
第二种:原本的三角形序列为 abc,经过切割线切割后得到bda、dea和dce三个三角形。
处理数据时加入新的三角形序列,同时删除掉原有的三角形即可。下面以一个面为例实验:

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

public class MeshSubdivide : MonoBehaviour
{
   
    private List<Vector3> vertices;
    private List<Vector3> normals;
    private List<Color> colors;
    private List<Vector2> uv;
    private List<Vector2> uv1;
    private List<Vector2> uv2;
    private List<int> trangles;

    private MeshFilter meshfilter;
    private List<Vector3> inVertices = new List<Vector3>();
    /// <summary>
    /// 所有三角面的索引列表
    /// </summary>
    private List<Vector3> trianglesIndexList = new List<Vector3>();
    private List<Vector3> inIndexList = new List<Vector3>();

    void Start()
    {
   
        meshfilter = GetComponent<MeshFilter>();

        StartSubdivide(meshfilter.mesh);
    }


    private void InitArrays(Mesh mesh)
    {
   
        vertices = new List<Vector3>(mesh.vertices);
        normals = new List<Vector3>(mesh.normals);
        colors = new List<Color>(mesh.colors);
        uv = new List<Vector2>(mesh.uv);
        uv1 = new List<Vector2>(mesh.uv2);
        uv2 = new List<Vector2>(mesh.uv2);
        trangles = new List<int>();
    }

    private void CleanUp()
    {
   
        vertices = null;
        normals = null;
        colors = null;
        uv = null;
        uv1 = null;
        uv2 = null;
    }

    #region Subdivide4 (2x2)
    private int GetNewVertex4(int i1, int i2, float rate)
    {
   
        int newIndex = vertices.Count;
        //vertices.Add((vertices[i1] + vertices[i2]) * rate);
        if (normals.Count > 0)
            normals.Add((normals[i1] + normals[i2]).normalized);
        if (colors.Count > 0)
            colors.Add((colors[i1] + colors[i2]) * rate);
        if (uv.Count > 0)
            uv.Add((uv[i1] + uv[i2]) * rate);
        if (uv1.Count > 0)
            uv1.Add((uv1[i1] + uv1[i2]) * rate);
        if (uv2.Count > 0)
            uv2.Add((uv2[i1] + uv2[i2]) * rate);

        return newIndex;
    }


    /// <summary>
    /// 横向加面算法
    /// </summary>
    /// <param name="mesh"></param>
    public void StartSubdivide(Mesh mesh)
    {
   
        //初始化Mesh信息
        InitArrays(mesh);
        //获得最外层顶点序列
        GetInVertices();
        //获得初始三角形序列
        GetInitTriangles(mesh);
        //开始切割增加三角形
        StartSliceAddTriangles();

        mesh.vertices = vertices.ToArray();
        if (normals.Count > 0)
            mesh.normals = normals.ToArray();
        if (colors.Count > 0)
            mesh.colors = colors.ToArray();
        if (uv.Count 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值