Bounding Box Wire

Blitz3D Forums/Blitz3D Programming/Bounding Box Wire

..hey guys, im looking for function for creating bounding box (lined one) around any object/entity, according to its size...anyone did this?

A 3d box or a 2d box?

3D box..i do have some code but it seems that its rendering expensive once I have plenty of objects around..

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.

I've had problems (misunderstandings) with fitmesh.
Can you knock up a simple example?

@ 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

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.

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.

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.

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.

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.

Ah, nice solution!

IMO the tform commands are the most useful in Blitz - I definately couldn't like without them :)