More single surface particles

Blitz3D Forums/Blitz3D Programming/More single surface particles

Ross C(Posted 2003) [#1]
Hey, i'm still working on a single surface particle system, but i need to check a few thing :)

1. When i load in the texture i want for the particles, i load them in as an unanimated texture, formatted like an animated texture, but just loaded using loadtexture?

2. Then when i want to animate a particular quad, i simply adjust the uv co-ords for that triangle?

3. I need to know if using sin and cos are slow? I'm using them constantly and need any feisable speed ups i can get.

4. I assume that when a quad isn't being used, i adjust the uv co-ords so that no tetxure is showing?

5. I read something a while back about calling clear surface, and building the quads back from scratch every frame. Think i read that from Anthony Flacks post about his game.


Sorry about the large number number of questions, but i feel like i'm learning alot jumping in with this stuff:)


Ross C(Posted 2003) [#2]
It's ok, i've answered many of my own questions by mucking about. Question 3 would still be handy if answered :) I'll post my code. All you need is an image called "fire.png".

Please try this and give me your opinions/suggestions for making it faster if possible :)

Graphics3D 800,600
SetBuffer BackBuffer()

cam=CreatePivot()

camera=CreateCamera(cam)
PositionEntity camera,0,0,-15

mesh=CreateMesh()

surface=CreateSurface(mesh)

NUM_PARTICLES=60


Type s_part
	Field x#,y#,z#; central position for the quad
	Field index; index for the first vertex
	Field ang#; ang value. -45 for normal
	Field alpha#
	Field speed#
	Field time
	Field timer
	Field ang_speed#
	Field active
	Field pindex
End Type

g_time=1
g_timer=MilliSecs()

cpx#=0
cpy#=0
cyz#=0

ang=-45
index=0

v0=AddVertex(surface,cpx+Sin(ang),cpy+Cos(ang),cpz,0,1)
v1=AddVertex(surface,cpx+Sin(ang+90),cpy+Cos(ang+90),cpz,1,1)
v2=AddVertex(surface,cpx+Sin(ang-90),cpy+Cos(ang-90),cpz,0,0)
v3=AddVertex(surface,cpx+Sin(ang+180),cpy+Cos(ang+180),cpz,1,0)


tri=AddTriangle(surface,v0,v1,v2)
tri1=AddTriangle(surface,v1,v3,v2)

tex=LoadTexture("fire.png",2)



EntityTexture mesh,tex
EntityFX mesh,32+2
EntityBlend mesh,3

VertexColor surface,0,200,200,200;,0.8
VertexColor surface,1,200,200,200;,0
VertexColor surface,2,200,200,200;,0
VertexColor surface,3,200,200,200;,0

For loop=0 To NUM_PARTICLES
	Gosub create_spart
Next


While Not KeyHit(1)
	
	;TranslateEntity mesh,0,0.01,0,True
	TurnEntity mesh,0,0,1
	
	cx=EntityPitch(camera,True)
	cy=EntityYaw(camera,True)
	cz=0
	
	If MouseDown(1) Then ang=ang+1:Gosub rotatequad
	If MouseDown(2) Then ang=ang-1:Gosub rotatequad
	If KeyDown(203) Then cpx=cpx-0.1:Gosub rotatequad
	If KeyDown(205) Then cpx=cpx+0.1:Gosub rotatequad
	If KeyDown(200) Then cpy=cpy+0.1:Gosub rotatequad
	If KeyDown(208) Then cpy=cpy-0.1:Gosub rotatequad
	If KeyDown(2) Then Gosub create_spart
	
	If MilliSecs()>g_time+g_timer Then
										g_timer=MilliSecs()
										Gosub new_spart
	End If
	
	RotateEntity mesh,cx,cy,cz
	
	If MilliSecs()<timer+1000 Then
								frame=frame+1
	Else
								fps=frame
								frame=0
								timer=MilliSecs()
	End If
	
	Gosub update_spart
	UpdateWorld
	RenderWorld
	Text 0,0," Number of quads="+(index/4)+" fps="+fps+" trirednered="+TrisRendered()
	Flip False
Wend
End

.rotatequad
VertexCoords(surface,0,cpx+Sin(ang),cpy+Cos(ang),cpz)
VertexCoords(surface,1,cpx+Sin(ang+90),cpy+Cos(ang+90),cpz)
VertexCoords(surface,2,cpx+Sin(ang-90),cpy+Cos(ang-90),cpz)
VertexCoords(surface,3,cpx+Sin(ang+180),cpy+Cos(ang+180),cpz)
Return

.create_spart
	p.s_part=New s_part
	p\pindex=index
	index=index+4
	p\x=Rnd(-2,2)
	p\y=0;Rnd(-4,4)
	p\z=Rnd(-2,2)
	p\speed=Rnd(0.001,0.01)
	p\time=Int(Rnd(500,2000))
	p\ang_speed=Rnd(0.1,2)
	p\ang=Rnd(-45,135)	
	v0=AddVertex(surface,p\x+Sin(p\ang),p\y+Cos(p\ang),p\z,0,1)
	v1=AddVertex(surface,p\x+Sin(p\ang+90),p\y+Cos(p\ang+90),p\z,1,1)
	v2=AddVertex(surface,p\x+Sin(p\ang-90),p\y+Cos(p\ang-90),p\z,0,0)
	v3=AddVertex(surface,p\x+Sin(p\ang+180),p\y+Cos(p\ang+180),p\z,1,0)
	tri=AddTriangle(surface,v0,v1,v2)
	tri1=AddTriangle(surface,v1,v3,v2)
Return

.update_spart
	For p.s_part=Each s_part
		If p\active=1 Then
			p\y=p\y+p\speed
			p\ang=p\ang+p\ang_speed
			VertexCoords(surface,p\pindex+0,p\x+Sin(p\ang),p\y+Cos(p\ang),p\z)
			VertexCoords(surface,p\pindex+1,p\x+Sin(p\ang+90),p\y+Cos(p\ang+90),p\z)
			VertexCoords(surface,p\pindex+2,p\x+Sin(p\ang-90),p\y+Cos(p\ang-90),p\z)
			VertexCoords(surface,p\pindex+3,p\x+Sin(p\ang+180),p\y+Cos(p\ang+180),p\z)
			If MilliSecs()>p\time+p\timer Then
											p\active=0
											VertexColor surface,p\pindex+0,200,200,200,0
											VertexColor surface,p\pindex+1,200,200,200,0
											VertexColor surface,p\pindex+2,200,200,200,0
											VertexColor surface,p\pindex+3,200,200,200,0
			End If
		End If
	Next
Return

.new_spart
	loop_exit=0
	For p.s_part=Each s_part
		If p\active=0 Then
			VertexColor surface,p\pindex+0,200,200,200,1
			VertexColor surface,p\pindex+1,200,200,200,1
			VertexColor surface,p\pindex+2,200,200,200,1
			VertexColor surface,p\pindex+3,200,200,200,1
			p\active=1
			p\y=0
			p\speed=Rnd(0.001,0.01)
			p\timer=MilliSecs()
			p\time=Int(Rnd(500,2000))
			p\ang_speed=Rnd(0.01,0.3)
			p\ang=Rnd(-45,135)
			p\x=Rnd(-2,2)
			p\z=Rnd(-2,2)
			loop_exit=1
			VertexCoords(surface,p\pindex+0,p\x+Sin(p\ang),p\y+Cos(p\ang),p\z)
			VertexCoords(surface,p\pindex+1,p\x+Sin(p\ang+90),p\y+Cos(p\ang+90),p\z)
			VertexCoords(surface,p\pindex+2,p\x+Sin(p\ang-90),p\y+Cos(p\ang-90),p\z)
			VertexCoords(surface,p\pindex+3,p\x+Sin(p\ang+180),p\y+Cos(p\ang+180),p\z)
		End If
		If loop_exit=1 Then Exit
	Next
Return


And use this for anything you want to.
:D