Cycles Hair: refactoring to store curves with the index of the first key and the
number of keys in the curve, rather than curve segments with the indices of two keys. ShaderData.segment now stores the segment number in the curve.
This commit is contained in:
@@ -652,11 +652,10 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter
|
|||||||
|
|
||||||
void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments)
|
void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments)
|
||||||
{
|
{
|
||||||
int cks = 0;
|
int num_keys = 0;
|
||||||
int curs = 0;
|
int num_curves = 0;
|
||||||
int segs = 0;
|
|
||||||
|
|
||||||
if(!(mesh->curve_segments.empty() && mesh->curve_keys.empty()))
|
if(!(mesh->curves.empty() && mesh->curve_keys.empty()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Attribute *attr_uv = mesh->curve_attributes.add(ATTR_STD_UV);
|
Attribute *attr_uv = mesh->curve_attributes.add(ATTR_STD_UV);
|
||||||
@@ -672,6 +671,8 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
|
|||||||
if(CData->curve_keynum[curve] <= 1)
|
if(CData->curve_keynum[curve] <= 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
size_t num_curve_keys = 0;
|
||||||
|
|
||||||
for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
|
for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
|
||||||
|
|
||||||
int subv = 1;
|
int subv = 1;
|
||||||
@@ -696,26 +697,23 @@ void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation
|
|||||||
mesh->add_curve_key(ickey_loc, radius);
|
mesh->add_curve_key(ickey_loc, radius);
|
||||||
attr_intercept->add(time);
|
attr_intercept->add(time);
|
||||||
|
|
||||||
if(subv != 0) {
|
num_curve_keys++;
|
||||||
attr_uv->add(CData->curve_uv[curve]);
|
|
||||||
mesh->add_curve_segment(cks - 1, cks, CData->psys_shader[sys], curs);
|
|
||||||
segs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cks++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curs++;
|
mesh->add_curve(num_keys, num_curve_keys, CData->psys_shader[sys]);
|
||||||
|
attr_uv->add(CData->curve_uv[curve]);
|
||||||
|
|
||||||
|
num_keys += num_curve_keys;
|
||||||
|
num_curves++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check allocation*/
|
/* check allocation*/
|
||||||
if((mesh->curve_keys.size() != cks) || (mesh->curve_segments.size() != segs)) {
|
if((mesh->curve_keys.size() != num_keys) || (mesh->curves.size() != num_curves)) {
|
||||||
/* allocation failed -> clear data */
|
/* allocation failed -> clear data */
|
||||||
mesh->curve_keys.clear();
|
mesh->curve_keys.clear();
|
||||||
mesh->curve_segments.clear();
|
mesh->curves.clear();
|
||||||
mesh->curve_attributes.clear();
|
mesh->curve_attributes.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -824,7 +822,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool
|
|||||||
{
|
{
|
||||||
/* Clear stored curve data */
|
/* Clear stored curve data */
|
||||||
mesh->curve_keys.clear();
|
mesh->curve_keys.clear();
|
||||||
mesh->curve_segments.clear();
|
mesh->curves.clear();
|
||||||
mesh->curve_attributes.clear();
|
mesh->curve_attributes.clear();
|
||||||
|
|
||||||
/* obtain general settings */
|
/* obtain general settings */
|
||||||
|
@@ -76,7 +76,7 @@ bool BVH::cache_read(CacheData& key)
|
|||||||
key.add(ob->mesh->verts);
|
key.add(ob->mesh->verts);
|
||||||
key.add(ob->mesh->triangles);
|
key.add(ob->mesh->triangles);
|
||||||
key.add(ob->mesh->curve_keys);
|
key.add(ob->mesh->curve_keys);
|
||||||
key.add(ob->mesh->curve_segments);
|
key.add(ob->mesh->curves);
|
||||||
key.add(&ob->bounds, sizeof(ob->bounds));
|
key.add(&ob->bounds, sizeof(ob->bounds));
|
||||||
key.add(&ob->visibility, sizeof(ob->visibility));
|
key.add(&ob->visibility, sizeof(ob->visibility));
|
||||||
key.add(&ob->mesh->transform_applied, sizeof(bool));
|
key.add(&ob->mesh->transform_applied, sizeof(bool));
|
||||||
@@ -93,7 +93,7 @@ bool BVH::cache_read(CacheData& key)
|
|||||||
value.read(pack.nodes);
|
value.read(pack.nodes);
|
||||||
value.read(pack.object_node);
|
value.read(pack.object_node);
|
||||||
value.read(pack.tri_woop);
|
value.read(pack.tri_woop);
|
||||||
value.read(pack.prim_type);
|
value.read(pack.prim_segment);
|
||||||
value.read(pack.prim_visibility);
|
value.read(pack.prim_visibility);
|
||||||
value.read(pack.prim_index);
|
value.read(pack.prim_index);
|
||||||
value.read(pack.prim_object);
|
value.read(pack.prim_object);
|
||||||
@@ -115,7 +115,7 @@ void BVH::cache_write(CacheData& key)
|
|||||||
value.add(pack.nodes);
|
value.add(pack.nodes);
|
||||||
value.add(pack.object_node);
|
value.add(pack.object_node);
|
||||||
value.add(pack.tri_woop);
|
value.add(pack.tri_woop);
|
||||||
value.add(pack.prim_type);
|
value.add(pack.prim_segment);
|
||||||
value.add(pack.prim_visibility);
|
value.add(pack.prim_visibility);
|
||||||
value.add(pack.prim_index);
|
value.add(pack.prim_index);
|
||||||
value.add(pack.prim_object);
|
value.add(pack.prim_object);
|
||||||
@@ -161,11 +161,11 @@ void BVH::build(Progress& progress)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* build nodes */
|
/* build nodes */
|
||||||
vector<int> prim_type;
|
vector<int> prim_segment;
|
||||||
vector<int> prim_index;
|
vector<int> prim_index;
|
||||||
vector<int> prim_object;
|
vector<int> prim_object;
|
||||||
|
|
||||||
BVHBuild bvh_build(objects, prim_type, prim_index, prim_object, params, progress);
|
BVHBuild bvh_build(objects, prim_segment, prim_index, prim_object, params, progress);
|
||||||
BVHNode *root = bvh_build.run();
|
BVHNode *root = bvh_build.run();
|
||||||
|
|
||||||
if(progress.get_cancel()) {
|
if(progress.get_cancel()) {
|
||||||
@@ -174,7 +174,7 @@ void BVH::build(Progress& progress)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* todo: get rid of this copy */
|
/* todo: get rid of this copy */
|
||||||
pack.prim_type = prim_type;
|
pack.prim_segment = prim_segment;
|
||||||
pack.prim_index = prim_index;
|
pack.prim_index = prim_index;
|
||||||
pack.prim_object = prim_object;
|
pack.prim_object = prim_object;
|
||||||
|
|
||||||
@@ -271,13 +271,16 @@ void BVH::pack_triangle(int idx, float4 woop[3])
|
|||||||
|
|
||||||
/* Curves*/
|
/* Curves*/
|
||||||
|
|
||||||
void BVH::pack_curve_seg(int idx, float4 woop[3])
|
void BVH::pack_curve_segment(int idx, float4 woop[3])
|
||||||
{
|
{
|
||||||
int tob = pack.prim_object[idx];
|
int tob = pack.prim_object[idx];
|
||||||
const Mesh *mesh = objects[tob]->mesh;
|
const Mesh *mesh = objects[tob]->mesh;
|
||||||
int tidx = pack.prim_index[idx];
|
int tidx = pack.prim_index[idx];
|
||||||
float3 v0 = mesh->curve_keys[mesh->curve_segments[tidx].v[0]].co;
|
int segment = pack.prim_segment[idx];
|
||||||
float3 v1 = mesh->curve_keys[mesh->curve_segments[tidx].v[1]].co;
|
int k0 = mesh->curves[tidx].first_key + segment;
|
||||||
|
int k1 = mesh->curves[tidx].first_key + segment + 1;
|
||||||
|
float3 v0 = mesh->curve_keys[k0].co;
|
||||||
|
float3 v1 = mesh->curve_keys[k1].co;
|
||||||
|
|
||||||
float3 d0 = v1 - v0;
|
float3 d0 = v1 - v0;
|
||||||
float l = len(d0);
|
float l = len(d0);
|
||||||
@@ -289,19 +292,19 @@ void BVH::pack_curve_seg(int idx, float4 woop[3])
|
|||||||
* nextkey, flags/tip?, 0, 0);
|
* nextkey, flags/tip?, 0, 0);
|
||||||
*/
|
*/
|
||||||
Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT);
|
Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT);
|
||||||
|
float3 tg0 = make_float3(1.0f, 0.0f, 0.0f);
|
||||||
float3 tg1 = make_float3(1.0f, 0.0f, 0.0f);
|
float3 tg1 = make_float3(1.0f, 0.0f, 0.0f);
|
||||||
float3 tg2 = make_float3(1.0f, 0.0f, 0.0f);
|
|
||||||
|
|
||||||
if(attr_tangent) {
|
if(attr_tangent) {
|
||||||
const float3 *data_tangent = attr_tangent->data_float3();
|
const float3 *data_tangent = attr_tangent->data_float3();
|
||||||
|
|
||||||
tg1 = data_tangent[mesh->curve_segments[tidx].v[0]];
|
tg0 = data_tangent[k0];
|
||||||
tg2 = data_tangent[mesh->curve_segments[tidx].v[1]];
|
tg1 = data_tangent[k1];
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform tfm = make_transform(
|
Transform tfm = make_transform(
|
||||||
tg1.x, tg1.y, tg1.z, l,
|
tg0.x, tg0.y, tg0.z, l,
|
||||||
tg2.x, tg2.y, tg2.z, 0,
|
tg1.x, tg1.y, tg1.z, 0,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
|
|
||||||
@@ -325,8 +328,8 @@ void BVH::pack_primitives()
|
|||||||
if(pack.prim_index[i] != -1) {
|
if(pack.prim_index[i] != -1) {
|
||||||
float4 woop[3];
|
float4 woop[3];
|
||||||
|
|
||||||
if(pack.prim_type[i])
|
if(pack.prim_segment[i] != ~0)
|
||||||
pack_curve_seg(i, woop);
|
pack_curve_segment(i, woop);
|
||||||
else
|
else
|
||||||
pack_triangle(i, woop);
|
pack_triangle(i, woop);
|
||||||
|
|
||||||
@@ -353,8 +356,8 @@ void BVH::pack_instances(size_t nodes_size)
|
|||||||
* meshes with transform applied and already in the top level BVH */
|
* meshes with transform applied and already in the top level BVH */
|
||||||
for(size_t i = 0; i < pack.prim_index.size(); i++)
|
for(size_t i = 0; i < pack.prim_index.size(); i++)
|
||||||
if(pack.prim_index[i] != -1) {
|
if(pack.prim_index[i] != -1) {
|
||||||
if(pack.prim_type[i])
|
if(pack.prim_segment[i] != ~0)
|
||||||
pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curveseg_offset;
|
pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
|
||||||
else
|
else
|
||||||
pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
|
pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
|
||||||
}
|
}
|
||||||
@@ -395,7 +398,7 @@ void BVH::pack_instances(size_t nodes_size)
|
|||||||
mesh_map.clear();
|
mesh_map.clear();
|
||||||
|
|
||||||
pack.prim_index.resize(prim_index_size);
|
pack.prim_index.resize(prim_index_size);
|
||||||
pack.prim_type.resize(prim_index_size);
|
pack.prim_segment.resize(prim_index_size);
|
||||||
pack.prim_object.resize(prim_index_size);
|
pack.prim_object.resize(prim_index_size);
|
||||||
pack.prim_visibility.resize(prim_index_size);
|
pack.prim_visibility.resize(prim_index_size);
|
||||||
pack.tri_woop.resize(tri_woop_size);
|
pack.tri_woop.resize(tri_woop_size);
|
||||||
@@ -403,7 +406,7 @@ void BVH::pack_instances(size_t nodes_size)
|
|||||||
pack.object_node.resize(objects.size());
|
pack.object_node.resize(objects.size());
|
||||||
|
|
||||||
int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
|
int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
|
||||||
int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
|
int *pack_prim_segment = (pack.prim_segment.size())? &pack.prim_segment[0]: NULL;
|
||||||
int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
|
int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
|
||||||
uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL;
|
uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL;
|
||||||
float4 *pack_tri_woop = (pack.tri_woop.size())? &pack.tri_woop[0]: NULL;
|
float4 *pack_tri_woop = (pack.tri_woop.size())? &pack.tri_woop[0]: NULL;
|
||||||
@@ -434,7 +437,7 @@ void BVH::pack_instances(size_t nodes_size)
|
|||||||
|
|
||||||
int noffset = nodes_offset/nsize;
|
int noffset = nodes_offset/nsize;
|
||||||
int mesh_tri_offset = mesh->tri_offset;
|
int mesh_tri_offset = mesh->tri_offset;
|
||||||
int mesh_curve_offset = mesh->curveseg_offset;
|
int mesh_curve_offset = mesh->curve_offset;
|
||||||
|
|
||||||
/* fill in node indexes for instances */
|
/* fill in node indexes for instances */
|
||||||
if((bvh->pack.is_leaf.size() != 0) && bvh->pack.is_leaf[0])
|
if((bvh->pack.is_leaf.size() != 0) && bvh->pack.is_leaf[0])
|
||||||
@@ -448,16 +451,16 @@ void BVH::pack_instances(size_t nodes_size)
|
|||||||
if(bvh->pack.prim_index.size()) {
|
if(bvh->pack.prim_index.size()) {
|
||||||
size_t bvh_prim_index_size = bvh->pack.prim_index.size();
|
size_t bvh_prim_index_size = bvh->pack.prim_index.size();
|
||||||
int *bvh_prim_index = &bvh->pack.prim_index[0];
|
int *bvh_prim_index = &bvh->pack.prim_index[0];
|
||||||
int *bvh_prim_type = &bvh->pack.prim_type[0];
|
int *bvh_prim_segment = &bvh->pack.prim_segment[0];
|
||||||
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
|
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
|
||||||
|
|
||||||
for(size_t i = 0; i < bvh_prim_index_size; i++) {
|
for(size_t i = 0; i < bvh_prim_index_size; i++) {
|
||||||
if(bvh->pack.prim_type[i])
|
if(bvh->pack.prim_segment[i] != ~0)
|
||||||
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
|
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
|
||||||
else
|
else
|
||||||
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
|
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
|
||||||
|
|
||||||
pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
|
pack_prim_segment[pack_prim_index_offset] = bvh_prim_segment[i];
|
||||||
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
|
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
|
||||||
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
|
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
|
||||||
pack_prim_index_offset++;
|
pack_prim_index_offset++;
|
||||||
@@ -622,13 +625,14 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
|
|||||||
/* primitives */
|
/* primitives */
|
||||||
const Mesh *mesh = ob->mesh;
|
const Mesh *mesh = ob->mesh;
|
||||||
|
|
||||||
if(pack.prim_type[prim]) {
|
if(pack.prim_segment[prim] != ~0) {
|
||||||
/* strands */
|
/* curves */
|
||||||
int str_offset = (params.top_level)? mesh->curveseg_offset: 0;
|
int str_offset = (params.top_level)? mesh->curve_offset: 0;
|
||||||
const int *hidx = mesh->curve_segments[pidx - str_offset].v;
|
int k0 = mesh->curves[pidx - str_offset].first_key + pack.prim_segment[prim]; // XXX!
|
||||||
|
int k1 = k0 + 1;
|
||||||
|
|
||||||
bbox.grow(mesh->curve_keys[hidx[0]].co, mesh->curve_keys[hidx[0]].radius);
|
bbox.grow(mesh->curve_keys[k0].co, mesh->curve_keys[k0].radius);
|
||||||
bbox.grow(mesh->curve_keys[hidx[1]].co, mesh->curve_keys[hidx[1]].radius);
|
bbox.grow(mesh->curve_keys[k1].co, mesh->curve_keys[k1].radius);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* triangles */
|
/* triangles */
|
||||||
|
@@ -53,7 +53,7 @@ struct PackedBVH {
|
|||||||
/* precomputed triangle intersection data, one triangle is 4x float4 */
|
/* precomputed triangle intersection data, one triangle is 4x float4 */
|
||||||
array<float4> tri_woop;
|
array<float4> tri_woop;
|
||||||
/* primitive type - triangle or strand (should be moved to flag?) */
|
/* primitive type - triangle or strand (should be moved to flag?) */
|
||||||
array<int> prim_type;
|
array<int> prim_segment;
|
||||||
/* visibility visibilitys for primitives */
|
/* visibility visibilitys for primitives */
|
||||||
array<uint> prim_visibility;
|
array<uint> prim_visibility;
|
||||||
/* mapping from BVH primitive index to true primitive index, as primitives
|
/* mapping from BVH primitive index to true primitive index, as primitives
|
||||||
@@ -106,7 +106,7 @@ protected:
|
|||||||
/* triangles and strands*/
|
/* triangles and strands*/
|
||||||
void pack_primitives();
|
void pack_primitives();
|
||||||
void pack_triangle(int idx, float4 woop[3]);
|
void pack_triangle(int idx, float4 woop[3]);
|
||||||
void pack_curve_seg(int idx, float4 woop[3]);
|
void pack_curve_segment(int idx, float4 woop[3]);
|
||||||
|
|
||||||
/* merge instance BVH's */
|
/* merge instance BVH's */
|
||||||
void pack_instances(size_t nodes_size);
|
void pack_instances(size_t nodes_size);
|
||||||
|
@@ -48,10 +48,10 @@ public:
|
|||||||
/* Constructor / Destructor */
|
/* Constructor / Destructor */
|
||||||
|
|
||||||
BVHBuild::BVHBuild(const vector<Object*>& objects_,
|
BVHBuild::BVHBuild(const vector<Object*>& objects_,
|
||||||
vector<int>& prim_type_, vector<int>& prim_index_, vector<int>& prim_object_,
|
vector<int>& prim_segment_, vector<int>& prim_index_, vector<int>& prim_object_,
|
||||||
const BVHParams& params_, Progress& progress_)
|
const BVHParams& params_, Progress& progress_)
|
||||||
: objects(objects_),
|
: objects(objects_),
|
||||||
prim_type(prim_type_),
|
prim_segment(prim_segment_),
|
||||||
prim_index(prim_index_),
|
prim_index(prim_index_),
|
||||||
prim_object(prim_object_),
|
prim_object(prim_object_),
|
||||||
params(params_),
|
params(params_),
|
||||||
@@ -74,30 +74,34 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
|
|||||||
BoundBox bounds = BoundBox::empty;
|
BoundBox bounds = BoundBox::empty;
|
||||||
|
|
||||||
for(int k = 0; k < 3; k++) {
|
for(int k = 0; k < 3; k++) {
|
||||||
float3 pt = mesh->verts[t.v[k]];
|
float3 co = mesh->verts[t.v[k]];
|
||||||
bounds.grow(pt);
|
bounds.grow(co);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bounds.valid()) {
|
if(bounds.valid()) {
|
||||||
references.push_back(BVHReference(bounds, j, i, false));
|
references.push_back(BVHReference(bounds, j, i, ~0));
|
||||||
root.grow(bounds);
|
root.grow(bounds);
|
||||||
center.grow(bounds.center2());
|
center.grow(bounds.center2());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uint j = 0; j < mesh->curve_segments.size(); j++) {
|
for(uint j = 0; j < mesh->curves.size(); j++) {
|
||||||
Mesh::CurveSegment s = mesh->curve_segments[j];
|
Mesh::Curve curve = mesh->curves[j];
|
||||||
BoundBox bounds = BoundBox::empty;
|
|
||||||
|
|
||||||
for(int k = 0; k < 2; k++) {
|
for(int k = 0; k < curve.num_keys - 1; k++) {
|
||||||
float3 pt = mesh->curve_keys[s.v[k]].co;
|
BoundBox bounds = BoundBox::empty;
|
||||||
bounds.grow(pt, mesh->curve_keys[s.v[k]].radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bounds.valid()) {
|
float3 co0 = mesh->curve_keys[curve.first_key + k].co;
|
||||||
references.push_back(BVHReference(bounds, j, i, true));
|
float3 co1 = mesh->curve_keys[curve.first_key + k + 1].co;
|
||||||
root.grow(bounds);
|
|
||||||
center.grow(bounds.center2());
|
bounds.grow(co0, mesh->curve_keys[curve.first_key + k].radius);
|
||||||
|
bounds.grow(co1, mesh->curve_keys[curve.first_key + k + 1].radius);
|
||||||
|
|
||||||
|
if(bounds.valid()) {
|
||||||
|
references.push_back(BVHReference(bounds, j, i, k));
|
||||||
|
root.grow(bounds);
|
||||||
|
center.grow(bounds.center2());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,6 +113,16 @@ void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob
|
|||||||
center.grow(ob->bounds.center2());
|
center.grow(ob->bounds.center2());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t count_curve_segments(Mesh *mesh)
|
||||||
|
{
|
||||||
|
size_t num = 0, num_curves = mesh->curves.size();
|
||||||
|
|
||||||
|
for(size_t i = 0; i < num_curves; i++)
|
||||||
|
num += mesh->curves[i].num_keys - 1;
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
void BVHBuild::add_references(BVHRange& root)
|
void BVHBuild::add_references(BVHRange& root)
|
||||||
{
|
{
|
||||||
/* reserve space for references */
|
/* reserve space for references */
|
||||||
@@ -118,14 +132,14 @@ void BVHBuild::add_references(BVHRange& root)
|
|||||||
if(params.top_level) {
|
if(params.top_level) {
|
||||||
if(ob->mesh->transform_applied) {
|
if(ob->mesh->transform_applied) {
|
||||||
num_alloc_references += ob->mesh->triangles.size();
|
num_alloc_references += ob->mesh->triangles.size();
|
||||||
num_alloc_references += ob->mesh->curve_segments.size();
|
num_alloc_references += count_curve_segments(ob->mesh);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
num_alloc_references++;
|
num_alloc_references++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
num_alloc_references += ob->mesh->triangles.size();
|
num_alloc_references += ob->mesh->triangles.size();
|
||||||
num_alloc_references += ob->mesh->curve_segments.size();
|
num_alloc_references += count_curve_segments(ob->mesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +197,7 @@ BVHNode* BVHBuild::run()
|
|||||||
progress_total = references.size();
|
progress_total = references.size();
|
||||||
progress_original_total = progress_total;
|
progress_original_total = progress_total;
|
||||||
|
|
||||||
prim_type.resize(references.size());
|
prim_segment.resize(references.size());
|
||||||
prim_index.resize(references.size());
|
prim_index.resize(references.size());
|
||||||
prim_object.resize(references.size());
|
prim_object.resize(references.size());
|
||||||
|
|
||||||
@@ -341,12 +355,12 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
|
|||||||
if(start == prim_index.size()) {
|
if(start == prim_index.size()) {
|
||||||
assert(params.use_spatial_split);
|
assert(params.use_spatial_split);
|
||||||
|
|
||||||
prim_type.push_back(ref->prim_type());
|
prim_segment.push_back(ref->prim_segment());
|
||||||
prim_index.push_back(ref->prim_index());
|
prim_index.push_back(ref->prim_index());
|
||||||
prim_object.push_back(ref->prim_object());
|
prim_object.push_back(ref->prim_object());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prim_type[start] = ref->prim_type();
|
prim_segment[start] = ref->prim_segment();
|
||||||
prim_index[start] = ref->prim_index();
|
prim_index[start] = ref->prim_index();
|
||||||
prim_object[start] = ref->prim_object();
|
prim_object[start] = ref->prim_object();
|
||||||
}
|
}
|
||||||
@@ -369,7 +383,7 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
|
|||||||
|
|
||||||
BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
|
BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
|
||||||
{
|
{
|
||||||
vector<int>& p_type = prim_type;
|
vector<int>& p_segment = prim_segment;
|
||||||
vector<int>& p_index = prim_index;
|
vector<int>& p_index = prim_index;
|
||||||
vector<int>& p_object = prim_object;
|
vector<int>& p_object = prim_object;
|
||||||
BoundBox bounds = BoundBox::empty;
|
BoundBox bounds = BoundBox::empty;
|
||||||
@@ -383,12 +397,12 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
|
|||||||
if(range.start() + num == prim_index.size()) {
|
if(range.start() + num == prim_index.size()) {
|
||||||
assert(params.use_spatial_split);
|
assert(params.use_spatial_split);
|
||||||
|
|
||||||
p_type.push_back(ref.prim_type());
|
p_segment.push_back(ref.prim_segment());
|
||||||
p_index.push_back(ref.prim_index());
|
p_index.push_back(ref.prim_index());
|
||||||
p_object.push_back(ref.prim_object());
|
p_object.push_back(ref.prim_object());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p_type[range.start() + num] = ref.prim_type();
|
p_segment[range.start() + num] = ref.prim_segment();
|
||||||
p_index[range.start() + num] = ref.prim_index();
|
p_index[range.start() + num] = ref.prim_index();
|
||||||
p_object[range.start() + num] = ref.prim_object();
|
p_object[range.start() + num] = ref.prim_object();
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,7 @@ public:
|
|||||||
/* Constructor/Destructor */
|
/* Constructor/Destructor */
|
||||||
BVHBuild(
|
BVHBuild(
|
||||||
const vector<Object*>& objects,
|
const vector<Object*>& objects,
|
||||||
vector<int>& prim_type,
|
vector<int>& prim_segment,
|
||||||
vector<int>& prim_index,
|
vector<int>& prim_index,
|
||||||
vector<int>& prim_object,
|
vector<int>& prim_object,
|
||||||
const BVHParams& params,
|
const BVHParams& params,
|
||||||
@@ -88,7 +88,7 @@ protected:
|
|||||||
int num_original_references;
|
int num_original_references;
|
||||||
|
|
||||||
/* output primitive indexes and objects */
|
/* output primitive indexes and objects */
|
||||||
vector<int>& prim_type;
|
vector<int>& prim_segment;
|
||||||
vector<int>& prim_index;
|
vector<int>& prim_index;
|
||||||
vector<int>& prim_object;
|
vector<int>& prim_object;
|
||||||
|
|
||||||
|
@@ -98,22 +98,22 @@ class BVHReference
|
|||||||
public:
|
public:
|
||||||
__forceinline BVHReference() {}
|
__forceinline BVHReference() {}
|
||||||
|
|
||||||
__forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_type)
|
__forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_segment)
|
||||||
: rbounds(bounds_)
|
: rbounds(bounds_)
|
||||||
{
|
{
|
||||||
rbounds.min.w = __int_as_float(prim_index_);
|
rbounds.min.w = __int_as_float(prim_index_);
|
||||||
rbounds.max.w = __int_as_float(prim_object_);
|
rbounds.max.w = __int_as_float(prim_object_);
|
||||||
type = prim_type;
|
segment = prim_segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline const BoundBox& bounds() const { return rbounds; }
|
__forceinline const BoundBox& bounds() const { return rbounds; }
|
||||||
__forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
|
__forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
|
||||||
__forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
|
__forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
|
||||||
__forceinline int prim_type() const { return type; }
|
__forceinline int prim_segment() const { return segment; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BoundBox rbounds;
|
BoundBox rbounds;
|
||||||
uint type;
|
uint segment;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BVH Range
|
/* BVH Range
|
||||||
|
@@ -43,8 +43,8 @@ public:
|
|||||||
else if(ra.prim_object() > rb.prim_object()) return false;
|
else if(ra.prim_object() > rb.prim_object()) return false;
|
||||||
else if(ra.prim_index() < rb.prim_index()) return true;
|
else if(ra.prim_index() < rb.prim_index()) return true;
|
||||||
else if(ra.prim_index() > rb.prim_index()) return false;
|
else if(ra.prim_index() > rb.prim_index()) return false;
|
||||||
else if(ra.prim_type() < rb.prim_type()) return true;
|
else if(ra.prim_segment() < rb.prim_segment()) return true;
|
||||||
else if(ra.prim_type() > rb.prim_type()) return false;
|
else if(ra.prim_segment() > rb.prim_segment()) return false;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -253,7 +253,7 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
|
|||||||
Object *ob = builder->objects[ref.prim_object()];
|
Object *ob = builder->objects[ref.prim_object()];
|
||||||
const Mesh *mesh = ob->mesh;
|
const Mesh *mesh = ob->mesh;
|
||||||
|
|
||||||
if (!ref.prim_type()) {
|
if (ref.prim_segment() == ~0) {
|
||||||
const int *inds = mesh->triangles[ref.prim_index()].v;
|
const int *inds = mesh->triangles[ref.prim_index()].v;
|
||||||
const float3 *verts = &mesh->verts[0];
|
const float3 *verts = &mesh->verts[0];
|
||||||
const float3* v1 = &verts[inds[2]];
|
const float3* v1 = &verts[inds[2]];
|
||||||
@@ -281,11 +281,11 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Strand split: NOTE - Currently ignores strand width and needs to be fixed.*/
|
/* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
|
||||||
|
const int k0 = mesh->curves[ref.prim_index()].first_key + ref.prim_segment();
|
||||||
const int *inds = mesh->curve_segments[ref.prim_index()].v;
|
const int k1 = k0 + 1;
|
||||||
const float3* v0 = &mesh->curve_keys[inds[0]].co;
|
const float3* v0 = &mesh->curve_keys[k0].co;
|
||||||
const float3* v1 = &mesh->curve_keys[inds[1]].co;
|
const float3* v1 = &mesh->curve_keys[k1].co;
|
||||||
|
|
||||||
float v0p = (*v0)[dim];
|
float v0p = (*v0)[dim];
|
||||||
float v1p = (*v1)[dim];
|
float v1p = (*v1)[dim];
|
||||||
@@ -318,8 +318,8 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
|
|||||||
right_bounds.intersect(ref.bounds());
|
right_bounds.intersect(ref.bounds());
|
||||||
|
|
||||||
/* set references */
|
/* set references */
|
||||||
left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
|
left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
|
||||||
right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
|
right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
|
||||||
}
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -207,22 +207,22 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise
|
|||||||
|
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
__device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
|
__device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
|
||||||
float3 P, float3 idir, uint visibility, int object, int triAddr)
|
float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment)
|
||||||
{
|
{
|
||||||
/* curve Intersection check */
|
/* curve Intersection check */
|
||||||
|
|
||||||
int flags = kernel_data.curve_kernel_data.curveflags;
|
int flags = kernel_data.curve_kernel_data.curveflags;
|
||||||
|
|
||||||
int prim = kernel_tex_fetch(__prim_index, triAddr);
|
int prim = kernel_tex_fetch(__prim_index, curveAddr);
|
||||||
float4 v00 = kernel_tex_fetch(__curve_segments, prim);
|
float4 v00 = kernel_tex_fetch(__curves, prim);
|
||||||
|
|
||||||
int v1 = __float_as_int(v00.x);
|
int k0 = __float_as_int(v00.x) + segment;
|
||||||
int v2 = __float_as_int(v00.y);
|
int k1 = k0 + 1;
|
||||||
|
|
||||||
float4 P1 = kernel_tex_fetch(__curve_keys, v1);
|
float4 P1 = kernel_tex_fetch(__curve_keys, k0);
|
||||||
float4 P2 = kernel_tex_fetch(__curve_keys, v2);
|
float4 P2 = kernel_tex_fetch(__curve_keys, k1);
|
||||||
|
|
||||||
float l = v00.w;
|
float l = len(P2 - P1); // XXX slower
|
||||||
float r1 = P1.w;
|
float r1 = P1.w;
|
||||||
float r2 = P2.w;
|
float r2 = P2.w;
|
||||||
float mr = max(r1,r2);
|
float mr = max(r1,r2);
|
||||||
@@ -329,14 +329,15 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
|
|||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
#ifdef __VISIBILITY_FLAG__
|
#ifdef __VISIBILITY_FLAG__
|
||||||
/* visibility flag test. we do it here under the assumption
|
/* visibility flag test. we do it here under the assumption
|
||||||
* that most triangles are culled by node flags */
|
* that most triangles are culled by node flags */
|
||||||
if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
|
if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* record intersection */
|
/* record intersection */
|
||||||
isect->prim = triAddr;
|
isect->prim = curveAddr;
|
||||||
|
isect->segment = segment;
|
||||||
isect->object = object;
|
isect->object = object;
|
||||||
isect->u = z/l;
|
isect->u = z/l;
|
||||||
isect->v = td/(4*a*a);
|
isect->v = td/(4*a*a);
|
||||||
@@ -430,8 +431,9 @@ __device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint
|
|||||||
while(primAddr < primAddr2) {
|
while(primAddr < primAddr2) {
|
||||||
/* intersect ray against primitive */
|
/* intersect ray against primitive */
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(kernel_tex_fetch(__prim_type, primAddr))
|
uint segment = kernel_tex_fetch(__prim_segment, primAddr);
|
||||||
bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr);
|
if(segment != ~0)
|
||||||
|
bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
|
bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
|
||||||
@@ -555,8 +557,9 @@ __device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, con
|
|||||||
while(primAddr < primAddr2) {
|
while(primAddr < primAddr2) {
|
||||||
/* intersect ray against primitive */
|
/* intersect ray against primitive */
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(kernel_tex_fetch(__prim_type, primAddr))
|
uint segment = kernel_tex_fetch(__prim_segment, primAddr);
|
||||||
bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr);
|
if(segment != ~0)
|
||||||
|
bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
|
bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
|
||||||
@@ -720,14 +723,14 @@ __device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
int prim = kernel_tex_fetch(__prim_index, isect->prim);
|
int prim = kernel_tex_fetch(__prim_index, isect->prim);
|
||||||
float4 v00 = kernel_tex_fetch(__curve_segments, prim);
|
float4 v00 = kernel_tex_fetch(__curves, prim);
|
||||||
|
|
||||||
int v1 = __float_as_int(v00.x);
|
int k0 = __float_as_int(v00.x) + isect->segment;
|
||||||
int v2 = __float_as_int(v00.y);
|
int k1 = k0 + 1;
|
||||||
|
|
||||||
float4 P1 = kernel_tex_fetch(__curve_keys, v1);
|
float4 P1 = kernel_tex_fetch(__curve_keys, k0);
|
||||||
float4 P2 = kernel_tex_fetch(__curve_keys, v2);
|
float4 P2 = kernel_tex_fetch(__curve_keys, k1);
|
||||||
float l = v00.w;
|
float l = len(P2 - P1); // XXX slower
|
||||||
float r1 = P1.w;
|
float r1 = P1.w;
|
||||||
float r2 = P2.w;
|
float r2 = P2.w;
|
||||||
float3 tg = float4_to_float3(P2 - P1) / l;
|
float3 tg = float4_to_float3(P2 - P1) / l;
|
||||||
|
@@ -24,19 +24,21 @@ CCL_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
__device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
|
__device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
|
||||||
{
|
{
|
||||||
if(elem == ATTR_ELEMENT_CURVE_SEGMENT) {
|
if(elem == ATTR_ELEMENT_CURVE) {
|
||||||
#ifdef __RAY_DIFFERENTIALS__
|
#ifdef __RAY_DIFFERENTIALS__
|
||||||
if(dx) *dx = 0.0f;
|
if(dx) *dx = 0.0f;
|
||||||
if(dy) *dy = 0.0f;
|
if(dy) *dy = 0.0f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return kernel_tex_fetch(__attributes_float, offset + sd->curve_seg);
|
return kernel_tex_fetch(__attributes_float, offset + sd->prim);
|
||||||
}
|
}
|
||||||
else if(elem == ATTR_ELEMENT_CURVE_KEY) {
|
else if(elem == ATTR_ELEMENT_CURVE_KEY) {
|
||||||
float4 segment = kernel_tex_fetch(__curve_segments, sd->curve_seg);
|
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
||||||
|
int k0 = __float_as_int(curvedata.x) + sd->segment;
|
||||||
|
int k1 = k0 + 1;
|
||||||
|
|
||||||
float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(segment.x));
|
float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
|
||||||
float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(segment.y));
|
float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
|
||||||
|
|
||||||
#ifdef __RAY_DIFFERENTIALS__
|
#ifdef __RAY_DIFFERENTIALS__
|
||||||
if(dx) *dx = sd->du.dx*(f1 - f0);
|
if(dx) *dx = sd->du.dx*(f1 - f0);
|
||||||
@@ -57,7 +59,7 @@ __device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, At
|
|||||||
|
|
||||||
__device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
|
__device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
|
||||||
{
|
{
|
||||||
if(elem == ATTR_ELEMENT_CURVE_SEGMENT) {
|
if(elem == ATTR_ELEMENT_CURVE) {
|
||||||
/* idea: we can't derive any useful differentials here, but for tiled
|
/* idea: we can't derive any useful differentials here, but for tiled
|
||||||
* mipmap image caching it would be useful to avoid reading the highest
|
* mipmap image caching it would be useful to avoid reading the highest
|
||||||
* detail level always. maybe a derivative based on the hair density
|
* detail level always. maybe a derivative based on the hair density
|
||||||
@@ -67,13 +69,15 @@ __device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd,
|
|||||||
if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
|
if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->curve_seg));
|
return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
|
||||||
}
|
}
|
||||||
else if(elem == ATTR_ELEMENT_CURVE_KEY) {
|
else if(elem == ATTR_ELEMENT_CURVE_KEY) {
|
||||||
float4 segment = kernel_tex_fetch(__curve_segments, sd->curve_seg);
|
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
||||||
|
int k0 = __float_as_int(curvedata.x) + sd->segment;
|
||||||
|
int k1 = k0 + 1;
|
||||||
|
|
||||||
float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(segment.x)));
|
float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
|
||||||
float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(segment.y)));
|
float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
|
||||||
|
|
||||||
#ifdef __RAY_DIFFERENTIALS__
|
#ifdef __RAY_DIFFERENTIALS__
|
||||||
if(dx) *dx = sd->du.dx*(f1 - f0);
|
if(dx) *dx = sd->du.dx*(f1 - f0);
|
||||||
@@ -96,19 +100,16 @@ __device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd,
|
|||||||
|
|
||||||
__device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
|
__device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
|
||||||
{
|
{
|
||||||
int prim = sd->curve_seg;
|
|
||||||
float u = sd->u;
|
|
||||||
float r = 0.0f;
|
float r = 0.0f;
|
||||||
|
|
||||||
if(prim != -1) {
|
if(sd->segment != ~0) {
|
||||||
float4 v00 = kernel_tex_fetch(__curve_segments, prim);
|
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
||||||
|
int k0 = __float_as_int(curvedata.x) + sd->segment;
|
||||||
|
int k1 = k0 + 1;
|
||||||
|
|
||||||
int v1 = __float_as_int(v00.x);
|
float4 P1 = kernel_tex_fetch(__curve_keys, k0);
|
||||||
int v2 = __float_as_int(v00.y);
|
float4 P2 = kernel_tex_fetch(__curve_keys, k1);
|
||||||
|
r = (P2.w - P1.w) * sd->u + P1.w;
|
||||||
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;
|
return r*2.0f;
|
||||||
@@ -118,7 +119,7 @@ __device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
|
|||||||
{
|
{
|
||||||
float3 tgN = make_float3(0.0f,0.0f,0.0f);
|
float3 tgN = make_float3(0.0f,0.0f,0.0f);
|
||||||
|
|
||||||
if(sd->curve_seg != ~0) {
|
if(sd->segment != ~0) {
|
||||||
float normalmix = kernel_data.curve_kernel_data.normalmix;
|
float normalmix = kernel_data.curve_kernel_data.normalmix;
|
||||||
|
|
||||||
tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * normalmix / len_squared(sd->dPdu)));
|
tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * normalmix / len_squared(sd->dPdu)));
|
||||||
|
@@ -157,7 +157,7 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
|
|||||||
float3 L = shader_emissive_eval(kg, sd);
|
float3 L = shader_emissive_eval(kg, sd);
|
||||||
|
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->curve_seg == ~0)) {
|
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->segment == ~0)) {
|
||||||
#else
|
#else
|
||||||
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
|
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
|
||||||
#endif
|
#endif
|
||||||
|
@@ -329,18 +329,20 @@ __device float triangle_light_pdf(KernelGlobals *kg,
|
|||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
/* Strand Light */
|
/* Strand Light */
|
||||||
|
|
||||||
__device void curve_seg_light_sample(KernelGlobals *kg, int prim, int object,
|
__device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object,
|
||||||
float randu, float randv, float time, LightSample *ls)
|
int segment, float randu, float randv, float time, LightSample *ls)
|
||||||
{
|
{
|
||||||
/* this strand code needs completion */
|
/* this strand code needs completion */
|
||||||
float4 v00 = kernel_tex_fetch(__curve_segments, prim);
|
float4 v00 = kernel_tex_fetch(__curves, prim);
|
||||||
|
|
||||||
int v1 = __float_as_int(v00.x);
|
int k0 = __float_as_int(v00.x) + segment;
|
||||||
int v2 = __float_as_int(v00.y);
|
int k1 = k0 + 1;
|
||||||
float l = v00.w;
|
|
||||||
|
float4 P1 = kernel_tex_fetch(__curve_keys, k0);
|
||||||
|
float4 P2 = kernel_tex_fetch(__curve_keys, k1);
|
||||||
|
|
||||||
|
float l = len(P2 - P1); // XXX slower
|
||||||
|
|
||||||
float4 P1 = kernel_tex_fetch(__curve_keys, v1);
|
|
||||||
float4 P2 = kernel_tex_fetch(__curve_keys, v2);
|
|
||||||
float r1 = P1.w;
|
float r1 = P1.w;
|
||||||
float r2 = P2.w;
|
float r2 = P2.w;
|
||||||
float3 tg = float4_to_float3(P2 - P1) / l;
|
float3 tg = float4_to_float3(P2 - P1) / l;
|
||||||
@@ -419,15 +421,15 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
|
|||||||
float4 l = kernel_tex_fetch(__light_distribution, index);
|
float4 l = kernel_tex_fetch(__light_distribution, index);
|
||||||
int prim = __float_as_int(l.y);
|
int prim = __float_as_int(l.y);
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
/* currently use l.z to indicate is strand sample which isn't ideal */
|
int segment = __float_as_int(l.z);
|
||||||
bool is_curve = __float_as_int(l.z) == 0.0f;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(prim >= 0) {
|
if(prim >= 0) {
|
||||||
int object = __float_as_int(l.w);
|
int object = __float_as_int(l.w);
|
||||||
|
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if (is_curve)
|
if (segment != ~0)
|
||||||
curve_seg_light_sample(kg, prim, object, randu, randv, time, ls);
|
curve_segment_light_sample(kg, prim, object, segment, randu, randv, time, ls);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
triangle_light_sample(kg, prim, object, randu, randv, time, ls);
|
triangle_light_sample(kg, prim, object, randu, randv, time, ls);
|
||||||
|
@@ -37,7 +37,7 @@ __device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, A
|
|||||||
{
|
{
|
||||||
/* for SVM, find attribute by unique id */
|
/* for SVM, find attribute by unique id */
|
||||||
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
|
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
|
||||||
attr_offset = (sd->curve_seg == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
|
attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
|
||||||
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
|
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
|
||||||
|
|
||||||
while(attr_map.x != id) {
|
while(attr_map.x != id) {
|
||||||
@@ -55,7 +55,7 @@ __device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, A
|
|||||||
__device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
|
__device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
|
||||||
{
|
{
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(sd->curve_seg == ~0)
|
if(sd->segment == ~0)
|
||||||
#endif
|
#endif
|
||||||
return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
|
return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
@@ -67,7 +67,7 @@ __device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd
|
|||||||
__device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
|
__device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
|
||||||
{
|
{
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(sd->curve_seg == ~0)
|
if(sd->segment == ~0)
|
||||||
#endif
|
#endif
|
||||||
return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
|
return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
@@ -92,7 +92,7 @@ __device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
|
|||||||
__device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
|
__device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
|
||||||
{
|
{
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(sd->curve_seg != ~0)
|
if(sd->segment != ~0)
|
||||||
return normalize(sd->dPdu);
|
return normalize(sd->dPdu);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -69,25 +69,22 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
|
sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
|
||||||
#ifdef __HAIR__
|
|
||||||
sd->curve_seg = ~0;
|
|
||||||
#endif
|
|
||||||
sd->ray_length = isect->t;
|
sd->ray_length = isect->t;
|
||||||
|
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(kernel_tex_fetch(__prim_type, isect->prim)) {
|
if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
|
||||||
/* Strand Shader setting*/
|
/* Strand Shader setting*/
|
||||||
float4 CurSeg = kernel_tex_fetch(__curve_segments, sd->prim);
|
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
||||||
sd->shader = __float_as_int(CurSeg.z);
|
|
||||||
|
|
||||||
sd->curve_seg = sd->prim;
|
sd->shader = __float_as_int(curvedata.z);
|
||||||
sd->prim = isect->prim;
|
sd->segment = isect->segment;
|
||||||
|
|
||||||
float tcorr = isect->t;
|
float tcorr = isect->t;
|
||||||
if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION) {
|
if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION) {
|
||||||
tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
|
tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
|
||||||
sd->ray_length = tcorr;
|
sd->ray_length = tcorr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
|
sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -97,6 +94,10 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
|
|||||||
float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
|
float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
|
||||||
sd->shader = __float_as_int(Ns.w);
|
sd->shader = __float_as_int(Ns.w);
|
||||||
|
|
||||||
|
#ifdef __HAIR__
|
||||||
|
sd->segment = ~0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __UV__
|
#ifdef __UV__
|
||||||
sd->u = isect->u;
|
sd->u = isect->u;
|
||||||
sd->v = isect->v;
|
sd->v = isect->v;
|
||||||
@@ -107,7 +108,6 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
|
|||||||
sd->Ng = Ng;
|
sd->Ng = Ng;
|
||||||
sd->N = Ng;
|
sd->N = Ng;
|
||||||
|
|
||||||
|
|
||||||
/* smooth normal */
|
/* smooth normal */
|
||||||
if(sd->shader & SHADER_SMOOTH_NORMAL)
|
if(sd->shader & SHADER_SMOOTH_NORMAL)
|
||||||
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
|
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
|
||||||
@@ -162,7 +162,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
|
|||||||
|
|
||||||
__device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
|
__device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
|
||||||
const float3 P, const float3 Ng, const float3 I,
|
const float3 P, const float3 Ng, const float3 I,
|
||||||
int shader, int object, int prim, float u, float v, float t, float time, int curve = ~0)
|
int shader, int object, int prim, float u, float v, float t, float time, int segment = ~0)
|
||||||
{
|
{
|
||||||
/* vectors */
|
/* vectors */
|
||||||
sd->P = P;
|
sd->P = P;
|
||||||
@@ -171,7 +171,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
|
|||||||
sd->I = I;
|
sd->I = I;
|
||||||
sd->shader = shader;
|
sd->shader = shader;
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
sd->curve_seg = curve;
|
sd->segment = segment;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* primitive */
|
/* primitive */
|
||||||
@@ -215,7 +215,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
|
|||||||
|
|
||||||
/* smooth normal */
|
/* smooth normal */
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(sd->shader & SHADER_SMOOTH_NORMAL && sd->curve_seg == ~0) {
|
if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) {
|
||||||
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
|
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
|
||||||
#else
|
#else
|
||||||
if(sd->shader & SHADER_SMOOTH_NORMAL) {
|
if(sd->shader & SHADER_SMOOTH_NORMAL) {
|
||||||
@@ -231,7 +231,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
|
|||||||
#ifdef __DPDU__
|
#ifdef __DPDU__
|
||||||
/* dPdu/dPdv */
|
/* dPdu/dPdv */
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(sd->prim == ~0 || sd->curve_seg != ~0) {
|
if(sd->prim == ~0 || sd->segment != ~0) {
|
||||||
sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
|
sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
|
||||||
sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
|
sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
@@ -323,7 +323,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
|
|||||||
#endif
|
#endif
|
||||||
sd->prim = ~0;
|
sd->prim = ~0;
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
sd->curve_seg = ~0;
|
sd->segment = ~0;
|
||||||
#endif
|
#endif
|
||||||
#ifdef __UV__
|
#ifdef __UV__
|
||||||
sd->u = 0.0f;
|
sd->u = 0.0f;
|
||||||
@@ -781,14 +781,14 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
|
|||||||
int shader = 0;
|
int shader = 0;
|
||||||
|
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
if(!kernel_tex_fetch(__prim_type, isect->prim)) {
|
if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
|
||||||
#endif
|
#endif
|
||||||
float4 Ns = kernel_tex_fetch(__tri_normal, prim);
|
float4 Ns = kernel_tex_fetch(__tri_normal, prim);
|
||||||
shader = __float_as_int(Ns.w);
|
shader = __float_as_int(Ns.w);
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float4 str = kernel_tex_fetch(__curve_segments, prim);
|
float4 str = kernel_tex_fetch(__curves, prim);
|
||||||
shader = __float_as_int(str.z);
|
shader = __float_as_int(str.z);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
/* bvh */
|
/* bvh */
|
||||||
KERNEL_TEX(float4, texture_float4, __bvh_nodes)
|
KERNEL_TEX(float4, texture_float4, __bvh_nodes)
|
||||||
KERNEL_TEX(float4, texture_float4, __tri_woop)
|
KERNEL_TEX(float4, texture_float4, __tri_woop)
|
||||||
KERNEL_TEX(uint, texture_uint, __prim_type)
|
KERNEL_TEX(uint, texture_uint, __prim_segment)
|
||||||
KERNEL_TEX(uint, texture_uint, __prim_visibility)
|
KERNEL_TEX(uint, texture_uint, __prim_visibility)
|
||||||
KERNEL_TEX(uint, texture_uint, __prim_index)
|
KERNEL_TEX(uint, texture_uint, __prim_index)
|
||||||
KERNEL_TEX(uint, texture_uint, __prim_object)
|
KERNEL_TEX(uint, texture_uint, __prim_object)
|
||||||
@@ -44,7 +44,7 @@ KERNEL_TEX(float4, texture_float4, __tri_vindex)
|
|||||||
KERNEL_TEX(float4, texture_float4, __tri_verts)
|
KERNEL_TEX(float4, texture_float4, __tri_verts)
|
||||||
|
|
||||||
/* curves */
|
/* curves */
|
||||||
KERNEL_TEX(float4, texture_float4, __curve_segments)
|
KERNEL_TEX(float4, texture_float4, __curves)
|
||||||
KERNEL_TEX(float4, texture_float4, __curve_keys)
|
KERNEL_TEX(float4, texture_float4, __curve_keys)
|
||||||
|
|
||||||
/* attributes */
|
/* attributes */
|
||||||
|
@@ -344,6 +344,7 @@ typedef struct Intersection {
|
|||||||
float t, u, v;
|
float t, u, v;
|
||||||
int prim;
|
int prim;
|
||||||
int object;
|
int object;
|
||||||
|
int segment;
|
||||||
} Intersection;
|
} Intersection;
|
||||||
|
|
||||||
/* Attributes */
|
/* Attributes */
|
||||||
@@ -357,7 +358,7 @@ typedef enum AttributeElement {
|
|||||||
ATTR_ELEMENT_FACE,
|
ATTR_ELEMENT_FACE,
|
||||||
ATTR_ELEMENT_VERTEX,
|
ATTR_ELEMENT_VERTEX,
|
||||||
ATTR_ELEMENT_CORNER,
|
ATTR_ELEMENT_CORNER,
|
||||||
ATTR_ELEMENT_CURVE_SEGMENT,
|
ATTR_ELEMENT_CURVE,
|
||||||
ATTR_ELEMENT_CURVE_KEY
|
ATTR_ELEMENT_CURVE_KEY
|
||||||
} AttributeElement;
|
} AttributeElement;
|
||||||
|
|
||||||
@@ -464,8 +465,8 @@ typedef struct ShaderData {
|
|||||||
int prim;
|
int prim;
|
||||||
|
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
/* strand id if there is one, -1 otherwise */
|
/* for curves, segment number in curve, ~0 for triangles */
|
||||||
int curve_seg;
|
int segment;
|
||||||
#endif
|
#endif
|
||||||
/* parametric coordinates
|
/* parametric coordinates
|
||||||
* - barycentric weights for triangles */
|
* - barycentric weights for triangles */
|
||||||
|
@@ -605,7 +605,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
|
|||||||
return set_attribute_int(3, type, derivatives, val);
|
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) {
|
&& sd->segment == ~0) {
|
||||||
float3 P[3];
|
float3 P[3];
|
||||||
triangle_vertices(kg, sd->prim, P);
|
triangle_vertices(kg, sd->prim, P);
|
||||||
|
|
||||||
@@ -625,7 +625,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
|
|||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
/* Hair Attributes */
|
/* Hair Attributes */
|
||||||
else if (name == u_is_curve) {
|
else if (name == u_is_curve) {
|
||||||
float f = !(sd->curve_seg == ~0);
|
float f = (sd->segment != ~0);
|
||||||
return set_attribute_float(f, type, derivatives, val);
|
return set_attribute_float(f, type, derivatives, val);
|
||||||
}
|
}
|
||||||
else if (name == u_curve_thickness) {
|
else if (name == u_curve_thickness) {
|
||||||
@@ -659,7 +659,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
|
|||||||
{
|
{
|
||||||
KernelGlobals *kg = kernel_globals;
|
KernelGlobals *kg = kernel_globals;
|
||||||
ShaderData *sd = (ShaderData *)renderstate;
|
ShaderData *sd = (ShaderData *)renderstate;
|
||||||
int object, prim, curve_seg;
|
int object, prim, segment;
|
||||||
|
|
||||||
/* lookup of attribute on another object */
|
/* lookup of attribute on another object */
|
||||||
if (object_name != u_empty || sd == NULL) {
|
if (object_name != u_empty || sd == NULL) {
|
||||||
@@ -670,19 +670,19 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
|
|||||||
|
|
||||||
object = it->second;
|
object = it->second;
|
||||||
prim = ~0;
|
prim = ~0;
|
||||||
curve_seg = ~0;
|
segment = ~0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
object = sd->object;
|
object = sd->object;
|
||||||
prim = sd->prim;
|
prim = sd->prim;
|
||||||
curve_seg = sd->curve_seg;
|
segment = sd->segment;
|
||||||
|
|
||||||
if (object == ~0)
|
if (object == ~0)
|
||||||
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find attribute on object */
|
/* find attribute on object */
|
||||||
object = object*ATTR_PRIM_TYPES + (curve_seg != ~0);
|
object = object*ATTR_PRIM_TYPES + (segment != ~0);
|
||||||
OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
|
OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
|
||||||
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
|
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
|
||||||
|
|
||||||
|
@@ -457,7 +457,7 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_
|
|||||||
int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
|
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. */
|
/* for OSL, a hash map is used to lookup the attribute by name. */
|
||||||
int object = sd->object*ATTR_PRIM_TYPES + (sd->curve_seg != ~0);
|
int object = sd->object*ATTR_PRIM_TYPES + (sd->segment != ~0);
|
||||||
OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
|
OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
|
||||||
ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
|
ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
|
||||||
OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
|
OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
|
||||||
|
@@ -28,7 +28,7 @@ __device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
|
|||||||
/* find attribute by unique id */
|
/* find attribute by unique id */
|
||||||
uint id = node.y;
|
uint id = node.y;
|
||||||
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
|
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
|
||||||
attr_offset = (sd->curve_seg == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
|
attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
|
||||||
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
|
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
|
||||||
|
|
||||||
while(attr_map.x != id) {
|
while(attr_map.x != id) {
|
||||||
|
@@ -155,7 +155,7 @@ __device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *stack
|
|||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case NODE_INFO_CURVE_IS_STRAND: {
|
case NODE_INFO_CURVE_IS_STRAND: {
|
||||||
data = !(sd->curve_seg == ~0);
|
data = (sd->segment != ~0);
|
||||||
stack_store_float(stack, out_offset, data);
|
stack_store_float(stack, out_offset, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -80,7 +80,7 @@ size_t Attribute::element_size(int numverts, int numtris, int numcurves, int num
|
|||||||
return numtris;
|
return numtris;
|
||||||
else if(element == ATTR_ELEMENT_CORNER)
|
else if(element == ATTR_ELEMENT_CORNER)
|
||||||
return numtris*3;
|
return numtris*3;
|
||||||
else if(element == ATTR_ELEMENT_CURVE_SEGMENT)
|
else if(element == ATTR_ELEMENT_CURVE)
|
||||||
return numcurves;
|
return numcurves;
|
||||||
else if(element == ATTR_ELEMENT_CURVE_KEY)
|
else if(element == ATTR_ELEMENT_CURVE_KEY)
|
||||||
return numkeys;
|
return numkeys;
|
||||||
@@ -176,7 +176,7 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme
|
|||||||
if(triangle_mesh)
|
if(triangle_mesh)
|
||||||
attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
|
attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
|
||||||
if(curve_mesh)
|
if(curve_mesh)
|
||||||
attr->reserve(0, 0, curve_mesh->curve_segments.size(), curve_mesh->curve_keys.size());
|
attr->reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
|
||||||
|
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
@@ -239,9 +239,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
|
|||||||
}
|
}
|
||||||
else if(curve_mesh) {
|
else if(curve_mesh) {
|
||||||
if(std == ATTR_STD_UV)
|
if(std == ATTR_STD_UV)
|
||||||
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_SEGMENT);
|
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
|
||||||
else if(std == ATTR_STD_GENERATED)
|
else if(std == ATTR_STD_GENERATED)
|
||||||
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_SEGMENT);
|
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
|
||||||
else if(std == ATTR_STD_MOTION_PRE)
|
else if(std == ATTR_STD_MOTION_PRE)
|
||||||
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
|
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
|
||||||
else if(std == ATTR_STD_MOTION_POST)
|
else if(std == ATTR_STD_MOTION_POST)
|
||||||
@@ -298,7 +298,7 @@ void AttributeSet::reserve()
|
|||||||
if(triangle_mesh)
|
if(triangle_mesh)
|
||||||
attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
|
attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
|
||||||
if(curve_mesh)
|
if(curve_mesh)
|
||||||
attr.reserve(0, 0, curve_mesh->curve_segments.size(), curve_mesh->curve_keys.size());
|
attr.reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -171,13 +171,14 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
|
|||||||
num_triangles++;
|
num_triangles++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* disabled for strands*/
|
/* disabled for curves */
|
||||||
/*for(size_t i = 0; i < mesh->curve_segments.size(); i++) {
|
#if 0
|
||||||
* Shader *shader = scene->shaders[mesh->curve_segments[i].shader];
|
foreach(Mesh::Curve& curve, mesh->curves) {
|
||||||
*
|
Shader *shader = scene->shaders[curve.shader];
|
||||||
* if(shader->sample_as_light && shader->has_surface_emission)
|
|
||||||
* num_curve_segments++;
|
if(shader->sample_as_light && shader->has_surface_emission)
|
||||||
}*/
|
num_curve_segments += curve.num_segments();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +226,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
|
|||||||
if(shader->sample_as_light && shader->has_surface_emission) {
|
if(shader->sample_as_light && shader->has_surface_emission) {
|
||||||
distribution[offset].x = totarea;
|
distribution[offset].x = totarea;
|
||||||
distribution[offset].y = __int_as_float(i + mesh->tri_offset);
|
distribution[offset].y = __int_as_float(i + mesh->tri_offset);
|
||||||
distribution[offset].z = 1.0f;
|
distribution[offset].z = __int_as_float(~0);
|
||||||
distribution[offset].w = __int_as_float(object_id);
|
distribution[offset].w = __int_as_float(object_id);
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
@@ -245,30 +246,38 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*sample as light disabled for strands*/
|
/*sample as light disabled for strands*/
|
||||||
/*for(size_t i = 0; i < mesh->curve_segments.size(); i++) {
|
#if 0
|
||||||
* Shader *shader = scene->shaders[mesh->curve_segments[i].shader];
|
size_t i = 0;
|
||||||
*
|
|
||||||
* if(shader->sample_as_light && shader->has_surface_emission) {
|
foreach(Mesh::Curve& curve, mesh->curves) {
|
||||||
* distribution[offset].x = totarea;
|
Shader *shader = scene->shaders[curve.shader];
|
||||||
* distribution[offset].y = __int_as_float(i + mesh->curveseg_offset);
|
int first_key = curve.first_key;
|
||||||
* distribution[offset].z = 0.0f;
|
|
||||||
* distribution[offset].w = __int_as_float(object_id);
|
if(shader->sample_as_light && shader->has_surface_emission) {
|
||||||
* offset++;
|
for(int j = 0; j < curve.num_segments(); j++) {
|
||||||
*
|
distribution[offset].x = totarea;
|
||||||
* Mesh::CurveSeg s = mesh->curve_segments[i];
|
distribution[offset].y = __int_as_float(i + mesh->curve_offset); // XXX fix kernel code
|
||||||
* float3 p1 = mesh->curve_keys[s.v[0]].loc;
|
distribution[offset].z = __int_as_float(j);
|
||||||
* float r1 = mesh->curve_keys[s.v[0]].radius;
|
distribution[offset].w = __int_as_float(object_id);
|
||||||
* float3 p2 = mesh->curve_keys[s.v[1]].loc;
|
offset++;
|
||||||
* float r2 = mesh->curve_keys[s.v[1]].radius;
|
|
||||||
*
|
float3 p1 = mesh->curve_keys[first_key + j].loc;
|
||||||
* if(!transform_applied) {
|
float r1 = mesh->curve_keys[first_key + j].radius;
|
||||||
* p1 = transform_point(&tfm, p1);
|
float3 p2 = mesh->curve_keys[first_key + j + 1].loc;
|
||||||
* p2 = transform_point(&tfm, p2);
|
float r2 = mesh->curve_keys[first_key + j + 1].radius;
|
||||||
* }
|
|
||||||
*
|
if(!transform_applied) {
|
||||||
* totarea += M_PI_F * (r1 + r2) * len(p1 - p2);
|
p1 = transform_point(&tfm, p1);
|
||||||
* }
|
p2 = transform_point(&tfm, p2);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
totarea += M_PI_F * (r1 + r2) * len(p1 - p2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(progress.get_cancel()) return;
|
if(progress.get_cancel()) return;
|
||||||
|
@@ -51,7 +51,7 @@ Mesh::Mesh()
|
|||||||
tri_offset = 0;
|
tri_offset = 0;
|
||||||
vert_offset = 0;
|
vert_offset = 0;
|
||||||
|
|
||||||
curveseg_offset = 0;
|
curve_offset = 0;
|
||||||
curvekey_offset = 0;
|
curvekey_offset = 0;
|
||||||
|
|
||||||
attributes.triangle_mesh = this;
|
attributes.triangle_mesh = this;
|
||||||
@@ -71,7 +71,7 @@ void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys)
|
|||||||
shader.resize(numtris);
|
shader.resize(numtris);
|
||||||
smooth.resize(numtris);
|
smooth.resize(numtris);
|
||||||
curve_keys.resize(numcurvekeys);
|
curve_keys.resize(numcurvekeys);
|
||||||
curve_segments.resize(numcurves);
|
curves.resize(numcurves);
|
||||||
|
|
||||||
attributes.reserve();
|
attributes.reserve();
|
||||||
curve_attributes.reserve();
|
curve_attributes.reserve();
|
||||||
@@ -86,7 +86,7 @@ void Mesh::clear()
|
|||||||
smooth.clear();
|
smooth.clear();
|
||||||
|
|
||||||
curve_keys.clear();
|
curve_keys.clear();
|
||||||
curve_segments.clear();
|
curves.clear();
|
||||||
|
|
||||||
attributes.clear();
|
attributes.clear();
|
||||||
curve_attributes.clear();
|
curve_attributes.clear();
|
||||||
@@ -98,34 +98,33 @@ void Mesh::clear()
|
|||||||
|
|
||||||
void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
|
void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
|
||||||
{
|
{
|
||||||
Triangle t;
|
Triangle tri;
|
||||||
t.v[0] = v0;
|
tri.v[0] = v0;
|
||||||
t.v[1] = v1;
|
tri.v[1] = v1;
|
||||||
t.v[2] = v2;
|
tri.v[2] = v2;
|
||||||
|
|
||||||
triangles.push_back(t);
|
triangles.push_back(tri);
|
||||||
shader.push_back(shader_);
|
shader.push_back(shader_);
|
||||||
smooth.push_back(smooth_);
|
smooth.push_back(smooth_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::add_curve_key(float3 co, float radius)
|
void Mesh::add_curve_key(float3 co, float radius)
|
||||||
{
|
{
|
||||||
CurveKey ck;
|
CurveKey key;
|
||||||
ck.co = co;
|
key.co = co;
|
||||||
ck.radius = radius;
|
key.radius = radius;
|
||||||
|
|
||||||
curve_keys.push_back(ck);
|
curve_keys.push_back(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::add_curve_segment(int v0, int v1, int shader, int curveid)
|
void Mesh::add_curve(int first_key, int num_keys, int shader)
|
||||||
{
|
{
|
||||||
CurveSegment s;
|
Curve curve;
|
||||||
s.v[0] = v0;
|
curve.first_key = first_key;
|
||||||
s.v[1] = v1;
|
curve.num_keys = num_keys;
|
||||||
s.shader = shader;
|
curve.shader = shader;
|
||||||
s.curve = curveid;
|
|
||||||
|
|
||||||
curve_segments.push_back(s);
|
curves.push_back(curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::compute_bounds()
|
void Mesh::compute_bounds()
|
||||||
@@ -284,7 +283,7 @@ void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_keys, size_t curvekey_offset)
|
void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset)
|
||||||
{
|
{
|
||||||
size_t curve_keys_size = curve_keys.size();
|
size_t curve_keys_size = curve_keys.size();
|
||||||
CurveKey *keys_ptr = NULL;
|
CurveKey *keys_ptr = NULL;
|
||||||
@@ -302,25 +301,21 @@ void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_key
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* pack curve segments */
|
/* pack curve segments */
|
||||||
size_t curve_seg_num = curve_segments.size();
|
size_t curve_num = curves.size();
|
||||||
|
|
||||||
if(curve_seg_num) {
|
if(curve_num) {
|
||||||
CurveSegment *curve_ptr = &curve_segments[0];
|
Curve *curve_ptr = &curves[0];
|
||||||
int shader_id = 0;
|
int shader_id = 0;
|
||||||
|
|
||||||
for(size_t i = 0; i < curve_seg_num; i++) {
|
for(size_t i = 0; i < curve_num; i++) {
|
||||||
CurveSegment s = curve_ptr[i];
|
Curve curve = curve_ptr[i];
|
||||||
shader_id = scene->shader_manager->get_shader_id(s.shader, this, false);
|
shader_id = scene->shader_manager->get_shader_id(curve.shader, this, false);
|
||||||
|
|
||||||
float3 p1 = keys_ptr[s.v[0]].co;
|
curve_data[i] = make_float4(
|
||||||
float3 p2 = keys_ptr[s.v[1]].co;
|
__int_as_float(curve.first_key + curvekey_offset),
|
||||||
float length = len(p2 - p1);
|
__int_as_float(curve.num_keys),
|
||||||
|
|
||||||
curve_seg_keys[i] = make_float4(
|
|
||||||
__int_as_float(s.v[0] + curvekey_offset),
|
|
||||||
__int_as_float(s.v[1] + curvekey_offset),
|
|
||||||
__int_as_float(shader_id),
|
__int_as_float(shader_id),
|
||||||
length);
|
0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,7 +536,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
|
|||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if(mesh->curve_segments.size()) {
|
if(mesh->curves.size()) {
|
||||||
attr_map[index].x = id;
|
attr_map[index].x = id;
|
||||||
attr_map[index].y = req.curve_element;
|
attr_map[index].y = req.curve_element;
|
||||||
attr_map[index].z = as_uint(req.curve_offset);
|
attr_map[index].z = as_uint(req.curve_offset);
|
||||||
@@ -588,7 +583,7 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
|
|||||||
size_t size = mattr->element_size(
|
size_t size = mattr->element_size(
|
||||||
mesh->verts.size(),
|
mesh->verts.size(),
|
||||||
mesh->triangles.size(),
|
mesh->triangles.size(),
|
||||||
mesh->curve_segments.size(),
|
mesh->curves.size(),
|
||||||
mesh->curve_keys.size());
|
mesh->curve_keys.size());
|
||||||
|
|
||||||
if(mattr->type == TypeDesc::TypeFloat) {
|
if(mattr->type == TypeDesc::TypeFloat) {
|
||||||
@@ -618,8 +613,8 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
|
|||||||
offset -= mesh->tri_offset;
|
offset -= mesh->tri_offset;
|
||||||
else if(element == ATTR_ELEMENT_CORNER)
|
else if(element == ATTR_ELEMENT_CORNER)
|
||||||
offset -= 3*mesh->tri_offset;
|
offset -= 3*mesh->tri_offset;
|
||||||
else if(element == ATTR_ELEMENT_CURVE_SEGMENT)
|
else if(element == ATTR_ELEMENT_CURVE)
|
||||||
offset -= mesh->curveseg_offset;
|
offset -= mesh->curve_offset;
|
||||||
else if(element == ATTR_ELEMENT_CURVE_KEY)
|
else if(element == ATTR_ELEMENT_CURVE_KEY)
|
||||||
offset -= mesh->curvekey_offset;
|
offset -= mesh->curvekey_offset;
|
||||||
}
|
}
|
||||||
@@ -713,20 +708,20 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
|
|||||||
size_t tri_size = 0;
|
size_t tri_size = 0;
|
||||||
|
|
||||||
size_t curve_key_size = 0;
|
size_t curve_key_size = 0;
|
||||||
size_t curve_seg_keys = 0;
|
size_t curve_size = 0;
|
||||||
|
|
||||||
foreach(Mesh *mesh, scene->meshes) {
|
foreach(Mesh *mesh, scene->meshes) {
|
||||||
mesh->vert_offset = vert_size;
|
mesh->vert_offset = vert_size;
|
||||||
mesh->tri_offset = tri_size;
|
mesh->tri_offset = tri_size;
|
||||||
|
|
||||||
mesh->curvekey_offset = curve_key_size;
|
mesh->curvekey_offset = curve_key_size;
|
||||||
mesh->curveseg_offset = curve_seg_keys;
|
mesh->curve_offset = curve_size;
|
||||||
|
|
||||||
vert_size += mesh->verts.size();
|
vert_size += mesh->verts.size();
|
||||||
tri_size += mesh->triangles.size();
|
tri_size += mesh->triangles.size();
|
||||||
|
|
||||||
curve_key_size += mesh->curve_keys.size();
|
curve_key_size += mesh->curve_keys.size();
|
||||||
curve_seg_keys += mesh->curve_segments.size();
|
curve_size += mesh->curves.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tri_size != 0) {
|
if(tri_size != 0) {
|
||||||
@@ -754,19 +749,19 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
|
|||||||
device->tex_alloc("__tri_vindex", dscene->tri_vindex);
|
device->tex_alloc("__tri_vindex", dscene->tri_vindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(curve_seg_keys != 0) {
|
if(curve_size != 0) {
|
||||||
progress.set_status("Updating Mesh", "Copying Strands to device");
|
progress.set_status("Updating Mesh", "Copying Strands to device");
|
||||||
|
|
||||||
float4 *curve_keys = dscene->curve_keys.resize(curve_key_size);
|
float4 *curve_keys = dscene->curve_keys.resize(curve_key_size);
|
||||||
float4 *curve_segments = dscene->curve_segments.resize(curve_seg_keys);
|
float4 *curves = dscene->curves.resize(curve_size);
|
||||||
|
|
||||||
foreach(Mesh *mesh, scene->meshes) {
|
foreach(Mesh *mesh, scene->meshes) {
|
||||||
mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curve_segments[mesh->curveseg_offset], mesh->curvekey_offset);
|
mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curves[mesh->curve_offset], mesh->curvekey_offset);
|
||||||
if(progress.get_cancel()) return;
|
if(progress.get_cancel()) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
device->tex_alloc("__curve_keys", dscene->curve_keys);
|
device->tex_alloc("__curve_keys", dscene->curve_keys);
|
||||||
device->tex_alloc("__curve_segments", dscene->curve_segments);
|
device->tex_alloc("__curves", dscene->curves);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,9 +799,9 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
|
|||||||
dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size());
|
dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size());
|
||||||
device->tex_alloc("__tri_woop", dscene->tri_woop);
|
device->tex_alloc("__tri_woop", dscene->tri_woop);
|
||||||
}
|
}
|
||||||
if(pack.prim_type.size()) {
|
if(pack.prim_segment.size()) {
|
||||||
dscene->prim_type.reference((uint*)&pack.prim_type[0], pack.prim_type.size());
|
dscene->prim_segment.reference((uint*)&pack.prim_segment[0], pack.prim_segment.size());
|
||||||
device->tex_alloc("__prim_type", dscene->prim_type);
|
device->tex_alloc("__prim_segment", dscene->prim_segment);
|
||||||
}
|
}
|
||||||
if(pack.prim_visibility.size()) {
|
if(pack.prim_visibility.size()) {
|
||||||
dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size());
|
dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size());
|
||||||
@@ -917,7 +912,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
|
|||||||
device->tex_free(dscene->bvh_nodes);
|
device->tex_free(dscene->bvh_nodes);
|
||||||
device->tex_free(dscene->object_node);
|
device->tex_free(dscene->object_node);
|
||||||
device->tex_free(dscene->tri_woop);
|
device->tex_free(dscene->tri_woop);
|
||||||
device->tex_free(dscene->prim_type);
|
device->tex_free(dscene->prim_segment);
|
||||||
device->tex_free(dscene->prim_visibility);
|
device->tex_free(dscene->prim_visibility);
|
||||||
device->tex_free(dscene->prim_index);
|
device->tex_free(dscene->prim_index);
|
||||||
device->tex_free(dscene->prim_object);
|
device->tex_free(dscene->prim_object);
|
||||||
@@ -925,7 +920,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
|
|||||||
device->tex_free(dscene->tri_vnormal);
|
device->tex_free(dscene->tri_vnormal);
|
||||||
device->tex_free(dscene->tri_vindex);
|
device->tex_free(dscene->tri_vindex);
|
||||||
device->tex_free(dscene->tri_verts);
|
device->tex_free(dscene->tri_verts);
|
||||||
device->tex_free(dscene->curve_segments);
|
device->tex_free(dscene->curves);
|
||||||
device->tex_free(dscene->curve_keys);
|
device->tex_free(dscene->curve_keys);
|
||||||
device->tex_free(dscene->attributes_map);
|
device->tex_free(dscene->attributes_map);
|
||||||
device->tex_free(dscene->attributes_float);
|
device->tex_free(dscene->attributes_float);
|
||||||
@@ -934,7 +929,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
|
|||||||
dscene->bvh_nodes.clear();
|
dscene->bvh_nodes.clear();
|
||||||
dscene->object_node.clear();
|
dscene->object_node.clear();
|
||||||
dscene->tri_woop.clear();
|
dscene->tri_woop.clear();
|
||||||
dscene->prim_type.clear();
|
dscene->prim_segment.clear();
|
||||||
dscene->prim_visibility.clear();
|
dscene->prim_visibility.clear();
|
||||||
dscene->prim_index.clear();
|
dscene->prim_index.clear();
|
||||||
dscene->prim_object.clear();
|
dscene->prim_object.clear();
|
||||||
@@ -942,7 +937,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
|
|||||||
dscene->tri_vnormal.clear();
|
dscene->tri_vnormal.clear();
|
||||||
dscene->tri_vindex.clear();
|
dscene->tri_vindex.clear();
|
||||||
dscene->tri_verts.clear();
|
dscene->tri_verts.clear();
|
||||||
dscene->curve_segments.clear();
|
dscene->curves.clear();
|
||||||
dscene->curve_keys.clear();
|
dscene->curve_keys.clear();
|
||||||
dscene->attributes_map.clear();
|
dscene->attributes_map.clear();
|
||||||
dscene->attributes_float.clear();
|
dscene->attributes_float.clear();
|
||||||
|
@@ -51,10 +51,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Mesh Curve */
|
/* Mesh Curve */
|
||||||
struct CurveSegment {
|
struct Curve {
|
||||||
int v[2];
|
int first_key;
|
||||||
|
int num_keys;
|
||||||
uint shader;
|
uint shader;
|
||||||
int curve;
|
uint pad;
|
||||||
|
|
||||||
|
int num_segments() { return num_keys - 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CurveKey {
|
struct CurveKey {
|
||||||
@@ -78,7 +81,7 @@ public:
|
|||||||
vector<bool> smooth;
|
vector<bool> smooth;
|
||||||
|
|
||||||
vector<CurveKey> curve_keys;
|
vector<CurveKey> curve_keys;
|
||||||
vector<CurveSegment> curve_segments;
|
vector<Curve> curves;
|
||||||
|
|
||||||
vector<uint> used_shaders;
|
vector<uint> used_shaders;
|
||||||
AttributeSet attributes;
|
AttributeSet attributes;
|
||||||
@@ -98,7 +101,7 @@ public:
|
|||||||
size_t tri_offset;
|
size_t tri_offset;
|
||||||
size_t vert_offset;
|
size_t vert_offset;
|
||||||
|
|
||||||
size_t curveseg_offset;
|
size_t curve_offset;
|
||||||
size_t curvekey_offset;
|
size_t curvekey_offset;
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
@@ -109,7 +112,7 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
|
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
|
||||||
void add_curve_key(float3 loc, float radius);
|
void add_curve_key(float3 loc, float radius);
|
||||||
void add_curve_segment(int v0, int v1, int shader, int curveid);
|
void add_curve(int first_key, int num_keys, int shader);
|
||||||
|
|
||||||
void compute_bounds();
|
void compute_bounds();
|
||||||
void add_face_normals();
|
void add_face_normals();
|
||||||
@@ -117,7 +120,7 @@ public:
|
|||||||
|
|
||||||
void pack_normals(Scene *scene, float4 *normal, float4 *vnormal);
|
void pack_normals(Scene *scene, float4 *normal, float4 *vnormal);
|
||||||
void pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset);
|
void pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset);
|
||||||
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_seg_keys, size_t curvekey_offset);
|
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
|
||||||
void compute_bvh(SceneParams *params, Progress *progress, int n, int total);
|
void compute_bvh(SceneParams *params, Progress *progress, int n, int total);
|
||||||
|
|
||||||
bool need_attribute(Scene *scene, AttributeStandard std);
|
bool need_attribute(Scene *scene, AttributeStandard std);
|
||||||
|
@@ -203,14 +203,18 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
|||||||
surface_area += triangle_area(p1, p2, p3);
|
surface_area += triangle_area(p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(Mesh::CurveSegment& t, mesh->curve_segments) {
|
foreach(Mesh::Curve& curve, mesh->curves) {
|
||||||
float3 p1 = mesh->curve_keys[t.v[0]].co;
|
int first_key = curve.first_key;
|
||||||
float r1 = mesh->curve_keys[t.v[0]].radius;
|
|
||||||
float3 p2 = mesh->curve_keys[t.v[1]].co;
|
|
||||||
float r2 = mesh->curve_keys[t.v[1]].radius;
|
|
||||||
|
|
||||||
/* currently ignores segment overlaps*/
|
for(int i = 0; i < curve.num_segments(); i++) {
|
||||||
surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
|
float3 p1 = mesh->curve_keys[first_key + i].co;
|
||||||
|
float r1 = mesh->curve_keys[first_key + i].radius;
|
||||||
|
float3 p2 = mesh->curve_keys[first_key + i + 1].co;
|
||||||
|
float r2 = mesh->curve_keys[first_key + i + 1].radius;
|
||||||
|
|
||||||
|
/* currently ignores segment overlaps*/
|
||||||
|
surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
surface_area_map[mesh] = surface_area;
|
surface_area_map[mesh] = surface_area;
|
||||||
@@ -229,14 +233,21 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
|||||||
surface_area += triangle_area(p1, p2, p3);
|
surface_area += triangle_area(p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(Mesh::CurveSegment& t, mesh->curve_segments) {
|
foreach(Mesh::Curve& curve, mesh->curves) {
|
||||||
float3 p1 = mesh->curve_keys[t.v[0]].co;
|
int first_key = curve.first_key;
|
||||||
float r1 = mesh->curve_keys[t.v[0]].radius;
|
|
||||||
float3 p2 = mesh->curve_keys[t.v[1]].co;
|
|
||||||
float r2 = mesh->curve_keys[t.v[1]].radius;
|
|
||||||
|
|
||||||
/* currently ignores segment overlaps*/
|
for(int i = 0; i < curve.num_segments(); i++) {
|
||||||
surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
|
float3 p1 = mesh->curve_keys[first_key + i].co;
|
||||||
|
float r1 = mesh->curve_keys[first_key + i].radius;
|
||||||
|
float3 p2 = mesh->curve_keys[first_key + i + 1].co;
|
||||||
|
float r2 = mesh->curve_keys[first_key + i + 1].radius;
|
||||||
|
|
||||||
|
p1 = transform_point(&tfm, p1);
|
||||||
|
p2 = transform_point(&tfm, p2);
|
||||||
|
|
||||||
|
/* currently ignores segment overlaps*/
|
||||||
|
surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -62,7 +62,7 @@ public:
|
|||||||
device_vector<float4> bvh_nodes;
|
device_vector<float4> bvh_nodes;
|
||||||
device_vector<uint> object_node;
|
device_vector<uint> object_node;
|
||||||
device_vector<float4> tri_woop;
|
device_vector<float4> tri_woop;
|
||||||
device_vector<uint> prim_type;
|
device_vector<uint> prim_segment;
|
||||||
device_vector<uint> prim_visibility;
|
device_vector<uint> prim_visibility;
|
||||||
device_vector<uint> prim_index;
|
device_vector<uint> prim_index;
|
||||||
device_vector<uint> prim_object;
|
device_vector<uint> prim_object;
|
||||||
@@ -73,7 +73,7 @@ public:
|
|||||||
device_vector<float4> tri_vindex;
|
device_vector<float4> tri_vindex;
|
||||||
device_vector<float4> tri_verts;
|
device_vector<float4> tri_verts;
|
||||||
|
|
||||||
device_vector<float4> curve_segments;
|
device_vector<float4> curves;
|
||||||
device_vector<float4> curve_keys;
|
device_vector<float4> curve_keys;
|
||||||
|
|
||||||
/* objects */
|
/* objects */
|
||||||
|
Reference in New Issue
Block a user