EntityPickMode eating up my ram

BlitzMax Forums/MiniB3D Module/EntityPickMode eating up my ram

Digital Anime(Posted 2009) [#1]
For some reason the EntityPickMode I used in my TPlanet type is causing troubles as soon as I spawn a Planet (sphere with texture) by clicking with the mouse somewhere in the window.

Is there a good way to solve this?

Code is still a little messy and uses both MiniB3d and MaxGui and you need to ad a Planet.png as texture for standard planet.

The idea is to create a editor for making levels for a spaceshooter with lot's of freedom, but I need to solve this first before I can continue.

Strict

Import sidesign.minib3d

Global w:Int = 800		'width
Global h:Int = 600		'heigth
Global b:Int = 32		'bit
Global f:Int = 60		'frequency

Graphics3D w, h, b, 2, f

ClearTextureFilters()

'Global
Global PlanetList:TList = CreateList()
Global PlanetTexture:TTexture = LoadTexture("Planet.png", 1)
If PlanetTexture = Null Then RuntimeError "Texture not found"

Global id:Int = 1
Global Planet:TPlanet

Global Cam:TCamera = CreateCamera()
CameraClsColor Cam, 0, 0, 0
PositionEntity Cam, 0, 0, -30
CreateLight()

Global plane:Tmesh = CreateCube()
ScaleEntity plane, 1000, 1000, 0
PositionEntity plane, 0, 0, 0
EntityAlpha plane, 0
EntityPickMode plane, 2, 0

'MaxGUI
Global Edit:TGadget
Global Label1:Tgadget
Global Label2:Tgadget
Global Label3:Tgadget

Edit = CreateWindow("Edit", 900, 0, 320, 500, Null, WINDOW_TITLEBAR)
Label1 = CreateLabel("id:", 20, 10, 80, 20, Edit)
Label2 = CreateLabel("x:", 20, 30, 80, 20, Edit)
Label3 = CreateLabel("y:", 20, 50, 80, 20, Edit)

'Main loop
While Not KeyHit(KEY_ESCAPE)

	'Control
	If MouseHit(1)
		TPlanet.Create(id, CreateSphere(16), 5, PickedX(), PickedY(), 0, 0, 0, 0, 0, 0.1, "", 0, PlanetTexture)
		id = id + 1
	EndIf

	If KeyHit(KEY_Z)
		PlanetList.Last
		FreeEntity Planet.mesh
		ListRemove PlanetList, PlanetList.Last()
	EndIf

	CameraPick(Cam, MouseX(), MouseY())
	
	MoveEntity Cam, KeyDown(KEY_RIGHT) - KeyDown(KEY_LEFT), KeyDown(KEY_UP) - KeyDown(KEY_DOWN), 0
	PositionEntity Cam, EntityX(Cam), EntityY(Cam), MouseZ() - 30
	PositionEntity plane, EntityX(Cam), EntityY(Cam), 0

	For Planet = EachIn PlanetList
		Planet.Update()
		Planet.Collision()
	Next
	
	UpdateWorld()
	RenderWorld()

	BeginMax2D()

	SetColor 0, 128, 255
	DrawText "Space Editor Alpha testing", 10, 10
	SetColor 255, 255, 255
	DrawText PickedX(), 10, 40
	DrawText PickedY(), 10, 50
	SetColor 255, 255, 255
	DrawLine (w / 2) - 10, (h / 2), (w / 2) + 10, (h / 2)
	DrawLine (w / 2), (h / 2) - 10, (w / 2), (h / 2) + 10

	PollEvent()
	Select EventID()
	Case EVENT_WINDOWCLOSE
	End
	End Select
	
	EndMax2D()
		
	Flip 1
Wend

End

Type TPlanet
	Field id:Int = 0
	Field mesh:TMesh
	Field scale:Float = 0
	Field x:Float = 0
	Field y:Float = 0
	Field z:Float = 0
	Field a:Float = 0
	Field xt:Float = 0
	Field yt:Float = 0
	Field ms:Float = 0
	Field rs:Float = 0
	Field name:String = ""
	Field pid:Int = 0
	Field txt:TTexture
	
	Function Create:TPlanet(id:Int, mesh:Tmesh, scale:Float, x_start:Float, y_start:Float, z_start:Float, a_start:Float, xt:Float, yt:Float, ms:Float, rs:Float, name:String, pid:Int, txt:TTexture)
		Local Planet:TPlanet = New TPlanet
		Planet.id = id				'Planet ID
		Planet.mesh = mesh			'Mesh
		Planet.scale = scale		'Scale
		Planet.x = x_start			'X position
		Planet.y = y_start			'Y position
		Planet.z = z_start			'Z position
		Planet.a = a_start			'Angle
		Planet.xt = xt				'X tilt
		Planet.yt = yt				'Y tilt
		Planet.ms = ms				'Movement speed
		Planet.rs = rs				'Rotation speed
		Planet.name = name			'Planet name
		Planet.pid = pid			'Parent planet ID
		Planet.txt = txt			'Texture
		
		PositionEntity(Planet.mesh, Planet.x, Planet.y, Planet.z)
		ScaleEntity(Planet.mesh, Planet.scale, Planet.scale, Planet.scale)
		EntityTexture(Planet.mesh, Planet.txt)
		RotateMesh (Planet.mesh, -90, 0, 0)
		RotateEntity (Planet.mesh, 60, 0, 0)
		EntityPickMode Planet.mesh, 2, 0		'<- this one eats up my memmory
		ListAddLast PlanetList, Planet
				
		Return Planet
	End Function
	
	Method Update()
		Self.a = Self.a + Self.rs
		RotateMesh (Self.mesh, 0, 0, Self.rs)
		If PickedEntity() = Self.mesh
			EntityAlpha Self.mesh, 0.5
			SetGadgetText(Label1, "id: " + Self.id)
			SetGadgetText(Label2, "x: " + Self.x)
			SetGadgetText(Label3, "y: " + Self.y)
		Else
			EntityAlpha Self.mesh, 1
		EndIf
	End Method

	Method Collision()

	End Method
	
End Type


[edit] removed the unneeded UpdateWorld()


GIB3D(Posted 2009) [#2]
Why are you calling UpdateWorld inside Method Update()?
I don't use BlitzMax (I use Blitz3D) but I'm sure you don't need to keep calling that when you already have it called elsewhere.


Digital Anime(Posted 2009) [#3]
I already removed it myself indeed, but thanks for noticing :-p

But issue still remains. I just wonder if entitypickmode and objects don't mix for some reason or if I'm just missing/misplacing something.

Any help would be great

[edit] I narrowed it down to the commands pickentitymode combined with rotatemesh... As soon as a mesh with pickentitymode on starts to rotate the program starts eating more and more ram, and as soon when the rotation stops, memmory usage doesn't increase/decrease.

I think I need to get a workarround for this.


Digital Anime(Posted 2009) [#4]
Import sidesign.minib3d

Strict

Graphics3D 800, 600, 32, 2, 60

Local Cam:TCamera = CreateCamera()
PositionEntity Cam, 0, 0, -5
CreateLight()

Local Sphere:TMesh = CreateSphere(8)
PositionEntity Sphere, 0, 0, 0
EntityPickMode Sphere, 2, 0

Repeat

	RotateMesh Sphere, 1, 1, 1
	
	CameraPick (Cam, MouseX(), MouseY())
	
	UpdateWorld()
	RenderWorld()
	
	BeginMax2D()
	
		DrawText "X = " + PickedX(), 10, 10
		DrawText "Y = " + PickedY(), 10, 20
		DrawText "Z = " + PickedZ(), 10, 30
	
	EndMax2D()
	
	Flip 1

Until KeyHit(KEY_ESCAPE)

End


I made a smaller example wich still eats up my ram.
Is this a memmory leak within MiniB3D?
Try this code with the taskmanager open and look if within the following minutes this code eats up your ram as well...

I don't see any programming error's in this small example myself, but if there is, please tell... :-(


GIB3D(Posted 2009) [#5]
When I used it in Blitz3D it works just fine.




Digital Anime(Posted 2009) [#6]
Seems like a small bug/memmory leak within MiniB3D then. Hope Simonh will fix it :-)

I just decided to get me Blitz3D SDK, and after downloading changing the code a bit I got this small example working perfectly.
I rather pay 100$ for something that works then hoping for a fix on something that is free. MiniB3D is still a great project and very stable, but in my case it's not fitted for creating my games, yet.

I will use MiniB3D again when it's more stable in the future, but for now I can continue programming...

The SDK version :

Import blitz3d.blitz3dsdk

Import "bbtype.bmx"
Import "blitz3d.bmx"

Strict

bbBeginBlitz3D

bbGraphics3D 800, 600, 32, 2

Local Cam = bbCreateCamera()
bbPositionEntity Cam, 0, 0, -5
bbCreateLight()

Local Sphere = bbCreateSphere(8)
bbPositionEntity Sphere, 0, 0, 0
bbEntityPickMode Sphere, 2, 1

Repeat

	bbRotateMesh Sphere, 1, 1, 1
	
	bbCameraPick (Cam, bbMouseX(), bbMouseY())
	
	bbUpdateWorld()
	bbRenderWorld()
	
	bbText 10, 10, "X = " + bbPickedX()
	bbText 10, 20, "Y = " + bbPickedY()
	bbText 10, 30, "Z = " + bbPickedZ()
		
	bbFlip 1

Until KeyHit(KEY_ESCAPE)

End



Warner(Posted 2009) [#7]
Well, I don't know what it could be. Are you sure that it's EntityPickMode that does that? In Entity.bmx, the code for EntityPickMode is this:

I can't imagine that would require a lot of memory.

Instead of creating a sphere for each new planet, create one original sphere and use CopyEntity to create new spheres.



Digital Anime(Posted 2009) [#8]
It's entitypickmode in combination with rotatemesh on the same entity/mesh and it only happens in MiniB3D, not in Blitz3D (according to GIA_Green_Fire_) and not in Blitz3D SDK in BlitzMax (wich I tested myself).

The same code of my small example uses about 15Mb of memmory in total and stays that way, while under MiniB3D it's getting bigger and bigger untill you stop it or your memmory runs out...


Uncle(Posted 2009) [#9]
Hello all,

Last night I noticed the same thing and then I found this thread this morning. I thought it was my bad coding, but it looks like MiniB3D does have a leak.

I have an editor which uses a lot of rotatemesh commands. Every time I use it I saw my memory usage increase. I've been looking into why this happens, and I have managed to narrow the leak down to the TreeCheck(mesh:Tmesh) method in the TcolTree.bmx file. I'm not a hundred percent sure what this function does, but it seems to create another mesh using C_AddSurface(). If you comment out this line the leak stops. This isn't a fix though! I don't understand the code enough yet to find the fix. Perhaps Simon could take a look or point give an explanation of this method?

Cheers,

Unc


simonh(Posted 2009) [#10]
I think I've found it - try changing C_AddSurface in tree.cpp to this:

	void C_AddSurface(MeshInfo &mesh_info,int no_tris,int no_verts,short tris[],float verts[],int surface)
	{

		int t;

		for( t=0;t<no_tris;++t ){

			int v0=(int)tris[t*3];
			int v1=(int)tris[t*3+1];
			int v2=(int)tris[t*3+2];
			
			MeshCollider::Triangle tri;
			
			tri.verts[0]=v0;
			tri.verts[1]=v1;
			tri.verts[2]=v2;
			
			tri.surface=surface;
			tri.index=t;
	
			mesh_info.tri_list.push_back(tri);
		}

		int v;

		for( v=0;v<no_verts;++v ){
		
			float vx=verts[v*3]; // surf.VertexX(v)
			float vy=verts[v*3+1]; // surf.VertexY(v)
			float vz=verts[v*3+2]; // surf.VertexZ(v)
	
			MeshCollider::Vertex vert;
	
			vert.coords.x=vx;
			vert.coords.y=vy;
			vert.coords.z=vz;
	
			mesh_info.vert_list.push_back(vert);
		}

	}


Basically the Triangle and Vertex objects were being created using 'new' (allocated on the heap, which then wasn't released), when they didn't need to be.

Let me know if this fixes it.


Uncle(Posted 2009) [#11]
Yep that fixed it :) Thanks for your quick answer and great support Si.