Am I using GKOctree correctly?

G

I reported what I thought was a bug in GKOctree to Apple and they closed my report stating that it was investigated and found to be working as documented, which leads me to believe that there is something wrong with my code. The problem is that I'm inserting some points in the tree and when I query for the exact location of those points it returns lots of points that were not originally inserted at those locations.


Here is the test code that I wrote and ran on iOS 12.4 and 13.3 with similar results:


@import GameplayKit;

@import SceneKit;


int main(int argc, char * argv[]) {

GKBox box;

box.boxMin = simd_make_float3(-30.0, -30.0, -30.0);

box.boxMax = simd_make_float3(30.0, 30.0, 30.0);

GKOctree<NSValue *> *tree = [GKOctree octreeWithBoundingBox:box minimumCellSize:1.0];

for (float x = -1.0; x <= 1.0; x += 1.0) {

for (float y = -1.0; y <= 1.0; y += 1.0) {

for (float z = -1.0; z <= 1.0; z += 1.0) {

simd_float3 point = simd_make_float3(x, y, z);

NSValue *value = [NSValue valueWithSCNVector3:SCNVector3FromFloat3(point)];

[tree addElement:value withPoint:point];

}

}

}

for (float x = -1.0; x <= 1.0; x += 1.0) {

for (float y = -1.0; y <= 1.0; y += 1.0) {

for (float z = -1.0; z <= 1.0; z += 1.0) {

printf("Querying for point: %.0f, %.0f, %.0f...\n", x, y, z);

simd_float3 point = simd_make_float3(x, y, z);

NSArray<NSValue *> *values = [tree elementsAtPoint:point];

for (NSValue *value in values) {

SCNVector3 vector = value.SCNVector3Value;

printf("Found: %.0f, %.0f, %.0f\n", vector.x, vector.y, vector.z);

}

}

}

}

return 0;

}


The idea is that for each queried point there should be only one result, but when I run this code it returns lots of results for each query and I can't figure out why. Can anyone help?

Replies

I have same issue which looks like bugs of GKOctree
It may be related to this topic.
Here is reproduction code.

Code Block swift
import GameplayKit
class point: NSObject {
  var vec: simd_float3
  init(x: Float, y: Float, z: Float) {
    self.vec = simd_float3(x,y,z)
  }
}
func test () {
  let points = [
    point(x: 1, y: 1, z: 2),
    point(x: 2, y: 2, z: 1),
    point(x: 2, y: 1, z: 1)
  ]
  let min = point(x:0, y: 0, z: 0)
  let max = point(x:3, y: 3, z: 3)
  let box = GKBox(boxMin: min.vec, boxMax: max.vec)
  let tree = GKOctree<point>(boundingBox: box, minimumCellSize: 0.01)
  print("=== registering ===")
  for p in points {
    let node = tree.add(p, at: p.vec)
    print("at:", p.vec, "box:", node.box)
  }
  print("=== list in elements(at:) ===")
  for p in tree.elements(at: points[0].vec) {
    print(p.vec)
  }
  print("=== elements(in:) ===")
  for p in tree.elements(in: box) {
    print(p.vec)
  }
}
test()


It generates these results in the following.

Code Block swift
=== registering ===
at: SIMD3<Float>(1.0, 1.0, 2.0) box: GKBox(boxMin: SIMD3<Float>(0.4921875, 0.99609375, 1.9921875), boxMax: SIMD3<Float>(0.50390625, 1.0078125, 2.0039062))
at: SIMD3<Float>(2.0, 2.0, 1.0) box: GKBox(boxMin: SIMD3<Float>(0.99609375, 1.9921875, 0.99609375), boxMax: SIMD3<Float>(1.0078125, 2.0039062, 1.0078125))
at: SIMD3<Float>(2.0, 1.0, 1.0) box: GKBox(boxMin: SIMD3<Float>(2.4960938, 0.99609375, 0.4921875), boxMax: SIMD3<Float>(2.5078125, 1.0078125, 0.50390625))
=== list in elements(at:) ===
SIMD3<Float>(1.0, 1.0, 2.0)
=== elements(in:) ===


Results report that each point which added to GKOctree are not in each GTKOctreeNode.box.
And when code specifies box to get elements, it doesn't return any elements at all.

It seems bugs.

Platform: iOS 14.2