G3dCubeTestProc: Commander.CommandProc = {
cube: Cube;
obj: REF ANY;
nMarbles: INT = 200;
objList: LIST OF CubeObject;
rs: Random.RandomStream ¬ Random.Create[1000];
report:
PROC [obj:
REF
ANY, shouldBe:
ROPE ¬
NIL] ~ {
IF shouldBe # NIL THEN IO.PutF1[cmd.out,"Next line should say: '%g'\n", IO.rope[shouldBe]];
IF obj =
NIL
THEN {
IO.PutRope[cmd.out,"No hit.\n"];
RETURN;
};
WITH obj
SELECT
FROM
ns: NamedSphere => IO.PutF1[cmd.out,"Hit Sphere '%g'\n", IO.rope[ns.name]];
ENDCASE => IO.PutRope[cmd.out, "Hit an object of a weird type.\n"];
};
-) make a really simple one, around one big sphere:
cube ¬ G3dOctree.FromObjects[LIST[COSphere["Alice",[500,500,500],500]]];
obj ¬ G3dOctree.QueryObjects[cube,[500,500,500]];
report[obj, "Hit Sphere 'Alice'"];
obj ¬ G3dOctree.QueryObjects[cube,[1,1,1]];
report[obj, "No Hit"];
obj ¬ G3dOctree.QueryObjects[cube,[2000,2000, 2000]];
report[obj, "No Hit"];
Two objects:
cube ¬ G3dOctree.FromObjects[LIST[COSphere["Bob",[100,100,100],100], COSphere["Chuck",[200,200,100],25]]];
obj ¬ G3dOctree.QueryObjects[cube,[30,70,100]];
report[obj, "Hit Sphere 'Bob'"];
obj ¬ G3dOctree.QueryObjects[cube,[205,195,100]];
report[obj, "Hit Sphere 'Chuck'"];
obj ¬ G3dOctree.QueryObjects[cube,[190,190,100]];
report[obj, "Hit Sphere 'Chuck'"];
obj ¬ G3dOctree.QueryObjects[cube,[1500,1500,500]];
report[obj, "No Hit"];
obj ¬ G3dOctree.QueryObjects[cube,[175,175,100]];
report[obj, "No Hit"];
create some outside objects, and then add some on the inside:
cube ¬ G3dOctree.FromObjects[LIST[COSphere["Dave",[50,50,500],45], COSphere["Ed",[350,50,500],45], COSphere["Fred",[50,350,500],45],COSphere["George",[350,350,500],45]]];
G3dOctree.AddObject[cube,COSphere["Harry",[150,250,500],45]];
G3dOctree.AddObject[cube,COSphere["Irene",[250,150,500],45]];
obj ¬ G3dOctree.QueryObjects[cube,[40,40,500]];
report[obj, "Hit Sphere 'Dave'"];
obj ¬ G3dOctree.QueryObjects[cube,[360,40,500]];
report[obj, "Hit Sphere 'Ed'"];
obj ¬ G3dOctree.QueryObjects[cube,[40,360,500]];
report[obj, "Hit Sphere 'Fred'"];
obj ¬ G3dOctree.QueryObjects[cube,[360,360,500]];
report[obj, "Hit Sphere 'George'"];
obj ¬ G3dOctree.QueryObjects[cube,[165,235,500]];
report[obj, "Hit Sphere 'Harry'"];
obj ¬ G3dOctree.QueryObjects[cube,[265,140,500]];
report[obj, "Hit Sphere 'Irene'"];
obj ¬ G3dOctree.QueryObjects[cube,[150,150,500]];
report[obj, "No Hit'"];
obj ¬ G3dOctree.QueryObjects[cube,[200,200,500]];
report[obj, "No Hit'"];
Subdivide it so that no cube contains more than one element, and try again:
G3dOctree.SubdivideGivenObjects[cube,1,6];
obj ¬ G3dOctree.QueryObjects[cube,[40,40,500]];
report[obj, "Hit Sphere 'Dave'"];
obj ¬ G3dOctree.QueryObjects[cube,[360,40,500]];
report[obj, "Hit Sphere 'Ed'"];
obj ¬ G3dOctree.QueryObjects[cube,[40,360,500]];
report[obj, "Hit Sphere 'Fred'"];
obj ¬ G3dOctree.QueryObjects[cube,[360,360,500]];
report[obj, "Hit Sphere 'George'"];
obj ¬ G3dOctree.QueryObjects[cube,[165,235,500]];
report[obj, "Hit Sphere 'Harry'"];
obj ¬ G3dOctree.QueryObjects[cube,[265,140,500]];
report[obj, "Hit Sphere 'Irene'"];
obj ¬ G3dOctree.QueryObjects[cube,[150,150,500]];
report[obj, "No Hit'"];
obj ¬ G3dOctree.QueryObjects[cube,[200,200,500]];
report[obj, "No Hit'"];
Make a whole bunch of little marbles, and check it out:
objList ¬ NIL;
FOR i:
INT
IN [0 .. nMarbles)
DO
objList ¬ CONS[COSphere[IO.PutFR1["m%g", IO.int[i]], [Random.NextInt[rs], Random.NextInt[rs], Random.NextInt[rs]], 50], objList];
ENDLOOP;
cube ¬ G3dOctree.FromObjects[objList];
G3dOctree.SubdivideGivenObjects[cube,8,10];
FOR i:
INT
IN [0 .. nMarbles * 2)
DO
pt: Triple ¬ [Random.NextInt[rs], Random.NextInt[rs], Random.NextInt[rs]];
IO.PutFL[cmd.out,"probe #%g: [%g, %g, %g]\n", LIST[IO.int[i], IO.real[pt.x], IO.real[pt.y], IO.real[pt.z]]];
obj ¬ G3dOctree.QueryObjects[cube,pt];
report[obj];
IF obj =
NIL
THEN {
FOR l2:
LIST
OF CubeObject ← objList, l2.rest
WHILE l2 #
NIL
DO
obj2: REF ANY ¬ l2.first.val;
IF SphereQueryProc[obj2, pt]
THEN {
IO.PutFL[cmd.out,"ERROR: [%g,%g,%g] IS in sphere '%g'.\n",LIST[IO.real[pt.x], IO.real[pt.y], IO.real[pt.z], IO.rope[NARROW[obj2,NamedSphere].name]]];
};
ENDLOOP;
}
ELSE {
IF
NOT SphereQueryProc[obj,pt]
THEN {
ns: NamedSphere ¬ NARROW[obj];
IO.PutFL[cmd.out,"ERROR: [%g,%g,%g] not in sphere '%g' as claimed.\n",LIST[IO.real[pt.x], IO.real[pt.y], IO.real[pt.z], IO.rope[NARROW[obj,NamedSphere].name]]];
};
};
ENDLOOP;
};
Commander.Register[key: "G3dCubeTest", proc: G3dCubeTestProc, doc: G3dCubeTestDoc, clientData: NIL];