public Vector3 CalculateFaceNormal(int faceIndex) { int i; Face face = faces[faceIndex]; int vertCount = face.cornerCount; int[] vindex = face.v; Vector3[] vec = new Vector3[vertCount + 1]; for (i = 0; i < vertCount - 1; ++i) { vec[i] = vertices[vindex[i + 1]].coords - vertices[vindex[i]].coords; } vec[i] = vertices[vindex[0]].coords - vertices[vindex[i]].coords; Vector3 normal = Vector3.zero; if (vertCount == 3) { normal = Vector3.Cross(vec[0], vec[1]); } else { // Sum normals based on consequtive pairs of edges vec[vertCount] = vec[0]; for (i = 0; i < vertCount; ++i) { normal += Vector3.Cross(vec[i], vec[i + 1]); } } UnityUtils.NormalizeSmallVector(ref normal); face.normal = normal; return(face.normal); }
void _determinePdeToConstrainEdge(Edge edge, float weight, ref PlaneDistanceError pde) { int vi0 = edge.v[0]; int vi1 = edge.v[1]; Vector3 v0 = mesh.vertices[vi0].coords; Vector3 vEdge = mesh.vertices[vi1].coords - v0; Vector3 edgeNormal; pde.Clear(); float mag = vEdge.sqrMagnitude; for (int i = 0; i < edge.linkedFaces.Count; ++i) { edgeNormal = mesh.faces[edge.linkedFaces[i]].normal; Vector3 n = Vector3.Cross(vEdge, edgeNormal); // normal to edge and face UnityUtils.NormalizeSmallVector(ref n); float d = -Vector3.Dot(n, v0); pde2.Set(n.x, n.y, n.z, d, mag); // Multiply by face area (factor) for weighting pde2.OpMul(pde2.Factor() * weight * 0.5f); pde.OpAdd(pde2); } }
public Vector3 CalculateVertexNormal(int vertexIndex) { Vertex vert = vertices[vertexIndex]; Vector3 n = Vector3.zero; IndexList linkedFaces = vert.linkedFaces; int num = linkedFaces.Count; for (int i = 0; i < num; ++i) { int faceIndex = linkedFaces[i]; n += faces[faceIndex].normal; } UnityUtils.NormalizeSmallVector(ref n); vert.normal = n; return(n); }
public void CalculateFaceVertexNormalsFromEdgeCreasesForVertex(int vertexIndex, ref List <int>[] faceLinkedEdges) { int i, j, grp; List <int> grpCornerIndex = new List <int>(); Vertex v = vertices[vertexIndex]; IndexList vertexFaces = v.linkedFaces; int vertexFaceCount = vertexFaces.Count; // List<int> vertexEdges = linkedEdges[vertexIndex]; // Clear face marks around vertex for (j = 0; j < vertexFaceCount; ++j) { faces[vertexFaces[j]].mark = -1; // TODO: could be faster with uniqueTag } // This will add each facemark to a groupIndex int groupIndex = 0; for (j = 0; j < vertexFaceCount; ++j) { int faceIndex = vertexFaces[j]; if (faces[faceIndex].mark == -1) // face still available { _markGroupFaceNeightbours(vertexIndex, vertexFaces[j], ref faceLinkedEdges, groupIndex); groupIndex++; } } // Build group arrays List <int>[] groups = new List <int> [groupIndex]; // are these too many allocations? for (i = 0; i < groupIndex; ++i) { groups[i] = new List <int>(); } for (i = 0; i < vertexFaceCount; ++i) { int faceIndex = vertexFaces[i]; int mark = faces[faceIndex].mark; groups[mark].Add(faceIndex); } // Calculate and set normal for each face on the vertex based on the groups Vector3 normal; for (grp = 0; grp < groupIndex; ++grp) { normal = Vector3.zero; List <int> grpFaces = groups[grp]; int cnt = grpFaces.Count; grpCornerIndex.Clear(); for (i = 0; i < cnt; ++i) { Face f = faces[grpFaces[i]]; if (f.normal == Vector3.zero) { // Debug.Log("face has zero normal .. valid " + f.valid); } // Multiply with corner angle (=SLOW?) int corner = f.CornerIndex(vertexIndex); float fact = CornerAngle(grpFaces[i], corner); normal += f.normal * fact; grpCornerIndex.Add(corner); } UnityUtils.NormalizeSmallVector(ref normal); if (normal == Vector3.zero) { // Debug.Log("NORMAL == ZERO facecount " + cnt); } // Now set the normal to all group faces for (i = 0; i < cnt; ++i) { faces[grpFaces[i]].vertexNormal[grpCornerIndex[i]] = normal; } } }