596 lines
26 KiB
C++
596 lines
26 KiB
C++
// Copyright 2016 Mookie. All Rights Reserved.
|
|
|
|
#include "EBJsonImportExportTool.h"
|
|
#include "Widgets/Layout/SBorder.h"
|
|
#include "Widgets/Layout/SBox.h"
|
|
#include "Widgets/Layout/SScrollBox.h"
|
|
#include "Widgets/Text/STextBlock.h"
|
|
#include "Widgets/Input/SButton.h"
|
|
#include "Widgets/Layout/SUniformGridPanel.h"
|
|
#include "Framework/Application/SlateApplication.h"
|
|
#include "DesktopPlatformModule.h"
|
|
#include "Json.h"
|
|
#include "Engine/Engine.h"
|
|
#include "AssetToolsModule.h"
|
|
#include "ContentBrowserModule.h"
|
|
#include "IContentBrowserSingleton.h"
|
|
#include "Framework/Docking/TabManager.h"
|
|
#include "WorkspaceMenuStructure.h"
|
|
#include "WorkspaceMenuStructureModule.h"
|
|
#include "ToolMenus.h"
|
|
#include "HAL/IConsoleManager.h"
|
|
|
|
const FName FEBJsonImportExportTool::ImportExportTabName("EBJsonImportExport");
|
|
|
|
// Console command to open the tool
|
|
static FAutoConsoleCommand OpenJsonToolCommand(
|
|
TEXT("EasyBallistics.OpenJsonTool"),
|
|
TEXT("Opens the EasyBallistics JSON Import/Export tool"),
|
|
FConsoleCommandDelegate::CreateStatic(&FEBJsonImportExportTool::OpenImportExportWindow)
|
|
);
|
|
|
|
void SEBJsonImportExportTool::Construct(const FArguments& InArgs)
|
|
{
|
|
ChildSlot
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
[
|
|
SNew(SScrollBox)
|
|
+ SScrollBox::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.Padding(10.0f)
|
|
[
|
|
SNew(SVerticalBox)
|
|
|
|
// Title
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0, 0, 0, 20)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(FText::FromString("EasyBallistics JSON Import/Export Tool"))
|
|
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 16))
|
|
.Justification(ETextJustify::Center)
|
|
]
|
|
|
|
// Bullet Properties Section
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0, 0, 0, 15)
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("DetailsView.CategoryTop"))
|
|
.Padding(10)
|
|
[
|
|
SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(FText::FromString("Bullet Properties"))
|
|
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 14))
|
|
]
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0, 10, 0, 0)
|
|
[
|
|
SNew(SUniformGridPanel)
|
|
.SlotPadding(5)
|
|
+ SUniformGridPanel::Slot(0, 0)
|
|
[
|
|
SNew(SButton)
|
|
.Text(FText::FromString("Export Bullet Properties"))
|
|
.OnClicked(this, &SEBJsonImportExportTool::OnExportBulletPropertiesClicked)
|
|
]
|
|
+ SUniformGridPanel::Slot(1, 0)
|
|
[
|
|
SNew(SButton)
|
|
.Text(FText::FromString("Import Bullet Properties"))
|
|
.OnClicked(this, &SEBJsonImportExportTool::OnImportBulletPropertiesClicked)
|
|
]
|
|
]
|
|
]
|
|
]
|
|
|
|
// Material Response Section
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0, 0, 0, 15)
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("DetailsView.CategoryTop"))
|
|
.Padding(10)
|
|
[
|
|
SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(FText::FromString("Material Response Maps"))
|
|
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 14))
|
|
]
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0, 10, 0, 0)
|
|
[
|
|
SNew(SUniformGridPanel)
|
|
.SlotPadding(5)
|
|
+ SUniformGridPanel::Slot(0, 0)
|
|
[
|
|
SNew(SButton)
|
|
.Text(FText::FromString("Export Material Response"))
|
|
.OnClicked(this, &SEBJsonImportExportTool::OnExportMaterialResponseClicked)
|
|
]
|
|
+ SUniformGridPanel::Slot(1, 0)
|
|
[
|
|
SNew(SButton)
|
|
.Text(FText::FromString("Import Material Response"))
|
|
.OnClicked(this, &SEBJsonImportExportTool::OnImportMaterialResponseClicked)
|
|
]
|
|
]
|
|
]
|
|
]
|
|
|
|
// Status Section
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0, 20, 0, 0)
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("DetailsView.CategoryBottom"))
|
|
.Padding(10)
|
|
[
|
|
SAssignNew(StatusText, STextBlock)
|
|
.Text(FText::FromString("Ready"))
|
|
.AutoWrapText(true)
|
|
]
|
|
]
|
|
]
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
FReply SEBJsonImportExportTool::OnExportBulletPropertiesClicked()
|
|
{
|
|
FString Filename;
|
|
if (SaveFileDialog("Export Bullet Properties", "", "JSON Files (*.json)|*.json", Filename))
|
|
{
|
|
// For demo purposes, create default bullet properties
|
|
FMathematicalBulletProperties DefaultProperties;
|
|
|
|
TSharedPtr<FJsonObject> JsonObject = BulletPropertiesToJson(DefaultProperties);
|
|
|
|
FString OutputString;
|
|
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutputString);
|
|
FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer);
|
|
|
|
if (FFileHelper::SaveStringToFile(OutputString, *Filename))
|
|
{
|
|
UpdateStatus(FString::Printf(TEXT("Successfully exported bullet properties to: %s"), *Filename));
|
|
}
|
|
else
|
|
{
|
|
UpdateStatus(TEXT("Failed to save bullet properties file."));
|
|
}
|
|
}
|
|
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SEBJsonImportExportTool::OnImportBulletPropertiesClicked()
|
|
{
|
|
FString Filename;
|
|
if (OpenFileDialog("Import Bullet Properties", "", "JSON Files (*.json)|*.json", Filename))
|
|
{
|
|
FString FileContent;
|
|
if (FFileHelper::LoadFileToString(FileContent, *Filename))
|
|
{
|
|
TSharedPtr<FJsonObject> JsonObject;
|
|
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(FileContent);
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
|
|
{
|
|
FMathematicalBulletProperties ImportedProperties;
|
|
if (JsonToBulletProperties(JsonObject, ImportedProperties))
|
|
{
|
|
UpdateStatus(FString::Printf(TEXT("Successfully imported bullet properties from: %s"), *Filename));
|
|
// Here you would typically create a new asset or update an existing one
|
|
}
|
|
else
|
|
{
|
|
UpdateStatus(TEXT("Failed to parse bullet properties from JSON."));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UpdateStatus(TEXT("Failed to parse JSON file."));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UpdateStatus(TEXT("Failed to load file."));
|
|
}
|
|
}
|
|
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SEBJsonImportExportTool::OnExportMaterialResponseClicked()
|
|
{
|
|
FString Filename;
|
|
if (SaveFileDialog("Export Material Response", "", "JSON Files (*.json)|*.json", Filename))
|
|
{
|
|
// For demo purposes, create default material response
|
|
FEBMaterialResponseMapEntry DefaultEntry;
|
|
|
|
TSharedPtr<FJsonObject> JsonObject = MaterialResponseToJson(DefaultEntry);
|
|
|
|
FString OutputString;
|
|
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutputString);
|
|
FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer);
|
|
|
|
if (FFileHelper::SaveStringToFile(OutputString, *Filename))
|
|
{
|
|
UpdateStatus(FString::Printf(TEXT("Successfully exported material response to: %s"), *Filename));
|
|
}
|
|
else
|
|
{
|
|
UpdateStatus(TEXT("Failed to save material response file."));
|
|
}
|
|
}
|
|
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SEBJsonImportExportTool::OnImportMaterialResponseClicked()
|
|
{
|
|
FString Filename;
|
|
if (OpenFileDialog("Import Material Response", "", "JSON Files (*.json)|*.json", Filename))
|
|
{
|
|
FString FileContent;
|
|
if (FFileHelper::LoadFileToString(FileContent, *Filename))
|
|
{
|
|
TSharedPtr<FJsonObject> JsonObject;
|
|
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(FileContent);
|
|
|
|
if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
|
|
{
|
|
FEBMaterialResponseMapEntry ImportedEntry;
|
|
if (JsonToMaterialResponse(JsonObject, ImportedEntry))
|
|
{
|
|
UpdateStatus(FString::Printf(TEXT("Successfully imported material response from: %s"), *Filename));
|
|
// Here you would typically create a new asset or update an existing one
|
|
}
|
|
else
|
|
{
|
|
UpdateStatus(TEXT("Failed to parse material response from JSON."));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UpdateStatus(TEXT("Failed to parse JSON file."));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UpdateStatus(TEXT("Failed to load file."));
|
|
}
|
|
}
|
|
|
|
return FReply::Handled();
|
|
}
|
|
|
|
bool SEBJsonImportExportTool::OpenFileDialog(const FString& DialogTitle, const FString& DefaultPath, const FString& FileTypes, FString& OutFilename)
|
|
{
|
|
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
|
|
if (DesktopPlatform)
|
|
{
|
|
TArray<FString> OutFilenames;
|
|
bool bOpened = DesktopPlatform->OpenFileDialog(
|
|
FSlateApplication::Get().FindBestParentWindowHandleForDialogs(nullptr),
|
|
DialogTitle,
|
|
DefaultPath,
|
|
TEXT(""),
|
|
FileTypes,
|
|
EFileDialogFlags::None,
|
|
OutFilenames
|
|
);
|
|
|
|
if (bOpened && OutFilenames.Num() > 0)
|
|
{
|
|
OutFilename = OutFilenames[0];
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool SEBJsonImportExportTool::SaveFileDialog(const FString& DialogTitle, const FString& DefaultPath, const FString& FileTypes, FString& OutFilename)
|
|
{
|
|
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
|
|
if (DesktopPlatform)
|
|
{
|
|
TArray<FString> OutFilenames;
|
|
bool bOpened = DesktopPlatform->SaveFileDialog(
|
|
FSlateApplication::Get().FindBestParentWindowHandleForDialogs(nullptr),
|
|
DialogTitle,
|
|
DefaultPath,
|
|
TEXT(""),
|
|
FileTypes,
|
|
EFileDialogFlags::None,
|
|
OutFilenames
|
|
);
|
|
|
|
if (bOpened && OutFilenames.Num() > 0)
|
|
{
|
|
OutFilename = OutFilenames[0];
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
TSharedPtr<FJsonObject> SEBJsonImportExportTool::BulletPropertiesToJson(const FMathematicalBulletProperties& Properties)
|
|
{
|
|
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
|
|
|
|
// Basic Properties
|
|
JsonObject->SetNumberField("GrainWeight", Properties.GrainWeight);
|
|
JsonObject->SetNumberField("DiameterInches", Properties.DiameterInches);
|
|
JsonObject->SetNumberField("LengthInches", Properties.LengthInches);
|
|
JsonObject->SetNumberField("BulletType", static_cast<int32>(Properties.BulletType));
|
|
JsonObject->SetNumberField("BulletMaterial", static_cast<int32>(Properties.BulletMaterial));
|
|
|
|
// Ballistics
|
|
JsonObject->SetNumberField("BallisticCoefficientG1", Properties.BallisticCoefficientG1);
|
|
JsonObject->SetNumberField("BallisticCoefficientG7", Properties.BallisticCoefficientG7);
|
|
JsonObject->SetBoolField("UseG7Model", Properties.UseG7Model);
|
|
JsonObject->SetNumberField("SectionalDensity", Properties.SectionalDensity);
|
|
|
|
// Penetration
|
|
JsonObject->SetNumberField("BulletHardness", Properties.BulletHardness);
|
|
JsonObject->SetNumberField("PenetrationEnergyThreshold", Properties.PenetrationEnergyThreshold);
|
|
JsonObject->SetNumberField("ExpansionVelocityThreshold", Properties.ExpansionVelocityThreshold);
|
|
JsonObject->SetNumberField("MaxExpansionMultiplier", Properties.MaxExpansionMultiplier);
|
|
|
|
return JsonObject;
|
|
}
|
|
|
|
bool SEBJsonImportExportTool::JsonToBulletProperties(const TSharedPtr<FJsonObject>& JsonObject, FMathematicalBulletProperties& OutProperties)
|
|
{
|
|
if (!JsonObject.IsValid())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Basic Properties
|
|
OutProperties.GrainWeight = JsonObject->GetNumberField(TEXT("GrainWeight"));
|
|
OutProperties.DiameterInches = JsonObject->GetNumberField(TEXT("DiameterInches"));
|
|
OutProperties.LengthInches = JsonObject->GetNumberField(TEXT("LengthInches"));
|
|
OutProperties.BulletType = static_cast<EBulletType>(JsonObject->GetIntegerField(TEXT("BulletType")));
|
|
OutProperties.BulletMaterial = static_cast<EBulletMaterial>(JsonObject->GetIntegerField(TEXT("BulletMaterial")));
|
|
|
|
// Ballistics
|
|
OutProperties.BallisticCoefficientG1 = JsonObject->GetNumberField(TEXT("BallisticCoefficientG1"));
|
|
OutProperties.BallisticCoefficientG7 = JsonObject->GetNumberField(TEXT("BallisticCoefficientG7"));
|
|
OutProperties.UseG7Model = JsonObject->GetBoolField(TEXT("UseG7Model"));
|
|
OutProperties.SectionalDensity = JsonObject->GetNumberField(TEXT("SectionalDensity"));
|
|
|
|
// Penetration
|
|
OutProperties.BulletHardness = JsonObject->GetNumberField(TEXT("BulletHardness"));
|
|
OutProperties.PenetrationEnergyThreshold = JsonObject->GetNumberField(TEXT("PenetrationEnergyThreshold"));
|
|
OutProperties.ExpansionVelocityThreshold = JsonObject->GetNumberField(TEXT("ExpansionVelocityThreshold"));
|
|
OutProperties.MaxExpansionMultiplier = JsonObject->GetNumberField(TEXT("MaxExpansionMultiplier"));
|
|
|
|
return true;
|
|
}
|
|
|
|
TSharedPtr<FJsonObject> SEBJsonImportExportTool::MaterialResponseToJson(const FEBMaterialResponseMapEntry& Entry)
|
|
{
|
|
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
|
|
|
|
// Artistic Properties
|
|
JsonObject->SetNumberField("PenTraceType", static_cast<int32>(Entry.PenTraceType));
|
|
JsonObject->SetBoolField("NeverPenetrate", Entry.NeverPenetrate);
|
|
JsonObject->SetNumberField("PenetrationDepthMultiplier", Entry.PenetrationDepthMultiplier);
|
|
JsonObject->SetNumberField("PenetrationNormalization", Entry.PenetrationNormalization);
|
|
JsonObject->SetNumberField("PenetrationNormalizationGrazing", Entry.PenetrationNormalizationGrazing);
|
|
JsonObject->SetNumberField("PenetrationEntryAngleSpread", Entry.PenetrationEntryAngleSpread);
|
|
JsonObject->SetNumberField("PenetrationExitAngleSpread", Entry.PenetrationExitAngleSpread);
|
|
JsonObject->SetBoolField("NeverRicochet", Entry.NeverRicochet);
|
|
JsonObject->SetNumberField("RicochetProbabilityMultiplier", Entry.RicochetProbabilityMultiplier);
|
|
JsonObject->SetNumberField("RicochetRestitution", Entry.RicochetRestitution);
|
|
JsonObject->SetNumberField("RicochetRestitutionInfluence", Entry.RicochetRestitutionInfluence);
|
|
JsonObject->SetNumberField("RicochetFriction", Entry.RicochetFriction);
|
|
JsonObject->SetNumberField("RicochetFrictionInfluence", Entry.RicochetFrictionInfluence);
|
|
JsonObject->SetNumberField("RicochetSpread", Entry.RicochetSpread);
|
|
|
|
// Spalling Properties
|
|
JsonObject->SetBoolField("EnableSpalling", Entry.EnableSpalling);
|
|
JsonObject->SetNumberField("SpallVelocityThreshold", Entry.SpallVelocityThreshold);
|
|
JsonObject->SetNumberField("SpallFragmentCount", Entry.SpallFragmentCount);
|
|
JsonObject->SetNumberField("SpallSpreadAngle", Entry.SpallSpreadAngle);
|
|
JsonObject->SetNumberField("SpallVelocityMultiplier", Entry.SpallVelocityMultiplier);
|
|
JsonObject->SetNumberField("SpallMassMultiplier", Entry.SpallMassMultiplier);
|
|
|
|
// Mathematical Properties
|
|
JsonObject->SetBoolField("UseMathematicalProperties", Entry.UseMathematicalProperties);
|
|
if (Entry.UseMathematicalProperties)
|
|
{
|
|
TSharedPtr<FJsonObject> MathProps = MaterialPropertiesToJson(Entry.MathematicalProperties);
|
|
JsonObject->SetObjectField("MathematicalProperties", MathProps);
|
|
}
|
|
|
|
return JsonObject;
|
|
}
|
|
|
|
bool SEBJsonImportExportTool::JsonToMaterialResponse(const TSharedPtr<FJsonObject>& JsonObject, FEBMaterialResponseMapEntry& OutEntry)
|
|
{
|
|
if (!JsonObject.IsValid())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Artistic Properties
|
|
OutEntry.PenTraceType = static_cast<EPenTraceType>(JsonObject->GetIntegerField(TEXT("PenTraceType")));
|
|
OutEntry.NeverPenetrate = JsonObject->GetBoolField(TEXT("NeverPenetrate"));
|
|
OutEntry.PenetrationDepthMultiplier = JsonObject->GetNumberField(TEXT("PenetrationDepthMultiplier"));
|
|
OutEntry.PenetrationNormalization = JsonObject->GetNumberField(TEXT("PenetrationNormalization"));
|
|
OutEntry.PenetrationNormalizationGrazing = JsonObject->GetNumberField(TEXT("PenetrationNormalizationGrazing"));
|
|
OutEntry.PenetrationEntryAngleSpread = JsonObject->GetNumberField(TEXT("PenetrationEntryAngleSpread"));
|
|
OutEntry.PenetrationExitAngleSpread = JsonObject->GetNumberField(TEXT("PenetrationExitAngleSpread"));
|
|
OutEntry.NeverRicochet = JsonObject->GetBoolField(TEXT("NeverRicochet"));
|
|
OutEntry.RicochetProbabilityMultiplier = JsonObject->GetNumberField(TEXT("RicochetProbabilityMultiplier"));
|
|
OutEntry.RicochetRestitution = JsonObject->GetNumberField(TEXT("RicochetRestitution"));
|
|
OutEntry.RicochetRestitutionInfluence = JsonObject->GetNumberField(TEXT("RicochetRestitutionInfluence"));
|
|
OutEntry.RicochetFriction = JsonObject->GetNumberField(TEXT("RicochetFriction"));
|
|
OutEntry.RicochetFrictionInfluence = JsonObject->GetNumberField(TEXT("RicochetFrictionInfluence"));
|
|
OutEntry.RicochetSpread = JsonObject->GetNumberField(TEXT("RicochetSpread"));
|
|
|
|
// Spalling Properties
|
|
OutEntry.EnableSpalling = JsonObject->GetBoolField(TEXT("EnableSpalling"));
|
|
OutEntry.SpallVelocityThreshold = JsonObject->GetNumberField(TEXT("SpallVelocityThreshold"));
|
|
OutEntry.SpallFragmentCount = JsonObject->GetIntegerField(TEXT("SpallFragmentCount"));
|
|
OutEntry.SpallSpreadAngle = JsonObject->GetNumberField(TEXT("SpallSpreadAngle"));
|
|
OutEntry.SpallVelocityMultiplier = JsonObject->GetNumberField(TEXT("SpallVelocityMultiplier"));
|
|
OutEntry.SpallMassMultiplier = JsonObject->GetNumberField(TEXT("SpallMassMultiplier"));
|
|
|
|
// Mathematical Properties
|
|
OutEntry.UseMathematicalProperties = JsonObject->GetBoolField(TEXT("UseMathematicalProperties"));
|
|
if (OutEntry.UseMathematicalProperties)
|
|
{
|
|
const TSharedPtr<FJsonObject>* MathPropsPtr;
|
|
if (JsonObject->TryGetObjectField(TEXT("MathematicalProperties"), MathPropsPtr))
|
|
{
|
|
JsonToMaterialProperties(*MathPropsPtr, OutEntry.MathematicalProperties);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
TSharedPtr<FJsonObject> SEBJsonImportExportTool::MaterialPropertiesToJson(const FMathematicalMaterialProperties& Properties)
|
|
{
|
|
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
|
|
|
|
// Material Properties
|
|
JsonObject->SetNumberField("DensityGPerCm3", Properties.DensityGPerCm3);
|
|
JsonObject->SetNumberField("MaterialHardness", Properties.MaterialHardness);
|
|
JsonObject->SetNumberField("TensileStrengthMPa", Properties.TensileStrengthMPa);
|
|
JsonObject->SetNumberField("YieldStrengthMPa", Properties.YieldStrengthMPa);
|
|
JsonObject->SetNumberField("ElasticModulusGPa", Properties.ElasticModulusGPa);
|
|
|
|
// Ballistic Properties
|
|
JsonObject->SetNumberField("BallisticLimitVelocity", Properties.BallisticLimitVelocity);
|
|
JsonObject->SetNumberField("PerforationCoefficient", Properties.PerforationCoefficient);
|
|
JsonObject->SetNumberField("EnergyAbsorptionCoefficient", Properties.EnergyAbsorptionCoefficient);
|
|
|
|
// Spalling Properties
|
|
JsonObject->SetBoolField("EnableMathematicalSpalling", Properties.EnableMathematicalSpalling);
|
|
JsonObject->SetNumberField("SpallStrengthMPa", Properties.SpallStrengthMPa);
|
|
JsonObject->SetNumberField("CriticalStressFactor", Properties.CriticalStressFactor);
|
|
JsonObject->SetNumberField("FragmentVelocityEfficiency", Properties.FragmentVelocityEfficiency);
|
|
JsonObject->SetNumberField("AverageFragmentMassRatio", Properties.AverageFragmentMassRatio);
|
|
JsonObject->SetNumberField("FragmentSizeExponent", Properties.FragmentSizeExponent);
|
|
JsonObject->SetNumberField("MaxFragmentDensity", Properties.MaxFragmentDensity);
|
|
|
|
return JsonObject;
|
|
}
|
|
|
|
bool SEBJsonImportExportTool::JsonToMaterialProperties(const TSharedPtr<FJsonObject>& JsonObject, FMathematicalMaterialProperties& OutProperties)
|
|
{
|
|
if (!JsonObject.IsValid())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Material Properties
|
|
OutProperties.DensityGPerCm3 = JsonObject->GetNumberField(TEXT("DensityGPerCm3"));
|
|
OutProperties.MaterialHardness = JsonObject->GetNumberField(TEXT("MaterialHardness"));
|
|
OutProperties.TensileStrengthMPa = JsonObject->GetNumberField(TEXT("TensileStrengthMPa"));
|
|
OutProperties.YieldStrengthMPa = JsonObject->GetNumberField(TEXT("YieldStrengthMPa"));
|
|
OutProperties.ElasticModulusGPa = JsonObject->GetNumberField(TEXT("ElasticModulusGPa"));
|
|
|
|
// Ballistic Properties
|
|
OutProperties.BallisticLimitVelocity = JsonObject->GetNumberField(TEXT("BallisticLimitVelocity"));
|
|
OutProperties.PerforationCoefficient = JsonObject->GetNumberField(TEXT("PerforationCoefficient"));
|
|
OutProperties.EnergyAbsorptionCoefficient = JsonObject->GetNumberField(TEXT("EnergyAbsorptionCoefficient"));
|
|
|
|
// Spalling Properties
|
|
OutProperties.EnableMathematicalSpalling = JsonObject->GetBoolField(TEXT("EnableMathematicalSpalling"));
|
|
OutProperties.SpallStrengthMPa = JsonObject->GetNumberField(TEXT("SpallStrengthMPa"));
|
|
OutProperties.CriticalStressFactor = JsonObject->GetNumberField(TEXT("CriticalStressFactor"));
|
|
OutProperties.FragmentVelocityEfficiency = JsonObject->GetNumberField(TEXT("FragmentVelocityEfficiency"));
|
|
OutProperties.AverageFragmentMassRatio = JsonObject->GetNumberField(TEXT("AverageFragmentMassRatio"));
|
|
OutProperties.FragmentSizeExponent = JsonObject->GetNumberField(TEXT("FragmentSizeExponent"));
|
|
OutProperties.MaxFragmentDensity = JsonObject->GetNumberField(TEXT("MaxFragmentDensity"));
|
|
|
|
return true;
|
|
}
|
|
|
|
void SEBJsonImportExportTool::UpdateStatus(const FString& Message)
|
|
{
|
|
if (StatusText.IsValid())
|
|
{
|
|
StatusText->SetText(FText::FromString(Message));
|
|
}
|
|
}
|
|
|
|
// FEBJsonImportExportTool implementation
|
|
|
|
void FEBJsonImportExportTool::RegisterMenus()
|
|
{
|
|
// Register the tab spawner
|
|
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(ImportExportTabName, FOnSpawnTab::CreateStatic(&FEBJsonImportExportTool::OnSpawnImportExportTab))
|
|
.SetDisplayName(NSLOCTEXT("EasyBallisticsEditor", "ImportExportTabTitle", "Ballistics JSON Import/Export"))
|
|
.SetMenuType(ETabSpawnerMenuType::Hidden);
|
|
|
|
// Add to main menu bar under Tools
|
|
UToolMenus* ToolMenus = UToolMenus::Get();
|
|
{
|
|
UToolMenu* MainMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Tools");
|
|
{
|
|
FToolMenuSection& Section = MainMenu->FindOrAddSection("Programming");
|
|
Section.AddMenuEntry(
|
|
"OpenEBJsonImportExport",
|
|
NSLOCTEXT("EasyBallisticsEditor", "OpenEBJsonImportExport", "Ballistics JSON Import/Export"),
|
|
NSLOCTEXT("EasyBallisticsEditor", "OpenEBJsonImportExportTooltip", "Open the Ballistics JSON Import/Export tool"),
|
|
FSlateIcon(),
|
|
FUIAction(FExecuteAction::CreateStatic(&FEBJsonImportExportTool::OpenImportExportWindow))
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FEBJsonImportExportTool::OpenImportExportWindow()
|
|
{
|
|
// Ensure the tab spawner is registered
|
|
if (!FGlobalTabmanager::Get()->HasTabSpawner(ImportExportTabName))
|
|
{
|
|
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(ImportExportTabName, FOnSpawnTab::CreateStatic(&FEBJsonImportExportTool::OnSpawnImportExportTab))
|
|
.SetDisplayName(NSLOCTEXT("EasyBallisticsEditor", "ImportExportTabTitle", "Ballistics JSON Import/Export"))
|
|
.SetMenuType(ETabSpawnerMenuType::Hidden);
|
|
}
|
|
|
|
FGlobalTabmanager::Get()->TryInvokeTab(ImportExportTabName);
|
|
}
|
|
|
|
void FEBJsonImportExportTool::UnregisterMenus()
|
|
{
|
|
if (FGlobalTabmanager::Get()->HasTabSpawner(ImportExportTabName))
|
|
{
|
|
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(ImportExportTabName);
|
|
}
|
|
}
|
|
|
|
TSharedRef<SDockTab> FEBJsonImportExportTool::OnSpawnImportExportTab(const FSpawnTabArgs& SpawnTabArgs)
|
|
{
|
|
return SNew(SDockTab)
|
|
.TabRole(ETabRole::NomadTab)
|
|
[
|
|
SNew(SEBJsonImportExportTool)
|
|
];
|
|
} |