Fast Vertex Manipulation

Blitz3D Forums/Blitz3D Programming/Fast Vertex Manipulation

Hey peeps!

The discussion about the fastest way to manipulate meshes in another thread the other day lead me to write a bit of code.

The code basically buffered all manipulation commands and executed them all at once on an "updatemesh".

I found it to be the same speed, initially... until just now... when i realised i never free any of the types..

So, the first go moves 100 vertices. the second go moves 200, etc etc.

yet, this code still ran the same speed as directly calling the original commands (for the most part of course).

Im wondering then- This code must be considerably FASTER once i put the "delete" line in. lol..

I will post here later to test. I'm hoping its much faster anyway. I used a similar method doing car damage in the racer without realising. Took it out because i had no way to reset the meshes :/

OKAY! I added the code! (Messy but followable i suppose...)

Now, after a few tests, i can tell you that if you are NOT doing much with a mesh other than updating it, you can actually lose speed using this technique. If you are updating a mesh which is pickable, and are picking, you get a massive increase.

Could do with a few people testing it out actually!

Use the provided commands, and call "updatemesh" before you render, that should be all :)


Graphics3D 640,480,16,2
light=CreateLight()

mesh=CreateSphere(8)
Global dst#
camera=CreateCamera()
EntityFX mesh,3
MoveEntity camera,0,20,-30
PointEntity camera,mesh

EntityPickMode mesh,2
sf=GetSurface(mesh,1)

ms=MilliSecs()
For n=1 To 2500
	vert=Rand(0,CountVertices(sf))
	VertexCoords(sf,vert,Rand(-10,10),Rand(-10,10),Rand(-10,10))
	VertexTexCoords(sf,vert,Rand(-10,10),Rand(-10,10),Rand(-10,10))
	LinePick(0,0,0,1,1,1)
Next
ms2=MilliSecs()
normalupdate=ms2-ms

ms=MilliSecs()
For n=1 To 2500
	vert=Rand(0,CountVertices(sf))
	VertexCoords2(sf,vert,Rand(-10,10),Rand(-10,10),Rand(-10,10))
	VertexTexCoords2(sf,vert,Rand(-10,10),Rand(-10,10),Rand(-10,10))
	LinePick(0,0,0,1,1,1)
Next
updatemeshes()
ms2=MilliSecs()
Speedupdate=ms2-ms


WireFrame 1

Repeat
	If mode=1 Then
		For n=1 To 1000
			vert=Rand(0,CountVertices(sf))
			VertexCoords2(sf,vert,Rand(-10,10),Rand(-10,10),Rand(-10,10))
			VertexTexCoords2(sf,vert,Rand(-10,10),Rand(-10,10),Rand(-10,10))
			LinePick(0,0,0,1,1,1)
		Next
		updatemeshes
	Else
		For n=1 To 1000
			vert=Rand(0,CountVertices(sf))
			VertexCoords(sf,vert,Rand(-10,10),Rand(-10,10),Rand(-10,10))
			VertexTexCoords(sf,vert,Rand(-10,10),Rand(-10,10),Rand(-10,10))
			LinePick(0,0,0,1,1,1)
		Next
EndIf

;Text "
MoveEntity mesh,KeyDown(203)-KeyDown(205),0,KeyDown(200)-KeyDown(208)
TurnEntity mesh,1,1,1
RenderWorld
Text 0,0,dst
Text 0,20,"Normal update:"+normalupdate
Text 0,32,"Speed update:"+speedupdate

Text 0,50,"Hit space to toggle mode"
If KeyHit(57) Then mode=(mode+1) Mod 2
If mode=0 Then txt$="Normal" Else txt$="Speed"
Text 0,62,"Current mode:"+txt$

Flip
Until KeyDown(1)
End


Type vertexupd
Field commandindex
Field surface,index,x#,y#,z#
Field u#,v#,w#,coordset
Field r#,g#,b#,a#

End Type
;Const vertex
Function VertexCoords2(surface,index,x#,y#,z#)
Local t.vertexupd
t.vertexupd=New vertexupd
t\commandindex=1
t\surface=surface
t\index=index
t\x=x
t\y=y
t\z=z
End Function

Function VertexTexCoords2(surface,index,u#,v#,w#=0,coord_set=0)
Local t.vertexupd
t.vertexupd=New vertexupd
t\commandindex=2
t\surface=surface
t\index=index
t\u#=u
t\v#=v
t\w#=w
t\coordset=coord_set
End Function

Function VertexColor2(surface,index,r#,g#,b#,a#=1)
Local t.vertexupd
t.vertexupd=New vertexupd
t\commandindex=3
t\surface=surface
t\index=index
t\r=r
t\g=g
t\b=b
t\a=a
End Function

Function updatemeshes()
Local t.vertexupd
Local dogrouped=1
;For selc=1 To 3
For t.vertexupd=Each vertexupd
Select t\commandindex
Case 1;=selc
VertexCoords t\surface,t\index,t\x,t\y,t\z
Case 2;=selc
VertexTexCoords t\surface,t\index,t\u,t\v,t\w,t\coordset
Case 3;=selc
VertexColor t\surface,t\index,t\r,t\g,t\b,t\a
End Select
Delete t
Next
;Next
End Function


Sounds almost too good to be true. . . can't wait to see the code :O)

Isn't using types slow though? epecially when you create + delete large numbers of them at a time. . . there's a lot of dynamic memory allocation going on there.

I guess I'll have to see the code before I see what you mean really. . .

Types are indeed pretty slow comapred to dynamicly created banks (that may hold some kind of homegrown types as well). additionally it's a lot faster to access things using an absolute index. But of course, this is an other issue.

Can't you reuse the types? I think the delete command can be slow.

the delete command can be slow. hmmm!

ive ran tests on types vs banks and types were faster. the continuous function calling on banks is what caused the types to win.

Mann.... I updated.


If you have to update a mesh and are using collision stuff in between each update, then you get (apparently) a 650% speed up.

If its just moving stuff, IE no line pick, then its quicker the blitz way :/

:(

Clarks - I think it really depends on the way you use it. Of course, there is an overhead when you call a function each time you want to access a bank. If you're familar with asm code then it may be easier to use the bank access syntax right away, instead of a function call that emulates type access syntax.

youre right jfk, the only reason why types are faster is because the banks accessed with functions

Was this of no use then? ;)

thats a major speed difference