public Vertex Average(Vertex[] vs, VertexContent mask = VertexContent.full, float[] weights = null) { VertexContent c = mask & content; Vertex r = new Vertex(); float ws = 0; for (int i = 0; i < vs.Length; ++i) { Vertex v = vs[i]; float w = weights?[i] ?? 1f; if (c.HasPosition()) { r.position += w * v.position; } ws += w; } if (c.HasPosition()) { r.position /= ws; } r.posIndex = -1; return(r); }
static Vertex[] GetMeshVertices(Mesh mesh, VertexContent content) { var vs = new Vertex[mesh.vertexCount]; for (int i = 0; i < mesh.vertexCount; ++i) { var v = new Vertex(); if ((content & VertexContent.pos) != 0) { v.pos = mesh.vertices[i]; } if ((content & VertexContent.normal) != 0) { v.normal = mesh.normals [i]; } if ((content & VertexContent.tangent) != 0) { v.tangent = mesh.tangents[i]; } if ((content & VertexContent.uv) != 0) { v.uv = mesh.uv [i]; } vs[i] = v; } return(vs); }
public MeshX(Mesh mesh) { content = GetMeshVertexContent(); var poses = new List <Vector3>(); posIndices = new int[mesh.vertexCount]; for (int i = 0; i < mesh.vertexCount; ++i) { Vector3 pos = mesh.vertices[i]; int posIndex = poses.IndexOf(pos); if (posIndex == -1) { poses.Add(pos); posIndex = poses.Count - 1; } posIndices[i] = posIndex; } positions = poses.ToArray(); int submeshCount = mesh.subMeshCount; submeshes = new Submesh[submeshCount]; for (int s = 0; s < submeshCount; ++s) { int[][] faces = TrianglesToFaces(mesh.GetTriangles(s)); submeshes[s] = new Submesh { faces = faces }; } name = mesh.name; }
public MeshData(Mesh mesh) { vertexContent = GetVertexContent(mesh); vertices = GetMeshVertices(mesh, vertexContent); if (MeshStruct.CheckQuads(mesh.triangles) != -1) { throw new UnityException("Can't create MeshData: Mesh has no quads topology. Try to 'Keep Quads' on mesh importing."); } meshStruct = new MeshStruct(mesh.vertexCount, MeshStruct.GetQuads(mesh.triangles)); }
private void AddVertexColorChannel(VertexContent content) { if (content.Channels.Contains(VertexChannelNames.Color(0)) == false) { List <Microsoft.Xna.Framework.Color> VertexColors = new List <Microsoft.Xna.Framework.Color>(); for (int i = 0; i < content.VertexCount; i++) { VertexColors.Add(Color.Purple); } content.Channels.Add(VertexChannelNames.Color(0), VertexColors); } }
public Vertex GetVertex(int vi, VertexContent mask = VertexContent.full) { VertexContent c = content & mask; int pi = posIndices[vi]; Vertex v = new Vertex(); v.posIndex = pi; if (c.HasPosition()) { v.position = positions[pi]; } return(v); }
public static void SetMeshVertices(Mesh mesh, Vertex[] vs, VertexContent content) { if ((content & VertexContent.pos) != 0) { mesh.SetVertices(vs.Select(v => v.pos).ToList()); } if ((content & VertexContent.normal) != 0) { mesh.SetNormals(vs.Select(v => v.normal).ToList()); } if ((content & VertexContent.tangent) != 0) { mesh.SetTangents(vs.Select(v => v.tangent).Select(t => new Vector4(t.x, t.y, t.z, 1)).ToList()); } if ((content & VertexContent.uv) != 0) { mesh.SetUVs(0, vs.Select(v => v.uv).ToList()); } }
public void GenerateVerticesRecursive(NodeContent input) { MeshContent mesh = input as MeshContent; if (mesh != null) { GeometryContentCollection gc = mesh.Geometry; foreach (GeometryContent g in gc) { VertexContent vc = g.Vertices; IndirectPositionCollection ipc = vc.Positions; IndexCollection ic = g.Indices; float[] vertexData = new float[ipc.Count * 3]; for (int i = 0; i < ipc.Count; i++) { Vector3 v0 = ipc[i]; vertexData[(i * 3) + 0] = v0.X; vertexData[(i * 3) + 1] = v0.Y; vertexData[(i * 3) + 2] = v0.Z; } int[] indexData = new int[ic.Count]; for (int j = 0; j < ic.Count; j++) { indexData[j] = ic[j] + indexOffset; } tag.appendVertexData(vertexData); tag.appendIndexData(indexData); indexOffset += ipc.Count; } } foreach (NodeContent child in input.Children) { GenerateVerticesRecursive(child); } }
public Vertex GetVertex(int vi, VertexContent mask = VertexContent.full) { VertexContent c = content & mask; int pi = posIndices[vi]; Vertex v = new Vertex(); v.posIndex = pi; // always set if (c.HasPosition()) { v.position = positions[pi]; } if (c.HasNormal()) { v.normal = normals[normalPerPosition ? pi : vi]; } if (c.HasTangent()) { v.tangent = tangents[vi]; } if (c.HasUV0()) { v.uv0 = uvs0[vi]; } if (c.HasUV1()) { v.uv1 = uvs1[vi]; } if (c.HasUV2()) { v.uv2 = uvs2[vi]; } if (c.HasUV3()) { v.uv3 = uvs3[vi]; } return(v); }
public static bool HasNormal(this VertexContent c) { return((c & VertexContent.normal) != 0); }
public Vertex GetVertex(VertexKey key, VertexContent mask = VertexContent.full) { return(mesh.GetVertex(vertexIndices[key], mask)); }
/// <summary> /// Helper function adds a single new billboard sprite to the output geometry. /// </summary> private void GenerateBillboard(MeshContent mesh, GeometryContent geometry, Vector3 position, Vector3 normal) { VertexContent vertices = geometry.Vertices; VertexChannelCollection channels = vertices.Channels; // First, create a vertex position entry for this billboard. Each // billboard is going to be rendered a quad, so we need to create four // vertices, but at this point we only have a single position that is // shared by all the vertices. The real position of each vertex will be // computed on the fly in the vertex shader, thus allowing us to // implement effects like making the billboard rotate to always face the // camera, and sway in the wind. As input the vertex shader only wants to // know the center point of the billboard, and that is the same for all // the vertices, so only a single position is needed here. int positionIndex = mesh.Positions.Count; mesh.Positions.Add(position); // Second, create the four vertices, all referencing the same position. int index = vertices.PositionIndices.Count; for (int i = 0; i < 4; i++) { vertices.Add(positionIndex); } // Third, add normal data for each of the four vertices. A normal for a // billboard is kind of a silly thing to define, since we are using a // 2D sprite to fake a complex 3D object that would in reality have many // different normals across its surface. Here we are just using a copy // of the normal from the ground underneath the billboard, which can be // used in our lighting computation to make the vegetation darker or // lighter depending on the lighting of the underlying landscape. VertexChannel <Vector3> normals; normals = channels.Get <Vector3>(VertexChannelNames.Normal()); for (int i = 0; i < 4; i++) { normals[index + i] = normal; } // Fourth, add texture coordinates. VertexChannel <Vector2> texCoords; texCoords = channels.Get <Vector2>(VertexChannelNames.TextureCoordinate(0)); texCoords[index + 0] = new Vector2(0, 0); texCoords[index + 1] = new Vector2(1, 0); texCoords[index + 2] = new Vector2(1, 1); texCoords[index + 3] = new Vector2(0, 1); // Fifth, add a per-billboard random value, which is the same for // all four vertices. This is used in the vertex shader to make // each billboard a slightly different size, and to be affected // differently by the wind animation. float randomValue = (float)random.NextDouble() * 2 - 1; VertexChannel <float> randomValues; randomValues = channels.Get <float>(VertexChannelNames.TextureCoordinate(1)); for (int i = 0; i < 4; i++) { randomValues[index + i] = randomValue; } // Sixth and finally, add indices defining the pair of // triangles that will be used to render the billboard. geometry.Indices.Add(index + 0); geometry.Indices.Add(index + 1); geometry.Indices.Add(index + 2); geometry.Indices.Add(index + 0); geometry.Indices.Add(index + 2); geometry.Indices.Add(index + 3); }
public Vertex GetVertex(System.UInt32 key, VertexContent mask = VertexContent.full) { return(mesh.GetVertex(vertexIndices[key], mask)); }
public static bool HasUV3(this VertexContent c) { return((c & VertexContent.uv3) != 0); }
public MeshData(Vertex[] vertices, int[][] quads, VertexContent vertexContent) { this.vertices = vertices; this.meshStruct = new MeshStruct(vertices.Length, quads); this.vertexContent = vertexContent; }
public static bool HasTangent(this VertexContent c) { return((c & VertexContent.tangent) != 0); }
public MeshX(Mesh mesh) { // set vertex content content = GetMeshVertexContent(mesh); // init positions var poses = new List <Vector>(); posIndices = new int[mesh.vertexCount]; for (int i = 0; i < mesh.vertexCount; ++i) { Vector pos = mesh.vertices[i]; int posIndex = poses.IndexOf(pos); //!!! use threshold? if (posIndex == -1) { poses.Add(pos); posIndex = poses.Count - 1; } posIndices[i] = posIndex; } positions = poses.ToArray(); // init vertex content if (content.HasNormal()) { normals = mesh.normals; normalPerPosition = false; } if (content.HasTangent()) { tangents = new Vector[mesh.vertexCount]; for (int i = 0; i < mesh.vertexCount; ++i) { tangents[i] = (Vector)mesh.tangents[i]; } } if (content.HasUV0()) { uvs0 = mesh.uv; } if (content.HasUV1()) { uvs1 = mesh.uv2; } if (content.HasUV2()) { uvs2 = mesh.uv3; } if (content.HasUV3()) { uvs3 = mesh.uv4; } // set faces int submeshCount = mesh.subMeshCount; submeshes = new Submesh[submeshCount]; for (int s = 0; s < submeshCount; ++s) { int[][] faces = MeshX.TrianglesToFaces(mesh.GetTriangles(s)); submeshes[s] = new Submesh { faces = faces }; } // copy name this.name = mesh.name; }
/// <summary> /// Creates an instance of GeometryContent. /// </summary> public GeometryContent() { indices = new IndexCollection(); vertices = new VertexContent(this); }
private static Vertex AverageVertices(Vertex[] vs, VertexContent c, float[] weights = null) { Vertex r = new Vertex(); float ws = 0; for (int i = 0; i < vs.Length; ++i) { Vertex v = vs[i]; float w = weights != null ? weights[i] : 1f; if (c.HasPosition()) { r.position += w * v.position; } if (c.HasNormal()) { r.normal += w * v.normal; } if (c.HasTangent()) { r.tangent += w * v.tangent; } if (c.HasUV0()) { r.uv0 += w * v.uv0; } if (c.HasUV1()) { r.uv1 += w * v.uv1; } if (c.HasUV2()) { r.uv2 += w * v.uv2; } if (c.HasUV3()) { r.uv3 += w * v.uv3; } ws += w; } if (c.HasPosition()) { r.position /= ws; } if (c.HasNormal()) { r.normal.Normalize(); } if (c.HasTangent()) { r.tangent.Normalize(); } if (c.HasUV0()) { r.uv0 /= ws; } if (c.HasUV1()) { r.uv1 /= ws; } if (c.HasUV2()) { r.uv2 /= ws; } if (c.HasUV3()) { r.uv3 /= ws; } r.posIndex = -1; return(r); }
/// <summary> /// Creates an instance of GeometryContent. /// </summary> public GeometryContent() { indices = new IndexCollection(); vertices = new VertexContent(); }
public static bool HasPosition(this VertexContent c) { return((c & VertexContent.pos) != 0); }
public Vertex Average(Vertex[] vs, VertexContent mask = VertexContent.full, float[] weights = null) { return(MeshX.AverageVertices(vs, content & mask, weights)); }
/// <summary> /// Return true if the vertex content contains skinning blend indices. /// </summary> /// <param name="vc">The vertex content to check.</param> /// <param name="context">For reporting errors.</param> /// <returns>true if skinning should be applied to these vertices</returns> protected virtual bool VerticesAreSkinned(VertexContent vc, ContentProcessorContext context) { return(vc.Channels.Contains(VertexChannelNames.Weights())); }
/// <summary> /// Creates an instance of <see cref="GeometryContent"/>. /// </summary> public GeometryContent() { Indices = new IndexCollection(); Vertices = new VertexContent(this); }