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/kernel/geom/geom_patch.h')
-rw-r--r--intern/cycles/kernel/geom/geom_patch.h554
1 files changed, 303 insertions, 251 deletions
diff --git a/intern/cycles/kernel/geom/geom_patch.h b/intern/cycles/kernel/geom/geom_patch.h
index edb82172959..df19199f68e 100644
--- a/intern/cycles/kernel/geom/geom_patch.h
+++ b/intern/cycles/kernel/geom/geom_patch.h
@@ -27,342 +27,394 @@
CCL_NAMESPACE_BEGIN
typedef struct PatchHandle {
- int array_index, patch_index, vert_index;
+ int array_index, patch_index, vert_index;
} PatchHandle;
ccl_device_inline int patch_map_resolve_quadrant(float median, float *u, float *v)
{
- int quadrant = -1;
-
- if(*u < median) {
- if(*v < median) {
- quadrant = 0;
- }
- else {
- quadrant = 1;
- *v -= median;
- }
- }
- else {
- if(*v < median) {
- quadrant = 3;
- }
- else {
- quadrant = 2;
- *v -= median;
- }
- *u -= median;
- }
-
- return quadrant;
+ int quadrant = -1;
+
+ if (*u < median) {
+ if (*v < median) {
+ quadrant = 0;
+ }
+ else {
+ quadrant = 1;
+ *v -= median;
+ }
+ }
+ else {
+ if (*v < median) {
+ quadrant = 3;
+ }
+ else {
+ quadrant = 2;
+ *v -= median;
+ }
+ *u -= median;
+ }
+
+ return quadrant;
}
/* retrieve PatchHandle from patch coords */
-ccl_device_inline PatchHandle patch_map_find_patch(KernelGlobals *kg, int object, int patch, float u, float v)
+ccl_device_inline PatchHandle
+patch_map_find_patch(KernelGlobals *kg, int object, int patch, float u, float v)
{
- PatchHandle handle;
+ PatchHandle handle;
- kernel_assert((u >= 0.0f) && (u <= 1.0f) && (v >= 0.0f) && (v <= 1.0f));
+ kernel_assert((u >= 0.0f) && (u <= 1.0f) && (v >= 0.0f) && (v <= 1.0f));
- int node = (object_patch_map_offset(kg, object) + patch)/2;
- float median = 0.5f;
+ int node = (object_patch_map_offset(kg, object) + patch) / 2;
+ float median = 0.5f;
- for(int depth = 0; depth < 0xff; depth++) {
- float delta = median * 0.5f;
+ for (int depth = 0; depth < 0xff; depth++) {
+ float delta = median * 0.5f;
- int quadrant = patch_map_resolve_quadrant(median, &u, &v);
- kernel_assert(quadrant >= 0);
+ int quadrant = patch_map_resolve_quadrant(median, &u, &v);
+ kernel_assert(quadrant >= 0);
- uint child = kernel_tex_fetch(__patches, node + quadrant);
+ uint child = kernel_tex_fetch(__patches, node + quadrant);
- /* is the quadrant a hole? */
- if(!(child & PATCH_MAP_NODE_IS_SET)) {
- handle.array_index = -1;
- return handle;
- }
+ /* is the quadrant a hole? */
+ if (!(child & PATCH_MAP_NODE_IS_SET)) {
+ handle.array_index = -1;
+ return handle;
+ }
- uint index = child & PATCH_MAP_NODE_INDEX_MASK;
+ uint index = child & PATCH_MAP_NODE_INDEX_MASK;
- if(child & PATCH_MAP_NODE_IS_LEAF) {
- handle.array_index = kernel_tex_fetch(__patches, index + 0);
- handle.patch_index = kernel_tex_fetch(__patches, index + 1);
- handle.vert_index = kernel_tex_fetch(__patches, index + 2);
+ if (child & PATCH_MAP_NODE_IS_LEAF) {
+ handle.array_index = kernel_tex_fetch(__patches, index + 0);
+ handle.patch_index = kernel_tex_fetch(__patches, index + 1);
+ handle.vert_index = kernel_tex_fetch(__patches, index + 2);
- return handle;
- } else {
- node = index;
- }
+ return handle;
+ }
+ else {
+ node = index;
+ }
- median = delta;
- }
+ median = delta;
+ }
- /* no leaf found */
- kernel_assert(0);
+ /* no leaf found */
+ kernel_assert(0);
- handle.array_index = -1;
- return handle;
+ handle.array_index = -1;
+ return handle;
}
ccl_device_inline void patch_eval_bspline_weights(float t, float *point, float *deriv)
{
- /* The four uniform cubic B-Spline basis functions evaluated at t */
- float inv_6 = 1.0f / 6.0f;
-
- float t2 = t * t;
- float t3 = t * t2;
-
- point[0] = inv_6 * (1.0f - 3.0f*(t - t2) - t3);
- point[1] = inv_6 * (4.0f - 6.0f*t2 + 3.0f*t3);
- point[2] = inv_6 * (1.0f + 3.0f*(t + t2 - t3));
- point[3] = inv_6 * t3;
-
- /* Derivatives of the above four basis functions at t */
- deriv[0] = -0.5f*t2 + t - 0.5f;
- deriv[1] = 1.5f*t2 - 2.0f*t;
- deriv[2] = -1.5f*t2 + t + 0.5f;
- deriv[3] = 0.5f*t2;
+ /* The four uniform cubic B-Spline basis functions evaluated at t */
+ float inv_6 = 1.0f / 6.0f;
+
+ float t2 = t * t;
+ float t3 = t * t2;
+
+ point[0] = inv_6 * (1.0f - 3.0f * (t - t2) - t3);
+ point[1] = inv_6 * (4.0f - 6.0f * t2 + 3.0f * t3);
+ point[2] = inv_6 * (1.0f + 3.0f * (t + t2 - t3));
+ point[3] = inv_6 * t3;
+
+ /* Derivatives of the above four basis functions at t */
+ deriv[0] = -0.5f * t2 + t - 0.5f;
+ deriv[1] = 1.5f * t2 - 2.0f * t;
+ deriv[2] = -1.5f * t2 + t + 0.5f;
+ deriv[3] = 0.5f * t2;
}
ccl_device_inline void patch_eval_adjust_boundary_weights(uint bits, float *s, float *t)
{
- int boundary = ((bits >> 8) & 0xf);
-
- if(boundary & 1) {
- t[2] -= t[0];
- t[1] += 2*t[0];
- t[0] = 0;
- }
-
- if(boundary & 2) {
- s[1] -= s[3];
- s[2] += 2*s[3];
- s[3] = 0;
- }
-
- if(boundary & 4) {
- t[1] -= t[3];
- t[2] += 2*t[3];
- t[3] = 0;
- }
-
- if(boundary & 8) {
- s[2] -= s[0];
- s[1] += 2*s[0];
- s[0] = 0;
- }
+ int boundary = ((bits >> 8) & 0xf);
+
+ if (boundary & 1) {
+ t[2] -= t[0];
+ t[1] += 2 * t[0];
+ t[0] = 0;
+ }
+
+ if (boundary & 2) {
+ s[1] -= s[3];
+ s[2] += 2 * s[3];
+ s[3] = 0;
+ }
+
+ if (boundary & 4) {
+ t[1] -= t[3];
+ t[2] += 2 * t[3];
+ t[3] = 0;
+ }
+
+ if (boundary & 8) {
+ s[2] -= s[0];
+ s[1] += 2 * s[0];
+ s[0] = 0;
+ }
}
ccl_device_inline int patch_eval_depth(uint patch_bits)
{
- return (patch_bits & 0xf);
+ return (patch_bits & 0xf);
}
ccl_device_inline float patch_eval_param_fraction(uint patch_bits)
{
- bool non_quad_root = (patch_bits >> 4) & 0x1;
- int depth = patch_eval_depth(patch_bits);
-
- if(non_quad_root) {
- return 1.0f / (float)(1 << (depth-1));
- }
- else {
- return 1.0f / (float)(1 << depth);
- }
+ bool non_quad_root = (patch_bits >> 4) & 0x1;
+ int depth = patch_eval_depth(patch_bits);
+
+ if (non_quad_root) {
+ return 1.0f / (float)(1 << (depth - 1));
+ }
+ else {
+ return 1.0f / (float)(1 << depth);
+ }
}
ccl_device_inline void patch_eval_normalize_coords(uint patch_bits, float *u, float *v)
{
- float frac = patch_eval_param_fraction(patch_bits);
+ float frac = patch_eval_param_fraction(patch_bits);
- int iu = (patch_bits >> 22) & 0x3ff;
- int iv = (patch_bits >> 12) & 0x3ff;
+ int iu = (patch_bits >> 22) & 0x3ff;
+ int iv = (patch_bits >> 12) & 0x3ff;
- /* top left corner */
- float pu = (float)iu*frac;
- float pv = (float)iv*frac;
+ /* top left corner */
+ float pu = (float)iu * frac;
+ float pv = (float)iv * frac;
- /* normalize uv coordinates */
- *u = (*u - pu) / frac;
- *v = (*v - pv) / frac;
+ /* normalize uv coordinates */
+ *u = (*u - pu) / frac;
+ *v = (*v - pv) / frac;
}
/* retrieve patch control indices */
-ccl_device_inline int patch_eval_indices(KernelGlobals *kg, const PatchHandle *handle, int channel,
+ccl_device_inline int patch_eval_indices(KernelGlobals *kg,
+ const PatchHandle *handle,
+ int channel,
int indices[PATCH_MAX_CONTROL_VERTS])
{
- int index_base = kernel_tex_fetch(__patches, handle->array_index + 2) + handle->vert_index;
+ int index_base = kernel_tex_fetch(__patches, handle->array_index + 2) + handle->vert_index;
- /* XXX: regular patches only */
- for(int i = 0; i < 16; i++) {
- indices[i] = kernel_tex_fetch(__patches, index_base + i);
- }
+ /* XXX: regular patches only */
+ for (int i = 0; i < 16; i++) {
+ indices[i] = kernel_tex_fetch(__patches, index_base + i);
+ }
- return 16;
+ return 16;
}
/* evaluate patch basis functions */
-ccl_device_inline void patch_eval_basis(KernelGlobals *kg, const PatchHandle *handle, float u, float v,
- float weights[PATCH_MAX_CONTROL_VERTS],
- float weights_du[PATCH_MAX_CONTROL_VERTS],
- float weights_dv[PATCH_MAX_CONTROL_VERTS])
+ccl_device_inline void patch_eval_basis(KernelGlobals *kg,
+ const PatchHandle *handle,
+ float u,
+ float v,
+ float weights[PATCH_MAX_CONTROL_VERTS],
+ float weights_du[PATCH_MAX_CONTROL_VERTS],
+ float weights_dv[PATCH_MAX_CONTROL_VERTS])
{
- uint patch_bits = kernel_tex_fetch(__patches, handle->patch_index + 1); /* read patch param */
- float d_scale = 1 << patch_eval_depth(patch_bits);
+ uint patch_bits = kernel_tex_fetch(__patches, handle->patch_index + 1); /* read patch param */
+ float d_scale = 1 << patch_eval_depth(patch_bits);
- bool non_quad_root = (patch_bits >> 4) & 0x1;
- if(non_quad_root) {
- d_scale *= 0.5f;
- }
+ bool non_quad_root = (patch_bits >> 4) & 0x1;
+ if (non_quad_root) {
+ d_scale *= 0.5f;
+ }
- patch_eval_normalize_coords(patch_bits, &u, &v);
+ patch_eval_normalize_coords(patch_bits, &u, &v);
- /* XXX: regular patches only for now. */
+ /* XXX: regular patches only for now. */
- float s[4], t[4], ds[4], dt[4];
+ float s[4], t[4], ds[4], dt[4];
- patch_eval_bspline_weights(u, s, ds);
- patch_eval_bspline_weights(v, t, dt);
+ patch_eval_bspline_weights(u, s, ds);
+ patch_eval_bspline_weights(v, t, dt);
- patch_eval_adjust_boundary_weights(patch_bits, s, t);
- patch_eval_adjust_boundary_weights(patch_bits, ds, dt);
+ patch_eval_adjust_boundary_weights(patch_bits, s, t);
+ patch_eval_adjust_boundary_weights(patch_bits, ds, dt);
- for(int k = 0; k < 4; k++) {
- for(int l = 0; l < 4; l++) {
- weights[4*k+l] = s[l] * t[k];
- weights_du[4*k+l] = ds[l] * t[k] * d_scale;
- weights_dv[4*k+l] = s[l] * dt[k] * d_scale;
- }
- }
+ for (int k = 0; k < 4; k++) {
+ for (int l = 0; l < 4; l++) {
+ weights[4 * k + l] = s[l] * t[k];
+ weights_du[4 * k + l] = ds[l] * t[k] * d_scale;
+ weights_dv[4 * k + l] = s[l] * dt[k] * d_scale;
+ }
+ }
}
/* generic function for evaluating indices and weights from patch coords */
-ccl_device_inline int patch_eval_control_verts(KernelGlobals *kg, int object, int patch, float u, float v, int channel,
- int indices[PATCH_MAX_CONTROL_VERTS],
- float weights[PATCH_MAX_CONTROL_VERTS],
- float weights_du[PATCH_MAX_CONTROL_VERTS],
- float weights_dv[PATCH_MAX_CONTROL_VERTS])
+ccl_device_inline int patch_eval_control_verts(KernelGlobals *kg,
+ int object,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ int indices[PATCH_MAX_CONTROL_VERTS],
+ float weights[PATCH_MAX_CONTROL_VERTS],
+ float weights_du[PATCH_MAX_CONTROL_VERTS],
+ float weights_dv[PATCH_MAX_CONTROL_VERTS])
{
- PatchHandle handle = patch_map_find_patch(kg, object, patch, u, v);
- kernel_assert(handle.array_index >= 0);
+ PatchHandle handle = patch_map_find_patch(kg, object, patch, u, v);
+ kernel_assert(handle.array_index >= 0);
- int num_control = patch_eval_indices(kg, &handle, channel, indices);
- patch_eval_basis(kg, &handle, u, v, weights, weights_du, weights_dv);
+ int num_control = patch_eval_indices(kg, &handle, channel, indices);
+ patch_eval_basis(kg, &handle, u, v, weights, weights_du, weights_dv);
- return num_control;
+ return num_control;
}
/* functions for evaluating attributes on patches */
-ccl_device float patch_eval_float(KernelGlobals *kg, const ShaderData *sd, int offset,
- int patch, float u, float v, int channel,
- float *du, float* dv)
+ccl_device float patch_eval_float(KernelGlobals *kg,
+ const ShaderData *sd,
+ int offset,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ float *du,
+ float *dv)
{
- int indices[PATCH_MAX_CONTROL_VERTS];
- float weights[PATCH_MAX_CONTROL_VERTS];
- float weights_du[PATCH_MAX_CONTROL_VERTS];
- float weights_dv[PATCH_MAX_CONTROL_VERTS];
-
- int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
- indices, weights, weights_du, weights_dv);
-
- float val = 0.0f;
- if(du) *du = 0.0f;
- if(dv) *dv = 0.0f;
-
- for(int i = 0; i < num_control; i++) {
- float v = kernel_tex_fetch(__attributes_float, offset + indices[i]);
-
- val += v * weights[i];
- if(du) *du += v * weights_du[i];
- if(dv) *dv += v * weights_dv[i];
- }
-
- return val;
+ int indices[PATCH_MAX_CONTROL_VERTS];
+ float weights[PATCH_MAX_CONTROL_VERTS];
+ float weights_du[PATCH_MAX_CONTROL_VERTS];
+ float weights_dv[PATCH_MAX_CONTROL_VERTS];
+
+ int num_control = patch_eval_control_verts(
+ kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv);
+
+ float val = 0.0f;
+ if (du)
+ *du = 0.0f;
+ if (dv)
+ *dv = 0.0f;
+
+ for (int i = 0; i < num_control; i++) {
+ float v = kernel_tex_fetch(__attributes_float, offset + indices[i]);
+
+ val += v * weights[i];
+ if (du)
+ *du += v * weights_du[i];
+ if (dv)
+ *dv += v * weights_dv[i];
+ }
+
+ return val;
}
-ccl_device float2 patch_eval_float2(KernelGlobals *kg, const ShaderData *sd, int offset,
- int patch, float u, float v, int channel,
- float2 *du, float2 *dv)
+ccl_device float2 patch_eval_float2(KernelGlobals *kg,
+ const ShaderData *sd,
+ int offset,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ float2 *du,
+ float2 *dv)
{
- int indices[PATCH_MAX_CONTROL_VERTS];
- float weights[PATCH_MAX_CONTROL_VERTS];
- float weights_du[PATCH_MAX_CONTROL_VERTS];
- float weights_dv[PATCH_MAX_CONTROL_VERTS];
-
- int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
- indices, weights, weights_du, weights_dv);
-
- float2 val = make_float2(0.0f, 0.0f);
- if(du) *du = make_float2(0.0f, 0.0f);
- if(dv) *dv = make_float2(0.0f, 0.0f);
-
- for(int i = 0; i < num_control; i++) {
- float2 v = kernel_tex_fetch(__attributes_float2, offset + indices[i]);
-
- val += v * weights[i];
- if(du) *du += v * weights_du[i];
- if(dv) *dv += v * weights_dv[i];
- }
-
- return val;
+ int indices[PATCH_MAX_CONTROL_VERTS];
+ float weights[PATCH_MAX_CONTROL_VERTS];
+ float weights_du[PATCH_MAX_CONTROL_VERTS];
+ float weights_dv[PATCH_MAX_CONTROL_VERTS];
+
+ int num_control = patch_eval_control_verts(
+ kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv);
+
+ float2 val = make_float2(0.0f, 0.0f);
+ if (du)
+ *du = make_float2(0.0f, 0.0f);
+ if (dv)
+ *dv = make_float2(0.0f, 0.0f);
+
+ for (int i = 0; i < num_control; i++) {
+ float2 v = kernel_tex_fetch(__attributes_float2, offset + indices[i]);
+
+ val += v * weights[i];
+ if (du)
+ *du += v * weights_du[i];
+ if (dv)
+ *dv += v * weights_dv[i];
+ }
+
+ return val;
}
-ccl_device float3 patch_eval_float3(KernelGlobals *kg, const ShaderData *sd, int offset,
- int patch, float u, float v, int channel,
- float3 *du, float3 *dv)
+ccl_device float3 patch_eval_float3(KernelGlobals *kg,
+ const ShaderData *sd,
+ int offset,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ float3 *du,
+ float3 *dv)
{
- int indices[PATCH_MAX_CONTROL_VERTS];
- float weights[PATCH_MAX_CONTROL_VERTS];
- float weights_du[PATCH_MAX_CONTROL_VERTS];
- float weights_dv[PATCH_MAX_CONTROL_VERTS];
-
- int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
- indices, weights, weights_du, weights_dv);
-
- float3 val = make_float3(0.0f, 0.0f, 0.0f);
- if(du) *du = make_float3(0.0f, 0.0f, 0.0f);
- if(dv) *dv = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int i = 0; i < num_control; i++) {
- float3 v = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + indices[i]));
-
- val += v * weights[i];
- if(du) *du += v * weights_du[i];
- if(dv) *dv += v * weights_dv[i];
- }
-
- return val;
+ int indices[PATCH_MAX_CONTROL_VERTS];
+ float weights[PATCH_MAX_CONTROL_VERTS];
+ float weights_du[PATCH_MAX_CONTROL_VERTS];
+ float weights_dv[PATCH_MAX_CONTROL_VERTS];
+
+ int num_control = patch_eval_control_verts(
+ kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv);
+
+ float3 val = make_float3(0.0f, 0.0f, 0.0f);
+ if (du)
+ *du = make_float3(0.0f, 0.0f, 0.0f);
+ if (dv)
+ *dv = make_float3(0.0f, 0.0f, 0.0f);
+
+ for (int i = 0; i < num_control; i++) {
+ float3 v = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + indices[i]));
+
+ val += v * weights[i];
+ if (du)
+ *du += v * weights_du[i];
+ if (dv)
+ *dv += v * weights_dv[i];
+ }
+
+ return val;
}
-ccl_device float3 patch_eval_uchar4(KernelGlobals *kg, const ShaderData *sd, int offset,
- int patch, float u, float v, int channel,
- float3 *du, float3 *dv)
+ccl_device float3 patch_eval_uchar4(KernelGlobals *kg,
+ const ShaderData *sd,
+ int offset,
+ int patch,
+ float u,
+ float v,
+ int channel,
+ float3 *du,
+ float3 *dv)
{
- int indices[PATCH_MAX_CONTROL_VERTS];
- float weights[PATCH_MAX_CONTROL_VERTS];
- float weights_du[PATCH_MAX_CONTROL_VERTS];
- float weights_dv[PATCH_MAX_CONTROL_VERTS];
-
- int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
- indices, weights, weights_du, weights_dv);
-
- float3 val = make_float3(0.0f, 0.0f, 0.0f);
- if(du) *du = make_float3(0.0f, 0.0f, 0.0f);
- if(dv) *dv = make_float3(0.0f, 0.0f, 0.0f);
-
- for(int i = 0; i < num_control; i++) {
- float3 v = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, offset + indices[i]));
-
- val += v * weights[i];
- if(du) *du += v * weights_du[i];
- if(dv) *dv += v * weights_dv[i];
- }
-
- return val;
+ int indices[PATCH_MAX_CONTROL_VERTS];
+ float weights[PATCH_MAX_CONTROL_VERTS];
+ float weights_du[PATCH_MAX_CONTROL_VERTS];
+ float weights_dv[PATCH_MAX_CONTROL_VERTS];
+
+ int num_control = patch_eval_control_verts(
+ kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv);
+
+ float3 val = make_float3(0.0f, 0.0f, 0.0f);
+ if (du)
+ *du = make_float3(0.0f, 0.0f, 0.0f);
+ if (dv)
+ *dv = make_float3(0.0f, 0.0f, 0.0f);
+
+ for (int i = 0; i < num_control; i++) {
+ float3 v = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, offset + indices[i]));
+
+ val += v * weights[i];
+ if (du)
+ *du += v * weights_du[i];
+ if (dv)
+ *dv += v * weights_dv[i];
+ }
+
+ return val;
}
CCL_NAMESPACE_END