From 17bdb945d5d99e1fd09285a58fb33892a2e58da4 Mon Sep 17 00:00:00 2001 From: wada Date: Thu, 5 Dec 2024 11:11:58 +0900 Subject: [PATCH] Update to Cubism 5 SDK for Unreal Engine R1 alpha4 --- CHANGELOG.md | 14 ++++ Live2DCubismSDK.uplugin | 2 +- NOTICE.ja.md | 12 +-- NOTICE.md | 14 +--- README.ja.md | 1 - README.md | 1 - .../DisplayInfo/CubismDisplayInfo3Json.cpp | 42 ++++++++++ .../Private/Expression/CubismExp3Json.cpp | 42 ++++++++++ .../Private/Model/CubismMoc.cpp | 33 ++++++++ .../Private/Model/CubismModel3Json.cpp | 42 ++++++++++ .../Private/Motion/CubismMotion3Json.cpp | 42 ++++++++++ .../Private/Physics/CubismPhysics3Json.cpp | 42 ++++++++++ .../Private/Pose/CubismPose3Json.cpp | 42 ++++++++++ .../Private/UserData/CubismUserData3Json.cpp | 42 ++++++++++ .../DisplayInfo/CubismDisplayInfo3Json.h | 14 ++++ .../Public/Expression/CubismExp3Json.h | 13 +++ .../Public/Model/CubismMoc3.h | 13 +++ .../Public/Model/CubismModel3Json.h | 14 ++++ .../Public/Motion/CubismMotion3Json.h | 14 ++++ .../Public/Physics/CubismPhysics3Json.h | 14 ++++ .../Public/Pose/CubismPose3Json.h | 14 ++++ .../Public/UserData/CubismUserData3Json.h | 14 ++++ .../Private/CubismModelActorFactory.cpp | 14 +++- .../Live2DCubismFrameworkImporter.Build.cs | 1 + .../AssetDefinition_CubismDisplayInfo3Json.h | 29 +++++++ .../CubismDisplayInfo3JsonFactory.cpp | 81 ++++++++++++++++++- .../CubismDisplayInfo3JsonFactory.h | 10 ++- .../AssetDefinition_CubismExp3Json.h | 29 +++++++ .../Expression/CubismExp3JsonFactory.cpp | 80 +++++++++++++++++- .../Expression/CubismExp3JsonFactory.h | 10 ++- .../Private/Moc/AssetDefinition_CubismMoc3.h | 29 +++++++ .../Private/Moc/CubismMoc3Factory.cpp | 71 +++++++++++++++- .../Private/Moc/CubismMoc3Factory.h | 10 ++- .../Model/AssetDefinition_CubismModel3Json.h | 29 +++++++ .../Private/Model/CubismModel3JsonFactory.cpp | 81 +++++++++++++++++++ .../Private/Model/CubismModel3JsonFactory.h | 12 ++- .../AssetDefinition_CubismMotion3Json.h | 29 +++++++ .../Motion/CubismMotion3JsonFactory.cpp | 79 ++++++++++++++++++ .../Private/Motion/CubismMotion3JsonFactory.h | 10 ++- .../Motion/CubismMotion3JsonImporter.cpp | 36 ++++++++- .../Motion/CubismMotion3JsonImporter.h | 10 ++- .../AssetDefinition_CubismPhysics3Json.h | 29 +++++++ .../Physics/CubismPhysics3JsonFactory.cpp | 79 ++++++++++++++++++ .../Physics/CubismPhysics3JsonFactory.h | 11 ++- .../Pose/AssetDefinition_CubismPose3Json.h | 29 +++++++ .../Private/Pose/CubismPose3JsonFactory.cpp | 81 ++++++++++++++++++- .../Private/Pose/CubismPose3JsonFactory.h | 10 ++- .../AssetDefinition_CubismUserData3Json.h | 29 +++++++ .../UserData/CubismUserData3JsonFactory.cpp | 79 ++++++++++++++++++ .../UserData/CubismUserData3JsonFactory.h | 10 ++- 50 files changed, 1440 insertions(+), 48 deletions(-) create mode 100644 Source/Live2DCubismFramework/Private/DisplayInfo/CubismDisplayInfo3Json.cpp create mode 100644 Source/Live2DCubismFramework/Private/Expression/CubismExp3Json.cpp create mode 100644 Source/Live2DCubismFramework/Private/Model/CubismModel3Json.cpp create mode 100644 Source/Live2DCubismFramework/Private/Motion/CubismMotion3Json.cpp create mode 100644 Source/Live2DCubismFramework/Private/Physics/CubismPhysics3Json.cpp create mode 100644 Source/Live2DCubismFramework/Private/Pose/CubismPose3Json.cpp create mode 100644 Source/Live2DCubismFramework/Private/UserData/CubismUserData3Json.cpp create mode 100644 Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/AssetDefinition_CubismDisplayInfo3Json.h create mode 100644 Source/Live2DCubismFrameworkImporter/Private/Expression/AssetDefinition_CubismExp3Json.h create mode 100644 Source/Live2DCubismFrameworkImporter/Private/Moc/AssetDefinition_CubismMoc3.h create mode 100644 Source/Live2DCubismFrameworkImporter/Private/Model/AssetDefinition_CubismModel3Json.h create mode 100644 Source/Live2DCubismFrameworkImporter/Private/Motion/AssetDefinition_CubismMotion3Json.h create mode 100644 Source/Live2DCubismFrameworkImporter/Private/Physics/AssetDefinition_CubismPhysics3Json.h create mode 100644 Source/Live2DCubismFrameworkImporter/Private/Pose/AssetDefinition_CubismPose3Json.h create mode 100644 Source/Live2DCubismFrameworkImporter/Private/UserData/AssetDefinition_CubismUserData3Json.h diff --git a/CHANGELOG.md b/CHANGELOG.md index f3243fa..92b2db3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [5-r.1-alpha.4] - 2024-12-05 + +### Added + +* Add motion curve validations to `motion3.json` importer. by [@pillowtrucker](https://github.com/Live2D/CubismNativeFramework/pull/57) +* Add feature to reimport Cubism assets. + * Due to incompatibility with this update, support for Unreal Engine 5.1 will be discontinued. + +### Fixed + +* Fix texture misidentification as normal maps. + + ## [5-r.1-alpha.3] - 2024-10-31 ### Changed @@ -36,5 +49,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * New released! +[5-r.1-alpha.4]: https://github.com/Live2D/CubismUnrealEngineComponents/compare/5-r.1-alpha.3...5-r.1-alpha.4 [5-r.1-alpha.3]: https://github.com/Live2D/CubismUnrealEngineComponents/compare/5-r.1-alpha.2...5-r.1-alpha.3 [5-r.1-alpha.2]: https://github.com/Live2D/CubismUnrealEngineComponents/compare/5-r.1-alpha.1...5-r.1-alpha.2 diff --git a/Live2DCubismSDK.uplugin b/Live2DCubismSDK.uplugin index b76e36c..3e3761e 100644 --- a/Live2DCubismSDK.uplugin +++ b/Live2DCubismSDK.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 1, - "VersionName": "5-r.1-alpha.3", + "VersionName": "5-r.1-alpha.4", "FriendlyName": "Live2DCubismSDK", "Description": "Live2D Cubism SDK for Unreal Engine Components", "Category": "Other", diff --git a/NOTICE.ja.md b/NOTICE.ja.md index 2c65dd0..a163fc8 100644 --- a/NOTICE.ja.md +++ b/NOTICE.ja.md @@ -4,7 +4,7 @@ # お知らせ -## [制限事項] alpha版における機能制限について (2024-09-05) +## [制限事項] alpha版における機能制限について (2024-12-05 更新) ### レベル @@ -13,11 +13,6 @@ alpha版ではOpenWorldレベルでの利用に対応しておりません。 ### モデルの表示 -#### モデルテクスチャ - -現在モデルのテクスチャが1024x1024 1枚の場合に正常に描画されない問題を確認しています。 -これを回避するにはCubism Editorにてテクスチャアトラスを1024x1024 1枚以外(2048x2048 1枚、1024x1024 2枚 等)に設定し再度書き出し直したモデルをインポートしてください。 - #### ピューポート表示 レベルにLive2Dモデルをスポーンした直後正しく表示されない場合があります。 @@ -27,11 +22,6 @@ alpha版ではOpenWorldレベルでの利用に対応しておりません。 alpha版ではモバイル端末上でのパフォーマンス向上のためのダブルバッファリングは実装されていません。 -### 再インポート機能 - -alpha版では組み込み用ファイルの再インポート機能が実装されていません。 -再インポートを行う場合は、インポート済みのアセットを削除してから再度インポートを行ってください。 - ### コンポーネント 各コンポーネントのプロパティ値を変更しPlayした際、Playする前に変更した値が反映されない問題を確認しています。 diff --git a/NOTICE.md b/NOTICE.md index 0c46f38..aac98ee 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -4,7 +4,7 @@ # Notices -## [Restrictions] Feature Restrictions in the Alpha Version (2024-09-05) +## [Restrictions] Feature Restrictions in the Alpha Version (2024-12-05 update) ### Level @@ -13,12 +13,7 @@ The alpha version does not support the use of OpenWorld levels. Please use the B ### Display the model -#### Model Textures - -We have identified an issue where models with a single 1024x1024 texture do not render correctly. -To avoid this issue, please adjust the texture atlas in Cubism Editor to anything other than a single 1024x1024 (e.g., a single 2048x2048, or two 1024x1024 textures), then re-export and re-import the model. - -### Viewport Display +#### Viewport Display Live2D models may not display correctly immediately after being spawned in a level. In such cases, please enable the real-time update feature in the viewport to refresh the screen. @@ -27,11 +22,6 @@ In such cases, please enable the real-time update feature in the viewport to ref Double buffering for performance improvement on mobile devices is not implemented in the alpha version. -### Assets Reimport - -The assets reimport feature for embedded files is not implemented in the alpha version. -If you need to reimport, please delete the imported assets and then reimport them. - ### Components We have identified an issue where property values changed in each component are not reflected when you play after making changes. diff --git a/README.ja.md b/README.ja.md index 4ff66ce..c9b65a4 100644 --- a/README.ja.md +++ b/README.ja.md @@ -66,7 +66,6 @@ Cubismファイルをuassetファイルに変換する機能は `./Source/Live2D | Unreal Editor 5.4 | 5.4.4 | | Unreal Editor 5.3 | 5.3.2 | | Unreal Editor 5.2 | 5.2.1 | -| Unreal Editor 5.1 | 5.1.1 | | ライブラリ / ツール | バージョン | | --- | --- | diff --git a/README.md b/README.md index 3cc02b0..4272648 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,6 @@ Resources like shaders and other assets are located in `./Content/Materials`. | Unreal Editor 5.4 | 5.4.4 | | Unreal Editor 5.3 | 5.3.2 | | Unreal Editor 5.2 | 5.2.1 | -| Unreal Editor 5.1 | 5.1.1 | | Library / Tool | Version | | --- | --- | diff --git a/Source/Live2DCubismFramework/Private/DisplayInfo/CubismDisplayInfo3Json.cpp b/Source/Live2DCubismFramework/Private/DisplayInfo/CubismDisplayInfo3Json.cpp new file mode 100644 index 0000000..2123419 --- /dev/null +++ b/Source/Live2DCubismFramework/Private/DisplayInfo/CubismDisplayInfo3Json.cpp @@ -0,0 +1,42 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#include "DisplayInfo/CubismDisplayInfo3Json.h" + +void UCubismDisplayInfo3Json::PostInitProperties() +{ +#if WITH_EDITORONLY_DATA + if (!HasAnyFlags(RF_ClassDefaultObject)) + { + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +#endif + Super::PostInitProperties(); +} + +#if WITH_EDITORONLY_DATA +void UCubismDisplayInfo3Json::GetAssetRegistryTags(TArray& OutTags) const +{ + if (AssetImportData) + { + OutTags.Add( FAssetRegistryTag(SourceFileTagName(), AssetImportData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) ); + } + + Super::GetAssetRegistryTags(OutTags); +} +void UCubismDisplayInfo3Json::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + + if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !AssetImportData) + { + // AssetImportData should always be valid + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +} +#endif diff --git a/Source/Live2DCubismFramework/Private/Expression/CubismExp3Json.cpp b/Source/Live2DCubismFramework/Private/Expression/CubismExp3Json.cpp new file mode 100644 index 0000000..d8eb8cb --- /dev/null +++ b/Source/Live2DCubismFramework/Private/Expression/CubismExp3Json.cpp @@ -0,0 +1,42 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#include "Expression/CubismExp3Json.h" + +void UCubismExp3Json::PostInitProperties() +{ +#if WITH_EDITORONLY_DATA + if (!HasAnyFlags(RF_ClassDefaultObject)) + { + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +#endif + Super::PostInitProperties(); +} + +#if WITH_EDITORONLY_DATA +void UCubismExp3Json::GetAssetRegistryTags(TArray& OutTags) const +{ + if (AssetImportData) + { + OutTags.Add( FAssetRegistryTag(SourceFileTagName(), AssetImportData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) ); + } + + Super::GetAssetRegistryTags(OutTags); +} +void UCubismExp3Json::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + + if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !AssetImportData) + { + // AssetImportData should always be valid + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +} +#endif diff --git a/Source/Live2DCubismFramework/Private/Model/CubismMoc.cpp b/Source/Live2DCubismFramework/Private/Model/CubismMoc.cpp index ac70211..44ca636 100644 --- a/Source/Live2DCubismFramework/Private/Model/CubismMoc.cpp +++ b/Source/Live2DCubismFramework/Private/Model/CubismMoc.cpp @@ -109,3 +109,36 @@ void UCubismMoc3::PostLoad() Setup(); } + +void UCubismMoc3::PostInitProperties() +{ +#if WITH_EDITORONLY_DATA + if (!HasAnyFlags(RF_ClassDefaultObject)) + { + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +#endif + Super::PostInitProperties(); +} + +#if WITH_EDITORONLY_DATA +void UCubismMoc3::GetAssetRegistryTags(TArray& OutTags) const +{ + if (AssetImportData) + { + OutTags.Add( FAssetRegistryTag(SourceFileTagName(), AssetImportData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) ); + } + + Super::GetAssetRegistryTags(OutTags); +} +void UCubismMoc3::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + + if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !AssetImportData) + { + // AssetImportData should always be valid + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +} +#endif diff --git a/Source/Live2DCubismFramework/Private/Model/CubismModel3Json.cpp b/Source/Live2DCubismFramework/Private/Model/CubismModel3Json.cpp new file mode 100644 index 0000000..68cc8e3 --- /dev/null +++ b/Source/Live2DCubismFramework/Private/Model/CubismModel3Json.cpp @@ -0,0 +1,42 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#include "Model/CubismModel3Json.h" + +void UCubismModel3Json::PostInitProperties() +{ +#if WITH_EDITORONLY_DATA + if (!HasAnyFlags(RF_ClassDefaultObject)) + { + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +#endif + Super::PostInitProperties(); +} + +#if WITH_EDITORONLY_DATA +void UCubismModel3Json::GetAssetRegistryTags(TArray& OutTags) const +{ + if (AssetImportData) + { + OutTags.Add( FAssetRegistryTag(SourceFileTagName(), AssetImportData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) ); + } + + Super::GetAssetRegistryTags(OutTags); +} +void UCubismModel3Json::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + + if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !AssetImportData) + { + // AssetImportData should always be valid + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +} +#endif diff --git a/Source/Live2DCubismFramework/Private/Motion/CubismMotion3Json.cpp b/Source/Live2DCubismFramework/Private/Motion/CubismMotion3Json.cpp new file mode 100644 index 0000000..75ec3c9 --- /dev/null +++ b/Source/Live2DCubismFramework/Private/Motion/CubismMotion3Json.cpp @@ -0,0 +1,42 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#include "Motion/CubismMotion3Json.h" + +void UCubismMotion3Json::PostInitProperties() +{ +#if WITH_EDITORONLY_DATA + if (!HasAnyFlags(RF_ClassDefaultObject)) + { + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +#endif + Super::PostInitProperties(); +} + +#if WITH_EDITORONLY_DATA +void UCubismMotion3Json::GetAssetRegistryTags(TArray& OutTags) const +{ + if (AssetImportData) + { + OutTags.Add( FAssetRegistryTag(SourceFileTagName(), AssetImportData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) ); + } + + Super::GetAssetRegistryTags(OutTags); +} +void UCubismMotion3Json::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + + if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !AssetImportData) + { + // AssetImportData should always be valid + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +} +#endif diff --git a/Source/Live2DCubismFramework/Private/Physics/CubismPhysics3Json.cpp b/Source/Live2DCubismFramework/Private/Physics/CubismPhysics3Json.cpp new file mode 100644 index 0000000..abd5db3 --- /dev/null +++ b/Source/Live2DCubismFramework/Private/Physics/CubismPhysics3Json.cpp @@ -0,0 +1,42 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#include "Physics/CubismPhysics3Json.h" + +void UCubismPhysics3Json::PostInitProperties() +{ +#if WITH_EDITORONLY_DATA + if (!HasAnyFlags(RF_ClassDefaultObject)) + { + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +#endif + Super::PostInitProperties(); +} + +#if WITH_EDITORONLY_DATA +void UCubismPhysics3Json::GetAssetRegistryTags(TArray& OutTags) const +{ + if (AssetImportData) + { + OutTags.Add( FAssetRegistryTag(SourceFileTagName(), AssetImportData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) ); + } + + Super::GetAssetRegistryTags(OutTags); +} +void UCubismPhysics3Json::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + + if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !AssetImportData) + { + // AssetImportData should always be valid + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +} +#endif diff --git a/Source/Live2DCubismFramework/Private/Pose/CubismPose3Json.cpp b/Source/Live2DCubismFramework/Private/Pose/CubismPose3Json.cpp new file mode 100644 index 0000000..7b49776 --- /dev/null +++ b/Source/Live2DCubismFramework/Private/Pose/CubismPose3Json.cpp @@ -0,0 +1,42 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#include "Pose/CubismPose3Json.h" + +void UCubismPose3Json::PostInitProperties() +{ +#if WITH_EDITORONLY_DATA + if (!HasAnyFlags(RF_ClassDefaultObject)) + { + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +#endif + Super::PostInitProperties(); +} + +#if WITH_EDITORONLY_DATA +void UCubismPose3Json::GetAssetRegistryTags(TArray& OutTags) const +{ + if (AssetImportData) + { + OutTags.Add( FAssetRegistryTag(SourceFileTagName(), AssetImportData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) ); + } + + Super::GetAssetRegistryTags(OutTags); +} +void UCubismPose3Json::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + + if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !AssetImportData) + { + // AssetImportData should always be valid + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +} +#endif diff --git a/Source/Live2DCubismFramework/Private/UserData/CubismUserData3Json.cpp b/Source/Live2DCubismFramework/Private/UserData/CubismUserData3Json.cpp new file mode 100644 index 0000000..df02f3f --- /dev/null +++ b/Source/Live2DCubismFramework/Private/UserData/CubismUserData3Json.cpp @@ -0,0 +1,42 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#include "UserData/CubismUserData3Json.h" + +void UCubismUserData3Json::PostInitProperties() +{ +#if WITH_EDITORONLY_DATA + if (!HasAnyFlags(RF_ClassDefaultObject)) + { + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +#endif + Super::PostInitProperties(); +} + +#if WITH_EDITORONLY_DATA +void UCubismUserData3Json::GetAssetRegistryTags(TArray& OutTags) const +{ + if (AssetImportData) + { + OutTags.Add( FAssetRegistryTag(SourceFileTagName(), AssetImportData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) ); + } + + Super::GetAssetRegistryTags(OutTags); +} +void UCubismUserData3Json::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + + if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !AssetImportData) + { + // AssetImportData should always be valid + AssetImportData = NewObject(this, TEXT("AssetImportData")); + } +} +#endif diff --git a/Source/Live2DCubismFramework/Public/DisplayInfo/CubismDisplayInfo3Json.h b/Source/Live2DCubismFramework/Public/DisplayInfo/CubismDisplayInfo3Json.h index 7f64546..006cbaa 100644 --- a/Source/Live2DCubismFramework/Public/DisplayInfo/CubismDisplayInfo3Json.h +++ b/Source/Live2DCubismFramework/Public/DisplayInfo/CubismDisplayInfo3Json.h @@ -8,6 +8,8 @@ #pragma once +#include "EditorFramework/AssetImportData.h" + #include "CubismDisplayInfo3Json.generated.h" /** @@ -111,4 +113,16 @@ class LIVE2DCUBISMFRAMEWORK_API UCubismDisplayInfo3Json : public UObject */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Display Info Data") TArray Parts; + +#if WITH_EDITORONLY_DATA + // Import data for this + UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings) + TObjectPtr AssetImportData; + + // UObject interface + virtual void PostInitProperties() override; + virtual void GetAssetRegistryTags(TArray& OutTags) const override; + virtual void Serialize(FArchive& Ar) override; + // End of UObject interface +#endif }; diff --git a/Source/Live2DCubismFramework/Public/Expression/CubismExp3Json.h b/Source/Live2DCubismFramework/Public/Expression/CubismExp3Json.h index 2d59163..99e64b9 100644 --- a/Source/Live2DCubismFramework/Public/Expression/CubismExp3Json.h +++ b/Source/Live2DCubismFramework/Public/Expression/CubismExp3Json.h @@ -9,6 +9,7 @@ #pragma once #include "Model/CubismModelComponent.h" +#include "EditorFramework/AssetImportData.h" #include "CubismExp3Json.generated.h" @@ -71,4 +72,16 @@ class LIVE2DCUBISMFRAMEWORK_API UCubismExp3Json : public UObject */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Expression Data") TArray Parameters; + +#if WITH_EDITORONLY_DATA + // Import data for this + UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings) + TObjectPtr AssetImportData; + + // UObject interface + virtual void PostInitProperties() override; + virtual void GetAssetRegistryTags(TArray& OutTags) const override; + virtual void Serialize(FArchive& Ar) override; + // End of UObject interface +#endif }; diff --git a/Source/Live2DCubismFramework/Public/Model/CubismMoc3.h b/Source/Live2DCubismFramework/Public/Model/CubismMoc3.h index 3773205..24bca19 100644 --- a/Source/Live2DCubismFramework/Public/Model/CubismMoc3.h +++ b/Source/Live2DCubismFramework/Public/Model/CubismMoc3.h @@ -9,6 +9,7 @@ #pragma once #include "Live2DCubismCore.h" +#include "EditorFramework/AssetImportData.h" #include "CubismMoc3.generated.h" @@ -124,4 +125,16 @@ class LIVE2DCUBISMFRAMEWORK_API UCubismMoc3 : public UObject // UObject interface virtual void PostLoad() override; // End of UObject interface + +#if WITH_EDITORONLY_DATA + // Import data for this + UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings) + TObjectPtr AssetImportData; + + // UObject interface + virtual void PostInitProperties() override; + virtual void GetAssetRegistryTags(TArray& OutTags) const override; + virtual void Serialize(FArchive& Ar) override; + // End of UObject interface +#endif }; diff --git a/Source/Live2DCubismFramework/Public/Model/CubismModel3Json.h b/Source/Live2DCubismFramework/Public/Model/CubismModel3Json.h index 87484c1..ebe094a 100644 --- a/Source/Live2DCubismFramework/Public/Model/CubismModel3Json.h +++ b/Source/Live2DCubismFramework/Public/Model/CubismModel3Json.h @@ -8,6 +8,8 @@ #pragma once +#include "EditorFramework/AssetImportData.h" + #include "CubismModel3Json.generated.h" /** @@ -163,4 +165,16 @@ class LIVE2DCUBISMFRAMEWORK_API UCubismModel3Json : public UObject */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Model Data") TArray HitAreas; + +#if WITH_EDITORONLY_DATA + // Import data for this + UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings) + TObjectPtr AssetImportData; + + // UObject interface + virtual void PostInitProperties() override; + virtual void GetAssetRegistryTags(TArray& OutTags) const override; + virtual void Serialize(FArchive& Ar) override; + // End of UObject interface +#endif }; diff --git a/Source/Live2DCubismFramework/Public/Motion/CubismMotion3Json.h b/Source/Live2DCubismFramework/Public/Motion/CubismMotion3Json.h index de0e03d..ea06db0 100644 --- a/Source/Live2DCubismFramework/Public/Motion/CubismMotion3Json.h +++ b/Source/Live2DCubismFramework/Public/Motion/CubismMotion3Json.h @@ -8,6 +8,8 @@ #pragma once +#include "EditorFramework/AssetImportData.h" + #include "CubismMotion3Json.generated.h" /** @@ -133,6 +135,18 @@ class LIVE2DCUBISMFRAMEWORK_API UCubismMotion3Json : public UObject */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Motion Data") TArray Events; + +#if WITH_EDITORONLY_DATA + // Import data for this + UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings) + TObjectPtr AssetImportData; + + // UObject interface + virtual void PostInitProperties() override; + virtual void GetAssetRegistryTags(TArray& OutTags) const override; + virtual void Serialize(FArchive& Ar) override; + // End of UObject interface +#endif }; /** diff --git a/Source/Live2DCubismFramework/Public/Physics/CubismPhysics3Json.h b/Source/Live2DCubismFramework/Public/Physics/CubismPhysics3Json.h index d5590bb..1bda849 100644 --- a/Source/Live2DCubismFramework/Public/Physics/CubismPhysics3Json.h +++ b/Source/Live2DCubismFramework/Public/Physics/CubismPhysics3Json.h @@ -8,6 +8,8 @@ #pragma once +#include "EditorFramework/AssetImportData.h" + #include "CubismPhysics3Json.generated.h" /** @@ -314,4 +316,16 @@ class LIVE2DCUBISMFRAMEWORK_API UCubismPhysics3Json : public UObject */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Physics Data") TArray PhysicsSettings; + +#if WITH_EDITORONLY_DATA + // Import data for this + UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings) + TObjectPtr AssetImportData; + + // UObject interface + virtual void PostInitProperties() override; + virtual void GetAssetRegistryTags(TArray& OutTags) const override; + virtual void Serialize(FArchive& Ar) override; + // End of UObject interface +#endif }; diff --git a/Source/Live2DCubismFramework/Public/Pose/CubismPose3Json.h b/Source/Live2DCubismFramework/Public/Pose/CubismPose3Json.h index 3ae8d22..8aac1cb 100644 --- a/Source/Live2DCubismFramework/Public/Pose/CubismPose3Json.h +++ b/Source/Live2DCubismFramework/Public/Pose/CubismPose3Json.h @@ -8,6 +8,8 @@ #pragma once +#include "EditorFramework/AssetImportData.h" + #include "CubismPose3Json.generated.h" /** @@ -72,4 +74,16 @@ class LIVE2DCUBISMFRAMEWORK_API UCubismPose3Json : public UObject */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pose Data") TArray PartGroups; + +#if WITH_EDITORONLY_DATA + // Import data for this + UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings) + TObjectPtr AssetImportData; + + // UObject interface + virtual void PostInitProperties() override; + virtual void GetAssetRegistryTags(TArray& OutTags) const override; + virtual void Serialize(FArchive& Ar) override; + // End of UObject interface +#endif }; diff --git a/Source/Live2DCubismFramework/Public/UserData/CubismUserData3Json.h b/Source/Live2DCubismFramework/Public/UserData/CubismUserData3Json.h index 1fb6b1b..6131be1 100644 --- a/Source/Live2DCubismFramework/Public/UserData/CubismUserData3Json.h +++ b/Source/Live2DCubismFramework/Public/UserData/CubismUserData3Json.h @@ -8,6 +8,8 @@ #pragma once +#include "EditorFramework/AssetImportData.h" + #include "CubismUserData3Json.generated.h" /** @@ -55,4 +57,16 @@ class LIVE2DCUBISMFRAMEWORK_API UCubismUserData3Json : public UObject */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "User Data") TMap Data; + +#if WITH_EDITORONLY_DATA + // Import data for this + UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings) + TObjectPtr AssetImportData; + + // UObject interface + virtual void PostInitProperties() override; + virtual void GetAssetRegistryTags(TArray& OutTags) const override; + virtual void Serialize(FArchive& Ar) override; + // End of UObject interface +#endif }; diff --git a/Source/Live2DCubismFrameworkEditor/Private/CubismModelActorFactory.cpp b/Source/Live2DCubismFrameworkEditor/Private/CubismModelActorFactory.cpp index de58aab..69474ec 100644 --- a/Source/Live2DCubismFrameworkEditor/Private/CubismModelActorFactory.cpp +++ b/Source/Live2DCubismFrameworkEditor/Private/CubismModelActorFactory.cpp @@ -209,7 +209,7 @@ TObjectPtr UCubismModelActorFactory::LoadMoc(const TObjectPtr> UCubismModelActorFactory::LoadTextures(const TObjectPtr& Model3Json) -{ +{ TArray> Textures; const FString& LongPackagePath = FPackageName::GetLongPackagePath(Model3Json->GetOutermost()->GetPathName()); @@ -220,6 +220,18 @@ TArray> UCubismModelActorFactory::LoadTextures(const TObj TObjectPtr Texture = LoadObject(nullptr, *AssetPath); + // Workaround for when the texture is loaded as a normal map + if (!Texture->SRGB || Texture->CompressionSettings != TC_Default || Texture->LODGroup != TEXTUREGROUP_World) + { + Texture->SRGB = true; + Texture->CompressionSettings = TC_Default; + Texture->LODGroup = TEXTUREGROUP_World; + + Texture->UpdateResource(); + + Texture->MarkPackageDirty(); + } + Textures.Add(Texture); } diff --git a/Source/Live2DCubismFrameworkImporter/Live2DCubismFrameworkImporter.Build.cs b/Source/Live2DCubismFrameworkImporter/Live2DCubismFrameworkImporter.Build.cs index a07dea3..87abcc5 100644 --- a/Source/Live2DCubismFrameworkImporter/Live2DCubismFrameworkImporter.Build.cs +++ b/Source/Live2DCubismFrameworkImporter/Live2DCubismFrameworkImporter.Build.cs @@ -44,6 +44,7 @@ public Live2DCubismFrameworkImporter(ReadOnlyTargetRules Target) : base(Target) "Json", "Engine", "UnrealEd", + "AssetDefinition", "Live2DCubismFramework", // ... add private dependencies that you statically link with here ... } diff --git a/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/AssetDefinition_CubismDisplayInfo3Json.h b/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/AssetDefinition_CubismDisplayInfo3Json.h new file mode 100644 index 0000000..9ee9ead --- /dev/null +++ b/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/AssetDefinition_CubismDisplayInfo3Json.h @@ -0,0 +1,29 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#pragma once + +#include "DisplayInfo/CubismDisplayInfo3Json.h" +#include "AssetDefinitionDefault.h" + +#include "AssetDefinition_CubismDisplayInfo3Json.generated.h" + +UCLASS() +class UAssetDefinition_CubismDisplayInfo3Json : public UAssetDefinitionDefault +{ + GENERATED_BODY() + +public: + // UAssetDefinition Begin + virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_CubismDisplayInfo3Json", "CubismDisplayInfo3Json"); } + virtual FLinearColor GetAssetColor() const override { return FLinearColor(FColor::Orange); } + virtual TSoftClassPtr GetAssetClass() const override { return UCubismDisplayInfo3Json::StaticClass(); } + virtual TConstArrayView GetAssetCategories() const override { return TArray(); } + virtual bool CanImport() const override { return true; } + // UAssetDefinition End +}; diff --git a/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/CubismDisplayInfo3JsonFactory.cpp b/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/CubismDisplayInfo3JsonFactory.cpp index a324faa..0fe347a 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/CubismDisplayInfo3JsonFactory.cpp +++ b/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/CubismDisplayInfo3JsonFactory.cpp @@ -12,6 +12,7 @@ #include "DisplayInfo/CubismDisplayInfo3JsonImporter.h" #include "Misc/FileHelper.h" #include "Misc/PackageName.h" +#include "CubismLog.h" UCubismDisplayInfo3JsonFactory::UCubismDisplayInfo3JsonFactory() { @@ -27,7 +28,7 @@ UCubismDisplayInfo3JsonFactory::UCubismDisplayInfo3JsonFactory() FText UCubismDisplayInfo3JsonFactory::GetToolTip() const { - return NSLOCTEXT("Live2D Cubism Framework", "CubismDisplayInfo3JsonFactoryDescription", "Model JSON exported from Live2D Cubism Editor"); + return NSLOCTEXT("Live2D Cubism Framework", "CubismDisplayInfo3JsonFactoryDescription", "DisplayInfo JSON exported from Live2D Cubism Editor"); } bool UCubismDisplayInfo3JsonFactory::FactoryCanImport(const FString& Filename) @@ -57,7 +58,85 @@ UObject* UCubismDisplayInfo3JsonFactory::FactoryCreateText Result = NewObject(InParent, InName, Flags); Importer.ApplyParams(Flags, Result); + + // Update asset import data + if (Result->AssetImportData) + { + Result->AssetImportData->Update(CurrentFilename); + } + else + { + Result->AssetImportData = NewObject(Result, TEXT("AssetImportData")); + Result->AssetImportData->Update(CurrentFilename); + } } return Result; } + +bool UCubismDisplayInfo3JsonFactory::CanReimport(UObject* Obj, TArray& OutFilenames) +{ + UCubismDisplayInfo3Json* DisplayInfo = Cast(Obj); + if (DisplayInfo && DisplayInfo->AssetImportData) + { + DisplayInfo->AssetImportData->ExtractFilenames(OutFilenames); + return true; + } + return false; +} + +void UCubismDisplayInfo3JsonFactory::SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) +{ + UCubismDisplayInfo3Json* DisplayInfo = Cast(Obj); + if (DisplayInfo && ensure(NewReimportPaths.Num() == 1)) + { + DisplayInfo->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]); + } +} + +EReimportResult::Type UCubismDisplayInfo3JsonFactory::Reimport(UObject* Obj) +{ + UCubismDisplayInfo3Json* DisplayInfo = Cast(Obj); + if (!DisplayInfo) + { + return EReimportResult::Failed; + } + + const FString Filename = DisplayInfo->AssetImportData->GetFirstFilename(); + if (!Filename.Len()) + { + return EReimportResult::Failed; + } + + if (IFileManager::Get().FileSize(*Filename) == INDEX_NONE) + { + UE_LOG(LogCubism, Warning, TEXT("Cannot reimport: source file '%s' cannot be found."), *Filename); + return EReimportResult::Failed; + } + + bool OutCanceled = false; + + if (ImportObject(DisplayInfo->GetClass(), DisplayInfo->GetOuter(), *DisplayInfo->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled)) + { + UE_LOG(LogCubism, Log, TEXT("Reimported successfully")); + + DisplayInfo->AssetImportData->Update(Filename); + + DisplayInfo->MarkPackageDirty(); + + return EReimportResult::Succeeded; + } + else + { + if (OutCanceled) + { + UE_LOG(LogCubism, Warning, TEXT("Reimport was canceled")); + return EReimportResult::Cancelled; + } + else + { + UE_LOG(LogCubism, Error, TEXT("Reimport failed")); + return EReimportResult::Failed; + } + } +} diff --git a/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/CubismDisplayInfo3JsonFactory.h b/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/CubismDisplayInfo3JsonFactory.h index 9b0eca9..4d8d912 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/CubismDisplayInfo3JsonFactory.h +++ b/Source/Live2DCubismFrameworkImporter/Private/DisplayInfo/CubismDisplayInfo3JsonFactory.h @@ -8,13 +8,15 @@ #pragma once +#include "EditorReimportHandler.h" + #include "CubismDisplayInfo3JsonFactory.generated.h" /** * A factory for creating Cubism display info json assets from cdi3.json files. */ UCLASS() -class UCubismDisplayInfo3JsonFactory : public UFactory +class UCubismDisplayInfo3JsonFactory : public UFactory, public FReimportHandler { GENERATED_BODY() @@ -27,4 +29,10 @@ class UCubismDisplayInfo3JsonFactory : public UFactory UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext * Warn ) override; + + //~ Begin FReimportHandler Interface + virtual bool CanReimport(UObject* Obj, TArray& OutFilenames) override; + virtual void SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) override; + virtual EReimportResult::Type Reimport(UObject* Obj) override; + //~ End FReimportHandler Interface }; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Expression/AssetDefinition_CubismExp3Json.h b/Source/Live2DCubismFrameworkImporter/Private/Expression/AssetDefinition_CubismExp3Json.h new file mode 100644 index 0000000..418d800 --- /dev/null +++ b/Source/Live2DCubismFrameworkImporter/Private/Expression/AssetDefinition_CubismExp3Json.h @@ -0,0 +1,29 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#pragma once + +#include "Expression/CubismExp3Json.h" +#include "AssetDefinitionDefault.h" + +#include "AssetDefinition_CubismExp3Json.generated.h" + +UCLASS() +class UAssetDefinition_CubismExp3Json : public UAssetDefinitionDefault +{ + GENERATED_BODY() + +public: + // UAssetDefinition Begin + virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_CubismExp3Json", "CubismExp3Json"); } + virtual FLinearColor GetAssetColor() const override { return FLinearColor(FColor::Orange); } + virtual TSoftClassPtr GetAssetClass() const override { return UCubismExp3Json::StaticClass(); } + virtual TConstArrayView GetAssetCategories() const override { return TArray(); } + virtual bool CanImport() const override { return true; } + // UAssetDefinition End +}; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Expression/CubismExp3JsonFactory.cpp b/Source/Live2DCubismFrameworkImporter/Private/Expression/CubismExp3JsonFactory.cpp index 4132b06..d354235 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Expression/CubismExp3JsonFactory.cpp +++ b/Source/Live2DCubismFrameworkImporter/Private/Expression/CubismExp3JsonFactory.cpp @@ -8,11 +8,11 @@ #include "CubismExp3JsonFactory.h" - #include "Expression/CubismExp3Json.h" #include "Expression/CubismExp3JsonImporter.h" #include "Misc/FileHelper.h" #include "Misc/PackageName.h" +#include "CubismLog.h" UCubismExp3JsonFactory::UCubismExp3JsonFactory() { @@ -58,7 +58,85 @@ UObject* UCubismExp3JsonFactory::FactoryCreateText Result = NewObject(InParent, InName, Flags); Importer.ApplyParams(Flags, Result); + + // Update asset import data + if (Result->AssetImportData) + { + Result->AssetImportData->Update(CurrentFilename); + } + else + { + Result->AssetImportData = NewObject(Result, TEXT("AssetImportData")); + Result->AssetImportData->Update(CurrentFilename); + } } return Result; } + +bool UCubismExp3JsonFactory::CanReimport(UObject* Obj, TArray& OutFilenames) +{ + UCubismExp3Json* Exp = Cast(Obj); + if (Exp && Exp->AssetImportData) + { + Exp->AssetImportData->ExtractFilenames(OutFilenames); + return true; + } + return false; +} + +void UCubismExp3JsonFactory::SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) +{ + UCubismExp3Json* Exp = Cast(Obj); + if (Exp && ensure(NewReimportPaths.Num() == 1)) + { + Exp->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]); + } +} + +EReimportResult::Type UCubismExp3JsonFactory::Reimport(UObject* Obj) +{ + UCubismExp3Json* Exp = Cast(Obj); + if (!Exp) + { + return EReimportResult::Failed; + } + + const FString Filename = Exp->AssetImportData->GetFirstFilename(); + if (!Filename.Len()) + { + return EReimportResult::Failed; + } + + if (IFileManager::Get().FileSize(*Filename) == INDEX_NONE) + { + UE_LOG(LogCubism, Warning, TEXT("Cannot reimport: source file '%s' cannot be found."), *Filename); + return EReimportResult::Failed; + } + + bool OutCanceled = false; + + if (ImportObject(Exp->GetClass(), Exp->GetOuter(), *Exp->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled)) + { + UE_LOG(LogCubism, Log, TEXT("Reimported successfully")); + + Exp->AssetImportData->Update(Filename); + + Exp->MarkPackageDirty(); + + return EReimportResult::Succeeded; + } + else + { + if (OutCanceled) + { + UE_LOG(LogCubism, Warning, TEXT("Reimport was canceled")); + return EReimportResult::Cancelled; + } + else + { + UE_LOG(LogCubism, Error, TEXT("Reimport failed")); + return EReimportResult::Failed; + } + } +} diff --git a/Source/Live2DCubismFrameworkImporter/Private/Expression/CubismExp3JsonFactory.h b/Source/Live2DCubismFrameworkImporter/Private/Expression/CubismExp3JsonFactory.h index f0cca3d..bf3d626 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Expression/CubismExp3JsonFactory.h +++ b/Source/Live2DCubismFrameworkImporter/Private/Expression/CubismExp3JsonFactory.h @@ -8,13 +8,15 @@ #pragma once +#include "EditorReimportHandler.h" + #include "CubismExp3JsonFactory.generated.h" /** * A factory for creating Cubism expression json assets from exp3.json files. */ UCLASS() -class UCubismExp3JsonFactory : public UFactory +class UCubismExp3JsonFactory : public UFactory, public FReimportHandler { GENERATED_BODY() @@ -27,4 +29,10 @@ class UCubismExp3JsonFactory : public UFactory UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext* Warn ) override; + + //~ Begin FReimportHandler Interface + virtual bool CanReimport(UObject* Obj, TArray& OutFilenames) override; + virtual void SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) override; + virtual EReimportResult::Type Reimport(UObject* Obj) override; + //~ End FReimportHandler Interface }; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Moc/AssetDefinition_CubismMoc3.h b/Source/Live2DCubismFrameworkImporter/Private/Moc/AssetDefinition_CubismMoc3.h new file mode 100644 index 0000000..3ebdb3f --- /dev/null +++ b/Source/Live2DCubismFrameworkImporter/Private/Moc/AssetDefinition_CubismMoc3.h @@ -0,0 +1,29 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#pragma once + +#include "Model/CubismMoc3.h" +#include "AssetDefinitionDefault.h" + +#include "AssetDefinition_CubismMoc3.generated.h" + +UCLASS() +class UAssetDefinition_CubismMoc3 : public UAssetDefinitionDefault +{ + GENERATED_BODY() + +public: + // UAssetDefinition Begin + virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_CubismMoc3", "CubismMoc3"); } + virtual FLinearColor GetAssetColor() const override { return FLinearColor(FColor::Orange); } + virtual TSoftClassPtr GetAssetClass() const override { return UCubismMoc3::StaticClass(); } + virtual TConstArrayView GetAssetCategories() const override { return TArray(); } + virtual bool CanImport() const override { return true; } + // UAssetDefinition End +}; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Moc/CubismMoc3Factory.cpp b/Source/Live2DCubismFrameworkImporter/Private/Moc/CubismMoc3Factory.cpp index 1745ed9..23877b7 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Moc/CubismMoc3Factory.cpp +++ b/Source/Live2DCubismFrameworkImporter/Private/Moc/CubismMoc3Factory.cpp @@ -21,13 +21,13 @@ UCubismMoc3Factory::UCubismMoc3Factory() bEditorImport = true; bText = false; - Formats.Add(TEXT("moc3;Cubism Model Binary file")); + Formats.Add(TEXT("moc3;Cubism Moc Binary file")); } FText UCubismMoc3Factory::GetToolTip() const { - return NSLOCTEXT("Live2D Cubism Framework", "CubismMoc3FactoryDescription", "Model exported from Live2D Cubism Editor"); + return NSLOCTEXT("Live2D Cubism Framework", "CubismMoc3FactoryDescription", "Moc exported from Live2D Cubism Editor"); } bool UCubismMoc3Factory::FactoryCanImport(const FString& Filename) @@ -68,3 +68,70 @@ UObject* UCubismMoc3Factory::FactoryCreateBinary return Result; } + +bool UCubismMoc3Factory::CanReimport(UObject* Obj, TArray& OutFilenames) +{ + UCubismMoc3* Moc = Cast(Obj); + if (Moc && Moc->AssetImportData) + { + Moc->AssetImportData->ExtractFilenames(OutFilenames); + return true; + } + return false; +} + +void UCubismMoc3Factory::SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) +{ + UCubismMoc3* Moc = Cast(Obj); + if (Moc && ensure(NewReimportPaths.Num() == 1)) + { + Moc->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]); + } +} + +EReimportResult::Type UCubismMoc3Factory::Reimport(UObject* Obj) +{ + UCubismMoc3* Moc = Cast(Obj); + if (!Moc) + { + return EReimportResult::Failed; + } + + const FString Filename = Moc->AssetImportData->GetFirstFilename(); + if (!Filename.Len()) + { + return EReimportResult::Failed; + } + + if (IFileManager::Get().FileSize(*Filename) == INDEX_NONE) + { + UE_LOG(LogCubism, Warning, TEXT("Cannot reimport: source file '%s' cannot be found."), *Filename); + return EReimportResult::Failed; + } + + bool OutCanceled = false; + + if (ImportObject(Moc->GetClass(), Moc->GetOuter(), *Moc->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled)) + { + UE_LOG(LogCubism, Log, TEXT("Reimported successfully")); + + Moc->AssetImportData->Update(Filename); + + Moc->MarkPackageDirty(); + + return EReimportResult::Succeeded; + } + else + { + if (OutCanceled) + { + UE_LOG(LogCubism, Warning, TEXT("Reimport was canceled")); + return EReimportResult::Cancelled; + } + else + { + UE_LOG(LogCubism, Error, TEXT("Reimport failed")); + return EReimportResult::Failed; + } + } +} diff --git a/Source/Live2DCubismFrameworkImporter/Private/Moc/CubismMoc3Factory.h b/Source/Live2DCubismFrameworkImporter/Private/Moc/CubismMoc3Factory.h index 63e0409..65735f4 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Moc/CubismMoc3Factory.h +++ b/Source/Live2DCubismFrameworkImporter/Private/Moc/CubismMoc3Factory.h @@ -8,13 +8,15 @@ #pragma once +#include "EditorReimportHandler.h" + #include "CubismMoc3Factory.generated.h" /** * A factory for creating Cubism moc assets from moc3 files. */ UCLASS() -class UCubismMoc3Factory : public UFactory +class UCubismMoc3Factory : public UFactory, public FReimportHandler { GENERATED_BODY() @@ -27,4 +29,10 @@ class UCubismMoc3Factory : public UFactory UObject* Context, const TCHAR* Type, const uint8*& Buffer, const uint8* BufferEnd, FFeedbackContext * Warn ) override; + + //~ Begin FReimportHandler Interface + virtual bool CanReimport(UObject* Obj, TArray& OutFilenames) override; + virtual void SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) override; + virtual EReimportResult::Type Reimport(UObject* Obj) override; + //~ End FReimportHandler Interface }; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Model/AssetDefinition_CubismModel3Json.h b/Source/Live2DCubismFrameworkImporter/Private/Model/AssetDefinition_CubismModel3Json.h new file mode 100644 index 0000000..cbd15d4 --- /dev/null +++ b/Source/Live2DCubismFrameworkImporter/Private/Model/AssetDefinition_CubismModel3Json.h @@ -0,0 +1,29 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#pragma once + +#include "Model/CubismModel3Json.h" +#include "AssetDefinitionDefault.h" + +#include "AssetDefinition_CubismModel3Json.generated.h" + +UCLASS() +class UAssetDefinition_CubismModel3Json : public UAssetDefinitionDefault +{ + GENERATED_BODY() + +public: + // UAssetDefinition Begin + virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_CubismModel3Json", "CubismModel3Json"); } + virtual FLinearColor GetAssetColor() const override { return FLinearColor(FColor::Orange); } + virtual TSoftClassPtr GetAssetClass() const override { return UCubismModel3Json::StaticClass(); } + virtual TConstArrayView GetAssetCategories() const override { return TArray(); } + virtual bool CanImport() const override { return true; } + // UAssetDefinition End +}; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Model/CubismModel3JsonFactory.cpp b/Source/Live2DCubismFrameworkImporter/Private/Model/CubismModel3JsonFactory.cpp index 18fba5f..994ac4f 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Model/CubismModel3JsonFactory.cpp +++ b/Source/Live2DCubismFrameworkImporter/Private/Model/CubismModel3JsonFactory.cpp @@ -7,9 +7,12 @@ #include "CubismModel3JsonFactory.h" + #include "Model/CubismModel3Json.h" +#include "Model/CubismModel3JsonImporter.h" #include "Misc/FileHelper.h" #include "Misc/PackageName.h" +#include "CubismLog.h" UCubismModel3JsonFactory::UCubismModel3JsonFactory() { @@ -55,7 +58,85 @@ UObject* UCubismModel3JsonFactory::FactoryCreateText Result = NewObject(InParent, InName, Flags); Importer.ApplyParams(Flags, Result); + + // Update asset import data + if (Result->AssetImportData) + { + Result->AssetImportData->Update(CurrentFilename); + } + else + { + Result->AssetImportData = NewObject(Result, TEXT("AssetImportData")); + Result->AssetImportData->Update(CurrentFilename); + } } return Result; } + +bool UCubismModel3JsonFactory::CanReimport(UObject* Obj, TArray& OutFilenames) +{ + UCubismModel3Json* Model = Cast(Obj); + if (Model && Model->AssetImportData) + { + Model->AssetImportData->ExtractFilenames(OutFilenames); + return true; + } + return false; +} + +void UCubismModel3JsonFactory::SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) +{ + UCubismModel3Json* Model = Cast(Obj); + if (Model && ensure(NewReimportPaths.Num() == 1)) + { + Model->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]); + } +} + +EReimportResult::Type UCubismModel3JsonFactory::Reimport(UObject* Obj) +{ + UCubismModel3Json* Model = Cast(Obj); + if (!Model) + { + return EReimportResult::Failed; + } + + const FString Filename = Model->AssetImportData->GetFirstFilename(); + if (!Filename.Len()) + { + return EReimportResult::Failed; + } + + if (IFileManager::Get().FileSize(*Filename) == INDEX_NONE) + { + UE_LOG(LogCubism, Warning, TEXT("Cannot reimport: source file '%s' cannot be found."), *Filename); + return EReimportResult::Failed; + } + + bool OutCanceled = false; + + if (ImportObject(Model->GetClass(), Model->GetOuter(), *Model->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled)) + { + UE_LOG(LogCubism, Log, TEXT("Reimported successfully")); + + Model->AssetImportData->Update(Filename); + + Model->MarkPackageDirty(); + + return EReimportResult::Succeeded; + } + else + { + if (OutCanceled) + { + UE_LOG(LogCubism, Warning, TEXT("Reimport was canceled")); + return EReimportResult::Cancelled; + } + else + { + UE_LOG(LogCubism, Error, TEXT("Reimport failed")); + return EReimportResult::Failed; + } + } +} diff --git a/Source/Live2DCubismFrameworkImporter/Private/Model/CubismModel3JsonFactory.h b/Source/Live2DCubismFrameworkImporter/Private/Model/CubismModel3JsonFactory.h index 35bb985..2cc3cf8 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Model/CubismModel3JsonFactory.h +++ b/Source/Live2DCubismFrameworkImporter/Private/Model/CubismModel3JsonFactory.h @@ -8,15 +8,15 @@ #pragma once -#include "CubismModel3JsonImporter.h" -#include "Factories/Factory.h" +#include "EditorReimportHandler.h" + #include "CubismModel3JsonFactory.generated.h" /** * A factory for creating Cubism model json assets from model3.json files. */ UCLASS() -class UCubismModel3JsonFactory : public UFactory +class UCubismModel3JsonFactory : public UFactory, public FReimportHandler { GENERATED_BODY() @@ -29,4 +29,10 @@ class UCubismModel3JsonFactory : public UFactory UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext * Warn ) override; + + //~ Begin FReimportHandler Interface + virtual bool CanReimport(UObject* Obj, TArray& OutFilenames) override; + virtual void SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) override; + virtual EReimportResult::Type Reimport(UObject* Obj) override; + //~ End FReimportHandler Interface }; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Motion/AssetDefinition_CubismMotion3Json.h b/Source/Live2DCubismFrameworkImporter/Private/Motion/AssetDefinition_CubismMotion3Json.h new file mode 100644 index 0000000..e282bfd --- /dev/null +++ b/Source/Live2DCubismFrameworkImporter/Private/Motion/AssetDefinition_CubismMotion3Json.h @@ -0,0 +1,29 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#pragma once + +#include "Motion/CubismMotion3Json.h" +#include "AssetDefinitionDefault.h" + +#include "AssetDefinition_CubismMotion3Json.generated.h" + +UCLASS() +class UAssetDefinition_CubismMotion3Json : public UAssetDefinitionDefault +{ + GENERATED_BODY() + +public: + // UAssetDefinition Begin + virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_CubismMotion3Json", "CubismMotion3Json"); } + virtual FLinearColor GetAssetColor() const override { return FLinearColor(FColor::Orange); } + virtual TSoftClassPtr GetAssetClass() const override { return UCubismMotion3Json::StaticClass(); } + virtual TConstArrayView GetAssetCategories() const override { return TArray(); } + virtual bool CanImport() const override { return true; } + // UAssetDefinition End +}; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonFactory.cpp b/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonFactory.cpp index 0927794..7a195b1 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonFactory.cpp +++ b/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonFactory.cpp @@ -12,6 +12,7 @@ #include "Motion/CubismMotion3JsonImporter.h" #include "Misc/FileHelper.h" #include "Misc/PackageName.h" +#include "CubismLog.h" UCubismMotion3JsonFactory::UCubismMotion3JsonFactory() { @@ -56,8 +57,86 @@ UObject* UCubismMotion3JsonFactory::FactoryCreateText Result = NewObject(InParent, InName, Flags); Importer.ApplyParams(Flags, Result); + + // Update asset import data + if (Result->AssetImportData) + { + Result->AssetImportData->Update(CurrentFilename); + } + else + { + Result->AssetImportData = NewObject(Result, TEXT("AssetImportData")); + Result->AssetImportData->Update(CurrentFilename); + } } return Result; } +bool UCubismMotion3JsonFactory::CanReimport(UObject* Obj, TArray& OutFilenames) +{ + UCubismMotion3Json* Motion = Cast(Obj); + if (Motion && Motion->AssetImportData) + { + Motion->AssetImportData->ExtractFilenames(OutFilenames); + return true; + } + return false; +} + +void UCubismMotion3JsonFactory::SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) +{ + UCubismMotion3Json* Motion = Cast(Obj); + if (Motion && ensure(NewReimportPaths.Num() == 1)) + { + Motion->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]); + } +} + +EReimportResult::Type UCubismMotion3JsonFactory::Reimport(UObject* Obj) +{ + UCubismMotion3Json* Motion = Cast(Obj); + if (!Motion) + { + return EReimportResult::Failed; + } + + const FString Filename = Motion->AssetImportData->GetFirstFilename(); + if (!Filename.Len()) + { + return EReimportResult::Failed; + } + + if (IFileManager::Get().FileSize(*Filename) == INDEX_NONE) + { + UE_LOG(LogCubism, Warning, TEXT("Cannot reimport: source file '%s' cannot be found."), *Filename); + return EReimportResult::Failed; + } + + bool OutCanceled = false; + + if (ImportObject(Motion->GetClass(), Motion->GetOuter(), *Motion->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled)) + { + UE_LOG(LogCubism, Log, TEXT("Reimported successfully")); + + Motion->AssetImportData->Update(Filename); + + Motion->MarkPackageDirty(); + + return EReimportResult::Succeeded; + } + else + { + if (OutCanceled) + { + UE_LOG(LogCubism, Warning, TEXT("Reimport was canceled")); + return EReimportResult::Cancelled; + } + else + { + UE_LOG(LogCubism, Error, TEXT("Reimport failed")); + return EReimportResult::Failed; + } + } +} + diff --git a/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonFactory.h b/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonFactory.h index 36e4970..42c67ee 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonFactory.h +++ b/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonFactory.h @@ -8,13 +8,15 @@ #pragma once +#include "EditorReimportHandler.h" + #include "CubismMotion3JsonFactory.generated.h" /** * A factory for creating Cubism motion json assets from motion3.json files. */ UCLASS() -class UCubismMotion3JsonFactory : public UFactory +class UCubismMotion3JsonFactory : public UFactory, public FReimportHandler { GENERATED_BODY() @@ -27,4 +29,10 @@ class UCubismMotion3JsonFactory : public UFactory UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext* Warn ) override; + + //~ Begin FReimportHandler Interface + virtual bool CanReimport(UObject* Obj, TArray& OutFilenames) override; + virtual void SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) override; + virtual EReimportResult::Type Reimport(UObject* Obj) override; + //~ End FReimportHandler Interface }; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonImporter.cpp b/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonImporter.cpp index 1618659..4876e43 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonImporter.cpp +++ b/Source/Live2DCubismFrameworkImporter/Private/Motion/CubismMotion3JsonImporter.cpp @@ -52,11 +52,17 @@ bool FCubismMotion3JsonImporter::ImportFromString(const FString& FileContent) (*Meta)->TryGetNumberField(TEXT("FadeInTime"), FadeInTime); (*Meta)->TryGetNumberField(TEXT("FadeOutTime"), FadeOutTime); ASSERT((*Meta)->TryGetBoolField(TEXT("Loop"), bLoop), "Failed to get Loop field."); + ASSERT((*Meta)->TryGetNumberField(TEXT("CurveCount"), CurveCount), "Failed to get CurveCount field."); + ASSERT((*Meta)->TryGetNumberField(TEXT("TotalSegmentCount"), TotalSegmentCount), "Failed to get TotalSegmentCount field."); + ASSERT((*Meta)->TryGetNumberField(TEXT("TotalPointCount"), TotalPointCount), "Failed to get TotalPointCount field."); } const TArray< TSharedPtr >* CurvesArrayObject; ASSERT(JsonObject->TryGetArrayField(TEXT("Curves"), CurvesArrayObject), "Failed to get Curves field."); { + int32 NumSegments = 0; + int32 NumPoints = 0; + for (const TSharedPtr& CurveValue : *CurvesArrayObject) { FCubismMotionCurve Curve; @@ -98,9 +104,26 @@ bool FCubismMotion3JsonImporter::ImportFromString(const FString& FileContent) Segments.Add(SegmentValue->AsNumber()); } - MotionCurves.Add(*Curve.Id, Segments); + MotionCurves.Add(*Curve.Id, ParseSegments(Segments, NumSegments, NumPoints)); } + } + + if (Curves.Num() != CurveCount) + { + UE_LOG(LogCubism, Error, TEXT("Curves count mismatch. Expected: %d, Actual: %d"), CurveCount, Curves.Num()); + return false; + } + if (NumSegments != TotalSegmentCount) + { + UE_LOG(LogCubism, Error, TEXT("Segments count mismatch. Expected: %d, Actual: %d"), TotalSegmentCount, NumSegments); + return false; + } + + if (NumPoints != TotalPointCount) + { + UE_LOG(LogCubism, Error, TEXT("Points count mismatch. Expected: %d, Actual: %d"), TotalPointCount, NumPoints); + return false; } } @@ -121,17 +144,18 @@ void FCubismMotion3JsonImporter::ApplyParams(EObjectFlags Flags, const TObjectPt for (const auto& Entry : MotionCurves) { FRichCurve& Curve = CurveTable->AddRichCurve(Entry.Key); - Curve.SetKeys(ParseSegments(Entry.Value)); + Curve.SetKeys(Entry.Value); } Json->CurveTable = CurveTable; } -TArray FCubismMotion3JsonImporter::ParseSegments(const TArray &Segments) const +TArray FCubismMotion3JsonImporter::ParseSegments(const TArray &Segments, int32& NumSegments, int32& NumPoints) const { TArray KeyFrames; KeyFrames.Add(FRichCurveKey(Segments[0], Segments[1])); + NumPoints += 1; int32 i = 2; while (i < Segments.Num()) @@ -154,6 +178,7 @@ TArray FCubismMotion3JsonImporter::ParseSegments(const TArray FCubismMotion3JsonImporter::ParseSegments(const TArray FCubismMotion3JsonImporter::ParseSegments(const TArray FCubismMotion3JsonImporter::ParseSegments(const TArray FCubismMotion3JsonImporter::ParseSegments(const TArray ParseJSON(const FString& FileContent, bool bSilent); - TArray ParseSegments(const TArray& Segments) const; + TArray ParseSegments(const TArray& Segments, int32& NumSegments, int32& NumPoints) const; protected: int32 Version; @@ -38,9 +38,15 @@ class FCubismMotion3JsonImporter float FadeOutTime = 1.0f; + int32 CurveCount; + + int32 TotalSegmentCount; + + int32 TotalPointCount; + TArray Curves; - TMap> MotionCurves; + TMap> MotionCurves; TArray Events; }; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Physics/AssetDefinition_CubismPhysics3Json.h b/Source/Live2DCubismFrameworkImporter/Private/Physics/AssetDefinition_CubismPhysics3Json.h new file mode 100644 index 0000000..17a74b0 --- /dev/null +++ b/Source/Live2DCubismFrameworkImporter/Private/Physics/AssetDefinition_CubismPhysics3Json.h @@ -0,0 +1,29 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#pragma once + +#include "Physics/CubismPhysics3Json.h" +#include "AssetDefinitionDefault.h" + +#include "AssetDefinition_CubismPhysics3Json.generated.h" + +UCLASS() +class UAssetDefinition_CubismPhysics3Json : public UAssetDefinitionDefault +{ + GENERATED_BODY() + +public: + // UAssetDefinition Begin + virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_CubismPhysics3Json", "CubismPhysics3Json"); } + virtual FLinearColor GetAssetColor() const override { return FLinearColor(FColor::Orange); } + virtual TSoftClassPtr GetAssetClass() const override { return UCubismPhysics3Json::StaticClass(); } + virtual TConstArrayView GetAssetCategories() const override { return TArray(); } + virtual bool CanImport() const override { return true; } + // UAssetDefinition End +}; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Physics/CubismPhysics3JsonFactory.cpp b/Source/Live2DCubismFrameworkImporter/Private/Physics/CubismPhysics3JsonFactory.cpp index 1468a25..7047c30 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Physics/CubismPhysics3JsonFactory.cpp +++ b/Source/Live2DCubismFrameworkImporter/Private/Physics/CubismPhysics3JsonFactory.cpp @@ -12,6 +12,7 @@ #include "Physics/CubismPhysics3JsonImporter.h" #include "Misc/FileHelper.h" #include "Misc/PackageName.h" +#include "CubismLog.h" UCubismPhysics3JsonFactory::UCubismPhysics3JsonFactory() { @@ -57,7 +58,85 @@ UObject* UCubismPhysics3JsonFactory::FactoryCreateText Result = NewObject(InParent, InName, Flags); Importer.ApplyParams(Flags, Result); + + // Update asset import data + if (Result->AssetImportData) + { + Result->AssetImportData->Update(CurrentFilename); + } + else + { + Result->AssetImportData = NewObject(Result, TEXT("AssetImportData")); + Result->AssetImportData->Update(CurrentFilename); + } } return Result; } + +bool UCubismPhysics3JsonFactory::CanReimport(UObject* Obj, TArray& OutFilenames) +{ + UCubismPhysics3Json* Physics = Cast(Obj); + if (Physics && Physics->AssetImportData) + { + Physics->AssetImportData->ExtractFilenames(OutFilenames); + return true; + } + return false; +} + +void UCubismPhysics3JsonFactory::SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) +{ + UCubismPhysics3Json* Physics = Cast(Obj); + if (Physics && ensure(NewReimportPaths.Num() == 1)) + { + Physics->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]); + } +} + +EReimportResult::Type UCubismPhysics3JsonFactory::Reimport(UObject* Obj) +{ + UCubismPhysics3Json* Physics = Cast(Obj); + if (!Physics) + { + return EReimportResult::Failed; + } + + const FString Filename = Physics->AssetImportData->GetFirstFilename(); + if (!Filename.Len()) + { + return EReimportResult::Failed; + } + + if (IFileManager::Get().FileSize(*Filename) == INDEX_NONE) + { + UE_LOG(LogCubism, Warning, TEXT("Cannot reimport: source file '%s' cannot be found."), *Filename); + return EReimportResult::Failed; + } + + bool OutCanceled = false; + + if (ImportObject(Physics->GetClass(), Physics->GetOuter(), *Physics->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled)) + { + UE_LOG(LogCubism, Log, TEXT("Reimported successfully")); + + Physics->AssetImportData->Update(Filename); + + Physics->MarkPackageDirty(); + + return EReimportResult::Succeeded; + } + else + { + if (OutCanceled) + { + UE_LOG(LogCubism, Warning, TEXT("Reimport was canceled")); + return EReimportResult::Cancelled; + } + else + { + UE_LOG(LogCubism, Error, TEXT("Reimport failed")); + return EReimportResult::Failed; + } + } +} diff --git a/Source/Live2DCubismFrameworkImporter/Private/Physics/CubismPhysics3JsonFactory.h b/Source/Live2DCubismFrameworkImporter/Private/Physics/CubismPhysics3JsonFactory.h index 19c733a..fcd32df 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Physics/CubismPhysics3JsonFactory.h +++ b/Source/Live2DCubismFrameworkImporter/Private/Physics/CubismPhysics3JsonFactory.h @@ -8,14 +8,15 @@ #pragma once -#include "Factories/Factory.h" +#include "EditorReimportHandler.h" + #include "CubismPhysics3JsonFactory.generated.h" /** * A factory for creating Cubism physics json assets from physics3.json files. */ UCLASS() -class UCubismPhysics3JsonFactory : public UFactory +class UCubismPhysics3JsonFactory : public UFactory, public FReimportHandler { GENERATED_BODY() @@ -28,4 +29,10 @@ class UCubismPhysics3JsonFactory : public UFactory UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext * Warn ) override; + + //~ Begin FReimportHandler Interface + virtual bool CanReimport(UObject* Obj, TArray& OutFilenames) override; + virtual void SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) override; + virtual EReimportResult::Type Reimport(UObject* Obj) override; + //~ End FReimportHandler Interface }; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Pose/AssetDefinition_CubismPose3Json.h b/Source/Live2DCubismFrameworkImporter/Private/Pose/AssetDefinition_CubismPose3Json.h new file mode 100644 index 0000000..15ab80e --- /dev/null +++ b/Source/Live2DCubismFrameworkImporter/Private/Pose/AssetDefinition_CubismPose3Json.h @@ -0,0 +1,29 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#pragma once + +#include "Pose/CubismPose3Json.h" +#include "AssetDefinitionDefault.h" + +#include "AssetDefinition_CubismPose3Json.generated.h" + +UCLASS() +class UAssetDefinition_CubismPose3Json : public UAssetDefinitionDefault +{ + GENERATED_BODY() + +public: + // UAssetDefinition Begin + virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_CubismPose3Json", "CubismPose3Json"); } + virtual FLinearColor GetAssetColor() const override { return FLinearColor(FColor::Orange); } + virtual TSoftClassPtr GetAssetClass() const override { return UCubismPose3Json::StaticClass(); } + virtual TConstArrayView GetAssetCategories() const override { return TArray(); } + virtual bool CanImport() const override { return true; } + // UAssetDefinition End +}; diff --git a/Source/Live2DCubismFrameworkImporter/Private/Pose/CubismPose3JsonFactory.cpp b/Source/Live2DCubismFrameworkImporter/Private/Pose/CubismPose3JsonFactory.cpp index bd05488..5aea1e4 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Pose/CubismPose3JsonFactory.cpp +++ b/Source/Live2DCubismFrameworkImporter/Private/Pose/CubismPose3JsonFactory.cpp @@ -12,6 +12,7 @@ #include "Pose/CubismPose3JsonImporter.h" #include "Misc/FileHelper.h" #include "Misc/PackageName.h" +#include "CubismLog.h" UCubismPose3JsonFactory::UCubismPose3JsonFactory() { @@ -26,7 +27,7 @@ UCubismPose3JsonFactory::UCubismPose3JsonFactory() FText UCubismPose3JsonFactory::GetToolTip() const { - return NSLOCTEXT("Live2D Cubism Framework", "CubismPose3JsonFactoryDescription", "Model JSON exported from Live2D Cubism Editor"); + return NSLOCTEXT("Live2D Cubism Framework", "CubismPose3JsonFactoryDescription", "Pose JSON exported from Live2D Cubism Editor"); } bool UCubismPose3JsonFactory::FactoryCanImport(const FString& Filename) @@ -56,7 +57,85 @@ UObject* UCubismPose3JsonFactory::FactoryCreateText Result = NewObject(InParent, InName, Flags); Importer.ApplyParams(Flags, Result); + + // Update asset import data + if (Result->AssetImportData) + { + Result->AssetImportData->Update(CurrentFilename); + } + else + { + Result->AssetImportData = NewObject(Result, TEXT("AssetImportData")); + Result->AssetImportData->Update(CurrentFilename); + } } return Result; } + +bool UCubismPose3JsonFactory::CanReimport(UObject* Obj, TArray& OutFilenames) +{ + UCubismPose3Json* Pose = Cast(Obj); + if (Pose && Pose->AssetImportData) + { + Pose->AssetImportData->ExtractFilenames(OutFilenames); + return true; + } + return false; +} + +void UCubismPose3JsonFactory::SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) +{ + UCubismPose3Json* Pose = Cast(Obj); + if (Pose && ensure(NewReimportPaths.Num() == 1)) + { + Pose->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]); + } +} + +EReimportResult::Type UCubismPose3JsonFactory::Reimport(UObject* Obj) +{ + UCubismPose3Json* Pose = Cast(Obj); + if (!Pose) + { + return EReimportResult::Failed; + } + + const FString Filename = Pose->AssetImportData->GetFirstFilename(); + if (!Filename.Len()) + { + return EReimportResult::Failed; + } + + if (IFileManager::Get().FileSize(*Filename) == INDEX_NONE) + { + UE_LOG(LogCubism, Warning, TEXT("Cannot reimport: source file '%s' cannot be found."), *Filename); + return EReimportResult::Failed; + } + + bool OutCanceled = false; + + if (ImportObject(Pose->GetClass(), Pose->GetOuter(), *Pose->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled)) + { + UE_LOG(LogCubism, Log, TEXT("Reimported successfully")); + + Pose->AssetImportData->Update(Filename); + + Pose->MarkPackageDirty(); + + return EReimportResult::Succeeded; + } + else + { + if (OutCanceled) + { + UE_LOG(LogCubism, Warning, TEXT("Reimport was canceled")); + return EReimportResult::Cancelled; + } + else + { + UE_LOG(LogCubism, Error, TEXT("Reimport failed")); + return EReimportResult::Failed; + } + } +} diff --git a/Source/Live2DCubismFrameworkImporter/Private/Pose/CubismPose3JsonFactory.h b/Source/Live2DCubismFrameworkImporter/Private/Pose/CubismPose3JsonFactory.h index 0fac9cf..403f228 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/Pose/CubismPose3JsonFactory.h +++ b/Source/Live2DCubismFrameworkImporter/Private/Pose/CubismPose3JsonFactory.h @@ -8,13 +8,15 @@ #pragma once +#include "EditorReimportHandler.h" + #include "CubismPose3JsonFactory.generated.h" /** * A factory for creating Cubism pose json assets from pose3.json files. */ UCLASS() -class UCubismPose3JsonFactory : public UFactory +class UCubismPose3JsonFactory : public UFactory, public FReimportHandler { GENERATED_BODY() @@ -27,4 +29,10 @@ class UCubismPose3JsonFactory : public UFactory UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext* Warn ) override; + + //~ Begin FReimportHandler Interface + virtual bool CanReimport(UObject* Obj, TArray& OutFilenames) override; + virtual void SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) override; + virtual EReimportResult::Type Reimport(UObject* Obj) override; + //~ End FReimportHandler Interface }; diff --git a/Source/Live2DCubismFrameworkImporter/Private/UserData/AssetDefinition_CubismUserData3Json.h b/Source/Live2DCubismFrameworkImporter/Private/UserData/AssetDefinition_CubismUserData3Json.h new file mode 100644 index 0000000..59da2fe --- /dev/null +++ b/Source/Live2DCubismFrameworkImporter/Private/UserData/AssetDefinition_CubismUserData3Json.h @@ -0,0 +1,29 @@ +/** + * Copyright(c) Live2D Inc. All rights reserved. + * + * Use of this source code is governed by the Live2D Open Software license + * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. + */ + + +#pragma once + +#include "UserData/CubismUserData3Json.h" +#include "AssetDefinitionDefault.h" + +#include "AssetDefinition_CubismUserData3Json.generated.h" + +UCLASS() +class UAssetDefinition_CubismUserData3Json : public UAssetDefinitionDefault +{ + GENERATED_BODY() + +public: + // UAssetDefinition Begin + virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_CubismUserData3Json", "CubismUserData3Json"); } + virtual FLinearColor GetAssetColor() const override { return FLinearColor(FColor::Orange); } + virtual TSoftClassPtr GetAssetClass() const override { return UCubismUserData3Json::StaticClass(); } + virtual TConstArrayView GetAssetCategories() const override { return TArray(); } + virtual bool CanImport() const override { return true; } + // UAssetDefinition End +}; diff --git a/Source/Live2DCubismFrameworkImporter/Private/UserData/CubismUserData3JsonFactory.cpp b/Source/Live2DCubismFrameworkImporter/Private/UserData/CubismUserData3JsonFactory.cpp index a374dac..5b10b21 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/UserData/CubismUserData3JsonFactory.cpp +++ b/Source/Live2DCubismFrameworkImporter/Private/UserData/CubismUserData3JsonFactory.cpp @@ -12,6 +12,7 @@ #include "UserData/CubismUserData3JsonImporter.h" #include "Misc/FileHelper.h" #include "Misc/PackageName.h" +#include "CubismLog.h" UCubismUserData3JsonFactory::UCubismUserData3JsonFactory() { @@ -57,7 +58,85 @@ UObject* UCubismUserData3JsonFactory::FactoryCreateText Result = NewObject(InParent, InName, Flags); Importer.ApplyParams(Flags, Result); + + // Update asset import data + if (Result->AssetImportData) + { + Result->AssetImportData->Update(CurrentFilename); + } + else + { + Result->AssetImportData = NewObject(Result, TEXT("AssetImportData")); + Result->AssetImportData->Update(CurrentFilename); + } } return Result; } + +bool UCubismUserData3JsonFactory::CanReimport(UObject* Obj, TArray& OutFilenames) +{ + UCubismUserData3Json* UserData = Cast(Obj); + if (UserData && UserData->AssetImportData) + { + UserData->AssetImportData->ExtractFilenames(OutFilenames); + return true; + } + return false; +} + +void UCubismUserData3JsonFactory::SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) +{ + UCubismUserData3Json* UserData = Cast(Obj); + if (UserData && ensure(NewReimportPaths.Num() == 1)) + { + UserData->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]); + } +} + +EReimportResult::Type UCubismUserData3JsonFactory::Reimport(UObject* Obj) +{ + UCubismUserData3Json* UserData = Cast(Obj); + if (!UserData) + { + return EReimportResult::Failed; + } + + const FString Filename = UserData->AssetImportData->GetFirstFilename(); + if (!Filename.Len()) + { + return EReimportResult::Failed; + } + + if (IFileManager::Get().FileSize(*Filename) == INDEX_NONE) + { + UE_LOG(LogCubism, Warning, TEXT("Cannot reimport: source file '%s' cannot be found."), *Filename); + return EReimportResult::Failed; + } + + bool OutCanceled = false; + + if (ImportObject(UserData->GetClass(), UserData->GetOuter(), *UserData->GetName(), RF_Public | RF_Standalone, Filename, nullptr, OutCanceled)) + { + UE_LOG(LogCubism, Log, TEXT("Reimported successfully")); + + UserData->AssetImportData->Update(Filename); + + UserData->MarkPackageDirty(); + + return EReimportResult::Succeeded; + } + else + { + if (OutCanceled) + { + UE_LOG(LogCubism, Warning, TEXT("Reimport was canceled")); + return EReimportResult::Cancelled; + } + else + { + UE_LOG(LogCubism, Error, TEXT("Reimport failed")); + return EReimportResult::Failed; + } + } +} diff --git a/Source/Live2DCubismFrameworkImporter/Private/UserData/CubismUserData3JsonFactory.h b/Source/Live2DCubismFrameworkImporter/Private/UserData/CubismUserData3JsonFactory.h index 5eb9c55..d9e6c15 100644 --- a/Source/Live2DCubismFrameworkImporter/Private/UserData/CubismUserData3JsonFactory.h +++ b/Source/Live2DCubismFrameworkImporter/Private/UserData/CubismUserData3JsonFactory.h @@ -8,13 +8,15 @@ #pragma once +#include "EditorReimportHandler.h" + #include "CubismUserData3JsonFactory.generated.h" /** * A factory for creating Cubism user data json assets from userdata3.json files. */ UCLASS() -class UCubismUserData3JsonFactory : public UFactory +class UCubismUserData3JsonFactory : public UFactory, public FReimportHandler { GENERATED_BODY() @@ -27,4 +29,10 @@ class UCubismUserData3JsonFactory : public UFactory UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext * Warn ) override; + + //~ Begin FReimportHandler Interface + virtual bool CanReimport(UObject* Obj, TArray& OutFilenames) override; + virtual void SetReimportPaths(UObject* Obj, const TArray& NewReimportPaths) override; + virtual EReimportResult::Type Reimport(UObject* Obj) override; + //~ End FReimportHandler Interface };