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 |