listing nearest entities to the camera

Blitz3D Forums/Blitz3D Beginners Area/listing nearest entities to the camera

I have 100 entities and I want to display a list ('Text' is fine for now) of the top 10 entities closest to the camera. My entities are contained in a Type and have an 'ID' field that is set during creation (For i = 1 to 100, entity\ID = i, etc). Not sure if that is the most efficient way to sort through them... but regardless I can't get my head around this. The list needs to be updated according to where the camera is at all times.

I would create a type to sort the distances. This type should be able to hold a distance, and some reference to the entity.

Each frame update/main loop, clear the list that contains the distances.
Loop through all entities, and add their distance to the list.

But before adding a new distance to the list, first check at what point in the list it should be inserted. Loop through the list. If one of the distances in the list is bigger than the new one, insert the new one right before the one in the list, and leave the loop.

If the list contains no distances, or all distances in the list are smaller than the new distance, the new distance should be placed at the end of the list.

Thanks Warner! This works but I am having trouble listing each entity on a new line... the text is all on the same line on the Y axis.

Info$="This door is locked"+Chr(13) ;The text message
Info$=Info$+"You need the Green Key" ;Second line of text

using the +Chr(13) will make another line of text...hope this helps...

Well, I think Chr$(13) would only work with text files. It could also be Chr$(13)+Chr$(10) or even Chr$(0), can't exactly remember. I usually try them all out, and then forget again. Maybe I don't understand the problem correctly, but you are printing everything to the screen after the sorting is completed, right ? And -just to eliminate that option- you are using the 'y' parameter of Text ?

Here is my code. What a horrible mess eh? Thanks everyone for the help.


Type listitem
    Field name$
    Field dist#
    Field id
End Type

Type enemy
    Field mesh
    Field name$
    Field id
End Type

For i = 1 To 50
    e.enemy = New enemy
    e\mesh = CreateCube()
    e\id = i
    PositionEntity e\mesh,Rnd(-5000,5000),Rnd(-100,100),Rnd(-5000,5000)
    e\name = "Enemy"
Next

Repeat
        ......

	For e.enemy = each enemy
		If EntityDistance(camera, e\mesh) < 1000
			this.listitem = New listitem
			this\name$ = e\name
			this\dist = EntityDistance (camera,e\mesh)
			this\id = e\id ;
			addtolist(this.listitem)
			Delete this
		EndIf
	Next

	Flip

Until KeyHit (1)

End

Function addtolist(this.listitem)
	
	Text 10,10,this\name+" - "+this\id+" - "+this\dist+Chr$(13)
	;Text3D(font2,-500,0,this\name+" - "+this\id+" - "+this\dist,0)
	
End Function



Here is the code I wrote to try things out, hopefully it helps:
Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()

cam = CreateCamera()
CameraZoom cam, 0.5

Type entity
	Field name$
	Field mesh
End Type

Type distance
	Field e.entity
	Field dist#
End Type

For i = 1 To 100
	e.entity = New entity
	e\name$ = "cube" + i
	e\mesh = CreateCube()
	PositionEntity e\mesh, Rnd(-50, 50), Rnd(-50, 50), Rnd(-50, 50)
Next


Repeat

	MoveEntity cam, 0, 0, KeyDown(200) - KeyDown(208)
	MoveEntity cam, 0, 0, KeyDown(17) - KeyDown(31)
	
	pt# = pt + MouseYSpeed() * 0.1
	yw# = yw - MouseXSpeed() * 0.1
	RotateEntity cam, pt, yw, 0
	MoveMouse 400, 300
	
	;update distances
	Delete Each distance
	For e.entity = Each entity
		newdist# = EntityDistance(e\mesh, cam)
		test = False
		For d.distance = Each distance
			If d\dist > newdist Then 
				newd.distance = New distance
				newd\dist# = newdist#
				newd\e = e
				Insert newd Before d
				test = True
				Exit
			End If
		Next
		If Not(test) Then
			newd.distance = New distance
			newd\dist# = newdist#		
			newd\e = e
		End If
	Next

	RenderWorld

	;print list	
	d.distance = First distance
	For i = 1 To 10
			If d <> Null Then 
			Text 0, i * 20, d\e\name
			
			CameraProject(cam, EntityX(d\e\mesh), EntityY(d\e\mesh), EntityZ(d\e\mesh))
			Text ProjectedX(), ProjectedY(), d\e\name
			
			d = After d
		End If
	Next
	
	Flip
	
Until KeyHit(1)


Warner it works flawlessly and taught me a great deal. Thank you so much for taking the time to suss that out.