/// <summary> /// Compute UV tangen space /// </summary> public void ComputeTangents() { if (this.Vertices.Length > 0) { if (this.Indices.Length > 0) { for (int i = 0; i < this.Indices.Length; i += 3) { var v0 = this.Vertices[(int)this.Indices[i + 0]]; var v1 = this.Vertices[(int)this.Indices[i + 1]]; var v2 = this.Vertices[(int)this.Indices[i + 2]]; GeometryUtil.ComputeNormals( v0.Position.Value, v1.Position.Value, v2.Position.Value, v0.Texture.Value, v1.Texture.Value, v2.Texture.Value, out Vector3 tangent, out Vector3 binormal, out Vector3 normal); v0.Tangent = tangent; v1.Tangent = tangent; v2.Tangent = tangent; v0.BiNormal = binormal; v1.BiNormal = binormal; v2.BiNormal = binormal; this.Vertices[(int)this.Indices[i + 0]] = v0; this.Vertices[(int)this.Indices[i + 1]] = v1; this.Vertices[(int)this.Indices[i + 2]] = v2; } } else { for (int i = 0; i < this.Vertices.Length; i += 3) { var v0 = this.Vertices[i + 0]; var v1 = this.Vertices[i + 1]; var v2 = this.Vertices[i + 2]; GeometryUtil.ComputeNormals( v0.Position.Value, v1.Position.Value, v2.Position.Value, v0.Texture.Value, v1.Texture.Value, v2.Texture.Value, out Vector3 tangent, out Vector3 binormal, out Vector3 normal); v0.Tangent = tangent; v1.Tangent = tangent; v2.Tangent = tangent; v0.BiNormal = binormal; v1.BiNormal = binormal; v2.BiNormal = binormal; this.Vertices[i + 0] = v0; this.Vertices[i + 1] = v1; this.Vertices[i + 2] = v2; } } this.VertexType = VertexData.GetVertexType(this.Vertices[0], this.Textured); } }
/// <summary> /// Generates the height map normals /// </summary> /// <param name="cellSize">Cell size</param> /// <returns>Returns the generated normals array</returns> private static void ComputeHeightMapNormals(VertexData[] vertList, long width, long depth) { for (long x = 0; x < depth; x++) { for (long y = 0; y < width; y++) { long index1 = (y * width) + x; Vector3 normal; Vector3 tangent; Vector3 binormal; if (x == 0 || y == 0 || x == (depth - 1) || y == (width - 1)) { // The vertices in the borders have always the up normal normal = Vector3.UnitY; tangent = Vector3.UnitX; binormal = Vector3.UnitZ; } else { long index2; long index3; VertexData pos1 = vertList[index1]; VertexData pos2; VertexData pos3; index2 = ((y - 1) * width) + x; index3 = (y * width) + (x - 1); pos2 = vertList[index2]; pos3 = vertList[index3]; GeometryUtil.ComputeNormals( pos1.Position.Value, pos3.Position.Value, pos2.Position.Value, pos1.Texture.Value, pos3.Texture.Value, pos2.Texture.Value, out Vector3 tan1, out Vector3 biNorm1, out Vector3 norm1); index2 = (y * width) + (x - 1); index3 = ((y + 1) * width) + (x - 1); pos2 = vertList[index2]; pos3 = vertList[index3]; GeometryUtil.ComputeNormals( pos1.Position.Value, pos3.Position.Value, pos2.Position.Value, pos1.Texture.Value, pos3.Texture.Value, pos2.Texture.Value, out Vector3 tan2, out Vector3 biNorm2, out Vector3 norm2); index2 = ((y + 1) * width) + (x - 1); index3 = ((y + 1) * width) + x; pos2 = vertList[index2]; pos3 = vertList[index3]; GeometryUtil.ComputeNormals( pos1.Position.Value, pos3.Position.Value, pos2.Position.Value, pos1.Texture.Value, pos3.Texture.Value, pos2.Texture.Value, out Vector3 tan3, out Vector3 biNorm3, out Vector3 norm3); index2 = ((y + 1) * width) + x; index3 = (y * width) + (x + 1); pos2 = vertList[index2]; pos3 = vertList[index3]; GeometryUtil.ComputeNormals( pos1.Position.Value, pos3.Position.Value, pos2.Position.Value, pos1.Texture.Value, pos3.Texture.Value, pos2.Texture.Value, out Vector3 tan4, out Vector3 biNorm4, out Vector3 norm4); index2 = (y * width) + (x + 1); index3 = ((y - 1) * width) + (x + 1); pos2 = vertList[index2]; pos3 = vertList[index3]; GeometryUtil.ComputeNormals( pos1.Position.Value, pos3.Position.Value, pos2.Position.Value, pos1.Texture.Value, pos3.Texture.Value, pos2.Texture.Value, out Vector3 tan5, out Vector3 biNorm5, out Vector3 norm5); index2 = ((y - 1) * width) + (x + 1); index3 = ((y - 1) * width) + x; pos2 = vertList[index2]; pos3 = vertList[index3]; GeometryUtil.ComputeNormals( pos1.Position.Value, pos3.Position.Value, pos2.Position.Value, pos1.Texture.Value, pos3.Texture.Value, pos2.Texture.Value, out Vector3 tan6, out Vector3 biNorm6, out Vector3 norm6); Vector3 norm = (norm1 + norm2 + norm3 + norm4 + norm5 + norm6) / 6.0f; Vector3 tang = (tan1 + tan2 + tan3 + tan4 + tan5 + tan6) / 6.0f; Vector3 binorm = (biNorm1 + biNorm2 + biNorm3 + biNorm4 + biNorm5 + biNorm6) / 6.0f; normal = Vector3.Normalize(norm); tangent = Vector3.Normalize(tang); binormal = Vector3.Normalize(binorm); } vertList[index1].Normal = normal; vertList[index1].Tangent = tangent; vertList[index1].BiNormal = binormal; } } }