May 30, 2020, 03:13:58 AM

Author Topic: [bb] Bezier Patches - Editable 3D surfaces. by Jeppe Nielsen [ 1+ years ago ]  (Read 1467 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Bezier Patches - Editable 3D surfaces.
Author : Jeppe Nielsen
Posted : 1+ years ago

Description : Shows how bezier patches can be created, example demonstrates an interactive 3d surface.

Code :
Code: BlitzBasic
  1. ;*****************************************************
  2. ;*               Bezier Patch example                *
  3. ;*****************************************************
  4. ;*              By Jeppe Nielsen 2005                *
  5. ;*****************************************************
  6. ;*                jeppe@gameart.dk                   *
  7. ;*****************************************************
  8.  
  9. Graphics3D 800,600
  10.  
  11. segments=10
  12.  
  13. b.bezierpatch = BezierPatchNew()
  14.  
  15. patch=BezierPatchMesh(b,segments,segments)
  16.  
  17. patchtexture=CreateTexture(32,32)
  18. SetBuffer TextureBuffer(patchtexture)
  19.         ClsColor 255,0,0
  20.         Cls
  21.         Color 255,255,255
  22.         Rect 0,0,16,16,True
  23.         Rect 16,16,16,16,True
  24.        
  25. SetBuffer BackBuffer()
  26.  
  27. ScaleTexture patchtexture,0.25,0.25
  28. EntityTexture patch,patchtexture
  29.  
  30. Global camera,camerarx#,camerary#
  31.  
  32. CameraInit
  33.  
  34. light=CreateLight(2)
  35. PositionEntity light,0,10,0
  36. LightRange light,5
  37.  
  38.  
  39.  
  40. plane=CreatePlane()
  41. EntityPickMode plane,2
  42. EntityAlpha plane,0
  43.  
  44. selectedpoint=-1
  45.  
  46. Repeat
  47.  
  48. cameraupdate 0.1
  49.  
  50. Select state
  51.  
  52.         Case 0
  53.        
  54.                 If MouseDown(1)
  55.                         selectedpoint=BezierPatchGetPoint(b,camera,MouseX(),MouseY())
  56.                         If selectedpoint<>-1
  57.                                 state=1
  58.                                 PositionEntity plane,bpx[selectedpoint],bpy[selectedpoint],bpz[selectedpoint]
  59.                         EndIf
  60.                 EndIf
  61.                
  62.         Case 1
  63.        
  64.                 If MouseDown(1)
  65.                        
  66.                         CameraPick(camera,MouseX(),MouseY())
  67.                
  68.                         BezierPatchSetPoint(b,selectedpoint,PickedX#(),PickedY#(),PickedZ#())
  69.                         If patch<>0
  70.                                 FreeEntity patch
  71.                                 patch=0
  72.                         EndIf
  73.                        
  74.                         patch=BezierPatchMesh(b,segments,segments)
  75.                         EntityTexture patch,patchtexture
  76.                                
  77.                 Else
  78.                
  79.                         state=0
  80.                        
  81.                 EndIf
  82.                
  83. End Select
  84.  
  85. If selectedpoint<>-1
  86.        
  87.         If KeyDown(201)
  88.        
  89.                 bpy[selectedpoint]=bpy[selectedpoint]+0.5
  90.                 If patch<>0
  91.                         FreeEntity patch
  92.                         patch=0
  93.                 EndIf
  94.                
  95.                 patch=BezierPatchMesh(b,segments,segments)
  96.                 EntityTexture patch,patchtexture
  97.  
  98.        
  99.         ElseIf KeyDown(209)    
  100.        
  101.                 bpy[selectedpoint]=bpy[selectedpoint]-0.5
  102.                 If patch<>0
  103.                         FreeEntity patch
  104.                         patch=0
  105.                 EndIf
  106.                
  107.                 patch=BezierPatchMesh(b,segments,segments)
  108.                 EntityTexture patch,patchtexture
  109.  
  110.  
  111.         EndIf
  112.        
  113.  
  114. EndIf
  115.  
  116. If KeyHit(78)
  117.  
  118.         segments=segments+1
  119.         If patch<>0
  120.                 FreeEntity patch
  121.                 patch=0
  122.         EndIf
  123.        
  124.         patch=BezierPatchMesh(b,segments,segments)
  125.         EntityTexture patch,patchtexture
  126.  
  127.  
  128. ElseIf KeyHit(74)      
  129.  
  130.         segments=segments-1
  131.         If segments<1
  132.                 segments=1
  133.         EndIf
  134.         If patch<>0
  135.                 FreeEntity patch
  136.                 patch=0
  137.         EndIf
  138.        
  139.         patch=BezierPatchMesh(b,segments,segments)
  140.         EntityTexture patch,patchtexture
  141.  
  142. EndIf
  143.  
  144. If KeyHit(57)
  145.  
  146.         wire=1-wire
  147.         WireFrame wire
  148.  
  149. EndIf
  150.  
  151.  
  152. RenderWorld
  153.  
  154. Color 0,0,255
  155. BezierPatchDraw(b,camera,selectedpoint)
  156.  
  157. Color 0,0,0
  158. Text 401,11,"Bezier Patch example by Jeppe Nielsen, 2005",True
  159. Text 401,31,"Left mouse button to move control points",True
  160. Text 401,51,"Right mouse button & mouse to rotate camera, cursor keys to move camera",True
  161. Text 401,71,"Page Up/down to move selected control point up/down",True
  162. Text 401,91,"+ / - to adjust polygon segments : "+segments,True
  163. Text 401,111,"Space to toggle wireframe",True
  164.  
  165. Color 0,128,255
  166. Text 400,10,"Bezier Patch example by Jeppe Nielsen, 2005",True
  167. Text 400,30,"Left mouse button to move control points",True
  168. Text 401,51,"Right mouse button & mouse to rotate camera, cursor keys to move camera",True
  169. Text 400,70,"Page Up/down to move selected control point up/down",True
  170. Text 400,90,"+ / - to adjust polygon segments : "+segments,True
  171. Text 400,110,"Space to toggle wireframe",True
  172.  
  173. x=MouseX()
  174. y=MouseY()
  175.  
  176. Color 255,255,255
  177.  
  178. Rect x-6,y,13,1
  179. Rect x,y-6,1,13
  180.  
  181.  
  182. Flip
  183.  
  184. Until KeyDown(1)
  185. End
  186.  
  187.  
  188. Type bezierpatch
  189.  
  190. Field px#[15]
  191. Field py#[15]
  192. Field pz#[15]
  193.  
  194. End Type
  195.  
  196. Function BezierPatchNew.bezierpatch()
  197.  
  198. b.bezierpatch=New bezierpatch
  199.  
  200. For u=0 To 3
  201.        
  202.         For v=0 To 3
  203.        
  204.                 bpx[u+v*4]=u*3
  205.                 bpy[u+v*4]=0
  206.                 bpz[u+v*4]=v*3
  207.                
  208.         Next
  209.        
  210. Next
  211.  
  212. Return b
  213. End Function
  214.  
  215. Function BezierPatchSetPoint(b.bezierpatch,point,x#,y#,z#)
  216.  
  217.         bpx[point]=x
  218.         bpy[point]=y
  219.         bpz[point]=z
  220.  
  221. End Function
  222.  
  223. Function BezierPatchGetPoint(b.bezierpatch,cam,x,y,size=15)
  224.  
  225. sizesq=size*size
  226.  
  227. For n=0 To 15
  228.        
  229.         CameraProject cam,bpx[n],bpy[n],bpz[n]
  230.        
  231.         dx=x-ProjectedX()
  232.         dy=y-ProjectedY()
  233.  
  234.         dist=dx*dx+dy*dy
  235.  
  236.         If dist<=sizesq
  237.                 Return n
  238.         EndIf
  239.        
  240. Next
  241.  
  242. Return -1
  243. End Function
  244.  
  245. Function BezierPatchMesh(b.bezierpatch,useg=10,vseg=10)
  246.  
  247. mesh=CreateMesh()
  248.  
  249. surf=CreateSurface(mesh)
  250.  
  251. usegstep#=1/Float(useg)
  252. vsegstep#=1/Float(vseg)
  253.  
  254. v#=0
  255.  
  256. While v<0.99
  257.  
  258.         u#=0
  259.  
  260.         While u<0.99
  261.        
  262.                 uu#=u
  263.                
  264.                 px1#=bpx[0]*(1-uu)^3 + bpx[1]*3*(1-uu)^2*uu + bpx[2]*3*(1-uu)*uu*uu + bpx[3]*uu^3
  265.                 py1#=bpy[0]*(1-uu)^3 + bpy[1]*3*(1-uu)^2*uu + bpy[2]*3*(1-uu)*uu*uu + bpy[3]*uu^3
  266.                 pz1#=bpz[0]*(1-uu)^3 + bpz[1]*3*(1-uu)^2*uu + bpz[2]*3*(1-uu)*uu*uu + bpz[3]*uu^3
  267.                
  268.                 px2#=bpx[4]*(1-uu)^3 + bpx[5]*3*(1-uu)^2*uu + bpx[6]*3*(1-uu)*uu*uu + bpx[7]*uu^3
  269.                 py2#=bpy[4]*(1-uu)^3 + bpy[5]*3*(1-uu)^2*uu + bpy[6]*3*(1-uu)*uu*uu + bpy[7]*uu^3
  270.                 pz2#=bpz[4]*(1-uu)^3 + bpz[5]*3*(1-uu)^2*uu + bpz[6]*3*(1-uu)*uu*uu + bpz[7]*uu^3
  271.                
  272.                 px3#=bpx[8]*(1-uu)^3 + bpx[9]*3*(1-uu)^2*uu + bpx[10]*3*(1-uu)*uu*uu + bpx[11]*uu^3
  273.                 py3#=bpy[8]*(1-uu)^3 + bpy[9]*3*(1-uu)^2*uu + bpy[10]*3*(1-uu)*uu*uu + bpy[11]*uu^3
  274.                 pz3#=bpz[8]*(1-uu)^3 + bpz[9]*3*(1-uu)^2*uu + bpz[10]*3*(1-uu)*uu*uu + bpz[11]*uu^3
  275.                
  276.                 px4#=bpx[12]*(1-uu)^3 + bpx[13]*3*(1-uu)^2*uu + bpx[14]*3*(1-uu)*uu*uu + bpx[15]*uu^3
  277.                 py4#=bpy[12]*(1-uu)^3 + bpy[13]*3*(1-uu)^2*uu + bpy[14]*3*(1-uu)*uu*uu + bpy[15]*uu^3
  278.                 pz4#=bpz[12]*(1-uu)^3 + bpz[13]*3*(1-uu)^2*uu + bpz[14]*3*(1-uu)*uu*uu + bpz[15]*uu^3
  279.                
  280.                 vv#=v
  281.                
  282.                 x1# = px1*(1-vv)^3 + 3*px2*(1-vv)^2*vv + 3*px3*(1-vv)*vv*vv + px4*vv^3
  283.                 y1# = py1*(1-vv)^3 + 3*py2*(1-vv)^2*vv + 3*py3*(1-vv)*vv*vv + py4*vv^3
  284.                 z1# = pz1*(1-vv)^3 + 3*pz2*(1-vv)^2*vv + 3*pz3*(1-vv)*vv*vv + pz4*vv^3
  285.                
  286.                 uu#=u+usegstep
  287.                
  288.                 px1#=bpx[0]*(1-uu)^3 + bpx[1]*3*(1-uu)^2*uu + bpx[2]*3*(1-uu)*uu*uu + bpx[3]*uu^3
  289.                 py1#=bpy[0]*(1-uu)^3 + bpy[1]*3*(1-uu)^2*uu + bpy[2]*3*(1-uu)*uu*uu + bpy[3]*uu^3
  290.                 pz1#=bpz[0]*(1-uu)^3 + bpz[1]*3*(1-uu)^2*uu + bpz[2]*3*(1-uu)*uu*uu + bpz[3]*uu^3
  291.                
  292.                 px2#=bpx[4]*(1-uu)^3 + bpx[5]*3*(1-uu)^2*uu + bpx[6]*3*(1-uu)*uu*uu + bpx[7]*uu^3
  293.                 py2#=bpy[4]*(1-uu)^3 + bpy[5]*3*(1-uu)^2*uu + bpy[6]*3*(1-uu)*uu*uu + bpy[7]*uu^3
  294.                 pz2#=bpz[4]*(1-uu)^3 + bpz[5]*3*(1-uu)^2*uu + bpz[6]*3*(1-uu)*uu*uu + bpz[7]*uu^3
  295.                
  296.                 px3#=bpx[8]*(1-uu)^3 + bpx[9]*3*(1-uu)^2*uu + bpx[10]*3*(1-uu)*uu*uu + bpx[11]*uu^3
  297.                 py3#=bpy[8]*(1-uu)^3 + bpy[9]*3*(1-uu)^2*uu + bpy[10]*3*(1-uu)*uu*uu + bpy[11]*uu^3
  298.                 pz3#=bpz[8]*(1-uu)^3 + bpz[9]*3*(1-uu)^2*uu + bpz[10]*3*(1-uu)*uu*uu + bpz[11]*uu^3
  299.                
  300.                 px4#=bpx[12]*(1-uu)^3 + bpx[13]*3*(1-uu)^2*uu + bpx[14]*3*(1-uu)*uu*uu + bpx[15]*uu^3
  301.                 py4#=bpy[12]*(1-uu)^3 + bpy[13]*3*(1-uu)^2*uu + bpy[14]*3*(1-uu)*uu*uu + bpy[15]*uu^3
  302.                 pz4#=bpz[12]*(1-uu)^3 + bpz[13]*3*(1-uu)^2*uu + bpz[14]*3*(1-uu)*uu*uu + bpz[15]*uu^3
  303.                
  304.                 vv#=v
  305.                
  306.                 x2# = px1*(1-vv)^3 + 3*px2*(1-vv)^2*vv + 3*px3*(1-vv)*vv*vv + px4*vv^3
  307.                 y2# = py1*(1-vv)^3 + 3*py2*(1-vv)^2*vv + 3*py3*(1-vv)*vv*vv + py4*vv^3
  308.                 z2# = pz1*(1-vv)^3 + 3*pz2*(1-vv)^2*vv + 3*pz3*(1-vv)*vv*vv + pz4*vv^3
  309.                
  310.                 uu#=u
  311.                
  312.                 px1#=bpx[0]*(1-uu)^3 + bpx[1]*3*(1-uu)^2*uu + bpx[2]*3*(1-uu)*uu*uu + bpx[3]*uu^3
  313.                 py1#=bpy[0]*(1-uu)^3 + bpy[1]*3*(1-uu)^2*uu + bpy[2]*3*(1-uu)*uu*uu + bpy[3]*uu^3
  314.                 pz1#=bpz[0]*(1-uu)^3 + bpz[1]*3*(1-uu)^2*uu + bpz[2]*3*(1-uu)*uu*uu + bpz[3]*uu^3
  315.                
  316.                 px2#=bpx[4]*(1-uu)^3 + bpx[5]*3*(1-uu)^2*uu + bpx[6]*3*(1-uu)*uu*uu + bpx[7]*uu^3
  317.                 py2#=bpy[4]*(1-uu)^3 + bpy[5]*3*(1-uu)^2*uu + bpy[6]*3*(1-uu)*uu*uu + bpy[7]*uu^3
  318.                 pz2#=bpz[4]*(1-uu)^3 + bpz[5]*3*(1-uu)^2*uu + bpz[6]*3*(1-uu)*uu*uu + bpz[7]*uu^3
  319.                
  320.                 px3#=bpx[8]*(1-uu)^3 + bpx[9]*3*(1-uu)^2*uu + bpx[10]*3*(1-uu)*uu*uu + bpx[11]*uu^3
  321.                 py3#=bpy[8]*(1-uu)^3 + bpy[9]*3*(1-uu)^2*uu + bpy[10]*3*(1-uu)*uu*uu + bpy[11]*uu^3
  322.                 pz3#=bpz[8]*(1-uu)^3 + bpz[9]*3*(1-uu)^2*uu + bpz[10]*3*(1-uu)*uu*uu + bpz[11]*uu^3
  323.                
  324.                 px4#=bpx[12]*(1-uu)^3 + bpx[13]*3*(1-uu)^2*uu + bpx[14]*3*(1-uu)*uu*uu + bpx[15]*uu^3
  325.                 py4#=bpy[12]*(1-uu)^3 + bpy[13]*3*(1-uu)^2*uu + bpy[14]*3*(1-uu)*uu*uu + bpy[15]*uu^3
  326.                 pz4#=bpz[12]*(1-uu)^3 + bpz[13]*3*(1-uu)^2*uu + bpz[14]*3*(1-uu)*uu*uu + bpz[15]*uu^3
  327.                
  328.                 vv#=v+vsegstep
  329.                
  330.                 x3# = px1*(1-vv)^3 + 3*px2*(1-vv)^2*vv + 3*px3*(1-vv)*vv*vv + px4*vv^3
  331.                 y3# = py1*(1-vv)^3 + 3*py2*(1-vv)^2*vv + 3*py3*(1-vv)*vv*vv + py4*vv^3
  332.                 z3# = pz1*(1-vv)^3 + 3*pz2*(1-vv)^2*vv + 3*pz3*(1-vv)*vv*vv + pz4*vv^3
  333.                
  334.                 uu#=u+usegstep
  335.                
  336.                 px1#=bpx[0]*(1-uu)^3 + bpx[1]*3*(1-uu)^2*uu + bpx[2]*3*(1-uu)*uu*uu + bpx[3]*uu^3
  337.                 py1#=bpy[0]*(1-uu)^3 + bpy[1]*3*(1-uu)^2*uu + bpy[2]*3*(1-uu)*uu*uu + bpy[3]*uu^3
  338.                 pz1#=bpz[0]*(1-uu)^3 + bpz[1]*3*(1-uu)^2*uu + bpz[2]*3*(1-uu)*uu*uu + bpz[3]*uu^3
  339.                
  340.                 px2#=bpx[4]*(1-uu)^3 + bpx[5]*3*(1-uu)^2*uu + bpx[6]*3*(1-uu)*uu*uu + bpx[7]*uu^3
  341.                 py2#=bpy[4]*(1-uu)^3 + bpy[5]*3*(1-uu)^2*uu + bpy[6]*3*(1-uu)*uu*uu + bpy[7]*uu^3
  342.                 pz2#=bpz[4]*(1-uu)^3 + bpz[5]*3*(1-uu)^2*uu + bpz[6]*3*(1-uu)*uu*uu + bpz[7]*uu^3
  343.                
  344.                 px3#=bpx[8]*(1-uu)^3 + bpx[9]*3*(1-uu)^2*uu + bpx[10]*3*(1-uu)*uu*uu + bpx[11]*uu^3
  345.                 py3#=bpy[8]*(1-uu)^3 + bpy[9]*3*(1-uu)^2*uu + bpy[10]*3*(1-uu)*uu*uu + bpy[11]*uu^3
  346.                 pz3#=bpz[8]*(1-uu)^3 + bpz[9]*3*(1-uu)^2*uu + bpz[10]*3*(1-uu)*uu*uu + bpz[11]*uu^3
  347.                
  348.                 px4#=bpx[12]*(1-uu)^3 + bpx[13]*3*(1-uu)^2*uu + bpx[14]*3*(1-uu)*uu*uu + bpx[15]*uu^3
  349.                 py4#=bpy[12]*(1-uu)^3 + bpy[13]*3*(1-uu)^2*uu + bpy[14]*3*(1-uu)*uu*uu + bpy[15]*uu^3
  350.                 pz4#=bpz[12]*(1-uu)^3 + bpz[13]*3*(1-uu)^2*uu + bpz[14]*3*(1-uu)*uu*uu + bpz[15]*uu^3
  351.                
  352.                 vv#=v+vsegstep
  353.                
  354.                 x4# = px1*(1-vv)^3 + 3*px2*(1-vv)^2*vv + 3*px3*(1-vv)*vv*vv + px4*vv^3
  355.                 y4# = py1*(1-vv)^3 + 3*py2*(1-vv)^2*vv + 3*py3*(1-vv)*vv*vv + py4*vv^3
  356.                 z4# = pz1*(1-vv)^3 + 3*pz2*(1-vv)^2*vv + 3*pz3*(1-vv)*vv*vv + pz4*vv^3
  357.                
  358.                
  359.                 vert=AddVertex(surf,x1,y1,z1,u,v)
  360.                      AddVertex(surf,x2,y2,z2,u+usegstep,v)
  361.                      AddVertex(surf,x3,y3,z3,u,v+vsegstep)
  362.                      AddVertex(surf,x4,y4,z4,u+usegstep,v+vsegstep)
  363.                
  364.                         AddTriangle surf,vert+0,vert+3,vert+1
  365.                         AddTriangle surf,vert+0,vert+2,vert+3
  366.                
  367.                 u=u+usegstep
  368.  
  369.         Wend
  370.  
  371.         v=v+vsegstep
  372.  
  373. Wend
  374.  
  375. UpdateNormals mesh
  376.  
  377. Return mesh
  378. End Function
  379.  
  380. Function BezierPatchDraw(b.bezierpatch,cam,selectedpoint)
  381.  
  382. Local projx[15],projy[15]
  383.  
  384. For n=0 To 15
  385.        
  386.         CameraProject cam,bpx[n],bpy[n],bpz[n]
  387.        
  388.         projx[n]=ProjectedX()
  389.         projy[n]=ProjectedY()
  390.        
  391.         If selectedpoint=n
  392.        
  393.                 Color 255,255,0
  394.        
  395.         Else
  396.        
  397.                 Color 0,0,255
  398.        
  399.         EndIf
  400.        
  401.         Oval projx[n]-5,projy[n]-5,10,10,True
  402.        
  403.        
  404. Next
  405.  
  406. Color 0,255,0
  407.  
  408. For u=0 To 3
  409.        
  410.         For v=0 To 3
  411.                 If u<3
  412.                 Line projx[u+v*4],projy[u+v*4],projx[u+v*4+1],projy[u+v*4+1]
  413.                 EndIf
  414.                 If v<3
  415.                 Line projx[u+v*4],projy[u+v*4],projx[u+v*4+4],projy[u+v*4+4]
  416.                 EndIf
  417.                
  418.         Next
  419.        
  420. Next
  421.  
  422. End Function
  423.  
  424. Function CameraInit(r=0,g=0,b=0,x#=12,y#=10,z#=12,px#=0,py#=0,pz#=0)
  425.  
  426.         camera=CreateCamera()
  427.         CameraClsColor camera,r,g,b
  428.         PositionEntity camera,x,y,z
  429.         p=CreatePivot()
  430.         PositionEntity p,px,py,pz
  431.         PointEntity camera,p
  432.         FreeEntity p
  433.         MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
  434.         camerarx=EntityPitch(camera)
  435.         camerary=EntityYaw(camera)
  436.                
  437. End Function
  438.  
  439. Function CameraClear()
  440.  
  441.         If camera<>0 Then FreeEntity camera     : camera=0
  442.        
  443. End Function
  444.  
  445. Function CameraUpdate(speed#=1)
  446.  
  447.                
  448.         If MouseHit(2)
  449.        
  450.         MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
  451.                
  452.         EndIf
  453.        
  454.         If MouseDown(2)
  455.  
  456.                 camerarx#=camerarx#+MouseYSpeed()*0.5
  457.                 camerary#=camerary#-MouseXSpeed()*0.5
  458.                 If camerarx#>89
  459.                         camerarx#=89
  460.                 ElseIf camerarx#<-89
  461.                         camerarx#=-89
  462.                 EndIf
  463.                 RotateEntity camera,camerarx,camerary,0
  464.                 MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
  465.                
  466.         EndIf
  467.        
  468.         If KeyDown(200) Or KeyDown(17) Then MoveEntity camera,0,0,speed#
  469.         If KeyDown(208) Or KeyDown(31) Then MoveEntity camera,0,0,-speed#
  470.         If KeyDown(203) Or KeyDown(30) Then MoveEntity camera,-speed#,0,0
  471.         If KeyDown(205) Or KeyDown(32) Then MoveEntity camera,speed#,0,0
  472.        
  473. End Function


Comments :


BlitzSupport(Posted 1+ years ago)

 Very cool indeed -- only thing is you have to run windowed as there's no pointer in full-screen mode! The resulting meshes look great though.


Jeppe Nielsen(Posted 1+ years ago)

 Yes I forgot to include a pointer as I was creating this in windowed mode :-)I have updated the code now.


Barliesque(Posted 1+ years ago)

 Looking forward to seeing this when I get home to my own computer... for now, I'm wondering if this might be a basis for supporting models from Hash Animation:Master--which is patch-based.


WarpZone(Posted 1+ years ago)

 Wow.  This is great.  This explains all those terrain programs that suddenly appeared simultaneously. =)  Now if only I UNDERSTOOD enough of what was going on here to make it *scalable.*


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal