News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Rotate Vertex List Directly Into Arrays

Started by kevin, April 30, 2009, 08:31:08 AM

Previous topic - Next topic

kevin

 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.  

PlayBASIC Code: [Select]
  ; 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







kevin

#1
 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.  

 
PlayBASIC Code: [Select]
; 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#
Login required to view complete source code




kevin

#2
  Lerp Vertex


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

requires PlayBasic V1.64j8 or higher

PlayBASIC Code: [Select]
; 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





  Video

   




-

ATLUS