Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_curves.cpp160
-rw-r--r--intern/cycles/blender/blender_mesh.cpp8
-rw-r--r--intern/cycles/bvh/bvh.cpp37
-rw-r--r--intern/cycles/bvh/bvh_build.cpp10
-rw-r--r--intern/cycles/bvh/bvh_split.cpp6
-rw-r--r--intern/cycles/kernel/CMakeLists.txt3
-rw-r--r--intern/cycles/kernel/kernel_attribute.h50
-rw-r--r--intern/cycles/kernel/kernel_bvh.h12
-rw-r--r--intern/cycles/kernel/kernel_curve.h140
-rw-r--r--intern/cycles/kernel/kernel_light.h6
-rw-r--r--intern/cycles/kernel/kernel_object.h50
-rw-r--r--intern/cycles/kernel/kernel_passes.h4
-rw-r--r--intern/cycles/kernel/kernel_path.h5
-rw-r--r--intern/cycles/kernel/kernel_primitive.h183
-rw-r--r--intern/cycles/kernel/kernel_shader.h4
-rw-r--r--intern/cycles/kernel/kernel_textures.h4
-rw-r--r--intern/cycles/kernel/kernel_triangle.h231
-rw-r--r--intern/cycles/kernel/kernel_types.h29
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp44
-rw-r--r--intern/cycles/kernel/osl/osl_services.h3
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp11
-rw-r--r--intern/cycles/kernel/osl/osl_shader.h2
-rw-r--r--intern/cycles/kernel/shaders/node_hair_info.osl8
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h153
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h33
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h33
-rw-r--r--intern/cycles/render/attribute.cpp205
-rw-r--r--intern/cycles/render/attribute.h46
-rw-r--r--intern/cycles/render/curves.h3
-rw-r--r--intern/cycles/render/light.cpp16
-rw-r--r--intern/cycles/render/mesh.cpp316
-rw-r--r--intern/cycles/render/mesh.h30
-rw-r--r--intern/cycles/render/nodes.cpp13
-rw-r--r--intern/cycles/render/nodes.h2
-rw-r--r--intern/cycles/render/object.cpp26
-rw-r--r--intern/cycles/render/scene.h5
-rw-r--r--intern/cycles/subd/subd_dice.cpp2
-rw-r--r--intern/cycles/util/CMakeLists.txt2
-rw-r--r--intern/cycles/util/util_attribute.cpp51
-rw-r--r--intern/cycles/util/util_attribute.h31
-rw-r--r--intern/cycles/util/util_types.h18
41 files changed, 1051 insertions, 944 deletions
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 68b5d18a093..61628aae535 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -67,8 +67,7 @@ ParticleCurveData::~ParticleCurveData()
curve_firstkey.clear();
curve_keynum.clear();
curve_length.clear();
- curve_u.clear();
- curve_v.clear();
+ curve_uv.clear();
curvekey_co.clear();
curvekey_time.clear();
@@ -78,13 +77,13 @@ void interp_weights(float t, float data[4], int type)
{
float t2, t3, fc;
- if (type == CURVE_LINEAR) {
+ if(type == CURVE_LINEAR) {
data[0] = 0.0f;
data[1] = -t + 1.0f;
data[2] = t;
data[3] = 0.0f;
}
- else if (type == CURVE_CARDINAL) {
+ else if(type == CURVE_CARDINAL) {
t2 = t * t;
t3 = t2 * t;
fc = 0.71f;
@@ -94,7 +93,7 @@ void interp_weights(float t, float data[4], int type)
data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
data[3] = fc * t3 - fc * t2;
}
- else if (type == CURVE_BSPLINE) {
+ else if(type == CURVE_BSPLINE) {
t2 = t * t;
t3 = t2 * t;
@@ -115,8 +114,8 @@ void curveinterp_v3_v3v3v3v3(float3 *p, float3 *v1, float3 *v2, float3 *v3, floa
float shaperadius(float shape, float root, float tip, float time)
{
float radius = 1.0f - time;
- if (shape != 0.0f) {
- if (shape < 0.0f)
+ if(shape != 0.0f) {
+ if(shape < 0.0f)
radius = (float)pow(1.0f - time, 1.f + shape);
else
radius = (float)pow(1.0f - time, 1.f / (1.f - shape));
@@ -133,10 +132,10 @@ void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyl
float3 ckey_loc3 = CData->curvekey_co[key+1];
float3 ckey_loc4 = ckey_loc3;
- if (key > CData->curve_firstkey[curve])
+ if(key > CData->curve_firstkey[curve])
ckey_loc1 = CData->curvekey_co[key - 1];
- if (key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)
+ if(key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)
ckey_loc4 = CData->curvekey_co[key + 2];
@@ -167,7 +166,7 @@ bool ObtainParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Particle
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())) {
+ if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
BL::ParticleSystemModifier psmd(b_mod->ptr);
@@ -213,7 +212,7 @@ bool ObtainParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Particle
float nco[3];
b_cKey->co_object( *b_ob, psmd, *b_pa, nco);
float3 cKey = make_float3(nco[0],nco[1],nco[2]);
- if (step_no > 0)
+ if(step_no > 0)
curve_length += len(cKey - pcKey);
CData->curvekey_co.push_back(cKey);
CData->curvekey_time.push_back(curve_length);
@@ -227,11 +226,10 @@ bool ObtainParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Particle
BL::Mesh::tessface_uv_textures_iterator l;
b_mesh->tessface_uv_textures.begin(l);
- float uvs[3] = {0,0};
+ float3 uv = make_float3(0.0f, 0.0f, 0.0f);
if(b_mesh->tessface_uv_textures.length())
- b_pa->uv_on_emitter(psmd,uvs);
- CData->curve_u.push_back(uvs[0]);
- CData->curve_v.push_back(uvs[1]);
+ b_pa->uv_on_emitter(psmd,&uv.x);
+ CData->curve_uv.push_back(uv);
curvenum++;
@@ -258,7 +256,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
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())) {
+ 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);
@@ -277,10 +275,10 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
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)
+ if(use_parents || b_psys.settings().child_type() == 0)
totcurves += totparts;
- if (totcurves == 0)
+ if(totcurves == 0)
continue;
PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles");
@@ -314,7 +312,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
b_psys.co_hair(*b_ob, psmd, pa_no, step_no, nco);
float3 cKey = make_float3(nco[0],nco[1],nco[2]);
cKey = transform_point(&itfm, cKey);
- if (step_no > 0)
+ if(step_no > 0)
curve_length += len(cKey - pcKey);
CData->curvekey_co.push_back(cKey);
CData->curvekey_time.push_back(curve_length);
@@ -327,17 +325,14 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
BL::Mesh::tessface_uv_textures_iterator l;
b_mesh->tessface_uv_textures.begin(l);
- float uvs[2] = {0,0};
+ float3 uv = make_float3(0.0f, 0.0f, 0.0f);
if(b_mesh->tessface_uv_textures.length())
- b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uvs);
-
+ b_psys.uv_on_emitter(psmd, *b_pa, pa_no, &uv.x);
+ CData->curve_uv.push_back(uv);
if(pa_no < totparts && b_pa != b_psys.particles.end())
++b_pa;
- CData->curve_u.push_back(uvs[0]);
- CData->curve_v.push_back(uvs[1]);
-
curvenum++;
}
@@ -365,11 +360,11 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpo
float3 v1;
- if (curvekey == CData->curve_firstkey[curve]) {
+ if(curvekey == CData->curve_firstkey[curve]) {
subv = 0;
v1 = CData->curvekey_co[curvekey+2] - 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] - 2)
v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 2];
else
v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1];
@@ -387,10 +382,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] - 2))
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] - 2) && (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));
@@ -408,7 +403,7 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpo
}
}
- mesh->reserve(mesh->verts.size(), mesh->triangles.size());
+ mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0);
mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
mesh->add_face_normals();
@@ -439,11 +434,11 @@ void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interp
float3 v1;
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];
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] - 2) {
v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[curvekey-2];
}
@@ -467,12 +462,12 @@ void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interp
float3 v2;
float3 xbasis;
- if (curvekey == CData->curve_firstkey[curve]) {
+ if(curvekey == CData->curve_firstkey[curve]) {
subv = 0;
v1 = CData->curvekey_co[curvekey+2] - 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] - 2) {
v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[curvekey-2];
}
@@ -502,10 +497,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] - 2))
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] - 2) && (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;
@@ -522,7 +517,7 @@ void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interp
}
}
- mesh->reserve(mesh->verts.size(), mesh->triangles.size());
+ mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0);
mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
mesh->add_face_normals();
@@ -553,11 +548,11 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter
float3 v1;
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];
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] - 2) {
v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[curvekey-2];
}
@@ -582,12 +577,12 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter
float3 v1;
float3 v2;
- if (curvekey == CData->curve_firstkey[curve]) {
+ if(curvekey == CData->curve_firstkey[curve]) {
subv = 0;
v1 = CData->curvekey_co[curvekey+2] - 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] - 2) {
v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[curvekey-2];
}
@@ -619,10 +614,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] - 2))
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] - 2) && (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;
@@ -645,7 +640,7 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter
}
}
- mesh->reserve(mesh->verts.size(), mesh->triangles.size());
+ mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0);
mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
mesh->add_face_normals();
@@ -661,9 +656,12 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
int curs = 0;
int segs = 0;
- if(!(mesh->curve_segs.empty() && mesh->curve_keys.empty() && mesh->curve_attrib.empty()))
+ if(!(mesh->curve_segments.empty() && mesh->curve_keys.empty()))
return;
+ Attribute *attr_uv = mesh->curve_attributes.add(ATTR_STD_UV);
+ Attribute *attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
+
for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
if(CData->psys_curvenum[sys] == 0)
@@ -677,7 +675,7 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
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])
+ if(curvekey == CData->curve_firstkey[curve])
subv = 0;
for (; subv <= segments; subv++) {
@@ -685,20 +683,22 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
float time = 0.0f;
- if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
+ if((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
ickey_loc = CData->curvekey_co[curvekey];
else
InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
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] - 2))
radius =0.0f;
- mesh->add_curvekey(ickey_loc, radius, time);
+ mesh->add_curve_key(ickey_loc, radius);
+ attr_intercept->add(time);
if(subv != 0) {
- mesh->add_curve(cks - 1, cks, CData->psys_shader[sys], curs);
+ attr_uv->add(CData->curve_uv[curve]);
+ mesh->add_curve_segment(cks - 1, cks, CData->psys_shader[sys], curs);
segs++;
}
@@ -706,18 +706,17 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
}
}
- mesh->add_curveattrib(CData->curve_u[curve], CData->curve_v[curve]);
curs++;
}
}
/* check allocation*/
- if((mesh->curve_keys.size() != cks) || (mesh->curve_segs.size() != segs) || (mesh->curve_attrib.size() != curs)) {
+ if((mesh->curve_keys.size() != cks) || (mesh->curve_segments.size() != segs)) {
/* allocation failed -> clear data */
mesh->curve_keys.clear();
- mesh->curve_segs.clear();
- mesh->curve_attrib.clear();
+ mesh->curve_segments.clear();
+ mesh->curve_attributes.clear();
}
}
@@ -734,7 +733,7 @@ void BlenderSync::sync_curve_settings()
curve_system_manager->use_curves = get_boolean(csscene, "use_curves");
- if (preset == CURVE_CUSTOM) {
+ if(preset == CURVE_CUSTOM) {
/*custom properties*/
curve_system_manager->primitive = get_enum(csscene, "primitive");
curve_system_manager->line_method = get_enum(csscene, "line_method");
@@ -824,15 +823,18 @@ void BlenderSync::sync_curve_settings()
void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool object_updated)
{
/* Clear stored curve data */
- mesh->curve_attrib.clear();
mesh->curve_keys.clear();
- mesh->curve_keysCD.clear();
- mesh->curve_segs.clear();
+ mesh->curve_segments.clear();
+ mesh->curve_attributes.clear();
/* obtain general settings */
bool use_curves = scene->curve_system_manager->use_curves;
- if(use_curves && b_ob.mode() == b_ob.mode_OBJECT) {
+ if(!(use_curves && b_ob.mode() == b_ob.mode_OBJECT)) {
+ mesh->compute_bounds();
+ return;
+ }
+
int primitive = scene->curve_system_manager->primitive;
int interpolation = scene->curve_system_manager->interpolation;
int triangle_method = scene->curve_system_manager->triangle_method;
@@ -845,12 +847,12 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
/* extract particle hair data - should be combined with connecting to mesh later*/
- ParticleCurveData *CData = new ParticleCurveData();
+ ParticleCurveData CData;
- if (use_cache)
- ObtainCacheParticleData(mesh, &b_mesh, &b_ob, CData, use_parents);
+ if(use_cache)
+ ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, use_parents);
else
- ObtainParticleData(mesh, &b_mesh, &b_ob, CData);
+ ObtainParticleData(mesh, &b_mesh, &b_ob, &CData);
/* attach strands to mesh */
BL::Object b_CamOb = b_scene.camera();
@@ -862,37 +864,33 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
RotCam = transform_point(&itfm, make_float3(ctfm.x.w, ctfm.y.w, ctfm.z.w));
}
- if (primitive == CURVE_TRIANGLES){
- if (triangle_method == CURVE_CAMERA)
- ExportCurveTrianglePlanes(mesh, CData, interpolation, use_smooth, segments, RotCam);
- else if (triangle_method == CURVE_RIBBONS)
- ExportCurveTriangleRibbons(mesh, CData, interpolation, use_smooth, segments);
+ if(primitive == CURVE_TRIANGLES){
+ if(triangle_method == CURVE_CAMERA)
+ ExportCurveTrianglePlanes(mesh, &CData, interpolation, use_smooth, segments, RotCam);
+ else if(triangle_method == CURVE_RIBBONS)
+ ExportCurveTriangleRibbons(mesh, &CData, interpolation, use_smooth, segments);
else
- ExportCurveTriangleGeometry(mesh, CData, interpolation, use_smooth, resolution, segments);
+ ExportCurveTriangleGeometry(mesh, &CData, interpolation, use_smooth, resolution, segments);
}
else {
- ExportCurveSegments(mesh, CData, interpolation, segments);
+ ExportCurveSegments(mesh, &CData, interpolation, segments);
int ckey_num = mesh->curve_keys.size();
/*export tangents or curve data? - not functional yet*/
- if (export_tgs && ckey_num > 1) {
+ if(export_tgs && ckey_num > 1) {
+ Attribute *attr_tangent = mesh->curve_attributes.add(ATTR_STD_CURVE_TANGENT);
+ float3 *data_tangent = attr_tangent->data_float3();
for(int ck = 0; ck < ckey_num; ck++) {
- Mesh::CurveData SCD;
- SCD.tg = normalize(normalize(mesh->curve_keys[min(ck + 1, ckey_num - 1)].loc - mesh->curve_keys[ck].loc) -
- normalize(mesh->curve_keys[max(ck - 1, 0)].loc - mesh->curve_keys[ck].loc));
- mesh->curve_keysCD.push_back(SCD);
+ float3 tg = normalize(normalize(mesh->curve_keys[min(ck + 1, ckey_num - 1)].co - mesh->curve_keys[ck].co) -
+ normalize(mesh->curve_keys[max(ck - 1, 0)].co - mesh->curve_keys[ck].co));
+
+ data_tangent[ck] = tg;
}
}
}
-
- delete CData;
-
- }
-
mesh->compute_bounds();
-
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index a01b2e9ee38..86f996320cb 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -147,7 +147,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
if(active_render)
attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
else
- attr = mesh->attributes.add(name, TypeDesc::TypeVector, Attribute::CORNER);
+ attr = mesh->attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
float3 *tangent = attr->data_float3();
@@ -161,7 +161,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
if(active_render)
attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
else
- attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, Attribute::CORNER);
+ attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
tangent_sign = attr_sign->data_float();
}
@@ -249,7 +249,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
continue;
Attribute *attr = mesh->attributes.add(
- ustring(l->name().c_str()), TypeDesc::TypeColor, Attribute::CORNER);
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER);
BL::MeshColorLayer::data_iterator c;
float3 *fdata = attr->data_float3();
@@ -288,7 +288,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
if(active_render)
attr = mesh->attributes.add(std, name);
else
- attr = mesh->attributes.add(name, TypeDesc::TypePoint, Attribute::CORNER);
+ attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
BL::MeshTextureFaceLayer::data_iterator t;
float3 *fdata = attr->data_float3();
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 102414e4a3d..0b43704b7b8 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -76,9 +76,7 @@ bool BVH::cache_read(CacheData& key)
key.add(ob->mesh->verts);
key.add(ob->mesh->triangles);
key.add(ob->mesh->curve_keys);
- key.add(ob->mesh->curve_keysCD);
- key.add(ob->mesh->curve_segs);
- key.add(ob->mesh->curve_attrib);
+ key.add(ob->mesh->curve_segments);
key.add(&ob->bounds, sizeof(ob->bounds));
key.add(&ob->visibility, sizeof(ob->visibility));
key.add(&ob->mesh->transform_applied, sizeof(bool));
@@ -278,34 +276,33 @@ void BVH::pack_curve_seg(int idx, float4 woop[3])
int tob = pack.prim_object[idx];
const Mesh *mesh = objects[tob]->mesh;
int tidx = pack.prim_index[idx];
- float3 v0 = mesh->curve_keys[mesh->curve_segs[tidx].v[0]].loc;
- float3 v1 = mesh->curve_keys[mesh->curve_segs[tidx].v[1]].loc;
- float t0 = mesh->curve_keys[mesh->curve_segs[tidx].v[0]].time;
- float t1 = mesh->curve_keys[mesh->curve_segs[tidx].v[1]].time;
+ float3 v0 = mesh->curve_keys[mesh->curve_segments[tidx].v[0]].co;
+ float3 v1 = mesh->curve_keys[mesh->curve_segments[tidx].v[1]].co;
float3 d0 = v1 - v0;
float l = len(d0);
- float u = mesh->curve_attrib[mesh->curve_segs[tidx].curve].uv[0];
- float v = mesh->curve_attrib[mesh->curve_segs[tidx].curve].uv[1];
-
/*Plan
*Transform tfm = make_transform(
* location <3> , l,
* extra curve data <3> , StrID,
- * nextkey, flags/tip?, r, t);
+ * nextkey, flags/tip?, 0, 0);
*/
- float3 tg1 = make_float3(1.0f,0.0f,0.0f);
- float3 tg2 = make_float3(1.0f,0.0f,0.0f);
- if(mesh->curve_keysCD.size()) {
- tg1 = mesh->curve_keysCD[mesh->curve_segs[tidx].v[0]].tg;
- tg2 = mesh->curve_keysCD[mesh->curve_segs[tidx].v[1]].tg;
+ Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT);
+ float3 tg1 = make_float3(1.0f, 0.0f, 0.0f);
+ float3 tg2 = make_float3(1.0f, 0.0f, 0.0f);
+
+ if(attr_tangent) {
+ const float3 *data_tangent = attr_tangent->data_float3();
+
+ tg1 = data_tangent[mesh->curve_segments[tidx].v[0]];
+ tg2 = data_tangent[mesh->curve_segments[tidx].v[1]];
}
Transform tfm = make_transform(
tg1.x, tg1.y, tg1.z, l,
tg2.x, tg2.y, tg2.z, 0,
- t0, t1, u, v,
+ 0, 0, 0, 0,
0, 0, 0, 1);
woop[0] = tfm.x;
@@ -628,10 +625,10 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
if(pack.prim_type[prim]) {
/* strands */
int str_offset = (params.top_level)? mesh->curveseg_offset: 0;
- const int *hidx = mesh->curve_segs[pidx - str_offset].v;
+ const int *hidx = mesh->curve_segments[pidx - str_offset].v;
- bbox.grow(mesh->curve_keys[hidx[0]].loc, mesh->curve_keys[hidx[0]].radius);
- bbox.grow(mesh->curve_keys[hidx[1]].loc, mesh->curve_keys[hidx[1]].radius);
+ bbox.grow(mesh->curve_keys[hidx[0]].co, mesh->curve_keys[hidx[0]].radius);
+ bbox.grow(mesh->curve_keys[hidx[1]].co, mesh->curve_keys[hidx[1]].radius);
}
else {
/* triangles */
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index cdd94324f53..665c783b2d8 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -85,12 +85,12 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
}
}
- for(uint j = 0; j < mesh->curve_segs.size(); j++) {
- Mesh::CurveSeg s = mesh->curve_segs[j];
+ for(uint j = 0; j < mesh->curve_segments.size(); j++) {
+ Mesh::CurveSegment s = mesh->curve_segments[j];
BoundBox bounds = BoundBox::empty;
for(int k = 0; k < 2; k++) {
- float3 pt = mesh->curve_keys[s.v[k]].loc;
+ float3 pt = mesh->curve_keys[s.v[k]].co;
bounds.grow(pt, mesh->curve_keys[s.v[k]].radius);
}
@@ -118,14 +118,14 @@ void BVHBuild::add_references(BVHRange& root)
if(params.top_level) {
if(ob->mesh->transform_applied) {
num_alloc_references += ob->mesh->triangles.size();
- num_alloc_references += ob->mesh->curve_segs.size();
+ num_alloc_references += ob->mesh->curve_segments.size();
}
else
num_alloc_references++;
}
else {
num_alloc_references += ob->mesh->triangles.size();
- num_alloc_references += ob->mesh->curve_segs.size();
+ num_alloc_references += ob->mesh->curve_segments.size();
}
}
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 860e2c8d7df..67fdfd77657 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -283,9 +283,9 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
else {
/* Strand split: NOTE - Currently ignores strand width and needs to be fixed.*/
- const int *inds = mesh->curve_segs[ref.prim_index()].v;
- const float3* v0 = &mesh->curve_keys[inds[0]].loc;
- const float3* v1 = &mesh->curve_keys[inds[1]].loc;
+ const int *inds = mesh->curve_segments[ref.prim_index()].v;
+ const float3* v0 = &mesh->curve_keys[inds[0]].co;
+ const float3* v1 = &mesh->curve_keys[inds[1]].co;
float v0p = (*v0)[dim];
float v1p = (*v1)[dim];
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index fde881c0a06..6d5b9a063a0 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -20,12 +20,12 @@ set(SRC
set(SRC_HEADERS
kernel.h
kernel_accumulate.h
- kernel_attribute.h
kernel_bvh.h
kernel_camera.h
kernel_compat_cpu.h
kernel_compat_cuda.h
kernel_compat_opencl.h
+ kernel_curve.h
kernel_differential.h
kernel_displace.h
kernel_emission.h
@@ -37,6 +37,7 @@ set(SRC_HEADERS
kernel_object.h
kernel_passes.h
kernel_path.h
+ kernel_primitive.h
kernel_projection.h
kernel_random.h
kernel_shader.h
diff --git a/intern/cycles/kernel/kernel_attribute.h b/intern/cycles/kernel/kernel_attribute.h
deleted file mode 100644
index b7ad731c883..00000000000
--- a/intern/cycles/kernel/kernel_attribute.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __KERNEL_ATTRIBUTE_CL__
-#define __KERNEL_ATTRIBUTE_CL__
-
-CCL_NAMESPACE_BEGIN
-
-/* note: declared in kernel.h, have to add it here because kernel.h is not available */
-bool kernel_osl_use(KernelGlobals *kg);
-
-__device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id)
-{
-#ifdef __OSL__
- if (kg->osl) {
- return OSLShader::find_attribute(kg, sd, id);
- }
- else
-#endif
- {
- /* for SVM, find attribute by unique id */
- uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id)
- attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
-
- /* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
- }
-}
-
-CCL_NAMESPACE_END
-
-#endif /* __KERNEL_ATTRIBUTE_CL__ */
diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h
index 15af35a05f8..d32287f91e8 100644
--- a/intern/cycles/kernel/kernel_bvh.h
+++ b/intern/cycles/kernel/kernel_bvh.h
@@ -214,13 +214,13 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
int flags = kernel_data.curve_kernel_data.curveflags;
int prim = kernel_tex_fetch(__prim_index, triAddr);
- float4 v00 = kernel_tex_fetch(__cur_segs, prim);
+ float4 v00 = kernel_tex_fetch(__curve_segments, prim);
int v1 = __float_as_int(v00.x);
int v2 = __float_as_int(v00.y);
- float4 P1 = kernel_tex_fetch(__cur_keys, v1);
- float4 P2 = kernel_tex_fetch(__cur_keys, v2);
+ float4 P1 = kernel_tex_fetch(__curve_keys, v1);
+ float4 P2 = kernel_tex_fetch(__curve_keys, v2);
float l = v00.w;
float r1 = P1.w;
@@ -720,13 +720,13 @@ __device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const
}
int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 v00 = kernel_tex_fetch(__cur_segs, prim);
+ float4 v00 = kernel_tex_fetch(__curve_segments, prim);
int v1 = __float_as_int(v00.x);
int v2 = __float_as_int(v00.y);
- float4 P1 = kernel_tex_fetch(__cur_keys, v1);
- float4 P2 = kernel_tex_fetch(__cur_keys, v2);
+ float4 P1 = kernel_tex_fetch(__curve_keys, v1);
+ float4 P2 = kernel_tex_fetch(__curve_keys, v2);
float l = v00.w;
float r1 = P1.w;
float r2 = P2.w;
diff --git a/intern/cycles/kernel/kernel_curve.h b/intern/cycles/kernel/kernel_curve.h
new file mode 100644
index 00000000000..fef1a48644d
--- /dev/null
+++ b/intern/cycles/kernel/kernel_curve.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+#ifdef __HAIR__
+
+/* curve attributes */
+
+__device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+ if(elem == ATTR_ELEMENT_CURVE_SEGMENT) {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+#endif
+
+ return kernel_tex_fetch(__attributes_float, offset + sd->curve_seg);
+ }
+ else if(elem == ATTR_ELEMENT_CURVE_KEY) {
+ float4 segment = kernel_tex_fetch(__curve_segments, sd->curve_seg);
+
+ float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(segment.x));
+ float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(segment.y));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*(f1 - f0);
+ if(dy) *dy = 0.0f;
+#endif
+
+ return (1.0f - sd->u)*f0 + sd->u*f1;
+ }
+ else {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+#endif
+
+ return 0.0f;
+ }
+}
+
+__device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+ if(elem == ATTR_ELEMENT_CURVE_SEGMENT) {
+ /* idea: we can't derive any useful differentials here, but for tiled
+ * mipmap image caching it would be useful to avoid reading the highest
+ * detail level always. maybe a derivative based on the hair density
+ * could be computed somehow? */
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->curve_seg));
+ }
+ else if(elem == ATTR_ELEMENT_CURVE_KEY) {
+ float4 segment = kernel_tex_fetch(__curve_segments, sd->curve_seg);
+
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(segment.x)));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(segment.y)));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*(f1 - f0);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return (1.0f - sd->u)*f0 + sd->u*f1;
+ }
+ else {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+/* hair info node functions */
+
+__device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
+{
+ int prim = sd->curve_seg;
+ float u = sd->u;
+ float r = 0.0f;
+
+ if(prim != -1) {
+ float4 v00 = kernel_tex_fetch(__curve_segments, prim);
+
+ int v1 = __float_as_int(v00.x);
+ int v2 = __float_as_int(v00.y);
+
+ float4 P1 = kernel_tex_fetch(__curve_keys, v1);
+ float4 P2 = kernel_tex_fetch(__curve_keys, v2);
+ r = (P2.w - P1.w) * u + P1.w;
+ }
+
+ return r*2.0f;
+}
+
+__device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
+{
+ float3 tgN = make_float3(0.0f,0.0f,0.0f);
+
+ if(sd->curve_seg != ~0) {
+ float normalmix = kernel_data.curve_kernel_data.normalmix;
+
+ tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * normalmix / len_squared(sd->dPdu)));
+ tgN = normalize(tgN);
+
+ /* need to find suitable scaled gd for corrected normal */
+#if 0
+ if (kernel_data.curve_kernel_data.use_tangent_normal_correction)
+ tgN = normalize(tgN - gd * sd->dPdu);
+#endif
+ }
+
+ return tgN;
+}
+
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 0f74ab75dd4..09ee1f68e12 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -333,14 +333,14 @@ __device void curve_seg_light_sample(KernelGlobals *kg, int prim, int object,
float randu, float randv, float time, LightSample *ls)
{
/* this strand code needs completion */
- float4 v00 = kernel_tex_fetch(__cur_segs, prim);
+ float4 v00 = kernel_tex_fetch(__curve_segments, prim);
int v1 = __float_as_int(v00.x);
int v2 = __float_as_int(v00.y);
float l = v00.w;
- float4 P1 = kernel_tex_fetch(__cur_keys, v1);
- float4 P2 = kernel_tex_fetch(__cur_keys, v2);
+ float4 P1 = kernel_tex_fetch(__curve_keys, v1);
+ float4 P2 = kernel_tex_fetch(__curve_keys, v2);
float r1 = P1.w;
float r2 = P2.w;
float3 tg = float4_to_float3(P2 - P1) / l;
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h
index 2260094aa70..40aa4753daa 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/kernel_object.h
@@ -288,55 +288,5 @@ __device float3 particle_angular_velocity(KernelGlobals *kg, int particle)
return make_float3(f3.z, f3.w, f4.x);
}
-#ifdef __HAIR__
-/* Hair Info Node fns */
-
-__device float hair_radius(KernelGlobals *kg, int prim, float u)
-{
- float r = 0.0f;
-
- if (prim != -1) {
- float4 v00 = kernel_tex_fetch(__cur_segs, prim);
-
- int v1 = __float_as_int(v00.x);
- int v2 = __float_as_int(v00.y);
-
- float4 P1 = kernel_tex_fetch(__cur_keys, v1);
- float4 P2 = kernel_tex_fetch(__cur_keys, v2);
- r = (P2.w - P1.w) * u + P1.w;
- }
-
- return r;
-}
-
-__device float3 hair_tangent_normal(KernelGlobals *kg, ShaderData *sd)
-{
- float3 tgN = make_float3(0.0f,0.0f,0.0f);
-
- if (sd->curve_seg != ~0) {
- tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * kernel_data.curve_kernel_data.normalmix / len_squared(sd->dPdu)));
- tgN = normalize(tgN);
- /*if (kernel_data.curve_kernel_data.use_tangent_normal_correction) need to find suitable scaled gd for corrected normal
- {
- tgN = normalize(tgN - gd * sd->dPdu);
- }*/
- }
-
- return tgN;
-}
-
-__device float intercept(KernelGlobals *kg, int prim, int triAddr, float u)
-{
- float t = 0.0f;
-
- if (prim != -1) {
- float4 sd2 = kernel_tex_fetch(__tri_woop, triAddr*3+2);
- t = (sd2.y - sd2.x) * u + sd2.x;
- }
-
- return t;
-}
-#endif
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index 7f8b611ba14..727639386ed 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -70,11 +70,11 @@ __device_inline void kernel_write_data_passes(KernelGlobals *kg, __global float
kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, sample, normal);
}
if(flag & PASS_UV) {
- float3 uv = triangle_uv(kg, sd);
+ float3 uv = primitive_uv(kg, sd);
kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, sample, uv);
}
if(flag & PASS_MOTION) {
- float4 speed = triangle_motion_vector(kg, sd);
+ float4 speed = primitive_motion_vector(kg, sd);
kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, sample, speed);
kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, sample, 1.0f);
}
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 8da21751cbe..20feaf50a2e 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -24,9 +24,10 @@
#include "kernel_montecarlo.h"
#include "kernel_projection.h"
#include "kernel_object.h"
-#include "kernel_attribute.h"
-#include "kernel_projection.h"
#include "kernel_triangle.h"
+#include "kernel_curve.h"
+#include "kernel_primitive.h"
+#include "kernel_projection.h"
#ifdef __QBVH__
#include "kernel_qbvh.h"
#else
diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/kernel_primitive.h
new file mode 100644
index 00000000000..2296017c686
--- /dev/null
+++ b/intern/cycles/kernel/kernel_primitive.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KERNEL_ATTRIBUTE_CL__
+#define __KERNEL_ATTRIBUTE_CL__
+
+CCL_NAMESPACE_BEGIN
+
+/* attribute lookup */
+
+__device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, AttributeElement *elem)
+{
+ if(sd->object == ~0)
+ return (int)ATTR_STD_NOT_FOUND;
+
+#ifdef __OSL__
+ if (kg->osl) {
+ return OSLShader::find_attribute(kg, sd, id, elem);
+ }
+ else
+#endif
+ {
+ /* for SVM, find attribute by unique id */
+ uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+ attr_offset = (sd->curve_seg == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while(attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
+
+ *elem = (AttributeElement)attr_map.y;
+
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+ }
+}
+
+__device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+#ifdef __HAIR__
+ if(sd->curve_seg == ~0)
+#endif
+ return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
+#ifdef __HAIR__
+ else
+ return curve_attribute_float(kg, sd, elem, offset, dx, dy);
+#endif
+}
+
+__device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+#ifdef __HAIR__
+ if(sd->curve_seg == ~0)
+#endif
+ return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
+#ifdef __HAIR__
+ else
+ return curve_attribute_float3(kg, sd, elem, offset, dx, dy);
+#endif
+}
+
+__device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
+{
+ AttributeElement elem_uv;
+ int offset_uv = find_attribute(kg, sd, ATTR_STD_UV, &elem_uv);
+
+ if(offset_uv == ATTR_STD_NOT_FOUND)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float3 uv = primitive_attribute_float3(kg, sd, elem_uv, offset_uv, NULL, NULL);
+ uv.z = 1.0f;
+ return uv;
+}
+
+__device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
+{
+#ifdef __HAIR__
+ if(sd->curve_seg != ~0)
+ return normalize(sd->dPdu);
+#endif
+
+ /* try to create spherical tangent from generated coordinates */
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED, &attr_elem);
+
+ if(attr_offset != ATTR_STD_NOT_FOUND) {
+ float3 data = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
+ data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
+ object_normal_transform(kg, sd, &data);
+ return cross(sd->N, normalize(cross(data, sd->N)));;
+ }
+ else {
+ /* otherwise use surface derivatives */
+ return normalize(sd->dPdu);
+ }
+}
+
+/* motion */
+
+__device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
+{
+ float3 motion_pre = sd->P, motion_post = sd->P;
+
+ /* deformation motion */
+ AttributeElement elem_pre, elem_post;
+ int offset_pre = find_attribute(kg, sd, ATTR_STD_MOTION_PRE, &elem_pre);
+ int offset_post = find_attribute(kg, sd, ATTR_STD_MOTION_POST, &elem_post);
+
+ if(offset_pre != ATTR_STD_NOT_FOUND)
+ motion_pre = primitive_attribute_float3(kg, sd, elem_pre, offset_pre, NULL, NULL);
+ if(offset_post != ATTR_STD_NOT_FOUND)
+ motion_post = primitive_attribute_float3(kg, sd, elem_post, offset_post, NULL, NULL);
+
+ /* object motion. note that depending on the mesh having motion vectors, this
+ * transformation was set match the world/object space of motion_pre/post */
+ Transform tfm;
+
+ tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_PRE);
+ motion_pre = transform_point(&tfm, motion_pre);
+
+ tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_POST);
+ motion_post = transform_point(&tfm, motion_post);
+
+ float3 P;
+
+ /* camera motion, for perspective/orthographic motion.pre/post will be a
+ * world-to-raster matrix, for panorama it's world-to-camera */
+ if (kernel_data.cam.type != CAMERA_PANORAMA) {
+ tfm = kernel_data.cam.worldtoraster;
+ P = transform_perspective(&tfm, sd->P);
+
+ tfm = kernel_data.cam.motion.pre;
+ motion_pre = transform_perspective(&tfm, motion_pre);
+
+ tfm = kernel_data.cam.motion.post;
+ motion_post = transform_perspective(&tfm, motion_post);
+ }
+ else {
+ tfm = kernel_data.cam.worldtocamera;
+ P = normalize(transform_point(&tfm, sd->P));
+ P = float2_to_float3(direction_to_panorama(kg, P));
+ P.x *= kernel_data.cam.width;
+ P.y *= kernel_data.cam.height;
+
+ tfm = kernel_data.cam.motion.pre;
+ motion_pre = normalize(transform_point(&tfm, motion_pre));
+ motion_pre = float2_to_float3(direction_to_panorama(kg, motion_pre));
+ motion_pre.x *= kernel_data.cam.width;
+ motion_pre.y *= kernel_data.cam.height;
+
+ tfm = kernel_data.cam.motion.post;
+ motion_post = normalize(transform_point(&tfm, motion_post));
+ motion_post = float2_to_float3(direction_to_panorama(kg, motion_post));
+ motion_post.x *= kernel_data.cam.width;
+ motion_post.y *= kernel_data.cam.height;
+ }
+
+ motion_pre = motion_pre - P;
+ motion_post = P - motion_post;
+
+ return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __KERNEL_ATTRIBUTE_CL__ */
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 652efa18b93..49bbc5a74ab 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -77,7 +77,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
#ifdef __HAIR__
if(kernel_tex_fetch(__prim_type, isect->prim)) {
/* Strand Shader setting*/
- float4 CurSeg = kernel_tex_fetch(__cur_segs, sd->prim);
+ float4 CurSeg = kernel_tex_fetch(__curve_segments, sd->prim);
sd->shader = __float_as_int(CurSeg.z);
sd->curve_seg = sd->prim;
@@ -788,7 +788,7 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
#ifdef __HAIR__
}
else {
- float4 str = kernel_tex_fetch(__cur_segs, prim);
+ float4 str = kernel_tex_fetch(__curve_segments, prim);
shader = __float_as_int(str.z);
}
#endif
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 0b6107b398e..072df21a188 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -44,8 +44,8 @@ KERNEL_TEX(float4, texture_float4, __tri_vindex)
KERNEL_TEX(float4, texture_float4, __tri_verts)
/* curves */
-KERNEL_TEX(float4, texture_float4, __cur_segs)
-KERNEL_TEX(float4, texture_float4, __cur_keys)
+KERNEL_TEX(float4, texture_float4, __curve_segments)
+KERNEL_TEX(float4, texture_float4, __curve_keys)
/* attributes */
KERNEL_TEX(uint4, texture_uint4, __attributes_map)
diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h
index 1f2618d3507..d346137760f 100644
--- a/intern/cycles/kernel/kernel_triangle.h
+++ b/intern/cycles/kernel/kernel_triangle.h
@@ -106,195 +106,88 @@ __device_inline void triangle_dPdudv(KernelGlobals *kg, float3 *dPdu, float3 *dP
__device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
{
-#ifdef __HAIR__
- if(sd->curve_seg == ~0) {
+ if(elem == ATTR_ELEMENT_FACE) {
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+
+ return kernel_tex_fetch(__attributes_float, offset + sd->prim);
+ }
+ else if(elem == ATTR_ELEMENT_VERTEX) {
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
+
+ float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.x));
+ float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.y));
+ float f2 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.z));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
+ if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
#endif
- if(elem == ATTR_ELEMENT_FACE) {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-
- return kernel_tex_fetch(__attributes_float, offset + sd->prim);
- }
- else if(elem == ATTR_ELEMENT_VERTEX) {
- float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
-
- float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.x));
- float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.y));
- float f2 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.z));
-
- #ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
- #endif
-
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else if(elem == ATTR_ELEMENT_CORNER) {
- int tri = offset + sd->prim*3;
- float f0 = kernel_tex_fetch(__attributes_float, tri + 0);
- float f1 = kernel_tex_fetch(__attributes_float, tri + 1);
- float f2 = kernel_tex_fetch(__attributes_float, tri + 2);
-
- #ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
- #endif
-
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else {
- if(dx) *dx = 0.0f;
- if(dy) *dy = 0.0f;
-
- return 0.0f;
- }
-#ifdef __HAIR__
+
+ return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
+ }
+ else if(elem == ATTR_ELEMENT_CORNER) {
+ int tri = offset + sd->prim*3;
+ float f0 = kernel_tex_fetch(__attributes_float, tri + 0);
+ float f1 = kernel_tex_fetch(__attributes_float, tri + 1);
+ float f2 = kernel_tex_fetch(__attributes_float, tri + 2);
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
+ if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
+#endif
+
+ return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
}
else {
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+
return 0.0f;
}
-#endif
}
__device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
{
-#ifdef __HAIR__
- if(sd->curve_seg == ~0) {
-#endif
- if(elem == ATTR_ELEMENT_FACE) {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-
- return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
- }
- else if(elem == ATTR_ELEMENT_VERTEX) {
- float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
-
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x)));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y)));
- float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z)));
-
- #ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
- #endif
-
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else if(elem == ATTR_ELEMENT_CORNER) {
- int tri = offset + sd->prim*3;
- float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0));
- float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1));
- float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2));
-
- #ifdef __RAY_DIFFERENTIALS__
- if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
- if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
- #endif
-
- return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
- }
- else {
- if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
- if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-
- return make_float3(0.0f, 0.0f, 0.0f);
- }
-#ifdef __HAIR__
- }
- else
- {
- return make_float3(0.0f, 0.0f, 0.0f);
- }
-#endif
-}
+ if(elem == ATTR_ELEMENT_FACE) {
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
-/* motion */
-
-__device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd)
-{
- float3 motion_pre = sd->P, motion_post = sd->P;
+ return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
+ }
+ else if(elem == ATTR_ELEMENT_VERTEX) {
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
- /* deformation motion */
- int offset_pre = find_attribute(kg, sd, ATTR_STD_MOTION_PRE);
- int offset_post = find_attribute(kg, sd, ATTR_STD_MOTION_POST);
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x)));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y)));
+ float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z)));
-#ifdef __HAIR__
- if(sd->curve_seg == ~0) {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
+ if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
#endif
- if(offset_pre != ATTR_STD_NOT_FOUND)
- motion_pre = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_pre, NULL, NULL);
- if(offset_post != ATTR_STD_NOT_FOUND)
- motion_post = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_post, NULL, NULL);
-#ifdef __HAIR__
+
+ return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
}
+ else if(elem == ATTR_ELEMENT_CORNER) {
+ int tri = offset + sd->prim*3;
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1));
+ float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
+ if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
#endif
- /* object motion. note that depending on the mesh having motion vectors, this
- * transformation was set match the world/object space of motion_pre/post */
- Transform tfm;
-
- tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_PRE);
- motion_pre = transform_point(&tfm, motion_pre);
-
- tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_POST);
- motion_post = transform_point(&tfm, motion_post);
-
- float3 P;
-
- /* camera motion, for perspective/orthographic motion.pre/post will be a
- * world-to-raster matrix, for panorama it's world-to-camera */
- if (kernel_data.cam.type != CAMERA_PANORAMA) {
- tfm = kernel_data.cam.worldtoraster;
- P = transform_perspective(&tfm, sd->P);
-
- tfm = kernel_data.cam.motion.pre;
- motion_pre = transform_perspective(&tfm, motion_pre);
-
- tfm = kernel_data.cam.motion.post;
- motion_post = transform_perspective(&tfm, motion_post);
+ return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
}
else {
- tfm = kernel_data.cam.worldtocamera;
- P = normalize(transform_point(&tfm, sd->P));
- P = float2_to_float3(direction_to_panorama(kg, P));
- P.x *= kernel_data.cam.width;
- P.y *= kernel_data.cam.height;
-
- tfm = kernel_data.cam.motion.pre;
- motion_pre = normalize(transform_point(&tfm, motion_pre));
- motion_pre = float2_to_float3(direction_to_panorama(kg, motion_pre));
- motion_pre.x *= kernel_data.cam.width;
- motion_pre.y *= kernel_data.cam.height;
-
- tfm = kernel_data.cam.motion.post;
- motion_post = normalize(transform_point(&tfm, motion_post));
- motion_post = float2_to_float3(direction_to_panorama(kg, motion_post));
- motion_post.x *= kernel_data.cam.width;
- motion_post.y *= kernel_data.cam.height;
- }
-
- motion_pre = motion_pre - P;
- motion_post = P - motion_post;
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
- return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
-}
-
-__device float3 triangle_uv(KernelGlobals *kg, ShaderData *sd)
-{
- int offset_uv = find_attribute(kg, sd, ATTR_STD_UV);
-
-#ifdef __HAIR__
- if(offset_uv == ATTR_STD_NOT_FOUND || sd->curve_seg != ~0)
return make_float3(0.0f, 0.0f, 0.0f);
-#else
- if(offset_uv == ATTR_STD_NOT_FOUND)
- return make_float3(0.0f, 0.0f, 0.0f);
-#endif
-
- float3 uv = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, offset_uv, NULL, NULL);
- uv.z = 1.0f;
- return uv;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index d051006f165..e80772bd4e2 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -348,14 +348,39 @@ typedef struct Intersection {
/* Attributes */
+#define ATTR_PRIM_TYPES 2
+#define ATTR_PRIM_CURVE 1
+
typedef enum AttributeElement {
+ ATTR_ELEMENT_NONE,
+ ATTR_ELEMENT_VALUE,
ATTR_ELEMENT_FACE,
ATTR_ELEMENT_VERTEX,
ATTR_ELEMENT_CORNER,
- ATTR_ELEMENT_VALUE,
- ATTR_ELEMENT_NONE
+ ATTR_ELEMENT_CURVE_SEGMENT,
+ ATTR_ELEMENT_CURVE_KEY
} AttributeElement;
+typedef enum AttributeStandard {
+ ATTR_STD_NONE = 0,
+ ATTR_STD_VERTEX_NORMAL,
+ ATTR_STD_FACE_NORMAL,
+ ATTR_STD_UV,
+ ATTR_STD_UV_TANGENT,
+ ATTR_STD_UV_TANGENT_SIGN,
+ ATTR_STD_GENERATED,
+ ATTR_STD_POSITION_UNDEFORMED,
+ ATTR_STD_POSITION_UNDISPLACED,
+ ATTR_STD_MOTION_PRE,
+ ATTR_STD_MOTION_POST,
+ ATTR_STD_PARTICLE,
+ ATTR_STD_CURVE_TANGENT,
+ ATTR_STD_CURVE_INTERCEPT,
+ ATTR_STD_NUM,
+
+ ATTR_STD_NOT_FOUND = ~0
+} AttributeStandard;
+
/* Closure data */
#define MAX_CLOSURE 8
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 64c4d109452..afa5211216b 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -37,9 +37,10 @@
#include "kernel_differential.h"
#include "kernel_object.h"
#include "kernel_bvh.h"
-#include "kernel_attribute.h"
-#include "kernel_projection.h"
#include "kernel_triangle.h"
+#include "kernel_curve.h"
+#include "kernel_primitive.h"
+#include "kernel_projection.h"
#include "kernel_accumulate.h"
#include "kernel_shader.h"
@@ -75,10 +76,9 @@ ustring OSLRenderServices::u_geom_trianglevertices("geom:trianglevertices");
ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices");
ustring OSLRenderServices::u_geom_name("geom:name");
#ifdef __HAIR__
-ustring OSLRenderServices::u_curve_is_strand("curve:is_strand");
-ustring OSLRenderServices::u_curve_intercept("curve:intercept");
-ustring OSLRenderServices::u_curve_thickness("curve:thickness");
-ustring OSLRenderServices::u_curve_tangent_normal("curve:tangent_normal");
+ustring OSLRenderServices::u_is_curve("geom:is_curve");
+ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness");
+ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
#endif
ustring OSLRenderServices::u_path_ray_length("path:ray_length");
ustring OSLRenderServices::u_trace("trace");
@@ -501,14 +501,14 @@ static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OS
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
{
float3 fval[3];
- fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ fval[0] = primitive_attribute_float3(kg, sd, attr.elem, attr.offset,
+ (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
return set_attribute_float3(fval, type, derivatives, val);
}
else if (attr.type == TypeDesc::TypeFloat) {
float fval[3];
- fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ fval[0] = primitive_attribute_float(kg, sd, attr.elem, attr.offset,
+ (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
return set_attribute_float(fval, type, derivatives, val);
}
else {
@@ -604,7 +604,8 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
else if (name == u_geom_numpolyvertices) {
return set_attribute_int(3, type, derivatives, val);
}
- else if (name == u_geom_trianglevertices || name == u_geom_polyvertices) {
+ else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices)
+ && sd->curve_seg == ~0) {
float3 P[3];
triangle_vertices(kg, sd->prim, P);
@@ -623,20 +624,16 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
#ifdef __HAIR__
/* Hair Attributes */
- else if (name == u_curve_is_strand) {
+ else if (name == u_is_curve) {
float f = !(sd->curve_seg == ~0);
return set_attribute_float(f, type, derivatives, val);
}
- else if (name == u_curve_intercept) {
- float f = intercept(kg, sd->curve_seg, sd->prim, sd->u);
- return set_attribute_float(f, type, derivatives, val);
- }
else if (name == u_curve_thickness) {
- float f = 2 * hair_radius(kg, sd->curve_seg, sd->u);
+ float f = curve_thickness(kg, sd);
return set_attribute_float(f, type, derivatives, val);
}
else if (name == u_curve_tangent_normal) {
- float3 f = hair_tangent_normal(kg, sd);
+ float3 f = curve_tangent_normal(kg, sd);
return set_attribute_float3(f, type, derivatives, val);
}
#endif
@@ -662,7 +659,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
{
KernelGlobals *kg = kernel_globals;
ShaderData *sd = (ShaderData *)renderstate;
- int object, tri;
+ int object, prim, curve_seg;
/* lookup of attribute on another object */
if (object_name != u_empty || sd == NULL) {
@@ -672,17 +669,20 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
return false;
object = it->second;
- tri = ~0;
+ prim = ~0;
+ curve_seg = ~0;
}
else {
object = sd->object;
- tri = sd->prim;
+ prim = sd->prim;
+ curve_seg = sd->curve_seg;
if (object == ~0)
return get_background_attribute(kg, sd, name, type, derivatives, val);
}
/* find attribute on object */
+ object = object*ATTR_PRIM_TYPES + (curve_seg != ~0);
OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
@@ -691,7 +691,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
if (attr.elem != ATTR_ELEMENT_VALUE) {
/* triangle and vertex attributes */
- if (tri != ~0)
+ if (prim != ~0)
return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
}
else {
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index 9b7c9a423ff..50c50b9952c 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -130,8 +130,7 @@ public:
static ustring u_geom_trianglevertices;
static ustring u_geom_polyvertices;
static ustring u_geom_name;
- static ustring u_curve_is_strand;
- static ustring u_curve_intercept;
+ static ustring u_is_curve;
static ustring u_curve_thickness;
static ustring u_curve_tangent_normal;
static ustring u_path_ray_length;
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 3ff032374fc..18486eba114 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -26,9 +26,10 @@
#include "osl_services.h"
#include "osl_shader.h"
-#include "util_attribute.h"
#include "util_foreach.h"
+#include "attribute.h"
+
#include <OSL/oslexec.h>
CCL_NAMESPACE_BEGIN
@@ -453,15 +454,17 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_
/* Attributes */
-int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)
+int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
{
/* for OSL, a hash map is used to lookup the attribute by name. */
- OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[sd->object];
- ustring stdname(std::string("std::") + std::string(attribute_standard_name((AttributeStandard)id)));
+ int object = sd->object*ATTR_PRIM_TYPES + (sd->curve_seg != ~0);
+ OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
+ ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
if (it != attr_map.end()) {
const OSLGlobals::Attribute &osl_attr = it->second;
+ *elem = osl_attr.elem;
/* return result */
return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset;
}
diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h
index 2e46a2de42c..2062c651162 100644
--- a/intern/cycles/kernel/osl/osl_shader.h
+++ b/intern/cycles/kernel/osl/osl_shader.h
@@ -74,7 +74,7 @@ public:
const float3 omega_in, const float3 omega_out);
/* attributes */
- static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id);
+ static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/shaders/node_hair_info.osl b/intern/cycles/kernel/shaders/node_hair_info.osl
index a44fc67f4bc..cbb3b98383f 100644
--- a/intern/cycles/kernel/shaders/node_hair_info.osl
+++ b/intern/cycles/kernel/shaders/node_hair_info.osl
@@ -24,9 +24,9 @@ shader node_hair_info(
output float Thickness = 0.0,
output normal TangentNormal = N)
{
- getattribute("curve:is_strand", IsStrand);
- getattribute("curve:intercept", Intercept);
- getattribute("curve:thickness", Thickness);
- getattribute("curve:tangent_normal", TangentNormal);
+ getattribute("geom:is_curve", IsStrand);
+ getattribute("geom:curve_intercept", Intercept);
+ getattribute("geom:curve_thickness", Thickness);
+ getattribute("geom:curve_tangent_normal", TangentNormal);
}
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index 4f9dc4af007..f11b69138d1 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -28,10 +28,13 @@ __device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
/* find attribute by unique id */
uint id = node.y;
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+ attr_offset = (sd->curve_seg == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id)
- attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
+
+ while(attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
/* return result */
*elem = (AttributeElement)attr_map.y;
@@ -58,45 +61,27 @@ __device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uin
svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
-#ifdef __HAIR__
- if (sd->curve_seg != ~0) {
- /*currently strand attributes aren't enabled - only exports stored uvs*/
- if(type == NODE_ATTR_FLOAT)
- stack_store_float(stack, out_offset, 0.0f);
+ /* fetch and store attribute */
+ if(type == NODE_ATTR_FLOAT) {
+ if(mesh_type == NODE_ATTR_FLOAT) {
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, NULL);
+ stack_store_float(stack, out_offset, f);
+ }
else {
- float4 sd2 = kernel_tex_fetch(__tri_woop, sd->prim*3+2);
- float3 uv = make_float3(sd2.z,sd2.w,0.0f);
- stack_store_float3(stack, out_offset, uv);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL);
+ stack_store_float(stack, out_offset, average(f));
}
}
- else
- {
-#endif
-
- /* fetch and store attribute */
- if(type == NODE_ATTR_FLOAT) {
- if(mesh_type == NODE_ATTR_FLOAT) {
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
- stack_store_float(stack, out_offset, f);
- }
- else {
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
- stack_store_float(stack, out_offset, average(f));
- }
+ else {
+ if(mesh_type == NODE_ATTR_FLOAT3) {
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL);
+ stack_store_float3(stack, out_offset, f);
}
else {
- if(mesh_type == NODE_ATTR_FLOAT3) {
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
- stack_store_float3(stack, out_offset, f);
- }
- else {
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
- stack_store_float3(stack, out_offset, make_float3(f, f, f));
- }
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, NULL);
+ stack_store_float3(stack, out_offset, make_float3(f, f, f));
}
-#ifdef __HAIR__
}
-#endif
}
__device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
@@ -109,43 +94,30 @@ __device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *st
svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
/* fetch and store attribute */
-#ifdef __HAIR__
- if (sd->curve_seg != ~0) {
- /*currently strand attributes aren't enabled*/
- if(type == NODE_ATTR_FLOAT)
- stack_store_float(stack, out_offset, 0.0f);
- else
- stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
+ if(type == NODE_ATTR_FLOAT) {
+ if(mesh_type == NODE_ATTR_FLOAT) {
+ float dx;
+ float f = primitive_attribute_float(kg, sd, elem, offset, &dx, NULL);
+ stack_store_float(stack, out_offset, f+dx);
+ }
+ else {
+ float3 dx;
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, NULL);
+ stack_store_float(stack, out_offset, average(f+dx));
+ }
}
else {
-#endif
- if(type == NODE_ATTR_FLOAT) {
- if(mesh_type == NODE_ATTR_FLOAT) {
- float dx;
- float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
- stack_store_float(stack, out_offset, f+dx);
- }
- else {
- float3 dx;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
- stack_store_float(stack, out_offset, average(f+dx));
- }
+ if(mesh_type == NODE_ATTR_FLOAT3) {
+ float3 dx;
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, NULL);
+ stack_store_float3(stack, out_offset, f+dx);
}
else {
- if(mesh_type == NODE_ATTR_FLOAT3) {
- float3 dx;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
- stack_store_float3(stack, out_offset, f+dx);
- }
- else {
- float dx;
- float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
- stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx));
- }
+ float dx;
+ float f = primitive_attribute_float(kg, sd, elem, offset, &dx, NULL);
+ stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx));
}
-#ifdef __HAIR__
}
-#endif
}
__device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
@@ -158,43 +130,30 @@ __device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *st
svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
/* fetch and store attribute */
-#ifdef __HAIR__
- if (sd->curve_seg != ~0) {
- /*currently strand attributes aren't enabled*/
- if(type == NODE_ATTR_FLOAT)
- stack_store_float(stack, out_offset, 0.0f);
- else
- stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
+ if(type == NODE_ATTR_FLOAT) {
+ if(mesh_type == NODE_ATTR_FLOAT) {
+ float dy;
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, &dy);
+ stack_store_float(stack, out_offset, f+dy);
+ }
+ else {
+ float3 dy;
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, &dy);
+ stack_store_float(stack, out_offset, average(f+dy));
+ }
}
else {
-#endif
- if(type == NODE_ATTR_FLOAT) {
- if(mesh_type == NODE_ATTR_FLOAT) {
- float dy;
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
- stack_store_float(stack, out_offset, f+dy);
- }
- else {
- float3 dy;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
- stack_store_float(stack, out_offset, average(f+dy));
- }
+ if(mesh_type == NODE_ATTR_FLOAT3) {
+ float3 dy;
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, &dy);
+ stack_store_float3(stack, out_offset, f+dy);
}
else {
- if(mesh_type == NODE_ATTR_FLOAT3) {
- float3 dy;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
- stack_store_float3(stack, out_offset, f+dy);
- }
- else {
- float dy;
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
- stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy));
- }
+ float dy;
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, &dy);
+ stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy));
}
-#ifdef __HAIR__
}
-#endif
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index e1b898e9b14..db8bbabe0ec 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -28,26 +28,7 @@ __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack,
case NODE_GEOM_P: data = sd->P; break;
case NODE_GEOM_N: data = sd->N; break;
#ifdef __DPDU__
- case NODE_GEOM_T: {
- /* try to create spherical tangent from generated coordinates */
- int attr_offset = (sd->object != ~0)? find_attribute(kg, sd, ATTR_STD_GENERATED): ATTR_STD_NOT_FOUND;
-#ifdef __HAIR__
- if(attr_offset != ATTR_STD_NOT_FOUND && sd->curve_seg == ~0) {
-#else
- if(attr_offset != ATTR_STD_NOT_FOUND) {
-#endif
- data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
- data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
- object_normal_transform(kg, sd, &data);
- data = cross(sd->N, normalize(cross(data, sd->N)));;
- }
- else {
- /* otherwise use surface derivatives */
- data = normalize(sd->dPdu);
- }
-
- break;
- }
+ case NODE_GEOM_T: data = primitive_tangent(kg, sd); break;
#endif
case NODE_GEOM_I: data = sd->I; break;
case NODE_GEOM_Ng: data = sd->Ng; break;
@@ -164,6 +145,7 @@ __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *s
}
#ifdef __HAIR__
+
/* Hair Info */
__device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
@@ -177,18 +159,15 @@ __device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *stack
stack_store_float(stack, out_offset, data);
break;
}
- case NODE_INFO_CURVE_INTERCEPT: {
- data = intercept(kg, sd->curve_seg, sd->prim, sd->u);
- stack_store_float(stack, out_offset, data);
- break;
- }
+ case NODE_INFO_CURVE_INTERCEPT:
+ break; /* handled as attribute */
case NODE_INFO_CURVE_THICKNESS: {
- data = 2 * hair_radius(kg, sd->curve_seg, sd->u);
+ data = curve_thickness(kg, sd);
stack_store_float(stack, out_offset, data);
break;
}
case NODE_INFO_CURVE_TANGENT_NORMAL: {
- data3 = hair_tangent_normal(kg, sd);
+ data3 = curve_tangent_normal(kg, sd);
stack_store_float3(stack, out_offset, data3);
break;
}
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 5e7c92ba93c..7a1af43b625 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -242,18 +242,15 @@ __device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stac
if(space == NODE_NORMAL_MAP_TANGENT) {
/* tangent space */
-#ifdef __HAIR__
- if(sd->object == ~0 || sd->curve_seg != ~0) {
-#else
- if(sd->object == ~0) {
-#endif
+ if(sd->object == ~0) {
stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
return;
}
/* first try to get tangent attribute */
- int attr_offset = find_attribute(kg, sd, node.z);
- int attr_sign_offset = find_attribute(kg, sd, node.w);
+ AttributeElement attr_elem, attr_sign_elem;
+ int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
+ int attr_sign_offset = find_attribute(kg, sd, node.w, &attr_sign_elem);
if(attr_offset == ATTR_STD_NOT_FOUND || attr_sign_offset == ATTR_STD_NOT_FOUND) {
stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
@@ -261,8 +258,8 @@ __device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stac
}
/* ensure orthogonal and normalized (interpolation breaks it) */
- float3 tangent = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
- float sign = triangle_attribute_float(kg, sd, ATTR_ELEMENT_CORNER, attr_sign_offset, NULL, NULL);
+ float3 tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
+ float sign = primitive_attribute_float(kg, sd, attr_sign_elem, attr_sign_offset, NULL, NULL);
object_normal_transform(kg, sd, &tangent);
tangent = cross(sd->N, normalize(cross(tangent, sd->N)));;
@@ -299,30 +296,24 @@ __device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack,
if(direction_type == NODE_TANGENT_UVMAP) {
/* UV map */
- int attr_offset = find_attribute(kg, sd, node.z);
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
-#ifdef __HAIR__
- if(attr_offset == ATTR_STD_NOT_FOUND || sd->curve_seg != ~0)
-#else
if(attr_offset == ATTR_STD_NOT_FOUND)
-#endif
tangent = make_float3(0.0f, 0.0f, 0.0f);
else
- tangent = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
+ tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
}
else {
/* radial */
- int attr_offset = find_attribute(kg, sd, node.z);
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
float3 generated;
-#ifdef __HAIR__
- if(attr_offset == ATTR_STD_NOT_FOUND || sd->curve_seg != ~0)
-#else
if(attr_offset == ATTR_STD_NOT_FOUND)
-#endif
generated = sd->P;
else
- generated = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
+ generated = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
if(axis == NODE_TANGENT_AXIS_X)
tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f));
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 95941c14b6c..758e4e5e820 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -26,7 +26,7 @@ CCL_NAMESPACE_BEGIN
/* Attribute */
-void Attribute::set(ustring name_, TypeDesc type_, Element element_)
+void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
{
name = name_;
type = type_;
@@ -39,12 +39,30 @@ void Attribute::set(ustring name_, TypeDesc type_, Element element_)
type == TypeDesc::TypeNormal);
}
-void Attribute::reserve(int numverts, int numtris)
+void Attribute::reserve(int numverts, int numtris, int numcurves, int numkeys)
{
- buffer.resize(buffer_size(numverts, numtris), 0);
+ buffer.resize(buffer_size(numverts, numtris, numcurves, numkeys), 0);
}
-size_t Attribute::data_sizeof()
+void Attribute::add(const float& f)
+{
+ char *data = (char*)&f;
+ size_t size = sizeof(f);
+
+ for(size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
+}
+
+void Attribute::add(const float3& f)
+{
+ char *data = (char*)&f;
+ size_t size = sizeof(f);
+
+ for(size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
+}
+
+size_t Attribute::data_sizeof() const
{
if(type == TypeDesc::TypeFloat)
return sizeof(float);
@@ -52,19 +70,27 @@ size_t Attribute::data_sizeof()
return sizeof(float3);
}
-size_t Attribute::element_size(int numverts, int numtris)
+size_t Attribute::element_size(int numverts, int numtris, int numcurves, int numkeys) const
{
- if(element == VERTEX)
+ if(element == ATTR_ELEMENT_VALUE)
+ return 1;
+ if(element == ATTR_ELEMENT_VERTEX)
return numverts;
- else if(element == FACE)
+ else if(element == ATTR_ELEMENT_FACE)
return numtris;
- else
+ else if(element == ATTR_ELEMENT_CORNER)
return numtris*3;
+ else if(element == ATTR_ELEMENT_CURVE_SEGMENT)
+ return numcurves;
+ else if(element == ATTR_ELEMENT_CURVE_KEY)
+ return numkeys;
+
+ return 0;
}
-size_t Attribute::buffer_size(int numverts, int numtris)
+size_t Attribute::buffer_size(int numverts, int numtris, int numcurves, int numkeys) const
{
- return element_size(numverts, numtris)*data_sizeof();
+ return element_size(numverts, numtris, numcurves, numkeys)*data_sizeof();
}
bool Attribute::same_storage(TypeDesc a, TypeDesc b)
@@ -84,18 +110,51 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b)
return false;
}
+const char *Attribute::standard_name(AttributeStandard std)
+{
+ if(std == ATTR_STD_VERTEX_NORMAL)
+ return "N";
+ else if(std == ATTR_STD_FACE_NORMAL)
+ return "Ng";
+ else if(std == ATTR_STD_UV)
+ return "uv";
+ else if(std == ATTR_STD_GENERATED)
+ return "generated";
+ else if(std == ATTR_STD_UV_TANGENT)
+ return "tangent";
+ else if(std == ATTR_STD_UV_TANGENT_SIGN)
+ return "tangent_sign";
+ else if(std == ATTR_STD_POSITION_UNDEFORMED)
+ return "undeformed";
+ else if(std == ATTR_STD_POSITION_UNDISPLACED)
+ return "undisplaced";
+ else if(std == ATTR_STD_MOTION_PRE)
+ return "motion_pre";
+ else if(std == ATTR_STD_MOTION_POST)
+ return "motion_post";
+ else if(std == ATTR_STD_PARTICLE)
+ return "particle";
+ else if(std == ATTR_STD_CURVE_TANGENT)
+ return "curve_tangent";
+ else if(std == ATTR_STD_CURVE_INTERCEPT)
+ return "curve_intercept";
+
+ return "";
+}
+
/* Attribute Set */
AttributeSet::AttributeSet()
{
- mesh = NULL;
+ triangle_mesh = NULL;
+ curve_mesh = NULL;
}
AttributeSet::~AttributeSet()
{
}
-Attribute *AttributeSet::add(ustring name, TypeDesc type, Attribute::Element element)
+Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement element)
{
Attribute *attr = find(name);
@@ -111,24 +170,22 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, Attribute::Element ele
attributes.push_back(Attribute());
attr = &attributes.back();
- if(element == Attribute::VERTEX)
- attr->set(name, type, element);
- else if(element == Attribute::FACE)
- attr->set(name, type, element);
- else if(element == Attribute::CORNER)
- attr->set(name, type, element);
+ attr->set(name, type, element);
- if(mesh)
- attr->reserve(mesh->verts.size(), mesh->triangles.size());
+ /* this is weak .. */
+ if(triangle_mesh)
+ attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
+ if(curve_mesh)
+ attr->reserve(0, 0, curve_mesh->curve_segments.size(), curve_mesh->curve_keys.size());
return attr;
}
-Attribute *AttributeSet::find(ustring name)
+Attribute *AttributeSet::find(ustring name) const
{
- foreach(Attribute& attr, attributes)
+ foreach(const Attribute& attr, attributes)
if(attr.name == name)
- return &attr;
+ return (Attribute*)&attr;
return NULL;
}
@@ -154,41 +211,59 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
Attribute *attr = NULL;
if(name == ustring())
- name = attribute_standard_name(std);
-
- if(std == ATTR_STD_VERTEX_NORMAL)
- attr = add(name, TypeDesc::TypeNormal, Attribute::VERTEX);
- else if(std == ATTR_STD_FACE_NORMAL)
- attr = add(name, TypeDesc::TypeNormal, Attribute::FACE);
- else if(std == ATTR_STD_UV)
- attr = add(name, TypeDesc::TypePoint, Attribute::CORNER);
- else if(std == ATTR_STD_UV_TANGENT)
- attr = add(name, TypeDesc::TypeVector, Attribute::CORNER);
- else if(std == ATTR_STD_UV_TANGENT_SIGN)
- attr = add(name, TypeDesc::TypeFloat, Attribute::CORNER);
- else if(std == ATTR_STD_GENERATED)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_POSITION_UNDEFORMED)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_POSITION_UNDISPLACED)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_MOTION_PRE)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_MOTION_POST)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else
- assert(0);
+ name = Attribute::standard_name(std);
+
+ if(triangle_mesh) {
+ if(std == ATTR_STD_VERTEX_NORMAL)
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_FACE_NORMAL)
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_FACE);
+ else if(std == ATTR_STD_UV)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
+ else if(std == ATTR_STD_UV_TANGENT)
+ attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
+ else if(std == ATTR_STD_UV_TANGENT_SIGN)
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
+ else if(std == ATTR_STD_GENERATED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_POSITION_UNDEFORMED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_POSITION_UNDISPLACED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_MOTION_PRE)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_MOTION_POST)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else
+ assert(0);
+ }
+ else if(curve_mesh) {
+ if(std == ATTR_STD_UV)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_SEGMENT);
+ else if(std == ATTR_STD_GENERATED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_SEGMENT);
+ else if(std == ATTR_STD_MOTION_PRE)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
+ else if(std == ATTR_STD_MOTION_POST)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
+ else if(std == ATTR_STD_CURVE_TANGENT)
+ attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CURVE_KEY);
+ else if(std == ATTR_STD_CURVE_INTERCEPT)
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY);
+ else
+ assert(0);
+ }
attr->std = std;
return attr;
}
-Attribute *AttributeSet::find(AttributeStandard std)
+Attribute *AttributeSet::find(AttributeStandard std) const
{
- foreach(Attribute& attr, attributes)
+ foreach(const Attribute& attr, attributes)
if(attr.std == std)
- return &attr;
+ return (Attribute*)&attr;
return NULL;
}
@@ -217,10 +292,14 @@ Attribute *AttributeSet::find(AttributeRequest& req)
return find(req.std);
}
-void AttributeSet::reserve(int numverts, int numtris)
+void AttributeSet::reserve()
{
- foreach(Attribute& attr, attributes)
- attr.reserve(numverts, numtris);
+ foreach(Attribute& attr, attributes) {
+ if(triangle_mesh)
+ attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
+ if(curve_mesh)
+ attr.reserve(0, 0, curve_mesh->curve_segments.size(), curve_mesh->curve_keys.size());
+ }
}
void AttributeSet::clear()
@@ -235,9 +314,13 @@ AttributeRequest::AttributeRequest(ustring name_)
name = name_;
std = ATTR_STD_NONE;
- type = TypeDesc::TypeFloat;
- element = ATTR_ELEMENT_NONE;
- offset = 0;
+ triangle_type = TypeDesc::TypeFloat;
+ triangle_element = ATTR_ELEMENT_NONE;
+ triangle_offset = 0;
+
+ curve_type = TypeDesc::TypeFloat;
+ curve_element = ATTR_ELEMENT_NONE;
+ curve_offset = 0;
}
AttributeRequest::AttributeRequest(AttributeStandard std_)
@@ -245,9 +328,13 @@ AttributeRequest::AttributeRequest(AttributeStandard std_)
name = ustring();
std = std_;
- type = TypeDesc::TypeFloat;
- element = ATTR_ELEMENT_NONE;
- offset = 0;
+ triangle_type = TypeDesc::TypeFloat;
+ triangle_element = ATTR_ELEMENT_NONE;
+ triangle_offset = 0;
+
+ curve_type = TypeDesc::TypeFloat;
+ curve_element = ATTR_ELEMENT_NONE;
+ curve_offset = 0;
}
/* AttributeRequestSet */
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index d05952edfd7..6c0c06d0425 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -21,7 +21,6 @@
#include "kernel_types.h"
-#include "util_attribute.h"
#include "util_list.h"
#include "util_param.h"
#include "util_types.h"
@@ -42,36 +41,34 @@ class Mesh;
class Attribute {
public:
- enum Element {
- VERTEX,
- FACE,
- CORNER
- };
-
ustring name;
AttributeStandard std;
TypeDesc type;
vector<char> buffer;
- Element element;
+ AttributeElement element;
Attribute() {}
- void set(ustring name, TypeDesc type, Element element);
- void reserve(int numverts, int numfaces);
+ void set(ustring name, TypeDesc type, AttributeElement element);
+ void reserve(int numverts, int numfaces, int numcurves, int numkeys);
- size_t data_sizeof();
- size_t element_size(int numverts, int numfaces);
- size_t buffer_size(int numverts, int numfaces);
+ size_t data_sizeof() const;
+ size_t element_size(int numverts, int numfaces, int numcurves, int numkeys) const;
+ size_t buffer_size(int numverts, int numfaces, int numcurves, int numkeys) const;
char *data() { return (buffer.size())? &buffer[0]: NULL; };
float3 *data_float3() { return (float3*)data(); }
float *data_float() { return (float*)data(); }
const char *data() const { return (buffer.size())? &buffer[0]: NULL; }
- const float3 *data_float3() const { return (float3*)data(); }
- const float *data_float() const { return (float*)data(); }
+ const float3 *data_float3() const { return (const float3*)data(); }
+ const float *data_float() const { return (const float*)data(); }
+
+ void add(const float& f);
+ void add(const float3& f);
static bool same_storage(TypeDesc a, TypeDesc b);
+ static const char *standard_name(AttributeStandard std);
};
/* Attribute Set
@@ -80,23 +77,24 @@ public:
class AttributeSet {
public:
- Mesh *mesh;
+ Mesh *triangle_mesh;
+ Mesh *curve_mesh;
list<Attribute> attributes;
AttributeSet();
~AttributeSet();
- Attribute *add(ustring name, TypeDesc type, Attribute::Element element);
- Attribute *find(ustring name);
+ Attribute *add(ustring name, TypeDesc type, AttributeElement element);
+ Attribute *find(ustring name) const;
void remove(ustring name);
Attribute *add(AttributeStandard std, ustring name = ustring());
- Attribute *find(AttributeStandard std);
+ Attribute *find(AttributeStandard std) const;
void remove(AttributeStandard std);
Attribute *find(AttributeRequest& req);
- void reserve(int numverts, int numfaces);
+ void reserve();
void clear();
};
@@ -104,7 +102,7 @@ public:
*
* Request from a shader to use a certain attribute, so we can figure out
* which ones we need to export from the host app end store for the kernel.
- * The attribute is found either by name or by standard. */
+ * The attribute is found either by name or by standard attribute type. */
class AttributeRequest {
public:
@@ -112,9 +110,9 @@ public:
AttributeStandard std;
/* temporary variables used by MeshManager */
- TypeDesc type;
- AttributeElement element;
- int offset;
+ TypeDesc triangle_type, curve_type;
+ AttributeElement triangle_element, curve_element;
+ int triangle_offset, curve_offset;
AttributeRequest(ustring name_);
AttributeRequest(AttributeStandard std);
diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h
index 581b3010d77..85a549082f2 100644
--- a/intern/cycles/render/curves.h
+++ b/intern/cycles/render/curves.h
@@ -80,8 +80,7 @@ public:
vector<int> curve_firstkey;
vector<int> curve_keynum;
vector<float> curve_length;
- vector<float> curve_u;
- vector<float> curve_v;
+ vector<float3> curve_uv;
vector<float3> curvekey_co;
vector<float> curvekey_time;
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 66e528c7230..cab6008dd7c 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -142,7 +142,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* count */
size_t num_lights = scene->lights.size();
size_t num_triangles = 0;
- size_t num_curve_segs = 0;
+ size_t num_curve_segments = 0;
foreach(Object *object, scene->objects) {
Mesh *mesh = object->mesh;
@@ -172,16 +172,16 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
}
/* disabled for strands*/
- /*for(size_t i = 0; i < mesh->curve_segs.size(); i++) {
- * Shader *shader = scene->shaders[mesh->curve_segs[i].curveshader];
+ /*for(size_t i = 0; i < mesh->curve_segments.size(); i++) {
+ * Shader *shader = scene->shaders[mesh->curve_segments[i].shader];
*
* if(shader->sample_as_light && shader->has_surface_emission)
- * num_curve_segs++;
+ * num_curve_segments++;
}*/
}
}
- size_t num_distribution = num_triangles + num_curve_segs;
+ size_t num_distribution = num_triangles + num_curve_segments;
num_distribution += num_lights;
/* emission area */
@@ -245,8 +245,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
}
/*sample as light disabled for strands*/
- /*for(size_t i = 0; i < mesh->curve_segs.size(); i++) {
- * Shader *shader = scene->shaders[mesh->curve_segs[i].curveshader];
+ /*for(size_t i = 0; i < mesh->curve_segments.size(); i++) {
+ * Shader *shader = scene->shaders[mesh->curve_segments[i].shader];
*
* if(shader->sample_as_light && shader->has_surface_emission) {
* distribution[offset].x = totarea;
@@ -255,7 +255,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
* distribution[offset].w = __int_as_float(object_id);
* offset++;
*
- * Mesh::CurveSeg s = mesh->curve_segs[i];
+ * Mesh::CurveSeg s = mesh->curve_segments[i];
* float3 p1 = mesh->curve_keys[s.v[0]].loc;
* float r1 = mesh->curve_keys[s.v[0]].radius;
* float3 p2 = mesh->curve_keys[s.v[1]].loc;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index b20e5cebdc5..53cae53ef69 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -54,7 +54,8 @@ Mesh::Mesh()
curveseg_offset = 0;
curvekey_offset = 0;
- attributes.mesh = this;
+ attributes.triangle_mesh = this;
+ curve_attributes.curve_mesh = this;
}
Mesh::~Mesh()
@@ -62,15 +63,18 @@ Mesh::~Mesh()
delete bvh;
}
-void Mesh::reserve(int numverts, int numtris)
+void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys)
{
/* reserve space to add verts and triangles later */
verts.resize(numverts);
triangles.resize(numtris);
shader.resize(numtris);
smooth.resize(numtris);
- /*currently no need in hair segment resize and curve data needs including*/
- attributes.reserve(numverts, numtris);
+ curve_keys.resize(numcurvekeys);
+ curve_segments.resize(numcurves);
+
+ attributes.reserve();
+ curve_attributes.reserve();
}
void Mesh::clear()
@@ -82,11 +86,10 @@ void Mesh::clear()
smooth.clear();
curve_keys.clear();
- curve_keysCD.clear();
- curve_segs.clear();
- curve_attrib.clear();
+ curve_segments.clear();
attributes.clear();
+ curve_attributes.clear();
used_shaders.clear();
transform_applied = false;
@@ -105,34 +108,24 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
smooth.push_back(smooth_);
}
-void Mesh::add_curvekey(float3 loc, float radius, float time)
+void Mesh::add_curve_key(float3 co, float radius)
{
CurveKey ck;
- ck.loc = loc;
+ ck.co = co;
ck.radius = radius;
- ck.time = time;
curve_keys.push_back(ck);
}
-void Mesh::add_curve(int v0, int v1, int shader, int curveid)
+void Mesh::add_curve_segment(int v0, int v1, int shader, int curveid)
{
- CurveSeg s;
+ CurveSegment s;
s.v[0] = v0;
s.v[1] = v1;
- s.curveshader = shader;
+ s.shader = shader;
s.curve = curveid;
- curve_segs.push_back(s);
-}
-
-void Mesh::add_curveattrib(float u, float v)
-{
- Curve_Attribute s;
- s.uv[0] = u;
- s.uv[1] = v;
-
- curve_attrib.push_back(s);
+ curve_segments.push_back(s);
}
void Mesh::compute_bounds()
@@ -145,7 +138,7 @@ void Mesh::compute_bounds()
bnds.grow(verts[i]);
for(size_t i = 0; i < curve_keys_size; i++)
- bnds.grow(curve_keys[i].loc, curve_keys[i].radius);
+ bnds.grow(curve_keys[i].co, curve_keys[i].radius);
/* happens mostly on empty meshes */
if(!bnds.valid())
@@ -296,29 +289,31 @@ void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_key
size_t curve_keys_size = curve_keys.size();
CurveKey *keys_ptr = NULL;
+ /* pack curve keys */
if(curve_keys_size) {
-
keys_ptr = &curve_keys[0];
for(size_t i = 0; i < curve_keys_size; i++) {
- float3 p = keys_ptr[i].loc;
- curve_key_co[i] = make_float4(p.x, p.y, p.z, keys_ptr[i].radius);
+ float3 p = keys_ptr[i].co;
+ float radius = keys_ptr[i].radius;
+
+ curve_key_co[i] = make_float4(p.x, p.y, p.z, radius);
}
}
- size_t curve_seg_num = curve_segs.size();
+ /* pack curve segments */
+ size_t curve_seg_num = curve_segments.size();
if(curve_seg_num) {
- CurveSeg *curve_ptr = &curve_segs[0];
-
+ CurveSegment *curve_ptr = &curve_segments[0];
int shader_id = 0;
for(size_t i = 0; i < curve_seg_num; i++) {
- CurveSeg s = curve_ptr[i];
- shader_id = scene->shader_manager->get_shader_id(s.curveshader, this, false);
+ CurveSegment s = curve_ptr[i];
+ shader_id = scene->shader_manager->get_shader_id(s.shader, this, false);
- float3 p1 = keys_ptr[s.v[0]].loc;
- float3 p2 = keys_ptr[s.v[1]].loc;
+ float3 p1 = keys_ptr[s.v[0]].co;
+ float3 p2 = keys_ptr[s.v[1]].co;
float length = len(p2 - p1);
curve_seg_keys[i] = make_float4(
@@ -414,7 +409,7 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
og->attribute_map.clear();
og->object_names.clear();
- og->attribute_map.resize(scene->objects.size());
+ og->attribute_map.resize(scene->objects.size()*ATTR_PRIM_TYPES);
for(size_t i = 0; i < scene->objects.size(); i++) {
/* set object name to object index map */
@@ -430,7 +425,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
osl_attr.elem = ATTR_ELEMENT_VALUE;
osl_attr.value = attr;
- og->attribute_map[i][attr.name()] = osl_attr;
+ og->attribute_map[i*ATTR_PRIM_TYPES][attr.name()] = osl_attr;
+ og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr;
}
/* find mesh attributes */
@@ -444,27 +440,46 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
/* set object attributes */
foreach(AttributeRequest& req, attributes.requests) {
- if(req.element == ATTR_ELEMENT_NONE)
- continue;
-
OSLGlobals::Attribute osl_attr;
- osl_attr.elem = req.element;
- osl_attr.offset = req.offset;
-
- if(req.type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if(req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(attribute_standard_name(req.std)));
- og->attribute_map[i][stdname] = osl_attr;
+ if(req.triangle_element != ATTR_ELEMENT_NONE) {
+ osl_attr.elem = req.triangle_element;
+ osl_attr.offset = req.triangle_offset;
+
+ if(req.triangle_type == TypeDesc::TypeFloat)
+ osl_attr.type = TypeDesc::TypeFloat;
+ else
+ osl_attr.type = TypeDesc::TypeColor;
+
+ if(req.std != ATTR_STD_NONE) {
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
+ og->attribute_map[i*ATTR_PRIM_TYPES][stdname] = osl_attr;
+ }
+ else if(req.name != ustring()) {
+ /* add lookup by mesh attribute name */
+ og->attribute_map[i*ATTR_PRIM_TYPES][req.name] = osl_attr;
+ }
}
- else if(req.name != ustring()) {
- /* add lookup by mesh attribute name */
- og->attribute_map[i][req.name] = osl_attr;
+
+ if(req.curve_element != ATTR_ELEMENT_NONE) {
+ osl_attr.elem = req.curve_element;
+ osl_attr.offset = req.curve_offset;
+
+ if(req.curve_type == TypeDesc::TypeFloat)
+ osl_attr.type = TypeDesc::TypeFloat;
+ else
+ osl_attr.type = TypeDesc::TypeColor;
+
+ if(req.std != ATTR_STD_NONE) {
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
+ og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr;
+ }
+ else if(req.name != ustring()) {
+ /* add lookup by mesh attribute name */
+ og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr;
+ }
}
}
}
@@ -480,7 +495,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
int attr_map_stride = 0;
for(size_t i = 0; i < scene->meshes.size(); i++)
- attr_map_stride = max(attr_map_stride, mesh_attributes[i].size()+1);
+ attr_map_stride = max(attr_map_stride, (mesh_attributes[i].size() + 1)*ATTR_PRIM_TYPES);
if(attr_map_stride == 0)
return;
@@ -491,12 +506,13 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
for(size_t i = 0; i < scene->objects.size(); i++) {
Object *object = scene->objects[i];
+ Mesh *mesh = object->mesh;
/* find mesh attributes */
size_t j;
for(j = 0; j < scene->meshes.size(); j++)
- if(scene->meshes[j] == object->mesh)
+ if(scene->meshes[j] == mesh)
break;
AttributeRequestSet& attributes = mesh_attributes[j];
@@ -512,14 +528,29 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
else
id = scene->shader_manager->get_attribute_id(req.std);
- attr_map[index].x = id;
- attr_map[index].y = req.element;
- attr_map[index].z = as_uint(req.offset);
+ if(mesh->triangles.size()) {
+ attr_map[index].x = id;
+ attr_map[index].y = req.triangle_element;
+ attr_map[index].z = as_uint(req.triangle_offset);
- if(req.type == TypeDesc::TypeFloat)
- attr_map[index].w = NODE_ATTR_FLOAT;
- else
- attr_map[index].w = NODE_ATTR_FLOAT3;
+ if(req.triangle_type == TypeDesc::TypeFloat)
+ attr_map[index].w = NODE_ATTR_FLOAT;
+ else
+ attr_map[index].w = NODE_ATTR_FLOAT3;
+ }
+
+ index++;
+
+ if(mesh->curve_segments.size()) {
+ attr_map[index].x = id;
+ attr_map[index].y = req.curve_element;
+ attr_map[index].z = as_uint(req.curve_offset);
+
+ if(req.curve_type == TypeDesc::TypeFloat)
+ attr_map[index].w = NODE_ATTR_FLOAT;
+ else
+ attr_map[index].w = NODE_ATTR_FLOAT3;
+ }
index++;
}
@@ -529,6 +560,15 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
attr_map[index].y = 0;
attr_map[index].z = 0;
attr_map[index].w = 0;
+
+ index++;
+
+ attr_map[index].x = ATTR_STD_NONE;
+ attr_map[index].y = 0;
+ attr_map[index].z = 0;
+ attr_map[index].w = 0;
+
+ index++;
}
/* copy to device */
@@ -536,6 +576,60 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
device->tex_alloc("__attributes_map", dscene->attributes_map);
}
+static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_float, vector<float4>& attr_float3,
+ Attribute *mattr, TypeDesc& type, int& offset, AttributeElement& element)
+{
+ if(mattr) {
+ /* store element and type */
+ element = mattr->element;
+ type = mattr->type;
+
+ /* store attribute data in arrays */
+ size_t size = mattr->element_size(
+ mesh->verts.size(),
+ mesh->triangles.size(),
+ mesh->curve_segments.size(),
+ mesh->curve_keys.size());
+
+ if(mattr->type == TypeDesc::TypeFloat) {
+ float *data = mattr->data_float();
+ offset = attr_float.size();
+
+ attr_float.resize(attr_float.size() + size);
+
+ for(size_t k = 0; k < size; k++)
+ attr_float[offset+k] = data[k];
+ }
+ else {
+ float3 *data = mattr->data_float3();
+ offset = attr_float3.size();
+
+ attr_float3.resize(attr_float3.size() + size);
+
+ for(size_t k = 0; k < size; k++)
+ attr_float3[offset+k] = float3_to_float4(data[k]);
+ }
+
+ /* mesh vertex/curve index is global, not per object, so we sneak
+ * a correction for that in here */
+ if(element == ATTR_ELEMENT_VERTEX)
+ offset -= mesh->vert_offset;
+ else if(element == ATTR_ELEMENT_FACE)
+ offset -= mesh->tri_offset;
+ else if(element == ATTR_ELEMENT_CORNER)
+ offset -= 3*mesh->tri_offset;
+ else if(element == ATTR_ELEMENT_CURVE_SEGMENT)
+ offset -= mesh->curveseg_offset;
+ else if(element == ATTR_ELEMENT_CURVE_KEY)
+ offset -= mesh->curvekey_offset;
+ }
+ else {
+ /* attribute not found */
+ element = ATTR_ELEMENT_NONE;
+ offset = 0;
+ }
+}
+
void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
progress.set_status("Updating Mesh", "Computing attributes");
@@ -569,66 +663,24 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
/* todo: we now store std and name attributes from requests even if
* they actually refer to the same mesh attributes, optimize */
foreach(AttributeRequest& req, attributes.requests) {
- Attribute *mattr = mesh->attributes.find(req);
-
- /* todo: get rid of this exception */
- if(!mattr && req.std == ATTR_STD_GENERATED) {
- mattr = mesh->attributes.add(ATTR_STD_GENERATED);
+ Attribute *triangle_mattr = mesh->attributes.find(req);
+ Attribute *curve_mattr = mesh->curve_attributes.find(req);
+
+ /* todo: get rid of this exception, it's only here for giving some
+ * working texture coordinate for subdivision as we can't preserve
+ * any attributes yet */
+ if(!triangle_mattr && req.std == ATTR_STD_GENERATED) {
+ triangle_mattr = mesh->attributes.add(ATTR_STD_GENERATED);
if(mesh->verts.size())
- memcpy(mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
+ memcpy(triangle_mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
}
- /* attribute not found */
- if(!mattr) {
- req.element = ATTR_ELEMENT_NONE;
- req.offset = 0;
- continue;
- }
-
- /* we abuse AttributeRequest to pass on info like element and
- * offset, it doesn't really make sense but is convenient */
-
- /* store element and type */
- if(mattr->element == Attribute::VERTEX)
- req.element = ATTR_ELEMENT_VERTEX;
- else if(mattr->element == Attribute::FACE)
- req.element = ATTR_ELEMENT_FACE;
- else if(mattr->element == Attribute::CORNER)
- req.element = ATTR_ELEMENT_CORNER;
-
- req.type = mattr->type;
-
- /* store attribute data in arrays */
- size_t size = mattr->element_size(mesh->verts.size(), mesh->triangles.size());
-
- if(mattr->type == TypeDesc::TypeFloat) {
- float *data = mattr->data_float();
- req.offset = attr_float.size();
-
- attr_float.resize(attr_float.size() + size);
-
- for(size_t k = 0; k < size; k++)
- attr_float[req.offset+k] = data[k];
- }
- else {
- float3 *data = mattr->data_float3();
- req.offset = attr_float3.size();
-
- attr_float3.resize(attr_float3.size() + size);
-
- for(size_t k = 0; k < size; k++)
- attr_float3[req.offset+k] = float3_to_float4(data[k]);
- }
-
- /* mesh vertex/triangle index is global, not per object, so we sneak
- * a correction for that in here */
- if(req.element == ATTR_ELEMENT_VERTEX)
- req.offset -= mesh->vert_offset;
- else if(mattr->element == Attribute::FACE)
- req.offset -= mesh->tri_offset;
- else if(mattr->element == Attribute::CORNER)
- req.offset -= 3*mesh->tri_offset;
+ update_attribute_element_offset(mesh, attr_float, attr_float3, triangle_mattr,
+ req.triangle_type, req.triangle_offset, req.triangle_element);
+ update_attribute_element_offset(mesh, attr_float, attr_float3, curve_mattr,
+ req.curve_type, req.curve_offset, req.curve_element);
+
if(progress.get_cancel()) return;
}
}
@@ -660,21 +712,21 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
size_t vert_size = 0;
size_t tri_size = 0;
- size_t CurveKey_size = 0;
+ size_t curve_key_size = 0;
size_t curve_seg_keys = 0;
foreach(Mesh *mesh, scene->meshes) {
mesh->vert_offset = vert_size;
mesh->tri_offset = tri_size;
- mesh->curvekey_offset = CurveKey_size;
+ mesh->curvekey_offset = curve_key_size;
mesh->curveseg_offset = curve_seg_keys;
vert_size += mesh->verts.size();
tri_size += mesh->triangles.size();
- CurveKey_size += mesh->curve_keys.size();
- curve_seg_keys += mesh->curve_segs.size();
+ curve_key_size += mesh->curve_keys.size();
+ curve_seg_keys += mesh->curve_segments.size();
}
if(tri_size != 0) {
@@ -705,16 +757,16 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
if(curve_seg_keys != 0) {
progress.set_status("Updating Mesh", "Copying Strands to device");
- float4 *cur_keys = dscene->cur_keys.resize(CurveKey_size);
- float4 *cur_segs = dscene->cur_segs.resize(curve_seg_keys);
+ float4 *curve_keys = dscene->curve_keys.resize(curve_key_size);
+ float4 *curve_segments = dscene->curve_segments.resize(curve_seg_keys);
foreach(Mesh *mesh, scene->meshes) {
- mesh->pack_curves(scene, &cur_keys[mesh->curvekey_offset], &cur_segs[mesh->curveseg_offset], mesh->curvekey_offset);
+ mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curve_segments[mesh->curveseg_offset], mesh->curvekey_offset);
if(progress.get_cancel()) return;
}
- device->tex_alloc("__cur_keys", dscene->cur_keys);
- device->tex_alloc("__cur_segs", dscene->cur_segs);
+ device->tex_alloc("__curve_keys", dscene->curve_keys);
+ device->tex_alloc("__curve_segments", dscene->curve_segments);
}
}
@@ -873,8 +925,8 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->tri_vnormal);
device->tex_free(dscene->tri_vindex);
device->tex_free(dscene->tri_verts);
- device->tex_free(dscene->cur_segs);
- device->tex_free(dscene->cur_keys);
+ device->tex_free(dscene->curve_segments);
+ device->tex_free(dscene->curve_keys);
device->tex_free(dscene->attributes_map);
device->tex_free(dscene->attributes_float);
device->tex_free(dscene->attributes_float3);
@@ -890,8 +942,8 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
dscene->tri_vnormal.clear();
dscene->tri_vindex.clear();
dscene->tri_verts.clear();
- dscene->cur_segs.clear();
- dscene->cur_keys.clear();
+ dscene->curve_segments.clear();
+ dscene->curve_keys.clear();
dscene->attributes_map.clear();
dscene->attributes_float.clear();
dscene->attributes_float3.clear();
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 24d3f02e082..ca8c755671f 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -50,26 +50,16 @@ public:
int v[3];
};
- /* Mesh Strand Data*/
- struct CurveSeg {
+ /* Mesh Curve */
+ struct CurveSegment {
int v[2];
- uint curveshader;
+ uint shader;
int curve;
};
- struct Curve_Attribute {
- float uv[2];
- };
-
struct CurveKey {
- float3 loc;
+ float3 co;
float radius;
- float time;
- };
-
- /*curve data for hair - currently only contains key tangent instead*/
- struct CurveData {
- float3 tg;
};
/* Displacement */
@@ -88,12 +78,11 @@ public:
vector<bool> smooth;
vector<CurveKey> curve_keys;
- vector<CurveData> curve_keysCD;
- vector<CurveSeg> curve_segs;
- vector<Curve_Attribute> curve_attrib;
+ vector<CurveSegment> curve_segments;
vector<uint> used_shaders;
AttributeSet attributes;
+ AttributeSet curve_attributes;
BoundBox bounds;
bool transform_applied;
@@ -116,12 +105,11 @@ public:
Mesh();
~Mesh();
- void reserve(int numverts, int numfaces);
+ void reserve(int numverts, int numfaces, int numcurves, int numcurvekeys);
void clear();
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
- void add_curvekey(float3 loc, float radius, float time);
- void add_curve(int v0, int v1, int shader, int curveid);
- void add_curveattrib(float u, float v);
+ void add_curve_key(float3 loc, float radius);
+ void add_curve_segment(int v0, int v1, int shader, int curveid);
void compute_bounds();
void add_face_normals();
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 13e9ae81cf0..14ef3c68ad3 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2251,6 +2251,16 @@ HairInfoNode::HairInfoNode()
add_output("Tangent Normal", SHADER_SOCKET_NORMAL);
}
+void HairInfoNode::attributes(AttributeRequestSet *attributes)
+{
+ ShaderOutput *intercept_out = output("Intercept");
+
+ if(!intercept_out->links.empty())
+ attributes->add(ATTR_STD_CURVE_INTERCEPT);
+
+ ShaderNode::attributes(attributes);
+}
+
void HairInfoNode::compile(SVMCompiler& compiler)
{
ShaderOutput *out;
@@ -2263,8 +2273,9 @@ void HairInfoNode::compile(SVMCompiler& compiler)
out = output("Intercept");
if(!out->links.empty()) {
+ int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
compiler.stack_assign(out);
- compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_INTERCEPT, out->stack_offset);
+ compiler.add_node(NODE_ATTR, attr, out->stack_offset, NODE_ATTR_FLOAT);
}
out = output("Thickness");
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index ee7afccb0e1..564ceee5a5b 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -334,6 +334,8 @@ public:
class HairInfoNode : public ShaderNode {
public:
SHADER_NODE_CLASS(HairInfoNode)
+
+ void attributes(AttributeRequestSet *attributes);
};
class ValueNode : public ShaderNode {
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 588b4d50e1b..4862b47c342 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -89,12 +89,9 @@ void Object::apply_transform()
mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
for(size_t i = 0; i < mesh->curve_keys.size(); i++)
- mesh->curve_keys[i].loc = transform_point(&tfm, mesh->curve_keys[i].loc);
-
- for(size_t i = 0; i < mesh->curve_keysCD.size(); i++)
- mesh->curve_keysCD[i].tg = transform_direction(&tfm, mesh->curve_keysCD[i].tg);
-
+ mesh->curve_keys[i].co = transform_point(&tfm, mesh->curve_keys[i].co);
+ Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT);
Attribute *attr_fN = mesh->attributes.find(ATTR_STD_FACE_NORMAL);
Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
@@ -119,6 +116,13 @@ void Object::apply_transform()
vN[i] = transform_direction(&ntfm, vN[i]);
}
+ if(attr_tangent) {
+ float3 *tangent = attr_tangent->data_float3();
+
+ for(size_t i = 0; i < mesh->curve_keys.size(); i++)
+ tangent[i] = transform_direction(&tfm, tangent[i]);
+ }
+
if(bounds.valid()) {
mesh->compute_bounds();
compute_bounds(false, 0.0f);
@@ -199,10 +203,10 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
surface_area += triangle_area(p1, p2, p3);
}
- foreach(Mesh::CurveSeg& t, mesh->curve_segs) {
- float3 p1 = mesh->curve_keys[t.v[0]].loc;
+ foreach(Mesh::CurveSegment& t, mesh->curve_segments) {
+ float3 p1 = mesh->curve_keys[t.v[0]].co;
float r1 = mesh->curve_keys[t.v[0]].radius;
- float3 p2 = mesh->curve_keys[t.v[1]].loc;
+ float3 p2 = mesh->curve_keys[t.v[1]].co;
float r2 = mesh->curve_keys[t.v[1]].radius;
/* currently ignores segment overlaps*/
@@ -225,10 +229,10 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
surface_area += triangle_area(p1, p2, p3);
}
- foreach(Mesh::CurveSeg& t, mesh->curve_segs) {
- float3 p1 = mesh->curve_keys[t.v[0]].loc;
+ foreach(Mesh::CurveSegment& t, mesh->curve_segments) {
+ float3 p1 = mesh->curve_keys[t.v[0]].co;
float r1 = mesh->curve_keys[t.v[0]].radius;
- float3 p2 = mesh->curve_keys[t.v[1]].loc;
+ float3 p2 = mesh->curve_keys[t.v[1]].co;
float r2 = mesh->curve_keys[t.v[1]].radius;
/* currently ignores segment overlaps*/
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 8b121d3b2fb..9490fd96be0 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -25,7 +25,6 @@
#include "kernel_types.h"
-#include "util_attribute.h"
#include "util_param.h"
#include "util_string.h"
#include "util_thread.h"
@@ -74,8 +73,8 @@ public:
device_vector<float4> tri_vindex;
device_vector<float4> tri_verts;
- device_vector<float4> cur_segs;
- device_vector<float4> cur_keys;
+ device_vector<float4> curve_segments;
+ device_vector<float4> curve_keys;
/* objects */
device_vector<float4> objects;
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 6920df9954c..48e6808bc38 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -47,7 +47,7 @@ void EdgeDice::reserve(int num_verts, int num_tris)
vert_offset = mesh->verts.size();
tri_offset = mesh->triangles.size();
- mesh->reserve(vert_offset + num_verts, tri_offset + num_tris);
+ mesh->reserve(vert_offset + num_verts, tri_offset + num_tris, 0, 0);
Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index dce417704cc..bcaaa9a71b9 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -9,7 +9,6 @@ set(INC_SYS
)
set(SRC
- util_attribute.cpp
util_cache.cpp
util_cuda.cpp
util_dynlib.cpp
@@ -33,7 +32,6 @@ endif()
set(SRC_HEADERS
util_algorithm.h
util_args.h
- util_attribute.h
util_boundbox.h
util_cache.h
util_cuda.h
diff --git a/intern/cycles/util/util_attribute.cpp b/intern/cycles/util/util_attribute.cpp
deleted file mode 100644
index 057fb6213e9..00000000000
--- a/intern/cycles/util/util_attribute.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "util_attribute.h"
-
-CCL_NAMESPACE_BEGIN
-
-const char *attribute_standard_name(AttributeStandard std)
-{
- if(std == ATTR_STD_VERTEX_NORMAL)
- return "N";
- else if(std == ATTR_STD_FACE_NORMAL)
- return "Ng";
- else if(std == ATTR_STD_UV)
- return "uv";
- else if(std == ATTR_STD_GENERATED)
- return "generated";
- else if(std == ATTR_STD_UV_TANGENT)
- return "tangent";
- else if(std == ATTR_STD_UV_TANGENT_SIGN)
- return "tangent_sign";
- else if(std == ATTR_STD_POSITION_UNDEFORMED)
- return "undeformed";
- else if(std == ATTR_STD_POSITION_UNDISPLACED)
- return "undisplaced";
- else if(std == ATTR_STD_MOTION_PRE)
- return "motion_pre";
- else if(std == ATTR_STD_MOTION_POST)
- return "motion_post";
- else if(std == ATTR_STD_PARTICLE)
- return "particle";
-
- return "";
-}
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_attribute.h b/intern/cycles/util/util_attribute.h
deleted file mode 100644
index 334864c7f44..00000000000
--- a/intern/cycles/util/util_attribute.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __UTIL_ATTRIBUTE_H__
-#define __UTIL_ATTRIBUTE_H__
-
-#include "util_types.h"
-
-CCL_NAMESPACE_BEGIN
-
-const char *attribute_standard_name(AttributeStandard std);
-
-CCL_NAMESPACE_END
-
-#endif /* __UTIL_ATTRIBUTE_H__ */
-
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index 00b6cf5c56e..bb6de1197e7 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -448,24 +448,6 @@ __device_inline int4 make_int4(const float3& f)
#endif
-typedef enum AttributeStandard {
- ATTR_STD_NONE = 0,
- ATTR_STD_VERTEX_NORMAL,
- ATTR_STD_FACE_NORMAL,
- ATTR_STD_UV,
- ATTR_STD_UV_TANGENT,
- ATTR_STD_UV_TANGENT_SIGN,
- ATTR_STD_GENERATED,
- ATTR_STD_POSITION_UNDEFORMED,
- ATTR_STD_POSITION_UNDISPLACED,
- ATTR_STD_MOTION_PRE,
- ATTR_STD_MOTION_POST,
- ATTR_STD_PARTICLE,
- ATTR_STD_NUM,
-
- ATTR_STD_NOT_FOUND = ~0
-} AttributeStandard;
-
CCL_NAMESPACE_END
#endif /* __UTIL_TYPES_H__ */