mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 01:36:02 +08:00
[ue4] Closes #1246. Rewrote the way asset re-imports work and are signaled to the Spine components.
This commit is contained in:
parent
3c06a0881f
commit
c255347fb1
@ -130,7 +130,7 @@ UTexture2D* resolveTexture (USpineAtlasAsset* Asset, const FString& PageFileName
|
|||||||
}
|
}
|
||||||
|
|
||||||
void USpineAtlasAssetFactory::LoadAtlas (USpineAtlasAsset* Asset, const FString& CurrentSourcePath, const FString& LongPackagePath) {
|
void USpineAtlasAssetFactory::LoadAtlas (USpineAtlasAsset* Asset, const FString& CurrentSourcePath, const FString& LongPackagePath) {
|
||||||
Atlas* atlas = Asset->GetAtlas(true);
|
Atlas* atlas = Asset->GetAtlas();
|
||||||
Asset->atlasPages.Empty();
|
Asset->atlasPages.Empty();
|
||||||
|
|
||||||
const FString targetTexturePath = LongPackagePath / TEXT("Textures");
|
const FString targetTexturePath = LongPackagePath / TEXT("Textures");
|
||||||
|
|||||||
@ -77,9 +77,11 @@ UObject* USpineSkeletonAssetFactory::FactoryCreateFile (UClass * InClass, UObjec
|
|||||||
name.Append("-data");
|
name.Append("-data");
|
||||||
|
|
||||||
USpineSkeletonDataAsset* asset = NewObject<USpineSkeletonDataAsset>(InParent, InClass, FName(*name), Flags);
|
USpineSkeletonDataAsset* asset = NewObject<USpineSkeletonDataAsset>(InParent, InClass, FName(*name), Flags);
|
||||||
if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *Filename, 0)) {
|
TArray<uint8> rawData;
|
||||||
|
if (!FFileHelper::LoadFileToArray(rawData, *Filename, 0)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
asset->SetRawData(rawData);
|
||||||
|
|
||||||
asset->SetSkeletonDataFileName(FName(*Filename));
|
asset->SetSkeletonDataFileName(FName(*Filename));
|
||||||
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
|
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
|
||||||
@ -107,7 +109,9 @@ void USpineSkeletonAssetFactory::SetReimportPaths (UObject* Obj, const TArray<FS
|
|||||||
|
|
||||||
EReimportResult::Type USpineSkeletonAssetFactory::Reimport (UObject* Obj) {
|
EReimportResult::Type USpineSkeletonAssetFactory::Reimport (UObject* Obj) {
|
||||||
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
|
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
|
||||||
if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *asset->GetSkeletonDataFileName().ToString(), 0)) return EReimportResult::Failed;
|
TArray<uint8> rawData;
|
||||||
|
if (!FFileHelper::LoadFileToArray(rawData, *asset->GetSkeletonDataFileName().ToString(), 0)) return EReimportResult::Failed;
|
||||||
|
asset->SetRawData(rawData);
|
||||||
|
|
||||||
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
|
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
|
||||||
LoadAtlas(*asset->GetSkeletonDataFileName().ToString(), longPackagePath);
|
LoadAtlas(*asset->GetSkeletonDataFileName().ToString(), longPackagePath);
|
||||||
|
|||||||
@ -86,7 +86,7 @@ int32 SSpineWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeo
|
|||||||
widget->pageToScreenBlendMaterial.Empty();
|
widget->pageToScreenBlendMaterial.Empty();
|
||||||
|
|
||||||
for (int i = 0; i < widget->Atlas->atlasPages.Num(); i++) {
|
for (int i = 0; i < widget->Atlas->atlasPages.Num(); i++) {
|
||||||
AtlasPage* currPage = widget->Atlas->GetAtlas(false)->getPages()[i];
|
AtlasPage* currPage = widget->Atlas->GetAtlas()->getPages()[i];
|
||||||
|
|
||||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(widget->NormalBlendMaterial, widget);
|
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(widget->NormalBlendMaterial, widget);
|
||||||
material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]);
|
material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]);
|
||||||
@ -115,7 +115,7 @@ int32 SSpineWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeo
|
|||||||
widget->pageToScreenBlendMaterial.Empty();
|
widget->pageToScreenBlendMaterial.Empty();
|
||||||
|
|
||||||
for (int i = 0; i < widget->Atlas->atlasPages.Num(); i++) {
|
for (int i = 0; i < widget->Atlas->atlasPages.Num(); i++) {
|
||||||
AtlasPage* currPage = widget->Atlas->GetAtlas(false)->getPages()[i];
|
AtlasPage* currPage = widget->Atlas->GetAtlas()->getPages()[i];
|
||||||
|
|
||||||
UTexture2D* texture = widget->Atlas->atlasPages[i];
|
UTexture2D* texture = widget->Atlas->atlasPages[i];
|
||||||
UTexture* oldTexture = nullptr;
|
UTexture* oldTexture = nullptr;
|
||||||
|
|||||||
@ -38,26 +38,7 @@
|
|||||||
|
|
||||||
using namespace spine;
|
using namespace spine;
|
||||||
|
|
||||||
FString USpineAtlasAsset::GetRawData () const {
|
|
||||||
return rawData;
|
|
||||||
}
|
|
||||||
|
|
||||||
FName USpineAtlasAsset::GetAtlasFileName () const {
|
|
||||||
#if WITH_EDITORONLY_DATA
|
#if WITH_EDITORONLY_DATA
|
||||||
TArray<FString> files;
|
|
||||||
if (importData) importData->ExtractFilenames(files);
|
|
||||||
if (files.Num() > 0) return FName(*files[0]);
|
|
||||||
else return atlasFileName;
|
|
||||||
#else
|
|
||||||
return atlasFileName;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WITH_EDITORONLY_DATA
|
|
||||||
|
|
||||||
void USpineAtlasAsset::SetRawData (const FString &RawData) {
|
|
||||||
this->rawData = RawData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USpineAtlasAsset::SetAtlasFileName (const FName &AtlasFileName) {
|
void USpineAtlasAsset::SetAtlasFileName (const FName &AtlasFileName) {
|
||||||
importData->UpdateFilenameOnly(AtlasFileName.ToString());
|
importData->UpdateFilenameOnly(AtlasFileName.ToString());
|
||||||
@ -87,6 +68,25 @@ void USpineAtlasAsset::Serialize (FArchive& Ar) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FName USpineAtlasAsset::GetAtlasFileName() const {
|
||||||
|
#if WITH_EDITORONLY_DATA
|
||||||
|
TArray<FString> files;
|
||||||
|
if (importData) importData->ExtractFilenames(files);
|
||||||
|
if (files.Num() > 0) return FName(*files[0]);
|
||||||
|
else return atlasFileName;
|
||||||
|
#else
|
||||||
|
return atlasFileName;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void USpineAtlasAsset::SetRawData(const FString &RawData) {
|
||||||
|
this->rawData = RawData;
|
||||||
|
if (atlas) {
|
||||||
|
delete atlas;
|
||||||
|
atlas = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void USpineAtlasAsset::BeginDestroy () {
|
void USpineAtlasAsset::BeginDestroy () {
|
||||||
if (atlas) {
|
if (atlas) {
|
||||||
delete atlas;
|
delete atlas;
|
||||||
@ -95,8 +95,8 @@ void USpineAtlasAsset::BeginDestroy () {
|
|||||||
Super::BeginDestroy();
|
Super::BeginDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
Atlas* USpineAtlasAsset::GetAtlas (bool ForceReload) {
|
Atlas* USpineAtlasAsset::GetAtlas () {
|
||||||
if (!atlas || ForceReload) {
|
if (!atlas) {
|
||||||
if (atlas) {
|
if (atlas) {
|
||||||
delete atlas;
|
delete atlas;
|
||||||
atlas = nullptr;
|
atlas = nullptr;
|
||||||
@ -111,7 +111,7 @@ Atlas* USpineAtlasAsset::GetAtlas (bool ForceReload) {
|
|||||||
page->setRendererObject(atlasPages[j++]);
|
page->setRendererObject(atlasPages[j++]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this->atlas;
|
return this->atlas;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef LOCTEXT_NAMESPACE
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|||||||
@ -104,23 +104,39 @@ void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime, bool CallDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
void USpineSkeletonAnimationComponent::CheckState () {
|
void USpineSkeletonAnimationComponent::CheckState () {
|
||||||
if (lastAtlas != Atlas || lastData != SkeletonData) {
|
bool needsUpdate = lastAtlas != Atlas || lastData != SkeletonData;
|
||||||
|
|
||||||
|
if (!needsUpdate) {
|
||||||
|
// Are we doing a re-import? Then check if the underlying spine-cpp data
|
||||||
|
// has changed.
|
||||||
|
if (lastAtlas && lastAtlas == Atlas && lastData && lastData == SkeletonData) {
|
||||||
|
spine::Atlas* atlas = Atlas->GetAtlas();
|
||||||
|
if (lastSpineAtlas != atlas) {
|
||||||
|
needsUpdate = true;
|
||||||
|
}
|
||||||
|
if (skeleton && skeleton->getData() != SkeletonData->GetSkeletonData(atlas)) {
|
||||||
|
needsUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsUpdate) {
|
||||||
DisposeState();
|
DisposeState();
|
||||||
|
|
||||||
if (Atlas && SkeletonData) {
|
if (Atlas && SkeletonData) {
|
||||||
spine::SkeletonData *data = SkeletonData->GetSkeletonData(Atlas->GetAtlas(false), false);
|
spine::SkeletonData *data = SkeletonData->GetSkeletonData(Atlas->GetAtlas());
|
||||||
if (data) {
|
if (data) {
|
||||||
skeleton = new (__FILE__, __LINE__) Skeleton(data);
|
skeleton = new (__FILE__, __LINE__) Skeleton(data);
|
||||||
AnimationStateData* stateData = SkeletonData->GetAnimationStateData(Atlas->GetAtlas(false));
|
AnimationStateData* stateData = SkeletonData->GetAnimationStateData(Atlas->GetAtlas());
|
||||||
state = new (__FILE__, __LINE__) AnimationState(stateData);
|
state = new (__FILE__, __LINE__) AnimationState(stateData);
|
||||||
state->setRendererObject((void*)this);
|
state->setRendererObject((void*)this);
|
||||||
state->setListener(callback);
|
state->setListener(callback);
|
||||||
trackEntries.Empty();
|
trackEntries.Empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastAtlas = Atlas;
|
lastAtlas = Atlas;
|
||||||
lastSpineAtlas = Atlas ? Atlas->GetAtlas(false) : nullptr;
|
lastSpineAtlas = Atlas ? Atlas->GetAtlas() : nullptr;
|
||||||
lastData = SkeletonData;
|
lastData = SkeletonData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -206,7 +206,7 @@ void USpineSkeletonComponent::CheckState () {
|
|||||||
// Are we doing a re-import? Then check if the underlying spine-cpp data
|
// Are we doing a re-import? Then check if the underlying spine-cpp data
|
||||||
// has changed.
|
// has changed.
|
||||||
if (lastAtlas && lastAtlas == Atlas && lastData && lastData == SkeletonData) {
|
if (lastAtlas && lastAtlas == Atlas && lastData && lastData == SkeletonData) {
|
||||||
spine::Atlas* atlas = Atlas->GetAtlas(false);
|
spine::Atlas* atlas = Atlas->GetAtlas();
|
||||||
if (lastSpineAtlas != atlas) {
|
if (lastSpineAtlas != atlas) {
|
||||||
needsUpdate = true;
|
needsUpdate = true;
|
||||||
}
|
}
|
||||||
@ -220,12 +220,12 @@ void USpineSkeletonComponent::CheckState () {
|
|||||||
DisposeState();
|
DisposeState();
|
||||||
|
|
||||||
if (Atlas && SkeletonData) {
|
if (Atlas && SkeletonData) {
|
||||||
spine::SkeletonData* data = SkeletonData->GetSkeletonData(Atlas->GetAtlas(false), false);
|
spine::SkeletonData* data = SkeletonData->GetSkeletonData(Atlas->GetAtlas());
|
||||||
skeleton = new (__FILE__, __LINE__) Skeleton(data);
|
skeleton = new (__FILE__, __LINE__) Skeleton(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastAtlas = Atlas;
|
lastAtlas = Atlas;
|
||||||
lastSpineAtlas = Atlas ? Atlas->GetAtlas(false) : nullptr;
|
lastSpineAtlas = Atlas ? Atlas->GetAtlas() : nullptr;
|
||||||
lastData = SkeletonData;
|
lastData = SkeletonData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,10 +50,6 @@ FName USpineSkeletonDataAsset::GetSkeletonDataFileName () const {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<uint8>& USpineSkeletonDataAsset::GetRawData () {
|
|
||||||
return this->rawData;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WITH_EDITORONLY_DATA
|
#if WITH_EDITORONLY_DATA
|
||||||
|
|
||||||
void USpineSkeletonDataAsset::SetSkeletonDataFileName (const FName &SkeletonDataFileName) {
|
void USpineSkeletonDataAsset::SetSkeletonDataFileName (const FName &SkeletonDataFileName) {
|
||||||
@ -96,8 +92,17 @@ void USpineSkeletonDataAsset::BeginDestroy () {
|
|||||||
Super::BeginDestroy();
|
Super::BeginDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
SkeletonData* USpineSkeletonDataAsset::GetSkeletonData (Atlas* Atlas, bool ForceReload) {
|
void USpineSkeletonDataAsset::SetRawData(TArray<uint8> &Data) {
|
||||||
if (!skeletonData || lastAtlas != Atlas || ForceReload) {
|
this->rawData.Empty();
|
||||||
|
this->rawData.Append(Data);
|
||||||
|
if (skeletonData) {
|
||||||
|
delete skeletonData;
|
||||||
|
skeletonData = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SkeletonData* USpineSkeletonDataAsset::GetSkeletonData (Atlas* Atlas) {
|
||||||
|
if (!skeletonData || lastAtlas != Atlas) {
|
||||||
if (skeletonData) {
|
if (skeletonData) {
|
||||||
delete skeletonData;
|
delete skeletonData;
|
||||||
skeletonData = nullptr;
|
skeletonData = nullptr;
|
||||||
@ -136,7 +141,7 @@ SkeletonData* USpineSkeletonDataAsset::GetSkeletonData (Atlas* Atlas, bool Force
|
|||||||
|
|
||||||
AnimationStateData* USpineSkeletonDataAsset::GetAnimationStateData(Atlas* atlas) {
|
AnimationStateData* USpineSkeletonDataAsset::GetAnimationStateData(Atlas* atlas) {
|
||||||
if (!animationStateData) {
|
if (!animationStateData) {
|
||||||
SkeletonData* data = GetSkeletonData(atlas, false);
|
SkeletonData* data = GetSkeletonData(atlas);
|
||||||
animationStateData = new (__FILE__, __LINE__) AnimationStateData(data);
|
animationStateData = new (__FILE__, __LINE__) AnimationStateData(data);
|
||||||
}
|
}
|
||||||
for (auto& data : MixData) {
|
for (auto& data : MixData) {
|
||||||
|
|||||||
@ -90,7 +90,7 @@ void USpineSkeletonRendererComponent::TickComponent (float DeltaTime, ELevelTick
|
|||||||
pageToScreenBlendMaterial.Empty();
|
pageToScreenBlendMaterial.Empty();
|
||||||
|
|
||||||
for (int i = 0; i < skeleton->Atlas->atlasPages.Num(); i++) {
|
for (int i = 0; i < skeleton->Atlas->atlasPages.Num(); i++) {
|
||||||
AtlasPage* currPage = skeleton->Atlas->GetAtlas(false)->getPages()[i];
|
AtlasPage* currPage = skeleton->Atlas->GetAtlas()->getPages()[i];
|
||||||
|
|
||||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(NormalBlendMaterial, owner);
|
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(NormalBlendMaterial, owner);
|
||||||
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
||||||
@ -119,7 +119,7 @@ void USpineSkeletonRendererComponent::TickComponent (float DeltaTime, ELevelTick
|
|||||||
pageToScreenBlendMaterial.Empty();
|
pageToScreenBlendMaterial.Empty();
|
||||||
|
|
||||||
for (int i = 0; i < skeleton->Atlas->atlasPages.Num(); i++) {
|
for (int i = 0; i < skeleton->Atlas->atlasPages.Num(); i++) {
|
||||||
AtlasPage* currPage = skeleton->Atlas->GetAtlas(false)->getPages()[i];
|
AtlasPage* currPage = skeleton->Atlas->GetAtlas()->getPages()[i];
|
||||||
|
|
||||||
UTexture2D* texture = skeleton->Atlas->atlasPages[i];
|
UTexture2D* texture = skeleton->Atlas->atlasPages[i];
|
||||||
UTexture* oldTexture = nullptr;
|
UTexture* oldTexture = nullptr;
|
||||||
|
|||||||
@ -96,7 +96,7 @@ void USpineWidget::CheckState() {
|
|||||||
DisposeState();
|
DisposeState();
|
||||||
|
|
||||||
if (Atlas && SkeletonData) {
|
if (Atlas && SkeletonData) {
|
||||||
spine::SkeletonData* data = SkeletonData->GetSkeletonData(Atlas->GetAtlas(false), false);
|
spine::SkeletonData* data = SkeletonData->GetSkeletonData(Atlas->GetAtlas());
|
||||||
skeleton = new (__FILE__, __LINE__) spine::Skeleton(data);
|
skeleton = new (__FILE__, __LINE__) spine::Skeleton(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,12 +39,12 @@ class SPINEPLUGIN_API USpineAtlasAsset: public UObject {
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
spine::Atlas* GetAtlas (bool ForceReload = false);
|
spine::Atlas* GetAtlas ();
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||||
TArray<UTexture2D*> atlasPages;
|
TArray<UTexture2D*> atlasPages;
|
||||||
|
|
||||||
FString GetRawData () const;
|
void SetRawData(const FString &RawData);
|
||||||
|
|
||||||
FName GetAtlasFileName () const;
|
FName GetAtlasFileName () const;
|
||||||
|
|
||||||
@ -62,7 +62,6 @@ protected:
|
|||||||
#if WITH_EDITORONLY_DATA
|
#if WITH_EDITORONLY_DATA
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void SetRawData (const FString &RawData);
|
|
||||||
void SetAtlasFileName (const FName &AtlasFileName);
|
void SetAtlasFileName (const FName &AtlasFileName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -54,14 +54,14 @@ class SPINEPLUGIN_API USpineSkeletonDataAsset: public UObject {
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
spine::SkeletonData* GetSkeletonData(spine::Atlas* Atlas, bool ForceReload = false);
|
spine::SkeletonData* GetSkeletonData(spine::Atlas* Atlas);
|
||||||
|
|
||||||
spine::AnimationStateData* GetAnimationStateData(spine::Atlas* atlas);
|
spine::AnimationStateData* GetAnimationStateData(spine::Atlas* atlas);
|
||||||
void SetMix(const FString& from, const FString& to, float mix);
|
void SetMix(const FString& from, const FString& to, float mix);
|
||||||
float GetMix(const FString& from, const FString& to);
|
float GetMix(const FString& from, const FString& to);
|
||||||
|
|
||||||
FName GetSkeletonDataFileName () const;
|
FName GetSkeletonDataFileName () const;
|
||||||
TArray<uint8>& GetRawData ();
|
void SetRawData (TArray<uint8> &Data);
|
||||||
|
|
||||||
virtual void BeginDestroy () override;
|
virtual void BeginDestroy () override;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user