Ejemplo n.º 1
0
        // Create a new vertex between this vertex and `other` by linearly
        // interpolating all properties using a parameter of `t`. Subclasses should
        // override this to interpolate additional properties.
        public static CSG_Vertex Interpolate(CSG_Vertex a, CSG_Vertex b, float t)
        {
            CSG_Vertex ret = new CSG_Vertex();

            ret.position = Vector3.Lerp(a.position, b.position, t);
            ret.normal   = Vector3.Lerp(a.normal, b.normal, t);
            ret.uv       = Vector2.Lerp(a.uv, b.uv, t);
            ret.color    = (a.color + b.color) / 2f;

            return(ret);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Transform a vertex into world space.
        /// </summary>
        /// <param name="transform">The transform to apply.</param>
        /// <param name="vertex">A model space vertex.</param>
        /// <returns>A new vertex in world coordinate space.</returns>
        public static CSG_Vertex TransformVertex(this Transform transform, CSG_Vertex vertex)
        {
            var v = new CSG_Vertex();

            if (vertex.HasArrays(MeshArrays.Position))
            {
                v.position = transform.TransformPoint(vertex.position);
            }

            if (vertex.HasArrays(MeshArrays.Color))
            {
                v.color = vertex.color;
            }

            if (vertex.HasArrays(MeshArrays.Normal))
            {
                v.normal = transform.TransformDirection(vertex.normal);
            }

            if (vertex.HasArrays(MeshArrays.Tangent))
            {
                v.tangent = transform.rotation * vertex.tangent;
            }

            if (vertex.HasArrays(MeshArrays.Texture0))
            {
                v.uv0 = vertex.uv0;
            }

            if (vertex.HasArrays(MeshArrays.Texture1))
            {
                v.uv2 = vertex.uv2;
            }

            if (vertex.HasArrays(MeshArrays.Texture2))
            {
                v.uv3 = vertex.uv3;
            }

            if (vertex.HasArrays(MeshArrays.Texture3))
            {
                v.uv4 = vertex.uv4;
            }

            return(v);
        }
Ejemplo n.º 3
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, List <CSG_Polygon> front, 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 < -CSG.EPSILON) ? EPolygonType.Back : ((t > CSG.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(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);
                    }
                }

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

                if (b.Count >= 3)
                {
                    back.Add(new CSG_Polygon(b));
                }
            }
            break;
            }   // End switch(polygonType)
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Linearly interpolate between two vertices.
        /// </summary>
        /// <param name="x">Left parameter.</param>
        /// <param name="y">Right parameter.</param>
        /// <param name="weight">The weight of the interpolation. 0 is fully x, 1 is fully y.</param>
        /// <returns>A new vertex interpolated by weight between x and y.</returns>
        public static CSG_Vertex Mix(this CSG_Vertex x, CSG_Vertex y, float weight)
        {
            float i = 1f - weight;

            CSG_Vertex v = new CSG_Vertex();

            v.position = x.position * i + y.position * weight;

            if (x.hasColor && y.hasColor)
            {
                v.color = x.color * i + y.color * weight;
            }
            else if (x.hasColor)
            {
                v.color = x.color;
            }
            else if (y.hasColor)
            {
                v.color = y.color;
            }

            if (x.hasNormal && y.hasNormal)
            {
                v.normal = x.normal * i + y.normal * weight;
            }
            else if (x.hasNormal)
            {
                v.normal = x.normal;
            }
            else if (y.hasNormal)
            {
                v.normal = y.normal;
            }

            if (x.hasTangent && y.hasTangent)
            {
                v.tangent = x.tangent * i + y.tangent * weight;
            }
            else if (x.hasTangent)
            {
                v.tangent = x.tangent;
            }
            else if (y.hasTangent)
            {
                v.tangent = y.tangent;
            }

            if (x.hasUV0 && y.hasUV0)
            {
                v.uv0 = x.uv0 * i + y.uv0 * weight;
            }
            else if (x.hasUV0)
            {
                v.uv0 = x.uv0;
            }
            else if (y.hasUV0)
            {
                v.uv0 = y.uv0;
            }

            if (x.hasUV2 && y.hasUV2)
            {
                v.uv2 = x.uv2 * i + y.uv2 * weight;
            }
            else if (x.hasUV2)
            {
                v.uv2 = x.uv2;
            }
            else if (y.hasUV2)
            {
                v.uv2 = y.uv2;
            }

            if (x.hasUV3 && y.hasUV3)
            {
                v.uv3 = x.uv3 * i + y.uv3 * weight;
            }
            else if (x.hasUV3)
            {
                v.uv3 = x.uv3;
            }
            else if (y.hasUV3)
            {
                v.uv3 = y.uv3;
            }

            if (x.hasUV4 && y.hasUV4)
            {
                v.uv4 = x.uv4 * i + y.uv4 * weight;
            }
            else if (x.hasUV4)
            {
                v.uv4 = x.uv4;
            }
            else if (y.hasUV4)
            {
                v.uv4 = y.uv4;
            }

            return(v);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Replace mesh values with vertex array. Mesh is cleared during this function, so be sure to set the triangles after calling.
        /// </summary>
        /// <param name="mesh">The target mesh.</param>
        /// <param name="vertices">The vertices to replace the mesh attributes with.</param>
        public static void SetMesh(Mesh mesh, IList <CSG_Vertex> vertices)
        {
            if (mesh == null)
            {
                throw new ArgumentNullException("mesh");
            }

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

            Vector3[]      positions = null;
            Color[]        colors    = null;
            Vector2[]      uv0s      = null;
            Vector3[]      normals   = null;
            Vector4[]      tangents  = null;
            Vector2[]      uv2s      = null;
            List <Vector4> uv3s      = null;
            List <Vector4> uv4s      = null;

            GetArrays(vertices, out positions,
                      out colors,
                      out uv0s,
                      out normals,
                      out tangents,
                      out uv2s,
                      out uv3s,
                      out uv4s);

            mesh.Clear();

            CSG_Vertex first = vertices[0];

            if (first.hasPosition)
            {
                mesh.vertices = positions;
            }
            if (first.hasColor)
            {
                mesh.colors = colors;
            }
            if (first.hasUV0)
            {
                mesh.uv = uv0s;
            }
            if (first.hasNormal)
            {
                mesh.normals = normals;
            }
            if (first.hasTangent)
            {
                mesh.tangents = tangents;
            }
            if (first.hasUV2)
            {
                mesh.uv2 = uv2s;
            }
#if !UNITY_4_7 && !UNITY_5_0
            if (first.hasUV3)
            {
                if (uv3s != null)
                {
                    mesh.SetUVs(2, uv3s);
                }
            }
            if (first.hasUV4)
            {
                if (uv4s != null)
                {
                    mesh.SetUVs(3, uv4s);
                }
            }
#endif
        }
Ejemplo n.º 6
0
        public static CSG_Vertex[] GetVertices(this Mesh mesh)
        {
            if (mesh == null)
            {
                return(null);
            }

            int vertexCount = mesh.vertexCount;

            CSG_Vertex[] v = new CSG_Vertex[vertexCount];

            Vector3[]      positions = mesh.vertices;
            Color[]        colors    = mesh.colors;
            Vector3[]      normals   = mesh.normals;
            Vector4[]      tangents  = mesh.tangents;
            Vector2[]      uv0s      = mesh.uv;
            Vector2[]      uv2s      = mesh.uv2;
            List <Vector4> uv3s      = new List <Vector4>();
            List <Vector4> uv4s      = new List <Vector4>();

            mesh.GetUVs(2, uv3s);
            mesh.GetUVs(3, uv4s);

            bool _hasPositions = positions != null && positions.Length == vertexCount;
            bool _hasColors    = colors != null && colors.Length == vertexCount;
            bool _hasNormals   = normals != null && normals.Length == vertexCount;
            bool _hasTangents  = tangents != null && tangents.Length == vertexCount;
            bool _hasUv0       = uv0s != null && uv0s.Length == vertexCount;
            bool _hasUv2       = uv2s != null && uv2s.Length == vertexCount;
            bool _hasUv3       = uv3s.Count == vertexCount;
            bool _hasUv4       = uv4s.Count == vertexCount;

            for (int i = 0; i < vertexCount; i++)
            {
                v[i] = new CSG_Vertex();

                if (_hasPositions)
                {
                    v[i].position = positions[i];
                }

                if (_hasColors)
                {
                    v[i].color = colors[i];
                }

                if (_hasNormals)
                {
                    v[i].normal = normals[i];
                }

                if (_hasTangents)
                {
                    v[i].tangent = tangents[i];
                }

                if (_hasUv0)
                {
                    v[i].uv0 = uv0s[i];
                }

                if (_hasUv2)
                {
                    v[i].uv2 = uv2s[i];
                }

                if (_hasUv3)
                {
                    v[i].uv3 = uv3s[i];
                }

                if (_hasUv4)
                {
                    v[i].uv4 = uv4s[i];
                }
            }

            return(v);
        }