3D-RotateVertexList

Started by Kman1011, January 26, 2009, 05:21:32 PM

Previous topic - Next topic

Kman1011

Hi Kevin

  Just to let know I revised a peice of code that was a playbasic example in the folder. I modified it so that I could use it in a game. The Vertexes are ordered rather than random and I have given it the illusion of infinite movement. This part of PB KICKS ASS!!!.  ;D

  I'm not sure how this is moving so fast but I am curious as to how well this will run once I have added the texturemapped panels to the vertex's and exactly what clipping will have to be done for them (ie panels offscreen).

PlayBASIC Code: [Select]
; PROJECT : 3dCam
; AUTHOR : Kevin Picone
; MODIFIED: Kent Seburn
; CREATED : 17/01/2006
; EDITED : 1/26/2009
; ---------------------------------------------------------------------

#Include "VertexObjects"

MakeBitmapFont 1,$ffffff

sw=GetScreenWidth()
sh=GetScreenHeight()

ProjectionX#=400
ProjectionY#=400

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

Global Xpos#
Global Ypos#
Global Zpos#
Global Map_X
Global Map_Y
Global Map_Z

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=10000


Obj=1


; ==================================
; make the corner pillars
; ==================================
x=1000
z=1000
y=1000
sizex=2000
Sizey=2000
sizez=2000

NewObject(obj,x,y,z,SizeX,SizeY,SizeZ,8000)

Inc obj






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






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



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

Dim ShadeBufferBuffer(20000)
NumberOfVertexdepth#=1000
scaler#=100/NumberOfVertexdepth#
col=RGB(255,255,255)
For lp=0 To NumberOfVertexdepth#
ShadeBufferBuffer(lp)=RGBFade(col,(NumberOfVertexdepth#-lp)*scaler#)
Next

CreateCamera 1


StartTime=Timer()+5000

Do
CaptureToScene
ClsScene

; Rotate vertex list (with XYZ rotation order)
CameraAddress=GetBankPtr(CameraObject)

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
Login required to view complete source code


Any comments and suggestions from anyone are appreciated..

Thanks
Ahh... Another visitor. Stay awhile....STAY FOREVER!!!...MWA-HA-HA-HA

kevin

QuoteI'm not sure how this is moving so fast but I am curious as to how well this will run once I have added the texturemapped panels to the vertex's and exactly what clipping will have to be done for them (ie panels offscreen).

     If you simply connect the verts to form cubes say, it'll choke because the cost per pixel is way too high.   It'd choke in PBFX is also btw, same reason.       I assume you want to make some sort a tunnel through the cubic space,  if so, you'll really have to be very diligent about only rendering what's visible to the camera.   

    In terms of polygon level clipping,  you can choose to do the clipping manually, or let PB do it.  If you use the rendering triangle commands, then you'll need to clip these yourself.   I'm not talking about 2d viewport here, i'm talking about clipping against the near and far planes, aka down the Z axis.   The near plane being the camera, the far being the horizon.   

    So to clip on the near plane,  what you do is check if any vertex of the polygon your drawing has a Z lower than 1 (after transformation). (you can't project a vert with transformed z of 0 or lower)   

   If we have the polygon A->B->C  and C is behind the camera and but A and B aren't.  The we need to clip (calc the X/Y cords in 3d space at this z ) the edges  B->C calc 2 new coordinates.   We then render 2 triangles in the place of the original.   

   Or you can use the build in the mesh stuff, which does all the grunt work for you .    There's few examples that come with Pb that use this, one that comes to mind is the terrain example in the Project/Demos folder.    Basically you just build a mesh and tell Pb to translate it to the scene buffer.

  Pb is easil;y quick enough to handle the work load.    In the UW3D engine for example,  all the vertex rotation / polygon clipping (2d & 3d) are done in pure PlayBasic code.  The rendering is  done with the either triangle or the gouraud triangle command.  Depending on the mode though.   

  UW3D


  PS. You know that this is the PlayBasic user forum, and not the talk to kevin forum right ?

Kman1011

#2
QuotePS. You know that this is the PlayBasic user forum, and not the talk to kevin forum right ?

LOL. Yes I was merely refering to author of the program I was modiyfing

QuoteSo to clip on the near plane,  what you do is check if any vertex of the polygon your drawing has a Z lower than 1 (after transformation). (you can't project a vert with transformed z of 0 or lower)

Yes, I discovered that when I did the math for a program just like this. a copy of the same dots were on the screen but they were moving in reverse.

We'll I re-modified the program again but instead of trying to use 1 object with 20wx20hx20d vertex's I created 20wx20hx20d objects with 8 vertex's to make each object a cube just to make it easier to acess each cube but as soon as do more than 5wx20hx20d it crashes.  On another computer I get a limited number of objects.

PlayBASIC Code: [Select]
; PROJECT : 3dDepths2
; AUTHOR : Kevin Picone
; CREATED : 17/01/2006
; EDITED : 1/27/2009
; ---------------------------------------------------------------------

#Include "VertexObjects"

MakeBitmapFont 1,$ffffff

sw=GetScreenWidth()
sh=GetScreenHeight()

ProjectionX#=400
ProjectionY#=400

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

Global Xpos#
Global Ypos#
Global Zpos#
Global Map_X
Global Map_Y
Global Map_Z

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


Dim Object(8000) As tObject



NumberOfVertex=8


Obj=1


; ==================================
; make the corner pillars
; ==================================
;x=-9
;z=-9
;y=0
sizex=50
Sizey=50
sizez=50


For z=-9 To 9
For y=-5 To 5
For x=-9 To 9
NewObject(obj,x*100,y*100,z*100,SizeX,SizeY,SizeZ,8)
Inc obj
Next x
Next y
Next z






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






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



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

Dim ShadeBufferBuffer(20000)
NumberOfVertexdepth#=1000
scaler#=100/NumberOfVertexdepth#
col=RGB(255,255,255)
For lp=0 To NumberOfVertexdepth#
ShadeBufferBuffer(lp)=RGBFade(col,(NumberOfVertexdepth#-lp)*scaler#)
Next

CreateCamera 1


StartTime=Timer()+5000

Do
CaptureToScene
ClsScene

; Rotate vertex list (with XYZ rotation order)
CameraAddress=GetBankPtr(CameraObject)

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)
ScrnX=400+PeekFloat(Address+4)
ScrnY=300+PeekFloat(Address+8)
Login required to view complete source code


I'm guessing it's a memory issue or some sort of limitation. I can't see any other problem with the code.

Ahh... Another visitor. Stay awhile....STAY FOREVER!!!...MWA-HA-HA-HA

kevin


   From memory, the scene buffer has a set capacity,  and according to the debugger this is limited to 8000 items.   If so, that would mean that it can only hold 8000 unique entities (of whatever type Dots,lines,Images etc) in the scene at once.   



Kman1011

It would seem it's limited to 8000 Vertex's, Yes.

I decided to go the original way of making one object with 8000 Vertex's.

I found I could access each point relative to another by mathmatically calculating the address.

ie: in a cube 20 x 20 x20

   AddX=DestVertSize
   AddY=DestVertSize*20
   AddZ=DestVertSize*20*20

So far it's good. I just have to get the Z plane to clip at the camera.

QuoteSo to clip on the near plane,  what you do is check if any vertex of the polygon your drawing has a Z lower than 1 (after transformation). (you can't project a vert with transformed z of 0 or lower)   

   If we have the polygon A->B->C  and C is behind the camera and but A and B aren't.  The we need to clip (calc the X/Y cords in 3d space at this z ) the edges  B->C calc 2 new coordinates.   We then render 2 triangles in the place of the original.

I'm going try this

I'll send some screen shots as soon as I get some

Kman



Ahh... Another visitor. Stay awhile....STAY FOREVER!!!...MWA-HA-HA-HA

kevin

#5
   The scene limit isn't particularly relevant, as if you need more then 8k of dynamic polygons in screen in PlayBasic V1.64 editions, then it's simply not going to happen.   Too much overdraw = Too slow.

   The key point there is you'll need to work on some approaches on how to limit the amount of stuff that actually needs to be drawn/managed and is therefore going to be captured into the scene buffer and rendered.   For example the UW3D demo can run worlds of over 100,000 polygons in PB1.64, but only about 1->2% of those are ever visible and make it into the rendering queue.  You can take this further by implementing spacial partitioning and pre or dynamically computed object visibility. 
   
   I'd recommend getting the a bare bones object manager/scene render up and running.  A cube will do,  work out how to clip and when it's needed.  As you get more familiar with the process, you'll notice there are countless short cuts that can be taken to eliminate objects from ever making it the rendering stage.   Early rejection is the key.

   

     

Kman1011

Well I've already reduced the number of polygons 4 fold

1) No polygons with vertex's behind the camera

2) Creating a local area where object info passes in and out of the area of ther camera so that it does't
get bogged down trying to draw the entire world. I do this by looping through a certian area to give the   illusion that you are moving through infinite space like in my first example.

3) Only exposed faces are being draw within the scene (Cubes surrounded by other cubes are ignored)

4) Only faces which are visible are drawn. (Maximum 3 per cube at any time)

I just put a counter on the program and got anywhere from 100 to 505 polygons at a time. It seems to run quite well :)

otherwise I would have about 40000 - 48000(max) polygons to draw and that's just crazy

Right now, clipping the polygons AT the camera are the biggist issue and being able calculate that X/y you mentioned. 


Ahh... Another visitor. Stay awhile....STAY FOREVER!!!...MWA-HA-HA-HA

kevin


  Sounds like you're stepping through the process nicely.  Don't keep us in suspense tho, we want screenies :)

  Are using texture mapped polygons ?  if so,  you might want to sub-divide the nearest cubes so the textures hold perspective.  PB doesn't have perspective correct mapping. Why ? - it's a 2D.  However, old hardware renders didn't have it either.  (Playstation 1 for example)    Anyway, so this makes the mapping affine linear.

   When we project the vertexes we're projecting the 3D scene onto the 2d plane.   However the texels are linearly interpolated between the projected points.  So the closer a vert is to the camera, and greater the distance between it's neighbour verts,  the more the texture will skew/slip and slide.  The bigger distance between the points/ or the more acute the view angle the more obvious it becomes.

  So what you can do is sub dividie near faces of close up objects.  Effectively converting those faces into mini meshes.    The splitting and the extra edge conversion will be slower than drawing one big quad/triangle, but it'll help to fool your eyes.   One of the demos that comes with PB does this.



 

Kman1011

QuoteSo what you can do is sub dividie near faces of close up objects.  Effectively converting those faces into mini meshes.

Your not going to believe this, but I just thought of that idea last night as I was struggling with the concept. Our minds are in total sync. I'm freaked out :o

QuoteAre using texture mapped polygons ?  if so,  you might want to sub-divide the nearest cubes so the textures hold perspective.

Yes! that is exactly my plan. I'm just wondering to what degree I should break it down. The finer the slower but less choppy and vice versa. I was going to try 4 x 4 and see if that would be good enough.

I can give you some preliminary shots with un-texuremapped polygons of a building I quickly put together soon. I still have to load in images of varying fades to give the illusion of depth and light.

Just hang in there. :)   
Ahh... Another visitor. Stay awhile....STAY FOREVER!!!...MWA-HA-HA-HA