Please help me align this :)

Blitz3D Forums/Blitz3D Programming/Please help me align this :)

FlagDKT(Posted 2008) [#1]
I need to align the emission cone to the emission vector.
What's the best way?

Use Arrows to modify emission pitch/yaw
+ - to modify emission cone

Graphics3D 800,600,32,2
Global frameTimer = CreateTimer(60)
Global camera=CreateCamera()
CameraZoom camera,1
CameraRange camera, 0.1, 1000
MoveEntity camera,0,0,-3
Color 255,255,0
light=CreateLight(1)

Type part
	Field sprite
	Field vx#
	Field vy#
	Field vz#
	Field deathtime
End Type

Global pAlive

Global emDirX#
Global emDirY#
Global emDirZ#
Global emDirYaw#
Global emDirPitch#=90
Global emissionCone#=2
Global partSpeed#=.1

Global sphere=CreateSphere(2)
ScaleEntity sphere,.08,.08,.08
HideEntity sphere

Global arrow=CreateCone()
ScaleEntity arrow,.08,.08,.08
RotateMesh arrow,90,0,0
EntityColor arrow,255,255,0

Global pole=CreateCube()
ScaleEntity pole,.03,.03,.45
EntityColor pole,255,255,0

Function emissionTest()
	a.part=New part
	pAlive=pAlive+1
	a\sprite=CopyEntity (sphere)
	EntityAlpha a\sprite,.3
	a\deathtime=MilliSecs()+2000
	
	rndEmCone#=Rnd(-emissionCone,emissionCone)
	p#=emDirPitch#+rndEmCone
	y#=emDirYaw#-rndEmCone
	
	sx#=Sin(p)*Cos(y#)
	sy#=Sin(p)*Sin(y#)
	sy#=Cos(p)
	
	a\vx#=sx*partSpeed#
	a\vy#=sy*partSpeed#
	a\vz#=sz*partSpeed#						
	moveParticles()
End Function

Function moveParticles()
	For a.part=Each part
		MoveEntity a\sprite,a\vx*partSpeed,a\vy*partSpeed,a\vz*partSpeed
		If MilliSecs()>=a\deathtime Then
			FreeEntity a\sprite
			Delete a
			pAlive=pAlive-1
		EndIf
	Next
End Function

Function drawEmDir()
	emDirX#=Sin(emDirPitch)*Cos(emDirYaw)
	emDirY#=Sin(emDirPitch)*Sin(emDirYaw)
	emDirZ#=Cos(emDirPitch)
	
	AlignToVector arrow,emDirX,emDirY,emDirZ,3
	PositionEntity arrow,emDirX#*1.02,emDirY#*1.02,emDirZ#*1.02
	
	AlignToVector pole,emDirX,emDirY,emDirZ,3
	PositionEntity pole,emDirX#*.5,emDirY#*.5,emDirZ#*.5
End Function

;----------------------------------------------------------------------------------------------------
; MAIN LOOP -----------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------
While Not KeyHit(1)
	WaitTimer(frameTimer)	;rispetta il limite di fps
	
	If KeyDown(205) Then emDirYaw=emDirYaw+2
	If KeyDown(203) Then emDirYaw=emDirYaw-2
	If KeyDown(200) Then emDirPitch=emDirPitch+2
	If KeyDown(208) Then emDirPitch=emDirPitch-2
	If KeyDown(78) And emissionCone<360 Then emissionCone=emissionCone+1
	If KeyDown(74) And emissionCone>0 Then emissionCone=emissionCone-1
	
	emissionTest()
	UpdateWorld()
	RenderWorld()
	drawEmDir()
	tc=0
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirPitch : "+emDirPitch
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirYaw : "+emDirYaw
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirX : "+emDirX
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirY : "+emDirY
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirZ : "+emDirZ
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emissionCone : "+emissionCone
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"Parts  Alive : "+pAlive
	Flip()
Wend
End



Stevie G(Posted 2008) [#2]
No need to use sin/cos maths - use a couple of pivots ..

Graphics3D 800,600,32,2
Global frameTimer = CreateTimer(60)
Global camera=CreateCamera()
CameraZoom camera,1
CameraRange camera, 0.1, 1000
MoveEntity camera,0,0,-3
Color 255,255,0
light=CreateLight(1)

Type part
	Field sprite
	Field vx#
	Field vy#
	Field vz#
	Field deathtime
End Type

Global pAlive

Global emDirX#
Global emDirY#
Global emDirZ#
Global emDirYaw#
Global emDirPitch#=90
Global emissionCone#=10
Global partSpeed#=.1

;SG
Global emPivot = CreatePivot() 
Global emPivotRnd = CreatePivot( emPivot )

Global sphere=CreateSphere(2)
ScaleEntity sphere,.08,.08,.08
HideEntity sphere

Global arrow=CreateCone()
ScaleEntity arrow,.08,.08,.08
RotateMesh arrow,90,0,0
EntityColor arrow,255,255,0

Global pole=CreateCube()
ScaleEntity pole,.03,.03,.45
EntityColor pole,255,255,0

Function emissionTest()

	a.part=New part
	pAlive=pAlive+1
	a\sprite=CopyEntity (sphere)
	EntityAlpha a\sprite,.3
	a\deathtime=MilliSecs()+2000
	
	rndEmCone#=Rnd(-emissionCone,emissionCone)
	
	;SG
	RotateEntity emPivotRnd, rndEmCone, -rndEMCone, 0
	TFormVector 0,0,1, emPivotRnd, 0
	a\vx# = TFormedX() * partSpeed#
	a\vy# = TFormedY() * partSpeed#
	a\vz# = TFormedZ() * partSpeed#						

	moveParticles()

End Function

Function moveParticles()
	For a.part=Each part
		MoveEntity a\sprite,a\vx*partSpeed,a\vy*partSpeed,a\vz*partSpeed
		If MilliSecs()>=a\deathtime Then
			FreeEntity a\sprite
			Delete a
			pAlive=pAlive-1
		EndIf
	Next
End Function

Function drawEmDir()

	;SG
	TFormVector 0,0,1,emPivot, 0
	emDirX# = TFormedX() 
	emDirY# = TFormedY() 
	emDirZ# = TFormedZ() 
	
	AlignToVector arrow,emDirX,emDirY,emDirZ,3
	PositionEntity arrow,emDirX#*1.02,emDirY#*1.02,emDirZ#*1.02
	
	AlignToVector pole,emDirX,emDirY,emDirZ,3
	PositionEntity pole,emDirX#*.5,emDirY#*.5,emDirZ#*.5
End Function

;----------------------------------------------------------------------------------------------------
; MAIN LOOP -----------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------
While Not KeyHit(1)
	WaitTimer(frameTimer)	;rispetta il limite di fps
	
	If KeyDown(205) Then emDirYaw=emDirYaw+2
	If KeyDown(203) Then emDirYaw=emDirYaw-2
	If KeyDown(200) Then emDirPitch=emDirPitch+2
	If KeyDown(208) Then emDirPitch=emDirPitch-2
	If KeyDown(78) And emissionCone<360 Then emissionCone=emissionCone+1
	If KeyDown(74) And emissionCone>0 Then emissionCone=emissionCone-1
	
	;SG
	RotateEntity emPivot, emDirPitch, emDirYaw, 0
	
	emissionTest()
	UpdateWorld()
	RenderWorld()
	drawEmDir()
	tc=0
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirPitch : "+emDirPitch
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirYaw : "+emDirYaw
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirX : "+emDirX
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirY : "+emDirY
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emDirZ : "+emDirZ
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"emissionCone : "+emissionCone
	tc=tc+1 Text (26-FontWidth()),FontHeight()*tc,"Parts  Alive : "+pAlive
	Flip()
Wend
End



FlagDKT(Posted 2008) [#3]
Thnx Stevie :)
But don't you think that creating pivots on the fly could lead to slowdowns?
I didn't want to use it for this reason...
Do you know a faster way perhaps?

Anyway I've just seen that the emission shape is not correct...it is not a cone...try increasing the emission range with + and rotate the emitter with Z pointing to the observer or in the opposite dir.

the emission part should be modified this way
	rndEmConeA#=Rnd(-emissionCone,emissionCone)
	rndEmConeB#=Rnd(-emissionCone,emissionCone)
	
	RotateEntity emPivotRnd, rndEmConeA, rndEmConeB, 0,False

But I don't think it could be really defined "Emission cone"


Stevie G(Posted 2008) [#4]
Creating and deleting pivots will create no noticable slowdown unless you're using thousands of them each frame. The biggest issue in terms of slowdown would be the number of surfaces on screen and your fill-rate if your using loads of alpha. If the former happens - look into creating a single surface system.