diff --git a/spine-ue4/Content/Maps/example.umap b/spine-ue4/Content/Maps/example.umap index a655e3565..d70c9b0b8 100644 Binary files a/spine-ue4/Content/Maps/example.umap and b/spine-ue4/Content/Maps/example.umap differ diff --git a/spine-ue4/Content/SpineBoy/Textures/spineboy.uasset b/spine-ue4/Content/SpineBoy/Textures/spineboy.uasset index f49942272..92a31a59f 100644 Binary files a/spine-ue4/Content/SpineBoy/Textures/spineboy.uasset and b/spine-ue4/Content/SpineBoy/Textures/spineboy.uasset differ diff --git a/spine-ue4/Content/SpineBoy/spineboy.uasset b/spine-ue4/Content/SpineBoy/spineboy.uasset index 43116b775..03940e9e6 100644 Binary files a/spine-ue4/Content/SpineBoy/spineboy.uasset and b/spine-ue4/Content/SpineBoy/spineboy.uasset differ diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineAtlasImportFactory.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineAtlasImportFactory.cpp index fc71635d5..696a1b740 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineAtlasImportFactory.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineAtlasImportFactory.cpp @@ -85,8 +85,7 @@ UTexture2D* resolveTexture (USpineAtlasAsset* asset, const FString& pageFileName TArray fileNames; fileNames.Add(pageFileName); - - //@TODO: Avoid the first compression, since we're going to recompress + TArray importedAsset = AssetToolsModule.Get().ImportAssets(fileNames, targetSubPath); UTexture2D* texture = (importedAsset.Num() > 0) ? Cast(importedAsset[0]) : nullptr; diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp index c45ada286..6309f2c47 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp @@ -24,7 +24,7 @@ void USpineSkeletonComponent::TickComponent( float DeltaTime, ELevelTick TickTyp DisposeState(); if (atlas && skeletonData) { - spSkeletonData* data = skeletonData->GetSkeletonData(atlas->GetAtlas(true), true); + spSkeletonData* data = skeletonData->GetSkeletonData(atlas->GetAtlas(false), false); skeleton = spSkeleton_create(data); stateData = spAnimationStateData_create(data); state = spAnimationState_create(stateData); diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp index b531af94a..2df24dded 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp @@ -31,13 +31,52 @@ void USpineSkeletonRendererComponent::TickComponent( float DeltaTime, ELevelTick AActor* owner = GetOwner(); if (owner) { USpineSkeletonComponent* skeleton = Cast(owner->GetComponentByClass(skeletonClass)); - if (skeleton && skeleton->skeleton) { + if (skeleton && !skeleton->IsBeingDestroyed() && skeleton->skeleton) { + if (atlasMaterials.Num() != skeleton->atlas->atlasPages.Num()) { + atlasMaterials.SetNum(0); + pageToMaterial.Empty(); + spAtlasPage* currPage = skeleton->atlas->GetAtlas(false)->pages; + for (int i = 0; i < skeleton->atlas->atlasPages.Num(); i++) { + UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(DefaultMaterial, owner); + material->SetTextureParameterValue(FName(TEXT("SpriteTexture")), skeleton->atlas->atlasPages[i]); + atlasMaterials.Add(material); + pageToMaterial.Add(currPage, material); + currPage = currPage->next; + } + } + else { + pageToMaterial.Empty(); + spAtlasPage* currPage = skeleton->atlas->GetAtlas(false)->pages; + for (int i = 0; i < skeleton->atlas->atlasPages.Num(); i++) { + UMaterialInstanceDynamic* current = atlasMaterials[i]; + UTexture2D* texture = skeleton->atlas->atlasPages[i]; + UTexture* oldTexture = nullptr; + if(!current->GetTextureParameterValue(FName(TEXT("SpriteTexture")), oldTexture) || oldTexture != texture) { + UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(DefaultMaterial, owner); + material->SetTextureParameterValue("SpriteTexture", texture); + atlasMaterials[i] = material; + } + pageToMaterial.Add(currPage, atlasMaterials[i]); + currPage = currPage->next; + } + } spSkeleton_updateWorldTransform(skeleton->skeleton); UpdateMesh(skeleton->skeleton); } } } +void USpineSkeletonRendererComponent::Flush(int &idx, TArray &vertices, TArray &indices, TArray &uvs, TArray &colors, UMaterialInstanceDynamic* material) { + if (vertices.Num() == 0) return; + CreateMeshSection(idx, vertices, indices, TArray(), uvs, colors, TArray(), false); + SetMaterial(idx, material); + vertices.SetNum(0); + indices.SetNum(0); + uvs.SetNum(0); + colors.SetNum(0); + idx++; +} + void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) { TArray vertices; TArray indices; @@ -48,6 +87,7 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) { worldVertices.SetNumUninitialized(2 * 1024); int idx = 0; int meshSection = 0; + UMaterialInstanceDynamic* lastMaterial = nullptr; ClearAllMeshSections(); @@ -59,7 +99,15 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) { if (!attachment) continue; if (attachment->type == SP_ATTACHMENT_REGION) { - spRegionAttachment* regionAttachment = (spRegionAttachment*)attachment; + spRegionAttachment* regionAttachment = (spRegionAttachment*)attachment; + spAtlasRegion* region = (spAtlasRegion*)regionAttachment->rendererObject; + UMaterialInstanceDynamic* material = pageToMaterial[region->page]; + + if (lastMaterial != material) { + Flush(meshSection, vertices, indices, uvs, colors, lastMaterial); + lastMaterial = material; + } + spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, worldVertices.GetData()); uint8 r = static_cast(skeleton->r * slot->r * 255); @@ -91,8 +139,18 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) { indices.Add(idx + 3); idx += 4; depthOffset -= this->depthOffset; + + SetMaterial(meshSection, material); } else if (attachment->type == SP_ATTACHMENT_MESH) { spMeshAttachment* mesh = (spMeshAttachment*)attachment; + spAtlasRegion* region = (spAtlasRegion*)mesh->rendererObject; + UMaterialInstanceDynamic* material = pageToMaterial[region->page]; + + if (lastMaterial != material) { + Flush(meshSection, vertices, indices, uvs, colors, lastMaterial); + lastMaterial = material; + } + if (mesh->super.worldVerticesLength> worldVertices.Num()) { worldVertices.SetNum(mesh->super.worldVerticesLength); } @@ -114,16 +172,9 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) { } idx += mesh->super.worldVerticesLength >> 1; depthOffset -= this->depthOffset; + SetMaterial(meshSection, material); } } - - CreateMeshSection(0, vertices, indices, TArray(), uvs, colors, TArray(), false); -} - -UMaterialInterface* USpineSkeletonRendererComponent::GetMaterial(int32 MaterialIndex) const { - return MaterialIndex == 0 ? GetDefaultMaterial() : nullptr; -} - -int32 USpineSkeletonRendererComponent::GetNumMaterials() const { - return 1; + + Flush(meshSection, vertices, indices, uvs, colors, lastMaterial); } \ No newline at end of file diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonRendererComponent.h b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonRendererComponent.h index e8baaa1d3..0d2254548 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonRendererComponent.h +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonRendererComponent.h @@ -21,21 +21,15 @@ public: virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly) - UMaterialInterface* DefaultMaterial; - - UMaterialInterface* GetDefaultMaterial() const { return DefaultMaterial; } - - UMaterialInterface* GetAlternateMaterial() const { return nullptr; } - - UMaterialInterface* GetMaterial(int32 MaterialIndex) const; - - int32 GetNumMaterials() const; + UMaterialInterface* DefaultMaterial; UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite) float depthOffset = 0.1f; protected: void UpdateMesh (spSkeleton* skeleton); - UPROPERTY() + void Flush(int &idx, TArray &vertices, TArray &indices, TArray &uvs, TArray &colors, UMaterialInstanceDynamic* material); + TArray atlasMaterials; + TMap pageToMaterial; };