Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfredo de Greef <eeshlo@yahoo.com>2004-10-26 04:52:12 +0400
committerAlfredo de Greef <eeshlo@yahoo.com>2004-10-26 04:52:12 +0400
commitc245379175a23f26a92b3e2adbda39b9fb46c396 (patch)
tree2c8aad713df994a5c910198e0f9a2f0120ccf0ba /source/blender/yafray
parent85c889108d0b656e3d6f6193b4d11c41f6798e49 (diff)
Bugfixes:
Blender hemilight shadow flag now ignored (reported by varuag). Texture axes were not exported for procedural textures. Duplicate armatures were not handled correctly (reported by richie). Triangle uv-coord splitting (reported by anael, richie & Alvaro). Additions: Material 'TexFace' mode now works too, as in Blender it functions as an extra first texture channel, replacing the base color. The new noise functions for procedural textures are now supported in yafray, but is not quite completed yet, still undergoing changes. (needs yafray from cvs). The 'power' button has been renamed to 'EmitPwr', since it controls background, arealight (including lamp with radius) & material emit power. This button can now be used with the 'SkyDome' method as well to control background lighting. To control indirect lighting power, a button called 'GI pwr' has been added, only use this when really necessary, first try modifying 'EmitPwr' instead. Removed: The 'gradient' button. This includes the python code to set this parameter as well.
Diffstat (limited to 'source/blender/yafray')
-rwxr-xr-xsource/blender/yafray/intern/export_File.cpp743
-rwxr-xr-xsource/blender/yafray/intern/export_File.h6
-rw-r--r--source/blender/yafray/intern/export_Plugin.cpp839
-rw-r--r--source/blender/yafray/intern/export_Plugin.h12
-rw-r--r--source/blender/yafray/intern/yafray_Render.cpp43
-rw-r--r--source/blender/yafray/intern/yafray_Render.h6
6 files changed, 1024 insertions, 625 deletions
diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp
index 5584ac47bd3..eca34a65504 100755
--- a/source/blender/yafray/intern/export_File.cpp
+++ b/source/blender/yafray/intern/export_File.cpp
@@ -313,13 +313,47 @@ static void adjustPath(string &path)
}
+static string noise2string(short nbtype)
+{
+ switch (nbtype) {
+ case TEX_BLENDER:
+ return "blender";
+ case TEX_STDPERLIN:
+ return "stdperlin";
+ case TEX_VORONOI_F1:
+ return "voronoi_f1";
+ case TEX_VORONOI_F2:
+ return "voronoi_f2";
+ case TEX_VORONOI_F3:
+ return "voronoi_f3";
+ case TEX_VORONOI_F4:
+ return "voronoi_f4";
+ case TEX_VORONOI_F2F1:
+ return "voronoi_f2f1";
+ case TEX_VORONOI_CRACKLE:
+ return "voronoi_crackle";
+ case TEX_CELLNOISE:
+ return "cellnoise";
+ default:
+ case TEX_NEWPERLIN:
+ return "newperlin";
+ }
+}
+
void yafrayFileRender_t::writeTextures()
{
- for (map<string, pair<Material*, MTex*> >::const_iterator blendtex=used_textures.begin();
+ string ts;
+ for (map<string, MTex*>::const_iterator blendtex=used_textures.begin();
blendtex!=used_textures.end();++blendtex) {
- //Material* matr = blendtex->second.first;
- MTex* mtex = blendtex->second.second;
+ MTex* mtex = blendtex->second;
Tex* tex = mtex->tex;
+
+ float nsz = tex->noisesize;
+ if (nsz!=0.f) nsz=1.f/nsz;
+
+ // noisebasis type
+ string ntype = noise2string(tex->noisebasis);
+
switch (tex->type) {
case TEX_STUCCI:
// stucci is clouds as bump, but could be added to yafray to handle both wall in/out as well.
@@ -329,8 +363,9 @@ void yafrayFileRender_t::writeTextures()
ostr << "<shader type=\"clouds\" name=\"" << blendtex->first << "\" >\n";
ostr << "\t<attributes>\n";
ostr << "\t\t<depth value=\"" << tex->noisedepth+1 << "\" />\n";
- ostr << "\t</attributes>\n";
- ostr << "</shader >\n\n";
+ ostr << "\t\t<size value=\"" << nsz << "\" />\n";
+ ostr << "\t\t<noise_type value=\"" << ntype << "\" />\n";
+ ostr << "\t</attributes>\n</shader >\n\n";
xmlfile << ostr.str();
break;
}
@@ -342,11 +377,10 @@ void yafrayFileRender_t::writeTextures()
ostr << "\t\t<turbulence value=\"" << tex->turbul << "\" />\n";
ostr << "\t\t<ringscale_x value=\"" << mtex->size[0] << "\" />\n";
ostr << "\t\t<ringscale_y value=\"" << mtex->size[1] << "\" />\n";
- string ts = "on";
+ ts = "on";
if (tex->noisetype==TEX_NOISESOFT) ts = "off";
ostr << "\t\t<hard value=\"" << ts << "\" />\n";
- ostr << "\t</attributes>\n";
- ostr << "</shader>\n\n";
+ ostr << "\t</attributes>\n</shader>\n\n";
xmlfile << ostr.str();
break;
}
@@ -356,28 +390,115 @@ void yafrayFileRender_t::writeTextures()
ostr << "\t<attributes>\n";
ostr << "\t\t<depth value=\"" << tex->noisedepth+1 << "\" />\n";
ostr << "\t\t<turbulence value=\"" << tex->turbul << "\" />\n";
- string ts = "on";
+ ts = "on";
if (tex->noisetype==TEX_NOISESOFT) ts = "off";
ostr << "\t\t<hard value=\"" << ts << "\" />\n";
ts = "1";
if (tex->stype==1) ts="5"; else if (tex->stype==2) ts="10";
ostr << "\t\t<sharpness value=\"" << ts << "\" />\n";
- ostr << "\t</attributes>\n";
- ostr << "</shader>\n\n";
+ ostr << "\t</attributes>\n</shader>\n\n";
+ xmlfile << ostr.str();
+ break;
+ }
+ case TEX_VORONOI: {
+ ostr.str("");
+ ostr << "<shader type=\"voronoi\" name=\"" << blendtex->first << "\" >\n";
+ ostr << "\t<attributes>\n";
+ ts = "int";
+ if (tex->vn_coltype==1)
+ ts = "col1";
+ else if (tex->vn_coltype==2)
+ ts = "col2";
+ else if (tex->vn_coltype==3)
+ ts = "col3";
+ ostr << "\t\t<color_type value=\"" << ts << "\" />\n";
+ ostr << "\t\t<weight1 value=\"" << tex->vn_w1 << "\" />\n";
+ ostr << "\t\t<weight2 value=\"" << tex->vn_w2 << "\" />\n";
+ ostr << "\t\t<weight3 value=\"" << tex->vn_w3 << "\" />\n";
+ ostr << "\t\t<weight4 value=\"" << tex->vn_w4 << "\" />\n";
+ ostr << "\t\t<mk_exponent value=\"" << tex->vn_mexp << "\" />\n";
+ ostr << "\t\t<intensity value=\"" << tex->ns_outscale << "\" />\n";
+ ostr << "\t\t<size value=\"" << nsz << "\" />\n";
+ ts = "actual";
+ if (tex->vn_distm==TEX_DISTANCE_SQUARED)
+ ts = "squared";
+ else if (tex->vn_distm==TEX_MANHATTAN)
+ ts = "manhattan";
+ else if (tex->vn_distm==TEX_CHEBYCHEV)
+ ts = "chebychev";
+ else if (tex->vn_distm==TEX_MINKOVSKY_HALF)
+ ts = "minkovsky_half";
+ else if (tex->vn_distm==TEX_MINKOVSKY_FOUR)
+ ts = "minkovsky_four";
+ else if (tex->vn_distm==TEX_MINKOVSKY)
+ ts = "minkovsky";
+ ostr << "\t\t<distance_metric value=\"" << ts << "\" />\n";
+ ostr << "\t</attributes>\n</shader>\n\n";
+ xmlfile << ostr.str();
+ break;
+ }
+ case TEX_MUSGRAVE: {
+ ostr.str("");
+ ostr << "<shader type=\"musgrave\" name=\"" << blendtex->first << "\" >\n";
+ ostr << "\t<attributes>\n";
+ switch (tex->stype) {
+ case TEX_MFRACTAL:
+ ts = "multifractal";
+ break;
+ case TEX_RIDGEDMF:
+ ts = "ridgedmf";
+ break;
+ case TEX_HYBRIDMF:
+ ts = "hybridmf";
+ break;
+ case TEX_HTERRAIN:
+ ts = "heteroterrain";
+ break;
+ default:
+ case TEX_FBM:
+ ts = "fBm";
+ }
+ ostr << "\t\t<musgrave_type value=\"" << ts << "\" />\n";
+ ostr << "\t\t<noise_type value=\"" << ntype << "\" />\n";
+ ostr << "\t\t<H value=\"" << tex->mg_H << "\" />\n";
+ ostr << "\t\t<lacunarity value=\"" << tex->mg_lacunarity << "\" />\n";
+ ostr << "\t\t<octaves value=\"" << tex->mg_octaves << "\" />\n";
+ if ((tex->stype==TEX_HTERRAIN) || (tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF)) {
+ ostr << "\t\t<offset value=\"" << tex->mg_offset << "\" />\n";
+ if ((tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF))
+ ostr << "\t\t<gain value=\"" << tex->mg_gain << "\" />\n";
+ }
+ ostr << "\t\t<size value=\"" << nsz << "\" />\n";
+ ostr << "\t\t<intensity value=\"" << tex->ns_outscale << "\" />\n";
+ ostr << "\t</attributes>\n</shader>\n\n";
+ xmlfile << ostr.str();
+ break;
+ }
+ case TEX_DISTNOISE: {
+ ostr.str("");
+ ostr << "<shader type=\"distorted_noise\" name=\"" << blendtex->first << "\" >\n";
+ ostr << "\t<attributes>\n";
+ ostr << "\t\t<distort value=\"" << tex->dist_amount << "\" />\n";
+ ostr << "\t\t<size value=\"" << nsz << "\" />\n";
+ ostr << "\t\t<noise_type1 value=\"" << ntype << "\" />\n";
+ ostr << "\t\t<noise_type2 value=\"" << noise2string(tex->noisebasis2) << "\" />\n";
+ ostr << "\t</attributes>\n</shader>\n\n";
xmlfile << ostr.str();
break;
}
case TEX_IMAGE: {
Image* ima = tex->ima;
if (ima) {
+ // remove from imagetex list to avoid possible duplicates when TexFace used
+ imagetex.erase(ima);
ostr.str("");
- ostr << "<shader type=\"image\" name=\"" << blendtex->first << "\" >\n";
+ // use image name instead of texname here
+ ostr << "<shader type=\"image\" name=\"" << ima->id.name << "\" >\n";
ostr << "\t<attributes>\n";
- string texpath = ima->name;
+ string texpath(ima->name);
adjustPath(texpath);
ostr << "\t\t<filename value=\"" << texpath << "\" />\n";
- ostr << "\t</attributes>\n";
- ostr << "</shader>\n\n";
+ ostr << "\t</attributes>\n</shader>\n\n";
xmlfile << ostr.str();
}
break;
@@ -409,19 +530,235 @@ void yafrayFileRender_t::writeTextures()
}
}
+
+ // If used, textures for the material 'TexFace' case
+ if (!imagetex.empty()) {
+ for (map<Image*, Material*>::const_iterator imgtex=imagetex.begin();
+ imgtex!=imagetex.end();++imgtex)
+ {
+ ostr.str("");
+ ostr << "<shader type=\"image\" name=\"" << imgtex->first->id.name << "\" >\n";
+ ostr << "\t<attributes>\n";
+ string texpath(imgtex->first->name);
+ adjustPath(texpath);
+ ostr << "\t\t<filename value=\"" << texpath << "\" />\n";
+ ostr << "\t</attributes>\n</shader>\n\n";
+ xmlfile << ostr.str();
+ }
+ }
+
+}
+
+void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr, const string &facetexname)
+{
+ ostr.str("");
+ ostr << "<shader type=\"blendershader\" name=\"" << shader_name << "\" >\n";
+ ostr << "\t<attributes>\n";
+ float diff = matr->alpha;
+ ostr << "\t\t<color r=\"" << matr->r*diff << "\" g=\"" << matr->g*diff << "\" b=\"" << matr->b*diff << "\" />\n";
+ ostr << "\t\t<specular_color r=\"" << matr->specr << "\" g=\"" << matr->specg << "\" b=\"" << matr->specb << "\" />\n";
+ ostr << "\t\t<mirror_color r=\"" << matr->mirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n";
+ ostr << "\t\t<diffuse_reflect value=\"" << matr->ref << "\" />\n";
+ ostr << "\t\t<specular_amount value=\"" << matr->spec << "\" />\n";
+ ostr << "\t\t<hard value=\"" << matr->har << "\" />\n";
+ ostr << "\t\t<alpha value=\"" << matr->alpha << "\" />\n";
+ // if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
+ float bg_mult = (R.r.GImethod==0) ? 1 : R.r.GIpower;
+ ostr << "\t\t<emit value=\"" << (matr->emit * bg_mult) << "\" />\n";
+
+ // reflection/refraction
+ if ( (matr->mode & MA_RAYMIRROR) || (matr->mode & MA_RAYTRANSP) )
+ ostr << "\t\t<IOR value=\"" << matr->ang << "\" />\n";
+ if (matr->mode & MA_RAYMIRROR) {
+ float rf = matr->ray_mirror;
+ // blender uses mir color for reflection as well
+ ostr << "\t\t<reflected r=\"" << matr->mirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n";
+ ostr << "\t\t<min_refle value=\""<< rf << "\" />\n";
+ if (matr->ray_depth>maxraydepth) maxraydepth = matr->ray_depth;
+ }
+ if (matr->mode & MA_RAYTRANSP)
+ {
+ float tr=1.0-matr->alpha;
+ ostr << "\t\t<transmitted r=\"" << matr->r * tr << "\" g=\"" << matr->g * tr << "\" b=\"" << matr->b * tr << "\" />\n";
+ // tir on by default
+ ostr << "\t\t<tir value=\"on\" />\n";
+ if (matr->ray_depth_tra>maxraydepth) maxraydepth = matr->ray_depth_tra;
+ }
+
+ string Mmode = "";
+ if (matr->mode & MA_TRACEBLE) Mmode += "traceable";
+ if (matr->mode & MA_SHADOW) Mmode += " shadow";
+ if (matr->mode & MA_SHLESS) Mmode += " shadeless";
+ if (matr->mode & MA_VERTEXCOL) Mmode += " vcol_light";
+ if (matr->mode & MA_VERTEXCOLP) Mmode += " vcol_paint";
+ if (matr->mode & MA_ZTRA) Mmode += " ztransp";
+ if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
+ if (Mmode!="") ostr << "\t\t<matmodes value=\"" << Mmode << "\" />\n";
+ ostr << "\t</attributes>\n";
+ xmlfile << ostr.str();
+
+ // modulators
+ // first modulator is the texture of the face, if used (TexFace mode)
+ if (facetexname.length()!=0) {
+ ostr.str("");
+ ostr << "\t<modulator>\n";
+ ostr << "\t\t<input value=\"" << facetexname << "\" />\n";
+ ostr << "\t\t<color value=\"1\" />\n";
+ ostr << "\t</modulator>\n";
+ xmlfile << ostr.str();
+ }
+
+ for (int m2=0;m2<8;m2++) {
+
+ if (matr->septex & (1<<m2)) continue;// all active channels
+
+ // ignore null mtex
+ MTex* mtex = matr->mtex[m2];
+ if (mtex==NULL) continue;
+
+ // ignore null tex
+ Tex* tex = mtex->tex;
+ if (tex==NULL) continue;
+
+ map<string, MTex*>::const_iterator mtexL = used_textures.find(string(tex->id.name));
+ if (mtexL!=used_textures.end()) {
+
+ ostr.str("");
+ ostr << "\t<modulator>\n";
+ // when no facetex used, shader_name is created from original material name
+ if (facetexname.length()!=0)
+ ostr << "\t\t<input value=\"" << matr->id.name << "_map" << m2 << "\" />\n";
+ else
+ ostr << "\t\t<input value=\"" << shader_name << "_map" << m2 << "\" />\n";
+
+ // blendtype
+ string ts = "mix";
+ if (mtex->blendtype==MTEX_MUL) ts="mul";
+ else if (mtex->blendtype==MTEX_ADD) ts="add";
+ else if (mtex->blendtype==MTEX_SUB) ts="sub";
+ ostr << "\t\t<mode value=\"" << ts << "\" />\n";
+
+ // texture color (for use with MUL and/or no_rgb etc..)
+ ostr << "\t\t<texcol r=\"" << mtex->r << "\" g=\"" << mtex->g << "\" b=\"" << mtex->b << "\" />\n";
+
+ // texture contrast, brightness & color adjustment
+ ostr << "\t\t<filtercolor r=\"" << tex->rfac << "\" g=\"" << tex->gfac << "\" b=\"" << tex->bfac << "\" />\n";
+ ostr << "\t\t<contrast value=\"" << tex->contrast << "\" />\n";
+ ostr << "\t\t<brightness value=\"" << tex->bright << "\" />\n";
+
+ // all texture flags now are switches, having the value 1 or -1 (negative option)
+ // the negative option only used for the intensity modulation options.
+
+ // material (diffuse) color, amount controlled by colfac (see below)
+ if (mtex->mapto & MAP_COL)
+ ostr << "\t\t<color value=\"1\" />\n";
+
+ // bumpmapping
+ if ((mtex->mapto & MAP_NORM) || (mtex->maptoneg & MAP_NORM)) {
+ // for yafray, bump factor is negated (unless negative option of 'Nor', is not affected by 'Neg')
+ // scaled down quite a bit for yafray
+ float nf = -mtex->norfac;
+ if (mtex->maptoneg & MAP_NORM) nf *= -1.f;
+ ostr << "\t\t<normal value=\"" << (nf/60.f) << "\" />\n";
+
+ }
+
+ // all blender texture modulation as switches, either 1 or -1 (negative state of button)
+ // Csp, specular color modulation
+ if (mtex->mapto & MAP_COLSPEC)
+ ostr << "\t\t<colspec value=\"1\" />\n";
+
+ // CMir, mirror color modulation
+ if (mtex->mapto & MAP_COLMIR)
+ ostr << "\t\t<colmir value=\"1\" />\n";
+
+ // Ref, diffuse reflection amount modulation
+ if ((mtex->mapto & MAP_REF) || (mtex->maptoneg & MAP_REF)) {
+ int t = 1;
+ if (mtex->maptoneg & MAP_REF) t = -1;
+ ostr << "\t\t<difref value=\"" << t << "\" />\n";
+ }
+
+ // Spec, specular amount mod
+ if ((mtex->mapto & MAP_SPEC) || (mtex->maptoneg & MAP_SPEC)) {
+ int t = 1;
+ if (mtex->maptoneg & MAP_SPEC) t = -1;
+ ostr << "\t\t<specular value=\"" << t << "\" />\n";
+ }
+
+ // hardness modulation
+ if ((mtex->mapto & MAP_HAR) || (mtex->maptoneg & MAP_HAR)) {
+ int t = 1;
+ if (mtex->maptoneg & MAP_HAR) t = -1;
+ ostr << "\t\t<hard value=\"" << t << "\" />\n";
+ }
+
+ // alpha modulation
+ if ((mtex->mapto & MAP_ALPHA) || (mtex->maptoneg & MAP_ALPHA)) {
+ int t = 1;
+ if (mtex->maptoneg & MAP_ALPHA) t = -1;
+ ostr << "\t\t<alpha value=\"" << t << "\" />\n";
+
+ }
+
+ // emit modulation
+ if ((mtex->mapto & MAP_EMIT) || (mtex->maptoneg & MAP_EMIT)) {
+ int t = 1;
+ if (mtex->maptoneg & MAP_EMIT) t = -1;
+ ostr << "\t\t<emit value=\"" << t << "\" />\n";
+ }
+
+ // texture flag, combination of strings
+ if (mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE)) {
+ ts = "";
+ if (mtex->texflag & MTEX_RGBTOINT) ts += "no_rgb ";
+ if (mtex->texflag & MTEX_STENCIL) ts += "stencil ";
+ if (mtex->texflag & MTEX_NEGATIVE) ts += "negative";
+ ostr << "\t\t<texflag value=\"" << ts << "\" />\n";
+ }
+
+ // colfac, controls amount of color modulation
+ ostr << "\t\t<colfac value=\"" << mtex->colfac << "\" />\n";
+
+ // def_var
+ ostr << "\t\t<def_var value=\"" << mtex->def_var << "\" />\n";
+
+ //varfac
+ ostr << "\t\t<varfac value=\"" << mtex->varfac << "\" />\n";
+
+ if ((tex->imaflag & (TEX_CALCALPHA | TEX_USEALPHA)) || (tex->flag & TEX_NEGALPHA)) {
+ ts = "";
+ if (tex->imaflag & TEX_CALCALPHA) ts += "calc_alpha ";
+ if (tex->imaflag & TEX_USEALPHA) ts += "use_alpha ";
+ if (tex->flag & TEX_NEGALPHA) ts += "neg_alpha";
+ ostr << "\t\t<alpha_flag value=\"" << ts << "\" />\n";
+ }
+
+ ostr << "\t</modulator>\n";
+ xmlfile << ostr.str();
+
+ }
+ }
+ xmlfile << "</shader>\n\n";
+
}
// write all materials & modulators
void yafrayFileRender_t::writeMaterialsAndModulators()
{
+ // shaders/mappers for regular texture (or non-texture) mode
+ // In case material has texface mode, and all faces have an image texture,
+ // this shader will not be used, but still be written
for (map<string, Material*>::const_iterator blendmat=used_materials.begin();
- blendmat!=used_materials.end();++blendmat) {
+ blendmat!=used_materials.end();++blendmat)
+ {
Material* matr = blendmat->second;
- // blendermappers
- for (int m=0;m<8;m++) {
+ // mapper(s)
+ for (int m=0;m<8;m++)
+ {
if (matr->septex & (1<<m)) continue;// all active channels
@@ -432,8 +769,7 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
Tex* tex = mtex->tex;
if (tex==NULL) continue;
- // now included the full name
- map<string, pair<Material*, MTex*> >::const_iterator mtexL = used_textures.find(string(tex->id.name));
+ map<string, MTex*>::const_iterator mtexL = used_textures.find(string(tex->id.name));
if (mtexL!=used_textures.end()) {
ostr.str("");
ostr << "<shader type=\"blendermapper\" name=\"" << blendmat->first + "_map" << m <<"\"";
@@ -448,34 +784,30 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
else // also for refl. map
MTC_Mat4CpyMat4(texmat, maincam_obj->obmat);
MTC_Mat4Invert(itexmat, texmat);
- ostr << "\n m00=\"" << itexmat[0][0] << "\" m01=\"" << itexmat[1][0]
- << "\" m02=\"" << itexmat[2][0] << "\" m03=\"" << itexmat[3][0] << "\"\n\t";
- ostr << " m10=\"" << itexmat[0][1] << "\" m11=\"" << itexmat[1][1]
- << "\" m12=\"" << itexmat[2][1] << "\" m13=\"" << itexmat[3][1] << "\"\n\t";
- ostr << " m20=\"" << itexmat[0][2] << "\" m21=\"" << itexmat[1][2]
- << "\" m22=\"" << itexmat[2][2] << "\" m23=\"" << itexmat[3][2] << "\"\n\t";
- ostr << " m30=\"" << itexmat[0][3] << "\" m31=\"" << itexmat[1][3]
- << "\" m32=\"" << itexmat[2][3] << "\" m33=\"" << itexmat[3][3] << "\">\n";
+ ostr << "\n\t\tm00=\"" << itexmat[0][0] << "\" m01=\"" << itexmat[1][0]
+ << "\" m02=\"" << itexmat[2][0] << "\" m03=\"" << itexmat[3][0] << "\"\n";
+ ostr << "\t\tm10=\"" << itexmat[0][1] << "\" m11=\"" << itexmat[1][1]
+ << "\" m12=\"" << itexmat[2][1] << "\" m13=\"" << itexmat[3][1] << "\"\n";
+ ostr << "\t\tm20=\"" << itexmat[0][2] << "\" m21=\"" << itexmat[1][2]
+ << "\" m22=\"" << itexmat[2][2] << "\" m23=\"" << itexmat[3][2] << "\"\n";
+ ostr << "\t\tm30=\"" << itexmat[0][3] << "\" m31=\"" << itexmat[1][3]
+ << "\" m32=\"" << itexmat[2][3] << "\" m33=\"" << itexmat[3][3] << "\">\n";
}
else ostr << ">\n";
ostr << "\t<attributes>\n";
- if ((tex->flag & TEX_COLORBAND) & (tex->coba!=NULL))
+ // use image name instead of texname when texture is image
+ if ((tex->type==TEX_IMAGE) && tex->ima)
+ ostr << "\t\t<input value=\"" << tex->ima->id.name << "\" />\n";
+ else if ((tex->flag & TEX_COLORBAND) & (tex->coba!=NULL))
ostr << "\t\t<input value=\"" << mtexL->first + "_coba" << "\" />\n";
else
ostr << "\t\t<input value=\"" << mtexL->first << "\" />\n";
- // size, if the texturetype is clouds/marble/wood, also take noisesize into account
- float sc = 1;
- if ((tex->type==TEX_CLOUDS) || (tex->type==TEX_MARBLE) || (tex->type==TEX_WOOD)) {
- sc = tex->noisesize;
- if (sc!=0) sc = 1.f/sc;
-
- }
// texture size
- ostr << "\t\t<sizex value=\"" << mtex->size[0]*sc << "\" />\n";
- ostr << "\t\t<sizey value=\"" << mtex->size[1]*sc << "\" />\n";
- ostr << "\t\t<sizez value=\"" << mtex->size[2]*sc << "\" />\n";
+ ostr << "\t\t<sizex value=\"" << mtex->size[0] << "\" />\n";
+ ostr << "\t\t<sizey value=\"" << mtex->size[1] << "\" />\n";
+ ostr << "\t\t<sizez value=\"" << mtex->size[2] << "\" />\n";
// texture offset
ostr << "\t\t<ofsx value=\"" << mtex->ofs[0] << "\" />\n";
@@ -483,7 +815,7 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
ostr << "\t\t<ofsz value=\"" << mtex->ofs[2] << "\" />\n";
// texture coordinates, have to disable 'sticky' in Blender
- if ((mtex->texco & TEXCO_UV) || (matr->mode & MA_FACETEXTURE))
+ if (mtex->texco & TEXCO_UV)
ostr << "\t\t<texco value=\"uv\" />\n";
else if ((mtex->texco & TEXCO_GLOB) || (mtex->texco & TEXCO_OBJECT))
// object mode is also set as global, but the object matrix was specified above with <modulator..>
@@ -497,6 +829,12 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
else if (mtex->texco & TEXCO_REFL)
ostr << "\t\t<texco value=\"reflect\" />\n";
+ // texture projection axes, both image & procedural
+ string proj = "nxyz"; // 'n' for 'none'
+ ostr << "\t\t<proj_x value=\"" << proj[mtex->projx] << "\" />\n";
+ ostr << "\t\t<proj_y value=\"" << proj[mtex->projy] << "\" />\n";
+ ostr << "\t\t<proj_z value=\"" << proj[mtex->projz] << "\" />\n";
+
// texture mapping parameters only relevant to image type
if (tex->type==TEX_IMAGE) {
if (mtex->mapping==MTEX_FLAT)
@@ -508,12 +846,6 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
else if (mtex->mapping==MTEX_SPHERE)
ostr << "\t\t<mapping value=\"sphere\" />\n";
- // texture projection axes
- string proj = "nxyz"; // 'n' for 'none'
- ostr << "\t\t<proj_x value=\"" << proj[mtex->projx] << "\" />\n";
- ostr << "\t\t<proj_y value=\"" << proj[mtex->projy] << "\" />\n";
- ostr << "\t\t<proj_z value=\"" << proj[mtex->projz] << "\" />\n";
-
// repeat
ostr << "\t\t<xrepeat value=\"" << tex->xrepeat << "\" />\n";
ostr << "\t\t<yrepeat value=\"" << tex->yrepeat << "\" />\n";
@@ -547,185 +879,45 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
}
}
- // blendershaders + modulators
- ostr.str("");
- ostr << "<shader type=\"blendershader\" name=\"" << blendmat->first << "\" >\n";
- ostr << "\t<attributes>\n";
- float diff=matr->alpha;
- ostr << "\t\t<color r=\"" << matr->r*diff << "\" g=\"" << matr->g*diff << "\" b=\"" << matr->b*diff << "\" />\n";
- ostr << "\t\t<specular_color r=\"" << matr->specr << "\" g=\"" << matr->specg << "\" b=\"" << matr->specb<< "\" />\n";
- ostr << "\t\t<mirror_color r=\"" << matr->mirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n";
- ostr << "\t\t<diffuse_reflect value=\"" << matr->ref << "\" />\n";
- ostr << "\t\t<specular_amount value=\"" << matr->spec << "\" />\n";
- ostr << "\t\t<hard value=\"" << matr->har << "\" />\n";
- ostr << "\t\t<alpha value=\"" << matr->alpha << "\" />\n";
- // if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
- float bg_mult;
- if (R.r.GImethod==0) bg_mult=1; else bg_mult=R.r.GIpower;
- ostr << "\t\t<emit value=\"" << (matr->emit * bg_mult) << "\" />\n";
-
- // reflection/refraction
- if ( (matr->mode & MA_RAYMIRROR) || (matr->mode & MA_RAYTRANSP) )
- ostr << "\t\t<IOR value=\"" << matr->ang << "\" />\n";
- if (matr->mode & MA_RAYMIRROR) {
- float rf = matr->ray_mirror;
- // blender uses mir color for reflection as well
- ostr << "\t\t<reflected r=\"" << matr->mirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n";
- ostr << "\t\t<min_refle value=\""<< rf << "\" />\n";
- if (matr->ray_depth>maxraydepth) maxraydepth = matr->ray_depth;
- }
- if (matr->mode & MA_RAYTRANSP)
- {
- float tr=1.0-matr->alpha;
- ostr << "\t\t<transmitted r=\"" << matr->r * tr << "\" g=\"" << matr->g * tr << "\" b=\"" << matr->b * tr << "\" />\n";
- // tir on by default
- ostr << "\t\t<tir value=\"on\" />\n";
- if (matr->ray_depth_tra>maxraydepth) maxraydepth = matr->ray_depth_tra;
- }
-
- string Mmode = "";
- if (matr->mode & MA_TRACEBLE) Mmode += "traceable";
- if (matr->mode & MA_SHADOW) Mmode += " shadow";
- if (matr->mode & MA_SHLESS) Mmode += " shadeless";
- if (matr->mode & MA_VERTEXCOL) Mmode += " vcol_light";
- if (matr->mode & MA_VERTEXCOLP) Mmode += " vcol_paint";
- if (matr->mode & MA_ZTRA) Mmode += " ztransp";
- if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
- if (Mmode!="") ostr << "\t\t<matmodes value=\"" << Mmode << "\" />\n";
- ostr << "\t</attributes>\n";
- xmlfile << ostr.str();
-
- // modulators
- for (int m2=0;m2<8;m2++) {
-
- if (matr->septex & (1<<m2)) continue;// all active channels
-
- // ignore null mtex
- MTex* mtex = matr->mtex[m2];
- if (mtex==NULL) continue;
-
- // ignore null tex
- Tex* tex = mtex->tex;
- if (tex==NULL) continue;
-
- map<string, pair<Material*, MTex*> >::const_iterator mtexL = used_textures.find(string(tex->id.name));
- if (mtexL!=used_textures.end()) {
-
- ostr.str("");
- ostr << "\t<modulator>\n";
- ostr << "\t\t<input value=\"" << blendmat->first + "_map" << m2 << "\" />\n";
-
- // blendtype
- string ts = "mix";
- if (mtex->blendtype==MTEX_MUL) ts="mul";
- else if (mtex->blendtype==MTEX_ADD) ts="add";
- else if (mtex->blendtype==MTEX_SUB) ts="sub";
- ostr << "\t\t<mode value=\"" << ts << "\" />\n";
-
- // texture color (for use with MUL and/or no_rgb etc..)
- ostr << "\t\t<texcol r=\"" << mtex->r << "\" g=\"" << mtex->g << "\" b=\"" << mtex->b << "\" />\n";
-
- // texture contrast, brightness & color adjustment
- ostr << "\t\t<filtercolor r=\"" << tex->rfac << "\" g=\"" << tex->gfac << "\" b=\"" << tex->bfac << "\" />\n";
- ostr << "\t\t<contrast value=\"" << tex->contrast << "\" />\n";
- ostr << "\t\t<brightness value=\"" << tex->bright << "\" />\n";
-
- // all texture flags now are switches, having the value 1 or -1 (negative option)
- // the negative option only used for the intensity modulation options.
-
- // material (diffuse) color, amount controlled by colfac (see below)
- if (mtex->mapto & MAP_COL)
- ostr << "\t\t<color value=\"1\" />\n";
-
- // bumpmapping
- if ((mtex->mapto & MAP_NORM) || (mtex->maptoneg & MAP_NORM)) {
- // for yafray, bump factor is negated (unless negative option of 'Nor', is not affected by 'Neg')
- // scaled down quite a bit for yafray
- float nf = -mtex->norfac;
- if (mtex->maptoneg & MAP_NORM) nf *= -1.f;
- if (tex->type==TEX_IMAGE) nf/=60.f; else nf/=30.f;
- ostr << "\t\t<normal value=\"" << nf << "\" />\n";
-
- }
+ // shader + modulators
+ writeShader(blendmat->first, matr);
- // all blender texture modulation as switches, either 1 or -1 (negative state of button)
- // Csp, specular color modulation
- if (mtex->mapto & MAP_COLSPEC)
- ostr << "\t\t<colspec value=\"1\" />\n";
-
- // CMir, mirror color modulation
- if (mtex->mapto & MAP_COLMIR)
- ostr << "\t\t<colmir value=\"1\" />\n";
-
- // Ref, diffuse reflection amount modulation
- if ((mtex->mapto & MAP_REF) || (mtex->maptoneg & MAP_REF)) {
- int t = 1;
- if (mtex->maptoneg & MAP_REF) t = -1;
- ostr << "\t\t<difref value=\"" << t << "\" />\n";
- }
-
- // Spec, specular amount mod
- if ((mtex->mapto & MAP_SPEC) || (mtex->maptoneg & MAP_SPEC)) {
- int t = 1;
- if (mtex->maptoneg & MAP_SPEC) t = -1;
- ostr << "\t\t<specular value=\"" << t << "\" />\n";
- }
-
- // hardness modulation
- if ((mtex->mapto & MAP_HAR) || (mtex->maptoneg & MAP_HAR)) {
- int t = 1;
- if (mtex->maptoneg & MAP_HAR) t = -1;
- ostr << "\t\t<hard value=\"" << t << "\" />\n";
- }
-
- // alpha modulation
- if ((mtex->mapto & MAP_ALPHA) || (mtex->maptoneg & MAP_ALPHA)) {
- int t = 1;
- if (mtex->maptoneg & MAP_ALPHA) t = -1;
- ostr << "\t\t<alpha value=\"" << t << "\" />\n";
-
- }
-
- // emit modulation
- if ((mtex->mapto & MAP_EMIT) || (mtex->maptoneg & MAP_EMIT)) {
- int t = 1;
- if (mtex->maptoneg & MAP_EMIT) t = -1;
- ostr << "\t\t<emit value=\"" << t << "\" />\n";
- }
-
- // texture flag, combination of strings
- if (mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE)) {
- ts = "";
- if (mtex->texflag & MTEX_RGBTOINT) ts += "no_rgb ";
- if (mtex->texflag & MTEX_STENCIL) ts += "stencil ";
- if (mtex->texflag & MTEX_NEGATIVE) ts += "negative";
- ostr << "\t\t<texflag value=\"" << ts << "\" />\n";
- }
-
- // colfac, controls amount of color modulation
- ostr << "\t\t<colfac value=\"" << mtex->colfac << "\" />\n";
+ }
- // def_var
- ostr << "\t\t<def_var value=\"" << mtex->def_var << "\" />\n";
+ // write the mappers & shaders for the TexFace case
+ if (!imagetex.empty()) {
+ // Yafray doesn't have per-face-textures, only per-face-shaders,
+ // so create as many mappers/shaders as the images used by the object
+ int snum = 0;
+ for (map<Image*, Material*>::const_iterator imgtex=imagetex.begin();
+ imgtex!=imagetex.end();++imgtex)
+ {
+ Material* matr = imgtex->second;
- //varfac
- ostr << "\t\t<varfac value=\"" << mtex->varfac << "\" />\n";
+ // mapper
+ ostr.str("");
+ ostr << "<shader type=\"blendermapper\" name=\"" << string(matr->id.name) + "_ftex_mp" << snum << "\" >\n";
+ ostr << "\t<attributes>\n";
+ ostr << "\t\t<input value=\"" << imgtex->first->id.name << "\" />\n";
+ // all yafray default settings, except for texco, so no need to set others
+ ostr << "\t\t<texco value=\"uv\" />\n";
+ ostr << "\t</attributes>\n";
+ ostr << "</shader>\n\n";
+ xmlfile << ostr.str();
- if ((tex->imaflag & (TEX_CALCALPHA | TEX_USEALPHA)) || (tex->flag & TEX_NEGALPHA)) {
- ts = "";
- if (tex->imaflag & TEX_CALCALPHA) ts += "calc_alpha ";
- if (tex->imaflag & TEX_USEALPHA) ts += "use_alpha ";
- if (tex->flag & TEX_NEGALPHA) ts += "neg_alpha";
- ostr << "\t\t<alpha_flag value=\"" << ts << "\" />\n";
- }
+ // shader, remember name, used later when writing per-face-shaders
+ ostr.str("");
+ ostr << matr->id.name << "_ftex_sh" << snum;
+ string shader_name = ostr.str();
+ imgtex_shader[imgtex->first] = shader_name;
- ostr << "\t</modulator>\n";
- xmlfile << ostr.str();
+ ostr.str("");
+ ostr << matr->id.name << "_ftex_mp" << snum++;
+ writeShader(shader_name, matr, ostr.str());
- }
}
- xmlfile << "</shader>\n\n";
}
+
}
@@ -744,35 +936,45 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
xmlfile << ostr.str();
ostr.str("");
- ostr << "<object name=\"" << obj->id.name+2 << "\"";
- // yafray still needs default shader name in object def.,
- // since we write a shader with every face, simply use the material of the first face
- // if this is an empty string, assume default mat
- char* matname = VLR_list[0]->mat->id.name;
- bool shadow=VLR_list[0]->mat->mode & MA_TRACEBLE;
- ostr <<" shadow=\""<< (shadow ? "on" : "off" )<<"\" ";
- bool caus = (((VLR_list[0]->mat->mode & MA_RAYTRANSP) | (VLR_list[0]->mat->mode & MA_RAYMIRROR))!=0);
- if (caus) ostr << "caus_IOR=\"" << VLR_list[0]->mat->ang << "\"";
- if (strlen(matname)==0) matname = "blender_default";
+ ostr << "<object name=\"" << obj->id.name << "\"";
+ // Yafray still needs default shader name in object def.,
+ // since we write a shader with every face, simply use the material of the first face.
+ // If this is an empty string, assume default material.
+ VlakRen* face0 = VLR_list[0];
+ Material* face0mat = face0->mat;
+ string matname(face0mat->id.name);
+ // use name in imgtex_shader list if 'TexFace' enabled for this material
+ if (face0mat->mode & MA_FACETEXTURE) {
+ TFace* tface = face0->tface;
+ if (tface) {
+ Image* fimg = (Image*)tface->tpage;
+ if (fimg) matname = imgtex_shader[fimg];
+ }
+ }
+ bool shadow = face0mat->mode & MA_TRACEBLE;
+ ostr <<" shadow=\""<< (shadow ? "on" : "off" ) << "\" ";
+ bool caus = (((face0mat->mode & MA_RAYTRANSP) | (face0->mat->mode & MA_RAYMIRROR))!=0);
+ if (caus) ostr << "caus_IOR=\"" << face0mat->ang << "\"";
+ if (matname.length()==0) matname = "blender_default";
ostr << " shader_name=\"" << matname << "\" >\n";
ostr << "\t<attributes>\n";
if (caus)
{
- float tr = 1.0-VLR_list[0]->mat->alpha;
- ostr << "\t\t<caus_tcolor r=\"" << VLR_list[0]->mat->r*tr
- << "\" g=\"" << VLR_list[0]->mat->g*tr
- << "\" b=\"" << VLR_list[0]->mat->b*tr << "\" />\n";
- tr = VLR_list[0]->mat->ray_mirror;
- ostr << "\t\t<caus_rcolor r=\"" << VLR_list[0]->mat->mirr*tr
- << "\" g=\"" << VLR_list[0]->mat->mirg*tr
- << "\" b=\"" << VLR_list[0]->mat->mirb*tr << "\" />\n";
+ float tr = 1.0-face0mat->alpha;
+ ostr << "\t\t<caus_tcolor r=\"" << face0mat->r*tr
+ << "\" g=\"" << face0mat->g*tr
+ << "\" b=\"" << face0mat->b*tr << "\" />\n";
+ tr = face0mat->ray_mirror;
+ ostr << "\t\t<caus_rcolor r=\"" << face0mat->mirr*tr
+ << "\" g=\"" << face0mat->mirg*tr
+ << "\" b=\"" << face0mat->mirb*tr << "\" />\n";
}
ostr << "\t</attributes>\n";
xmlfile << ostr.str();
// if any face in the Blender mesh uses an orco texture, every face has orco coords,
// so only need to check the first facevtx.orco in the list if they need to be exported
- bool EXPORT_ORCO = (VLR_list[0]->v1->orco!=NULL);
+ bool EXPORT_ORCO = (face0->v1->orco!=NULL);
string has_orco = "off";
if (EXPORT_ORCO) has_orco = "on";
@@ -793,7 +995,7 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
// If AutoSmooth not used, since yafray currently cannot specify if a face is smooth
// or flat shaded, the smooth flag of the first face is used to determine
// the shading for the whole mesh
- if (VLR_list[0]->flag & ME_SMOOTH)
+ if (face0->flag & ME_SMOOTH)
xmlfile << "\t<mesh autosmooth=\"90\" has_orco=\"" << has_orco << "\" >\n";
else
xmlfile << "\t<mesh autosmooth=\"0.1\" has_orco=\"" << has_orco << "\" >\n"; //0 shows artefacts
@@ -885,33 +1087,38 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
VlakRen* vlr = *fci2;
Material* fmat = vlr->mat;
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
- char* fmatname = fmat->id.name;
- if (strlen(fmatname)==0) fmatname = "blender_default";
- TFace* uvc = vlr->tface; // possible uvcoords (v upside down)
- int idx1, idx2, idx3;
-
- idx1 = vert_idx.find(vlr->v1)->second;
- idx2 = vert_idx.find(vlr->v2)->second;
- idx3 = vert_idx.find(vlr->v3)->second;
-
+ string fmatname(fmat->id.name);
+ // use name in imgtex_shader list if 'TexFace' enabled for this face material
+ if (fmat->mode & MA_FACETEXTURE) {
+ TFace* tface = vlr->tface;
+ if (tface) {
+ Image* fimg = (Image*)tface->tpage;
+ if (fimg) fmatname = imgtex_shader[fimg];
+ }
+ }
+ else if (fmatname.length()==0) fmatname = "blender_default";
+
+ int idx1 = vert_idx.find(vlr->v1)->second;
+ int idx2 = vert_idx.find(vlr->v2)->second;
+ int idx3 = vert_idx.find(vlr->v3)->second;
// make sure the indices point to the vertices when orco coords exported
if (EXPORT_ORCO) { idx1*=2; idx2*=2; idx3*=2; }
ostr.str("");
ostr << "\t\t\t<f a=\"" << idx1 << "\" b=\"" << idx2 << "\" c=\"" << idx3 << "\"";
+ TFace* uvc = vlr->tface; // possible uvcoords (v upside down)
if (uvc) {
// use correct uv coords for this triangle
- if (vlr->flag & R_FACE_SPLIT) {
- ostr << " u_a=\"" << uvc->uv[0][0] << "\" v_a=\"" << 1-uvc->uv[0][1] << "\""
- << " u_b=\"" << uvc->uv[2][0] << "\" v_b=\"" << 1-uvc->uv[2][1] << "\""
- << " u_c=\"" << uvc->uv[3][0] << "\" v_c=\"" << 1-uvc->uv[3][1] << "\"";
- }
- else {
- ostr << " u_a=\"" << uvc->uv[0][0] << "\" v_a=\"" << 1-uvc->uv[0][1] << "\""
- << " u_b=\"" << uvc->uv[1][0] << "\" v_b=\"" << 1-uvc->uv[1][1] << "\""
- << " u_c=\"" << uvc->uv[2][0] << "\" v_c=\"" << 1-uvc->uv[2][1] << "\"";
+ int ui1=0, ui2=1, ui3=2;
+ if (vlr->flag & R_DIVIDE_24) {
+ ui3++;
+ if (vlr->flag & R_FACE_SPLIT) { ui1++; ui2++; }
}
+ else if (vlr->flag & R_FACE_SPLIT) { ui2++; ui3++; }
+ ostr << " u_a=\"" << uvc->uv[ui1][0] << "\" v_a=\"" << 1-uvc->uv[ui1][1] << "\""
+ << " u_b=\"" << uvc->uv[ui2][0] << "\" v_b=\"" << 1-uvc->uv[ui2][1] << "\""
+ << " u_c=\"" << uvc->uv[ui3][0] << "\" v_c=\"" << 1-uvc->uv[ui3][1] << "\"";
}
// since Blender seems to need vcols when uvs are used, for yafray only export when the material actually uses vcols
@@ -982,7 +1189,7 @@ void yafrayFileRender_t::writeAllObjects()
for (map<Object*, vector<VlakRen*> >::const_iterator obi=all_objects.begin();
obi!=all_objects.end(); ++obi)
{
- // skip main duplivert object if in dupliMtx_list, written later
+ // skip main duplivert object if in dupliMtx_list, written later
Object* obj = obi->first;
if (dupliMtx_list.find(string(obj->id.name))!=dupliMtx_list.end()) continue;
writeObject(obj, obi->second, obj->obmat);
@@ -1031,7 +1238,7 @@ void yafrayFileRender_t::writeAllObjects()
// new name from original
ostr.str("");
- ostr << "<object name=\"" << obj->id.name+2 << "_dup" << (curmtx>>4) << "\" original=\"" << obj->id.name+2 << "\" >\n";
+ ostr << "<object name=\"" << obj->id.name << "_dup" << (curmtx>>4) << "\" original=\"" << obj->id.name << "\" >\n";
xmlfile << ostr.str();
xmlfile << "\t<attributes>\n\t</attributes>\n\t<null/>\n</object>\n</transform>\n\n";
@@ -1150,11 +1357,16 @@ void yafrayFileRender_t::writeLamps()
// cast_shadows flag not used with softlight, spherelight or photonlight
if ((!is_softL) && (!is_sphereL) && (lamp->type!=LA_YF_PHOTON)) {
string lpmode="off";
- // shadows only when Blender has shadow button enabled, only spots use LA_SHAD flag
- if (R.r.mode & R_SHADOW)
- if (((lamp->type==LA_SPOT) && (lamp->mode & LA_SHAD)) || (lamp->mode & LA_SHAD_RAY)) lpmode="on";
+ // Shadows only when Blender has shadow button enabled, only spots use LA_SHAD flag.
+ // Also blender hemilights exported as sunlights which might have shadow flag set
+ // should have cast_shadows set to off (reported by varuag)
+ if (lamp->type!=LA_HEMI) {
+ if (R.r.mode & R_SHADOW)
+ if (((lamp->type==LA_SPOT) && (lamp->mode & LA_SHAD)) || (lamp->mode & LA_SHAD_RAY)) lpmode="on";
+ }
ostr << " cast_shadows=\"" << lpmode << "\"";
}
+
// spot specific stuff
bool has_halo = ((lamp->type==LA_SPOT) && (lamp->mode & LA_HALO) && (lamp->haint>0.0));
@@ -1287,7 +1499,7 @@ void yafrayFileRender_t::writeCamera()
void yafrayFileRender_t::writeHemilight()
{
ostr.str("");
- ostr << "<light type=\"hemilight\" name=\"hemi_LT\" power=\"1.0\" ";
+ ostr << "<light type=\"hemilight\" name=\"hemi_LT\" power=\"" << R.r.GIpower << "\"";
switch (R.r.GIquality)
{
case 1 :
@@ -1311,7 +1523,7 @@ void yafrayFileRender_t::writePathlight()
<< "\" caus_depth=\""<<R.r.GIcausdepth<< "\" search=\""<< R.r.GImixphotons<<"\" >"<<endl;
ostr << "</light>"<<endl;
}
- ostr << "<light type=\"pathlight\" name=\"path_LT\" power=\"1.0\" ";
+ ostr << "<light type=\"pathlight\" name=\"path_LT\" power=\"" << R.r.GIindirpower << "\"";
ostr << " depth=\"" << ((R.r.GIphotons) ? 1 : R.r.GIdepth) << "\" caus_depth=\"" << R.r.GIcausdepth <<"\"\n";
if(R.r.GIdirect && R.r.GIphotons) ostr << "direct=\"on\"" << endl;
if (R.r.GIcache && ! (R.r.GIdirect && R.r.GIphotons))
@@ -1327,12 +1539,10 @@ void yafrayFileRender_t::writePathlight()
}
float aspect = 1;
if (R.r.xsch < R.r.ysch) aspect = float(R.r.xsch)/float(R.r.ysch);
- //float sbase = 2.0*atan(0.5/(mainCamLens/(aspect*32.0)))/float(R.r.xsch);
float sbase = 2.0/float(R.r.xsch);
ostr << " cache=\"on\" use_QMC=\"on\" threshold=\"" <<R.r.GIrefinement<<"\""<<endl;
ostr << " cache_size=\"" << sbase*R.r.GIpixelspersample << "\" shadow_threshold=\"" <<
- 1.0 - R.r.GIshadowquality << "\" grid=\"82\" search=\"35\" gradient=\"" <<
- ((R.r.GIgradient)? "on" : "off") << "\" >\n";
+ 1.0 - R.r.GIshadowquality << "\" grid=\"82\" search=\"35\" >\n";
}
else
{
@@ -1404,8 +1614,7 @@ bool yafrayFileRender_t::writeWorld()
ostr << "<background type=\"constant\" name=\"world_background\" >\n";
// if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
// (have to change method to init yafray vars in Blender)
- float bg_mult;
- if (R.r.GImethod==0) bg_mult=1; else bg_mult=R.r.GIpower;
+ float bg_mult = (R.r.GImethod==0) ? 1 : R.r.GIpower;
ostr << "\t<color r=\"" << (world->horr * bg_mult) <<
"\" g=\"" << (world->horg * bg_mult) <<
"\" b=\"" << (world->horb * bg_mult) << "\" />\n";
diff --git a/source/blender/yafray/intern/export_File.h b/source/blender/yafray/intern/export_File.h
index c9d650f578f..5d2e0c53a21 100755
--- a/source/blender/yafray/intern/export_File.h
+++ b/source/blender/yafray/intern/export_File.h
@@ -16,11 +16,11 @@ class yafrayFileRender_t : public yafrayRender_t
void displayImage();
bool executeYafray(const std::string &xmlpath);
virtual void writeTextures();
+ virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname="");
virtual void writeMaterialsAndModulators();
- virtual void writeObject(Object* obj,
- const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
+ virtual void writeObject(Object* obj, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
virtual void writeAllObjects();
- void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
+ virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
virtual void writeLamps();
virtual void writeCamera();
virtual void writeHemilight();
diff --git a/source/blender/yafray/intern/export_Plugin.cpp b/source/blender/yafray/intern/export_Plugin.cpp
index 960e65c13c2..40e87d3856f 100644
--- a/source/blender/yafray/intern/export_Plugin.cpp
+++ b/source/blender/yafray/intern/export_Plugin.cpp
@@ -317,34 +317,74 @@ static void adjustPath(string &path)
}
+static string noise2string(short nbtype)
+{
+ switch (nbtype) {
+ case TEX_BLENDER:
+ return "blender";
+ case TEX_STDPERLIN:
+ return "stdperlin";
+ case TEX_VORONOI_F1:
+ return "voronoi_f1";
+ case TEX_VORONOI_F2:
+ return "voronoi_f2";
+ case TEX_VORONOI_F3:
+ return "voronoi_f3";
+ case TEX_VORONOI_F4:
+ return "voronoi_f4";
+ case TEX_VORONOI_F2F1:
+ return "voronoi_f2f1";
+ case TEX_VORONOI_CRACKLE:
+ return "voronoi_crackle";
+ case TEX_CELLNOISE:
+ return "cellnoise";
+ default:
+ case TEX_NEWPERLIN:
+ return "newperlin";
+ }
+}
+
void yafrayPluginRender_t::writeTextures()
{
- for (map<string, pair<Material*, MTex*> >::const_iterator blendtex=used_textures.begin();
+ string ts;
+ yafray::paramMap_t params;
+ list<yafray::paramMap_t> lparams;
+ for (map<string, MTex*>::const_iterator blendtex=used_textures.begin();
blendtex!=used_textures.end();++blendtex)
{
- yafray::paramMap_t params;
- list<yafray::paramMap_t> lparams;
- MTex* mtex = blendtex->second.second;
+ MTex* mtex = blendtex->second;
Tex* tex = mtex->tex;
- params["name"]=yafray::parameter_t(blendtex->first);
+ // name is image name instead of texture name when type is image (see TEX_IMAGE case below)
+ // (done because of possible combinations of 'TexFace' images and regular image textures, to avoid duplicates)
+ if (tex->type!=TEX_IMAGE) params["name"] = yafray::parameter_t(blendtex->first);
+
+ float nsz = tex->noisesize;
+ if (nsz!=0.f) nsz=1.f/nsz;
+
+ // noisebasis type
+ string ntype = noise2string(tex->noisebasis);
+
switch (tex->type) {
case TEX_STUCCI:
// stucci is clouds as bump, but could be added to yafray to handle both wall in/out as well.
// noisedepth must be at least 1 in yafray
- case TEX_CLOUDS:
- params["type"]=yafray::parameter_t("clouds");
- params["depth"]=yafray::parameter_t(tex->noisedepth+1);
+ case TEX_CLOUDS: {
+ params["type"] = yafray::parameter_t("clouds");
+ params["depth"] = yafray::parameter_t(tex->noisedepth+1);
+ params["size"] = yafray::parameter_t(nsz);
+ params["noise_type"] = ntype;
break;
+ }
case TEX_WOOD:
{
- params["type"]=yafray::parameter_t("wood");
- params["depth"]=yafray::parameter_t(tex->noisedepth+1);
- params["turbulence"]=yafray::parameter_t(tex->turbul);
- params["ringscale_x"]=yafray::parameter_t(mtex->size[0]);
- params["ringscale_y"]=yafray::parameter_t(mtex->size[1]);
- string ts = "on";
+ params["type"] = yafray::parameter_t("wood");
+ params["depth"] = yafray::parameter_t(tex->noisedepth+1);
+ params["turbulence"] = yafray::parameter_t(tex->turbul);
+ params["ringscale_x"] = yafray::parameter_t(mtex->size[0]);
+ params["ringscale_y"] = yafray::parameter_t(mtex->size[1]);
+ ts = "on";
if (tex->noisetype==TEX_NOISESOFT) ts = "off";
- params["hard"]=yafray::parameter_t(ts);
+ params["hard"] = yafray::parameter_t(ts);
break;
}
case TEX_MARBLE:
@@ -352,7 +392,7 @@ void yafrayPluginRender_t::writeTextures()
params["type"]=yafray::parameter_t("marble");
params["depth"]=yafray::parameter_t(tex->noisedepth+1);
params["turbulence"]=yafray::parameter_t(tex->turbul);
- string ts = "on";
+ ts = "on";
if (tex->noisetype==TEX_NOISESOFT) ts = "off";
params["hard"]=yafray::parameter_t(ts);
if (tex->stype==1)
@@ -367,17 +407,97 @@ void yafrayPluginRender_t::writeTextures()
{
Image* ima = tex->ima;
if (ima) {
- params["type"]=yafray::parameter_t("image");
+ // remove from imagetex list to avoid possible duplicates when TexFace used
+ imagetex.erase(ima);
+ params["type"] = yafray::parameter_t("image");
+ params["name"] = yafray::parameter_t(ima->id.name);
string texpath = ima->name;
adjustPath(texpath);
params["filename"] = yafray::parameter_t(texpath);
}
break;
}
+ case TEX_VORONOI:
+ {
+ params["type"] = yafray::parameter_t("voronoi");
+ ts = "int";
+ if (tex->vn_coltype==1)
+ ts = "col1";
+ else if (tex->vn_coltype==2)
+ ts = "col2";
+ else if (tex->vn_coltype==3)
+ ts = "col3";
+ params["color_type"] = yafray::parameter_t(ts);
+ params["weight1"] = yafray::parameter_t(tex->vn_w1);
+ params["weight2"] = yafray::parameter_t(tex->vn_w2);
+ params["weight3"] = yafray::parameter_t(tex->vn_w3);
+ params["weight4"] = yafray::parameter_t(tex->vn_w4);
+ params["mk_exponent"] = yafray::parameter_t(tex->vn_mexp);
+ params["intensity"] = yafray::parameter_t(tex->ns_outscale);
+ params["size"] = yafray::parameter_t(nsz);
+ ts = "actual";
+ if (tex->vn_distm==TEX_DISTANCE_SQUARED)
+ ts = "squared";
+ else if (tex->vn_distm==TEX_MANHATTAN)
+ ts = "manhattan";
+ else if (tex->vn_distm==TEX_CHEBYCHEV)
+ ts = "chebychev";
+ else if (tex->vn_distm==TEX_MINKOVSKY_HALF)
+ ts = "minkovsky_half";
+ else if (tex->vn_distm==TEX_MINKOVSKY_FOUR)
+ ts = "minkovsky_four";
+ else if (tex->vn_distm==TEX_MINKOVSKY)
+ ts = "minkovsky";
+ params["distance_metric"] = yafray::parameter_t(ts);
+ break;
+ }
+ case TEX_MUSGRAVE:
+ {
+ params["type"] = yafray::parameter_t("musgrave");
+ switch (tex->stype) {
+ case TEX_MFRACTAL:
+ ts = "multifractal";
+ break;
+ case TEX_RIDGEDMF:
+ ts = "ridgedmf";
+ break;
+ case TEX_HYBRIDMF:
+ ts = "hybridmf";
+ break;
+ case TEX_HTERRAIN:
+ ts = "heteroterrain";
+ break;
+ default:
+ case TEX_FBM:
+ ts = "fBm";
+ }
+ params["musgrave_type"] = yafray::parameter_t(ts);
+ params["noise_type"] = yafray::parameter_t(ntype);
+ params["H"] = yafray::parameter_t(tex->mg_H);
+ params["lacunarity"] = yafray::parameter_t(tex->mg_lacunarity);
+ params["octaves"] = yafray::parameter_t(tex->mg_octaves);
+ if ((tex->stype==TEX_HTERRAIN) || (tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF)) {
+ params["offset"] = yafray::parameter_t(tex->mg_offset);
+ if ((tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF))
+ params["gain"] = yafray::parameter_t(tex->mg_gain);
+ }
+ params["size"] = yafray::parameter_t(nsz);
+ params["intensity"] = yafray::parameter_t(tex->ns_outscale);
+ break;
+ }
+ case TEX_DISTNOISE:
+ {
+ params["type"] = yafray::parameter_t("distorted_noise");
+ params["distort"] = yafray::parameter_t(tex->dist_amount);
+ params["size"] = yafray::parameter_t(nsz);
+ params["noise_type1"] = yafray::parameter_t(ntype);
+ params["noise_type2"] = yafray::parameter_t(noise2string(tex->noisebasis2));
+ }
default:
cout << "Unsupported texture type\n";
}
- yafrayGate->addShader(params,lparams);
+ yafrayGate->addShader(params, lparams);
+
// colorbands
if (tex->flag & TEX_COLORBAND)
{
@@ -398,23 +518,231 @@ void yafrayPluginRender_t::writeTextures()
cb->data[i].a));
lparams.push_back(mparams);
}
- yafrayGate->addShader(params,lparams);
+ yafrayGate->addShader(params, lparams);
}
}
}
+
+ // If used, textures for the material 'TexFace' case
+ if (!imagetex.empty()) {
+ for (map<Image*, Material*>::const_iterator imgtex=imagetex.begin();
+ imgtex!=imagetex.end();++imgtex)
+ {
+ params.clear();
+ params["name"] = yafray::parameter_t(imgtex->first->id.name);
+ params["type"] = yafray::parameter_t("image");
+ string texpath(imgtex->first->name);
+ adjustPath(texpath);
+ params["filename"] = yafray::parameter_t(texpath);
+ yafrayGate->addShader(params, lparams);
+ }
+ }
+
}
+void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr, const string &facetexname)
+{
+ yafray::paramMap_t params;
+ params["type"] = yafray::parameter_t("blendershader");
+ params["name"] = yafray::parameter_t(shader_name);
+ float diff = matr->alpha;
+ params["color"] = yafray::parameter_t(yafray::color_t(matr->r*diff, matr->g*diff, matr->b*diff));
+ params["specular_color"] = yafray::parameter_t(yafray::color_t(matr->specr, matr->specg, matr->specb));
+ params["mirror_color"] = yafray::parameter_t(yafray::color_t(matr->mirr, matr->mirg, matr->mirb));
+ params["diffuse_reflect"] = yafray::parameter_t(matr->ref);
+ params["specular_amount"] = yafray::parameter_t(matr->spec);
+ params["hard"] = yafray::parameter_t(matr->har);
+ params["alpha"] = yafray::parameter_t(matr->alpha);
+
+ // if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
+ float bg_mult = (R.r.GImethod==0) ? 1 : R.r.GIpower;
+ params["emit"]=yafray::parameter_t(matr->emit*bg_mult);
+
+ // reflection/refraction
+ if ( (matr->mode & MA_RAYMIRROR) || (matr->mode & MA_RAYTRANSP) )
+ params["IOR"] = yafray::parameter_t(matr->ang);
+ if (matr->mode & MA_RAYMIRROR)
+ {
+ float rf = matr->ray_mirror;
+ // blender uses mir color for reflection as well
+ params["reflected"] = yafray::parameter_t(yafray::color_t(matr->mirr, matr->mirg, matr->mirb));
+ params["min_refle"] = yafray::parameter_t(rf);
+ if (matr->ray_depth>maxraydepth) maxraydepth = matr->ray_depth;
+ }
+ if (matr->mode & MA_RAYTRANSP)
+ {
+ float tr = 1.0-matr->alpha;
+ params["transmitted"]=yafray::parameter_t(yafray::color_t(matr->r*tr, matr->g*tr, matr->b*tr));
+ // tir on by default
+ params["tir"] = yafray::parameter_t("on");
+ if (matr->ray_depth_tra>maxraydepth) maxraydepth = matr->ray_depth_tra;
+ }
+
+ string Mmode = "";
+ if (matr->mode & MA_TRACEBLE) Mmode += "traceable";
+ if (matr->mode & MA_SHADOW) Mmode += " shadow";
+ if (matr->mode & MA_SHLESS) Mmode += " shadeless";
+ if (matr->mode & MA_VERTEXCOL) Mmode += " vcol_light";
+ if (matr->mode & MA_VERTEXCOLP) Mmode += " vcol_paint";
+ if (matr->mode & MA_ZTRA) Mmode += " ztransp";
+ if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
+ if (Mmode!="") params["matmodes"] = yafray::parameter_t(Mmode);
+
+ // modulators
+ list<yafray::paramMap_t> lparams;
+
+ // first modulator is the texture of the face, if used (TexFace mode)
+ if (facetexname.length()!=0) {
+ yafray::paramMap_t mparams;
+ mparams["input"] = yafray::parameter_t(facetexname);
+ mparams["color"] = yafray::parameter_t(1);
+ lparams.push_back(mparams);
+ }
+
+ for (int m2=0;m2<8;m2++)
+ {
+ if (matr->septex & (1<<m2)) continue;// all active channels
+ // ignore null mtex
+ MTex* mtex = matr->mtex[m2];
+ if (mtex==NULL) continue;
+ // ignore null tex
+ Tex* tex = mtex->tex;
+ if (tex==NULL) continue;
+
+ map<string, MTex*>::const_iterator mtexL = used_textures.find(string(tex->id.name));
+ if (mtexL!=used_textures.end())
+ {
+ yafray::paramMap_t mparams;
+ // when no facetex used, shader_name is created from original material name
+ char temp[32];
+ sprintf(temp,"_map%d", m2);
+ if (facetexname.length()!=0)
+ mparams["input"] = yafray::parameter_t(string(matr->id.name) + string(temp));
+ else
+ mparams["input"] = yafray::parameter_t(shader_name + temp);
+ // blendtype
+ string ts = "mix";
+ if (mtex->blendtype==MTEX_MUL) ts="mul";
+ else if (mtex->blendtype==MTEX_ADD) ts="add";
+ else if (mtex->blendtype==MTEX_SUB) ts="sub";
+ mparams["mode"]=yafray::parameter_t(ts);
+
+ // texture color (for use with MUL and/or no_rgb etc..)
+ mparams["texcol"]=yafray::parameter_t(yafray::color_t(mtex->r,mtex->g,mtex->b));
+ // texture contrast, brightness & color adjustment
+ mparams["filtercolor"]=yafray::parameter_t(yafray::color_t(tex->rfac,tex->gfac,tex->bfac));
+ mparams["contrast"]=yafray::parameter_t(tex->contrast);
+ mparams["brightness"]=yafray::parameter_t(tex->bright);
+ // all texture flags now are switches, having the value 1 or -1 (negative option)
+ // the negative option only used for the intensity modulation options.
+
+ // material (diffuse) color, amount controlled by colfac (see below)
+ if (mtex->mapto & MAP_COL)
+ mparams["color"]=yafray::parameter_t(1.0);
+ // bumpmapping
+ if ((mtex->mapto & MAP_NORM) || (mtex->maptoneg & MAP_NORM))
+ {
+ // for yafray, bump factor is negated (unless negative option of 'Nor',
+ // is not affected by 'Neg')
+ // scaled down quite a bit for yafray
+ float nf = -mtex->norfac;
+ if (mtex->maptoneg & MAP_NORM) nf *= -1.f;
+ mparams["normal"] = yafray::parameter_t(nf/60.f);
+ }
+
+ // all blender texture modulation as switches, either 1 or -1 (negative state of button)
+ // Csp, specular color modulation
+ if (mtex->mapto & MAP_COLSPEC)
+ mparams["colspec"]=yafray::parameter_t(1.0);
+ // CMir, mirror color modulation
+ if (mtex->mapto & MAP_COLMIR)
+ mparams["colmir"]=yafray::parameter_t(1.0);
+
+ // Ref, diffuse reflection amount modulation
+ if ((mtex->mapto & MAP_REF) || (mtex->maptoneg & MAP_REF))
+ {
+ int t = 1;
+ if (mtex->maptoneg & MAP_REF) t = -1;
+ mparams["difref"]=yafray::parameter_t(t);
+ }
+
+ // Spec, specular amount mod
+ if ((mtex->mapto & MAP_SPEC) || (mtex->maptoneg & MAP_SPEC))
+ {
+ int t = 1;
+ if (mtex->maptoneg & MAP_SPEC) t = -1;
+ mparams["specular"]=yafray::parameter_t(t);
+ }
+
+ // hardness modulation
+ if ((mtex->mapto & MAP_HAR) || (mtex->maptoneg & MAP_HAR))
+ {
+ int t = 1;
+ if (mtex->maptoneg & MAP_HAR) t = -1;
+ mparams["hard"]=yafray::parameter_t(t);
+ }
+
+ // alpha modulation
+ if ((mtex->mapto & MAP_ALPHA) || (mtex->maptoneg & MAP_ALPHA))
+ {
+ int t = 1;
+ if (mtex->maptoneg & MAP_ALPHA) t = -1;
+ mparams["alpha"]=yafray::parameter_t(t);
+ }
+
+ // emit modulation
+ if ((mtex->mapto & MAP_EMIT) || (mtex->maptoneg & MAP_EMIT)) {
+ int t = 1;
+ if (mtex->maptoneg & MAP_EMIT) t = -1;
+ mparams["emit"]=yafray::parameter_t(t);
+ }
+
+ // texture flag, combination of strings
+ if (mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE)) {
+ ts = "";
+ if (mtex->texflag & MTEX_RGBTOINT) ts += "no_rgb ";
+ if (mtex->texflag & MTEX_STENCIL) ts += "stencil ";
+ if (mtex->texflag & MTEX_NEGATIVE) ts += "negative";
+ mparams["texflag"]=yafray::parameter_t(ts);
+ }
+
+ // colfac, controls amount of color modulation
+ mparams["colfac"]=yafray::parameter_t(mtex->colfac);
+ // def_var
+ mparams["def_var"]=yafray::parameter_t(mtex->def_var);
+ //varfac
+ mparams["varfac"]=yafray::parameter_t(mtex->varfac);
+
+ if ((tex->imaflag & (TEX_CALCALPHA | TEX_USEALPHA)) || (tex->flag & TEX_NEGALPHA))
+ {
+ ts = "";
+ if (tex->imaflag & TEX_CALCALPHA) ts += "calc_alpha ";
+ if (tex->imaflag & TEX_USEALPHA) ts += "use_alpha ";
+ if (tex->flag & TEX_NEGALPHA) ts += "neg_alpha";
+ mparams["alpha_flag"]=yafray::parameter_t(ts);
+ }
+ lparams.push_back(mparams);
+ }
+ }
+ yafrayGate->addShader(params,lparams);
+
+}
+
// write all materials & modulators
void yafrayPluginRender_t::writeMaterialsAndModulators()
{
-
+ // shaders/mappers for regular texture (or non-texture) mode
+ // In case material has texface mode, and all faces have an image texture,
+ // this shader will not be used, but still be written
+ yafray::paramMap_t params;
+ list<yafray::paramMap_t> lparams;
for (map<string, Material*>::const_iterator blendmat=used_materials.begin();
blendmat!=used_materials.end();++blendmat)
{
Material* matr = blendmat->second;
- // blendermappers
+ // mapper(s)
for (int m=0;m<8;m++)
{
if (matr->septex & (1<<m)) continue;// all active channels
@@ -425,18 +753,13 @@ void yafrayPluginRender_t::writeMaterialsAndModulators()
Tex* tex = mtex->tex;
if (tex==NULL) continue;
- // now included the full name
- map<string, pair<Material*, MTex*> >::const_iterator mtexL = used_textures.find(string(tex->id.name));
+ map<string, MTex*>::const_iterator mtexL = used_textures.find(string(tex->id.name));
if (mtexL!=used_textures.end())
{
- yafray::paramMap_t params;
- list<yafray::paramMap_t> lparams;
- //params.clear();
- //lparams.clear();
- char temp[16];
- sprintf(temp,"%d",m);
- params["type"]=yafray::parameter_t("blendermapper");
- params["name"]=yafray::parameter_t(blendmat->first + "_map"+temp);
+ char temp[32];
+ sprintf(temp, "_map%d", m);
+ params["type"] = yafray::parameter_t("blendermapper");
+ params["name"] = yafray::parameter_t(blendmat->first + string(temp));
if ((mtex->texco & TEXCO_OBJECT) || (mtex->texco & TEXCO_REFL))
{
// For object & reflection mapping, add the object matrix to the modulator,
@@ -449,327 +772,171 @@ void yafrayPluginRender_t::writeMaterialsAndModulators()
MTC_Mat4CpyMat4(texmat, maincam_obj->obmat);
MTC_Mat4Invert(itexmat, texmat);
#define flp yafray::parameter_t
- params["m00"]=flp(itexmat[0][0]);params["m01"]=flp(itexmat[1][0]);
- params["m02"]=flp(itexmat[2][0]);params["m03"]=flp(itexmat[3][0]);
- params["m10"]=flp(itexmat[0][1]);params["m11"]=flp(itexmat[1][1]);
- params["m12"]=flp(itexmat[2][1]);params["m13"]=flp(itexmat[3][1]);
- params["m20"]=flp(itexmat[0][2]);params["m21"]=flp(itexmat[1][2]);
- params["m22"]=flp(itexmat[2][2]);params["m23"]=flp(itexmat[3][2]);
- params["m30"]=flp(itexmat[0][3]);params["m31"]=flp(itexmat[1][3]);
- params["m32"]=flp(itexmat[2][3]);params["m33"]=flp(itexmat[3][3]);
+ params["m00"]=flp(itexmat[0][0]); params["m01"]=flp(itexmat[1][0]);
+ params["m02"]=flp(itexmat[2][0]); params["m03"]=flp(itexmat[3][0]);
+ params["m10"]=flp(itexmat[0][1]); params["m11"]=flp(itexmat[1][1]);
+ params["m12"]=flp(itexmat[2][1]); params["m13"]=flp(itexmat[3][1]);
+ params["m20"]=flp(itexmat[0][2]); params["m21"]=flp(itexmat[1][2]);
+ params["m22"]=flp(itexmat[2][2]); params["m23"]=flp(itexmat[3][2]);
+ params["m30"]=flp(itexmat[0][3]); params["m31"]=flp(itexmat[1][3]);
+ params["m32"]=flp(itexmat[2][3]); params["m33"]=flp(itexmat[3][3]);
#undef flp
}
- if ((tex->flag & TEX_COLORBAND) & (tex->coba!=NULL))
- params["input"]=yafray::parameter_t(mtexL->first + "_coba");
+ // use image name instead of texname when texture is image
+ if ((tex->type==TEX_IMAGE) && tex->ima)
+ params["input"] = yafray::parameter_t(tex->ima->id.name);
+ else if ((tex->flag & TEX_COLORBAND) & (tex->coba!=NULL))
+ params["input"] = yafray::parameter_t(mtexL->first + "_coba");
else
- params["input"]=yafray::parameter_t(mtexL->first);
+ params["input"] = yafray::parameter_t(mtexL->first);
- // size, if the texturetype is clouds/marble/wood, also take noisesize into account
- float sc = 1;
- if ((tex->type==TEX_CLOUDS) || (tex->type==TEX_MARBLE) || (tex->type==TEX_WOOD))
- {
- sc = tex->noisesize;
- if (sc!=0) sc = 1.f/sc;
- }
// texture size
- params["sizex"]=yafray::parameter_t(mtex->size[0]*sc);
- params["sizey"]=yafray::parameter_t(mtex->size[1]*sc);
- params["sizez"]=yafray::parameter_t(mtex->size[2]*sc);
+ params["sizex"] = yafray::parameter_t(mtex->size[0]);
+ params["sizey"] = yafray::parameter_t(mtex->size[1]);
+ params["sizez"] = yafray::parameter_t(mtex->size[2]);
// texture offset
- params["ofsx"]=yafray::parameter_t(mtex->ofs[0]*sc);
- params["ofsy"]=yafray::parameter_t(mtex->ofs[1]*sc);
- params["ofsz"]=yafray::parameter_t(mtex->ofs[2]*sc);
+ params["ofsx"] = yafray::parameter_t(mtex->ofs[0]);
+ params["ofsy"] = yafray::parameter_t(mtex->ofs[1]);
+ params["ofsz"] = yafray::parameter_t(mtex->ofs[2]);
// texture coordinates, have to disable 'sticky' in Blender
- if ((mtex->texco & TEXCO_UV) || (matr->mode & MA_FACETEXTURE))
- params["texco"]=yafray::parameter_t("uv");
+ if (mtex->texco & TEXCO_UV)
+ params["texco"] = yafray::parameter_t("uv");
else if ((mtex->texco & TEXCO_GLOB) || (mtex->texco & TEXCO_OBJECT))
// object mode is also set as global, but the object matrix
// was specified above with <modulator..>
- params["texco"]=yafray::parameter_t("global");
+ params["texco"] = yafray::parameter_t("global");
else if (mtex->texco & TEXCO_ORCO)
- params["texco"]=yafray::parameter_t("orco");
+ params["texco"] = yafray::parameter_t("orco");
else if (mtex->texco & TEXCO_WINDOW)
- params["texco"]=yafray::parameter_t("window");
+ params["texco"] = yafray::parameter_t("window");
else if (mtex->texco & TEXCO_NORM)
- params["texco"]=yafray::parameter_t("normal");
+ params["texco"] = yafray::parameter_t("normal");
else if (mtex->texco & TEXCO_REFL)
- params["texco"]=yafray::parameter_t("reflect");
+ params["texco"] = yafray::parameter_t("reflect");
+
+ // texture projection axes, both image & procedural
+ string proj = "nxyz"; // 'n' for 'none'
+ params["proj_x"] = yafray::parameter_t(string(1,proj[mtex->projx]));
+ params["proj_y"] = yafray::parameter_t(string(1,proj[mtex->projy]));
+ params["proj_z"] = yafray::parameter_t(string(1,proj[mtex->projz]));
// texture mapping parameters only relevant to image type
if (tex->type==TEX_IMAGE)
{
if (mtex->mapping==MTEX_FLAT)
- params["mapping"]=yafray::parameter_t("flat");
+ params["mapping"] = yafray::parameter_t("flat");
else if (mtex->mapping==MTEX_CUBE)
- params["mapping"]=yafray::parameter_t("cube");
+ params["mapping"] = yafray::parameter_t("cube");
else if (mtex->mapping==MTEX_TUBE)
- params["mapping"]=yafray::parameter_t("tube");
+ params["mapping"] = yafray::parameter_t("tube");
else if (mtex->mapping==MTEX_SPHERE)
- params["mapping"]=yafray::parameter_t("sphere");
-
- // texture projection axes
- string proj = "nxyz"; // 'n' for 'none'
- params["proj_x"]=yafray::parameter_t(string(1,proj[mtex->projx]));
- params["proj_y"]=yafray::parameter_t(string(1,proj[mtex->projy]));
- params["proj_z"]=yafray::parameter_t(string(1,proj[mtex->projz]));
+ params["mapping"] = yafray::parameter_t("sphere");
// repeat
- params["xrepeat"]=yafray::parameter_t(tex->xrepeat);
- params["yrepeat"]=yafray::parameter_t(tex->yrepeat);
+ params["xrepeat"] = yafray::parameter_t(tex->xrepeat);
+ params["yrepeat"] = yafray::parameter_t(tex->yrepeat);
// clipping
if (tex->extend==TEX_EXTEND)
- params["clipping"]=yafray::parameter_t("extend");
+ params["clipping"] = yafray::parameter_t("extend");
else if (tex->extend==TEX_CLIP)
- params["clipping"]=yafray::parameter_t("clip");
+ params["clipping"] = yafray::parameter_t("clip");
else if (tex->extend==TEX_CLIPCUBE)
- params["clipping"]=yafray::parameter_t("clipcube");
+ params["clipping"] = yafray::parameter_t("clipcube");
else
- params["clipping"]=yafray::parameter_t("repeat");
+ params["clipping"] = yafray::parameter_t("repeat");
// crop min/max
- params["cropmin_x"]=yafray::parameter_t(tex->cropxmin);
- params["cropmin_y"]=yafray::parameter_t(tex->cropymin);
- params["cropmax_x"]=yafray::parameter_t(tex->cropxmax);
- params["cropmax_y"]=yafray::parameter_t(tex->cropymax);
+ params["cropmin_x"] = yafray::parameter_t(tex->cropxmin);
+ params["cropmin_y"] = yafray::parameter_t(tex->cropymin);
+ params["cropmax_x"] = yafray::parameter_t(tex->cropxmax);
+ params["cropmax_y"] = yafray::parameter_t(tex->cropymax);
// rot90 flag
if (tex->imaflag & TEX_IMAROT)
- params["rot90"]=yafray::parameter_t("on");
+ params["rot90"] = yafray::parameter_t("on");
else
- params["rot90"]=yafray::parameter_t("off");
+ params["rot90"] = yafray::parameter_t("off");
}
- yafrayGate->addShader(params,lparams);
+ yafrayGate->addShader(params, lparams);
}
}
- yafray::paramMap_t params;
- // blendershaders + modulators
- params["type"]=yafray::parameter_t("blendershader");
- params["name"]=yafray::parameter_t(blendmat->first);
- float diff=matr->alpha;
-
- params["color"]=yafray::parameter_t(yafray::color_t(matr->r*diff,matr->g*diff,matr->b*diff));
-
- params["specular_color"]=yafray::parameter_t(yafray::color_t(matr->specr,
- matr->specg,
- matr->specb));
- params["mirror_color"]=yafray::parameter_t(yafray::color_t(matr->mirr, matr->mirg,matr->mirb));
- params["diffuse_reflect"]=yafray::parameter_t(matr->ref);
- params["specular_amount"]=yafray::parameter_t(matr->spec);
- params["hard"]=yafray::parameter_t(matr->har);
- params["alpha"]=yafray::parameter_t(matr->alpha);
- // if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
- float bg_mult;
- if (R.r.GImethod==0) bg_mult=1; else bg_mult=R.r.GIpower;
- params["emit"]=yafray::parameter_t(matr->emit * bg_mult);
-
- // reflection/refraction
- if ( (matr->mode & MA_RAYMIRROR) || (matr->mode & MA_RAYTRANSP) )
- params["IOR"]=yafray::parameter_t(matr->ang);
- if (matr->mode & MA_RAYMIRROR)
- {
- float rf = matr->ray_mirror;
- // blender uses mir color for reflection as well
- params["reflected"]=yafray::parameter_t(yafray::color_t(matr->mirr, matr->mirg,matr->mirb));
- params["min_refle"]=yafray::parameter_t(rf);
- if (matr->ray_depth>maxraydepth) maxraydepth = matr->ray_depth;
- }
- if (matr->mode & MA_RAYTRANSP)
- {
- float tr=1.0-matr->alpha;
- params["transmitted"]=yafray::parameter_t(yafray::color_t(matr->r*tr,matr->g*tr,matr->b*tr));
- // tir on by default
- params["tir"]=yafray::parameter_t("on");
- if (matr->ray_depth_tra>maxraydepth) maxraydepth = matr->ray_depth_tra;
- }
- string Mmode = "";
- if (matr->mode & MA_TRACEBLE) Mmode += "traceable";
- if (matr->mode & MA_SHADOW) Mmode += " shadow";
- if (matr->mode & MA_SHLESS) Mmode += " shadeless";
- if (matr->mode & MA_VERTEXCOL) Mmode += " vcol_light";
- if (matr->mode & MA_VERTEXCOLP) Mmode += " vcol_paint";
- if (matr->mode & MA_ZTRA) Mmode += " ztransp";
- if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
- if (Mmode!="") params["matmodes"]=yafray::parameter_t(Mmode);
-
- // modulators
- list<yafray::paramMap_t> lparams;
- for (int m2=0;m2<8;m2++)
- {
- if (matr->septex & (1<<m2)) continue;// all active channels
- // ignore null mtex
- MTex* mtex = matr->mtex[m2];
- if (mtex==NULL) continue;
- // ignore null tex
- Tex* tex = mtex->tex;
- if (tex==NULL) continue;
+ // shader + modulators
+ writeShader(blendmat->first, matr);
- map<string, pair<Material*, MTex*> >::const_iterator mtexL = used_textures.find(string(tex->id.name));
- if (mtexL!=used_textures.end())
- {
- yafray::paramMap_t mparams;
- char temp[16];
- sprintf(temp,"%d",m2);
- mparams["input"]=yafray::parameter_t(blendmat->first + "_map" + temp);
- // blendtype
- string ts = "mix";
- if (mtex->blendtype==MTEX_MUL) ts="mul";
- else if (mtex->blendtype==MTEX_ADD) ts="add";
- else if (mtex->blendtype==MTEX_SUB) ts="sub";
- mparams["mode"]=yafray::parameter_t(ts);
-
- // texture color (for use with MUL and/or no_rgb etc..)
- mparams["texcol"]=yafray::parameter_t(yafray::color_t(mtex->r,mtex->g,mtex->b));
- // texture contrast, brightness & color adjustment
- mparams["filtercolor"]=yafray::parameter_t(yafray::color_t(tex->rfac,tex->gfac,tex->bfac));
- mparams["contrast"]=yafray::parameter_t(tex->contrast);
- mparams["brightness"]=yafray::parameter_t(tex->bright);
- // all texture flags now are switches, having the value 1 or -1 (negative option)
- // the negative option only used for the intensity modulation options.
-
- // material (diffuse) color, amount controlled by colfac (see below)
- if (mtex->mapto & MAP_COL)
- mparams["color"]=yafray::parameter_t(1.0);
- // bumpmapping
- if ((mtex->mapto & MAP_NORM) || (mtex->maptoneg & MAP_NORM))
- {
- // for yafray, bump factor is negated (unless negative option of 'Nor',
- // is not affected by 'Neg')
- // scaled down quite a bit for yafray
- float nf = -mtex->norfac;
- if (mtex->maptoneg & MAP_NORM) nf *= -1.f;
- if (tex->type==TEX_IMAGE) nf/=60.f; else nf/=30.f;
- mparams["normal"]=yafray::parameter_t(nf);
- }
-
- // all blender texture modulation as switches, either 1 or -1 (negative state of button)
- // Csp, specular color modulation
- if (mtex->mapto & MAP_COLSPEC)
- mparams["colspec"]=yafray::parameter_t(1.0);
- // CMir, mirror color modulation
- if (mtex->mapto & MAP_COLMIR)
- mparams["colmir"]=yafray::parameter_t(1.0);
-
- // Ref, diffuse reflection amount modulation
- if ((mtex->mapto & MAP_REF) || (mtex->maptoneg & MAP_REF))
- {
- int t = 1;
- if (mtex->maptoneg & MAP_REF) t = -1;
- mparams["difref"]=yafray::parameter_t(t);
- }
-
- // Spec, specular amount mod
- if ((mtex->mapto & MAP_SPEC) || (mtex->maptoneg & MAP_SPEC))
- {
- int t = 1;
- if (mtex->maptoneg & MAP_SPEC) t = -1;
- mparams["specular"]=yafray::parameter_t(t);
- }
-
- // hardness modulation
- if ((mtex->mapto & MAP_HAR) || (mtex->maptoneg & MAP_HAR))
- {
- int t = 1;
- if (mtex->maptoneg & MAP_HAR) t = -1;
- mparams["hard"]=yafray::parameter_t(t);
- }
-
- // alpha modulation
- if ((mtex->mapto & MAP_ALPHA) || (mtex->maptoneg & MAP_ALPHA))
- {
- int t = 1;
- if (mtex->maptoneg & MAP_ALPHA) t = -1;
- mparams["alpha"]=yafray::parameter_t(t);
- }
-
- // emit modulation
- if ((mtex->mapto & MAP_EMIT) || (mtex->maptoneg & MAP_EMIT)) {
- int t = 1;
- if (mtex->maptoneg & MAP_EMIT) t = -1;
- mparams["emit"]=yafray::parameter_t(t);
- }
-
- // texture flag, combination of strings
- if (mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE)) {
- ts = "";
- if (mtex->texflag & MTEX_RGBTOINT) ts += "no_rgb ";
- if (mtex->texflag & MTEX_STENCIL) ts += "stencil ";
- if (mtex->texflag & MTEX_NEGATIVE) ts += "negative";
- mparams["texflag"]=yafray::parameter_t(ts);
- }
+ }
- // colfac, controls amount of color modulation
- mparams["colfac"]=yafray::parameter_t(mtex->colfac);
- // def_var
- mparams["def_var"]=yafray::parameter_t(mtex->def_var);
- //varfac
- mparams["varfac"]=yafray::parameter_t(mtex->varfac);
+ // write the mappers & shaders for the TexFace case
+ if (!imagetex.empty()) {
+ // Yafray doesn't have per-face-textures, only per-face-shaders,
+ // so create as many mappers/shaders as the images used by the object
+ params.clear();
+ lparams.clear();
+ int snum = 0;
+ for (map<Image*, Material*>::const_iterator imgtex=imagetex.begin();
+ imgtex!=imagetex.end();++imgtex)
+ {
+ Material* matr = imgtex->second;
+
+ // mapper
+ params["type"] = yafray::parameter_t("blendermapper");
+ char temp[32];
+ sprintf(temp, "_ftex_mp%d", snum);
+ params["name"] = yafray::parameter_t(string(matr->id.name) + string(temp));
+ params["input"] = yafray::parameter_t(imgtex->first->id.name);
+ // all yafray default settings, except for texco, so no need to set others
+ params["texco"] = yafray::parameter_t("uv");
+ yafrayGate->addShader(params, lparams);
+
+ // shader, remember name, used later when writing per-face-shaders
+ sprintf(temp, "_ftex_sh%d", snum);
+ string shader_name = string(matr->id.name) + string(temp);
+ imgtex_shader[imgtex->first] = shader_name;
+
+ sprintf(temp, "_ftex_mp%d", snum++);
+ string facetexname = string(matr->id.name) + string(temp);
+ writeShader(shader_name, matr, facetexname);
- if ((tex->imaflag & (TEX_CALCALPHA | TEX_USEALPHA)) || (tex->flag & TEX_NEGALPHA))
- {
- ts = "";
- if (tex->imaflag & TEX_CALCALPHA) ts += "calc_alpha ";
- if (tex->imaflag & TEX_USEALPHA) ts += "use_alpha ";
- if (tex->flag & TEX_NEGALPHA) ts += "neg_alpha";
- mparams["alpha_flag"]=yafray::parameter_t(ts);
- }
- lparams.push_back(mparams);
- }
}
- yafrayGate->addShader(params,lparams);
}
+
}
-void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords,VlakRen *vlr,TFace* uvc)
+void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, VlakRen *vlr, TFace* uvc, bool comple)
{
if (uvc)
{
- // use correct uv coords for this triangle
- if (vlr->flag & R_FACE_SPLIT)
- {
- uvcoords.push_back(uvc->uv[0][0]);uvcoords.push_back(1-uvc->uv[0][1]);
- uvcoords.push_back(uvc->uv[2][0]);uvcoords.push_back(1-uvc->uv[2][1]);
- uvcoords.push_back(uvc->uv[3][0]);uvcoords.push_back(1-uvc->uv[3][1]);
+ // use correct uv coords for this triangle
+ int ui1=0, ui2=1, ui3=2;
+ if (vlr->flag & R_DIVIDE_24) {
+ ui3++;
+ if (vlr->flag & R_FACE_SPLIT) { ui1++; ui2++; }
}
- else
- {
- uvcoords.push_back(uvc->uv[0][0]);uvcoords.push_back(1-uvc->uv[0][1]);
- uvcoords.push_back(uvc->uv[1][0]);uvcoords.push_back(1-uvc->uv[1][1]);
- uvcoords.push_back(uvc->uv[2][0]);uvcoords.push_back(1-uvc->uv[2][1]);
+ else if (vlr->flag & R_FACE_SPLIT) { ui2++; ui3++; }
+ if (comple) {
+ ui1 = (ui1+2) & 3;
+ ui2 = (ui2+2) & 3;
+ ui3 = (ui3+2) & 3;
}
+ uvcoords.push_back(uvc->uv[ui1][0]); uvcoords.push_back(1-uvc->uv[ui1][1]);
+ uvcoords.push_back(uvc->uv[ui2][0]); uvcoords.push_back(1-uvc->uv[ui2][1]);
+ uvcoords.push_back(uvc->uv[ui3][0]); uvcoords.push_back(1-uvc->uv[ui3][1]);
}
else
{
- uvcoords.push_back(0);uvcoords.push_back(0);
- uvcoords.push_back(0);uvcoords.push_back(0);
- uvcoords.push_back(0);uvcoords.push_back(0);
- }
-}
-
-void yafrayPluginRender_t::genCompleUVcoords(vector<yafray::GFLOAT> &uvcoords,/*VlakRen *vlr,*/TFace* uvc)
-{
- if (uvc)
- {
- // use correct uv coords for this triangle
- uvcoords.push_back(uvc->uv[2][0]);uvcoords.push_back(1-uvc->uv[2][1]);
- uvcoords.push_back(uvc->uv[3][0]);uvcoords.push_back(1-uvc->uv[3][1]);
- uvcoords.push_back(uvc->uv[0][0]);uvcoords.push_back(1-uvc->uv[0][1]);
- }
- else
- {
- uvcoords.push_back(0);uvcoords.push_back(0);
- uvcoords.push_back(0);uvcoords.push_back(0);
- uvcoords.push_back(0);uvcoords.push_back(0);
+ uvcoords.push_back(0); uvcoords.push_back(0);
+ uvcoords.push_back(0); uvcoords.push_back(0);
+ uvcoords.push_back(0); uvcoords.push_back(0);
}
}
void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol,VlakRen *vlr,
- int p1,int p2,int p3,bool EXPORT_VCOL)
+ int p1,int p2,int p3)
{
- if ((EXPORT_VCOL) && (vlr->vcol))
+ if (vlr->vcol)
{
// vertex colors
float vr, vg, vb;
@@ -797,12 +964,20 @@ void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol,VlakRen *vlr,
void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,vector<int> &faceshader,
vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol,
map<VertRen*, int> &vert_idx,VlakRen *vlr,
- bool has_orco,bool has_uv, bool has_vcol)
+ bool has_orco,bool has_uv)
{
Material* fmat = vlr->mat;
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
- string fmatname = fmat->id.name;
- if (fmatname=="") fmatname = "blender_default";
+ string fmatname(fmat->id.name);
+ // use name in imgtex_shader list if 'TexFace' enabled for this face material
+ if (fmat->mode & MA_FACETEXTURE) {
+ TFace* tface = vlr->tface;
+ if (tface) {
+ Image* fimg = (Image*)tface->tpage;
+ if (fimg) fmatname = imgtex_shader[fimg];
+ }
+ }
+ else if (fmatname.length()==0) fmatname = "blender_default";
bool newmat=true;
for(unsigned int i=0;i<shaders.size();++i)
if(shaders[i]==fmatname)
@@ -826,18 +1001,18 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve
// make sure the indices point to the vertices when orco coords exported
if (has_orco) { idx1*=2; idx2*=2; idx3*=2; }
- faces.push_back(idx1);faces.push_back(idx2);faces.push_back(idx3);
+ faces.push_back(idx1); faces.push_back(idx2); faces.push_back(idx3);
if(has_uv) genUVcoords(uvcoords,vlr,uvc);
// since Blender seems to need vcols when uvs are used, for yafray only export when the material actually uses vcols
- if (has_vcol) genVcol(vcol,vlr,0,1,2,EXPORT_VCOL);
+ if (EXPORT_VCOL) genVcol(vcol, vlr, 0, 1, 2);
}
void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &shaders,*/vector<int> &faceshader,
vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol,
map<VertRen*, int> &vert_idx,VlakRen *vlr,
- bool has_orco,bool has_uv, bool has_vcol)
+ bool has_orco,bool has_uv)
{
Material* fmat = vlr->mat;
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
@@ -852,10 +1027,10 @@ void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &sh
// make sure the indices point to the vertices when orco coords exported
if (has_orco) { idx1*=2; idx2*=2; idx3*=2; }
- faces.push_back(idx1);faces.push_back(idx2);faces.push_back(idx3);
+ faces.push_back(idx1); faces.push_back(idx2); faces.push_back(idx3);
- if(has_uv) genCompleUVcoords(uvcoords,/*vlr,*/uvc);
- if (has_vcol) genVcol(vcol,vlr,2,3,0,EXPORT_VCOL);
+ if (has_uv) genUVcoords(uvcoords, vlr, uvc, true);
+ if (EXPORT_VCOL) genVcol(vcol, vlr, 2, 3, 0);
}
void yafrayPluginRender_t::genVertices(vector<yafray::point3d_t> &verts, int &vidx,
@@ -913,19 +1088,22 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
mtr[2*4+0]=obmat[0][2]; mtr[2*4+1]=obmat[1][2]; mtr[2*4+2]=obmat[2][2]; mtr[2*4+3]=obmat[3][2];
mtr[3*4+0]=obmat[0][3]; mtr[3*4+1]=obmat[1][3]; mtr[3*4+2]=obmat[2][3]; mtr[3*4+3]=obmat[3][3];
yafrayGate->transformPush(mtr);
- string name=string(obj->id.name+2);
- bool castShadows=VLR_list[0]->mat->mode & MA_TRACEBLE;
+
+ VlakRen* face0 = VLR_list[0];
+ Material* face0mat = face0->mat;
+
+ bool castShadows = face0mat->mode & MA_TRACEBLE;
float caus_IOR=1.0;
- yafray::color_t caus_tcolor(0.0,0.0,0.0),caus_rcolor(0.0,0.0,0.0);
- bool caus = (((VLR_list[0]->mat->mode & MA_RAYTRANSP) | (VLR_list[0]->mat->mode & MA_RAYMIRROR))!=0);
+ yafray::color_t caus_tcolor(0.0, 0.0, 0.0), caus_rcolor(0.0, 0.0, 0.0);
+ bool caus = (((face0->mat->mode & MA_RAYTRANSP) | (face0->mat->mode & MA_RAYMIRROR))!=0);
if (caus) {
- caus_IOR = VLR_list[0]->mat->ang;
- float tr = 1.0-VLR_list[0]->mat->alpha;
- caus_tcolor.set(VLR_list[0]->mat->r*tr, VLR_list[0]->mat->g*tr, VLR_list[0]->mat->b*tr);
- tr = VLR_list[0]->mat->ray_mirror;
- caus_rcolor.set(VLR_list[0]->mat->mirr*tr, VLR_list[0]->mat->mirg*tr, VLR_list[0]->mat->mirb*tr);
+ caus_IOR = face0mat->ang;
+ float tr = 1.0-face0mat->alpha;
+ caus_tcolor.set(face0mat->r*tr, face0mat->g*tr, face0mat->b*tr);
+ tr = face0mat->ray_mirror;
+ caus_rcolor.set(face0mat->mirr*tr, face0mat->mirg*tr, face0mat->mirb*tr);
}
- bool has_orco = (VLR_list[0]->v1->orco!=NULL);
+ bool has_orco = (face0->v1->orco!=NULL);
bool no_auto = true; //in case non-mesh, or mesh has no autosmooth
float sm_angle = 0.1f;
if (obj->type==OB_MESH)
@@ -940,12 +1118,8 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
if (no_auto) {
// no per face smooth flag in yafray, if AutoSmooth not used,
// use smooth flag of the first face instead
- if (VLR_list[0]->flag & ME_SMOOTH) sm_angle=90;
+ if (face0->flag & ME_SMOOTH) sm_angle=90;
}
- // Guess if we need to set vertex colors Could be faster? sure
- bool has_vcol=false;
- if ((obj->type==OB_MESH) && (obj->data!=NULL))
- has_vcol = (((Mesh*)obj->data)->mcol!=NULL);
vector<yafray::point3d_t> verts;
vector<yafray::CFLOAT> vcol;
// now all vertices
@@ -968,14 +1142,14 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
fci2!=VLR_list.end();++fci2)
{
VlakRen* vlr = *fci2;
- genFace(faces, shaders, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv, has_vcol);
+ genFace(faces, shaders, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv);
if (vlr->v4)
- genCompleFace(faces, /*shaders,*/ faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv, has_vcol);
+ genCompleFace(faces, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv);
}
- yafrayGate->addObject_trimesh(name,verts,faces,uvcoords,vcol,
- shaders,faceshader,sm_angle,castShadows,true,true,caus,has_orco,
- caus_rcolor,caus_tcolor,caus_IOR);
+ yafrayGate->addObject_trimesh(string(obj->id.name), verts, faces, uvcoords, vcol,
+ shaders, faceshader, sm_angle, castShadows, true, true, caus, has_orco,
+ caus_rcolor, caus_tcolor, caus_IOR);
yafrayGate->transformPop();
}
@@ -1029,11 +1203,11 @@ void yafrayPluginRender_t::writeAllObjects()
yafrayGate->transformPush(mtr);
// new name from original
- string name=(obj->id.name+2);
+ string name=(obj->id.name);
char temp[16];
sprintf(temp,"_dup%d",(curmtx>>4));
name+=temp;
- yafrayGate->addObject_reference(name,obj->id.name+2);
+ yafrayGate->addObject_reference(name,obj->id.name);
yafrayGate->transformPop();
}
@@ -1159,9 +1333,13 @@ void yafrayPluginRender_t::writeLamps()
// cast_shadows flag not used with softlight, spherelight or photonlight
if ((!is_softL) && (!is_sphereL) && (lamp->type!=LA_YF_PHOTON)) {
string lpmode="off";
- // shadows only when Blender has shadow button enabled, only spots use LA_SHAD flag
- if (R.r.mode & R_SHADOW)
- if (((lamp->type==LA_SPOT) && (lamp->mode & LA_SHAD)) || (lamp->mode & LA_SHAD_RAY)) lpmode="on";
+ // Shadows only when Blender has shadow button enabled, only spots use LA_SHAD flag.
+ // Also blender hemilights exported as sunlights which might have shadow flag set
+ // should have cast_shadows set to off (reported by varuag)
+ if (lamp->type!=LA_HEMI) {
+ if (R.r.mode & R_SHADOW)
+ if (((lamp->type==LA_SPOT) && (lamp->mode & LA_SHAD)) || (lamp->mode & LA_SHAD_RAY)) lpmode="on";
+ }
params["cast_shadows"] = yafray::parameter_t(lpmode);
}
@@ -1289,9 +1467,9 @@ void yafrayPluginRender_t::writeCamera()
void yafrayPluginRender_t::writeHemilight()
{
yafray::paramMap_t params;
- params["type"]=yafray::parameter_t("hemilight");
- params["name"]=yafray::parameter_t("hemi_LT");
- params["power"]=yafray::parameter_t(1.0);
+ params["type"] = yafray::parameter_t("hemilight");
+ params["name"] = yafray::parameter_t("hemi_LT");
+ params["power"] = yafray::parameter_t(R.r.GIpower);
switch (R.r.GIquality)
{
case 1 :
@@ -1321,7 +1499,7 @@ void yafrayPluginRender_t::writePathlight()
yafray::paramMap_t params;
params["type"]=yafray::parameter_t("pathlight");
params["name"]=yafray::parameter_t("path_LT");
- params["power"]=yafray::parameter_t(1.0);
+ params["power"]=yafray::parameter_t(R.r.GIindirpower);
params["depth"]=yafray::parameter_t(((R.r.GIphotons) ? 1 : R.r.GIdepth));
params["caus_depth"]=yafray::parameter_t(R.r.GIcausdepth);
if(R.r.GIdirect && R.r.GIphotons) params["direct"]=yafray::parameter_t("on");
@@ -1338,7 +1516,6 @@ void yafrayPluginRender_t::writePathlight()
}
float aspect = 1;
if (R.r.xsch < R.r.ysch) aspect = float(R.r.xsch)/float(R.r.ysch);
- //float sbase = 2.0*atan(0.5/(mainCamLens/(aspect*32.0)))/float(R.r.xsch);
float sbase = 2.0/float(R.r.xsch);
params["cache"]=yafray::parameter_t("on");
params["use_QMC"]=yafray::parameter_t("on");
@@ -1347,7 +1524,6 @@ void yafrayPluginRender_t::writePathlight()
params["shadow_threshold"]=yafray::parameter_t(1.0 - R.r.GIshadowquality);
params["grid"]=yafray::parameter_t(82);
params["search"]=yafray::parameter_t(35);
- //params["gradient"]=yafray::parameter_t("off");
}
else
{
@@ -1418,8 +1594,7 @@ bool yafrayPluginRender_t::writeWorld()
params["name"] = yafray::parameter_t("world_background");
// if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
// (have to change method to init yafray vars in Blender)
- float bg_mult;
- if (R.r.GImethod==0) bg_mult=1; else bg_mult=R.r.GIpower;
+ float bg_mult = (R.r.GImethod==0) ? 1 : R.r.GIpower;
params["color"]=yafray::parameter_t(yafray::color_t(world->horr * bg_mult,
world->horg * bg_mult,
world->horb * bg_mult));
diff --git a/source/blender/yafray/intern/export_Plugin.h b/source/blender/yafray/intern/export_Plugin.h
index c7adab723a6..d2d9128d824 100644
--- a/source/blender/yafray/intern/export_Plugin.h
+++ b/source/blender/yafray/intern/export_Plugin.h
@@ -31,11 +31,12 @@ class yafrayPluginRender_t : public yafrayRender_t
void displayImage();
virtual void writeTextures();
+ virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname="");
virtual void writeMaterialsAndModulators();
virtual void writeObject(Object* obj,
const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
virtual void writeAllObjects();
- void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
+ virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
virtual void writeLamps();
virtual void writeCamera();
virtual void writeHemilight();
@@ -45,18 +46,17 @@ class yafrayPluginRender_t : public yafrayRender_t
virtual bool initExport();
virtual bool finishExport();
- void genUVcoords(std::vector<yafray::GFLOAT> &uvcoords,VlakRen *vlr,TFace* uvc);
- void genCompleUVcoords(std::vector<yafray::GFLOAT> &uvcoords,/*VlakRen *vlr,*/TFace* uvc);
+ void genUVcoords(std::vector<yafray::GFLOAT> &uvcoords,VlakRen *vlr,TFace* uvc, bool comple=false);
void genVcol(std::vector<yafray::CFLOAT> &vcol,VlakRen *vlr,
- int p1,int p2,int p3,bool EXPORT_VCOL);
+ int p1,int p2,int p3);
void genFace(std::vector<int> &faces,std::vector<std::string> &shaders,std::vector<int> &faceshader,
std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol,
std::map<VertRen*, int> &vert_idx,VlakRen *vlr,
- bool has_orco,bool has_uv, bool has_vcol);
+ bool has_orco,bool has_uv);
void genCompleFace(std::vector<int> &faces,/*std::vector<std::string> &shaders,*/std::vector<int> &faceshader,
std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol,
std::map<VertRen*, int> &vert_idx,VlakRen *vlr,
- bool has_orco,bool has_uv, bool has_vcol);
+ bool has_orco,bool has_uv);
void genVertices(std::vector<yafray::point3d_t> &verts, int &vidx,
std::map<VertRen*, int> &vert_idx, VlakRen* vlr, bool has_orco, Object* obj);
};
diff --git a/source/blender/yafray/intern/yafray_Render.cpp b/source/blender/yafray/intern/yafray_Render.cpp
index 461e5d5dfe5..bbb5855b964 100644
--- a/source/blender/yafray/intern/yafray_Render.cpp
+++ b/source/blender/yafray/intern/yafray_Render.cpp
@@ -18,6 +18,8 @@ void yafrayRender_t::clearAll()
dupliMtx_list.clear();
dup_srcob.clear();
objectData.clear();
+ imagetex.clear();
+ imgtex_shader.clear();
}
bool yafrayRender_t::exportScene()
@@ -102,8 +104,7 @@ bool yafrayRender_t::getAllMatTexObs()
if (strlen(matr->id.name)==0)
used_materials["blender_default"] = matr;
else
- used_materials[matr->id.name] = matr; // <-- full name to avoid name collision in yafray
- //used_materials[matr->id.name+2] = matr; // skip 'MA' id
+ used_materials[matr->id.name] = matr;
// textures, all active channels
for (int m=0;m<8;m++) {
if (matr->septex & (1<<m)) continue; // only active channels
@@ -115,26 +116,36 @@ bool yafrayRender_t::getAllMatTexObs()
if (tx==NULL) continue;
short txtp = tx->type;
// if texture type not available in yafray, ignore
- if ((txtp!=TEX_STUCCI) &&
- (txtp!=TEX_CLOUDS) &&
- (txtp!=TEX_WOOD) &&
- (txtp!=TEX_MARBLE) &&
- (txtp!=TEX_IMAGE)) continue;
- // in the case of an image texture, check that there is an actual image, otherwise ignore
- if ((txtp & TEX_IMAGE) && (!tx->ima)) continue;
- used_textures[tx->id.name] = make_pair(matr, mx); // <-- full name to avoid name collision in yafray
- //used_textures[tx->id.name+2] = make_pair(matr, mx);
+ if ((txtp==0) ||
+ (txtp==TEX_MAGIC) ||
+ (txtp==TEX_BLEND) ||
+ (txtp==TEX_NOISE) ||
+ (txtp==TEX_PLUGIN) ||
+ (txtp==TEX_ENVMAP)) continue;
+ // In the case of an image texture, check that there is an actual image, otherwise ignore.
+ // Stupid error was here (...if (txtp & TEX_IMAGE)...),
+ // which happened to work sofar, but not anymore with the extended texture support..
+ if ((txtp==TEX_IMAGE) && (!tx->ima)) continue;
+ used_textures[tx->id.name] = mx;
}
}
- // make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later
- // make sure null object pointers are ignored
+ // Make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later.
+ // ignore null object pointers.
+ // Also make list of facetexture images (material 'TexFace').
if (vlr->ob) {
int nv = 0; // number of vertices
if (vlr->v4) nv=4; else if (vlr->v3) nv=3;
if (nv) all_objects[vlr->ob].push_back(vlr);
+ if (vlr->tface) {
+ Image* fc_img = (Image*)vlr->tface->tpage;
+ if (fc_img) {
+ Material* fmat = vlr->mat;
+ // only save if TexFace enabled
+ if (fmat && (fmat->mode & MA_FACETEXTURE)) imagetex[fc_img] = fmat;
+ }
+ }
}
- //else cout << "WARNING: VlakRen struct with null obj.ptr!\n";
}
@@ -167,7 +178,7 @@ void yafrayRender_t::addDupliMtx(Object* obj)
{
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
- dupliMtx_list[string(obj->id.name)].push_back(obj->obmat[i][j]);
+ dupliMtx_list[obj->id.name].push_back(obj->obmat[i][j]);
}
@@ -184,7 +195,7 @@ bool yafrayRender_t::objectKnownData(Object* obj)
// then save matrix of linked object in dupliMtx_list, using name of ORIGINAL object
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
- dupliMtx_list[string(orgob->id.name)].push_back(obj->obmat[i][j]);
+ dupliMtx_list[orgob->id.name].push_back(obj->obmat[i][j]);
return true;
}
// object not known yet
diff --git a/source/blender/yafray/intern/yafray_Render.h b/source/blender/yafray/intern/yafray_Render.h
index c65dab58615..e5c710c465d 100644
--- a/source/blender/yafray/intern/yafray_Render.h
+++ b/source/blender/yafray/intern/yafray_Render.h
@@ -88,20 +88,24 @@ class yafrayRender_t
std::map<Object*, std::vector<VlakRen*> > all_objects;
std::map<std::string, Material*> used_materials;
- std::map<std::string, std::pair<Material*, MTex*> > used_textures;
+ std::map<std::string, MTex*> used_textures;
std::map<std::string, std::vector<float> > dupliMtx_list;
std::map<std::string, Object*> dup_srcob;
std::map<void*, Object*> objectData;
+ std::map<Image*, Material*> imagetex;
+ std::map<Image*, std::string> imgtex_shader;
Object* findObject(const char* name);
bool getAllMatTexObs();
virtual void writeTextures()=0;
+ virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname)=0;
virtual void writeMaterialsAndModulators()=0;
virtual void writeObject(Object* obj, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4])=0;
virtual void writeAllObjects()=0;
virtual void writeLamps()=0;
virtual void writeCamera()=0;
+ virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4])=0;
virtual void writeHemilight()=0;
virtual void writePathlight()=0;
virtual bool writeWorld()=0;