Эх сурвалжийг харах

Merge branch '3.8' into 4.0-beta

Harald Csaszar 4 жил өмнө
parent
commit
ac23599638

+ 2 - 1
CHANGELOG.md

@@ -240,7 +240,8 @@
 * Removed dependency on `RHI`, `RenderCore`, and `ShaderCore`.
 * Re-importing atlases and their textures now works consistently in all situations.
 * Added mix-and-match example to demonstrate the new Skin API.
-* Materials on `SkeletonRendererComponent` are now blueprint read and writeable. This allows setting dynamic material instances at runtime
+* Materials on `SkeletonRendererComponent` are now blueprint read and writeable. This allows setting dynamic material instances at runtime.
+* Added `InitialSkin` property to `USpineWidget`. This allows previewing different skins in the UMG Designer. Initial skins can still be overridden via blueprint events such as `On Initialized`.
 
 ## C# ##
 * **Breaking changes**

+ 48 - 7
spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp

@@ -281,8 +281,16 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
 	}
 
 	/* Skins. */
-	for (size_t i = 0, n = (size_t)readVarint(input, true); i < n; ++i)
-		skeletonData->_skins.add(readSkin(input, false, skeletonData, nonessential));
+	for (size_t i = 0, n = (size_t)readVarint(input, true); i < n; ++i) {
+		Skin* skin = readSkin(input, false, skeletonData, nonessential);
+		if (skin)
+			skeletonData->_skins.add(skin);
+		else {
+			delete input;
+			delete skeletonData;
+			return NULL;
+		}
+	}
 
 	/* Linked meshes. */
 	for (int i = 0, n = _linkedMeshes.size(); i < n; ++i) {
@@ -470,7 +478,12 @@ Skin *SkeletonBinary::readSkin(DataInput *input, bool defaultSkin, SkeletonData
 		for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) {
 			String name(readStringRef(input, skeletonData));
 			Attachment *attachment = readAttachment(input, skin, slotIndex, name, skeletonData, nonessential);
-			if (attachment) skin->setAttachment(slotIndex, String(name), attachment);
+			if (attachment)
+				skin->setAttachment(slotIndex, String(name), attachment);
+			else {
+				delete skin;
+				return nullptr;
+			}
 		}
 	}
 	return skin;
@@ -488,6 +501,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		String path(readStringRef(input, skeletonData));
 		if (path.isEmpty()) path = name;
 		RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path));
+		if (!region) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		region->_path = path;
 		region->_rotation = readFloat(input);
 		region->_x = readFloat(input) * _scale;
@@ -504,6 +521,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 	case AttachmentType_Boundingbox: {
 		int vertexCount = readVarint(input, true);
 		BoundingBoxAttachment *box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name));
+		if (!box) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		readVertices(input, static_cast<VertexAttachment *>(box), vertexCount);
 		if (nonessential) {
 			/* Skip color. */
@@ -519,6 +540,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		if (path.isEmpty()) path = name;
 
 		mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
+		if (!mesh) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		mesh->_path = path;
 		readColor(input, mesh->getColor());
 		vertexCount = readVarint(input, true);
@@ -543,6 +568,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		if (path.isEmpty()) path = name;
 
 		MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
+		if (!mesh) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		mesh->_path = path;
 		readColor(input, mesh->getColor());
 		String skinName(readStringRef(input, skeletonData));
@@ -559,7 +588,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		return mesh;
 	}
 	case AttachmentType_Path: {
-		PathAttachment *path = _attachmentLoader->newPathAttachment(*skin, String(name));
+		PathAttachment* path = _attachmentLoader->newPathAttachment(*skin, String(name));
+		if (!path) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		path->_closed = readBoolean(input);
 		path->_constantSpeed = readBoolean(input);
 		int vertexCount = readVarint(input, true);
@@ -577,7 +610,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		return path;
 	}
 	case AttachmentType_Point: {
-		PointAttachment *point = _attachmentLoader->newPointAttachment(*skin, String(name));
+		PointAttachment* point = _attachmentLoader->newPointAttachment(*skin, String(name));
+		if (!point) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		point->_rotation = readFloat(input);
 		point->_x = readFloat(input) * _scale;
 		point->_y = readFloat(input) * _scale;
@@ -592,7 +629,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 	case AttachmentType_Clipping: {
 		int endSlotIndex = readVarint(input, true);
 		int vertexCount = readVarint(input, true);
-		ClippingAttachment *clip = _attachmentLoader->newClippingAttachment(*skin, name);
+		ClippingAttachment* clip = _attachmentLoader->newClippingAttachment(*skin, name);
+		if (!clip) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		readVertices(input, static_cast<VertexAttachment *>(clip), vertexCount);
 		clip->_endSlot = skeletonData->_slots[endSlotIndex];
 		if (nonessential) {
@@ -603,7 +644,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		return clip;
 	}
 	}
-	return NULL;
+	return nullptr;
 }
 
 void SkeletonBinary::readVertices(DataInput *input, VertexAttachment *attachment, int vertexCount) {

+ 12 - 1
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp

@@ -99,6 +99,15 @@ void USpineWidget::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 {
@@ -204,6 +213,7 @@ bool USpineWidget::SetSkin(const FString skinName) {
 		spine::Skin* skin = skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName));
 		if (!skin) return false;
 		skeleton->setSkin(skin);
+		bSkinInitialized = true;
 		return true;
 	}
 	else return false;
@@ -211,7 +221,7 @@ bool USpineWidget::SetSkin(const FString skinName) {
 
 bool USpineWidget::SetSkins(UPARAM(ref) TArray<FString>& SkinNames) {
 	CheckState();
-	if (skeleton) {	
+	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));
@@ -222,6 +232,7 @@ bool USpineWidget::SetSkins(UPARAM(ref) TArray<FString>& SkinNames) {
 			newSkin->addSkin(skin);
 		}
 		skeleton->setSkin(newSkin);
+		bSkinInitialized = true;
 		if (customSkin != nullptr) {
 			delete customSkin;
 		}

+ 5 - 1
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h

@@ -51,6 +51,9 @@ public:
 	virtual const FText GetPaletteCategory() override;
 #endif
 
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
+	FString InitialSkin;
+
 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
 	USpineAtlasAsset* Atlas;
 
@@ -216,7 +219,7 @@ protected:
 	virtual void CheckState();
 	virtual void DisposeState();
 
-	TSharedPtr<SSpineWidget> slateWidget;	
+	TSharedPtr<SSpineWidget> slateWidget;
 
 	spine::Skeleton* skeleton;
 	spine::AnimationState* state;
@@ -254,4 +257,5 @@ private:
 	/* If the animation should update automatically. */
 	UPROPERTY()
 	bool bAutoPlaying;
+	bool bSkinInitialized = false;
 };