Ejemplo n.º 1
0
        /// <summary>
        /// Initialize a Model from a UnityEngine.Mesh and transform.
        /// </summary>
        public CSG_Model(Mesh mesh, Material[] materials, Transform transform)
        {
            if (mesh == null)
            {
                throw new ArgumentNullException("mesh");
            }

            if (transform == null)
            {
                throw new ArgumentNullException("transform");
            }

            vertices    = CSG_VertexUtility.GetVertices(mesh).Select(x => transform.TransformVertex(x)).ToList();
            m_Materials = new List <Material>(materials);
            m_Indices   = new List <List <int> >();

            for (int i = 0, c = mesh.subMeshCount; i < c; i++)
            {
                if (mesh.GetTopology(i) != MeshTopology.Triangles)
                {
                    continue;
                }
                var indices = new List <int>();
                mesh.GetIndices(indices, i);
                m_Indices.Add(indices);
            }
        }
Ejemplo n.º 2
0
        // Split `polygon` by this plane if needed, then put the polygon or polygon
        // fragments in the appropriate lists. Coplanar polygons go into either
        // `coplanarFront` or `coplanarBack` depending on their orientation with
        // respect to this plane. Polygons in front or in back of this plane go into
        // either `front` or `back`.
        public void SplitPolygon(CSG_Polygon polygon, List <CSG_Polygon> coplanarFront, List <CSG_Polygon> coplanarBack, ref List <CSG_Polygon> front, ref List <CSG_Polygon> back)
        {
            // Classify each point as well as the entire polygon into one of the above
            // four classes.
            EPolygonType        polygonType = 0;
            List <EPolygonType> types       = new List <EPolygonType>();

            for (int i = 0; i < polygon.vertices.Count; i++)
            {
                float        t    = Vector3.Dot(this.normal, polygon.vertices[i].position) - this.w;
                EPolygonType type = (t < -Boolean.k_Epsilon) ? EPolygonType.Back : ((t > Boolean.k_Epsilon) ? EPolygonType.Front : EPolygonType.Coplanar);
                polygonType |= type;
                types.Add(type);
            }

            // Put the polygon in the correct list, splitting it when necessary.
            switch (polygonType)
            {
            case EPolygonType.Coplanar:
            {
                if (Vector3.Dot(this.normal, polygon.plane.normal) > 0)
                {
                    coplanarFront.Add(polygon);
                }
                else
                {
                    coplanarBack.Add(polygon);
                }
            }
            break;

            case EPolygonType.Front:
            {
                front.Add(polygon);
            }
            break;

            case EPolygonType.Back:
            {
                back.Add(polygon);
            }
            break;

            case EPolygonType.Spanning:
            {
                List <CSG_Vertex> f = new List <CSG_Vertex>();
                List <CSG_Vertex> b = new List <CSG_Vertex>();

                for (int i = 0; i < polygon.vertices.Count; i++)
                {
                    int j = (i + 1) % polygon.vertices.Count;

                    EPolygonType ti = types[i], tj = types[j];

                    CSG_Vertex vi = polygon.vertices[i], vj = polygon.vertices[j];

                    if (ti != EPolygonType.Back)
                    {
                        f.Add(vi);
                    }
                    if (ti != EPolygonType.Front)
                    {
                        b.Add(ti != EPolygonType.Back ? vi.Clone() : vi);
                    }

                    if ((ti | tj) == EPolygonType.Spanning)
                    {
                        float t = (this.w - Vector3.Dot(this.normal, vi.position)) / Vector3.Dot(this.normal, vj.position - vi.position);

                        CSG_Vertex v = CSG_VertexUtility.Mix(vi, vj, t);

                        f.Add(v);
                        b.Add(v.Clone());
                    }
                }

                if (f.Count >= 3)
                {
                    front.Add(new CSG_Polygon(f, polygon.material));
                }

                if (b.Count >= 3)
                {
                    back.Add(new CSG_Polygon(b, polygon.material));
                }
            }
            break;
            }   // End switch(polygonType)
        }