[bb] Point Inside Oriented Bounding Box by sswift [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:39

Previous topic - Next topic

BlitzBot

Title : Point Inside Oriented Bounding Box
Author : sswift
Posted : 1+ years ago

Description : This function does an oriented bounding box check.  

An oriented bounding box is a box which is rotated with an entity and aligned with it's axes, and not with the axes of the world.

An oriented bounding box usually will be smaller and fit an entity more snugly than an axis aligned bounding box will, and thus the check is more accurate.

Also, since an oriented bounding box is in object space, the locations of the object's vertices realtive to the box never change, so the box is a fixed size.  That means you can precalculate the shape of the box for every object in your game.  

Calcualting the shape of the box is the most costly part of the algorithm, and this makes an oriented bounding box check better than an axis aligned bounding box check for two reasons... one is the afformentioned increased accuracy, and the other is that you can precalculate the size and shape of the box to make the check really fast.  You can't do that with an axis aligned bounding box check because the box's size and shape changes as the object rotates in space.


Code :
Code (blitzbasic) Select
; -------------------------------------------------------------------------------------------------------------------
; This function returns true if a point is inside an object's oriented bounding box, and false if it is not.
; -------------------------------------------------------------------------------------------------------------------
Function Point_Inside_Oriented_Bounding_Box(ThisEntity, Px#, Px#, Pz#)


; Transform point from global space to object space.
TFormPoint Px#, Py#, Pz#, 0, ThisEntity
Px# = TFormedX#()
Py# = TFormedY#()
Pz# = TFormedZ#()


; Calculate the bounding box (in object space) for this object.
; You can precalculate this for every object in your game for a huge speed increase!
Surfaces = CountSurfaces(ThisEntity)

For LOOP_Surface = 1 To Surfaces

Surface_Handle = GetSurface(ThisEntity, LOOP_Surface)

Verts = CountVertices(Surface_Handle) - 1
For LOOP_Verts = 0 To Verts-1

Vx# = VertexX#(Surface_Handle, LOOP_Verts)
Vy# = VertexY#(Surface_Handle, LOOP_Verts)
Vz# = VertexZ#(Surface_Handle, LOOP_Verts)

If (Vx# > Max_X#) Then Max_X# = Vx#
If (Vy# > Max_Y#) Then Max_Y# = Vy#
If (Vz# > Max_Z#) Then Max_Z# = Vz#

If (Vx# < Min_X#) Then Min_X# = Vx#
If (Vy# < Min_Y#) Then Min_Y# = Vy#
If (Vz# < Min_Z#) Then Min_Z# = Vz#

Next

Next


; Determine if the point (in object space) is inside the bounding box (in object space).
If (Px# > Min_X#) And (Px# < Max_X#) And (Py# > Min_Y#) And (Py# < Max_Y#) And (Pz# > Min_Z#) And (Pz# < Max_Z#)
Return True
Else
Return False
EndIf


End Function


Comments :


Wayne(Posted 1+ years ago)

 How did the above code ever work with two Px# references ?Now I have to test it.8)Function Point_Inside_Oriented_Bounding_Box(ThisEntity, Px#, Px#, Pz#)should be:Function Point_Inside_Oriented_Bounding_Box(ThisEntity, Px#, Py#, Pz#)