void Mesh::updateNormal(Vertex *v) { uint vertexIndex; std::vector<glm::uvec3> faces; std::vector<glm::vec3> normals; for (uint i=0; i<indices.size(); i++) { bool included = false; for (uint j=0; j<3; j++) { if(&vertices[indices[i][j]] == v) { faces.push_back(indices[i]); vertexIndex = indices[i][j]; glm::vec3 normal; calculateFaceNormal(normal, i); normals.push_back(normal); included = true; break; } } if(!included) { normals.push_back(glm::vec3(0)); } } //std::cout << "updating normal " << vertexIndex << std::endl; calculateVertexNormal(normals, vertexIndex); }
void KHalfEdgeMeshPrivate::calculateVertexNormals() { std::vector<KVector3D> accumulator; calculateFaceNormals(); for (Vertex &v : m_vertices) { v.normal = calculateVertexNormal(&v, accumulator); } }
void Mesh::calculateVertexNormals() { std::vector<glm::vec3> faceNormals; calculateFaceNormals(faceNormals); //std::cout << "calculating vertex normals.. "; //std::cout.flush(); //aF contains indices of adjacend faces per vertex //interpolate normals of adjacend faces per vertex for(uint i = 0; i< vertices.size(); i++){ calculateVertexNormal(faceNormals, i); /* glm::vec3 vertexNormal = glm::vec3(0); for(uint j= 0; j < aF[i].size(); j++){ // find out which vertex of the current face is the vertex we are currently looking at // aF[i] is a list of faces (aka a list of indices of the indices-vector) // so indices[aF[i][j]] is a glm::vec3 that contains one face // and the current vertex is vertex[i] int thisVertexIndex = -1; for(int vIndex=0; vIndex < 3; vIndex++) { glm::vec3 pos1 = vertices[indices[aF[i][j]][vIndex]].Position; glm::vec3 pos2 = vertices[i].Position; if(glm::distance(pos1, pos2) < 0.0001f) { thisVertexIndex = vIndex; break; } } // we got index of our current vertex within the face, now get others int other1 = (thisVertexIndex+1) % 3; int other2 = (thisVertexIndex+2) % 3; // create the vectors the represent the edges from current vertex to the other 2 glm::vec3 edge1 = vertices[indices[aF[i][j]][thisVertexIndex]].Position - vertices[indices[aF[i][j]][other1]].Position; glm::vec3 edge2 = vertices[indices[aF[i][j]][thisVertexIndex]].Position - vertices[indices[aF[i][j]][other2]].Position; // get angle between the edges float incidentAngle = abs(glm::angle(glm::normalize(edge1), glm::normalize(edge2))); if(incidentAngle > 180) incidentAngle = 360 - incidentAngle; // use that angle as weighting vertexNormal += (faceNormals[aF[i][j]] * incidentAngle); } vertices[i].Normal = glm::normalize(vertexNormal);*/ } //std::cout << "done." << std::endl; }
int32 UGridMesher::buildNewMesh(const TArray<float>& vertexRadii, const TArray<FColor>& vertexColors, const TArray<FVector>& vertexNormals, UMaterialInterface* newMeshMaterial, int32 meshToRebuild /*= -1 if we're to build a new mesh*/) { /*void CreateMeshSection(int32 SectionIndex, const TArray<FVector>& Vertices, const TArray<int32>& Triangles, const TArray<FVector>& Normals, const TArray<FVector2D>& UV0, const TArray<FColor>& VertexColors, const TArray<FProcMeshTangent>& Tangents, bool bCreateCollision);*/ bool calcNormals = vertexNormals.Num() == 0; TArray<FVector> Vertices; TArray<int32> Triangles; TArray<FVector> Normals; TArray<FVector2D> UV0; TArray<FProcMeshTangent> Tangents; if (debugTextOutArray.Num() != 0) { for (USceneComponent* debugText : debugTextOutArray) { debugText->DetachFromParent(); debugText->DestroyComponent(); } } debugLineOut->Flush(); for (const FRectGridLocation& gridLoc : myGrid->gridLocationsM) { FVector tilePos = myGrid->getNodeLocationOnSphere(gridLoc); Vertices.Add(tilePos * vertexRadii[gridLoc.tileIndex]); if (calcNormals) { FVector vertexNormal = calculateVertexNormal(gridLoc, vertexRadii); Normals.Add(vertexNormal); } else { Normals.Add(vertexNormals[gridLoc.tileIndex]); } if (renderNodes) { debugLineOut->DrawPoint(tilePos * baseMeshRadius, FLinearColor::Blue, 8, 2); } if (renderNodeIndexes) { UTextRenderComponent* nodeTextId = NewObject<UTextRenderComponent>(this); nodeTextId->RegisterComponent(); nodeTextId->SetRelativeLocation(tilePos * (baseMeshRadius*1.01)); nodeTextId->SetText(FText::FromString(FString::FromInt(gridLoc.tileIndex))); nodeTextId->SetTextRenderColor(FColor::Red); nodeTextId->SetWorldSize(baseMeshRadius / 50.0f); FVector xAxis(1.0, 0.0, 0.0); FRotator textRotator = Normals[gridLoc.tileIndex].Rotation() - xAxis.Rotation(); nodeTextId->AddRelativeRotation(textRotator); nodeTextId->AttachTo(this); debugTextOutArray.Add(nodeTextId); } } for (int32 uLoc = 0; uLoc < myGrid->rectilinearGridM.Num(); ++uLoc) { for (int32 vLoc = 0; vLoc <= myGrid->gridFrequency * 2; ++vLoc) { if (vLoc != myGrid->gridFrequency * 2) { //upperTriangle int32 vertU = uLoc; int32 vertV = vLoc; Triangles.Add(myGrid->rectilinearGridM[vertU][vertV]); ++vertV; Triangles.Add(myGrid->rectilinearGridM[vertU][vertV]); --vertV; myGrid->decrementU(vertU, vertV); Triangles.Add(myGrid->rectilinearGridM[vertU][vertV]); } if (vLoc != 0) { //lowerTriangle int32 vertU = uLoc; int32 vertV = vLoc; Triangles.Add(myGrid->rectilinearGridM[vertU][vertV]); myGrid->decrementU(vertU, vertV); Triangles.Add(myGrid->rectilinearGridM[vertU][vertV]); --vertV; Triangles.Add(myGrid->rectilinearGridM[vertU][vertV]); } } } int32 targetMeshNum = numMeshes; if (meshToRebuild != -1) { targetMeshNum = meshToRebuild; } CreateMeshSection(targetMeshNum, Vertices, Triangles, Normals, UV0, vertexColors, Tangents, false); SetMaterial(targetMeshNum, newMeshMaterial); if (meshToRebuild != -1) { ++numMeshes; } return targetMeshNum; }