Пример #1
0
SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, const int length) {
	bool nonessential;
	SkeletonData *skeletonData;

	DataInput *input = new(__FILE__, __LINE__) DataInput();
	input->cursor = binary;
	input->end = binary + length;

	_linkedMeshes.clear();

	skeletonData = new(__FILE__, __LINE__) SkeletonData();

	char *skeletonData_hash = readString(input);
	skeletonData->_hash.own(skeletonData_hash);

	char *skeletonData_version = readString(input);
	skeletonData->_version.own(skeletonData_version);

	skeletonData->_width = readFloat(input);
	skeletonData->_height = readFloat(input);

	nonessential = readBoolean(input);

	if (nonessential) {
		/* Skip images path, audio path & fps */
		skeletonData->_fps = readFloat(input);
		skeletonData->_imagesPath.own(readString(input));
		skeletonData->_audioPath.own(readString(input));
	}

	/* Bones. */
	int numBones = readVarint(input, true);
	skeletonData->_bones.setSize(numBones, 0);
	for (int i = 0; i < numBones; ++i) {
		const char *name = readString(input);
		BoneData *parent = i == 0 ? 0 : skeletonData->_bones[readVarint(input, true)];
		BoneData *data = new(__FILE__, __LINE__) BoneData(i, String(name, true), parent);
		data->_rotation = readFloat(input);
		data->_x = readFloat(input) * _scale;
		data->_y = readFloat(input) * _scale;
		data->_scaleX = readFloat(input);
		data->_scaleY = readFloat(input);
		data->_shearX = readFloat(input);
		data->_shearY = readFloat(input);
		data->_length = readFloat(input) * _scale;
		data->_transformMode = static_cast<TransformMode>(readVarint(input, true));
		if (nonessential) {
			/* Skip bone color. */
			readInt(input);
		}
		skeletonData->_bones[i] = data;
	}

	/* Slots. */
	int slotsCount = readVarint(input, true);
	skeletonData->_slots.setSize(slotsCount, 0);
	for (int i = 0; i < slotsCount; ++i) {
		const char *slotName = readString(input);
		BoneData *boneData = skeletonData->_bones[readVarint(input, true)];
		SlotData *slotData = new(__FILE__, __LINE__) SlotData(i, String(slotName, true), *boneData);

		readColor(input, slotData->getColor());
		unsigned char r = readByte(input);
		unsigned char g = readByte(input);
		unsigned char b = readByte(input);
		unsigned char a = readByte(input);
		if (!(r == 0xff && g == 0xff && b == 0xff && a == 0xff)) {
			slotData->getDarkColor().set(r / 255.0f, g / 255.0f, b / 255.0f, 1);
			slotData->setHasDarkColor(true);
		}
		slotData->_attachmentName.own(readString(input));
		slotData->_blendMode = static_cast<BlendMode>(readVarint(input, true));
		skeletonData->_slots[i] = slotData;
	}

	/* IK constraints. */
	int ikConstraintsCount = readVarint(input, true);
	skeletonData->_ikConstraints.setSize(ikConstraintsCount, 0);
	for (int i = 0; i < ikConstraintsCount; ++i) {
		const char *name = readString(input);
		IkConstraintData *data = new(__FILE__, __LINE__) IkConstraintData(String(name, true));
		data->_order = readVarint(input, true);
		int bonesCount = readVarint(input, true);
		data->_bones.setSize(bonesCount, 0);
		for (int ii = 0; ii < bonesCount; ++ii) {
			data->_bones[ii] = skeletonData->_bones[readVarint(input, true)];
		}
		data->_target = skeletonData->_bones[readVarint(input, true)];
		data->_mix = readFloat(input);
		data->_bendDirection = readSByte(input);
		data->_compress = readBoolean(input);
		data->_stretch = readBoolean(input);
		data->_uniform = readBoolean(input);
		skeletonData->_ikConstraints[i] = data;
	}

	/* Transform constraints. */
	int transformConstraintsCount = readVarint(input, true);
	skeletonData->_transformConstraints.setSize(transformConstraintsCount, 0);
	for (int i = 0; i < transformConstraintsCount; ++i) {
		const char *name = readString(input);
		TransformConstraintData *data = new(__FILE__, __LINE__) TransformConstraintData(String(name, true));
		data->_order = readVarint(input, true);
		int bonesCount = readVarint(input, true);
		data->_bones.setSize(bonesCount, 0);
		for (int ii = 0; ii < bonesCount; ++ii) {
			data->_bones[ii] = skeletonData->_bones[readVarint(input, true)];
		}
		data->_target = skeletonData->_bones[readVarint(input, true)];
		data->_local = readBoolean(input);
		data->_relative = readBoolean(input);
		data->_offsetRotation = readFloat(input);
		data->_offsetX = readFloat(input) * _scale;
		data->_offsetY = readFloat(input) * _scale;
		data->_offsetScaleX = readFloat(input);
		data->_offsetScaleY = readFloat(input);
		data->_offsetShearY = readFloat(input);
		data->_rotateMix = readFloat(input);
		data->_translateMix = readFloat(input);
		data->_scaleMix = readFloat(input);
		data->_shearMix = readFloat(input);
		skeletonData->_transformConstraints[i] = data;
	}

	/* Path constraints */
	int pathConstraintsCount = readVarint(input, true);
	skeletonData->_pathConstraints.setSize(pathConstraintsCount, 0);
	for (int i = 0; i < pathConstraintsCount; ++i) {
		const char *name = readString(input);
		PathConstraintData *data = new(__FILE__, __LINE__) PathConstraintData(String(name, true));
		data->_order = readVarint(input, true);
		int bonesCount = readVarint(input, true);
		data->_bones.setSize(bonesCount, 0);
		for (int ii = 0; ii < bonesCount; ++ii) {
			data->_bones[ii] = skeletonData->_bones[readVarint(input, true)];
		}
		data->_target = skeletonData->_slots[readVarint(input, true)];
		data->_positionMode = static_cast<PositionMode>(readVarint(input, true));
		data->_spacingMode = static_cast<SpacingMode>(readVarint(input, true));
		data->_rotateMode = static_cast<RotateMode>(readVarint(input, true));
		data->_offsetRotation = readFloat(input);
		data->_position = readFloat(input);
		if (data->_positionMode == PositionMode_Fixed) data->_position *= _scale;
		data->_spacing = readFloat(input);
		if (data->_spacingMode == SpacingMode_Length || data->_spacingMode == SpacingMode_Fixed)
			data->_spacing *= _scale;
		data->_rotateMix = readFloat(input);
		data->_translateMix = readFloat(input);
		skeletonData->_pathConstraints[i] = data;
	}

	/* Default skin. */
	skeletonData->_defaultSkin = readSkin(input, "default", skeletonData, nonessential);
	int skinsCount = readVarint(input, true);
	if (skeletonData->_defaultSkin) {
		++skinsCount;
	}
	skeletonData->_skins.setSize(skinsCount, 0);
	if (skeletonData->_defaultSkin) {
		skeletonData->_skins[0] = skeletonData->_defaultSkin;
	}

	/* Skins. */
	for (size_t i = skeletonData->_defaultSkin ? 1 : 0; i < skeletonData->_skins.size(); ++i) {
		String skinName(readString(input), true);
		skeletonData->_skins[i] = readSkin(input, skinName, skeletonData, nonessential);
	}

	/* Linked meshes. */
	for (int i = 0, n = _linkedMeshes.size(); i < n; ++i) {
		LinkedMesh *linkedMesh = _linkedMeshes[i];
		Skin *skin = linkedMesh->_skin.length() == 0 ? skeletonData->getDefaultSkin() : skeletonData->findSkin(
				linkedMesh->_skin);
		if (skin == NULL) {
			delete input;
			delete skeletonData;
			setError("Skin not found: ", linkedMesh->_skin.buffer());
			return NULL;
		}
		Attachment *parent = skin->getAttachment(linkedMesh->_slotIndex, linkedMesh->_parent);
		if (parent == NULL) {
			delete input;
			delete skeletonData;
			setError("Parent mesh not found: ", linkedMesh->_parent.buffer());
			return NULL;
		}
		linkedMesh->_mesh->setParentMesh(static_cast<MeshAttachment *>(parent));
		linkedMesh->_mesh->updateUVs();
		_attachmentLoader->configureAttachment(linkedMesh->_mesh);
	}
	ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes);
	_linkedMeshes.clear();

	/* Events. */
	int eventsCount = readVarint(input, true);
	skeletonData->_events.setSize(eventsCount, 0);
	for (int i = 0; i < eventsCount; ++i) {
		const char *name = readString(input);
		EventData *eventData = new(__FILE__, __LINE__) EventData(String(name, true));
		eventData->_intValue = readVarint(input, false);
		eventData->_floatValue = readFloat(input);
		eventData->_stringValue.own(readString(input));
		eventData->_audioPath.own(readString(input)); // skip audio path
		if (!eventData->_audioPath.isEmpty()) {
			eventData->_volume = readFloat(input);
			eventData->_balance = readFloat(input);
		}
		skeletonData->_events[i] = eventData;
	}

	/* Animations. */
	int animationsCount = readVarint(input, true);
	skeletonData->_animations.setSize(animationsCount, 0);
	for (int i = 0; i < animationsCount; ++i) {
		String name(readString(input), true);
		Animation *animation = readAnimation(name, input, skeletonData);
		if (!animation) {
			delete input;
			delete skeletonData;
			return NULL;
		}
		skeletonData->_animations[i] = animation;
	}

	delete input;
	return skeletonData;
}