using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Collections.ObjectModel;
using System.Text;
namespace UnityEngine.ProBuilder
{
///
/// Holds information about a single vertex, and provides methods for averaging between multiple Vertex objects.
///
/// All values are optional; however, ProBuilder can use default values if necessary.
[Serializable]
public sealed class Vertex : IEquatable
{
[SerializeField]
Vector3 m_Position;
[SerializeField]
Color m_Color;
[SerializeField]
Vector3 m_Normal;
[SerializeField]
Vector4 m_Tangent;
[SerializeField]
Vector2 m_UV0;
[SerializeField]
Vector2 m_UV2;
[SerializeField]
Vector4 m_UV3;
[SerializeField]
Vector4 m_UV4;
[SerializeField]
MeshArrays m_Attributes;
///
/// Gets or sets the position in local space.
///
/// The position in local space.
///
public Vector3 position
{
get { return m_Position; }
set
{
hasPosition = true;
m_Position = value;
}
}
///
/// Gets or sets the [vertex color](../manual/workflow-vertexcolors.html).
///
/// The color applied to this vertex.
///
///
public Color color
{
get { return m_Color; }
set
{
hasColor = true;
m_Color = value;
}
}
///
/// Gets or sets the unit vector normal.
///
/// The unit vector normal.
///
public Vector3 normal
{
get { return m_Normal; }
set
{
hasNormal = true;
m_Normal = value;
}
}
///
/// Gets or sets the vertex tangent (sometimes called binormal).
///
/// The vertex tangent.
///
public Vector4 tangent
{
get { return m_Tangent; }
set
{
hasTangent = true;
m_Tangent = value;
}
}
///
/// Gets or sets the UV0 channel. Also called texture UVs.
///
/// The UV0 channel.
///
///
public Vector2 uv0
{
get { return m_UV0; }
set
{
hasUV0 = true;
m_UV0 = value;
}
}
///
/// Gets or sets the UV2 channel.
///
/// The UV2 channel.
///
public Vector2 uv2
{
get { return m_UV2; }
set
{
hasUV2 = true;
m_UV2 = value;
}
}
///
/// Gets or sets the UV3 channel.
///
/// The UV3 channel.
///
public Vector4 uv3
{
get { return m_UV3; }
set
{
hasUV3 = true;
m_UV3 = value;
}
}
///
/// Gets or sets the UV4 channel.
///
/// The UV4 channel.
///
public Vector4 uv4
{
get { return m_UV4; }
set
{
hasUV4 = true;
m_UV4 = value;
}
}
internal MeshArrays attributes
{
get { return m_Attributes; }
}
///
/// Tests whether the specified vertex attribute has been set.
///
/// An array containing one or more attribute(s) to find.
/// True if this vertex has the specified attributes set; false if they are default values.
public bool HasArrays(MeshArrays attribute)
{
return (m_Attributes & attribute) == attribute;
}
bool hasPosition
{
get { return (m_Attributes & MeshArrays.Position) == MeshArrays.Position; }
set { m_Attributes = value ? (m_Attributes | MeshArrays.Position) : (m_Attributes & ~(MeshArrays.Position)); }
}
bool hasColor
{
get { return (m_Attributes & MeshArrays.Color) == MeshArrays.Color; }
set { m_Attributes = value ? (m_Attributes | MeshArrays.Color) : (m_Attributes & ~(MeshArrays.Color)); }
}
bool hasNormal
{
get { return (m_Attributes & MeshArrays.Normal) == MeshArrays.Normal; }
set { m_Attributes = value ? (m_Attributes | MeshArrays.Normal) : (m_Attributes & ~(MeshArrays.Normal)); }
}
bool hasTangent
{
get { return (m_Attributes & MeshArrays.Tangent) == MeshArrays.Tangent; }
set { m_Attributes = value ? (m_Attributes | MeshArrays.Tangent) : (m_Attributes & ~(MeshArrays.Tangent)); }
}
bool hasUV0
{
get { return (m_Attributes & MeshArrays.Texture0) == MeshArrays.Texture0; }
set { m_Attributes = value ? (m_Attributes | MeshArrays.Texture0) : (m_Attributes & ~(MeshArrays.Texture0)); }
}
bool hasUV2
{
get { return (m_Attributes & MeshArrays.Texture1) == MeshArrays.Texture1; }
set { m_Attributes = value ? (m_Attributes | MeshArrays.Texture1) : (m_Attributes & ~(MeshArrays.Texture1)); }
}
bool hasUV3
{
get { return (m_Attributes & MeshArrays.Texture2) == MeshArrays.Texture2; }
set { m_Attributes = value ? (m_Attributes | MeshArrays.Texture2) : (m_Attributes & ~(MeshArrays.Texture2)); }
}
bool hasUV4
{
get { return (m_Attributes & MeshArrays.Texture3) == MeshArrays.Texture3; }
set { m_Attributes = value ? (m_Attributes | MeshArrays.Texture3) : (m_Attributes & ~(MeshArrays.Texture3)); }
}
///
/// Initializes a Vertex with no values.
///
public Vertex()
{
}
///
/// Determines whether the specified generic object is equal to this Vertex.
///
/// The object to compare this Vertex object to.
/// True if the other object is a Vertex and is equal to this.
public override bool Equals(object obj)
{
return obj is Vertex && Equals((Vertex)obj);
}
///
/// Determines whether the specified Vertex object is equal to this Vertex by checking whether all
/// components are within a certain distance of the other.
///
/// The other Vertex to compare to.
/// True if all values are the same (within float.Epsilon).
public bool Equals(Vertex other)
{
if (ReferenceEquals(other, null))
return false;
return Math.Approx3(m_Position, other.m_Position) &&
Math.ApproxC(m_Color, other.m_Color) &&
Math.Approx3(m_Normal, other.m_Normal) &&
Math.Approx4(m_Tangent, other.m_Tangent) &&
Math.Approx2(m_UV0, other.m_UV0) &&
Math.Approx2(m_UV2, other.m_UV2) &&
Math.Approx4(m_UV3, other.m_UV3) &&
Math.Approx4(m_UV4, other.m_UV4);
}
///
/// Determines whether the specified Vertex object is equal to this Vertex by checking whether each
/// component for a specific set of attributes is within a certain distance of the other. The MeshArrays
/// `mask` determines which set of attributes to compare.
///
/// The other Vertex to compare to.
/// A bitmask that defines which attributes to compare.
/// True if all values are the same (within float.Epsilon).
public bool Equals(Vertex other, MeshArrays mask)
{
if (ReferenceEquals(other, null))
return false;
return ((mask & MeshArrays.Position) != MeshArrays.Position || Math.Approx3(m_Position, other.m_Position)) &&
((mask & MeshArrays.Color) != MeshArrays.Color || Math.ApproxC(m_Color, other.m_Color)) &&
((mask & MeshArrays.Normal) != MeshArrays.Normal || Math.Approx3(m_Normal, other.m_Normal)) &&
((mask & MeshArrays.Tangent) != MeshArrays.Tangent || Math.Approx4(m_Tangent, other.m_Tangent)) &&
((mask & MeshArrays.Texture0) != MeshArrays.Texture0 || Math.Approx2(m_UV0, other.m_UV0)) &&
((mask & MeshArrays.Texture1) != MeshArrays.Texture1 || Math.Approx2(m_UV2, other.m_UV2)) &&
((mask & MeshArrays.Texture2) != MeshArrays.Texture2 || Math.Approx4(m_UV3, other.m_UV3)) &&
((mask & MeshArrays.Texture3) != MeshArrays.Texture3 || Math.Approx4(m_UV4, other.m_UV4));
}
///
/// Creates a new hashcode from this Vertex's position, UV0, and normal.
///
/// A hashcode for this object.
public override int GetHashCode()
{
// 783 is 27 * 29
unchecked
{
int hash = 783 + VectorHash.GetHashCode(position);
hash = hash * 29 + VectorHash.GetHashCode(uv0);
hash = hash * 31 + VectorHash.GetHashCode(normal);
return hash;
}
}
///
/// Creates a new Vertex object as a copy of another Vertex object.
///
/// The Vertex to copy field data from.
public Vertex(Vertex vertex)
{
if (vertex == null)
throw new ArgumentNullException("vertex");
m_Position = vertex.m_Position;
hasPosition = vertex.hasPosition;
m_Color = vertex.m_Color;
hasColor = vertex.hasColor;
m_UV0 = vertex.m_UV0;
hasUV0 = vertex.hasUV0;
m_Normal = vertex.m_Normal;
hasNormal = vertex.hasNormal;
m_Tangent = vertex.m_Tangent;
hasTangent = vertex.hasTangent;
m_UV2 = vertex.m_UV2;
hasUV2 = vertex.hasUV2;
m_UV3 = vertex.m_UV3;
hasUV3 = vertex.hasUV3;
m_UV4 = vertex.m_UV4;
hasUV4 = vertex.hasUV4;
}
///
/// Determines whether the specified Vertex is equal to this one.
///
/// Left operand.
/// Right operand.
/// True if `a` equals `b`.
public static bool operator==(Vertex a, Vertex b)
{
if (ReferenceEquals(a, b))
return true;
if (object.ReferenceEquals(a, null) || object.ReferenceEquals(b, null))
return false;
return a.Equals(b);
}
///
/// Determines whether the specified Vertex is not equal to this one.
///
/// Left operand.
/// Right operand.
/// True if `a` does not equal `b`.
public static bool operator!=(Vertex a, Vertex b)
{
return !(a == b);
}
///
/// Adds two Vertex objects together and returns the result in a new Vertex object.
/// Addition is performed component-wise for every attribute on the Vertex.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// Left operand.
/// Right operand.
/// A new Vertex with the sum of `a` + `b`.
public static Vertex operator+(Vertex a, Vertex b)
{
return Add(a, b);
}
///
/// Adds two Vertex objects together and returns the result in a new Vertex object.
/// Addition is performed component-wise for every attribute on the Vertex.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// First Vertex object.
/// Second Vertex object.
/// A new Vertex with the sum of `a` + `b`.
public static Vertex Add(Vertex a, Vertex b)
{
Vertex v = new Vertex(a);
v.Add(b);
return v;
}
///
/// Adds another Vertex object to this one using component-wise addition on each attribute.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// The Vertex object to add.
public void Add(Vertex b)
{
if (b == null)
throw new ArgumentNullException("b");
m_Position += b.m_Position;
m_Color += b.m_Color;
m_Normal += b.m_Normal;
m_Tangent += b.m_Tangent;
m_UV0 += b.m_UV0;
m_UV2 += b.m_UV2;
m_UV3 += b.m_UV3;
m_UV4 += b.m_UV4;
}
///
/// Subtracts two Vertex objects and returns the result in a new Vertex object.
/// Subtraction is performed component-wise for every attribute.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// Left operand.
/// Right operand.
/// A new Vertex with the difference of `a` - `b`.
public static Vertex operator-(Vertex a, Vertex b)
{
return Subtract(a, b);
}
///
/// Subtracts two Vertex objects and returns the result in a new Vertex object.
/// Subtraction is performed component-wise for every attribute on the Vertex.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// First Vertex object.
/// Second Vertex object.
/// A new Vertex with the difference of `a` - `b`.
public static Vertex Subtract(Vertex a, Vertex b)
{
var c = new Vertex(a);
c.Subtract(b);
return c;
}
///
/// Subtracts another Vertex object from this one using component-wise subtraction on each attribute.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// The Vertex object to subtract.
public void Subtract(Vertex b)
{
if (b == null)
throw new ArgumentNullException("b");
m_Position -= b.m_Position;
m_Color -= b.m_Color;
m_Normal -= b.m_Normal;
m_Tangent -= b.m_Tangent;
m_UV0 -= b.m_UV0;
m_UV2 -= b.m_UV2;
m_UV3 -= b.m_UV3;
m_UV4 -= b.m_UV4;
}
///
/// Multiples a Vertex object by the specified `value` and returns the result in a new Vertex object.
/// Multiplication is performed component-wise for every attribute.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// Vertex object to multiply
/// Multiplication factor.
/// A new Vertex with the product of `a` * `b`.
public static Vertex operator*(Vertex a, float value)
{
return Multiply(a, value);
}
///
/// Multiples a Vertex object by the specified `value` and returns the result in a new Vertex object.
/// Multiplication is performed component-wise for every attribute on the Vertex.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// Vertex object to multiply
/// Multiplication factor.
/// A new Vertex with the product of `a` * `b`.
public static Vertex Multiply(Vertex a, float value)
{
Vertex v = new Vertex(a);
v.Multiply(value);
return v;
}
///
/// Multiples this Vertex object by the specified `value` using component-wise multiplication on each attribute.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// Multiplication factor.
public void Multiply(float value)
{
m_Position *= value;
m_Color *= value;
m_Normal *= value;
m_Tangent *= value;
m_UV0 *= value;
m_UV2 *= value;
m_UV3 *= value;
m_UV4 *= value;
}
///
/// Divides a Vertex object by the specified `value` and returns the result in a new Vertex object.
/// Division is performed component-wise for every attribute.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// Vertex object to divide (dividend).
/// Divisor.
/// A new Vertex with the quotient of `a` / `b`.
public static Vertex operator/(Vertex a, float value)
{
return Divide(a, value);
}
///
/// Divides a Vertex object by the specified `value` and returns the result in a new Vertex object.
/// Division is performed component-wise for every attribute.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// Vertex object to divide (dividend).
/// Divisor.
/// A new Vertex with the quotient of `a` / `b`.
public static Vertex Divide(Vertex a, float value)
{
Vertex v = new Vertex(a);
v.Divide(value);
return v;
}
///
/// Divides this Vertex object by the specified `value` using component-wise division on each attribute.
///
///
/// Color, normal, and tangent values are not normalized within this function.
/// If you are expecting unit vectors, you need to normalize these attributes.
///
/// Divisor.
public void Divide(float value)
{
m_Position /= value;
m_Color /= value;
m_Normal /= value;
m_Tangent /= value;
m_UV0 /= value;
m_UV2 /= value;
m_UV3 /= value;
m_UV4 /= value;
}
///
/// Normalizes all vector values in place.
///
public void Normalize()
{
m_Position.Normalize();
Vector4 color4 = m_Color;
color4.Normalize();
m_Color = color4;
m_Normal.Normalize();
m_Tangent.Normalize();
m_UV0.Normalize();
m_UV2.Normalize();
m_UV3.Normalize();
m_UV4.Normalize();
}
///
/// Returns a multi-line string listing every populated attribute.
///
/// An [optional string argument](https://docs.microsoft.com/en-us/dotnet/api/system.int16.tostring?view=net-5.0#System_Int16_ToString_System_String_) to pass to the component ToString calls.
/// A string with the values of all populated attributes.
public string ToString(string args = null)
{
StringBuilder sb = new StringBuilder();
if (hasPosition) sb.AppendLine("position: " + m_Position.ToString(args));
if (hasColor) sb.AppendLine("color: " + m_Color.ToString(args));
if (hasNormal) sb.AppendLine("normal: " + m_Normal.ToString(args));
if (hasTangent) sb.AppendLine("tangent: " + m_Tangent.ToString(args));
if (hasUV0) sb.AppendLine("uv0: " + m_UV0.ToString(args));
if (hasUV2) sb.AppendLine("uv2: " + m_UV2.ToString(args));
if (hasUV3) sb.AppendLine("uv3: " + m_UV3.ToString(args));
if (hasUV4) sb.AppendLine("uv4: " + m_UV4.ToString(args));
return sb.ToString();
}
///
/// Allocates and fills all attribute arrays. This method fills all arrays, regardless of whether or not
/// real data populates the values. You can check which attributes a Vertex contains with `HasAttribute()`).
///
///
/// If you are using this function to rebuild a mesh, use instead.
/// SetMesh handles setting null arrays where appropriate.
///
/// The source vertices.
/// A new array of the vertex position values.
/// A new array of the vertex color values.
/// A new array of the vertex uv0 values.
/// A new array of the vertex normal values.
/// A new array of the vertex tangent values.
/// A new array of the vertex uv2 values.
/// A new array of the vertex uv3 values.
/// A new array of the vertex uv4 values.
public static void GetArrays(
IList vertices,
out Vector3[] position,
out Color[] color,
out Vector2[] uv0,
out Vector3[] normal,
out Vector4[] tangent,
out Vector2[] uv2,
out List uv3,
out List uv4)
{
GetArrays(vertices, out position, out color, out uv0, out normal, out tangent, out uv2, out uv3, out uv4, MeshArrays.All);
}
///
/// Allocates and fills the specified attribute arrays.
///
///
/// If you are using this function to rebuild a mesh, use instead.
/// SetMesh handles setting null arrays where appropriate.
///
/// The source vertices.
/// A new array of the vertex position values if requested by the attributes parameter, or null.
/// A new array of the vertex color values if requested by the attributes parameter, or null.
/// A new array of the vertex uv0 values if requested by the attributes parameter, or null.
/// A new array of the vertex normal values if requested by the attributes parameter, or null.
/// A new array of the vertex tangent values if requested by the attributes parameter, or null.
/// A new array of the vertex uv2 values if requested by the attributes parameter, or null.
/// A new array of the vertex uv3 values if requested by the attributes parameter, or null.
/// A new array of the vertex uv4 values if requested by the attributes parameter, or null.
/// A bitmask of the set of MeshAttributes you want.
///
public static void GetArrays(
IList vertices,
out Vector3[] position,
out Color[] color,
out Vector2[] uv0,
out Vector3[] normal,
out Vector4[] tangent,
out Vector2[] uv2,
out List uv3,
out List uv4,
MeshArrays attributes)
{
if (vertices == null)
throw new ArgumentNullException("vertices");
int vc = vertices.Count;
var first = vc < 1 ? new Vertex() : vertices[0];
bool hasPosition = ((attributes & MeshArrays.Position) == MeshArrays.Position) && first.hasPosition;
bool hasColor = ((attributes & MeshArrays.Color) == MeshArrays.Color) && first.hasColor;
bool hasUv0 = ((attributes & MeshArrays.Texture0) == MeshArrays.Texture0) && first.hasUV0;
bool hasNormal = ((attributes & MeshArrays.Normal) == MeshArrays.Normal) && first.hasNormal;
bool hasTangent = ((attributes & MeshArrays.Tangent) == MeshArrays.Tangent) && first.hasTangent;
bool hasUv2 = ((attributes & MeshArrays.Texture1) == MeshArrays.Texture1) && first.hasUV2;
bool hasUv3 = ((attributes & MeshArrays.Texture2) == MeshArrays.Texture2) && first.hasUV3;
bool hasUv4 = ((attributes & MeshArrays.Texture3) == MeshArrays.Texture3) && first.hasUV4;
position = hasPosition ? new Vector3[vc] : null;
color = hasColor ? new Color[vc] : null;
uv0 = hasUv0 ? new Vector2[vc] : null;
normal = hasNormal ? new Vector3[vc] : null;
tangent = hasTangent ? new Vector4[vc] : null;
uv2 = hasUv2 ? new Vector2[vc] : null;
uv3 = hasUv3 ? new List(vc) : null;
uv4 = hasUv4 ? new List(vc) : null;
for (int i = 0; i < vc; i++)
{
if (hasPosition) position[i] = vertices[i].m_Position;
if (hasColor) color[i] = vertices[i].m_Color;
if (hasUv0) uv0[i] = vertices[i].m_UV0;
if (hasNormal) normal[i] = vertices[i].m_Normal;
if (hasTangent) tangent[i] = vertices[i].m_Tangent;
if (hasUv2) uv2[i] = vertices[i].m_UV2;
if (hasUv3) uv3.Add(vertices[i].m_UV3);
if (hasUv4) uv4.Add(vertices[i].m_UV4);
}
}
///
/// Replaces mesh values with the specified vertex array. The mesh is cleared during this function,
/// so you need to set the triangles after calling this method.
///
/// The target mesh.
/// The vertices to replace the mesh attributes with.
public static void SetMesh(Mesh mesh, IList 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 uv3s = null;
List uv4s = null;
GetArrays(vertices, out positions,
out colors,
out uv0s,
out normals,
out tangents,
out uv2s,
out uv3s,
out uv4s);
mesh.Clear();
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 (first.hasUV3)
if (uv3s != null)
mesh.SetUVs(2, uv3s);
if (first.hasUV4)
if (uv4s != null)
mesh.SetUVs(3, uv4s);
mesh.indexFormat = mesh.vertexCount > ushort.MaxValue ? Rendering.IndexFormat.UInt32 : Rendering.IndexFormat.UInt16;
}
///
/// Averages all vertices to a single vertex and returns the result as a new Vertex object.
///
/// The list of vertices to average.
///
/// Specify a list of vertex points to calculate the average from.
/// If not specified, it averages the entire set of vertices instead.
///
/// An averaged vertex value.
public static Vertex Average(IList vertices, IList indexes = null)
{
if (vertices == null)
throw new ArgumentNullException("vertices");
Vertex v = new Vertex();
int vertexCount = indexes != null ? indexes.Count : vertices.Count;
int positionCount = 0,
colorCount = 0,
uv0Count = 0,
normalCount = 0,
tangentCount = 0,
uv2Count = 0,
uv3Count = 0,
uv4Count = 0;
for (int i = 0; i < vertexCount; i++)
{
int index = indexes == null ? i : indexes[i];
if (vertices[index].hasPosition)
{
positionCount++;
v.m_Position += vertices[index].m_Position;
}
if (vertices[index].hasColor)
{
colorCount++;
v.m_Color += vertices[index].m_Color;
}
if (vertices[index].hasUV0)
{
uv0Count++;
v.m_UV0 += vertices[index].m_UV0;
}
if (vertices[index].hasNormal)
{
normalCount++;
v.m_Normal += vertices[index].m_Normal;
}
if (vertices[index].hasTangent)
{
tangentCount++;
v.m_Tangent += vertices[index].m_Tangent;
}
if (vertices[index].hasUV2)
{
uv2Count++;
v.m_UV2 += vertices[index].m_UV2;
}
if (vertices[index].hasUV3)
{
uv3Count++;
v.m_UV3 += vertices[index].m_UV3;
}
if (vertices[index].hasUV4)
{
uv4Count++;
v.m_UV4 += vertices[index].m_UV4;
}
}
if (positionCount > 0)
{
v.hasPosition = true;
v.m_Position *= (1f / positionCount);
}
if (colorCount > 0)
{
v.hasColor = true;
v.m_Color *= (1f / colorCount);
}
if (uv0Count > 0)
{
v.hasUV0 = true;
v.m_UV0 *= (1f / uv0Count);
}
if (normalCount > 0)
{
v.hasNormal = true;
v.m_Normal *= (1f / normalCount);
}
if (tangentCount > 0)
{
v.hasTangent = true;
v.m_Tangent *= (1f / tangentCount);
}
if (uv2Count > 0)
{
v.hasUV2 = true;
v.m_UV2 *= (1f / uv2Count);
}
if (uv3Count > 0)
{
v.hasUV3 = true;
v.m_UV3 *= (1f / uv3Count);
}
if (uv4Count > 0)
{
v.hasUV4 = true;
v.m_UV4 *= (1f / uv4Count);
}
return v;
}
///
/// Linearly interpolates between two vertices using the specified weight.
///
/// The first Vertex object.
/// The second Vertex object.
///
/// The weight of the interpolation, where `0` is weighted fully towards the first Vertex
/// object `x`, and `1` is weighted fully towards the second Vertex object `y`.
///
/// A new Vertex object interpolated between the two objects according to the specified `weight`.
public static Vertex Mix(Vertex x, Vertex y, float weight)
{
if (x == null || y == null)
throw new ArgumentNullException("x", "Mix does accept null vertices.");
float i = 1f - weight;
Vertex v = new Vertex();
v.m_Position = x.m_Position * i + y.m_Position * weight;
if (x.hasColor && y.hasColor)
v.m_Color = x.m_Color * i + y.m_Color * weight;
else if (x.hasColor)
v.m_Color = x.m_Color;
else if (y.hasColor)
v.m_Color = y.m_Color;
if (x.hasNormal && y.hasNormal)
v.m_Normal = x.m_Normal * i + y.m_Normal * weight;
else if (x.hasNormal)
v.m_Normal = x.m_Normal;
else if (y.hasNormal)
v.m_Normal = y.m_Normal;
if (x.hasTangent && y.hasTangent)
v.m_Tangent = x.m_Tangent * i + y.m_Tangent * weight;
else if (x.hasTangent)
v.m_Tangent = x.m_Tangent;
else if (y.hasTangent)
v.m_Tangent = y.m_Tangent;
if (x.hasUV0 && y.hasUV0)
v.m_UV0 = x.m_UV0 * i + y.m_UV0 * weight;
else if (x.hasUV0)
v.m_UV0 = x.m_UV0;
else if (y.hasUV0)
v.m_UV0 = y.m_UV0;
if (x.hasUV2 && y.hasUV2)
v.m_UV2 = x.m_UV2 * i + y.m_UV2 * weight;
else if (x.hasUV2)
v.m_UV2 = x.m_UV2;
else if (y.hasUV2)
v.m_UV2 = y.m_UV2;
if (x.hasUV3 && y.hasUV3)
v.m_UV3 = x.m_UV3 * i + y.m_UV3 * weight;
else if (x.hasUV3)
v.m_UV3 = x.m_UV3;
else if (y.hasUV3)
v.m_UV3 = y.m_UV3;
if (x.hasUV4 && y.hasUV4)
v.m_UV4 = x.m_UV4 * i + y.m_UV4 * weight;
else if (x.hasUV4)
v.m_UV4 = x.m_UV4;
else if (y.hasUV4)
v.m_UV4 = y.m_UV4;
return v;
}
}
}