DIRECTORY Commander, G3dBasic, G3dBox, G3dOctree, IO, Random, Rope; G3dCubeTestImpl: CEDAR PROGRAM IMPORTS Commander, G3dBox, G3dOctree, IO, Random ~ BEGIN ROPE: TYPE ~ Rope.ROPE; Box: TYPE ~ G3dBasic.Box; Cube: TYPE ~ G3dOctree.Cube; CubeObject: TYPE ~ G3dOctree.CubeObject; Triple: TYPE ~ G3dBasic.Triple; NamedSphere: TYPE ~ REF NamedSphereRep; NamedSphereRep: TYPE ~ RECORD [ name: ROPE ¬ NIL, center: Triple, radius: REAL ]; NewNamedSphere: PROC [name: ROPE ¬ NIL, center: Triple, radius: REAL] RETURNS [NamedSphere] ~ { RETURN [NEW[NamedSphereRep ¬ [name,center,radius]]]; }; SphereBbox: PROC [ns: NamedSphere] RETURNS [Box] ~ { RETURN [G3dBox.BoxFromPoints[[ns.center.x - ns.radius, ns.center.y - ns.radius, ns.center.z - ns.radius], [ns.center.x + ns.radius, ns.center.y + ns.radius, ns.center.z + ns.radius]]]; }; SphereQueryProc: G3dOctree.CubeObjectQueryProc ~ { ns: NamedSphere ¬ NARROW[val]; distSq: REAL ¬ (pt.x - ns.center.x) * (pt.x - ns.center.x) + (pt.y - ns.center.y)*(pt.y-ns.center.y) + (pt.z-ns.center.z)*(pt.z-ns.center.z); RETURN [distSq <= ns.radius*ns.radius]; }; COSphere: PROC [name: ROPE ¬ NIL, center: Triple, radius: REAL] RETURNS [CubeObject] ~ { ns: NamedSphere ¬ NewNamedSphere[name,center,radius]; RETURN [NEW[G3dOctree.CubeObjectRep ¬ [ns, SphereBbox[ns], SphereQueryProc]]]; }; G3dCubeTestDoc: ROPE _ "G3dCubeTest: no aguments"; 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"]; }; 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"]; 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"]; 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'"]; 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'"]; 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]]; obj ¬ G3dOctree.QueryObjects[cube,pt]; 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]; END. > G3dCubeTestImpl.mesa Ken Fishkin, August 25, 1992 12:17 pm PDT Jules Bloomenthal November 21, 1992 2:53 pm PST CubeObjectQueryProc: TYPE ~ PROC[val: REF ANY, pt: Triple] RETURNS [BOOL]; -) make a really simple one, around one big sphere: Two objects: create some outside objects, and then add some on the inside: Subdivide it so that no cube contains more than one element, and try again: Make a whole bunch of little marbles, and check it out: 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]]]; report[obj]; Κ9•NewlineDelimiter ™šΟnœ™Icode™)K™/—J˜šΟk ˜ J˜ J˜ J˜J˜ Jšžœ˜J˜J˜J˜—J˜šœžœž˜šž˜J˜ J˜J˜ Jšžœ˜J˜—J˜Jšœž˜J˜Jšžœžœžœ˜Jšœžœ˜Jšœžœ˜Jšœ žœ˜(Jšœžœ˜J˜Kšœ žœžœ˜'šœžœžœ˜Kšœžœžœ˜K˜Kšœž˜ K˜K˜—š œžœžœžœžœžœ˜_Kšžœžœ)˜4K˜—š œžœžœ ˜4Kšžœ²˜ΈK˜—šœ#˜2Kš œžœžœžœžœžœžœ™JKšœžœ˜Kšœžœ˜Kšžœ!˜'Kšœ˜—š œžœžœžœžœžœ˜XK˜5KšžœžœC˜NK˜—K˜šœžœ˜J˜—K˜J˜šœ˜*J˜ Jšœžœžœ˜ Jšœ žœ˜Jšœ žœžœ ˜J˜.J˜š œžœžœžœ žœžœ˜5Kš žœ žœžœžœ/žœ˜[šžœžœžœ˜Kšžœ˜ Kšžœ˜Kšœ˜—šžœžœž˜Kšœžœ$žœ˜KKšžœžœ6˜C—K˜—J˜J™3Jšœžœ'˜HJ˜1J˜"J˜+J˜J˜5J˜J˜J™ JšœžœI˜jJ˜/J˜ J˜1J˜"J˜1J˜"J˜3J˜J˜1J˜J˜J™=Jšœžœ‰˜ͺJ˜=J˜=J˜/J˜!J˜0J˜J˜0J˜!J˜1J˜$J˜1J˜"J˜1J˜"J˜1J˜J˜1J˜J˜J™KJ˜*J˜/J˜!J˜0J˜J˜0J˜!J˜1J˜$J˜1J˜"J˜1J˜"J˜1J˜J˜1J˜J˜J™7Jšœ žœ˜šžœžœžœž˜ Kšœ žœ žœžœV˜Kšžœ˜—K˜&K˜+šžœžœžœž˜$K˜JKšœ>žœ žœ žœ™lK˜&K™ šžœžœ˜ šžœ˜š žœžœžœžœžœž˜?Kšœžœžœ˜šžœžœ˜#Kšžœ8žœžœ žœ žœ žœžœ˜•Kšœ˜—Kšžœ˜—K˜—šžœ˜šžœžœžœ˜%Kšœžœ˜KšžœDžœžœ žœ žœ žœžœ˜ K˜Kšœ˜—Kšœ˜——Kšžœ˜—J˜J˜—J˜Jšœ_žœ˜dJ˜Jšžœ˜—J˜—…—fέ