[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");
}
bool USpineAtlasAssetFactory::FactoryCanImport (const FString& filename) {
bool USpineAtlasAssetFactory::FactoryCanImport (const FString& Filename) {
return true;
}
@ -35,75 +35,80 @@ UObject* USpineAtlasAssetFactory::FactoryCreateFile (UClass * InClass, UObject *
if (!FFileHelper::LoadFileToString(rawString, *Filename)) {
return nullptr;
}
FString currentSourcePath, filenameNoExtension, unusedExtension;
const FString longPackagePath = FPackageName::GetLongPackagePath(InParent->GetOutermost()->GetPathName());
FString CurrentSourcePath;
FString FilenameNoExtension;
FString UnusedExtension;
FPaths::Split(UFactory::GetCurrentFilename(), CurrentSourcePath, FilenameNoExtension, UnusedExtension);
FPaths::Split(UFactory::GetCurrentFilename(), currentSourcePath, filenameNoExtension, unusedExtension);
FString name(InName.ToString());
name.Append("-atlas");
USpineAtlasAsset* asset = NewObject<USpineAtlasAsset>(InParent, InClass, FName(*name), Flags);
asset->SetRawData(rawString);
asset->SetAtlasFileName(FName(*Filename));
LoadAtlas(asset, CurrentSourcePath, longPackagePath);
LoadAtlas(asset, currentSourcePath, longPackagePath);
return asset;
}
bool USpineAtlasAssetFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames) {
bool USpineAtlasAssetFactory::CanReimport (UObject* Obj, TArray<FString>& OutFilenames) {
USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
if (!asset) return false;
FString filename = asset->GetAtlasFileName().ToString();
if (!filename.IsEmpty())
OutFilenames.Add(filename);
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);
if (asset && ensure(NewReimportPaths.Num() == 1))
asset->SetAtlasFileName(FName(*NewReimportPaths[0]));
}
EReimportResult::Type USpineAtlasAssetFactory::Reimport(UObject* Obj) {
EReimportResult::Type USpineAtlasAssetFactory::Reimport (UObject* Obj) {
USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
FString rawString;
if (!FFileHelper::LoadFileToString(rawString, *asset->GetAtlasFileName().ToString())) return EReimportResult::Failed;
asset->SetRawData(rawString);
FString currentSourcePath, filenameNoExtension, unusedExtension;
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
FString CurrentSourcePath;
FString FilenameNoExtension;
FString UnusedExtension;
FPaths::Split(UFactory::GetCurrentFilename(), CurrentSourcePath, FilenameNoExtension, UnusedExtension);
LoadAtlas(asset, CurrentSourcePath, longPackagePath);
FPaths::Split(UFactory::GetCurrentFilename(), currentSourcePath, filenameNoExtension, unusedExtension);
LoadAtlas(asset, currentSourcePath, longPackagePath);
if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
else Obj->MarkPackageDirty();
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");
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;
return texture;
}
void USpineAtlasAssetFactory::LoadAtlas(USpineAtlasAsset* asset, const FString& currentSourcePath, const FString& longPackagePath) {
spAtlas* atlas = asset->GetAtlas(true);
asset->atlasPages.Empty();
void USpineAtlasAssetFactory::LoadAtlas (USpineAtlasAsset* Asset, const FString& CurrentSourcePath, const FString& LongPackagePath) {
spAtlas* atlas = Asset->GetAtlas(true);
Asset->atlasPages.Empty();
const FString targetTexturePath = longPackagePath / TEXT("Textures");
const FString targetTexturePath = LongPackagePath / TEXT("Textures");
spAtlasPage* page = atlas->pages;
while (page) {
const FString sourceTextureFilename = FPaths::Combine(*currentSourcePath, UTF8_TO_TCHAR(page->name));
UTexture2D* texture = resolveTexture(asset, sourceTextureFilename, targetTexturePath);
const FString sourceTextureFilename = FPaths::Combine(*CurrentSourcePath, UTF8_TO_TCHAR(page->name));
UTexture2D* texture = resolveTexture(Asset, sourceTextureFilename, targetTexturePath);
page = page->next;
asset->atlasPages.Add(texture);
Asset->atlasPages.Add(texture);
}
}

View File

@ -4,28 +4,18 @@
#include "spine/spine.h"
class FSpineEditorPlugin : public ISpineEditorPlugin
{
/** IModuleInterface implementation */
class FSpineEditorPlugin: public ISpineEditorPlugin {
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
IMPLEMENT_MODULE( FSpineEditorPlugin, ISpineEditorPlugin )
IMPLEMENT_MODULE(FSpineEditorPlugin, ISpineEditorPlugin)
void FSpineEditorPlugin::StartupModule()
{
// This code will execute after your module is loaded into memory (but after global variables are initialized, of course.)
}
void FSpineEditorPlugin::StartupModule () { }
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.
}
void FSpineEditorPlugin::ShutdownModule () { }

View File

@ -27,57 +27,65 @@ FText USpineSkeletonAssetFactory::GetToolTip () const {
return LOCTEXT("USpineSkeletonAssetFactory", "Animations exported from Spine");
}
bool USpineSkeletonAssetFactory::FactoryCanImport (const FString& filename) {
bool USpineSkeletonAssetFactory::FactoryCanImport (const FString& Filename) {
return true;
}
void LoadAtlas (const FString& filename, const FString& targetPath) {
void LoadAtlas (const FString& Filename, const FString& TargetPath) {
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;
TArray<FString> fileNames;
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) {
FString name(InName.ToString());
name.Append("-data");
USpineSkeletonDataAsset* asset = NewObject<USpineSkeletonDataAsset>(InParent, InClass, FName(*name), Flags);
if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *Filename, 0)) {
return nullptr;
}
asset->SetSkeletonDataFileName(FName(*Filename));
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
LoadAtlas(Filename, longPackagePath);
return asset;
}
bool USpineSkeletonAssetFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames) {
bool USpineSkeletonAssetFactory::CanReimport (UObject* Obj, TArray<FString>& OutFilenames) {
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
if (!asset) return false;
FString filename = asset->GetSkeletonDataFileName().ToString();
if (!filename.IsEmpty())
OutFilenames.Add(filename);
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);
if (asset && ensure(NewReimportPaths.Num() == 1))
asset->SetSkeletonDataFileName(FName(*NewReimportPaths[0]));
}
EReimportResult::Type USpineSkeletonAssetFactory::Reimport(UObject* Obj) {
EReimportResult::Type USpineSkeletonAssetFactory::Reimport (UObject* Obj) {
USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
FString rawString;
if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *asset->GetSkeletonDataFileName().ToString(), 0)) return EReimportResult::Failed;
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
LoadAtlas(*asset->GetSkeletonDataFileName().ToString(), longPackagePath);
if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
else Obj->MarkPackageDirty();
return EReimportResult::Succeeded;
}
#undef LOCTEXT_NAMESPACE

View File

@ -6,11 +6,11 @@
#include "SpineAtlasImportFactory.generated.h"
UCLASS()
class USpineAtlasAssetFactory : public UFactory, public FReimportHandler
{
class USpineAtlasAssetFactory: public UFactory, public FReimportHandler {
GENERATED_UCLASS_BODY()
virtual FText GetToolTip() const 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;
@ -18,5 +18,5 @@ class USpineAtlasAssetFactory : public UFactory, public FReimportHandler
virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) 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"
UCLASS()
class USpineSkeletonAssetFactory : public UFactory, public FReimportHandler
{
class USpineSkeletonAssetFactory : public UFactory, public FReimportHandler {
GENERATED_UCLASS_BODY()
virtual FText GetToolTip() const override;
virtual bool FactoryCanImport(const FString& Filename) override;
virtual FText GetToolTip () const 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 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 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;
};

View File

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

View File

@ -1,41 +1,24 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "SpinePluginPrivatePCH.h"
#include "spine/spine.h"
class FSpinePlugin : public SpinePlugin {
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
IMPLEMENT_MODULE( FSpinePlugin, SpinePlugin )
void FSpinePlugin::StartupModule() { }
void FSpinePlugin::StartupModule() {
// 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.
}
void FSpinePlugin::ShutdownModule() { }
// 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" {
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_createTexture (spAtlasPage* self, const char* path) { }
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"
// Sets default values for this component's properties
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.
#define LOCTEXT_NAMESPACE "Spine"
USpineSkeletonComponent::USpineSkeletonComponent () {
bWantsBeginPlay = true;
PrimaryComponentTick.bCanEverTick = true;
bTickInEditor = true;
@ -17,8 +13,8 @@ void USpineSkeletonComponent::BeginPlay() {
Super::BeginPlay();
}
void USpineSkeletonComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) {
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
void USpineSkeletonComponent::TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (lastAtlas != atlas || lastData != skeletonData) {
DisposeState();
@ -28,7 +24,6 @@ void USpineSkeletonComponent::TickComponent( float DeltaTime, ELevelTick TickTyp
skeleton = spSkeleton_create(data);
stateData = spAnimationStateData_create(data);
state = spAnimationState_create(stateData);
spAnimationState_setAnimationByName(state, 0, "walk", true);
}
lastAtlas = atlas;
@ -38,11 +33,11 @@ void USpineSkeletonComponent::TickComponent( float DeltaTime, ELevelTick TickTyp
if (state) {
spAnimationState_update(state, DeltaTime);
spAnimationState_apply(state, skeleton);
spSkeleton_updateWorldTransform(skeleton);
spSkeleton_updateWorldTransform(skeleton);
}
}
void USpineSkeletonComponent::DisposeState() {
void USpineSkeletonComponent::DisposeState () {
if (stateData) {
spAnimationStateData_dispose(stateData);
stateData = nullptr;
@ -59,7 +54,9 @@ void USpineSkeletonComponent::DisposeState() {
}
}
void USpineSkeletonComponent::FinishDestroy() {
void USpineSkeletonComponent::FinishDestroy () {
DisposeState();
Super::FinishDestroy();
}
}
#undef LOCTEXT_NAMESPACE

View File

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

View File

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

View File

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

View File

@ -1,37 +1,16 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "ModuleManager.h"
/**
* 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
{
class SPINEPLUGIN_API SpinePlugin : public IModuleInterface {
public:
/**
* 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()
{
static inline SpinePlugin& Get() {
return FModuleManager::LoadModuleChecked< SpinePlugin >( "SpinePlugin" );
}
/**
* 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()
{
static inline bool IsAvailable() {
return FModuleManager::Get().IsModuleLoaded( "SpinePlugin" );
}
};

View File

@ -13,26 +13,31 @@ class SPINEPLUGIN_API USpineSkeletonComponent : public UActorComponent
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
USpineAtlasAsset* atlas;
USpineAtlasAsset* Atlas;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
USpineSkeletonDataAsset* skeletonData;
spAnimationStateData* stateData;
spAnimationState* state;
spSkeleton* skeleton;
USpineSkeletonDataAsset* SkeletonData;
spAnimationStateData* GetAnimationStateData () { return stateData; };
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:
void DisposeState();
void DisposeState();
spAnimationStateData* stateData;
spAnimationState* state;
spSkeleton* skeleton;
USpineAtlasAsset* lastAtlas = nullptr;
USpineSkeletonDataAsset* lastData = nullptr;
};

View File

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

View File

@ -8,9 +8,8 @@
#include "SpineSkeletonRendererComponent.generated.h"
UCLASS( ClassGroup=(Spine), meta=(BlueprintSpawnableComponent) )
class SPINEPLUGIN_API USpineSkeletonRendererComponent : public UProceduralMeshComponent
{
UCLASS(ClassGroup=(Spine), meta=(BlueprintSpawnableComponent))
class SPINEPLUGIN_API USpineSkeletonRendererComponent: public UProceduralMeshComponent {
GENERATED_BODY()
public:
@ -24,11 +23,15 @@ public:
UMaterialInterface* DefaultMaterial;
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
float depthOffset = 0.1f;
float DepthOffset = 0.1f;
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
FName TextureParameterName;
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;
TMap<spAtlasPage*, UMaterialInstanceDynamic*> pageToMaterial;