UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on April 30, 2009, 08:31:08 AM

Title: Rotate Vertex List Directly Into Arrays
Post by: kevin on April 30, 2009, 08:31:08 AM
 Rotate Vertex List Directly Into Arrays

  Since array accesses have a higher precedence (faster) in Vm1/Vm2 than pointer and bank accesses, then if you're dealing with lots of vertex /rotation stuff, it makes more sense to rotate your vertex buffers into a 2D array.  Then access the rotated verts through the array interface.

  Here's  version the Rotation demo fro the example pack that uses this method.  

[pbcode]

 ; include the Vertex Objects expansion library
  #include "VertexObjects"

   MakeBitmapFont 1,$ffffff


   SceneProjectionX#=300
   SceneProjectionY#=300

   // Size of the vertex cube
   ObjectSizeX=1000
   ObjectSizeY=1000
   ObjectSizeZ=1000


   NumberOfVertex=5000

   // Size of a single vertex (XYZ)
   SrcVertSize            =12
   DestVertSize         =20      

   // Array to hold the none rotated vertex
   Dim Vertex#(2         ,(NumberOfVertex+1))

   // Array to hold the rotated vertex
   Dim RotatedVertex#(4,(NumberOfVertex+1))

   // Randomly Init the none rotated vertex
   For lp=0 To NumberOfVertex-1
      Vertex#(0,lp)=RndRange#(-ObjectSizex,ObjectSizex)      // X
      Vertex#(1,lp)=RndRange#(-ObjectSizey,ObjectSizey)      // Y
      Vertex#(2,lp)=RndRange#(-ObjectSizez,ObjectSizez)      // Z
   Next   


   //   Objects Base X/Y position
   basex#=0
   basey#=0
   basez#=1000



   // Precalc the Depth que shade array to shade the dots based upon the dots depth from the viewer
   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   


   // Create a camera to draw the scene (with depth ordering)
   CreateCamera 1

   // Turn CLS off in the camera.  This allows us to perform an Asycn CLS while the
   // vertex are being rotataed
   CameraCls 1,off
   
   
   // --------------------------------------------------------------------------------
   // Main loop  ---------------------------------------------------------------------
   // --------------------------------------------------------------------------------
   Do
   
      // Clear the screen to black
      Cls rgb(0,0,0)

      // Tell PB to capture draw commands to the Scene buffer
      CaptureToScene

      // Clear the scene at start of the frame, so there's no left over junk in there from a previous frame
      ClsScene


      // Get Address of Array source vertex
      SrcAddress      =GetArrayPtr(Vertex#())+PBArraystruct_Size

      // Get address of rotated vertex (none projected)  
      DestAddress      =GetArrayPtr(RotatedVertex#())+PBArraystruct_Size

      // Rotated the vertex list
      RotateVertexListXYZ SrcAddress,SrcVertSize,DestAddress,DestVertSize,baseX#,basey#,baseZ#,ax#,ay#,az#,NumberOfVertex   

      // Draw the list of camera. So they can drawn in order when the
      t=Timer()
      For vert=0 to NumberOfVertex-1
            z#=RotatedVertex#(2,Vert)
            If z#>10
               Capturedepth z#
               X#=400+(RotatedVertex#(0,Vert)*SceneProjectionx#)/z#
               Y#=300+(RotatedVertex#(1,Vert)*SceneProjectiony#)/z#
               DotC x#,y#,ShadeBufferBuffer(z#)
            endif                  
      next
      t=Timer()-t      
   
   
      // draw the scene
      DrawCamera 1


      SetCursor 0,0
      speed#=10

      If UpKey() Then basez#=basez#-speed#
      If DownKey() Then  basez#=basez#+speed#

      If basez#>3000 Then Basez#=3000
      If basez#<-3000 Then Basez#=-3000

      ax#=WrapAngle(ax#,1.01)
      ay#=WrapAngle(ay#,0.42)
      az#=WrapAngle(az#,0.9)
   
      Print "Rotated Vertex Lists"
      Print Str$(NumberOfVertex)+" Shaded Z buffered Vertex"
      Print "draw time:"+Str$(t)
      Print FPS()

   Sync
Loop



[/pbcode]

Title: Re: Rotate Vertex List Directly Into Arrays
Post by: kevin on May 04, 2009, 11:19:38 PM
 Lerp Vertex Animation (Linear Interpolation between two vertex arrays)

 This is variation of the demo above, but this one includes vertex animation via linear interpolation.   So the demo generates two vertex arrays.  Frame1 has the vertex positions randomly within a cubic space, and frame2 see the vertex randomly positioned on the surface of a sphere.    The LERP function then lets us calculate transistion between the two frames.    If your wondering this is how old school 3d animation works.  

 
[pbcode]


; include the Vertex Objects expansion library
  #include "VertexObjects"

   openscreen 800,600,32,2
   screenvsync on


   SceneProjectionX#=300
   SceneProjectionY#=300

   // Size of the vertex cube
   ObjectSizeX=500
   ObjectSizeY=500
   ObjectSizeZ=500

   NumberOfVertex=5000

   // Size of a single vertex (XYZ)
   SrcVertSize            =12
   DestVertSize         =20      

   // Array to hold the two frames of vertex data
   Dim VertexFrame1#(2         ,(NumberOfVertex+1))
   Dim VertexFrame2#(2         ,(NumberOfVertex+1))

   // Array to hold the distance between each vertex in frane1 and frame2
   Dim VertexDeltas#(2         ,(NumberOfVertex+1))

  // array to hold the interpolation frame of vertex data (transistional state)
   Dim LerpVertexFrame#(2         ,(NumberOfVertex+1))


   // Array to hold the rotated vertex
   Dim RotatedVertex#(4,(NumberOfVertex+1))

   // Randomly Init the none rotated vertex (FRAME1 the random cube shaped vertex array)
   For lp=0 To NumberOfVertex-1
      VertexFrame1#(0,lp)=RndRange#(-ObjectSizex,ObjectSizex)      // X
      VertexFrame1#(1,lp)=RndRange#(-ObjectSizey,ObjectSizey)      // Y
      VertexFrame1#(2,lp)=RndRange#(-ObjectSizez,ObjectSizez)      // Z
   Next   


   // Randomly generate vertex on the sphere as frame 2
   for t= 0 To NumberOfVertex
      xd = Rndrange(-90,90)
      x0 = (Cos(xd) * 10) * (Cos(t) * 10)
      y0 = (Cos(xd) * 10) * (Sin(t) * 10)
      z0 = Sin(xd) * 100
      VertexFrame2#(0,t)=x0*6
      VertexFrame2#(1,t)=y0*6
      VertexFrame2#(2,t)=z0*6
   Next


   // Calc the difference between each vertex
   CalcVertexDeltas(NumberOfVertex)


   //   Objects Base X/Y position
   basex#=0
   basey#=0
   basez#=1000



   // Precalc the Depth que shade array to shade the dots based upon the dots depth from the viewer
   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   


   // Create a camera to draw the scene (with depth ordering)
   CreateCamera 1

   // Turn CLS off in the camera.  This allows us to perform an Asyns CLS while the
   // vertex are being rotated
   CameraCls 1,off
   
   
   // --------------------------------------------------------------------------------
   // Main loop  ---------------------------------------------------------------------
   // --------------------------------------------------------------------------------
   Do
   
      // Clear the screen to black
      Cls rgb(0,0,0)



      // Tell PB to capture draw commands to the Scene buffer
      CaptureToScene

      // Clear the scene at start of the frame, so there's no left over junk in there from a previous frame
      ClsScene



      // Lerp between the Frame 1 and Frame
       Lerp(NumberOfVertex,Scaler#)


      if spacekey() or kev=0
         Scaler#      =cos(ScalerAngle#)*3
         Scaler#      =cliprange#(Scaler#,0,1)
         ScalerAngle#=wrapangle(ScalerAngle#,0.4)
      endif
      


      // Get Address of Array source vertex
      SrcAddress      =GetArrayPtr(LerpVertexFrame#())+PBArraystruct_Size

      // Get address of rotated vertex (none projected)  
      DestAddress      =GetArrayPtr(RotatedVertex#())+PBArraystruct_Size

      // Rotated the vertex list
      RotateVertexListXYZ SrcAddress,SrcVertSize,DestAddress,DestVertSize,baseX#,basey#,baseZ#,ax#,ay#,az#,NumberOfVertex   


      // Draw the list to camera. So they can drawn in Z order when the camera is drawn
      t=Timer()
         For vert=0 to NumberOfVertex-1
               z#=RotatedVertex#(2,Vert)
               If z#>10
                  Capturedepth z#   // Set this dots Z depth in the scene
                  X#=400+(RotatedVertex#(0,Vert)*SceneProjectionx#)/z#
                  Y#=300+(RotatedVertex#(1,Vert)*SceneProjectiony#)/z#
                  DotC x#,y#,ShadeBufferBuffer(z#)
               endif                  
         next
      t=Timer()-t      
   
      // draw the scene
      DrawCamera 1

      // Set the text cursor to position 0,0 (top left) on the screem
      SetCursor 0,0

      // Check if the user is pressing the Arrow to move the scene in/out
      speed#=10
      If UpKey() Then basez#=basez#-speed#
      If DownKey() Then  basez#=basez#+speed#
      If basez#>3000 Then Basez#=3000
      If basez#<-3000 Then Basez#=-3000

      // Bump objects rotation angles
      ax#=WrapAngle(ax#,1.01)
      ay#=WrapAngle(ay#,0.72)
      az#=WrapAngle(az#,0.9)

      // Display the vertex lists
      Print "Rotated Vertex Lists"
      Print Str$(NumberOfVertex)+" Shaded Z buffered Vertex"
      Print "draw time:"+Str$(t)
      Print FPS()

   Sync
Loop



Psub CalcVertexDeltas(NumberOfVertex)
      // Calc the diff between each vertex in the two frames
      For lp=0 To NumberOfVertex-1
          VertexDeltas#(0,lp)=VertexFrame2#(0,lp)-VertexFrame1#(0,lp)
          VertexDeltas#(1,lp)=VertexFrame2#(1,lp)-VertexFrame1#(1,lp)
          VertexDeltas#(2,lp)=VertexFrame2#(2,lp)-VertexFrame1#(2,lp)
      next
EndPsub


Psub Lerp(NumberOfVertex,Scaler#)
   // Linearly Interpolate the vertexs
   For lp=0 To NumberOfVertex-1
      LerpVertexFrame#(0,lp)=VertexFrame1#(0,lp)+(VertexDeltas#(0,lp)*Scaler#)
      LerpVertexFrame#(1,lp)=VertexFrame1#(1,lp)+(VertexDeltas#(1,lp)*Scaler#)
      LerpVertexFrame#(2,lp)=VertexFrame1#(2,lp)+(VertexDeltas#(2,lp)*Scaler#)
   Next   
EndPsub



[/pbcode]


Title: Re: Rotate Vertex List Directly Into Arrays
Post by: kevin on May 07, 2009, 11:37:43 AM
  Lerp Vertex


Here's the version used to created the screen shots bellow.

requires PlayBasic V1.64j8 or higher

[pbcode]
; include the Vertex Objects expansion library
  #include "VertexObjects"

   MakeBitmapFont 1,$ffffff


   SceneProjectionX#   =300
   SceneProjectionY#   =300

   // Size of the vertex cube
   ObjectSizeX         =500
   ObjectSizeY         =500
   ObjectSizeZ         =500

   NumberOfVertex      =2500

   // Size of a single vertex (XYZ)
   SrcVertSize            =12
   DestVertSize         =20      

   // Array to hold the none rotated vertex
   Dim VertexFrame1#(2         ,(NumberOfVertex+1))
   Dim VertexFrame2#(2         ,(NumberOfVertex+1))

   Dim LerpVertexFrame#(2         ,(NumberOfVertex+1))

   // Array to hold the rotated vertex
   Dim RotatedVertex#(4,(NumberOfVertex+1))

   // Randomly Init the none rotated vertex
   For lp=0 To NumberOfVertex-1
      VertexFrame1#(0,lp)=RndRange#(-ObjectSizex,ObjectSizex)      // X
      VertexFrame1#(1,lp)=RndRange#(-ObjectSizey,ObjectSizey)      // Y
      VertexFrame1#(2,lp)=RndRange#(-ObjectSizez,ObjectSizez)      // Z
   Next   



for t= 0 To NumberOfVertex
   xd = Rndrange(-90,90)
   x0 = (Cos(xd) * 10) * (Cos(t) * 10)
   y0 = (Cos(xd) * 10) * (Sin(t) * 10)
   z0 = Sin(xd) * 100
   VertexFrame2#(0,t)=x0*6
   VertexFrame2#(1,t)=y0*6
   VertexFrame2#(2,t)=z0*6

Next


   //   Objects Base X/Y position
   basex#=0
   basey#=0
   basez#=1000

   // Precalc the Depth que shade array to shade the dots based upon the dots depth from the viewer
   Dim ShadeBufferBuffer(20000)
   NumberOfVertexdepth#=3000
   scaler#=100/NumberOfVertexdepth#   
   col=rndrgb()
   ;RGB(255,125,055)
   For lp=0 To NumberOfVertexdepth#
      ShadeBufferBuffer(lp)=RGBFade(col,(NumberOfVertexdepth#-lp)*scaler#)
   Next   


   // Create a camera to draw the scene (with depth ordering)
   CreateCamera 1

   // Turn CLS off in the camera.  This allows us to perform an Asycn CLS while the
   // vertex are being rotataed
   CameraCls 1,off
   
   
   // --------------------------------------------------------------------------------
   // Main loop  ---------------------------------------------------------------------
   // --------------------------------------------------------------------------------
   Do
   
      // Clear the screen to black
      Cls rgb(0,0,0)

      // Tell PB to capture draw commands to the Scene buffer
      CaptureToScene

      // Clear the scene at start of the frame, so there's no left over junk in there from a previous frame
      ClsScene


      // Lerp between the Frame 1 and Frame

      Frame1Address      =GetArrayPtr(VertexFrame1#())+PBArraystruct_Size
      Frame2Address      =GetArrayPtr(VertexFrame2#())+PBArraystruct_Size
      DestAddress      =GetArrayPtr(LerpVertexFrame#())+PBArraystruct_Size

      LerpVertexList(Frame1Address,SrcVertSize,Frame2Address, SrcVertSize,DestAddress,SrcVertSize, NumberOfVertex, Scaler# )
      
      if spacekey() or kev=0

         Scaler#=(cos(ScalerAngle#)*5)
         Scaler#=cliprange#(Scaler#,0,1)
         ScalerAngle#=wrapangle(ScalerAngle#,0.1)
      endif
      


      // Get Address of Array source vertex
      SrcAddress      =GetArrayPtr(LerpVertexFrame#())+PBArraystruct_Size


      // Get address of rotated vertex (none projected)  
      DestAddress      =GetArrayPtr(RotatedVertex#())+PBArraystruct_Size

      // Rotated the vertex list
      RotateVertexListXYZ SrcAddress,SrcVertSize,DestAddress,DestVertSize,baseX#,basey#,baseZ#,ax#,ay#,az#,NumberOfVertex   

      // Draw the list of camera. So they can drawn in order when the
         For vert=0 to NumberOfVertex-1
            z#=RotatedVertex#(2,Vert)
            If z#>10
               Capturedepth z#
               X#=400+(RotatedVertex#(0,Vert)*SceneProjectionx#)/z#
               Y#=300+(RotatedVertex#(1,Vert)*SceneProjectiony#)/z#
               CircleC x#,y#,16,true,ShadeBufferBuffer(z#)
            endif                  
         next
   
      // draw the scene
      DrawCamera 1

      SetCursor 0,0
      speed#=10

      If UpKey() Then basez#=basez#-speed#
      If DownKey() Then  basez#=basez#+speed#

      If basez#>3000 Then Basez#=3000
      If basez#<-3000 Then Basez#=-3000

      ax#=WrapAngle(ax#,1.01)
      ay#=WrapAngle(ay#,0.42)
      az#=WrapAngle(az#,0.9)
   
      Print FPS()

   Sync
Loop
[/pbcode]



  Video

   




(http://www.underwaredesign.com/forums/index.php?action=dlattach;topic=2610.0;attach=2584;image) - (http://www.underwaredesign.com/forums/index.php?action=dlattach;topic=2610.0;attach=2586;image)
Title: Re: Rotate Vertex List Directly Into Arrays
Post by: ATLUS on May 23, 2011, 05:31:07 PM
and video
http://www.youtube.com/watch?v=FmNVJ9gDa8k&feature=channel_video_title