[ue4] Clean up, tabs need fixing

This commit is contained in:
badlogic 2016-12-01 13:52:03 +01:00
parent 6d84a04de9
commit dbc9c9fb5d
15 changed files with 178 additions and 201 deletions

View File

@ -26,7 +26,7 @@ FText USpineAtlasAssetFactory::GetToolTip () const {
return LOCTEXT("SpineAtlasAssetFactory", "Animations exported from Spine"); return LOCTEXT("SpineAtlasAssetFactory", "Animations exported from Spine");
} }
bool USpineAtlasAssetFactory::FactoryCanImport (const FString& filename) { bool USpineAtlasAssetFactory::FactoryCanImport (const FString& Filename) {
return true; return true;
} }
@ -35,75 +35,80 @@ UObject* USpineAtlasAssetFactory::FactoryCreateFile (UClass * InClass, UObject *
if (!FFileHelper::LoadFileToString(rawString, *Filename)) { if (!FFileHelper::LoadFileToString(rawString, *Filename)) {
return nullptr; return nullptr;
} }
FString currentSourcePath, filenameNoExtension, unusedExtension;
const FString longPackagePath = FPackageName::GetLongPackagePath(InParent->GetOutermost()->GetPathName()); const FString longPackagePath = FPackageName::GetLongPackagePath(InParent->GetOutermost()->GetPathName());
FString CurrentSourcePath; FPaths::Split(UFactory::GetCurrentFilename(), currentSourcePath, filenameNoExtension, unusedExtension);
FString FilenameNoExtension;
FString UnusedExtension;
FPaths::Split(UFactory::GetCurrentFilename(), CurrentSourcePath, FilenameNoExtension, UnusedExtension);
FString name(InName.ToString()); FString name(InName.ToString());
name.Append("-atlas"); name.Append("-atlas");
USpineAtlasAsset* asset = NewObject<USpineAtlasAsset>(InParent, InClass, FName(*name), Flags); USpineAtlasAsset* asset = NewObject<USpineAtlasAsset>(InParent, InClass, FName(*name), Flags);
asset->SetRawData(rawString); asset->SetRawData(rawString);
asset->SetAtlasFileName(FName(*Filename)); asset->SetAtlasFileName(FName(*Filename));
LoadAtlas(asset, CurrentSourcePath, longPackagePath); LoadAtlas(asset, currentSourcePath, longPackagePath);
return asset; return asset;
} }
bool USpineAtlasAssetFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames) { bool USpineAtlasAssetFactory::CanReimport (UObject* Obj, TArray<FString>& OutFilenames) {
USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj); USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
if (!asset) return false; if (!asset) return false;
FString filename = asset->GetAtlasFileName().ToString(); FString filename = asset->GetAtlasFileName().ToString();
if (!filename.IsEmpty()) if (!filename.IsEmpty())
OutFilenames.Add(filename); OutFilenames.Add(filename);
return true; return true;
} }
void USpineAtlasAssetFactory::SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) { void USpineAtlasAssetFactory::SetReimportPaths (UObject* Obj, const TArray<FString>& NewReimportPaths) {
USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj); USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
if (asset && ensure(NewReimportPaths.Num() == 1)) if (asset && ensure(NewReimportPaths.Num() == 1))
asset->SetAtlasFileName(FName(*NewReimportPaths[0])); asset->SetAtlasFileName(FName(*NewReimportPaths[0]));
} }
EReimportResult::Type USpineAtlasAssetFactory::Reimport(UObject* Obj) { EReimportResult::Type USpineAtlasAssetFactory::Reimport (UObject* Obj) {
USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj); USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
FString rawString; FString rawString;
if (!FFileHelper::LoadFileToString(rawString, *asset->GetAtlasFileName().ToString())) return EReimportResult::Failed; if (!FFileHelper::LoadFileToString(rawString, *asset->GetAtlasFileName().ToString())) return EReimportResult::Failed;
asset->SetRawData(rawString); asset->SetRawData(rawString);
FString currentSourcePath, filenameNoExtension, unusedExtension;
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName()); const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
FString CurrentSourcePath; FPaths::Split(UFactory::GetCurrentFilename(), currentSourcePath, filenameNoExtension, unusedExtension);
FString FilenameNoExtension;
FString UnusedExtension; LoadAtlas(asset, currentSourcePath, longPackagePath);
FPaths::Split(UFactory::GetCurrentFilename(), CurrentSourcePath, FilenameNoExtension, UnusedExtension);
LoadAtlas(asset, CurrentSourcePath, longPackagePath);
if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty(); if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
else Obj->MarkPackageDirty(); else Obj->MarkPackageDirty();
return EReimportResult::Succeeded; return EReimportResult::Succeeded;
} }
UTexture2D* resolveTexture (USpineAtlasAsset* asset, const FString& pageFileName, const FString& targetSubPath) { UTexture2D* resolveTexture (USpineAtlasAsset* Asset, const FString& PageFileName, const FString& TargetSubPath) {
FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools"); FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
TArray<FString> fileNames; TArray<FString> fileNames;
fileNames.Add(pageFileName); fileNames.Add(PageFileName);
TArray<UObject*> importedAsset = AssetToolsModule.Get().ImportAssets(fileNames, targetSubPath); TArray<UObject*> importedAsset = AssetToolsModule.Get().ImportAssets(fileNames, TargetSubPath);
UTexture2D* texture = (importedAsset.Num() > 0) ? Cast<UTexture2D>(importedAsset[0]) : nullptr; UTexture2D* texture = (importedAsset.Num() > 0) ? Cast<UTexture2D>(importedAsset[0]) : nullptr;
return texture; return texture;
} }
void USpineAtlasAssetFactory::LoadAtlas(USpineAtlasAsset* asset, const FString& currentSourcePath, const FString& longPackagePath) { void USpineAtlasAssetFactory::LoadAtlas (USpineAtlasAsset* Asset, const FString& CurrentSourcePath, const FString& LongPackagePath) {
spAtlas* atlas = asset->GetAtlas(true); spAtlas* atlas = Asset->GetAtlas(true);
asset->atlasPages.Empty(); Asset->atlasPages.Empty();
const FString targetTexturePath = longPackagePath / TEXT("Textures"); const FString targetTexturePath = LongPackagePath / TEXT("Textures");
spAtlasPage* page = atlas->pages; spAtlasPage* page = atlas->pages;
while (page) { while (page) {
const FString sourceTextureFilename = FPaths::Combine(*currentSourcePath, UTF8_TO_TCHAR(page->name)); const FString sourceTextureFilename = FPaths::Combine(*CurrentSourcePath, UTF8_TO_TCHAR(page->name));
UTexture2D* texture = resolveTexture(asset, sourceTextureFilename, targetTexturePath); UTexture2D* texture = resolveTexture(Asset, sourceTextureFilename, targetTexturePath);
page = page->next; page = page->next;
asset->atlasPages.Add(texture); Asset->atlasPages.Add(texture);
} }
} }

View File

@ -4,28 +4,18 @@
#include "spine/spine.h" #include "spine/spine.h"
class FSpineEditorPlugin : public ISpineEditorPlugin class FSpineEditorPlugin: public ISpineEditorPlugin {
{
/** IModuleInterface implementation */
virtual void StartupModule() override; virtual void StartupModule() override;
virtual void ShutdownModule() override; virtual void ShutdownModule() override;
}; };
IMPLEMENT_MODULE( FSpineEditorPlugin, ISpineEditorPlugin ) IMPLEMENT_MODULE(FSpineEditorPlugin, ISpineEditorPlugin)
void FSpineEditorPlugin::StartupModule() void FSpineEditorPlugin::StartupModule () { }
{
// This code will execute after your module is loaded into memory (but after global variables are initialized, of course.)
}
void FSpineEditorPlugin::ShutdownModule () { }
void FSpineEditorPlugin::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}

View File

@ -27,57 +27,65 @@ FText USpineSkeletonAssetFactory::GetToolTip () const {
return LOCTEXT("USpineSkeletonAssetFactory", "Animations exported from Spine"); return LOCTEXT("USpineSkeletonAssetFactory", "Animations exported from Spine");
} }
bool USpineSkeletonAssetFactory::FactoryCanImport (const FString& filename) { bool USpineSkeletonAssetFactory::FactoryCanImport (const FString& Filename) {
return true; return true;
} }
void LoadAtlas (const FString& filename, const FString& targetPath) { void LoadAtlas (const FString& Filename, const FString& TargetPath) {
FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools"); FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
FString skelFile = filename.Replace(TEXT(".skel"), TEXT(".atlas")).Replace(TEXT(".json"), TEXT(".atlas")); FString skelFile = Filename.Replace(TEXT(".skel"), TEXT(".atlas")).Replace(TEXT(".json"), TEXT(".atlas"));
if (!FPaths::FileExists(skelFile)) return; if (!FPaths::FileExists(skelFile)) return;
TArray<FString> fileNames; TArray<FString> fileNames;
fileNames.Add(skelFile); fileNames.Add(skelFile);
TArray<UObject*> importedAssets = AssetToolsModule.Get().ImportAssets(fileNames, targetPath); AssetToolsModule.Get().ImportAssets(fileNames, TargetPath);
} }
UObject* USpineSkeletonAssetFactory::FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) { UObject* USpineSkeletonAssetFactory::FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) {
FString name(InName.ToString()); FString name(InName.ToString());
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)) { if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *Filename, 0)) {
return nullptr; return nullptr;
} }
asset->SetSkeletonDataFileName(FName(*Filename)); asset->SetSkeletonDataFileName(FName(*Filename));
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName()); const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
LoadAtlas(Filename, longPackagePath); LoadAtlas(Filename, longPackagePath);
return asset; return asset;
} }
bool USpineSkeletonAssetFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames) { bool USpineSkeletonAssetFactory::CanReimport (UObject* Obj, TArray<FString>& OutFilenames) {
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj); USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
if (!asset) return false; if (!asset) return false;
FString filename = asset->GetSkeletonDataFileName().ToString(); FString filename = asset->GetSkeletonDataFileName().ToString();
if (!filename.IsEmpty()) if (!filename.IsEmpty())
OutFilenames.Add(filename); OutFilenames.Add(filename);
return true; return true;
} }
void USpineSkeletonAssetFactory::SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) { void USpineSkeletonAssetFactory::SetReimportPaths (UObject* Obj, const TArray<FString>& NewReimportPaths) {
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj); USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
if (asset && ensure(NewReimportPaths.Num() == 1)) if (asset && ensure(NewReimportPaths.Num() == 1))
asset->SetSkeletonDataFileName(FName(*NewReimportPaths[0])); asset->SetSkeletonDataFileName(FName(*NewReimportPaths[0]));
} }
EReimportResult::Type USpineSkeletonAssetFactory::Reimport(UObject* Obj) { EReimportResult::Type USpineSkeletonAssetFactory::Reimport (UObject* Obj) {
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj); USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
FString rawString;
if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *asset->GetSkeletonDataFileName().ToString(), 0)) return EReimportResult::Failed; if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *asset->GetSkeletonDataFileName().ToString(), 0)) return EReimportResult::Failed;
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);
if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty(); if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
else Obj->MarkPackageDirty(); else Obj->MarkPackageDirty();
return EReimportResult::Succeeded; return EReimportResult::Succeeded;
} }
#undef LOCTEXT_NAMESPACE #undef LOCTEXT_NAMESPACE

View File

@ -6,11 +6,11 @@
#include "SpineAtlasImportFactory.generated.h" #include "SpineAtlasImportFactory.generated.h"
UCLASS() UCLASS()
class USpineAtlasAssetFactory : public UFactory, public FReimportHandler class USpineAtlasAssetFactory: public UFactory, public FReimportHandler {
{
GENERATED_UCLASS_BODY() GENERATED_UCLASS_BODY()
virtual FText GetToolTip() const override; virtual FText GetToolTip() const override;
virtual bool FactoryCanImport(const FString& Filename) override; virtual bool FactoryCanImport(const FString& Filename) override;
virtual UObject* FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) override; virtual UObject* FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) override;
@ -18,5 +18,5 @@ class USpineAtlasAssetFactory : public UFactory, public FReimportHandler
virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override; virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override;
virtual EReimportResult::Type Reimport(UObject* Obj) override; virtual EReimportResult::Type Reimport(UObject* Obj) override;
void LoadAtlas(USpineAtlasAsset* asset, const FString& currentSourcePath, const FString& longPackagePath); void LoadAtlas(USpineAtlasAsset* Asset, const FString& CurrentSourcePath, const FString& LongPackagePath);
}; };

View File

@ -6,15 +6,14 @@
#include "SpineSkeletonImportFactory.generated.h" #include "SpineSkeletonImportFactory.generated.h"
UCLASS() UCLASS()
class USpineSkeletonAssetFactory : public UFactory, public FReimportHandler class USpineSkeletonAssetFactory : public UFactory, public FReimportHandler {
{
GENERATED_UCLASS_BODY() GENERATED_UCLASS_BODY()
virtual FText GetToolTip() const override; virtual FText GetToolTip () const override;
virtual bool FactoryCanImport(const FString& Filename) override; virtual bool FactoryCanImport (const FString& Filename) override;
virtual UObject* FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) override; virtual UObject* FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) override;
virtual bool CanReimport(UObject* Obj, TArray<FString>& OutFilenames) override; virtual bool CanReimport (UObject* Obj, TArray<FString>& OutFilenames) override;
virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override; virtual void SetReimportPaths (UObject* Obj, const TArray<FString>& NewReimportPaths) override;
virtual EReimportResult::Type Reimport(UObject* Obj) override; virtual EReimportResult::Type Reimport (UObject* Obj) override;
}; };

View File

@ -4,6 +4,8 @@
#include <string> #include <string>
#include <stdlib.h> #include <stdlib.h>
#define LOCTEXT_NAMESPACE "Spine"
FString USpineAtlasAsset::GetRawData () const { FString USpineAtlasAsset::GetRawData () const {
return rawData; return rawData;
} }
@ -21,12 +23,12 @@ FName USpineAtlasAsset::GetAtlasFileName () const {
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
void USpineAtlasAsset::SetRawData (const FString &_rawData) { void USpineAtlasAsset::SetRawData (const FString &RawData) {
this->rawData = _rawData; this->rawData = RawData;
} }
void USpineAtlasAsset::SetAtlasFileName (const FName &_atlasFileName) { void USpineAtlasAsset::SetAtlasFileName (const FName &AtlasFileName) {
importData->UpdateFilenameOnly(_atlasFileName.ToString()); importData->UpdateFilenameOnly(AtlasFileName.ToString());
TArray<FString> files; TArray<FString> files;
importData->ExtractFilenames(files); importData->ExtractFilenames(files);
if (files.Num() > 0) atlasFileName = FName(*files[0]); if (files.Num() > 0) atlasFileName = FName(*files[0]);
@ -59,8 +61,8 @@ void USpineAtlasAsset::BeginDestroy () {
Super::BeginDestroy(); Super::BeginDestroy();
} }
spAtlas* USpineAtlasAsset::GetAtlas (bool forceReload) { spAtlas* USpineAtlasAsset::GetAtlas (bool ForceReload) {
if (!atlas || forceReload) { if (!atlas || ForceReload) {
if (atlas) { if (atlas) {
spAtlas_dispose(atlas); spAtlas_dispose(atlas);
atlas = nullptr; atlas = nullptr;
@ -74,9 +76,11 @@ spAtlas* USpineAtlasAsset::GetAtlas (bool forceReload) {
if (atlasPages.Num() > 0 && atlasPages.Num() > i) if (atlasPages.Num() > 0 && atlasPages.Num() > i)
page->rendererObject = atlasPages[i++]; page->rendererObject = atlasPages[i++];
page = page->next; page = page->next;
} }
} }
return this->atlas; return this->atlas;
} }
#endif #endif
#undef LOCTEXT_NAMESPACE

View File

@ -1,41 +1,24 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "SpinePluginPrivatePCH.h" #include "SpinePluginPrivatePCH.h"
#include "spine/spine.h"
class FSpinePlugin : public SpinePlugin { class FSpinePlugin : public SpinePlugin {
/** IModuleInterface implementation */
virtual void StartupModule() override; virtual void StartupModule() override;
virtual void ShutdownModule() override; virtual void ShutdownModule() override;
}; };
IMPLEMENT_MODULE( FSpinePlugin, SpinePlugin ) IMPLEMENT_MODULE( FSpinePlugin, SpinePlugin )
void FSpinePlugin::StartupModule() { }
void FSpinePlugin::StartupModule() { void FSpinePlugin::ShutdownModule() { }
// This code will execute after your module is loaded into memory (but after global variables are initialized, of course.)
printf("This is a test");
}
void FSpinePlugin::ShutdownModule() {
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
// These are not used in the Spine UE4 plugin, see SpineAtlasAsset on how atlas page textures
// are loaded, See SpineSkeletonRendererComponent on how these textures are used for rendering.
extern "C" { extern "C" {
void _spAtlasPage_createTexture (spAtlasPage* self, const char* path) { void _spAtlasPage_createTexture (spAtlasPage* self, const char* path) { }
void _spAtlasPage_disposeTexture (spAtlasPage* self) { }
} char* _spUtil_readFile (const char* path, int* length) { return 0; }
void _spAtlasPage_disposeTexture (spAtlasPage* self) {
}
char* _spUtil_readFile (const char* path, int* length) {
return 0;
}
} }

View File

@ -1,12 +1,8 @@
// iFll out your copyright notice in the Description page of Project Settings.
#include "SpinePluginPrivatePCH.h" #include "SpinePluginPrivatePCH.h"
// Sets default values for this component's properties #define LOCTEXT_NAMESPACE "Spine"
USpineSkeletonComponent::USpineSkeletonComponent()
{ USpineSkeletonComponent::USpineSkeletonComponent () {
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
bWantsBeginPlay = true; bWantsBeginPlay = true;
PrimaryComponentTick.bCanEverTick = true; PrimaryComponentTick.bCanEverTick = true;
bTickInEditor = true; bTickInEditor = true;
@ -17,8 +13,8 @@ void USpineSkeletonComponent::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
} }
void USpineSkeletonComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) { void USpineSkeletonComponent::TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
Super::TickComponent( DeltaTime, TickType, ThisTickFunction ); Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (lastAtlas != atlas || lastData != skeletonData) { if (lastAtlas != atlas || lastData != skeletonData) {
DisposeState(); DisposeState();
@ -28,7 +24,6 @@ void USpineSkeletonComponent::TickComponent( float DeltaTime, ELevelTick TickTyp
skeleton = spSkeleton_create(data); skeleton = spSkeleton_create(data);
stateData = spAnimationStateData_create(data); stateData = spAnimationStateData_create(data);
state = spAnimationState_create(stateData); state = spAnimationState_create(stateData);
spAnimationState_setAnimationByName(state, 0, "walk", true);
} }
lastAtlas = atlas; lastAtlas = atlas;
@ -38,11 +33,11 @@ void USpineSkeletonComponent::TickComponent( float DeltaTime, ELevelTick TickTyp
if (state) { if (state) {
spAnimationState_update(state, DeltaTime); spAnimationState_update(state, DeltaTime);
spAnimationState_apply(state, skeleton); spAnimationState_apply(state, skeleton);
spSkeleton_updateWorldTransform(skeleton); spSkeleton_updateWorldTransform(skeleton);
} }
} }
void USpineSkeletonComponent::DisposeState() { void USpineSkeletonComponent::DisposeState () {
if (stateData) { if (stateData) {
spAnimationStateData_dispose(stateData); spAnimationStateData_dispose(stateData);
stateData = nullptr; stateData = nullptr;
@ -59,7 +54,9 @@ void USpineSkeletonComponent::DisposeState() {
} }
} }
void USpineSkeletonComponent::FinishDestroy() { void USpineSkeletonComponent::FinishDestroy () {
DisposeState(); DisposeState();
Super::FinishDestroy(); Super::FinishDestroy();
} }
#undef LOCTEXT_NAMESPACE

View File

@ -4,6 +4,8 @@
#include <string> #include <string>
#include <stdlib.h> #include <stdlib.h>
#define LOCTEXT_NAMESPACE "Spine"
FName USpineSkeletonDataAsset::GetSkeletonDataFileName () const { FName USpineSkeletonDataAsset::GetSkeletonDataFileName () const {
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
TArray<FString> files; TArray<FString> files;
@ -21,8 +23,8 @@ TArray<uint8>& USpineSkeletonDataAsset::GetRawData () {
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
void USpineSkeletonDataAsset::SetSkeletonDataFileName (const FName &_skeletonDataFileName) { void USpineSkeletonDataAsset::SetSkeletonDataFileName (const FName &SkeletonDataFileName) {
importData->UpdateFilenameOnly(_skeletonDataFileName.ToString()); importData->UpdateFilenameOnly(SkeletonDataFileName.ToString());
TArray<FString> files; TArray<FString> files;
importData->ExtractFilenames(files); importData->ExtractFilenames(files);
if (files.Num() > 0) this->skeletonDataFileName = FName(*files[0]); if (files.Num() > 0) this->skeletonDataFileName = FName(*files[0]);
@ -55,25 +57,27 @@ void USpineSkeletonDataAsset::BeginDestroy () {
Super::BeginDestroy(); Super::BeginDestroy();
} }
spSkeletonData* USpineSkeletonDataAsset::GetSkeletonData (spAtlas* atlas, bool forceReload) { spSkeletonData* USpineSkeletonDataAsset::GetSkeletonData (spAtlas* Atlas, bool ForceReload) {
if (!skeletonData || forceReload) { if (!skeletonData || ForceReload) {
if (skeletonData) { if (skeletonData) {
spSkeletonData_dispose(skeletonData); spSkeletonData_dispose(skeletonData);
skeletonData = nullptr; skeletonData = nullptr;
} }
int dataLen = rawData.Num(); int dataLen = rawData.Num();
if (skeletonDataFileName.GetPlainNameString().Contains(TEXT(".json"))) { if (skeletonDataFileName.GetPlainNameString().Contains(TEXT(".json"))) {
spSkeletonJson* json = spSkeletonJson_create(atlas); spSkeletonJson* json = spSkeletonJson_create(Atlas);
this->skeletonData = spSkeletonJson_readSkeletonData(json, (const char*)rawData.GetData()); this->skeletonData = spSkeletonJson_readSkeletonData(json, (const char*)rawData.GetData());
spSkeletonJson_dispose(json); spSkeletonJson_dispose(json);
} else { } else {
spSkeletonBinary* binary = spSkeletonBinary_create(atlas); spSkeletonBinary* binary = spSkeletonBinary_create(Atlas);
this->skeletonData = spSkeletonBinary_readSkeletonData(binary, (const unsigned char*)rawData.GetData(), (int)rawData.Num()); this->skeletonData = spSkeletonBinary_readSkeletonData(binary, (const unsigned char*)rawData.GetData(), (int)rawData.Num());
spSkeletonBinary_dispose(binary); spSkeletonBinary_dispose(binary);
} }
lastAtlas = atlas; lastAtlas = Atlas;
} }
return this->skeletonData; return this->skeletonData;
} }
#endif #endif
#undef LOCTEXT_NAMESPACE

View File

@ -3,10 +3,9 @@
#include "spine/spine.h" #include "spine/spine.h"
#include <stdlib.h> #include <stdlib.h>
USpineSkeletonRendererComponent::USpineSkeletonRendererComponent(const FObjectInitializer& ObjectInitializer) #define LOCTEXT_NAMESPACE "Spine"
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features USpineSkeletonRendererComponent::USpineSkeletonRendererComponent (const FObjectInitializer& ObjectInitializer) {
// off to improve performance if you don't need them.
bWantsBeginPlay = true; bWantsBeginPlay = true;
PrimaryComponentTick.bCanEverTick = true; PrimaryComponentTick.bCanEverTick = true;
bTickInEditor = true; bTickInEditor = true;
@ -14,18 +13,16 @@ USpineSkeletonRendererComponent::USpineSkeletonRendererComponent(const FObjectIn
static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaskedMaterialRef(TEXT("/Paper2D/MaskedUnlitSpriteMaterial")); static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaskedMaterialRef(TEXT("/Paper2D/MaskedUnlitSpriteMaterial"));
DefaultMaterial = MaskedMaterialRef.Object; DefaultMaterial = MaskedMaterialRef.Object;
TextureParameterName = FName(TEXT("SpriteTexture"));
} }
// Called when the game starts void USpineSkeletonRendererComponent::BeginPlay () {
void USpineSkeletonRendererComponent::BeginPlay()
{
Super::BeginPlay(); Super::BeginPlay();
} }
// Called every frame void USpineSkeletonRendererComponent::TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
void USpineSkeletonRendererComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
{
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
UClass* skeletonClass = USpineSkeletonComponent::StaticClass(); UClass* skeletonClass = USpineSkeletonComponent::StaticClass();
AActor* owner = GetOwner(); AActor* owner = GetOwner();
@ -38,7 +35,7 @@ void USpineSkeletonRendererComponent::TickComponent( float DeltaTime, ELevelTick
spAtlasPage* currPage = skeleton->atlas->GetAtlas(false)->pages; spAtlasPage* currPage = skeleton->atlas->GetAtlas(false)->pages;
for (int i = 0; i < skeleton->atlas->atlasPages.Num(); i++) { for (int i = 0; i < skeleton->atlas->atlasPages.Num(); i++) {
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(DefaultMaterial, owner); UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(DefaultMaterial, owner);
material->SetTextureParameterValue(FName(TEXT("SpriteTexture")), skeleton->atlas->atlasPages[i]); material->SetTextureParameterValue(TextureParameterName, skeleton->atlas->atlasPages[i]);
atlasMaterials.Add(material); atlasMaterials.Add(material);
pageToMaterial.Add(currPage, material); pageToMaterial.Add(currPage, material);
currPage = currPage->next; currPage = currPage->next;
@ -50,34 +47,34 @@ void USpineSkeletonRendererComponent::TickComponent( float DeltaTime, ELevelTick
for (int i = 0; i < skeleton->atlas->atlasPages.Num(); i++) { for (int i = 0; i < skeleton->atlas->atlasPages.Num(); i++) {
UMaterialInstanceDynamic* current = atlasMaterials[i]; UMaterialInstanceDynamic* current = atlasMaterials[i];
UTexture2D* texture = skeleton->atlas->atlasPages[i]; UTexture2D* texture = skeleton->atlas->atlasPages[i];
UTexture* oldTexture = nullptr; UTexture* oldTexture = nullptr;
if(!current->GetTextureParameterValue(FName(TEXT("SpriteTexture")), oldTexture) || oldTexture != texture) { if(!current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(DefaultMaterial, owner); UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(DefaultMaterial, owner);
material->SetTextureParameterValue("SpriteTexture", texture); material->SetTextureParameterValue(TextureParameterName, texture);
atlasMaterials[i] = material; atlasMaterials[i] = material;
} }
pageToMaterial.Add(currPage, atlasMaterials[i]); pageToMaterial.Add(currPage, atlasMaterials[i]);
currPage = currPage->next; currPage = currPage->next;
} }
} }
spSkeleton_updateWorldTransform(skeleton->skeleton); spSkeleton_updateWorldTransform(skeleton->skeleton);
UpdateMesh(skeleton->skeleton); UpdateMesh(skeleton->skeleton);
} }
} }
} }
void USpineSkeletonRendererComponent::Flush(int &idx, TArray<FVector> &vertices, TArray<int32> &indices, TArray<FVector2D> &uvs, TArray<FColor> &colors, UMaterialInstanceDynamic* material) { void USpineSkeletonRendererComponent::Flush (int &Idx, TArray<FVector> &Vertices, TArray<int32> &Indices, TArray<FVector2D> &Uvs, TArray<FColor> &Colors, UMaterialInstanceDynamic* Material) {
if (vertices.Num() == 0) return; if (Vertices.Num() == 0) return;
CreateMeshSection(idx, vertices, indices, TArray<FVector>(), uvs, colors, TArray<FProcMeshTangent>(), false); CreateMeshSection(Idx, Vertices, Indices, TArray<FVector>(), Uvs, Colors, TArray<FProcMeshTangent>(), false);
SetMaterial(idx, material); SetMaterial(Idx, Material);
vertices.SetNum(0); Vertices.SetNum(0);
indices.SetNum(0); Indices.SetNum(0);
uvs.SetNum(0); Uvs.SetNum(0);
colors.SetNum(0); Colors.SetNum(0);
idx++; Idx++;
} }
void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) { void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* Skeleton) {
TArray<FVector> vertices; TArray<FVector> vertices;
TArray<int32> indices; TArray<int32> indices;
TArray<FVector2D> uvs; TArray<FVector2D> uvs;
@ -93,8 +90,8 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
float depthOffset = 0; float depthOffset = 0;
for (int i = 0; i < skeleton->slotsCount; ++i) { for (int i = 0; i < Skeleton->slotsCount; ++i) {
spSlot* slot = skeleton->drawOrder[i]; spSlot* slot = Skeleton->drawOrder[i];
spAttachment* attachment = slot->attachment; spAttachment* attachment = slot->attachment;
if (!attachment) continue; if (!attachment) continue;
@ -110,10 +107,10 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, worldVertices.GetData()); spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, worldVertices.GetData());
uint8 r = static_cast<uint8>(skeleton->r * slot->r * 255); uint8 r = static_cast<uint8>(Skeleton->r * slot->r * 255);
uint8 g = static_cast<uint8>(skeleton->g * slot->g * 255); uint8 g = static_cast<uint8>(Skeleton->g * slot->g * 255);
uint8 b = static_cast<uint8>(skeleton->b * slot->b * 255); uint8 b = static_cast<uint8>(Skeleton->b * slot->b * 255);
uint8 a = static_cast<uint8>(skeleton->a * slot->a * 255); uint8 a = static_cast<uint8>(Skeleton->a * slot->a * 255);
colors.Add(FColor(r, g, b, a)); colors.Add(FColor(r, g, b, a));
vertices.Add(FVector(worldVertices[0], depthOffset, worldVertices[1])); vertices.Add(FVector(worldVertices[0], depthOffset, worldVertices[1]));
@ -156,10 +153,10 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
} }
spMeshAttachment_computeWorldVertices(mesh, slot, worldVertices.GetData()); spMeshAttachment_computeWorldVertices(mesh, slot, worldVertices.GetData());
uint8 r = static_cast<uint8>(skeleton->r * slot->r * 255); uint8 r = static_cast<uint8>(Skeleton->r * slot->r * 255);
uint8 g = static_cast<uint8>(skeleton->g * slot->g * 255); uint8 g = static_cast<uint8>(Skeleton->g * slot->g * 255);
uint8 b = static_cast<uint8>(skeleton->b * slot->b * 255); uint8 b = static_cast<uint8>(Skeleton->b * slot->b * 255);
uint8 a = static_cast<uint8>(skeleton->a * slot->a * 255); uint8 a = static_cast<uint8>(Skeleton->a * slot->a * 255);
for (int i = 0; i < mesh->super.worldVerticesLength; i += 2) { for (int i = 0; i < mesh->super.worldVerticesLength; i += 2) {
colors.Add(FColor(r, g, b, a)); colors.Add(FColor(r, g, b, a));
@ -177,4 +174,6 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
} }
Flush(meshSection, vertices, indices, uvs, colors, lastMaterial); Flush(meshSection, vertices, indices, uvs, colors, lastMaterial);
} }
#undef LOCTEXT_NAMESPACE

View File

@ -4,17 +4,18 @@
#include "spine/spine.h" #include "spine/spine.h"
#include "SpineAtlasAsset.generated.h" #include "SpineAtlasAsset.generated.h"
UCLASS( ClassGroup=(Spine) ) UCLASS(ClassGroup=(Spine))
class SPINEPLUGIN_API USpineAtlasAsset : public UObject { class SPINEPLUGIN_API USpineAtlasAsset: public UObject {
GENERATED_BODY() GENERATED_BODY()
public: public:
spAtlas* GetAtlas (bool forceReload = false); spAtlas* GetAtlas (bool ForceReload = false);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
TArray<UTexture2D*> atlasPages; TArray<UTexture2D*> atlasPages;
FString GetRawData () const; FString GetRawData () const;
FName GetAtlasFileName () const; FName GetAtlasFileName () const;
virtual void BeginDestroy () override; virtual void BeginDestroy () override;
@ -31,8 +32,8 @@ protected:
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
public: public:
void SetRawData (const FString &rawData); void SetRawData (const FString &RawData);
void SetAtlasFileName (const FName &atlasFileName); void SetAtlasFileName (const FName &AtlasFileName);
protected: protected:
UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings) UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings)

View File

@ -1,37 +1,16 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#pragma once #pragma once
#include "ModuleManager.h" #include "ModuleManager.h"
class SPINEPLUGIN_API SpinePlugin : public IModuleInterface {
/**
* The public interface to this module. In most cases, this interface is only public to sibling modules
* within this plugin.
*/
class SPINEPLUGIN_API SpinePlugin : public IModuleInterface
{
public: public:
/** static inline SpinePlugin& Get() {
* Singleton-like access to this module's interface. This is just for convenience!
* Beware of calling this during the shutdown phase, though. Your module might have been unloaded already.
*
* @return Returns singleton instance, loading the module on demand if needed
*/
static inline SpinePlugin& Get()
{
return FModuleManager::LoadModuleChecked< SpinePlugin >( "SpinePlugin" ); return FModuleManager::LoadModuleChecked< SpinePlugin >( "SpinePlugin" );
} }
/** static inline bool IsAvailable() {
* Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true.
*
* @return True if the module is loaded and ready to use
*/
static inline bool IsAvailable()
{
return FModuleManager::Get().IsModuleLoaded( "SpinePlugin" ); return FModuleManager::Get().IsModuleLoaded( "SpinePlugin" );
} }
}; };

View File

@ -13,26 +13,31 @@ class SPINEPLUGIN_API USpineSkeletonComponent : public UActorComponent
public: public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
USpineAtlasAsset* atlas; USpineAtlasAsset* Atlas;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
USpineSkeletonDataAsset* skeletonData; USpineSkeletonDataAsset* SkeletonData;
spAnimationStateData* stateData; spAnimationStateData* GetAnimationStateData () { return stateData; };
spAnimationState* state;
spSkeleton* skeleton; spAnimationState* GetAnimationState () { return state; };
spSkeleton* GetSkeleton () { return skeleton; };
USpineSkeletonComponent(); USpineSkeletonComponent ();
virtual void BeginPlay() override; virtual void BeginPlay () override;
virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override; virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
virtual void FinishDestroy () override; virtual void FinishDestroy () override;
protected: protected:
void DisposeState(); void DisposeState();
spAnimationStateData* stateData;
spAnimationState* state;
spSkeleton* skeleton;
USpineAtlasAsset* lastAtlas = nullptr; USpineAtlasAsset* lastAtlas = nullptr;
USpineSkeletonDataAsset* lastData = nullptr; USpineSkeletonDataAsset* lastData = nullptr;
}; };

View File

@ -4,12 +4,12 @@
#include "spine/spine.h" #include "spine/spine.h"
#include "SpineSkeletonDataAsset.generated.h" #include "SpineSkeletonDataAsset.generated.h"
UCLASS( ClassGroup=(Spine) ) UCLASS(ClassGroup=(Spine))
class SPINEPLUGIN_API USpineSkeletonDataAsset : public UObject { class SPINEPLUGIN_API USpineSkeletonDataAsset: public UObject {
GENERATED_BODY() GENERATED_BODY()
public: public:
spSkeletonData* GetSkeletonData(spAtlas* atlas, bool forceReload = false); spSkeletonData* GetSkeletonData(spAtlas* Atlas, bool ForceReload = false);
FName GetSkeletonDataFileName () const; FName GetSkeletonDataFileName () const;
TArray<uint8>& GetRawData (); TArray<uint8>& GetRawData ();

View File

@ -8,9 +8,8 @@
#include "SpineSkeletonRendererComponent.generated.h" #include "SpineSkeletonRendererComponent.generated.h"
UCLASS( ClassGroup=(Spine), meta=(BlueprintSpawnableComponent) ) UCLASS(ClassGroup=(Spine), meta=(BlueprintSpawnableComponent))
class SPINEPLUGIN_API USpineSkeletonRendererComponent : public UProceduralMeshComponent class SPINEPLUGIN_API USpineSkeletonRendererComponent: public UProceduralMeshComponent {
{
GENERATED_BODY() GENERATED_BODY()
public: public:
@ -24,11 +23,15 @@ public:
UMaterialInterface* DefaultMaterial; UMaterialInterface* DefaultMaterial;
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite) UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
float depthOffset = 0.1f; float DepthOffset = 0.1f;
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
FName TextureParameterName;
protected: protected:
void UpdateMesh (spSkeleton* skeleton); void UpdateMesh (spSkeleton* Skeleton);
void Flush(int &idx, TArray<FVector> &vertices, TArray<int32> &indices, TArray<FVector2D> &uvs, TArray<FColor> &colors, UMaterialInstanceDynamic* material); void Flush (int &Idx, TArray<FVector> &Vertices, TArray<int32> &Indices, TArray<FVector2D> &Uvs, TArray<FColor> &Colors, UMaterialInstanceDynamic* Material);
TArray<UMaterialInstanceDynamic*> atlasMaterials; TArray<UMaterialInstanceDynamic*> atlasMaterials;
TMap<spAtlasPage*, UMaterialInstanceDynamic*> pageToMaterial; TMap<spAtlasPage*, UMaterialInstanceDynamic*> pageToMaterial;