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:
-rw-r--r--intern/cycles/blender/blender_curves.cpp20
-rw-r--r--intern/cycles/blender/blender_mesh.cpp4
-rw-r--r--intern/cycles/bvh/bvh.cpp30
-rw-r--r--intern/cycles/bvh/bvh_build.cpp21
-rw-r--r--intern/cycles/bvh/bvh_split.cpp18
-rw-r--r--intern/cycles/render/mesh.cpp53
-rw-r--r--intern/cycles/render/mesh.h9
-rw-r--r--intern/cycles/render/object.cpp11
-rw-r--r--intern/cycles/util/util_math.h19
9 files changed, 102 insertions, 83 deletions
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 92c51b0aad3..4420a306e31 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -588,7 +588,7 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
- radius =0.0f;
+ radius = 0.0f;
mesh->add_curve_key(ickey_loc, radius);
if(attr_intercept)
@@ -617,8 +617,8 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveDat
/* export motion vectors for curve keys */
AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST;
Attribute *attr_motion = mesh->curve_attributes.add(std);
- float3 *data_motion = attr_motion->data_float3();
- float3 *current_motion = data_motion;
+ float4 *data_motion = attr_motion->data_float4();
+ float4 *current_motion = data_motion;
size_t size = mesh->curve_keys.size();
size_t i = 0;
bool have_motion = false;
@@ -633,12 +633,20 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveDat
for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) {
if(i < mesh->curve_keys.size()) {
- *current_motion = CData->curvekey_co[curvekey];
+ float3 ickey_loc = CData->curvekey_co[curvekey];
+ float time = CData->curvekey_time[curvekey]/CData->curve_length[curve];
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
+ radius = 0.0f;
+
+ *current_motion = float3_to_float4(ickey_loc);
+ current_motion->w = radius;
/* unlike mesh coordinates, these tend to be slightly different
* between frames due to particle transforms into/out of object
* space, so we use an epsilon to detect actual changes */
- if(len_squared(*current_motion - mesh->curve_keys[i].co) > 1e-5f*1e-5f)
+ if(len_squared(*current_motion - mesh->curve_keys[i]) > 1e-5f*1e-5f)
have_motion = true;
current_motion++;
@@ -876,7 +884,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, int
size_t i = 0;
foreach(Mesh::Curve& curve, mesh->curves) {
- float3 co = mesh->curve_keys[curve.first_key].co;
+ float3 co = float4_to_float3(mesh->curve_keys[curve.first_key]);
generated[i++] = co*size - loc;
}
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 0972cf6a939..b356537e971 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -481,7 +481,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
/* compares curve_keys rather than strands in order to handle quick hair
* adjustsments in dynamic BVH - other methods could probably do this better*/
- vector<Mesh::CurveKey> oldcurve_keys = mesh->curve_keys;
+ vector<float4> oldcurve_keys = mesh->curve_keys;
mesh->clear();
mesh->used_shaders = used_shaders;
@@ -535,7 +535,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
if(oldcurve_keys.size() != mesh->curve_keys.size())
rebuild = true;
else if(oldcurve_keys.size()) {
- if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(Mesh::CurveKey)*oldcurve_keys.size()) != 0)
+ if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float4)*oldcurve_keys.size()) != 0)
rebuild = true;
}
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 0d46638c82d..c0d70e0bc61 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -283,8 +283,8 @@ void BVH::pack_curve_segment(int idx, float4 woop[3])
int segment = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[idx]);
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 v0 = float4_to_float3(mesh->curve_keys[k0]);
+ float3 v1 = float4_to_float3(mesh->curve_keys[k1]);
float3 d0 = v1 - v0;
float l = len(d0);
@@ -632,34 +632,20 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* curves */
int str_offset = (params.top_level)? mesh->curve_offset: 0;
- int k0 = mesh->curves[pidx - str_offset].first_key + PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
- int k1 = k0 + 1;
-
- float3 p[4];
- p[0] = mesh->curve_keys[max(k0 - 1,mesh->curves[pidx - str_offset].first_key)].co;
- p[1] = mesh->curve_keys[k0].co;
- p[2] = mesh->curve_keys[k1].co;
- p[3] = mesh->curve_keys[min(k1 + 1,mesh->curves[pidx - str_offset].first_key + mesh->curves[pidx - str_offset].num_keys - 1)].co;
- float3 lower;
- float3 upper;
- curvebounds(&lower.x, &upper.x, p, 0);
- curvebounds(&lower.y, &upper.y, p, 1);
- curvebounds(&lower.z, &upper.z, p, 2);
- float mr = max(mesh->curve_keys[k0].radius,mesh->curve_keys[k1].radius);
- bbox.grow(lower, mr);
- bbox.grow(upper, mr);
+ const Mesh::Curve& curve = mesh->curves[pidx - str_offset];
+ int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
+
+ curve.bounds_grow(k, &mesh->curve_keys[0], bbox);
visibility |= PATH_RAY_CURVE;
}
else {
/* triangles */
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
- const int *vidx = mesh->triangles[pidx - tri_offset].v;
+ const Mesh::Triangle& triangle = mesh->triangles[pidx - tri_offset];
const float3 *vpos = &mesh->verts[0];
- bbox.grow(vpos[vidx[0]]);
- bbox.grow(vpos[vidx[1]]);
- bbox.grow(vpos[vidx[2]]);
+ triangle.bounds_grow(vpos, bbox);
}
}
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index aa8ba36f891..ef48c1edc63 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -75,10 +75,7 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
BoundBox bounds = BoundBox::empty;
PrimitiveType type = PRIMITIVE_TRIANGLE;
- for(int k = 0; k < 3; k++) {
- float3 co = mesh->verts[t.v[k]];
- bounds.grow(co);
- }
+ t.bounds_grow(&mesh->verts[0], bounds);
if(bounds.valid()) {
references.push_back(BVHReference(bounds, j, i, type));
@@ -93,21 +90,7 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
for(int k = 0; k < curve.num_keys - 1; k++) {
BoundBox bounds = BoundBox::empty;
-
- float3 co[4];
- co[0] = mesh->curve_keys[max(curve.first_key + k - 1,curve.first_key)].co;
- co[1] = mesh->curve_keys[curve.first_key + k].co;
- co[2] = mesh->curve_keys[curve.first_key + k + 1].co;
- co[3] = mesh->curve_keys[min(curve.first_key + k + 2, curve.first_key + curve.num_keys - 1)].co;
-
- float3 lower;
- float3 upper;
- curvebounds(&lower.x, &upper.x, co, 0);
- curvebounds(&lower.y, &upper.y, co, 1);
- curvebounds(&lower.z, &upper.z, co, 2);
- float mr = max(mesh->curve_keys[curve.first_key + k].radius, mesh->curve_keys[curve.first_key + k + 1].radius);
- bounds.grow(lower, mr);
- bounds.grow(upper, mr);
+ curve.bounds_grow(k, &mesh->curve_keys[0], bounds);
if(bounds.valid()) {
int packed_type = PRIMITIVE_PACK_SEGMENT(type, k);
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 864626da134..e293e8f4c3f 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -284,28 +284,28 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
/* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
const int k0 = mesh->curves[ref.prim_index()].first_key + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type());
const int k1 = k0 + 1;
- const float3* v0 = &mesh->curve_keys[k0].co;
- const float3* v1 = &mesh->curve_keys[k1].co;
+ const float3 v0 = float4_to_float3(mesh->curve_keys[k0]);
+ const float3 v1 = float4_to_float3(mesh->curve_keys[k1]);
- float v0p = (*v0)[dim];
- float v1p = (*v1)[dim];
+ float v0p = v0[dim];
+ float v1p = v1[dim];
/* insert vertex to the boxes it belongs to. */
if(v0p <= pos)
- left_bounds.grow(*v0);
+ left_bounds.grow(v0);
if(v0p >= pos)
- right_bounds.grow(*v0);
+ right_bounds.grow(v0);
if(v1p <= pos)
- left_bounds.grow(*v1);
+ left_bounds.grow(v1);
if(v1p >= pos)
- right_bounds.grow(*v1);
+ right_bounds.grow(v1);
/* edge intersects the plane => insert intersection to both boxes. */
if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
- float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
+ float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
left_bounds.grow(t);
right_bounds.grow(t);
}
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 717ebb42f5c..c6ddb00e76b 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -18,6 +18,7 @@
#include "bvh_build.h"
#include "camera.h"
+#include "curves.h"
#include "device.h"
#include "shader.h"
#include "light.h"
@@ -34,6 +35,39 @@
CCL_NAMESPACE_BEGIN
+/* Triangle */
+
+void Mesh::Triangle::bounds_grow(const float3 *verts, BoundBox& bounds) const
+{
+ bounds.grow(verts[v[0]]);
+ bounds.grow(verts[v[1]]);
+ bounds.grow(verts[v[2]]);
+}
+
+/* Curve */
+
+void Mesh::Curve::bounds_grow(const int k, const float4 *curve_keys, BoundBox& bounds) const
+{
+ float3 P[4];
+
+ P[0] = float4_to_float3(curve_keys[max(first_key + k - 1,first_key)]);
+ P[1] = float4_to_float3(curve_keys[first_key + k]);
+ P[2] = float4_to_float3(curve_keys[first_key + k + 1]);
+ P[3] = float4_to_float3(curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]);
+
+ float3 lower;
+ float3 upper;
+
+ curvebounds(&lower.x, &upper.x, P, 0);
+ curvebounds(&lower.y, &upper.y, P, 1);
+ curvebounds(&lower.z, &upper.z, P, 2);
+
+ float mr = max(curve_keys[first_key + k].w, curve_keys[first_key + k + 1].w);
+
+ bounds.grow(lower, mr);
+ bounds.grow(upper, mr);
+}
+
/* Mesh */
Mesh::Mesh()
@@ -125,9 +159,8 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
void Mesh::add_curve_key(float3 co, float radius)
{
- CurveKey key;
- key.co = co;
- key.radius = radius;
+ float4 key = float3_to_float4(co);
+ key.w = radius;
curve_keys.push_back(key);
}
@@ -153,7 +186,7 @@ void Mesh::compute_bounds()
bnds.grow(verts[i]);
for(size_t i = 0; i < curve_keys_size; i++)
- bnds.grow(curve_keys[i].co, curve_keys[i].radius);
+ bnds.grow(float4_to_float3(curve_keys[i]), curve_keys[i].w);
if(!bnds.valid()) {
bnds = BoundBox::empty;
@@ -163,7 +196,7 @@ void Mesh::compute_bounds()
bnds.grow_safe(verts[i]);
for(size_t i = 0; i < curve_keys_size; i++)
- bnds.grow_safe(curve_keys[i].co, curve_keys[i].radius);
+ bnds.grow_safe(float4_to_float3(curve_keys[i]), curve_keys[i].w);
}
}
@@ -337,18 +370,14 @@ 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_data, size_t curvekey_offset)
{
size_t curve_keys_size = curve_keys.size();
- CurveKey *keys_ptr = NULL;
+ float4 *keys_ptr = NULL;
/* pack curve keys */
if(curve_keys_size) {
keys_ptr = &curve_keys[0];
- for(size_t i = 0; i < curve_keys_size; i++) {
- float3 p = keys_ptr[i].co;
- float radius = keys_ptr[i].radius;
-
- curve_key_co[i] = make_float4(p.x, p.y, p.z, radius);
- }
+ for(size_t i = 0; i < curve_keys_size; i++)
+ curve_key_co[i] = keys_ptr[i];
}
/* pack curve segments */
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 9c59aca4c72..5ae8f1f6033 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -46,6 +46,8 @@ public:
/* Mesh Triangle */
struct Triangle {
int v[3];
+
+ void bounds_grow(const float3 *verts, BoundBox& bounds) const;
};
/* Mesh Curve */
@@ -55,11 +57,8 @@ public:
uint shader;
int num_segments() { return num_keys - 1; }
- };
- struct CurveKey {
- float3 co;
- float radius;
+ void bounds_grow(const int k, const float4 *curve_keys, BoundBox& bounds) const;
};
/* Displacement */
@@ -77,7 +76,7 @@ public:
vector<uint> shader;
vector<bool> smooth;
- vector<CurveKey> curve_keys;
+ vector<float4> curve_keys; /* co + radius */
vector<Curve> curves;
vector<uint> used_shaders;
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 0a89642fc4a..362b4762b74 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -86,19 +86,24 @@ void Object::apply_transform()
{
if(!mesh || tfm == transform_identity())
return;
-
+
float3 c0 = transform_get_column(&tfm, 0);
float3 c1 = transform_get_column(&tfm, 1);
float3 c2 = transform_get_column(&tfm, 2);
float scalar = pow(fabsf(dot(cross(c0, c1), c2)), 1.0f/3.0f);
+ /* apply to mesh vertices */
for(size_t i = 0; i < mesh->verts.size(); i++)
mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
+ /* apply to curve keys */
for(size_t i = 0; i < mesh->curve_keys.size(); i++) {
- mesh->curve_keys[i].co = transform_point(&tfm, mesh->curve_keys[i].co);
+ float3 co = transform_point(&tfm, float4_to_float3(mesh->curve_keys[i]));
+ float radius = mesh->curve_keys[i].w * scalar;
+
+ mesh->curve_keys[i] = float3_to_float4(co);
/* scale for strand radius - only correct for uniform transforms*/
- mesh->curve_keys[i].radius *= scalar;
+ mesh->curve_keys[i].w *= radius;
}
/* store matrix to transform later. when accessing these as attributes we
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 2e73639d2bb..dc58b93bd5d 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -469,6 +469,15 @@ ccl_device_inline float dot(const float3 a, const float3 b)
#endif
}
+ccl_device_inline float dot(const float4 a, const float4 b)
+{
+#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
+ return _mm_cvtss_f32(_mm_dp_ps(a, b, 0xFF));
+#else
+ return (a.x*b.x + a.y*b.y) + (a.z*b.z + a.w*b.w);
+#endif
+}
+
ccl_device_inline float3 cross(const float3 a, const float3 b)
{
float3 r = make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
@@ -493,6 +502,11 @@ ccl_device_inline float len_squared(const float3 a)
#ifndef __KERNEL_OPENCL__
+ccl_device_inline float len_squared(const float4 a)
+{
+ return dot(a, a);
+}
+
ccl_device_inline float3 normalize(const float3 a)
{
#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
@@ -812,11 +826,6 @@ ccl_device_inline float average(const float4& a)
return reduce_add(a) * 0.25f;
}
-ccl_device_inline float dot(const float4& a, const float4& b)
-{
- return reduce_add(a * b);
-}
-
ccl_device_inline float len(const float4 a)
{
return sqrtf(dot(a, a));