67 lines · 2.5 KB · C++
RawDownload
////  HashKey.cpp//  libraries/shared/src////  Created by Andrew Meadows 2017.10.25//  Copyright 2017 High Fidelity, Inc.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #include "HashKey.h" #include "NumericalConstants.h"  const uint8_t NUM_PRIMES = 64;const uint64_t PRIMES[] = {    4194301UL, 4194287UL, 4194277UL, 4194271UL, 4194247UL, 4194217UL, 4194199UL, 4194191UL,    4194187UL, 4194181UL, 4194173UL, 4194167UL, 4194143UL, 4194137UL, 4194131UL, 4194107UL,    4194103UL, 4194023UL, 4194011UL, 4194007UL, 4193977UL, 4193971UL, 4193963UL, 4193957UL,    4193939UL, 4193929UL, 4193909UL, 4193869UL, 4193807UL, 4193803UL, 4193801UL, 4193789UL,    4193759UL, 4193753UL, 4193743UL, 4193701UL, 4193663UL, 4193633UL, 4193573UL, 4193569UL,    4193551UL, 4193549UL, 4193531UL, 4193513UL, 4193507UL, 4193459UL, 4193447UL, 4193443UL,    4193417UL, 4193411UL, 4193393UL, 4193389UL, 4193381UL, 4193377UL, 4193369UL, 4193359UL,    4193353UL, 4193327UL, 4193309UL, 4193303UL, 4193297UL, 4193279UL, 4193269UL, 4193263UL};  // this hash function inspired by Squirrel Eiserloh's GDC2017 talk: "Noise-Based RNG"uint64_t squirrel3_64(uint64_t data, uint8_t primeIndex) {    constexpr uint64_t BIT_NOISE1 = 2760725261486592643UL;    constexpr uint64_t BIT_NOISE2 = 6774464464027632833UL;    constexpr uint64_t BIT_NOISE3 = 5545331650366059883UL;     // blend prime numbers into the hash to prevent dupes    // when hashing the same set of numbers in a different order    uint64_t hash = PRIMES[primeIndex % NUM_PRIMES] * data;    hash *= BIT_NOISE1;    hash ^= (hash >> 16);    hash += BIT_NOISE2;    hash ^= (hash << 16);    hash *= BIT_NOISE3;    return hash ^ (hash >> 16);} constexpr float QUANTIZED_VALUES_PER_METER = 250.0f; // staticfloat HashKey::getNumQuantizedValuesPerMeter() {    return QUANTIZED_VALUES_PER_METER;} void HashKey::Hasher::hashUint64(uint64_t data) {    _hash += squirrel3_64(data, ++_hashCount);} void HashKey::Hasher::hashFloat(float data) {    _hash += squirrel3_64((uint64_t)((int64_t)(data * QUANTIZED_VALUES_PER_METER)), ++_hashCount);} void HashKey::Hasher::hashVec3(const glm::vec3& data) {    _hash += squirrel3_64((uint64_t)((int64_t)(data[0] * QUANTIZED_VALUES_PER_METER)), ++_hashCount);    _hash *= squirrel3_64((uint64_t)((int64_t)(data[1] * QUANTIZED_VALUES_PER_METER)), ++_hashCount);    _hash ^= squirrel3_64((uint64_t)((int64_t)(data[2] * QUANTIZED_VALUES_PER_METER)), ++_hashCount);}