接入Spine
This commit is contained in:
BIN
Plugins/SpinePlugin/Content/SpineLitNormalMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/SpineLitNormalMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Content/SpineUnlitAdditiveMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/SpineUnlitAdditiveMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Content/SpineUnlitMultiplyMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/SpineUnlitMultiplyMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Content/SpineUnlitNormalMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/SpineUnlitNormalMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Content/SpineUnlitScreenMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/SpineUnlitScreenMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Content/TestMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/TestMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Content/UI_SpineUnlitAdditiveMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/UI_SpineUnlitAdditiveMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Content/UI_SpineUnlitMultiplyMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/UI_SpineUnlitMultiplyMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Content/UI_SpineUnlitNormalMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/UI_SpineUnlitNormalMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Content/UI_SpineUnlitScreenMaterial.uasset
Normal file
BIN
Plugins/SpinePlugin/Content/UI_SpineUnlitScreenMaterial.uasset
Normal file
Binary file not shown.
BIN
Plugins/SpinePlugin/Resources/Icon128.png
Normal file
BIN
Plugins/SpinePlugin/Resources/Icon128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,143 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineAtlasImportFactory.h"
|
||||
#include "AssetToolsModule.h"
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "Editor.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
using namespace spine;
|
||||
|
||||
USpineAtlasAssetFactory::USpineAtlasAssetFactory(const FObjectInitializer &objectInitializer) : Super(objectInitializer) {
|
||||
bCreateNew = false;
|
||||
bEditAfterNew = true;
|
||||
bEditorImport = true;
|
||||
SupportedClass = USpineAtlasAsset::StaticClass();
|
||||
|
||||
Formats.Add(TEXT("atlas;Spine Atlas file"));
|
||||
}
|
||||
|
||||
FText USpineAtlasAssetFactory::GetToolTip() const {
|
||||
return LOCTEXT("SpineAtlasAssetFactory", "Animations exported from Spine");
|
||||
}
|
||||
|
||||
bool USpineAtlasAssetFactory::FactoryCanImport(const FString &Filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
UObject *USpineAtlasAssetFactory::FactoryCreateFile(UClass *InClass, UObject *InParent, FName InName, EObjectFlags Flags, const FString &Filename, const TCHAR *Parms, FFeedbackContext *Warn, bool &bOutOperationCanceled) {
|
||||
FString FileExtension = FPaths::GetExtension(Filename);
|
||||
GEditor->GetEditorSubsystem<UImportSubsystem>()->BroadcastAssetPreImport(this, InClass, InParent, InName, *FileExtension);
|
||||
|
||||
FString rawString;
|
||||
if (!FFileHelper::LoadFileToString(rawString, *Filename)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FString currentSourcePath, filenameNoExtension, unusedExtension;
|
||||
const FString longPackagePath = FPackageName::GetLongPackagePath(InParent->GetOutermost()->GetPathName());
|
||||
FPaths::Split(UFactory::GetCurrentFilename(), currentSourcePath, filenameNoExtension, unusedExtension);
|
||||
|
||||
USpineAtlasAsset *asset = NewObject<USpineAtlasAsset>(InParent, InClass, InName, Flags);
|
||||
asset->SetRawData(rawString);
|
||||
asset->SetAtlasFileName(FName(*Filename));
|
||||
LoadAtlas(asset, currentSourcePath, longPackagePath);
|
||||
GEditor->GetEditorSubsystem<UImportSubsystem>()->BroadcastAssetPostImport(this, asset);
|
||||
return asset;
|
||||
}
|
||||
|
||||
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) {
|
||||
USpineAtlasAsset *asset = Cast<USpineAtlasAsset>(Obj);
|
||||
|
||||
if (asset && ensure(NewReimportPaths.Num() == 1))
|
||||
asset->SetAtlasFileName(FName(*NewReimportPaths[0]));
|
||||
}
|
||||
|
||||
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 currentFileName = asset->GetAtlasFileName().ToString();
|
||||
FPaths::Split(currentFileName, currentSourcePath, filenameNoExtension, unusedExtension);
|
||||
|
||||
LoadAtlas(asset, currentSourcePath, longPackagePath);
|
||||
|
||||
if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
|
||||
else
|
||||
Obj->MarkPackageDirty();
|
||||
|
||||
GEditor->GetEditorSubsystem<UImportSubsystem>()->BroadcastAssetReimport(asset);
|
||||
return EReimportResult::Succeeded;
|
||||
}
|
||||
|
||||
UTexture2D *resolveTexture(USpineAtlasAsset *Asset, const FString &PageFileName, const FString &TargetSubPath) {
|
||||
FAssetToolsModule &AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
|
||||
|
||||
TArray<FString> fileNames;
|
||||
fileNames.Add(PageFileName);
|
||||
|
||||
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) {
|
||||
Atlas *atlas = Asset->GetAtlas();
|
||||
Asset->atlasPages.Empty();
|
||||
|
||||
const FString targetTexturePath = LongPackagePath / TEXT("Textures");
|
||||
|
||||
Vector<AtlasPage *> &pages = atlas->getPages();
|
||||
for (size_t i = 0, n = pages.size(); i < n; i++) {
|
||||
AtlasPage *page = pages[i];
|
||||
const FString sourceTextureFilename = FPaths::Combine(*CurrentSourcePath, UTF8_TO_TCHAR(page->name.buffer()));
|
||||
UTexture2D *texture = resolveTexture(Asset, sourceTextureFilename, targetTexturePath);
|
||||
Asset->atlasPages.Add(texture);
|
||||
}
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,71 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineEditorPlugin.h"
|
||||
#include "AssetTypeActions_Base.h"
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "SpineSkeletonDataAsset.h"
|
||||
|
||||
class FSpineAtlasAssetTypeActions : public FAssetTypeActions_Base {
|
||||
public:
|
||||
UClass *GetSupportedClass() const override { return USpineAtlasAsset::StaticClass(); };
|
||||
FText GetName() const override { return INVTEXT("Spine atlas asset"); };
|
||||
FColor GetTypeColor() const override { return FColor::Red; };
|
||||
uint32 GetCategories() override { return EAssetTypeCategories::Misc; };
|
||||
};
|
||||
|
||||
class FSpineSkeletonDataAssetTypeActions : public FAssetTypeActions_Base {
|
||||
public:
|
||||
UClass *GetSupportedClass() const override { return USpineSkeletonDataAsset::StaticClass(); };
|
||||
FText GetName() const override { return INVTEXT("Spine data asset"); };
|
||||
FColor GetTypeColor() const override { return FColor::Red; };
|
||||
uint32 GetCategories() override { return EAssetTypeCategories::Misc; };
|
||||
};
|
||||
|
||||
class FSpineEditorPlugin : public ISpineEditorPlugin {
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
TSharedPtr<FSpineAtlasAssetTypeActions> SpineAtlasAssetTypeActions;
|
||||
TSharedPtr<FSpineSkeletonDataAssetTypeActions> SpineSkeletonDataAssetTypeActions;
|
||||
};
|
||||
|
||||
IMPLEMENT_MODULE(FSpineEditorPlugin, SpineEditorPlugin)
|
||||
|
||||
void FSpineEditorPlugin::StartupModule() {
|
||||
SpineAtlasAssetTypeActions = MakeShared<FSpineAtlasAssetTypeActions>();
|
||||
FAssetToolsModule::GetModule().Get().RegisterAssetTypeActions(SpineAtlasAssetTypeActions.ToSharedRef());
|
||||
SpineSkeletonDataAssetTypeActions = MakeShared<FSpineSkeletonDataAssetTypeActions>();
|
||||
FAssetToolsModule::GetModule().Get().RegisterAssetTypeActions(SpineSkeletonDataAssetTypeActions.ToSharedRef());
|
||||
}
|
||||
|
||||
void FSpineEditorPlugin::ShutdownModule() {
|
||||
if (!FModuleManager::Get().IsModuleLoaded("AssetTools")) return;
|
||||
FAssetToolsModule::GetModule().Get().UnregisterAssetTypeActions(SpineAtlasAssetTypeActions.ToSharedRef());
|
||||
FAssetToolsModule::GetModule().Get().UnregisterAssetTypeActions(SpineSkeletonDataAssetTypeActions.ToSharedRef());
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineSkeletonImportFactory.h"
|
||||
#include "AssetToolsModule.h"
|
||||
#include "Developer/AssetTools/Public/IAssetTools.h"
|
||||
#include "SpineSkeletonDataAsset.h"
|
||||
#include <string.h>
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
USpineSkeletonAssetFactory::USpineSkeletonAssetFactory(const FObjectInitializer &objectInitializer) : Super(objectInitializer) {
|
||||
bCreateNew = false;
|
||||
bEditAfterNew = true;
|
||||
bEditorImport = true;
|
||||
SupportedClass = USpineSkeletonDataAsset::StaticClass();
|
||||
|
||||
Formats.Add(TEXT("json;Spine skeleton file"));
|
||||
Formats.Add(TEXT("skel;Spine skeleton file"));
|
||||
}
|
||||
|
||||
FText USpineSkeletonAssetFactory::GetToolTip() const {
|
||||
return LOCTEXT("USpineSkeletonAssetFactory", "Animations exported from Spine");
|
||||
}
|
||||
|
||||
bool USpineSkeletonAssetFactory::FactoryCanImport(const FString &Filename) {
|
||||
if (Filename.Contains(TEXT(".skel"))) return true;
|
||||
|
||||
if (Filename.Contains(TEXT(".json"))) {
|
||||
TArray<uint8> rawData;
|
||||
if (!FFileHelper::LoadFileToArray(rawData, *Filename, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (rawData.Num() == 0) return false;
|
||||
return strcmp((const char *) rawData.GetData(), "skeleton") > 0 && strcmp((const char *) rawData.GetData(), "spine") > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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"));
|
||||
if (!FPaths::FileExists(skelFile)) return;
|
||||
|
||||
TArray<FString> fileNames;
|
||||
fileNames.Add(skelFile);
|
||||
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) {
|
||||
USpineSkeletonDataAsset *asset = NewObject<USpineSkeletonDataAsset>(InParent, InClass, InName, Flags);
|
||||
TArray<uint8> rawData;
|
||||
if (!FFileHelper::LoadFileToArray(rawData, *Filename, 0)) {
|
||||
return nullptr;
|
||||
}
|
||||
asset->SetSkeletonDataFileName(FName(*Filename));
|
||||
asset->SetRawData(rawData);
|
||||
|
||||
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
|
||||
LoadAtlas(Filename, longPackagePath);
|
||||
return asset;
|
||||
}
|
||||
|
||||
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) {
|
||||
USpineSkeletonDataAsset *asset = Cast<USpineSkeletonDataAsset>(Obj);
|
||||
|
||||
if (asset && ensure(NewReimportPaths.Num() == 1))
|
||||
asset->SetSkeletonDataFileName(FName(*NewReimportPaths[0]));
|
||||
}
|
||||
|
||||
EReimportResult::Type USpineSkeletonAssetFactory::Reimport(UObject *Obj) {
|
||||
USpineSkeletonDataAsset *asset = Cast<USpineSkeletonDataAsset>(Obj);
|
||||
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());
|
||||
LoadAtlas(*asset->GetSkeletonDataFileName().ToString(), longPackagePath);
|
||||
|
||||
if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
|
||||
else
|
||||
Obj->MarkPackageDirty();
|
||||
|
||||
return EReimportResult::Succeeded;
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,52 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "UnrealEd.h"
|
||||
#include "SpineAtlasImportFactory.generated.h"
|
||||
// clang-format on
|
||||
|
||||
UCLASS()
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
void LoadAtlas(USpineAtlasAsset *Asset, const FString &CurrentSourcePath, const FString &LongPackagePath);
|
||||
};
|
||||
@ -0,0 +1,44 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class ISpineEditorPlugin : public IModuleInterface {
|
||||
|
||||
public:
|
||||
static inline ISpineEditorPlugin &Get() {
|
||||
return FModuleManager::LoadModuleChecked<ISpineEditorPlugin>("SpineEditorPlugin");
|
||||
}
|
||||
|
||||
static inline bool IsAvailable() {
|
||||
return FModuleManager::Get().IsModuleLoaded("SpineEditorPlugin");
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,49 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "UnrealEd.h"
|
||||
#include "SpineSkeletonImportFactory.generated.h"
|
||||
// clang-format on
|
||||
|
||||
UCLASS()
|
||||
class USpineSkeletonAssetFactory : 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;
|
||||
|
||||
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;
|
||||
};
|
||||
@ -0,0 +1,36 @@
|
||||
using System.IO;
|
||||
|
||||
namespace UnrealBuildTool.Rules
|
||||
{
|
||||
public class SpineEditorPlugin : ModuleRules
|
||||
{
|
||||
public SpineEditorPlugin(ReadOnlyTargetRules target) : base(target)
|
||||
{
|
||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public"));
|
||||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "../SpinePlugin/Public/spine-cpp/include"));
|
||||
|
||||
PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "Private"));
|
||||
PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "../SpinePlugin/Public/spine-cpp/include"));
|
||||
|
||||
PublicDependencyModuleNames.AddRange(new [] {
|
||||
"Core",
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"UnrealEd",
|
||||
"SpinePlugin"
|
||||
});
|
||||
|
||||
PublicIncludePathModuleNames.AddRange(new [] {
|
||||
"AssetTools",
|
||||
"AssetRegistry"
|
||||
});
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(new [] {
|
||||
"AssetTools",
|
||||
"AssetRegistry"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
415
Plugins/SpinePlugin/Source/SpinePlugin/Private/SSpineWidget.cpp
Normal file
415
Plugins/SpinePlugin/Source/SpinePlugin/Private/SSpineWidget.cpp
Normal file
@ -0,0 +1,415 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SSpineWidget.h"
|
||||
#include "Framework/Application/SlateApplication.h"
|
||||
#include "Materials/MaterialInstanceDynamic.h"
|
||||
#include "Materials/MaterialInterface.h"
|
||||
#include "Rendering/DrawElements.h"
|
||||
#include "Runtime/SlateRHIRenderer/Public/Interfaces/ISlateRHIRendererModule.h"
|
||||
#include "Slate/SMeshWidget.h"
|
||||
#include "Slate/SlateVectorArtData.h"
|
||||
#include "SlateMaterialBrush.h"
|
||||
#include "SpineWidget.h"
|
||||
#include <spine/spine.h>
|
||||
|
||||
using namespace spine;
|
||||
|
||||
static int brushNameId = 0;
|
||||
|
||||
// Workaround for https://github.com/EsotericSoftware/spine-runtimes/issues/1458
|
||||
// See issue comments for more information.
|
||||
struct SpineSlateMaterialBrush : public FSlateBrush {
|
||||
static TArray<FName> NamePool;
|
||||
static FCriticalSection NamePoolLock;
|
||||
|
||||
SpineSlateMaterialBrush(class UMaterialInterface &InMaterial, const FVector2D &InImageSize)
|
||||
: FSlateBrush(ESlateBrushDrawType::Image, FName(TEXT("None")), FMargin(0), ESlateBrushTileType::NoTile, ESlateBrushImageType::FullColor, InImageSize, FLinearColor::White, &InMaterial) {
|
||||
// Workaround for https://github.com/EsotericSoftware/spine-runtimes/issues/2006
|
||||
FScopeLock Lock(&NamePoolLock);
|
||||
|
||||
if (NamePool.Num() > 0) {
|
||||
ResourceName = NamePool.Pop(false);
|
||||
} else {
|
||||
static uint32 NextId = 0;
|
||||
FString brushName = TEXT("SpineSlateMatBrush");
|
||||
brushName.AppendInt(NextId++);
|
||||
ResourceName = FName(*brushName);
|
||||
}
|
||||
}
|
||||
|
||||
~SpineSlateMaterialBrush() {
|
||||
FScopeLock Lock(&NamePoolLock);
|
||||
NamePool.Add(ResourceName);
|
||||
}
|
||||
};
|
||||
|
||||
TArray<FName> SpineSlateMaterialBrush::NamePool;
|
||||
FCriticalSection SpineSlateMaterialBrush::NamePoolLock;
|
||||
|
||||
void SSpineWidget::Construct(const FArguments &args) {
|
||||
}
|
||||
|
||||
void SSpineWidget::SetData(USpineWidget *Widget) {
|
||||
this->widget = Widget;
|
||||
if (widget && widget->skeleton && widget->Atlas) {
|
||||
Skeleton *skeleton = widget->skeleton;
|
||||
skeleton->setToSetupPose();
|
||||
skeleton->updateWorldTransform(Physics_None);
|
||||
Vector<float> scratchBuffer;
|
||||
float x, y, w, h;
|
||||
skeleton->getBounds(x, y, w, h, scratchBuffer);
|
||||
boundsMin.X = x;
|
||||
boundsMin.Y = y;
|
||||
boundsSize.X = w;
|
||||
boundsSize.Y = h;
|
||||
}
|
||||
}
|
||||
|
||||
static void setVertex(FSlateVertex *vertex, float x, float y, float u, float v, const FColor &color, const FVector2D &offset) {
|
||||
vertex->Position.X = offset.X + x;
|
||||
vertex->Position.Y = offset.Y + y;
|
||||
vertex->TexCoords[0] = u;
|
||||
vertex->TexCoords[1] = v;
|
||||
vertex->TexCoords[2] = u;
|
||||
vertex->TexCoords[3] = v;
|
||||
vertex->MaterialTexCoords.X = u;
|
||||
vertex->MaterialTexCoords.Y = v;
|
||||
vertex->Color = color;
|
||||
vertex->PixelSize[0] = 1;
|
||||
vertex->PixelSize[1] = 1;
|
||||
}
|
||||
|
||||
int32 SSpineWidget::OnPaint(const FPaintArgs &Args, const FGeometry &AllottedGeometry, const FSlateRect &MyClippingRect, FSlateWindowElementList &OutDrawElements,
|
||||
int32 LayerId, const FWidgetStyle &InWidgetStyle, bool bParentEnabled) const {
|
||||
|
||||
SSpineWidget *self = (SSpineWidget *) this;
|
||||
UMaterialInstanceDynamic *MatNow = nullptr;
|
||||
|
||||
if (widget && widget->skeleton && widget->Atlas) {
|
||||
widget->skeleton->getColor().set(widget->Color.R, widget->Color.G, widget->Color.B, widget->Color.A);
|
||||
|
||||
if (widget->atlasNormalBlendMaterials.Num() != widget->Atlas->atlasPages.Num()) {
|
||||
widget->atlasNormalBlendMaterials.SetNum(0);
|
||||
widget->pageToNormalBlendMaterial.Empty();
|
||||
widget->atlasAdditiveBlendMaterials.SetNum(0);
|
||||
widget->pageToAdditiveBlendMaterial.Empty();
|
||||
widget->atlasMultiplyBlendMaterials.SetNum(0);
|
||||
widget->pageToMultiplyBlendMaterial.Empty();
|
||||
widget->atlasScreenBlendMaterials.SetNum(0);
|
||||
widget->pageToScreenBlendMaterial.Empty();
|
||||
|
||||
for (int i = 0; i < widget->Atlas->atlasPages.Num(); i++) {
|
||||
AtlasPage *currPage = widget->Atlas->GetAtlas()->getPages()[i];
|
||||
|
||||
UMaterialInstanceDynamic *material = UMaterialInstanceDynamic::Create(widget->NormalBlendMaterial, widget);
|
||||
material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]);
|
||||
widget->atlasNormalBlendMaterials.Add(material);
|
||||
widget->pageToNormalBlendMaterial.Add(currPage, material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(widget->AdditiveBlendMaterial, widget);
|
||||
material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]);
|
||||
widget->atlasAdditiveBlendMaterials.Add(material);
|
||||
widget->pageToAdditiveBlendMaterial.Add(currPage, material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(widget->MultiplyBlendMaterial, widget);
|
||||
material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]);
|
||||
widget->atlasMultiplyBlendMaterials.Add(material);
|
||||
widget->pageToMultiplyBlendMaterial.Add(currPage, material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(widget->ScreenBlendMaterial, widget);
|
||||
material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]);
|
||||
widget->atlasScreenBlendMaterials.Add(material);
|
||||
widget->pageToScreenBlendMaterial.Add(currPage, material);
|
||||
}
|
||||
} else {
|
||||
widget->pageToNormalBlendMaterial.Empty();
|
||||
widget->pageToAdditiveBlendMaterial.Empty();
|
||||
widget->pageToMultiplyBlendMaterial.Empty();
|
||||
widget->pageToScreenBlendMaterial.Empty();
|
||||
|
||||
for (int i = 0; i < widget->Atlas->atlasPages.Num(); i++) {
|
||||
AtlasPage *currPage = widget->Atlas->GetAtlas()->getPages()[i];
|
||||
|
||||
UTexture2D *texture = widget->Atlas->atlasPages[i];
|
||||
UTexture *oldTexture = nullptr;
|
||||
|
||||
UMaterialInstanceDynamic *current = widget->atlasNormalBlendMaterials[i];
|
||||
if (!current || !current->GetTextureParameterValue(widget->TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic *material = UMaterialInstanceDynamic::Create(widget->NormalBlendMaterial, widget);
|
||||
material->SetTextureParameterValue(widget->TextureParameterName, texture);
|
||||
widget->atlasNormalBlendMaterials[i] = material;
|
||||
}
|
||||
widget->pageToNormalBlendMaterial.Add(currPage, widget->atlasNormalBlendMaterials[i]);
|
||||
|
||||
current = widget->atlasAdditiveBlendMaterials[i];
|
||||
if (!current || !current->GetTextureParameterValue(widget->TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic *material = UMaterialInstanceDynamic::Create(widget->AdditiveBlendMaterial, widget);
|
||||
material->SetTextureParameterValue(widget->TextureParameterName, texture);
|
||||
widget->atlasAdditiveBlendMaterials[i] = material;
|
||||
}
|
||||
widget->pageToAdditiveBlendMaterial.Add(currPage, widget->atlasAdditiveBlendMaterials[i]);
|
||||
|
||||
current = widget->atlasMultiplyBlendMaterials[i];
|
||||
if (!current || !current->GetTextureParameterValue(widget->TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic *material = UMaterialInstanceDynamic::Create(widget->MultiplyBlendMaterial, widget);
|
||||
material->SetTextureParameterValue(widget->TextureParameterName, texture);
|
||||
widget->atlasMultiplyBlendMaterials[i] = material;
|
||||
}
|
||||
widget->pageToMultiplyBlendMaterial.Add(currPage, widget->atlasMultiplyBlendMaterials[i]);
|
||||
|
||||
current = widget->atlasScreenBlendMaterials[i];
|
||||
if (!current || !current->GetTextureParameterValue(widget->TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic *material = UMaterialInstanceDynamic::Create(widget->ScreenBlendMaterial, widget);
|
||||
material->SetTextureParameterValue(widget->TextureParameterName, texture);
|
||||
widget->atlasScreenBlendMaterials[i] = material;
|
||||
}
|
||||
widget->pageToScreenBlendMaterial.Add(currPage, widget->atlasScreenBlendMaterials[i]);
|
||||
}
|
||||
}
|
||||
|
||||
self->UpdateMesh(LayerId, OutDrawElements, AllottedGeometry, widget->skeleton);
|
||||
}
|
||||
|
||||
return LayerId;
|
||||
}
|
||||
|
||||
void SSpineWidget::Flush(int32 LayerId, FSlateWindowElementList &OutDrawElements, const FGeometry &AllottedGeometry, int &Idx, TArray<FVector> &Vertices, TArray<int32> &Indices, TArray<FVector2D> &Uvs, TArray<FColor> &Colors, TArray<FVector> &Colors2, UMaterialInstanceDynamic *Material) {
|
||||
if (Vertices.Num() == 0) return;
|
||||
SSpineWidget *self = (SSpineWidget *) this;
|
||||
|
||||
const FVector2D widgetSize = AllottedGeometry.GetLocalSize();
|
||||
const FVector2D sizeScale = widgetSize / FVector2D(boundsSize.X, boundsSize.Y);
|
||||
const float setupScale = sizeScale.GetMin();
|
||||
|
||||
for (int i = 0; i < Vertices.Num(); i++) {
|
||||
Vertices[i] = (Vertices[i] + FVector(-boundsMin.X - boundsSize.X / 2, boundsMin.Y + boundsSize.Y / 2, 0)) * setupScale + FVector(widgetSize.X / 2, widgetSize.Y / 2, 0);
|
||||
}
|
||||
|
||||
self->renderData.IndexData.SetNumUninitialized(Indices.Num());
|
||||
SlateIndex *indexData = (SlateIndex *) renderData.IndexData.GetData();
|
||||
for (int i = 0; i < Indices.Num(); i++) {
|
||||
indexData[i] = (SlateIndex) Indices[i];
|
||||
}
|
||||
|
||||
self->renderData.VertexData.SetNumUninitialized(Vertices.Num());
|
||||
FSlateVertex *vertexData = (FSlateVertex *) renderData.VertexData.GetData();
|
||||
FVector2D offset = AllottedGeometry.GetAbsolutePositionAtCoordinates(FVector2D(0.0f, 0.0f));
|
||||
FColor white = FColor(0xffffffff);
|
||||
const FSlateRenderTransform &Transform = AllottedGeometry.GetAccumulatedRenderTransform();
|
||||
|
||||
for (size_t i = 0; i < (size_t) Vertices.Num(); i++) {
|
||||
setVertex(&vertexData[i], 0, 0, Uvs[i].X, Uvs[i].Y, Colors[i], Transform.TransformPoint(FVector2D(Vertices[i])));
|
||||
}
|
||||
|
||||
brush = &widget->Brush;
|
||||
if (Material) {
|
||||
renderData.Brush = MakeShareable(new SpineSlateMaterialBrush(*Material, FVector2D(64, 64)));
|
||||
renderData.RenderingResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(*renderData.Brush);
|
||||
}
|
||||
|
||||
if (renderData.RenderingResourceHandle.IsValid()) {
|
||||
FSlateDrawElement::MakeCustomVerts(OutDrawElements, LayerId, renderData.RenderingResourceHandle, renderData.VertexData, renderData.IndexData, nullptr, 0, 0);
|
||||
}
|
||||
|
||||
Vertices.SetNum(0);
|
||||
Indices.SetNum(0);
|
||||
Uvs.SetNum(0);
|
||||
Colors.SetNum(0);
|
||||
Colors2.SetNum(0);
|
||||
Idx++;
|
||||
}
|
||||
|
||||
FVector2D SSpineWidget::ComputeDesiredSize(float X) const {
|
||||
if (widget && widget->skeleton && widget->Atlas) {
|
||||
return FVector2D(boundsSize.X, boundsSize.Y);
|
||||
} else {
|
||||
return FVector2D(256, 256);
|
||||
}
|
||||
}
|
||||
|
||||
void SSpineWidget::UpdateMesh(int32 LayerId, FSlateWindowElementList &OutDrawElements, const FGeometry &AllottedGeometry, Skeleton *Skeleton) {
|
||||
TArray<FVector> vertices;
|
||||
TArray<int32> indices;
|
||||
TArray<FVector2D> uvs;
|
||||
TArray<FColor> colors;
|
||||
TArray<FVector> darkColors;
|
||||
|
||||
int idx = 0;
|
||||
int meshSection = 0;
|
||||
UMaterialInstanceDynamic *lastMaterial = nullptr;
|
||||
|
||||
SkeletonClipping &clipper = widget->clipper;
|
||||
Vector<float> &worldVertices = widget->worldVertices;
|
||||
|
||||
float depthOffset = 0;
|
||||
unsigned short quadIndices[] = {0, 1, 2, 0, 2, 3};
|
||||
|
||||
for (int i = 0; i < (int) Skeleton->getSlots().size(); ++i) {
|
||||
Vector<float> *attachmentVertices = &worldVertices;
|
||||
unsigned short *attachmentIndices = nullptr;
|
||||
int numVertices;
|
||||
int numIndices;
|
||||
AtlasRegion *attachmentAtlasRegion = nullptr;
|
||||
Color attachmentColor;
|
||||
attachmentColor.set(1, 1, 1, 1);
|
||||
float *attachmentUvs = nullptr;
|
||||
|
||||
Slot *slot = Skeleton->getDrawOrder()[i];
|
||||
if (!slot->getBone().isActive()) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
Attachment *attachment = slot->getAttachment();
|
||||
if (!attachment) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
if (!attachment->getRTTI().isExactly(RegionAttachment::rtti) && !attachment->getRTTI().isExactly(MeshAttachment::rtti) && !attachment->getRTTI().isExactly(ClippingAttachment::rtti)) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
|
||||
RegionAttachment *regionAttachment = (RegionAttachment *) attachment;
|
||||
attachmentColor.set(regionAttachment->getColor());
|
||||
attachmentVertices->setSize(8, 0);
|
||||
regionAttachment->computeWorldVertices(*slot, *attachmentVertices, 0, 2);
|
||||
attachmentAtlasRegion = (AtlasRegion *) regionAttachment->getRegion();
|
||||
attachmentIndices = quadIndices;
|
||||
attachmentUvs = regionAttachment->getUVs().buffer();
|
||||
numVertices = 4;
|
||||
numIndices = 6;
|
||||
} else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
|
||||
MeshAttachment *mesh = (MeshAttachment *) attachment;
|
||||
attachmentColor.set(mesh->getColor());
|
||||
attachmentVertices->setSize(mesh->getWorldVerticesLength(), 0);
|
||||
mesh->computeWorldVertices(*slot, 0, mesh->getWorldVerticesLength(), attachmentVertices->buffer(), 0, 2);
|
||||
attachmentAtlasRegion = (AtlasRegion *) mesh->getRegion();
|
||||
attachmentIndices = mesh->getTriangles().buffer();
|
||||
attachmentUvs = mesh->getUVs().buffer();
|
||||
numVertices = mesh->getWorldVerticesLength() >> 1;
|
||||
numIndices = mesh->getTriangles().size();
|
||||
} else /* clipping */ {
|
||||
ClippingAttachment *clip = (ClippingAttachment *) attachment;
|
||||
clipper.clipStart(*slot, clip);
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the user switches the atlas data while not having switched
|
||||
// to the correct skeleton data yet, we won't find any regions.
|
||||
// ignore regions for which we can't find a material
|
||||
UMaterialInstanceDynamic *material = nullptr;
|
||||
switch (slot->getData().getBlendMode()) {
|
||||
case BlendMode_Normal:
|
||||
if (!widget->pageToNormalBlendMaterial.Contains(attachmentAtlasRegion->page)) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
material = widget->pageToNormalBlendMaterial[attachmentAtlasRegion->page];
|
||||
break;
|
||||
case BlendMode_Additive:
|
||||
if (!widget->pageToAdditiveBlendMaterial.Contains(attachmentAtlasRegion->page)) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
material = widget->pageToAdditiveBlendMaterial[attachmentAtlasRegion->page];
|
||||
break;
|
||||
case BlendMode_Multiply:
|
||||
if (!widget->pageToMultiplyBlendMaterial.Contains(attachmentAtlasRegion->page)) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
material = widget->pageToMultiplyBlendMaterial[attachmentAtlasRegion->page];
|
||||
break;
|
||||
case BlendMode_Screen:
|
||||
if (!widget->pageToScreenBlendMaterial.Contains(attachmentAtlasRegion->page)) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
material = widget->pageToScreenBlendMaterial[attachmentAtlasRegion->page];
|
||||
break;
|
||||
default:
|
||||
if (!widget->pageToNormalBlendMaterial.Contains(attachmentAtlasRegion->page)) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
material = widget->pageToNormalBlendMaterial[attachmentAtlasRegion->page];
|
||||
}
|
||||
|
||||
if (clipper.isClipping()) {
|
||||
clipper.clipTriangles(attachmentVertices->buffer(), attachmentIndices, numIndices, attachmentUvs, 2);
|
||||
attachmentVertices = &clipper.getClippedVertices();
|
||||
numVertices = clipper.getClippedVertices().size() >> 1;
|
||||
attachmentIndices = clipper.getClippedTriangles().buffer();
|
||||
numIndices = clipper.getClippedTriangles().size();
|
||||
attachmentUvs = clipper.getClippedUVs().buffer();
|
||||
if (clipper.getClippedTriangles().size() == 0) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastMaterial != material) {
|
||||
Flush(LayerId, OutDrawElements, AllottedGeometry, meshSection, vertices, indices, uvs, colors, darkColors, lastMaterial);
|
||||
lastMaterial = material;
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
uint8 r = static_cast<uint8>(Skeleton->getColor().r * slot->getColor().r * attachmentColor.r * 255);
|
||||
uint8 g = static_cast<uint8>(Skeleton->getColor().g * slot->getColor().g * attachmentColor.g * 255);
|
||||
uint8 b = static_cast<uint8>(Skeleton->getColor().b * slot->getColor().b * attachmentColor.b * 255);
|
||||
uint8 a = static_cast<uint8>(Skeleton->getColor().a * slot->getColor().a * attachmentColor.a * 255);
|
||||
|
||||
float dr = slot->hasDarkColor() ? slot->getDarkColor().r : 0.0f;
|
||||
float dg = slot->hasDarkColor() ? slot->getDarkColor().g : 0.0f;
|
||||
float db = slot->hasDarkColor() ? slot->getDarkColor().b : 0.0f;
|
||||
|
||||
float *verticesPtr = attachmentVertices->buffer();
|
||||
for (int j = 0; j < numVertices << 1; j += 2) {
|
||||
colors.Add(FColor(r, g, b, a));
|
||||
darkColors.Add(FVector(dr, dg, db));
|
||||
vertices.Add(FVector(verticesPtr[j], -verticesPtr[j + 1], depthOffset));
|
||||
uvs.Add(FVector2D(attachmentUvs[j], attachmentUvs[j + 1]));
|
||||
}
|
||||
|
||||
for (int j = 0; j < numIndices; j++) {
|
||||
indices.Add(idx + attachmentIndices[j]);
|
||||
}
|
||||
|
||||
idx += numVertices;
|
||||
depthOffset += widget->DepthOffset;
|
||||
|
||||
clipper.clipEnd(*slot);
|
||||
}
|
||||
|
||||
Flush(LayerId, OutDrawElements, AllottedGeometry, meshSection, vertices, indices, uvs, colors, darkColors, lastMaterial);
|
||||
clipper.clipEnd();
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "spine/spine.h"
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "EditorFramework/AssetImportData.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
using namespace spine;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
|
||||
void USpineAtlasAsset::SetAtlasFileName(const FName &AtlasFileName) {
|
||||
importData->UpdateFilenameOnly(AtlasFileName.ToString());
|
||||
TArray<FString> files;
|
||||
importData->ExtractFilenames(files);
|
||||
if (files.Num() > 0)
|
||||
atlasFileName = FName(*files[0]);
|
||||
}
|
||||
|
||||
void USpineAtlasAsset::PostInitProperties() {
|
||||
if (!HasAnyFlags(RF_ClassDefaultObject))
|
||||
importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
|
||||
Super::PostInitProperties();
|
||||
}
|
||||
|
||||
void USpineAtlasAsset::Serialize(FArchive &Ar) {
|
||||
Super::Serialize(Ar);
|
||||
#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION <= 27
|
||||
if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData)
|
||||
#else
|
||||
if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData)
|
||||
#endif
|
||||
importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
|
||||
}
|
||||
|
||||
#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() {
|
||||
if (atlas) {
|
||||
delete atlas;
|
||||
atlas = nullptr;
|
||||
}
|
||||
Super::BeginDestroy();
|
||||
}
|
||||
|
||||
class UETextureLoader : public TextureLoader {
|
||||
void load(AtlasPage &page, const String &path) {
|
||||
page.texture = (void *) (uintptr_t) page.index;
|
||||
}
|
||||
|
||||
void unload(void *texture) {
|
||||
}
|
||||
};
|
||||
|
||||
UETextureLoader _spineUETextureLoader;
|
||||
|
||||
Atlas *USpineAtlasAsset::GetAtlas() {
|
||||
if (!atlas) {
|
||||
if (atlas) {
|
||||
delete atlas;
|
||||
atlas = nullptr;
|
||||
}
|
||||
std::string t = TCHAR_TO_UTF8(*rawData);
|
||||
|
||||
atlas = new (__FILE__, __LINE__)
|
||||
Atlas(t.c_str(), strlen(t.c_str()), "", &_spineUETextureLoader);
|
||||
}
|
||||
return this->atlas;
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,67 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineBoneDriverComponent.h"
|
||||
#include "SpineSkeletonComponent.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
|
||||
USpineBoneDriverComponent::USpineBoneDriverComponent() {
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
}
|
||||
|
||||
void USpineBoneDriverComponent::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void USpineBoneDriverComponent::BeforeUpdateWorldTransform(USpineSkeletonComponent *skeleton) {
|
||||
if (skeleton == lastBoundComponent && skeleton) {
|
||||
if (UseComponentTransform) {
|
||||
skeleton->SetBoneWorldPosition(BoneName, GetComponentLocation());
|
||||
} else {
|
||||
AActor *owner = GetOwner();
|
||||
if (owner) skeleton->SetBoneWorldPosition(BoneName, owner->GetActorLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USpineBoneDriverComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) {
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
if (Target) {
|
||||
USpineSkeletonComponent *skeleton = static_cast<USpineSkeletonComponent *>(Target->GetComponentByClass(USpineSkeletonComponent::StaticClass()));
|
||||
if (skeleton != lastBoundComponent && skeleton) {
|
||||
// if (lastBoundComponent) lastBoundComponent->BeforeUpdateWorldTransform.RemoveAll(this);
|
||||
if (!skeleton->BeforeUpdateWorldTransform.GetAllObjects().Contains(this))
|
||||
skeleton->BeforeUpdateWorldTransform.AddDynamic(this, &USpineBoneDriverComponent::BeforeUpdateWorldTransform);
|
||||
lastBoundComponent = skeleton;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineBoneFollowerComponent.h"
|
||||
#include "SpineSkeletonComponent.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
|
||||
USpineBoneFollowerComponent::USpineBoneFollowerComponent() {
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
}
|
||||
|
||||
void USpineBoneFollowerComponent::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void USpineBoneFollowerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) {
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
if (Target) {
|
||||
USpineSkeletonComponent *skeleton = static_cast<USpineSkeletonComponent *>(Target->GetComponentByClass(USpineSkeletonComponent::StaticClass()));
|
||||
if (skeleton) {
|
||||
FTransform transform = skeleton->GetBoneWorldTransform(BoneName);
|
||||
if (UseComponentTransform) {
|
||||
if (UsePosition) SetWorldLocation(transform.GetLocation());
|
||||
if (UseRotation) SetWorldRotation(transform.GetRotation());
|
||||
if (UseScale) SetWorldScale3D(transform.GetScale3D());
|
||||
} else {
|
||||
AActor *owner = GetOwner();
|
||||
if (owner) {
|
||||
if (UsePosition) owner->SetActorLocation(transform.GetLocation());
|
||||
if (UseRotation) owner->SetActorRotation(transform.GetRotation());
|
||||
if (UseScale) owner->SetActorScale3D(transform.GetScale3D());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpinePlugin.h"
|
||||
#include "spine/Extension.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY(SpineLog);
|
||||
|
||||
class FSpinePlugin : public SpinePlugin {
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
|
||||
IMPLEMENT_MODULE(FSpinePlugin, SpinePlugin)
|
||||
|
||||
void FSpinePlugin::StartupModule() {
|
||||
}
|
||||
|
||||
void FSpinePlugin::ShutdownModule() {}
|
||||
|
||||
class Ue4Extension : public spine::DefaultSpineExtension {
|
||||
public:
|
||||
Ue4Extension() : spine::DefaultSpineExtension() {}
|
||||
|
||||
virtual ~Ue4Extension() {}
|
||||
|
||||
virtual void *_alloc(size_t size, const char *file, int line) {
|
||||
return FMemory::Malloc(size);
|
||||
}
|
||||
|
||||
virtual void *_calloc(size_t size, const char *file, int line) {
|
||||
void *result = FMemory::Malloc(size);
|
||||
FMemory::Memset(result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void *_realloc(void *ptr, size_t size, const char *file, int line) {
|
||||
return FMemory::Realloc(ptr, size);
|
||||
}
|
||||
|
||||
virtual void _free(void *mem, const char *file, int line) {
|
||||
FMemory::Free(mem);
|
||||
}
|
||||
};
|
||||
|
||||
spine::SpineExtension *spine::getDefaultExtension() {
|
||||
return new Ue4Extension();
|
||||
}
|
||||
@ -0,0 +1,314 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineSkeletonAnimationComponent.h"
|
||||
#include "SpineAtlasAsset.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
using namespace spine;
|
||||
|
||||
void UTrackEntry::SetTrackEntry(TrackEntry *trackEntry) {
|
||||
if (entry) entry->setRendererObject(nullptr);
|
||||
this->entry = trackEntry;
|
||||
if (entry) entry->setRendererObject((void *) this);
|
||||
}
|
||||
|
||||
void callback(AnimationState *state, spine::EventType type, TrackEntry *entry, Event *event) {
|
||||
USpineSkeletonAnimationComponent *component = (USpineSkeletonAnimationComponent *) state->getRendererObject();
|
||||
|
||||
if (entry->getRendererObject()) {
|
||||
UTrackEntry *uEntry = (UTrackEntry *) entry->getRendererObject();
|
||||
if (type == EventType_Start) {
|
||||
component->AnimationStart.Broadcast(uEntry);
|
||||
uEntry->AnimationStart.Broadcast(uEntry);
|
||||
} else if (type == EventType_Interrupt) {
|
||||
component->AnimationInterrupt.Broadcast(uEntry);
|
||||
uEntry->AnimationInterrupt.Broadcast(uEntry);
|
||||
} else if (type == EventType_Event) {
|
||||
FSpineEvent evt;
|
||||
evt.SetEvent(event);
|
||||
component->AnimationEvent.Broadcast(uEntry, evt);
|
||||
uEntry->AnimationEvent.Broadcast(uEntry, evt);
|
||||
} else if (type == EventType_Complete) {
|
||||
component->AnimationComplete.Broadcast(uEntry);
|
||||
uEntry->AnimationComplete.Broadcast(uEntry);
|
||||
} else if (type == EventType_End) {
|
||||
component->AnimationEnd.Broadcast(uEntry);
|
||||
uEntry->AnimationEnd.Broadcast(uEntry);
|
||||
} else if (type == EventType_Dispose) {
|
||||
component->AnimationDispose.Broadcast(uEntry);
|
||||
uEntry->AnimationDispose.Broadcast(uEntry);
|
||||
uEntry->SetTrackEntry(nullptr);
|
||||
component->GCTrackEntry(uEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
USpineSkeletonAnimationComponent::USpineSkeletonAnimationComponent() {
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
bAutoPlaying = true;
|
||||
physicsTimeScale = 1;
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
for (UTrackEntry *entry : trackEntries) {
|
||||
if (entry && entry->GetTrackEntry()) {
|
||||
entry->GetTrackEntry()->setRendererObject(nullptr);
|
||||
}
|
||||
}
|
||||
trackEntries.Empty();
|
||||
}
|
||||
|
||||
void UTrackEntry::BeginDestroy() {
|
||||
Super::BeginDestroy();
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) {
|
||||
Super::Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
InternalTick(DeltaTime, true, TickType == LEVELTICK_ViewportsOnly);
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime, bool CallDelegates, bool Preview) {
|
||||
CheckState();
|
||||
|
||||
if (state && bAutoPlaying) {
|
||||
if (Preview) {
|
||||
if (lastPreviewAnimation != PreviewAnimation) {
|
||||
if (PreviewAnimation != "") SetAnimation(0, PreviewAnimation, true);
|
||||
else
|
||||
SetEmptyAnimation(0, 0);
|
||||
lastPreviewAnimation = PreviewAnimation;
|
||||
}
|
||||
|
||||
if (lastPreviewSkin != PreviewSkin) {
|
||||
if (PreviewSkin != "") SetSkin(PreviewSkin);
|
||||
else
|
||||
SetSkin("default");
|
||||
lastPreviewSkin = PreviewSkin;
|
||||
}
|
||||
}
|
||||
state->update(DeltaTime);
|
||||
state->apply(*skeleton);
|
||||
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||
skeleton->update(physicsTimeScale * DeltaTime);
|
||||
skeleton->updateWorldTransform(Physics_Update);
|
||||
if (CallDelegates) AfterUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::CheckState() {
|
||||
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();
|
||||
|
||||
if (Atlas && SkeletonData) {
|
||||
spine::SkeletonData *data = SkeletonData->GetSkeletonData(Atlas->GetAtlas());
|
||||
if (data) {
|
||||
skeleton = new (__FILE__, __LINE__) Skeleton(data);
|
||||
AnimationStateData *stateData = SkeletonData->GetAnimationStateData(Atlas->GetAtlas());
|
||||
state = new (__FILE__, __LINE__) AnimationState(stateData);
|
||||
state->setRendererObject((void *) this);
|
||||
state->setListener(callback);
|
||||
trackEntries.Empty();
|
||||
}
|
||||
}
|
||||
|
||||
lastAtlas = Atlas;
|
||||
lastSpineAtlas = Atlas ? Atlas->GetAtlas() : nullptr;
|
||||
lastData = SkeletonData;
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::DisposeState() {
|
||||
if (state) {
|
||||
delete state;
|
||||
state = nullptr;
|
||||
}
|
||||
|
||||
if (skeleton) {
|
||||
delete skeleton;
|
||||
skeleton = nullptr;
|
||||
}
|
||||
|
||||
trackEntries.Empty();
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::FinishDestroy() {
|
||||
DisposeState();
|
||||
Super::FinishDestroy();
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::SetAutoPlay(bool bInAutoPlays) {
|
||||
bAutoPlaying = bInAutoPlays;
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::SetPlaybackTime(float InPlaybackTime, bool bCallDelegates) {
|
||||
CheckState();
|
||||
|
||||
if (state && state->getCurrent(0)) {
|
||||
spine::Animation *CurrentAnimation = state->getCurrent(0)->getAnimation();
|
||||
const float CurrentTime = state->getCurrent(0)->getTrackTime();
|
||||
InPlaybackTime = FMath::Clamp(InPlaybackTime, 0.0f, CurrentAnimation->getDuration());
|
||||
const float DeltaTime = InPlaybackTime - CurrentTime;
|
||||
state->update(DeltaTime);
|
||||
state->apply(*skeleton);
|
||||
|
||||
//Call delegates and perform the world transform
|
||||
if (bCallDelegates) {
|
||||
BeforeUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
skeleton->updateWorldTransform(Physics_Update);
|
||||
if (bCallDelegates) {
|
||||
AfterUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::SetTimeScale(float timeScale) {
|
||||
CheckState();
|
||||
if (state) state->setTimeScale(timeScale);
|
||||
}
|
||||
|
||||
float USpineSkeletonAnimationComponent::GetTimeScale() {
|
||||
CheckState();
|
||||
if (state) return state->getTimeScale();
|
||||
return 1;
|
||||
}
|
||||
|
||||
UTrackEntry *USpineSkeletonAnimationComponent::SetAnimation(int trackIndex, FString animationName, bool loop) {
|
||||
CheckState();
|
||||
if (state && skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*animationName))) {
|
||||
state->disableQueue();
|
||||
TrackEntry *entry = state->setAnimation(trackIndex, TCHAR_TO_UTF8(*animationName), loop);
|
||||
state->enableQueue();
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry *USpineSkeletonAnimationComponent::AddAnimation(int trackIndex, FString animationName, bool loop, float delay) {
|
||||
CheckState();
|
||||
if (state && skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*animationName))) {
|
||||
state->disableQueue();
|
||||
TrackEntry *entry = state->addAnimation(trackIndex, TCHAR_TO_UTF8(*animationName), loop, delay);
|
||||
state->enableQueue();
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry *USpineSkeletonAnimationComponent::SetEmptyAnimation(int trackIndex, float mixDuration) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
TrackEntry *entry = state->setEmptyAnimation(trackIndex, mixDuration);
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry *USpineSkeletonAnimationComponent::AddEmptyAnimation(int trackIndex, float mixDuration, float delay) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
TrackEntry *entry = state->addEmptyAnimation(trackIndex, mixDuration, delay);
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry *USpineSkeletonAnimationComponent::GetCurrent(int trackIndex) {
|
||||
CheckState();
|
||||
if (state && state->getCurrent(trackIndex)) {
|
||||
TrackEntry *entry = state->getCurrent(trackIndex);
|
||||
if (entry->getRendererObject()) {
|
||||
return (UTrackEntry *) entry->getRendererObject();
|
||||
} else {
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
}
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::ClearTracks() {
|
||||
CheckState();
|
||||
if (state) {
|
||||
state->clearTracks();
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::ClearTrack(int trackIndex) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
state->clearTrack(trackIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::SetPhysicsTimeScale(float scale) {
|
||||
physicsTimeScale = scale;
|
||||
}
|
||||
|
||||
float USpineSkeletonAnimationComponent::GetPhysicsTimeScale() {
|
||||
return physicsTimeScale;
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,376 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineSkeletonComponent.h"
|
||||
#include "SpineSkeletonRendererComponent.h"
|
||||
#include "SpineAtlasAsset.h"
|
||||
|
||||
#include "spine/spine.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
using namespace spine;
|
||||
|
||||
USpineSkeletonComponent::USpineSkeletonComponent() {
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::SetSkins(UPARAM(ref) TArray<FString> &SkinNames) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
spine::Skin *newSkin = new spine::Skin("__spine-ue3_custom_skin");
|
||||
for (auto &skinName : SkinNames) {
|
||||
spine::Skin *skin = skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName));
|
||||
if (!skin) {
|
||||
delete newSkin;
|
||||
return false;
|
||||
}
|
||||
newSkin->addSkin(skin);
|
||||
}
|
||||
skeleton->setSkin(newSkin);
|
||||
if (customSkin != nullptr) {
|
||||
delete customSkin;
|
||||
}
|
||||
customSkin = newSkin;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::SetSkin(const FString skinName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Skin *skin = skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName));
|
||||
if (!skin) return false;
|
||||
skeleton->setSkin(skin);
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::GetSkins(TArray<FString> &Skins) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getData()->getSkins().size(); i < n; i++) {
|
||||
Skins.Add(skeleton->getData()->getSkins()[i]->getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::HasSkin(const FString skinName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::SetAttachment(const FString slotName, const FString attachmentName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
if (attachmentName.IsEmpty()) {
|
||||
skeleton->setAttachment(TCHAR_TO_UTF8(*slotName), NULL);
|
||||
return true;
|
||||
}
|
||||
if (!skeleton->getAttachment(TCHAR_TO_UTF8(*slotName), TCHAR_TO_UTF8(*attachmentName))) return false;
|
||||
skeleton->setAttachment(TCHAR_TO_UTF8(*slotName), TCHAR_TO_UTF8(*attachmentName));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FTransform USpineSkeletonComponent::GetBoneWorldTransform(const FString &BoneName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Bone *bone = skeleton->findBone(TCHAR_TO_UTF8(*BoneName));
|
||||
if (!bone) return FTransform();
|
||||
|
||||
// Need to fetch the renderer component to get world transform of actor plus
|
||||
// offset by renderer component and its parent component(s). If no renderer
|
||||
// component is found, this components owner's transform is used as a fallback
|
||||
FTransform baseTransform;
|
||||
AActor *owner = GetOwner();
|
||||
if (owner) {
|
||||
USpineSkeletonRendererComponent *rendererComponent = static_cast<USpineSkeletonRendererComponent *>(owner->GetComponentByClass(USpineSkeletonRendererComponent::StaticClass()));
|
||||
if (rendererComponent) baseTransform = rendererComponent->GetComponentTransform();
|
||||
else
|
||||
baseTransform = owner->GetActorTransform();
|
||||
}
|
||||
|
||||
FVector position(bone->getWorldX(), 0, bone->getWorldY());
|
||||
FMatrix localTransform;
|
||||
localTransform.SetIdentity();
|
||||
localTransform.SetAxis(2, FVector(bone->getA(), 0, bone->getC()));
|
||||
localTransform.SetAxis(0, FVector(bone->getB(), 0, bone->getD()));
|
||||
localTransform.SetOrigin(FVector(bone->getWorldX(), 0, bone->getWorldY()));
|
||||
localTransform = localTransform * baseTransform.ToMatrixWithScale();
|
||||
|
||||
FTransform result;
|
||||
result.SetFromMatrix(localTransform);
|
||||
return result;
|
||||
}
|
||||
return FTransform();
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetBoneWorldPosition(const FString &BoneName, const FVector &position) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Bone *bone = skeleton->findBone(TCHAR_TO_UTF8(*BoneName));
|
||||
if (!bone) return;
|
||||
|
||||
// Need to fetch the renderer component to get world transform of actor plus
|
||||
// offset by renderer component and its parent component(s). If no renderer
|
||||
// component is found, this components owner's transform is used as a fallback
|
||||
FTransform baseTransform;
|
||||
AActor *owner = GetOwner();
|
||||
if (owner) {
|
||||
USpineSkeletonRendererComponent *rendererComponent = static_cast<USpineSkeletonRendererComponent *>(owner->GetComponentByClass(USpineSkeletonRendererComponent::StaticClass()));
|
||||
if (rendererComponent) baseTransform = rendererComponent->GetComponentTransform();
|
||||
else
|
||||
baseTransform = owner->GetActorTransform();
|
||||
}
|
||||
|
||||
baseTransform = baseTransform.Inverse();
|
||||
FVector localPosition = baseTransform.TransformPosition(position);
|
||||
float localX = 0, localY = 0;
|
||||
if (bone->getParent()) {
|
||||
bone->getParent()->worldToLocal(localPosition.X, localPosition.Z, localX, localY);
|
||||
} else {
|
||||
bone->worldToLocal(localPosition.X, localPosition.Z, localX, localY);
|
||||
}
|
||||
bone->setX(localX);
|
||||
bone->setY(localY);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::UpdateWorldTransform() {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
skeleton->updateWorldTransform(Physics_Update);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetToSetupPose() {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setToSetupPose();
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetBonesToSetupPose() {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setBonesToSetupPose();
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetSlotsToSetupPose() {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setSlotsToSetupPose();
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetScaleX(float scaleX) {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setScaleX(scaleX);
|
||||
}
|
||||
|
||||
float USpineSkeletonComponent::GetScaleX() {
|
||||
CheckState();
|
||||
if (skeleton) return skeleton->getScaleX();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetScaleY(float scaleY) {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setScaleY(scaleY);
|
||||
}
|
||||
|
||||
float USpineSkeletonComponent::GetScaleY() {
|
||||
CheckState();
|
||||
if (skeleton) return skeleton->getScaleY();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::GetBones(TArray<FString> &Bones) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getBones().size(); i < n; i++) {
|
||||
Bones.Add(skeleton->getBones()[i]->getData().getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::HasBone(const FString BoneName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findBone(TCHAR_TO_UTF8(*BoneName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::GetSlots(TArray<FString> &Slots) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getSlots().size(); i < n; i++) {
|
||||
Slots.Add(skeleton->getSlots()[i]->getData().getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::HasSlot(const FString SlotName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findSlot(TCHAR_TO_UTF8(*SlotName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetSlotColor(const FString SlotName, const FColor color) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Slot *slot = skeleton->findSlot(TCHAR_TO_UTF8(*SlotName));
|
||||
if (slot) {
|
||||
slot->getColor().set(color.R / 255.f, color.G / 255.f, color.B / 255.f, color.A / 255.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::GetAnimations(TArray<FString> &Animations) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getData()->getAnimations().size(); i < n; i++) {
|
||||
Animations.Add(skeleton->getData()->getAnimations()[i]->getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::HasAnimation(FString AnimationName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*AnimationName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float USpineSkeletonComponent::GetAnimationDuration(FString AnimationName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Animation *animation = skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*AnimationName));
|
||||
if (animation == nullptr) return 0;
|
||||
else
|
||||
return animation->getDuration();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::PhysicsTranslate(float x, float y) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
skeleton->physicsTranslate(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::PhysicsRotate(float x, float y, float degrees) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
skeleton->physicsRotate(x, y, degrees);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::ResetPhysicsConstraints() {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Vector<PhysicsConstraint *> &constraints = skeleton->getPhysicsConstraints();
|
||||
for (int i = 0, n = (int) constraints.size(); i < n; i++) {
|
||||
constraints[i]->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) {
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
InternalTick(DeltaTime);
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::InternalTick(float DeltaTime, bool CallDelegates, bool Preview) {
|
||||
CheckState();
|
||||
|
||||
if (skeleton) {
|
||||
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||
skeleton->updateWorldTransform(Physics_Update);
|
||||
if (CallDelegates) AfterUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::CheckState() {
|
||||
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();
|
||||
|
||||
if (Atlas && SkeletonData) {
|
||||
spine::SkeletonData *data = SkeletonData->GetSkeletonData(Atlas->GetAtlas());
|
||||
skeleton = new (__FILE__, __LINE__) Skeleton(data);
|
||||
}
|
||||
|
||||
lastAtlas = Atlas;
|
||||
lastSpineAtlas = Atlas ? Atlas->GetAtlas() : nullptr;
|
||||
lastData = SkeletonData;
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::DisposeState() {
|
||||
if (skeleton) {
|
||||
delete skeleton;
|
||||
skeleton = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::FinishDestroy() {
|
||||
DisposeState();
|
||||
Super::FinishDestroy();
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,404 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineSkeletonDataAsset.h"
|
||||
#include "EditorFramework/AssetImportData.h"
|
||||
#include "Runtime/Core/Public/Misc/MessageDialog.h"
|
||||
#include "SpinePlugin.h"
|
||||
#include "spine/Version.h"
|
||||
#include "spine/spine.h"
|
||||
#include <string>
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
using namespace spine;
|
||||
|
||||
FName USpineSkeletonDataAsset::GetSkeletonDataFileName() const {
|
||||
#if WITH_EDITORONLY_DATA
|
||||
TArray<FString> files;
|
||||
if (importData)
|
||||
importData->ExtractFilenames(files);
|
||||
if (files.Num() > 0)
|
||||
return FName(*files[0]);
|
||||
else
|
||||
return skeletonDataFileName;
|
||||
#else
|
||||
return skeletonDataFileName;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::PostInitProperties() {
|
||||
if (!HasAnyFlags(RF_ClassDefaultObject))
|
||||
importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
|
||||
Super::PostInitProperties();
|
||||
}
|
||||
|
||||
#if ((ENGINE_MAJOR_VERSION >= 5) && (ENGINE_MINOR_VERSION >= 4))
|
||||
void USpineSkeletonDataAsset::GetAssetRegistryTags(FAssetRegistryTagsContext Context) const {
|
||||
if (importData) {
|
||||
Context.AddTag(FAssetRegistryTag(SourceFileTagName(), importData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden));
|
||||
}
|
||||
Super::GetAssetRegistryTags(Context);
|
||||
}
|
||||
#else
|
||||
void USpineSkeletonDataAsset::GetAssetRegistryTags(
|
||||
TArray<FAssetRegistryTag> &OutTags) const {
|
||||
if (importData) {
|
||||
OutTags.Add(FAssetRegistryTag(SourceFileTagName(),
|
||||
importData->GetSourceData().ToJson(),
|
||||
FAssetRegistryTag::TT_Hidden));
|
||||
}
|
||||
|
||||
Super::GetAssetRegistryTags(OutTags);
|
||||
}
|
||||
#endif
|
||||
|
||||
void USpineSkeletonDataAsset::Serialize(FArchive &Ar) {
|
||||
Super::Serialize(Ar);
|
||||
#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION <= 27
|
||||
if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData)
|
||||
#else
|
||||
if (Ar.IsLoading() && Ar.UEVer() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData)
|
||||
#endif
|
||||
importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
|
||||
LoadInfo();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void USpineSkeletonDataAsset::ClearNativeData() {
|
||||
for (auto &pair : atlasToNativeData) {
|
||||
if (pair.Value.skeletonData)
|
||||
delete pair.Value.skeletonData;
|
||||
if (pair.Value.animationStateData)
|
||||
delete pair.Value.animationStateData;
|
||||
}
|
||||
atlasToNativeData.Empty();
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::BeginDestroy() {
|
||||
ClearNativeData();
|
||||
|
||||
Super::BeginDestroy();
|
||||
}
|
||||
|
||||
class SP_API NullAttachmentLoader : public AttachmentLoader {
|
||||
public:
|
||||
virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &name,
|
||||
const String &path,
|
||||
Sequence *sequence) {
|
||||
return new (__FILE__, __LINE__) RegionAttachment(name);
|
||||
}
|
||||
|
||||
virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &name,
|
||||
const String &path,
|
||||
Sequence *sequence) {
|
||||
return new (__FILE__, __LINE__) MeshAttachment(name);
|
||||
}
|
||||
|
||||
virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin,
|
||||
const String &name) {
|
||||
return new (__FILE__, __LINE__) BoundingBoxAttachment(name);
|
||||
}
|
||||
|
||||
virtual PathAttachment *newPathAttachment(Skin &skin, const String &name) {
|
||||
return new (__FILE__, __LINE__) PathAttachment(name);
|
||||
}
|
||||
|
||||
virtual PointAttachment *newPointAttachment(Skin &skin, const String &name) {
|
||||
return new (__FILE__, __LINE__) PointAttachment(name);
|
||||
}
|
||||
|
||||
virtual ClippingAttachment *newClippingAttachment(Skin &skin,
|
||||
const String &name) {
|
||||
return new (__FILE__, __LINE__) ClippingAttachment(name);
|
||||
}
|
||||
|
||||
virtual void configureAttachment(Attachment *attachment) {}
|
||||
};
|
||||
|
||||
void USpineSkeletonDataAsset::SetRawData(TArray<uint8> &Data) {
|
||||
this->rawData.Empty();
|
||||
this->rawData.Append(Data);
|
||||
|
||||
ClearNativeData();
|
||||
|
||||
LoadInfo();
|
||||
}
|
||||
|
||||
static bool checkVersion(const char *version) {
|
||||
if (!version)
|
||||
return false;
|
||||
char *result = (char *) (strstr(version, SPINE_VERSION_STRING) - version);
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
static bool checkJson(const char *jsonData) {
|
||||
Json json(jsonData);
|
||||
Json *skeleton = Json::getItem(&json, "skeleton");
|
||||
if (!skeleton)
|
||||
return false;
|
||||
const char *version = Json::getString(skeleton, "spine", 0);
|
||||
if (!version)
|
||||
return false;
|
||||
|
||||
return checkVersion(version);
|
||||
}
|
||||
|
||||
struct BinaryInput {
|
||||
const unsigned char *cursor;
|
||||
const unsigned char *end;
|
||||
};
|
||||
|
||||
static unsigned char readByte(BinaryInput *input) { return *input->cursor++; }
|
||||
|
||||
static int readVarint(BinaryInput *input, bool optimizePositive) {
|
||||
unsigned char b = readByte(input);
|
||||
int value = b & 0x7F;
|
||||
if (b & 0x80) {
|
||||
b = readByte(input);
|
||||
value |= (b & 0x7F) << 7;
|
||||
if (b & 0x80) {
|
||||
b = readByte(input);
|
||||
value |= (b & 0x7F) << 14;
|
||||
if (b & 0x80) {
|
||||
b = readByte(input);
|
||||
value |= (b & 0x7F) << 21;
|
||||
if (b & 0x80)
|
||||
value |= (readByte(input) & 0x7F) << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!optimizePositive) {
|
||||
value = (((unsigned int) value >> 1) ^ -(value & 1));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static char *readString(BinaryInput *input) {
|
||||
int length = readVarint(input, true);
|
||||
char *string;
|
||||
if (length == 0) {
|
||||
return NULL;
|
||||
}
|
||||
string = SpineExtension::alloc<char>(length, __FILE__, __LINE__);
|
||||
memcpy(string, input->cursor, length - 1);
|
||||
input->cursor += length - 1;
|
||||
string[length - 1] = '\0';
|
||||
return string;
|
||||
}
|
||||
|
||||
static bool checkBinary(const char *binaryData, int length) {
|
||||
BinaryInput input;
|
||||
input.cursor = (const unsigned char *) binaryData;
|
||||
input.end = (const unsigned char *) binaryData + length;
|
||||
// Skip hash
|
||||
input.cursor += 8;
|
||||
char *version = readString(&input);
|
||||
bool result = checkVersion(version);
|
||||
SpineExtension::free(version, __FILE__, __LINE__);
|
||||
return result;
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::LoadInfo() {
|
||||
#if WITH_EDITORONLY_DATA
|
||||
int dataLen = rawData.Num();
|
||||
if (dataLen == 0)
|
||||
return;
|
||||
NullAttachmentLoader loader;
|
||||
SkeletonData *skeletonData = nullptr;
|
||||
if (skeletonDataFileName.GetPlainNameString().Contains(TEXT(".json"))) {
|
||||
SkeletonJson *json = new (__FILE__, __LINE__) SkeletonJson(&loader);
|
||||
if (checkJson((const char *) rawData.GetData()))
|
||||
skeletonData = json->readSkeletonData((const char *) rawData.GetData());
|
||||
if (!skeletonData) {
|
||||
FMessageDialog::Debugf(FText::FromString(
|
||||
FString("Couldn't load skeleton data and/or atlas. Please ensure the "
|
||||
"version of your exported data matches your runtime "
|
||||
"version.\n\n") +
|
||||
skeletonDataFileName.GetPlainNameString() + FString("\n\n") +
|
||||
UTF8_TO_TCHAR(json->getError().buffer())));
|
||||
UE_LOG(SpineLog, Error, TEXT("Couldn't load skeleton data and atlas: %s"),
|
||||
UTF8_TO_TCHAR(json->getError().buffer()));
|
||||
}
|
||||
delete json;
|
||||
} else {
|
||||
SkeletonBinary *binary = new (__FILE__, __LINE__) SkeletonBinary(&loader);
|
||||
if (checkBinary((const char *) rawData.GetData(), (int) rawData.Num()))
|
||||
skeletonData = binary->readSkeletonData(
|
||||
(const unsigned char *) rawData.GetData(), (int) rawData.Num());
|
||||
if (!skeletonData) {
|
||||
FMessageDialog::Debugf(FText::FromString(
|
||||
FString("Couldn't load skeleton data and/or atlas. Please ensure the "
|
||||
"version of your exported data matches your runtime "
|
||||
"version.\n\n") +
|
||||
skeletonDataFileName.GetPlainNameString() + FString("\n\n") +
|
||||
UTF8_TO_TCHAR(binary->getError().buffer())));
|
||||
UE_LOG(SpineLog, Error, TEXT("Couldn't load skeleton data and atlas: %s"),
|
||||
UTF8_TO_TCHAR(binary->getError().buffer()));
|
||||
}
|
||||
delete binary;
|
||||
}
|
||||
if (skeletonData) {
|
||||
Bones.Empty();
|
||||
for (int i = 0; i < skeletonData->getBones().size(); i++)
|
||||
Bones.Add(UTF8_TO_TCHAR(skeletonData->getBones()[i]->getName().buffer()));
|
||||
Skins.Empty();
|
||||
for (int i = 0; i < skeletonData->getSkins().size(); i++)
|
||||
Skins.Add(UTF8_TO_TCHAR(skeletonData->getSkins()[i]->getName().buffer()));
|
||||
Slots.Empty();
|
||||
for (int i = 0; i < skeletonData->getSlots().size(); i++)
|
||||
Slots.Add(UTF8_TO_TCHAR(skeletonData->getSlots()[i]->getName().buffer()));
|
||||
Animations.Empty();
|
||||
for (int i = 0; i < skeletonData->getAnimations().size(); i++)
|
||||
Animations.Add(
|
||||
UTF8_TO_TCHAR(skeletonData->getAnimations()[i]->getName().buffer()));
|
||||
Events.Empty();
|
||||
for (int i = 0; i < skeletonData->getEvents().size(); i++)
|
||||
Events.Add(
|
||||
UTF8_TO_TCHAR(skeletonData->getEvents()[i]->getName().buffer()));
|
||||
delete skeletonData;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SkeletonData *USpineSkeletonDataAsset::GetSkeletonData(Atlas *Atlas) {
|
||||
SkeletonData *skeletonData = nullptr;
|
||||
AnimationStateData *animationStateData = nullptr;
|
||||
if (atlasToNativeData.Contains(Atlas)) {
|
||||
skeletonData = atlasToNativeData[Atlas].skeletonData;
|
||||
animationStateData = atlasToNativeData[Atlas].animationStateData;
|
||||
}
|
||||
|
||||
if (!skeletonData) {
|
||||
int dataLen = rawData.Num();
|
||||
if (skeletonDataFileName.GetPlainNameString().Contains(TEXT(".json"))) {
|
||||
SkeletonJson *json = new (__FILE__, __LINE__) SkeletonJson(Atlas);
|
||||
if (checkJson((const char *) rawData.GetData()))
|
||||
skeletonData = json->readSkeletonData((const char *) rawData.GetData());
|
||||
if (!skeletonData) {
|
||||
#if WITH_EDITORONLY_DATA
|
||||
FMessageDialog::Debugf(FText::FromString(
|
||||
FString("Couldn't load skeleton data and/or atlas. Please ensure "
|
||||
"the version of your exported data matches your runtime "
|
||||
"version.\n\n") +
|
||||
skeletonDataFileName.GetPlainNameString() + FString("\n\n") +
|
||||
UTF8_TO_TCHAR(json->getError().buffer())));
|
||||
#endif
|
||||
UE_LOG(SpineLog, Error,
|
||||
TEXT("Couldn't load skeleton data and atlas: %s"),
|
||||
UTF8_TO_TCHAR(json->getError().buffer()));
|
||||
}
|
||||
delete json;
|
||||
} else {
|
||||
SkeletonBinary *binary = new (__FILE__, __LINE__) SkeletonBinary(Atlas);
|
||||
if (checkBinary((const char *) rawData.GetData(), (int) rawData.Num()))
|
||||
skeletonData = binary->readSkeletonData(
|
||||
(const unsigned char *) rawData.GetData(), (int) rawData.Num());
|
||||
if (!skeletonData) {
|
||||
#if WITH_EDITORONLY_DATA
|
||||
FMessageDialog::Debugf(FText::FromString(
|
||||
FString("Couldn't load skeleton data and/or atlas. Please ensure "
|
||||
"the version of your exported data matches your runtime "
|
||||
"version.\n\n") +
|
||||
skeletonDataFileName.GetPlainNameString() + FString("\n\n") +
|
||||
UTF8_TO_TCHAR(binary->getError().buffer())));
|
||||
#endif
|
||||
UE_LOG(SpineLog, Error,
|
||||
TEXT("Couldn't load skeleton data and atlas: %s"),
|
||||
UTF8_TO_TCHAR(binary->getError().buffer()));
|
||||
}
|
||||
delete binary;
|
||||
}
|
||||
|
||||
if (skeletonData) {
|
||||
animationStateData =
|
||||
new (__FILE__, __LINE__) AnimationStateData(skeletonData);
|
||||
SetMixes(animationStateData);
|
||||
atlasToNativeData.Add(Atlas, {skeletonData, animationStateData});
|
||||
}
|
||||
}
|
||||
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::SetMixes(AnimationStateData *animationStateData) {
|
||||
for (auto &data : MixData) {
|
||||
if (!data.From.IsEmpty() && !data.To.IsEmpty()) {
|
||||
std::string fromChar = TCHAR_TO_UTF8(*data.From);
|
||||
std::string toChar = TCHAR_TO_UTF8(*data.To);
|
||||
animationStateData->setMix(fromChar.c_str(), toChar.c_str(), data.Mix);
|
||||
}
|
||||
}
|
||||
animationStateData->setDefaultMix(DefaultMix);
|
||||
}
|
||||
|
||||
AnimationStateData *
|
||||
USpineSkeletonDataAsset::GetAnimationStateData(Atlas *atlas) {
|
||||
if (!atlasToNativeData.Contains(atlas))
|
||||
return nullptr;
|
||||
AnimationStateData *data = atlasToNativeData[atlas].animationStateData;
|
||||
SetMixes(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::SetMix(const FString &from, const FString &to,
|
||||
float mix) {
|
||||
FSpineAnimationStateMixData data;
|
||||
data.From = from;
|
||||
data.To = to;
|
||||
data.Mix = mix;
|
||||
this->MixData.Add(data);
|
||||
for (auto &pair : atlasToNativeData) {
|
||||
SetMixes(pair.Value.animationStateData);
|
||||
}
|
||||
}
|
||||
|
||||
float USpineSkeletonDataAsset::GetMix(const FString &from, const FString &to) {
|
||||
for (auto &data : MixData) {
|
||||
if (data.From.Equals(from) && data.To.Equals(to))
|
||||
return data.Mix;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@ -0,0 +1,360 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineSkeletonRendererComponent.h"
|
||||
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include "Materials/MaterialInstanceDynamic.h"
|
||||
#include "spine/spine.h"
|
||||
#include "UObject/ConstructorHelpers.h"
|
||||
#if ENGINE_MAJOR_VERSION >= 5
|
||||
#include "PhysicsEngine/BodySetup.h"
|
||||
#endif
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
using namespace spine;
|
||||
|
||||
USpineSkeletonRendererComponent::USpineSkeletonRendererComponent(const FObjectInitializer &ObjectInitializer)
|
||||
: UProceduralMeshComponent(ObjectInitializer) {
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> NormalMaterialRef(TEXT("/SpinePlugin/SpineUnlitNormalMaterial"));
|
||||
NormalBlendMaterial = NormalMaterialRef.Object;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> AdditiveMaterialRef(TEXT("/SpinePlugin/SpineUnlitAdditiveMaterial"));
|
||||
AdditiveBlendMaterial = AdditiveMaterialRef.Object;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> MultiplyMaterialRef(TEXT("/SpinePlugin/SpineUnlitMultiplyMaterial"));
|
||||
MultiplyBlendMaterial = MultiplyMaterialRef.Object;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> ScreenMaterialRef(TEXT("/SpinePlugin/SpineUnlitScreenMaterial"));
|
||||
ScreenBlendMaterial = ScreenMaterialRef.Object;
|
||||
|
||||
TextureParameterName = FName(TEXT("SpriteTexture"));
|
||||
|
||||
worldVertices.ensureCapacity(1024 * 2);
|
||||
|
||||
SetTickGroup(TG_EndPhysics);
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::FinishDestroy() {
|
||||
Super::FinishDestroy();
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) {
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
AActor *owner = GetOwner();
|
||||
if (owner) {
|
||||
UClass *skeletonClass = USpineSkeletonComponent::StaticClass();
|
||||
USpineSkeletonComponent *skeletonComponent = Cast<USpineSkeletonComponent>(owner->GetComponentByClass(skeletonClass));
|
||||
|
||||
UpdateRenderer(skeletonComponent);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::UpdateRenderer(USpineSkeletonComponent *component) {
|
||||
if (component && !component->IsBeingDestroyed() && component->GetSkeleton() && component->Atlas) {
|
||||
component->GetSkeleton()->getColor().set(Color.R, Color.G, Color.B, Color.A);
|
||||
|
||||
if (atlasNormalBlendMaterials.Num() != component->Atlas->atlasPages.Num()) {
|
||||
atlasNormalBlendMaterials.SetNum(0);
|
||||
atlasAdditiveBlendMaterials.SetNum(0);
|
||||
atlasMultiplyBlendMaterials.SetNum(0);
|
||||
atlasScreenBlendMaterials.SetNum(0);
|
||||
|
||||
for (int i = 0; i < component->Atlas->atlasPages.Num(); i++) {
|
||||
AtlasPage *currPage = component->Atlas->GetAtlas()->getPages()[i];
|
||||
|
||||
UMaterialInstanceDynamic *material = UMaterialInstanceDynamic::Create(NormalBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, component->Atlas->atlasPages[i]);
|
||||
atlasNormalBlendMaterials.Add(material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(AdditiveBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, component->Atlas->atlasPages[i]);
|
||||
atlasAdditiveBlendMaterials.Add(material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(MultiplyBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, component->Atlas->atlasPages[i]);
|
||||
atlasMultiplyBlendMaterials.Add(material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(ScreenBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, component->Atlas->atlasPages[i]);
|
||||
atlasScreenBlendMaterials.Add(material);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < component->Atlas->atlasPages.Num(); i++) {
|
||||
UTexture2D *texture = component->Atlas->atlasPages[i];
|
||||
UpdateMaterial(texture, atlasNormalBlendMaterials[i], NormalBlendMaterial);
|
||||
UpdateMaterial(texture, atlasAdditiveBlendMaterials[i], AdditiveBlendMaterial);
|
||||
UpdateMaterial(texture, atlasMultiplyBlendMaterials[i], MultiplyBlendMaterial);
|
||||
UpdateMaterial(texture, atlasScreenBlendMaterials[i], ScreenBlendMaterial);
|
||||
}
|
||||
}
|
||||
UpdateMesh(component, component->GetSkeleton());
|
||||
} else {
|
||||
ClearAllMeshSections();
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::UpdateMaterial(UTexture2D *Texture, UMaterialInstanceDynamic *&CurrentInstance, UMaterialInterface *ParentMaterial) {
|
||||
|
||||
UTexture *oldTexture = nullptr;
|
||||
if (!CurrentInstance || !CurrentInstance->GetTextureParameterValue(TextureParameterName, oldTexture) ||
|
||||
oldTexture != Texture || CurrentInstance->Parent != ParentMaterial) {
|
||||
|
||||
UMaterialInstanceDynamic *material = UMaterialInstanceDynamic::Create(ParentMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, Texture);
|
||||
CurrentInstance = material;
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::Flush(int &Idx, TArray<FVector> &Vertices, TArray<int32> &Indices, TArray<FVector> &Normals, TArray<FVector2D> &Uvs, TArray<FColor> &Colors, UMaterialInstanceDynamic *Material) {
|
||||
if (Vertices.Num() == 0) return;
|
||||
SetMaterial(Idx, Material);
|
||||
|
||||
bool bShouldCreateCollision = false;
|
||||
if (bCreateCollision) {
|
||||
UWorld *world = GetWorld();
|
||||
if (world && world->IsGameWorld()) {
|
||||
bShouldCreateCollision = true;
|
||||
}
|
||||
}
|
||||
|
||||
GetBodySetup()->bGenerateMirroredCollision = GetComponentScale().X < 0 || GetComponentScale().Y < 0 || GetComponentScale().Z < 0;
|
||||
CreateMeshSection(Idx, Vertices, Indices, Normals, Uvs, Colors, TArray<FProcMeshTangent>(), bShouldCreateCollision);
|
||||
|
||||
Vertices.SetNum(0);
|
||||
Indices.SetNum(0);
|
||||
Normals.SetNum(0);
|
||||
Uvs.SetNum(0);
|
||||
Colors.SetNum(0);
|
||||
Idx++;
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::UpdateMesh(USpineSkeletonComponent *component, Skeleton *Skeleton) {
|
||||
vertices.Empty();
|
||||
indices.Empty();
|
||||
normals.Empty();
|
||||
uvs.Empty();
|
||||
colors.Empty();
|
||||
|
||||
int idx = 0;
|
||||
int meshSection = 0;
|
||||
UMaterialInstanceDynamic *lastMaterial = nullptr;
|
||||
|
||||
ClearAllMeshSections();
|
||||
|
||||
// Early out if skeleton is invisible
|
||||
if (Skeleton->getColor().a == 0) return;
|
||||
|
||||
float depthOffset = 0;
|
||||
unsigned short quadIndices[] = {0, 1, 2, 0, 2, 3};
|
||||
|
||||
for (size_t i = 0; i < Skeleton->getSlots().size(); ++i) {
|
||||
Vector<float> *attachmentVertices = &worldVertices;
|
||||
unsigned short *attachmentIndices = nullptr;
|
||||
int numVertices;
|
||||
int numIndices;
|
||||
AtlasRegion *attachmentAtlasRegion = nullptr;
|
||||
spine::Color attachmentColor;
|
||||
attachmentColor.set(1, 1, 1, 1);
|
||||
float *attachmentUvs = nullptr;
|
||||
|
||||
Slot *slot = Skeleton->getDrawOrder()[i];
|
||||
Attachment *attachment = slot->getAttachment();
|
||||
|
||||
if (slot->getColor().a == 0 || !slot->getBone().isActive()) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!attachment) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
if (!attachment->getRTTI().isExactly(RegionAttachment::rtti) && !attachment->getRTTI().isExactly(MeshAttachment::rtti) && !attachment->getRTTI().isExactly(ClippingAttachment::rtti)) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
|
||||
RegionAttachment *regionAttachment = (RegionAttachment *) attachment;
|
||||
|
||||
// Early out if region is invisible
|
||||
if (regionAttachment->getColor().a == 0) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
attachmentColor.set(regionAttachment->getColor());
|
||||
attachmentVertices->setSize(8, 0);
|
||||
regionAttachment->computeWorldVertices(*slot, *attachmentVertices, 0, 2);
|
||||
attachmentAtlasRegion = (AtlasRegion *) regionAttachment->getRegion();
|
||||
attachmentIndices = quadIndices;
|
||||
attachmentUvs = regionAttachment->getUVs().buffer();
|
||||
numVertices = 4;
|
||||
numIndices = 6;
|
||||
} else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
|
||||
MeshAttachment *mesh = (MeshAttachment *) attachment;
|
||||
|
||||
// Early out if region is invisible
|
||||
if (mesh->getColor().a == 0) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
attachmentColor.set(mesh->getColor());
|
||||
attachmentVertices->setSize(mesh->getWorldVerticesLength(), 0);
|
||||
mesh->computeWorldVertices(*slot, 0, mesh->getWorldVerticesLength(), attachmentVertices->buffer(), 0, 2);
|
||||
attachmentAtlasRegion = (AtlasRegion *) mesh->getRegion();
|
||||
attachmentIndices = mesh->getTriangles().buffer();
|
||||
attachmentUvs = mesh->getUVs().buffer();
|
||||
numVertices = mesh->getWorldVerticesLength() >> 1;
|
||||
numIndices = mesh->getTriangles().size();
|
||||
} else /* clipping */ {
|
||||
ClippingAttachment *clip = (ClippingAttachment *) attachment;
|
||||
clipper.clipStart(*slot, clip);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (clipper.isClipping()) {
|
||||
clipper.clipTriangles(attachmentVertices->buffer(), attachmentIndices, numIndices, attachmentUvs, 2);
|
||||
attachmentVertices = &clipper.getClippedVertices();
|
||||
numVertices = clipper.getClippedVertices().size() >> 1;
|
||||
attachmentIndices = clipper.getClippedTriangles().buffer();
|
||||
numIndices = clipper.getClippedTriangles().size();
|
||||
attachmentUvs = clipper.getClippedUVs().buffer();
|
||||
if (clipper.getClippedTriangles().size() == 0) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// if the user switches the atlas data while not having switched
|
||||
// to the correct skeleton data yet, we won't find any regions.
|
||||
// ignore regions for which we can't find a material
|
||||
UMaterialInstanceDynamic *material = nullptr;
|
||||
int foundPageIndex = (int) (intptr_t) attachmentAtlasRegion->rendererObject;
|
||||
if (foundPageIndex == -1) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
switch (slot->getData().getBlendMode()) {
|
||||
case BlendMode_Additive:
|
||||
if (foundPageIndex >= atlasAdditiveBlendMaterials.Num()) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
material = atlasAdditiveBlendMaterials[foundPageIndex];
|
||||
break;
|
||||
case BlendMode_Multiply:
|
||||
if (foundPageIndex >= atlasMultiplyBlendMaterials.Num()) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
material = atlasMultiplyBlendMaterials[foundPageIndex];
|
||||
break;
|
||||
case BlendMode_Screen:
|
||||
if (foundPageIndex >= atlasScreenBlendMaterials.Num()) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
material = atlasScreenBlendMaterials[foundPageIndex];
|
||||
break;
|
||||
case BlendMode_Normal:
|
||||
default:
|
||||
if (foundPageIndex >= atlasNormalBlendMaterials.Num()) {
|
||||
clipper.clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
material = atlasNormalBlendMaterials[foundPageIndex];
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastMaterial != material) {
|
||||
Flush(meshSection, vertices, indices, normals, uvs, colors, lastMaterial);
|
||||
lastMaterial = material;
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
SetMaterial(meshSection, material);
|
||||
|
||||
uint8 r = static_cast<uint8>(Skeleton->getColor().r * slot->getColor().r * attachmentColor.r * 255);
|
||||
uint8 g = static_cast<uint8>(Skeleton->getColor().g * slot->getColor().g * attachmentColor.g * 255);
|
||||
uint8 b = static_cast<uint8>(Skeleton->getColor().b * slot->getColor().b * attachmentColor.b * 255);
|
||||
uint8 a = static_cast<uint8>(Skeleton->getColor().a * slot->getColor().a * attachmentColor.a * 255);
|
||||
|
||||
float *verticesPtr = attachmentVertices->buffer();
|
||||
for (int j = 0; j < numVertices << 1; j += 2) {
|
||||
colors.Add(FColor(r, g, b, a));
|
||||
vertices.Add(FVector(verticesPtr[j], depthOffset, verticesPtr[j + 1]));
|
||||
uvs.Add(FVector2D(attachmentUvs[j], attachmentUvs[j + 1]));
|
||||
}
|
||||
|
||||
for (int j = 0; j < numIndices; j++) {
|
||||
indices.Add(idx + attachmentIndices[j]);
|
||||
}
|
||||
|
||||
int numTriangles = indices.Num() / 3;
|
||||
for (int j = 0; j < numTriangles; j++) {
|
||||
const int triangleIndex = j * 3;
|
||||
if (FVector::CrossProduct(
|
||||
vertices[indices[triangleIndex + 2]] - vertices[indices[triangleIndex]],
|
||||
vertices[indices[triangleIndex + 1]] - vertices[indices[triangleIndex]])
|
||||
.Y < 0.f) {
|
||||
const int32 targetVertex = indices[triangleIndex];
|
||||
indices[triangleIndex] = indices[triangleIndex + 2];
|
||||
indices[triangleIndex + 2] = targetVertex;
|
||||
}
|
||||
}
|
||||
|
||||
FVector normal = FVector(0, 1, 0);
|
||||
for (int j = 0; j < numVertices; j++) {
|
||||
normals.Add(normal);
|
||||
}
|
||||
|
||||
idx += numVertices;
|
||||
depthOffset += this->DepthOffset;
|
||||
|
||||
clipper.clipEnd(*slot);
|
||||
}
|
||||
|
||||
Flush(meshSection, vertices, indices, normals, uvs, colors, lastMaterial);
|
||||
clipper.clipEnd();
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
564
Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp
Normal file
564
Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp
Normal file
@ -0,0 +1,564 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineWidget.h"
|
||||
#include "SSpineWidget.h"
|
||||
#include "SpineSkeletonAnimationComponent.h"
|
||||
#include "spine/spine.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
using namespace spine;
|
||||
|
||||
void callbackWidget(AnimationState *state, spine::EventType type, TrackEntry *entry, Event *event) {
|
||||
USpineWidget *component = (USpineWidget *) state->getRendererObject();
|
||||
|
||||
if (entry->getRendererObject()) {
|
||||
UTrackEntry *uEntry = (UTrackEntry *) entry->getRendererObject();
|
||||
if (type == EventType_Start) {
|
||||
component->AnimationStart.Broadcast(uEntry);
|
||||
uEntry->AnimationStart.Broadcast(uEntry);
|
||||
} else if (type == EventType_Interrupt) {
|
||||
component->AnimationInterrupt.Broadcast(uEntry);
|
||||
uEntry->AnimationInterrupt.Broadcast(uEntry);
|
||||
} else if (type == EventType_Event) {
|
||||
FSpineEvent evt;
|
||||
evt.SetEvent(event);
|
||||
component->AnimationEvent.Broadcast(uEntry, evt);
|
||||
uEntry->AnimationEvent.Broadcast(uEntry, evt);
|
||||
} else if (type == EventType_Complete) {
|
||||
component->AnimationComplete.Broadcast(uEntry);
|
||||
uEntry->AnimationComplete.Broadcast(uEntry);
|
||||
} else if (type == EventType_End) {
|
||||
component->AnimationEnd.Broadcast(uEntry);
|
||||
uEntry->AnimationEnd.Broadcast(uEntry);
|
||||
} else if (type == EventType_Dispose) {
|
||||
component->AnimationDispose.Broadcast(uEntry);
|
||||
uEntry->AnimationDispose.Broadcast(uEntry);
|
||||
uEntry->SetTrackEntry(nullptr);
|
||||
component->GCTrackEntry(uEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
USpineWidget::USpineWidget(const FObjectInitializer &ObjectInitializer) : Super(ObjectInitializer) {
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> NormalMaterialRef(TEXT("/SpinePlugin/UI_SpineUnlitNormalMaterial"));
|
||||
NormalBlendMaterial = NormalMaterialRef.Object;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> AdditiveMaterialRef(TEXT("/SpinePlugin/UI_SpineUnlitAdditiveMaterial"));
|
||||
AdditiveBlendMaterial = AdditiveMaterialRef.Object;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> MultiplyMaterialRef(TEXT("/SpinePlugin/UI_SpineUnlitMultiplyMaterial"));
|
||||
MultiplyBlendMaterial = MultiplyMaterialRef.Object;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> ScreenMaterialRef(TEXT("/SpinePlugin/UI_SpineUnlitScreenMaterial"));
|
||||
ScreenBlendMaterial = ScreenMaterialRef.Object;
|
||||
|
||||
TextureParameterName = FName(TEXT("SpriteTexture"));
|
||||
|
||||
physicsTimeScale = 1.0f;
|
||||
worldVertices.ensureCapacity(1024 * 2);
|
||||
|
||||
bAutoPlaying = true;
|
||||
}
|
||||
|
||||
void USpineWidget::SynchronizeProperties() {
|
||||
Super::SynchronizeProperties();
|
||||
|
||||
if (slateWidget.IsValid()) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
if (!bSkinInitialized) {// blueprint On Initialized may be called beforehand
|
||||
if (InitialSkin != "") SetSkin(InitialSkin);
|
||||
#if WITH_EDITOR
|
||||
if (IsDesignTime()) {
|
||||
if (InitialSkin == "") SetSkin("default");
|
||||
bSkinInitialized = false;// allow multiple edits in editor
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Tick(0, false);
|
||||
slateWidget->SetData(this);
|
||||
} else {
|
||||
slateWidget->SetData(nullptr);
|
||||
}
|
||||
for (UTrackEntry *entry : trackEntries) {
|
||||
if (entry && entry->GetTrackEntry()) {
|
||||
entry->GetTrackEntry()->setRendererObject(nullptr);
|
||||
}
|
||||
}
|
||||
trackEntries.Empty();
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::ReleaseSlateResources(bool bReleaseChildren) {
|
||||
Super::ReleaseSlateResources(bReleaseChildren);
|
||||
slateWidget.Reset();
|
||||
}
|
||||
|
||||
TSharedRef<SWidget> USpineWidget::RebuildWidget() {
|
||||
this->slateWidget = SNew(SSpineWidget);
|
||||
return this->slateWidget.ToSharedRef();
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
const FText USpineWidget::GetPaletteCategory() {
|
||||
return LOCTEXT("Spine", "Spine");
|
||||
}
|
||||
#endif
|
||||
|
||||
void USpineWidget::Tick(float DeltaTime, bool CallDelegates) {
|
||||
CheckState();
|
||||
|
||||
if (state && bAutoPlaying) {
|
||||
state->update(DeltaTime);
|
||||
state->apply(*skeleton);
|
||||
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||
skeleton->update(physicsTimeScale * DeltaTime);
|
||||
skeleton->updateWorldTransform(Physics_Update);
|
||||
if (CallDelegates) AfterUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::CheckState() {
|
||||
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();
|
||||
|
||||
if (Atlas && SkeletonData) {
|
||||
spine::SkeletonData *data = SkeletonData->GetSkeletonData(Atlas->GetAtlas());
|
||||
if (data) {
|
||||
skeleton = new (__FILE__, __LINE__) Skeleton(data);
|
||||
AnimationStateData *stateData = SkeletonData->GetAnimationStateData(Atlas->GetAtlas());
|
||||
state = new (__FILE__, __LINE__) AnimationState(stateData);
|
||||
state->setRendererObject((void *) this);
|
||||
state->setListener(callbackWidget);
|
||||
trackEntries.Empty();
|
||||
skeleton->setToSetupPose();
|
||||
skeleton->updateWorldTransform(Physics_Update);
|
||||
slateWidget->SetData(this);
|
||||
}
|
||||
}
|
||||
|
||||
lastAtlas = Atlas;
|
||||
lastSpineAtlas = Atlas ? Atlas->GetAtlas() : nullptr;
|
||||
lastData = SkeletonData;
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::DisposeState() {
|
||||
if (state) {
|
||||
delete state;
|
||||
state = nullptr;
|
||||
}
|
||||
|
||||
if (skeleton) {
|
||||
delete skeleton;
|
||||
skeleton = nullptr;
|
||||
}
|
||||
|
||||
if (customSkin) {
|
||||
delete customSkin;
|
||||
customSkin = nullptr;
|
||||
}
|
||||
|
||||
trackEntries.Empty();
|
||||
}
|
||||
|
||||
void USpineWidget::FinishDestroy() {
|
||||
DisposeState();
|
||||
Super::FinishDestroy();
|
||||
}
|
||||
|
||||
bool USpineWidget::SetSkin(const FString skinName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
spine::Skin *skin = skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName));
|
||||
if (!skin) return false;
|
||||
skeleton->setSkin(skin);
|
||||
bSkinInitialized = true;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool USpineWidget::SetSkins(UPARAM(ref) TArray<FString> &SkinNames) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
spine::Skin *newSkin = new spine::Skin("__spine-ue3_custom_skin");
|
||||
for (auto &skinName : SkinNames) {
|
||||
spine::Skin *skin = skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName));
|
||||
if (!skin) {
|
||||
delete newSkin;
|
||||
return false;
|
||||
}
|
||||
newSkin->addSkin(skin);
|
||||
}
|
||||
skeleton->setSkin(newSkin);
|
||||
bSkinInitialized = true;
|
||||
if (customSkin != nullptr) {
|
||||
delete customSkin;
|
||||
}
|
||||
customSkin = newSkin;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineWidget::GetSkins(TArray<FString> &Skins) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getData()->getSkins().size(); i < n; i++) {
|
||||
Skins.Add(skeleton->getData()->getSkins()[i]->getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineWidget::HasSkin(const FString skinName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool USpineWidget::SetAttachment(const FString slotName, const FString attachmentName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
if (attachmentName.IsEmpty()) {
|
||||
skeleton->setAttachment(TCHAR_TO_UTF8(*slotName), NULL);
|
||||
return true;
|
||||
}
|
||||
if (!skeleton->getAttachment(TCHAR_TO_UTF8(*slotName), TCHAR_TO_UTF8(*attachmentName))) return false;
|
||||
skeleton->setAttachment(TCHAR_TO_UTF8(*slotName), TCHAR_TO_UTF8(*attachmentName));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineWidget::UpdateWorldTransform() {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
skeleton->updateWorldTransform(Physics_Update);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::SetToSetupPose() {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setToSetupPose();
|
||||
}
|
||||
|
||||
void USpineWidget::SetBonesToSetupPose() {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setBonesToSetupPose();
|
||||
}
|
||||
|
||||
void USpineWidget::SetSlotsToSetupPose() {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setSlotsToSetupPose();
|
||||
}
|
||||
|
||||
void USpineWidget::SetScaleX(float scaleX) {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setScaleX(scaleX);
|
||||
}
|
||||
|
||||
float USpineWidget::GetScaleX() {
|
||||
CheckState();
|
||||
if (skeleton) return skeleton->getScaleX();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void USpineWidget::SetScaleY(float scaleY) {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setScaleY(scaleY);
|
||||
}
|
||||
|
||||
float USpineWidget::GetScaleY() {
|
||||
CheckState();
|
||||
if (skeleton) return skeleton->getScaleY();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void USpineWidget::GetBones(TArray<FString> &Bones) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getBones().size(); i < n; i++) {
|
||||
Bones.Add(skeleton->getBones()[i]->getData().getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineWidget::HasBone(const FString BoneName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findBone(TCHAR_TO_UTF8(*BoneName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FTransform USpineWidget::GetBoneTransform(const FString &BoneName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Bone *bone = skeleton->findBone(TCHAR_TO_UTF8(*BoneName));
|
||||
if (!bone) return FTransform();
|
||||
|
||||
FMatrix localTransform;
|
||||
localTransform.SetIdentity();
|
||||
localTransform.SetAxis(2, FVector(bone->getA(), 0, bone->getC()));
|
||||
localTransform.SetAxis(0, FVector(bone->getB(), 0, bone->getD()));
|
||||
localTransform.SetOrigin(FVector(bone->getWorldX(), 0, bone->getWorldY()));
|
||||
|
||||
FTransform result;
|
||||
result.SetFromMatrix(localTransform);
|
||||
return result;
|
||||
}
|
||||
return FTransform();
|
||||
}
|
||||
|
||||
void USpineWidget::GetSlots(TArray<FString> &Slots) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getSlots().size(); i < n; i++) {
|
||||
Slots.Add(skeleton->getSlots()[i]->getData().getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineWidget::HasSlot(const FString SlotName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findSlot(TCHAR_TO_UTF8(*SlotName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineWidget::SetSlotColor(const FString SlotName, const FColor SlotColor) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
spine::Slot *slot = skeleton->findSlot(TCHAR_TO_UTF8(*SlotName));
|
||||
if (slot) {
|
||||
slot->getColor().set(SlotColor.R / 255.f, SlotColor.G / 255.f, SlotColor.B / 255.f, SlotColor.A / 255.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::GetAnimations(TArray<FString> &Animations) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getData()->getAnimations().size(); i < n; i++) {
|
||||
Animations.Add(skeleton->getData()->getAnimations()[i]->getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineWidget::HasAnimation(FString AnimationName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*AnimationName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float USpineWidget::GetAnimationDuration(FString AnimationName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
spine::Animation *animation = skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*AnimationName));
|
||||
if (animation == nullptr) return 0;
|
||||
else
|
||||
return animation->getDuration();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USpineWidget::SetAutoPlay(bool bInAutoPlays) {
|
||||
bAutoPlaying = bInAutoPlays;
|
||||
}
|
||||
|
||||
void USpineWidget::SetPlaybackTime(float InPlaybackTime, bool bCallDelegates) {
|
||||
CheckState();
|
||||
|
||||
if (state && state->getCurrent(0)) {
|
||||
spine::Animation *CurrentAnimation = state->getCurrent(0)->getAnimation();
|
||||
const float CurrentTime = state->getCurrent(0)->getTrackTime();
|
||||
InPlaybackTime = FMath::Clamp(InPlaybackTime, 0.0f, CurrentAnimation->getDuration());
|
||||
const float DeltaTime = InPlaybackTime - CurrentTime;
|
||||
state->update(DeltaTime);
|
||||
state->apply(*skeleton);
|
||||
|
||||
//Call delegates and perform the world transform
|
||||
if (bCallDelegates) {
|
||||
BeforeUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
skeleton->updateWorldTransform(Physics_Update);
|
||||
if (bCallDelegates) {
|
||||
AfterUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::SetTimeScale(float timeScale) {
|
||||
CheckState();
|
||||
if (state) state->setTimeScale(timeScale);
|
||||
}
|
||||
|
||||
float USpineWidget::GetTimeScale() {
|
||||
CheckState();
|
||||
if (state) return state->getTimeScale();
|
||||
return 1;
|
||||
}
|
||||
|
||||
UTrackEntry *USpineWidget::SetAnimation(int trackIndex, FString animationName, bool loop) {
|
||||
CheckState();
|
||||
if (state && skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*animationName))) {
|
||||
state->disableQueue();
|
||||
TrackEntry *entry = state->setAnimation(trackIndex, TCHAR_TO_UTF8(*animationName), loop);
|
||||
state->enableQueue();
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry *USpineWidget::AddAnimation(int trackIndex, FString animationName, bool loop, float delay) {
|
||||
CheckState();
|
||||
if (state && skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*animationName))) {
|
||||
state->disableQueue();
|
||||
TrackEntry *entry = state->addAnimation(trackIndex, TCHAR_TO_UTF8(*animationName), loop, delay);
|
||||
state->enableQueue();
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry *USpineWidget::SetEmptyAnimation(int trackIndex, float mixDuration) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
TrackEntry *entry = state->setEmptyAnimation(trackIndex, mixDuration);
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry *USpineWidget::AddEmptyAnimation(int trackIndex, float mixDuration, float delay) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
TrackEntry *entry = state->addEmptyAnimation(trackIndex, mixDuration, delay);
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
UTrackEntry *USpineWidget::GetCurrent(int trackIndex) {
|
||||
CheckState();
|
||||
if (state && state->getCurrent(trackIndex)) {
|
||||
TrackEntry *entry = state->getCurrent(trackIndex);
|
||||
if (entry->getRendererObject()) {
|
||||
return (UTrackEntry *) entry->getRendererObject();
|
||||
} else {
|
||||
UTrackEntry *uEntry = NewObject<UTrackEntry>();
|
||||
uEntry->SetTrackEntry(entry);
|
||||
trackEntries.Add(uEntry);
|
||||
return uEntry;
|
||||
}
|
||||
} else
|
||||
return NewObject<UTrackEntry>();
|
||||
}
|
||||
|
||||
void USpineWidget::ClearTracks() {
|
||||
CheckState();
|
||||
if (state) {
|
||||
state->clearTracks();
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::ClearTrack(int trackIndex) {
|
||||
CheckState();
|
||||
if (state) {
|
||||
state->clearTrack(trackIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::PhysicsTranslate(float x, float y) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
skeleton->physicsTranslate(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::PhysicsRotate(float x, float y, float degrees) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
skeleton->physicsRotate(x, y, degrees);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::ResetPhysicsConstraints() {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Vector<PhysicsConstraint *> &constraints = skeleton->getPhysicsConstraints();
|
||||
for (int i = 0, n = (int) constraints.size(); i < n; i++) {
|
||||
constraints[i]->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USpineWidget::SetPhysicsTimeScale(float scale) {
|
||||
physicsTimeScale = scale;
|
||||
}
|
||||
|
||||
float USpineWidget::GetPhysicsTimeScale() {
|
||||
return physicsTimeScale;
|
||||
}
|
||||
64
Plugins/SpinePlugin/Source/SpinePlugin/Public/SSpineWidget.h
Normal file
64
Plugins/SpinePlugin/Source/SpinePlugin/Public/SSpineWidget.h
Normal file
@ -0,0 +1,64 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Slate/SMeshWidget.h"
|
||||
#include "SlateCore.h"
|
||||
#include "SpineAtlasAsset.h"
|
||||
#include <spine/spine.h>
|
||||
|
||||
class USpineWidget;
|
||||
|
||||
class SSpineWidget : public SMeshWidget {
|
||||
|
||||
public:
|
||||
SLATE_BEGIN_ARGS(SSpineWidget) : _MeshData(nullptr) {}
|
||||
SLATE_ARGUMENT(USlateVectorArtData *, MeshData)
|
||||
SLATE_END_ARGS()
|
||||
|
||||
void Construct(const FArguments &Args);
|
||||
|
||||
void SetData(USpineWidget *Widget);
|
||||
FSlateBrush *brush;
|
||||
|
||||
protected:
|
||||
virtual int32 OnPaint(const FPaintArgs &Args, const FGeometry &AllottedGeometry, const FSlateRect &MyCullingRect, FSlateWindowElementList &OutDrawElements, int32 LayerId, const FWidgetStyle &InWidgetStyle, bool bParentEnabled) const override;
|
||||
|
||||
void UpdateMesh(int32 LayerId, FSlateWindowElementList &OutDrawElements, const FGeometry &AllottedGeometry, spine::Skeleton *Skeleton);
|
||||
|
||||
void Flush(int32 LayerId, FSlateWindowElementList &OutDrawElements, const FGeometry &AllottedGeometry, int &Idx, TArray<FVector> &Vertices, TArray<int32> &Indices, TArray<FVector2D> &Uvs, TArray<FColor> &Colors, TArray<FVector> &Colors2, UMaterialInstanceDynamic *Material);
|
||||
|
||||
virtual FVector2D ComputeDesiredSize(float) const override;
|
||||
|
||||
USpineWidget *widget;
|
||||
FRenderData renderData;
|
||||
FVector boundsMin;
|
||||
FVector boundsSize;
|
||||
};
|
||||
@ -0,0 +1,75 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#include "Engine/Texture2D.h"
|
||||
#include "spine/spine.h"
|
||||
#include "SpineAtlasAsset.generated.h"
|
||||
// clang-format on
|
||||
|
||||
UCLASS(BlueprintType, ClassGroup = (Spine))
|
||||
class SPINEPLUGIN_API USpineAtlasAsset : public UPrimaryDataAsset {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
spine::Atlas *GetAtlas();
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TArray<UTexture2D *> atlasPages;
|
||||
|
||||
void SetRawData(const FString &RawData);
|
||||
|
||||
FName GetAtlasFileName() const;
|
||||
|
||||
virtual void BeginDestroy() override;
|
||||
|
||||
protected:
|
||||
spine::Atlas *atlas = nullptr;
|
||||
|
||||
UPROPERTY()
|
||||
FString rawData;
|
||||
|
||||
UPROPERTY()
|
||||
FName atlasFileName;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
|
||||
public:
|
||||
void SetAtlasFileName(const FName &AtlasFileName);
|
||||
|
||||
protected:
|
||||
UPROPERTY(VisibleAnywhere, Instanced, Category = ImportSettings)
|
||||
class UAssetImportData *importData;
|
||||
|
||||
virtual void PostInitProperties() override;
|
||||
virtual void Serialize(FArchive &Ar) override;
|
||||
#endif
|
||||
};
|
||||
@ -0,0 +1,72 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Components/SceneComponent.h"
|
||||
#include "SpineBoneDriverComponent.generated.h"
|
||||
|
||||
class USpineSkeletonComponent;
|
||||
|
||||
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineBoneDriverComponent : public USceneComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
AActor *Target = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString BoneName;
|
||||
|
||||
//Uses just this component when set to true. Updates owning actor otherwise.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseComponentTransform = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UsePosition = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseRotation = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseScale = true;
|
||||
|
||||
USpineBoneDriverComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
||||
|
||||
protected:
|
||||
UFUNCTION()
|
||||
void BeforeUpdateWorldTransform(USpineSkeletonComponent *skeleton);
|
||||
|
||||
USpineSkeletonComponent *lastBoundComponent = nullptr;
|
||||
};
|
||||
@ -0,0 +1,66 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "Components/SceneComponent.h"
|
||||
#include "SpineBoneFollowerComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineBoneFollowerComponent : public USceneComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
AActor *Target = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString BoneName;
|
||||
|
||||
//Updates just this component when set to true. Updates owning actor otherwise.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseComponentTransform = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UsePosition = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseRotation = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseScale = true;
|
||||
|
||||
USpineBoneFollowerComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
||||
};
|
||||
46
Plugins/SpinePlugin/Source/SpinePlugin/Public/SpinePlugin.h
Normal file
46
Plugins/SpinePlugin/Source/SpinePlugin/Public/SpinePlugin.h
Normal file
@ -0,0 +1,46 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(SpineLog, Log, All);
|
||||
|
||||
class SPINEPLUGIN_API SpinePlugin : public IModuleInterface {
|
||||
|
||||
public:
|
||||
static inline SpinePlugin &Get() {
|
||||
return FModuleManager::LoadModuleChecked<SpinePlugin>("SpinePlugin");
|
||||
}
|
||||
|
||||
static inline bool IsAvailable() {
|
||||
return FModuleManager::Get().IsModuleLoaded("SpinePlugin");
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,339 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "SpineSkeletonComponent.h"
|
||||
#include "spine/spine.h"
|
||||
#include "SpineSkeletonAnimationComponent.generated.h"
|
||||
// clang-format on
|
||||
|
||||
USTRUCT(BlueprintType, Category = "Spine")
|
||||
struct SPINEPLUGIN_API FSpineEvent {
|
||||
GENERATED_BODY();
|
||||
|
||||
public:
|
||||
FSpineEvent() : IntValue(0), FloatValue(0.0f), Time(0.0f) {}
|
||||
|
||||
void SetEvent(spine::Event *event) {
|
||||
Name = FString(UTF8_TO_TCHAR(event->getData().getName().buffer()));
|
||||
if (!event->getStringValue().isEmpty()) {
|
||||
StringValue = FString(UTF8_TO_TCHAR(event->getStringValue().buffer()));
|
||||
}
|
||||
this->IntValue = event->getIntValue();
|
||||
this->FloatValue = event->getFloatValue();
|
||||
this->Time = event->getTime();
|
||||
}
|
||||
|
||||
UPROPERTY(BlueprintReadonly)
|
||||
FString Name;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FString StringValue;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
int IntValue;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
float FloatValue;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
float Time;
|
||||
};
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationStartDelegate, UTrackEntry *, entry);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FSpineAnimationEventDelegate, UTrackEntry *, entry, FSpineEvent, evt);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationInterruptDelegate, UTrackEntry *, entry);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationCompleteDelegate, UTrackEntry *, entry);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationEndDelegate, UTrackEntry *, entry);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAnimationDisposeDelegate, UTrackEntry *, entry);
|
||||
|
||||
UCLASS(ClassGroup = (Spine), meta = (BlueprintSpawnableComponent), BlueprintType)
|
||||
class SPINEPLUGIN_API UTrackEntry : public UObject {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UTrackEntry() {}
|
||||
|
||||
void SetTrackEntry(spine::TrackEntry *trackEntry);
|
||||
spine::TrackEntry *GetTrackEntry() { return entry; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
int GetTrackIndex() { return entry ? entry->getTrackIndex() : 0; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
bool GetLoop() { return entry ? entry->getLoop() : false; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetLoop(bool loop) {
|
||||
if (entry) entry->setLoop(loop);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetEventThreshold() { return entry ? entry->getEventThreshold() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetEventThreshold(float eventThreshold) {
|
||||
if (entry) entry->setEventThreshold(eventThreshold);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetAlphaAttachmentThreshold() { return entry ? entry->getAlphaAttachmentThreshold() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetAlphaAttachmentThreshold(float attachmentThreshold) {
|
||||
if (entry) entry->setAlphaAttachmentThreshold(attachmentThreshold);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetMixDrawOrderThreshold() { return entry ? entry->getMixDrawOrderThreshold() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetMixDrawOrderThreshold(float drawOrderThreshold) {
|
||||
if (entry) entry->setMixDrawOrderThreshold(drawOrderThreshold);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetMixAttachmentThreshold() { return entry ? entry->getMixAttachmentThreshold() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetMixAttachmentThreshold(float drawOrderThreshold) {
|
||||
if (entry) entry->setMixAttachmentThreshold(drawOrderThreshold);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetAnimationStart() { return entry ? entry->getAnimationStart() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetAnimationStart(float animationStart) {
|
||||
if (entry) entry->setAnimationStart(animationStart);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetAnimationEnd() { return entry ? entry->getAnimationEnd() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetAnimationEnd(float animationEnd) {
|
||||
if (entry) entry->setAnimationEnd(animationEnd);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetAnimationLast() { return entry ? entry->getAnimationLast() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetAnimationLast(float animationLast) {
|
||||
if (entry) entry->setAnimationLast(animationLast);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetDelay() { return entry ? entry->getDelay() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetDelay(float delay) {
|
||||
if (entry) entry->setDelay(delay);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetTrackTime() { return entry ? entry->getTrackTime() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetTrackTime(float trackTime) {
|
||||
if (entry) entry->setTrackTime(trackTime);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetTrackEnd() { return entry ? entry->getTrackEnd() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetTrackEnd(float trackEnd) {
|
||||
if (entry) entry->setTrackEnd(trackEnd);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetTimeScale() { return entry ? entry->getTimeScale() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetTimeScale(float timeScale) {
|
||||
if (entry) entry->setTimeScale(timeScale);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetAlpha() { return entry ? entry->getAlpha() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetAlpha(float alpha) {
|
||||
if (entry) entry->setAlpha(alpha);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetMixTime() { return entry ? entry->getMixTime() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetMixTime(float mixTime) {
|
||||
if (entry) entry->setMixTime(mixTime);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float GetMixDuration() { return entry ? entry->getMixDuration() : 0; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
void SetMixDuration(float mixDuration) {
|
||||
if (entry) entry->setMixDuration(mixDuration);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
FString getAnimationName() { return entry ? entry->getAnimation()->getName().buffer() : ""; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float getAnimationDuration() { return entry ? entry->getAnimation()->getDuration() : 0; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
bool isValidAnimation() { return entry != nullptr; }
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationStartDelegate AnimationStart;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationInterruptDelegate AnimationInterrupt;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationEventDelegate AnimationEvent;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationCompleteDelegate AnimationComplete;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationEndDelegate AnimationEnd;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationDisposeDelegate AnimationDispose;
|
||||
|
||||
virtual void BeginDestroy() override;
|
||||
|
||||
protected:
|
||||
spine::TrackEntry *entry = nullptr;
|
||||
};
|
||||
|
||||
class USpineAtlasAsset;
|
||||
UCLASS(ClassGroup = (Spine), meta = (BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineSkeletonAnimationComponent : public USpineSkeletonComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
spine::AnimationState *GetAnimationState() { return state; };
|
||||
|
||||
USpineSkeletonAnimationComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
||||
|
||||
virtual void FinishDestroy() override;
|
||||
|
||||
//Added functions for manual configuration
|
||||
|
||||
/* Manages if this skeleton should update automatically or is paused. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void SetAutoPlay(bool bInAutoPlays);
|
||||
|
||||
/* Directly set the time of the current animation, will clamp to animation range. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void SetPlaybackTime(float InPlaybackTime, bool bCallDelegates = true);
|
||||
|
||||
// Blueprint functions
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void SetTimeScale(float timeScale);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
float GetTimeScale();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *SetAnimation(int trackIndex, FString animationName, bool loop);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *AddAnimation(int trackIndex, FString animationName, bool loop, float delay);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *SetEmptyAnimation(int trackIndex, float mixDuration);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *AddEmptyAnimation(int trackIndex, float mixDuration, float delay);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *GetCurrent(int trackIndex);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void ClearTracks();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void ClearTrack(int trackIndex);
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationStartDelegate AnimationStart;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationInterruptDelegate AnimationInterrupt;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationEventDelegate AnimationEvent;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationCompleteDelegate AnimationComplete;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationEndDelegate AnimationEnd;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationDisposeDelegate AnimationDispose;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = Spine)
|
||||
FString PreviewAnimation;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = Spine)
|
||||
FString PreviewSkin;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetPhysicsTimeScale(float scale);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
float GetPhysicsTimeScale();
|
||||
|
||||
// used in C event callback. Needs to be public as we can't call
|
||||
// protected methods from plain old C function.
|
||||
void GCTrackEntry(UTrackEntry *entry) { trackEntries.Remove(entry); }
|
||||
|
||||
protected:
|
||||
virtual void CheckState() override;
|
||||
virtual void InternalTick(float DeltaTime, bool CallDelegates = true, bool Preview = false) override;
|
||||
virtual void DisposeState() override;
|
||||
|
||||
spine::AnimationState *state;
|
||||
|
||||
// keep track of track entries so they won't get GCed while
|
||||
// in transit within a blueprint
|
||||
UPROPERTY()
|
||||
TSet<UTrackEntry *> trackEntries;
|
||||
|
||||
float physicsTimeScale;
|
||||
|
||||
private:
|
||||
/* If the animation should update automatically. */
|
||||
UPROPERTY()
|
||||
bool bAutoPlaying;
|
||||
|
||||
FString lastPreviewAnimation;
|
||||
FString lastPreviewSkin;
|
||||
};
|
||||
@ -0,0 +1,163 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "SpineSkeletonDataAsset.h"
|
||||
#include "spine/spine.h"
|
||||
#include "SpineSkeletonComponent.generated.h"
|
||||
// clang-format on
|
||||
|
||||
class USpineSkeletonComponent;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineBeforeUpdateWorldTransformDelegate, USpineSkeletonComponent *, skeleton);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineAfterUpdateWorldTransformDelegate, USpineSkeletonComponent *, skeleton);
|
||||
|
||||
class USpineAtlasAsset;
|
||||
UCLASS(ClassGroup = (Spine), meta = (BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineSkeletonComponent : public UActorComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
||||
USpineAtlasAsset *Atlas;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
||||
USpineSkeletonDataAsset *SkeletonData;
|
||||
|
||||
spine::Skeleton *GetSkeleton() {
|
||||
CheckState();
|
||||
return skeleton;
|
||||
};
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetSkins(TArray<FString> &Skins);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetSkins(UPARAM(ref) TArray<FString> &SkinNames);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetSkin(const FString SkinName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasSkin(const FString SkinName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetAttachment(const FString slotName, const FString attachmentName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
FTransform GetBoneWorldTransform(const FString &BoneName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetBoneWorldPosition(const FString &BoneName, const FVector &position);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void UpdateWorldTransform();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetToSetupPose();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetBonesToSetupPose();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetSlotsToSetupPose();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetScaleX(float scaleX);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
float GetScaleX();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetScaleY(float scaleY);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
float GetScaleY();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetBones(TArray<FString> &Bones);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasBone(const FString BoneName);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetSlots(TArray<FString> &Slots);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasSlot(const FString SlotName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetSlotColor(const FString SlotName, const FColor color);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetAnimations(TArray<FString> &Animations);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasAnimation(FString AnimationName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
float GetAnimationDuration(FString AnimationName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void PhysicsTranslate(float x, float y);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void PhysicsRotate(float x, float y, float degrees);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void ResetPhysicsConstraints();
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Skeleton")
|
||||
FSpineBeforeUpdateWorldTransformDelegate BeforeUpdateWorldTransform;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Skeleton")
|
||||
FSpineAfterUpdateWorldTransformDelegate AfterUpdateWorldTransform;
|
||||
|
||||
USpineSkeletonComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
||||
|
||||
virtual void FinishDestroy() override;
|
||||
|
||||
protected:
|
||||
virtual void CheckState();
|
||||
virtual void InternalTick(float DeltaTime, bool CallDelegates = true, bool Preview = false);
|
||||
virtual void DisposeState();
|
||||
|
||||
spine::Skeleton *skeleton;
|
||||
USpineAtlasAsset *lastAtlas = nullptr;
|
||||
spine::Atlas *lastSpineAtlas = nullptr;
|
||||
USpineSkeletonDataAsset *lastData = nullptr;
|
||||
spine::Skin *customSkin = nullptr;
|
||||
};
|
||||
@ -0,0 +1,127 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#include "spine/spine.h"
|
||||
#include "SpineSkeletonDataAsset.generated.h"
|
||||
// clang-format on
|
||||
|
||||
USTRUCT(BlueprintType, Category = "Spine")
|
||||
struct SPINEPLUGIN_API FSpineAnimationStateMixData {
|
||||
GENERATED_BODY();
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString From;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString To;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
float Mix = 0;
|
||||
};
|
||||
|
||||
UCLASS(BlueprintType, ClassGroup = (Spine))
|
||||
class SPINEPLUGIN_API USpineSkeletonDataAsset : public UObject {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
spine::SkeletonData *GetSkeletonData(spine::Atlas *Atlas);
|
||||
|
||||
spine::AnimationStateData *GetAnimationStateData(spine::Atlas *atlas);
|
||||
void SetMix(const FString &from, const FString &to, float mix);
|
||||
float GetMix(const FString &from, const FString &to);
|
||||
|
||||
FName GetSkeletonDataFileName() const;
|
||||
void SetRawData(TArray<uint8> &Data);
|
||||
|
||||
virtual void BeginDestroy() override;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
float DefaultMix = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TArray<FSpineAnimationStateMixData> MixData;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Bones;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Slots;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Skins;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Animations;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Events;
|
||||
|
||||
protected:
|
||||
UPROPERTY()
|
||||
TArray<uint8> rawData;
|
||||
|
||||
UPROPERTY()
|
||||
FName skeletonDataFileName;
|
||||
|
||||
// These are created at runtime
|
||||
struct NativeSkeletonData {
|
||||
spine::SkeletonData *skeletonData;
|
||||
spine::AnimationStateData *animationStateData;
|
||||
};
|
||||
|
||||
TMap<spine::Atlas *, NativeSkeletonData> atlasToNativeData;
|
||||
|
||||
void ClearNativeData();
|
||||
|
||||
void SetMixes(spine::AnimationStateData *animationStateData);
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
public:
|
||||
void SetSkeletonDataFileName(const FName &skeletonDataFileName);
|
||||
|
||||
protected:
|
||||
UPROPERTY(VisibleAnywhere, Instanced, Category = ImportSettings)
|
||||
class UAssetImportData *importData = nullptr;
|
||||
|
||||
virtual void PostInitProperties() override;
|
||||
#if ((ENGINE_MAJOR_VERSION >= 5) && (ENGINE_MINOR_VERSION >= 4))
|
||||
virtual void GetAssetRegistryTags(FAssetRegistryTagsContext Context) const override;
|
||||
#else
|
||||
virtual void GetAssetRegistryTags(TArray<FAssetRegistryTag> &OutTags) const override;
|
||||
#endif
|
||||
|
||||
virtual void Serialize(FArchive &Ar) override;
|
||||
#endif
|
||||
|
||||
void LoadInfo();
|
||||
};
|
||||
@ -0,0 +1,113 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "ProceduralMeshComponent.h"
|
||||
#include "SpineSkeletonAnimationComponent.h"
|
||||
#include "SpineSkeletonRendererComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS(ClassGroup = (Spine), meta = (BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineSkeletonRendererComponent : public UProceduralMeshComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
USpineSkeletonRendererComponent(const FObjectInitializer &ObjectInitializer);
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
||||
|
||||
/* Updates this skeleton renderer using the provided skeleton animation component. */
|
||||
void UpdateRenderer(USpineSkeletonComponent *Skeleton);
|
||||
|
||||
// Material Instance parents
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
UMaterialInterface *NormalBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
UMaterialInterface *AdditiveBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
UMaterialInterface *MultiplyBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
UMaterialInterface *ScreenBlendMaterial;
|
||||
|
||||
// Need to hold on to the dynamic instances, or the GC will kill us while updating them
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
TArray<UMaterialInstanceDynamic *> atlasNormalBlendMaterials;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
TArray<UMaterialInstanceDynamic *> atlasAdditiveBlendMaterials;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
TArray<UMaterialInstanceDynamic *> atlasMultiplyBlendMaterials;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
TArray<UMaterialInstanceDynamic *> atlasScreenBlendMaterials;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
float DepthOffset = 0.1f;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
FName TextureParameterName;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
FLinearColor Color = FLinearColor(1, 1, 1, 1);
|
||||
|
||||
/** Whether to generate collision geometry for the skeleton, or not. */
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
bool bCreateCollision;
|
||||
|
||||
virtual void FinishDestroy() override;
|
||||
|
||||
protected:
|
||||
void UpdateMaterial(UTexture2D *Texture, UMaterialInstanceDynamic *&CurrentInstance, UMaterialInterface *ParentMaterial);
|
||||
|
||||
void UpdateMesh(USpineSkeletonComponent *component, spine::Skeleton *Skeleton);
|
||||
|
||||
void Flush(int &Idx, TArray<FVector> &Vertices, TArray<int32> &Indices, TArray<FVector> &Normals, TArray<FVector2D> &Uvs, TArray<FColor> &Colors, UMaterialInstanceDynamic *Material);
|
||||
|
||||
spine::Vector<float> worldVertices;
|
||||
spine::SkeletonClipping clipper;
|
||||
|
||||
UPROPERTY();
|
||||
TArray<FVector> vertices;
|
||||
UPROPERTY();
|
||||
TArray<int32> indices;
|
||||
UPROPERTY();
|
||||
TArray<FVector> normals;
|
||||
UPROPERTY();
|
||||
TArray<FVector2D> uvs;
|
||||
UPROPERTY();
|
||||
TArray<FColor> colors;
|
||||
};
|
||||
287
Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h
Normal file
287
Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h
Normal file
@ -0,0 +1,287 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#include "Runtime/UMG/Public/UMG.h"
|
||||
#include "SpineSkeletonDataAsset.h"
|
||||
#include "SpineSkeletonAnimationComponent.h"
|
||||
#include "spine/spine.h"
|
||||
#include "SpineWidget.generated.h"
|
||||
// clang-format on
|
||||
|
||||
class SSpineWidget;
|
||||
class USpineWidget;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineWidgetBeforeUpdateWorldTransformDelegate, USpineWidget *, skeleton);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSpineWidgetAfterUpdateWorldTransformDelegate, USpineWidget *, skeleton);
|
||||
|
||||
UCLASS(ClassGroup = (Spine), meta = (BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineWidget : public UWidget {
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
virtual void ReleaseSlateResources(bool bReleaseChildren) override;
|
||||
virtual void SynchronizeProperties() override;
|
||||
#if WITH_EDITOR
|
||||
virtual const FText GetPaletteCategory() override;
|
||||
#endif
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
||||
FString InitialSkin;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
||||
USpineAtlasAsset *Atlas;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
||||
USpineSkeletonDataAsset *SkeletonData;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
UMaterialInterface *NormalBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
UMaterialInterface *AdditiveBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
UMaterialInterface *MultiplyBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
UMaterialInterface *ScreenBlendMaterial;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
FName TextureParameterName;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
float DepthOffset = 0.1f;
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||
FLinearColor Color = FLinearColor(1, 1, 1, 1);
|
||||
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
FSlateBrush Brush;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetSkins(TArray<FString> &Skins);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetSkin(const FString SkinName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetSkins(UPARAM(ref) TArray<FString> &SkinNames);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasSkin(const FString SkinName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetAttachment(const FString slotName, const FString attachmentName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void UpdateWorldTransform();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetToSetupPose();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetBonesToSetupPose();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetSlotsToSetupPose();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetScaleX(float scaleX);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
float GetScaleX();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetScaleY(float scaleY);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
float GetScaleY();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetBones(TArray<FString> &Bones);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasBone(const FString BoneName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
FTransform GetBoneTransform(const FString &BoneName);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetSlots(TArray<FString> &Slots);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasSlot(const FString SlotName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetSlotColor(const FString SlotName, const FColor SlotColor);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetAnimations(TArray<FString> &Animations);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasAnimation(FString AnimationName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
float GetAnimationDuration(FString AnimationName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void PhysicsTranslate(float x, float y);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void PhysicsRotate(float x, float y, float degrees);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void ResetPhysicsConstraints();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
void SetPhysicsTimeScale(float scale);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
float GetPhysicsTimeScale();
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Skeleton")
|
||||
FSpineWidgetBeforeUpdateWorldTransformDelegate BeforeUpdateWorldTransform;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Skeleton")
|
||||
FSpineWidgetAfterUpdateWorldTransformDelegate AfterUpdateWorldTransform;
|
||||
|
||||
/* Manages if this skeleton should update automatically or is paused. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void SetAutoPlay(bool bInAutoPlays);
|
||||
|
||||
/* Directly set the time of the current animation, will clamp to animation range. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void SetPlaybackTime(float InPlaybackTime, bool bCallDelegates = true);
|
||||
|
||||
// Blueprint functions
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void SetTimeScale(float timeScale);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
float GetTimeScale();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *SetAnimation(int trackIndex, FString animationName, bool loop);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *AddAnimation(int trackIndex, FString animationName, bool loop, float delay);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *SetEmptyAnimation(int trackIndex, float mixDuration);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *AddEmptyAnimation(int trackIndex, float mixDuration, float delay);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
UTrackEntry *GetCurrent(int trackIndex);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void ClearTracks();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void ClearTrack(int trackIndex);
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationStartDelegate AnimationStart;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationInterruptDelegate AnimationInterrupt;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationEventDelegate AnimationEvent;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationCompleteDelegate AnimationComplete;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationEndDelegate AnimationEnd;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Animation")
|
||||
FSpineAnimationDisposeDelegate AnimationDispose;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Animation")
|
||||
void Tick(float DeltaTime, bool CallDelegates = true);
|
||||
|
||||
virtual void FinishDestroy() override;
|
||||
|
||||
// used in C event callback. Needs to be public as we can't call
|
||||
// protected methods from plain old C function.
|
||||
void GCTrackEntry(UTrackEntry *entry) { trackEntries.Remove(entry); }
|
||||
|
||||
protected:
|
||||
friend class SSpineWidget;
|
||||
|
||||
virtual TSharedRef<SWidget> RebuildWidget() override;
|
||||
virtual void CheckState();
|
||||
virtual void DisposeState();
|
||||
|
||||
TSharedPtr<SSpineWidget> slateWidget;
|
||||
|
||||
spine::Skeleton *skeleton;
|
||||
spine::AnimationState *state;
|
||||
USpineAtlasAsset *lastAtlas = nullptr;
|
||||
spine::Atlas *lastSpineAtlas = nullptr;
|
||||
USpineSkeletonDataAsset *lastData = nullptr;
|
||||
spine::Skin *customSkin = nullptr;
|
||||
float physicsTimeScale;
|
||||
|
||||
// Need to hold on to the dynamic instances, or the GC will kill us while updating them
|
||||
UPROPERTY()
|
||||
TArray<UMaterialInstanceDynamic *> atlasNormalBlendMaterials;
|
||||
TMap<spine::AtlasPage *, UMaterialInstanceDynamic *> pageToNormalBlendMaterial;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UMaterialInstanceDynamic *> atlasAdditiveBlendMaterials;
|
||||
TMap<spine::AtlasPage *, UMaterialInstanceDynamic *> pageToAdditiveBlendMaterial;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UMaterialInstanceDynamic *> atlasMultiplyBlendMaterials;
|
||||
TMap<spine::AtlasPage *, UMaterialInstanceDynamic *> pageToMultiplyBlendMaterial;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UMaterialInstanceDynamic *> atlasScreenBlendMaterials;
|
||||
TMap<spine::AtlasPage *, UMaterialInstanceDynamic *> pageToScreenBlendMaterial;
|
||||
|
||||
spine::Vector<float> worldVertices;
|
||||
spine::SkeletonClipping clipper;
|
||||
|
||||
// keep track of track entries so they won't get GCed while
|
||||
// in transit within a blueprint
|
||||
UPROPERTY()
|
||||
TSet<UTrackEntry *> trackEntries;
|
||||
|
||||
private:
|
||||
/* If the animation should update automatically. */
|
||||
UPROPERTY()
|
||||
bool bAutoPlaying;
|
||||
bool bSkinInitialized = false;
|
||||
};
|
||||
@ -0,0 +1,131 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Animation_h
|
||||
#define Spine_Animation_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/HashMap.h>
|
||||
#include <spine/MixBlend.h>
|
||||
#include <spine/MixDirection.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
#include <spine/Property.h>
|
||||
|
||||
namespace spine {
|
||||
class Timeline;
|
||||
|
||||
class Skeleton;
|
||||
|
||||
class Event;
|
||||
|
||||
class AnimationState;
|
||||
|
||||
class SP_API Animation : public SpineObject {
|
||||
friend class AnimationState;
|
||||
|
||||
friend class TrackEntry;
|
||||
|
||||
friend class AnimationStateData;
|
||||
|
||||
friend class AttachmentTimeline;
|
||||
|
||||
friend class RGBATimeline;
|
||||
|
||||
friend class RGBTimeline;
|
||||
|
||||
friend class AlphaTimeline;
|
||||
|
||||
friend class RGBA2Timeline;
|
||||
|
||||
friend class RGB2Timeline;
|
||||
|
||||
friend class DeformTimeline;
|
||||
|
||||
friend class DrawOrderTimeline;
|
||||
|
||||
friend class EventTimeline;
|
||||
|
||||
friend class IkConstraintTimeline;
|
||||
|
||||
friend class PathConstraintMixTimeline;
|
||||
|
||||
friend class PathConstraintPositionTimeline;
|
||||
|
||||
friend class PathConstraintSpacingTimeline;
|
||||
|
||||
friend class RotateTimeline;
|
||||
|
||||
friend class ScaleTimeline;
|
||||
|
||||
friend class ShearTimeline;
|
||||
|
||||
friend class TransformConstraintTimeline;
|
||||
|
||||
friend class TranslateTimeline;
|
||||
|
||||
friend class TranslateXTimeline;
|
||||
|
||||
friend class TranslateYTimeline;
|
||||
|
||||
friend class TwoColorTimeline;
|
||||
|
||||
public:
|
||||
Animation(const String &name, Vector<Timeline *> &timelines, float duration);
|
||||
|
||||
~Animation();
|
||||
|
||||
/// Applies all the animation's timelines to the specified skeleton.
|
||||
/// See also Timeline::apply(Skeleton&, float, float, Vector, float, MixPose, MixDirection)
|
||||
void apply(Skeleton &skeleton, float lastTime, float time, bool loop, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction);
|
||||
|
||||
const String &getName();
|
||||
|
||||
Vector<Timeline *> &getTimelines();
|
||||
|
||||
bool hasTimeline(Vector<PropertyId> &ids);
|
||||
|
||||
float getDuration();
|
||||
|
||||
void setDuration(float inValue);
|
||||
|
||||
/// @param target After the first and before the last entry.
|
||||
static int search(Vector<float> &values, float target);
|
||||
|
||||
static int search(Vector<float> &values, float target, int step);
|
||||
private:
|
||||
Vector<Timeline *> _timelines;
|
||||
HashMap<PropertyId, bool> _timelineIds;
|
||||
float _duration;
|
||||
String _name;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Animation_h */
|
||||
@ -0,0 +1,521 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_AnimationState_h
|
||||
#define Spine_AnimationState_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/Pool.h>
|
||||
#include <spine/Property.h>
|
||||
#include <spine/MixBlend.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
#include <spine/HasRendererObject.h>
|
||||
#include "Slot.h"
|
||||
|
||||
#ifdef SPINE_USE_STD_FUNCTION
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
namespace spine {
|
||||
enum EventType {
|
||||
EventType_Start = 0,
|
||||
EventType_Interrupt,
|
||||
EventType_End,
|
||||
EventType_Complete,
|
||||
EventType_Dispose,
|
||||
EventType_Event
|
||||
};
|
||||
|
||||
class AnimationState;
|
||||
|
||||
class TrackEntry;
|
||||
|
||||
class Animation;
|
||||
|
||||
class Event;
|
||||
|
||||
class AnimationStateData;
|
||||
|
||||
class Skeleton;
|
||||
|
||||
class RotateTimeline;
|
||||
|
||||
class AttachmentTimeline;
|
||||
|
||||
#ifdef SPINE_USE_STD_FUNCTION
|
||||
typedef std::function<void (AnimationState* state, EventType type, TrackEntry* entry, Event* event)> AnimationStateListener;
|
||||
#else
|
||||
|
||||
typedef void (*AnimationStateListener)(AnimationState *state, EventType type, TrackEntry *entry, Event *event);
|
||||
|
||||
#endif
|
||||
|
||||
/// Abstract class to inherit from to create a callback object
|
||||
class SP_API AnimationStateListenerObject {
|
||||
public:
|
||||
AnimationStateListenerObject() {};
|
||||
|
||||
virtual ~AnimationStateListenerObject() {};
|
||||
public:
|
||||
/// The callback function to be called
|
||||
virtual void callback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) = 0;
|
||||
};
|
||||
|
||||
/// State for the playback of an animation
|
||||
class SP_API TrackEntry : public SpineObject, public HasRendererObject {
|
||||
friend class EventQueue;
|
||||
|
||||
friend class AnimationState;
|
||||
|
||||
public:
|
||||
TrackEntry();
|
||||
|
||||
virtual ~TrackEntry();
|
||||
|
||||
/// The index of the track where this entry is either current or queued.
|
||||
int getTrackIndex();
|
||||
|
||||
/// The animation to apply for this track entry.
|
||||
Animation *getAnimation();
|
||||
|
||||
TrackEntry *getPrevious();
|
||||
|
||||
/// If true, the animation will repeat. If false, it will not, instead its last frame is applied if played beyond its duration.
|
||||
bool getLoop();
|
||||
|
||||
void setLoop(bool inValue);
|
||||
|
||||
/// If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead
|
||||
/// of being mixed out.
|
||||
///
|
||||
/// When mixing between animations that key the same property, if a lower track also keys that property then the value will
|
||||
/// briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0%
|
||||
/// while the second animation mixes from 0% to 100%. Setting holdPrevious to true applies the first animation
|
||||
/// at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which
|
||||
/// keys the property, only when a higher track also keys the property.
|
||||
///
|
||||
/// Snapping will occur if holdPrevious is true and this animation does not key all the same properties as the
|
||||
/// previous animation.
|
||||
bool getHoldPrevious();
|
||||
|
||||
void setHoldPrevious(bool inValue);
|
||||
|
||||
bool getReverse();
|
||||
|
||||
void setReverse(bool inValue);
|
||||
|
||||
bool getShortestRotation();
|
||||
|
||||
void setShortestRotation(bool inValue);
|
||||
|
||||
/// Seconds to postpone playing the animation. When a track entry is the current track entry, delay postpones incrementing
|
||||
/// the track time. When a track entry is queued, delay is the time from the start of the previous animation to when the
|
||||
/// track entry will become the current track entry.
|
||||
float getDelay();
|
||||
|
||||
void setDelay(float inValue);
|
||||
|
||||
/// Current time in seconds this track entry has been the current track entry. The track time determines
|
||||
/// TrackEntry.AnimationTime. The track time can be set to start the animation at a time other than 0, without affecting looping.
|
||||
float getTrackTime();
|
||||
|
||||
void setTrackTime(float inValue);
|
||||
|
||||
/// The track time in seconds when this animation will be removed from the track. Defaults to the animation duration for
|
||||
/// non-looping animations and to int.MaxValue for looping animations. If the track end time is reached and no
|
||||
/// other animations are queued for playback, and mixing from any previous animations is complete, properties keyed by the animation,
|
||||
/// are set to the setup pose and the track is cleared.
|
||||
///
|
||||
/// It may be desired to use AnimationState.addEmptyAnimation(int, float, float) to mix the properties back to the
|
||||
/// setup pose over time, rather than have it happen instantly.
|
||||
float getTrackEnd();
|
||||
|
||||
void setTrackEnd(float inValue);
|
||||
|
||||
/// Seconds when this animation starts, both initially and after looping. Defaults to 0.
|
||||
///
|
||||
/// When changing the animation start time, it often makes sense to set TrackEntry.AnimationLast to the same value to
|
||||
/// prevent timeline keys before the start time from triggering.
|
||||
float getAnimationStart();
|
||||
|
||||
void setAnimationStart(float inValue);
|
||||
|
||||
/// Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will
|
||||
/// loop back to TrackEntry.AnimationStart at this time. Defaults to the animation duration.
|
||||
float getAnimationEnd();
|
||||
|
||||
void setAnimationEnd(float inValue);
|
||||
|
||||
/// The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this
|
||||
/// animation is applied, event timelines will fire all events between the animation last time (exclusive) and animation time
|
||||
/// (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation is applied.
|
||||
float getAnimationLast();
|
||||
|
||||
void setAnimationLast(float inValue);
|
||||
|
||||
/// Uses TrackEntry.TrackTime to compute the animation time between TrackEntry.AnimationStart. and
|
||||
/// TrackEntry.AnimationEnd. When the track time is 0, the animation time is equal to the animation start time.
|
||||
float getAnimationTime();
|
||||
|
||||
/// Multiplier for the delta time when the animation state is updated, causing time for this animation to play slower or
|
||||
/// faster. Defaults to 1.
|
||||
float getTimeScale();
|
||||
|
||||
void setTimeScale(float inValue);
|
||||
|
||||
/// Values less than 1 mix this animation with the last skeleton pose. Defaults to 1, which overwrites the last skeleton pose with
|
||||
/// this animation.
|
||||
///
|
||||
/// Typically track 0 is used to completely pose the skeleton, then alpha can be used on higher tracks. It doesn't make sense
|
||||
/// to use alpha on track 0 if the skeleton pose is from the last frame render.
|
||||
float getAlpha();
|
||||
|
||||
void setAlpha(float inValue);
|
||||
|
||||
///
|
||||
/// When the mix percentage (mix time / mix duration) is less than the event threshold, event timelines for the animation
|
||||
/// being mixed out will be applied. Defaults to 0, so event timelines are not applied for an animation being mixed out.
|
||||
float getEventThreshold();
|
||||
|
||||
void setEventThreshold(float inValue);
|
||||
|
||||
/// When the mix percentage (mix time / mix duration) is less than the attachment threshold, attachment timelines for the
|
||||
/// animation being mixed out will be applied. Defaults to 0, so attachment timelines are not applied for an animation being
|
||||
/// mixed out.
|
||||
float getMixAttachmentThreshold();
|
||||
|
||||
void setMixAttachmentThreshold(float inValue);
|
||||
|
||||
/// When getAlpha() is greater than alphaAttachmentThreshold, attachment timelines are applied.
|
||||
/// Defaults to 0, so attachment timelines are always applied. */
|
||||
float getAlphaAttachmentThreshold();
|
||||
|
||||
void setAlphaAttachmentThreshold(float inValue);
|
||||
|
||||
/// When the mix percentage (mix time / mix duration) is less than the draw order threshold, draw order timelines for the
|
||||
/// animation being mixed out will be applied. Defaults to 0, so draw order timelines are not applied for an animation being
|
||||
/// mixed out.
|
||||
float getMixDrawOrderThreshold();
|
||||
|
||||
void setMixDrawOrderThreshold(float inValue);
|
||||
|
||||
/// The animation queued to start after this animation, or NULL.
|
||||
TrackEntry *getNext();
|
||||
|
||||
/// Returns true if at least one loop has been completed.
|
||||
bool isComplete();
|
||||
|
||||
/// Seconds from 0 to the mix duration when mixing from the previous animation to this animation. May be slightly more than
|
||||
/// TrackEntry.MixDuration when the mix is complete.
|
||||
float getMixTime();
|
||||
|
||||
void setMixTime(float inValue);
|
||||
|
||||
/// Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
|
||||
/// AnimationStateData based on the animation before this animation (if any).
|
||||
///
|
||||
/// The mix duration can be set manually rather than use the value from AnimationStateData.GetMix.
|
||||
/// In that case, the mixDuration must be set before AnimationState.update(float) is next called.
|
||||
///
|
||||
/// When using AnimationState::addAnimation(int, Animation, bool, float) with a delay
|
||||
/// less than or equal to 0, note the Delay is set using the mix duration from the AnimationStateData
|
||||
float getMixDuration();
|
||||
|
||||
void setMixDuration(float inValue);
|
||||
|
||||
void setMixDuration(float mixDuration, float delay);
|
||||
|
||||
MixBlend getMixBlend();
|
||||
|
||||
void setMixBlend(MixBlend blend);
|
||||
|
||||
/// The track entry for the previous animation when mixing from the previous animation to this animation, or NULL if no
|
||||
/// mixing is currently occuring. When mixing from multiple animations, MixingFrom makes up a double linked list with MixingTo.
|
||||
TrackEntry *getMixingFrom();
|
||||
|
||||
/// The track entry for the next animation when mixing from this animation, or NULL if no mixing is currently occuring.
|
||||
/// When mixing from multiple animations, MixingTo makes up a double linked list with MixingFrom.
|
||||
TrackEntry *getMixingTo();
|
||||
|
||||
/// Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
|
||||
/// long way around when using alpha and starting animations on other tracks.
|
||||
///
|
||||
/// Mixing involves finding a rotation between two others, which has two possible solutions: the short way or the long way around.
|
||||
/// The two rotations likely change over time, so which direction is the short or long way also changes.
|
||||
/// If the short way was always chosen, bones would flip to the other side when that direction became the long way.
|
||||
/// TrackEntry chooses the short way the first time it is applied and remembers that direction.
|
||||
void resetRotationDirections();
|
||||
|
||||
float getTrackComplete();
|
||||
|
||||
void setListener(AnimationStateListener listener);
|
||||
|
||||
void setListener(AnimationStateListenerObject *listener);
|
||||
|
||||
/// Returns true if this track entry has been applied at least once.
|
||||
///
|
||||
/// See AnimationState::apply(Skeleton).
|
||||
bool wasApplied();
|
||||
|
||||
/// Returns true if there is a getNext() track entry that is ready to become the current track entry during the
|
||||
/// next AnimationState::update(float)}
|
||||
bool isNextReady () {
|
||||
return _next != NULL && _nextTrackLast - _next->_delay >= 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Animation *_animation;
|
||||
TrackEntry *_previous;
|
||||
TrackEntry *_next;
|
||||
TrackEntry *_mixingFrom;
|
||||
TrackEntry *_mixingTo;
|
||||
int _trackIndex;
|
||||
|
||||
bool _loop, _holdPrevious, _reverse, _shortestRotation;
|
||||
float _eventThreshold, _mixAttachmentThreshold, _alphaAttachmentThreshold, _mixDrawOrderThreshold;
|
||||
float _animationStart, _animationEnd, _animationLast, _nextAnimationLast;
|
||||
float _delay, _trackTime, _trackLast, _nextTrackLast, _trackEnd, _timeScale;
|
||||
float _alpha, _mixTime, _mixDuration, _interruptAlpha, _totalAlpha;
|
||||
MixBlend _mixBlend;
|
||||
Vector<int> _timelineMode;
|
||||
Vector<TrackEntry *> _timelineHoldMix;
|
||||
Vector<float> _timelinesRotation;
|
||||
AnimationStateListener _listener;
|
||||
AnimationStateListenerObject *_listenerObject;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
class SP_API EventQueueEntry : public SpineObject {
|
||||
friend class EventQueue;
|
||||
|
||||
public:
|
||||
EventType _type;
|
||||
TrackEntry *_entry;
|
||||
Event *_event;
|
||||
|
||||
EventQueueEntry(EventType eventType, TrackEntry *trackEntry, Event *event = NULL);
|
||||
};
|
||||
|
||||
class SP_API EventQueue : public SpineObject {
|
||||
friend class AnimationState;
|
||||
|
||||
private:
|
||||
Vector<EventQueueEntry> _eventQueueEntries;
|
||||
AnimationState &_state;
|
||||
bool _drainDisabled;
|
||||
|
||||
static EventQueue *newEventQueue(AnimationState &state);
|
||||
|
||||
static EventQueueEntry newEventQueueEntry(EventType eventType, TrackEntry *entry, Event *event = NULL);
|
||||
|
||||
EventQueue(AnimationState &state);
|
||||
|
||||
~EventQueue();
|
||||
|
||||
void start(TrackEntry *entry);
|
||||
|
||||
void interrupt(TrackEntry *entry);
|
||||
|
||||
void end(TrackEntry *entry);
|
||||
|
||||
void dispose(TrackEntry *entry);
|
||||
|
||||
void complete(TrackEntry *entry);
|
||||
|
||||
void event(TrackEntry *entry, Event *event);
|
||||
|
||||
/// Raises all events in the queue and drains the queue.
|
||||
void drain();
|
||||
};
|
||||
|
||||
class SP_API AnimationState : public SpineObject, public HasRendererObject {
|
||||
friend class TrackEntry;
|
||||
|
||||
friend class EventQueue;
|
||||
|
||||
public:
|
||||
explicit AnimationState(AnimationStateData *data);
|
||||
|
||||
~AnimationState();
|
||||
|
||||
/// Increments the track entry times, setting queued animations as current if needed
|
||||
/// @param delta delta time
|
||||
void update(float delta);
|
||||
|
||||
/// Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the
|
||||
/// animation state can be applied to multiple skeletons to pose them identically.
|
||||
bool apply(Skeleton &skeleton);
|
||||
|
||||
/// Removes all animations from all tracks, leaving skeletons in their previous pose.
|
||||
/// It may be desired to use AnimationState.setEmptyAnimations(float) to mix the skeletons back to the setup pose,
|
||||
/// rather than leaving them in their previous pose.
|
||||
void clearTracks();
|
||||
|
||||
/// Removes all animations from the tracks, leaving skeletons in their previous pose.
|
||||
/// It may be desired to use AnimationState.setEmptyAnimations(float) to mix the skeletons back to the setup pose,
|
||||
/// rather than leaving them in their previous pose.
|
||||
void clearTrack(size_t trackIndex);
|
||||
|
||||
/// Sets an animation by name. setAnimation(int, Animation, bool)
|
||||
TrackEntry *setAnimation(size_t trackIndex, const String &animationName, bool loop);
|
||||
|
||||
/// Sets the current animation for a track, discarding any queued animations.
|
||||
/// @param loop If true, the animation will repeat.
|
||||
/// If false, it will not, instead its last frame is applied if played beyond its duration.
|
||||
/// In either case TrackEntry.TrackEnd determines when the track is cleared.
|
||||
/// @return
|
||||
/// A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
/// after AnimationState.Dispose.
|
||||
TrackEntry *setAnimation(size_t trackIndex, Animation *animation, bool loop);
|
||||
|
||||
/// Queues an animation by name.
|
||||
/// addAnimation(int, Animation, bool, float)
|
||||
TrackEntry *addAnimation(size_t trackIndex, const String &animationName, bool loop, float delay);
|
||||
|
||||
/// Adds an animation to be played delay seconds after the current or last queued animation
|
||||
/// for a track. If the track is empty, it is equivalent to calling setAnimation.
|
||||
/// @param delay
|
||||
/// Seconds to begin this animation after the start of the previous animation. May be <= 0 to use the animation
|
||||
/// duration of the previous track minus any mix duration plus the negative delay.
|
||||
///
|
||||
/// @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
/// after AnimationState.Dispose
|
||||
TrackEntry *addAnimation(size_t trackIndex, Animation *animation, bool loop, float delay);
|
||||
|
||||
/// Sets an empty animation for a track, discarding any queued animations, and mixes to it over the specified mix duration.
|
||||
TrackEntry *setEmptyAnimation(size_t trackIndex, float mixDuration);
|
||||
|
||||
/// Adds an empty animation to be played after the current or last queued animation for a track, and mixes to it over the
|
||||
/// specified mix duration.
|
||||
/// @return
|
||||
/// A track entry to allow further customization of animation playback. References to the track entry must not be kept after AnimationState.Dispose.
|
||||
///
|
||||
/// @param trackIndex Track number.
|
||||
/// @param mixDuration Mix duration.
|
||||
/// @param delay Seconds to begin this animation after the start of the previous animation. May be <= 0 to use the animation
|
||||
/// duration of the previous track minus any mix duration plus the negative delay.
|
||||
TrackEntry *addEmptyAnimation(size_t trackIndex, float mixDuration, float delay);
|
||||
|
||||
/// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
|
||||
void setEmptyAnimations(float mixDuration);
|
||||
|
||||
/// @return The track entry for the animation currently playing on the track, or NULL if no animation is currently playing.
|
||||
TrackEntry *getCurrent(size_t trackIndex);
|
||||
|
||||
AnimationStateData *getData();
|
||||
|
||||
/// A list of tracks that have animations, which may contain NULLs.
|
||||
Vector<TrackEntry *> &getTracks();
|
||||
|
||||
float getTimeScale();
|
||||
|
||||
void setTimeScale(float inValue);
|
||||
|
||||
void setListener(AnimationStateListener listener);
|
||||
|
||||
void setListener(AnimationStateListenerObject *listener);
|
||||
|
||||
void disableQueue();
|
||||
|
||||
void enableQueue();
|
||||
|
||||
void setManualTrackEntryDisposal(bool inValue);
|
||||
|
||||
bool getManualTrackEntryDisposal();
|
||||
|
||||
void disposeTrackEntry(TrackEntry *entry);
|
||||
|
||||
private:
|
||||
static const int Subsequent = 0;
|
||||
static const int First = 1;
|
||||
static const int HoldSubsequent = 2;
|
||||
static const int HoldFirst = 3;
|
||||
static const int HoldMix = 4;
|
||||
|
||||
static const int Setup = 1;
|
||||
static const int Current = 2;
|
||||
|
||||
AnimationStateData *_data;
|
||||
|
||||
Pool<TrackEntry> _trackEntryPool;
|
||||
Vector<TrackEntry *> _tracks;
|
||||
Vector<Event *> _events;
|
||||
EventQueue *_queue;
|
||||
|
||||
HashMap<PropertyId, bool> _propertyIDs;
|
||||
bool _animationsChanged;
|
||||
|
||||
AnimationStateListener _listener;
|
||||
AnimationStateListenerObject *_listenerObject;
|
||||
|
||||
int _unkeyedState;
|
||||
|
||||
float _timeScale;
|
||||
|
||||
bool _manualTrackEntryDisposal;
|
||||
|
||||
static Animation *getEmptyAnimation();
|
||||
|
||||
static void
|
||||
applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleton &skeleton, float time, float alpha, MixBlend pose,
|
||||
Vector<float> &timelinesRotation, size_t i, bool firstFrame);
|
||||
|
||||
void applyAttachmentTimeline(AttachmentTimeline *attachmentTimeline, Skeleton &skeleton, float animationTime,
|
||||
MixBlend pose, bool firstFrame);
|
||||
|
||||
/// Returns true when all mixing from entries are complete.
|
||||
bool updateMixingFrom(TrackEntry *to, float delta);
|
||||
|
||||
float applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBlend currentPose);
|
||||
|
||||
void queueEvents(TrackEntry *entry, float animationTime);
|
||||
|
||||
/// Sets the active TrackEntry for a given track number.
|
||||
void setCurrent(size_t index, TrackEntry *current, bool interrupt);
|
||||
|
||||
/// Removes the next entry and all entries after it for the specified entry. */
|
||||
void clearNext(TrackEntry *entry);
|
||||
|
||||
TrackEntry *expandToIndex(size_t index);
|
||||
|
||||
/// Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values.
|
||||
/// @param last May be NULL.
|
||||
TrackEntry *newTrackEntry(size_t trackIndex, Animation *animation, bool loop, TrackEntry *last);
|
||||
|
||||
void animationsChanged();
|
||||
|
||||
void computeHold(TrackEntry *entry);
|
||||
|
||||
void setAttachment(Skeleton &skeleton, spine::Slot &slot, const String &attachmentName, bool attachments);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_AnimationState_h */
|
||||
@ -0,0 +1,90 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_AnimationStateData_h
|
||||
#define Spine_AnimationStateData_h
|
||||
|
||||
#include <spine/HashMap.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace spine {
|
||||
class SkeletonData;
|
||||
|
||||
class Animation;
|
||||
|
||||
/// Stores mix (crossfade) durations to be applied when AnimationState animations are changed.
|
||||
class SP_API AnimationStateData : public SpineObject {
|
||||
friend class AnimationState;
|
||||
|
||||
public:
|
||||
explicit AnimationStateData(SkeletonData *skeletonData);
|
||||
|
||||
/// The SkeletonData to look up animations when they are specified by name.
|
||||
SkeletonData *getSkeletonData();
|
||||
|
||||
/// The mix duration to use when no mix duration has been specifically defined between two animations.
|
||||
float getDefaultMix();
|
||||
|
||||
void setDefaultMix(float inValue);
|
||||
|
||||
/// Sets a mix duration by animation names.
|
||||
void setMix(const String &fromName, const String &toName, float duration);
|
||||
|
||||
/// Sets a mix duration when changing from the specified animation to the other.
|
||||
/// See TrackEntry.MixDuration.
|
||||
void setMix(Animation *from, Animation *to, float duration);
|
||||
|
||||
/// The mix duration to use when changing from the specified animation to the other,
|
||||
/// or the DefaultMix if no mix duration has been set.
|
||||
float getMix(Animation *from, Animation *to);
|
||||
|
||||
/// Removes all mixes and sets the default mix to 0.
|
||||
void clear();
|
||||
|
||||
private:
|
||||
class AnimationPair : public SpineObject {
|
||||
public:
|
||||
Animation *_a1;
|
||||
Animation *_a2;
|
||||
|
||||
explicit AnimationPair(Animation *a1 = NULL, Animation *a2 = NULL);
|
||||
|
||||
bool operator==(const AnimationPair &other) const;
|
||||
};
|
||||
|
||||
SkeletonData *_skeletonData;
|
||||
float _defaultMix;
|
||||
HashMap<AnimationPair, float> _animationToMixTime;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_AnimationStateData_h */
|
||||
@ -0,0 +1,139 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Atlas_h
|
||||
#define Spine_Atlas_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/Extension.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
#include <spine/HasRendererObject.h>
|
||||
#include "TextureRegion.h"
|
||||
|
||||
namespace spine {
|
||||
enum Format {
|
||||
Format_Alpha,
|
||||
Format_Intensity,
|
||||
Format_LuminanceAlpha,
|
||||
Format_RGB565,
|
||||
Format_RGBA4444,
|
||||
Format_RGB888,
|
||||
Format_RGBA8888
|
||||
};
|
||||
|
||||
// Our TextureFilter collides with UE4's TextureFilter in unity builds. We rename
|
||||
// TextureFilter to SpineTextureFilter in UE4.
|
||||
#ifdef SPINE_UE4
|
||||
#define TEXTURE_FILTER_ENUM SpineTextureFilter
|
||||
#else
|
||||
#define TEXTURE_FILTER_ENUM TextureFilter
|
||||
#endif
|
||||
|
||||
enum TEXTURE_FILTER_ENUM {
|
||||
TextureFilter_Unknown,
|
||||
TextureFilter_Nearest,
|
||||
TextureFilter_Linear,
|
||||
TextureFilter_MipMap,
|
||||
TextureFilter_MipMapNearestNearest,
|
||||
TextureFilter_MipMapLinearNearest,
|
||||
TextureFilter_MipMapNearestLinear,
|
||||
TextureFilter_MipMapLinearLinear
|
||||
};
|
||||
|
||||
enum TextureWrap {
|
||||
TextureWrap_MirroredRepeat,
|
||||
TextureWrap_ClampToEdge,
|
||||
TextureWrap_Repeat
|
||||
};
|
||||
|
||||
class SP_API AtlasPage : public SpineObject {
|
||||
public:
|
||||
String name;
|
||||
String texturePath;
|
||||
Format format;
|
||||
TEXTURE_FILTER_ENUM minFilter;
|
||||
TEXTURE_FILTER_ENUM magFilter;
|
||||
TextureWrap uWrap;
|
||||
TextureWrap vWrap;
|
||||
int width, height;
|
||||
bool pma;
|
||||
int index;
|
||||
void *texture;
|
||||
|
||||
explicit AtlasPage(const String &inName) : name(inName), format(Format_RGBA8888),
|
||||
minFilter(TextureFilter_Nearest),
|
||||
magFilter(TextureFilter_Nearest), uWrap(TextureWrap_ClampToEdge),
|
||||
vWrap(TextureWrap_ClampToEdge), width(0), height(0), pma(false), index(0), texture(NULL) {
|
||||
}
|
||||
};
|
||||
|
||||
class SP_API AtlasRegion : public TextureRegion {
|
||||
public:
|
||||
AtlasPage *page;
|
||||
String name;
|
||||
int index;
|
||||
int x, y;
|
||||
Vector<int> splits;
|
||||
Vector<int> pads;
|
||||
Vector <String> names;
|
||||
Vector<float> values;
|
||||
};
|
||||
|
||||
class TextureLoader;
|
||||
|
||||
class SP_API Atlas : public SpineObject {
|
||||
public:
|
||||
Atlas(const String &path, TextureLoader *textureLoader, bool createTexture = true);
|
||||
|
||||
Atlas(const char *data, int length, const char *dir, TextureLoader *textureLoader, bool createTexture = true);
|
||||
|
||||
~Atlas();
|
||||
|
||||
void flipV();
|
||||
|
||||
/// Returns the first region found with the specified name. This method uses String comparison to find the region, so the result
|
||||
/// should be cached rather than calling this method multiple times.
|
||||
/// @return The region, or NULL.
|
||||
AtlasRegion *findRegion(const String &name);
|
||||
|
||||
Vector<AtlasPage *> &getPages();
|
||||
|
||||
Vector<AtlasRegion *> &getRegions();
|
||||
|
||||
private:
|
||||
Vector<AtlasPage *> _pages;
|
||||
Vector<AtlasRegion *> _regions;
|
||||
TextureLoader *_textureLoader;
|
||||
|
||||
void load(const char *begin, int length, const char *dir, bool createTexture);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Atlas_h */
|
||||
@ -0,0 +1,72 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_AtlasAttachmentLoader_h
|
||||
#define Spine_AtlasAttachmentLoader_h
|
||||
|
||||
#include <spine/AttachmentLoader.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
|
||||
namespace spine {
|
||||
class Atlas;
|
||||
|
||||
class AtlasRegion;
|
||||
|
||||
/// An AttachmentLoader that configures attachments using texture regions from an Atlas.
|
||||
/// See http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data about Loading Skeleton Data in the Spine Runtimes Guide.
|
||||
class SP_API AtlasAttachmentLoader : public AttachmentLoader {
|
||||
public:
|
||||
RTTI_DECL
|
||||
|
||||
explicit AtlasAttachmentLoader(Atlas *atlas);
|
||||
|
||||
virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence);
|
||||
|
||||
virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence);
|
||||
|
||||
virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &name);
|
||||
|
||||
virtual PathAttachment *newPathAttachment(Skin &skin, const String &name);
|
||||
|
||||
virtual PointAttachment *newPointAttachment(Skin &skin, const String &name);
|
||||
|
||||
virtual ClippingAttachment *newClippingAttachment(Skin &skin, const String &name);
|
||||
|
||||
virtual void configureAttachment(Attachment *attachment);
|
||||
|
||||
AtlasRegion *findRegion(const String &name);
|
||||
|
||||
private:
|
||||
Atlas *_atlas;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_AtlasAttachmentLoader_h */
|
||||
@ -0,0 +1,62 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Attachment_h
|
||||
#define Spine_Attachment_h
|
||||
|
||||
#include <spine/RTTI.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API Attachment : public SpineObject {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit Attachment(const String &name);
|
||||
|
||||
virtual ~Attachment();
|
||||
|
||||
const String &getName() const;
|
||||
|
||||
virtual Attachment *copy() = 0;
|
||||
|
||||
int getRefCount();
|
||||
|
||||
void reference();
|
||||
|
||||
void dereference();
|
||||
|
||||
private:
|
||||
const String _name;
|
||||
int _refCount;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Attachment_h */
|
||||
@ -0,0 +1,84 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_AttachmentLoader_h
|
||||
#define Spine_AttachmentLoader_h
|
||||
|
||||
#include <spine/RTTI.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
namespace spine {
|
||||
class Skin;
|
||||
|
||||
class Attachment;
|
||||
|
||||
class RegionAttachment;
|
||||
|
||||
class MeshAttachment;
|
||||
|
||||
class BoundingBoxAttachment;
|
||||
|
||||
class PathAttachment;
|
||||
|
||||
class PointAttachment;
|
||||
|
||||
class ClippingAttachment;
|
||||
|
||||
class Sequence;
|
||||
|
||||
class SP_API AttachmentLoader : public SpineObject {
|
||||
public:
|
||||
RTTI_DECL
|
||||
|
||||
AttachmentLoader();
|
||||
|
||||
virtual ~AttachmentLoader();
|
||||
|
||||
/// @return May be NULL to not load any attachment.
|
||||
virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) = 0;
|
||||
|
||||
/// @return May be NULL to not load any attachment.
|
||||
virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) = 0;
|
||||
|
||||
/// @return May be NULL to not load any attachment.
|
||||
virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &name) = 0;
|
||||
|
||||
/// @return May be NULL to not load any attachment
|
||||
virtual PathAttachment *newPathAttachment(Skin &skin, const String &name) = 0;
|
||||
|
||||
virtual PointAttachment *newPointAttachment(Skin &skin, const String &name) = 0;
|
||||
|
||||
virtual ClippingAttachment *newClippingAttachment(Skin &skin, const String &name) = 0;
|
||||
|
||||
virtual void configureAttachment(Attachment *attachment) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_AttachmentLoader_h */
|
||||
@ -0,0 +1,82 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_AttachmentTimeline_h
|
||||
#define Spine_AttachmentTimeline_h
|
||||
|
||||
#include <spine/Timeline.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/MixBlend.h>
|
||||
#include <spine/MixDirection.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
namespace spine {
|
||||
|
||||
class Skeleton;
|
||||
|
||||
class Slot;
|
||||
|
||||
class Event;
|
||||
|
||||
class SP_API AttachmentTimeline : public Timeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit AttachmentTimeline(size_t frameCount, int slotIndex);
|
||||
|
||||
virtual ~AttachmentTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frame, float time, const String &attachmentName);
|
||||
|
||||
Vector<String> &getAttachmentNames();
|
||||
|
||||
int getSlotIndex() { return _slotIndex; }
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
Vector<String> _attachmentNames;
|
||||
|
||||
void setAttachment(Skeleton &skeleton, Slot &slot, String *attachmentName);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_AttachmentTimeline_h */
|
||||
@ -0,0 +1,45 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_AttachmentType_h
|
||||
#define Spine_AttachmentType_h
|
||||
|
||||
namespace spine {
|
||||
enum AttachmentType {
|
||||
AttachmentType_Region,
|
||||
AttachmentType_Boundingbox,
|
||||
AttachmentType_Mesh,
|
||||
AttachmentType_Linkedmesh,
|
||||
AttachmentType_Path,
|
||||
AttachmentType_Point,
|
||||
AttachmentType_Clipping
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_AttachmentType_h */
|
||||
@ -0,0 +1,42 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_BlendMode_h
|
||||
#define Spine_BlendMode_h
|
||||
|
||||
namespace spine {
|
||||
enum BlendMode {
|
||||
BlendMode_Normal = 0,
|
||||
BlendMode_Additive,
|
||||
BlendMode_Multiply,
|
||||
BlendMode_Screen
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_BlendMode_h */
|
||||
@ -0,0 +1,114 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_BlockAllocator_h
|
||||
#define Spine_BlockAllocator_h
|
||||
|
||||
#include <cstdint>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/Extension.h>
|
||||
#include <spine/MathUtil.h>
|
||||
#include <spine/Vector.h>
|
||||
|
||||
namespace spine {
|
||||
struct Block {
|
||||
int size;
|
||||
int allocated;
|
||||
uint8_t *memory;
|
||||
|
||||
int free() {
|
||||
return size - allocated;
|
||||
}
|
||||
|
||||
bool canFit(int numBytes) {
|
||||
return free() >= numBytes;
|
||||
}
|
||||
|
||||
uint8_t *allocate(int numBytes) {
|
||||
uint8_t *ptr = memory + allocated;
|
||||
allocated += numBytes;
|
||||
return ptr;
|
||||
}
|
||||
};
|
||||
|
||||
class BlockAllocator : public SpineObject {
|
||||
int initialBlockSize;
|
||||
Vector <Block> blocks;
|
||||
|
||||
public:
|
||||
BlockAllocator(int initialBlockSize) : initialBlockSize(initialBlockSize) {
|
||||
blocks.add(newBlock(initialBlockSize));
|
||||
}
|
||||
|
||||
~BlockAllocator() {
|
||||
for (int i = 0, n = (int) blocks.size(); i < n; i++) {
|
||||
SpineExtension::free(blocks[i].memory, __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *allocate(size_t num) {
|
||||
return (T *) _allocate((int) (sizeof(T) * num));
|
||||
}
|
||||
|
||||
void compress() {
|
||||
if (blocks.size() == 1) {
|
||||
blocks[0].allocated = 0;
|
||||
return;
|
||||
}
|
||||
int totalSize = 0;
|
||||
for (int i = 0, n = (int)blocks.size(); i < n; i++) {
|
||||
totalSize += blocks[i].size;
|
||||
SpineExtension::free(blocks[i].memory, __FILE__, __LINE__);
|
||||
}
|
||||
blocks.clear();
|
||||
blocks.add(newBlock(totalSize));
|
||||
}
|
||||
|
||||
private:
|
||||
void *_allocate(int numBytes) {
|
||||
// 16-byte align allocations
|
||||
int alignedNumBytes = numBytes + (numBytes % 16 != 0 ? 16 - (numBytes % 16) : 0);
|
||||
Block *block = &blocks[blocks.size() - 1];
|
||||
if (!block->canFit(alignedNumBytes)) {
|
||||
blocks.add(newBlock(MathUtil::max(initialBlockSize, alignedNumBytes)));
|
||||
block = &blocks[blocks.size() - 1];
|
||||
}
|
||||
return block->allocate(alignedNumBytes);
|
||||
}
|
||||
|
||||
Block newBlock(int numBytes) {
|
||||
Block block = {MathUtil::max(initialBlockSize, numBytes), 0, nullptr};
|
||||
block.memory = SpineExtension::alloc<uint8_t>(block.size, __FILE__, __LINE__);
|
||||
return block;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,286 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Bone_h
|
||||
#define Spine_Bone_h
|
||||
|
||||
#include <spine/Updatable.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/Inherit.h>
|
||||
|
||||
namespace spine {
|
||||
class BoneData;
|
||||
|
||||
class Skeleton;
|
||||
|
||||
/// Stores a bone's current pose.
|
||||
///
|
||||
/// A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a
|
||||
/// local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a
|
||||
/// constraint or application code modifies the world transform after it was computed from the local transform.
|
||||
class SP_API Bone : public Updatable {
|
||||
friend class AnimationState;
|
||||
|
||||
friend class RotateTimeline;
|
||||
|
||||
friend class IkConstraint;
|
||||
|
||||
friend class TransformConstraint;
|
||||
|
||||
friend class VertexAttachment;
|
||||
|
||||
friend class PathConstraint;
|
||||
|
||||
friend class PhysicsConstraint;
|
||||
|
||||
friend class Skeleton;
|
||||
|
||||
friend class RegionAttachment;
|
||||
|
||||
friend class PointAttachment;
|
||||
|
||||
friend class AttachmentTimeline;
|
||||
|
||||
friend class RGBATimeline;
|
||||
|
||||
friend class RGBTimeline;
|
||||
|
||||
friend class AlphaTimeline;
|
||||
|
||||
friend class RGBA2Timeline;
|
||||
|
||||
friend class RGB2Timeline;
|
||||
|
||||
friend class ScaleTimeline;
|
||||
|
||||
friend class ScaleXTimeline;
|
||||
|
||||
friend class ScaleYTimeline;
|
||||
|
||||
friend class ShearTimeline;
|
||||
|
||||
friend class ShearXTimeline;
|
||||
|
||||
friend class ShearYTimeline;
|
||||
|
||||
friend class TranslateTimeline;
|
||||
|
||||
friend class TranslateXTimeline;
|
||||
|
||||
friend class TranslateYTimeline;
|
||||
|
||||
friend class InheritTimeline;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static void setYDown(bool inValue);
|
||||
|
||||
static bool isYDown();
|
||||
|
||||
/// @param parent May be NULL.
|
||||
Bone(BoneData &data, Skeleton &skeleton, Bone *parent = NULL);
|
||||
|
||||
/// Same as updateWorldTransform. This method exists for Bone to implement Spine::Updatable.
|
||||
virtual void update(Physics physics);
|
||||
|
||||
/// Computes the world transform using the parent bone and this bone's local transform.
|
||||
void updateWorldTransform();
|
||||
|
||||
/// Computes the world transform using the parent bone and the specified local transform.
|
||||
void
|
||||
updateWorldTransform(float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY);
|
||||
|
||||
/// Computes the individual applied transform values from the world transform. This can be useful to perform processing using
|
||||
/// the applied transform after the world transform has been modified directly (eg, by a constraint)..
|
||||
///
|
||||
/// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation.
|
||||
void updateAppliedTransform();
|
||||
|
||||
void setToSetupPose();
|
||||
|
||||
void worldToLocal(float worldX, float worldY, float &outLocalX, float &outLocalY);
|
||||
|
||||
void worldToParent(float worldX, float worldY, float &outParentX, float &outParentY);
|
||||
|
||||
void localToWorld(float localX, float localY, float &outWorldX, float &outWorldY);
|
||||
|
||||
void parentToWorld(float worldX, float worldY, float &outX, float &outY);
|
||||
|
||||
float worldToLocalRotation(float worldRotation);
|
||||
|
||||
float localToWorldRotation(float localRotation);
|
||||
|
||||
/// Rotates the world transform the specified amount and sets isAppliedValid to false.
|
||||
/// @param degrees Degrees.
|
||||
void rotateWorld(float degrees);
|
||||
|
||||
float getWorldToLocalRotationX();
|
||||
|
||||
float getWorldToLocalRotationY();
|
||||
|
||||
BoneData &getData();
|
||||
|
||||
Skeleton &getSkeleton();
|
||||
|
||||
Bone *getParent();
|
||||
|
||||
Vector<Bone *> &getChildren();
|
||||
|
||||
/// The local X translation.
|
||||
float getX();
|
||||
|
||||
void setX(float inValue);
|
||||
|
||||
/// The local Y translation.
|
||||
float getY();
|
||||
|
||||
void setY(float inValue);
|
||||
|
||||
/// The local rotation.
|
||||
float getRotation();
|
||||
|
||||
void setRotation(float inValue);
|
||||
|
||||
/// The local scaleX.
|
||||
float getScaleX();
|
||||
|
||||
void setScaleX(float inValue);
|
||||
|
||||
/// The local scaleY.
|
||||
float getScaleY();
|
||||
|
||||
void setScaleY(float inValue);
|
||||
|
||||
/// The local shearX.
|
||||
float getShearX();
|
||||
|
||||
void setShearX(float inValue);
|
||||
|
||||
/// The local shearY.
|
||||
float getShearY();
|
||||
|
||||
void setShearY(float inValue);
|
||||
|
||||
/// The rotation, as calculated by any constraints.
|
||||
float getAppliedRotation();
|
||||
|
||||
void setAppliedRotation(float inValue);
|
||||
|
||||
/// The applied local x translation.
|
||||
float getAX();
|
||||
|
||||
void setAX(float inValue);
|
||||
|
||||
/// The applied local y translation.
|
||||
float getAY();
|
||||
|
||||
void setAY(float inValue);
|
||||
|
||||
/// The applied local scaleX.
|
||||
float getAScaleX();
|
||||
|
||||
void setAScaleX(float inValue);
|
||||
|
||||
/// The applied local scaleY.
|
||||
float getAScaleY();
|
||||
|
||||
void setAScaleY(float inValue);
|
||||
|
||||
/// The applied local shearX.
|
||||
float getAShearX();
|
||||
|
||||
void setAShearX(float inValue);
|
||||
|
||||
/// The applied local shearY.
|
||||
float getAShearY();
|
||||
|
||||
void setAShearY(float inValue);
|
||||
|
||||
float getA();
|
||||
|
||||
void setA(float inValue);
|
||||
|
||||
float getB();
|
||||
|
||||
void setB(float inValue);
|
||||
|
||||
float getC();
|
||||
|
||||
void setC(float inValue);
|
||||
|
||||
float getD();
|
||||
|
||||
void setD(float inValue);
|
||||
|
||||
float getWorldX();
|
||||
|
||||
void setWorldX(float inValue);
|
||||
|
||||
float getWorldY();
|
||||
|
||||
void setWorldY(float inValue);
|
||||
|
||||
float getWorldRotationX();
|
||||
|
||||
float getWorldRotationY();
|
||||
|
||||
/// Returns the magnitide (always positive) of the world scale X.
|
||||
float getWorldScaleX();
|
||||
|
||||
/// Returns the magnitide (always positive) of the world scale Y.
|
||||
float getWorldScaleY();
|
||||
|
||||
bool isActive();
|
||||
|
||||
void setActive(bool inValue);
|
||||
|
||||
Inherit getInherit() { return _inherit; }
|
||||
|
||||
void setInherit(Inherit inValue) { _inherit = inValue; }
|
||||
|
||||
private:
|
||||
static bool yDown;
|
||||
|
||||
BoneData &_data;
|
||||
Skeleton &_skeleton;
|
||||
Bone *_parent;
|
||||
Vector<Bone *> _children;
|
||||
float _x, _y, _rotation, _scaleX, _scaleY, _shearX, _shearY;
|
||||
float _ax, _ay, _arotation, _ascaleX, _ascaleY, _ashearX, _ashearY;
|
||||
float _a, _b, _worldX;
|
||||
float _c, _d, _worldY;
|
||||
bool _sorted;
|
||||
bool _active;
|
||||
Inherit _inherit;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Bone_h */
|
||||
@ -0,0 +1,150 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_BoneData_h
|
||||
#define Spine_BoneData_h
|
||||
|
||||
#include <spine/Inherit.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
#include <spine/Color.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API BoneData : public SpineObject {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class AnimationState;
|
||||
|
||||
friend class RotateTimeline;
|
||||
|
||||
friend class ScaleTimeline;
|
||||
|
||||
friend class ScaleXTimeline;
|
||||
|
||||
friend class ScaleYTimeline;
|
||||
|
||||
friend class ShearTimeline;
|
||||
|
||||
friend class ShearXTimeline;
|
||||
|
||||
friend class ShearYTimeline;
|
||||
|
||||
friend class TranslateTimeline;
|
||||
|
||||
friend class TranslateXTimeline;
|
||||
|
||||
friend class TranslateYTimeline;
|
||||
|
||||
public:
|
||||
BoneData(int index, const String &name, BoneData *parent = NULL);
|
||||
|
||||
/// The index of the bone in Skeleton.Bones
|
||||
int getIndex();
|
||||
|
||||
/// The name of the bone, which is unique within the skeleton.
|
||||
const String &getName();
|
||||
|
||||
/// May be NULL.
|
||||
BoneData *getParent();
|
||||
|
||||
float getLength();
|
||||
|
||||
void setLength(float inValue);
|
||||
|
||||
/// Local X translation.
|
||||
float getX();
|
||||
|
||||
void setX(float inValue);
|
||||
|
||||
/// Local Y translation.
|
||||
float getY();
|
||||
|
||||
void setY(float inValue);
|
||||
|
||||
/// Local rotation.
|
||||
float getRotation();
|
||||
|
||||
void setRotation(float inValue);
|
||||
|
||||
/// Local scaleX.
|
||||
float getScaleX();
|
||||
|
||||
void setScaleX(float inValue);
|
||||
|
||||
/// Local scaleY.
|
||||
float getScaleY();
|
||||
|
||||
void setScaleY(float inValue);
|
||||
|
||||
/// Local shearX.
|
||||
float getShearX();
|
||||
|
||||
void setShearX(float inValue);
|
||||
|
||||
/// Local shearY.
|
||||
float getShearY();
|
||||
|
||||
void setShearY(float inValue);
|
||||
|
||||
/// The transform mode for how parent world transforms affect this bone.
|
||||
Inherit getInherit();
|
||||
|
||||
void setInherit(Inherit inValue);
|
||||
|
||||
bool isSkinRequired();
|
||||
|
||||
void setSkinRequired(bool inValue);
|
||||
|
||||
Color &getColor();
|
||||
|
||||
const String &getIcon();
|
||||
|
||||
void setIcon(const String &icon);
|
||||
|
||||
bool isVisible();
|
||||
|
||||
void setVisible(bool inValue);
|
||||
|
||||
private:
|
||||
const int _index;
|
||||
const String _name;
|
||||
BoneData *_parent;
|
||||
float _length;
|
||||
float _x, _y, _rotation, _scaleX, _scaleY, _shearX, _shearY;
|
||||
Inherit _inherit;
|
||||
bool _skinRequired;
|
||||
Color _color;
|
||||
String _icon;
|
||||
bool _visible;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_BoneData_h */
|
||||
@ -0,0 +1,54 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_BoundingBoxAttachment_h
|
||||
#define Spine_BoundingBoxAttachment_h
|
||||
|
||||
#include <spine/VertexAttachment.h>
|
||||
#include <spine/Color.h>
|
||||
#include <spine/SpineObject.h>
|
||||
|
||||
namespace spine {
|
||||
/// Attachment that has a polygon for bounds checking.
|
||||
class SP_API BoundingBoxAttachment : public VertexAttachment {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit BoundingBoxAttachment(const String &name);
|
||||
|
||||
Color &getColor();
|
||||
|
||||
virtual Attachment *copy();
|
||||
|
||||
private:
|
||||
Color _color;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_BoundingBoxAttachment_h */
|
||||
@ -0,0 +1,65 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_ClippingAttachment_h
|
||||
#define Spine_ClippingAttachment_h
|
||||
|
||||
#include <spine/VertexAttachment.h>
|
||||
#include <spine/Color.h>
|
||||
|
||||
namespace spine {
|
||||
class SlotData;
|
||||
|
||||
class SP_API ClippingAttachment : public VertexAttachment {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class SkeletonClipping;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit ClippingAttachment(const String &name);
|
||||
|
||||
SlotData *getEndSlot();
|
||||
|
||||
void setEndSlot(SlotData *inValue);
|
||||
|
||||
Color &getColor();
|
||||
|
||||
virtual Attachment *copy();
|
||||
|
||||
private:
|
||||
SlotData *_endSlot;
|
||||
Color _color;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_ClippingAttachment_h */
|
||||
@ -0,0 +1,110 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SPINE_COLOR_H
|
||||
#define SPINE_COLOR_H
|
||||
|
||||
#include <spine/MathUtil.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API Color : public SpineObject {
|
||||
public:
|
||||
Color() : r(0), g(0), b(0), a(0) {
|
||||
}
|
||||
|
||||
Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {
|
||||
clamp();
|
||||
}
|
||||
|
||||
inline Color &set(float _r, float _g, float _b, float _a) {
|
||||
this->r = _r;
|
||||
this->g = _g;
|
||||
this->b = _b;
|
||||
this->a = _a;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &set(float _r, float _g, float _b) {
|
||||
this->r = _r;
|
||||
this->g = _g;
|
||||
this->b = _b;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &set(const Color &other) {
|
||||
r = other.r;
|
||||
g = other.g;
|
||||
b = other.b;
|
||||
a = other.a;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &add(float _r, float _g, float _b, float _a) {
|
||||
this->r += _r;
|
||||
this->g += _g;
|
||||
this->b += _b;
|
||||
this->a += _a;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &add(float _r, float _g, float _b) {
|
||||
this->r += _r;
|
||||
this->g += _g;
|
||||
this->b += _b;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &add(const Color &other) {
|
||||
r += other.r;
|
||||
g += other.g;
|
||||
b += other.b;
|
||||
a += other.a;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &clamp() {
|
||||
r = MathUtil::clamp(this->r, 0, 1);
|
||||
g = MathUtil::clamp(this->g, 0, 1);
|
||||
b = MathUtil::clamp(this->b, 0, 1);
|
||||
a = MathUtil::clamp(this->a, 0, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
float r, g, b, a;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //SPINE_COLOR_H
|
||||
@ -0,0 +1,197 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_ColorTimeline_h
|
||||
#define Spine_ColorTimeline_h
|
||||
|
||||
#include <spine/CurveTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API RGBATimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit RGBATimeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
virtual ~RGBATimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frame, float time, float r, float g, float b, float a);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
static const int ENTRIES = 5;
|
||||
static const int R = 1;
|
||||
static const int G = 2;
|
||||
static const int B = 3;
|
||||
static const int A = 4;
|
||||
};
|
||||
|
||||
class SP_API RGBTimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit RGBTimeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
virtual ~RGBTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frame, float time, float r, float g, float b);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
static const int ENTRIES = 4;
|
||||
static const int R = 1;
|
||||
static const int G = 2;
|
||||
static const int B = 3;
|
||||
};
|
||||
|
||||
class SP_API AlphaTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit AlphaTimeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
virtual ~AlphaTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
};
|
||||
|
||||
class SP_API RGBA2Timeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit RGBA2Timeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
virtual ~RGBA2Timeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frame, float time, float r, float g, float b, float a, float r2, float g2, float b2);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
static const int ENTRIES = 8;
|
||||
static const int R = 1;
|
||||
static const int G = 2;
|
||||
static const int B = 3;
|
||||
static const int A = 4;
|
||||
static const int R2 = 5;
|
||||
static const int G2 = 6;
|
||||
static const int B2 = 7;
|
||||
};
|
||||
|
||||
class SP_API RGB2Timeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit RGB2Timeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
virtual ~RGB2Timeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frame, float time, float r, float g, float b, float r2, float g2, float b2);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
static const int ENTRIES = 7;
|
||||
static const int R = 1;
|
||||
static const int G = 2;
|
||||
static const int B = 3;
|
||||
static const int R2 = 4;
|
||||
static const int G2 = 5;
|
||||
static const int B2 = 6;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_ColorTimeline_h */
|
||||
@ -0,0 +1,69 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Constraint_h
|
||||
#define Spine_Constraint_h
|
||||
|
||||
#include <spine/Updatable.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
namespace spine {
|
||||
/// The interface for all constraints.
|
||||
class SP_API ConstraintData : public SpineObject {
|
||||
|
||||
friend class SkeletonBinary;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
ConstraintData(const String &name);
|
||||
|
||||
virtual ~ConstraintData();
|
||||
|
||||
/// The IK constraint's name, which is unique within the skeleton.
|
||||
const String &getName();
|
||||
|
||||
/// The ordinal for the order a skeleton's constraints will be applied.
|
||||
size_t getOrder();
|
||||
|
||||
void setOrder(size_t inValue);
|
||||
|
||||
/// Whether the constraint is only active for a specific skin.
|
||||
bool isSkinRequired();
|
||||
|
||||
void setSkinRequired(bool inValue);
|
||||
|
||||
private:
|
||||
const String _name;
|
||||
size_t _order;
|
||||
bool _skinRequired;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Constraint_h */
|
||||
@ -0,0 +1,129 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_ContainerUtil_h
|
||||
#define Spine_ContainerUtil_h
|
||||
|
||||
#include <spine/Extension.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/HashMap.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API ContainerUtil : public SpineObject {
|
||||
public:
|
||||
/// Finds an item by comparing each item's name.
|
||||
/// It is more efficient to cache the results of this method than to call it multiple times.
|
||||
/// @return May be NULL.
|
||||
template<typename T>
|
||||
static T *findWithName(Vector<T *> &items, const String &name) {
|
||||
assert(name.length() > 0);
|
||||
|
||||
for (size_t i = 0; i < items.size(); ++i) {
|
||||
T *item = items[i];
|
||||
if (item->getName() == name) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// @return -1 if the item was not found.
|
||||
template<typename T>
|
||||
static int findIndexWithName(Vector<T *> &items, const String &name) {
|
||||
assert(name.length() > 0);
|
||||
|
||||
for (size_t i = 0, len = items.size(); i < len; ++i) {
|
||||
T *item = items[i];
|
||||
if (item->getName() == name) {
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// Finds an item by comparing each item's name.
|
||||
/// It is more efficient to cache the results of this method than to call it multiple times.
|
||||
/// @return May be NULL.
|
||||
template<typename T>
|
||||
static T *findWithDataName(Vector<T *> &items, const String &name) {
|
||||
assert(name.length() > 0);
|
||||
|
||||
for (size_t i = 0; i < items.size(); ++i) {
|
||||
T *item = items[i];
|
||||
if (item->getData().getName() == name) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// @return -1 if the item was not found.
|
||||
template<typename T>
|
||||
static int findIndexWithDataName(Vector<T *> &items, const String &name) {
|
||||
assert(name.length() > 0);
|
||||
|
||||
for (size_t i = 0, len = items.size(); i < len; ++i) {
|
||||
T *item = items[i];
|
||||
if (item->getData().getName() == name) {
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void cleanUpVectorOfPointers(Vector<T *> &items) {
|
||||
for (int i = (int) items.size() - 1; i >= 0; i--) {
|
||||
T *item = items[i];
|
||||
|
||||
delete item;
|
||||
|
||||
items.removeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// ctor, copy ctor, and assignment should be private in a Singleton
|
||||
ContainerUtil();
|
||||
|
||||
ContainerUtil(const ContainerUtil &);
|
||||
|
||||
ContainerUtil &operator=(const ContainerUtil &);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_ContainerUtil_h */
|
||||
@ -0,0 +1,111 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_CurveTimeline_h
|
||||
#define Spine_CurveTimeline_h
|
||||
|
||||
#include <spine/Timeline.h>
|
||||
#include <spine/Vector.h>
|
||||
|
||||
namespace spine {
|
||||
/// Base class for frames that use an interpolation bezier curve.
|
||||
class SP_API CurveTimeline : public Timeline {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit CurveTimeline(size_t frameCount, size_t frameEntries, size_t bezierCount);
|
||||
|
||||
virtual ~CurveTimeline();
|
||||
|
||||
void setLinear(size_t frame);
|
||||
|
||||
void setStepped(size_t frame);
|
||||
|
||||
virtual void
|
||||
setBezier(size_t bezier, size_t frame, float value, float time1, float value1, float cx1, float cy1, float cx2,
|
||||
float cy2, float time2, float value2);
|
||||
|
||||
float getBezierValue(float time, size_t frame, size_t valueOffset, size_t i);
|
||||
|
||||
Vector<float> &getCurves();
|
||||
|
||||
protected:
|
||||
static const int LINEAR = 0;
|
||||
static const int STEPPED = 1;
|
||||
static const int BEZIER = 2;
|
||||
static const int BEZIER_SIZE = 18;
|
||||
|
||||
Vector<float> _curves; // type, x, y, ...
|
||||
};
|
||||
|
||||
class SP_API CurveTimeline1 : public CurveTimeline {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit CurveTimeline1(size_t frameCount, size_t bezierCount);
|
||||
|
||||
virtual ~CurveTimeline1();
|
||||
|
||||
void setFrame(size_t frame, float time, float value);
|
||||
|
||||
float getCurveValue(float time);
|
||||
|
||||
float getRelativeValue(float time, float alpha, MixBlend blend, float current, float setup);
|
||||
|
||||
float getAbsoluteValue(float time, float alpha, MixBlend blend, float current, float setup);
|
||||
|
||||
float getAbsoluteValue (float time, float alpha, MixBlend blend, float current, float setup, float value);
|
||||
|
||||
float getScaleValue (float time, float alpha, MixBlend blend, MixDirection direction, float current, float setup);
|
||||
|
||||
protected:
|
||||
static const int ENTRIES = 2;
|
||||
static const int VALUE = 1;
|
||||
};
|
||||
|
||||
class SP_API CurveTimeline2 : public CurveTimeline {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit CurveTimeline2(size_t frameCount, size_t bezierCount);
|
||||
|
||||
virtual ~CurveTimeline2();
|
||||
|
||||
void setFrame(size_t frame, float time, float value1, float value2);
|
||||
|
||||
float getCurveValue(float time);
|
||||
|
||||
protected:
|
||||
static const int ENTRIES = 3;
|
||||
static const int VALUE1 = 1;
|
||||
static const int VALUE2 = 2;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_CurveTimeline_h */
|
||||
@ -0,0 +1,139 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SPINE_LOG_H
|
||||
#define SPINE_LOG_H
|
||||
|
||||
#include <spine/Extension.h>
|
||||
#include <spine/Vector.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SP_API DebugExtension : public SpineExtension {
|
||||
struct Allocation {
|
||||
void *address;
|
||||
size_t size;
|
||||
const char *fileName;
|
||||
int line;
|
||||
|
||||
Allocation() : address(NULL), size(0), fileName(NULL), line(0) {
|
||||
}
|
||||
|
||||
Allocation(void *a, size_t s, const char *f, int l) : address(a), size(s), fileName(f), line(l) {
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
DebugExtension(SpineExtension *extension) : _extension(extension), _allocations(0), _reallocations(0),
|
||||
_frees(0) {
|
||||
}
|
||||
|
||||
void reportLeaks() {
|
||||
for (std::map<void *, Allocation>::iterator it = _allocated.begin(); it != _allocated.end(); it++) {
|
||||
printf("\"%s:%i (%zu bytes at %p)\n", it->second.fileName, it->second.line, it->second.size,
|
||||
it->second.address);
|
||||
}
|
||||
printf("allocations: %zu, reallocations: %zu, frees: %zu\n", _allocations, _reallocations, _frees);
|
||||
if (_allocated.empty()) printf("No leaks detected\n");
|
||||
}
|
||||
|
||||
void clearAllocations() {
|
||||
_allocated.clear();
|
||||
_usedMemory = 0;
|
||||
}
|
||||
|
||||
virtual void *_alloc(size_t size, const char *file, int line) {
|
||||
void *result = _extension->_alloc(size, file, line);
|
||||
_allocated[result] = Allocation(result, size, file, line);
|
||||
_allocations++;
|
||||
_usedMemory += size;
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void *_calloc(size_t size, const char *file, int line) {
|
||||
void *result = _extension->_calloc(size, file, line);
|
||||
_allocated[result] = Allocation(result, size, file, line);
|
||||
_allocations++;
|
||||
_usedMemory += size;
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void *_realloc(void *ptr, size_t size, const char *file, int line) {
|
||||
if (_allocated.count(ptr)) _usedMemory -= _allocated[ptr].size;
|
||||
_allocated.erase(ptr);
|
||||
void *result = _extension->_realloc(ptr, size, file, line);
|
||||
_reallocations++;
|
||||
_allocated[result] = Allocation(result, size, file, line);
|
||||
_usedMemory += size;
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void _free(void *mem, const char *file, int line) {
|
||||
if (_allocated.count(mem)) {
|
||||
_extension->_free(mem, file, line);
|
||||
_frees++;
|
||||
_usedMemory -= _allocated[mem].size;
|
||||
_allocated.erase(mem);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s:%i (address %p): Double free or not allocated through SpineExtension\n", file, line, mem);
|
||||
_extension->_free(mem, file, line);
|
||||
}
|
||||
|
||||
virtual char *_readFile(const String &path, int *length) {
|
||||
auto data = _extension->_readFile(path, length);
|
||||
|
||||
if (_allocated.count(data) == 0) {
|
||||
_allocated[data] = Allocation(data, sizeof(char) * (*length), nullptr, 0);
|
||||
_allocations++;
|
||||
_usedMemory += sizeof(char) * (*length);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
size_t getUsedMemory() {
|
||||
return _usedMemory;
|
||||
}
|
||||
|
||||
private:
|
||||
SpineExtension *_extension;
|
||||
std::map<void *, Allocation> _allocated;
|
||||
size_t _allocations;
|
||||
size_t _reallocations;
|
||||
size_t _frees;
|
||||
size_t _usedMemory;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //SPINE_LOG_H
|
||||
@ -0,0 +1,80 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_DeformTimeline_h
|
||||
#define Spine_DeformTimeline_h
|
||||
|
||||
#include <spine/CurveTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
class VertexAttachment;
|
||||
|
||||
class SP_API DeformTimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit DeformTimeline(size_t frameCount, size_t bezierCount, int slotIndex, VertexAttachment *attachment);
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, Vector<float> &vertices);
|
||||
|
||||
Vector <Vector<float>> &getVertices();
|
||||
|
||||
VertexAttachment *getAttachment();
|
||||
|
||||
void setAttachment(VertexAttachment *inValue);
|
||||
|
||||
virtual void
|
||||
setBezier(size_t bezier, size_t frame, float value, float time1, float value1, float cx1, float cy1, float cx2,
|
||||
float cy2, float time2, float value2);
|
||||
|
||||
float getCurvePercent(float time, int frame);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; }
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
Vector <Vector<float>> _vertices;
|
||||
|
||||
VertexAttachment *_attachment;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_DeformTimeline_h */
|
||||
@ -0,0 +1,61 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_DrawOrderTimeline_h
|
||||
#define Spine_DrawOrderTimeline_h
|
||||
|
||||
#include <spine/Timeline.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API DrawOrderTimeline : public Timeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit DrawOrderTimeline(size_t frameCount);
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
/// @param drawOrder May be NULL to use bind pose draw order
|
||||
void setFrame(size_t frame, float time, Vector<int> &drawOrder);
|
||||
|
||||
Vector <Vector<int>> &getDrawOrders();
|
||||
|
||||
private:
|
||||
Vector <Vector<int>> _drawOrders;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_DrawOrderTimeline_h */
|
||||
@ -0,0 +1,86 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Event_h
|
||||
#define Spine_Event_h
|
||||
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
namespace spine {
|
||||
class EventData;
|
||||
|
||||
/// Stores the current pose values for an Event.
|
||||
class SP_API Event : public SpineObject {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class AnimationState;
|
||||
|
||||
public:
|
||||
Event(float time, const EventData &data);
|
||||
|
||||
const EventData &getData();
|
||||
|
||||
/// The animation time this event was keyed.
|
||||
float getTime();
|
||||
|
||||
int getIntValue();
|
||||
|
||||
void setIntValue(int inValue);
|
||||
|
||||
float getFloatValue();
|
||||
|
||||
void setFloatValue(float inValue);
|
||||
|
||||
const String &getStringValue();
|
||||
|
||||
void setStringValue(const String &inValue);
|
||||
|
||||
float getVolume();
|
||||
|
||||
void setVolume(float inValue);
|
||||
|
||||
float getBalance();
|
||||
|
||||
void setBalance(float inValue);
|
||||
|
||||
private:
|
||||
const EventData &_data;
|
||||
const float _time;
|
||||
int _intValue;
|
||||
float _floatValue;
|
||||
String _stringValue;
|
||||
float _volume;
|
||||
float _balance;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Event_h */
|
||||
@ -0,0 +1,86 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_EventData_h
|
||||
#define Spine_EventData_h
|
||||
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
namespace spine {
|
||||
/// Stores the setup pose values for an Event.
|
||||
class SP_API EventData : public SpineObject {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class Event;
|
||||
|
||||
public:
|
||||
explicit EventData(const String &name);
|
||||
|
||||
/// The name of the event, which is unique within the skeleton.
|
||||
const String &getName() const;
|
||||
|
||||
int getIntValue() const;
|
||||
|
||||
void setIntValue(int inValue);
|
||||
|
||||
float getFloatValue() const;
|
||||
|
||||
void setFloatValue(float inValue);
|
||||
|
||||
const String &getStringValue() const;
|
||||
|
||||
void setStringValue(const String &inValue);
|
||||
|
||||
const String &getAudioPath() const;
|
||||
|
||||
void setAudioPath(const String &inValue);
|
||||
|
||||
float getVolume() const;
|
||||
|
||||
void setVolume(float inValue);
|
||||
|
||||
float getBalance() const;
|
||||
|
||||
void setBalance(float inValue);
|
||||
|
||||
private:
|
||||
const String _name;
|
||||
int _intValue;
|
||||
float _floatValue;
|
||||
String _stringValue;
|
||||
String _audioPath;
|
||||
float _volume;
|
||||
float _balance;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_EventData_h */
|
||||
@ -0,0 +1,62 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_EventTimeline_h
|
||||
#define Spine_EventTimeline_h
|
||||
|
||||
#include <spine/Timeline.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API EventTimeline : public Timeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit EventTimeline(size_t frameCount);
|
||||
|
||||
~EventTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(size_t frame, Event *event);
|
||||
|
||||
Vector<Event *> &getEvents();
|
||||
|
||||
private:
|
||||
Vector<Event *> _events;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_EventTimeline_h */
|
||||
@ -0,0 +1,125 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Extension_h
|
||||
#define Spine_Extension_h
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <spine/dll.h>
|
||||
|
||||
#define SP_UNUSED(x) (void)(x)
|
||||
|
||||
namespace spine {
|
||||
class String;
|
||||
|
||||
class SP_API SpineExtension {
|
||||
public:
|
||||
template<typename T>
|
||||
static T *alloc(size_t num, const char *file, int line) {
|
||||
return (T *) getInstance()->_alloc(sizeof(T) * num, file, line);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T *calloc(size_t num, const char *file, int line) {
|
||||
return (T *) getInstance()->_calloc(sizeof(T) * num, file, line);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T *realloc(T *ptr, size_t num, const char *file, int line) {
|
||||
return (T *) getInstance()->_realloc(ptr, sizeof(T) * num, file, line);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void free(T *ptr, const char *file, int line) {
|
||||
getInstance()->_free((void *) ptr, file, line);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void beforeFree(T *ptr) {
|
||||
getInstance()->_beforeFree((void *) ptr);
|
||||
}
|
||||
|
||||
static char *readFile(const String &path, int *length) {
|
||||
return getInstance()->_readFile(path, length);
|
||||
}
|
||||
|
||||
static void setInstance(SpineExtension *inSpineExtension);
|
||||
|
||||
static SpineExtension *getInstance();
|
||||
|
||||
virtual ~SpineExtension();
|
||||
|
||||
/// Implement this function to use your own memory allocator
|
||||
virtual void *_alloc(size_t size, const char *file, int line) = 0;
|
||||
|
||||
virtual void *_calloc(size_t size, const char *file, int line) = 0;
|
||||
|
||||
virtual void *_realloc(void *ptr, size_t size, const char *file, int line) = 0;
|
||||
|
||||
/// If you provide a spineAllocFunc, you should also provide a spineFreeFunc
|
||||
virtual void _free(void *mem, const char *file, int line) = 0;
|
||||
|
||||
virtual char *_readFile(const String &path, int *length) = 0;
|
||||
|
||||
virtual void _beforeFree(void *ptr) { SP_UNUSED(ptr); }
|
||||
|
||||
protected:
|
||||
SpineExtension();
|
||||
|
||||
private:
|
||||
static SpineExtension *_instance;
|
||||
};
|
||||
|
||||
class SP_API DefaultSpineExtension : public SpineExtension {
|
||||
public:
|
||||
DefaultSpineExtension();
|
||||
|
||||
virtual ~DefaultSpineExtension();
|
||||
|
||||
protected:
|
||||
virtual void *_alloc(size_t size, const char *file, int line) override;
|
||||
|
||||
virtual void *_calloc(size_t size, const char *file, int line) override;
|
||||
|
||||
virtual void *_realloc(void *ptr, size_t size, const char *file, int line) override;
|
||||
|
||||
virtual void _free(void *mem, const char *file, int line) override;
|
||||
|
||||
virtual char *_readFile(const String &path, int *length) override;
|
||||
};
|
||||
|
||||
// This function is to be implemented by engine specific runtimes to provide
|
||||
// the default extension for that engine. It is called the first time
|
||||
// SpineExtension::getInstance() is called, when no instance has been set
|
||||
// yet.
|
||||
extern SpineExtension *getDefaultExtension();
|
||||
}
|
||||
|
||||
#endif /* Spine_Extension_h */
|
||||
@ -0,0 +1,65 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_HasRendererObject_h
|
||||
#define Spine_HasRendererObject_h
|
||||
|
||||
#include <spine/dll.h>
|
||||
|
||||
namespace spine {
|
||||
|
||||
typedef void (*DisposeRendererObject)(void *rendererObject);
|
||||
|
||||
class SP_API HasRendererObject {
|
||||
public:
|
||||
explicit HasRendererObject() : _rendererObject(0), _dispose(0) {};
|
||||
|
||||
virtual ~HasRendererObject() {
|
||||
if (_dispose && _rendererObject)
|
||||
_dispose(_rendererObject);
|
||||
}
|
||||
|
||||
void *getRendererObject() { return _rendererObject; }
|
||||
|
||||
void setRendererObject(void *rendererObject, DisposeRendererObject dispose = 0) {
|
||||
if (_dispose && _rendererObject && _rendererObject != rendererObject)
|
||||
_dispose(_rendererObject);
|
||||
|
||||
_rendererObject = rendererObject;
|
||||
_dispose = dispose;
|
||||
}
|
||||
|
||||
private:
|
||||
void *_rendererObject;
|
||||
DisposeRendererObject _dispose;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,200 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_HashMap_h
|
||||
#define Spine_HashMap_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/SpineObject.h>
|
||||
|
||||
// Required for new with line number and file name in MSVC
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4291)
|
||||
|
||||
#pragma warning(disable:4251)
|
||||
|
||||
#endif
|
||||
|
||||
namespace spine {
|
||||
template<typename K, typename V>
|
||||
class SP_API HashMap : public SpineObject {
|
||||
private:
|
||||
class Entry;
|
||||
|
||||
public:
|
||||
class SP_API Pair {
|
||||
public:
|
||||
explicit Pair(K &k, V &v) : key(k), value(v) {}
|
||||
|
||||
K &key;
|
||||
V &value;
|
||||
};
|
||||
|
||||
class SP_API Entries {
|
||||
public:
|
||||
friend class HashMap;
|
||||
|
||||
explicit Entries(Entry *entry) : _entry(NULL), _hasChecked(false) {
|
||||
_start.next = entry;
|
||||
_entry = &_start;
|
||||
}
|
||||
|
||||
Pair next() {
|
||||
assert(_entry);
|
||||
assert(_hasChecked);
|
||||
_entry = _entry->next;
|
||||
Pair pair(_entry->_key, _entry->_value);
|
||||
_hasChecked = false;
|
||||
return pair;
|
||||
}
|
||||
|
||||
bool hasNext() {
|
||||
_hasChecked = true;
|
||||
return _entry->next;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _hasChecked;
|
||||
Entry _start;
|
||||
Entry *_entry;
|
||||
};
|
||||
|
||||
HashMap() :
|
||||
_head(NULL),
|
||||
_size(0) {
|
||||
}
|
||||
|
||||
~HashMap() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for (Entry *entry = _head; entry != NULL;) {
|
||||
Entry *next = entry->next;
|
||||
delete entry;
|
||||
entry = next;
|
||||
}
|
||||
_head = NULL;
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
size_t size() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
void put(const K &key, const V &value) {
|
||||
Entry *entry = find(key);
|
||||
if (entry) {
|
||||
entry->_key = key;
|
||||
entry->_value = value;
|
||||
} else {
|
||||
entry = new(__FILE__, __LINE__) Entry();
|
||||
entry->_key = key;
|
||||
entry->_value = value;
|
||||
|
||||
Entry *oldHead = _head;
|
||||
|
||||
if (oldHead) {
|
||||
_head = entry;
|
||||
oldHead->prev = entry;
|
||||
entry->next = oldHead;
|
||||
} else {
|
||||
_head = entry;
|
||||
}
|
||||
_size++;
|
||||
}
|
||||
}
|
||||
|
||||
bool addAll(Vector <K> &keys, const V &value) {
|
||||
size_t oldSize = _size;
|
||||
for (size_t i = 0; i < keys.size(); i++) {
|
||||
put(keys[i], value);
|
||||
}
|
||||
return _size != oldSize;
|
||||
}
|
||||
|
||||
bool containsKey(const K &key) {
|
||||
return find(key) != NULL;
|
||||
}
|
||||
|
||||
bool remove(const K &key) {
|
||||
Entry *entry = find(key);
|
||||
if (!entry) return false;
|
||||
|
||||
Entry *prev = entry->prev;
|
||||
Entry *next = entry->next;
|
||||
|
||||
if (prev) prev->next = next;
|
||||
else _head = next;
|
||||
if (next) next->prev = entry->prev;
|
||||
|
||||
delete entry;
|
||||
_size--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
V operator[](const K &key) {
|
||||
Entry *entry = find(key);
|
||||
if (entry) return entry->_value;
|
||||
else {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Entries getEntries() const {
|
||||
return Entries(_head);
|
||||
}
|
||||
|
||||
private:
|
||||
Entry *find(const K &key) {
|
||||
for (Entry *entry = _head; entry != NULL; entry = entry->next) {
|
||||
if (entry->_key == key)
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class SP_API Entry : public SpineObject {
|
||||
public:
|
||||
K _key;
|
||||
V _value;
|
||||
Entry *next;
|
||||
Entry *prev;
|
||||
|
||||
Entry() : next(NULL), prev(NULL) {}
|
||||
};
|
||||
|
||||
Entry *_head;
|
||||
size_t _size;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_HashMap_h */
|
||||
@ -0,0 +1,118 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_IkConstraint_h
|
||||
#define Spine_IkConstraint_h
|
||||
|
||||
#include <spine/ConstraintData.h>
|
||||
|
||||
#include <spine/Vector.h>
|
||||
|
||||
namespace spine {
|
||||
class IkConstraintData;
|
||||
|
||||
class Skeleton;
|
||||
|
||||
class Bone;
|
||||
|
||||
class SP_API IkConstraint : public Updatable {
|
||||
friend class Skeleton;
|
||||
|
||||
friend class IkConstraintTimeline;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
/// Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified
|
||||
/// in the world coordinate system.
|
||||
static void
|
||||
apply(Bone &bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float alpha);
|
||||
|
||||
/// Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as
|
||||
/// possible. The target is specified in the world coordinate system.
|
||||
/// @param child A direct descendant of the parent bone.
|
||||
static void
|
||||
apply(Bone &parent, Bone &child, float targetX, float targetY, int bendDir, bool stretch, bool uniform,
|
||||
float softness,
|
||||
float alpha);
|
||||
|
||||
IkConstraint(IkConstraintData &data, Skeleton &skeleton);
|
||||
|
||||
virtual void update(Physics physics);
|
||||
|
||||
virtual int getOrder();
|
||||
|
||||
IkConstraintData &getData();
|
||||
|
||||
Vector<Bone *> &getBones();
|
||||
|
||||
Bone *getTarget();
|
||||
|
||||
void setTarget(Bone *inValue);
|
||||
|
||||
int getBendDirection();
|
||||
|
||||
void setBendDirection(int inValue);
|
||||
|
||||
bool getCompress();
|
||||
|
||||
void setCompress(bool inValue);
|
||||
|
||||
bool getStretch();
|
||||
|
||||
void setStretch(bool inValue);
|
||||
|
||||
float getMix();
|
||||
|
||||
void setMix(float inValue);
|
||||
|
||||
float getSoftness();
|
||||
|
||||
void setSoftness(float inValue);
|
||||
|
||||
bool isActive();
|
||||
|
||||
void setActive(bool inValue);
|
||||
|
||||
void setToSetupPose();
|
||||
|
||||
private:
|
||||
IkConstraintData &_data;
|
||||
Vector<Bone *> _bones;
|
||||
int _bendDirection;
|
||||
bool _compress;
|
||||
bool _stretch;
|
||||
float _mix;
|
||||
float _softness;
|
||||
Bone *_target;
|
||||
bool _active;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_IkConstraint_h */
|
||||
@ -0,0 +1,102 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_IkConstraintData_h
|
||||
#define Spine_IkConstraintData_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
#include <spine/ConstraintData.h>
|
||||
|
||||
namespace spine {
|
||||
class BoneData;
|
||||
|
||||
class SP_API IkConstraintData : public ConstraintData {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class IkConstraint;
|
||||
|
||||
friend class Skeleton;
|
||||
|
||||
friend class IkConstraintTimeline;
|
||||
|
||||
public:
|
||||
RTTI_DECL
|
||||
|
||||
explicit IkConstraintData(const String &name);
|
||||
|
||||
/// The bones that are constrained by this IK Constraint.
|
||||
Vector<BoneData *> &getBones();
|
||||
|
||||
/// The bone that is the IK target.
|
||||
BoneData *getTarget();
|
||||
|
||||
void setTarget(BoneData *inValue);
|
||||
|
||||
/// Controls the bend direction of the IK bones, either 1 or -1.
|
||||
int getBendDirection();
|
||||
|
||||
void setBendDirection(int inValue);
|
||||
|
||||
bool getCompress();
|
||||
|
||||
void setCompress(bool inValue);
|
||||
|
||||
bool getStretch();
|
||||
|
||||
void setStretch(bool inValue);
|
||||
|
||||
bool getUniform();
|
||||
|
||||
void setUniform(bool inValue);
|
||||
|
||||
float getMix();
|
||||
|
||||
void setMix(float inValue);
|
||||
|
||||
float getSoftness();
|
||||
|
||||
void setSoftness(float inValue);
|
||||
|
||||
private:
|
||||
Vector<BoneData *> _bones;
|
||||
BoneData *_target;
|
||||
int _bendDirection;
|
||||
bool _compress;
|
||||
bool _stretch;
|
||||
bool _uniform;
|
||||
float _mix;
|
||||
float _softness;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_IkConstraintData_h */
|
||||
@ -0,0 +1,70 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_IkConstraintTimeline_h
|
||||
#define Spine_IkConstraintTimeline_h
|
||||
|
||||
#include <spine/CurveTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SP_API IkConstraintTimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit IkConstraintTimeline(size_t frameCount, size_t bezierCount, int ikConstraintIndex);
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time, mix and bend direction of the specified keyframe.
|
||||
void setFrame(int frame, float time, float mix, float softness, int bendDirection, bool compress, bool stretch);
|
||||
|
||||
int getIkConstraintIndex() { return _constraintIndex; }
|
||||
|
||||
void setIkConstraintIndex(int inValue) { _constraintIndex = inValue; }
|
||||
|
||||
private:
|
||||
int _constraintIndex;
|
||||
|
||||
static const int ENTRIES = 6;
|
||||
static const int MIX = 1;
|
||||
static const int SOFTNESS = 2;
|
||||
static const int BEND_DIRECTION = 3;
|
||||
static const int COMPRESS = 4;
|
||||
static const int STRETCH = 5;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_IkConstraintTimeline_h */
|
||||
@ -0,0 +1,43 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_TransformMode_h
|
||||
#define Spine_TransformMode_h
|
||||
|
||||
namespace spine {
|
||||
enum Inherit {
|
||||
Inherit_Normal = 0,
|
||||
Inherit_OnlyTranslation,
|
||||
Inherit_NoRotationOrReflection,
|
||||
Inherit_NoScale,
|
||||
Inherit_NoScaleOrReflection
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_TransformMode_h */
|
||||
@ -0,0 +1,71 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_InheritTimeline_h
|
||||
#define Spine_InheritTimeline_h
|
||||
|
||||
#include <spine/Timeline.h>
|
||||
|
||||
#include <spine/Animation.h>
|
||||
#include <spine/Property.h>
|
||||
#include <spine/Inherit.h>
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SP_API InheritTimeline : public Timeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit InheritTimeline(size_t frameCount, int boneIndex);
|
||||
|
||||
virtual ~InheritTimeline();
|
||||
|
||||
void setFrame(int frame, float time, Inherit inherit);
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getBoneIndex() { return _boneIndex; }
|
||||
|
||||
void setBoneIndex(int inValue) { _boneIndex = inValue; }
|
||||
|
||||
private:
|
||||
int _boneIndex;
|
||||
|
||||
static const int ENTRIES = 2;
|
||||
static const int INHERIT = 1;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_InheritTimeline_h */
|
||||
@ -0,0 +1,116 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Json_h
|
||||
#define Spine_Json_h
|
||||
|
||||
#include <spine/SpineObject.h>
|
||||
|
||||
#ifndef SPINE_JSON_HAVE_PREV
|
||||
/* spine doesn't use the "prev" link in the Json sibling lists. */
|
||||
#define SPINE_JSON_HAVE_PREV 0
|
||||
#endif
|
||||
|
||||
namespace spine {
|
||||
class SP_API Json : public SpineObject {
|
||||
friend class SkeletonJson;
|
||||
|
||||
public:
|
||||
/* Json Types: */
|
||||
static const int JSON_FALSE;
|
||||
static const int JSON_TRUE;
|
||||
static const int JSON_NULL;
|
||||
static const int JSON_NUMBER;
|
||||
static const int JSON_STRING;
|
||||
static const int JSON_ARRAY;
|
||||
static const int JSON_OBJECT;
|
||||
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
static Json *getItem(Json *object, const char *string);
|
||||
|
||||
static Json *getItem(Json *object, int childIndex);
|
||||
|
||||
static const char *getString(Json *object, const char *name, const char *defaultValue);
|
||||
|
||||
static float getFloat(Json *object, const char *name, float defaultValue);
|
||||
|
||||
static int getInt(Json *object, const char *name, int defaultValue);
|
||||
|
||||
static bool getBoolean(Json *object, const char *name, bool defaultValue);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when Json_create() returns 0. 0 when Json_create() succeeds. */
|
||||
static const char *getError();
|
||||
|
||||
/* Supply a block of JSON, and this returns a Json object you can interrogate. Call Json_dispose when finished. */
|
||||
explicit Json(const char *value);
|
||||
|
||||
~Json();
|
||||
|
||||
|
||||
private:
|
||||
static const char *_error;
|
||||
|
||||
Json *_next;
|
||||
#if SPINE_JSON_HAVE_PREV
|
||||
Json* _prev; /* next/prev allow you to walk array/object chains. Alternatively, use getSize/getItem */
|
||||
#endif
|
||||
Json *_child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
|
||||
int _type; /* The type of the item, as above. */
|
||||
int _size; /* The number of children. */
|
||||
|
||||
const char *_valueString; /* The item's string, if type==JSON_STRING */
|
||||
int _valueInt; /* The item's number, if type==JSON_NUMBER */
|
||||
float _valueFloat; /* The item's number, if type==JSON_NUMBER */
|
||||
|
||||
const char *_name; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
|
||||
/* Utility to jump whitespace and cr/lf */
|
||||
static const char *skip(const char *inValue);
|
||||
|
||||
/* Parser core - when encountering text, process appropriately. */
|
||||
static const char *parseValue(Json *item, const char *value);
|
||||
|
||||
/* Parse the input text into an unescaped cstring, and populate item. */
|
||||
static const char *parseString(Json *item, const char *str);
|
||||
|
||||
/* Parse the input text to generate a number, and populate the result into item. */
|
||||
static const char *parseNumber(Json *item, const char *num);
|
||||
|
||||
/* Build an array from input text. */
|
||||
static const char *parseArray(Json *item, const char *value);
|
||||
|
||||
/* Build an object from the text. */
|
||||
static const char *parseObject(Json *item, const char *value);
|
||||
|
||||
static int json_strcasecmp(const char *s1, const char *s2);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Json_h */
|
||||
@ -0,0 +1,61 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_LinkedMesh_h
|
||||
#define Spine_LinkedMesh_h
|
||||
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
namespace spine {
|
||||
class MeshAttachment;
|
||||
|
||||
class SP_API LinkedMesh : public SpineObject {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
public:
|
||||
LinkedMesh(MeshAttachment *mesh, const int skinIndex, size_t slotIndex, const String &parent,
|
||||
bool inheritTimeline);
|
||||
|
||||
LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent,
|
||||
bool inheritTimeline);
|
||||
|
||||
private:
|
||||
MeshAttachment *_mesh;
|
||||
int _skinIndex;
|
||||
String _skin;
|
||||
size_t _slotIndex;
|
||||
String _parent;
|
||||
bool _inheritTimeline;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_LinkedMesh_h */
|
||||
@ -0,0 +1,57 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SPINE_DEBUG_LOG_H
|
||||
#define SPINE_DEBUG_LOG_H
|
||||
|
||||
#include <spine/spine.h>
|
||||
|
||||
namespace spine {
|
||||
SP_API void spDebug_printSkeletonData(SkeletonData *skeletonData);
|
||||
|
||||
SP_API void spDebug_printAnimation(Animation *animation);
|
||||
|
||||
SP_API void spDebug_printTimeline(Timeline *timeline);
|
||||
|
||||
SP_API void spDebug_printBoneDatas(Vector<BoneData *> &boneDatas);
|
||||
|
||||
SP_API void spDebug_printBoneData(BoneData *boneData);
|
||||
|
||||
SP_API void spDebug_printSkeleton(Skeleton *skeleton);
|
||||
|
||||
SP_API void spDebug_printBones(Vector<Bone *> &bones);
|
||||
|
||||
SP_API void spDebug_printBone(Bone *bone);
|
||||
|
||||
SP_API void spDebug_printFloats(float *values, int numFloats);
|
||||
|
||||
SP_API void spDebug_printFloats(Vector<float> &values);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,139 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_MathUtil_h
|
||||
#define Spine_MathUtil_h
|
||||
|
||||
#include <spine/SpineObject.h>
|
||||
|
||||
#include <string.h>
|
||||
// Needed for older MSVC versions
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SP_API MathUtil : public SpineObject {
|
||||
private:
|
||||
MathUtil();
|
||||
|
||||
public:
|
||||
static const float Pi;
|
||||
static const float Pi_2;
|
||||
static const float InvPi_2;
|
||||
static const float Deg_Rad;
|
||||
static const float Rad_Deg;
|
||||
|
||||
template<typename T>
|
||||
static inline T min(T a, T b) { return a < b ? a : b; }
|
||||
|
||||
template<typename T>
|
||||
static inline T max(T a, T b) { return a > b ? a : b; }
|
||||
|
||||
static float sign(float val);
|
||||
|
||||
static float clamp(float x, float lower, float upper);
|
||||
|
||||
static float abs(float v);
|
||||
|
||||
/// Returns the sine in radians from a lookup table.
|
||||
static float sin(float radians);
|
||||
|
||||
/// Returns the cosine in radians from a lookup table.
|
||||
static float cos(float radians);
|
||||
|
||||
/// Returns the sine in radians from a lookup table.
|
||||
static float sinDeg(float degrees);
|
||||
|
||||
/// Returns the cosine in radians from a lookup table.
|
||||
static float cosDeg(float degrees);
|
||||
|
||||
/// Returns atan2 in radians, faster but less accurate than Math.Atan2. Average error of 0.00231 radians (0.1323
|
||||
/// degrees), largest error of 0.00488 radians (0.2796 degrees).
|
||||
static float atan2(float y, float x);
|
||||
|
||||
static float atan2Deg(float x, float y);
|
||||
|
||||
static float acos(float v);
|
||||
|
||||
static float sqrt(float v);
|
||||
|
||||
static float fmod(float a, float b);
|
||||
|
||||
static bool isNan(float v);
|
||||
|
||||
static float quietNan();
|
||||
|
||||
static float random();
|
||||
|
||||
static float randomTriangular(float min, float max);
|
||||
|
||||
static float randomTriangular(float min, float max, float mode);
|
||||
|
||||
static float pow(float a, float b);
|
||||
|
||||
static float ceil(float v);
|
||||
};
|
||||
|
||||
struct SP_API Interpolation {
|
||||
virtual float apply(float a) = 0;
|
||||
|
||||
virtual float interpolate(float start, float end, float a) {
|
||||
return start + (end - start) * apply(a);
|
||||
}
|
||||
|
||||
virtual ~Interpolation() {};
|
||||
};
|
||||
|
||||
struct SP_API PowInterpolation : public Interpolation {
|
||||
PowInterpolation(int power) : power(power) {
|
||||
}
|
||||
|
||||
float apply(float a) {
|
||||
if (a <= 0.5f) return MathUtil::pow(a * 2.0f, (float) power) / 2.0f;
|
||||
return MathUtil::pow((a - 1.0f) * 2.0f, (float) power) / (power % 2 == 0 ? -2.0f : 2.0f) + 1.0f;
|
||||
}
|
||||
|
||||
int power;
|
||||
};
|
||||
|
||||
struct SP_API PowOutInterpolation : public Interpolation {
|
||||
PowOutInterpolation(int power) : power(power) {
|
||||
}
|
||||
|
||||
float apply(float a) {
|
||||
return MathUtil::pow(a - 1, (float) power) * (power % 2 == 0 ? -1.0f : 1.0f) + 1.0f;
|
||||
}
|
||||
|
||||
int power;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* Spine_MathUtil_h */
|
||||
@ -0,0 +1,122 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_MeshAttachment_h
|
||||
#define Spine_MeshAttachment_h
|
||||
|
||||
#include <spine/VertexAttachment.h>
|
||||
#include <spine/TextureRegion.h>
|
||||
#include <spine/Sequence.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/Color.h>
|
||||
#include <spine/HasRendererObject.h>
|
||||
|
||||
namespace spine {
|
||||
/// Attachment that displays a texture region using a mesh.
|
||||
class SP_API MeshAttachment : public VertexAttachment {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class AtlasAttachmentLoader;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit MeshAttachment(const String &name);
|
||||
|
||||
virtual ~MeshAttachment();
|
||||
|
||||
using VertexAttachment::computeWorldVertices;
|
||||
|
||||
virtual void computeWorldVertices(Slot &slot, size_t start, size_t count, float *worldVertices, size_t offset,
|
||||
size_t stride = 2);
|
||||
|
||||
void updateRegion();
|
||||
|
||||
int getHullLength();
|
||||
|
||||
void setHullLength(int inValue);
|
||||
|
||||
Vector<float> &getRegionUVs();
|
||||
|
||||
/// The UV pair for each vertex, normalized within the entire texture. See also MeshAttachment::updateRegion
|
||||
Vector<float> &getUVs();
|
||||
|
||||
Vector<unsigned short> &getTriangles();
|
||||
|
||||
Color &getColor();
|
||||
|
||||
const String &getPath();
|
||||
|
||||
void setPath(const String &inValue);
|
||||
|
||||
TextureRegion *getRegion();
|
||||
|
||||
void setRegion(TextureRegion *region);
|
||||
|
||||
Sequence *getSequence();
|
||||
|
||||
void setSequence(Sequence *sequence);
|
||||
|
||||
MeshAttachment *getParentMesh();
|
||||
|
||||
void setParentMesh(MeshAttachment *inValue);
|
||||
|
||||
// Nonessential.
|
||||
Vector<unsigned short> &getEdges();
|
||||
|
||||
float getWidth();
|
||||
|
||||
void setWidth(float inValue);
|
||||
|
||||
float getHeight();
|
||||
|
||||
void setHeight(float inValue);
|
||||
|
||||
virtual Attachment *copy();
|
||||
|
||||
MeshAttachment *newLinkedMesh();
|
||||
|
||||
private:
|
||||
MeshAttachment *_parentMesh;
|
||||
Vector<float> _uvs;
|
||||
Vector<float> _regionUVs;
|
||||
Vector<unsigned short> _triangles;
|
||||
Vector<unsigned short> _edges;
|
||||
String _path;
|
||||
Color _color;
|
||||
int _hullLength;
|
||||
int _width, _height;
|
||||
TextureRegion *_region;
|
||||
Sequence *_sequence;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_MeshAttachment_h */
|
||||
@ -0,0 +1,45 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_MixPose_h
|
||||
#define Spine_MixPose_h
|
||||
|
||||
namespace spine {
|
||||
|
||||
/// Controls how a timeline is mixed with the setup or current pose.
|
||||
/// See also Timeline::apply(Skeleton&, float, float, Vector&, float, Blend, MixDirection)
|
||||
enum MixBlend {
|
||||
MixBlend_Setup = 0,
|
||||
MixBlend_First,
|
||||
MixBlend_Replace,
|
||||
MixBlend_Add
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_MixPose_h */
|
||||
@ -0,0 +1,44 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_MixDirection_h
|
||||
#define Spine_MixDirection_h
|
||||
|
||||
namespace spine {
|
||||
|
||||
/// Indicates whether a timeline's alpha is mixing out over time toward 0 (the setup or current pose) or mixing in toward 1 (the timeline's pose).
|
||||
/// See also Timeline::apply(Skeleton&, float, float, Vector&, float, MixPose, MixDirection)
|
||||
enum MixDirection {
|
||||
MixDirection_In = 0,
|
||||
MixDirection_Out
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* Spine_MixDirection_h */
|
||||
@ -0,0 +1,70 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PathAttachment_h
|
||||
#define Spine_PathAttachment_h
|
||||
|
||||
#include <spine/VertexAttachment.h>
|
||||
#include <spine/Color.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API PathAttachment : public VertexAttachment {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PathAttachment(const String &name);
|
||||
|
||||
/// The length in the setup pose from the start of the path to the end of each curve.
|
||||
Vector<float> &getLengths();
|
||||
|
||||
bool isClosed();
|
||||
|
||||
void setClosed(bool inValue);
|
||||
|
||||
bool isConstantSpeed();
|
||||
|
||||
void setConstantSpeed(bool inValue);
|
||||
|
||||
Color &getColor();
|
||||
|
||||
virtual Attachment *copy();
|
||||
|
||||
private:
|
||||
Vector<float> _lengths;
|
||||
bool _closed;
|
||||
bool _constantSpeed;
|
||||
Color _color;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PathAttachment_h */
|
||||
@ -0,0 +1,133 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PathConstraint_h
|
||||
#define Spine_PathConstraint_h
|
||||
|
||||
#include <spine/ConstraintData.h>
|
||||
|
||||
#include <spine/Vector.h>
|
||||
|
||||
namespace spine {
|
||||
class PathConstraintData;
|
||||
|
||||
class Skeleton;
|
||||
|
||||
class PathAttachment;
|
||||
|
||||
class Bone;
|
||||
|
||||
class Slot;
|
||||
|
||||
class SP_API PathConstraint : public Updatable {
|
||||
friend class Skeleton;
|
||||
|
||||
friend class PathConstraintMixTimeline;
|
||||
|
||||
friend class PathConstraintPositionTimeline;
|
||||
|
||||
friend class PathConstraintSpacingTimeline;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
PathConstraint(PathConstraintData &data, Skeleton &skeleton);
|
||||
|
||||
virtual void update(Physics physics);
|
||||
|
||||
virtual int getOrder();
|
||||
|
||||
PathConstraintData &getData();
|
||||
|
||||
Vector<Bone *> &getBones();
|
||||
|
||||
Slot *getTarget();
|
||||
|
||||
void setTarget(Slot *inValue);
|
||||
|
||||
float getPosition();
|
||||
|
||||
void setPosition(float inValue);
|
||||
|
||||
float getSpacing();
|
||||
|
||||
void setSpacing(float inValue);
|
||||
|
||||
float getMixRotate();
|
||||
|
||||
void setMixRotate(float inValue);
|
||||
|
||||
float getMixX();
|
||||
|
||||
void setMixX(float inValue);
|
||||
|
||||
float getMixY();
|
||||
|
||||
void setMixY(float inValue);
|
||||
|
||||
bool isActive();
|
||||
|
||||
void setActive(bool inValue);
|
||||
|
||||
void setToSetupPose();
|
||||
|
||||
private:
|
||||
static const float EPSILON;
|
||||
static const int NONE;
|
||||
static const int BEFORE;
|
||||
static const int AFTER;
|
||||
|
||||
PathConstraintData &_data;
|
||||
Vector<Bone *> _bones;
|
||||
Slot *_target;
|
||||
float _position, _spacing;
|
||||
float _mixRotate, _mixX, _mixY;
|
||||
|
||||
Vector<float> _spaces;
|
||||
Vector<float> _positions;
|
||||
Vector<float> _world;
|
||||
Vector<float> _curves;
|
||||
Vector<float> _lengths;
|
||||
Vector<float> _segments;
|
||||
|
||||
bool _active;
|
||||
|
||||
Vector<float> &computeWorldPositions(PathAttachment &path, int spacesCount, bool tangents);
|
||||
|
||||
static void addBeforePosition(float p, Vector<float> &temp, int i, Vector<float> &output, int o);
|
||||
|
||||
static void addAfterPosition(float p, Vector<float> &temp, int i, Vector<float> &output, int o);
|
||||
|
||||
static void
|
||||
addCurvePosition(float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2,
|
||||
Vector<float> &output, int o, bool tangents);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PathConstraint_h */
|
||||
@ -0,0 +1,119 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PathConstraintData_h
|
||||
#define Spine_PathConstraintData_h
|
||||
|
||||
#include <spine/PositionMode.h>
|
||||
#include <spine/SpacingMode.h>
|
||||
#include <spine/RotateMode.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
#include <spine/ConstraintData.h>
|
||||
|
||||
namespace spine {
|
||||
class BoneData;
|
||||
|
||||
class SlotData;
|
||||
|
||||
class SP_API PathConstraintData : public ConstraintData {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class PathConstraint;
|
||||
|
||||
friend class Skeleton;
|
||||
|
||||
friend class PathConstraintMixTimeline;
|
||||
|
||||
friend class PathConstraintPositionTimeline;
|
||||
|
||||
friend class PathConstraintSpacingTimeline;
|
||||
public:
|
||||
RTTI_DECL
|
||||
|
||||
explicit PathConstraintData(const String &name);
|
||||
|
||||
Vector<BoneData *> &getBones();
|
||||
|
||||
SlotData *getTarget();
|
||||
|
||||
void setTarget(SlotData *inValue);
|
||||
|
||||
PositionMode getPositionMode();
|
||||
|
||||
void setPositionMode(PositionMode inValue);
|
||||
|
||||
SpacingMode getSpacingMode();
|
||||
|
||||
void setSpacingMode(SpacingMode inValue);
|
||||
|
||||
RotateMode getRotateMode();
|
||||
|
||||
void setRotateMode(RotateMode inValue);
|
||||
|
||||
float getOffsetRotation();
|
||||
|
||||
void setOffsetRotation(float inValue);
|
||||
|
||||
float getPosition();
|
||||
|
||||
void setPosition(float inValue);
|
||||
|
||||
float getSpacing();
|
||||
|
||||
void setSpacing(float inValue);
|
||||
|
||||
float getMixRotate();
|
||||
|
||||
void setMixRotate(float inValue);
|
||||
|
||||
float getMixX();
|
||||
|
||||
void setMixX(float inValue);
|
||||
|
||||
float getMixY();
|
||||
|
||||
void setMixY(float inValue);
|
||||
|
||||
private:
|
||||
Vector<BoneData *> _bones;
|
||||
SlotData *_target;
|
||||
PositionMode _positionMode;
|
||||
SpacingMode _spacingMode;
|
||||
RotateMode _rotateMode;
|
||||
float _offsetRotation;
|
||||
float _position, _spacing;
|
||||
float _mixRotate, _mixX, _mixY;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PathConstraintData_h */
|
||||
@ -0,0 +1,68 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PathConstraintMixTimeline_h
|
||||
#define Spine_PathConstraintMixTimeline_h
|
||||
|
||||
#include <spine/CurveTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SP_API PathConstraintMixTimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PathConstraintMixTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex);
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and mixes of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, float mixRotate, float mixX, float mixY);
|
||||
|
||||
int getPathConstraintIndex() { return _constraintIndex; }
|
||||
|
||||
void setPathConstraintIndex(int inValue) { _constraintIndex = inValue; }
|
||||
|
||||
private:
|
||||
int _constraintIndex;
|
||||
|
||||
static const int ENTRIES = 4;
|
||||
static const int ROTATE = 1;
|
||||
static const int X = 2;
|
||||
static const int Y = 3;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PathConstraintMixTimeline_h */
|
||||
@ -0,0 +1,64 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PathConstraintPositionTimeline_h
|
||||
#define Spine_PathConstraintPositionTimeline_h
|
||||
|
||||
#include <spine/CurveTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SP_API PathConstraintPositionTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
explicit PathConstraintPositionTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex);
|
||||
|
||||
virtual ~PathConstraintPositionTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getPathConstraintIndex() { return _constraintIndex; }
|
||||
|
||||
void setPathConstraintIndex(int inValue) { _constraintIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _constraintIndex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PathConstraintPositionTimeline_h */
|
||||
@ -0,0 +1,59 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PathConstraintSpacingTimeline_h
|
||||
#define Spine_PathConstraintSpacingTimeline_h
|
||||
|
||||
#include <spine/PathConstraintPositionTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API PathConstraintSpacingTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PathConstraintSpacingTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex);
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getPathConstraintIndex() { return _pathConstraintIndex; }
|
||||
|
||||
void setPathConstraintIndex(int inValue) { _pathConstraintIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _pathConstraintIndex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PathConstraintSpacingTimeline_h */
|
||||
@ -0,0 +1,50 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Physics_h
|
||||
#define Spine_Physics_h
|
||||
|
||||
/** Determines how physics and other non-deterministic updates are applied. */
|
||||
namespace spine {
|
||||
enum Physics {
|
||||
/** Physics are not updated or applied. */
|
||||
Physics_None,
|
||||
|
||||
/** Physics are reset to the current pose. */
|
||||
Physics_Reset,
|
||||
|
||||
/** Physics are updated and the pose from physics is applied. */
|
||||
Physics_Update,
|
||||
|
||||
/** Physics are not updated but the pose from physics is applied. */
|
||||
Physics_Pose
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,197 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PhysicsConstraint_h
|
||||
#define Spine_PhysicsConstraint_h
|
||||
|
||||
#include <spine/ConstraintData.h>
|
||||
|
||||
#include <spine/Vector.h>
|
||||
|
||||
namespace spine {
|
||||
class PhysicsConstraintData;
|
||||
|
||||
class Skeleton;
|
||||
|
||||
class Bone;
|
||||
|
||||
class SP_API PhysicsConstraint : public Updatable {
|
||||
|
||||
friend class Skeleton;
|
||||
|
||||
friend class PhysicsConstraintTimeline;
|
||||
|
||||
friend class PhysicsConstraintInertiaTimeline;
|
||||
|
||||
friend class PhysicsConstraintStrengthTimeline;
|
||||
|
||||
friend class PhysicsConstraintDampingTimeline;
|
||||
|
||||
friend class PhysicsConstraintMassTimeline;
|
||||
|
||||
friend class PhysicsConstraintWindTimeline;
|
||||
|
||||
friend class PhysicsConstraintGravityTimeline;
|
||||
|
||||
friend class PhysicsConstraintMixTimeline;
|
||||
|
||||
friend class PhysicsConstraintResetTimeline;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
PhysicsConstraint(PhysicsConstraintData& data, Skeleton& skeleton);
|
||||
|
||||
PhysicsConstraintData &getData();
|
||||
|
||||
void setBone(Bone* bone);
|
||||
Bone* getBone();
|
||||
|
||||
void setInertia(float value);
|
||||
float getInertia();
|
||||
|
||||
void setStrength(float value);
|
||||
float getStrength();
|
||||
|
||||
void setDamping(float value);
|
||||
float getDamping();
|
||||
|
||||
void setMassInverse(float value);
|
||||
float getMassInverse();
|
||||
|
||||
void setWind(float value);
|
||||
float getWind();
|
||||
|
||||
void setGravity(float value);
|
||||
float getGravity();
|
||||
|
||||
void setMix(float value);
|
||||
float getMix();
|
||||
|
||||
void setReset(bool value);
|
||||
bool getReset();
|
||||
|
||||
void setUx(float value);
|
||||
float getUx();
|
||||
|
||||
void setUy(float value);
|
||||
float getUy();
|
||||
|
||||
void setCx(float value);
|
||||
float getCx();
|
||||
|
||||
void setCy(float value);
|
||||
float getCy();
|
||||
|
||||
void setTx(float value);
|
||||
float getTx();
|
||||
|
||||
void setTy(float value);
|
||||
float getTy();
|
||||
|
||||
void setXOffset(float value);
|
||||
float getXOffset();
|
||||
|
||||
void setXVelocity(float value);
|
||||
float getXVelocity();
|
||||
|
||||
void setYOffset(float value);
|
||||
float getYOffset();
|
||||
|
||||
void setYVelocity(float value);
|
||||
float getYVelocity();
|
||||
|
||||
void setRotateOffset(float value);
|
||||
float getRotateOffset();
|
||||
|
||||
void setRotateVelocity(float value);
|
||||
float getRotateVelocity();
|
||||
|
||||
void setScaleOffset(float value);
|
||||
float getScaleOffset();
|
||||
|
||||
void setScaleVelocity(float value);
|
||||
float getScaleVelocity();
|
||||
|
||||
void setActive(bool value);
|
||||
bool isActive();
|
||||
|
||||
void setRemaining(float value);
|
||||
float getRemaining();
|
||||
|
||||
void setLastTime(float value);
|
||||
float getLastTime();
|
||||
|
||||
void reset();
|
||||
|
||||
void setToSetupPose();
|
||||
|
||||
virtual void update(Physics physics);
|
||||
|
||||
void translate(float x, float y);
|
||||
|
||||
void rotate(float x, float y, float degrees);
|
||||
|
||||
private:
|
||||
PhysicsConstraintData& _data;
|
||||
Bone* _bone;
|
||||
|
||||
float _inertia;
|
||||
float _strength;
|
||||
float _damping;
|
||||
float _massInverse;
|
||||
float _wind;
|
||||
float _gravity;
|
||||
float _mix;
|
||||
|
||||
bool _reset;
|
||||
float _ux;
|
||||
float _uy;
|
||||
float _cx;
|
||||
float _cy;
|
||||
float _tx;
|
||||
float _ty;
|
||||
float _xOffset;
|
||||
float _xVelocity;
|
||||
float _yOffset;
|
||||
float _yVelocity;
|
||||
float _rotateOffset;
|
||||
float _rotateVelocity;
|
||||
float _scaleOffset;
|
||||
float _scaleVelocity;
|
||||
|
||||
bool _active;
|
||||
|
||||
Skeleton& _skeleton;
|
||||
float _remaining;
|
||||
float _lastTime;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PhysicsConstraint_h */
|
||||
@ -0,0 +1,151 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PhysicsConstraintData_h
|
||||
#define Spine_PhysicsConstraintData_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/SpineString.h>
|
||||
#include <spine/ConstraintData.h>
|
||||
|
||||
namespace spine {
|
||||
class BoneData;
|
||||
|
||||
class SP_API PhysicsConstraintData : public ConstraintData {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class Skeleton;
|
||||
|
||||
friend class PhysicsConstraint;
|
||||
|
||||
public:
|
||||
RTTI_DECL
|
||||
|
||||
explicit PhysicsConstraintData(const String &name);
|
||||
|
||||
void setBone(BoneData* bone);
|
||||
|
||||
BoneData* getBone() const;
|
||||
|
||||
void setX(float x);
|
||||
|
||||
float getX() const;
|
||||
|
||||
void setY(float y);
|
||||
|
||||
float getY() const;
|
||||
|
||||
void setRotate(float rotate);
|
||||
|
||||
float getRotate() const;
|
||||
|
||||
void setScaleX(float scaleX);
|
||||
|
||||
float getScaleX() const;
|
||||
|
||||
void setShearX(float shearX);
|
||||
|
||||
float getShearX() const;
|
||||
|
||||
void setLimit(float limit);
|
||||
|
||||
float getLimit() const;
|
||||
|
||||
void setStep(float step);
|
||||
|
||||
float getStep() const;
|
||||
|
||||
void setInertia(float inertia);
|
||||
|
||||
float getInertia() const;
|
||||
|
||||
void setStrength(float strength);
|
||||
|
||||
float getStrength() const;
|
||||
|
||||
void setDamping(float damping);
|
||||
|
||||
float getDamping() const;
|
||||
|
||||
void setMassInverse(float massInverse);
|
||||
|
||||
float getMassInverse() const;
|
||||
|
||||
void setWind(float wind);
|
||||
|
||||
float getWind() const;
|
||||
|
||||
void setGravity(float gravity);
|
||||
|
||||
float getGravity() const;
|
||||
|
||||
void setMix(float mix);
|
||||
|
||||
float getMix() const;
|
||||
|
||||
void setInertiaGlobal(bool inertiaGlobal);
|
||||
|
||||
bool isInertiaGlobal() const;
|
||||
|
||||
void setStrengthGlobal(bool strengthGlobal);
|
||||
|
||||
bool isStrengthGlobal() const;
|
||||
|
||||
void setDampingGlobal(bool dampingGlobal);
|
||||
|
||||
bool isDampingGlobal() const;
|
||||
|
||||
void setMassGlobal(bool massGlobal);
|
||||
|
||||
bool isMassGlobal() const;
|
||||
|
||||
void setWindGlobal(bool windGlobal);
|
||||
|
||||
bool isWindGlobal() const;
|
||||
|
||||
void setGravityGlobal(bool gravityGlobal);
|
||||
|
||||
bool isGravityGlobal() const;
|
||||
|
||||
void setMixGlobal(bool mixGlobal);
|
||||
|
||||
bool isMixGlobal() const;
|
||||
|
||||
private:
|
||||
BoneData *_bone;
|
||||
float _x, _y, _rotate, _scaleX, _shearX, _limit;
|
||||
float _step, _inertia, _strength, _damping, _massInverse, _wind, _gravity, _mix;
|
||||
bool _inertiaGlobal, _strengthGlobal, _dampingGlobal, _massGlobal, _windGlobal, _gravityGlobal, _mixGlobal;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PhysicsConstraintData_h */
|
||||
@ -0,0 +1,288 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PhysicsConstraintTimeline_h
|
||||
#define Spine_PhysicsConstraintTimeline_h
|
||||
|
||||
#include <spine/CurveTimeline.h>
|
||||
#include <spine/PhysicsConstraint.h>
|
||||
#include <spine/PhysicsConstraintData.h>
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SP_API PhysicsConstraintTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PhysicsConstraintTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex, Property property);
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getPhysicsConstraintIndex() { return _constraintIndex; }
|
||||
|
||||
void setPhysicsConstraintIndex(int inValue) { _constraintIndex = inValue; }
|
||||
|
||||
protected:
|
||||
virtual float setup(PhysicsConstraint *constraint) = 0;
|
||||
virtual float get(PhysicsConstraint *constraint) = 0;
|
||||
virtual void set(PhysicsConstraint *constraint, float value) = 0;
|
||||
virtual bool global(PhysicsConstraintData &constraintData) = 0;
|
||||
|
||||
private:
|
||||
int _constraintIndex;
|
||||
};
|
||||
|
||||
class SP_API PhysicsConstraintInertiaTimeline : public PhysicsConstraintTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PhysicsConstraintInertiaTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintInertia) {};
|
||||
|
||||
protected:
|
||||
float setup(PhysicsConstraint *constraint) {
|
||||
return constraint->_data.getInertia();
|
||||
}
|
||||
|
||||
float get(PhysicsConstraint *constraint) {
|
||||
return constraint->_inertia;
|
||||
}
|
||||
|
||||
void set(PhysicsConstraint *constraint, float value) {
|
||||
constraint->_inertia = value;
|
||||
}
|
||||
|
||||
bool global(PhysicsConstraintData &constraintData) {
|
||||
return constraintData.isInertiaGlobal();
|
||||
}
|
||||
};
|
||||
|
||||
class SP_API PhysicsConstraintStrengthTimeline : public PhysicsConstraintTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PhysicsConstraintStrengthTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintStrength) {};
|
||||
|
||||
protected:
|
||||
float setup(PhysicsConstraint *constraint) {
|
||||
return constraint->_data.getStrength();
|
||||
}
|
||||
|
||||
float get(PhysicsConstraint *constraint) {
|
||||
return constraint->_strength;
|
||||
}
|
||||
|
||||
void set(PhysicsConstraint *constraint, float value) {
|
||||
constraint->_strength = value;
|
||||
}
|
||||
|
||||
bool global(PhysicsConstraintData &constraintData) {
|
||||
return constraintData.isStrengthGlobal();
|
||||
}
|
||||
};
|
||||
|
||||
class SP_API PhysicsConstraintDampingTimeline : public PhysicsConstraintTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PhysicsConstraintDampingTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintDamping) {};
|
||||
|
||||
protected:
|
||||
float setup(PhysicsConstraint *constraint) {
|
||||
return constraint->_data.getDamping();
|
||||
}
|
||||
|
||||
float get(PhysicsConstraint *constraint) {
|
||||
return constraint->_damping;
|
||||
}
|
||||
|
||||
void set(PhysicsConstraint *constraint, float value) {
|
||||
constraint->_damping = value;
|
||||
}
|
||||
|
||||
bool global(PhysicsConstraintData &constraintData) {
|
||||
return constraintData.isDampingGlobal();
|
||||
}
|
||||
};
|
||||
|
||||
class SP_API PhysicsConstraintMassTimeline : public PhysicsConstraintTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PhysicsConstraintMassTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintMass) {};
|
||||
|
||||
protected:
|
||||
float setup(PhysicsConstraint *constraint) {
|
||||
return 1 / constraint->_data.getMassInverse();
|
||||
}
|
||||
|
||||
float get(PhysicsConstraint *constraint) {
|
||||
return 1 / constraint->_massInverse;
|
||||
}
|
||||
|
||||
void set(PhysicsConstraint *constraint, float value) {
|
||||
constraint->_massInverse = 1 / value;
|
||||
}
|
||||
|
||||
bool global(PhysicsConstraintData &constraintData) {
|
||||
return constraintData.isMassGlobal();
|
||||
}
|
||||
};
|
||||
|
||||
class SP_API PhysicsConstraintWindTimeline : public PhysicsConstraintTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PhysicsConstraintWindTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintWind) {};
|
||||
|
||||
protected:
|
||||
float setup(PhysicsConstraint *constraint) {
|
||||
return constraint->_data.getWind();
|
||||
}
|
||||
|
||||
float get(PhysicsConstraint *constraint) {
|
||||
return constraint->_wind;
|
||||
}
|
||||
|
||||
void set(PhysicsConstraint *constraint, float value) {
|
||||
constraint->_wind = value;
|
||||
}
|
||||
|
||||
bool global(PhysicsConstraintData &constraintData) {
|
||||
return constraintData.isWindGlobal();
|
||||
}
|
||||
};
|
||||
|
||||
class SP_API PhysicsConstraintGravityTimeline : public PhysicsConstraintTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PhysicsConstraintGravityTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintGravity) {};
|
||||
|
||||
protected:
|
||||
float setup(PhysicsConstraint *constraint) {
|
||||
return constraint->_data.getGravity();
|
||||
}
|
||||
|
||||
float get(PhysicsConstraint *constraint) {
|
||||
return constraint->_gravity;
|
||||
}
|
||||
|
||||
void set(PhysicsConstraint *constraint, float value) {
|
||||
constraint->_gravity = value;
|
||||
}
|
||||
|
||||
bool global(PhysicsConstraintData &constraintData) {
|
||||
return constraintData.isGravityGlobal();
|
||||
}
|
||||
};
|
||||
|
||||
class SP_API PhysicsConstraintMixTimeline : public PhysicsConstraintTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PhysicsConstraintMixTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintMix) {};
|
||||
|
||||
protected:
|
||||
float setup(PhysicsConstraint *constraint) {
|
||||
return constraint->_data.getMix();
|
||||
}
|
||||
|
||||
float get(PhysicsConstraint *constraint) {
|
||||
return constraint->_mix;
|
||||
}
|
||||
|
||||
void set(PhysicsConstraint *constraint, float value) {
|
||||
constraint->_mix = value;
|
||||
}
|
||||
|
||||
bool global(PhysicsConstraintData &constraintData) {
|
||||
return constraintData.isMixGlobal();
|
||||
}
|
||||
};
|
||||
|
||||
class SP_API PhysicsConstraintResetTimeline : public Timeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PhysicsConstraintResetTimeline(size_t frameCount, int physicsConstraintIndex): Timeline(frameCount, 1), _constraintIndex(physicsConstraintIndex) {
|
||||
PropertyId ids[] = {((PropertyId)Property_PhysicsConstraintReset) << 32};
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
void setFrame(int frame, float time) {
|
||||
_frames[frame] = time;
|
||||
}
|
||||
private:
|
||||
int _constraintIndex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PhysicsConstraintTimeline_h */
|
||||
@ -0,0 +1,81 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PointAttachment_h
|
||||
#define Spine_PointAttachment_h
|
||||
|
||||
#include <spine/Attachment.h>
|
||||
#include <spine/Color.h>
|
||||
|
||||
namespace spine {
|
||||
class Bone;
|
||||
|
||||
/// An attachment which is a single point and a rotation. This can be used to spawn projectiles, particles, etc. A bone can be
|
||||
/// used in similar ways, but a PointAttachment is slightly less expensive to compute and can be hidden, shown, and placed in a
|
||||
/// skin.
|
||||
///
|
||||
/// See http://esotericsoftware.com/spine-point-attachments for Point Attachments in the Spine User Guide.
|
||||
///
|
||||
class SP_API PointAttachment : public Attachment {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PointAttachment(const String &name);
|
||||
|
||||
void computeWorldPosition(Bone &bone, float &ox, float &oy);
|
||||
|
||||
float computeWorldRotation(Bone &bone);
|
||||
|
||||
float getX();
|
||||
|
||||
void setX(float inValue);
|
||||
|
||||
float getY();
|
||||
|
||||
void setY(float inValue);
|
||||
|
||||
float getRotation();
|
||||
|
||||
void setRotation(float inValue);
|
||||
|
||||
Color &getColor();
|
||||
|
||||
virtual Attachment *copy();
|
||||
|
||||
private:
|
||||
float _x, _y, _rotation;
|
||||
Color _color;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PointAttachment_h */
|
||||
@ -0,0 +1,74 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Pool_h
|
||||
#define Spine_Pool_h
|
||||
|
||||
#include <spine/Extension.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/ContainerUtil.h>
|
||||
#include <spine/SpineObject.h>
|
||||
|
||||
namespace spine {
|
||||
template<typename T>
|
||||
class SP_API Pool : public SpineObject {
|
||||
public:
|
||||
Pool() {
|
||||
}
|
||||
|
||||
~Pool() {
|
||||
ContainerUtil::cleanUpVectorOfPointers(_objects);
|
||||
}
|
||||
|
||||
T *obtain() {
|
||||
if (_objects.size() > 0) {
|
||||
T **object = &_objects[_objects.size() - 1];
|
||||
T *ret = *object;
|
||||
_objects.removeAt(_objects.size() - 1);
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
T *ret = new(__FILE__, __LINE__) T();
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void free(T *object) {
|
||||
if (!_objects.contains(object)) {
|
||||
_objects.add(object);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Vector<T *> _objects;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Pool_h */
|
||||
@ -0,0 +1,40 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_PositionMode_h
|
||||
#define Spine_PositionMode_h
|
||||
|
||||
namespace spine {
|
||||
enum PositionMode {
|
||||
PositionMode_Fixed = 0,
|
||||
PositionMode_Percent
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_PositionMode_h */
|
||||
@ -0,0 +1,68 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Property_h
|
||||
#define Spine_Property_h
|
||||
|
||||
namespace spine {
|
||||
typedef long long PropertyId;
|
||||
enum Property {
|
||||
Property_Rotate = 1 << 0,
|
||||
Property_X = 1 << 1,
|
||||
Property_Y = 1 << 2,
|
||||
Property_ScaleX = 1 << 3,
|
||||
Property_ScaleY = 1 << 4,
|
||||
Property_ShearX = 1 << 5,
|
||||
Property_ShearY = 1 << 6,
|
||||
Property_Inherit = 1 << 7,
|
||||
Property_Rgb = 1 << 8,
|
||||
Property_Alpha = 1 << 9,
|
||||
Property_Rgb2 = 1 << 10,
|
||||
Property_Attachment = 1 << 11,
|
||||
Property_Deform = 1 << 12,
|
||||
Property_Event = 1 << 13,
|
||||
Property_DrawOrder = 1 << 14,
|
||||
Property_IkConstraint = 1 << 15,
|
||||
Property_TransformConstraint = 1 << 16,
|
||||
Property_PathConstraintPosition = 1 << 17,
|
||||
Property_PathConstraintSpacing = 1 << 18,
|
||||
Property_PathConstraintMix = 1 << 19,
|
||||
Property_PhysicsConstraintInertia = 1 << 20,
|
||||
Property_PhysicsConstraintStrength = 1 << 21,
|
||||
Property_PhysicsConstraintDamping = 1 << 22,
|
||||
Property_PhysicsConstraintMass = 1 << 23,
|
||||
Property_PhysicsConstraintWind = 1 << 24,
|
||||
Property_PhysicsConstraintGravity = 1 << 25,
|
||||
Property_PhysicsConstraintMix = 1 << 26,
|
||||
Property_PhysicsConstraintReset = 1 << 27,
|
||||
Property_Sequence = 1 << 28
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Property_h */
|
||||
@ -0,0 +1,72 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_RTTI_h
|
||||
#define Spine_RTTI_h
|
||||
|
||||
#include <spine/dll.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API RTTI {
|
||||
public:
|
||||
explicit RTTI(const char *className);
|
||||
|
||||
RTTI(const char *className, const RTTI &baseRTTI);
|
||||
|
||||
const char *getClassName() const;
|
||||
|
||||
bool isExactly(const RTTI &rtti) const;
|
||||
|
||||
bool instanceOf(const RTTI &rtti) const;
|
||||
|
||||
private:
|
||||
// Prevent copying
|
||||
RTTI(const RTTI &obj);
|
||||
|
||||
RTTI &operator=(const RTTI &obj);
|
||||
|
||||
const char *_className;
|
||||
const RTTI *_pBaseRTTI;
|
||||
};
|
||||
}
|
||||
|
||||
#define RTTI_DECL \
|
||||
public: \
|
||||
static const spine::RTTI rtti; \
|
||||
virtual const spine::RTTI& getRTTI() const;
|
||||
|
||||
#define RTTI_IMPL_NOPARENT(name) \
|
||||
const spine::RTTI name::rtti(#name); \
|
||||
const spine::RTTI& name::getRTTI() const { return rtti; }
|
||||
|
||||
#define RTTI_IMPL(name, parent) \
|
||||
const spine::RTTI name::rtti(#name, parent::rtti); \
|
||||
const spine::RTTI& name::getRTTI() const { return rtti; }
|
||||
|
||||
#endif /* Spine_RTTI_h */
|
||||
@ -0,0 +1,140 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_RegionAttachment_h
|
||||
#define Spine_RegionAttachment_h
|
||||
|
||||
#include <spine/Attachment.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/Color.h>
|
||||
#include <spine/Sequence.h>
|
||||
#include <spine/TextureRegion.h>
|
||||
|
||||
#include <spine/HasRendererObject.h>
|
||||
|
||||
#define NUM_UVS 8
|
||||
|
||||
namespace spine {
|
||||
class Bone;
|
||||
|
||||
/// Attachment that displays a texture region.
|
||||
class SP_API RegionAttachment : public Attachment {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class AtlasAttachmentLoader;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit RegionAttachment(const String &name);
|
||||
|
||||
virtual ~RegionAttachment();
|
||||
|
||||
void updateRegion();
|
||||
|
||||
/// Transforms the attachment's four vertices to world coordinates.
|
||||
/// @param slot The parent slot.
|
||||
/// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + 8.
|
||||
/// @param offset The worldVertices index to begin writing values.
|
||||
/// @param stride The number of worldVertices entries between the value pairs written.
|
||||
void computeWorldVertices(Slot &slot, float *worldVertices, size_t offset, size_t stride = 2);
|
||||
|
||||
void computeWorldVertices(Slot &slot, Vector<float> &worldVertices, size_t offset, size_t stride = 2);
|
||||
|
||||
float getX();
|
||||
|
||||
void setX(float inValue);
|
||||
|
||||
float getY();
|
||||
|
||||
void setY(float inValue);
|
||||
|
||||
float getRotation();
|
||||
|
||||
void setRotation(float inValue);
|
||||
|
||||
float getScaleX();
|
||||
|
||||
void setScaleX(float inValue);
|
||||
|
||||
float getScaleY();
|
||||
|
||||
void setScaleY(float inValue);
|
||||
|
||||
float getWidth();
|
||||
|
||||
void setWidth(float inValue);
|
||||
|
||||
float getHeight();
|
||||
|
||||
void setHeight(float inValue);
|
||||
|
||||
Color &getColor();
|
||||
|
||||
const String &getPath();
|
||||
|
||||
void setPath(const String &inValue);
|
||||
|
||||
TextureRegion *getRegion();
|
||||
|
||||
void setRegion(TextureRegion *region);
|
||||
|
||||
Sequence *getSequence();
|
||||
|
||||
void setSequence(Sequence *sequence);
|
||||
|
||||
Vector<float> &getOffset();
|
||||
|
||||
Vector<float> &getUVs();
|
||||
|
||||
virtual Attachment *copy();
|
||||
|
||||
private:
|
||||
static const int BLX;
|
||||
static const int BLY;
|
||||
static const int ULX;
|
||||
static const int ULY;
|
||||
static const int URX;
|
||||
static const int URY;
|
||||
static const int BRX;
|
||||
static const int BRY;
|
||||
|
||||
float _x, _y, _rotation, _scaleX, _scaleY, _width, _height;
|
||||
Vector<float> _vertexOffset;
|
||||
Vector<float> _uvs;
|
||||
String _path;
|
||||
Color _color;
|
||||
TextureRegion *_region;
|
||||
Sequence *_sequence;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_RegionAttachment_h */
|
||||
@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_RotateMode_h
|
||||
#define Spine_RotateMode_h
|
||||
|
||||
namespace spine {
|
||||
enum RotateMode {
|
||||
RotateMode_Tangent = 0,
|
||||
RotateMode_Chain,
|
||||
RotateMode_ChainScale
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_RotateMode_h */
|
||||
@ -0,0 +1,61 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_RotateTimeline_h
|
||||
#define Spine_RotateTimeline_h
|
||||
|
||||
#include <spine/CurveTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API RotateTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
friend class AnimationState;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit RotateTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getBoneIndex() { return _boneIndex; }
|
||||
|
||||
void setBoneIndex(int inValue) { _boneIndex = inValue; }
|
||||
|
||||
private:
|
||||
int _boneIndex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_RotateTimeline_h */
|
||||
@ -0,0 +1,109 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_ScaleTimeline_h
|
||||
#define Spine_ScaleTimeline_h
|
||||
|
||||
#include <spine/TranslateTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API ScaleTimeline : public CurveTimeline2 {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit ScaleTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
|
||||
|
||||
virtual ~ScaleTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getBoneIndex() { return _boneIndex; }
|
||||
|
||||
void setBoneIndex(int inValue) { _boneIndex = inValue; }
|
||||
|
||||
private:
|
||||
int _boneIndex;
|
||||
};
|
||||
|
||||
class SP_API ScaleXTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit ScaleXTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
|
||||
|
||||
virtual ~ScaleXTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getBoneIndex() { return _boneIndex; }
|
||||
|
||||
void setBoneIndex(int inValue) { _boneIndex = inValue; }
|
||||
|
||||
private:
|
||||
int _boneIndex;
|
||||
};
|
||||
|
||||
class SP_API ScaleYTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit ScaleYTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
|
||||
|
||||
virtual ~ScaleYTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getBoneIndex() { return _boneIndex; }
|
||||
|
||||
void setBoneIndex(int inValue) { _boneIndex = inValue; }
|
||||
|
||||
private:
|
||||
int _boneIndex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_ScaleTimeline_h */
|
||||
@ -0,0 +1,98 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Sequence_h
|
||||
#define Spine_Sequence_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/SpineString.h>
|
||||
#include <spine/TextureRegion.h>
|
||||
|
||||
namespace spine {
|
||||
class Slot;
|
||||
|
||||
class Attachment;
|
||||
|
||||
class SkeletonBinary;
|
||||
class SkeletonJson;
|
||||
|
||||
class SP_API Sequence : public SpineObject {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
public:
|
||||
Sequence(int count);
|
||||
|
||||
~Sequence();
|
||||
|
||||
Sequence *copy();
|
||||
|
||||
void apply(Slot *slot, Attachment *attachment);
|
||||
|
||||
String getPath(const String &basePath, int index);
|
||||
|
||||
int getId() { return _id; }
|
||||
|
||||
void setId(int id) { _id = id; }
|
||||
|
||||
int getStart() { return _start; }
|
||||
|
||||
void setStart(int start) { _start = start; }
|
||||
|
||||
int getDigits() { return _digits; }
|
||||
|
||||
void setDigits(int digits) { _digits = digits; }
|
||||
|
||||
int getSetupIndex() { return _setupIndex; }
|
||||
|
||||
void setSetupIndex(int setupIndex) { _setupIndex = setupIndex; }
|
||||
|
||||
Vector<TextureRegion *> &getRegions() { return _regions; }
|
||||
|
||||
private:
|
||||
int _id;
|
||||
Vector<TextureRegion *> _regions;
|
||||
int _start;
|
||||
int _digits;
|
||||
int _setupIndex;
|
||||
|
||||
int getNextID();
|
||||
};
|
||||
|
||||
enum SequenceMode {
|
||||
hold = 0,
|
||||
once = 1,
|
||||
loop = 2,
|
||||
pingpong = 3,
|
||||
onceReverse = 4,
|
||||
loopReverse = 5,
|
||||
pingpongReverse = 6
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,73 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_SequenceTimeline_h
|
||||
#define Spine_SequenceTimeline_h
|
||||
|
||||
#include <spine/Timeline.h>
|
||||
#include <spine/Sequence.h>
|
||||
|
||||
namespace spine {
|
||||
class Attachment;
|
||||
|
||||
class SP_API SequenceTimeline : public Timeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit SequenceTimeline(size_t frameCount, int slotIndex, spine::Attachment *attachment);
|
||||
|
||||
virtual ~SequenceTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
void setFrame(int frame, float time, SequenceMode mode, int index, float delay);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
Attachment *getAttachment() { return _attachment; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
Attachment *_attachment;
|
||||
|
||||
static const int ENTRIES = 3;
|
||||
static const int MODE = 1;
|
||||
static const int DELAY = 2;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_SequenceTimeline_h */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user