void USetupDefinition::DoInstallSteps( FInstallPoll* Poll ) { guard(USetupDefinition::DoInstallSteps); // Handle all install steps. BeginSteps(); TotalBytes = 0; InstallTree( TEXT("ProcessPreCopy"), Poll, (INSTALL_STEP)ProcessPreCopy ); InstallTree( TEXT("ProcessCopy"), Poll, (INSTALL_STEP)ProcessCopy ); InstallTree( TEXT("ProcessExtra"), Poll, (INSTALL_STEP)ProcessExtra ); InstallTree( TEXT("ProcessPostCopy"), Poll, (INSTALL_STEP)ProcessPostCopy ); Exists = FolderExists = 1; RegistryFolder = DestPath; if( IsMasterProduct ) GConfig->SetString( TEXT("Setup"), TEXT("MasterProduct"), *Product, *(DestPath * TEXT("System") * SETUP_INI) ); TMultiMap<FString,FString>* Map = GConfig->GetSectionPrivate( TEXT("Setup"), 1, 0, *(DestPath * TEXT("System") * SETUP_INI) ); Map->AddUnique( TEXT("Group"), *Product ); for( TArray<FSavedIni>::TIterator It(SavedIni); It; ++It ) GConfig->SetString( *It->Section, *It->Key, *It->SavedValue, *It->File ); UninstallLogAdd( TEXT("Caption"), *LocalProduct, 1, 0 ); RootGroup->UninstallLog.Remove( TEXT("Version") ); UninstallLogAdd( TEXT("Version"), *Version, 1, 0 ); for( INT i=0; i<Requires.Num(); i++ ) { USetupProduct* SetupProduct = new(GetOuter(),*Requires(i))USetupProduct; if( SetupProduct->Product!=Product ) UninstallLogAdd( TEXT("Requires"), *SetupProduct->Product, 0, 0 ); } EndSteps(); unguard; }
void USceneCaptureComponentCube::UpdateContent() { if (World && World->Scene && IsVisible()) { // Defer until after updates finish CubedSceneCapturesToUpdateMap.AddUnique( World, this ); } }
void FBlueprintNativeCodeGenModule::CollectBoundFunctions(UBlueprint* BP) { TArray<UFunction*> Functions = IBlueprintCompilerCppBackendModule::CollectBoundFunctions(BP); for (UFunction* Func : Functions) { if (Func) { FunctionsBoundToADelegate.AddUnique(Func->GetFName(), Func->GetOwnerClass()); } } }
void USetupDefinition::ProcessPreCopy( FString Key, FString Value, UBOOL Selected, FInstallPoll* Poll ) { guard(USetupDefinition::ProcessPreCopy); if( Selected && Key==TEXT("File") ) { // Verify that file exists and is copyable. FFileInfo Info(*Value); if( Info.Lang==TEXT("") || Info.Lang==UObject::GetLanguage() ) { if( !LocateSourceFile(Info.Src) ) LocalizedFileError( TEXT("MissingInstallerFile"), Patch ? TEXT("AdviseBadDownload") : TEXT("AdviseBadMedia"), *Info.Src ); if( Info.Ref!=TEXT("") ) { FString FullRef = GetFullRef(*Info.Ref); if( GFileManager->FileSize(*FullRef)<=0 ) LocalizedFileError( TEXT("MissingReferenceFile"), TEXT("AdviseBadMedia"), *FullRef ); TotalBytes += GFileManager->FileSize(*FullRef); TotalBytes += Info.Size; } else TotalBytes += Info.Size; } } else if( Selected && Key==TEXT("SaveIni") ) { Value = Format(Value,NULL); INT Pos = Value.InStr(TEXT(",")); check(Pos>=0); FString File = DestPath * Value.Left(Pos); Value = Value.Mid(Pos+1); Pos = Value.InStr(TEXT("."),1); check(Pos>=0); FString Section = Value.Left(Pos); FString Key = Value.Mid(Pos+1); TMultiMap<FString,FString>* Map = GConfig->GetSectionPrivate( *Section, 0, 0, *File ); if( Map ) Map->AddUnique( *Key, *Value ); } unguard; }
void URuntimeMeshLibrary::CalculateTangentsForMesh(TFunction<int32(int32 Index)> IndexAccessor, TFunction<FVector(int32 Index)> VertexAccessor, TFunction<FVector2D(int32 Index)> UVAccessor, TFunction<void(int32 Index, FVector TangentX, FVector TangentY, FVector TangentZ)> TangentSetter, int32 NumVertices, int32 NumUVs, int32 NumIndices, bool bCreateSmoothNormals) { SCOPE_CYCLE_COUNTER(STAT_RuntimeMeshLibrary_CalculateTangentsForMesh); if (NumVertices == 0 || NumIndices == 0) { return; } // Calculate the duplicate vertices map if we're wanting smooth normals. Don't find duplicates if we don't want smooth normals // that will cause it to only smooth across faces sharing a common vertex, not across faces with vertices of common position const TMultiMap<uint32, uint32> DuplicateVertexMap = bCreateSmoothNormals ? FRuntimeMeshInternalUtilities::FindDuplicateVerticesMap(VertexAccessor, NumVertices) : TMultiMap<uint32, uint32>(); // Number of triangles const int32 NumTris = NumIndices / 3; // Map of vertex to triangles in Triangles array TMultiMap<uint32, uint32> VertToTriMap; // Map of vertex to triangles to consider for normal calculation TMultiMap<uint32, uint32> VertToTriSmoothMap; // Normal/tangents for each face TArray<FVector> FaceTangentX, FaceTangentY, FaceTangentZ; FaceTangentX.AddUninitialized(NumTris); FaceTangentY.AddUninitialized(NumTris); FaceTangentZ.AddUninitialized(NumTris); // Iterate over triangles for (int TriIdx = 0; TriIdx < NumTris; TriIdx++) { uint32 CornerIndex[3]; FVector P[3]; for (int32 CornerIdx = 0; CornerIdx < 3; CornerIdx++) { // Find vert index (clamped within range) uint32 VertIndex = FMath::Min(IndexAccessor((TriIdx * 3) + CornerIdx), NumVertices - 1); CornerIndex[CornerIdx] = VertIndex; P[CornerIdx] = VertexAccessor(VertIndex); // Find/add this vert to index buffer TArray<uint32> VertOverlaps; DuplicateVertexMap.MultiFind(VertIndex, VertOverlaps); // Remember which triangles map to this vert VertToTriMap.AddUnique(VertIndex, TriIdx); VertToTriSmoothMap.AddUnique(VertIndex, TriIdx); // Also update map of triangles that 'overlap' this vert (ie don't match UV, but do match smoothing) and should be considered when calculating normal for (int32 OverlapIdx = 0; OverlapIdx < VertOverlaps.Num(); OverlapIdx++) { // For each vert we overlap.. int32 OverlapVertIdx = VertOverlaps[OverlapIdx]; // Add this triangle to that vert VertToTriSmoothMap.AddUnique(OverlapVertIdx, TriIdx); // And add all of its triangles to us TArray<uint32> OverlapTris; VertToTriMap.MultiFind(OverlapVertIdx, OverlapTris); for (int32 OverlapTriIdx = 0; OverlapTriIdx < OverlapTris.Num(); OverlapTriIdx++) { VertToTriSmoothMap.AddUnique(VertIndex, OverlapTris[OverlapTriIdx]); } } } // Calculate triangle edge vectors and normal const FVector Edge21 = P[1] - P[2]; const FVector Edge20 = P[0] - P[2]; const FVector TriNormal = (Edge21 ^ Edge20).GetSafeNormal(); // If we have UVs, use those to calculate if (NumUVs == NumVertices) { const FVector2D T1 = UVAccessor(CornerIndex[0]); const FVector2D T2 = UVAccessor(CornerIndex[1]); const FVector2D T3 = UVAccessor(CornerIndex[2]); // float X1 = P[1].X - P[0].X; // float X2 = P[2].X - P[0].X; // float Y1 = P[1].Y - P[0].Y; // float Y2 = P[2].Y - P[0].Y; // float Z1 = P[1].Z - P[0].Z; // float Z2 = P[2].Z - P[0].Z; // // float S1 = U1.X - U0.X; // float S2 = U2.X - U0.X; // float T1 = U1.Y - U0.Y; // float T2 = U2.Y - U0.Y; // // float R = 1.0f / (S1 * T2 - S2 * T1); // FaceTangentX[TriIdx] = FVector((T2 * X1 - T1 * X2) * R, (T2 * Y1 - T1 * Y2) * R, // (T2 * Z1 - T1 * Z2) * R); // FaceTangentY[TriIdx] = FVector((S1 * X2 - S2 * X1) * R, (S1 * Y2 - S2 * Y1) * R, // (S1 * Z2 - S2 * Z1) * R); FMatrix ParameterToLocal( FPlane(P[1].X - P[0].X, P[1].Y - P[0].Y, P[1].Z - P[0].Z, 0), FPlane(P[2].X - P[0].X, P[2].Y - P[0].Y, P[2].Z - P[0].Z, 0), FPlane(P[0].X, P[0].Y, P[0].Z, 0), FPlane(0, 0, 0, 1) ); FMatrix ParameterToTexture( FPlane(T2.X - T1.X, T2.Y - T1.Y, 0, 0), FPlane(T3.X - T1.X, T3.Y - T1.Y, 0, 0), FPlane(T1.X, T1.Y, 1, 0), FPlane(0, 0, 0, 1) ); // Use InverseSlow to catch singular matrices. Inverse can miss this sometimes. const FMatrix TextureToLocal = ParameterToTexture.Inverse() * ParameterToLocal; FaceTangentX[TriIdx] = TextureToLocal.TransformVector(FVector(1, 0, 0)).GetSafeNormal(); FaceTangentY[TriIdx] = TextureToLocal.TransformVector(FVector(0, 1, 0)).GetSafeNormal(); } else { FaceTangentX[TriIdx] = Edge20.GetSafeNormal(); FaceTangentY[TriIdx] = (FaceTangentX[TriIdx] ^ TriNormal).GetSafeNormal(); } FaceTangentZ[TriIdx] = TriNormal; } // Arrays to accumulate tangents into TArray<FVector> VertexTangentXSum, VertexTangentYSum, VertexTangentZSum; VertexTangentXSum.AddZeroed(NumVertices); VertexTangentYSum.AddZeroed(NumVertices); VertexTangentZSum.AddZeroed(NumVertices); // For each vertex.. for (int VertxIdx = 0; VertxIdx < NumVertices; VertxIdx++) { // Find relevant triangles for normal TArray<uint32> SmoothTris; VertToTriSmoothMap.MultiFind(VertxIdx, SmoothTris); for (int i = 0; i < SmoothTris.Num(); i++) { uint32 TriIdx = SmoothTris[i]; VertexTangentZSum[VertxIdx] += FaceTangentZ[TriIdx]; } // Find relevant triangles for tangents TArray<uint32> TangentTris; VertToTriMap.MultiFind(VertxIdx, TangentTris); for (int i = 0; i < TangentTris.Num(); i++) { uint32 TriIdx = TangentTris[i]; VertexTangentXSum[VertxIdx] += FaceTangentX[TriIdx]; VertexTangentYSum[VertxIdx] += FaceTangentY[TriIdx]; } } // Finally, normalize tangents and build output arrays for (int VertxIdx = 0; VertxIdx < NumVertices; VertxIdx++) { FVector& TangentX = VertexTangentXSum[VertxIdx]; FVector& TangentY = VertexTangentYSum[VertxIdx]; FVector& TangentZ = VertexTangentZSum[VertxIdx]; TangentX.Normalize(); //TangentY.Normalize(); TangentZ.Normalize(); // Use Gram-Schmidt orthogonalization to make sure X is orthonormal with Z TangentX -= TangentZ * (TangentZ | TangentX); TangentX.Normalize(); TangentY.Normalize(); TangentSetter(VertxIdx, TangentX, TangentY, TangentZ); } }