From 315dfe37eed4059fbb5947356e10c218e77c7be6 Mon Sep 17 00:00:00 2001 From: badlogic Date: Wed, 30 Nov 2016 18:29:25 +0100 Subject: [PATCH] [ue4] Multi-page atlases and instanced materials working as intended! Only blend modes and functions for blueprints left! --- spine-ue4/Content/Maps/example.umap | Bin 658379 -> 659485 bytes .../Content/SpineBoy/Textures/spineboy.uasset | Bin 771947 -> 771947 bytes spine-ue4/Content/SpineBoy/spineboy.uasset | Bin 21036 -> 21036 bytes .../Private/SpineAtlasImportFactory.cpp | 3 +- .../Private/SpineSkeletonComponent.cpp | 2 +- .../SpineSkeletonRendererComponent.cpp | 75 +++++++++++++++--- .../Public/SpineSkeletonRendererComponent.h | 14 +--- 7 files changed, 69 insertions(+), 25 deletions(-) diff --git a/spine-ue4/Content/Maps/example.umap b/spine-ue4/Content/Maps/example.umap index a655e35658ee68814a2e985752374c80a15f744a..d70c9b0b8cbe4d2e253e9bdd786a95247cbcd273 100644 GIT binary patch delta 33937 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 delta 31745 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 delta 157 zcmaFer~kT7e?p|di*3hE6fZctugI#}=sua_L}TXGOhyk$4s%OOBXdi0^X)q&850@d z-048B>GW`E#yr8eT+3xCzfOD1T)5Wera;m`k?8_5j1tq|Ni$v-Sgl>5tS)To(wqPK qqeFk&@Aj)Qj6lo;#LPg<0>rF9%m&2lK+FNeoIuRA{i+Q2v{e9zy*w=d diff --git a/spine-ue4/Content/SpineBoy/spineboy.uasset b/spine-ue4/Content/SpineBoy/spineboy.uasset index 43116b7758965013d5df89a5ada962cb81fc9ce3..03940e9e6a5b373e299e10a2893e721ab32c4634 100644 GIT binary patch delta 29 ncmV+&0OJ3wqyem?0gzb` 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; };