Ezyslice (Mesh切割算法) 学习笔记(未完成 待补充)

前提知识

Mesh & SharedMesh

在Mesh中存储着三维模型的数据:vertices(顶点数据数组Vector3[])、triangles(三角形顶点索引数组,int[])、normals(法线向量数组,Vector3[])、uv(纹理坐标数组,Vector2[])。

sharedMesh是公用的,是引用传递。而mesh是值传递,是各自拥有的实例。sharedMesh改变,则所有的使用到此mesh的都改变。(如果一堆meshfilter是多次clone出来的,那么sharedMesh就是一样的,改变一个的sharedMesh就会改变所有的。而mesh是那个引用在某个具体object的拷贝,改变mesh只改变当前对象。)

Mesh Filter & Mesh Render

Mesh Filter是用了一个从资源里取到的mesh资源,然后通过Mesh Render,渲染到屏幕中

什么是UV坐标

对于三维模型,有两个最重要的坐标系统,一是顶点的位置(X,Y,Z)坐标,另一个就是UV坐标。什么是UV?简单的说,就是贴图影射到模型表面的依据。 完整的说,其实应该是UVW(因为XYZ已经用过了,所以另选三个字母表示)。U和V分别是图片在显示器水平、垂直方向上的坐标,取值一般都是0~1,也 就是(水平方向的第U个像素/图片宽度,垂直方向的第V个像素/图片高度)。那W呢?贴图是二维的,何来三个坐标?嗯嗯,W的方向垂直于显示器表面,一般 用于程序贴图或者某些3D贴图技术(记住,确实有三维贴图这种概念!),对于游戏而言不常用到,所以一般我们就简称UV了。

所有的图象文件都是二维的一个平面。水平方向是U,垂直方向是V,通过这个平面的,二维的UV坐标系。我们可以定位图象上的任意一个象素。但是一个问题是如何把这个二维的平面贴到三维的NURBS表面和多边形表面呢? 对于NURBS表面。由于他本身具有UV参数,尽管这个UV值是用来定位表面上的点的参数,但由于它也是二维的,所以很容易通过换算把表面上的点和平面图象上的象素对应起来。所以把图象贴带NURBS是很直接的一件事。但是对于多变形模型来讲,贴图就变成一件麻烦的事了。所以多边形为了贴图就额外引进了一个UV坐标,以便把多边形的顶点和图象文件上的象素对应起来,这样才能在多边形表面上定位纹理贴图。所以说多边形的顶点除了具有三维的空间坐标外。还具有二维的UV坐标。

SlicedHull类

从切片操作生成的最终数据结构。这提供了方便的访问实用函数和最终的网格数据为每个部分的船体。主要是定义方法和步骤 具体实现和计算细节在其它类中

创建上片

public GameObject CreateUpperHull(GameObject original, Material crossSectionMat)//创建上、下片
public GameObject CreateLowerHull(GameObject original, Material crossSectionMat)
//在层次结构中没有改变,横截面必须与子网格一起批处理,按原样返回,不需要任何改变
if (mesh.subMeshCount == upper_hull.subMeshCount) //subMesh:返回子网格的数量。每种材料都有一个单独的三角形列表
{
    // the the material information
    newObject.GetComponent<Renderer>().sharedMaterials = shared;
	return newObject;
 }

创建空物体

private static GameObject CreateEmptyObject(string name, Mesh hull) //参数hull来自于上层物体的Mesh
{
            if (hull == null) {
                return null;
            }

            GameObject newObject = new GameObject(name);
			//Mesh Filter是用了一个从资源里取到的mesh资源,然后通过Mesh Render,渲染到屏幕中
            newObject.AddComponent<MeshRenderer>();//添加mesh渲染组件
            MeshFilter filter = newObject.AddComponent<MeshFilter>();

            filter.mesh = hull;

            return newObject;
        }

Slicer类

切割的方法在这个类中!!

crossSection:

		/**
         * 从一组交点和一个平面法线生成两个网格(上、下)截面
         */
        private static List<Triangle> CreateFrom(List<Vector3> intPoints, Vector3 planeNormal, TextureRegion region) {
            List<Triangle> tris;

            if (Triangulator.MonotoneChain(intPoints, planeNormal, out tris, region)) {
                return tris;
            }
//代码中切割部分!!!

        /**
         * 使用该平面切片gameobject mesh(如果有的话),
         * 它将生成最多2个其他网格。这个功能将重新计算新的UV坐标,
         * 以确保纹理被正确应用。如果没有找到交集,
         * 或者GameObject(游戏物体)不包含一个要切割的有效网格,则返回null。
         */
        public static SlicedHull Slice(Mesh sharedMesh, Plane pl, TextureRegion region, int crossIndex) {
            if (sharedMesh == null) {
                return null;
            }

            Vector3[] verts = sharedMesh.vertices;//顶点
            Vector2[] uv = sharedMesh.uv;//纹理
            Vector3[] norm = sharedMesh.normals;//法向量
            Vector4[] tan = sharedMesh.tangents;//获取物体的顶点切线

            int submeshCount = sharedMesh.subMeshCount;//计算出共有多少个子网格

            // 每个子网格将被切片并放置在它自己的数组结构中
            SlicedSubmesh[] slices = new SlicedSubmesh[submeshCount];
            // 船体的横截面(crossHull )在所有的子网格中都是通用的
            List<Vector3> crossHull = new List<Vector3>();

            // 我们将此对象用于所有交集测试
            IntersectionResult result = new IntersectionResult();

            // 看看我们是否要分裂网格使用uv,法线和切线
            bool genUV = verts.Length == uv.Length;
            bool genNorm = verts.Length == norm.Length;
            bool genTan = verts.Length == tan.Length;

            // iterate over all(遍历所有) the submeshes individually. vertices and indices   
            // are all shared within the submesh
            for (int submesh = 0; submesh < submeshCount; submesh++) {
                int[] indices = sharedMesh.GetTriangles(submesh);
                int indicesCount = indices.Length;

                SlicedSubmesh mesh = new SlicedSubmesh();

                // loop through all the mesh vertices, generating upper and lower hulls
                // and all intersection points
                for (int index = 0; index < indicesCount; index += 3) {
                    int i0 = indices[index + 0];
                    int i1 = indices[index + 1];
                    int i2 = indices[index + 2];
					//**triangle()函数 用于初始化三角矩阵 除了顶点值外 全部赋值0
                    Triangle newTri = new Triangle(verts[i0], verts[i1], verts[i2]);

                    // generate UV if available
                    if (genUV) {
                        newTri.SetUV(uv[i0], uv[i1], uv[i2]);
                    }

                    // generate normals if available
                    if (genNorm) {
                        newTri.SetNormal(norm[i0], norm[i1], norm[i2]);
                    }

                    // generate tangents if available
                    if (genTan) {
                        newTri.SetTangent(tan[i0], tan[i1], tan[i2]);
                    }

                    // slice this particular triangle with the provided
                    // plane
                    if (newTri.Split(pl, result)) {
                        int upperHullCount = result.upperHullCount;
                        int lowerHullCount = result.lowerHullCount;
                        int interHullCount = result.intersectionPointCount;

                        for (int i = 0; i < upperHullCount; i++) {
                            mesh.upperHull.Add(result.upperHull[i]);
                        }

                        for (int i = 0; i < lowerHullCount; i++) {
                            mesh.lowerHull.Add(result.lowerHull[i]);
                        }

                        for (int i = 0; i < interHullCount; i++) {
                            crossHull.Add(result.intersectionPoints[i]);
                        }
                    } else {
                        SideOfPlane side = pl.SideOf(verts[i0]);

                        if (side == SideOfPlane.UP || side == SideOfPlane.ON) {
                            mesh.upperHull.Add(newTri);
                        } else {
                            mesh.lowerHull.Add(newTri);
                        }
                    }
                }

                // register into the index
                slices[submesh] = mesh;
            }

            // check if slicing actually occured
            for (int i = 0; i < slices.Length; i++) {
                // check if at least one of the submeshes was sliced. If so, stop checking
                // because we need to go through the generation step
                if (slices[i] != null && slices[i].isValid) {
                    return CreateFrom(slices, CreateFrom(crossHull, pl.normal, region), crossIndex);
                }
            }

            // no slicing occured, just return null to signify
            return null;
        }

        /**
         * Generates a single SlicedHull from a set of cut submeshes 
         */
        private static SlicedHull CreateFrom(SlicedSubmesh[] meshes, List<Triangle> cross, int crossSectionIndex)
        {//Triangle依赖Framework文件夹
            int submeshCount = meshes.Length;

            int upperHullCount = 0;
            int lowerHullCount = 0;

            // get the total amount of upper, lower and intersection counts
            for (int submesh = 0; submesh < submeshCount; submesh++) {
                upperHullCount += meshes[submesh].upperHull.Count;
                lowerHullCount += meshes[submesh].lowerHull.Count;
            }

            Mesh upperHull = CreateUpperHull(meshes, upperHullCount, cross, crossSectionIndex);
            Mesh lowerHull = CreateLowerHull(meshes, lowerHullCount, cross, crossSectionIndex);

            return new SlicedHull(upperHull, lowerHull);
        }

        private static Mesh CreateUpperHull(SlicedSubmesh[] mesh, int total, List<Triangle> crossSection, int crossSectionIndex) {
            return CreateHull(mesh, total, crossSection, crossSectionIndex, true);
        }

        private static Mesh CreateLowerHull(SlicedSubmesh[] mesh, int total, List<Triangle> crossSection, int crossSectionIndex) {
            return CreateHull(mesh, total, crossSection, crossSectionIndex, false);
        }

Intersector 类

Intersect函数 共有两个重载

        /**
        * 执行平面p1与直线ab的交叉操作 有交点返回true 反之false
        * 其中交叉点将存于vector3数组 q中(out型可直接被接收并使用)
        */
        public static bool Intersect(Plane pl, Vector3 a, Vector3 b, out Vector3 q) {
            Vector3 normal = pl.normal;
            Vector3 ab = b - a;//得到ab直线所在向量

            float t = (pl.dist - Vector3.Dot(normal, a)) / Vector3.Dot(normal, ab);

            // need to be careful and compensate for floating errors
            if (t >= -float.Epsilon && t <= (1 + float.Epsilon)) {=
                q = a + t * ab;

                return true;
            }

            q = Vector3.zero;//结束时消除数据 全置0

            return false;
        }

//第二个Intersect函数 其中调用第一个Intersect函数

public static void Intersect(Plane pl, Triangle tri, IntersectionResult result) {
            // clear the previous results from the IntersectionResult
            result.Clear();

            // grab local variables for easier access
            //获取本地变量以方便访问
            Vector3 a = tri.positionA;
            Vector3 b = tri.positionB;
            Vector3 c = tri.positionC;

            /*
             * 检查a点在平面的哪一边。SideOf操作是一个简单的点积和一些比较操作,所以这些是非常快速的检查
             * check to see which side of the plane the points all 
             * lay in. SideOf operation is a simple dot product and some comparison
             * operations, so these are a very quick checks
             */
            SideOfPlane sa = pl.SideOf(a);//检查a点在平面的哪一边(三种结果 UP DOWN ON)
            SideOfPlane sb = pl.SideOf(b);
            SideOfPlane sc = pl.SideOf(c);
            //其数学原理??(待看)
            // we cannot intersect if the triangle points all fall on the same side
            // of the plane. This is an easy early out test as no intersections are possible.
            if (sa == sb && sb == sc) {//均在同一侧 -->不切
                return;
            }

            // detect cases where two points lay straight on the plane, meaning
            // that the plane is actually parralel with one of the edges of the triangle
            else if ((sa == SideOfPlane.ON && sa == sb) ||
                (sa == SideOfPlane.ON && sa == sc) ||
                (sb == SideOfPlane.ON && sb == sc))
            {//一个点在平面上 其余两个点在同侧 -->不切
                return;
            }

            /* keep in mind that intersection points are shared by both
            * the upper HULL and lower HULL hence they lie perfectly
            * on the plane that cut them
            * 切割点/交点 正位于切割平面 且上下两个Hull共享它
            */
            Vector3 qa;
            Vector3 qb;

            // check the cases where the points of the triangle actually lie on the plane itself
            // in these cases, there is only going to be 2 triangles, one for the upper HULL and
            // the other on the lower HULL
            // we just need to figure out which points to accept into the upper or lower hulls.
            //找出上下Hull中的点各是那些点!!(重要)-->对顶点分类
            if (sa == SideOfPlane.ON) {
                // if the point a is on the plane, test line b-c
                if (Intersector.Intersect(pl, b, c, out qa))
                {//调用上面Intersect的Intersect函数 -->若有交点则运行接下来的步骤 并将交点存储于qa
                    // line b-c intersected, construct out triangles and return approprietly
                    result.AddIntersectionPoint(qa);//加入数组(vector3类型)
                    result.AddIntersectionPoint(a);

                    // our two generated triangles, we need to figure out which
                    // triangle goes into the UPPER hull and which goes into the LOWER hull
                    Triangle ta = new Triangle(a, b, qa);//创建三角
                    Triangle tb = new Triangle(a, qa, c);

                    // generate UV coordinates if there is any
                    if (tri.hasUV) {
                        // the computed UV coordinate if the intersection point(交点)
                        Vector2 pq = tri.GenerateUV(qa);
                        Vector2 pa = tri.uvA;
                        Vector2 pb = tri.uvB;
                        Vector2 pc = tri.uvC;

                        ta.SetUV(pa, pb, pq);
                        tb.SetUV(pa, pq, pc);
                    }

                    // generate Normal coordinates if there is any
                    if (tri.hasNormal) {
                        // the computed Normal coordinate if the intersection point
                        Vector3 pq = tri.GenerateNormal(qa);
                        Vector3 pa = tri.normalA;
                        Vector3 pb = tri.normalB;
                        Vector3 pc = tri.normalC;

                        ta.SetNormal(pa, pb, pq);
                        tb.SetNormal(pa, pq, pc);
                    }

                    // generate Tangent coordinates if there is any
                    if (tri.hasTangent) {
                        // the computed Tangent coordinate if the intersection point
                        Vector4 pq = tri.GenerateTangent(qa);
                        Vector4 pa = tri.tangentA;
                        Vector4 pb = tri.tangentB;
                        Vector4 pc = tri.tangentC;

                        ta.SetTangent(pa, pb, pq);
                        tb.SetTangent(pa, pq, pc);
                    }

                    // b point lies on the upside of the plane
                    if (sb == SideOfPlane.UP) {
                        result.AddUpperHull(ta).AddLowerHull(tb);
                    }

                    // b point lies on the downside of the plane
                    else if (sb == SideOfPlane.DOWN) {
                        result.AddUpperHull(tb).AddLowerHull(ta);
                    }
                }
            }

            // test the case where the b point lies on the plane itself
            else if (sb == SideOfPlane.ON) {
                // if the point b is on the plane, test line a-c
                if (Intersector.Intersect(pl, a, c, out qa)) {
                    // line a-c intersected, construct out triangles and return approprietly
                    result.AddIntersectionPoint(qa);
                    result.AddIntersectionPoint(b);

                    // our two generated triangles, we need to figure out which
                    // triangle goes into the UPPER hull and which goes into the LOWER hull
                    Triangle ta = new Triangle(a, b, qa);
                    Triangle tb = new Triangle(qa, b, c);

                    // generate UV coordinates if there is any
                    if (tri.hasUV) {
                        // the computed UV coordinate if the intersection point
                        Vector2 pq = tri.GenerateUV(qa);
                        Vector2 pa = tri.uvA;
                        Vector2 pb = tri.uvB;
                        Vector2 pc = tri.uvC;

                        ta.SetUV(pa, pb, pq);
                        tb.SetUV(pq, pb, pc);
                    }

                    // generate Normal coordinates if there is any
                    if (tri.hasNormal) {
                        // the computed Normal coordinate if the intersection point
                        Vector3 pq = tri.GenerateNormal(qa);
                        Vector3 pa = tri.normalA;
                        Vector3 pb = tri.normalB;
                        Vector3 pc = tri.normalC;

                        ta.SetNormal(pa, pb, pq);
                        tb.SetNormal(pq, pb, pc);
                    }

                    // generate Tangent coordinates if there is any
                    if (tri.hasTangent) {
                        // the computed Tangent coordinate if the intersection point
                        Vector4 pq = tri.GenerateTangent(qa);
                        Vector4 pa = tri.tangentA;
                        Vector4 pb = tri.tangentB;
                        Vector4 pc = tri.tangentC;

                        ta.SetTangent(pa, pb, pq);
                        tb.SetTangent(pq, pb, pc);
                    }

                    // a point lies on the upside of the plane
                    if (sa == SideOfPlane.UP) {
                        result.AddUpperHull(ta).AddLowerHull(tb);
                    }

                    // a point lies on the downside of the plane
                    else if (sa == SideOfPlane.DOWN) {
                        result.AddUpperHull(tb).AddLowerHull(ta);
                    }
                }
            }

            // test the case where the c point lies on the plane itself
            else if (sc == SideOfPlane.ON) {
                // if the point c is on the plane, test line a-b
                if (Intersector.Intersect(pl, a, b, out qa)) {
                    // line a-c intersected, construct out triangles and return approprietly
                    result.AddIntersectionPoint(qa);
                    result.AddIntersectionPoint(c);

                    // our two generated triangles, we need to figure out which
                    // triangle goes into the UPPER hull and which goes into the LOWER hull
                    Triangle ta = new Triangle(a, qa, c);
                    Triangle tb = new Triangle(qa, b, c);

                    // generate UV coordinates if there is any
                    if (tri.hasUV) {
                        // the computed UV coordinate if the intersection point
                        Vector2 pq = tri.GenerateUV(qa);
                        Vector2 pa = tri.uvA;
                        Vector2 pb = tri.uvB;
                        Vector2 pc = tri.uvC;

                        ta.SetUV(pa, pq, pc);
                        tb.SetUV(pq, pb, pc);
                    }

                    // generate Normal coordinates if there is any
                    if (tri.hasNormal) {
                        // the computed Normal coordinate if the intersection point
                        Vector3 pq = tri.GenerateNormal(qa);
                        Vector3 pa = tri.normalA;
                        Vector3 pb = tri.normalB;
                        Vector3 pc = tri.normalC;

                        ta.SetNormal(pa, pq, pc);
                        tb.SetNormal(pq, pb, pc);
                    }

                    // generate Tangent coordinates if there is any
                    if (tri.hasTangent) {
                        // the computed Tangent coordinate if the intersection point
                        Vector4 pq = tri.GenerateTangent(qa);
                        Vector4 pa = tri.tangentA;
                        Vector4 pb = tri.tangentB;
                        Vector4 pc = tri.tangentC;

                        ta.SetTangent(pa, pq, pc);
                        tb.SetTangent(pq, pb, pc);
                    }

                    // a point lies on the upside of the plane
                    if (sa == SideOfPlane.UP) {
                        result.AddUpperHull(ta).AddLowerHull(tb);
                    }

                    // a point lies on the downside of the plane
                    else if (sa == SideOfPlane.DOWN) {
                        result.AddUpperHull(tb).AddLowerHull(ta);
                    }
                }
            }

            // at this point, all edge cases have been tested and failed, we need to perform
            // full intersection tests against the lines. From this point onwards we will generate
            // 3 triangles
            else if (sa != sb && Intersector.Intersect(pl, a, b, out qa)) {
                // intersection found against a - b
                result.AddIntersectionPoint(qa);

                // since intersection was found against a - b, we need to check which other
                // lines to check (we only need to check one more line) for intersection.
                // the line we check against will be the line against the point which lies on
                // the other side of the plane.
                if (sa == sc) {
                    // we likely have an intersection against line b-c which will complete this loop
                    if (Intersector.Intersect(pl, b, c, out qb)) {
                        result.AddIntersectionPoint(qb);

                        // our three generated triangles. Two of these triangles will end
                        // up on either the UPPER or LOWER hulls.
                        Triangle ta = new Triangle(qa, b, qb);
                        Triangle tb = new Triangle(a, qa, qb);
                        Triangle tc = new Triangle(a, qb, c);

                        // generate UV coordinates if there is any
                        if (tri.hasUV) {
                            // the computed UV coordinate if the intersection point
                            Vector2 pqa = tri.GenerateUV(qa);
                            Vector2 pqb = tri.GenerateUV(qb);
                            Vector2 pa = tri.uvA;
                            Vector2 pb = tri.uvB;
                            Vector2 pc = tri.uvC;

                            ta.SetUV(pqa, pb, pqb);
                            tb.SetUV(pa, pqa, pqb);
                            tc.SetUV(pa, pqb, pc);
                        }

                        // generate Normal coordinates if there is any
                        if (tri.hasNormal) {
                            // the computed Normal coordinate if the intersection point
                            Vector3 pqa = tri.GenerateNormal(qa);
                            Vector3 pqb = tri.GenerateNormal(qb);
                            Vector3 pa = tri.normalA;
                            Vector3 pb = tri.normalB;
                            Vector3 pc = tri.normalC;

                            ta.SetNormal(pqa, pb, pqb);
                            tb.SetNormal(pa, pqa, pqb);
                            tc.SetNormal(pa, pqb, pc);
                        }

                        // generate Tangent coordinates if there is any
                        if (tri.hasTangent) {
                            // the computed Tangent coordinate if the intersection point
                            Vector4 pqa = tri.GenerateTangent(qa);
                            Vector4 pqb = tri.GenerateTangent(qb);
                            Vector4 pa = tri.tangentA;
                            Vector4 pb = tri.tangentB;
                            Vector4 pc = tri.tangentC;

                            ta.SetTangent(pqa, pb, pqb);
                            tb.SetTangent(pa, pqa, pqb);
                            tc.SetTangent(pa, pqb, pc);
                        }

                        if (sa == SideOfPlane.UP) {
                            result.AddUpperHull(tb).AddUpperHull(tc).AddLowerHull(ta);
                        } else {
                            result.AddLowerHull(tb).AddLowerHull(tc).AddUpperHull(ta);
                        }
                    }
                } else {
                    // in this scenario, the point a is a "lone" point which lies in either upper
                    // or lower HULL. We need to perform another intersection to find the last point
                    if (Intersector.Intersect(pl, a, c, out qb)) {
                        result.AddIntersectionPoint(qb);

                        // our three generated triangles. Two of these triangles will end
                        // up on either the UPPER or LOWER hulls.
                        Triangle ta = new Triangle(a, qa, qb);
                        Triangle tb = new Triangle(qa, b, c);
                        Triangle tc = new Triangle(qb, qa, c);

                        // generate UV coordinates if there is any
                        if (tri.hasUV) {
                            // the computed UV coordinate if the intersection point
                            Vector2 pqa = tri.GenerateUV(qa);
                            Vector2 pqb = tri.GenerateUV(qb);
                            Vector2 pa = tri.uvA;
                            Vector2 pb = tri.uvB;
                            Vector2 pc = tri.uvC;

                            ta.SetUV(pa, pqa, pqb);
                            tb.SetUV(pqa, pb, pc);
                            tc.SetUV(pqb, pqa, pc);
                        }

                        // generate Normal coordinates if there is any
                        if (tri.hasNormal) {
                            // the computed Normal coordinate if the intersection point
                            Vector3 pqa = tri.GenerateNormal(qa);
                            Vector3 pqb = tri.GenerateNormal(qb);
                            Vector3 pa = tri.normalA;
                            Vector3 pb = tri.normalB;
                            Vector3 pc = tri.normalC;

                            ta.SetNormal(pa, pqa, pqb);
                            tb.SetNormal(pqa, pb, pc);
                            tc.SetNormal(pqb, pqa, pc);
                        }

                        // generate Tangent coordinates if there is any
                        if (tri.hasTangent) {
                            // the computed Tangent coordinate if the intersection point
                            Vector4 pqa = tri.GenerateTangent(qa);
                            Vector4 pqb = tri.GenerateTangent(qb);
                            Vector4 pa = tri.tangentA;
                            Vector4 pb = tri.tangentB;
                            Vector4 pc = tri.tangentC;

                            ta.SetTangent(pa, pqa, pqb);
                            tb.SetTangent(pqa, pb, pc);
                            tc.SetTangent(pqb, pqa, pc);
                        }

                        if (sa == SideOfPlane.UP) {
                            result.AddUpperHull(ta).AddLowerHull(tb).AddLowerHull(tc);
                        } else {
                            result.AddLowerHull(ta).AddUpperHull(tb).AddUpperHull(tc);
                        }
                    }
                }
            }

            // if line a-b did not intersect (or the lie on the same side of the plane)
            // this simplifies the problem a fair bit. This means we have an intersection 
            // in line a-c and b-c, which we can use to build a new UPPER and LOWER hulls
            // we are expecting both of these intersection tests to pass, otherwise something
            // went wrong (float errors? missed a checked case?)
            else if (Intersector.Intersect(pl, c, a, out qa) && Intersector.Intersect(pl, c, b, out qb)) {
                // in here we know that line a-b actually lie on the same side of the plane, this will
                // simplify the rest of the logic. We also have our intersection points
                // the computed UV coordinate of the intersection point

                result.AddIntersectionPoint(qa);
                result.AddIntersectionPoint(qb);

                // our three generated triangles. Two of these triangles will end
                // up on either the UPPER or LOWER hulls.
                Triangle ta = new Triangle(qa, qb, c);
                Triangle tb = new Triangle(a, qb, qa);
                Triangle tc = new Triangle(a, b, qb);

                // generate UV coordinates if there is any
                if (tri.hasUV) {
                    // the computed UV coordinate if the intersection point
                    Vector2 pqa = tri.GenerateUV(qa);
                    Vector2 pqb = tri.GenerateUV(qb);
                    Vector2 pa = tri.uvA;
                    Vector2 pb = tri.uvB;
                    Vector2 pc = tri.uvC;

                    ta.SetUV(pqa, pqb, pc);
                    tb.SetUV(pa, pqb, pqa);
                    tc.SetUV(pa, pb, pqb);
                }

                // generate Normal coordinates if there is any
                if (tri.hasNormal) {
                    // the computed Normal coordinate if the intersection point
                    Vector3 pqa = tri.GenerateNormal(qa);
                    Vector3 pqb = tri.GenerateNormal(qb);
                    Vector3 pa = tri.normalA;
                    Vector3 pb = tri.normalB;
                    Vector3 pc = tri.normalC;

                    ta.SetNormal(pqa, pqb, pc);
                    tb.SetNormal(pa, pqb, pqa);
                    tc.SetNormal(pa, pb, pqb);
                }

                // generate Tangent coordinates if there is any
                if (tri.hasTangent) {
                    // the computed Tangent coordinate if the intersection point
                    Vector4 pqa = tri.GenerateTangent(qa);
                    Vector4 pqb = tri.GenerateTangent(qb);
                    Vector4 pa = tri.tangentA;
                    Vector4 pb = tri.tangentB;
                    Vector4 pc = tri.tangentC;

                    ta.SetTangent(pqa, pqb, pc);
                    tb.SetTangent(pa, pqb, pqa);
                    tc.SetTangent(pa, pb, pqb);
                }

                if (sa == SideOfPlane.UP) {
                    result.AddUpperHull(tb).AddUpperHull(tc).AddLowerHull(ta);
                } else {
                    result.AddLowerHull(tb).AddLowerHull(tc).AddUpperHull(ta);
                }
            }
        }
发布了15 篇原创文章 · 获赞 14 · 访问量 575
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览