void light::remove_light(light* l)
{
    int lid = get_light_id(l);
    std::vector<light*>::iterator it = lightlist.begin();
    std::advance(it, lid);
    lightlist.erase(it);
    delete l;
}
void SceneExporter::writeNodes(Object *ob, Scene *sce)
{
	// Add associated armature first if available
	bool armature_exported = false;
	Object *ob_arm = bc_get_assigned_armature(ob);
	if (ob_arm != NULL) {
		armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm);
		if (armature_exported && bc_is_marked(ob_arm)) {
			bc_remove_mark(ob_arm);
			writeNodes(ob_arm, sce);
			armature_exported = true;
		}
	}

	COLLADASW::Node colladaNode(mSW);
	colladaNode.setNodeId(translate_id(id_name(ob)));
	colladaNode.setNodeName(translate_id(id_name(ob)));
	colladaNode.setType(COLLADASW::Node::NODE);

	colladaNode.start();

	std::list<Object *> child_objects;

	// list child objects
	LinkNode *node;
	for (node=this->export_settings->export_set; node; node=node->next) {
		// cob - child object
		Object *cob = (Object *)node->link;

		if (cob->parent == ob) {
			switch (cob->type) {
				case OB_MESH:
				case OB_CAMERA:
				case OB_LAMP:
				case OB_EMPTY:
				case OB_ARMATURE:
					if (bc_is_marked(cob))
						child_objects.push_back(cob);
					break;
			}
		}
	}

	if (ob->type == OB_MESH && armature_exported)
		// for skinned mesh we write obmat in <bind_shape_matrix>
		TransformWriter::add_node_transform_identity(colladaNode);
	else
		TransformWriter::add_node_transform_ob(colladaNode, ob);

	// <instance_geometry>
	if (ob->type == OB_MESH) {
		bool instance_controller_created = false;
		if (armature_exported) {
			instance_controller_created = arm_exporter->add_instance_controller(ob);
		}
		if (!instance_controller_created) {
			COLLADASW::InstanceGeometry instGeom(mSW);
			instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation)));

			InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only);

			instGeom.add();
		}
	}

	// <instance_controller>
	else if (ob->type == OB_ARMATURE) {
		arm_exporter->add_armature_bones(ob, sce, this, child_objects);
	}

	// <instance_camera>
	else if (ob->type == OB_CAMERA) {
		COLLADASW::InstanceCamera instCam(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_camera_id(ob)));
		instCam.add();
	}

	// <instance_light>
	else if (ob->type == OB_LAMP) {
		COLLADASW::InstanceLight instLa(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_light_id(ob)));
		instLa.add();
	}

	// empty object
	else if (ob->type == OB_EMPTY) { // TODO: handle groups (OB_DUPLIGROUP
		if ((ob->transflag & OB_DUPLIGROUP) == OB_DUPLIGROUP && ob->dup_group) {
			GroupObject *go = NULL;
			Group *gr = ob->dup_group;
			/* printf("group detected '%s'\n", gr->id.name+2); */
			for (go = (GroupObject *)(gr->gobject.first); go; go = go->next) {
				printf("\t%s\n", go->ob->id.name);
			}
		}
	}

	if (ob->type == OB_ARMATURE) {
		colladaNode.end();
	}

	for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) {
		if (bc_is_marked(*i)) {
			bc_remove_mark(*i);
			writeNodes(*i, sce);
		}
	}

	if (ob->type != OB_ARMATURE) {
		colladaNode.end();
	}
}
//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();
}
void SceneExporter::writeNodes(Object *ob, Scene *sce)
{
	// Add associated armature first if available
	bool armature_exported = false;
	Object *ob_arm = bc_get_assigned_armature(ob);
	if (ob_arm != NULL) {
		armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm);
		if (armature_exported && bc_is_marked(ob_arm)) {
			bc_remove_mark(ob_arm);
			writeNodes(ob_arm, sce);
			armature_exported = true;
		}
	}

	COLLADASW::Node colladaNode(mSW);
	colladaNode.setNodeId(translate_id(id_name(ob)));
	colladaNode.setNodeName(translate_id(id_name(ob)));
	colladaNode.setType(COLLADASW::Node::NODE);

	colladaNode.start();

	std::list<Object *> child_objects;

	// list child objects
	LinkNode *node;
	for (node=this->export_settings->export_set; node; node=node->next) {
		// cob - child object
		Object *cob = (Object *)node->link;

		if (cob->parent == ob) {
			switch (cob->type) {
				case OB_MESH:
				case OB_CAMERA:
				case OB_LAMP:
				case OB_EMPTY:
				case OB_ARMATURE:
					if (bc_is_marked(cob))
						child_objects.push_back(cob);
					break;
			}
		}
	}

	if (ob->type == OB_MESH && armature_exported)
		// for skinned mesh we write obmat in <bind_shape_matrix>
		TransformWriter::add_node_transform_identity(colladaNode);
	else {
		TransformWriter::add_node_transform_ob(colladaNode, ob, this->transformation_type);
	}

	// <instance_geometry>
	if (ob->type == OB_MESH) {
		bool instance_controller_created = false;
		if (armature_exported) {
			instance_controller_created = arm_exporter->add_instance_controller(ob);
		}
		if (!instance_controller_created) {
			COLLADASW::InstanceGeometry instGeom(mSW);
			instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation)));
			instGeom.setName(translate_id(id_name(ob)));
			InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only);

			instGeom.add();
		}
	}

	// <instance_controller>
	else if (ob->type == OB_ARMATURE) {
		arm_exporter->add_armature_bones(ob, sce, this, child_objects);
	}

	// <instance_camera>
	else if (ob->type == OB_CAMERA) {
		COLLADASW::InstanceCamera instCam(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_camera_id(ob)));
		instCam.add();
	}

	// <instance_light>
	else if (ob->type == OB_LAMP) {
		COLLADASW::InstanceLight instLa(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_light_id(ob)));
		instLa.add();
	}

	// empty object
	else if (ob->type == OB_EMPTY) { // TODO: handle groups (OB_DUPLIGROUP
		if ((ob->transflag & OB_DUPLIGROUP) == OB_DUPLIGROUP && ob->dup_group) {
			GroupObject *go = NULL;
			Group *gr = ob->dup_group;
			/* printf("group detected '%s'\n", gr->id.name + 2); */
			for (go = (GroupObject *)(gr->gobject.first); go; go = go->next) {
				printf("\t%s\n", go->ob->id.name);
			}
		}
	}

	if (ob->type == OB_ARMATURE) {
		colladaNode.end();
	}

	if (BLI_listbase_is_empty(&ob->constraints) == false) {
		bConstraint *con = (bConstraint *) ob->constraints.first;
		while (con) {
			std::string con_name(translate_id(con->name));
			std::string con_tag = con_name + "_constraint";
			printf("%s\n", con_name.c_str());
			printf("%s\n\n", con_tag.c_str());
			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"type",con->type);
			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"enforce",con->enforce);
			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"flag",con->flag);
			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"headtail",con->headtail);
			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"lin_error",con->lin_error);
			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"own_space",con->ownspace);
			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"rot_error",con->rot_error);
			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"tar_space",con->tarspace);
			colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"lin_error",con->lin_error);
			
			//not ideal: add the target object name as another parameter. 
			//No real mapping in the .dae
			//Need support for multiple target objects also.
			const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
			ListBase targets = {NULL, NULL};
			if (cti && cti->get_constraint_targets) {
			
				bConstraintTarget *ct;
				Object *obtar;
			
				cti->get_constraint_targets(con, &targets);

				for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) {
					obtar = ct->tar;
					std::string tar_id((obtar) ? id_name(obtar) : "");
					colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"target_id",tar_id);
				}

				if (cti->flush_constraint_targets)
					cti->flush_constraint_targets(con, &targets, 1);

			}

			con = con->next;
		}
	}

	for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) {
		if (bc_is_marked(*i)) {
			bc_remove_mark(*i);
			writeNodes(*i, sce);
		}
	}

	if (ob->type != OB_ARMATURE)
		colladaNode.end();
}
Beispiel #5
0
void LightsExporter::operator()(Object *ob)
{
	Lamp *la = (Lamp*)ob->data;
	std::string la_id(get_light_id(ob));
	std::string la_name(id_name(la));
	COLLADASW::Color col(la->r * la->energy, la->g * la->energy, la->b * la->energy);
	float d, constatt, linatt, quadatt;
	
	d = la->dist;
	
	constatt = 1.0f;
	
	if(la->falloff_type==LA_FALLOFF_INVLINEAR) {
		linatt = 1.0f / d;
		quadatt = 0.0f;
	}
	else {
		linatt = 0.0f;
		quadatt = 1.0f / (d * d);
	}
	
	// sun
	if (la->type == LA_SUN) {
		COLLADASW::DirectionalLight cla(mSW, la_id, la_name);
		cla.setColor(col,false,"color");
		cla.setConstantAttenuation(constatt);
		exportBlenderProfile(cla, la);
		addLight(cla);
	}
	// hemi
	else if (la->type == LA_HEMI) {
		COLLADASW::AmbientLight cla(mSW, la_id, la_name);
		cla.setColor(col,false,"color");
		cla.setConstantAttenuation(constatt);
		exportBlenderProfile(cla, la);
		addLight(cla);
	}
	// spot
	else if (la->type == LA_SPOT) {
		COLLADASW::SpotLight cla(mSW, la_id, la_name);
		cla.setColor(col,false,"color");
		cla.setFallOffAngle(la->spotsize,false,"fall_off_angle");
		cla.setFallOffExponent(la->spotblend,false,"fall_off_exponent");
		cla.setConstantAttenuation(constatt);
		cla.setLinearAttenuation(linatt);
		cla.setQuadraticAttenuation(quadatt);
		exportBlenderProfile(cla, la);
		addLight(cla);
	}
	// lamp
	else if (la->type == LA_LOCAL) {
		COLLADASW::PointLight cla(mSW, la_id, la_name);
		cla.setColor(col,false,"color");
		cla.setConstantAttenuation(constatt);
		cla.setLinearAttenuation(linatt);
		cla.setQuadraticAttenuation(quadatt);
		exportBlenderProfile(cla, la);
		addLight(cla);
	}
	// area lamp is not supported
	// it will be exported as a local lamp
	else {
		COLLADASW::PointLight cla(mSW, la_id, la_name);
		cla.setColor(col,false,"color");
		cla.setConstantAttenuation(constatt);
		cla.setLinearAttenuation(linatt);
		cla.setQuadraticAttenuation(quadatt);
		exportBlenderProfile(cla, la);
		addLight(cla);
	}
	
}