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
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/bvh')
-rw-r--r--intern/cycles/bvh/bvh.cpp82
-rw-r--r--intern/cycles/bvh/bvh.h10
-rw-r--r--intern/cycles/bvh/bvh2.cpp4
-rw-r--r--intern/cycles/bvh/bvh2.h4
-rw-r--r--intern/cycles/bvh/bvh4.cpp4
-rw-r--r--intern/cycles/bvh/bvh4.h4
-rw-r--r--intern/cycles/bvh/bvh8.cpp29
-rw-r--r--intern/cycles/bvh/bvh8.h4
-rw-r--r--intern/cycles/bvh/bvh_build.cpp79
-rw-r--r--intern/cycles/bvh/bvh_build.h6
-rw-r--r--intern/cycles/bvh/bvh_embree.cpp165
-rw-r--r--intern/cycles/bvh/bvh_embree.h10
-rw-r--r--intern/cycles/bvh/bvh_optix.cpp129
-rw-r--r--intern/cycles/bvh/bvh_optix.h7
-rw-r--r--intern/cycles/bvh/bvh_params.h5
-rw-r--r--intern/cycles/bvh/bvh_split.cpp41
-rw-r--r--intern/cycles/bvh/bvh_split.h6
-rw-r--r--intern/cycles/bvh/bvh_unaligned.cpp14
18 files changed, 329 insertions, 274 deletions
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 16c721da06a..3a8b0fe7fa2 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -17,6 +17,7 @@
#include "bvh/bvh.h"
+#include "render/hair.h"
#include "render/mesh.h"
#include "render/object.h"
@@ -99,31 +100,33 @@ int BVHStackEntry::encodeIdx() const
/* BVH */
-BVH::BVH(const BVHParams &params_, const vector<Mesh *> &meshes_, const vector<Object *> &objects_)
- : params(params_), meshes(meshes_), objects(objects_)
+BVH::BVH(const BVHParams &params_,
+ const vector<Geometry *> &geometry_,
+ const vector<Object *> &objects_)
+ : params(params_), geometry(geometry_), objects(objects_)
{
}
BVH *BVH::create(const BVHParams &params,
- const vector<Mesh *> &meshes,
+ const vector<Geometry *> &geometry,
const vector<Object *> &objects)
{
switch (params.bvh_layout) {
case BVH_LAYOUT_BVH2:
- return new BVH2(params, meshes, objects);
+ return new BVH2(params, geometry, objects);
case BVH_LAYOUT_BVH4:
- return new BVH4(params, meshes, objects);
+ return new BVH4(params, geometry, objects);
case BVH_LAYOUT_BVH8:
- return new BVH8(params, meshes, objects);
+ return new BVH8(params, geometry, objects);
case BVH_LAYOUT_EMBREE:
#ifdef WITH_EMBREE
- return new BVHEmbree(params, meshes, objects);
+ return new BVHEmbree(params, geometry, objects);
#else
break;
#endif
case BVH_LAYOUT_OPTIX:
#ifdef WITH_OPTIX
- return new BVHOptiX(params, meshes, objects);
+ return new BVHOptiX(params, geometry, objects);
#else
break;
#endif
@@ -217,36 +220,36 @@ void BVH::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility)
}
else {
/* Primitives. */
- const Mesh *mesh = ob->mesh;
-
if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* Curves. */
- int str_offset = (params.top_level) ? mesh->curve_offset : 0;
- Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
+ const Hair *hair = static_cast<const Hair *>(ob->geometry);
+ int prim_offset = (params.top_level) ? hair->prim_offset : 0;
+ Hair::Curve curve = hair->get_curve(pidx - prim_offset);
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
- curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
+ curve.bounds_grow(k, &hair->curve_keys[0], &hair->curve_radius[0], bbox);
visibility |= PATH_RAY_CURVE;
/* Motion curves. */
- if (mesh->use_motion_blur) {
- Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (hair->use_motion_blur) {
+ Attribute *attr = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (attr) {
- size_t mesh_size = mesh->curve_keys.size();
- size_t steps = mesh->motion_steps - 1;
+ size_t hair_size = hair->curve_keys.size();
+ size_t steps = hair->motion_steps - 1;
float3 *key_steps = attr->data_float3();
for (size_t i = 0; i < steps; i++)
- curve.bounds_grow(k, key_steps + i * mesh_size, &mesh->curve_radius[0], bbox);
+ curve.bounds_grow(k, key_steps + i * hair_size, &hair->curve_radius[0], bbox);
}
}
}
else {
/* Triangles. */
- int tri_offset = (params.top_level) ? mesh->tri_offset : 0;
- Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
+ const Mesh *mesh = static_cast<const Mesh *>(ob->geometry);
+ int prim_offset = (params.top_level) ? mesh->prim_offset : 0;
+ Mesh::Triangle triangle = mesh->get_triangle(pidx - prim_offset);
const float3 *vpos = &mesh->verts[0];
triangle.bounds_grow(vpos, bbox);
@@ -276,7 +279,7 @@ void BVH::pack_triangle(int idx, float4 tri_verts[3])
{
int tob = pack.prim_object[idx];
assert(tob >= 0 && tob < objects.size());
- const Mesh *mesh = objects[tob]->mesh;
+ const Mesh *mesh = static_cast<const Mesh *>(objects[tob]->geometry);
int tidx = pack.prim_index[idx];
Mesh::Triangle t = mesh->get_triangle(tidx);
@@ -347,15 +350,13 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
const bool use_obvh = (params.bvh_layout == BVH_LAYOUT_BVH8);
/* Adjust primitive index to point to the triangle in the global array, for
- * meshes with transform applied and already in the top level BVH.
+ * geometry 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_type[i] & PRIMITIVE_ALL_CURVE)
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
- else
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ pack.prim_index[i] += objects[pack.prim_object[i]]->geometry->prim_offset;
}
+ }
/* track offsets of instanced BVH data in global array */
size_t prim_offset = pack.prim_index.size();
@@ -375,10 +376,10 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
size_t pack_leaf_nodes_offset = leaf_nodes_size;
size_t object_offset = 0;
- foreach (Mesh *mesh, meshes) {
- BVH *bvh = mesh->bvh;
+ foreach (Geometry *geom, geometry) {
+ BVH *bvh = geom->bvh;
- if (mesh->need_build_bvh(params.bvh_layout)) {
+ if (geom->need_build_bvh(params.bvh_layout)) {
prim_index_size += bvh->pack.prim_index.size();
prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
nodes_size += bvh->pack.nodes.size();
@@ -410,36 +411,35 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
int4 *pack_leaf_nodes = (pack.leaf_nodes.size()) ? &pack.leaf_nodes[0] : NULL;
float2 *pack_prim_time = (pack.prim_time.size()) ? &pack.prim_time[0] : NULL;
- map<Mesh *, int> mesh_map;
+ map<Geometry *, int> geometry_map;
/* merge */
foreach (Object *ob, objects) {
- Mesh *mesh = ob->mesh;
+ Geometry *geom = ob->geometry;
/* We assume that if mesh doesn't need own BVH it was already included
* into a top-level BVH and no packing here is needed.
*/
- if (!mesh->need_build_bvh(params.bvh_layout)) {
+ if (!geom->need_build_bvh(params.bvh_layout)) {
pack.object_node[object_offset++] = 0;
continue;
}
/* if mesh already added once, don't add it again, but used set
* node offset for this object */
- map<Mesh *, int>::iterator it = mesh_map.find(mesh);
+ map<Geometry *, int>::iterator it = geometry_map.find(geom);
- if (mesh_map.find(mesh) != mesh_map.end()) {
+ if (geometry_map.find(geom) != geometry_map.end()) {
int noffset = it->second;
pack.object_node[object_offset++] = noffset;
continue;
}
- BVH *bvh = mesh->bvh;
+ BVH *bvh = geom->bvh;
int noffset = nodes_offset;
int noffset_leaf = nodes_leaf_offset;
- int mesh_tri_offset = mesh->tri_offset;
- int mesh_curve_offset = mesh->curve_offset;
+ int geom_prim_offset = geom->prim_offset;
/* fill in node indexes for instances */
if (bvh->pack.root_index == -1)
@@ -447,7 +447,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
else
pack.object_node[object_offset++] = noffset;
- mesh_map[mesh] = pack.object_node[object_offset - 1];
+ geometry_map[geom] = pack.object_node[object_offset - 1];
/* merge primitive, object and triangle indexes */
if (bvh->pack.prim_index.size()) {
@@ -460,11 +460,11 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
for (size_t i = 0; i < bvh_prim_index_size; i++) {
if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
- 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] + geom_prim_offset;
pack_prim_tri_index[pack_prim_index_offset] = -1;
}
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] + geom_prim_offset;
pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i] +
pack_prim_tri_verts_offset;
}
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 92082e4de86..bdde38640c9 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -33,7 +33,7 @@ struct BVHStackEntry;
class BVHParams;
class BoundBox;
class LeafNode;
-class Mesh;
+class Geometry;
class Object;
class Progress;
@@ -84,11 +84,11 @@ class BVH {
public:
PackedBVH pack;
BVHParams params;
- vector<Mesh *> meshes;
+ vector<Geometry *> geometry;
vector<Object *> objects;
static BVH *create(const BVHParams &params,
- const vector<Mesh *> &meshes,
+ const vector<Geometry *> &geometry,
const vector<Object *> &objects);
virtual ~BVH()
{
@@ -102,7 +102,9 @@ class BVH {
void refit(Progress &progress);
protected:
- BVH(const BVHParams &params, const vector<Mesh *> &meshes, const vector<Object *> &objects);
+ BVH(const BVHParams &params,
+ const vector<Geometry *> &geometry,
+ const vector<Object *> &objects);
/* Refit range of primitives. */
void refit_primitives(int start, int end, BoundBox &bbox, uint &visibility);
diff --git a/intern/cycles/bvh/bvh2.cpp b/intern/cycles/bvh/bvh2.cpp
index b1a9148c297..c903070429e 100644
--- a/intern/cycles/bvh/bvh2.cpp
+++ b/intern/cycles/bvh/bvh2.cpp
@@ -26,9 +26,9 @@
CCL_NAMESPACE_BEGIN
BVH2::BVH2(const BVHParams &params_,
- const vector<Mesh *> &meshes_,
+ const vector<Geometry *> &geometry_,
const vector<Object *> &objects_)
- : BVH(params_, meshes_, objects_)
+ : BVH(params_, geometry_, objects_)
{
}
diff --git a/intern/cycles/bvh/bvh2.h b/intern/cycles/bvh/bvh2.h
index a3eaff9cf65..fa3e45b72d2 100644
--- a/intern/cycles/bvh/bvh2.h
+++ b/intern/cycles/bvh/bvh2.h
@@ -46,7 +46,9 @@ class BVH2 : public BVH {
protected:
/* constructor */
friend class BVH;
- BVH2(const BVHParams &params, const vector<Mesh *> &meshes, const vector<Object *> &objects);
+ BVH2(const BVHParams &params,
+ const vector<Geometry *> &geometry,
+ const vector<Object *> &objects);
/* Building process. */
virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
diff --git a/intern/cycles/bvh/bvh4.cpp b/intern/cycles/bvh/bvh4.cpp
index 89b42ee1d21..143c3e54f94 100644
--- a/intern/cycles/bvh/bvh4.cpp
+++ b/intern/cycles/bvh/bvh4.cpp
@@ -32,9 +32,9 @@ CCL_NAMESPACE_BEGIN
*/
BVH4::BVH4(const BVHParams &params_,
- const vector<Mesh *> &meshes_,
+ const vector<Geometry *> &geometry_,
const vector<Object *> &objects_)
- : BVH(params_, meshes_, objects_)
+ : BVH(params_, geometry_, objects_)
{
params.bvh_layout = BVH_LAYOUT_BVH4;
}
diff --git a/intern/cycles/bvh/bvh4.h b/intern/cycles/bvh/bvh4.h
index c44f2833c84..afbb9007afb 100644
--- a/intern/cycles/bvh/bvh4.h
+++ b/intern/cycles/bvh/bvh4.h
@@ -46,7 +46,9 @@ class BVH4 : public BVH {
protected:
/* constructor */
friend class BVH;
- BVH4(const BVHParams &params, const vector<Mesh *> &meshes, const vector<Object *> &objects);
+ BVH4(const BVHParams &params,
+ const vector<Geometry *> &geometry,
+ const vector<Object *> &objects);
/* Building process. */
virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
diff --git a/intern/cycles/bvh/bvh8.cpp b/intern/cycles/bvh/bvh8.cpp
index d3516525f78..342dd9e85a5 100644
--- a/intern/cycles/bvh/bvh8.cpp
+++ b/intern/cycles/bvh/bvh8.cpp
@@ -28,6 +28,7 @@
#include "bvh/bvh8.h"
+#include "render/hair.h"
#include "render/mesh.h"
#include "render/object.h"
@@ -37,9 +38,9 @@
CCL_NAMESPACE_BEGIN
BVH8::BVH8(const BVHParams &params_,
- const vector<Mesh *> &meshes_,
+ const vector<Geometry *> &geometry_,
const vector<Object *> &objects_)
- : BVH(params_, meshes_, objects_)
+ : BVH(params_, geometry_, objects_)
{
}
@@ -429,37 +430,37 @@ void BVH8::refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility)
}
else {
/* Primitives. */
- const Mesh *mesh = ob->mesh;
-
if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* Curves. */
- int str_offset = (params.top_level) ? mesh->curve_offset : 0;
- Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
+ const Hair *hair = static_cast<const Hair *>(ob->geometry);
+ int prim_offset = (params.top_level) ? hair->prim_offset : 0;
+ Hair::Curve curve = hair->get_curve(pidx - prim_offset);
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
- curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
+ curve.bounds_grow(k, &hair->curve_keys[0], &hair->curve_radius[0], bbox);
visibility |= PATH_RAY_CURVE;
/* Motion curves. */
- if (mesh->use_motion_blur) {
- Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (hair->use_motion_blur) {
+ Attribute *attr = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (attr) {
- size_t mesh_size = mesh->curve_keys.size();
- size_t steps = mesh->motion_steps - 1;
+ size_t hair_size = hair->curve_keys.size();
+ size_t steps = hair->motion_steps - 1;
float3 *key_steps = attr->data_float3();
for (size_t i = 0; i < steps; i++) {
- curve.bounds_grow(k, key_steps + i * mesh_size, &mesh->curve_radius[0], bbox);
+ curve.bounds_grow(k, key_steps + i * hair_size, &hair->curve_radius[0], bbox);
}
}
}
}
else {
/* Triangles. */
- int tri_offset = (params.top_level) ? mesh->tri_offset : 0;
- Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
+ const Mesh *mesh = static_cast<const Mesh *>(ob->geometry);
+ int prim_offset = (params.top_level) ? mesh->prim_offset : 0;
+ Mesh::Triangle triangle = mesh->get_triangle(pidx - prim_offset);
const float3 *vpos = &mesh->verts[0];
triangle.bounds_grow(vpos, bbox);
diff --git a/intern/cycles/bvh/bvh8.h b/intern/cycles/bvh/bvh8.h
index 5f26fd423e1..d23fa528e3e 100644
--- a/intern/cycles/bvh/bvh8.h
+++ b/intern/cycles/bvh/bvh8.h
@@ -57,7 +57,9 @@ class BVH8 : public BVH {
protected:
/* constructor */
friend class BVH;
- BVH8(const BVHParams &params, const vector<Mesh *> &meshes, const vector<Object *> &objects);
+ BVH8(const BVHParams &params,
+ const vector<Geometry *> &geometry,
+ const vector<Object *> &objects);
/* Building process. */
virtual BVHNode *widen_children_nodes(const BVHNode *root) override;
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index 1d9b006e8cb..b472c55d156 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -22,6 +22,7 @@
#include "bvh/bvh_params.h"
#include "bvh_split.h"
+#include "render/hair.h"
#include "render/mesh.h"
#include "render/object.h"
#include "render/scene.h"
@@ -194,21 +195,21 @@ void BVHBuild::add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *m
}
}
-void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Mesh *mesh, int i)
+void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair, int i)
{
const Attribute *curve_attr_mP = NULL;
- if (mesh->has_motion_blur()) {
- curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (hair->has_motion_blur()) {
+ curve_attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
}
- const size_t num_curves = mesh->num_curves();
+ const size_t num_curves = hair->num_curves();
for (uint j = 0; j < num_curves; j++) {
- const Mesh::Curve curve = mesh->get_curve(j);
- const float *curve_radius = &mesh->curve_radius[0];
+ const Hair::Curve curve = hair->get_curve(j);
+ const float *curve_radius = &hair->curve_radius[0];
for (int k = 0; k < curve.num_keys - 1; k++) {
if (curve_attr_mP == NULL) {
/* Really simple logic for static hair. */
BoundBox bounds = BoundBox::empty;
- curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
+ curve.bounds_grow(k, &hair->curve_keys[0], curve_radius, bounds);
if (bounds.valid()) {
int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_CURVE, k);
references.push_back(BVHReference(bounds, j, i, packed_type));
@@ -223,9 +224,9 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Mesh *mesh
*/
/* TODO(sergey): Support motion steps for spatially split BVH. */
BoundBox bounds = BoundBox::empty;
- curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
- const size_t num_keys = mesh->curve_keys.size();
- const size_t num_steps = mesh->motion_steps;
+ curve.bounds_grow(k, &hair->curve_keys[0], curve_radius, bounds);
+ const size_t num_keys = hair->curve_keys.size();
+ const size_t num_steps = hair->motion_steps;
const float3 *key_steps = curve_attr_mP->data_float3();
for (size_t step = 0; step < num_steps - 1; step++) {
curve.bounds_grow(k, key_steps + step * num_keys, curve_radius, bounds);
@@ -244,10 +245,10 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Mesh *mesh
*/
const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
- const size_t num_steps = mesh->motion_steps;
- const float3 *curve_keys = &mesh->curve_keys[0];
+ const size_t num_steps = hair->motion_steps;
+ const float3 *curve_keys = &hair->curve_keys[0];
const float3 *key_steps = curve_attr_mP->data_float3();
- const size_t num_keys = mesh->curve_keys.size();
+ const size_t num_keys = hair->curve_keys.size();
/* Calculate bounding box of the previous time step.
* Will be reused later to avoid duplicated work on
* calculating BVH time step boundbox.
@@ -302,13 +303,15 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Mesh *mesh
}
}
-void BVHBuild::add_reference_mesh(BoundBox &root, BoundBox &center, Mesh *mesh, int i)
+void BVHBuild::add_reference_geometry(BoundBox &root, BoundBox &center, Geometry *geom, int i)
{
- if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
+ if (geom->type == Geometry::MESH) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
add_reference_triangles(root, center, mesh, i);
}
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- add_reference_curves(root, center, mesh, i);
+ else if (geom->type == Geometry::HAIR) {
+ Hair *hair = static_cast<Hair *>(geom);
+ add_reference_curves(root, center, hair, i);
}
}
@@ -319,16 +322,30 @@ void BVHBuild::add_reference_object(BoundBox &root, BoundBox &center, Object *ob
center.grow(ob->bounds.center2());
}
-static size_t count_curve_segments(Mesh *mesh)
+static size_t count_curve_segments(Hair *hair)
{
- size_t num = 0, num_curves = mesh->num_curves();
+ size_t num = 0, num_curves = hair->num_curves();
for (size_t i = 0; i < num_curves; i++)
- num += mesh->get_curve(i).num_keys - 1;
+ num += hair->get_curve(i).num_keys - 1;
return num;
}
+static size_t count_primitives(Geometry *geom)
+{
+ if (geom->type == Geometry::MESH) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ return mesh->num_triangles();
+ }
+ else if (geom->type == Geometry::HAIR) {
+ Hair *hair = static_cast<Hair *>(geom);
+ return count_curve_segments(hair);
+ }
+
+ return 0;
+}
+
void BVHBuild::add_references(BVHRange &root)
{
/* reserve space for references */
@@ -339,24 +356,14 @@ void BVHBuild::add_references(BVHRange &root)
if (!ob->is_traceable()) {
continue;
}
- if (!ob->mesh->is_instanced()) {
- if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
- num_alloc_references += ob->mesh->num_triangles();
- }
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- num_alloc_references += count_curve_segments(ob->mesh);
- }
+ if (!ob->geometry->is_instanced()) {
+ num_alloc_references += count_primitives(ob->geometry);
}
else
num_alloc_references++;
}
else {
- if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
- num_alloc_references += ob->mesh->num_triangles();
- }
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- num_alloc_references += count_curve_segments(ob->mesh);
- }
+ num_alloc_references += count_primitives(ob->geometry);
}
}
@@ -372,13 +379,13 @@ void BVHBuild::add_references(BVHRange &root)
++i;
continue;
}
- if (!ob->mesh->is_instanced())
- add_reference_mesh(bounds, center, ob->mesh, i);
+ if (!ob->geometry->is_instanced())
+ add_reference_geometry(bounds, center, ob->geometry, i);
else
add_reference_object(bounds, center, ob, i);
}
else
- add_reference_mesh(bounds, center, ob->mesh, i);
+ add_reference_geometry(bounds, center, ob->geometry, i);
i++;
diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h
index 9685e26cfac..3fe4c3799e2 100644
--- a/intern/cycles/bvh/bvh_build.h
+++ b/intern/cycles/bvh/bvh_build.h
@@ -35,6 +35,8 @@ class BVHNode;
class BVHSpatialSplitBuildTask;
class BVHParams;
class InnerNode;
+class Geometry;
+class Hair;
class Mesh;
class Object;
class Progress;
@@ -65,8 +67,8 @@ class BVHBuild {
/* Adding references. */
void add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *mesh, int i);
- void add_reference_curves(BoundBox &root, BoundBox &center, Mesh *mesh, int i);
- void add_reference_mesh(BoundBox &root, BoundBox &center, Mesh *mesh, int i);
+ void add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair, int i);
+ void add_reference_geometry(BoundBox &root, BoundBox &center, Geometry *geom, int i);
void add_reference_object(BoundBox &root, BoundBox &center, Object *ob, int i);
void add_references(BVHRange &root);
diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index 3e4978a2c0a..88302f11e7e 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -49,6 +49,7 @@
# include "kernel/kernel_globals.h"
# include "kernel/kernel_random.h"
+# include "render/hair.h"
# include "render/mesh.h"
# include "render/object.h"
# include "util/util_foreach.h"
@@ -301,10 +302,24 @@ RTCDevice BVHEmbree::rtc_shared_device = NULL;
int BVHEmbree::rtc_shared_users = 0;
thread_mutex BVHEmbree::rtc_shared_mutex;
+static size_t count_primitives(Geometry *geom)
+{
+ if (geom->type == Geometry::MESH) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ return mesh->num_triangles();
+ }
+ else if (geom->type == Geometry::HAIR) {
+ Hair *hair = static_cast<Hair *>(geom);
+ return hair->num_segments();
+ }
+
+ return 0;
+}
+
BVHEmbree::BVHEmbree(const BVHParams &params_,
- const vector<Mesh *> &meshes_,
+ const vector<Geometry *> &geometry_,
const vector<Object *> &objects_)
- : BVH(params_, meshes_, objects_),
+ : BVH(params_, geometry_, objects_),
scene(NULL),
mem_used(0),
top_level(NULL),
@@ -436,29 +451,15 @@ void BVHEmbree::build(Progress &progress, Stats *stats_)
if (!ob->is_traceable()) {
continue;
}
- if (!ob->mesh->is_instanced()) {
- if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
- prim_count += ob->mesh->num_triangles();
- }
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- for (size_t j = 0; j < ob->mesh->num_curves(); ++j) {
- prim_count += ob->mesh->get_curve(j).num_segments();
- }
- }
+ if (!ob->geometry->is_instanced()) {
+ prim_count += count_primitives(ob->geometry);
}
else {
++prim_count;
}
}
else {
- if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && ob->mesh->num_triangles() > 0) {
- prim_count += ob->mesh->num_triangles();
- }
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- for (size_t j = 0; j < ob->mesh->num_curves(); ++j) {
- prim_count += ob->mesh->get_curve(j).num_segments();
- }
- }
+ prim_count += count_primitives(ob->geometry);
}
}
@@ -477,7 +478,7 @@ void BVHEmbree::build(Progress &progress, Stats *stats_)
++i;
continue;
}
- if (!ob->mesh->is_instanced()) {
+ if (!ob->geometry->is_instanced()) {
add_object(ob, i);
}
else {
@@ -528,22 +529,29 @@ BVHNode *BVHEmbree::widen_children_nodes(const BVHNode * /*root*/)
void BVHEmbree::add_object(Object *ob, int i)
{
- Mesh *mesh = ob->mesh;
- if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && mesh->num_triangles() > 0) {
- add_triangles(ob, i);
+ Geometry *geom = ob->geometry;
+
+ if (geom->type == Geometry::MESH) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ if (mesh->num_triangles() > 0) {
+ add_triangles(ob, mesh, i);
+ }
}
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) {
- add_curves(ob, i);
+ else if (geom->type == Geometry::HAIR) {
+ Hair *hair = static_cast<Hair *>(geom);
+ if (hair->num_curves() > 0) {
+ add_curves(ob, hair, i);
+ }
}
}
void BVHEmbree::add_instance(Object *ob, int i)
{
- if (!ob || !ob->mesh) {
+ if (!ob || !ob->geometry) {
assert(0);
return;
}
- BVHEmbree *instance_bvh = (BVHEmbree *)(ob->mesh->bvh);
+ BVHEmbree *instance_bvh = (BVHEmbree *)(ob->geometry->bvh);
if (instance_bvh->top_level != this) {
instance_bvh->top_level = this;
@@ -577,10 +585,9 @@ void BVHEmbree::add_instance(Object *ob, int i)
rtcReleaseGeometry(geom_id);
}
-void BVHEmbree::add_triangles(Object *ob, int i)
+void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i)
{
size_t prim_offset = pack.prim_index.size();
- Mesh *mesh = ob->mesh;
const Attribute *attr_mP = NULL;
size_t num_motion_steps = 1;
if (mesh->has_motion_blur()) {
@@ -684,31 +691,31 @@ void BVHEmbree::update_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh)
}
}
-void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh)
+void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair)
{
const Attribute *attr_mP = NULL;
size_t num_motion_steps = 1;
- if (mesh->has_motion_blur()) {
- attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (hair->has_motion_blur()) {
+ attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (attr_mP) {
- num_motion_steps = mesh->motion_steps;
+ num_motion_steps = hair->motion_steps;
}
}
- const size_t num_curves = mesh->num_curves();
+ const size_t num_curves = hair->num_curves();
size_t num_keys = 0;
for (size_t j = 0; j < num_curves; ++j) {
- const Mesh::Curve c = mesh->get_curve(j);
+ const Hair::Curve c = hair->get_curve(j);
num_keys += c.num_keys;
}
/* Copy the CV data to Embree */
const int t_mid = (num_motion_steps - 1) / 2;
- const float *curve_radius = &mesh->curve_radius[0];
+ const float *curve_radius = &hair->curve_radius[0];
for (int t = 0; t < num_motion_steps; ++t) {
const float3 *verts;
if (t == t_mid || attr_mP == NULL) {
- verts = &mesh->curve_keys[0];
+ verts = &hair->curve_keys[0];
}
else {
int t_ = (t > t_mid) ? (t - 1) : t;
@@ -726,9 +733,9 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh
assert(rtc_verts);
if (rtc_verts) {
if (use_curves && rtc_tangents) {
- const size_t num_curves = mesh->num_curves();
+ const size_t num_curves = hair->num_curves();
for (size_t j = 0; j < num_curves; ++j) {
- Mesh::Curve c = mesh->get_curve(j);
+ Hair::Curve c = hair->get_curve(j);
int fk = c.first_key;
rtc_verts[0] = float3_to_float4(verts[fk]);
rtc_verts[0].w = curve_radius[fk];
@@ -760,23 +767,22 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh
}
}
-void BVHEmbree::add_curves(Object *ob, int i)
+void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
{
size_t prim_offset = pack.prim_index.size();
- const Mesh *mesh = ob->mesh;
const Attribute *attr_mP = NULL;
size_t num_motion_steps = 1;
- if (mesh->has_motion_blur()) {
- attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ if (hair->has_motion_blur()) {
+ attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if (attr_mP) {
- num_motion_steps = mesh->motion_steps;
+ num_motion_steps = hair->motion_steps;
}
}
- const size_t num_curves = mesh->num_curves();
+ const size_t num_curves = hair->num_curves();
size_t num_segments = 0;
for (size_t j = 0; j < num_curves; ++j) {
- Mesh::Curve c = mesh->get_curve(j);
+ Hair::Curve c = hair->get_curve(j);
assert(c.num_segments() > 0);
num_segments += c.num_segments();
}
@@ -802,7 +808,7 @@ void BVHEmbree::add_curves(Object *ob, int i)
geom_id, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT, sizeof(int), num_segments);
size_t rtc_index = 0;
for (size_t j = 0; j < num_curves; ++j) {
- Mesh::Curve c = mesh->get_curve(j);
+ Hair::Curve c = hair->get_curve(j);
for (size_t k = 0; k < c.num_segments(); ++k) {
rtc_indices[rtc_index] = c.first_key + k;
/* Cycles specific data. */
@@ -819,7 +825,7 @@ void BVHEmbree::add_curves(Object *ob, int i)
rtcSetGeometryBuildQuality(geom_id, build_quality);
rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
- update_curve_vertex_buffer(geom_id, mesh);
+ update_curve_vertex_buffer(geom_id, hair);
rtcSetGeometryUserData(geom_id, (void *)prim_offset);
rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_func);
@@ -840,10 +846,7 @@ void BVHEmbree::pack_nodes(const BVHNode *)
for (size_t i = 0; i < pack.prim_index.size(); ++i) {
if (pack.prim_index[i] != -1) {
- if (pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
- else
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ pack.prim_index[i] += objects[pack.prim_object[i]]->geometry->prim_offset;
}
}
@@ -857,22 +860,22 @@ void BVHEmbree::pack_nodes(const BVHNode *)
size_t pack_prim_tri_verts_offset = prim_tri_verts_size;
size_t object_offset = 0;
- map<Mesh *, int> mesh_map;
+ map<Geometry *, int> geometry_map;
foreach (Object *ob, objects) {
- Mesh *mesh = ob->mesh;
- BVH *bvh = mesh->bvh;
+ Geometry *geom = ob->geometry;
+ BVH *bvh = geom->bvh;
- if (mesh->need_build_bvh(BVH_LAYOUT_EMBREE)) {
- if (mesh_map.find(mesh) == mesh_map.end()) {
+ if (geom->need_build_bvh(BVH_LAYOUT_EMBREE)) {
+ if (geometry_map.find(geom) == geometry_map.end()) {
prim_index_size += bvh->pack.prim_index.size();
prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
- mesh_map[mesh] = 1;
+ geometry_map[geom] = 1;
}
}
}
- mesh_map.clear();
+ geometry_map.clear();
pack.prim_index.resize(prim_index_size);
pack.prim_type.resize(prim_index_size);
@@ -890,38 +893,37 @@ void BVHEmbree::pack_nodes(const BVHNode *)
/* merge */
foreach (Object *ob, objects) {
- Mesh *mesh = ob->mesh;
+ Geometry *geom = ob->geometry;
/* We assume that if mesh doesn't need own BVH it was already included
* into a top-level BVH and no packing here is needed.
*/
- if (!mesh->need_build_bvh(BVH_LAYOUT_EMBREE)) {
+ if (!geom->need_build_bvh(BVH_LAYOUT_EMBREE)) {
pack.object_node[object_offset++] = prim_offset;
continue;
}
- /* if mesh already added once, don't add it again, but used set
+ /* if geom already added once, don't add it again, but used set
* node offset for this object */
- map<Mesh *, int>::iterator it = mesh_map.find(mesh);
+ map<Geometry *, int>::iterator it = geometry_map.find(geom);
- if (mesh_map.find(mesh) != mesh_map.end()) {
+ if (geometry_map.find(geom) != geometry_map.end()) {
int noffset = it->second;
pack.object_node[object_offset++] = noffset;
continue;
}
- BVHEmbree *bvh = (BVHEmbree *)mesh->bvh;
+ BVHEmbree *bvh = (BVHEmbree *)geom->bvh;
rtc_memory_monitor_func(stats, unaccounted_mem, true);
unaccounted_mem = 0;
- int mesh_tri_offset = mesh->tri_offset;
- int mesh_curve_offset = mesh->curve_offset;
+ int prim_offset = geom->prim_offset;
/* fill in node indexes for instances */
pack.object_node[object_offset++] = prim_offset;
- mesh_map[mesh] = pack.object_node[object_offset - 1];
+ geometry_map[geom] = pack.object_node[object_offset - 1];
/* merge primitive, object and triangle indexes */
if (bvh->pack.prim_index.size()) {
@@ -932,11 +934,11 @@ void BVHEmbree::pack_nodes(const BVHNode *)
for (size_t i = 0; i < bvh_prim_index_size; ++i) {
if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
- 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] + prim_offset;
pack_prim_tri_index[pack_prim_index_offset] = -1;
}
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] + prim_offset;
pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i] +
pack_prim_tri_verts_offset;
}
@@ -966,15 +968,22 @@ void BVHEmbree::refit_nodes()
/* Update all vertex buffers, then tell Embree to rebuild/-fit the BVHs. */
unsigned geom_id = 0;
foreach (Object *ob, objects) {
- if (!params.top_level || (ob->is_traceable() && !ob->mesh->is_instanced())) {
- if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && ob->mesh->num_triangles() > 0) {
- update_tri_vertex_buffer(rtcGetGeometry(scene, geom_id), ob->mesh);
- rtcCommitGeometry(rtcGetGeometry(scene, geom_id));
+ if (!params.top_level || (ob->is_traceable() && !ob->geometry->is_instanced())) {
+ Geometry *geom = ob->geometry;
+
+ if (geom->type == Geometry::MESH) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ if (mesh->num_triangles() > 0) {
+ update_tri_vertex_buffer(rtcGetGeometry(scene, geom_id), mesh);
+ rtcCommitGeometry(rtcGetGeometry(scene, geom_id));
+ }
}
-
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE && ob->mesh->num_curves() > 0) {
- update_curve_vertex_buffer(rtcGetGeometry(scene, geom_id + 1), ob->mesh);
- rtcCommitGeometry(rtcGetGeometry(scene, geom_id + 1));
+ else if (geom->type == Geometry::HAIR) {
+ Hair *hair = static_cast<Hair *>(geom);
+ if (hair->num_curves() > 0) {
+ update_curve_vertex_buffer(rtcGetGeometry(scene, geom_id + 1), hair);
+ rtcCommitGeometry(rtcGetGeometry(scene, geom_id + 1));
+ }
}
}
geom_id += 2;
diff --git a/intern/cycles/bvh/bvh_embree.h b/intern/cycles/bvh/bvh_embree.h
index 123e87dd9b0..eb121d060b7 100644
--- a/intern/cycles/bvh/bvh_embree.h
+++ b/intern/cycles/bvh/bvh_embree.h
@@ -31,6 +31,8 @@
CCL_NAMESPACE_BEGIN
+class Geometry;
+class Hair;
class Mesh;
class BVHEmbree : public BVH {
@@ -47,7 +49,7 @@ class BVHEmbree : public BVH {
protected:
friend class BVH;
BVHEmbree(const BVHParams &params,
- const vector<Mesh *> &meshes,
+ const vector<Geometry *> &geometry,
const vector<Object *> &objects);
virtual void pack_nodes(const BVHNode *) override;
@@ -55,8 +57,8 @@ class BVHEmbree : public BVH {
void add_object(Object *ob, int i);
void add_instance(Object *ob, int i);
- void add_curves(Object *ob, int i);
- void add_triangles(Object *ob, int i);
+ void add_curves(const Object *ob, const Hair *hair, int i);
+ void add_triangles(const Object *ob, const Mesh *mesh, int i);
ssize_t mem_used;
@@ -69,7 +71,7 @@ class BVHEmbree : public BVH {
private:
void delete_rtcScene();
void update_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh);
- void update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh);
+ void update_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair);
static RTCDevice rtc_shared_device;
static int rtc_shared_users;
diff --git a/intern/cycles/bvh/bvh_optix.cpp b/intern/cycles/bvh/bvh_optix.cpp
index 86d755ab06a..a3b6261dcad 100644
--- a/intern/cycles/bvh/bvh_optix.cpp
+++ b/intern/cycles/bvh/bvh_optix.cpp
@@ -18,6 +18,8 @@
#ifdef WITH_OPTIX
# include "bvh/bvh_optix.h"
+# include "render/hair.h"
+# include "render/geometry.h"
# include "render/mesh.h"
# include "render/object.h"
# include "util/util_logging.h"
@@ -26,9 +28,9 @@
CCL_NAMESPACE_BEGIN
BVHOptiX::BVHOptiX(const BVHParams &params_,
- const vector<Mesh *> &meshes_,
+ const vector<Geometry *> &geometry_,
const vector<Object *> &objects_)
- : BVH(params_, meshes_, objects_)
+ : BVH(params_, geometry_, objects_)
{
}
@@ -56,47 +58,52 @@ void BVHOptiX::copy_to_device(Progress &progress, DeviceScene *dscene)
void BVHOptiX::pack_blas()
{
// Bottom-level BVH can contain multiple primitive types, so merge them:
- assert(meshes.size() == 1 && objects.size() == 1); // These are build per-mesh
- Mesh *const mesh = meshes[0];
-
- if (params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) {
- const size_t num_curves = mesh->num_curves();
- const size_t num_segments = mesh->num_segments();
- pack.prim_type.reserve(pack.prim_type.size() + num_segments);
- pack.prim_index.reserve(pack.prim_index.size() + num_segments);
- pack.prim_object.reserve(pack.prim_object.size() + num_segments);
- // 'pack.prim_time' is only used in geom_curve_intersect.h
- // It is not needed because of OPTIX_MOTION_FLAG_[START|END]_VANISH
-
- uint type = PRIMITIVE_CURVE;
- if (mesh->use_motion_blur && mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION))
- type = PRIMITIVE_MOTION_CURVE;
-
- for (size_t j = 0; j < num_curves; ++j) {
- const Mesh::Curve curve = mesh->get_curve(j);
- for (size_t k = 0; k < curve.num_segments(); ++k) {
- pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k));
- // Each curve segment points back to its curve index
- pack.prim_index.push_back_reserved(j);
- pack.prim_object.push_back_reserved(0);
+ assert(geometry.size() == 1 && objects.size() == 1); // These are built per-mesh
+ Geometry *const geom = geometry[0];
+
+ if (geom->type == Geometry::HAIR) {
+ Hair *const hair = static_cast<Hair *const>(geom);
+ if (hair->num_curves() > 0) {
+ const size_t num_curves = hair->num_curves();
+ const size_t num_segments = hair->num_segments();
+ pack.prim_type.reserve(pack.prim_type.size() + num_segments);
+ pack.prim_index.reserve(pack.prim_index.size() + num_segments);
+ pack.prim_object.reserve(pack.prim_object.size() + num_segments);
+ // 'pack.prim_time' is only used in geom_curve_intersect.h
+ // It is not needed because of OPTIX_MOTION_FLAG_[START|END]_VANISH
+
+ uint type = PRIMITIVE_CURVE;
+ if (hair->use_motion_blur && hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION))
+ type = PRIMITIVE_MOTION_CURVE;
+
+ for (size_t j = 0; j < num_curves; ++j) {
+ const Hair::Curve curve = hair->get_curve(j);
+ for (size_t k = 0; k < curve.num_segments(); ++k) {
+ pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k));
+ // Each curve segment points back to its curve index
+ pack.prim_index.push_back_reserved(j);
+ pack.prim_object.push_back_reserved(0);
+ }
}
}
}
-
- if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && mesh->num_triangles() > 0) {
- const size_t num_triangles = mesh->num_triangles();
- pack.prim_type.reserve(pack.prim_type.size() + num_triangles);
- pack.prim_index.reserve(pack.prim_index.size() + num_triangles);
- pack.prim_object.reserve(pack.prim_object.size() + num_triangles);
-
- uint type = PRIMITIVE_TRIANGLE;
- if (mesh->use_motion_blur && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION))
- type = PRIMITIVE_MOTION_TRIANGLE;
-
- for (size_t k = 0; k < num_triangles; ++k) {
- pack.prim_type.push_back_reserved(type);
- pack.prim_index.push_back_reserved(k);
- pack.prim_object.push_back_reserved(0);
+ else if (geom->type == Geometry::MESH) {
+ Mesh *const mesh = static_cast<Mesh *const>(geom);
+ if (mesh->num_triangles() > 0) {
+ const size_t num_triangles = mesh->num_triangles();
+ pack.prim_type.reserve(pack.prim_type.size() + num_triangles);
+ pack.prim_index.reserve(pack.prim_index.size() + num_triangles);
+ pack.prim_object.reserve(pack.prim_object.size() + num_triangles);
+
+ uint type = PRIMITIVE_TRIANGLE;
+ if (mesh->use_motion_blur && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION))
+ type = PRIMITIVE_MOTION_TRIANGLE;
+
+ for (size_t k = 0; k < num_triangles; ++k) {
+ pack.prim_type.push_back_reserved(type);
+ pack.prim_index.push_back_reserved(k);
+ pack.prim_object.push_back_reserved(0);
+ }
}
}
@@ -116,8 +123,8 @@ void BVHOptiX::pack_tlas()
// Calculate total packed size
size_t prim_index_size = 0;
size_t prim_tri_verts_size = 0;
- foreach (Mesh *mesh, meshes) {
- BVH *const bvh = mesh->bvh;
+ foreach (Geometry *geom, geometry) {
+ BVH *const bvh = geom->bvh;
prim_index_size += bvh->pack.prim_index.size();
prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
}
@@ -141,13 +148,12 @@ void BVHOptiX::pack_tlas()
pack.prim_tri_verts.resize(prim_tri_verts_size);
float4 *pack_prim_tri_verts = pack.prim_tri_verts.data();
- // Top-level BVH should only contain instances, see 'Mesh::need_build_bvh'
+ // Top-level BVH should only contain instances, see 'Geometry::need_build_bvh'
// Iterate over scene mesh list instead of objects, since the 'prim_offset' is calculated based
// on that list, which may be ordered differently from the object list.
- foreach (Mesh *mesh, meshes) {
- PackedBVH &bvh_pack = mesh->bvh->pack;
- int mesh_tri_offset = mesh->tri_offset;
- int mesh_curve_offset = mesh->curve_offset;
+ foreach (Geometry *geom, geometry) {
+ PackedBVH &bvh_pack = geom->bvh->pack;
+ int geom_prim_offset = geom->prim_offset;
// Merge primitive, object and triangle indexes
if (!bvh_pack.prim_index.empty()) {
@@ -158,16 +164,16 @@ void BVHOptiX::pack_tlas()
for (size_t i = 0; i < bvh_pack.prim_index.size(); i++, pack_offset++) {
if (bvh_pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
- pack_prim_index[pack_offset] = bvh_prim_index[i] + mesh_curve_offset;
+ pack_prim_index[pack_offset] = bvh_prim_index[i] + geom_prim_offset;
pack_prim_tri_index[pack_offset] = -1;
}
else {
- pack_prim_index[pack_offset] = bvh_prim_index[i] + mesh_tri_offset;
+ pack_prim_index[pack_offset] = bvh_prim_index[i] + geom_prim_offset;
pack_prim_tri_index[pack_offset] = bvh_prim_tri_index[i] + pack_verts_offset;
}
pack_prim_type[pack_offset] = bvh_prim_type[i];
- pack_prim_object[pack_offset] = 0; // Unused for instanced meshes
+ pack_prim_object[pack_offset] = 0; // Unused for instanced geometry
pack_prim_visibility[pack_offset] = bvh_prim_visibility[i];
}
}
@@ -182,15 +188,24 @@ void BVHOptiX::pack_tlas()
}
}
- // Merge visibility flags of all objects and fix object indices for non-instanced meshes
+ // Merge visibility flags of all objects and fix object indices for non-instanced geometry
foreach (Object *ob, objects) {
- Mesh *const mesh = ob->mesh;
- for (size_t i = 0; i < mesh->num_primitives(); ++i) {
- if (!ob->mesh->is_instanced()) {
- assert(pack.prim_object[mesh->prim_offset + i] == 0);
- pack.prim_object[mesh->prim_offset + i] = ob->get_device_index();
+ Geometry *const geom = ob->geometry;
+ size_t num_primitives = 0;
+
+ if (geom->type == Geometry::MESH) {
+ num_primitives = static_cast<Mesh *const>(geom)->num_triangles();
+ }
+ else if (geom->type == Geometry::HAIR) {
+ num_primitives = static_cast<Hair *const>(geom)->num_segments();
+ }
+
+ for (size_t i = 0; i < num_primitives; ++i) {
+ if (!geom->is_instanced()) {
+ assert(pack.prim_object[geom->optix_prim_offset + i] == 0);
+ pack.prim_object[geom->optix_prim_offset + i] = ob->get_device_index();
}
- pack.prim_visibility[mesh->prim_offset + i] |= ob->visibility_for_tracing();
+ pack.prim_visibility[geom->optix_prim_offset + i] |= ob->visibility_for_tracing();
}
}
}
diff --git a/intern/cycles/bvh/bvh_optix.h b/intern/cycles/bvh/bvh_optix.h
index 35033fe635f..e4745b093b5 100644
--- a/intern/cycles/bvh/bvh_optix.h
+++ b/intern/cycles/bvh/bvh_optix.h
@@ -26,11 +26,16 @@
CCL_NAMESPACE_BEGIN
+class Geometry;
+class Optix;
+
class BVHOptiX : public BVH {
friend class BVH;
public:
- BVHOptiX(const BVHParams &params, const vector<Mesh *> &meshes, const vector<Object *> &objects);
+ BVHOptiX(const BVHParams &params,
+ const vector<Geometry *> &geometry,
+ const vector<Object *> &objects);
virtual ~BVHOptiX();
virtual void build(Progress &progress, Stats *) override;
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index 2731662a39d..5e2c4b63f1b 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -69,9 +69,6 @@ class BVHParams {
/* BVH layout to be built. */
BVHLayout bvh_layout;
- /* Mask of primitives to be included into the BVH. */
- int primitive_mask;
-
/* Use unaligned bounding boxes.
* Only used for curves BVH.
*/
@@ -120,8 +117,6 @@ class BVHParams {
bvh_layout = BVH_LAYOUT_BVH2;
use_unaligned_nodes = false;
- primitive_mask = PRIMITIVE_ALL;
-
num_motion_curve_steps = 0;
num_motion_triangle_steps = 0;
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index bd261c10d55..7e787674b74 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -20,6 +20,7 @@
#include "bvh/bvh_build.h"
#include "bvh/bvh_sort.h"
+#include "render/hair.h"
#include "render/mesh.h"
#include "render/object.h"
@@ -378,7 +379,7 @@ void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh,
}
}
-void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh,
+void BVHSpatialSplit::split_curve_primitive(const Hair *hair,
const Transform *tfm,
int prim_index,
int segment_index,
@@ -388,11 +389,11 @@ void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh,
BoundBox &right_bounds)
{
/* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
- Mesh::Curve curve = mesh->get_curve(prim_index);
+ Hair::Curve curve = hair->get_curve(prim_index);
const int k0 = curve.first_key + segment_index;
const int k1 = k0 + 1;
- float3 v0 = mesh->curve_keys[k0];
- float3 v1 = mesh->curve_keys[k1];
+ float3 v0 = hair->curve_keys[k0];
+ float3 v1 = hair->curve_keys[k1];
if (tfm != NULL) {
v0 = transform_point(tfm, v0);
@@ -436,13 +437,13 @@ void BVHSpatialSplit::split_triangle_reference(const BVHReference &ref,
}
void BVHSpatialSplit::split_curve_reference(const BVHReference &ref,
- const Mesh *mesh,
+ const Hair *hair,
int dim,
float pos,
BoundBox &left_bounds,
BoundBox &right_bounds)
{
- split_curve_primitive(mesh,
+ split_curve_primitive(hair,
NULL,
ref.prim_index(),
PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()),
@@ -455,15 +456,22 @@ void BVHSpatialSplit::split_curve_reference(const BVHReference &ref,
void BVHSpatialSplit::split_object_reference(
const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
{
- Mesh *mesh = object->mesh;
- for (int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) {
- split_triangle_primitive(mesh, &object->tfm, tri_idx, dim, pos, left_bounds, right_bounds);
+ Geometry *geom = object->geometry;
+
+ if (geom->type == Geometry::MESH) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ for (int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) {
+ split_triangle_primitive(mesh, &object->tfm, tri_idx, dim, pos, left_bounds, right_bounds);
+ }
}
- for (int curve_idx = 0; curve_idx < mesh->num_curves(); ++curve_idx) {
- Mesh::Curve curve = mesh->get_curve(curve_idx);
- for (int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) {
- split_curve_primitive(
- mesh, &object->tfm, curve_idx, segment_idx, dim, pos, left_bounds, right_bounds);
+ else if (geom->type == Geometry::MESH) {
+ Hair *hair = static_cast<Hair *>(geom);
+ for (int curve_idx = 0; curve_idx < hair->num_curves(); ++curve_idx) {
+ Hair::Curve curve = hair->get_curve(curve_idx);
+ for (int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) {
+ split_curve_primitive(
+ hair, &object->tfm, curve_idx, segment_idx, dim, pos, left_bounds, right_bounds);
+ }
}
}
}
@@ -481,13 +489,14 @@ void BVHSpatialSplit::split_reference(const BVHBuild &builder,
/* loop over vertices/edges. */
const Object *ob = builder.objects[ref.prim_object()];
- const Mesh *mesh = ob->mesh;
if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
+ Mesh *mesh = static_cast<Mesh *>(ob->geometry);
split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds);
}
else if (ref.prim_type() & PRIMITIVE_ALL_CURVE) {
- split_curve_reference(ref, mesh, dim, pos, left_bounds, right_bounds);
+ Hair *hair = static_cast<Hair *>(ob->geometry);
+ split_curve_reference(ref, hair, dim, pos, left_bounds, right_bounds);
}
else {
split_object_reference(ob, dim, pos, left_bounds, right_bounds);
diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h
index eddd1c27f49..5f2e41cf343 100644
--- a/intern/cycles/bvh/bvh_split.h
+++ b/intern/cycles/bvh/bvh_split.h
@@ -24,6 +24,8 @@
CCL_NAMESPACE_BEGIN
class BVHBuild;
+class Hair;
+class Mesh;
struct Transform;
/* Object Split */
@@ -113,7 +115,7 @@ class BVHSpatialSplit {
float pos,
BoundBox &left_bounds,
BoundBox &right_bounds);
- void split_curve_primitive(const Mesh *mesh,
+ void split_curve_primitive(const Hair *hair,
const Transform *tfm,
int prim_index,
int segment_index,
@@ -134,7 +136,7 @@ class BVHSpatialSplit {
BoundBox &left_bounds,
BoundBox &right_bounds);
void split_curve_reference(const BVHReference &ref,
- const Mesh *mesh,
+ const Hair *hair,
int dim,
float pos,
BoundBox &left_bounds,
diff --git a/intern/cycles/bvh/bvh_unaligned.cpp b/intern/cycles/bvh/bvh_unaligned.cpp
index 1843ca403a5..f0995f343fe 100644
--- a/intern/cycles/bvh/bvh_unaligned.cpp
+++ b/intern/cycles/bvh/bvh_unaligned.cpp
@@ -16,7 +16,7 @@
#include "bvh/bvh_unaligned.h"
-#include "render/mesh.h"
+#include "render/hair.h"
#include "render/object.h"
#include "bvh/bvh_binning.h"
@@ -71,10 +71,10 @@ bool BVHUnaligned::compute_aligned_space(const BVHReference &ref, Transform *ali
if (type & PRIMITIVE_CURVE) {
const int curve_index = ref.prim_index();
const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
- const Mesh *mesh = object->mesh;
- const Mesh::Curve &curve = mesh->get_curve(curve_index);
+ const Hair *hair = static_cast<const Hair *>(object->geometry);
+ const Hair::Curve &curve = hair->get_curve(curve_index);
const int key = curve.first_key + segment;
- const float3 v1 = mesh->curve_keys[key], v2 = mesh->curve_keys[key + 1];
+ const float3 v1 = hair->curve_keys[key], v2 = hair->curve_keys[key + 1];
float length;
const float3 axis = normalize_len(v2 - v1, &length);
if (length > 1e-6f) {
@@ -96,10 +96,10 @@ BoundBox BVHUnaligned::compute_aligned_prim_boundbox(const BVHReference &prim,
if (type & PRIMITIVE_CURVE) {
const int curve_index = prim.prim_index();
const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
- const Mesh *mesh = object->mesh;
- const Mesh::Curve &curve = mesh->get_curve(curve_index);
+ const Hair *hair = static_cast<const Hair *>(object->geometry);
+ const Hair::Curve &curve = hair->get_curve(curve_index);
curve.bounds_grow(
- segment, &mesh->curve_keys[0], &mesh->curve_radius[0], aligned_space, bounds);
+ segment, &hair->curve_keys[0], &hair->curve_radius[0], aligned_space, bounds);
}
else {
bounds = prim.bounds().transformed(&aligned_space);