| accessing |
| automatic
|
^ automatic.
|
| copiedSelection
|
| result |
result _ selection copy.
^result.
|
| currentFrame
|
^ currentFrame.
|
| currentFrame: cf
|
currentFrame _ cf.
framePointer _ nil. " framePointer is now invalidated, so clear it "
framePosition _ nil. " framePosition is also crap."
|
| doSelect
|
^ doSelect.
|
| doSelect: bool
|
"Turns the ray test on/off so that the ray test will be focused on a selected item. This is done when we have a mouseDown and want to track the selected object."
doSelect _ bool.
|
| downRay
|
^ downRay.
|
| downRay: bool
|
downRay _ bool.
|
| framePointer
|
| inv |
framePointer ifNil:[
currentFrame ifNotNil:[
inv _ currentFrame inverseGlobalTransform.
self framePosition: (inv localPointToGlobal: self globalPosition).].
self framePointerTrans: currentFrame globalOrientation.
].
^ framePointer.
|
| framePointer: fp
|
framePointer _ fp.
|
| framePointerTrans: trans
|
" convert from global to local target frame coordinates. "
framePointer _ self globalTransform transposed composeWith: trans.
|
| framePosition
|
self framePointer.
^ framePosition.
|
| framePosition: fp
|
framePosition _ fp.
|
| lastSelection
|
^lastSelection
|
| maxDistance
|
^ maxDistance.
|
| maxDistance: md
|
maxDistance _ md.
maxDistanceSquared _ md*md.
|
| minDistance
|
^ minDistance.
|
| minDistance: md
|
minDistance _ md.
minDistanceSquared _ md*md.
|
| resetSelected
|
| lastFrame frame |
frame := self selectedObject.
lastFrame := self lastSelection object.
doSelect ifTrue:[
lastFrame ~= frame ifTrue:[
" ------ pointer has left the lastFrame "
lastFrame ifNotNil:[
lastFrame isComponent ifTrue:[
(lastFrame handlesPointerOver: self) ifTrue:[
lastFrame pointerLeave: self.
].
].
].
" ------ pointer has entered the frame "
frame ifNotNil:[
frame isComponent ifTrue:[
(frame handlesPointerOver: self) ifTrue: [
frame pointerEnter: self.
].
].
].
] ifFalse: [
" ------ pointer is still inside the same object "
frame ifNotNil:[
(frame handlesPointerOver: self) ifTrue: [
frame pointerOver: self.
].
].
].
lastSelection := selection.
selection := TSelection new.
selection distance: Float infinity.
] ifFalse: [
currentFrame _ self selectedFrame.
framePosition _ nil.
framePointer _ nil.].
self maxDistance: Float infinity.
|
| resetTotal
|
lastSelection := TSelection new.
selection := TSelection new.
selection distance: Float infinity.
self maxDistance: Float infinity.
|
| selected: sel
|
selection := sel.
|
| selectedDistance
|
^ selection distance.
|
| selectedDistance: dist
|
selection distance: dist* Croquet world frameScale.
|
| selectedDistanceSquared
|
^ selection distanceSquared.
|
| selectedDistanceSquared: dist
|
selection distanceSquared: dist* Croquet world frameScaleSquared.
|
| selectedFrame
|
^ selection frame
|
| selectedFrame: sf
|
selection frame: sf
|
| selectedFramePosition
|
^selection framePosition.
|
| selectedFramePosition: sfp
|
selection framePosition: sfp.
|
| selectedIndex
|
^ selection index
|
| selectedIndex: si
|
selection index: si
|
| selectedNormal
|
^ selection normal
|
| selectedNormal: sn
|
selection normal: sn.
|
| selectedObject
|
^ selection object
|
| selectedObject: so
|
selection object: so.
|
| selectedParent
|
^ selection parent
|
| selectedParent: sp
|
selection parent: sp.
|
| selectedParentTransform
|
^ selection parentTransform.
|
| selectedParentTransform: spt
|
selection parentTransform: spt.
|
| selectedPoint
|
^ selection point
|
| selectedPoint: sp
|
selection point: sp.
|
| selectedPointAt
|
^ (self selectedPoint - self selectedFramePosition)normalized.
|
| selectedTriangle
|
^selection triangle
|
| selectedTriangle: aTriangle
|
selection triangle: aTriangle
|
| selection
|
^selection
|
| setAutomatic: bool
|
automatic _ bool.
|
| sphereDistSquared
|
^ sphereDistSquared.
|
| sphereDistSquared: sds
|
sphereDistSquared _ sds.
|
| testDistance
|
^ testDistance.
|
| testDistance: bool
|
testDistance _ bool.
|
| testSelectedDistance: dist
|
| scaledDistance |
self testDistance ifFalse:[ ^ true. "don't test, just say yes."].
dist < 0 ifTrue:[^ false.].
scaledDistance _ dist * Croquet world frameScale.
selection distance < scaledDistance ifTrue:[^ false ]. "we already have a closer point."
minDistance > scaledDistance ifTrue:[^ false.]. "this is too close"
maxDistance < scaledDistance ifTrue:[^ false.]. "this is too far"
^ true.
|
| testSelectedDistanceSquared: dist
|
| scaledDistance |
self testDistance ifFalse:[ ^ true. "don't test, just say yes."].
scaledDistance _ Croquet world frameScaleSquared * dist.
selection distanceSquared < scaledDistance ifTrue:[^ false ]. "we already have a closer point."
minDistanceSquared > scaledDistance ifTrue:[^ false]. "this choice is too close "
maxDistanceSquared < scaledDistance ifTrue:[^ false]. "this choice is too far "
^ true.
|
| picking |
| frame: frame pickCylinderFrom: pnt1 radius: rad1 to: pnt2 radius: rad2
|
| rval |
self testDistance: false.
self currentFrame: frame.
rval _ self pickCylinderFrom: pnt1 radius: rad1 to: pnt2 radius: rad2.
self testDistance: true.
^ rval.
|
| frame: frame pickCylinderFrom: pnt1 to: pnt2 radius: rad
|
| rval |
self testDistance: false.
self currentFrame: frame.
rval _ self pickCylinderFrom: pnt1 to: pnt2 radius: rad.
self testDistance: true.
^ rval.
|
| frame: frame pickPlane: position normal: normal
|
| rval |
self testDistance: false.
self currentFrame: frame.
rval _ self pickPlane: position normal: normal.
self testDistance: true.
^ rval.
|
| frame: frame pickQuad: norm q1: p1 q2: p2 q3: p3 q4: p4
|
| rval |
self testDistance: false.
self currentFrame: frame.
rval _ self pickQuad: norm q1: p1 q2: p2 q3: p3 q4: p4.
self testDistance: true.
^ rval.
|
| frame: frame pickQuad: p1 q2: p2 q3: p3 q4: p4
|
| rval |
self testDistance: false.
self currentFrame: frame.
rval _ self pickQuad: p1 q2: p2 q3: p3 q4: p4.
self testDistance: true.
^ rval.
|
| frame: frame pickSphere: loc radiusSquared: rs
|
| rval |
self testDistance: false.
self currentFrame: frame.
rval _ self pickSphere: loc radiusSquared: rs.
self testDistance: true.
^ rval
|
| frame: frame pickTriangle: p1 tri: p2 tri: p3
|
| rval |
self testDistance: false.
self currentFrame: frame.
rval _ self pickTriangle: p1 tri: p2 tri: p3.
self testDistance: true.
^ rval.
|
| frame: frame pickTriangle: norm tri: p1 tri: p2 tri: p3
|
| rval |
self testDistance: false.
self currentFrame: frame.
rval _ self pickTriangle: norm tri: p1 tri: p2 tri: p3.
self testDistance: true.
^ rval.
|
| globalTransformUpdate
|
|trans|
downRay ifTrue:[
trans _ globalPosition.
globalTransform _ TDownRay clone.
globalTransform translation: trans.
].
|
| pick: bnds
|
| position |
bnds ifNil:[^ false ].
bnds frame ifNotNil:[
bnds frame isSolid ifTrue:[
self downRay ifFalse:[ self pointerPick: bnds.]
ifTrue:[
position _ (bnds globalPosition - self globalPosition).
position *= position.
(position x + position z < bnds radiusSquared) ifTrue:[
(self pickDownSphere: bnds) ifTrue:[
(self pointerPickFloor: bnds frame) ifTrue:[ ^ true. ].
].
].
].
].
].
^ false.
|
| pickBoundSphere: bnds
|
| position dp d gpAt |
gpAt _ self globalTransform column3.
position _ bnds globalPosition - self globalPosition.
dp _ position - ((gpAt dot: position)*gpAt).
d _ dp dot: dp.
d < bnds radiusSquared ifTrue:[
self sphereDistSquared: d.
^ true.].
^ false.
|
| pickCylinderFrom: pnt1 radius: rad1 to: pnt2 radius: rad2
|
| p1 p2 r1 r2 vn lv lx dx pv n nvn pd v ht cosCone cosPlane ip d1 d2 dd |
rad1 = rad2 ifTrue: [
"right cylinder"
^ self pickCylinderFrom: pnt1 to: pnt2 radius: rad1.
]
ifFalse: [ "cone"
" Figure out where the vertex is.
r1,r2 - top and bottom radii. r2 > r1
p1,p2 - top and bottom center points.
v - vertex of the cone
ht - true height of the cone
vn - vertex normal (up-down normal)
n - normal plane vector
nvn - vertex normal dot with plane normal
ip - actual intersection point"
rad2 < rad1 ifTrue:[
r1 _ rad2.
r2 _ rad1.
p1 _ pnt2 - self framePosition.
p2 _ pnt1 - self framePosition.]
ifFalse:[
r1 _ rad1.
r2 _ rad2.
p1 _ pnt1 - self framePosition.
p2 _ pnt2 - self framePosition.].
rad1 = 0 ifTrue:[
v _ p1.
ht _ (p1- p2) length.
vn _ (p2 - p1) normalized.
]
ifFalse:[
vn _ (p2 - p1) normalized.
pd _ (p1-p2)length.
ht _ (r2*pd)/(r2-r1).
v _ p2 - (vn * ht).
].
" Calculate the plane that cuts the cone. This is from Graphics Gems V pg 227."
n _ self framePointer row3 cross: v.
lv _ n length.
lv = 0 ifTrue:[^ false.] ifFalse:[ n _ n/lv.].
" We hit the vertex point."
(n dot: n)=0 ifTrue:[
ip _ v.]
ifFalse:[
" Test the plane to see if it intersects the cone."
cosCone _ ht/(((ht*ht) + (r2*r2))sqrt).
nvn _ n dot: vn.
cosPlane _ (1- (nvn * nvn)) sqrt.
cosCone > cosPlane ifTrue:[ ^ false. "no intersection."].
lx _ n dot: (p2-v). " distance of p2 from plane "
dx _ (lx*lx)/ht. " difference in height of closest point to p2"
lv _ (p2-v) - (n * lx). " actual location of closest point of p2 to plane "
pv _ v+ (lv * (ht/(ht-dx))). " location of this point on the plane defined by p2. "
dx_((r2*r2)-((pv-p2)squaredLength))sqrt. " distance from pv to r2 on circle at p2"
pv _ pv + (dx * ((n cross: vn) normalized)).
pv_(pv-v)normalized. "vector from v ON THE CYLINDER"
d1 _ self framePointer row3.
d2 _ pv.
dd _ d1 cross: d2.
dx _ dd dot: dd.
dx = 0 ifTrue:[^false].
dx _ ( (v cross: d2) dot: dd )/dx.
(self testSelectedDistance: dx abs) ifFalse:[^ false].
ip _ self framePosition + (d1*dx).
].
" Now that we (finally) have ip - the intersection of the pointer with the -infinite- cylinder, we need to test to see if it is between the top and bottom planes,"
((ip - pnt1) dot: vn)*((ip-pnt2) dot: vn) > 0 ifTrue:[
"the point is outside the bounds"
^ false.].
self selectedPoint: ip.
self selectedDistance: dx abs.
^ true.
].
|
| pickCylinderFrom: pnt1 to: pnt2 radius: rad
|
| p1 p2 pd d ps s pn pa dd ip |
" p1, p2 axis points of the cylinder relative to the framePosition.
pd - the cutting plane. The ray is on this plane, which is parallel to the cylinder axis.
d - distance of plane from cylinder axis.
s - distance from d point (p1 + d*p) to cylinder surface.
ps - vector on plane, perpendicular to axis.
pn - normal vector.
ip - selected point"
p1 _ pnt1 - self framePosition.
p2 _ pnt2 - self framePosition.
" Calculate the cutting plane between the ray and parallel to the axis of the cylinder. "
pd _ (self framePointer row3 cross: (p1-p2)).
" Test if we ray is parallel to axis."
(pd dot: pd)=0 ifTrue:[ ^ false.].
pd normalize.
" Test to see if the plane (and hence the ray) distance is less than the rad distance to the center of the cylinder."
d _ pd dot: p1.
d abs >rad ifTrue:[ ^ false.].
" Calculate the perpendicular normal to the axis on the plane."
s _ ((rad*rad)-(d*d))sqrt.
ps _ ((p1-p2) cross: pd) normalized.
" Calculate the normal on the cylinder at the intersection point."
pn _ ((s*ps)-(d*pd)).
" Now we just calculate the intersections between two lines."
p1 _ p1 + pn.
p2 _ p2 + pn.
pn normalize.
pa _ (p2-p1) normalized.
" We know that the two lines can't be parallel because we tested earlier."
dd _ (self framePointer row3) cross: pa.
s_ (((p1 cross: pa) dot: dd)/(dd dot: dd)).
ip _ framePointer row3 * s.
" Test if we are between the two ends of the cylinder."
((ip-p1) dot: pa)*((ip-p2) dot: pa)>0 ifTrue:[
"The point is outside the bounds"
^ false.].
s _ s abs.
(self testSelectedDistance: s) ifFalse:[^false].
self selectedDistance: s.
self selectedPoint: (ip + self framePosition).
self selectedNormal: pn.
^ true.
|
| pickDownSphere: bnds
|
| position |
position _ bnds globalPosition - self globalPosition.
^ (((position x *position x) + (position z*position z)) < bnds radiusSquared).
|
| pickFrame: framePtr tri: p1 tri: p2 tri: p3
|
" This method works by using the orthogonal picking matrix as orthogonal planes going through the origin at 'origin'. The points of the triangle are tested to the two planes orthoganal to the direction of picking. If they are on either side of both planes, then there is a very high probability that our picking ray interesects the triangle, and we do the actual calculation of the intersection point. Note the comments below. I use a vertical bar to indicate which side of the plane a point is on. ***** p1 p2 | ***** means that p1 and p2 are on the same side,
***** p1 | p2 ***** indicates that they are on opposite sides. p1 is always on the left side, because it is the first one I test. This really just means - same side as p1 - no meaning other than that.
This can be optimized for tri-strips, tri-fans, and even full face based meshes. When I have the time... "
| d1 d2 d3 pp1 pp2 dd1 dd2 xPlane yPlane |
xPlane _ framePtr row1.
d1 _ xPlane dot: p1.
d2 _ xPlane dot: p2.
d3 _ xPlane dot: p3.
dd1 _ d1*d2.
dd2 _ d1*d3.
" test if all points are on the same side of the x plane."
dd1 < 0 ifFalse:[ "***** p1 p2 | *****"
dd2 < 0 ifFalse:[ ^ false "***** p1 p2 p3 | *****" ]
ifTrue:[ "***** p1 p2 | p3 *****"
pp1 _ p1 + ((p3-p1) * d1/(d1-d3)).
pp2 _ p2 + ((p3-p2) * d2/(d2-d3)).]]
ifTrue:[ "***** p1 | p2 *****"
dd2 < 0 ifTrue:[ "***** p1 | p2 p3 *****"
pp1 _ p1 + ((p2-p1) * d1/(d1-d2)).
pp2 _ p1 + ((p3-p1) * d1/(d1-d3)).]
ifFalse:[ "***** p1 p3 | p2 *****"
pp1 _ p1 + ((p2-p1) * d1/(d1-d2)).
pp2 _ p3 + ((p2-p3) * d3/(d3-d2)).].].
" At this point, the triangle is intersected by the x plane and we know where. If both points are on the same side of the y plane, we are done. "
yPlane _ framePtr row2.
d1 _ yPlane dot: pp1.
d2 _ yPlane dot: pp2.
" test if both points are on the same side of the y plane."
d1 * d2 < 0 ifFalse:[
^ false ].
pp1 _ pp1 + ((pp2-pp1) * d1/ (d1-d2)).
d1 _ pp1 squaredLength.
(self testSelectedDistanceSquared: d1) ifTrue:
[
self selectedDistanceSquared: d1.
self selectedPoint: pp1.
^ true.
].
^ false.
|
| pickLocalBoundSphere: bnds
|
| lpAt position dp dd |
lpAt _ self framePointer row3.
position _ bnds localPosition - self framePosition.
" project center of sphere onto the ray"
dp _ position - (lpAt * (lpAt dot: position)).
dd _ dp dot: dp.
" distance of ray to center - if greater than radius, return false, otherwise, the ray intersects."
^ (dd < bnds radiusSquared)
|
| pickLocalNorm: norm
|
^ (self framePointer row3 dot: norm) < 0.
|
| pickPlane: position normal: normal
|
| div sp d |
div _ normal dot: self framePointer row3.
div = 0 ifTrue:[ ^ false ].
d _ ((position-self framePosition) dot: normal)/div.
sp_ self framePosition + (self framePointer row3 * d).
(self testSelectedDistance: d) ifFalse:[^false].
self selectedDistance: d.
self selectedPoint: sp.
self selectedNormal: normal.
^ true.
|
| pickQuad: norm q1: p1 q2: p2 q3: p3 q4: p4
|
| pointAt po1 po2 po3 po4 d1 d2 d3 d4 |
pointAt _ self framePointer row3.
norm ifNotNil:[
((pointAt dot: norm) < 0) ifTrue:[^ false ].].
po1 _ self framePosition - p1.
po2 _ self framePosition - p2.
po3 _ self framePosition - p3.
po4 _ self framePosition - p4.
d1 _ pointAt dot: po1.
d2 _ pointAt dot: po2.
d3 _ pointAt dot: po3.
d4 _ pointAt dot: po4.
" Are any of the points actually in front of the pointer?"
d1 < 0 ifTrue:[
d2 < 0 ifTrue:[
d3 < 0 ifTrue:[
d4 < 0 ifTrue:[^ false.]]]].
" (norm dot: po1) > 0 ifTrue:[ ^ false.]."
" If all of the points are further than the current selected distance, then we are done."
(self testSelectedDistance: d1) ifFalse:[
(self testSelectedDistance: d2) ifFalse:[
(self testSelectedDistance: d3) ifFalse:[
(self testSelectedDistance: d4) ifFalse:[^ false]]]].
" At some point, I need to write a special pickFrame for quads, because I calculate one of the vertices twice this way. In Squeak, every cycle counts!."
(self pickFrame: self framePointer tri: po1 tri: po2 tri: po3) ifFalse:[
(self pickFrame: self framePointer tri: po3 tri: po4 tri: po1) ifFalse:[^ false]].
self selectedPoint: (self framePosition - self selectedPoint).
self selectedNormal: norm.
^ true.
|
| pickQuad: p1 q2: p2 q3: p3 q4: p4
|
^ self pickQuad: nil q1: p1 q2: p2 q3: p3 q4: p4.
|
| pickSphere: loc radiusSquared: rs
|
| p dp d dd c |
" This method is used to find the surface of the actual sphere, not just determine if the pointer intersects it."
rs = 0.0 ifTrue:[^ false.].
p _ loc - self framePosition.
" project center of sphere onto the ray"
dp _ self framePointer row3 * (self framePointer row3 dot: p).
dd _ dp - p.
" distance of ray to center - if greater than radius, exit"
d _ dd dot: dd.
d > rs ifTrue:[^false.].
" calculate the point on the sphere"
c _ (rs-d)sqrt.
dp _ dp + (c * self framePointer row3).
d _ dp dot: dp.
" if it is closer than the current selected object, save and calc norm."
(self testSelectedDistanceSquared: d) ifTrue: [
self selectedDistanceSquared: d.
self selectedPoint: (self framePosition + dp).
self selectedNormal: (self selectedPoint - loc) normalized.
^ true.
].
^ false.
|
| pickTriangle: p1 tri: p2 tri: p3
|
^ self pickTriangle: nil tri: p1 tri: p2 tri: p3.
|
| pickTriangle: norm tri: p1 tri: p2 tri: p3
|
| pointAt po1 po2 po3 d1 d2 d3 |
pointAt _ self framePointer row3.
norm ifNotNil:[
((pointAt dot: norm) < 0) ifTrue:[^ false ].].
po1 _ self framePosition - p1.
po2 _ self framePosition - p2.
po3 _ self framePosition - p3.
" Are any of the points actually in front of the pointer?"
d1 _ pointAt dot: po1.
d2 _ pointAt dot: po2.
d3 _ pointAt dot: po3.
d1 < 0 ifTrue:[
d2< 0 ifTrue:[
d3 < 0 ifTrue:[^ false.]]].
" If all of the points are further than the current selected distance, then we are done."
(self testSelectedDistance: d1) ifFalse:[
(self testSelectedDistance: d2) ifFalse:[
(self testSelectedDistance: d3) ifFalse:[^ false]]].
(self pickFrame: self framePointer tri: po1 tri: po2 tri: po3) ifTrue: [
self selectedPoint: (self framePosition - self selectedPoint).
self selectedNormal: norm.
self selectedTriangle: (Array with: p1 with: p2 with: p3).
^ true.].
^ false.
|
| pickTriangles: vertices list: triList
|
"Pick an indexed triangle array"
| pointAt po1 po2 po3 d1 d2 d3 fp index v0 v1 v2 |
fp := self framePosition.
pointAt _ self framePointer row3.
index := 0.
[index < triList size] whileTrue:[
v0 := vertices at: (triList at: (index := index+1))+1.
v1 := vertices at: (triList at: (index := index+1))+1.
v2 := vertices at: (triList at: (index := index+1))+1.
po1 := fp - v0.
po2 := fp - v1.
po3 := fp - v2.
"Are any of the points actually in front of the pointer?"
d1 _ pointAt dot: po1.
d2 _ pointAt dot: po2.
d3 _ pointAt dot: po3.
(d1 >= 0.0 or:[d2 >= 0.0 or:[d3 >= 0.0]]) ifTrue:[
" If all of the points are further than the current selected distance, then we are done."
((self testSelectedDistance: d1) or:[
(self testSelectedDistance: d2) or:[
(self testSelectedDistance: d3)]]) ifTrue:[
(self pickFrame: self framePointer tri: po1 tri: po2 tri: po3) ifTrue: [
self selectedPoint: (self framePosition - self selectedPoint).
self selectedNormal: nil.
self selectedTriangle: (Array with: v0 with: v1 with: v2).
^ true.
].
].
].
].
^false
|
| pointerPick: bnds
|
| position frame gpAt dp d |
doSelect ifTrue:[
bnds ifNil:[^ false.].
bnds frame objectOwner isComponent ifTrue:[
position _ bnds globalPosition - self globalPosition.
self selectedDistance > ((position length - bnds radius) * Croquet world frameScale) ifTrue:[
gpAt _ self globalTransform column3.
dp _ position - ((gpAt dot: position)*gpAt).
d _ dp dot: dp.
d < bnds radiusSquared ifFalse:[ ^ false ].
self sphereDistSquared: d.
frame _ bnds frame.
self currentFrame: frame.
(frame pick: self) ifTrue:[
self selectedPoint ifNil:[self selectedPoint: B3DVector3 new.].
self selectedFrame: frame.
self selectedParent: frame parent.
self selectedFramePosition: self framePosition.
self selectedObject: frame objectOwner.
self selectedParentTransform: self parent globalTransform.
^ true.
].
].
].
].
^ false.
|
| pointerPickFloor: frame
|
self currentFrame: frame.
(frame pickFloor: self) ifTrue:[
self selectedFrame: frame.
self selectedParent: frame parent.
self selectedFramePosition: self framePosition.
self selectedObject: frame objectOwner.
^ true.
].
^ false.
|
| pointerPickTree: frame
|
frame visible ifTrue:[(self pointerPick: frame boundSphere) ifTrue:[^ true].].
frame frameChildren ifNotNil:[
frame frameChildren do:[ :fc | (self pointerPickTree: fc) ifTrue:[^ true.].].].
^ false.
|
| portalTest: frame at: at
|
| rval saveFP up side |
saveFP _ framePointer.
rval _ false.
up _ B3DVector3 x: 0.0 y:1.0 z:0.0.
side _ (up cross: at) normalized.
up _ (at cross: side) normalized.
framePointer _ B3DMatrix4x4 identity.
framePointer at: 1 at: 1 put: side x.
framePointer at: 1 at: 2 put: side y.
framePointer at: 1 at: 3 put: side z.
framePointer at: 2 at: 1 put: up x.
framePointer at: 2 at: 2 put: up y.
framePointer at: 2 at: 3 put: up z.
framePointer at: 3 at: 1 put: at x.
framePointer at: 3 at: 2 put: at y.
framePointer at: 3 at: 3 put: at z.
self testDistance: false.
(frame pick: self) ifTrue:[ rval _ true.].
self testDistance: true.
framePointer _ saveFP.
^ rval.
|