EReimportResult::Type UReimportSpeedTreeFactory::Reimport(UObject* Obj) { #if WITH_SPEEDTREE UStaticMesh* Mesh = Cast<UStaticMesh>(Obj); if (!Mesh) { return EReimportResult::Failed; } const FString Filename = Mesh->AssetImportData->GetFirstFilename(); const FString FileExtension = FPaths::GetExtension(Filename); const bool bIsSRT = FCString::Stricmp(*FileExtension, TEXT("SRT")) == 0; if (!bIsSRT) { return EReimportResult::Failed; } if (!(Filename.Len())) { // Since this is a new system most static meshes don't have paths, so logging has been commented out //UE_LOG(LogEditorFactories, Warning, TEXT("-- cannot reimport: static mesh resource does not have path stored.")); return EReimportResult::Failed; } UE_LOG(LogEditorFactories, Log, TEXT("Performing atomic reimport of [%s]"), *Filename); bool OutCanceled = false; if (ImportObject(Mesh->GetClass(), Mesh->GetOuter(), *Mesh->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled) != nullptr) { UE_LOG(LogEditorFactories, Log, TEXT("-- imported successfully")); Mesh->AssetImportData->Update(Filename); Mesh->MarkPackageDirty(); return EReimportResult::Succeeded; } else if (OutCanceled) { UE_LOG(LogEditorFactories, Warning, TEXT("-- import canceled")); } else { UE_LOG(LogEditorFactories, Warning, TEXT("-- import failed")); } #endif // #if WITH_SPEEDTREE return EReimportResult::Failed; }
void UJanusExporterTool::Export() { TArray<UObject*> ObjectsToExport; FString Root = FString(ExportPath); // copy so we dont mess with the original reference FString Index = "<html>\n\t<head>\n\t\t<title>Unreal Export</title>\n\t</head>\n\t<body>\n\t\t<FireBoxRoom>\n\t\t\t<Assets>"; TArray<AActor*> ActorsExported; TArray<UStaticMesh*> StaticMeshesExp; TArray<FString> TexturesExp; TArray<FString> MaterialsExported; for (TObjectIterator<AActor> Itr; Itr; ++Itr) { AActor *Actor = *Itr; FString Name = Actor->GetName(); /*if (!Name.StartsWith("SM_Floor_R")) { continue; }*/ if (Actor->IsHiddenEd()) { continue; } ActorsExported.Add(Actor); TArray<UStaticMeshComponent*> StaticMeshes; Actor->GetComponents<UStaticMeshComponent>(StaticMeshes); for (int32 i = 0; i < StaticMeshes.Num(); i++) { UStaticMeshComponent* Component = StaticMeshes[i]; UStaticMesh *Mesh = Component->StaticMesh; if (!Mesh) { continue; } if (Component->LODData.Num() > 0) //if (false) { FStaticMeshComponentLODInfo* LODInfo = &Component->LODData[0]; FLightMap* LightMap = LODInfo->LightMap; FShadowMap* ShadowMap = LODInfo->ShadowMap; if (LightMap != NULL) { FLightMap2D* LightMap2D = LightMap->GetLightMap2D(); UTexture2D* Texture = LightMap2D->GetTexture(0); // 0 = HQ LightMap FString TexName = Texture->GetName(); if (TexturesExp.Contains(TexName)) { continue; } TexturesExp.Add(TexName); ExportPNG(Texture, Root); } if (ShadowMap != NULL) { FShadowMap2D* ShadowMap2D = ShadowMap->GetShadowMap2D(); UShadowMapTexture2D* ShadowTex = ShadowMap2D->GetTexture(); FString TexName = ShadowTex->GetName(); if (TexturesExp.Contains(TexName)) { continue; } TexturesExp.Add(TexName); ExportPNG(ShadowTex, Root); } } if (!StaticMeshesExp.Contains(Mesh)) { StaticMeshesExp.Add(Mesh); ExportFBX(Mesh, Root); } TArray<UMaterialInterface*> Materials = Component->GetMaterials(); for (int32 j = 0; j < Materials.Num(); j++) { UMaterialInterface* Material = Materials[j]; if (!Material) { continue; } FString MatName = Material->GetName(); if (MaterialsExported.Contains(MatName)) { continue; } MaterialsExported.Add(MatName); ExportMaterial(Root, Material, &TexturesExp); } } } // Models before textures so we can start showing the scene faster (textures take too long to load) for (int32 i = 0; i < StaticMeshesExp.Num(); i++) { UStaticMesh *mesh = StaticMeshesExp[i]; Index.Append("\n\t\t\t\t<AssetObject id=\"" + mesh->GetName() + "\" src=\"" + mesh->GetName() + ".fbx\" />"); } for (int32 i = 0; i < TexturesExp.Num(); i++) { FString Path = TexturesExp[i]; Index.Append("\n\t\t\t\t<AssetImage id=\"" + Path + "\" src=\"" + Path + ".png\" />"); } Index.Append("\n\t\t\t</Assets>\n\t\t\t<Room>"); for (int32 i = 0; i < ActorsExported.Num(); i++) { AActor *Actor = ActorsExported[i]; TArray<UStaticMeshComponent*> StaticMeshes; Actor->GetComponents<UStaticMeshComponent>(StaticMeshes); for (int32 i = 0; i < StaticMeshes.Num(); i++) { UStaticMeshComponent* Component = StaticMeshes[i]; UStaticMesh *Mesh = Component->StaticMesh; if (!Mesh) { continue; } FString ImageID = ""; TArray<UMaterialInterface*> Materials = Component->GetMaterials(); for (int32 j = 0; j < Materials.Num(); j++) { UMaterialInterface* Material = Materials[j]; if (!Material) { continue; } ImageID = Material->GetName() + "_BaseColor"; break; } if (ImageID == "") { Index.Append("\n\t\t\t\t<Object collision_id=\"" + Mesh->GetName() + "\" id=\"" + Mesh->GetName() + "\" lighting=\"true\" pos=\""); } else { Index.Append("\n\t\t\t\t<Object collision_id=\"" + Mesh->GetName() + "\" id=\"" + Mesh->GetName() + "\" image_id=\"" + ImageID + "\" lighting=\"true\" pos=\""); } FRotator Rot = Actor->GetActorRotation(); FVector XDir = Rot.RotateVector(FVector::RightVector); FVector YDir = Rot.RotateVector(FVector::UpVector); FVector ZDir = Rot.RotateVector(FVector::ForwardVector); FVector Pos = Actor->GetActorLocation() * UniformScale; FVector Sca = Actor->GetActorScale(); Pos = ChangeSpace(Pos); Sca = ChangeSpaceScalar(Sca) * UniformScale; XDir = ChangeSpace(XDir); YDir = ChangeSpace(YDir); ZDir = ChangeSpace(ZDir); FVector Sign = GetSignVector(Sca); Index.Append(FString::SanitizeFloat(Pos.X) + " " + FString::SanitizeFloat(Pos.Y) + " " + FString::SanitizeFloat(Pos.Z)); if (Sca.X < 0 || Sca.Y < 0 || Sca.Z < 0) { Index.Append("\" cull_face=\"front"); } Index.Append("\" scale=\""); Index.Append(FString::SanitizeFloat(Sca.X) + " " + FString::SanitizeFloat(Sca.Y) + " " + FString::SanitizeFloat(Sca.Z)); Index.Append("\" xdir=\""); Index.Append(FString::SanitizeFloat(XDir.X) + " " + FString::SanitizeFloat(XDir.Y) + " " + FString::SanitizeFloat(XDir.Z)); Index.Append("\" ydir=\""); Index.Append(FString::SanitizeFloat(YDir.X) + " " + FString::SanitizeFloat(YDir.Y) + " " + FString::SanitizeFloat(YDir.Z)); Index.Append("\" zdir=\""); Index.Append(FString::SanitizeFloat(ZDir.X) + " " + FString::SanitizeFloat(ZDir.Y) + " " + FString::SanitizeFloat(ZDir.Z)); Index.Append("\" />"); } } Index.Append("\n\t\t\t</Room>\n\t\t</FireBoxRoom>\n\t</body>\n</html>"); FString IndexPath = FString(ExportPath).Append("index.html"); FFileHelper::SaveStringToFile(Index, *IndexPath); }
static void StaticMeshToSlateRenderData(const UStaticMesh& DataSource, TArray<FSlateMeshVertex>& OutSlateVerts, TArray<uint32>& OutIndexes, FVector2D& OutExtentMin, FVector2D& OutExtentMax ) { OutExtentMin = FVector2D(FLT_MAX, FLT_MAX); OutExtentMax = FVector2D(-FLT_MAX, -FLT_MAX); const FStaticMeshLODResources& LOD = DataSource.RenderData->LODResources[0]; const int32 NumSections = LOD.Sections.Num(); if (NumSections > 1) { UE_LOG(LogUMG, Warning, TEXT("StaticMesh %s has %d sections. SMeshWidget expects a static mesh with 1 section."), *DataSource.GetName(), NumSections); } else { // Populate Vertex Data { const uint32 NumVerts = LOD.PositionVertexBuffer.GetNumVertices(); OutSlateVerts.Empty(); OutSlateVerts.Reserve(NumVerts); static const int32 MAX_SUPPORTED_UV_SETS = 6; const int32 TexCoordsPerVertex = LOD.GetNumTexCoords(); if (TexCoordsPerVertex > MAX_SUPPORTED_UV_SETS) { UE_LOG(LogStaticMesh, Warning, TEXT("[%s] has %d UV sets; slate vertex data supports at most %d"), *DataSource.GetName(), TexCoordsPerVertex, MAX_SUPPORTED_UV_SETS); } for (uint32 i = 0; i < NumVerts; ++i) { // Copy Position const FVector& Position = LOD.PositionVertexBuffer.VertexPosition(i); OutExtentMin.X = FMath::Min(Position.X, OutExtentMin.X); OutExtentMin.Y = FMath::Min(Position.Y, OutExtentMin.Y); OutExtentMax.X = FMath::Max(Position.X, OutExtentMax.X); OutExtentMax.Y = FMath::Max(Position.Y, OutExtentMax.Y); // Copy Color FColor Color = (LOD.ColorVertexBuffer.GetNumVertices() > 0) ? LOD.ColorVertexBuffer.VertexColor(i) : FColor::White; // Copy all the UVs that we have, and as many as we can fit. const FVector2D& UV0 = (TexCoordsPerVertex > 0) ? LOD.VertexBuffer.GetVertexUV(i, 0) : FVector2D(1, 1); const FVector2D& UV1 = (TexCoordsPerVertex > 1) ? LOD.VertexBuffer.GetVertexUV(i, 1) : FVector2D(1, 1); const FVector2D& UV2 = (TexCoordsPerVertex > 2) ? LOD.VertexBuffer.GetVertexUV(i, 2) : FVector2D(1, 1); const FVector2D& UV3 = (TexCoordsPerVertex > 3) ? LOD.VertexBuffer.GetVertexUV(i, 3) : FVector2D(1, 1); const FVector2D& UV4 = (TexCoordsPerVertex > 4) ? LOD.VertexBuffer.GetVertexUV(i, 4) : FVector2D(1, 1); const FVector2D& UV5 = (TexCoordsPerVertex > 5) ? LOD.VertexBuffer.GetVertexUV(i, 5) : FVector2D(1, 1); OutSlateVerts.Add(FSlateMeshVertex( FVector2D(Position.X, Position.Y), Color, UV0, UV1, UV2, UV3, UV4, UV5 )); } } // Populate Index data { FIndexArrayView SourceIndexes = LOD.IndexBuffer.GetArrayView(); const int32 NumIndexes = SourceIndexes.Num(); OutIndexes.Empty(); OutIndexes.Reserve(NumIndexes); for (int32 i = 0; i < NumIndexes; ++i) { OutIndexes.Add(SourceIndexes[i]); } // Sort the index buffer such that verts are drawn in Z-order. // Assume that all triangles are coplanar with Z == SomeValue. ensure(NumIndexes % 3 == 0); for (int32 a = 0; a < NumIndexes; a += 3) { for (int32 b = 0; b < NumIndexes; b += 3) { const float VertADepth = LOD.PositionVertexBuffer.VertexPosition(OutIndexes[a]).Z; const float VertBDepth = LOD.PositionVertexBuffer.VertexPosition(OutIndexes[b]).Z; if ( VertADepth < VertBDepth ) { // Swap the order in which triangles will be drawn Swap(OutIndexes[a + 0], OutIndexes[b + 0]); Swap(OutIndexes[a + 1], OutIndexes[b + 1]); Swap(OutIndexes[a + 2], OutIndexes[b + 2]); } } } } } }