void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeom::Material& material) {
	openEffect(collada_id(material.name()) + "-fx");
	COLLADASW::EffectProfile effect(mSW);
	effect.setShaderType(COLLADASW::EffectProfile::LAMBERT);
	if (material.hasDiffuse()) {
		const double* diffuse = material.diffuse();
		effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse[0],diffuse[1],diffuse[2])));
	}
	if (material.hasSpecular()) {
		const double* specular = material.specular();
		effect.setSpecular(COLLADASW::ColorOrTexture(COLLADASW::Color(specular[0],specular[1],specular[2])));
	}
	if (material.hasSpecularity()) {
		effect.setShininess(material.specularity());
	}
	if (material.hasTransparency()) {
		const double transparency = material.transparency();
		if (transparency > 0) {
			// The default opacity mode for Collada is A_ONE, which apparently indicates a
			// transparency value of 1 to be fully opaque. Hence transparency is inverted.
			effect.setTransparency(1.0 - transparency);
		}
	}
	addEffectProfile(effect);
	closeEffect();
}
Ejemplo n.º 2
0
void EffectsExporter::exportEffects(Scene *sce)
{
	this->scene = sce;

	if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) {
		if (hasEffects(sce)) {
				MaterialFunctor mf;
				openLibrary();
				mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set);
				closeLibrary();
		}
	}
	else {
		std::set<Object *> uv_textured_obs = bc_getUVTexturedObjects(sce, !this->export_settings->active_uv_only);
		std::set<Image *> uv_images = bc_getUVImages(sce, !this->export_settings->active_uv_only);
		if (uv_images.size() > 0) {
			openLibrary();
			std::set<Image *>::iterator uv_images_iter;
			for (uv_images_iter = uv_images.begin();
			     uv_images_iter != uv_images.end();
			     uv_images_iter++)
			{

				Image *ima = *uv_images_iter;
				std::string key(id_name(ima));
				key = translate_id(key);
				COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
					key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
					key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
				sampler.setImageId(key);

				openEffect(key + "-effect");
				COLLADASW::EffectProfile ep(mSW);
				ep.setProfileType(COLLADASW::EffectProfile::COMMON);
				ep.setShaderType(COLLADASW::EffectProfile::PHONG);
				ep.setDiffuse(createTexture(ima, key, &sampler), false, "diffuse");
				COLLADASW::ColorOrTexture cot = getcol(0, 0, 0, 1.0f);
				ep.setSpecular(cot, false, "specular");
				ep.openProfile();
				ep.addProfileElements();
				ep.addExtraTechniques(mSW);
				ep.closeProfile();
				closeEffect();
			}
			closeLibrary();
		}
	}
}
Ejemplo n.º 3
0
void EffectsExporter::operator()(Material *ma, Object *ob)
{
	// create a list of indices to textures of type TEX_IMAGE
	std::vector<int> tex_indices;
	if (this->export_settings->include_material_textures)
		createTextureIndices(ma, tex_indices);

	openEffect(translate_id(id_name(ma)) + "-effect");
	
	COLLADASW::EffectProfile ep(mSW);
	ep.setProfileType(COLLADASW::EffectProfile::COMMON);
	ep.openProfile();
	// set shader type - one of three blinn, phong or lambert
	if (ma->spec > 0.0f) {
		if (ma->spec_shader == MA_SPEC_BLINN) {
			writeBlinn(ep, ma);
		}
		else {
			// \todo figure out handling of all spec+diff shader combos blender has, for now write phong
			// for now set phong in case spec shader is not blinn
			writePhong(ep, ma);
		}
	}
	else {
		if (ma->diff_shader == MA_DIFF_LAMBERT) {
			writeLambert(ep, ma);
		}
		else {
			// \todo figure out handling of all spec+diff shader combos blender has, for now write phong
			writePhong(ep, ma);
		}
	}
	
	// index of refraction
	if (ma->mode & MA_RAYTRANSP) {
		ep.setIndexOfRefraction(ma->ang, false, "index_of_refraction");
	}
	else {
		ep.setIndexOfRefraction(1.0f, false, "index_of_refraction");
	}

	COLLADASW::ColorOrTexture cot;

	// transparency
	if (ma->mode & MA_TRANSP) {
		// Tod: because we are in A_ONE mode transparency is calculated like this:
		ep.setTransparency(ma->alpha, false, "transparency");
		// cot = getcol(1.0f, 1.0f, 1.0f, 1.0f);
		// ep.setTransparent(cot);
	}

	// emission
	cot = getcol(ma->emit, ma->emit, ma->emit, 1.0f);
	ep.setEmission(cot, false, "emission");

	// diffuse multiplied by diffuse intensity
	cot = getcol(ma->r * ma->ref, ma->g * ma->ref, ma->b * ma->ref, 1.0f);
	ep.setDiffuse(cot, false, "diffuse");

	// ambient
	/* ma->ambX is calculated only on render, so lets do it here manually and not rely on ma->ambX. */
	if (this->scene->world)
		cot = getcol(this->scene->world->ambr * ma->amb, this->scene->world->ambg * ma->amb, this->scene->world->ambb * ma->amb, 1.0f);
	else
		cot = getcol(ma->amb, ma->amb, ma->amb, 1.0f);

	ep.setAmbient(cot, false, "ambient");

	// reflective, reflectivity
	if (ma->mode & MA_RAYMIRROR) {
		cot = getcol(ma->mirr, ma->mirg, ma->mirb, 1.0f);
		ep.setReflective(cot);
		ep.setReflectivity(ma->ray_mirror);
	}
	// else {
	//  cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f);
	//  ep.setReflective(cot);
	//  ep.setReflectivity(ma->spec);
	// }

	// specular
	if (ep.getShaderType() != COLLADASW::EffectProfile::LAMBERT) {
		cot = getcol(ma->specr * ma->spec, ma->specg * ma->spec, ma->specb * ma->spec, 1.0f);
		ep.setSpecular(cot, false, "specular");
	}

	// XXX make this more readable if possible

	// create <sampler> and <surface> for each image
	COLLADASW::Sampler samplers[MAX_MTEX];
	//COLLADASW::Surface surfaces[MAX_MTEX];
	//void *samp_surf[MAX_MTEX][2];
	void *samp_surf[MAX_MTEX][1];
	
	// image to index to samp_surf map
	// samp_surf[index] stores 2 pointers, sampler and surface
	std::map<std::string, int> im_samp_map;

	unsigned int a, b;
	for (a = 0, b = 0; a < tex_indices.size(); a++) {
		MTex *t = ma->mtex[tex_indices[a]];
		Image *ima = t->tex->ima;
		
		// Image not set for texture
		if (!ima) continue;
		
		std::string key(id_name(ima));
		key = translate_id(key);

		// create only one <sampler>/<surface> pair for each unique image
		if (im_samp_map.find(key) == im_samp_map.end()) {
			// //<newparam> <surface> <init_from>
			// COLLADASW::Surface surface(COLLADASW::Surface::SURFACE_TYPE_2D,
			//                         key + COLLADASW::Surface::SURFACE_SID_SUFFIX);
			// COLLADASW::SurfaceInitOption sio(COLLADASW::SurfaceInitOption::INIT_FROM);
			// sio.setImageReference(key);
			// surface.setInitOption(sio);

			// COLLADASW::NewParamSurface surface(mSW);
			// surface->setParamType(COLLADASW::CSW_SURFACE_TYPE_2D);
			
			//<newparam> <sampler> <source>
			COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
			                           key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
			                           key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
			sampler.setImageId(key);
			// copy values to arrays since they will live longer
			samplers[a] = sampler;
			//surfaces[a] = surface;
			
			// store pointers so they can be used later when we create <texture>s
			samp_surf[b][0] = &samplers[a];
			//samp_surf[b][1] = &surfaces[a];
			
			im_samp_map[key] = b;
			b++;
		}
	}


	std::set<Image *> uv_textures;
	if (ob->type == OB_MESH && ob->totcol && this->export_settings->include_uv_textures) {
		bool active_uv_only = this->export_settings->active_uv_only;
		Mesh *me     = (Mesh *) ob->data;
		int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);

		BKE_mesh_tessface_ensure(me);
		for (int i = 0; i < me->pdata.totlayer; i++) {
			if (!active_uv_only || active_uv_layer == i)
			{
				if (me->pdata.layers[i].type == CD_MTEXPOLY) {
					MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
					MFace *mface = me->mface;
					for (int j = 0; j < me->totpoly; j++, mface++, txface++) {

						Material *mat = give_current_material(ob, mface->mat_nr + 1);
						if (mat != ma) 
							continue;

						Image *ima = txface->tpage;
						if (ima == NULL)
							continue;


						bool not_in_list = uv_textures.find(ima)==uv_textures.end();
						if (not_in_list) {
							std::string name = id_name(ima);
							std::string key(name);
							key = translate_id(key);

							// create only one <sampler>/<surface> pair for each unique image
							if (im_samp_map.find(key) == im_samp_map.end()) {
								//<newparam> <sampler> <source>
								COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
														   key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
														   key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
								sampler.setImageId(key);
								samplers[a] = sampler;
								samp_surf[b][0] = &samplers[a];
								im_samp_map[key] = b;
								b++;
								a++;
								uv_textures.insert(ima);
							}
						}
					}
				}
			}
		}
	}

	// used as fallback when MTex->uvname is "" (this is pretty common)
	// it is indeed the correct value to use in that case
	std::string active_uv(getActiveUVLayerName(ob));

	// write textures
	// XXX very slow
	for (a = 0; a < tex_indices.size(); a++) {
		MTex *t = ma->mtex[tex_indices[a]];
		Image *ima = t->tex->ima;

		std::string key(id_name(ima));
		key = translate_id(key);
		int i = im_samp_map[key];
		std::string uvname = strlen(t->uvname) ? t->uvname : active_uv;
		COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0];
		writeTextures(ep, key, sampler, t, ima, uvname);
	}

	std::set<Image *>::iterator uv_t_iter;
	for (uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++ ) {
		Image *ima = *uv_t_iter;
		std::string key(id_name(ima));
		key = translate_id(key);
		int i = im_samp_map[key];
		COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0];
		ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse");
	}

	// performs the actual writing
	ep.addProfileElements();
	bool twoSided = false;
	if (ob->type == OB_MESH && ob->data) {
		Mesh *me = (Mesh *)ob->data;
		if (me->flag & ME_TWOSIDED)
			twoSided = true;
	}
	if (twoSided)
		ep.addExtraTechniqueParameter("GOOGLEEARTH", "double_sided", 1);
	ep.addExtraTechniques(mSW);

	ep.closeProfile();
	if (twoSided)
		mSW->appendTextBlock("<extra><technique profile=\"MAX3D\"><double_sided>1</double_sided></technique></extra>");
	closeEffect();
}
Ejemplo n.º 4
0
Document::~Document()
{
	closeEffect();
}