From 1e81403e62478b0322b850d5ba1cae9e5d6a3e93 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 2 Nov 2012 11:36:28 +0100 Subject: [PATCH] Hopefully fixed difference in A* between windows.Linux. --- .../include/PolyVoxCore/AStarPathfinder.h | 3 +- .../include/PolyVoxCore/AStarPathfinder.inl | 30 ++++++++++--- tests/TestAStarPathfinder.cpp | 42 +++++++++---------- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h index bf983314..83deb6af 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h +++ b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.h @@ -174,7 +174,8 @@ namespace PolyVox float SixConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b); float EighteenConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b); float TwentySixConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b); - float computeH(const Vector3DInt32& a, const Vector3DInt32& b); + float computeH(const Vector3DInt32& a, const Vector3DInt32& b); + uint32_t hash(uint32_t a); //Node containers AllNodesContainer allNodes; diff --git a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl index 03670d02..26c5c398 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl @@ -313,11 +313,17 @@ namespace PolyVox //bias means it is much les likely that two paths are exactly the same //length, and so far fewer nodes must be expanded to find the shortest path. //See http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html#S12 - polyvox_hash uint32Hash; - uint32_t hashValX = uint32Hash(a.getX()); - uint32_t hashValY = uint32Hash(a.getY()); - uint32_t hashValZ = uint32Hash(a.getZ()); - uint32_t hashVal = hashValX ^ hashValY ^ hashValZ; + + //Note that if the hash is zero we can have differences between the Linux vs. Windows + //(or perhaps GCC vs. VS) versions of the code. This is probably because of the way + //sorting inside the std::set works (i.e. one system swaps values which are identical + //while the other one doesn't - both approaches are valid). For the same reason we want + //to make sure that position (x,y,z) has a differnt hash from e.g. position (x,z,y). + uint32_t aX = (a.getX() << 16) & 0x00FF0000; + uint32_t aY = (a.getY() << 8) & 0x0000FF00; + uint32_t aZ = (a.getZ() ) & 0x000000FF; + uint32_t hashVal = hash(aX | aY | aZ); + //Stop hashVal going over 65535, and divide by 1000000 to make sure it is small. hashVal &= 0x0000FFFF; float fHash = hashVal / 1000000.0f; @@ -326,4 +332,18 @@ namespace PolyVox hVal += fHash; return hVal; } + + // Robert Jenkins' 32 bit integer hash function + // http://www.concentric.net/~ttwang/tech/inthash.htm + template + uint32_t AStarPathfinder::hash( uint32_t a) + { + a = (a+0x7ed55d16) + (a<<12); + a = (a^0xc761c23c) ^ (a>>19); + a = (a+0x165667b1) + (a<<5); + a = (a+0xd3a2646c) ^ (a<<9); + a = (a+0xfd7046c5) + (a<<3); + a = (a^0xb55a4f09) ^ (a>>16); + return a; + } } diff --git a/tests/TestAStarPathfinder.cpp b/tests/TestAStarPathfinder.cpp index 9493beb5..e8d0170c 100644 --- a/tests/TestAStarPathfinder.cpp +++ b/tests/TestAStarPathfinder.cpp @@ -59,27 +59,27 @@ void TestAStarPathfinder::testExecute() { Vector3DInt32(0,0,0), Vector3DInt32(1,1,1), - Vector3DInt32(1,2,1), - Vector3DInt32(1,3,1), - Vector3DInt32(1,4,1), - Vector3DInt32(1,5,1), - Vector3DInt32(1,6,1), - Vector3DInt32(1,7,1), - Vector3DInt32(1,8,1), - Vector3DInt32(2,9,2), - Vector3DInt32(3,10,3), - Vector3DInt32(3,11,4), - Vector3DInt32(4,12,5), - Vector3DInt32(5,12,5), - Vector3DInt32(6,13,6), - Vector3DInt32(7,13,7), - Vector3DInt32(8,13,8), - Vector3DInt32(9,13,9), - Vector3DInt32(10,13,10), - Vector3DInt32(11,13,11), - Vector3DInt32(12,13,12), - Vector3DInt32(13,13,13), - Vector3DInt32(14,14,14), + Vector3DInt32(2,1,2), + Vector3DInt32(3,1,3), + Vector3DInt32(3,1,4), + Vector3DInt32(3,1,5), + Vector3DInt32(3,1,6), + Vector3DInt32(3,1,7), + Vector3DInt32(4,2,8), + Vector3DInt32(5,3,9), + Vector3DInt32(5,3,10), + Vector3DInt32(5,3,11), + Vector3DInt32(6,4,12), + Vector3DInt32(7,5,13), + Vector3DInt32(8,6,13), + Vector3DInt32(9,7,13), + Vector3DInt32(9,8,13), + Vector3DInt32(10,9,13), + Vector3DInt32(11,10,14), + Vector3DInt32(12,11,15), + Vector3DInt32(13,12,15), + Vector3DInt32(14,13,15), + Vector3DInt32(14,14,15), Vector3DInt32(15,15,15) };