October 19, 2021, 09:03:57

Author Topic: [bb] Mesh Clipping Demo by big10p [ 1+ years ago ]  (Read 796 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Mesh Clipping Demo by big10p [ 1+ years ago ]
« on: June 29, 2017, 00:28:38 »
Title : Mesh Clipping Demo
Author : big10p
Posted : 1+ years ago

Description : Makes a copy of an existing mesh but cut in half (or whatever) along an arbitrary plane.

Could be used for various nifty in-game effects such as spawning etc., especially if used in conjuction with a decent particle system.

No media files required - therefore the demo meshes are a bit boring but try it on one of your own models!


Code :
Code: BlitzBasic
  1. ;
  2. ; Mesh clip demo by big10p (A.K.A. Chris Chadwick) 2004.
  3. ;
  4. ; Written with Blitz3D v1.87
  5. ;
  6. ; Known issues:
  7. ; 1) copy_mesh_clip() attempts to paint the clipped mesh with the same brushes
  8. ;    that are applied to the mesh being copied. For multiple surface meshes,
  9. ;    GetSurfaceBrush() is used but only works if the mesh's surfaces have been
  10. ;    painted with PaintSurface(). If the multi surface mesh has been painted
  11. ;    en masse - using EntityTexture, EntityColor etc. - it doesn't work.
  12. ; 2) There seems to be a slight, noticeable color change when clipping tris that
  13. ;    are vertex colored. Not sure if this is down to a lack of precision with floats
  14. ;    or something I'm doing wrong. I'll have to investigate some more, I think. :)
  15. ; 3) I seem to get a much higher FPS (with frame locking turned off) if I turn off the
  16. ;    visible clipping plane. Not sure why it makes such a big difference as it's only
  17. ;    one surface with two triangles in!? :/
  18. ;
  19.  
  20.  
  21.         Graphics3D 800,600,32
  22.  
  23.         ; Create chequer pattern texture.
  24.         Global tex = CreateTexture(64,64)
  25.         SetBuffer TextureBuffer(tex)
  26.         For y = 0 To 63 Step 4
  27.                 For x = 0 To 63 Step 2
  28.                         If c Then Color 255,255,255 Else Color 255,0,0
  29.                         c = Not c
  30.                         Rect x,y,2,4
  31.                 Next
  32.                 c = Not c
  33.         Next
  34.         SetBuffer BackBuffer()
  35.        
  36.         WireFrame 0
  37.         AntiAlias 0
  38.  
  39.         SeedRnd MilliSecs()
  40.  
  41.         ; Demo mesh info type.
  42.         Type infoT
  43.                 Field mesh
  44.                 Field FX%
  45.                 Field vert_info%
  46.         End Type
  47.        
  48.         ; Frame timing and control.
  49.         Global frame_count%
  50.         Global fps%
  51.         Global slowest_fps%
  52.         Global fps_timeout%
  53.         Global frame_time%
  54.         Global slowest_frame%
  55.         Global frame_start%
  56.         fps_timer = CreateTimer(60)
  57.  
  58.         ; Demo state flags.
  59.         show_text% = True
  60.         show_plane% = True
  61.         rotate_plane% = True
  62.         rotate_mesh% = True
  63.         cull_backface% = False
  64.         wiref% = False
  65.         slowmo% = False
  66.         frame_lock% = True
  67.  
  68.         ; Flags to tell clip_tri functions the order to wind triangles.
  69.         Const WIND_012% = 0
  70.         Const WIND_102% = 1
  71.         Const WIND_201% = 2
  72.  
  73.         ; Flags to tell copy_mesh_clip() which vertex info to include when clipping.
  74.         Const CLIP_NORMALS% = 1
  75.         Const CLIP_UV_SET0% = 2
  76.         Const CLIP_UV_SET1% = 4
  77.         Const CLIP_RGBA%    = 8
  78.         Const DEF_CLIP_INFO% = CLIP_NORMALS+CLIP_UV_SET0
  79.        
  80.         cam = CreateCamera()
  81.         CameraRange cam,1,100
  82.         PositionEntity cam,0,0,-3
  83.        
  84.         light = CreateLight()
  85.         AmbientLight 100,100,100
  86.        
  87.         ; Create the demo meshes.
  88.         Dim mesh.infoT(0)
  89.         create_meshes()
  90.         current_mesh% = 0
  91.                        
  92.         ; Clipping plane.
  93.         Const MAX_PLANE_DIST# = 1.3
  94.         plane_pitch# = 0
  95.         plane_yaw# = 0
  96.         plane_dist# = -MAX_PLANE_DIST
  97.         plane_move# = 0.01     
  98.         plane_piv = CreatePivot()
  99.         plane = CreateMesh(plane_piv)
  100.         ps = CreateSurface(plane)
  101.         AddVertex(ps,-2,0,2)
  102.         AddVertex(ps,2,0,2)
  103.         AddVertex(ps,-2,0,-2)
  104.         AddVertex(ps,2,0,-2)
  105.         AddTriangle(ps,0,1,2)
  106.         AddTriangle(ps,1,3,2)
  107.         EntityAlpha plane,.3
  108.         EntityColor plane,0,0,200
  109.         EntityFX plane,1+16
  110.         PositionEntity plane,0,plane_dist,0
  111.         RotateEntity plane_piv,plane_pitch,plane_yaw,0
  112.        
  113.         clip_mesh = copy_mesh_clip(mesh(current_mesh)mesh,plane_dist,plane_pitch,plane_yaw,mesh(current_mesh)vert_info)
  114.         EntityFX clip_mesh,mesh(current_mesh)FX Xor (cull_backface Shl 4)
  115.  
  116.         ;
  117.         ; --- Main loop ---
  118.         ;
  119.        
  120.         While Not KeyHit(1)
  121.  
  122.                 frame_start = MilliSecs()
  123.        
  124.                 If KeyHit(2) Then show_text = Not show_text
  125.                 If KeyHit(3)
  126.                         show_plane = Not show_plane
  127.                         If show_plane Then ShowEntity plane Else HideEntity plane
  128.                 EndIf
  129.                 If KeyHit(4)
  130.                         rotate_plane = Not rotate_plane
  131.                         plane_pitch = 0
  132.                         plane_yaw = 0
  133.                 EndIf
  134.                 If KeyHit(5) Then rotate_mesh = Not rotate_mesh
  135.                 If KeyHit(6) Then cull_backface = Not cull_backface
  136.                 If KeyHit(7) Then wiref = Not wiref : WireFrame wiref
  137.                 If KeyHit(8) Then slowmo = Not slowmo
  138.                 If KeyHit(9) Then frame_lock = Not frame_lock
  139.                 If KeyHit(57) Then current_mesh = (current_mesh + 1) Mod 5
  140.  
  141.                 If rotate_mesh Then RotateMesh mesh(current_mesh)mesh,1,0,1
  142.  
  143.                 ; Change clipping plane distance.
  144.                 plane_dist = plane_dist + plane_move
  145.                 If Abs(plane_dist) > MAX_PLANE_DIST Then plane_move = -plane_move
  146.                
  147.                 ; Rotate clipping plane.
  148.                 If rotate_plane
  149.                         plane_pitch = (plane_pitch + 1) Mod 360
  150.                         plane_yaw = (plane_yaw + .5) Mod 360
  151.                 EndIf
  152.                
  153.                 ; Create an updated, clipped version of the current mesh.
  154.                 FreeEntity clip_mesh
  155.                 clip_mesh = copy_mesh_clip(mesh(current_mesh)mesh,plane_dist,plane_pitch,plane_yaw,mesh(current_mesh)vert_info)
  156.                 EntityFX clip_mesh,mesh(current_mesh)FX Xor (cull_backface Shl 4)
  157.  
  158.                 ; Position visible plane to match clipping plane.
  159.                 If show_plane
  160.                         PositionEntity plane,0,plane_dist,0
  161.                         RotateEntity plane_piv,plane_pitch,plane_yaw,0
  162.                 EndIf
  163.                
  164.                 RenderWorld
  165.  
  166.                 frame_time = MilliSecs() - frame_start 
  167.                 If show_text Then show_info()
  168.  
  169.                 If frame_lock
  170.                         WaitTimer(fps_timer)
  171.                         Flip True
  172.                 Else
  173.                         Flip False
  174.                 EndIf
  175.  
  176.                 If slowmo Then Delay 200
  177.  
  178.         Wend
  179.  
  180.         End
  181.  
  182.  
  183. ;
  184. ; Creates a copy of a mesh, clipped along the given plane.
  185. ; Note: this function can only really perform clipping along an XZ aligned plane.
  186. ;       To perform clipping on an arbitrary, rotated plane, we cheat :) - first
  187. ;       we align the mesh to the XZ plane, perform the clipping, then return
  188. ;       the mesh to it's original orientation.
  189. ;
  190. ; Params:
  191. ; source_mesh - Mesh to be copied (remains unaltered by this function).
  192. ; plane_y     - Y distance of clipping plane from mesh origin.
  193. ; plane_pitch - Pitch of clipping plane.
  194. ; plane_yaw   - Yaw of clipping plane.
  195. ; vert_info   - Bit flags defining vertex info to include when clipping.
  196. ;
  197. ; Returns:
  198. ; Handle of newly created, clipped mesh.
  199. ;
  200. Function copy_mesh_clip(source_mesh,plane_y#,plane_pitch#,plane_yaw#,vert_info%=DEF_CLIP_INFO)
  201.  
  202.         surf_count = CountSurfaces(source_mesh)
  203.  
  204.         ; Temporarily align source mesh to XZ clipping plane.
  205.         ; Note: doing yaw THEN pitch rotation separately is important!
  206.         ; Prevents gimble lock when returning the mesh back to it's original rotation.
  207.         RotateMesh source_mesh,0,-plane_yaw,0
  208.         RotateMesh source_mesh,-plane_pitch,0,0
  209.  
  210.         If surf_count=1
  211.                 ; We can make a copy of single surface meshes more quickly using CopyMesh.
  212.                 ; (Unfortunately, CopyMesh combines surfs unless they use different textures
  213.                 ; so this method can't be used with multi surface meshes).
  214.                 dest_mesh = CopyMesh(source_mesh)
  215.  
  216.                 ; Kill tris but keep verts.
  217.                 ClearSurface GetSurface(dest_mesh,1),False,True
  218.  
  219.                 brush = GetEntityBrush(source_mesh)
  220.                 PaintEntity dest_mesh,brush
  221.                 FreeBrush brush
  222.         Else
  223.                 dest_mesh = CreateMesh()
  224.        
  225.                 ; Copy all surfaces and vertices from source_mesh into dest_mesh.
  226.                 ;
  227.                 For ss=1 To surf_count
  228.                        
  229.                         source_surf = GetSurface(source_mesh,ss)
  230.                         brush = GetSurfaceBrush(source_surf)
  231.                         dest_surf = CreateSurface(dest_mesh,brush)
  232.                         FreeBrush brush
  233.        
  234.                         For sv=0 To CountVertices(source_surf)-1
  235.                                 vy# = VertexY(source_surf,sv)
  236.                                 dv = AddVertex(dest_surf,VertexX(source_surf,sv),vy,VertexZ(source_surf,sv))
  237.                                
  238.                                 ; We don't need to bother with any other info for verts
  239.                                 ; in dest_mesh that are beyond the clipping plane.
  240.                                 If Not vy<plane_y
  241.                                         VertexNormal dest_surf,dv,VertexNX(source_surf,sv),VertexNY(source_surf,sv),VertexNZ(source_surf,sv)
  242.                                         VertexTexCoords dest_surf,dv,VertexU(source_surf,sv,0),VertexV(source_surf,sv,0),0, 0
  243.                                         VertexTexCoords dest_surf,dv,VertexU(source_surf,sv,1),VertexV(source_surf,sv,1),0, 1
  244.                                         VertexColor dest_surf,dv,VertexRed(source_surf,sv),VertexGreen(source_surf,sv),VertexBlue(source_surf,sv),VertexAlpha(source_surf,sv)
  245.                                 EndIf
  246.                         Next
  247.                 Next
  248.         EndIf  
  249.  
  250.         ; Process all surfaces in source_mesh...
  251.         ;
  252.         For ss=1 To CountSurfaces(source_mesh)
  253.                
  254.                 source_surf = GetSurface(source_mesh,ss)
  255.                 dest_surf = GetSurface(dest_mesh,ss)
  256.                
  257.                 ; Process all trinagles in source_surf...
  258.                 ;
  259.                 For t=0 To CountTriangles(source_surf)-1
  260.  
  261.                         v0 = TriangleVertex(source_surf,t,0)
  262.                         v1 = TriangleVertex(source_surf,t,1)
  263.                         v2 = TriangleVertex(source_surf,t,2)
  264.                        
  265.                         clip0 = VertexY(source_surf,v0) < plane_y
  266.                         clip1 = VertexY(source_surf,v1) < plane_y
  267.                         clip2 = VertexY(source_surf,v2) < plane_y
  268.                        
  269.                         Select clip0+clip1+clip2
  270.                        
  271.                         Case 0  ; There are no 'bad' verts in this triangle...
  272.                        
  273.                                 ; Add this triangle so it's the same as it appears in source_surf.
  274.                                 AddTriangle(dest_surf,v0,v1,v2)
  275.  
  276.                         Case 1  ; There is 1 'bad' vert in this triangle...
  277.                                        
  278.                                 ;Find the 1 'bad' vert.
  279.                                 ;
  280.                                 If clip0                ; v0 is bad...
  281.  
  282.                                         clip_tri_1bad(source_surf,dest_surf,plane_y, v0,v1,v2, WIND_012, vert_info)
  283.  
  284.                                 ElseIf clip1    ;v1 is bad...
  285.  
  286.                                         clip_tri_1bad(source_surf,dest_surf,plane_y, v1,v0,v2, WIND_102, vert_info)
  287.                                
  288.                                 Else                    ;v2 is bad...
  289.  
  290.                                         clip_tri_1bad(source_surf,dest_surf,plane_y, v2,v0,v1, WIND_201, vert_info)
  291.                        
  292.                                 EndIf
  293.                                
  294.                         Case 2  ; There are 2 'bad' verts in this triangle...
  295.                        
  296.                                 ; Find the 1 'good' vert.
  297.                                 ;
  298.                                 If Not clip0            ; v0 is good...
  299.                                
  300.                                         clip_tri_2bad(source_surf,dest_surf,plane_y, v0,v1,v2, WIND_012, vert_info)
  301.  
  302.                                 ElseIf Not clip1        ; v1 is good...
  303.  
  304.                                         clip_tri_2bad(source_surf,dest_surf,plane_y, v1,v0,v2, WIND_102, vert_info)
  305.  
  306.                                 Else                            ; v2 is good...
  307.  
  308.                                         clip_tri_2bad(source_surf,dest_surf,plane_y, v2,v0,v1, WIND_201, vert_info)
  309.  
  310.                                 EndIf                          
  311.  
  312.                         End Select
  313.  
  314.                 Next
  315.                
  316.         Next
  317.  
  318.         ; Rotate source_mesh and dest_mesh to source_mesh's original rotation.
  319.         RotateMesh source_mesh,plane_pitch,plane_yaw,0
  320.         RotateMesh dest_mesh,plane_pitch,plane_yaw,0
  321.  
  322.         Return dest_mesh
  323.        
  324. End Function
  325.  
  326.  
  327. ;
  328. ; Creates a clipped triangle from a source_surf triangle that has 2 'bad' vertices. i.e. 2 of the
  329. ; triangles verts are beyond the clipping plane.
  330. ;
  331. ; Params:
  332. ; source_surf - Surface containing the triangle to be clipped.
  333. ; dest_surf   - Surface to build the clipped triangle in.
  334. ; plane_y     - Y distance of clipping plane from mesh origin.
  335. ; good_v      - Index of the one 'good' vertex in triangle.
  336. ; bad1_v      - Index of the first 'bad' vertex in the triangle.
  337. ; bad2_v      - Index of the second 'bad' vertex in the triangle.
  338. ; wind_order  - Flag indicating the order to wind the clipped triangle.
  339. ; vert_info   - Bit flags defining vertex info to include when clipping.
  340. ;
  341. Function clip_tri_2bad(source_surf,dest_surf,plane_y#, good_v%,bad1_v%,bad2_v%, wind_order%, vert_info%)
  342.  
  343.         ; Retrieve good/bad vert coords.
  344.         good_vx# = VertexX(source_surf,good_v)
  345.         good_vy# = VertexY(source_surf,good_v)
  346.         good_vz# = VertexZ(source_surf,good_v)
  347.         bad1_vx# = VertexX(source_surf,bad1_v)
  348.         bad1_vy# = VertexY(source_surf,bad1_v)
  349.         bad1_vz# = VertexZ(source_surf,bad1_v)
  350.         bad2_vx# = VertexX(source_surf,bad2_v)
  351.         bad2_vy# = VertexY(source_surf,bad2_v)
  352.         bad2_vz# = VertexZ(source_surf,bad2_v)
  353.  
  354.         ; Find Y distance from good vert to clipping plane.
  355.         clip_y_dist# = good_vy-plane_y
  356.  
  357.         ;
  358.         ; Calculate & add first new vert...
  359.         ;
  360.        
  361.         ; Vector to bad vert 1 from good vert.
  362.         xv# = bad1_vx-good_vx
  363.         yv# = bad1_vy-good_vy
  364.         zv# = bad1_vz-good_vz
  365.        
  366.         y_dist# = good_vy-bad1_vy
  367.         side# = 1.0/y_dist
  368.         ratio1# = clip_y_dist*side
  369.         new1_v = AddVertex(dest_surf,good_vx+xv*ratio1,good_vy+yv*ratio1,good_vz+zv*ratio1)
  370.  
  371.         ;
  372.         ; Calculate & add second new vert...
  373.         ;
  374.        
  375.         ; Vector to bad vert 2 from good vert.
  376.         xv# = bad2_vx-good_vx
  377.         yv# = bad2_vy-good_vy
  378.         zv# = bad2_vz-good_vz
  379.        
  380.         y_dist# = good_vy-bad2_vy
  381.         side# = 1.0/y_dist
  382.         ratio2# = clip_y_dist*side
  383.         new2_v = AddVertex(dest_surf,good_vx+xv*ratio2,good_vy+yv*ratio2,good_vz+zv*ratio2)
  384.  
  385.         ; Make the clipped triangle, wound in the specified way.
  386.         Select wind_order
  387.         Case WIND_012
  388.                 AddTriangle(dest_surf,good_v,new1_v,new2_v)
  389.         Case WIND_102
  390.                 AddTriangle(dest_surf,new1_v,good_v,new2_v)
  391.         Case WIND_201
  392.                 AddTriangle(dest_surf,new1_v,new2_v,good_v)
  393.         End Select
  394.  
  395.         ;
  396.         ; Update the requested settings for the 2 new verts...
  397.         ;
  398.        
  399.         If vert_info And CLIP_NORMALS
  400.                 ; Retrieve original triangle's normals.
  401.                 good_nx# = VertexNX(source_surf,good_v)
  402.                 good_ny# = VertexNY(source_surf,good_v)
  403.                 good_nz# = VertexNZ(source_surf,good_v)
  404.                 bad1_nx# = VertexNX(source_surf,bad1_v)
  405.                 bad1_ny# = VertexNY(source_surf,bad1_v)
  406.                 bad1_nz# = VertexNZ(source_surf,bad1_v)
  407.                 bad2_nx# = VertexNX(source_surf,bad2_v)
  408.                 bad2_ny# = VertexNY(source_surf,bad2_v)
  409.                 bad2_nz# = VertexNZ(source_surf,bad2_v)
  410.        
  411.                 ; Calculate & set normals for the 2 new verts.
  412.                 nx# = good_nx + (bad1_nx-good_nx) * ratio1
  413.                 ny# = good_ny + (bad1_ny-good_ny) * ratio1
  414.                 nz# = good_nz + (bad1_nz-good_nz) * ratio1
  415.                 nl# = Sqr(nx*nx + ny*ny + nz*nz)
  416.                 VertexNormal dest_surf,new1_v,nx/nl,ny/nl,nz/nl
  417.                 nx# = good_nx + (bad2_nx-good_nx) * ratio2
  418.                 ny# = good_ny + (bad2_ny-good_ny) * ratio2
  419.                 nz# = good_nz + (bad2_nz-good_nz) * ratio2
  420.                 nl# = Sqr(nx*nx + ny*ny + nz*nz)
  421.                 VertexNormal dest_surf,new2_v,nx/nl,ny/nl,nz/nl
  422.         EndIf
  423.  
  424.         If vert_info And CLIP_UV_SET0
  425.                 ; Retrieve original triangle's set 0 UVs.
  426.                 good_tu# = VertexU(source_surf,good_v,0)
  427.                 good_tv# = VertexV(source_surf,good_v,0)
  428.                 bad1_tu# = VertexU(source_surf,bad1_v,0)
  429.                 bad1_tv# = VertexV(source_surf,bad1_v,0)
  430.                 bad2_tu# = VertexU(source_surf,bad2_v,0)
  431.                 bad2_tv# = VertexV(source_surf,bad2_v,0)
  432.        
  433.                 ; Calculate & set set 0 UVs for the 2 new verts.
  434.                 u# = good_tu + (bad1_tu-good_tu) * ratio1
  435.                 v# = good_tv + (bad1_tv-good_tv) * ratio1
  436.                 VertexTexCoords dest_surf,new1_v, u,v,0, 0
  437.                 u# = good_tu + (bad2_tu-good_tu) * ratio2
  438.                 v# = good_tv + (bad2_tv-good_tv) * ratio2
  439.                 VertexTexCoords dest_surf,new2_v, u,v,0, 0
  440.         EndIf
  441.  
  442.         If vert_info And CLIP_UV_SET1
  443.                 ; Retrieve original triangle's set 1 UVs.
  444.                 good_tu# = VertexU(source_surf,good_v,1)
  445.                 good_tv# = VertexV(source_surf,good_v,1)
  446.                 bad1_tu# = VertexU(source_surf,bad1_v,1)
  447.                 bad1_tv# = VertexV(source_surf,bad1_v,1)
  448.                 bad2_tu# = VertexU(source_surf,bad2_v,1)
  449.                 bad2_tv# = VertexV(source_surf,bad2_v,1)
  450.        
  451.                 ; Calculate & set set 1 UVs for the 2 new verts.
  452.                 u# = good_tu + (bad1_tu-good_tu) * ratio1
  453.                 v# = good_tv + (bad1_tv-good_tv) * ratio1
  454.                 VertexTexCoords dest_surf,new1_v, u,v,0, 1
  455.                 u# = good_tu + (bad2_tu-good_tu) * ratio2
  456.                 v# = good_tv + (bad2_tv-good_tv) * ratio2
  457.                 VertexTexCoords dest_surf,new2_v, u,v,0, 1
  458.         EndIf
  459.  
  460.         If vert_info And CLIP_RGBA
  461.                 ; Retrieve original triangle's vert colors.
  462.                 good_r# = VertexRed(source_surf,good_v)
  463.                 good_g# = VertexGreen(source_surf,good_v)
  464.                 good_b# = VertexBlue(source_surf,good_v)
  465.                 bad1_r# = VertexRed(source_surf,bad1_v)
  466.                 bad1_g# = VertexGreen(source_surf,bad1_v)
  467.                 bad1_b# = VertexBlue(source_surf,bad1_v)
  468.                 bad2_r# = VertexRed(source_surf,bad2_v)
  469.                 bad2_g# = VertexGreen(source_surf,bad2_v)
  470.                 bad2_b# = VertexBlue(source_surf,bad2_v)
  471.        
  472.                 ; Retrieve original triangle's vert alpha.
  473.                 good_a# = VertexAlpha(source_surf,good_v)
  474.                 bad1_a# = VertexAlpha(source_surf,bad1_v)
  475.                 bad2_a# = VertexAlpha(source_surf,bad2_v)
  476.        
  477.                 ; Calculate & set color and alpha for the 2 new verts.
  478.                 r# = good_r + (bad1_r-good_r) * ratio1
  479.                 g# = good_g + (bad1_g-good_g) * ratio1
  480.                 b# = good_b + (bad1_b-good_b) * ratio1
  481.                 a# = good_a + (bad1_a-good_a) * ratio1
  482.                 VertexColor dest_surf,new1_v,r,g,b,a
  483.                 r# = good_r + (bad2_r-good_r) * ratio2
  484.                 g# = good_g + (bad2_g-good_g) * ratio2
  485.                 b# = good_b + (bad2_b-good_b) * ratio2
  486.                 a# = good_a + (bad2_a-good_a) * ratio2
  487.                 VertexColor dest_surf,new2_v,r,g,b,a
  488.         EndIf
  489.  
  490. End Function
  491.  
  492.  
  493. ;
  494. ; Creates a clipped triangle from a source_surf triangle that has 1 'bad' vertex. i.e. 1 of the
  495. ; triangles verts is beyond the clipping plane.
  496. ; Note: this actually requires us to make a quad out of 2 tris.
  497. ;
  498. ; Params:
  499. ; source_surf - Surface containing the triangle to be clipped.
  500. ; dest_surf   - Surface to build the clipped triangle in.
  501. ; plane_y     - Y distance of clipping plane from mesh origin.
  502. ; bad_v       - Index of the one 'bad' vertex in triangle.
  503. ; good1_v     - Index of the first 'good' vertex in the triangle.
  504. ; good2_v     - Index of the second 'good' vertex in the triangle.
  505. ; wind_order  - Flag indicating the order to wind the clipped triangle(s).
  506. ; vert_info   - Bit flags defining vertex info to include when clipping.
  507. ;
  508. Function clip_tri_1bad(source_surf,dest_surf,plane_y#, bad_v%,good1_v%,good2_v%, wind_order%, vert_info)
  509.  
  510.         ; Retrieve good/bad vert coords.
  511.         bad_vx#   = VertexX(source_surf,bad_v)
  512.         bad_vy#   = VertexY(source_surf,bad_v)
  513.         bad_vz#   = VertexZ(source_surf,bad_v)
  514.         good1_vx# = VertexX(source_surf,good1_v)
  515.         good1_vy# = VertexY(source_surf,good1_v)
  516.         good1_vz# = VertexZ(source_surf,good1_v)
  517.         good2_vx# = VertexX(source_surf,good2_v)
  518.         good2_vy# = VertexY(source_surf,good2_v)
  519.         good2_vz# = VertexZ(source_surf,good2_v)
  520.  
  521.         ;
  522.         ; Calculate & add first new vert...
  523.         ;
  524.  
  525.         ; Find Y distance from good vert 1 to clipping plane.
  526.         clip_y_dist# = good1_vy-plane_y
  527.  
  528.         ; Vector to bad vert from good vert 1.
  529.         xv# = bad_vx-good1_vx
  530.         yv# = bad_vy-good1_vy
  531.         zv# = bad_vz-good1_vz
  532.        
  533.         y_dist# = good1_vy-bad_vy
  534.         side# = 1.0/y_dist
  535.         ratio1# = clip_y_dist*side
  536.         new1_v = AddVertex(dest_surf,good1_vx+xv*ratio1,good1_vy+yv*ratio1,good1_vz+zv*ratio1)
  537.  
  538.         ;
  539.         ; Calculate & add second new vert...
  540.         ;
  541.  
  542.         ; Find Y distance from good vert 2 to clipping plane.
  543.         clip_y_dist# = good2_vy-plane_y
  544.  
  545.         ; Vector to bad vert from good vert 2.
  546.         xv# = bad_vx-good2_vx
  547.         yv# = bad_vy-good2_vy
  548.         zv# = bad_vz-good2_vz
  549.        
  550.         y_dist# = good2_vy-bad_vy
  551.         side# = 1.0/y_dist
  552.         ratio2# = clip_y_dist*side
  553.         new2_v = AddVertex(dest_surf,good2_vx+xv*ratio2,good2_vy+yv*ratio2,good2_vz+zv*ratio2)
  554.        
  555.         ; Make the 2 clipped triangles, wound in the specified way.
  556.         Select wind_order
  557.         Case WIND_012
  558.                 AddTriangle(dest_surf,new1_v,good1_v,good2_v)
  559.                 AddTriangle(dest_surf,good2_v,new2_v,new1_v)
  560.         Case WIND_102
  561.                 AddTriangle(dest_surf,good1_v,new1_v,good2_v)
  562.                 AddTriangle(dest_surf,good2_v,new1_v,new2_v)
  563.         Case WIND_201
  564.                 AddTriangle(dest_surf,good1_v,good2_v,new1_v)
  565.                 AddTriangle(dest_surf,good2_v,new2_v,new1_v)
  566.         End Select
  567.  
  568.         ;
  569.         ; Update the requested settings for the 2 new verts...
  570.         ;
  571.        
  572.         If vert_info And CLIP_NORMALS
  573.                 ; Retrieve original triangle's normals.
  574.                 bad_nx#   = VertexNX(source_surf,bad_v)
  575.                 bad_ny#   = VertexNY(source_surf,bad_v)
  576.                 bad_nz#   = VertexNZ(source_surf,bad_v)
  577.                 good1_nx# = VertexNX(source_surf,good1_v)
  578.                 good1_ny# = VertexNY(source_surf,good1_v)
  579.                 good1_nz# = VertexNZ(source_surf,good1_v)
  580.                 good2_nx# = VertexNX(source_surf,good2_v)
  581.                 good2_ny# = VertexNY(source_surf,good2_v)
  582.                 good2_nz# = VertexNZ(source_surf,good2_v)
  583.        
  584.                 ; Calculate & set normals for the 2 new verts.
  585.                 nx# = good1_nx + (bad_nx-good1_nx) * ratio1
  586.                 ny# = good1_ny + (bad_ny-good1_ny) * ratio1
  587.                 nz# = good1_nz + (bad_nz-good1_nz) * ratio1
  588.                 nl# = Sqr(nx*nx + ny*ny + nz*nz)
  589.                 VertexNormal dest_surf,new1_v,nx/nl,ny/nl,nz/nl
  590.                 nx# = good2_nx + (bad_nx-good2_nx) * ratio2
  591.                 ny# = good2_ny + (bad_ny-good2_ny) * ratio2
  592.                 nz# = good2_nz + (bad_nz-good2_nz) * ratio2
  593.                 nl# = Sqr(nx*nx + ny*ny + nz*nz)
  594.                 VertexNormal dest_surf,new2_v,nx/nl,ny/nl,nz/nl
  595.         EndIf
  596.  
  597.         If vert_info And CLIP_UV_SET0
  598.                 ; Retrieve original triangle's set 0 UVs.
  599.                 bad_tu#   = VertexU(source_surf,bad_v,0)
  600.                 bad_tv#   = VertexV(source_surf,bad_v,0)
  601.                 good1_tu# = VertexU(source_surf,good1_v,0)
  602.                 good1_tv# = VertexV(source_surf,good1_v,0)
  603.                 good2_tu# = VertexU(source_surf,good2_v,0)
  604.                 good2_tv# = VertexV(source_surf,good2_v,0)
  605.        
  606.                 ; Calculate & set set 0 UVs for the 2 new verts.
  607.                 u# = good1_tu + (bad_tu-good1_tu) * ratio1
  608.                 v# = good1_tv + (bad_tv-good1_tv) * ratio1
  609.                 VertexTexCoords dest_surf,new1_v, u,v,0, 0
  610.                 u# = good2_tu + (bad_tu-good2_tu) * ratio2
  611.                 v# = good2_tv + (bad_tv-good2_tv) * ratio2
  612.                 VertexTexCoords dest_surf,new2_v, u,v,0, 0
  613.         EndIf
  614.  
  615.         If vert_info And CLIP_UV_SET1
  616.                 ; Retrieve original triangle's set 1 UVs.
  617.                 bad_tu#   = VertexU(source_surf,bad_v,1)
  618.                 bad_tv#   = VertexV(source_surf,bad_v,1)
  619.                 good1_tu# = VertexU(source_surf,good1_v,1)
  620.                 good1_tv# = VertexV(source_surf,good1_v,1)
  621.                 good2_tu# = VertexU(source_surf,good2_v,1)
  622.                 good2_tv# = VertexV(source_surf,good2_v,1)
  623.        
  624.                 ; Calculate & set set 1 UVs for the 2 new verts.
  625.                 u# = good1_tu + (bad_tu-good1_tu) * ratio1
  626.                 v# = good1_tv + (bad_tv-good1_tv) * ratio1
  627.                 VertexTexCoords dest_surf,new1_v, u,v,0, 1
  628.                 u# = good2_tu + (bad_tu-good2_tu) * ratio2
  629.                 v# = good2_tv + (bad_tv-good2_tv) * ratio2
  630.                 VertexTexCoords dest_surf,new2_v, u,v,0, 1
  631.         EndIf
  632.  
  633.         If vert_info And CLIP_RGBA
  634.                 ; Retrieve original triangle's vert colors.
  635.                 bad_r#   = VertexRed(source_surf,bad_v)
  636.                 bad_g#   = VertexGreen(source_surf,bad_v)
  637.                 bad_b#   = VertexBlue(source_surf,bad_v)
  638.                 good1_r# = VertexRed(source_surf,good1_v)
  639.                 good1_g# = VertexGreen(source_surf,good1_v)
  640.                 good1_b# = VertexBlue(source_surf,good1_v)
  641.                 good2_r# = VertexRed(source_surf,good2_v)
  642.                 good2_g# = VertexGreen(source_surf,good2_v)
  643.                 good2_b# = VertexBlue(source_surf,good2_v)
  644.        
  645.                 ; Retrieve original triangle's vert alpha.
  646.                 bad_a# = VertexAlpha(source_surf,bad_v)
  647.                 good1_a# = VertexAlpha(source_surf,good1_v)
  648.                 good2_a# = VertexAlpha(source_surf,good2_v)
  649.        
  650.                 ; Calculate & set color and alpha for the 2 new verts.
  651.                 r# = good1_r + (bad_r-good1_r) * ratio1
  652.                 g# = good1_g + (bad_g-good1_g) * ratio1
  653.                 b# = good1_b + (bad_b-good1_b) * ratio1
  654.                 a# = good1_a + (bad_a-good1_a) * ratio1
  655.                 VertexColor dest_surf,new1_v,r,g,b,a
  656.                 r# = good2_r + (bad_r-good2_r) * ratio2
  657.                 g# = good2_g + (bad_g-good2_g) * ratio2
  658.                 b# = good2_b + (bad_b-good2_b) * ratio2
  659.                 a# = good2_a + (bad_a-good2_a) * ratio2
  660.                 VertexColor dest_surf,new2_v,r,g,b,a
  661.         EndIf
  662.  
  663. End Function
  664.  
  665.  
  666. ;
  667. ; Creates various meshes to demonstrate clipping on.
  668. ;
  669. Function create_meshes()
  670.  
  671.         Dim mesh.infoT(4)
  672.        
  673.         ; Textured sphere.
  674.         mesh(0) = New infoT
  675.         mesh(0)mesh = CreateSphere(16)
  676.         mesh(0)FX = 16
  677.         mesh(0)vert_info = CLIP_NORMALS+CLIP_UV_SET0
  678.         ScaleMesh mesh(0)mesh,1.2,1.2,1.2
  679.         EntityTexture mesh(0)mesh,tex
  680.         HideEntity mesh(0)mesh
  681.                
  682.         ; Vertex colored cone.
  683.         mesh(1) = New infoT
  684.         mesh(1)mesh = CreateCone(32,1)
  685.         mesh(1)FX = 2+16
  686.         mesh(1)vert_info = CLIP_NORMALS+CLIP_RGBA
  687.         UpdateNormals mesh(1)mesh
  688.         For s=1 To 2
  689.                 surf = GetSurface(mesh(1)mesh,s)
  690.                 For v=0 To CountVertices(surf)-1
  691.                         VertexColor surf,v,Rand(0,255),Rand(0,255),Rand(0,255)
  692.                 Next
  693.         Next
  694.         HideEntity mesh(1)mesh
  695.        
  696.         ; Plain cylinder.
  697.         mesh(2) = New infoT
  698.         mesh(2)mesh = CreateCylinder(32,1)
  699.         mesh(2)FX = 16
  700.         mesh(2)vert_info = CLIP_NORMALS
  701.         HideEntity mesh(2)mesh
  702.        
  703.         ; Textured, vertex colored cube.
  704.         mesh(3) = New infoT
  705.         mesh(3)mesh = CreateCube()
  706.         mesh(3)FX = 2+16
  707.         mesh(3)vert_info = CLIP_NORMALS+CLIP_UV_SET0+CLIP_RGBA
  708.         surf = GetSurface(mesh(3)mesh,1)
  709.         For v=0 To CountVertices(surf)-1
  710.                 VertexColor surf,v,Rand(0,255),Rand(0,255),Rand(0,255)
  711.         Next
  712.         EntityTexture mesh(3)mesh,tex
  713.         HideEntity mesh(3)mesh
  714.  
  715.         ; Textured bars.
  716.         bar = CreateCylinder(16,1)
  717.         ScaleMesh bar,.2,1.5,.2
  718.         mesh(4) = New infoT
  719.         mesh(4)mesh = CreateMesh()
  720.         AddMesh bar,mesh(4)mesh
  721.         PositionMesh bar,.5,0,0
  722.         RotateMesh bar,20,0,0
  723.         AddMesh bar,mesh(4)mesh
  724.         PositionMesh bar,-1,0,0
  725.         RotateMesh bar,20,0,0
  726.         AddMesh bar,mesh(4)mesh
  727.         mesh(4)FX = 16
  728.         mesh(4)vert_info = CLIP_NORMALS+CLIP_UV_SET0
  729.         HideEntity mesh(4)mesh
  730.         FreeEntity bar
  731.         EntityTexture mesh(4)mesh,tex
  732.         EntityColor mesh(4)mesh,200,0,150
  733.         EntityShininess mesh(4)mesh,1
  734.  
  735. End Function
  736.  
  737.  
  738. ;
  739. ; Displays info.
  740. ;
  741. Function show_info()
  742.        
  743.         If fps_timeout
  744.                 frame_count = frame_count + 1
  745.  
  746.                 If MilliSecs() > fps_timeout Then
  747.                         fps_timeout = MilliSecs() + 1000
  748.                         fps = frame_count
  749.                         frame_count = 0
  750.                
  751.                         If fps < slowest_fps Or slowest_fps = 0 Then slowest_fps = fps
  752.                 EndIf
  753.                
  754.                 If frame_time > slowest_frame Then slowest_frame = frame_time
  755.                
  756.                 Color 255,255,255
  757.                 Text 10,10, "Press to toggle:"
  758.                 Text 10,25, "1 - This text"
  759.                 Text 10,40, "2 - Clipping plane"
  760.                 Text 10,55, "3 - Clipping plane rotation"
  761.                 Text 10,70, "4 - Mesh rotation"
  762.                 Text 10,85, "5 - Backface culling"
  763.                 Text 10,100,"6 - Wireframe"
  764.                 Text 10,115,"7 - Slow motion"
  765.                 Text 10,130,"8 - Frame lock"
  766.                 Text 10,160,"Press SPACE to change mesh"
  767.                 Color 255,255,0
  768.                 Text 10,190,"Millisecs: " + frame_time
  769.                 Text 10,205,"  Slowest: " + slowest_frame
  770.                 Color 0,255,255
  771.                 Text 10,220,"      FPS: " + fps
  772.                 Text 10,235,"    Worst: " + slowest_fps
  773.         Else
  774.                 ; First call initialization.
  775.                 fps_timeout = MilliSecs() + 1000
  776.         EndIf
  777.        
  778. End Function


Comments :


HNPhan(Posted 1+ years ago)

 niiice effect!! like the homeworld hyperspace clip fx


BlitzSupport(Posted 1+ years ago)

 Whoa, nice one -- very quick!


churchaxe(Posted 1+ years ago)

 cooool!


big10p(Posted 1+ years ago)

 Thanks all! :)I haven't seen Homeworld but I think this could be used for all kinds of effects. I first saw this effect in Soul Reaver on the Dreamcast: when you killed an enemy, a diagonal, invisible plane would gradually erase it's body. I always wondered how it was done.


Tracer(Posted 1+ years ago)

 Highly awesome!Tracer


Damien Sturdy(Posted 1+ years ago)

 Excelent stuff :D excelent! woo! woo! woo! :D


Gillissie(Posted 1+ years ago)

 Very cool. I'm surprised at how fast it runs.


Bot Builder(Posted 1+ years ago)

 Wow. Sweet routine. their must be somthing cool to use this for....... :D


Picklesworth(Posted 1+ years ago)

 I've been looking for this one so I can have a running example of my jumpgate concept. Thanks a lot!


puki(Posted 1+ years ago)

 Yep this is extremely good - very good demo - the only clipping stuff I have noted with regard to Blitz3D surface/vertex stuff.


Braincell(Posted 1+ years ago)

 WHOA!!!!!If you could make another mesh instead of the plane, then we would all have an awesome supa-fast shadow system.


Braincell(Posted 1+ years ago)

 <SNIP>(ouch seems blitzbasic.com is reacting a bit slow so i posted a few times...)


Braincell(Posted 1+ years ago)

 <SNIP>


Braincell(Posted 1+ years ago)

 <SNIP>


RemiD(Posted 8 months ago)

 very good effect ! thanks


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal