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.
This commit is contained in:
Stuart Broadfoot
2013-01-04 12:44:38 +00:00
parent 1022151d6e
commit ec33cacc62
5 changed files with 380 additions and 46 deletions

View File

@@ -975,7 +975,7 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
if cscene.primitive == 'TRIANGLES': if cscene.primitive == 'TRIANGLES':
layout.prop(cscene, "triangle_method", text="Method") 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, "resolution", text="Resolution")
layout.prop(cscene, "use_smooth", text="Smooth") layout.prop(cscene, "use_smooth", text="Smooth")
elif cscene.primitive == 'LINE_SEGMENTS': elif cscene.primitive == 'LINE_SEGMENTS':

View File

@@ -38,11 +38,14 @@ void interp_weights(float t, float data[4], int type);
float shaperadius(float shape, float root, float tip, float time); 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); 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 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); 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 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 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 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 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() ParticleCurveData::ParticleCurveData()
{ {
@@ -61,6 +64,7 @@ ParticleCurveData::~ParticleCurveData()
curve_keynum.clear(); curve_keynum.clear();
curve_length.clear(); curve_length.clear();
curve_uv.clear(); curve_uv.clear();
curve_vcol.clear();
curvekey_co.clear(); curvekey_co.clear();
curvekey_time.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)) if(!use_parents && !(b_psys.settings().child_type() == 0))
pa_no = totparts; pa_no = totparts;
BL::ParticleSystem::particles_iterator b_pa;
b_psys.particles.begin(b_pa);
for(; pa_no < totparts+totchild; pa_no++) { for(; pa_no < totparts+totchild; pa_no++) {
CData->curve_firstkey.push_back(keyno); 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); 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*/ /*add uvs*/
BL::Mesh::tessface_uv_textures_iterator l; BL::Mesh::tessface_uv_textures_iterator l;
b_mesh->tessface_uv_textures.begin(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()) if(pa_no < totparts && b_pa != b_psys.particles.end())
++b_pa; ++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]) { if(curvekey == CData->curve_firstkey[curve]) {
subv = 0; 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) else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 2]; v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])];
else else
v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1]; 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); 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); 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); radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
xbasis = normalize(cross(v1,RotCam - ickey_loc)); 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); mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
/* texture coords still needed */ /* texture coords still needed */
} }
void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments) 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; float3 v2;
if(curvekey == CData->curve_firstkey[curve]) { 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]; 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]; 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 { else {
v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; 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]) { if(curvekey == CData->curve_firstkey[curve]) {
subv = 0; 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]; 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]; 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 { else {
v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; 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); 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); 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); radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
float3 ickey_loc_shfl = ickey_loc - radius * xbasis; float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
@@ -542,12 +665,12 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter
float3 v2; float3 v2;
if(curvekey == CData->curve_firstkey[curve]) { 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]; 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]; 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 { else {
v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; 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]) { if(curvekey == CData->curve_firstkey[curve]) {
subv = 0; 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]; 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]; 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 { else {
v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; 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); 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); 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); radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
float angle = 2 * M_PI_F / (float)resolution; 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 */ /* Hair Curve Sync */
void BlenderSync::sync_curve_settings() 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; ParticleCurveData CData;
if(use_cache) if(use_cache) {
ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, use_parents); ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, use_parents);
ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, use_parents);
}
else else
ObtainParticleData(mesh, &b_mesh, &b_ob, &CData); 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(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); 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); 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); ExportCurveTriangleGeometry(mesh, &CData, interpolation, use_smooth, resolution, segments);
ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, resolution);
}
} }
else { else {
ExportCurveSegments(scene, mesh, &CData, interpolation, segments); 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; 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(); mesh->compute_bounds();

View File

@@ -231,13 +231,14 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
float3 dif = P - p1; float3 dif = P - p1;
float3 dir = 1.0f/idir; float3 dir = 1.0f/idir;
/* test bounding sphere intersection (introduce circular artifacts)*/ float sp_r = mr + 0.5f * l;
/*float3 bvector = 0.5f * (p1 + p2) - P; float3 sphere_dif = P - ((p1 + p2) * 0.5f);
float bvectorl_sq = len_squared(bvector); float sphere_b = dot(dir,sphere_dif);
float dot_bv_dir = dot(bvector,dir); sphere_dif = sphere_dif - sphere_b * dir;
float maxdist = l * 0.5f + mr; sphere_b = dot(dir,sphere_dif);
if(bvectorl_sq - dot_bv_dir * dot_bv_dir > maxdist * maxdist) float sdisc = sphere_b * sphere_b - len_squared(sphere_dif) + sp_r * sp_r;
return;*/ if(sdisc < 0.0f)
return;
/* obtain parameters and test midpoint distance for suitable modes*/ /* obtain parameters and test midpoint distance for suitable modes*/
float3 tg = (p2 - p1) / l; 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 tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - r1*r1 - 2*r1*tdifz*gd;
float td = tb*tb - 4*a*tc; float td = tb*tb - 4*a*tc;
if (td<0) if (td < 0.0f)
return; return;
float rootd = 0.0f; 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__ #ifdef __VISIBILITY_FLAG__
/* visibility flag test. we do it here under the assumption /* visibility flag test. we do it here under the assumption
* that most triangles are culled by node flags */ * that most triangles are culled by node flags */

View File

@@ -81,6 +81,7 @@ public:
vector<int> curve_keynum; vector<int> curve_keynum;
vector<float> curve_length; vector<float> curve_length;
vector<float3> curve_uv; vector<float3> curve_uv;
vector<float3> curve_vcol;
vector<float3> curvekey_co; vector<float3> curvekey_co;
vector<float> curvekey_time; vector<float> curvekey_time;

View File

@@ -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) static void particle_recalc(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr, short flag)
{ {
if (ptr->type == &RNA_ParticleSystem) { 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_property_flag(prop, PROP_THICK_WRAP);
RNA_def_function_output(func, prop); 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) void RNA_def_particle(BlenderRNA *brna)