/// <summary> /// Calculates the normal vector for a given face. /// </summary> /// <param name="f">The face to calculate the normal for.</param> /// <returns>The nomal vector for the face.</returns> /// <exception cref="System.Exception">The face doesn't consist of 3 or more vertices.</exception> public double3 CalcFaceNormal(Face f) { if (f.InxVert.Length < 3) throw new FormatException("Cannot calculate normal of degenerate face with only " + f.InxVert.Length + " vertices."); var vertex0 = f.InxVert[0]; double3 v1 = _vertices[vertex0] - _vertices[f.InxVert[2]]; double3 v2 = _vertices[vertex0] - _vertices[f.InxVert[1]]; return double3.Normalize(double3.Cross(v1, v2)); }
private IEnumerable<ushort> Triangulate(Face f, int[] indices) { if (f.InxVert.Length < 3) return null; if (indices == null) indices = f.InxVert; ushort[] ret = new ushort[3 * (f.InxVert.Length-2)]; // Perform a fan triangulation for (int i = 2; i < f.InxVert.Length; i++ ) { ret[(i - 2)*3 + 0] = (ushort)indices[0]; ret[(i - 2)*3 + 1] = (ushort)indices[i - 1]; ret[(i - 2)*3 + 2] = (ushort)indices[i]; } return ret; }
/// <summary> /// Adds the face. /// </summary> /// <param name="vertInx">The vert inx.</param> /// <param name="texCoordInx">The tex coord inx.</param> /// <param name="normalInx">The normal inx.</param> /// <returns>The face count as integer value.</returns> /// <exception cref="System.ArgumentNullException">vertInx</exception> /// <exception cref="System.ArgumentException"> /// "Vertex index out of range: vertInx[i]" /// or /// "Number of texture coordinate indices must match number of vertex indices" /// or /// "Texture coordinate index out of range: texCoordInx[i]" /// or /// "Number of normal indices must match number of vertex indices" /// or /// "Normal index out of range: normalInx[i]" /// </exception> public int AddFace(int[] vertInx, int[] texCoordInx, int[] normalInx) { int i; Face f = new Face(); // Plausibility checks interleaved... if (vertInx == null) throw new ArgumentNullException("vertInx"); f.InxVert = new int[vertInx.Length]; for(i = 0; i < vertInx.Length; i++) { var vInx = vertInx[i]; if (!(0 <= vInx && vInx < _vertices.Count)) throw new ArgumentException("Vertex index out of range: " + vInx, "vertInx[" + i + "]"); f.InxVert[i] = vInx; } if (texCoordInx != null) { if (texCoordInx.Length != vertInx.Length) throw new ArgumentException( "Number of texture coordinate indices must match number of vertex indices", "texCoordInx"); f.InxTexCoord = new int[texCoordInx.Length]; for (i = 0; i < texCoordInx.Length; i++) { var tInx = texCoordInx[i]; if (!(0 <= tInx && tInx < _texCoords.Count)) throw new ArgumentException("Texture coordinate index out of range: " + tInx, "texCoordInx[" + i + "]"); f.InxTexCoord[i] = tInx; } } if (normalInx != null) { if (normalInx.Length != vertInx.Length) throw new ArgumentException("Number of normal indices must match number of vertex indices", "normalInx"); f.InxNormal = new int[normalInx.Length]; for (i = 0; i < normalInx.Length; i++) { var nInx = normalInx[i]; if (!(0 <= nInx && nInx < _normals.Count)) throw new ArgumentException("Normal index out of range: " + nInx, "normalInx[" + i + "]"); f.InxNormal[i] = nInx; } } // Actually add the faces if (_faces == null) _faces = new List<Face>(); _faces.Add(f); return _faces.Count - 1; }