Bounding Box Wire

Blitz3D Forums/Blitz3D Programming/Bounding Box Wire

Naughty Alien(Posted 2008) [#1]
..hey guys, im looking for function for creating bounding box (lined one) around any object/entity, according to its size...anyone did this?


Ross C(Posted 2008) [#2]
A 3d box or a 2d box?


Naughty Alien(Posted 2008) [#3]
3D box..i do have some code but it seems that its rendering expensive once I have plenty of objects around..


Ross C(Posted 2008) [#4]
Create a cube. Use fitmesh on it, to fit to the entities dimensions. Then, texture the cube, with a masked texture, only having the outline drawn.


John Blackledge(Posted 2008) [#5]
I've had problems (misunderstandings) with fitmesh.
Can you knock up a simple example?


Stevie G(Posted 2008) [#6]
@ John,

Bare in mind that the first 3 params are a reference point ( I always use bottom/left/rear ) , the last 3 are the scale. So to center a mesh and retain the size do ..

Width# = meshwidth( mesh )
height# = meshheight( mesh )
depth# = meshdepth( mesh )
fitmesh mesh, -Width*.5, -Height*.5, -Depth*.5, Width, Height, Depth.

This clearly doesn't work when either width, height or depth = 0.

Stevie


Uncle(Posted 2008) [#7]
Here's a small demo.

Graphics3D 800,600,0,2
Global camera=CreateCamera()
CameraZoom camera,1.6
MoveEntity camera,0,0,-90
WireFrame True

; make the bounding box cube...
Global highlightcube=CreateCube()
EntityFX highlightcube,1
EntityColor  highlightcube,0,255,0
Global mesh

; make some objects to play with...
Type obj
	Field entity
End Type

Function makeObjects()
	For x=1 To 10
		objs.obj=New obj
		If Rand(1,2)=1 Then
			objs\entity=CreateCone()
		Else
			objs\entity=CreateSphere()
		EndIf
		EntityFX objs\entity,1
		EntityPickMode objs\entity,2
		PositionEntity objs\entity,Rand(-50,50),Rand(-50,50),Rand(50,50)
		RotateEntity objs\entity,Rand(360),Rand(360),Rand(360)
		EntityColor objs\entity,Rand(0,1)*255,Rand(0,1)*255,255
		; scale the mesh... its important to use scale mesh otherwise you will have problems with the mesh dimension commands
		scale#=Rnd(1,10)
		ScaleMesh objs\entity,scale,scale,scale
	Next
End Function

; function to check if the mouse is over and object and if so move the bounding box to it and resize it...
Function checkObjects()
	CameraPick camera,MouseX(),MouseY()
	If PickedEntity()<>0 Then
		mesh=PickedEntity()
	EndIf
	If mesh<>0 Then
		ShowEntity highlightcube
		Width# = MeshWidth( mesh )
		height# = MeshHeight( mesh )
		depth# = MeshDepth( mesh )
		FitMesh highlightcube, -Width*.5, -Height*.5, -Depth*.5, Width, Height, Depth
		RotateEntity highlightcube,EntityPitch(mesh,1),EntityYaw(mesh,1),EntityRoll(mesh,1)		
		PositionEntity highlightcube,EntityX(mesh,1),EntityY(mesh,1),EntityZ(mesh,1)
	Else
		HideEntity highlightcube
	EndIf
End Function

; the main loop...
makeObjects()
While Not KeyDown(1)
	; turn the objects
	For objs.obj=Each obj
		TurnEntity objs\entity,0.2,0.02,0.2
	Next
	; check for the mouse over and move the bounding box
	checkObjects()
	RenderWorld
	Flip 
Wend


I would also suggest looking at the Draw3d library that is floating around it. It has a nice line draw function, which you could use to draw a nice bounding box.


Vertigo(Posted 2008) [#8]
Adding to the above posted code...


WireFrame False                       ; Turn false to see effect.

; make the bounding box cube...
Global highlightcube=CreateCube()
EntityFX highlightcube,1 + 16         ; Add double-sided.
EntityColor  highlightcube,0,255,0

bound_texture = LoadTexture("bounding.png", 4 + 256) ; with masking and no mipmapping
EntityTexture highlightcube, bound_texture



For the texture simply make like a 256x256 color 0,0,0 black image. Then draw a 3 or so pixel border around the image in the color you want your highlight to be.


John Blackledge(Posted 2008) [#9]
Very nice, Uncle and Vertigo.
Super-efficient.

Before, I was getting every vertex position, left, top, right, bottom-most, then drawing a 2D box to the screen - very inefficient.

Thanks.


Ross C(Posted 2008) [#10]
I had a problem with the eshdepth/height/width. If you use ScaleEntity, you will need to loop through all the vertex positions to get to proper depth/height and width of the mesh. SO, avoid using scaleentity if you can. Else your end up looping through all the vertices.


Stevie G(Posted 2008) [#11]
No need to loop through vertices .. this should work ..


global G_Sx#, G_Sy#, G_Sz#

Function GetScale( Mesh )

   ;take a copy and reset it's rotation 
   tmp = copyentity( mesh )
   rotateentity tmp,0,0,0

   tformvector 1,1,1, tmp, 0
   G_Sx = tformedx() * meshwidth( mesh )
   G_Sy = tformedy() * meshheight( mesh )
   G_Sz = tformedz() * meshdepth( mesh )

   freeentity tmp

End function


You could probably also use the getmatelement commands to get quicker access.


Ross C(Posted 2008) [#12]
Ah, nice solution!


Stevie G(Posted 2008) [#13]
IMO the tform commands are the most useful in Blitz - I definately couldn't like without them :)