mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[ue4] Multi-page atlases and instanced materials working as intended! Only blend modes and functions for blueprints left!
This commit is contained in:
parent
7f96e2350b
commit
315dfe37ee
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -85,8 +85,7 @@ UTexture2D* resolveTexture (USpineAtlasAsset* asset, const FString& pageFileName
|
|||||||
|
|
||||||
TArray<FString> fileNames;
|
TArray<FString> fileNames;
|
||||||
fileNames.Add(pageFileName);
|
fileNames.Add(pageFileName);
|
||||||
|
|
||||||
//@TODO: Avoid the first compression, since we're going to recompress
|
|
||||||
TArray<UObject*> importedAsset = AssetToolsModule.Get().ImportAssets(fileNames, targetSubPath);
|
TArray<UObject*> importedAsset = AssetToolsModule.Get().ImportAssets(fileNames, targetSubPath);
|
||||||
UTexture2D* texture = (importedAsset.Num() > 0) ? Cast<UTexture2D>(importedAsset[0]) : nullptr;
|
UTexture2D* texture = (importedAsset.Num() > 0) ? Cast<UTexture2D>(importedAsset[0]) : nullptr;
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ void USpineSkeletonComponent::TickComponent( float DeltaTime, ELevelTick TickTyp
|
|||||||
DisposeState();
|
DisposeState();
|
||||||
|
|
||||||
if (atlas && skeletonData) {
|
if (atlas && skeletonData) {
|
||||||
spSkeletonData* data = skeletonData->GetSkeletonData(atlas->GetAtlas(true), true);
|
spSkeletonData* data = skeletonData->GetSkeletonData(atlas->GetAtlas(false), false);
|
||||||
skeleton = spSkeleton_create(data);
|
skeleton = spSkeleton_create(data);
|
||||||
stateData = spAnimationStateData_create(data);
|
stateData = spAnimationStateData_create(data);
|
||||||
state = spAnimationState_create(stateData);
|
state = spAnimationState_create(stateData);
|
||||||
|
|||||||
@ -31,13 +31,52 @@ void USpineSkeletonRendererComponent::TickComponent( float DeltaTime, ELevelTick
|
|||||||
AActor* owner = GetOwner();
|
AActor* owner = GetOwner();
|
||||||
if (owner) {
|
if (owner) {
|
||||||
USpineSkeletonComponent* skeleton = Cast<USpineSkeletonComponent>(owner->GetComponentByClass(skeletonClass));
|
USpineSkeletonComponent* skeleton = Cast<USpineSkeletonComponent>(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);
|
spSkeleton_updateWorldTransform(skeleton->skeleton);
|
||||||
UpdateMesh(skeleton->skeleton);
|
UpdateMesh(skeleton->skeleton);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USpineSkeletonRendererComponent::Flush(int &idx, TArray<FVector> &vertices, TArray<int32> &indices, TArray<FVector2D> &uvs, TArray<FColor> &colors, UMaterialInstanceDynamic* material) {
|
||||||
|
if (vertices.Num() == 0) return;
|
||||||
|
CreateMeshSection(idx, vertices, indices, TArray<FVector>(), uvs, colors, TArray<FProcMeshTangent>(), false);
|
||||||
|
SetMaterial(idx, material);
|
||||||
|
vertices.SetNum(0);
|
||||||
|
indices.SetNum(0);
|
||||||
|
uvs.SetNum(0);
|
||||||
|
colors.SetNum(0);
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
|
void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
|
||||||
TArray<FVector> vertices;
|
TArray<FVector> vertices;
|
||||||
TArray<int32> indices;
|
TArray<int32> indices;
|
||||||
@ -48,6 +87,7 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
|
|||||||
worldVertices.SetNumUninitialized(2 * 1024);
|
worldVertices.SetNumUninitialized(2 * 1024);
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
int meshSection = 0;
|
int meshSection = 0;
|
||||||
|
UMaterialInstanceDynamic* lastMaterial = nullptr;
|
||||||
|
|
||||||
ClearAllMeshSections();
|
ClearAllMeshSections();
|
||||||
|
|
||||||
@ -59,7 +99,15 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
|
|||||||
if (!attachment) continue;
|
if (!attachment) continue;
|
||||||
|
|
||||||
if (attachment->type == SP_ATTACHMENT_REGION) {
|
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());
|
spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, worldVertices.GetData());
|
||||||
|
|
||||||
uint8 r = static_cast<uint8>(skeleton->r * slot->r * 255);
|
uint8 r = static_cast<uint8>(skeleton->r * slot->r * 255);
|
||||||
@ -91,8 +139,18 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
|
|||||||
indices.Add(idx + 3);
|
indices.Add(idx + 3);
|
||||||
idx += 4;
|
idx += 4;
|
||||||
depthOffset -= this->depthOffset;
|
depthOffset -= this->depthOffset;
|
||||||
|
|
||||||
|
SetMaterial(meshSection, material);
|
||||||
} else if (attachment->type == SP_ATTACHMENT_MESH) {
|
} else if (attachment->type == SP_ATTACHMENT_MESH) {
|
||||||
spMeshAttachment* mesh = (spMeshAttachment*)attachment;
|
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()) {
|
if (mesh->super.worldVerticesLength> worldVertices.Num()) {
|
||||||
worldVertices.SetNum(mesh->super.worldVerticesLength);
|
worldVertices.SetNum(mesh->super.worldVerticesLength);
|
||||||
}
|
}
|
||||||
@ -114,16 +172,9 @@ void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {
|
|||||||
}
|
}
|
||||||
idx += mesh->super.worldVerticesLength >> 1;
|
idx += mesh->super.worldVerticesLength >> 1;
|
||||||
depthOffset -= this->depthOffset;
|
depthOffset -= this->depthOffset;
|
||||||
|
SetMaterial(meshSection, material);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateMeshSection(0, vertices, indices, TArray<FVector>(), uvs, colors, TArray<FProcMeshTangent>(), false);
|
Flush(meshSection, vertices, indices, uvs, colors, lastMaterial);
|
||||||
}
|
|
||||||
|
|
||||||
UMaterialInterface* USpineSkeletonRendererComponent::GetMaterial(int32 MaterialIndex) const {
|
|
||||||
return MaterialIndex == 0 ? GetDefaultMaterial() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 USpineSkeletonRendererComponent::GetNumMaterials() const {
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
@ -21,21 +21,15 @@ public:
|
|||||||
virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||||
|
|
||||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||||
UMaterialInterface* DefaultMaterial;
|
UMaterialInterface* DefaultMaterial;
|
||||||
|
|
||||||
UMaterialInterface* GetDefaultMaterial() const { return DefaultMaterial; }
|
|
||||||
|
|
||||||
UMaterialInterface* GetAlternateMaterial() const { return nullptr; }
|
|
||||||
|
|
||||||
UMaterialInterface* GetMaterial(int32 MaterialIndex) const;
|
|
||||||
|
|
||||||
int32 GetNumMaterials() const;
|
|
||||||
|
|
||||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadWrite)
|
||||||
float depthOffset = 0.1f;
|
float depthOffset = 0.1f;
|
||||||
protected:
|
protected:
|
||||||
void UpdateMesh (spSkeleton* skeleton);
|
void UpdateMesh (spSkeleton* skeleton);
|
||||||
|
|
||||||
UPROPERTY()
|
void Flush(int &idx, TArray<FVector> &vertices, TArray<int32> &indices, TArray<FVector2D> &uvs, TArray<FColor> &colors, UMaterialInstanceDynamic* material);
|
||||||
|
|
||||||
TArray<UMaterialInstanceDynamic*> atlasMaterials;
|
TArray<UMaterialInstanceDynamic*> atlasMaterials;
|
||||||
|
TMap<spAtlasPage*, UMaterialInstanceDynamic*> pageToMaterial;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user