Speed drop when rotating

BlitzMax Modules Forums/MiniB3D/Speed drop when rotating

Hi its me again,

i just noticed that a scene that usually runs at ~30fps slows down tremendously when rotating a few entities.
I this example only 5 spheres are rotated and the fps drops from 32 to 8 on my office computer.

Strict

Import "../MiniB3D.bmx"
Type TSun
Field PIVOT:TPivot
Field MESH:TMesh
Field LIGHT:TLight

Function Create:TSun()
	Local tmp:TSun = New TSun
	tmp.PIVOT = CreatePivot()
	tmp.MESH = CreateSphere(8,tmp.PIVOT)
	tmp.LIGHT = CreateLight(2,tmp.PIVOT)
	tmp.LIGHT.LightColor(230,20,20)	
	Return tmp
End Function
End Type

Local width=640,height=480,depth=16,mode=0

Graphics3D width,height,depth,mode

HideMouse()
AmbientLight(50,50,50)

Local cam:TCamera=CreateCamera()
cam.PositionEntity(0,0,-10)
cam.CameraZoom(2)

Local tex:TTexture=LoadTexture("media/test.png",1)
Local tex2:TTexture=LoadTexture("media/sand.bmp",1)

Local Sun:TSun = TSun.Create()
sun.MESH.EntityTexture(tex)
sun.MESH.EntityFX(1)
Sun.MESH.ScaleEntity(3,3,3)
Sun.PIVOT.PositionEntity(0,0,20)

Local spherearray:TMesh[5]
For Local i% = 0 Until 5
	spherearray[i] = CreateSphere(16)
	Local vx:Float,vy:Float,vz:Float
	Local pos:Float = Rand(0.0,360.0)
	vx = 0 + 10 * Cos(pos)
	vy = 0 
	vz = 20 + 10 * Sin(pos)
	spherearray[i].PositionEntity(vx,vy,vz)
	spherearray[i].EntityTexture(tex2)
	'spherearray[i].EntityColor(230,20,20)
Next

' used by camera code
Local mxs#=0
Local mys#=0
Local move#=0.5
MouseXSpeed() ' flush
MouseYSpeed() ' flush

' used by fps code
Local old_ms=MilliSecs()
Local renders
Local fps

While Not KeyDown(KEY_ESCAPE)		

	If KeyHit(KEY_ENTER) Then DebugStop


	For Local j% = 0 Until Len(spherearray)			'COMMENT THIS OUT TO SEE SPEED INCREASE DRASTICALLY
		spherearray[j].RotateMesh(0,1,0)			'
	Next											'
	
	'' control camera
	
	' mouse look
	
	mxs#=mxs#+(MouseXSpeed()/5.0)
	mys#=mys#+(MouseYSpeed()/5.0)

	RotateEntity cam,mys#,-mxs#,0

	MoveMouse width/2,height/2
	MouseXSpeed() ' flush
	MouseYSpeed() ' flush

	' move camera forwards/backwards/left/right with cursor keys
	
	If KeyDown(KEY_W)=True Then MoveEntity cam,0,0,move# ' move camera forward
	If KeyDown(KEY_S)=True Then MoveEntity cam,0,0,-move# ' move camera back

	If KeyDown(KEY_A)=True Then MoveEntity cam,-move#,0,0 ' move camera left
	If KeyDown(KEY_D)=True Then MoveEntity cam,move#,0,0 ' move camera right
	
	''
	
	'TurnEntity cube,0,1,0

	RenderWorld
	renders=renders+1

	' calculate fps
	If MilliSecs()-old_ms>=1000
		old_ms=MilliSecs()
		fps=renders
		renders=0
	EndIf
	
	Text 0,0,"FPS: "+String(fps)
	Text 0,20,"Light: " +Sun.LIGHT.EntityX(True)+", "+Sun.LIGHT.EntityY(True)+", "+Sun.LIGHT.EntityZ(True)
	Text 0,40,"Mesh : "+Sun.MESH.EntityX(True)+ ", "+Sun.MESH.EntityY(True)+ ", "+Sun.MESH.EntityZ(True)
	Text 0,60,"Pivot: "+Sun.PIVOT.EntityX(True)+", "+Sun.PIVOT.EntityY(True)+", "+Sun.PIVOT.EntityZ(True)	

	Flip

Wend
End



Am i doing something wrong? Because if i am not i just can't imagine populating a real scene with entities.

hmm

rotatemesh with sphere(12) are also slow here

use this ?

spherearray[j].TurnEntity (0,1,0)

The problem is you're using RotateMesh with several spheres with large amounts of polys. With RotateMesh, each vertex is rotated individually by MiniB3D itself which is quite slow.

Use RotateEntity where possible for real-time stuff.

Thing is when i substitute RotateEntity for RotateMesh nothing rotates. Thats why i used RotateMesh in the first place.
Your explanation that every vertex is rotated when using RotateMesh explains the speeddrop. Now i just need to figure out why RotateEntity has no effect in this example.

TurnEntity works nice and quick - thanks.

Now whats wrong with RotateEntity...?

And whats the difference while im at it ;)

RotateEntity uses absolute values, you need to increment the rotation values for it to rotate.

And sorry for another post but your explanation that a sphere with 16 Segments is considered high-poly got me worried. This is very low poly in my book.

So could you please provide some info what polycounts are the norm when working with (mini)B3D?
How many total scene polys are acceptable?
Whats low-poly? eg. 10-1000 poly?
Whats high-poly? 4000-8000?

Whats a good ballpark for e.g. a main character mesh?
Enemy-characters?
Terrains?

Maybe there is info like has already been compiled over the past years of B3D usage? Linky?

Don't worry about high poly and low poly. Just use whatever works for you.

When I said high poly I was taking into account the fact there were five spheres.

They are high-poly for entities being pushed to the graphics card every frame. When you use RotateEntity its only pushing a small amount of data (probably a matrix or similar), whereas RotateMesh pushes all the vertex and triangle data - which is huge.

Its a seperate issue, but polycounts depend on many things: type of game, target hardware, style of graphics, distance from camera, number of surfaces (at least in Blitz3D), use of alpha/masking etc. ie. very hard to pin down.

Actually without vertex buffers all the vertex data is passed to the graphics card every frame. With RotateMesh however, the vertex positions are rotated in Blitz itself, rather than using the gfx card to do it.

Aah! Interesting. My mistake.

Thanks - ills just keep adding entities over time and see where the limit is.