diff options
author | Stuart Broadfoot <gbroadfoot@hotmail.com> | 2013-01-04 16:44:38 +0400 |
---|---|---|
committer | Stuart Broadfoot <gbroadfoot@hotmail.com> | 2013-01-04 16:44:38 +0400 |
commit | ec33cacc62054fb1ca90aa860e6b9866ca4a7126 (patch) | |
tree | c56528a277483053ee3a89132ab10ef562d3aa80 | |
parent | 1022151d6ef644280074c29fd88c42007e17d45b (diff) |
Added vertex color attributes (currently limited to one) and UVs included for triangle mesh hair.
I have also included a small speedup for the intersection test.
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 2 | ||||
-rw-r--r-- | intern/cycles/blender/blender_curves.cpp | 277 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_bvh.h | 25 | ||||
-rw-r--r-- | intern/cycles/render/curves.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_particle.c | 121 |
5 files changed, 380 insertions, 46 deletions
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 2d059b365a1..81ee34b6b5e 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -975,7 +975,7 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel): if cscene.primitive == 'TRIANGLES': layout.prop(cscene, "triangle_method", text="Method") - if cscene.triangle_method == 'TESSELATED': + if cscene.triangle_method == 'TESSELLATED': layout.prop(cscene, "resolution", text="Resolution") layout.prop(cscene, "use_smooth", text="Smooth") elif cscene.primitive == 'LINE_SEGMENTS': diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index c38d0fe76dc..4fad7d45162 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -38,11 +38,14 @@ void interp_weights(float t, float data[4], int type); float shaperadius(float shape, float root, float tip, float time); void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData, int interpolation); bool ObtainParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData); +bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents); +bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int vcol_num); bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents); void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, float3 RotCam); void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments); void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int resolution, int segments); void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments); +void ExportCurveTriangleUVs(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, int vert_offset, int resol); ParticleCurveData::ParticleCurveData() { @@ -61,6 +64,7 @@ ParticleCurveData::~ParticleCurveData() curve_keynum.clear(); curve_length.clear(); curve_uv.clear(); + curve_vcol.clear(); curvekey_co.clear(); curvekey_time.clear(); @@ -291,8 +295,6 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par if(!use_parents && !(b_psys.settings().child_type() == 0)) pa_no = totparts; - BL::ParticleSystem::particles_iterator b_pa; - b_psys.particles.begin(b_pa); for(; pa_no < totparts+totchild; pa_no++) { CData->curve_firstkey.push_back(keyno); @@ -314,6 +316,63 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par } CData->curve_length.push_back(curve_length); + curvenum++; + + } + } + + } + } + + return true; + +} + +bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents) +{ + int keyno = 0; + + if(!(mesh && b_mesh && b_ob && CData)) + return false; + + Transform tfm = get_transform(b_ob->matrix_world()); + Transform itfm = transform_quick_inverse(tfm); + + BL::Object::modifiers_iterator b_mod; + for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) { + if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) { + BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr); + + BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr); + + BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); + + if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) { + + int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1); + int shader = mesh->used_shaders[mi]; + int draw_step = b_psys.settings().draw_step(); + int ren_step = (int)pow((float)2.0f,(float)draw_step); + /*b_psys.settings().render_step(draw_step);*/ + + int totparts = b_psys.particles.length(); + int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100; + int totcurves = totchild; + + if (use_parents || b_psys.settings().child_type() == 0) + totcurves += totparts; + + if (totcurves == 0) + continue; + + int pa_no = 0; + if(!use_parents && !(b_psys.settings().child_type() == 0)) + pa_no = totparts; + + BL::ParticleSystem::particles_iterator b_pa; + b_psys.particles.begin(b_pa); + for(; pa_no < totparts+totchild; pa_no++) { + /*add uvs*/ BL::Mesh::tessface_uv_textures_iterator l; b_mesh->tessface_uv_textures.begin(l); @@ -326,7 +385,72 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par if(pa_no < totparts && b_pa != b_psys.particles.end()) ++b_pa; - curvenum++; + } + } + + } + } + + return true; + +} + +bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int vcol_num) +{ + int keyno = 0; + + if(!(mesh && b_mesh && b_ob && CData)) + return false; + + Transform tfm = get_transform(b_ob->matrix_world()); + Transform itfm = transform_quick_inverse(tfm); + + BL::Object::modifiers_iterator b_mod; + for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) { + if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) { + BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr); + + BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr); + + BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); + + if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) { + + int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1); + int shader = mesh->used_shaders[mi]; + int draw_step = b_psys.settings().draw_step(); + int ren_step = (int)pow((float)2.0f,(float)draw_step); + /*b_psys.settings().render_step(draw_step);*/ + + int totparts = b_psys.particles.length(); + int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100; + int totcurves = totchild; + + if (use_parents || b_psys.settings().child_type() == 0) + totcurves += totparts; + + if (totcurves == 0) + continue; + + int pa_no = 0; + if(!use_parents && !(b_psys.settings().child_type() == 0)) + pa_no = totparts; + + BL::ParticleSystem::particles_iterator b_pa; + b_psys.particles.begin(b_pa); + for(; pa_no < totparts+totchild; pa_no++) { + + /*add uvs*/ + BL::Mesh::tessface_vertex_colors_iterator l; + b_mesh->tessface_vertex_colors.begin(l); + + float3 vcol = make_float3(0.0f, 0.0f, 0.0f); + if(b_mesh->tessface_vertex_colors.length()) + b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x); + CData->curve_vcol.push_back(vcol); + + if(pa_no < totparts && b_pa != b_psys.particles.end()) + ++b_pa; } } @@ -355,10 +479,10 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpo if(curvekey == CData->curve_firstkey[curve]) { subv = 0; - v1 = CData->curvekey_co[curvekey+2] - CData->curvekey_co[curvekey]; + v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey]; } - else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) - v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 2]; + else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) + v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])]; else v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1]; @@ -375,10 +499,10 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpo float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) + if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); - if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == segments)) + if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) && (subv == segments)) radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f); xbasis = normalize(cross(v1,RotCam - ickey_loc)); @@ -404,7 +528,6 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpo mesh->attributes.remove(ATTR_STD_FACE_NORMAL); /* texture coords still needed */ - } void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments) @@ -428,12 +551,12 @@ void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interp float3 v2; if(curvekey == CData->curve_firstkey[curve]) { - v1 = CData->curvekey_co[curvekey+2] - CData->curvekey_co[curvekey+1]; + v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1]; v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; } - else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) { + else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; - v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[curvekey-2]; + v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])]; } else { v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; @@ -457,12 +580,12 @@ void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interp if(curvekey == CData->curve_firstkey[curve]) { subv = 0; - v1 = CData->curvekey_co[curvekey+2] - CData->curvekey_co[curvekey+1]; + v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1]; v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; } - else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) { + else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; - v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[curvekey-2]; + v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])]; } else { v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; @@ -490,10 +613,10 @@ void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interp float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) + if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); - if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == segments)) + if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) && (subv == segments)) radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f); float3 ickey_loc_shfl = ickey_loc - radius * xbasis; @@ -542,12 +665,12 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter float3 v2; if(curvekey == CData->curve_firstkey[curve]) { - v1 = CData->curvekey_co[curvekey+2] - CData->curvekey_co[curvekey+1]; + v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1]; v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; } - else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) { + else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; - v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[curvekey-2]; + v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])]; } else { v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; @@ -572,12 +695,12 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter if(curvekey == CData->curve_firstkey[curve]) { subv = 0; - v1 = CData->curvekey_co[curvekey+2] - CData->curvekey_co[curvekey+1]; + v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1]; v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; } - else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) { + else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; - v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[curvekey-2]; + v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])]; } else { v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; @@ -607,10 +730,10 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) + if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); - if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == segments)) + if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) && (subv == segments)) radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f); float angle = 2 * M_PI_F / (float)resolution; @@ -717,6 +840,65 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa } } +void ExportCurveTriangleUVs(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, int vert_offset, int resol) +{ + float time = 0.0f; + float prevtime = 0.0f; + + Attribute *attr = mesh->attributes.find(ATTR_STD_UV); + if (attr == NULL) + return; + + float3 *uvdata = attr->data_float3(); + + int vertexindex = vert_offset; + + for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) { + for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) { + + for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { + + int subv = 1; + + if (curvekey == CData->curve_firstkey[curve]) + subv = 0; + + for (; subv <= segments; subv++) { + + float3 ickey_loc = make_float3(0.0f,0.0f,0.0f); + + InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation); + + if(subv!=0) { + for(int section = 0 ; section < resol; section++) { + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = prevtime; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = time; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = prevtime; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = time; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = prevtime; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = time; + vertexindex++; + } + } + + prevtime = time; + } + } + } + } + +} /* Hair Curve Sync */ void BlenderSync::sync_curve_settings() @@ -846,8 +1028,10 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool ParticleCurveData CData; - if(use_cache) + if(use_cache) { ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, use_parents); + ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, use_parents); + } else ObtainParticleData(mesh, &b_mesh, &b_ob, &CData); @@ -862,12 +1046,20 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool } if(primitive == CURVE_TRIANGLES){ - if(triangle_method == CURVE_CAMERA) + int vert_num = mesh->triangles.size() * 3; + if(triangle_method == CURVE_CAMERA) { ExportCurveTrianglePlanes(mesh, &CData, interpolation, use_smooth, segments, RotCam); - else if(triangle_method == CURVE_RIBBONS) + ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, 1); + } + else if(triangle_method == CURVE_RIBBONS) { ExportCurveTriangleRibbons(mesh, &CData, interpolation, use_smooth, segments); - else + ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, 1); + } + else { ExportCurveTriangleGeometry(mesh, &CData, interpolation, use_smooth, resolution, segments); + ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, resolution); + } + } else { ExportCurveSegments(scene, mesh, &CData, interpolation, segments); @@ -901,6 +1093,33 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool generated[i++] = co*size - loc; } } + + /* create vertex color attributes */ + BL::Mesh::tessface_vertex_colors_iterator l; + int vcol_num = 0; + + for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l, vcol_num++) { + if(!mesh->need_attribute(scene, ustring(l->name().c_str()))) + continue; + + /*error occurs with more than one vertex colour attribute so avoided*/ + if(vcol_num!=0) + break; + + Attribute *attr_vcol = mesh->curve_attributes.add( + ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); + + ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, use_parents, 0); + + float3 *vcol = attr_vcol->data_float3(); + + if(vcol) { + for(size_t curve = 0; curve < CData.curve_vcol.size() ;curve++) + vcol[curve] = color_srgb_to_scene_linear(CData.curve_vcol[curve]); + } + + } + } mesh->compute_bounds(); diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h index c73d9328c74..2cb29207b05 100644 --- a/intern/cycles/kernel/kernel_bvh.h +++ b/intern/cycles/kernel/kernel_bvh.h @@ -231,13 +231,14 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect, float3 dif = P - p1; float3 dir = 1.0f/idir; - /* test bounding sphere intersection (introduce circular artifacts)*/ - /*float3 bvector = 0.5f * (p1 + p2) - P; - float bvectorl_sq = len_squared(bvector); - float dot_bv_dir = dot(bvector,dir); - float maxdist = l * 0.5f + mr; - if(bvectorl_sq - dot_bv_dir * dot_bv_dir > maxdist * maxdist) - return;*/ + float sp_r = mr + 0.5f * l; + float3 sphere_dif = P - ((p1 + p2) * 0.5f); + float sphere_b = dot(dir,sphere_dif); + sphere_dif = sphere_dif - sphere_b * dir; + sphere_b = dot(dir,sphere_dif); + float sdisc = sphere_b * sphere_b - len_squared(sphere_dif) + sp_r * sp_r; + if(sdisc < 0.0f) + return; /* obtain parameters and test midpoint distance for suitable modes*/ float3 tg = (p2 - p1) / l; @@ -278,7 +279,7 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect, float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - r1*r1 - 2*r1*tdifz*gd; float td = tb*tb - 4*a*tc; - if (td<0) + if (td < 0.0f) return; float rootd = 0.0f; @@ -321,14 +322,6 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect, } } - /*remove overlap - not functional yet*/ - /*if (flags & CURVE_KN_CURVEDATA) { - float3 tg1 = float4_to_float3(kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0)); - float3 tg2 = float4_to_float3(kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1)); - if((dot(P + t * dir - p1, tg1) < 0.0f) || (dot(P + t * dir - p2, tg2) > 0.0f)) - return; - }*/ - #ifdef __VISIBILITY_FLAG__ /* visibility flag test. we do it here under the assumption * that most triangles are culled by node flags */ diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h index 85a549082f2..bb9ef6d99cf 100644 --- a/intern/cycles/render/curves.h +++ b/intern/cycles/render/curves.h @@ -81,6 +81,7 @@ public: vector<int> curve_keynum; vector<float> curve_length; vector<float3> curve_uv; + vector<float3> curve_vcol; vector<float3> curvekey_co; vector<float> curvekey_time; diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index c6d1adac19a..be3cbfaece3 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -452,6 +452,115 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Par } } +static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no, int vcol_no, + float n_mcol[3]) +{ + ParticleSettings *part = 0; + int totpart; + int totchild = 0; + int num; + MCol mcol = {255, 255, 255, 255}; + + /* 1. check that everything is ok & updated */ + if (particlesystem == NULL) + return; + + part = particlesystem->part; + + totchild = particlesystem->totchild; + + /* can happen for disconnected/global hair */ + if (part->type == PART_HAIR && !particlesystem->childcache) + totchild = 0; + + totpart = particlesystem->totpart; + + if (particle_no >= totpart + totchild) + return; + +/* 3. start creating renderable things */ + /* setup per particle individual stuff */ + if (particle_no < totpart) { + + /* get uvco & mcol */ + num = particle->num_dmcache; + + if (num == DMCACHE_NOTFOUND) + if (particle->num < modifier->dm->getNumTessFaces(modifier->dm)) + num = particle->num; + + if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); + MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no); + mc += num * 4; + + psys_interpolate_mcol(mc, mface->v4, particle->fuv, &mcol); + n_mcol[0] = (float)mcol.b / 255.0f; + n_mcol[1] = (float)mcol.g / 255.0f; + n_mcol[2] = (float)mcol.r / 255.0f; + } + else { + n_mcol[0] = 0.0f; + n_mcol[1] = 0.0f; + n_mcol[2] = 0.0f; + } + } + } + else { + ChildParticle *cpa = particlesystem->child + particle_no - totpart; + + num = cpa->num; + + /* get uvco & mcol */ + if (part->childtype == PART_CHILD_FACES) { + if (n_mcol && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (cpa->num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE); + MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); + mc += cpa->num * 4; + + psys_interpolate_mcol(mc, mface->v4, cpa->fuv, &mcol); + n_mcol[0] = (float)mcol.b / 255.0f; + n_mcol[1] = (float)mcol.g / 255.0f; + n_mcol[2] = (float)mcol.r / 255.0f; + } + else { + n_mcol[0] = 0.0f; + n_mcol[1] = 0.0f; + n_mcol[2] = 0.0f; + } + } + } + else { + ParticleData *parent = particlesystem->particles + cpa->parent; + num = parent->num_dmcache; + + if (num == DMCACHE_NOTFOUND) + if (parent->num < modifier->dm->getNumTessFaces(modifier->dm)) + num = parent->num; + + if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); + MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); + mc += num * 4; + + psys_interpolate_mcol(mc, mface->v4, parent->fuv, &mcol); + n_mcol[0] = (float)mcol.b / 255.0f; + n_mcol[1] = (float)mcol.g / 255.0f; + n_mcol[2] = (float)mcol.r / 255.0f; + } + else { + n_mcol[0] = 0.0f; + n_mcol[1] = 0.0f; + n_mcol[2] = 0.0f; + } + } + } + } +} + static void particle_recalc(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr, short flag) { if (ptr->type == &RNA_ParticleSystem) { @@ -3258,6 +3367,18 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_THICK_WRAP); RNA_def_function_output(func, prop); + /* extract hair mcols */ + func = RNA_def_function(srna, "mcol_on_emitter", "rna_ParticleSystem_mcol_on_emitter"); + RNA_def_function_ui_description(func, "Obtain mcol for all particles"); + prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier"); + prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle"); + prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX); + prop = RNA_def_int(func, "vcol_no", 0, INT_MIN, INT_MAX, "vcol no", "", INT_MIN, INT_MAX); + prop = RNA_def_property(func, "mcol", PROP_FLOAT, PROP_COLOR); + RNA_def_property_array(prop, 3); + RNA_def_property_flag(prop, PROP_THICK_WRAP); + RNA_def_function_output(func, prop); + } void RNA_def_particle(BlenderRNA *brna) |