Cylinder style 3d list

Blitz3D Forums/Blitz3D Beginners Area/Cylinder style 3d list

Hi all

Could some kind soul please take a look at this piece of code to see where i'm going wrong, Basically its a menu system with each item displayed on a seperate 3d sprite, all of the sprites rotate around a center pivot to give a cylinder effect.
The problem is my CurveAngle() function, I just can't get it to handle the jump from positive to negative angles.
; Use up and down keys to scroll the list

Graphics3D 800,600,32
Const MaxLines = 40
Global SelectedTrackIndex

; create camera
Global Camera = CreateCamera()

; create list wheel
Dim Item(MaxLines)
Dim ItemTex(MaxLines)
Global Wheel = CreatePivot()
PositionEntity Wheel,0,0,4
For n = 1 To MaxLines
	Item(n) = CreateSprite(Wheel)
	ScaleSprite Item(n),2,0.1
	TranslateEntity Item(n),0,0,-1.5,True
	EntityAutoFade Item(n),3.0,3.8	
	EntityBlend Item(n),3
	ItemTex(n) = CreateTexture(512,10)
	TurnEntity Wheel,(360/MaxLines),0,0
Next
UpdateWheelTextures()

Global BackPlate = CreateSprite()
ScaleSprite BackPlate,2,0.1
PositionEntity BackPlate,0,0,3
EntityColor BackPlate,0,0,50


; main loop
While Not KeyDown(1)

	; Scroll up
	If KeyHit(200)
		SelectedTrackIndex = SelectedTrackIndex - 1
		If SelectedTrackIndex < 0 Then SelectedTrackIndex = MaxLines
	EndIf
	
	; Scroll down
	If KeyHit(208)
		SelectedTrackIndex = SelectedTrackIndex + 1
		If SelectedTrackIndex > MaxLines Then SelectedTrackIndex = 0
	EndIf

	UpdateListWheel()

	UpdateWorld()
	RenderWorld()
	Flip

Wend
End



Function UpdateListWheel()

	current# = EntityPitch(Wheel)
	destin#	= (360 / MaxLines) * SelectedTrackIndex

	;dist# = destin# - current#
	;speed# = dist# / 5
	;TurnEntity Wheel,speed#,0,0

	RotateEntity Wheel,CurveAngle(current#,destin#,10),EntityYaw(wheel),EntityRoll(wheel)

End Function

Function UpdateWheelTextures()

	x = TextureWidth(ItemTex(1))/2
	y = TextureHeight(ItemTex(1))/2
	For n=1 To MaxLines
		SetBuffer TextureBuffer(ItemTex(n))
		ClsColor 0,0,0 : Cls
		Color 255,255,255
		Text x,y,"TEST LINE "+n,1,1
		EntityTexture Item(n),ItemTex(n)
	Next
	
End Function

Function CurveAngle#(current#,desired#,smooth#)

	Return current + (desired-current)/smooth

End Function

Thanx for your help!

Here's a hastily contrived version which seems to work.

CurveAngle has been fixed.

And Roll is used instead of Pitch.
Pitch has only a 180 degree range, from -90 to +90. Roll has 360 degree range.

; Use up and down keys to scroll the list

Graphics3D 800,600,32
Const MaxLines = 40
Global SelectedTrackIndex

Global current#, destin#  ; not necessary, just for debugging...

; create camera
Global Camera = CreateCamera()

; create list wheel
Dim Item(MaxLines)
Dim ItemTex(MaxLines)
Global Wheel = CreatePivot()
PositionEntity Wheel,0,0,4

TurnEntity wheel, 0, 90, 0 ; point z-axis along original x-axis

For n = 1 To MaxLines
	Item(n) = CreateSprite(Wheel)
	ScaleSprite Item(n),2,0.1
	TranslateEntity Item(n),0,0,-1.5,True
	EntityAutoFade Item(n),3.0,3.8	
	EntityBlend Item(n),3
	ItemTex(n) = CreateTexture(512,10)
	TurnEntity Wheel,0,0,(360/MaxLines)
Next
UpdateWheelTextures()

Global BackPlate = CreateSprite()
ScaleSprite BackPlate,2,0.1
PositionEntity BackPlate,0,0,3
EntityColor BackPlate,0,0,50


; main loop
While Not KeyDown(1)

	; Scroll up
	If KeyHit(200)
		SelectedTrackIndex = SelectedTrackIndex - 1
		If SelectedTrackIndex < 0 Then SelectedTrackIndex = MaxLines
	EndIf
	
	; Scroll down
	If KeyHit(208)
		SelectedTrackIndex = SelectedTrackIndex + 1
		If SelectedTrackIndex > MaxLines Then SelectedTrackIndex = 0
	EndIf

	UpdateListWheel()


	RenderWorld()
	Text 10,10, current
	Text 10,30, destin
	Flip

Wend
End



Function UpdateListWheel()  ; note use of Roll rather than Pitch

	current# = EntityRoll(Wheel)
	destin#	= (360 / MaxLines) * SelectedTrackIndex

; Orient in two steps. This gets rid of confusing interactions 
; among Pitch, Yaw and Roll.

	RotateEntity wheel, 0, 90, 0
	TurnEntity Wheel, 0, 0, CurveAngle(current ,destin ,10)

End Function

Function UpdateWheelTextures()

	x = TextureWidth(ItemTex(1))/2
	y = TextureHeight(ItemTex(1))/2
	For n=1 To MaxLines
		SetBuffer TextureBuffer(ItemTex(n))
		ClsColor 0,0,0 : Cls
		Color 255,255,255
		Text x,y,"TEST LINE "+n,1,1
		EntityTexture Item(n),ItemTex(n)
	Next
	SetBuffer BackBuffer()
	
End Function

Function CurveAngle#(current#,desired#,smooth#)
Local delta#   ;  small version of angle, e.g. +350 becomes -10.

	delta = desired-current
	If Abs(delta) > 180 Then delta = delta - 360 * Sgn(delta)
	Return current + delta/smooth

End Function

This could be neatened up with some effort. But it seems to work.

For some reason the sprite didn't work squidged up like you had it... however...

Added a bit to rotate the sprite so it's at the right angle on the cylinder... Just replace the initial loopy bit with this.

For n = 1 To MaxLines

	Item(n) = CreateSprite(Wheel)
	ScaleSprite Item(n),2,2
	SpriteViewMode item(n),2
	RotateEntity item(n),(360/maxlines)*(n-1),270,0
	EntityFX item(n),16
	TranslateEntity Item(n),0,0,-1.5,True
	;EntityAutoFade Item(n),3.0,3.8	
	EntityBlend Item(n),3
	ItemTex(n) = CreateTexture(256,256)
	TurnEntity Wheel,0,0,(360/MaxLines)

Next


Another possibility. Does not use curveangle at all... (to be honest I could not be bothered to try and figure out how to change it all, so consider this the lazy way).

Function UpdateListWheel()
	
	destin#	= (360 / MaxLines) * (SelectedTrackIndex-1)
	
	vecy#=-Sin(destin) : vecz#=Cos(destin)
		
	AlignToVector wheel,0,vecy,vecz,3,0.1

End Function



A couple of other changes are needed to limit the values correctly...

Global SelectedTrackIndex=1
;....
		If SelectedTrackIndex < 1 Then SelectedTrackIndex = MaxLines
;....
		If SelectedTrackIndex > MaxLines Then SelectedTrackIndex = 1


Well in fact three changes, but who's counting. ;)

Thanks for all your help guys! :)

I used Davids code in the end, works a treat! Cheers mate :D