| accessing |
| atRandom: segments
|
| dm |
dm _ (maxCorner - minCorner)/segments.
^ B3DVector3 x:(dm x * (segments atRandom) + minCorner x)
y:(dm y * (segments atRandom) + minCorner y)
z:(dm z * (segments atRandom) + minCorner z).
|
| center
|
^ (minCorner + maxCorner)/2.0.
|
| centerX
|
^ (minCorner x + maxCorner x)/2.0.
|
| centerY
|
^ (minCorner y + maxCorner y)/2.0.
|
| centerZ
|
^ (minCorner z + maxCorner z)/2.0.
|
| corner
|
^maxCorner
|
| cornerVertices
|
"Answer all the vertices defining the corners of this block"
| out |
out := (WriteStream on: (Array new: 8)).
self cornerVerticesDo:[:vtx| out nextPut: vtx].
^out contents
|
| cornerVerticesDo: aBlock
|
"Evaluate aBlock with all the vertices defining the corners of this block"
| min max |
min := minCorner.
max := maxCorner.
aBlock value: min x @ min y @ min z.
aBlock value: min x @ min y @ max z.
aBlock value: min x @ max y @ min z.
aBlock value: min x @ max y @ max z.
aBlock value: max x @ min y @ min z.
aBlock value: max x @ min y @ max z.
aBlock value: max x @ max y @ min z.
aBlock value: max x @ max y @ max z.
|
| diagonal
|
^ (maxCorner - minCorner)length.
|
| extent
|
^ maxCorner - minCorner.
|
| extentMax
|
^ (maxCorner - minCorner) max.
|
| extentMin
|
^ (maxCorner - minCorner) min.
|
| extentX
|
^ maxCorner x - minCorner x.
|
| extentY
|
^ maxCorner y - minCorner y.
|
| extentZ
|
^ maxCorner z - minCorner z.
|
| growVertex: v
|
minCorner _ minCorner min: v.
maxCorner _ maxCorner max: v.
|
| max
|
^ maxCorner.
|
| max: mx
|
maxCorner _ mx.
|
| merge: aBox
|
"Answer a Box that contains both the receiver and aBox."
^TBox
origin: (self origin min: aBox origin)
corner: (self corner max: aBox corner)
|
| min
|
^ minCorner.
|
| min: mn
|
minCorner _ mn.
|
| origin
|
^minCorner
|
| radius
|
^ self diagonal/2.0.
|
| scale: scale
|
minCorner _ minCorner * scale.
maxCorner _ maxCorner * scale.
|
| splitXMax
|
| corner |
corner _ self min copy.
corner x: self centerX.
^ TBox min: corner max: self max copy.
|
| splitXMin
|
| corner |
corner _ self max copy.
corner x: self centerX.
^ TBox min: self min copy max: corner.
|
| splitYMax
|
| corner |
corner _ self min copy.
corner y: self centerY.
^ TBox min: corner max: self max copy.
|
| splitYMin
|
| corner |
corner _ self max copy.
corner y: self centerY.
^ TBox min: self min copy max: corner.
|
| splitZMax
|
| corner |
corner _ self min copy.
corner z: self centerZ.
^ TBox min: corner max: self max copy.
|
| splitZMin
|
| corner |
corner _ self max copy.
corner z: self centerZ.
^ TBox min: self min copy max: corner.
|
| transformedBy: aTransform
|
"Answer a box transformed by the given transformation"
| aVertex min max |
min := max := nil.
self cornerVerticesDo:[:vtx|
aVertex := aTransform localPointToGlobal: vtx.
min ifNil:[
min := max := aVertex.
] ifNotNil:[
min := min min: aVertex.
max := max max: aVertex.
].
].
^TBox origin: min corner: max
|
| translatedBy: delta
|
"Answer a box transformed by the given transformation"
^TBox origin: minCorner + delta corner: maxCorner + delta
|
| comparing |
| axisTestXv1: v1 v2: v2 a: a b: b fa: fa fb: fb
|
| p0 p1 min max rad |
p0 _ (a * v1 y) - (b * v1 z).
p1 _ (a * v2 y) - (b * v2 z).
p0 < p1 ifTrue:[min _ p0. max _ p1.] ifFalse:[min _ p1. max _ p0.].
rad _ ((fa * self extentY) + (fb * self extentZ))/2.0.
(min > rad or:[max < (rad negated)]) ifTrue:[^ false.].
^ true.
|
| axisTestYv1: v1 v2: v2 a: a b: b fa: fa fb: fb
|
| p0 p1 min max rad |
p0 _ (b * v1 z) - (a * v1 x).
p1 _ (b * v2 z) - (a * v2 x).
p0 < p1 ifTrue:[min _ p0. max _ p1.] ifFalse:[min _ p1. max _ p0.].
rad _ ((fa * self extentX) + (fb * self extentZ))/2.0.
(min > rad or:[max < (rad negated)]) ifTrue:[^ false.].
^ true.
|
| axisTestZv1: v1 v2: v2 a: a b: b fa: fa fb: fb
|
| p0 p1 min max rad |
p0 _ (a * v1 x) - (b * v1 y).
p1 _ (a * v2 x) - (b * v2 y).
p0 < p1 ifTrue:[min _ p0. max _ p1.] ifFalse:[min _ p1. max _ p0.].
rad _ ((fa * self extentX) + (fb * self extentY))/2.0.
(min > rad or:[max < (rad negated)]) ifTrue:[^ false.].
^ true.
|
| intersectBox: bx
|
| mn mx |
mn _ bx min max: self min.
mx _ bx max min: self max.
^ TBox min: mn max: mx.
|
| intersectT1: t1 T2: t2 T3: t3
|
| v1 v2 v3 e1 e2 e3 a1 a2 a3 center tNormal d vmin vmax |
" This method is based upon:
Fast 3D Triangle-Box Overlap Testing
Tomas Akenine-Moller
March 2001, updated June 2001.
The order of this code is somewhat different from that presented in the example C source provided with the paper.
Though this is considered to be the fastest test in the graphics literature, I think that there is a better approach by attempting to construct a seperating plane between the two objects. Since I am not currently using it for real-time work, I won't worry about it."
" First, the naive test - is the triangle all on one side of a half-plane?"
(t1 x < minCorner x and:[ t2 x < minCorner x and:[ t3 x < minCorner x]])
ifTrue:[ ^ false. ].
(t1 x > maxCorner x and:[. t2 x > maxCorner x and:[ t3 x > maxCorner x]])
ifTrue:[ ^ false. ].
(t1 y < minCorner y and:[ t2 y < minCorner y and:[ t3 y < minCorner y]])
ifTrue:[^ false. ].
(t1 y > maxCorner y and:[ t2 y > maxCorner y and:[ t3 y > maxCorner y]])
ifTrue:[ ^ false. ].
(t1 z < minCorner z and:[ t2 z < minCorner z and:[ t3 z < minCorner z]])
ifTrue:[ ^ false. ].
(t1 z > maxCorner z and:[ t2 z > maxCorner z and:[ t3 z > maxCorner z]])
ifTrue:[ ^ false. ].
" Second, the cross product (edge from tri, (x y z) direction. "
center _ self center.
v1 _ t1 - center.
v2 _ t2 - center.
v3 _ t3 - center.
e1 _ t2 - t1.
a1 _ e1 abs.
(self axisTestXv1:v1 v2:v3 a: e1 z b: e1 y fa: a1 z fb: a1 y) ifFalse:[^ false.].
(self axisTestYv1:v1 v2:v3 a: e1 z b: e1 x fa: a1 z fb: a1 x) ifFalse:[^ false.].
(self axisTestZv1:v2 v2:v3 a: e1 y b: e1 x fa: a1 y fb: a1 x) ifFalse:[^ false.].
e2 _ t3 - t2.
a2 _ e2 abs.
(self axisTestXv1:v1 v2:v3 a: e2 z b: e2 y fa: a2 z fb: a2 y) ifFalse:[^ false.].
(self axisTestYv1:v1 v2:v3 a: e2 z b: e2 x fa: a2 z fb: a2 x) ifFalse:[^ false.].
(self axisTestZv1: v1 v2:v2 a:e2 y b: e2 x fa: a2 y fb: a2 x) ifFalse:[^ false.].
e3 _ t1 - t3.
a3 _ e3 abs.
(self axisTestXv1:v1 v2:v2 a: e3 z b: e3 y fa: a3 z fb: a3 y) ifFalse:[^ false.].
(self axisTestYv1:v1 v2:v2 a: e3 z b: e3 x fa: a3 z fb: a3 x) ifFalse:[^ false.].
(self axisTestZv1:v2 v2:v3 a: e3 y b: e3 x fa: a3 y fb: a3 x) ifFalse:[^ false.].
" Third, test if the box intersects the plane of the triangle."
tNormal _ e1 cross: e2.
d _ (tNormal dot: v1)negated.
vmin _ B3DVector3 new.
vmax _ B3DVector3 new.
tNormal x>0.0 ifTrue:[
vmin x: self extentX negated.
vmax x: self extentX.] ifFalse:[
vmin x: self extentX.
vmax x: self extentX negated.].
tNormal y>0.0 ifTrue:[
vmin y: self extentY negated.
vmax y: self extentY.] ifFalse:[
vmin y: self extentY.
vmax y: self extentY negated.].
tNormal z>0.0 ifTrue:[
vmin z: self extentZ negated.
vmax z: self extentZ.] ifFalse:[
vmin z: self extentZ.
vmax z: self extentZ negated.].
(tNormal dot: vmin)+d >0.0 ifTrue:[^ false. ].
(tNormal dot: vmax)+d >= 0.0 ifTrue:[^ true.].
^ true.
|
| pointInBox: v
|
v x < minCorner x ifTrue:[^ false.].
v x > maxCorner x ifTrue:[^ false.].
v y < minCorner y ifTrue:[^ false.].
v y > maxCorner y ifTrue:[^ false.].
v z < minCorner z ifTrue:[^ false.].
v z > maxCorner z ifTrue:[^ false. ].
^ true.
|
| pointOverBox: v
|
v x < minCorner x ifTrue:[^ false.].
v x > maxCorner x ifTrue:[^ false.].
" v y < minCorner y ifTrue:[^ false.].
v y > maxCorner y ifTrue:[^ false.]."
v z < minCorner z ifTrue:[^ false.].
v z > maxCorner z ifTrue:[^ false. ].
^ true.
|
| unionBox: bx
|
| mn mx |
mn _ bx min min: self min.
mx _ bx max max: self max.
^ TBox min: mn max: mx.
|
| unionSphere: position radius: radius
|
| mn mx |
mn _ (position - radius) min: self min.
mx _ (position + radius) max: self max.
^ TBox min: mn max: mx.
|