Merge branch 'master' into blender2.8
This commit is contained in:
commit
14af3e485f
|
@ -108,6 +108,73 @@ void BVH::refit(Progress& progress)
|
|||
refit_nodes();
|
||||
}
|
||||
|
||||
void BVH::refit_primitives(int start, int end, BoundBox& bbox, uint& visibility)
|
||||
{
|
||||
/* Refit range of primitives. */
|
||||
for(int prim = start; prim < end; prim++) {
|
||||
int pidx = pack.prim_index[prim];
|
||||
int tob = pack.prim_object[prim];
|
||||
Object *ob = objects[tob];
|
||||
|
||||
if(pidx == -1) {
|
||||
/* Object instance. */
|
||||
bbox.grow(ob->bounds);
|
||||
}
|
||||
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);
|
||||
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
|
||||
|
||||
curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->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(attr) {
|
||||
size_t mesh_size = mesh->curve_keys.size();
|
||||
size_t steps = mesh->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Triangles. */
|
||||
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
|
||||
Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
|
||||
const float3 *vpos = &mesh->verts[0];
|
||||
|
||||
triangle.bounds_grow(vpos, bbox);
|
||||
|
||||
/* Motion triangles. */
|
||||
if(mesh->use_motion_blur) {
|
||||
Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
|
||||
if(attr) {
|
||||
size_t mesh_size = mesh->verts.size();
|
||||
size_t steps = mesh->motion_steps - 1;
|
||||
float3 *vert_steps = attr->data_float3();
|
||||
|
||||
for(size_t i = 0; i < steps; i++)
|
||||
triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visibility |= ob->visibility_for_tracing();
|
||||
}
|
||||
}
|
||||
|
||||
/* Triangles */
|
||||
|
||||
void BVH::pack_triangle(int idx, float4 tri_verts[3])
|
||||
|
|
|
@ -91,6 +91,9 @@ public:
|
|||
protected:
|
||||
BVH(const BVHParams& params, const vector<Object*>& objects);
|
||||
|
||||
/* Refit range of primitives. */
|
||||
void refit_primitives(int start, int end, BoundBox& bbox, uint& visibility);
|
||||
|
||||
/* triangles and strands */
|
||||
void pack_primitives();
|
||||
void pack_triangle(int idx, float4 storage[3]);
|
||||
|
|
|
@ -247,73 +247,14 @@ void BVH2::refit_nodes()
|
|||
void BVH2::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
|
||||
{
|
||||
if(leaf) {
|
||||
/* refit leaf node */
|
||||
assert(idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
|
||||
const int4 *data = &pack.leaf_nodes[idx];
|
||||
const int c0 = data[0].x;
|
||||
const int c1 = data[0].y;
|
||||
/* refit leaf node */
|
||||
for(int prim = c0; prim < c1; prim++) {
|
||||
int pidx = pack.prim_index[prim];
|
||||
int tob = pack.prim_object[prim];
|
||||
Object *ob = objects[tob];
|
||||
|
||||
if(pidx == -1) {
|
||||
/* object instance */
|
||||
bbox.grow(ob->bounds);
|
||||
}
|
||||
else {
|
||||
/* primitives */
|
||||
const Mesh *mesh = ob->mesh;
|
||||
BVH::refit_primitives(c0, c1, bbox, visibility);
|
||||
|
||||
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);
|
||||
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
|
||||
|
||||
curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->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(attr) {
|
||||
size_t mesh_size = mesh->curve_keys.size();
|
||||
size_t steps = mesh->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* triangles */
|
||||
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
|
||||
Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
|
||||
const float3 *vpos = &mesh->verts[0];
|
||||
|
||||
triangle.bounds_grow(vpos, bbox);
|
||||
|
||||
/* motion triangles */
|
||||
if(mesh->use_motion_blur) {
|
||||
Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
|
||||
if(attr) {
|
||||
size_t mesh_size = mesh->verts.size();
|
||||
size_t steps = mesh->motion_steps - 1;
|
||||
float3 *vert_steps = attr->data_float3();
|
||||
|
||||
for(size_t i = 0; i < steps; i++)
|
||||
triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visibility |= ob->visibility_for_tracing();
|
||||
}
|
||||
/* TODO(sergey): De-duplicate with pack_leaf(). */
|
||||
float4 leaf_data[BVH_NODE_LEAF_SIZE];
|
||||
leaf_data[0].x = __int_as_float(c0);
|
||||
|
|
|
@ -375,71 +375,12 @@ void BVH4::refit_nodes()
|
|||
void BVH4::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
|
||||
{
|
||||
if(leaf) {
|
||||
/* Refit leaf node. */
|
||||
int4 *data = &pack.leaf_nodes[idx];
|
||||
int4 c = data[0];
|
||||
/* Refit leaf node. */
|
||||
for(int prim = c.x; prim < c.y; prim++) {
|
||||
int pidx = pack.prim_index[prim];
|
||||
int tob = pack.prim_object[prim];
|
||||
Object *ob = objects[tob];
|
||||
|
||||
if(pidx == -1) {
|
||||
/* Object instance. */
|
||||
bbox.grow(ob->bounds);
|
||||
}
|
||||
else {
|
||||
/* Primitives. */
|
||||
const Mesh *mesh = ob->mesh;
|
||||
BVH::refit_primitives(c.x, c.y, bbox, visibility);
|
||||
|
||||
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);
|
||||
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
|
||||
|
||||
curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->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(attr) {
|
||||
size_t mesh_size = mesh->curve_keys.size();
|
||||
size_t steps = mesh->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Triangles. */
|
||||
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
|
||||
Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
|
||||
const float3 *vpos = &mesh->verts[0];
|
||||
|
||||
triangle.bounds_grow(vpos, bbox);
|
||||
|
||||
/* Motion triangles. */
|
||||
if(mesh->use_motion_blur) {
|
||||
Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
|
||||
if(attr) {
|
||||
size_t mesh_size = mesh->verts.size();
|
||||
size_t steps = mesh->motion_steps - 1;
|
||||
float3 *vert_steps = attr->data_float3();
|
||||
|
||||
for(size_t i = 0; i < steps; i++)
|
||||
triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visibility |= ob->visibility_for_tracing();
|
||||
}
|
||||
/* TODO(sergey): This is actually a copy of pack_leaf(),
|
||||
* but this chunk of code only knows actual data and has
|
||||
* no idea about BVHNode.
|
||||
|
|
|
@ -87,7 +87,7 @@ ccl_device T kernel_tex_image_interp_bicubic(const TextureInfo& info, CUtexObjec
|
|||
g1x * tex2D<T>(tex, x1, y1));
|
||||
}
|
||||
|
||||
/* Fast tricubic texture lookup using 8 bilinear lookups. */
|
||||
/* Fast tricubic texture lookup using 8 trilinear lookups. */
|
||||
template<typename T>
|
||||
ccl_device T kernel_tex_image_interp_bicubic_3d(const TextureInfo& info, CUtexObject tex, float x, float y, float z)
|
||||
{
|
||||
|
|
|
@ -27,9 +27,21 @@ ccl_device_inline ccl_global TextureInfo* kernel_tex_info(KernelGlobals *kg, uin
|
|||
|
||||
#define tex_fetch(type, info, index) ((ccl_global type*)(kg->buffers[info->cl_buffer] + info->data))[(index)]
|
||||
|
||||
ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, int id, int offset)
|
||||
ccl_device_inline int svm_image_texture_wrap_periodic(int x, int width)
|
||||
{
|
||||
x %= width;
|
||||
if(x < 0)
|
||||
x += width;
|
||||
return x;
|
||||
}
|
||||
|
||||
ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width)
|
||||
{
|
||||
return clamp(x, 0, width-1);
|
||||
}
|
||||
|
||||
ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, const ccl_global TextureInfo *info, int id, int offset)
|
||||
{
|
||||
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
|
||||
const int texture_type = kernel_tex_type(id);
|
||||
|
||||
/* Float4 */
|
||||
|
@ -55,19 +67,45 @@ ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, int id, int o
|
|||
}
|
||||
}
|
||||
|
||||
ccl_device_inline int svm_image_texture_wrap_periodic(int x, int width)
|
||||
ccl_device_inline float4 svm_image_texture_read_2d(KernelGlobals *kg, int id, int x, int y)
|
||||
{
|
||||
x %= width;
|
||||
if(x < 0)
|
||||
x += width;
|
||||
return x;
|
||||
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
|
||||
|
||||
/* Wrap */
|
||||
if(info->extension == EXTENSION_REPEAT) {
|
||||
x = svm_image_texture_wrap_periodic(x, info->width);
|
||||
y = svm_image_texture_wrap_periodic(y, info->height);
|
||||
}
|
||||
else {
|
||||
x = svm_image_texture_wrap_clamp(x, info->width);
|
||||
y = svm_image_texture_wrap_clamp(y, info->height);
|
||||
}
|
||||
|
||||
int offset = x + info->width * y;
|
||||
return svm_image_texture_read(kg, info, id, offset);
|
||||
}
|
||||
|
||||
ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width)
|
||||
ccl_device_inline float4 svm_image_texture_read_3d(KernelGlobals *kg, int id, int x, int y, int z)
|
||||
{
|
||||
return clamp(x, 0, width-1);
|
||||
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
|
||||
|
||||
/* Wrap */
|
||||
if(info->extension == EXTENSION_REPEAT) {
|
||||
x = svm_image_texture_wrap_periodic(x, info->width);
|
||||
y = svm_image_texture_wrap_periodic(y, info->height);
|
||||
z = svm_image_texture_wrap_periodic(z, info->depth);
|
||||
}
|
||||
else {
|
||||
x = svm_image_texture_wrap_clamp(x, info->width);
|
||||
y = svm_image_texture_wrap_clamp(y, info->height);
|
||||
z = svm_image_texture_wrap_clamp(z, info->depth);
|
||||
}
|
||||
|
||||
int offset = x + info->width * y + info->width * info->height * z;
|
||||
return svm_image_texture_read(kg, info, id, offset);
|
||||
}
|
||||
|
||||
|
||||
ccl_device_inline float svm_image_texture_frac(float x, int *ix)
|
||||
{
|
||||
int i = float_to_int(x) - ((x < 0.0f)? 1: 0);
|
||||
|
@ -87,107 +125,52 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
|
|||
{
|
||||
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
|
||||
|
||||
uint width = info->width;
|
||||
uint height = info->height;
|
||||
uint interpolation = info->interpolation;
|
||||
uint extension = info->extension;
|
||||
if(info->extension == EXTENSION_CLIP) {
|
||||
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/* Actual sampling. */
|
||||
if(interpolation == INTERPOLATION_CLOSEST) {
|
||||
if(info->interpolation == INTERPOLATION_CLOSEST) {
|
||||
/* Closest interpolation. */
|
||||
int ix, iy;
|
||||
svm_image_texture_frac(x*width, &ix);
|
||||
svm_image_texture_frac(y*height, &iy);
|
||||
svm_image_texture_frac(x*info->width, &ix);
|
||||
svm_image_texture_frac(y*info->height, &iy);
|
||||
|
||||
if(extension == EXTENSION_REPEAT) {
|
||||
ix = svm_image_texture_wrap_periodic(ix, width);
|
||||
iy = svm_image_texture_wrap_periodic(iy, height);
|
||||
}
|
||||
else {
|
||||
if(extension == EXTENSION_CLIP) {
|
||||
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
/* Fall through. */
|
||||
/* EXTENSION_EXTEND */
|
||||
ix = svm_image_texture_wrap_clamp(ix, width);
|
||||
iy = svm_image_texture_wrap_clamp(iy, height);
|
||||
}
|
||||
return svm_image_texture_read_2d(kg, id, ix, iy);
|
||||
}
|
||||
else if(info->interpolation == INTERPOLATION_LINEAR) {
|
||||
/* Bilinear interpolation. */
|
||||
int ix, iy;
|
||||
float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
|
||||
float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
|
||||
|
||||
return svm_image_texture_read(kg, id, ix + iy*width);
|
||||
float4 r;
|
||||
r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read_2d(kg, id, ix, iy);
|
||||
r += (1.0f - ty)*tx*svm_image_texture_read_2d(kg, id, ix+1, iy);
|
||||
r += ty*(1.0f - tx)*svm_image_texture_read_2d(kg, id, ix, iy+1);
|
||||
r += ty*tx*svm_image_texture_read_2d(kg, id, ix+1, iy+1);
|
||||
return r;
|
||||
}
|
||||
else {
|
||||
/* Bilinear or bicubic interpolation. */
|
||||
int ix, iy, nix, niy;
|
||||
float tx = svm_image_texture_frac(x*width - 0.5f, &ix);
|
||||
float ty = svm_image_texture_frac(y*height - 0.5f, &iy);
|
||||
|
||||
if(extension == EXTENSION_REPEAT) {
|
||||
ix = svm_image_texture_wrap_periodic(ix, width);
|
||||
iy = svm_image_texture_wrap_periodic(iy, height);
|
||||
nix = svm_image_texture_wrap_periodic(ix+1, width);
|
||||
niy = svm_image_texture_wrap_periodic(iy+1, height);
|
||||
}
|
||||
else {
|
||||
if(extension == EXTENSION_CLIP) {
|
||||
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
ix = svm_image_texture_wrap_clamp(ix, width);
|
||||
iy = svm_image_texture_wrap_clamp(iy, height);
|
||||
nix = svm_image_texture_wrap_clamp(ix+1, width);
|
||||
niy = svm_image_texture_wrap_clamp(iy+1, height);
|
||||
}
|
||||
|
||||
if(interpolation == INTERPOLATION_LINEAR) {
|
||||
/* Bilinear interpolation. */
|
||||
float4 r;
|
||||
r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, ix + iy*width);
|
||||
r += (1.0f - ty)*tx*svm_image_texture_read(kg, id, nix + iy*width);
|
||||
r += ty*(1.0f - tx)*svm_image_texture_read(kg, id, ix + niy*width);
|
||||
r += ty*tx*svm_image_texture_read(kg, id, nix + niy*width);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Bicubic interpolation. */
|
||||
int pix, piy, nnix, nniy;
|
||||
if(extension == EXTENSION_REPEAT) {
|
||||
pix = svm_image_texture_wrap_periodic(ix-1, width);
|
||||
piy = svm_image_texture_wrap_periodic(iy-1, height);
|
||||
nnix = svm_image_texture_wrap_periodic(ix+2, width);
|
||||
nniy = svm_image_texture_wrap_periodic(iy+2, height);
|
||||
}
|
||||
else {
|
||||
pix = svm_image_texture_wrap_clamp(ix-1, width);
|
||||
piy = svm_image_texture_wrap_clamp(iy-1, height);
|
||||
nnix = svm_image_texture_wrap_clamp(ix+2, width);
|
||||
nniy = svm_image_texture_wrap_clamp(iy+2, height);
|
||||
}
|
||||
int ix, iy;
|
||||
float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
|
||||
float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
|
||||
|
||||
const int xc[4] = {pix, ix, nix, nnix};
|
||||
const int yc[4] = {width * piy,
|
||||
width * iy,
|
||||
width * niy,
|
||||
width * nniy};
|
||||
float u[4], v[4];
|
||||
/* Some helper macro to keep code reasonable size,
|
||||
* let compiler to inline all the matrix multiplications.
|
||||
*/
|
||||
#define DATA(x, y) (svm_image_texture_read(kg, id, xc[x] + yc[y]))
|
||||
#define TERM(col) \
|
||||
(v[col] * (u[0] * DATA(0, col) + \
|
||||
u[1] * DATA(1, col) + \
|
||||
u[2] * DATA(2, col) + \
|
||||
u[3] * DATA(3, col)))
|
||||
|
||||
SET_CUBIC_SPLINE_WEIGHTS(u, tx);
|
||||
SET_CUBIC_SPLINE_WEIGHTS(v, ty);
|
||||
|
||||
/* Actual interpolation. */
|
||||
return TERM(0) + TERM(1) + TERM(2) + TERM(3);
|
||||
#undef TERM
|
||||
#undef DATA
|
||||
float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
for(int y = 0; y < 4; y++) {
|
||||
for(int x = 0; x < 4; x++) {
|
||||
float weight = u[x]*v[y];
|
||||
r += weight*svm_image_texture_read_2d(kg, id, ix+x-1, iy+y-1);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,145 +179,67 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x,
|
|||
{
|
||||
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
|
||||
|
||||
uint width = info->width;
|
||||
uint height = info->height;
|
||||
uint depth = info->depth;
|
||||
if(info->extension == EXTENSION_CLIP) {
|
||||
if(x < 0.0f || y < 0.0f || z < 0.0f ||
|
||||
x > 1.0f || y > 1.0f || z > 1.0f)
|
||||
{
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
uint interpolation = (interp == INTERPOLATION_NONE)? info->interpolation: interp;
|
||||
uint extension = info->extension;
|
||||
|
||||
/* Actual sampling. */
|
||||
if(interpolation == INTERPOLATION_CLOSEST) {
|
||||
/* Closest interpolation. */
|
||||
int ix, iy, iz;
|
||||
svm_image_texture_frac(x*width, &ix);
|
||||
svm_image_texture_frac(y*height, &iy);
|
||||
svm_image_texture_frac(z*depth, &iz);
|
||||
svm_image_texture_frac(x*info->width, &ix);
|
||||
svm_image_texture_frac(y*info->height, &iy);
|
||||
svm_image_texture_frac(z*info->depth, &iz);
|
||||
|
||||
if(extension == EXTENSION_REPEAT) {
|
||||
ix = svm_image_texture_wrap_periodic(ix, width);
|
||||
iy = svm_image_texture_wrap_periodic(iy, height);
|
||||
iz = svm_image_texture_wrap_periodic(iz, depth);
|
||||
}
|
||||
else {
|
||||
if(extension == EXTENSION_CLIP) {
|
||||
if(x < 0.0f || y < 0.0f || z < 0.0f ||
|
||||
x > 1.0f || y > 1.0f || z > 1.0f)
|
||||
{
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
/* Fall through. */
|
||||
/* EXTENSION_EXTEND */
|
||||
ix = svm_image_texture_wrap_clamp(ix, width);
|
||||
iy = svm_image_texture_wrap_clamp(iy, height);
|
||||
iz = svm_image_texture_wrap_clamp(iz, depth);
|
||||
}
|
||||
return svm_image_texture_read(kg, id, ix + iy*width + iz*width*height);
|
||||
return svm_image_texture_read_3d(kg, id, ix, iy, iz);
|
||||
}
|
||||
else if(interpolation == INTERPOLATION_LINEAR) {
|
||||
/* Bilinear interpolation. */
|
||||
int ix, iy, iz;
|
||||
float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
|
||||
float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
|
||||
float tz = svm_image_texture_frac(z*info->depth - 0.5f, &iz);
|
||||
|
||||
float4 r;
|
||||
r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy, iz);
|
||||
r += (1.0f - tz)*(1.0f - ty)*tx*svm_image_texture_read_3d(kg, id, ix+1, iy, iz);
|
||||
r += (1.0f - tz)*ty*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy+1, iz);
|
||||
r += (1.0f - tz)*ty*tx*svm_image_texture_read_3d(kg, id, ix+1, iy+1, iz);
|
||||
|
||||
r += tz*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy, iz+1);
|
||||
r += tz*(1.0f - ty)*tx*svm_image_texture_read_3d(kg, id, ix+1, iy, iz+1);
|
||||
r += tz*ty*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy+1, iz+1);
|
||||
r += tz*ty*tx*svm_image_texture_read_3d(kg, id, ix+1, iy+1, iz+1);
|
||||
return r;
|
||||
}
|
||||
else {
|
||||
/* Bilinear or bicubic interpolation. */
|
||||
int ix, iy, iz, nix, niy, niz;
|
||||
float tx = svm_image_texture_frac(x*(float)width - 0.5f, &ix);
|
||||
float ty = svm_image_texture_frac(y*(float)height - 0.5f, &iy);
|
||||
float tz = svm_image_texture_frac(z*(float)depth - 0.5f, &iz);
|
||||
|
||||
if(extension == EXTENSION_REPEAT) {
|
||||
ix = svm_image_texture_wrap_periodic(ix, width);
|
||||
iy = svm_image_texture_wrap_periodic(iy, height);
|
||||
iz = svm_image_texture_wrap_periodic(iz, depth);
|
||||
|
||||
nix = svm_image_texture_wrap_periodic(ix+1, width);
|
||||
niy = svm_image_texture_wrap_periodic(iy+1, height);
|
||||
niz = svm_image_texture_wrap_periodic(iz+1, depth);
|
||||
}
|
||||
else {
|
||||
if(extension == EXTENSION_CLIP) {
|
||||
if(x < 0.0f || y < 0.0f || z < 0.0f ||
|
||||
x > 1.0f || y > 1.0f || z > 1.0f)
|
||||
{
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
/* Fall through. */
|
||||
/* EXTENSION_EXTEND */
|
||||
nix = svm_image_texture_wrap_clamp(ix+1, width);
|
||||
niy = svm_image_texture_wrap_clamp(iy+1, height);
|
||||
niz = svm_image_texture_wrap_clamp(iz+1, depth);
|
||||
|
||||
ix = svm_image_texture_wrap_clamp(ix, width);
|
||||
iy = svm_image_texture_wrap_clamp(iy, height);
|
||||
iz = svm_image_texture_wrap_clamp(iz, depth);
|
||||
}
|
||||
|
||||
if(interpolation == INTERPOLATION_LINEAR) {
|
||||
/* Bilinear interpolation. */
|
||||
float4 r;
|
||||
r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, ix + iy*width + iz*width*height);
|
||||
r += (1.0f - tz)*(1.0f - ty)*tx*svm_image_texture_read(kg, id, nix + iy*width + iz*width*height);
|
||||
r += (1.0f - tz)*ty*(1.0f - tx)*svm_image_texture_read(kg, id, ix + niy*width + iz*width*height);
|
||||
r += (1.0f - tz)*ty*tx*svm_image_texture_read(kg, id, nix + niy*width + iz*width*height);
|
||||
|
||||
r += tz*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, ix + iy*width + niz*width*height);
|
||||
r += tz*(1.0f - ty)*tx*svm_image_texture_read(kg, id, nix + iy*width + niz*width*height);
|
||||
r += tz*ty*(1.0f - tx)*svm_image_texture_read(kg, id, ix + niy*width + niz*width*height);
|
||||
r += tz*ty*tx*svm_image_texture_read(kg, id, nix + niy*width + niz*width*height);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Bicubic interpolation. */
|
||||
int pix, piy, piz, nnix, nniy, nniz;
|
||||
if(extension == EXTENSION_REPEAT) {
|
||||
pix = svm_image_texture_wrap_periodic(ix-1, width);
|
||||
piy = svm_image_texture_wrap_periodic(iy-1, height);
|
||||
piz = svm_image_texture_wrap_periodic(iz-1, depth);
|
||||
nnix = svm_image_texture_wrap_periodic(ix+2, width);
|
||||
nniy = svm_image_texture_wrap_periodic(iy+2, height);
|
||||
nniz = svm_image_texture_wrap_periodic(iz+2, depth);
|
||||
}
|
||||
else {
|
||||
pix = svm_image_texture_wrap_clamp(ix-1, width);
|
||||
piy = svm_image_texture_wrap_clamp(iy-1, height);
|
||||
piz = svm_image_texture_wrap_clamp(iz-1, depth);
|
||||
nnix = svm_image_texture_wrap_clamp(ix+2, width);
|
||||
nniy = svm_image_texture_wrap_clamp(iy+2, height);
|
||||
nniz = svm_image_texture_wrap_clamp(iz+2, depth);
|
||||
}
|
||||
int ix, iy, iz;
|
||||
float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
|
||||
float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
|
||||
float tz = svm_image_texture_frac(z*info->depth - 0.5f, &iz);
|
||||
|
||||
const int xc[4] = {pix, ix, nix, nnix};
|
||||
const int yc[4] = {width * piy,
|
||||
width * iy,
|
||||
width * niy,
|
||||
width * nniy};
|
||||
const int zc[4] = {width * height * piz,
|
||||
width * height * iz,
|
||||
width * height * niz,
|
||||
width * height * nniz};
|
||||
float u[4], v[4], w[4];
|
||||
|
||||
/* Some helper macro to keep code reasonable size,
|
||||
* let compiler to inline all the matrix multiplications.
|
||||
*/
|
||||
#define DATA(x, y, z) (svm_image_texture_read(kg, id, xc[x] + yc[y] + zc[z]))
|
||||
#define COL_TERM(col, row) \
|
||||
(v[col] * (u[0] * DATA(0, col, row) + \
|
||||
u[1] * DATA(1, col, row) + \
|
||||
u[2] * DATA(2, col, row) + \
|
||||
u[3] * DATA(3, col, row)))
|
||||
#define ROW_TERM(row) \
|
||||
(w[row] * (COL_TERM(0, row) + \
|
||||
COL_TERM(1, row) + \
|
||||
COL_TERM(2, row) + \
|
||||
COL_TERM(3, row)))
|
||||
|
||||
SET_CUBIC_SPLINE_WEIGHTS(u, tx);
|
||||
SET_CUBIC_SPLINE_WEIGHTS(v, ty);
|
||||
SET_CUBIC_SPLINE_WEIGHTS(w, tz);
|
||||
|
||||
/* Actual interpolation. */
|
||||
return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
|
||||
float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
#undef COL_TERM
|
||||
#undef ROW_TERM
|
||||
#undef DATA
|
||||
for(int z = 0; z < 4; z++) {
|
||||
for(int y = 0; y < 4; y++) {
|
||||
for(int x = 0; x < 4; x++) {
|
||||
float weight = u[x]*v[y]*w[z];
|
||||
r += weight*svm_image_texture_read_3d(kg, id, ix+x-1, iy+y-1, iz+z-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -827,7 +827,7 @@ static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, const wmEve
|
|||
/* TODO, hardcoded, extend WM_gesture_straightline_ */
|
||||
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
|
||||
wmGesture *gesture = op->customdata;
|
||||
gesture->mode = 1;
|
||||
gesture->is_active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,9 +73,6 @@ static EnumPropertyItem property_flag_items[] = {
|
|||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE', 'PROPORTIONAL'," \
|
||||
"'TEXTEDIT_UPDATE'].\n" \
|
||||
" :type options: set\n" \
|
||||
" :arg poll: function to be called to determine whether an item is valid for this property.\n" \
|
||||
" The function must take 2 values (self,object) and return Bool.\n" \
|
||||
" :type poll: function\n" \
|
||||
|
||||
static EnumPropertyItem property_flag_enum_items[] = {
|
||||
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
|
||||
|
@ -1941,6 +1938,11 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *ge
|
|||
" *Warning* there are no safety checks to avoid infinite recursion.\n" \
|
||||
" :type update: function\n" \
|
||||
|
||||
#define BPY_PROPDEF_POLL_DOC \
|
||||
" :arg poll: function to be called to determine whether an item is valid for this property.\n" \
|
||||
" The function must take 2 values (self, object) and return Bool.\n" \
|
||||
" :type poll: function\n" \
|
||||
|
||||
#define BPY_PROPDEF_GET_DOC \
|
||||
" :arg get: Function to be called when this value is 'read',\n" \
|
||||
" This function must take 1 value (self) and return the value of the property.\n" \
|
||||
|
@ -2884,6 +2886,7 @@ BPY_PROPDEF_TYPE_DOC
|
|||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
BPY_PROPDEF_OPTIONS_DOC
|
||||
BPY_PROPDEF_POLL_DOC
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
|
|
|
@ -414,11 +414,14 @@ typedef struct wmNotifier {
|
|||
typedef struct wmGesture {
|
||||
struct wmGesture *next, *prev;
|
||||
int event_type; /* event->type */
|
||||
int mode; /* for modal callback */
|
||||
int type; /* gesture type define */
|
||||
int swinid; /* initial subwindow id where it started */
|
||||
int points; /* optional, amount of points stored */
|
||||
int size; /* optional, maximum amount of points stored */
|
||||
int points_alloc; /* optional, maximum amount of points stored */
|
||||
|
||||
/* For modal operators which may be running idle, waiting for an event to activate the gesture.
|
||||
* Typically this is set when the user is click-dragging the gesture (border and circle select for eg). */
|
||||
uint is_active : 1;
|
||||
|
||||
void *customdata;
|
||||
/* customdata for border is a recti */
|
||||
|
|
|
@ -84,6 +84,9 @@
|
|||
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
/* Motion in pixels allowed before we don't consider single/double click. */
|
||||
#define WM_EVENT_CLICK_WIGGLE_ROOM 2
|
||||
|
||||
static void wm_notifier_clear(wmNotifier *note);
|
||||
static void update_tablet_data(wmWindow *win, wmEvent *event);
|
||||
|
||||
|
@ -2397,7 +2400,9 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
|
|||
|
||||
if ((event->val == KM_RELEASE) &&
|
||||
(win->eventstate->prevval == KM_PRESS) &&
|
||||
(win->eventstate->check_click == true))
|
||||
(win->eventstate->check_click == true) &&
|
||||
((abs(event->x - win->eventstate->prevclickx)) <= WM_EVENT_CLICK_WIGGLE_ROOM &&
|
||||
(abs(event->y - win->eventstate->prevclicky)) <= WM_EVENT_CLICK_WIGGLE_ROOM))
|
||||
{
|
||||
event->val = KM_CLICK;
|
||||
|
||||
|
@ -3394,8 +3399,9 @@ static bool wm_event_is_double_click(wmEvent *event, const wmEvent *event_state)
|
|||
(event_state->prevval == KM_RELEASE) &&
|
||||
(event->val == KM_PRESS))
|
||||
{
|
||||
if ((ISMOUSE(event->type) == false) || ((ABS(event->x - event_state->prevclickx)) <= 2 &&
|
||||
(ABS(event->y - event_state->prevclicky)) <= 2))
|
||||
if ((ISMOUSE(event->type) == false) ||
|
||||
((abs(event->x - event_state->prevclickx)) <= WM_EVENT_CLICK_WIGGLE_ROOM &&
|
||||
(abs(event->y - event_state->prevclicky)) <= WM_EVENT_CLICK_WIGGLE_ROOM))
|
||||
{
|
||||
if ((PIL_check_seconds_timer() - event_state->prevclicktime) * 1000 < U.dbl_click_time) {
|
||||
return true;
|
||||
|
|
|
@ -97,11 +97,11 @@ wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type)
|
|||
}
|
||||
else if (ELEM(type, WM_GESTURE_LINES, WM_GESTURE_LASSO)) {
|
||||
short *lasso;
|
||||
gesture->customdata = lasso = MEM_callocN(2 * sizeof(short) * WM_LASSO_MIN_POINTS, "lasso points");
|
||||
gesture->points_alloc = 1024;
|
||||
gesture->customdata = lasso = MEM_mallocN(sizeof(short[2]) * gesture->points_alloc, "lasso points");
|
||||
lasso[0] = event->x - sx;
|
||||
lasso[1] = event->y - sy;
|
||||
gesture->points = 1;
|
||||
gesture->size = WM_LASSO_MIN_POINTS;
|
||||
}
|
||||
|
||||
return gesture;
|
||||
|
@ -437,10 +437,12 @@ void wm_gesture_draw(wmWindow *win)
|
|||
else if (gt->type == WM_GESTURE_CIRCLE)
|
||||
wm_gesture_draw_circle(gt);
|
||||
else if (gt->type == WM_GESTURE_CROSS_RECT) {
|
||||
if (gt->mode == 1)
|
||||
if (gt->is_active) {
|
||||
wm_gesture_draw_rect(gt);
|
||||
else
|
||||
}
|
||||
else {
|
||||
wm_gesture_draw_cross(win, gt);
|
||||
}
|
||||
}
|
||||
else if (gt->type == WM_GESTURE_LINES)
|
||||
wm_gesture_draw_lasso(win, gt, false);
|
||||
|
|
|
@ -2389,7 +2389,7 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
if (event->type == MOUSEMOVE) {
|
||||
wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
|
||||
|
||||
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->mode == 0) {
|
||||
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
|
||||
rect->xmin = rect->xmax = event->x - sx;
|
||||
rect->ymin = rect->ymax = event->y - sy;
|
||||
}
|
||||
|
@ -2404,8 +2404,8 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
else if (event->type == EVT_MODAL_MAP) {
|
||||
switch (event->val) {
|
||||
case GESTURE_MODAL_BEGIN:
|
||||
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->mode == 0) {
|
||||
gesture->mode = 1;
|
||||
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
|
||||
gesture->is_active = true;
|
||||
wm_gesture_tag_redraw(C);
|
||||
}
|
||||
break;
|
||||
|
@ -2500,8 +2500,9 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
|
||||
wm_gesture_tag_redraw(C);
|
||||
|
||||
if (gesture->mode)
|
||||
if (gesture->is_active) {
|
||||
gesture_circle_apply(C, op);
|
||||
}
|
||||
}
|
||||
else if (event->type == EVT_MODAL_MAP) {
|
||||
float fac;
|
||||
|
@ -2534,7 +2535,7 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
if (event->val != GESTURE_MODAL_NOP) {
|
||||
/* apply first click */
|
||||
gesture_circle_apply(C, op);
|
||||
gesture->mode = 1;
|
||||
gesture->is_active = true;
|
||||
wm_gesture_tag_redraw(C);
|
||||
}
|
||||
break;
|
||||
|
@ -2744,28 +2745,24 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
switch (event->type) {
|
||||
case MOUSEMOVE:
|
||||
case INBETWEEN_MOUSEMOVE:
|
||||
|
||||
|
||||
wm_gesture_tag_redraw(C);
|
||||
|
||||
|
||||
wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
|
||||
|
||||
if (gesture->points == gesture->size) {
|
||||
short *old_lasso = gesture->customdata;
|
||||
gesture->customdata = MEM_callocN(2 * sizeof(short) * (gesture->size + WM_LASSO_MIN_POINTS), "lasso points");
|
||||
memcpy(gesture->customdata, old_lasso, 2 * sizeof(short) * gesture->size);
|
||||
gesture->size = gesture->size + WM_LASSO_MIN_POINTS;
|
||||
MEM_freeN(old_lasso);
|
||||
// printf("realloc\n");
|
||||
if (gesture->points == gesture->points_alloc) {
|
||||
gesture->points_alloc *= 2;
|
||||
gesture->customdata = MEM_reallocN(gesture->customdata, sizeof(short[2]) * gesture->points_alloc);
|
||||
}
|
||||
|
||||
{
|
||||
int x, y;
|
||||
short *lasso = gesture->customdata;
|
||||
|
||||
|
||||
lasso += (2 * gesture->points - 2);
|
||||
x = (event->x - sx - lasso[0]);
|
||||
y = (event->y - sy - lasso[1]);
|
||||
|
||||
|
||||
/* make a simple distance check to get a smoother lasso
|
||||
* add only when at least 2 pixels between this and previous location */
|
||||
if ((x * x + y * y) > 4) {
|
||||
|
@ -2776,7 +2773,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case LEFTMOUSE:
|
||||
case MIDDLEMOUSE:
|
||||
case RIGHTMOUSE:
|
||||
|
@ -2934,7 +2931,7 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev
|
|||
if (event->type == MOUSEMOVE) {
|
||||
wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
|
||||
|
||||
if (gesture->mode == 0) {
|
||||
if (gesture->is_active == false) {
|
||||
rect->xmin = rect->xmax = event->x - sx;
|
||||
rect->ymin = rect->ymax = event->y - sy;
|
||||
}
|
||||
|
@ -2949,8 +2946,8 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev
|
|||
else if (event->type == EVT_MODAL_MAP) {
|
||||
switch (event->val) {
|
||||
case GESTURE_MODAL_BEGIN:
|
||||
if (gesture->mode == 0) {
|
||||
gesture->mode = 1;
|
||||
if (gesture->is_active == false) {
|
||||
gesture->is_active = true;
|
||||
wm_gesture_tag_redraw(C);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -62,7 +62,6 @@ void wm_window_keymap(wmKeyConfig *keyconf);
|
|||
void wm_tweakevent_test(bContext *C, const wmEvent *event, int action);
|
||||
|
||||
/* wm_gesture.c */
|
||||
#define WM_LASSO_MIN_POINTS 1024
|
||||
void wm_gesture_draw(struct wmWindow *win);
|
||||
int wm_gesture_evaluate(wmGesture *gesture);
|
||||
void wm_gesture_tag_redraw(bContext *C);
|
||||
|
|
Loading…
Reference in New Issue