Add Games File

This commit is contained in:
Ivan Anikin
2026-05-19 13:42:41 +07:00
parent 7908479e0c
commit 12e7e22c1a
3672 changed files with 125922 additions and 0 deletions
@@ -0,0 +1,109 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AnimGraphNode_VrmConstraint.h"
#include "Misc/EngineVersionComparison.h"
#include "UnrealWidget.h"
#include "AnimNodeEditModes.h"
#include "AnimationRuntime.h"
#include "Animation/AnimInstance.h"
#include "Kismet2/CompilerResultsLog.h"
#include "Components/SkeletalMeshComponent.h"
#include "VrmMetaObject.h"
#include "VrmUtil.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
#define LOCTEXT_NAMESPACE "A3Nodesaaaa"
////////////////////
UAnimGraphNode_VrmConstraint::UAnimGraphNode_VrmConstraint(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if UE_VERSION_OLDER_THAN(5,0,0)
CurWidgetMode = (int32)FWidget::WM_Rotate;
#else
CurWidgetMode = UE::Widget::EWidgetMode::WM_Rotate;
#endif
}
void UAnimGraphNode_VrmConstraint::ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) {
if (Node.VrmMetaObject_Internal == nullptr) {
//MessageLog.Warning(*LOCTEXT("VrmNoMetaObject", "@@ - You must set VrmMetaObject").ToString(), this);
} else {
if (Node.VrmMetaObject_Internal->SkeletalMesh) {
if (VRMGetSkeleton(Node.VrmMetaObject_Internal->SkeletalMesh) != CompiledClass->GetTargetSkeleton()) {
MessageLog.Warning(*LOCTEXT("VrmDifferentSkeleton", "@@ - You must set VrmMetaObject has same skeleton").ToString(), this);
}
}
if (CompiledClass->GetTargetSkeleton()->GetReferenceSkeleton().GetRawBoneNum() <= 0) {
MessageLog.Warning(*LOCTEXT("VrmNoBone", "@@ - Skeleton bad data").ToString(), this);
}
}
Super::ValidateAnimNodePostCompile(MessageLog, CompiledClass, CompiledNodeIndex);
}
void UAnimGraphNode_VrmConstraint::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog)
{
Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog);
}
FText UAnimGraphNode_VrmConstraint::GetControllerDescription() const
{
if (Node.EnableAutoSearchMetaData) {
return LOCTEXT("VrmConstraint", "VrmConstraint(auto)");
} else {
return LOCTEXT("VrmConstraint", "VrmConstraint");
}
}
FText UAnimGraphNode_VrmConstraint::GetTooltipText() const
{
return LOCTEXT("AnimGraphNode_VrmConstraint_Tooltip", "VrmCopyHandBone");
}
FText UAnimGraphNode_VrmConstraint::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
return GetControllerDescription();
}
void UAnimGraphNode_VrmConstraint::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode)
{
FAnimNode_VrmConstraint* node = static_cast<FAnimNode_VrmConstraint*>(InPreviewNode);
// no copy
}
FEditorModeID UAnimGraphNode_VrmConstraint::GetEditorMode() const
{
return Super::GetEditorMode();
}
void UAnimGraphNode_VrmConstraint::Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const
{
if (PreviewSkelMeshComp)
{
/*
if (FAnimNode_VrmSpringBone* ActiveNode = GetActiveInstanceNode<FAnimNode_VrmSpringBone>(PreviewSkelMeshComp->GetAnimInstance()))
{
if (bPreviewLive) {
ActiveNode->ConditionalDebugDraw(PDI, PreviewSkelMeshComp, bPreviewForeground);
}
}
*/
if (bPreviewLive) {
Node.ConditionalDebugDraw(PDI, PreviewSkelMeshComp, bPreviewForeground);
}
}
}
void UAnimGraphNode_VrmConstraint::CopyPinDefaultsToNodeData(UEdGraphPin* InPin)
{
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,65 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmConstraint.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_SkeletalControlBase.h"
#include "UnrealWidget.h"
#include "AnimNodeEditMode.h"
#include "AnimGraphNode_VrmConstraint.generated.h"
class FCompilerResultsLog;
class FPrimitiveDrawInterface;
class USkeletalMeshComponent;
UCLASS(meta=(Keywords = "VRM4U"))
class UAnimGraphNode_VrmConstraint : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category=Settings)
FAnimNode_VrmConstraint Node;
UPROPERTY(EditAnywhere, Category = Preview)
bool bPreviewLive = true;
UPROPERTY(EditAnywhere, Category = Preview)
bool bPreviewForeground = true;
public:
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
// End of UEdGraphNode interface
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
virtual void ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) override;
// virtual FEditorModeID GetEditorMode() const override;
virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
virtual FEditorModeID GetEditorMode() const override;
virtual void Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const override;
// End of UAnimGraphNode_Base interface
// UAnimGraphNode_SkeletalControlBase interface
virtual FText GetControllerDescription() const override;
virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
// End of UAnimGraphNode_SkeletalControlBase interface
private:
/** Constructing FText strings can be costly, so we cache the node's title */
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
};
@@ -0,0 +1,131 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AnimGraphNode_VrmCopyHandBone.h"
#include "Misc/EngineVersionComparison.h"
#include "UnrealWidget.h"
#include "AnimNodeEditModes.h"
#include "Kismet2/CompilerResultsLog.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
#define LOCTEXT_NAMESPACE "A3Nodesaaaa"
UAnimGraphNode_VrmCopyHandBone::UAnimGraphNode_VrmCopyHandBone(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if UE_VERSION_OLDER_THAN(5,0,0)
CurWidgetMode = (int32)FWidget::WM_Rotate;
#else
CurWidgetMode = UE::Widget::EWidgetMode::WM_Rotate;
#endif
}
void UAnimGraphNode_VrmCopyHandBone::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog)
{
// Temporary fix where skeleton is not fully loaded during AnimBP compilation and thus virtual bone name check is invalid UE-39499 (NEED FIX)
if (ForSkeleton && !ForSkeleton->HasAnyFlags(RF_NeedPostLoad))
{
/*
//if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneToModify.BoneName) == INDEX_NONE)
if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneNameToModify) == INDEX_NONE)
{
//if (Node.BoneToModify.BoneName == NAME_None)
if (Node.BoneNameToModify == NAME_None)
{
MessageLog.Warning(*LOCTEXT("NoBoneSelectedToModify", "@@ - You must pick a bone to modify").ToString(), this);
}
else
{
FFormatNamedArguments Args;
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
FText Msg = FText::Format(LOCTEXT("NoBoneFoundToModify", "@@ - Bone {BoneName} not found in Skeleton"), Args);
MessageLog.Warning(*Msg.ToString(), this);
}
}
*/
}
//if ((Node.TranslationMode == BMM_Ignore) && (Node.RotationMode == BMM_Ignore) && (Node.ScaleMode == BMM_Ignore))
{
// MessageLog.Warning(*LOCTEXT("NothingToModify", "@@ - No components to modify selected. Either Rotation, Translation, or Scale should be set to something other than Ignore").ToString(), this);
}
Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog);
}
FText UAnimGraphNode_VrmCopyHandBone::GetControllerDescription() const
{
return LOCTEXT("VrmCopyHandBone", "VrmCopyHandBone");
}
FText UAnimGraphNode_VrmCopyHandBone::GetTooltipText() const
{
return LOCTEXT("AnimGraphNode_VrmCopyHandBone_Tooltip", "VrmCopyHandBone");
}
FText UAnimGraphNode_VrmCopyHandBone::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneToModify.BoneName == NAME_None))
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneNameToModify == NAME_None))
//{
return GetControllerDescription();
//}
// @TODO: the bone can be altered in the property editor, so we have to
// choose to mark this dirty when that happens for this to properly work
/*
else //if (!CachedNodeTitles.IsTitleCached(TitleType, this))
{
FFormatNamedArguments Args;
Args.Add(TEXT("ControllerDescription"), GetControllerDescription());
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
// FText::Format() is slow, so we cache this to save on performance
if (TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle)
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_ListTitle", "{ControllerDescription} - Bone: {BoneName}"), Args), this);
}
else
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_Title", "{ControllerDescription}\nBone: {BoneName}"), Args), this);
}
}
return CachedNodeTitles[TitleType];
*/
}
void UAnimGraphNode_VrmCopyHandBone::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode)
{
FAnimNode_VrmCopyHandBone* node = static_cast<FAnimNode_VrmCopyHandBone*>(InPreviewNode);
// no copy
}
//FEditorModeID UAnimGraphNode_VrmModifyBoneDynamic::GetEditorMode() const
//{
// return AnimNodeEditModes::ModifyBone;
//}
void UAnimGraphNode_VrmCopyHandBone::CopyPinDefaultsToNodeData(UEdGraphPin* InPin)
{
/*
if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Translation))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Translation), Node.Translation);
}
else if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Rotation))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Rotation), Node.Rotation);
}
else if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Scale))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Scale), Node.Scale);
}
*/
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,49 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmCopyHandBone.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_SkeletalControlBase.h"
#include "AnimGraphNode_VrmCopyHandBone.generated.h"
class FCompilerResultsLog;
UCLASS(meta=(Keywords = "VRM4U"))
class UAnimGraphNode_VrmCopyHandBone : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category=Settings)
FAnimNode_VrmCopyHandBone Node;
public:
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
// End of UEdGraphNode interface
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
// virtual FEditorModeID GetEditorMode() const override;
virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
// End of UAnimGraphNode_Base interface
// UAnimGraphNode_SkeletalControlBase interface
virtual FText GetControllerDescription() const override;
virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
// End of UAnimGraphNode_SkeletalControlBase interface
private:
/** Constructing FText strings can be costly, so we cache the node's title */
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
};
@@ -0,0 +1,138 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AnimGraphNode_VrmModifyBoneDynamic.h"
#include "Misc/EngineVersionComparison.h"
#include "UnrealWidget.h"
#include "AnimNodeEditModes.h"
#include "Kismet2/CompilerResultsLog.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
#define LOCTEXT_NAMESPACE "A3Nodesaaaa"
UAnimGraphNode_VrmModifyBoneDynamic::UAnimGraphNode_VrmModifyBoneDynamic(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if UE_VERSION_OLDER_THAN(5,0,0)
CurWidgetMode = (int32)FWidget::WM_Rotate;
#else
CurWidgetMode = UE::Widget::EWidgetMode::WM_Rotate;
#endif
}
void UAnimGraphNode_VrmModifyBoneDynamic::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog)
{
// Temporary fix where skeleton is not fully loaded during AnimBP compilation and thus virtual bone name check is invalid UE-39499 (NEED FIX)
if (ForSkeleton && !ForSkeleton->HasAnyFlags(RF_NeedPostLoad))
{
//if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneToModify.BoneName) == INDEX_NONE)
if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneNameToModify) == INDEX_NONE)
{
//if (Node.BoneToModify.BoneName == NAME_None)
if (Node.BoneNameToModify == NAME_None)
{
//MessageLog.Warning(*LOCTEXT("NoBoneSelectedToModify", "@@ - You must pick a bone to modify").ToString(), this);
}
else
{
FFormatNamedArguments Args;
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
FText Msg = FText::Format(LOCTEXT("NoBoneFoundToModify", "@@ - Bone {BoneName} not found in Skeleton"), Args);
//MessageLog.Warning(*Msg.ToString(), this);
}
}
}
if ((Node.TranslationMode == BMM_Ignore) && (Node.RotationMode == BMM_Ignore) && (Node.ScaleMode == BMM_Ignore))
{
MessageLog.Warning(*LOCTEXT("NothingToModify", "@@ - No components to modify selected. Either Rotation, Translation, or Scale should be set to something other than Ignore").ToString(), this);
}
Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog);
}
FText UAnimGraphNode_VrmModifyBoneDynamic::GetControllerDescription() const
{
return LOCTEXT("VrmTransformModifyBoneDynamic", "VrmTransform (Modify) BoneDynamic");
}
FText UAnimGraphNode_VrmModifyBoneDynamic::GetTooltipText() const
{
return LOCTEXT("AnimGraphNode_ModifyBone_Tooltip", "The Transform Bone node alters the transform - i.e. Translation, Rotation, or Scale - of the bone");
}
FText UAnimGraphNode_VrmModifyBoneDynamic::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneToModify.BoneName == NAME_None))
if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneNameToModify == NAME_None))
{
return GetControllerDescription();
}
// @TODO: the bone can be altered in the property editor, so we have to
// choose to mark this dirty when that happens for this to properly work
else //if (!CachedNodeTitles.IsTitleCached(TitleType, this))
{
FFormatNamedArguments Args;
Args.Add(TEXT("ControllerDescription"), GetControllerDescription());
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
// FText::Format() is slow, so we cache this to save on performance
if (TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle)
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_ListTitle", "{ControllerDescription} - Bone: {BoneName}"), Args), this);
}
else
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_Title", "{ControllerDescription}\nBone: {BoneName}"), Args), this);
}
}
return CachedNodeTitles[TitleType];
}
void UAnimGraphNode_VrmModifyBoneDynamic::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode)
{
FAnimNode_VrmModifyBoneDynamic* ModifyBone = static_cast<FAnimNode_VrmModifyBoneDynamic*>(InPreviewNode);
// copies Pin values from the internal node to get data which are not compiled yet
ModifyBone->Translation = Node.Translation;
ModifyBone->Rotation = Node.Rotation;
ModifyBone->Scale = Node.Scale;
// copies Modes
ModifyBone->TranslationMode = Node.TranslationMode;
ModifyBone->RotationMode = Node.RotationMode;
ModifyBone->ScaleMode = Node.ScaleMode;
// copies Spaces
ModifyBone->TranslationSpace = Node.TranslationSpace;
ModifyBone->RotationSpace = Node.RotationSpace;
ModifyBone->ScaleSpace = Node.ScaleSpace;
}
//FEditorModeID UAnimGraphNode_VrmModifyBoneDynamic::GetEditorMode() const
//{
// return AnimNodeEditModes::ModifyBone;
//}
void UAnimGraphNode_VrmModifyBoneDynamic::CopyPinDefaultsToNodeData(UEdGraphPin* InPin)
{
if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Translation))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Translation), Node.Translation);
}
else if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Rotation))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Rotation), Node.Rotation);
}
else if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Scale))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Scale), Node.Scale);
}
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,49 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmModifyBoneDynamic.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_SkeletalControlBase.h"
#include "AnimGraphNode_VrmModifyBoneDynamic.generated.h"
class FCompilerResultsLog;
UCLASS(meta=(Keywords = "VRM4U"))
class UAnimGraphNode_VrmModifyBoneDynamic : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category=Settings)
FAnimNode_VrmModifyBoneDynamic Node;
public:
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
// End of UEdGraphNode interface
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
// virtual FEditorModeID GetEditorMode() const override;
virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
// End of UAnimGraphNode_Base interface
// UAnimGraphNode_SkeletalControlBase interface
virtual FText GetControllerDescription() const override;
virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
// End of UAnimGraphNode_SkeletalControlBase interface
private:
/** Constructing FText strings can be costly, so we cache the node's title */
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
};
@@ -0,0 +1,128 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AnimGraphNode_VrmModifyBoneList.h"
#include "Misc/EngineVersionComparison.h"
#include "UnrealWidget.h"
#include "AnimNodeEditModes.h"
#include "AnimationRuntime.h"
#include "Animation/AnimInstance.h"
#include "Kismet2/CompilerResultsLog.h"
#include "Components/SkeletalMeshComponent.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
#define LOCTEXT_NAMESPACE "A3Nodesaaaa"
////////////////////
UAnimGraphNode_VrmModifyBoneList::UAnimGraphNode_VrmModifyBoneList(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if UE_VERSION_OLDER_THAN(5,0,0)
CurWidgetMode = (int32)FWidget::WM_Rotate;
#else
CurWidgetMode = UE::Widget::EWidgetMode::WM_Rotate;
#endif
}
void UAnimGraphNode_VrmModifyBoneList::ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) {
if (CompiledClass->GetTargetSkeleton()->GetReferenceSkeleton().GetRawBoneNum() <= 0) {
MessageLog.Warning(*LOCTEXT("VrmNoBone", "@@ - Skeleton bad data").ToString(), this);
}
Super::ValidateAnimNodePostCompile(MessageLog, CompiledClass, CompiledNodeIndex);
}
void UAnimGraphNode_VrmModifyBoneList::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog)
{
// Temporary fix where skeleton is not fully loaded during AnimBP compilation and thus virtual bone name check is invalid UE-39499 (NEED FIX)
if (ForSkeleton && !ForSkeleton->HasAnyFlags(RF_NeedPostLoad))
{
/*
//if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneToModify.BoneName) == INDEX_NONE)
if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneNameToModify) == INDEX_NONE)
{
//if (Node.BoneToModify.BoneName == NAME_None)
if (Node.BoneNameToModify == NAME_None)
{
MessageLog.Warning(*LOCTEXT("NoBoneSelectedToModify", "@@ - You must pick a bone to modify").ToString(), this);
}
else
{
FFormatNamedArguments Args;
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
FText Msg = FText::Format(LOCTEXT("NoBoneFoundToModify", "@@ - Bone {BoneName} not found in Skeleton"), Args);
MessageLog.Warning(*Msg.ToString(), this);
}
}
*/
}
//if ((Node.TranslationMode == BMM_Ignore) && (Node.RotationMode == BMM_Ignore) && (Node.ScaleMode == BMM_Ignore))
{
// MessageLog.Warning(*LOCTEXT("NothingToModify", "@@ - No components to modify selected. Either Rotation, Translation, or Scale should be set to something other than Ignore").ToString(), this);
}
Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog);
}
FText UAnimGraphNode_VrmModifyBoneList::GetControllerDescription() const
{
return LOCTEXT("VrmModifyBoneList", "VrmModifyBoneList");
}
FText UAnimGraphNode_VrmModifyBoneList::GetTooltipText() const
{
return LOCTEXT("AnimGraphNode_VrmModifyBoneList_Tooltip", "VrmModifyBoneList");
}
FText UAnimGraphNode_VrmModifyBoneList::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneToModify.BoneName == NAME_None))
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneNameToModify == NAME_None))
//{
return GetControllerDescription();
//}
// @TODO: the bone can be altered in the property editor, so we have to
// choose to mark this dirty when that happens for this to properly work
/*
else //if (!CachedNodeTitles.IsTitleCached(TitleType, this))
{
FFormatNamedArguments Args;
Args.Add(TEXT("ControllerDescription"), GetControllerDescription());
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
// FText::Format() is slow, so we cache this to save on performance
if (TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle)
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_ListTitle", "{ControllerDescription} - Bone: {BoneName}"), Args), this);
}
else
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_Title", "{ControllerDescription}\nBone: {BoneName}"), Args), this);
}
}
return CachedNodeTitles[TitleType];
*/
}
//void UAnimGraphNode_VrmModifyBoneList::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode)
//{
//}
FEditorModeID UAnimGraphNode_VrmModifyBoneList::GetEditorMode() const
{
return Super::GetEditorMode();
}
void UAnimGraphNode_VrmModifyBoneList::Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const
{
Super::Draw(PDI, PreviewSkelMeshComp);
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,60 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmModifyBoneList.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_SkeletalControlBase.h"
#include "UnrealWidget.h"
#include "AnimNodeEditMode.h"
#include "AnimGraphNode_VrmModifyBoneList.generated.h"
class FCompilerResultsLog;
class FPrimitiveDrawInterface;
class USkeletalMeshComponent;
UCLASS(meta=(Keywords = "VRM4U"))
class UAnimGraphNode_VrmModifyBoneList : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category=Settings)
FAnimNode_VrmModifyBoneList Node;
public:
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
// End of UEdGraphNode interface
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
virtual void ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) override;
// virtual FEditorModeID GetEditorMode() const override;
//virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
//virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
virtual FEditorModeID GetEditorMode() const override;
virtual void Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const override;
// End of UAnimGraphNode_Base interface
// UAnimGraphNode_SkeletalControlBase interface
virtual FText GetControllerDescription() const override;
virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
// End of UAnimGraphNode_SkeletalControlBase interface
private:
/** Constructing FText strings can be costly, so we cache the node's title */
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
};
@@ -0,0 +1,162 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AnimGraphNode_VrmModifyBoneListRetarget.h"
#include "Misc/EngineVersionComparison.h"
#include "UnrealWidget.h"
#include "AnimNodeEditModes.h"
#include "AnimationRuntime.h"
#include "Animation/AnimInstance.h"
#include "Kismet2/CompilerResultsLog.h"
#include "Components/SkeletalMeshComponent.h"
#include "VrmMetaObject.h"
#include "VrmUtil.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
#define LOCTEXT_NAMESPACE "A3Nodesaaaa"
////////////////////
UAnimGraphNode_VrmModifyBoneListRetarget::UAnimGraphNode_VrmModifyBoneListRetarget(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if UE_VERSION_OLDER_THAN(5,0,0)
CurWidgetMode = (int32)FWidget::WM_Rotate;
#else
CurWidgetMode = UE::Widget::EWidgetMode::WM_Rotate;
#endif
}
void UAnimGraphNode_VrmModifyBoneListRetarget::ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) {
if (Node.VrmMetaObject == nullptr) {
//MessageLog.Warning(*LOCTEXT("VrmNoMetaObject", "@@ - You must set VrmMetaObject").ToString(), this);
} else {
if (Node.VrmMetaObject->SkeletalMesh) {
if (VRMGetSkeleton(Node.VrmMetaObject->SkeletalMesh) != CompiledClass->GetTargetSkeleton()) {
MessageLog.Warning(*LOCTEXT("VrmDifferentSkeleton", "@@ - You must set VrmMetaObject has same skeleton").ToString(), this);
}
}
if (CompiledClass->GetTargetSkeleton()->GetReferenceSkeleton().GetRawBoneNum() <= 0) {
MessageLog.Warning(*LOCTEXT("VrmNoBone", "@@ - Skeleton bad data").ToString(), this);
}
}
Super::ValidateAnimNodePostCompile(MessageLog, CompiledClass, CompiledNodeIndex);
}
void UAnimGraphNode_VrmModifyBoneListRetarget::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog)
{
// Temporary fix where skeleton is not fully loaded during AnimBP compilation and thus virtual bone name check is invalid UE-39499 (NEED FIX)
if (ForSkeleton && !ForSkeleton->HasAnyFlags(RF_NeedPostLoad))
{
if (Node.VrmMetaObject == nullptr) {
//MessageLog.Warning(*LOCTEXT("VrmNoMetaObject", "@@ - You must set VrmMetaObject").ToString(), this);
} else {
if (Node.VrmMetaObject->SkeletalMesh){
if (VRMGetSkeleton(Node.VrmMetaObject->SkeletalMesh) != ForSkeleton) {
// MessageLog.Warning(*LOCTEXT("VrmDifferentSkeleton", "@@ - You must set VrmMetaObject has same skeleton").ToString(), this);
}
}
if (ForSkeleton->GetReferenceSkeleton().GetRawBoneNum() <= 0) {
// MessageLog.Warning(*LOCTEXT("VrmNoBone", "@@ - Skeleton bad data").ToString(), this);
}
}
/*
//if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneToModify.BoneName) == INDEX_NONE)
if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneNameToModify) == INDEX_NONE)
{
//if (Node.BoneToModify.BoneName == NAME_None)
if (Node.BoneNameToModify == NAME_None)
{
MessageLog.Warning(*LOCTEXT("NoBoneSelectedToModify", "@@ - You must pick a bone to modify").ToString(), this);
}
else
{
FFormatNamedArguments Args;
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
FText Msg = FText::Format(LOCTEXT("NoBoneFoundToModify", "@@ - Bone {BoneName} not found in Skeleton"), Args);
MessageLog.Warning(*Msg.ToString(), this);
}
}
*/
}
//if ((Node.TranslationMode == BMM_Ignore) && (Node.RotationMode == BMM_Ignore) && (Node.ScaleMode == BMM_Ignore))
{
// MessageLog.Warning(*LOCTEXT("NothingToModify", "@@ - No components to modify selected. Either Rotation, Translation, or Scale should be set to something other than Ignore").ToString(), this);
}
Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog);
}
FText UAnimGraphNode_VrmModifyBoneListRetarget::GetControllerDescription() const
{
return LOCTEXT("VrmModifyBoneListRetarget", "VrmModifyBoneListRetarget");
}
FText UAnimGraphNode_VrmModifyBoneListRetarget::GetTooltipText() const
{
return LOCTEXT("AnimGraphNode_VrmModifyBoneListRetarget_Tooltip", "VrmModifyBoneListRetarget");
}
FText UAnimGraphNode_VrmModifyBoneListRetarget::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneToModify.BoneName == NAME_None))
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneNameToModify == NAME_None))
//{
return GetControllerDescription();
//}
// @TODO: the bone can be altered in the property editor, so we have to
// choose to mark this dirty when that happens for this to properly work
/*
else //if (!CachedNodeTitles.IsTitleCached(TitleType, this))
{
FFormatNamedArguments Args;
Args.Add(TEXT("ControllerDescription"), GetControllerDescription());
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
// FText::Format() is slow, so we cache this to save on performance
if (TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle)
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_ListTitle", "{ControllerDescription} - Bone: {BoneName}"), Args), this);
}
else
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_Title", "{ControllerDescription}\nBone: {BoneName}"), Args), this);
}
}
return CachedNodeTitles[TitleType];
*/
}
//void UAnimGraphNode_VrmModifyBoneListRetarget::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode)
//{
//}
FEditorModeID UAnimGraphNode_VrmModifyBoneListRetarget::GetEditorMode() const
{
return Super::GetEditorMode();
}
void UAnimGraphNode_VrmModifyBoneListRetarget::Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const
{
if (PreviewSkelMeshComp)
{
if (FAnimNode_VrmModifyBoneListRetarget* ActiveNode = GetActiveInstanceNode<FAnimNode_VrmModifyBoneListRetarget>(PreviewSkelMeshComp->GetAnimInstance()))
{
if (bPreviewLive) {
//ActiveNode->ConditionalDebugDraw(PDI, PreviewSkelMeshComp, bPreviewForeground);
}
}
}
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,65 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmModifyBoneListRetarget.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_SkeletalControlBase.h"
#include "UnrealWidget.h"
#include "AnimNodeEditMode.h"
#include "AnimGraphNode_VrmModifyBoneListRetarget.generated.h"
class FCompilerResultsLog;
class FPrimitiveDrawInterface;
class USkeletalMeshComponent;
UCLASS(meta=(Keywords = "Modify Transform"))
class UAnimGraphNode_VrmModifyBoneListRetarget : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category = Settings)
FAnimNode_VrmModifyBoneListRetarget Node;
public:
UPROPERTY(EditAnywhere, Category = Preview)
bool bPreviewLive = true;
UPROPERTY(EditAnywhere, Category = Preview)
bool bPreviewForeground = false;
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
// End of UEdGraphNode interface
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
virtual void ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) override;
// virtual FEditorModeID GetEditorMode() const override;
//virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
//virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
virtual FEditorModeID GetEditorMode() const override;
virtual void Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const override;
// End of UAnimGraphNode_Base interface
// UAnimGraphNode_SkeletalControlBase interface
virtual FText GetControllerDescription() const override;
virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
// End of UAnimGraphNode_SkeletalControlBase interface
private:
/** Constructing FText strings can be costly, so we cache the node's title */
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
};
@@ -0,0 +1,68 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AnimGraphNode_VrmModifyHumanoidBone.h"
#include "Misc/EngineVersionComparison.h"
#include "UnrealWidget.h"
#include "AnimNodeEditModes.h"
#include "Kismet2/CompilerResultsLog.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
#define LOCTEXT_NAMESPACE "A3Nodesaaaa"
UAnimGraphNode_VrmModifyHumanoidBone::UAnimGraphNode_VrmModifyHumanoidBone(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if UE_VERSION_OLDER_THAN(5,0,0)
CurWidgetMode = (int32)FWidget::WM_Rotate;
#else
CurWidgetMode = UE::Widget::EWidgetMode::WM_Rotate;
#endif
}
void UAnimGraphNode_VrmModifyHumanoidBone::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog)
{
// Temporary fix where skeleton is not fully loaded during AnimBP compilation and thus virtual bone name check is invalid UE-39499 (NEED FIX)
if (ForSkeleton && !ForSkeleton->HasAnyFlags(RF_NeedPostLoad))
{
}
Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog);
}
FText UAnimGraphNode_VrmModifyHumanoidBone::GetControllerDescription() const
{
return LOCTEXT("VrmModifyHumanoidBone", "VrmTransform (Modify) Humanoid Bone");
}
FText UAnimGraphNode_VrmModifyHumanoidBone::GetTooltipText() const
{
return LOCTEXT("AnimGraphNode_ModifyBone_Tooltip", "The Transform Bone node alters the transform - i.e. Translation, Rotation, or Scale - of the bone");
}
FText UAnimGraphNode_VrmModifyHumanoidBone::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
return GetControllerDescription();
}
void UAnimGraphNode_VrmModifyHumanoidBone::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode)
{
FAnimNode_VrmModifyHumanoidBone* ModifyBone = static_cast<FAnimNode_VrmModifyHumanoidBone*>(InPreviewNode);
// copies Pin values from the internal node to get data which are not compiled yet
//ModifyBone->Transform = Node.Transform;
//ModifyBone->VrmAssetList = Node.VrmAssetList;
//ModifyBone->bEnableRotation = Node.bEnableRotation;
}
//FEditorModeID UAnimGraphNode_VrmModifyHumanoidBone::GetEditorMode() const
//{
// return AnimNodeEditModes::ModifyBone;
//}
void UAnimGraphNode_VrmModifyHumanoidBone::CopyPinDefaultsToNodeData(UEdGraphPin* InPin)
{
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,49 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmModifyHumanoidBone.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_SkeletalControlBase.h"
#include "AnimGraphNode_VrmModifyHumanoidBone.generated.h"
class FCompilerResultsLog;
UCLASS(meta=(Keywords = "VRM4U"))
class UAnimGraphNode_VrmModifyHumanoidBone : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category=Settings)
FAnimNode_VrmModifyHumanoidBone Node;
public:
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
// End of UEdGraphNode interface
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
// virtual FEditorModeID GetEditorMode() const override;
virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
// End of UAnimGraphNode_Base interface
// UAnimGraphNode_SkeletalControlBase interface
virtual FText GetControllerDescription() const override;
virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
// End of UAnimGraphNode_SkeletalControlBase interface
private:
/** Constructing FText strings can be costly, so we cache the node's title */
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
};
@@ -0,0 +1,214 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "AnimGraphNode_VrmPoseBlendNode.h"
#include "EdGraphSchema_K2_Actions.h"
#include "Modules/ModuleManager.h"
#if UE_VERSION_OLDER_THAN(4,24,0)
#else
#include "ToolMenus.h"
#endif
#include "AnimGraphCommands.h"
#include "BlueprintActionFilter.h"
#include "BlueprintActionDatabaseRegistrar.h"
#include "BlueprintNodeSpawner.h"
#if UE_VERSION_OLDER_THAN(4,26,0)
#else
#include "AssetRegistry/ARFilter.h"
#include "AssetRegistry/AssetRegistryModule.h"
#endif
#define LOCTEXT_NAMESPACE "PoseBlendNode"
/////////////////////////////////////////////////////
// UAnimGraphNode_VrmPoseBlendNode
UAnimGraphNode_VrmPoseBlendNode::UAnimGraphNode_VrmPoseBlendNode(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void UAnimGraphNode_VrmPoseBlendNode::GetAllAnimationSequencesReferred(TArray<UAnimationAsset*>& AnimationAssets) const
{
if (Node.PoseAsset)
{
HandleAnimReferenceCollection(Node.PoseAsset, AnimationAssets);
}
}
void UAnimGraphNode_VrmPoseBlendNode::ReplaceReferredAnimations(const TMap<UAnimationAsset*, UAnimationAsset*>& AnimAssetReplacementMap)
{
HandleAnimReferenceReplacement(Node.PoseAsset, AnimAssetReplacementMap);
}
FText UAnimGraphNode_VrmPoseBlendNode::GetTooltipText() const
{
// FText::Format() is slow, so we utilize the cached list title
return GetNodeTitle(ENodeTitleType::ListView);
}
FText UAnimGraphNode_VrmPoseBlendNode::GetNodeTitleForPoseAsset(ENodeTitleType::Type TitleType, UPoseAsset* InPoseAsset) const
{
FFormatNamedArguments Args;
Args.Add(TEXT("PoseAssetName"), FText::FromString(InPoseAsset->GetName()));
return FText::Format(LOCTEXT("PoseByName_Title", "VRM4U {PoseAssetName}"), Args);
}
FText UAnimGraphNode_VrmPoseBlendNode::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
if (Node.EnableAutoSearchMetaData)
{
// we may have a valid variable connected or default pin value
UEdGraphPin* PosePin = FindPin(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_VrmPoseBlendNode, PoseAsset));
if (PosePin && PosePin->LinkedTo.Num() > 0)
{
return LOCTEXT("PoseByName_TitleVariable", "VRM4U Pose");
}
else if (PosePin && PosePin->DefaultObject != nullptr)
{
return GetNodeTitleForPoseAsset(TitleType, CastChecked<UPoseAsset>(PosePin->DefaultObject));
}
else
{
return LOCTEXT("PoseByName_TitleNONE", "VRM4U Pose (Auto Search)");
}
}
else
{
return LOCTEXT("PoseByName_TitleVariable", "VRM4U Pose");
//return GetNodeTitleForPoseAsset(TitleType, Node.PoseAsset);
}
}
void UAnimGraphNode_VrmPoseBlendNode::GetMenuActions(FBlueprintActionDatabaseRegistrar& InActionRegistrar) const
{
#if UE_VERSION_OLDER_THAN(5,0,0)
#else
GetMenuActionsHelper(
InActionRegistrar,
GetClass(),
{ UPoseAsset::StaticClass() },
{ },
[](const FAssetData& InAssetData, UClass* InClass)
{
if (InAssetData.IsValid())
{
return GetTitleGivenAssetInfo(FText::FromName(InAssetData.AssetName));
}
else
{
return LOCTEXT("PlayerDesc", "VRM4U Evaluate Pose");
}
},
[](const FAssetData& InAssetData, UClass* InClass)
{
if (InAssetData.IsValid())
{
return GetTitleGivenAssetInfo(FText::FromName(InAssetData.AssetName));
}
else
{
return LOCTEXT("PlayerDescTooltip", "VRM4U Evaluate Pose Asset");
}
},
[](UEdGraphNode* InNewNode, bool bInIsTemplateNode, const FAssetData InAssetData)
{
UAnimGraphNode_AssetPlayerBase::SetupNewNode(InNewNode, bInIsTemplateNode, InAssetData);
});
#endif
}
FText UAnimGraphNode_VrmPoseBlendNode::GetTitleGivenAssetInfo(const FText& AssetName)
{
FFormatNamedArguments Args;
Args.Add(TEXT("AssetName"), AssetName);
return FText::Format(LOCTEXT("PoseAssetNodeTitle", "Evaluate Pose {AssetName}"), Args);
}
FText UAnimGraphNode_VrmPoseBlendNode::GetMenuCategory() const
{
return LOCTEXT("PoseAssetCategory_Label", "Animation|Poses");
}
bool UAnimGraphNode_VrmPoseBlendNode::DoesSupportTimeForTransitionGetter() const
{
return false;
}
#if UE_VERSION_OLDER_THAN(4,24,0)
#else
void UAnimGraphNode_VrmPoseBlendNode::GetNodeContextMenuActions(UToolMenu* Menu, UGraphNodeContextMenuContext* Context) const
{
#if UE_VERSION_OLDER_THAN(5,0,0)
#else
if (!Context->bIsDebugging)
{
// add an option to convert to single frame
{
FToolMenuSection& Section = Menu->AddSection("AnimGraphNodePoseBlender", LOCTEXT("PoseBlenderHeading", "Pose Blender"));
Section.AddMenuEntry(FAnimGraphCommands::Get().ConvertToPoseByName);
}
}
#endif
}
#endif
EAnimAssetHandlerType UAnimGraphNode_VrmPoseBlendNode::SupportsAssetClass(const UClass* AssetClass) const
{
if (AssetClass->IsChildOf(UPoseAsset::StaticClass()))
{
return EAnimAssetHandlerType::PrimaryHandler;
}
else
{
return EAnimAssetHandlerType::NotSupported;
}
}
////
void UAnimGraphNode_VrmPoseBlendNode::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) {
}
void UAnimGraphNode_VrmPoseBlendNode::PreloadRequiredAssets() {
}
UAnimationAsset* UAnimGraphNode_VrmPoseBlendNode::GetAnimationAsset() const {
UPoseAsset* PoseAsset = GetPoseHandlerNode()->PoseAsset;
UEdGraphPin* PoseAssetPin = FindPin(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_PoseHandler, PoseAsset));
if (PoseAssetPin != nullptr && PoseAsset == nullptr)
{
PoseAsset = Cast<UPoseAsset>(PoseAssetPin->DefaultObject);
}
return PoseAsset;
}
#if UE_VERSION_OLDER_THAN(5,0,0)
#else
TSubclassOf<UAnimationAsset> UAnimGraphNode_VrmPoseBlendNode::GetAnimationAssetClass() const {
return UPoseAsset::StaticClass();
}
void UAnimGraphNode_VrmPoseBlendNode::OnOverrideAssets(IAnimBlueprintNodeOverrideAssetsContext& InContext) const {
/*
if (InContext.GetAssets().Num() > 0)
{
if (UPoseAsset* PoseAsset = Cast<UPoseAsset>(InContext.GetAssets()[0]))
{
FAnimNode_PoseHandler& AnimNode = InContext.GetAnimNode<FAnimNode_PoseHandler>();
AnimNode.SetPoseAsset(PoseAsset);
}
}
*/
}
#endif
void UAnimGraphNode_VrmPoseBlendNode::SetAnimationAsset(UAnimationAsset* Asset) {
if (UPoseAsset* PoseAsset = Cast<UPoseAsset>(Asset))
{
GetPoseHandlerNode()->PoseAsset = PoseAsset;
}
}
////
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,156 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
/*
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmPoseBlendNode.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_PoseBlendNode.h"
#include "UnrealWidget.h"
#include "AnimNodeEditMode.h"
#include "AnimGraphNode_VrmPoseBlendNode.generated.h"
class FCompilerResultsLog;
class FPrimitiveDrawInterface;
class USkeletalMeshComponent;
UCLASS(meta=(Keywords = "VRM4U"))
class UAnimGraphNode_VrmPoseBlendNode : public UAnimGraphNode_PoseBlendNode
{
GENERATED_UCLASS_BODY()
//UPROPERTY(EditAnywhere, Category=Settings)
//FAnimNode_VrmPoseBlendNode Node;
UPROPERTY(EditAnywhere, Category = Preview)
bool bPreviewLive = true;
UPROPERTY(EditAnywhere, Category = Preview)
bool bPreviewForeground = true;
public:
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
virtual FText GetMenuCategory() const;
// End of UEdGraphNode interface
// UAnimGraphNode_Base interface
virtual void PreloadRequiredAssets() override;
UAnimationAsset* GetAnimationAsset() const override;
virtual TSubclassOf<UAnimationAsset> GetAnimationAssetClass() const override;
virtual void OnOverrideAssets(IAnimBlueprintNodeOverrideAssetsContext& InContext) const override {}
virtual void SetAnimationAsset(UAnimationAsset* Asset) override;
virtual bool DoesSupportTimeForTransitionGetter() const override { return true; }
virtual void GetAllAnimationSequencesReferred(TArray<UAnimationAsset*>& AnimationAssets) const override;
virtual void ReplaceReferredAnimations(const TMap<UAnimationAsset*, UAnimationAsset*>& AnimAssetReplacementMap) override;
virtual void GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const override;
virtual EAnimAssetHandlerType SupportsAssetClass(const UClass* AssetClass) const override;
virtual void GetNodeContextMenuActions(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context) const override {}
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
// virtual FEditorModeID GetEditorMode() const override;
virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
// End of UAnimGraphNode_Base interface
private:
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
static FText GetTitleGivenAssetInfo2(const FText& AssetName);
};
*/
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "AnimGraphNode_PoseHandler.h"
//#include "AnimNodes/AnimNode_PoseBlendNode.h"
#include "AnimNode_VrmPoseBlendNode.h"
#include "AnimGraphNode_VrmPoseBlendNode.generated.h"
class FBlueprintActionDatabaseRegistrar;
UCLASS(MinimalAPI)
class UAnimGraphNode_VrmPoseBlendNode : public UAnimGraphNode_PoseHandler
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category = Settings)
FAnimNode_VrmPoseBlendNode Node;
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
virtual FText GetMenuCategory() const override;
// End of UEdGraphNode
// UAnimGraphNode_Base interface
// Interface to support transition getter
virtual bool DoesSupportTimeForTransitionGetter() const override;
virtual void GetAllAnimationSequencesReferred(TArray<UAnimationAsset*>& AnimationAssets) const override;
virtual void ReplaceReferredAnimations(const TMap<UAnimationAsset*, UAnimationAsset*>& AnimAssetReplacementMap) override;
virtual void GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const override;
virtual EAnimAssetHandlerType SupportsAssetClass(const UClass* AssetClass) const override;
// End of UAnimGraphNode_Base
#if UE_VERSION_OLDER_THAN(4,24,0)
#else
// UK2Node interface
virtual void GetNodeContextMenuActions(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context) const override;
// End of UK2Node interface
#endif
private:
FText GetNodeTitleForPoseAsset(ENodeTitleType::Type TitleType, UPoseAsset* InPoseAsset) const;
private:
static FText GetTitleGivenAssetInfo(const FText& AssetName);
/** Used for filtering in the Blueprint context menu when the pose asset this node uses is unloaded */
FString UnloadedSkeletonName;
protected:
virtual FAnimNode_PoseHandler* GetPoseHandlerNode() override { return &Node; }
virtual const FAnimNode_PoseHandler* GetPoseHandlerNode() const override { return &Node; }
protected:
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
public:
virtual void PreloadRequiredAssets() override;
UAnimationAsset* GetAnimationAsset() const override;
#if UE_VERSION_OLDER_THAN(5,0,0)
#else
virtual TSubclassOf<UAnimationAsset> GetAnimationAssetClass() const override;
virtual void OnOverrideAssets(IAnimBlueprintNodeOverrideAssetsContext & InContext) const override;
#endif
virtual void SetAnimationAsset(UAnimationAsset* Asset) override;
#if UE_VERSION_OLDER_THAN(4,26,0)
#elif UE_VERSION_OLDER_THAN(5,0,0)
virtual void OnProcessDuringCompilation(IAnimBlueprintCompilationContext& InCompilationContext, IAnimBlueprintGeneratedClassCompiledData& OutCompiledData) override {
}
#endif
};
@@ -0,0 +1,131 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AnimGraphNode_VrmQuestHandBone.h"
#include "Misc/EngineVersionComparison.h"
#include "UnrealWidget.h"
#include "AnimNodeEditModes.h"
#include "Kismet2/CompilerResultsLog.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
#define LOCTEXT_NAMESPACE "A3Nodesaaaa"
UAnimGraphNode_VrmQuestHandBone::UAnimGraphNode_VrmQuestHandBone(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if UE_VERSION_OLDER_THAN(5,0,0)
CurWidgetMode = (int32)FWidget::WM_Rotate;
#else
CurWidgetMode = UE::Widget::EWidgetMode::WM_Rotate;
#endif
}
void UAnimGraphNode_VrmQuestHandBone::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog)
{
// Temporary fix where skeleton is not fully loaded during AnimBP compilation and thus virtual bone name check is invalid UE-39499 (NEED FIX)
if (ForSkeleton && !ForSkeleton->HasAnyFlags(RF_NeedPostLoad))
{
/*
//if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneToModify.BoneName) == INDEX_NONE)
if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneNameToModify) == INDEX_NONE)
{
//if (Node.BoneToModify.BoneName == NAME_None)
if (Node.BoneNameToModify == NAME_None)
{
MessageLog.Warning(*LOCTEXT("NoBoneSelectedToModify", "@@ - You must pick a bone to modify").ToString(), this);
}
else
{
FFormatNamedArguments Args;
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
FText Msg = FText::Format(LOCTEXT("NoBoneFoundToModify", "@@ - Bone {BoneName} not found in Skeleton"), Args);
MessageLog.Warning(*Msg.ToString(), this);
}
}
*/
}
//if ((Node.TranslationMode == BMM_Ignore) && (Node.RotationMode == BMM_Ignore) && (Node.ScaleMode == BMM_Ignore))
{
// MessageLog.Warning(*LOCTEXT("NothingToModify", "@@ - No components to modify selected. Either Rotation, Translation, or Scale should be set to something other than Ignore").ToString(), this);
}
Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog);
}
FText UAnimGraphNode_VrmQuestHandBone::GetControllerDescription() const
{
return LOCTEXT("VrmQuestHandBone", "VrmQuestHandBone");
}
FText UAnimGraphNode_VrmQuestHandBone::GetTooltipText() const
{
return LOCTEXT("AnimGraphNode_VrmQuestHandBone_Tooltip", "VrmQuestHandBone");
}
FText UAnimGraphNode_VrmQuestHandBone::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneToModify.BoneName == NAME_None))
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneNameToModify == NAME_None))
//{
return GetControllerDescription();
//}
// @TODO: the bone can be altered in the property editor, so we have to
// choose to mark this dirty when that happens for this to properly work
/*
else //if (!CachedNodeTitles.IsTitleCached(TitleType, this))
{
FFormatNamedArguments Args;
Args.Add(TEXT("ControllerDescription"), GetControllerDescription());
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
// FText::Format() is slow, so we cache this to save on performance
if (TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle)
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_ListTitle", "{ControllerDescription} - Bone: {BoneName}"), Args), this);
}
else
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_Title", "{ControllerDescription}\nBone: {BoneName}"), Args), this);
}
}
return CachedNodeTitles[TitleType];
*/
}
void UAnimGraphNode_VrmQuestHandBone::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode)
{
FAnimNode_VrmQuestHandBone* node = static_cast<FAnimNode_VrmQuestHandBone*>(InPreviewNode);
// no copy
}
//FEditorModeID UAnimGraphNode_VrmModifyBoneDynamic::GetEditorMode() const
//{
// return AnimNodeEditModes::ModifyBone;
//}
void UAnimGraphNode_VrmQuestHandBone::CopyPinDefaultsToNodeData(UEdGraphPin* InPin)
{
/*
if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Translation))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Translation), Node.Translation);
}
else if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Rotation))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Rotation), Node.Rotation);
}
else if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Scale))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Scale), Node.Scale);
}
*/
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,49 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmQuestHandBone.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_SkeletalControlBase.h"
#include "AnimGraphNode_VrmQuestHandBone.generated.h"
class FCompilerResultsLog;
UCLASS(meta=(Keywords = "VRM4U"))
class UAnimGraphNode_VrmQuestHandBone : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category=Settings)
FAnimNode_VrmQuestHandBone Node;
public:
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
// End of UEdGraphNode interface
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
// virtual FEditorModeID GetEditorMode() const override;
virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
// End of UAnimGraphNode_Base interface
// UAnimGraphNode_SkeletalControlBase interface
virtual FText GetControllerDescription() const override;
virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
// End of UAnimGraphNode_SkeletalControlBase interface
private:
/** Constructing FText strings can be costly, so we cache the node's title */
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
};
@@ -0,0 +1,91 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AnimGraphNode_VrmRetargetFromMannequin.h"
#include "Misc/EngineVersionComparison.h"
#include "UnrealWidget.h"
#include "AnimNodeEditModes.h"
#include "AnimationRuntime.h"
#include "Animation/AnimInstance.h"
#include "Kismet2/CompilerResultsLog.h"
#include "Components/SkeletalMeshComponent.h"
#include "VrmMetaObject.h"
#include "VrmUtil.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
#define LOCTEXT_NAMESPACE "A3Nodesaaaa"
////////////////////
UAnimGraphNode_VrmRetargetFromMannequin::UAnimGraphNode_VrmRetargetFromMannequin(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if UE_VERSION_OLDER_THAN(5,0,0)
CurWidgetMode = (int32)FWidget::WM_Rotate;
#else
CurWidgetMode = UE::Widget::EWidgetMode::WM_Rotate;
#endif
}
void UAnimGraphNode_VrmRetargetFromMannequin::ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) {
if (Node.VrmMetaObject == nullptr) {
//MessageLog.Warning(*LOCTEXT("VrmNoMetaObject", "@@ - You must set VrmMetaObject").ToString(), this);
} else {
if (Node.VrmMetaObject->SkeletalMesh) {
if (VRMGetSkeleton(Node.VrmMetaObject->SkeletalMesh) != CompiledClass->GetTargetSkeleton()) {
MessageLog.Warning(*LOCTEXT("VrmDifferentSkeleton", "@@ - You must set VrmMetaObject has same skeleton").ToString(), this);
}
}
if (CompiledClass->GetTargetSkeleton()->GetReferenceSkeleton().GetRawBoneNum() <= 0) {
MessageLog.Warning(*LOCTEXT("VrmNoBone", "@@ - Skeleton bad data").ToString(), this);
}
}
Super::ValidateAnimNodePostCompile(MessageLog, CompiledClass, CompiledNodeIndex);
}
void UAnimGraphNode_VrmRetargetFromMannequin::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog)
{
Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog);
}
FText UAnimGraphNode_VrmRetargetFromMannequin::GetControllerDescription() const
{
return LOCTEXT("VrmRetargetFromMannequin", "VrmRetargetFromMannequin");
}
FText UAnimGraphNode_VrmRetargetFromMannequin::GetTooltipText() const
{
return LOCTEXT("AnimGraphNode_VrmRetargetFromMannequin_Tooltip", "VrmCopyHandBone");
}
FText UAnimGraphNode_VrmRetargetFromMannequin::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
return GetControllerDescription();
}
void UAnimGraphNode_VrmRetargetFromMannequin::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode)
{
FAnimNode_VrmRetargetFromMannequin* node = static_cast<FAnimNode_VrmRetargetFromMannequin*>(InPreviewNode);
// no copy
}
FEditorModeID UAnimGraphNode_VrmRetargetFromMannequin::GetEditorMode() const
{
return Super::GetEditorMode();
}
void UAnimGraphNode_VrmRetargetFromMannequin::Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const
{
}
void UAnimGraphNode_VrmRetargetFromMannequin::CopyPinDefaultsToNodeData(UEdGraphPin* InPin)
{
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,59 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmRetargetFromMannequin.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_SkeletalControlBase.h"
#include "UnrealWidget.h"
#include "AnimNodeEditMode.h"
#include "AnimGraphNode_VrmRetargetFromMannequin.generated.h"
class FCompilerResultsLog;
class FPrimitiveDrawInterface;
class USkeletalMeshComponent;
UCLASS(meta=(Keywords = "VRM4U"))
class UAnimGraphNode_VrmRetargetFromMannequin : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category=Settings)
FAnimNode_VrmRetargetFromMannequin Node;
public:
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
// End of UEdGraphNode interface
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
virtual void ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) override;
// virtual FEditorModeID GetEditorMode() const override;
virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
virtual FEditorModeID GetEditorMode() const override;
virtual void Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const override;
// End of UAnimGraphNode_Base interface
// UAnimGraphNode_SkeletalControlBase interface
virtual FText GetControllerDescription() const override;
virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
// End of UAnimGraphNode_SkeletalControlBase interface
private:
/** Constructing FText strings can be costly, so we cache the node's title */
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
};
@@ -0,0 +1,250 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AnimGraphNode_VrmSpringBone.h"
#include "Misc/EngineVersionComparison.h"
#include "UnrealWidget.h"
#include "AnimNodeEditModes.h"
#include "AnimationRuntime.h"
#include "Animation/AnimInstance.h"
#include "Kismet2/CompilerResultsLog.h"
#include "Components/SkeletalMeshComponent.h"
#include "VrmMetaObject.h"
#include "VrmUtil.h"
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
#define LOCTEXT_NAMESPACE "A3Nodesaaaa"
////////////////////
const FEditorModeID FVrmSpringBoneEditMode::VrmSpringBone("AnimGraph.SkeletalControl.VrmSpringBone");
/*
void FVrmSpringBoneEditMode::EnterMode(class UAnimGraphNode_Base* InEditorNode, struct FAnimNode_Base* InRuntimeNode)
{
RuntimeNode = static_cast<FAnimNode_VrmSpringBone*>(InRuntimeNode);
GraphNode = CastChecked<UAnimGraphNode_VrmSpringBone>(InEditorNode);
FAnimNodeEditMode::EnterMode(InEditorNode, InRuntimeNode);
}
void FVrmSpringBoneEditMode::ExitMode()
{
RuntimeNode = nullptr;
GraphNode = nullptr;
FAnimNodeEditMode::ExitMode();
}
FVector FVrmSpringBoneEditMode::GetWidgetLocation() const
{
//USkeletalMeshComponent* SkelComp = GetAnimPreviewScene().GetPreviewMeshComponent();
//FBoneSocketTarget& Target = RuntimeNode->EffectorTarget;
//FVector Location = RuntimeNode->EffectorTransform.GetLocation();
//EBoneControlSpace Space = RuntimeNode->EffectorTransformSpace;
FVector WidgetLoc;// = ConvertWidgetLocation(SkelComp, RuntimeNode->ForwardedPose, Target, Location, Space);
return WidgetLoc;
}
FWidget::EWidgetMode FVrmSpringBoneEditMode::GetWidgetMode() const
{
// allow translation all the time for effectot target
return FWidget::WM_Translate;
}
void FVrmSpringBoneEditMode::DoTranslation(FVector& InTranslation)
{
//USkeletalMeshComponent* SkelComp = GetAnimPreviewScene().GetPreviewMeshComponent();
//FVector Offset = ConvertCSVectorToBoneSpace(SkelComp, InTranslation, RuntimeNode->ForwardedPose, RuntimeNode->EffectorTarget, RuntimeNode->EffectorTransformSpace);
//RuntimeNode->EffectorTransform.AddToTranslation(Offset);
//GraphNode->Node.EffectorTransform.SetTranslation(RuntimeNode->EffectorTransform.GetTranslation());
}
*/
////////////////////
UAnimGraphNode_VrmSpringBone::UAnimGraphNode_VrmSpringBone(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if UE_VERSION_OLDER_THAN(5,0,0)
CurWidgetMode = (int32)FWidget::WM_Rotate;
#else
CurWidgetMode = UE::Widget::EWidgetMode::WM_Rotate;
#endif
}
void UAnimGraphNode_VrmSpringBone::ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) {
if (Node.VrmMetaObject_Internal == nullptr) {
//MessageLog.Warning(*LOCTEXT("VrmNoMetaObject", "@@ - You must set VrmMetaObject").ToString(), this);
} else {
auto *targetSkeleton = CompiledClass->GetTargetSkeleton();
if (targetSkeleton) {
if (Node.VrmMetaObject_Internal->SkeletalMesh) {
if (VRMGetSkeleton(Node.VrmMetaObject_Internal->SkeletalMesh) != targetSkeleton) {
MessageLog.Warning(*LOCTEXT("VrmDifferentSkeleton", "@@ - You must set VrmMetaObject has same skeleton").ToString(), this);
}
}
if (targetSkeleton->GetReferenceSkeleton().GetRawBoneNum() <= 0) {
MessageLog.Warning(*LOCTEXT("VrmNoBone", "@@ - Skeleton bad data").ToString(), this);
}
}
else {
//MessageLog.Warning(*LOCTEXT("VrmNoBone", "@@ - no target skeleton").ToString(), this);
}
}
Super::ValidateAnimNodePostCompile(MessageLog, CompiledClass, CompiledNodeIndex);
}
void UAnimGraphNode_VrmSpringBone::ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog)
{
// Temporary fix where skeleton is not fully loaded during AnimBP compilation and thus virtual bone name check is invalid UE-39499 (NEED FIX)
if (ForSkeleton && !ForSkeleton->HasAnyFlags(RF_NeedPostLoad))
{
if (Node.VrmMetaObject_Internal == nullptr) {
//MessageLog.Warning(*LOCTEXT("VrmNoMetaObject", "@@ - You must set VrmMetaObject").ToString(), this);
} else {
if (Node.VrmMetaObject_Internal->SkeletalMesh){
if (VRMGetSkeleton(Node.VrmMetaObject_Internal->SkeletalMesh) != ForSkeleton) {
// MessageLog.Warning(*LOCTEXT("VrmDifferentSkeleton", "@@ - You must set VrmMetaObject has same skeleton").ToString(), this);
}
}
if (ForSkeleton->GetReferenceSkeleton().GetRawBoneNum() <= 0) {
// MessageLog.Warning(*LOCTEXT("VrmNoBone", "@@ - Skeleton bad data").ToString(), this);
}
}
/*
//if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneToModify.BoneName) == INDEX_NONE)
if (ForSkeleton->GetReferenceSkeleton().FindBoneIndex(Node.BoneNameToModify) == INDEX_NONE)
{
//if (Node.BoneToModify.BoneName == NAME_None)
if (Node.BoneNameToModify == NAME_None)
{
MessageLog.Warning(*LOCTEXT("NoBoneSelectedToModify", "@@ - You must pick a bone to modify").ToString(), this);
}
else
{
FFormatNamedArguments Args;
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
FText Msg = FText::Format(LOCTEXT("NoBoneFoundToModify", "@@ - Bone {BoneName} not found in Skeleton"), Args);
MessageLog.Warning(*Msg.ToString(), this);
}
}
*/
}
//if ((Node.TranslationMode == BMM_Ignore) && (Node.RotationMode == BMM_Ignore) && (Node.ScaleMode == BMM_Ignore))
{
// MessageLog.Warning(*LOCTEXT("NothingToModify", "@@ - No components to modify selected. Either Rotation, Translation, or Scale should be set to something other than Ignore").ToString(), this);
}
Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog);
}
FText UAnimGraphNode_VrmSpringBone::GetControllerDescription() const
{
if (Node.EnableAutoSearchMetaData) {
return LOCTEXT("VrmSpringBone", "VrmSpringBone(auto)");
}else {
return LOCTEXT("VrmSpringBone", "VrmSpringBone");
}
}
FText UAnimGraphNode_VrmSpringBone::GetTooltipText() const
{
return LOCTEXT("AnimGraphNode_VrmSpringBone_Tooltip", "VrmCopyHandBone");
}
FText UAnimGraphNode_VrmSpringBone::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneToModify.BoneName == NAME_None))
//if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) && (Node.BoneNameToModify == NAME_None))
//{
return GetControllerDescription();
//}
// @TODO: the bone can be altered in the property editor, so we have to
// choose to mark this dirty when that happens for this to properly work
/*
else //if (!CachedNodeTitles.IsTitleCached(TitleType, this))
{
FFormatNamedArguments Args;
Args.Add(TEXT("ControllerDescription"), GetControllerDescription());
//Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneToModify.BoneName));
Args.Add(TEXT("BoneName"), FText::FromName(Node.BoneNameToModify));
// FText::Format() is slow, so we cache this to save on performance
if (TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle)
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_ListTitle", "{ControllerDescription} - Bone: {BoneName}"), Args), this);
}
else
{
CachedNodeTitles.SetCachedTitle(TitleType, FText::Format(LOCTEXT("AnimGraphNode_ModifyBone_Title", "{ControllerDescription}\nBone: {BoneName}"), Args), this);
}
}
return CachedNodeTitles[TitleType];
*/
}
void UAnimGraphNode_VrmSpringBone::CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode)
{
FAnimNode_VrmSpringBone* node = static_cast<FAnimNode_VrmSpringBone*>(InPreviewNode);
// no copy
}
FEditorModeID UAnimGraphNode_VrmSpringBone::GetEditorMode() const
{
return Super::GetEditorMode();
//return FVrmSpringBoneEditMode::VrmSpringBone;
}
void UAnimGraphNode_VrmSpringBone::Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const
{
if (PreviewSkelMeshComp)
{
/*
if (FAnimNode_VrmSpringBone* ActiveNode = GetActiveInstanceNode<FAnimNode_VrmSpringBone>(PreviewSkelMeshComp->GetAnimInstance()))
{
if (bPreviewLive) {
ActiveNode->ConditionalDebugDraw(PDI, PreviewSkelMeshComp, bPreviewForeground);
}
}
*/
if (bPreviewLive) {
Node.ConditionalDebugDraw(PDI, PreviewSkelMeshComp, bPreviewForeground);
}
}
}
void UAnimGraphNode_VrmSpringBone::CopyPinDefaultsToNodeData(UEdGraphPin* InPin)
{
/*
if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Translation))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Translation), Node.Translation);
}
else if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Rotation))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Rotation), Node.Rotation);
}
else if (InPin->GetName() == GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Scale))
{
GetDefaultValue(GET_MEMBER_NAME_STRING_CHECKED(FAnimNode_ModifyBone, Scale), Node.Scale);
}
*/
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,91 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
//#include "BoneControllers/AnimNode_ModifyBone.h"
#include "AnimNode_VrmSpringBone.h"
#include "EdGraph/EdGraphNodeUtils.h"
#include "AnimGraphNode_SkeletalControlBase.h"
#include "UnrealWidget.h"
#include "AnimNodeEditMode.h"
#include "AnimGraphNode_VrmSpringBone.generated.h"
class FCompilerResultsLog;
class FPrimitiveDrawInterface;
class USkeletalMeshComponent;
class FVrmSpringBoneEditMode {
public:
static const FEditorModeID VrmSpringBone;
};
/*
class FVrmSpringBoneEditMode : public FAnimNodeEditMode
{
public:
//IAnimNodeEditMode interface
virtual void EnterMode(class UAnimGraphNode_Base* InEditorNode, struct FAnimNode_Base* InRuntimeNode) override;
virtual void ExitMode() override;
virtual FVector GetWidgetLocation() const override;
virtual FWidget::EWidgetMode GetWidgetMode() const override;
virtual void DoTranslation(FVector& InTranslation) override;
static const FEditorModeID VrmSpringBone;
private:
struct FAnimNode_VrmSpringBone* RuntimeNode;
class UAnimGraphNode_VrmSpringBone* GraphNode;
};
*/
UCLASS(meta=(Keywords = "VRM4U"))
class UAnimGraphNode_VrmSpringBone : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category=Settings)
FAnimNode_VrmSpringBone Node;
public:
UPROPERTY(EditAnywhere, Category = Preview)
bool bPreviewLive = true;
UPROPERTY(EditAnywhere, Category = Preview)
bool bPreviewForeground = false;
// UEdGraphNode interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FText GetTooltipText() const override;
// End of UEdGraphNode interface
protected:
// UAnimGraphNode_Base interface
virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
virtual void ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, UAnimBlueprintGeneratedClass* CompiledClass, int32 CompiledNodeIndex) override;
// virtual FEditorModeID GetEditorMode() const override;
virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
virtual FEditorModeID GetEditorMode() const override;
virtual void Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent * PreviewSkelMeshComp) const override;
// End of UAnimGraphNode_Base interface
// UAnimGraphNode_SkeletalControlBase interface
virtual FText GetControllerDescription() const override;
virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
// End of UAnimGraphNode_SkeletalControlBase interface
private:
/** Constructing FText strings can be costly, so we cache the node's title */
FNodeTitleTextTable CachedNodeTitles;
// storing current widget mode
int32 CurWidgetMode;
};
@@ -0,0 +1,15 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AssetDefinition_VRM1License.h"
#include "ContentBrowserMenuContexts.h"
#include "ToolMenus.h"
#include "Editor.h"
#include "Styling/AppStyle.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Input/SButton.h"
#include "Widgets/Images/SImage.h"
#define LOCTEXT_NAMESPACE "AssetTypeActions"
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,27 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "AssetDefinitionDefault.h"
#include "ContentBrowserMenuContexts.h"
#include "Vrm1LicenseObject.h"
#include "AssetDefinition_VRMAssetList.h"
#include "AssetDefinition_VRM1License.generated.h"
UCLASS()
class VRM4UIMPORTER_API UAssetDefinition_VRM1License : public UAssetDefinition_VRMAssetList
{
GENERATED_BODY()
public:
virtual FLinearColor GetAssetColor() const override { return UAssetDefinition_VRMAssetList::GetAssetColor(); }
virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_VRM1License", "VRM4U License"); }
virtual TSoftClassPtr<UObject> GetAssetClass() const override { return UVrm1LicenseObject::StaticClass(); }
//virtual bool GetThumbnailActionOverlay(const FAssetData& InAssetData, FAssetActionThumbnailOverlayInfo& OutActionOverlayInfo) const override {
// return UAssetDefinition_VRMAssetList::GetThumbnailActionOverlay(InAssetData, OutActionOverlayInfo);
//}
};
@@ -0,0 +1,39 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AssetDefinition_VRMAssetList.h"
#include "ContentBrowserMenuContexts.h"
#include "ToolMenus.h"
#include "Editor.h"
#include "Styling/AppStyle.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Input/SButton.h"
#include "Widgets/Images/SImage.h"
#include "ThumbnailRendering/SceneThumbnailInfo.h"
#include "VrmMetaObject.h"
#include "VrmLicenseObject.h"
#include "Vrm1LicenseObject.h"
#include "VrmAssetListObject.h"
#define LOCTEXT_NAMESPACE "AssetTypeActions"
UThumbnailInfo* UAssetDefinition_VRMAssetList::LoadThumbnailInfo(const FAssetData& InAssetData) const
{
return UE::Editor::FindOrCreateThumbnailInfo(InAssetData.GetAsset(), USceneThumbnailInfo::StaticClass());
}
//TSharedPtr<SWidget> UAssetDefinition_VRMAssetList::GetThumbnailOverlay(const FAssetData& AssetData) const {
// return nullptr;
//}
//bool UAssetDefinition_VRMAssetList::GetThumbnailActionOverlay(const FAssetData& InAssetData, FAssetActionThumbnailOverlayInfo& OutActionOverlayInfo) const
//{
// return false;
//}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,28 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "AssetDefinitionDefault.h"
#include "ContentBrowserMenuContexts.h"
#include "VrmAssetListObject.h"
#include "AssetDefinition_VRMAssetList.generated.h"
UCLASS()
class VRM4UIMPORTER_API UAssetDefinition_VRMAssetList : public UAssetDefinitionDefault
{
GENERATED_BODY()
public:
virtual FLinearColor GetAssetColor() const override { return FLinearColor( FColor(255, 223, 255) ); }
virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_VRMAssetList", "VRM4U Base"); }
virtual TSoftClassPtr<UObject> GetAssetClass() const override { return UVrmAssetListObject::StaticClass(); }
//virtual TSharedPtr<SWidget> GetThumbnailOverlay(const FAssetData& InAssetData) const override;
//virtual bool GetThumbnailActionOverlay(const FAssetData& InAssetData, FAssetActionThumbnailOverlayInfo& OutActionOverlayInfo) const override;
virtual UThumbnailInfo* LoadThumbnailInfo(const FAssetData& InAssetData) const override;
};
@@ -0,0 +1,16 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AssetDefinition_VRMLicense.h"
#include "ContentBrowserMenuContexts.h"
#include "ToolMenus.h"
#include "Editor.h"
#include "Styling/AppStyle.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Input/SButton.h"
#include "Widgets/Images/SImage.h"
#define LOCTEXT_NAMESPACE "AssetTypeActions"
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,27 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "AssetDefinitionDefault.h"
#include "ContentBrowserMenuContexts.h"
#include "VrmLicenseObject.h"
#include "AssetDefinition_VRMAssetList.h"
#include "AssetDefinition_VRMLicense.generated.h"
UCLASS()
class VRM4UIMPORTER_API UAssetDefinition_VRMLicense : public UAssetDefinition_VRMAssetList
{
GENERATED_BODY()
public:
virtual FLinearColor GetAssetColor() const override { return UAssetDefinition_VRMAssetList::GetAssetColor(); }
virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_VRMLicense", "VRM4U License"); }
virtual TSoftClassPtr<UObject> GetAssetClass() const override { return UVrmLicenseObject::StaticClass(); }
//virtual bool GetThumbnailActionOverlay(const FAssetData& InAssetData, FAssetActionThumbnailOverlayInfo& OutActionOverlayInfo) const override {
// return UAssetDefinition_VRMAssetList::GetThumbnailActionOverlay(InAssetData, OutActionOverlayInfo);
//}
};
@@ -0,0 +1,16 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "AssetDefinition_VRMMeta.h"
#include "ContentBrowserMenuContexts.h"
#include "ToolMenus.h"
#include "Editor.h"
#include "Styling/AppStyle.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Input/SButton.h"
#include "Widgets/Images/SImage.h"
#define LOCTEXT_NAMESPACE "AssetTypeActions"
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,27 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "AssetDefinitionDefault.h"
#include "ContentBrowserMenuContexts.h"
#include "VrmMetaObject.h"
#include "AssetDefinition_VRMAssetList.h"
#include "AssetDefinition_VRMMeta.generated.h"
UCLASS()
class VRM4UIMPORTER_API UAssetDefinition_VRMMeta : public UAssetDefinition_VRMAssetList
{
GENERATED_BODY()
public:
virtual FLinearColor GetAssetColor() const override { return UAssetDefinition_VRMAssetList::GetAssetColor(); }
virtual FText GetAssetDisplayName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_VRMMeta", "VRM4U Meta"); }
virtual TSoftClassPtr<UObject> GetAssetClass() const override { return UVrmMetaObject::StaticClass(); }
//virtual bool GetThumbnailActionOverlay(const FAssetData& InAssetData, FAssetActionThumbnailOverlayInfo& OutActionOverlayInfo) const override {
// return UAssetDefinition_VRMAssetList::GetThumbnailActionOverlay(InAssetData, OutActionOverlayInfo);
//}
};
@@ -0,0 +1,90 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "VRM4UDetailCustomize.h"
#include "VrmCustomStruct.h"
#include "AssetToolsModule.h"
#include "Modules/ModuleManager.h"
#include "Internationalization/Internationalization.h"
#include "ThumbnailRendering/ThumbnailManager.h"
#include "Editor/PropertyEditor/Public/PropertyEditorModule.h"
#include "Misc/EngineVersionComparison.h"
#include "IDetailChildrenBuilder.h"
#include "IDetailPropertyRow.h"
#include "DetailLayoutBuilder.h"
#include "DetailWidgetRow.h"
#include "Animation/AnimSequenceBase.h"
FVRMRetargetSrcAnimSequenceCustomization::FVRMRetargetSrcAnimSequenceCustomization()
{
}
bool FVRMRetargetSrcAnimSequenceCustomization::ShouldFilterAsset(const FAssetData& AssetData)
{
{
const FString keyword[] = {
TEXT("skel_"),
TEXT("vrm4u"),
TEXT("simple"),
};
#if UE_VERSION_OLDER_THAN(4,25,0)
const FString* Value = AssetData.TagsAndValues.Find(TEXT("Skeleton"));
#else
const FString V = AssetData.TagsAndValues.FindTag(TEXT("Skeleton")).GetValue();
const FString* Value = &V;
#endif
if (Value == nullptr) {
return false;
}
const FString s = Value->ToLower();
for (auto &a : keyword) {
if (s.Find(a) < 0) {
return true;
}
}
}
return false;
}
void FVRMRetargetSrcAnimSequenceCustomization::CustomizeChildren(TSharedRef<class IPropertyHandle> StructPropertyHandle, class IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) {
{
uint32 TotalChildren = 0;
StructPropertyHandle->GetNumChildren(TotalChildren);
for (uint32 ChildIndex = 0; ChildIndex < TotalChildren; ++ChildIndex)
{
TSharedPtr<IPropertyHandle> ChildHandle = StructPropertyHandle->GetChildHandle(ChildIndex);
if (ChildHandle->GetProperty()->GetFName() == GET_MEMBER_NAME_CHECKED(FVRMRetargetSrcAnimSequence, AnimSequence)) {
StructBuilder.AddCustomRow(ChildHandle->GetPropertyDisplayName())
.NameContent()
[
StructPropertyHandle->CreatePropertyNameWidget()
]
.ValueContent()
.MaxDesiredWidth(250.0f)
.MinDesiredWidth(250.0f)
[
SNew(SObjectPropertyEntryBox)
.AllowedClass(UAnimSequenceBase::StaticClass())
.OnShouldFilterAsset(this, &FVRMRetargetSrcAnimSequenceCustomization::ShouldFilterAsset)
.PropertyHandle(ChildHandle)
.ThumbnailPool(StructCustomizationUtils.GetThumbnailPool())
];
}
}
}
}
void FVRMRetargetSrcAnimSequenceCustomization::CustomizeHeader(TSharedRef<IPropertyHandle> StructPropertyHandle, class FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) {
}
///
@@ -0,0 +1,26 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "PropertyCustomizationHelpers.h"
class FVRMRetargetSrcAnimSequenceCustomization : public IPropertyTypeCustomization
{
public:
FVRMRetargetSrcAnimSequenceCustomization();
static TSharedRef<IPropertyTypeCustomization> MakeInstance()
{
return MakeShareable(new FVRMRetargetSrcAnimSequenceCustomization);
}
/** IPropertyTypeCustomization interface */
virtual void CustomizeHeader(TSharedRef<IPropertyHandle> StructPropertyHandle, class FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
virtual void CustomizeChildren(TSharedRef<class IPropertyHandle> StructPropertyHandle, class IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
private:
bool ShouldFilterAsset(const FAssetData& AssetData);
};
@@ -0,0 +1,681 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "VRM4UImporterFactory.h"
#include "VRM4UImporterLog.h"
#include "Misc/EngineVersionComparison.h"
#include "AssetToolsModule.h"
#if UE_VERSION_OLDER_THAN(4,26,0)
#include "AssetRegistryModule.h"
#else
#include "AssetRegistry/AssetRegistryModule.h"
#endif
#include "PackageTools.h"
#include "Misc/Paths.h"
#include "Engine/SkeletalMesh.h"
#include "EditorFramework/AssetImportData.h"
#include "Components/SkeletalMeshComponent.h"
//#include "Runtime/CoreUObject/Public/UObject/ConstructorHelpers.h"
#include "UObject/ConstructorHelpers.h"
#include "LoaderBPFunctionLibrary.h"
#include "VrmAssetListObject.h"
#include "VrmRuntimeSettings.h"
#include "VrmOptionWindow.h"
#include "Engine/Blueprint.h"
#include "Templates/SharedPointer.h"
#include "Misc/FeedbackContext.h"
#include "FileHelpers.h"
#include "TickableEditorObject.h"
#include "Interfaces/IMainFrameModule.h"
#include "Widgets/SWindow.h"
#include "Framework/Application/SlateApplication.h"
#include "HAL/PlatformApplicationMisc.h"
#include "VrmOptionWindow.h"
#include "VrmImportUI.h"
#include "VrmConvert.h"
#include "VrmLicenseObject.h"
#include "Vrm1LicenseObject.h"
#define LOCTEXT_NAMESPACE "VRMImporter"
// for tick Editor Object
class SWindow2 : public SWindow{
public:
// bCanTick = false;
SWindow2() : SWindow() {
#if UE_VERSION_OLDER_THAN(4,21,0)
bCanTick = true;
#else
SetCanTick(true);
#endif
}
public:
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) {
SWindow::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
FTickableEditorObject::TickObjects(InDeltaTime);
//FAssetRegistryModule::TickAssetRegistry(-1.0f);
}
bool OnIsActiveChanged(const FWindowActivateEvent& ActivateEvent) {
bool r = SWindow::OnIsActiveChanged(ActivateEvent);
#if UE_VERSION_OLDER_THAN(4,21,0)
bCanTick = true;
#else
SetCanTick(true);
#endif
return r;
}
};
/*
UCLASS(config=EditorPerProjectUserSettings, AutoExpandCategories=(FTransform), HideCategories=Object, MinimalAPI)
class UFbxImportUI : public UObject, public IImportSettingsParser
{
}
*/
namespace {
void RenameAsset(UObject* Asset, const FString& NewName, FText& ErrorMessage)
{
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
TArray<FAssetRenameData> AssetsAndNames;
const FString PackagePath = FPackageName::GetLongPackagePath(Asset->GetOutermost()->GetName());
new(AssetsAndNames) FAssetRenameData(Asset, PackagePath, NewName);
AssetToolsModule.Get().RenameAssetsWithDialog(AssetsAndNames);
}
}
UVRM4UImporterFactory::UVRM4UImporterFactory(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
TArray<FString> table = {
TEXT("vrm"),
TEXT("vrma"),
TEXT("glb"),
TEXT("bvh"),
};
const UVrmRuntimeSettings* Settings = GetDefault<UVrmRuntimeSettings>();
for (auto& a : Settings->extList) {
table.AddUnique(a);
}
if (Settings->bAllowAllAssimpFormat) {
TArray<FString> tmp = {
TEXT("pmx"),
TEXT("obj"),
TEXT("fbx"),
TEXT("dae"),
TEXT("gltf"),
};
for (auto& a : tmp) {
table.AddUnique(a);
}
}
for (auto &a : table) {
Formats.Add(a + TEXT(";Model VRM4U"));
}
bCreateNew = false;
bEditorImport = true;
ImportPriority = FMath::Max(1, Settings->ImportPriority);
}
bool UVRM4UImporterFactory::FactoryCanImport(const FString& Filename)
{
fullFileName.Empty();
const FString Extension = FPaths::GetExtension(Filename);
bool allowAll = false;
const UVrmRuntimeSettings* Settings = GetDefault<UVrmRuntimeSettings>();
if (Settings) {
if (Settings->bAllowAllAssimpFormat) {
allowAll = true;
}
for (auto& a : Settings->extList) {
if (Extension == a) {
allowAll = true;
}
}
}
//if( Extension == TEXT("vrm") || Extension == TEXT("gltf") || Extension == TEXT("glb"))
if(allowAll
|| Extension == TEXT("vrm")
|| Extension == TEXT("vrma")
|| Extension == TEXT("glb")
|| Extension == TEXT("bvh"))
{
fullFileName = Filename;
return true;
}
return false;
}
UClass* UVRM4UImporterFactory::ResolveSupportedClass()
{
UClass* ImportClass = USkeletalMesh::StaticClass();
return ImportClass;
}
/*
UObject* UVRMImporterFactory::FactoryCreateFile
(
UClass* Class,
UObject* InParent,
FName Name,
EObjectFlags Flags,
const FString& InFilename,
const TCHAR* Parms,
FFeedbackContext* Warn,
bool& bOutOperationCanceled
)
{
return nullptr;
}
*/
UObject* UVRM4UImporterFactory::FactoryCreateBinary(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, const TCHAR* Type, const uint8*& Buffer, const uint8* BufferEnd, FFeedbackContext* Warn, bool& bOutOperationCanceled)
{
if (fullFileName.IsEmpty()) {
return nullptr;
}
if (VRMConverter::Options::Get().IsDebugIgnoreVRMValidation() == false) {
if (ULoaderBPFunctionLibrary::IsValidVRM4UFile(fullFileName) == false) {
return nullptr;
}
}
static UVrmImportUI* ImportUI = nullptr;
#if UE_VERSION_OLDER_THAN(5,0,0)
TAssetPtr<UObject> refPointerToLic;
#else
TSoftObjectPtr<UObject> refPointerToLic;
#endif
{
if (ImportUI == nullptr) {
ImportUI = NewObject<UVrmImportUI>(this, NAME_None, RF_NoFlags);
ImportUI->AddToRoot();
}
// to default
{
ImportUI->bRemoveRootBoneRotation = true;
ImportUI->bRemoveRootBonePosition = false;
ImportUI->bVrm10RemoveLocalRotation = false;
ImportUI->ModelScale = 1.0f;
ImportUI->bMergeMaterial = true;
ImportUI->bMergePrimitive = false;
ImportUI->TitleAuthor.Empty();
ImportUI->Thumbnail = nullptr;
ImportUI->TitleAuthor.Empty();
ImportUI->Thumbnail = nullptr;
ImportUI->allowedUserName.Empty();
ImportUI->violentUsageName.Empty();
ImportUI->sexualUsageName.Empty();
ImportUI->commercialUsageName.Empty();
ImportUI->otherPermissionUrl.Empty();
ImportUI->licenseName.Empty();
ImportUI->otherLicenseUrl.Empty();
ImportUI->LicenseString.Empty();
ImportUI->LicenseBool.Empty();
ImportUI->LicenseStringArray.Empty();
}
if (1) {
UVrmLicenseObject* a = nullptr;
UVrm1LicenseObject* b = nullptr;
ULoaderBPFunctionLibrary::GetVRMMeta(fullFileName, a, b);
if (a) {
ImportUI->TitleAuthor = TEXT("\"") + a->title + TEXT("\"") + TEXT(" / ") + TEXT("\"") + a->author + TEXT("\"");
ImportUI->Thumbnail = a->thumbnail;
ImportUI->allowedUserName = a->allowedUserName;
ImportUI->violentUsageName = a->violentUsageName;
ImportUI->sexualUsageName = a->sexualUsageName;
ImportUI->commercialUsageName = a->commercialUsageName;
ImportUI->otherPermissionUrl = a->otherPermissionUrl;
ImportUI->licenseName = a->licenseName;
ImportUI->otherLicenseUrl = a->otherLicenseUrl;
refPointerToLic = a;
}
if (b) {
{
auto *p = b->LicenseString.FindByPredicate([](const FLicenseStringDataPair &pair) {
if (pair.key == TEXT("name")) return true;
return false;
});
if (p) {
ImportUI->TitleAuthor = p->value;
}
}
ImportUI->Thumbnail = b->thumbnail;
ImportUI->LicenseString = b->LicenseString;
ImportUI->LicenseBool = b->LicenseBool;
ImportUI->LicenseStringArray = b->LicenseStringArray;
refPointerToLic = b;
}
{
const FString Extension = FPaths::GetExtension(fullFileName);
if (Extension.ToLower() == TEXT("pmx")) {
ImportUI->ModelScale = 0.1f;
ImportUI->bMergeMaterial = false;
ImportUI->bMergePrimitive = false;
ImportUI->bForceTwoSided = true;
}
if (Extension.ToLower() == TEXT("bvh")) {
ImportUI->ModelScale = 0.01f;
}
}
#if UE_VERSION_OLDER_THAN(5,2,0)
{
ImportUI->bSingleUAssetFile = true;
}
#else
// 5.2でも動くが、デフォルトをOFFにする
#endif
#if UE_VERSION_OLDER_THAN(5,0,0)
#else
// for thumbnail update
if (GEditor){
auto* s = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
if (s && ImportUI->Thumbnail) {
s->OpenEditorForAsset(ImportUI->Thumbnail);
s->CloseAllEditorsForAsset(ImportUI->Thumbnail);
}
}
#endif
}
TSharedPtr<SWindow> ParentWindow;
if (FModuleManager::Get().IsModuleLoaded("MainFrame"))
{
IMainFrameModule& MainFrame = FModuleManager::LoadModuleChecked<IMainFrameModule>("MainFrame");
ParentWindow = MainFrame.GetParentWindow();
}
// Compute centered window position based on max window size, which include when all categories are expanded
const float FbxImportWindowWidth = 410.0f * 2.f;
const float FbxImportWindowHeight = 750.0f;
FVector2D FbxImportWindowSize = FVector2D(FbxImportWindowWidth, FbxImportWindowHeight); // Max window size it can get based on current slate
FSlateRect WorkAreaRect = FSlateApplicationBase::Get().GetPreferredWorkArea();
FVector2D DisplayTopLeft(WorkAreaRect.Left, WorkAreaRect.Top);
FVector2D DisplaySize(WorkAreaRect.Right - WorkAreaRect.Left, WorkAreaRect.Bottom - WorkAreaRect.Top);
float ScaleFactor = FPlatformApplicationMisc::GetDPIScaleFactorAtPoint(DisplayTopLeft.X, DisplayTopLeft.Y);
FbxImportWindowSize *= ScaleFactor;
FVector2D WindowPosition = (DisplayTopLeft + (DisplaySize - FbxImportWindowSize) / 2.0f) / ScaleFactor;
TSharedRef<SWindow2> Window = SNew(SWindow2)
.Title(NSLOCTEXT("UnrealEd", "VRMImportOpionsTitle", "VRM Import Options"))
.SizingRule(ESizingRule::Autosized)
.AutoCenter(EAutoCenter::None)
.ClientSize(FbxImportWindowSize)
.ScreenPosition(WindowPosition);
TSharedPtr<SVrmOptionWindow> VrmOptionWindow;
Window->SetContent
(
SAssignNew(VrmOptionWindow, SVrmOptionWindow)
.ImportUI(ImportUI)
.WidgetWindow(Window)
.FullPath(FText::FromString(fullFileName))
//.ForcedImportType( bForceImportType ? TOptional<EFBXImportType>( ImportType ) : TOptional<EFBXImportType>() )
//.IsObjFormat( bIsObjFormat )
.MaxWindowHeight(FbxImportWindowHeight)
.MaxWindowWidth(FbxImportWindowWidth)
);
// @todo: we can make this slow as showing progress bar later
FSlateApplication::Get().AddModalWindow(Window, ParentWindow);
if (VrmOptionWindow->ShouldImport() == false) {
bOutOperationCanceled = true;
return nullptr;
}
}
//static ConstructorHelpers::FObjectFinder<UObject> MatClass(TEXT("/Game/test/NewMaterial.NewMaterial"));
//static ConstructorHelpers::FObjectFinder<UClass> MatClass(TEXT("Blueprint'/VRM4U/VrmObjectListBP.VrmObjectListBP_C'"));
//static ConstructorHelpers::FObjectFinder<UVrmAssetListObject> MatClass(TEXT("Blueprint'/VRM4U/VrmObjectListBP'"));
//static ConstructorHelpers::FObjectFinder<UObject> MatClass(TEXT("/VRM4U/VrmObjectListBP.VrmObjectListBP"));
//UVrmAssetListObject *m = Cast<UVrmAssetListObject>(MatClass.Object);
//UObject* objFinder = StaticLoadObject(UVrmAssetListObject::StaticClass(), nullptr, TEXT("/VRM4U/VrmObjectListBP.VrmObjectListBP_C"));
//UObject* objFinder = NewObject<UVrmAssetListObject>(InParent, NAME_None, RF_Transactional);
auto& importOption = VRMConverter::Options::Get();
importOption.SetVrmOption(ImportUI->GenerateOptionData());
#if UE_VERSION_OLDER_THAN(5,0,0)
TAssetPtr<UVrmAssetListObject> vrmAssetList;
TArray< TAssetPtr<UObject> > tt;
#else
TSoftObjectPtr<UVrmAssetListObject> vrmAssetList;
TArray< TSoftObjectPtr<UObject> > tt;
#endif
tt.Add(InParent);
//TRefCountPtr<UVrmAssetListObject> m;
//UVrmAssetListObject *m = nullptr;
#if UE_VERSION_OLDER_THAN(5,0,0)
TAssetPtr<UClass> c;
#else
TSoftObjectPtr<UClass> c;
#endif
{
const UVrmRuntimeSettings* Settings = GetDefault<UVrmRuntimeSettings>();
{
FSoftObjectPath r = Settings->AssetListObject; //(TEXT("/VRM4U/VrmObjectListBP.VrmObjectListBP"));
UObject *u = r.TryLoad();
if (u) {
if (Cast<UBlueprint>(u)) {
c = (UClass*)(Cast<UBlueprint>(u)->GeneratedClass);
}
}
}
if (c == nullptr || VRMConverter::Options::Get().IsUE5Material()) {
FSoftObjectPath r(TEXT("/VRM4U/VrmAssetListObjectBPUE5.VrmAssetListObjectBPUE5"));
UObject *u = r.TryLoad();
if (u) {
c = (UClass*)(Cast<UBlueprint>(u)->GeneratedClass);
}
}
if (c == nullptr){
FSoftObjectPath r(TEXT("/VRM4U/VrmAssetListObjectBP.VrmAssetListObjectBP"));
UObject* u = r.TryLoad();
if (u) {
c = (UClass*)(Cast<UBlueprint>(u)->GeneratedClass);
}
}
if (c == nullptr) {
c = UVrmAssetListObject::StaticClass();
}
{
if (ReimportBase) {
vrmAssetList = ReimportBase;
VRMUtil::CloseEditorWindowByFolderPath(vrmAssetList.Get());
}
if (vrmAssetList) {
vrmAssetList->MarkPackageDirty();
}else{
vrmAssetList = NewObject<UVrmAssetListObject>((UObject*)GetTransientPackage(), c.Get());
}
}
}
//UVrmAssetListObject *m = Cast<UVrmAssetListObject>(u);
//FSoftClassPath r(TEXT("/VRM4U/VrmObjectListBP.VrmObjectListBP"));
//UObject *u = r.TryLoad();
//auto aaa = NewObject<UObject>(c);
UVrmAssetListObject* mret = nullptr;
if (vrmAssetList) {
//auto a = NewObject<UVrmAssetListObject>(MatClass.Object, NAME_None, RF_Transactional);
//MatClass.Object;
//ULoaderBPFunctionLibrary::LoadVRMFile(nullptr, fullFileName);
GWarn->BeginSlowTask( NSLOCTEXT("UnrealEd", "ImportVRM", "Importing VRM"), true );
int ret = true;
ULoaderBPFunctionLibrary::SetImportMode(true, Cast<UPackage>(InParent));
{
ret = ULoaderBPFunctionLibrary::LoadVRMFileLocal(vrmAssetList.Get(), mret, fullFileName);
}
/*
{
const bool bCheckDirty = false;
const bool bPromptToSave = false;
TArray<UPackage* > p;
p.Add(Cast<UPackage>(InParent));
p[0]->Modify();
p[0]->PostEditChange();
p[0]->FullyLoad();
p[0]->AddToRoot();
FEditorFileUtils::PromptForCheckoutAndSave(p, bCheckDirty, bPromptToSave);
p[0]->SetDirtyFlag(false);
//p[0]->AddToRoot();
//p[0]->Rename(*(p[0]->GetName() + TEXT("aatest")), nullptr);
//ContentBrowserUtils::RenameAsset(p[0], NewName, ErrorMessage);
FText ErrorMessage;
//RenameAsset(p[0], *(p[0]->GetName() + TEXT("aatest")), ErrorMessage);
RenameAsset(p[0], (TEXT("vrm_dummy_to_delete")), ErrorMessage);
p[0]->Rename(nullptr, GetTransientPackage(), 0);
p[0]->RemoveFromRoot();
//FEditorFileUtils::PromptForCheckoutAndSave(p, bCheckDirty, bPromptToSave);
}
*/
ULoaderBPFunctionLibrary::SetImportMode(false, nullptr);
importOption.SetVrmOption(nullptr);
#if UE_VERSION_OLDER_THAN(4,22,0)
#else
if (GEditor) {
GEditor->GetEditorSubsystem<UImportSubsystem>()->BroadcastAssetPostImport(this, mret);
}
#endif
GWarn->EndSlowTask();
//bool bDeleteSucceeded = ObjectTools::DeleteSingleObject( ExistingObject );
CollectGarbage( GARBAGE_COLLECTION_KEEPFLAGS );
if (ret == false) {
return nullptr;
}
}
//return InParent;
return mret;// ->GetOuter();
}
UObject* UVRM4UImporterFactory::FactoryCreateText(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext* Warn)
{
return nullptr;
}
bool UVRM4UImporterFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames) {
UVrmAssetListObject* assetList= Cast<UVrmAssetListObject>(Obj);
TArray<FString> FactoryExtensions;
GetSupportedFileExtensions(FactoryExtensions);
if (assetList)
{
if (UAssetImportData* AssetImportData = assetList->GetAssetImportData())
{
AssetImportData->ExtractFilenames(OutFilenames);
return true;
}
else
{
OutFilenames.Add(TEXT(""));
}
return true;
}
return false;
}
void UVRM4UImporterFactory::SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) {
UVrmAssetListObject* assetList = Cast<UVrmAssetListObject>(Obj);
if (assetList && ensure(NewReimportPaths.Num() == 1))
{
assetList->AssetImportData->UpdateFilenameOnly(NewReimportPaths[0]);
}
}
EReimportResult::Type UVRM4UImporterFactory::Reimport(UObject* Obj) {
UVrmAssetListObject* asset = Cast<UVrmAssetListObject>(Obj);
if (asset == nullptr)
{
return EReimportResult::Failed;
}
if (asset->AssetImportData == nullptr) {
return EReimportResult::Failed;
}
#if UE_VERSION_OLDER_THAN(4,22,0)
#else
if (asset->AssetImportData->GetSourceFileCount() <= 0) {
return EReimportResult::Failed;
}
#endif
#if UE_VERSION_OLDER_THAN(4,26,0)
#else
ReimportBase = asset;
asset->Package = asset->GetPackage();
asset->ReimportBase = asset;
#endif
{
FString str = asset->AssetImportData->GetSourceData().SourceFiles[0].RelativeFilename;
fullFileName = UAssetImportData::ResolveImportFilename(str, asset->Package);
}
const uint8_t *buf_dummy = nullptr;
bool b_dummy = false;
UObject* n = FactoryCreateBinary(nullptr, asset->Package, "name", (EObjectFlags)0, nullptr, nullptr, buf_dummy, buf_dummy, nullptr, b_dummy);
ReimportBase = nullptr;
fullFileName = "";
if (n == nullptr) {
return EReimportResult::Failed;
}
return EReimportResult::Succeeded;
}
int32 UVRM4UImporterFactory::GetPriority() const {
return ImportPriority;
}
//////////////////////////////////////////////////////////////////////////
////
UVrmImportUI::UVrmImportUI(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
bIsReimport = false;
//bAutomatedImportShouldDetectType = true;
//Make sure we are transactional to allow undo redo
this->SetFlags(RF_Transactional);
/*
StaticMeshImportData = CreateDefaultSubobject<UFbxStaticMeshImportData>(TEXT("StaticMeshImportData"));
StaticMeshImportData->SetFlags(RF_Transactional);
StaticMeshImportData->LoadOptions();
SkeletalMeshImportData = CreateDefaultSubobject<UFbxSkeletalMeshImportData>(TEXT("SkeletalMeshImportData"));
SkeletalMeshImportData->SetFlags(RF_Transactional);
SkeletalMeshImportData->LoadOptions();
AnimSequenceImportData = CreateDefaultSubobject<UFbxAnimSequenceImportData>(TEXT("AnimSequenceImportData"));
AnimSequenceImportData->SetFlags(RF_Transactional);
AnimSequenceImportData->LoadOptions();
TextureImportData = CreateDefaultSubobject<UFbxTextureImportData>(TEXT("TextureImportData"));
TextureImportData->SetFlags(RF_Transactional);
TextureImportData->LoadOptions();
*/
}
void UVrmImportUI::ParseFromJson(TSharedRef<class FJsonObject> ImportSettingsJson)
{
/*
// Skip instanced object references.
int64 SkipFlags = CPF_InstancedReference;
FJsonObjectConverter::JsonObjectToUStruct(ImportSettingsJson, GetClass(), this, 0, SkipFlags);
bAutomatedImportShouldDetectType = true;
if(ImportSettingsJson->TryGetField("MeshTypeToImport").IsValid())
{
// Import type was specified by the user if MeshTypeToImport exists
bAutomatedImportShouldDetectType = false;
}
const TSharedPtr<FJsonObject>* StaticMeshImportJson = nullptr;
ImportSettingsJson->TryGetObjectField(TEXT("StaticMeshImportData"), StaticMeshImportJson);
if(StaticMeshImportJson)
{
FJsonObjectConverter::JsonObjectToUStruct(StaticMeshImportJson->ToSharedRef(), StaticMeshImportData->GetClass(), StaticMeshImportData, 0, 0);
}
const TSharedPtr<FJsonObject>* SkeletalMeshImportJson = nullptr;
ImportSettingsJson->TryGetObjectField(TEXT("SkeletalMeshImportData"), SkeletalMeshImportJson);
if (SkeletalMeshImportJson)
{
FJsonObjectConverter::JsonObjectToUStruct(SkeletalMeshImportJson->ToSharedRef(), SkeletalMeshImportData->GetClass(), SkeletalMeshImportData, 0, 0);
}
const TSharedPtr<FJsonObject>* AnimImportJson = nullptr;
ImportSettingsJson->TryGetObjectField(TEXT("AnimSequenceImportData"), AnimImportJson);
if (AnimImportJson)
{
FJsonObjectConverter::JsonObjectToUStruct(AnimImportJson->ToSharedRef(), AnimSequenceImportData->GetClass(), AnimSequenceImportData, 0, 0);
}
const TSharedPtr<FJsonObject>* TextureImportJson = nullptr;
ImportSettingsJson->TryGetObjectField(TEXT("TextureImportData"), TextureImportJson);
if (TextureImportJson)
{
FJsonObjectConverter::JsonObjectToUStruct(TextureImportJson->ToSharedRef(), TextureImportData->GetClass(), TextureImportData, 0, 0);
}
*/
}
void UVrmImportUI::ResetToDefault()
{
ReloadConfig();
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,34 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "EditorReimportHandler.h"
#include "Factories/Factory.h"
#include "VRM4UImporterFactory.generated.h"
UCLASS()
class UVRM4UImporterFactory : public UFactory, public FReimportHandler
{
GENERATED_UCLASS_BODY()
// UFactory interface
//virtual FText GetToolTip() const override;
virtual bool FactoryCanImport(const FString& Filename) override;
virtual UClass* ResolveSupportedClass() override;
virtual UObject* FactoryCreateText(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext* Warn) override;
virtual UObject* FactoryCreateBinary(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, const TCHAR* Type, const uint8*& Buffer, const uint8* BufferEnd, FFeedbackContext* Warn, bool& bOutOperationCanceled) override;
// End of UFactory interface
// FReimportHandler interface
virtual bool CanReimport(UObject* Obj, TArray<FString>& OutFilenames) override;
virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override;
virtual EReimportResult::Type Reimport(UObject* Obj) override;
virtual int32 GetPriority() const override;
// End of FReimportHandler interface
protected:
FString fullFileName;
class UVrmAssetListObject* ReimportBase = nullptr;
};
@@ -0,0 +1,14 @@
#pragma once
#include "CoreMinimal.h"
//#include "VRMImporterModule.h"
DECLARE_LOG_CATEGORY_EXTERN(LogVRM4UImporter, Verbose, All);
#define SPRITER_IMPORT_ERROR(FormatString, ...) \
if (!bSilent) { UE_LOG(LogVRMImporter, Warning, FormatString, __VA_ARGS__); }
#define SPRITER_IMPORT_WARNING(FormatString, ...) \
if (!bSilent) { UE_LOG(LogVRMImporter, Warning, FormatString, __VA_ARGS__); }
@@ -0,0 +1,123 @@
#include "CoreMinimal.h"
#include "VRM4UImporterLog.h"
#include "VRM4UDetailCustomize.h"
#include "VrmAssetListThumbnailRenderer.h"
#include "VrmAssetListObject.h"
#include "VrmLicenseObject.h"
#include "Vrm1LicenseObject.h"
#include "VrmMetaObject.h"
#include "VrmCustomStruct.h"
#include "AssetToolsModule.h"
#include "Modules/ModuleManager.h"
#include "Internationalization/Internationalization.h"
#include "ThumbnailRendering/ThumbnailManager.h"
#include "Editor/PropertyEditor/Public/PropertyEditorModule.h"
#define LOCTEXT_NAMESPACE "VRM4UImporter"
DEFINE_LOG_CATEGORY(LogVRM4UImporter);
//////////////////////////////////////////////////////////////////////////
// FSpriterImporterModule
class FVRM4UImporterModule : public FDefaultModuleImpl
{
TArray< TSharedPtr<IAssetTypeActions> > AssetTypeActions;
public:
void OnObjectImported(UFactory* ImportFactory, UObject* InObject) {
}
void OnObjectReimported(UObject* InObject) {
auto *p = Cast<UVrmAssetListObject>(InObject);
if (p == nullptr) return;
}
void OnPostEngineInit() {
if (GEditor)
{
#if UE_VERSION_OLDER_THAN(4,22,0)
#else
GEditor->GetEditorSubsystem<UImportSubsystem>()->OnAssetPostImport.AddRaw(this, &FVRM4UImporterModule::OnObjectImported);
GEditor->GetEditorSubsystem<UImportSubsystem>()->OnAssetReimport.AddRaw(this, &FVRM4UImporterModule::OnObjectReimported);
#endif
}
}
virtual void StartupModule() override
{
{
auto &a = UThumbnailManager::Get();
a.RegisterCustomRenderer(UVrmAssetListObject::StaticClass(), UVrmAssetListThumbnailRenderer::StaticClass());
a.RegisterCustomRenderer(UVrmLicenseObject::StaticClass(), UVrmAssetListThumbnailRenderer::StaticClass());
a.RegisterCustomRenderer(UVrm1LicenseObject::StaticClass(), UVrmAssetListThumbnailRenderer::StaticClass());
a.RegisterCustomRenderer(UVrmMetaObject::StaticClass(), UVrmAssetListThumbnailRenderer::StaticClass());
}
{
AssetTypeActions.Empty();
AssetTypeActions.Add(MakeShareable(new FAssetTypeActions_VrmAssetList));
AssetTypeActions.Add(MakeShareable(new FAssetTypeActions_VrmLicense));
AssetTypeActions.Add(MakeShareable(new FAssetTypeActions_Vrm1License));
AssetTypeActions.Add(MakeShareable(new FAssetTypeActions_VrmMeta));
IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
for (decltype(auto) a : AssetTypeActions) {
AssetTools.RegisterAssetTypeActions(a.ToSharedRef());
}
}
{
FPropertyEditorModule& PropertyEditorModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyEditorModule.RegisterCustomPropertyTypeLayout(
("VRMRetargetSrcAnimSequence"),
FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FVRMRetargetSrcAnimSequenceCustomization::MakeInstance)
);
PropertyEditorModule.NotifyCustomizationModuleChanged();
}
{
if (GIsEditor)
{
FCoreDelegates::OnPostEngineInit.AddRaw(this, &FVRM4UImporterModule::OnPostEngineInit);
}
}
}
virtual void ShutdownModule() override
{
if (UObjectInitialized()){
UThumbnailManager::Get().UnregisterCustomRenderer(UVrmAssetListObject::StaticClass());
UThumbnailManager::Get().UnregisterCustomRenderer(UVrmLicenseObject::StaticClass());
UThumbnailManager::Get().UnregisterCustomRenderer(UVrm1LicenseObject::StaticClass());
UThumbnailManager::Get().UnregisterCustomRenderer(UVrmMetaObject::StaticClass());
FPropertyEditorModule& PropertyEditorModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyEditorModule.UnregisterCustomPropertyTypeLayout(("VRMRetargetSrcAnimSequence"));
IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
for (decltype(auto) a : AssetTypeActions) {
AssetTools.UnregisterAssetTypeActions(a.ToSharedRef());
a.Reset();
}
AssetTypeActions.Empty();
}
}
};
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_MODULE(FVRM4UImporterModule, VRM4UImporter);
//////////////////////////////////////////////////////////////////////////
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,316 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "VrmAssetListThumbnailRenderer.h"
#include "Engine/EngineTypes.h"
#include "CanvasItem.h"
#include "Engine/Texture2D.h"
#include "Engine/SkeletalMesh.h"
#include "CanvasTypes.h"
#include "Widgets/Text/STextBlock.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Layout/SBorder.h"
#include "Brushes/SlateColorBrush.h"
#include "EditorFramework/AssetImportData.h"
#include "ThumbnailRendering/SkeletalMeshThumbnailRenderer.h"
#include "VrmAssetListObject.h"
#include "VrmLicenseObject.h"
#include "Vrm1LicenseObject.h"
#include "VrmMetaObject.h"
//////////////////////////////////////////////////////////////////////////
// UPaperSpriteThumbnailRenderer
UClass* FAssetTypeActions_VrmAssetList::GetSupportedClass() const {
return UVrmAssetListObject::StaticClass();
}
FText FAssetTypeActions_VrmAssetList::GetName() const {
return NSLOCTEXT("AssetTypeActions", "FAssetTypeActions_VrmAssetList", "Vrm Asset List");
}
UClass* FAssetTypeActions_VrmLicense::GetSupportedClass() const {
return UVrmLicenseObject::StaticClass();
}
FText FAssetTypeActions_VrmLicense::GetName() const {
return NSLOCTEXT("AssetTypeActions", "FAssetTypeActions_VrmLicense", "Vrm License");
}
UClass* FAssetTypeActions_Vrm1License::GetSupportedClass() const {
return UVrm1LicenseObject::StaticClass();
}
FText FAssetTypeActions_Vrm1License::GetName() const {
return NSLOCTEXT("AssetTypeActions", "FAssetTypeActions_Vrm1License", "Vrm1 License");
}
UClass* FAssetTypeActions_VrmMeta::GetSupportedClass() const {
return UVrmMetaObject::StaticClass();
}
FText FAssetTypeActions_VrmMeta::GetName() const {
return NSLOCTEXT("AssetTypeActions", "FAssetTypeActions_VrmMeta", "Vrm Meta");
}
TSharedPtr<SWidget> FAssetTypeActions_VrmBase::GetThumbnailOverlay(const FAssetData& AssetData) const {
return nullptr; // サムネイルで描画するためスキップ
/*
FString str;
FColor col(0, 0, 0, 0);
if (str.Len() == 0) {
TWeakObjectPtr<UVrmAssetListObject> a = Cast<UVrmAssetListObject>(AssetData.GetAsset());
if (a.Get()) {
str = TEXT(" AssetList ");
}
}
if (str.Len() == 0){
TWeakObjectPtr<UVrmLicenseObject> a = Cast<UVrmLicenseObject>(AssetData.GetAsset());
if (a.Get()) {
str = TEXT(" License ");
//col.A = 128;
}
}
if (str.Len() == 0) {
TWeakObjectPtr<UVrm1LicenseObject> a = Cast<UVrm1LicenseObject>(AssetData.GetAsset());
if (a.Get()) {
str = TEXT(" License ");
//col.A = 128;
}
}
if (str.Len() == 0) {
TWeakObjectPtr<UVrmMetaObject> a = Cast<UVrmMetaObject>(AssetData.GetAsset());
if (a.Get()) {
str = TEXT(" Meta ");
//col.A = 128;
}
}
FText txt = FText::FromString(str);
return SNew(SBorder)
.HAlign(HAlign_Left)
.VAlign(VAlign_Top)
//.Padding(FMargin(4))
//.Padding(FMargin(4))
//.BorderImage(new FSlateColorBrush(FColor::White))
.BorderImage(new FSlateColorBrush(col))
//.AutoWidth()
[
SNew(STextBlock)
.Text(txt)
.HighlightText(txt)
.HighlightColor(FColor(64,64,64))
//.ShadowOffset(FVector2D(1.0f, 1.0f))
];
//return FAssetTypeActions_Base::GetThumbnailOverlay(AssetData);
*/
}
UVrmAssetListThumbnailRenderer::UVrmAssetListThumbnailRenderer(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void UVrmAssetListThumbnailRenderer::GetThumbnailSize(UObject* Object, float Zoom, uint32& OutWidth, uint32& OutHeight) const {
UVrmAssetListObject* a = Cast<UVrmAssetListObject>(Object);
if (a) {
if (a->VrmLicenseObject) {
auto tex = a->SmallThumbnailTexture;
if (tex == nullptr) {
tex = a->VrmLicenseObject->thumbnail;
}
if (tex) {
//return Super::GetThumbnailSize(tex, Zoom, OutWidth, OutHeight);
}
}
if (a->Vrm1LicenseObject) {
auto tex = a->SmallThumbnailTexture;
if (tex == nullptr) {
tex = a->Vrm1LicenseObject->thumbnail;
}
if (tex) {
//return Super::GetThumbnailSize(tex, Zoom, OutWidth, OutHeight);
}
}
}
Super::GetThumbnailSize(Object, Zoom, OutWidth, OutHeight);
}
#if UE_VERSION_OLDER_THAN(4,25,0)
void UVrmAssetListThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* RenderTarget, FCanvas* Canvas)
#else
void UVrmAssetListThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* RenderTarget, FCanvas* Canvas, bool bAdditionalViewFamily)
#endif
{
UTexture2D *tex = nullptr;
USkeletalMesh *sk = nullptr;
if (tex == nullptr){
UVrmAssetListObject* a = Cast<UVrmAssetListObject>(Object);
if (a) {
tex = a->SmallThumbnailTexture;
if (tex == nullptr) {
if (a->VrmLicenseObject) {
tex = a->VrmLicenseObject->thumbnail;
}
if (a->Vrm1LicenseObject) {
tex = a->Vrm1LicenseObject->thumbnail;
}
}
if (a->SkeletalMesh) {
sk = a->SkeletalMesh;
}
}
}
if (tex == nullptr) {
TArray<UObject*> ret;
{
UVrmMetaObject* a = Cast<UVrmMetaObject>(Object);
if (a) {
sk = a->SkeletalMesh;
if (a->VrmAssetListObject) {
tex = a->VrmAssetListObject->SmallThumbnailTexture;
}
}
}
{
UVrmLicenseObject* a = Cast<UVrmLicenseObject>(Object);
if (a) {
UPackage *pk = a->GetOutermost();
GetObjectsWithOuter(pk, ret);
// no sk
tex = a->thumbnail;
}
}
{
UVrm1LicenseObject* a = Cast<UVrm1LicenseObject>(Object);
if (a) {
UPackage* pk = a->GetOutermost();
GetObjectsWithOuter(pk, ret);
// no sk
tex = a->thumbnail;
}
}
for (auto *obj : ret) {
UVrmAssetListObject* t = Cast<UVrmAssetListObject>(obj);
if (t == nullptr) {
continue;
}
sk = t->SkeletalMesh;
if (t->SmallThumbnailTexture) tex = t->SmallThumbnailTexture;
break;
}
}
FString str = "none";
bool bDark = false;
if (Object->IsA(UVrmAssetListObject::StaticClass())) {
str = TEXT(" AssetList ");
} else if (Object->IsA(UVrmMetaObject::StaticClass())) {
str = TEXT(" Meta ");
bDark = true;
} else if (Object->IsA(UVrmLicenseObject::StaticClass())) {
str = TEXT(" License ");
bDark = true;
} else if (Object->IsA(UVrm1LicenseObject::StaticClass())) {
str = TEXT(" License ");
bDark = true;
}
auto DrawText = [&str, &Width, &Height, &Canvas, &bDark](){
FText ChannelText = FText::FromString(str);
FVector2D Position(Width / 24, Height / 24);
//FCanvasTextItem TextItem(Position, ChannelText, GEngine->GetLargeFont(), FLinearColor::Black);
FCanvasTextItem TextItem(Position, ChannelText, FSlateFontInfo(UEngine::GetMediumFont(), 28), FLinearColor::Black);
TextItem.DisableShadow();
//TextItem.Scale = FVector2D(Width / 64.0f, Height / 64.0f);
TextItem.Draw(Canvas); // サイズ取得のため一度描画する
if (bDark){
FCanvasTileItem BackgroundItem(FVector2D(0,0), FVector2D(Width, Height), FLinearColor(0, 0, 0, 0.5));
BackgroundItem.BlendMode = SE_BLEND_AlphaBlend;
Canvas->DrawItem(BackgroundItem);
}
{
float DPIScale = Canvas->GetDPIScale();
FVector2D TextSize = TextItem.DrawnSize;
FVector2D Padding(4.0f, 2.0f);
FVector2D BackgroundSize = TextSize + Padding * 2.0f;
FVector2D BackgroundPosition = Position - Padding;
FCanvasTileItem BackgroundItem(BackgroundPosition, BackgroundSize, FLinearColor(0.258, 0.539, 0.068, 0.9));
//BackgroundItem.BlendMode = SE_BLEND_Opaque;
BackgroundItem.BlendMode = SE_BLEND_AlphaBlend;
Canvas->DrawItem(BackgroundItem);
}
TextItem.Draw(Canvas);
};
// skeleton thumbnail
if (tex == nullptr) {
if (IsValid(meshThumbnail) == false) {
meshThumbnail = NewObject<USkeletalMeshThumbnailRenderer>(this);
}
if (sk) {
if (VRMGetSkeleton(sk)) {
#if UE_VERSION_OLDER_THAN(4,25,0)
meshThumbnail->Draw((UObject*)(sk), X, Y, Width, Height, RenderTarget, Canvas);
#else
meshThumbnail->Draw((UObject*)(sk), X, Y, Width, Height, RenderTarget, Canvas, bAdditionalViewFamily);
#endif
DrawText();
return;
}
}
}
auto obj = Object;
if (tex) {
obj = tex;
}
#if UE_VERSION_OLDER_THAN(4,25,0)
Super::Draw(obj, X, Y, Width, Height, RenderTarget, Canvas);
#else
Super::Draw(obj, X, Y, Width, Height, RenderTarget, Canvas, bAdditionalViewFamily);
#endif
DrawText();
}
#if UE_VERSION_OLDER_THAN(5,5,0)
#else
bool UVrmAssetListThumbnailRenderer::CanVisualizeAsset(UObject* Object)
{
if (UVrmLicenseObject* a = Cast<UVrmLicenseObject>(Object)) {
if (a->thumbnail == nullptr) {
// return false;
}
}
if (UVrm1LicenseObject* a = Cast<UVrm1LicenseObject>(Object)) {
if (a->thumbnail == nullptr) {
// return false;
}
}
return true;
//return UTextureThumbnailRenderer::CanVisualizeAsset(Object);
}
#endif
@@ -0,0 +1,82 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "ThumbnailRendering/TextureThumbnailRenderer.h"
#include "Misc/EngineVersionComparison.h"
#include "AssetTypeActions_Base.h"
#include "VrmAssetListThumbnailRenderer.generated.h"
class FCanvas;
class FRenderTarget;
class FAssetTypeActions_VrmBase : public FAssetTypeActions_Base {
virtual uint32 GetCategories() override { return EAssetTypeCategories::Misc; }
virtual TSharedPtr<SWidget> GetThumbnailOverlay(const FAssetData& AssetData) const override;
virtual FColor GetTypeColor() const override { return FColor(255, 223, 255); }
};
class FAssetTypeActions_VrmAssetList : public FAssetTypeActions_VrmBase
{
public:
// IAssetTypeActions Implementation
virtual FText GetName() const override;
virtual UClass* GetSupportedClass() const override;
virtual bool IsImportedAsset() const override { return true; }
};
class FAssetTypeActions_VrmLicense : public FAssetTypeActions_VrmBase
{
public:
// IAssetTypeActions Implementation
virtual FText GetName() const override;
virtual UClass* GetSupportedClass() const override;
};
class FAssetTypeActions_Vrm1License : public FAssetTypeActions_VrmBase
{
public:
// IAssetTypeActions Implementation
virtual FText GetName() const override;
virtual UClass* GetSupportedClass() const override;
};
class FAssetTypeActions_VrmMeta : public FAssetTypeActions_VrmBase
{
public:
// IAssetTypeActions Implementation
virtual FText GetName() const override;
virtual UClass* GetSupportedClass() const override;
};
UCLASS()
class UVrmAssetListThumbnailRenderer : public UTextureThumbnailRenderer
{
GENERATED_UCLASS_BODY()
// UThumbnailRenderer interface
virtual void GetThumbnailSize(UObject* Object, float Zoom, uint32& OutWidth, uint32& OutHeight) const override;
#if UE_VERSION_OLDER_THAN(4,25,0)
virtual void Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget*, FCanvas* Canvas) override;
#else
virtual void Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget*, FCanvas* Canvas, bool bAdditionalViewFamily) override;
#endif
// End of UThumbnailRenderer interface
#if UE_VERSION_OLDER_THAN(5,5,0)
#else
virtual bool CanVisualizeAsset(UObject* Object) override;
#endif
protected:
//void DrawFrame(class UPaperSprite* Sprite, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget*, FCanvas* Canvas, FBoxSphereBounds* OverrideRenderBounds);
//void DrawGrid(int32 X, int32 Y, uint32 Width, uint32 Height, FCanvas* Canvas);
UPROPERTY()
class USkeletalMeshThumbnailRenderer *meshThumbnail = nullptr;
};
@@ -0,0 +1,108 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "VrmImportUI.h"
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "UObject/Object.h"
#include "Factories/ImportSettings.h"
#include "VrmConvert.h"
const FImportOptionData* UVrmImportUI::GenerateOptionData() {
FImportOptionData &d = data;
#define c(a) d.a = a;
d.init();
c(bUEFN);
c(bAPoseRetarget);
c(bMobileBone);
c(MaterialType);
c(bForceOverride);
c(ModelScale);
c(AnimationTranslateScale);
c(PlayRateScale);
c(bRemoveRootBoneRotation);
c(bRemoveRootBonePosition);
c(bVrm10RemoveLocalRotation);
c(bVrm10UseBindToRestPose);
c(bVrm10Bindpose);
c(bForceOriginalBoneName);
c(bGenerateHumanoidRenamedMesh);
c(bGenerateIKBone);
c(bGenerateRigIK);
c(bSkipPhysics);
c(bSkipRetargeter);
c(bSkipMorphTarget);
c(bEnableMorphTargetNormal);
c(bForceOriginalMorphTargetName);
c(bRemoveBlendShapeGroupPrefix);
c(bForceOpaque);
c(bForceTwoSided);
c(bSingleUAssetFile);
c(bDefaultGridTextureMode);
c(bBC7Mode);
c(bMipmapGenerateMode);
c(bUseUE5Material);
c(bGenerateOutlineMaterial);
c(bMergeMaterial);
c(bMergePrimitive);
c(bOptimizeVertex);
c(bRemoveDegenerateTriangles);
c(BoneWeightInfluenceNum);
c(bSimpleRoot);
c(bActiveBone);
c(bSkipNoMeshBone);
c(bIgnoreVRMValidation);
c(bDebugOneBone);
c(bDebugNoMesh);
c(bDebugNoMaterial);
c(Skeleton);
return &data;
}
@@ -0,0 +1,258 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "UObject/Object.h"
#include "Factories/ImportSettings.h"
#include "VrmConvert.h"
#include "Vrm1LicenseObject.h"
#include "VrmImportUI.generated.h"
DECLARE_DELEGATE(FOnResolveFbxReImport);
UCLASS(config=EditorPerProjectUserSettings, AutoExpandCategories=(FTransform), HideCategories=Object, MinimalAPI)
class UVrmImportUI : public UObject, public IImportSettingsParser
{
GENERATED_UCLASS_BODY()
public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Thumbnail"))
UTexture2D *Thumbnail;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "VRM Title / Author"))
FString TitleAuthor;
/** for Mobile. Import root bone only */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "**UE5** UEFN mode"))
bool bUEFN = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "**UE4** RetargetPose A-pose(Off to T-pose)"))
bool bAPoseRetarget = true;
/** for Mobile. Import root bone only */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "**mobile** Reduce bonemap<=75"))
bool bMobileBone = false;
/** Materal Type */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mesh)
EVRMImportMaterialType MaterialType;
#if UE_VERSION_OLDER_THAN(5,2,0)
static const bool VRM4U_UseUE5Mat = false;
#else
static const bool VRM4U_UseUE5Mat = true;
#endif
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Use UE5 Material"))
bool bUseUE5Material = VRM4U_UseUE5Mat;
/** Outline Material*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "GenerateOutlineMaterial"))
bool bGenerateOutlineMaterial = true;
/** Force Override */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Force Override (as New Asset)"))
bool bForceOverride = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Model scale"))
float ModelScale = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Animation Translate scale"))
float AnimationTranslateScale = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Animation Play Rate Scale"))
float PlayRateScale = 1.0f;
/** Remove RootBone Rotation */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Remove RootBone Rotation"))
bool bRemoveRootBoneRotation = true;
/** Remove RootBone Position */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Remove RootBone Position"))
bool bRemoveRootBonePosition = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "VRM10 Convert to Restpose from Bindpose"))
bool bVrm10UseBindToRestPose = true;
/** Remove Local Rotation for VRM10 */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "VRM10 Remove Local Rotation"))
bool bVrm10RemoveLocalRotation = false;
/** Use Bindpose for VRM10 */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "VRM10 Bindpose"))
bool bVrm10Bindpose = false;
/** Force Original Bone Name */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Force original bone name"))
bool bForceOriginalBoneName = false;
/** Duplicate mesh and renamed humanoid bone */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName= "Generate renamed humanoid mesh"))
bool bGenerateHumanoidRenamedMesh = false;
/** Add IK Bone */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Generate IK Bone"))
bool bGenerateIKBone = false;
/** Add RigIK asset*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Generate RigIK Asset"))
bool bGenerateRigIK = true;
/** Remove Physics asset */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "No physics asset"))
bool bSkipPhysics = false;
/** Remove Retargeter asset */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "No Retargeter asset"))
bool bSkipRetargeter = false;
/** Remove MorphTarget */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "No MorphTarget"))
bool bSkipMorphTarget = false;
/** Use MorphTarget Normal */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Eable MorphTarget Normal(TangentZDelta)"))
bool bEnableMorphTargetNormal = false;
#if UE_VERSION_OLDER_THAN(4,26,0)
static const bool VRM4U_UseBC7 = false;
#else
static const bool VRM4U_UseBC7 = true;
#endif
/** Force Original MorphTarget Name Mode */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Force original morphtarget name"))
bool bForceOriginalMorphTargetName = false;
/** Use Strict MorphTarget Name Mode */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Remove BlendShapeGroup prefix for old VRM file"))
bool bRemoveBlendShapeGroupPrefix = false;
/** Use Opaque insted of translucent */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Force Opaque"))
bool bForceOpaque = false;
/** Use TwoSided */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Force TwoSided"))
bool bForceTwoSided = false;
/** Save as single uasset file */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "Single uasset file"))
bool bSingleUAssetFile = false;
/** Use GridTexture by Default */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Texture] Use DummyGrid by DefaultBaseTexture"))
bool bDefaultGridTextureMode = false;
/** Use BC7 */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Texture] Use BC7 for BaseTexture"))
bool bBC7Mode = VRM4U_UseBC7;
/** Generate mipmap (be careful of MatCap texture)*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Texture] Generate Mipmap"))
bool bMipmapGenerateMode = false;
/** Merge material using same parameter */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Optimize] Merge material"))
bool bMergeMaterial = true;
/** Merge primitives using same material */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Optimize] Merge primitive"))
bool bMergePrimitive = false;
/** Use optimized MaterialInstance */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Optimize] use opt material"))
bool bOptimizeMaterial = true;
/** Remove unused vertex */
//UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Optimize] remove unused vertex"))
bool bOptimizeVertex = false;
/** Remove degenerate triangles */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Optimize] remove degenerate triangles"))
bool bRemoveDegenerateTriangles = false;
/** BoneWeight influence */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Optimize] Bone Weight Influence Num"))
int BoneWeightInfluenceNum = 8;
/** Remove bone has no mesh */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Optimize] Remove bone used DCC tool"))
bool bSimpleRoot = true;
/** Remove bone has no mesh */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Optimize] Use ActiveBone List"))
bool bActiveBone = true;
//UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName="Delete bone without mesh"))
bool bSkipNoMeshBone = false;
/** for DEBUG. Ignore Validation */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Debug] Ignore VRM Validataion"))
bool bIgnoreVRMValidation = false;
/** for DEBUG. Import root bone only */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Debug] One bone only"))
bool bDebugOneBone = false;
/** for DEBUG. No mesh. Bone only */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Debug] No Mesh"))
bool bDebugNoMesh = false;
/** for DEBUG. No mesh. Bone only */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = Mesh, meta = (ImportType = "StaticMesh|SkeletalMesh", DisplayName = "[Debug] No Material"))
bool bDebugNoMaterial = false;
/** Skeleton to use for imported asset. When importing a mesh, leaving this as "None" will create a new skeleton. When importing an animation this MUST be specified to import the asset. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category=Mesh, meta=(ImportType="SkeletalMesh"))
class USkeleton* Skeleton;
//
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "VRM1_License")
TArray<FLicenseBoolDataPair> LicenseBool;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "VRM1_License")
TArray<FLicenseStringDataPair> LicenseString;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "VRM1_License")
TArray<FLicenseStringDataArray> LicenseStringArray;
//
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "License_Personation/CharacterizationPermission")
FString allowedUserName;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "License_Personation/CharacterizationPermission")
FString violentUsageName;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "License_Personation/CharacterizationPermission")
FString sexualUsageName;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "License_Personation/CharacterizationPermission")
FString commercialUsageName;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "License_Personation/CharacterizationPermission")
FString otherPermissionUrl;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "License_Redistribution/ModificationsLicense")
FString licenseName;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "License_Redistribution/ModificationsLicense")
FString otherLicenseUrl;
private:
UPROPERTY()
FImportOptionData data;
public:
const FImportOptionData *GenerateOptionData();
UFUNCTION(BlueprintCallable, Category = Miscellaneous)
void ResetToDefault();
//virtual bool CanEditChange(const FProperty* InProperty) const override;
/** IImportSettings Interface */
virtual void ParseFromJson(TSharedRef<class FJsonObject> ImportSettingsJson) override;
/* Whether this UI is construct for a reimport */
bool bIsReimport;
};
@@ -0,0 +1,226 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "VrmOptionWindow.h"
#include "Modules/ModuleManager.h"
#include "Widgets/Layout/SBorder.h"
#include "Widgets/Text/STextBlock.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Layout/SUniformGridPanel.h"
#include "Widgets/Input/SButton.h"
#include "EditorStyleSet.h"
//#include "Factories/FbxAnimSequenceImportData.h"
#include "IDocumentation.h"
#include "PropertyEditorModule.h"
#include "IDetailsView.h"
#define LOCTEXT_NAMESPACE "VRMOption"
void SVrmOptionWindow::Construct(const FArguments& InArgs)
{
ImportUI = InArgs._ImportUI;
WidgetWindow = InArgs._WidgetWindow;
//bIsObjFormat = InArgs._IsObjFormat;
check (ImportUI);
TSharedPtr<SBox> ImportTypeDisplay;
TSharedPtr<SHorizontalBox> FbxHeaderButtons;
TSharedPtr<SBox> InspectorBox;
this->ChildSlot
[
SNew(SBox)
.MaxDesiredHeight(InArgs._MaxWindowHeight)
.MaxDesiredWidth(InArgs._MaxWindowWidth)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(2)
[
SAssignNew(ImportTypeDisplay, SBox)
]
+SVerticalBox::Slot()
.AutoHeight()
.Padding(2)
[
#if UE_VERSION_OLDER_THAN(5,1,0)
SNew(SBorder)
.Padding(FMargin(3))
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Font(FEditorStyle::GetFontStyle("CurveEd.LabelFont"))
.Text(LOCTEXT("Import_CurrentFileTitle", "Current File: "))
]
+SHorizontalBox::Slot()
.Padding(5, 0, 0, 0)
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Font(FEditorStyle::GetFontStyle("CurveEd.InfoFont"))
.Text(InArgs._FullPath)
]
]
#else
SNew(SBorder)
.Padding(FMargin(3))
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Font(FAppStyle::GetFontStyle("CurveEd.LabelFont"))
.Text(LOCTEXT("Import_CurrentFileTitle", "Current File: "))
]
+ SHorizontalBox::Slot()
.Padding(5, 0, 0, 0)
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Font(FAppStyle::GetFontStyle("CurveEd.InfoFont"))
.Text(InArgs._FullPath)
]
]
#endif
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(2)
[
SAssignNew(InspectorBox, SBox)
.MaxDesiredHeight(650.0f)
.WidthOverride(400.0f*2.f)
]
+ SVerticalBox::Slot()
.AutoHeight()
.HAlign(HAlign_Right)
.Padding(2)
[
SNew(SUniformGridPanel)
.SlotPadding(2)
/*
+ SUniformGridPanel::Slot(0, 0)
[
IDocumentation::Get()->CreateAnchor(FString("Engine/Content/FBX/ImportOptions"))
]
*/
/*
+ SUniformGridPanel::Slot(1, 0)
[
SNew(SButton)
.HAlign(HAlign_Center)
.Text(LOCTEXT("FbxOptionWindow_ImportAll", "Import All"))
.ToolTipText(LOCTEXT("FbxOptionWindow_ImportAll_ToolTip", "Import all files with these same settings"))
.IsEnabled(this, &SVrmOptionWindow::CanImport)
.OnClicked(this, &SVrmOptionWindow::OnImportAll)
]
*/
+ SUniformGridPanel::Slot(2, 0)
[
SAssignNew(ImportButton, SButton)
.HAlign(HAlign_Center)
.Text(LOCTEXT("VRMOptionWindow_Import", "Import"))
.IsEnabled(this, &SVrmOptionWindow::CanImport)
.OnClicked(this, &SVrmOptionWindow::OnImport)
]
+ SUniformGridPanel::Slot(3, 0)
[
SNew(SButton)
.HAlign(HAlign_Center)
.Text(LOCTEXT("VRMOptionWindow_Cancel", "Cancel"))
.ToolTipText(LOCTEXT("VRMOptionWindow_Cancel_ToolTip", "Cancels importing this VRM file"))
.OnClicked(this, &SVrmOptionWindow::OnCancel)
]
]
]
];
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
FDetailsViewArgs DetailsViewArgs;
DetailsViewArgs.bAllowSearch = false;
DetailsViewArgs.NameAreaSettings = FDetailsViewArgs::HideNameArea;
DetailsView = PropertyEditorModule.CreateDetailView(DetailsViewArgs);
InspectorBox->SetContent(DetailsView->AsShared());
/*
ImportTypeDisplay->SetContent(
SNew(SBorder)
.Padding(FMargin(3))
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(this, &SVrmOptionWindow::GetImportTypeDisplayText)
]
+ SHorizontalBox::Slot()
[
SNew(SBox)
.HAlign(HAlign_Right)
[
SAssignNew(FbxHeaderButtons, SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(FMargin(2.0f, 0.0f))
[
SNew(SButton)
.Text(LOCTEXT("FbxOptionWindow_ResetOptions", "Reset to Default"))
.OnClicked(this, &SVrmOptionWindow::OnResetToDefaultClick)
]
]
]
]
);
*/
DetailsView->SetObject(ImportUI);
}
FReply SVrmOptionWindow::OnResetToDefaultClick() const
{
ImportUI->ResetToDefault();
//Refresh the view to make sure the custom UI are updating correctly
DetailsView->SetObject(ImportUI, true);
return FReply::Handled();
}
FText SVrmOptionWindow::GetImportTypeDisplayText() const
{
return FText::GetEmpty();
}
bool SVrmOptionWindow::CanImport() const
{
/*
// do test to see if we are ready to import
if (ImportUI->MeshTypeToImport == FBXIT_Animation)
{
if (ImportUI->Skeleton == NULL || !ImportUI->bImportAnimations)
{
return false;
}
}
if (ImportUI->AnimSequenceImportData->AnimationLength == FBXALIT_SetRange)
{
if (ImportUI->AnimSequenceImportData->FrameImportRange.Min > ImportUI->AnimSequenceImportData->FrameImportRange.Max)
{
return false;
}
}
*/
return true;
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,111 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "InputCoreTypes.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "Input/Reply.h"
#include "Widgets/SCompoundWidget.h"
#include "Widgets/SWindow.h"
#include "VrmImportUI.h"
class SButton;
class SVrmOptionWindow : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS( SVrmOptionWindow )
: _ImportUI(NULL)
, _WidgetWindow()
, _FullPath()
//, _ForcedImportType()
//, _IsObjFormat(false)
, _MaxWindowHeight(0.0f)
, _MaxWindowWidth(0.0f)
{}
SLATE_ARGUMENT( UVrmImportUI*, ImportUI )
SLATE_ARGUMENT( TSharedPtr<SWindow>, WidgetWindow )
SLATE_ARGUMENT( FText, FullPath )
//SLATE_ARGUMENT( TOptional<EFBXImportType>, ForcedImportType )
//SLATE_ARGUMENT( bool, IsObjFormat )
SLATE_ARGUMENT( float, MaxWindowHeight)
SLATE_ARGUMENT(float, MaxWindowWidth)
SLATE_END_ARGS()
public:
void Construct(const FArguments& InArgs);
virtual bool SupportsKeyboardFocus() const override { return true; }
FReply OnImport()
{
bShouldImport = true;
if ( WidgetWindow.IsValid() )
{
WidgetWindow.Pin()->RequestDestroyWindow();
}
return FReply::Handled();
}
FReply OnImportAll()
{
bShouldImportAll = true;
return OnImport();
}
FReply OnCancel()
{
bShouldImport = false;
bShouldImportAll = false;
if ( WidgetWindow.IsValid() )
{
WidgetWindow.Pin()->RequestDestroyWindow();
}
return FReply::Handled();
}
virtual FReply OnKeyDown( const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent ) override
{
if( InKeyEvent.GetKey() == EKeys::Escape )
{
return OnCancel();
}
return FReply::Unhandled();
}
bool ShouldImport() const
{
return bShouldImport;
}
bool ShouldImportAll() const
{
return bShouldImportAll;
}
SVrmOptionWindow()
: ImportUI(NULL)
, bShouldImport(false)
, bShouldImportAll(false)
{}
UVrmImportUI * GetImportUI() {
return ImportUI;
}
private:
bool CanImport() const;
FReply OnResetToDefaultClick() const;
FText GetImportTypeDisplayText() const;
private:
UVrmImportUI* ImportUI;
TSharedPtr<class IDetailsView> DetailsView;
TWeakPtr< SWindow > WidgetWindow;
TSharedPtr< SButton > ImportButton;
bool bShouldImport;
bool bShouldImportAll;
bool bIsObjFormat;
};
@@ -0,0 +1,68 @@
using System;
using UnrealBuildTool;
public class VRM4UImporter : ModuleRules
{
public VRM4UImporter(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PrivateDependencyModuleNames.AddRange(
new string[] {
"Core",
"CoreUObject",
"InputCore",
"EditorStyle",
"ApplicationCore",
"Engine",
"UnrealEd",
"Slate",
"SlateCore",
"VRM4U",
"VRM4ULoader",
"AnimGraphRuntime",
"AnimGraph",
"BlueprintGraph",
"PropertyEditor",
"Persona",
"MainFrame",
//"ToolMenus",
});
BuildVersion Version;
if (BuildVersion.TryRead(BuildVersion.GetDefaultFileName(), out Version)) {
//if (Version.MajorVersion == X && Version.MinorVersion == Y)
if (Version.MajorVersion == 4 && Version.MinorVersion <= 23)
{
}
else {
PrivateDependencyModuleNames.Add("ToolMenus");
}
if (Version.MajorVersion == 4 || (Version.MajorVersion == 5 && Version.MinorVersion <= 1))
{
}
else
{
PrivateDependencyModuleNames.Add("AssetDefinition");
}
}
PrivateIncludePathModuleNames.AddRange(
new string[] {
"AssetTools",
"AssetRegistry"
});
DynamicallyLoadedModuleNames.AddRange(
new string[] {
"AssetTools",
"AssetRegistry"
});
}
}