From d438208474e7d5a2dce6125f3fa727f3a93eb087 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 29 Aug 2014 16:44:16 +0600 Subject: Cycles: Fix triangle ribbons hair in viewport and ortho camera There were several issues involved into triangle ribbons hair: - Even for the viewport rendering the blender scene camera was used for orientation. This made hair triangles oriented to the scene camera, not to the viewport camera. - Triangle orientation was actually supposing the camera is perspective. Triangles weren't oriented properly for the orthographic camera resulting in different hair width across it's length. This issues are solved now, but there are some related TODOs: - Rotating viewport doesn't re-orient the triangles, so after viewport navigation hair might not look correct. However, with this fix toggling viewport render (to force hair sync) makes viewport render correct. This isn't so much trivial fix, would require making BVH aware of the dynamic triangle orientation, so they get properly oriented without full hair re-sync. - Panorama camera behavior didn't change but looks like it should, however not really sure atm what's the right thing to do here. --- intern/cycles/blender/blender_curves.cpp | 49 ++++++++++++++++++++----------- intern/cycles/blender/blender_session.cpp | 2 +- 2 files changed, 33 insertions(+), 18 deletions(-) (limited to 'intern') diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 7b1a8ec0b15..8cfaea59a06 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -15,10 +15,11 @@ */ #include "attribute.h" +#include "camera.h" +#include "curves.h" #include "mesh.h" #include "object.h" #include "scene.h" -#include "curves.h" #include "blender_sync.h" #include "blender_util.h" @@ -39,7 +40,8 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num); bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background); void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData); -void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotCam); +void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, + float3 RotCam, bool is_ortho); void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resolution); void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, float3 *uvdata); void ExportCurveTriangleVcol(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, uchar4 *cdata); @@ -328,7 +330,8 @@ static void set_resolution(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, BL::S } } -void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotCam) +void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, + float3 RotCam, bool is_ortho) { int vertexno = mesh->verts.size(); int vertexindex = vertexno; @@ -362,7 +365,10 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotC float3 ickey_loc = CData->curvekey_co[CData->curve_firstkey[curve]]; float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.0f); v1 = CData->curvekey_co[CData->curve_firstkey[curve] + 1] - CData->curvekey_co[CData->curve_firstkey[curve]]; - xbasis = normalize(cross(RotCam - ickey_loc,v1)); + if(is_ortho) + xbasis = normalize(cross(RotCam, v1)); + else + xbasis = normalize(cross(RotCam - ickey_loc, v1)); float3 ickey_loc_shfl = ickey_loc - radius * xbasis; float3 ickey_loc_shfr = ickey_loc + radius * xbasis; mesh->verts.push_back(ickey_loc_shfl); @@ -386,7 +392,10 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotC if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); - xbasis = normalize(cross(RotCam - ickey_loc,v1)); + if(is_ortho) + xbasis = normalize(cross(RotCam, v1)); + else + xbasis = normalize(cross(RotCam - ickey_loc, v1)); float3 ickey_loc_shfl = ickey_loc - radius * xbasis; float3 ickey_loc_shfr = ickey_loc + radius * xbasis; mesh->verts.push_back(ickey_loc_shfl); @@ -858,20 +867,26 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview); - /* obtain camera parameters */ - BL::Object b_CamOb = b_scene.camera(); - float3 RotCam = make_float3(0.0f, 0.0f, 0.0f); - if(b_CamOb) { - Transform ctfm = get_transform(b_CamOb.matrix_world()); - Transform tfm = get_transform(b_ob.matrix_world()); - Transform itfm = transform_quick_inverse(tfm); - RotCam = transform_point(&itfm, make_float3(ctfm.x.w, ctfm.y.w, ctfm.z.w)); - } - /* add hair geometry to mesh */ if(primitive == CURVE_TRIANGLES) { - if(triangle_method == CURVE_CAMERA_TRIANGLES) - ExportCurveTrianglePlanes(mesh, &CData, RotCam); + if(triangle_method == CURVE_CAMERA_TRIANGLES) { + /* obtain camera parameters */ + float3 RotCam; + Camera *camera = scene->camera; + Transform &ctfm = camera->matrix; + if(camera->type == CAMERA_ORTHOGRAPHIC) { + RotCam = -make_float3(ctfm.x.z, ctfm.y.z, ctfm.z.z); + } + else { + Transform tfm = get_transform(b_ob.matrix_world()); + Transform itfm = transform_quick_inverse(tfm); + RotCam = transform_point(&itfm, make_float3(ctfm.x.w, + ctfm.y.w, + ctfm.z.w)); + } + bool is_ortho = camera->type == CAMERA_ORTHOGRAPHIC; + ExportCurveTrianglePlanes(mesh, &CData, RotCam, is_ortho); + } else { ExportCurveTriangleGeometry(mesh, &CData, resolution); used_res = resolution; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 3e84110c335..4ff3d89f9f1 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -116,8 +116,8 @@ void BlenderSession::create_session() if(b_v3d) { if(session_pause == false) { /* full data sync */ - sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state); sync->sync_view(b_v3d, b_rv3d, width, height); + sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state); } } else { -- cgit v1.2.3