UnderwareDESIGN

PlayBASIC => Show Case => Topic started by: kevin on January 16, 2006, 05:43:38 AM

Title: Vertex List Rotation
Post by: kevin on January 16, 2006, 05:43:38 AM
This example show off the new RotateVertexList (support XYZ & ZYX rotations)  command (playBASIC V1.10).  These commands, as you might have guessed rotates a set of vertexes (stored in memory).  

The demo creates a set of random vertexes rotates them,  the draws them as a set of shaded pixels to the scene buffer for rendering.

Even with 5000 vertex on my duron 800 it's still running 35+ fps.   And about 19/20 FPS with 10000 vertex.  


[pbcode]

   MakeBitmapfont 1,$ffffff

   SizeX=1000
   SizeY=1000
   SizeZ=1000



   Max=5000
   VertSize  =12

   SrcBank=NewBank((Max+1)*VertSize)
   DEstBank=NewBank((Max+1)*VertSize)


   SrcAddress   =getbankptr(SrcBank)
   DestAddress   =getbankptr(SrcBank)

   for lp=0 to Max
 Pokefloat SrcAddress,float(rndrange(-sizex,sizex))
 Pokefloat SrcAddress+4,float(rndrange(-sizey,sizey))
 Pokefloat SrcAddress+8,float(rndrange(-sizez,sizez))
 SrcAddress=SrcAddress+12
   next   

   projectionx#=300
   projectiony#=300


   
   basex#=0
   basey#=0
   basez#=1000


   Dim ShadeBufferBuffer(20000)
   
   
   maxdepth#=3000
   scaler#=100/maxdepth#   
   col=$8fff3f
   col=rgb(255,255,255)
   For lp=0 to maxdepth#
;  if mod(lp,1000)=0 then col=rndrgb()
 ShadeBufferBuffer(lp)=rgbfade(col,(maxdepth#-lp)*scaler#)
   next   

   createcamera 1

Do
   capturetoscene
   clsscene
   
; Rotate vertex list (with XYZ rotation order)
   SrcAddress   =getbankptr(SrcBank)
   DestAddress   =getbankptr(destBank)
   RotateVertexListXYZ SrcAddress,DestAddress,12,12,baseX#,basey#,baseZ#,ax#,ay#,az#,max   

   t=timer()
   Address   =getbankptr(DestBank)
   counter=max
   do
    z#=Peekfloat(Address+8)
    if z#>10
   dotc 400+((Peekfloat(Address)*projectionx#)/z#),300+((Peekfloat(Address+4)*projectiony#)/z#),ShadeBufferBuffer(z#)
    endif
    address=address+12
   decloop counter
   
   t=timer()-t  


   drawcamera 1


   setcursor 0,0
   speed#=10
   if upkey() then basez#=basez#+speed#
   if downkey() then  basez#=basez#-speed#
   ax#=wrapangle(ax#,0.01)
   ay#=wrapangle(ay#,0.02)
   az#=wrapangle(az#,0)


   Print "Rotated Vertex Lists"
   print str$(max)+" Shaded Z buffered Vertex"
   print fps()
   Sync
loop



[/pbcode]


Title: Vertex List Rotation
Post by: stef on January 16, 2006, 10:02:24 AM
Hi!

Where can I get PB1.10 ? :unsure:

Greetings
stef
Title: Vertex List Rotation
Post by: kevin on January 16, 2006, 03:39:15 PM
I'll be building the V1.10 patch later on today/tonight.   It's not great deal different from V1.089 at this point, but a few critical VM bugs have been fixed.   And of course while i'm here i'm adding some new toys for good measure :)

See->[plink]PlayBASIC Developer Blog (http://www.underwaredesign.com/forums/index.php?topic=338.0)[/plink]  (OLD INFO) as of 2023  go to home  PlayBASIC home page to download PlayBASIC Updates (https://playbasic.com)


While were here, the above rotation commands have already change (different parameters). Now you pass the routines a pointer to a simple object structure which olds the (axis position/rotation/scale and projection flags).  It's too many parameters to be passing a function.  In the future the user will pass a pointer to Type, rather than a bank pointer.  But anyway.   So the current implementation is subject to change.

 I'm also adding a translate to viewer style rotation command.  This will rotate the vertex on their local access and then rotate/project them to a viewer.  This will allow your to build your own software 3D engine (like uw3d)  easier, with much faster results.

 Although it should be noted that polygon clipping (to the z near and far  z planes) will still have to be performed by the user.
Title: Vertex List Rotation
Post by: kevin on January 16, 2006, 11:13:16 PM
As mentioned, I've changed the above functions a little and have now finally got the RotateVertexListToCamera working.  This command rotates a vertex list(s) to a viewers perspective.  

The tech demo is runnnig a 30 plus FPS with 7000 depth shaded, Z sorted points on my crusty old Duron 800.

The viewer can move around with Arrow keys and look using the mouse.  ie. standard fps controls.
Title: Vertex List Rotation
Post by: kevin on January 16, 2006, 11:17:18 PM
Note: Was developed in and requires at least PlayBASIC V1.10  (2006)

Object Include

[pbcode]
// Define 'Object' Structure for RotateVertexLIst commands

  Constant  PB_RotationObject_iStatus    =0
  Constant  PB_RotationObject_fXpos    =4
  Constant  PB_RotationObject_fYpos    =8
  Constant  PB_RotationObject_fZpos    =12
   
  Constant  PB_RotationObject_fXAngle    =16
  Constant  PB_RotationObject_fYAngle    =20
  Constant  PB_RotationObject_fZAngle    =24

  Constant  PB_RotationObject_fXScale    =28
  Constant  PB_RotationObject_fYScale    =32
  Constant  PB_RotationObject_fZScale    =36

  Constant  PB_RotationObject_iRotationMode  =40
  Constant  PB_RotationObject_iProjectionMode   =44
  Constant  PB_RotationObject_fXProjection  =48
  Constant  PB_RotationObject_fYProjection  =52
  Constant  PB_RotationObject_StructSize     =56



Function CreateVertexObject(Xpos#,Ypos#,Zpos#)
   VertexObject=NewBank(PB_RotationObject_StructSize)

; seed Object Structure
   PokeBankint VertexObject,PB_RotationObject_iStatus,true
   PositionVertexObject(VertexObject,Xpos#,Ypos#,Zpos#)
  RotateVertexObject(VertexObject,0,0,0)
  ScaleVertexObject(VertexObject,1,1,1)
   VertexObjectRotationMode(VertexObject,0)
   VertexObjectProjectionMode(VertexObject,off,0,0)
   
EndFunction VertexObject



Function VertexObjectRotationMode(VertexObject,mode)
   if GetBankStatus(VertexObject)
 PokeBankInt VertexObject,PB_RotationObject_iRotationMode,Mode
   endif
EndFunction


Function VertexObjectProjectionMode(VertexObject,State,ProjectX#,ProjectY#)
   if GetBankStatus(VertexObject)
 PokeBankInt VertexObject,PB_RotationObject_iProjectionMode,state
 PokeBankFloat VertexObject,PB_RotationObject_fXProjection,ProjectX#
 PokeBankFloat VertexObject,PB_RotationObject_fYProjection,ProjectY# ; default X projection
   endif
EndFunction


Function PositionVertexObject(VertexObject,Xpos#,Ypos#,Zpos#)
   if GetBankStatus(VertexObject)
   ; seed Object Structure
 PokeBankFloat VertexObject,PB_RotationObject_fXpos,Xpos#
 PokeBankFloat VertexObject,PB_RotationObject_fYpos,Ypos#
 PokeBankFloat VertexObject,PB_RotationObject_fZpos,Zpos#
   endif
EndFunction



Function GetVertexObjectPosition(VertexObject)
   if GetBankStatus(VertexObject)
 ; seed Object Structure
    xpos#=PeekBankFloat(VertexObject,PB_RotationObject_fXpos)
    ypos#=PeekBankFloat(VertexObject,PB_RotationObject_fYpos)
    zpos#=PeekBankFloat(VertexObject,PB_RotationObject_fZpos)
   endif
EndFunction Xpos#,YPos#,Zpos#



Function RotateVertexObject(VertexObject,Xangle#,Yangle#,Zangle#)
   if GetBankStatus(VertexObject)
   ; seed Object Structure
 PokeBankFloat VertexObject,PB_RotationObject_fXAngle,Xangle#
 PokeBankFloat VertexObject,PB_RotationObject_fYAngle,Yangle#
 PokeBankFloat VertexObject,PB_RotationObject_fZAngle,Zangle#
   endif
EndFunction


Function GetVertexObjectRotation(VertexObject)
   if GetBankStatus(VertexObject)
   ; seed Object Structure
 Xangle#=PeekBankFloat(VertexObject,PB_RotationObject_fXAngle)
 Yangle#=PeekBankFloat(VertexObject,PB_RotationObject_fYAngle)
 Zangle#=PeekBankFloat(VertexObject,PB_RotationObject_fZAngle)
   endif
EndFunction Xangle#,Yangle#,Zangle#




Function ScaleVertexObject(VertexObject,Xscale#,Yscale#,Zscale#)
   if GetBankStatus(VertexObject)
   ; seed Object Structure
 PokeBankFloat VertexObject,PB_RotationObject_fXScale,Xscale#
 PokeBankFloat VertexObject,PB_RotationObject_fYScale,Yscale#
 PokeBankFloat VertexObject,PB_RotationObject_fZScale,Zscale#
   endif
EndFunction
[/pbcode]


demo

[pbcode]

   MakeBitmapfont 1,$ffffff

   ProjectionX#=300
   ProjectionY#=300

; Init the Size of the Source and rotated Vertexs  
   constant SrcVertSize    =12
   Constant DestVertSize     =20  




   Type tObject
 status
   ; Object Bank
 ObjectBank
   ; Vertex Bank
 VertexBank
   ; Rotation Speeds for this object
 RotSpeedX#
 RotSpeedY#
 RotSpeedZ#
 NumberOFVerts
   EndType


   Dim Object(10) as tObject



   NumberOfVertex=1000


   Obj=1


; ==================================
; make the corner pillars   
; ==================================
   x=800
   z=800
   sizex=100
   Sizey=650
   sizez=100

   NewObject(obj,x,sizey,z,SizeX,SizeY,SizeZ,1000)  
   object(obj).rotspeedy#=1.5
   inc obj

   NewObject(obj,-x,sizey,z,SizeX,SizeY,SizeZ,1000)  
   inc obj

   NewObject(obj,-x,sizey,-z,SizeX,SizeY,SizeZ,1000)  
   inc obj

   NewObject(obj,x,sizey,-z,SizeX,SizeY,SizeZ,1000)  
   inc obj


; create the ceiling plane
   NewObject(obj,0,sizey*2,0,X,50,Z,1000)  
   inc obj

; create a bigger floor plane
   NewObject(obj,0,0,0,2000,50,2000,2000)  
   inc obj


   

; Create Camera Object
; =====================================
  CameraObject=CreateVertexObject(0,0,-2000)
  VertexObjectProjectionMode(CameraObject,1,ProjectionX#,ProjectionY#)






; =====================================
; Create Desitnation Vertex Buffer
; =====================================
   DestVertexBank=NewBank(20000*DestVertSize)



; =======================================================
;  Pre-calc the shading
; =======================================================

   Dim ShadeBufferBuffer(20000)
   NumberOfVertexdepth#=3000
   scaler#=100/NumberOfVertexdepth#   
   col=rgb(255,255,255)
   For lp=0 to NumberOfVertexdepth#
 ShadeBufferBuffer(lp)=rgbfade(col,(NumberOfVertexdepth#-lp)*scaler#)
   next   

   createcamera 1

Do
   capturetoscene
   clsscene


    
 ; Rotate vertex list (with XYZ rotation order)
    CameraAddress=getbankptr(CameraObject)
    ObjectAddress=getbankptr(VertexObject)

    DestVertexbufferAddress   =GetBankPtr(DestVertexBank)


    TotalNumberOFVertexs=0

    For Obj=0 to GetarrayElements(Object().tObject,1)
   if Object(obj).status=true

      ThisObject=Object(obj).ObjectBank

      ax#,ay#,az#=GetVertexObjectRotation(ThisObject)

      ax#=wrapangle(ax#,object(obj).rotspeedx)
      ay#=wrapangle(ay#,object(obj).rotspeedy)
      az#=wrapangle(az#,object(obj).rotspeedz)
     
      RotateVertexObject ThisObject,ax#,ay#,az#
      
      ObjectAddress=GetBankPtr(ThisObject)
      SrcVertexBufferAddress=getBankPtr(Object(obj).vertexbank)

      NumberOfVertex=object(obj).NumberOFVerts

      TotalNumberOFVertexs=TotalNumberOFVertexs+NumberOFVertex
      RotateVertexListToCamera CameraAddress,ObjectAddress,SrcVertexBufferAddress,SrcVertSize,DestVertexbufferAddress,DestVertSize,NumberOfVertex   

      Address   =DestVertexbufferAddress+8
      do
        z#=Peekfloat(Address)
        if z#>10
       capturedepth z#
       dotc 400+Peekfloat(Address+4),300+Peekfloat(Address+8),ShadeBufferBuffer(z#)
        endif
        address=address+destVertSize
      decloop NumberOfVertex
   endif
    next   

   drawcamera 1


   setcursor 0,0
   speed#=10


   Control_Camera(CameraObject,20)

;   ax#=wrapangle(ax#,0.22)
;   ay#=wrapangle(ay#,0.42)
;   az#=wrapangle(az#,0.9)

   if KeyPressed=false
 if scancode()<>0 then KeyPressed=true
    if spacekey()
   DemoMOde=1-demoMOde
    endif
   else
 if scancode()=0 then KeyPressed=False
   endif

   Print "Rotating Vertex Lists To Viewer/Camera"
   print str$(TotalNumberOFVertexs)+" Shaded Z buffered Vertex"
   print "Fps:"+str$(fps())
   Sync
loop





Function NewObject(obj,x,y,z,SizeX,SizeY,SizeZ,Verts)
   Object(obj).status=true
   VertexObject=CreateVertexObject(x,y,z)
   Object(obj).ObjectBank=VertexObject
; create Vertex Obejct Structure
  VertexObjectRotationMode(VertexObject,0); ZYX
   Object(obj).VertexBank=Make_Random_Vertex_region(sizex,sizey,sizez,Verts)
   object(obj).NumberOFVerts=Verts

EndFUnction






Function Make_Random_Vertex_region(sizex,sizey,sizez,NumberOfVertex)
; Create Vertex Buffers    
   VertexBank=NewBank((NumberOfVertex+1)*SrcVertSize)
   Address   =getbankptr(VertexBank)
   for lp=0 to NumberOfVertex
 Pokefloat Address,float(rndrange(-sizex,sizex))
 Pokefloat Address+4,float(rndrange(-sizey,sizey))
 Pokefloat Address+8,float(rndrange(-sizez,sizez))
 Address=Address+SrcVertSize
   next   
EndFUnction VertexBank





Psub Control_Camera(CameraObject,camspeed#)

    W=GetScreenWidth()
    H=GetScreenHeight()
    
    x1=GetScreenXpos()     
      Y1=GetScreenYpos()     
    x2=x1+w
    y2=y1+h     
   

    MMX#=MouseMoveX()
    MMY#=MouseMoveY()
    
    x#=x1+MouseX()     
    y#=y1+MouseY()     
    

    flag=0      
    If x#=<(x1+75) Then x#=x1+(w/2): flag=1
    If x#=>(x2-75) And flag=0 Then x#=x1+(w/2): flag=1

    If y#=<(y1+75) Then y#=y1+(h/2): flag=1
    If y#=>(y2-75) Then y#=y1+(h/2): flag=1
    
    
    If flag=1
     SetMouse x#,y#
     MMX2#=MouseMoveX()
      MMY2#=MouseMoveY()
    SetMouse x#,y#  
    EndIf
    

    camf#=0   
    camx#=WrapAngle(camx#,Mmy#*0.7)
    camy#=WrapAngle(camy#,mmx#*0.7)

    acamx#=CurveAngle(camx#,acamx#,2.1)
    acamy#=CurveAngle(camy#,acamy#,2.1)

;     Rotate_Camera acamx#,acamy#,0
    RotateVertexObject(CameraObject,acamx#,acamy#,0)

    If UpKey()=1 Then camf#=camf#+camspeed#
    If DownKey()=1 Then camf#=camf#-camspeed#

`     if camf#<>0 then move camera camf#
    If camf#<>0
   movementx#,movementy#,movementz#=CalcMovement(acamx#,acamy#,0.0,Camf#)
   X#,Y#,Z#=GetVertexObjectPosition(CameraObject)
   x#=x#+movementx#
   y#=y#+movementy#
   z#=z#+movementz#

    ; clip the camera to 20 on y axis
   if y#<20 then y#=20
   PositionVertexObject(CameraObject,x#,y#,z#)
    EndIf
EndPsub



Function CalcMovement(Anglex#,angley#,anglez#,Speed#)

   ` invert angles
 anglex#=360-anglex#
 angley#=WrapAngle(90,-angley#)
 anglez#=360-anglez#

   ` precalc cos+sin for rotation
  cx#=Cos(anglex#)
  sx#=Sin(anglex#)

  cy#=Cos(angley#)
  sy#=Sin(angley#)

;   cz#=Cos(anglez#)
;   sz#=Sin(anglez#)

;  xpos#=0
;  Ypos#=0
 Zpos#=Speed#
 
 z#=(cx#*Zpos#)
 y#=(sx#*zpos#)
 ` Around Y axis
 x2#=(cY#*Z#)-(sy#*X#)
 z#=((cy#*X#)+(sy#*Z#))

EndFunction x2#,y#,z#


[/pbcode]

Title: Vertex List Rotation
Post by: kevin on February 04, 2006, 09:53:59 AM
Just toying with vertex lists for a tech demo.   Here's  some shots rendering a wall of circles within the vertex world.
Title: Vertex List Rotation
Post by: kevin on February 04, 2006, 09:55:28 AM
and another
Title: Vertex List Rotation
Post by: Ian Price on February 04, 2006, 11:02:50 AM
Cool :)
Title: Vertex List Rotation
Post by: kevin on February 04, 2006, 11:18:55 AM
Nah that's not cool..

But this is ! :)
Title: Vertex List Rotation
Post by: Ian Price on February 04, 2006, 11:20:37 AM
Seriously! :D

I actually saw a web remake of Super Mario Bros done like that. :)

I also saw ManicMiner3D a while back. (Don't forget to check out the 3D Dizzy mock-up too - it's really cool).
Title: Vertex List Rotation
Post by: kevin on February 04, 2006, 11:29:11 AM
That was basically the the plan.   Well, port the existing platformer demo in at least.