// dae_bone_animation -> add_bone_animation
// (blend this into dae_bone_animation)
void AnimationExporter::dae_bone_animation(std::vector<float> &fra, float *values, int tm_type, int axis, std::string ob_name, std::string bone_name)
{
	const char *axis_names[] = {"X", "Y", "Z"};
	const char *axis_name = NULL;
	char anim_id[200];
	bool is_rot = tm_type == 0;

	if (!fra.size())
		return;

	char rna_path[200];
	BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].%s", bone_name.c_str(),
	             tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location"));

	if (axis > -1)
		axis_name = axis_names[axis];

	std::string transform_sid = get_transform_sid(NULL, tm_type, axis_name, false);

	BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
	             (char *)translate_id(bone_name).c_str(), (char *)transform_sid.c_str());

	openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);

	// create input source
	std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, is_rot, anim_id, axis_name);

	// create output source
	std::string output_id;
	if (axis == -1)
		output_id = create_xyz_source(values, fra.size(), anim_id);
	else
		output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, values, fra.size(), is_rot, anim_id, axis_name);

	// create interpolations source
	std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, axis_name);

	std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
	COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
	std::string empty;
	sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
	sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));

	// TODO create in/out tangents source

	// this input is required
	sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));

	addSampler(sampler);

	std::string target = translate_id(ob_name + "_" + bone_name) + "/" + transform_sid;
	addChannel(COLLADABU::URI(empty, sampler_id), target);

	closeAnimation();
}
void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_arm, Bone *bone)
{
	std::string ob_name = id_name(ob_arm);
	std::string bone_name = bone->name;
	char anim_id[200];

	if (!fra.size())
		return;

	BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
	             (char *)translate_id(bone_name).c_str(), "pose_matrix");

	openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);

	// create input source
	std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, false, anim_id, "");

	// create output source
	std::string output_id;

	output_id = create_4x4_source(fra, ob_arm, bone, anim_id);

	// create interpolations source
	std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, "");

	std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
	COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
	std::string empty;
	sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
	sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));

	// TODO create in/out tangents source

	// this input is required
	sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));

	addSampler(sampler);

	std::string target = translate_id(bone_name) + "/transform";
	addChannel(COLLADABU::URI(empty, sampler_id), target);

	closeAnimation();
}
quint8 FieldModelFilePC::load(const QString &hrc, const QString &a, bool animate)
{
	if (hrc.isEmpty() || a.isEmpty()) {
		return 2;
	}

	CharArchive *charLgp = CharArchive::instance();
	if (!charLgp->isOpen()) {
		return 2;
	}
	_charLgp = charLgp;

	QString hrcFilename, aFilename;
	int index;

	index = hrc.lastIndexOf('.');
	hrcFilename = index > -1 ? hrc.left(index) : hrc;
	index = a.lastIndexOf('.');
	aFilename = index > -1 ? a.left(index) : a;

	clear();

	QMultiMap<int, QStringList> rsdFiles;

	if (openSkeleton(hrcFilename % ".hrc", rsdFiles)) {
		QStringList textureFiles;

		if (openMesh(rsdFiles, textureFiles)) {

			if (openAnimation(aFilename % ".a", animate)) {
				// Open all loaded tex
				int texID = 0;
				foreach(const QString &texName, textureFiles) {
					QImage tex = openTexture(texName % ".tex");
					if (!tex.isNull()) {
						_loadedTex.insert(texID, tex);
					}
					++texID;
				}

				return true;
			}
//convert f-curves to animation curves and write
void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformName, bool is_param, Material *ma)
{
	const char *axis_name = NULL;
	char anim_id[200];

	bool has_tangents = false;
	bool quatRotation = false;

	if (!strcmp(transformName, "rotation_quaternion") ) {
		fprintf(stderr, "quaternion rotation curves are not supported. rotation curve will not be exported\n");
		quatRotation = true;
		return;
	}

	//axis names for colors
	else if (!strcmp(transformName, "color") || !strcmp(transformName, "specular_color") || !strcmp(transformName, "diffuse_color") ||
	         (!strcmp(transformName, "alpha")))
	{
		const char *axis_names[] = {"R", "G", "B"};
		if (fcu->array_index < 3)
			axis_name = axis_names[fcu->array_index];
	}

	//axis names for transforms
	else if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) ||
	         (!strcmp(transformName, "rotation_euler")) || (!strcmp(transformName, "rotation_quaternion")))
	{
		const char *axis_names[] = {"X", "Y", "Z"};
		if (fcu->array_index < 3)
			axis_name = axis_names[fcu->array_index];
	}
	else {
		/* no axis name. single parameter */
		axis_name = "";
	}

	std::string ob_name = std::string("null");

	//Create anim Id
	if (ob->type == OB_ARMATURE) {
		ob_name =  getObjectBoneName(ob, fcu);
		BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char *)translate_id(ob_name).c_str(),
		             transformName, axis_name);
	}
	else {
		if (ma)
			ob_name = id_name(ob) + "_material";
		else
			ob_name = id_name(ob);
		BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
		             fcu->rna_path, axis_name);
	}

	openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);

	// create input source
	std::string input_id = create_source_from_fcurve(COLLADASW::InputSemantic::INPUT, fcu, anim_id, axis_name);

	// create output source
	std::string output_id;

	//quat rotations are skipped for now, because of complications with determining axis.
	if (quatRotation) {
		float *eul  = get_eul_source_for_quat(ob);
		float *eul_axis = (float *)MEM_callocN(sizeof(float) * fcu->totvert, "quat output source values");
		for (int i = 0; i < fcu->totvert; i++) {
			eul_axis[i] = eul[i * 3 + fcu->array_index];
		}
		output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, eul_axis, fcu->totvert, quatRotation, anim_id, axis_name);
		MEM_freeN(eul);
		MEM_freeN(eul_axis);
	}
	else {
		output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name);
	}
	// create interpolations source
	std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name, &has_tangents);

	// handle tangents (if required)
	std::string intangent_id;
	std::string outtangent_id;

	if (has_tangents) {
		// create in_tangent source
		intangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::IN_TANGENT, fcu, anim_id, axis_name);

		// create out_tangent source
		outtangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUT_TANGENT, fcu, anim_id, axis_name);
	}

	std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
	COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
	std::string empty;
	sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
	sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));

	// this input is required
	sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));

	if (has_tangents) {
		sampler.addInput(COLLADASW::InputSemantic::IN_TANGENT, COLLADABU::URI(empty, intangent_id));
		sampler.addInput(COLLADASW::InputSemantic::OUT_TANGENT, COLLADABU::URI(empty, outtangent_id));
	}

	addSampler(sampler);

	std::string target;

	if (!is_param)
		target = translate_id(ob_name) +
		         "/" + get_transform_sid(fcu->rna_path, -1, axis_name, true);
	else {
		if (ob->type == OB_LAMP)
			target = get_light_id(ob) +
			         "/" + get_light_param_sid(fcu->rna_path, -1, axis_name, true);

		if (ob->type == OB_CAMERA)
			target = get_camera_id(ob) +
			         "/" + get_camera_param_sid(fcu->rna_path, -1, axis_name, true);

		if (ma)
			target = translate_id(id_name(ma)) + "-effect" +
			         "/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true);
	}
	addChannel(COLLADABU::URI(empty, sampler_id), target);

	closeAnimation();
}