diff options
author | Hans Goudey <h.goudey@me.com> | 2020-12-17 16:43:31 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2020-12-17 16:43:31 +0300 |
commit | c9f8f7915fd8f65d1c57cd971f8e8a31a662a912 (patch) | |
tree | e0e74b0abef02e56943d97eac1d6affa761d6626 /source/blender/blenlib/BLI_hash.h | |
parent | a9edf2c869baf1b73d388796737c38a1eff06471 (diff) |
Geometry Nodes: Make random attribute node stable
Currently, the random attribute node doesn't work well for most
workflows because for any change in the input data it outputs
completely different results.
This patch adds an implicit seed attribute input to the node, referred
to by "id". The attribute is hashed for each element using the CPPType
system's hash method, meaning the attribute can have any data type.
Supporting any data type is also important so any attribute can be
copied into the "id" attribute and used as a seed.
The "id" attribute is an example of a "reserved name" attribute,
meaning attributes with this name can be used implicitly by nodes like
the random attribute node. Although it makes it a bit more difficult
to dig deeper, using the name implicitly rather than exposing it as an
input should make the system more accessible and predictable.
Differential Revision: https://developer.blender.org/D9832
Diffstat (limited to 'source/blender/blenlib/BLI_hash.h')
-rw-r--r-- | source/blender/blenlib/BLI_hash.h | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/source/blender/blenlib/BLI_hash.h b/source/blender/blenlib/BLI_hash.h index c2be416ef5f..d687e805323 100644 --- a/source/blender/blenlib/BLI_hash.h +++ b/source/blender/blenlib/BLI_hash.h @@ -26,35 +26,59 @@ extern "C" { #endif -BLI_INLINE unsigned int BLI_hash_int_2d(unsigned int kx, unsigned int ky) -{ +/** + * Jenkins Lookup3 Hash Functions. + * Source: http://burtleburtle.net/bob/c/lookup3.c + */ + #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) +#define final(a, b, c) \ + { \ + c ^= b; \ + c -= rot(b, 14); \ + a ^= c; \ + a -= rot(c, 11); \ + b ^= a; \ + b -= rot(a, 25); \ + c ^= b; \ + c -= rot(b, 16); \ + a ^= c; \ + a -= rot(c, 4); \ + b ^= a; \ + b -= rot(a, 14); \ + c ^= b; \ + c -= rot(b, 24); \ + } \ + ((void)0) + +BLI_INLINE unsigned int BLI_hash_int_3d(unsigned int kx, unsigned int ky, unsigned int kz) +{ + unsigned int a, b, c; + a = b = c = 0xdeadbeef + (3 << 2) + 13; + + c += kz; + b += ky; + a += kx; + final(a, b, c); + + return c; +} +BLI_INLINE unsigned int BLI_hash_int_2d(unsigned int kx, unsigned int ky) +{ unsigned int a, b, c; a = b = c = 0xdeadbeef + (2 << 2) + 13; a += kx; b += ky; - c ^= b; - c -= rot(b, 14); - a ^= c; - a -= rot(c, 11); - b ^= a; - b -= rot(a, 25); - c ^= b; - c -= rot(b, 16); - a ^= c; - a -= rot(c, 4); - b ^= a; - b -= rot(a, 14); - c ^= b; - c -= rot(b, 24); + final(a, b, c); return c; +} +#undef final #undef rot -} BLI_INLINE unsigned int BLI_hash_string(const char *str) { |