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.
This commit is contained in:
Alfredo de Greef 2004-07-12 03:20:31 +00:00
parent c90ffd49e0
commit f32b8e6b7f
7 changed files with 316 additions and 244 deletions

@ -746,13 +746,14 @@ void add_to_blurbuf(int blur)
void yafrayRender()
{
R.flag |= R_RENDERING; /* !!! */
printf("Starting scene conversion.\n");
prepareScene();
printf("Scene conversion done.\n");
if(!R.r.YFexportxml)
// switch must be done before prepareScene()
if (!R.r.YFexportxml)
YAF_switchFile();
else
YAF_switchPlugin();
printf("Starting scene conversion.\n");
prepareScene();
printf("Scene conversion done.\n");
YAF_exportScene();
finalizeScene();
}

@ -111,9 +111,8 @@
#include <config.h>
#endif
/* yafray: VertRen vertices are not transformed, transform is replaced with the identity matrix,
* since yafray needs the untransformed meshes to calculate orco texture space as in Blender.
* This is not true for lamps however, which use a copy of the original object matrix instead.
/* yafray: Identity transform 'hack' removed, exporter now transforms vertices back to world.
* Same is true for lamp coords & vec.
* Duplicated data objects & dupliframe/duplivert objects are only stored once,
* only the matrix is stored for all others, in yafray these objects are instances of the original.
* The main changes are in RE_rotateBlenderScene().
@ -1138,11 +1137,7 @@ static void init_render_mball(Object *ob)
if (ob!=find_basis_mball(ob))
return;
/* yafray: set transform to identity matrix */
if (R.r.renderer==R_YAFRAY)
MTC_Mat4One(mat);
else
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4Invert(ob->imat, mat);
MTC_Mat3CpyMat4(imat, ob->imat);
@ -1262,11 +1257,7 @@ static void init_render_mesh(Object *ob)
return;
}
/* yafray: set transform to identity matrix */
if (R.r.renderer==R_YAFRAY)
MTC_Mat4One(mat);
else
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4Invert(ob->imat, mat);
MTC_Mat3CpyMat4(imat, ob->imat);
@ -1591,11 +1582,7 @@ void RE_add_render_lamp(Object *ob, int doshadbuf)
lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
R.la[R.totlamp++]= lar;
/* yafray: in this case the lamp matrix is a copy of the object matrix */
if (R.r.renderer==R_YAFRAY)
MTC_Mat4CpyMat4(mat, ob->obmat);
else
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4Invert(ob->imat, mat);
MTC_Mat3CpyMat4(lar->mat, mat);
@ -1779,11 +1766,7 @@ static void init_render_surf(Object *ob)
nu= cu->nurb.first;
if(nu==0) return;
/* yafray: set transform to identity matrix */
if (R.r.renderer==R_YAFRAY)
MTC_Mat4One(mat);
else
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4Invert(ob->imat, mat);
/* material array */
@ -2184,11 +2167,7 @@ static void init_render_curve(Object *ob)
firststartvert= R.totvert;
/* yafray: set transform to identity matrix */
if (R.r.renderer==R_YAFRAY)
MTC_Mat4One(mat);
else
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4Invert(ob->imat, mat);
/* material array */
@ -2537,11 +2516,7 @@ static void init_render_object(Object *ob)
else if(ob->type==OB_MBALL)
init_render_mball(ob);
else {
/* yafray: set transform to identity matrix */
if (R.r.renderer==R_YAFRAY)
MTC_Mat4One(mat);
else
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4Invert(ob->imat, mat);
}
@ -2803,13 +2778,8 @@ void RE_rotateBlenderScene(void)
ob= G.main->object.first;
while(ob) {
if(ob->flag & OB_DO_IMAT) {
ob->flag &= ~OB_DO_IMAT;
/* yafray: set transform to identity matrix, not sure if this is needed here */
if (R.r.renderer==R_YAFRAY)
MTC_Mat4One(mat);
else
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4Invert(ob->imat, mat);
}
ob= ob->id.next;
@ -2928,11 +2898,7 @@ void RE_rotateBlenderScene(void)
}
else {
/* yafray: set transform to identity matrix, not sure if this is needed here */
if (R.r.renderer==R_YAFRAY)
MTC_Mat4One(mat);
else
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4Invert(ob->imat, mat);
}
@ -3065,7 +3031,7 @@ void displace_render_face(VlakRen *vlr, float *scale)
/* closest in displace value. This will help smooth edges. */
if ( fabs(vlr->v1->accum - vlr->v3->accum) > fabs(vlr->v2->accum - vlr->v4->accum))
vlr->flag |= R_DIVIDE_24;
else vlr->flag & ~R_DIVIDE_24;
else vlr->flag &= ~R_DIVIDE_24; // E: typo?, was missing '='
}
/* Recalculate the face normal - if flipped before, flip now */

@ -204,11 +204,9 @@ bool yafrayFileRender_t::writeRender()
ostr << "<render camera_name=\"MAINCAM\"\n";
ostr << "\traydepth=\"" << R.r.YF_raydepth << "\" gamma=\"" << R.r.YF_gamma << "\" exposure=\"" << R.r.YF_exposure << "\"\n";
//if( (G.scene->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=\""<<R.r.YF_raybias<<"\" >\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<outfile value=\"" << imgout << "\" />\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<string, pair<Material*, MTex*> >::const_iterator blendtex=used_textures.begin();
@ -352,12 +373,8 @@ void yafrayFileRender_t::writeTextures()
ostr.str("");
ostr << "<shader type=\"image\" name=\"" << blendtex->first << "\" >\n";
ostr << "\t<attributes>\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<filename value=\"" << texpath << "\" />\n";
ostr << "\t</attributes>\n";
ostr << "</shader>\n\n";
@ -760,7 +777,6 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &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<VlakRen*> &VLR_li
map<VertRen*, int> 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<points>\n";
for (vector<VlakRen*>::const_iterator fci=VLR_list.begin();
fci!=VLR_list.end();++fci)
@ -790,13 +807,16 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &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<p x=\"" << ver->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<p x=\"" << tvec[0]
<< "\" y=\"" << tvec[1]
<< "\" z=\"" << tvec[2] << "\" />\n";
if (EXPORT_ORCO) {
orco = ver->orco;
ostr << "\t\t\t<p x=\"" << orco[0]
@ -807,9 +827,11 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
if (vert_idx.find(vlr->v2)==vert_idx.end()) {
vert_idx[vlr->v2] = vidx++;
ver = vlr->v2;
ostr << "\t\t\t<p x=\"" << ver->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<p x=\"" << tvec[0]
<< "\" y=\"" << tvec[1]
<< "\" z=\"" << tvec[2] << "\" />\n";
if (EXPORT_ORCO) {
orco = ver->orco;
ostr << "\t\t\t<p x=\"" << orco[0]
@ -820,9 +842,11 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
if (vert_idx.find(vlr->v3)==vert_idx.end()) {
vert_idx[vlr->v3] = vidx++;
ver = vlr->v3;
ostr << "\t\t\t<p x=\"" << ver->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<p x=\"" << tvec[0]
<< "\" y=\"" << tvec[1]
<< "\" z=\"" << tvec[2] << "\" />\n";
if (EXPORT_ORCO) {
orco = ver->orco;
ostr << "\t\t\t<p x=\"" << orco[0]
@ -833,9 +857,11 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &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<p x=\"" << ver->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<p x=\"" << tvec[0]
<< "\" y=\"" << tvec[1]
<< "\" z=\"" << tvec[2] << "\" />\n";
if (EXPORT_ORCO) {
orco = ver->orco;
ostr << "\t\t\t<p x=\"" << orco[0]
@ -956,7 +982,7 @@ void yafrayFileRender_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
@ -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<a x=\""<< a[0] <<"\" y=\""<< a[1] <<"\" z=\"" << a[2] <<"\" />\n";
ostr << "\t<b x=\""<< b[0] <<"\" y=\""<< b[1] <<"\" z=\"" << b[2] <<"\" />\n";
ostr << "\t<c x=\""<< c[0] <<"\" y=\""<< c[1] <<"\" z=\"" << c[2] <<"\" />\n";
ostr << "\t<d x=\""<< d[0] <<"\" y=\""<< d[1] <<"\" z=\"" << d[2] <<"\" />\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<a x=\""<< lpco[0][0] <<"\" y=\""<< lpco[0][1] <<"\" z=\"" << lpco[0][2] <<"\" />\n";
ostr << "\t<b x=\""<< lpco[1][0] <<"\" y=\""<< lpco[1][1] <<"\" z=\"" << lpco[1][2] <<"\" />\n";
ostr << "\t<c x=\""<< lpco[2][0] <<"\" y=\""<< lpco[2][1] <<"\" z=\"" << lpco[2][2] <<"\" />\n";
ostr << "\t<d x=\""<< lpco[3][0] <<"\" y=\""<< lpco[3][1] <<"\" z=\"" << lpco[3][2] <<"\" />\n";
ostr << "\t<color r=\"" << lamp->r << "\" g=\"" << lamp->g << "\" b=\"" << lamp->b << "\" />\n";
ostr << "</light>\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;i<R.totlamp;i++)
{
ostr.str("");
LampRen* lamp = R.la[i];
if (lamp->type==LA_AREA) { writeAreaLamp(lamp, i); continue; }
if (lamp->type==LA_AREA) { writeAreaLamp(lamp, i, iview); continue; }
// TODO: add decay setting in yafray
ostr << "<light type=\"";
if (lamp->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 << "\t<from x=\"" << lamp->co[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<from x=\"" << -lpvec[0] << "\" y=\"" << -lpvec[1] << "\" z=\"" << -lpvec[2] << "\" />\n";
else
ostr << "\t<from x=\"" << lpco[0] << "\" y=\"" << lpco[1] << "\" z=\"" << lpco[2] << "\" />\n";
// 'to' for spot, already calculated by Blender
if (lamp->type==LA_SPOT)
ostr << "\t<to x=\"" << lamp->co[0]+lamp->vec[0]
<< "\" y=\"" << lamp->co[1]+lamp->vec[1]
<< "\" z=\"" << lamp->co[2]+lamp->vec[2]
<< "\" />\n";
ostr << "\t<to x=\"" << lpco[0] + lpvec[0]
<< "\" y=\"" << lpco[1] + lpvec[1]
<< "\" z=\"" << lpco[2] + lpvec[2] << "\" />\n";
// color
// rgb in LampRen is premultiplied by energy, power is compensated for that above
ostr << "\t<color r=\"" << lamp->r << "\" g=\"" << lamp->g << "\" b=\"" << lamp->b << "\" />\n";
@ -1109,7 +1167,11 @@ void yafrayFileRender_t::writeCamera()
{
// here Global used again
ostr.str("");
ostr << "<camera name=\"MAINCAM\"";
ostr << "<camera name=\"MAINCAM\" ";
if (R.r.mode & R_ORTHO)
ostr << "type=\"ortho\"";
else
ostr << "type=\"perspective\"";
// render resolution including the percentage buttons (aleady calculated in initrender for R renderdata)
int xres = R.r.xsch;
@ -1123,38 +1185,21 @@ void yafrayFileRender_t::writeCamera()
ostr << "\" focal=\"" << mainCamLens/(aspect*32.0) << "\" >\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<from x=\"" << camtx[3][0] << "\""
<< " y=\"" << camtx[3][1] << "\""
<< " z=\"" << camtx[3][2] << "\" />\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<to x=\"" << camtx[3][0] - fdist*camtx[2][0]
<< "\" y=\"" << camtx[3][1] - fdist*camtx[2][1]
<< "\" z=\"" << camtx[3][2] - fdist*camtx[2][2] << "\" />\n";
}
else {
ostr << "\t<to x=\"" << camtx[3][0] - camtx[2][0]
<< "\" y=\"" << camtx[3][1] - camtx[2][1]
<< "\" z=\"" << camtx[3][2] - camtx[2][2] << "\" />\n";
}
ostr << "\t<up x=\"" << camtx[3][0] + camtx[1][0]
<< "\" y=\"" << camtx[3][1] + camtx[1][1]
<< "\" z=\"" << camtx[3][2] + camtx[1][2] << "\" />\n";
ostr << "\t<from x=\"" << maincam_obj->obmat[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 << "\t<to x=\"" << maincam_obj->obmat[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 << "\t<up x=\"" << maincam_obj->obmat[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 << "</camera>\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 << "<background type=\"HDRI\" name=\"world_background\" ";
ostr << "exposure_adjust = \"";
ostr << (world->mtex[i]->tex->bright-1) << "\"";
ostr << " mapping = \"probe\" ";
ostr << ">\n";
ostr << "<filename value=\"" << world->mtex[i]->tex->ima->name << "\"/>\n";
ostr << "</background>\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 << "<background type=\"image\" name=\"world_background\" power=\"";
ostr << world->mtex[i]->tex->bright << "\">\n";
ostr << "<filename value=\"" << world->mtex[i]->tex->ima->name << "\"/>\n";
ostr << "<background type=\"HDRI\" name=\"world_background\" ";
// since exposure adjust is an integer, using the texbri slider isn't actually very useful here (result either -1/0/1)
// GIpower could be used, but is only active for GI
ostr << "exposure_adjust=\"" << int(world->mtex[i]->tex->bright-1) << "\" mapping=\"probe\" >\n";
ostr << "\t<filename value=\"" << wt_path << "\" />\n";
ostr << "</background>\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 << "<background type=\"image\" name=\"world_background\" >\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<filename value=\"" << wt_path << "\" />\n";
ostr << "</background>\n\n";
xmlfile << ostr.str();
return true;
@ -1275,7 +1320,8 @@ bool yafrayFileRender_t::writeWorld()
ostr.str("");
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)
// 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 << "\t<color r=\"" << (world->horr * bg_mult) <<
@ -1321,5 +1367,3 @@ bool yafrayFileRender_t::executeYafray(const string &xmlpath)
#endif
}

@ -20,7 +20,7 @@ class yafrayFileRender_t : public yafrayRender_t
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);
void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
virtual void writeLamps();
virtual void writeCamera();
virtual void writeHemilight();

@ -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<string, pair<Material*, MTex*> >::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<int> &faces,/*vector<string> &sh
if(has_vcol) genVcol(vcol,vlr,2,3,0,EXPORT_VCOL);
}
void yafrayPluginRender_t::genVertices(vector<yafray::point3d_t> &verts,int &vidx,
map<VertRen*, int> &vert_idx,VlakRen* vlr,bool has_orco)
void yafrayPluginRender_t::genVertices(vector<yafray::point3d_t> &verts, int &vidx,
map<VertRen*, int> &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<yafray::point3d_t> &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<yafray::point3d_t> &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<yafray::point3d_t> &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<VlakRen*> &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<VlakRen*> &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;i<R.totlamp;i++)
{
yafray::paramMap_t params;
string type="";
LampRen* lamp = R.la[i];
if (lamp->type==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,

@ -35,7 +35,7 @@ class yafrayPluginRender_t : public yafrayRender_t
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);
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<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);
void genVertices(std::vector<yafray::point3d_t> &verts,int &vidx,
std::map<VertRen*, int> &vert_idx,VlakRen* vlr,bool has_orco);
void genVertices(std::vector<yafray::point3d_t> &verts, int &vidx,
std::map<VertRen*, int> &vert_idx, VlakRen* vlr, bool has_orco, Object* obj);
};
class blenderYafrayOutput_t : public yafray::colorOutput_t

@ -40,12 +40,12 @@ bool yafrayRender_t::exportScene()
return false;
}
if(!initExport())
if (!initExport())
{
clearAll();
return false;
}
cout<<"Writing textures"<<endl;
// start actual data export
writeTextures();
writeMaterialsAndModulators();
@ -58,7 +58,7 @@ bool yafrayRender_t::exportScene()
// clear for next call, before render to free some memory
clearAll();
if(!finishExport())
if (!finishExport())
{
G.afbreek = 1; //stop render and anim if doing so
return false;
@ -137,6 +137,13 @@ bool yafrayRender_t::getAllMatTexObs()
}
// test
for (map<string, vector<float> >::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()) {