From f32b8e6b7f2caef90ef83b44864d2499619c4169 Mon Sep 17 00:00:00 2001 From: Alfredo de Greef Date: Mon, 12 Jul 2004 03:20:31 +0000 Subject: added support for ortho camera (needs yafray from cvs) When using xml export, yafray will now render the alpha channel as well when 'RGBA' button in blender is enabled (Plugin does this automatically). In plugin code, fixed smooth shading bug for non-mesh objects. Relative paths for textures are now recognized (plugin & xml). Fixed problem with duplicate objects (plugin & xml). Really old bug, sun position is now correct (plugin & xml). World background now can also be a regular image texture (jpeg & tga), but for now always assumes spheremapping, which is not the same as Blender either. In yafray the texture is assumed to be a full 360 (panorama type) map. convertBlenderScene.c cleanup, the identity transform 'hack' is removed. THIS AFFECTS ALL EXTERNAL RENDERERS (Aqsis and others) WHICH RELY ON THE RENDERDATA OUTPUT, VERTICES AND LAMPCOORDINATES/VECTORS NOW NEED TO BE TRANSFORMED BACK TO WORLD COORDINATES. See yafray plugin/export code. --- source/blender/yafray/intern/export_File.cpp | 244 +++++++++++++++---------- source/blender/yafray/intern/export_File.h | 2 +- source/blender/yafray/intern/export_Plugin.cpp | 230 ++++++++++++++--------- source/blender/yafray/intern/export_Plugin.h | 6 +- source/blender/yafray/intern/yafray_Render.cpp | 13 +- 5 files changed, 300 insertions(+), 195 deletions(-) (limited to 'source/blender/yafray') diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp index fa4f6a69c71..4067683d891 100755 --- a/source/blender/yafray/intern/export_File.cpp +++ b/source/blender/yafray/intern/export_File.cpp @@ -204,11 +204,9 @@ bool yafrayFileRender_t::writeRender() ostr << "world!=NULL) && (G.scene->world->GIquality>1) && ! G.scene->world->cache ) - if(R.r.YF_AA){ + if(R.r.YF_AA) ostr << "\tAA_passes=\"" << R.r.YF_AApasses << "\" AA_minsamples=\"" << R.r.YF_AAsamples << "\""; - } - else{ + else { if ((R.r.GImethod!=0) && (R.r.GIquality>1) && (!R.r.GIcache)) ostr << "\tAA_passes=\"5\" AA_minsamples=\"5\" " << endl; else if ((R.r.mode & R_OSA) && (R.r.osa)) { @@ -222,7 +220,11 @@ bool yafrayFileRender_t::writeRender() if (hasworld) ostr << "\tbackground_name=\"world_background\"\n"; - ostr << "\tAA_pixelwidth=\"2\" AA_threshold=\"0.05\" bias=\""<\n"; + ostr << "\tAA_pixelwidth=\"2\" AA_threshold=\"0.05\" bias=\"" << R.r.YF_raybias << "\""; + + // alpha channel render when RGBA button enabled + if (R.r.planes==R_PLANES32) ostr << "\n\tsave_alpha=\"on\""; + ostr << " >\n"; ostr << "\t\n"; @@ -292,6 +294,25 @@ void yafrayFileRender_t::displayImage() } +static void adjustPath(string &path) +{ + // if relative, expand to full path + if ((path[0]=='/') && (path[1]=='/')) { + string basepath = G.sce; + // fwd slash valid for win32 as well + int ls = basepath.find_last_of("/"); +#ifdef WIN32 + if (ls==-1) ls = basepath.find_last_of("\\"); +#endif + path = basepath.substr(0, ls) + path.substr(1, path.length()); + } +#ifdef WIN32 + // add drive char if not there + addDrive(path); +#endif +} + + void yafrayFileRender_t::writeTextures() { for (map >::const_iterator blendtex=used_textures.begin(); @@ -352,12 +373,8 @@ void yafrayFileRender_t::writeTextures() ostr.str(""); ostr << "first << "\" >\n"; ostr << "\t\n"; - // image->name is full path string texpath = ima->name; -#ifdef WIN32 - // add drive char if not there - addDrive(texpath); -#endif + adjustPath(texpath); ostr << "\t\t\n"; ostr << "\t\n"; ostr << "\n\n"; @@ -760,7 +777,6 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector &VLR_li bool no_auto = true; //in case non-mesh, or mesh has no autosmooth if (obj->type==OB_MESH) { Mesh* mesh = (Mesh*)obj->data; - if (mesh->flag & ME_AUTOSMOOTH) { no_auto = false; ostr.str(""); @@ -783,6 +799,7 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector &VLR_li map vert_idx; // for removing duplicate verts and creating an index list int vidx = 0; // vertex index counter + // vertices, transformed back to world xmlfile << "\t\t\n"; for (vector::const_iterator fci=VLR_list.begin(); fci!=VLR_list.end();++fci) @@ -790,13 +807,16 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector &VLR_li VlakRen* vlr = *fci; VertRen* ver; float* orco; + float tvec[3]; ostr.str(""); if (vert_idx.find(vlr->v1)==vert_idx.end()) { vert_idx[vlr->v1] = vidx++; ver = vlr->v1; - ostr << "\t\t\t

co[0] - << "\" y=\"" << ver->co[1] - << "\" z=\"" << ver->co[2] << "\" />\n"; + MTC_cp3Float(ver->co, tvec); + MTC_Mat4MulVecfl(obj->imat, tvec); + ostr << "\t\t\t

\n"; if (EXPORT_ORCO) { orco = ver->orco; ostr << "\t\t\t

&VLR_li if (vert_idx.find(vlr->v2)==vert_idx.end()) { vert_idx[vlr->v2] = vidx++; ver = vlr->v2; - ostr << "\t\t\t

co[0] - << "\" y=\"" << ver->co[1] - << "\" z=\"" << ver->co[2] << "\" />\n"; + MTC_cp3Float(ver->co, tvec); + MTC_Mat4MulVecfl(obj->imat, tvec); + ostr << "\t\t\t

\n"; if (EXPORT_ORCO) { orco = ver->orco; ostr << "\t\t\t

&VLR_li if (vert_idx.find(vlr->v3)==vert_idx.end()) { vert_idx[vlr->v3] = vidx++; ver = vlr->v3; - ostr << "\t\t\t

co[0] - << "\" y=\"" << ver->co[1] - << "\" z=\"" << ver->co[2] << "\" />\n"; + MTC_cp3Float(ver->co, tvec); + MTC_Mat4MulVecfl(obj->imat, tvec); + ostr << "\t\t\t

\n"; if (EXPORT_ORCO) { orco = ver->orco; ostr << "\t\t\t

&VLR_li if ((vlr->v4) && (vert_idx.find(vlr->v4)==vert_idx.end())) { vert_idx[vlr->v4] = vidx++; ver = vlr->v4; - ostr << "\t\t\t

co[0] - << "\" y=\"" << ver->co[1] - << "\" z=\"" << ver->co[2] << "\" />\n"; + MTC_cp3Float(ver->co, tvec); + MTC_Mat4MulVecfl(obj->imat, tvec); + ostr << "\t\t\t

\n"; if (EXPORT_ORCO) { orco = ver->orco; ostr << "\t\t\t

first; if (dupliMtx_list.find(string(obj->id.name))!=dupliMtx_list.end()) continue; - writeObject(obj, obi->second, obi->first->obmat); + writeObject(obj, obi->second, obj->obmat); } // Now all duplivert objects (if any) as instances of main object @@ -967,9 +993,11 @@ void yafrayFileRender_t::writeAllObjects() dupMtx!=dupliMtx_list.end();++dupMtx) { // original inverse matrix, not actual matrix of object, but first duplivert. + for (int i=0;i<4;i++) for (int j=0;j<4;j++) obmat[i][j] = dupMtx->second[(i<<2)+j]; + MTC_Mat4Invert(imat, obmat); // first object written as normal (but with transform of first duplivert) @@ -1010,7 +1038,7 @@ void yafrayFileRender_t::writeAllObjects() } -void yafrayFileRender_t::writeAreaLamp(LampRen* lamp, int num) +void yafrayFileRender_t::writeAreaLamp(LampRen* lamp, int num, float iview[4][4]) { if (lamp->area_shape!=LA_AREA_SQUARE) return; float *a=lamp->area[0], *b=lamp->area[1], *c=lamp->area[2], *d=lamp->area[3]; @@ -1026,10 +1054,22 @@ void yafrayFileRender_t::writeAreaLamp(LampRen* lamp, int num) ostr << "samples=\"" << sm << "\" psamples=\"" << psm << "\" "; } ostr << ">\n"; - ostr << "\t\n"; - ostr << "\t\n"; - ostr << "\t\n"; - ostr << "\t\n"; + + // transform area lamp coords back to world + float lpco[4][3]; + MTC_cp3Float(a, lpco[0]); + MTC_Mat4MulVecfl(iview, lpco[0]); + MTC_cp3Float(b, lpco[1]); + MTC_Mat4MulVecfl(iview, lpco[1]); + MTC_cp3Float(c, lpco[2]); + MTC_Mat4MulVecfl(iview, lpco[2]); + MTC_cp3Float(d, lpco[3]); + MTC_Mat4MulVecfl(iview, lpco[3]); + ostr << "\t\n"; + ostr << "\t\n"; + ostr << "\t\n"; + ostr << "\t\n"; + ostr << "\tr << "\" g=\"" << lamp->g << "\" b=\"" << lamp->b << "\" />\n"; ostr << "\n\n"; xmlfile << ostr.str(); @@ -1037,12 +1077,18 @@ void yafrayFileRender_t::writeAreaLamp(LampRen* lamp, int num) void yafrayFileRender_t::writeLamps() { + // inver viewmatrix needed for back2world transform + float iview[4][4]; + // R.viewinv != inv.R.viewmat because of possible ortho mode (see convertBlenderScene.c) + // have to invert it here + MTC_Mat4Invert(iview, R.viewmat); + // all lamps for (int i=0;itype==LA_AREA) { writeAreaLamp(lamp, i); continue; } + if (lamp->type==LA_AREA) { writeAreaLamp(lamp, i, iview); continue; } // TODO: add decay setting in yafray ostr << "type==LA_LOCAL) @@ -1069,7 +1115,7 @@ void yafrayFileRender_t::writeLamps() pwr = lamp->dist; //decay = 1; } - else pwr = 1; // sun/hemi distance irrelevent. + else pwr = 1; // sun/hemi distance irrelevant } ostr << "\" power=\"" << pwr; string lpmode="off"; @@ -1087,14 +1133,26 @@ void yafrayFileRender_t::writeLamps() << " beam_falloff=\"2\""; // no Blender equivalent (yet) } ostr << " >\n"; - // position - ostr << "\tco[0] << "\" y=\"" << lamp->co[1] << "\" z=\"" << lamp->co[2] << "\" />\n"; + + // transform lamp co & vec back to world + float lpco[3], lpvec[4]; + MTC_cp3Float(lamp->co, lpco); + MTC_Mat4MulVecfl(iview, lpco); + MTC_cp3Float(lamp->vec, lpvec); + lpvec[3] = 0; // vec, not point + MTC_Mat4MulVec4fl(iview, lpvec); + + // position, (==-blendir for sun/hemi) + if ((lamp->type==LA_SUN) || (lamp->type==LA_HEMI)) + ostr << "\t\n"; + else + ostr << "\t\n"; // 'to' for spot, already calculated by Blender if (lamp->type==LA_SPOT) - ostr << "\tco[0]+lamp->vec[0] - << "\" y=\"" << lamp->co[1]+lamp->vec[1] - << "\" z=\"" << lamp->co[2]+lamp->vec[2] - << "\" />\n"; + ostr << "\t\n"; + // color // rgb in LampRen is premultiplied by energy, power is compensated for that above ostr << "\tr << "\" g=\"" << lamp->g << "\" b=\"" << lamp->b << "\" />\n"; @@ -1109,7 +1167,11 @@ void yafrayFileRender_t::writeCamera() { // here Global used again ostr.str(""); - ostr << "\n"; xmlfile << ostr.str(); - // from, to, up vectors - // comment in MTC_matrixops.h not correct, copy is arg2->arg1 - float camtx[4][4]; - MTC_Mat4CpyMat4(camtx, maincam_obj->obmat); - MTC_normalise3DF(camtx[1]); //up - MTC_normalise3DF(camtx[2]); //dir ostr.str(""); - ostr << "\t\n"; - Object* dofob = findObject("OBFOCUS"); - if (dofob) { - // dof empty found, modify lookat point accordingly - // location from matrix, in case animated - float fdx = dofob->obmat[3][0] - camtx[3][0]; - float fdy = dofob->obmat[3][1] - camtx[3][1]; - float fdz = dofob->obmat[3][2] - camtx[3][2]; - float fdist = sqrt(fdx*fdx + fdy*fdy + fdz*fdz); - cout << "FOCUS object found, distance is: " << fdist << endl; - ostr << "\t\n"; - } - else { - ostr << "\t\n"; - } - ostr << "\t\n"; + ostr << "\tobmat[3][0] << "\"" + << " y=\"" << maincam_obj->obmat[3][1] << "\"" + << " z=\"" << maincam_obj->obmat[3][2] << "\" />\n"; + float fdist = -R.viewmat[3][2]; + if (R.r.mode & R_ORTHO) fdist *= 0.01f; + ostr << "\tobmat[3][0] - fdist * R.viewmat[0][2] + << "\" y=\"" << maincam_obj->obmat[3][1] - fdist * R.viewmat[1][2] + << "\" z=\"" << maincam_obj->obmat[3][2] - fdist * R.viewmat[2][2] << "\" />\n"; + ostr << "\tobmat[3][0] + R.viewmat[0][1] + << "\" y=\"" << maincam_obj->obmat[3][1] + R.viewmat[1][1] + << "\" z=\"" << maincam_obj->obmat[3][2] + R.viewmat[2][1] << "\" />\n"; + // add dof_distance param here xmlfile << ostr.str(); + xmlfile << "\n\n"; } @@ -1226,7 +1271,6 @@ void yafrayFileRender_t::writePathlight() bool yafrayFileRender_t::writeWorld() { World *world = G.scene->world; - short i=0,j=0; if (R.r.GIquality!=0) { if (R.r.GImethod==1) { if (world==NULL) cout << "WARNING: need world background for skydome!\n"; @@ -1237,35 +1281,36 @@ bool yafrayFileRender_t::writeWorld() if (world==NULL) return false; - for(i=0;i<8;i++){ - if(world->mtex[i] != NULL){ - if(world->mtex[i]->tex->type == TEX_IMAGE && world->mtex[i]->tex->ima != NULL){ - - for(j=0;j<160;j++){ - if(world->mtex[i]->tex->ima->name[j] == '\0' && j > 3){ - if( - (world->mtex[i]->tex->ima->name[j-3] == 'h' || world->mtex[i]->tex->ima->name[j-3] == 'H' ) && - (world->mtex[i]->tex->ima->name[j-2] == 'd' || world->mtex[i]->tex->ima->name[j-2] == 'D' ) && - (world->mtex[i]->tex->ima->name[j-1] == 'r' || world->mtex[i]->tex->ima->name[j-1] == 'R' ) - ){ - ostr.str(""); - ostr << "mtex[i]->tex->bright-1) << "\""; - ostr << " mapping = \"probe\" "; - ostr << ">\n"; - ostr << "mtex[i]->tex->ima->name << "\"/>\n"; - ostr << "\n\n"; - xmlfile << ostr.str(); - return true; - } - } - } - + for (int i=0;i<6;i++) { + MTex* wtex = world->mtex[i]; + if (!wtex) continue; + Image* wimg = wtex->tex->ima; + if ((wtex->tex->type==TEX_IMAGE) && (wimg!=NULL)) { + string wt_path = wimg->name; + adjustPath(wt_path); + if (BLI_testextensie(wimg->name, ".hdr")) { ostr.str(""); - ostr << "mtex[i]->tex->bright << "\">\n"; - ostr << "mtex[i]->tex->ima->name << "\"/>\n"; + ostr << "mtex[i]->tex->bright-1) << "\" mapping=\"probe\" >\n"; + ostr << "\t\n"; + ostr << "\n\n"; + xmlfile << ostr.str(); + return true; + } + else if (BLI_testextensie(wimg->name, ".jpg") || BLI_testextensie(wimg->name, ".jpeg") || BLI_testextensie(wimg->name, ".tga")) { + ostr.str(""); + ostr << "\n"; + /* + // not yet in yafray, always assumes spheremap for now, not the same as in Blender, + // which for some reason is scaled by 2 in Blender??? + if (wtex->texco & TEXCO_ANGMAP) + ostr << " mapping=\"probe\" >\n"; + else + ostr << " mapping=\"sphere\" >\n"; + */ + ostr << "\t\n"; ostr << "\n\n"; xmlfile << ostr.str(); return true; @@ -1275,7 +1320,8 @@ bool yafrayFileRender_t::writeWorld() ostr.str(""); ostr << "\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) + // 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; ostr << "\thorr * bg_mult) << @@ -1321,5 +1367,3 @@ bool yafrayFileRender_t::executeYafray(const string &xmlpath) #endif } - - diff --git a/source/blender/yafray/intern/export_File.h b/source/blender/yafray/intern/export_File.h index 144dc35752e..c9d650f578f 100755 --- a/source/blender/yafray/intern/export_File.h +++ b/source/blender/yafray/intern/export_File.h @@ -20,7 +20,7 @@ class yafrayFileRender_t : public yafrayRender_t virtual void writeObject(Object* obj, const std::vector &VLR_list, const float obmat[4][4]); virtual void writeAllObjects(); - void writeAreaLamp(LampRen* lamp,int num); + 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 02f7203e483..aaef91d198e 100644 --- a/source/blender/yafray/intern/export_Plugin.cpp +++ b/source/blender/yafray/intern/export_Plugin.cpp @@ -296,6 +296,25 @@ void yafrayPluginRender_t::displayImage() } +static void adjustPath(string &path) +{ + // if relative, expand to full path + if ((path[0]=='/') && (path[1]=='/')) { + string basepath = G.sce; + // fwd slash valid for win32 as well + int ls = basepath.find_last_of("/"); +#ifdef WIN32 + if (ls==-1) ls = basepath.find_last_of("\\"); +#endif + path = basepath.substr(0, ls) + path.substr(1, path.length()); + } +#ifdef WIN32 + // add drive char if not there + addDrive(path); +#endif +} + + void yafrayPluginRender_t::writeTextures() { for (map >::const_iterator blendtex=used_textures.begin(); @@ -347,13 +366,9 @@ void yafrayPluginRender_t::writeTextures() Image* ima = tex->ima; if (ima) { params["type"]=yafray::parameter_t("image"); - // image->name is full path string texpath = ima->name; -#ifdef WIN32 - // add drive char if not there - addDrive(texpath); -#endif - params["filename"]=yafray::parameter_t(texpath); + adjustPath(texpath); + params["filename"] = yafray::parameter_t(texpath); } break; } @@ -839,15 +854,18 @@ void yafrayPluginRender_t::genCompleFace(vector &faces,/*vector &sh if(has_vcol) genVcol(vcol,vlr,2,3,0,EXPORT_VCOL); } -void yafrayPluginRender_t::genVertices(vector &verts,int &vidx, - map &vert_idx,VlakRen* vlr,bool has_orco) +void yafrayPluginRender_t::genVertices(vector &verts, int &vidx, + map &vert_idx, VlakRen* vlr, bool has_orco, Object* obj) { VertRen* ver; + float tvec[3]; // for back2world transform if (vert_idx.find(vlr->v1)==vert_idx.end()) { vert_idx[vlr->v1] = vidx++; ver = vlr->v1; - verts.push_back(yafray::point3d_t(ver->co[0],ver->co[1],ver->co[2])); + MTC_cp3Float(ver->co, tvec); + MTC_Mat4MulVecfl(obj->imat, tvec); + verts.push_back(yafray::point3d_t(tvec[0], tvec[1], tvec[2])); if (has_orco) verts.push_back(yafray::point3d_t(ver->orco[0],ver->orco[1],ver->orco[2])); } @@ -855,7 +873,9 @@ void yafrayPluginRender_t::genVertices(vector &verts,int &vid { vert_idx[vlr->v2] = vidx++; ver = vlr->v2; - verts.push_back(yafray::point3d_t(ver->co[0],ver->co[1],ver->co[2])); + MTC_cp3Float(ver->co, tvec); + MTC_Mat4MulVecfl(obj->imat, tvec); + verts.push_back(yafray::point3d_t(tvec[0], tvec[1], tvec[2])); if (has_orco) verts.push_back(yafray::point3d_t(ver->orco[0],ver->orco[1],ver->orco[2])); } @@ -863,7 +883,9 @@ void yafrayPluginRender_t::genVertices(vector &verts,int &vid { vert_idx[vlr->v3] = vidx++; ver = vlr->v3; - verts.push_back(yafray::point3d_t(ver->co[0],ver->co[1],ver->co[2])); + MTC_cp3Float(ver->co, tvec); + MTC_Mat4MulVecfl(obj->imat, tvec); + verts.push_back(yafray::point3d_t(tvec[0], tvec[1], tvec[2])); if (has_orco) verts.push_back(yafray::point3d_t(ver->orco[0],ver->orco[1],ver->orco[2])); } @@ -871,7 +893,9 @@ void yafrayPluginRender_t::genVertices(vector &verts,int &vid { vert_idx[vlr->v4] = vidx++; ver = vlr->v4; - verts.push_back(yafray::point3d_t(ver->co[0],ver->co[1],ver->co[2])); + MTC_cp3Float(ver->co, tvec); + MTC_Mat4MulVecfl(obj->imat, tvec); + verts.push_back(yafray::point3d_t(tvec[0], tvec[1], tvec[2])); if (has_orco) verts.push_back(yafray::point3d_t(ver->orco[0],ver->orco[1],ver->orco[2])); } @@ -898,14 +922,21 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector &VLR_ caus=true; } bool has_orco=(VLR_list[0]->v1->orco!=NULL); - float sm_angle=0.1f; + bool no_auto = true; //in case non-mesh, or mesh has no autosmooth + float sm_angle = 0.1f; if (obj->type==OB_MESH) { Mesh* mesh = (Mesh*)obj->data; - if (mesh->flag & ME_AUTOSMOOTH) - sm_angle=mesh->smoothresh; - else - if (VLR_list[0]->flag & ME_SMOOTH) sm_angle=90; + if (mesh->flag & ME_AUTOSMOOTH) { + sm_angle = mesh->smoothresh; + no_auto = false; + } + } + // this for non-mesh as well + 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; } // Guess if we need to set vertex colors Could be faster? sure bool has_vcol=false; @@ -925,7 +956,7 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector &VLR_ fci!=VLR_list.end();++fci) { VlakRen* vlr = *fci; - genVertices(verts,vidx,vert_idx,vlr,has_orco); + genVertices(verts, vidx, vert_idx, vlr, has_orco, obj); if(vlr->tface) has_uv=true; } // all faces using the index list created above @@ -960,7 +991,7 @@ void yafrayPluginRender_t::writeAllObjects() // 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, obi->first->obmat); + writeObject(obj, obi->second, obj->obmat); } // Now all duplivert objects (if any) as instances of main object @@ -1010,7 +1041,7 @@ void yafrayPluginRender_t::writeAllObjects() } -void yafrayPluginRender_t::writeAreaLamp(LampRen* lamp, int num) +void yafrayPluginRender_t::writeAreaLamp(LampRen* lamp, int num, float iview[4][4]) { yafray::paramMap_t params; @@ -1033,23 +1064,42 @@ void yafrayPluginRender_t::writeAreaLamp(LampRen* lamp, int num) params["samples"]=yafray::parameter_t(sm); params["psamples"]=yafray::parameter_t(psm); } - params["a"]=yafray::parameter_t(yafray::point3d_t(a[0],a[1],a[2])); - params["b"]=yafray::parameter_t(yafray::point3d_t(b[0],b[1],b[2])); - params["c"]=yafray::parameter_t(yafray::point3d_t(c[0],c[1],c[2])); - params["d"]=yafray::parameter_t(yafray::point3d_t(d[0],d[1],d[2])); + + // transform area lamp coords back to world + float lpco[4][3]; + MTC_Mat4Invert(iview, R.viewmat); + MTC_cp3Float(a, lpco[0]); + MTC_Mat4MulVecfl(iview, lpco[0]); + MTC_cp3Float(b, lpco[1]); + MTC_Mat4MulVecfl(iview, lpco[1]); + MTC_cp3Float(c, lpco[2]); + MTC_Mat4MulVecfl(iview, lpco[2]); + MTC_cp3Float(d, lpco[3]); + MTC_Mat4MulVecfl(iview, lpco[3]); + params["a"] = yafray::parameter_t(yafray::point3d_t(lpco[0][0], lpco[0][1], lpco[0][2])); + params["b"] = yafray::parameter_t(yafray::point3d_t(lpco[1][0], lpco[1][1], lpco[1][2])); + params["c"] = yafray::parameter_t(yafray::point3d_t(lpco[2][0], lpco[2][1], lpco[2][2])); + params["d"] = yafray::parameter_t(yafray::point3d_t(lpco[3][0], lpco[3][1], lpco[3][2])); + params["color"]=yafray::parameter_t(yafray::color_t(lamp->r,lamp->g,lamp->b)); yafrayGate->addLight(params); } void yafrayPluginRender_t::writeLamps() { + // inver viewmatrix needed for back2world transform + float iview[4][4]; + // R.viewinv != inv.R.viewmat because of possible ortho mode (see convertBlenderScene.c) + // have to invert it here + MTC_Mat4Invert(iview, R.viewmat); + // all lamps for (int i=0;itype==LA_AREA) { writeAreaLamp(lamp, i); continue; } + if (lamp->type==LA_AREA) { writeAreaLamp(lamp, i, iview); continue; } // TODO: add decay setting in yafray if (lamp->type==LA_LOCAL) params["type"]=yafray::parameter_t("pointlight"); @@ -1098,13 +1148,25 @@ void yafrayPluginRender_t::writeLamps() params["blend"]=yafray::parameter_t(lamp->spotbl*ld); params["beam_falloff"]=yafray::parameter_t(2.0); } - params["from"]=yafray::parameter_t(yafray::point3d_t(lamp->co[0],lamp->co[1],lamp->co[2])); - // position + + // transform lamp co & vec back to world + float lpco[3], lpvec[4]; + MTC_cp3Float(lamp->co, lpco); + MTC_Mat4MulVecfl(iview, lpco); + MTC_cp3Float(lamp->vec, lpvec); + lpvec[3] = 0; // vec, not point + MTC_Mat4MulVec4fl(iview, lpvec); + + // position, (==-blendir for sun/hemi) + if ((lamp->type==LA_SUN) || (lamp->type==LA_HEMI)) + params["from"] = yafray::parameter_t(yafray::point3d_t(-lpvec[0], -lpvec[1], -lpvec[2])); + else + params["from"] = yafray::parameter_t(yafray::point3d_t(lpco[0], lpco[1], lpco[2])); // 'to' for spot, already calculated by Blender if (lamp->type==LA_SPOT) - params["to"]=yafray::parameter_t(yafray::point3d_t(lamp->co[0]+lamp->vec[0], - lamp->co[1]+lamp->vec[1], - lamp->co[2]+lamp->vec[2])); + params["to"]=yafray::parameter_t(yafray::point3d_t(lpco[0] + lpvec[0], + lpco[1] + lpvec[1], + lpco[2] + lpvec[2])); // color // rgb in LampRen is premultiplied by energy, power is compensated for that above params["color"]=yafray::parameter_t(yafray::color_t(lamp->r,lamp->g,lamp->b)); @@ -1118,37 +1180,29 @@ void yafrayPluginRender_t::writeCamera() { yafray::paramMap_t params; params["name"]=yafray::parameter_t("MAINCAM"); + if (R.r.mode & R_ORTHO) + params["type"] = yafray::parameter_t("ortho"); + else + params["type"] = yafray::parameter_t("perspective"); params["resx"]=yafray::parameter_t(R.r.xsch); params["resy"]=yafray::parameter_t(R.r.ysch); float aspect = 1; - if (R.r.xsch < R.r.ysch) aspect = float(R.r.xsch)/float(R.r.ysch); + if (R.r.xsch < R.r.ysch) aspect = float(R.r.xsch)/float(R.r.ysch); params["focal"]=yafray::parameter_t(mainCamLens/(aspect*32.0)); - float camtx[4][4]; - MTC_Mat4CpyMat4(camtx, maincam_obj->obmat); - MTC_normalise3DF(camtx[1]); //up - MTC_normalise3DF(camtx[2]); //dir params["from"]=yafray::parameter_t( - yafray::point3d_t(camtx[3][0],camtx[3][1],camtx[3][2])); - Object* dofob = findObject("OBFOCUS"); - float fdist=1; - if (dofob) { - // dof empty found, modify lookat point accordingly - // location from matrix, in case animated - float fdx = dofob->obmat[3][0] - camtx[3][0]; - float fdy = dofob->obmat[3][1] - camtx[3][1]; - float fdz = dofob->obmat[3][2] - camtx[3][2]; - fdist = sqrt(fdx*fdx + fdy*fdy + fdz*fdz); - cout << "FOCUS object found, distance is: " << fdist << endl; - } + yafray::point3d_t(maincam_obj->obmat[3][0], maincam_obj->obmat[3][1], maincam_obj->obmat[3][2])); + float fdist = -R.viewmat[3][2]; + if (R.r.mode & R_ORTHO) fdist *= 0.01f; params["to"]=yafray::parameter_t( - yafray::point3d_t(camtx[3][0] - fdist*camtx[2][0], - camtx[3][1] - fdist*camtx[2][1], - camtx[3][2] - fdist*camtx[2][2])); + yafray::point3d_t(maincam_obj->obmat[3][0] - fdist * R.viewmat[0][2], + maincam_obj->obmat[3][1] - fdist * R.viewmat[1][2], + maincam_obj->obmat[3][2] - fdist * R.viewmat[2][2])); params["up"]=yafray::parameter_t( - yafray::point3d_t(camtx[3][0] + camtx[1][0], - camtx[3][1] + camtx[1][1], - camtx[3][2] + camtx[1][2])); + yafray::point3d_t(maincam_obj->obmat[3][0] + R.viewmat[0][1], + maincam_obj->obmat[3][1] + R.viewmat[1][1], + maincam_obj->obmat[3][2] + R.viewmat[2][1])); + // add dof_distance param here yafrayGate->addCamera(params); } @@ -1232,7 +1286,6 @@ void yafrayPluginRender_t::writePathlight() bool yafrayPluginRender_t::writeWorld() { World *world = G.scene->world; - short i=0,j=0; if (R.r.GIquality!=0) { if (R.r.GImethod==1) { if (world==NULL) cout << "WARNING: need world background for skydome!\n"; @@ -1243,46 +1296,47 @@ bool yafrayPluginRender_t::writeWorld() if (world==NULL) return false; - for(i=0;i<8;i++){ - if(world->mtex[i] != NULL) - { - if(world->mtex[i]->tex->type == TEX_IMAGE && world->mtex[i]->tex->ima != NULL){ - - for(j=0;j<160;j++){ - if(world->mtex[i]->tex->ima->name[j] == '\0' && j > 3){ - if( - (world->mtex[i]->tex->ima->name[j-3] == 'h' || world->mtex[i]->tex->ima->name[j-3] == 'H' ) && - (world->mtex[i]->tex->ima->name[j-2] == 'd' || world->mtex[i]->tex->ima->name[j-2] == 'D' ) && - (world->mtex[i]->tex->ima->name[j-1] == 'r' || world->mtex[i]->tex->ima->name[j-1] == 'R' ) - ) - { - yafray::paramMap_t params; - params["type"]=yafray::parameter_t("HDRI"); - params["name"]=yafray::parameter_t("world_background"); - params["exposure_adjust"]=yafray::parameter_t(world->mtex[i]->tex->bright-1); - params["mapping"]=yafray::parameter_t("probe"); - params["filename"]=yafray::parameter_t(world->mtex[i]->tex->ima->name); - yafrayGate->addBackground(params); - return true; - } - } - } - - yafray::paramMap_t params; - params["type"]=yafray::parameter_t("image"); - params["name"]=yafray::parameter_t("world_background"); - params["power"]=yafray::parameter_t(world->mtex[i]->tex->bright); - params["filename"]=yafray::parameter_t(world->mtex[i]->tex->ima->name); + yafray::paramMap_t params; + for (int i=0;i<6;i++) { + MTex* wtex = world->mtex[i]; + if (!wtex) continue; + Image* wimg = wtex->tex->ima; + if ((wtex->tex->type==TEX_IMAGE) && (wimg!=NULL)) { + string wt_path = wimg->name; + adjustPath(wt_path); + if (BLI_testextensie(wimg->name, ".hdr")) { + params["type"] = yafray::parameter_t("HDRI"); + params["name"] = yafray::parameter_t("world_background"); + // since exposure adjust is an integer, using the texbri slider isn't actually very useful here (result either -1/0/1) + params["exposure_adjust"] = yafray::parameter_t(int(world->mtex[i]->tex->bright-1)); + params["mapping"] = yafray::parameter_t("probe"); + params["filename"] = yafray::parameter_t(wt_path); + yafrayGate->addBackground(params); + return true; + } + else if (BLI_testextensie(wimg->name, ".jpg") || BLI_testextensie(wimg->name, ".jpeg") || BLI_testextensie(wimg->name, ".tga")) { + params["type"] = yafray::parameter_t("image"); + params["name"] = yafray::parameter_t("world_background"); + /* + // not yet in yafray, always assumes spheremap for now, not the same as in Blender, + // which for some reason is scaled by 2 in Blender??? + if (wtex->texco & TEXCO_ANGMAP) + params["mapping"] = yafray::parameter_t("probe"); + else + params["mapping"] = yafray::parameter_t("sphere"); + */ + params["filename"] = yafray::parameter_t(wt_path); yafrayGate->addBackground(params); return true; } } } - yafray::paramMap_t params; - params["type"]=yafray::parameter_t("constant"); - 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) + params.clear(); + params["type"] = yafray::parameter_t("constant"); + 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; params["color"]=yafray::parameter_t(yafray::color_t(world->horr * bg_mult, diff --git a/source/blender/yafray/intern/export_Plugin.h b/source/blender/yafray/intern/export_Plugin.h index 53acf51350e..079b484b7ad 100644 --- a/source/blender/yafray/intern/export_Plugin.h +++ b/source/blender/yafray/intern/export_Plugin.h @@ -35,7 +35,7 @@ class yafrayPluginRender_t : public yafrayRender_t virtual void writeObject(Object* obj, const std::vector &VLR_list, const float obmat[4][4]); virtual void writeAllObjects(); - void writeAreaLamp(LampRen* lamp,int num); + void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]); virtual void writeLamps(); virtual void writeCamera(); virtual void writeHemilight(); @@ -57,8 +57,8 @@ class yafrayPluginRender_t : public yafrayRender_t std::vector &uvcoords,std::vector &vcol, std::map &vert_idx,VlakRen *vlr, bool has_orco,bool has_uv,bool has_vcol); - void genVertices(std::vector &verts,int &vidx, - std::map &vert_idx,VlakRen* vlr,bool has_orco); + void genVertices(std::vector &verts, int &vidx, + std::map &vert_idx, VlakRen* vlr, bool has_orco, Object* obj); }; class blenderYafrayOutput_t : public yafray::colorOutput_t diff --git a/source/blender/yafray/intern/yafray_Render.cpp b/source/blender/yafray/intern/yafray_Render.cpp index 57d2cd39b36..b24497ce98b 100644 --- a/source/blender/yafray/intern/yafray_Render.cpp +++ b/source/blender/yafray/intern/yafray_Render.cpp @@ -40,12 +40,12 @@ bool yafrayRender_t::exportScene() return false; } - if(!initExport()) + if (!initExport()) { clearAll(); return false; } - cout<<"Writing textures"< >::const_iterator obn=dupliMtx_list.begin(); + obn!=dupliMtx_list.end();++obn) + { + cout << obn->first << endl; + } + // in case dupliMtx_list not empty, make sure that there is at least one source object // in all_objects with the name given in dupliMtx_list if (!dupliMtx_list.empty()) { -- cgit v1.2.3