Code archives/3D Graphics - Mesh/Mesh Clipping Demo
This code has been declared by its author to be Public Domain code.
Download source code
| 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! |
; ; Mesh clip demo by big10p (A.K.A. Chris Chadwick) 2004. ; ; Written with Blitz3D v1.87 ; ; Known issues: ; 1) copy_mesh_clip() attempts to paint the clipped mesh with the same brushes ; that are applied to the mesh being copied. For multiple surface meshes, ; GetSurfaceBrush() is used but only works if the mesh's surfaces have been ; painted with PaintSurface(). If the multi surface mesh has been painted ; en masse - using EntityTexture, EntityColor etc. - it doesn't work. ; 2) There seems to be a slight, noticeable color change when clipping tris that ; are vertex colored. Not sure if this is down to a lack of precision with floats ; or something I'm doing wrong. I'll have to investigate some more, I think. :) ; 3) I seem to get a much higher FPS (with frame locking turned off) if I turn off the ; visible clipping plane. Not sure why it makes such a big difference as it's only ; one surface with two triangles in!? :/ ; Graphics3D 800,600,32 ; Create chequer pattern texture. Global tex = CreateTexture(64,64) SetBuffer TextureBuffer(tex) For y = 0 To 63 Step 4 For x = 0 To 63 Step 2 If c Then Color 255,255,255 Else Color 255,0,0 c = Not c Rect x,y,2,4 Next c = Not c Next SetBuffer BackBuffer() WireFrame 0 AntiAlias 0 SeedRnd MilliSecs() ; Demo mesh info type. Type infoT Field mesh Field FX% Field vert_info% End Type ; Frame timing and control. Global frame_count% Global fps% Global slowest_fps% Global fps_timeout% Global frame_time% Global slowest_frame% Global frame_start% fps_timer = CreateTimer(60) ; Demo state flags. show_text% = True show_plane% = True rotate_plane% = True rotate_mesh% = True cull_backface% = False wiref% = False slowmo% = False frame_lock% = True ; Flags to tell clip_tri functions the order to wind triangles. Const WIND_012% = 0 Const WIND_102% = 1 Const WIND_201% = 2 ; Flags to tell copy_mesh_clip() which vertex info to include when clipping. Const CLIP_NORMALS% = 1 Const CLIP_UV_SET0% = 2 Const CLIP_UV_SET1% = 4 Const CLIP_RGBA% = 8 Const DEF_CLIP_INFO% = CLIP_NORMALS+CLIP_UV_SET0 cam = CreateCamera() CameraRange cam,1,100 PositionEntity cam,0,0,-3 light = CreateLight() AmbientLight 100,100,100 ; Create the demo meshes. Dim mesh.infoT(0) create_meshes() current_mesh% = 0 ; Clipping plane. Const MAX_PLANE_DIST# = 1.3 plane_pitch# = 0 plane_yaw# = 0 plane_dist# = -MAX_PLANE_DIST plane_move# = 0.01 plane_piv = CreatePivot() plane = CreateMesh(plane_piv) ps = CreateSurface(plane) AddVertex(ps,-2,0,2) AddVertex(ps,2,0,2) AddVertex(ps,-2,0,-2) AddVertex(ps,2,0,-2) AddTriangle(ps,0,1,2) AddTriangle(ps,1,3,2) EntityAlpha plane,.3 EntityColor plane,0,0,200 EntityFX plane,1+16 PositionEntity plane,0,plane_dist,0 RotateEntity plane_piv,plane_pitch,plane_yaw,0 clip_mesh = copy_mesh_clip(mesh(current_mesh)\mesh,plane_dist,plane_pitch,plane_yaw,mesh(current_mesh)\vert_info) EntityFX clip_mesh,mesh(current_mesh)\FX Xor (cull_backface Shl 4) ; ; --- Main loop --- ; While Not KeyHit(1) frame_start = MilliSecs() If KeyHit(2) Then show_text = Not show_text If KeyHit(3) show_plane = Not show_plane If show_plane Then ShowEntity plane Else HideEntity plane EndIf If KeyHit(4) rotate_plane = Not rotate_plane plane_pitch = 0 plane_yaw = 0 EndIf If KeyHit(5) Then rotate_mesh = Not rotate_mesh If KeyHit(6) Then cull_backface = Not cull_backface If KeyHit(7) Then wiref = Not wiref : WireFrame wiref If KeyHit(8) Then slowmo = Not slowmo If KeyHit(9) Then frame_lock = Not frame_lock If KeyHit(57) Then current_mesh = (current_mesh + 1) Mod 5 If rotate_mesh Then RotateMesh mesh(current_mesh)\mesh,1,0,1 ; Change clipping plane distance. plane_dist = plane_dist + plane_move If Abs(plane_dist) > MAX_PLANE_DIST Then plane_move = -plane_move ; Rotate clipping plane. If rotate_plane plane_pitch = (plane_pitch + 1) Mod 360 plane_yaw = (plane_yaw + .5) Mod 360 EndIf ; Create an updated, clipped version of the current mesh. FreeEntity clip_mesh clip_mesh = copy_mesh_clip(mesh(current_mesh)\mesh,plane_dist,plane_pitch,plane_yaw,mesh(current_mesh)\vert_info) EntityFX clip_mesh,mesh(current_mesh)\FX Xor (cull_backface Shl 4) ; Position visible plane to match clipping plane. If show_plane PositionEntity plane,0,plane_dist,0 RotateEntity plane_piv,plane_pitch,plane_yaw,0 EndIf RenderWorld frame_time = MilliSecs() - frame_start If show_text Then show_info() If frame_lock WaitTimer(fps_timer) Flip True Else Flip False EndIf If slowmo Then Delay 200 Wend End ; ; Creates a copy of a mesh, clipped along the given plane. ; Note: this function can only really perform clipping along an XZ aligned plane. ; To perform clipping on an arbitrary, rotated plane, we cheat :) - first ; we align the mesh to the XZ plane, perform the clipping, then return ; the mesh to it's original orientation. ; ; Params: ; source_mesh - Mesh to be copied (remains unaltered by this function). ; plane_y - Y distance of clipping plane from mesh origin. ; plane_pitch - Pitch of clipping plane. ; plane_yaw - Yaw of clipping plane. ; vert_info - Bit flags defining vertex info to include when clipping. ; ; Returns: ; Handle of newly created, clipped mesh. ; Function copy_mesh_clip(source_mesh,plane_y#,plane_pitch#,plane_yaw#,vert_info%=DEF_CLIP_INFO) surf_count = CountSurfaces(source_mesh) ; Temporarily align source mesh to XZ clipping plane. ; Note: doing yaw THEN pitch rotation separately is important! ; Prevents gimble lock when returning the mesh back to it's original rotation. RotateMesh source_mesh,0,-plane_yaw,0 RotateMesh source_mesh,-plane_pitch,0,0 If surf_count=1 ; We can make a copy of single surface meshes more quickly using CopyMesh. ; (Unfortunately, CopyMesh combines surfs unless they use different textures ; so this method can't be used with multi surface meshes). dest_mesh = CopyMesh(source_mesh) ; Kill tris but keep verts. ClearSurface GetSurface(dest_mesh,1),False,True brush = GetEntityBrush(source_mesh) PaintEntity dest_mesh,brush FreeBrush brush Else dest_mesh = CreateMesh() ; Copy all surfaces and vertices from source_mesh into dest_mesh. ; For ss=1 To surf_count source_surf = GetSurface(source_mesh,ss) brush = GetSurfaceBrush(source_surf) dest_surf = CreateSurface(dest_mesh,brush) FreeBrush brush For sv=0 To CountVertices(source_surf)-1 vy# = VertexY(source_surf,sv) dv = AddVertex(dest_surf,VertexX(source_surf,sv),vy,VertexZ(source_surf,sv)) ; We don't need to bother with any other info for verts ; in dest_mesh that are beyond the clipping plane. If Not vy<plane_y VertexNormal dest_surf,dv,VertexNX(source_surf,sv),VertexNY(source_surf,sv),VertexNZ(source_surf,sv) VertexTexCoords dest_surf,dv,VertexU(source_surf,sv,0),VertexV(source_surf,sv,0),0, 0 VertexTexCoords dest_surf,dv,VertexU(source_surf,sv,1),VertexV(source_surf,sv,1),0, 1 VertexColor dest_surf,dv,VertexRed(source_surf,sv),VertexGreen(source_surf,sv),VertexBlue(source_surf,sv),VertexAlpha(source_surf,sv) EndIf Next Next EndIf ; Process all surfaces in source_mesh... ; For ss=1 To CountSurfaces(source_mesh) source_surf = GetSurface(source_mesh,ss) dest_surf = GetSurface(dest_mesh,ss) ; Process all trinagles in source_surf... ; For t=0 To CountTriangles(source_surf)-1 v0 = TriangleVertex(source_surf,t,0) v1 = TriangleVertex(source_surf,t,1) v2 = TriangleVertex(source_surf,t,2) clip0 = VertexY(source_surf,v0) < plane_y clip1 = VertexY(source_surf,v1) < plane_y clip2 = VertexY(source_surf,v2) < plane_y Select clip0+clip1+clip2 Case 0 ; There are no 'bad' verts in this triangle... ; Add this triangle so it's the same as it appears in source_surf. AddTriangle(dest_surf,v0,v1,v2) Case 1 ; There is 1 'bad' vert in this triangle... ;Find the 1 'bad' vert. ; If clip0 ; v0 is bad... clip_tri_1bad(source_surf,dest_surf,plane_y, v0,v1,v2, WIND_012, vert_info) ElseIf clip1 ;v1 is bad... clip_tri_1bad(source_surf,dest_surf,plane_y, v1,v0,v2, WIND_102, vert_info) Else ;v2 is bad... clip_tri_1bad(source_surf,dest_surf,plane_y, v2,v0,v1, WIND_201, vert_info) EndIf Case 2 ; There are 2 'bad' verts in this triangle... ; Find the 1 'good' vert. ; If Not clip0 ; v0 is good... clip_tri_2bad(source_surf,dest_surf,plane_y, v0,v1,v2, WIND_012, vert_info) ElseIf Not clip1 ; v1 is good... clip_tri_2bad(source_surf,dest_surf,plane_y, v1,v0,v2, WIND_102, vert_info) Else ; v2 is good... clip_tri_2bad(source_surf,dest_surf,plane_y, v2,v0,v1, WIND_201, vert_info) EndIf End Select Next Next ; Rotate source_mesh and dest_mesh to source_mesh's original rotation. RotateMesh source_mesh,plane_pitch,plane_yaw,0 RotateMesh dest_mesh,plane_pitch,plane_yaw,0 Return dest_mesh End Function ; ; Creates a clipped triangle from a source_surf triangle that has 2 'bad' vertices. i.e. 2 of the ; triangles verts are beyond the clipping plane. ; ; Params: ; source_surf - Surface containing the triangle to be clipped. ; dest_surf - Surface to build the clipped triangle in. ; plane_y - Y distance of clipping plane from mesh origin. ; good_v - Index of the one 'good' vertex in triangle. ; bad1_v - Index of the first 'bad' vertex in the triangle. ; bad2_v - Index of the second 'bad' vertex in the triangle. ; wind_order - Flag indicating the order to wind the clipped triangle. ; vert_info - Bit flags defining vertex info to include when clipping. ; Function clip_tri_2bad(source_surf,dest_surf,plane_y#, good_v%,bad1_v%,bad2_v%, wind_order%, vert_info%) ; Retrieve good/bad vert coords. good_vx# = VertexX(source_surf,good_v) good_vy# = VertexY(source_surf,good_v) good_vz# = VertexZ(source_surf,good_v) bad1_vx# = VertexX(source_surf,bad1_v) bad1_vy# = VertexY(source_surf,bad1_v) bad1_vz# = VertexZ(source_surf,bad1_v) bad2_vx# = VertexX(source_surf,bad2_v) bad2_vy# = VertexY(source_surf,bad2_v) bad2_vz# = VertexZ(source_surf,bad2_v) ; Find Y distance from good vert to clipping plane. clip_y_dist# = good_vy-plane_y ; ; Calculate & add first new vert... ; ; Vector to bad vert 1 from good vert. xv# = bad1_vx-good_vx yv# = bad1_vy-good_vy zv# = bad1_vz-good_vz y_dist# = good_vy-bad1_vy side# = 1.0/y_dist ratio1# = clip_y_dist*side new1_v = AddVertex(dest_surf,good_vx+xv*ratio1,good_vy+yv*ratio1,good_vz+zv*ratio1) ; ; Calculate & add second new vert... ; ; Vector to bad vert 2 from good vert. xv# = bad2_vx-good_vx yv# = bad2_vy-good_vy zv# = bad2_vz-good_vz y_dist# = good_vy-bad2_vy side# = 1.0/y_dist ratio2# = clip_y_dist*side new2_v = AddVertex(dest_surf,good_vx+xv*ratio2,good_vy+yv*ratio2,good_vz+zv*ratio2) ; Make the clipped triangle, wound in the specified way. Select wind_order Case WIND_012 AddTriangle(dest_surf,good_v,new1_v,new2_v) Case WIND_102 AddTriangle(dest_surf,new1_v,good_v,new2_v) Case WIND_201 AddTriangle(dest_surf,new1_v,new2_v,good_v) End Select ; ; Update the requested settings for the 2 new verts... ; If vert_info And CLIP_NORMALS ; Retrieve original triangle's normals. good_nx# = VertexNX(source_surf,good_v) good_ny# = VertexNY(source_surf,good_v) good_nz# = VertexNZ(source_surf,good_v) bad1_nx# = VertexNX(source_surf,bad1_v) bad1_ny# = VertexNY(source_surf,bad1_v) bad1_nz# = VertexNZ(source_surf,bad1_v) bad2_nx# = VertexNX(source_surf,bad2_v) bad2_ny# = VertexNY(source_surf,bad2_v) bad2_nz# = VertexNZ(source_surf,bad2_v) ; Calculate & set normals for the 2 new verts. nx# = good_nx + (bad1_nx-good_nx) * ratio1 ny# = good_ny + (bad1_ny-good_ny) * ratio1 nz# = good_nz + (bad1_nz-good_nz) * ratio1 nl# = Sqr(nx*nx + ny*ny + nz*nz) VertexNormal dest_surf,new1_v,nx/nl,ny/nl,nz/nl nx# = good_nx + (bad2_nx-good_nx) * ratio2 ny# = good_ny + (bad2_ny-good_ny) * ratio2 nz# = good_nz + (bad2_nz-good_nz) * ratio2 nl# = Sqr(nx*nx + ny*ny + nz*nz) VertexNormal dest_surf,new2_v,nx/nl,ny/nl,nz/nl EndIf If vert_info And CLIP_UV_SET0 ; Retrieve original triangle's set 0 UVs. good_tu# = VertexU(source_surf,good_v,0) good_tv# = VertexV(source_surf,good_v,0) bad1_tu# = VertexU(source_surf,bad1_v,0) bad1_tv# = VertexV(source_surf,bad1_v,0) bad2_tu# = VertexU(source_surf,bad2_v,0) bad2_tv# = VertexV(source_surf,bad2_v,0) ; Calculate & set set 0 UVs for the 2 new verts. u# = good_tu + (bad1_tu-good_tu) * ratio1 v# = good_tv + (bad1_tv-good_tv) * ratio1 VertexTexCoords dest_surf,new1_v, u,v,0, 0 u# = good_tu + (bad2_tu-good_tu) * ratio2 v# = good_tv + (bad2_tv-good_tv) * ratio2 VertexTexCoords dest_surf,new2_v, u,v,0, 0 EndIf If vert_info And CLIP_UV_SET1 ; Retrieve original triangle's set 1 UVs. good_tu# = VertexU(source_surf,good_v,1) good_tv# = VertexV(source_surf,good_v,1) bad1_tu# = VertexU(source_surf,bad1_v,1) bad1_tv# = VertexV(source_surf,bad1_v,1) bad2_tu# = VertexU(source_surf,bad2_v,1) bad2_tv# = VertexV(source_surf,bad2_v,1) ; Calculate & set set 1 UVs for the 2 new verts. u# = good_tu + (bad1_tu-good_tu) * ratio1 v# = good_tv + (bad1_tv-good_tv) * ratio1 VertexTexCoords dest_surf,new1_v, u,v,0, 1 u# = good_tu + (bad2_tu-good_tu) * ratio2 v# = good_tv + (bad2_tv-good_tv) * ratio2 VertexTexCoords dest_surf,new2_v, u,v,0, 1 EndIf If vert_info And CLIP_RGBA ; Retrieve original triangle's vert colors. good_r# = VertexRed(source_surf,good_v) good_g# = VertexGreen(source_surf,good_v) good_b# = VertexBlue(source_surf,good_v) bad1_r# = VertexRed(source_surf,bad1_v) bad1_g# = VertexGreen(source_surf,bad1_v) bad1_b# = VertexBlue(source_surf,bad1_v) bad2_r# = VertexRed(source_surf,bad2_v) bad2_g# = VertexGreen(source_surf,bad2_v) bad2_b# = VertexBlue(source_surf,bad2_v) ; Retrieve original triangle's vert alpha. good_a# = VertexAlpha(source_surf,good_v) bad1_a# = VertexAlpha(source_surf,bad1_v) bad2_a# = VertexAlpha(source_surf,bad2_v) ; Calculate & set color and alpha for the 2 new verts. r# = good_r + (bad1_r-good_r) * ratio1 g# = good_g + (bad1_g-good_g) * ratio1 b# = good_b + (bad1_b-good_b) * ratio1 a# = good_a + (bad1_a-good_a) * ratio1 VertexColor dest_surf,new1_v,r,g,b,a r# = good_r + (bad2_r-good_r) * ratio2 g# = good_g + (bad2_g-good_g) * ratio2 b# = good_b + (bad2_b-good_b) * ratio2 a# = good_a + (bad2_a-good_a) * ratio2 VertexColor dest_surf,new2_v,r,g,b,a EndIf End Function ; ; Creates a clipped triangle from a source_surf triangle that has 1 'bad' vertex. i.e. 1 of the ; triangles verts is beyond the clipping plane. ; Note: this actually requires us to make a quad out of 2 tris. ; ; Params: ; source_surf - Surface containing the triangle to be clipped. ; dest_surf - Surface to build the clipped triangle in. ; plane_y - Y distance of clipping plane from mesh origin. ; bad_v - Index of the one 'bad' vertex in triangle. ; good1_v - Index of the first 'good' vertex in the triangle. ; good2_v - Index of the second 'good' vertex in the triangle. ; wind_order - Flag indicating the order to wind the clipped triangle(s). ; vert_info - Bit flags defining vertex info to include when clipping. ; Function clip_tri_1bad(source_surf,dest_surf,plane_y#, bad_v%,good1_v%,good2_v%, wind_order%, vert_info) ; Retrieve good/bad vert coords. bad_vx# = VertexX(source_surf,bad_v) bad_vy# = VertexY(source_surf,bad_v) bad_vz# = VertexZ(source_surf,bad_v) good1_vx# = VertexX(source_surf,good1_v) good1_vy# = VertexY(source_surf,good1_v) good1_vz# = VertexZ(source_surf,good1_v) good2_vx# = VertexX(source_surf,good2_v) good2_vy# = VertexY(source_surf,good2_v) good2_vz# = VertexZ(source_surf,good2_v) ; ; Calculate & add first new vert... ; ; Find Y distance from good vert 1 to clipping plane. clip_y_dist# = good1_vy-plane_y ; Vector to bad vert from good vert 1. xv# = bad_vx-good1_vx yv# = bad_vy-good1_vy zv# = bad_vz-good1_vz y_dist# = good1_vy-bad_vy side# = 1.0/y_dist ratio1# = clip_y_dist*side new1_v = AddVertex(dest_surf,good1_vx+xv*ratio1,good1_vy+yv*ratio1,good1_vz+zv*ratio1) ; ; Calculate & add second new vert... ; ; Find Y distance from good vert 2 to clipping plane. clip_y_dist# = good2_vy-plane_y ; Vector to bad vert from good vert 2. xv# = bad_vx-good2_vx yv# = bad_vy-good2_vy zv# = bad_vz-good2_vz y_dist# = good2_vy-bad_vy side# = 1.0/y_dist ratio2# = clip_y_dist*side new2_v = AddVertex(dest_surf,good2_vx+xv*ratio2,good2_vy+yv*ratio2,good2_vz+zv*ratio2) ; Make the 2 clipped triangles, wound in the specified way. Select wind_order Case WIND_012 AddTriangle(dest_surf,new1_v,good1_v,good2_v) AddTriangle(dest_surf,good2_v,new2_v,new1_v) Case WIND_102 AddTriangle(dest_surf,good1_v,new1_v,good2_v) AddTriangle(dest_surf,good2_v,new1_v,new2_v) Case WIND_201 AddTriangle(dest_surf,good1_v,good2_v,new1_v) AddTriangle(dest_surf,good2_v,new2_v,new1_v) End Select ; ; Update the requested settings for the 2 new verts... ; If vert_info And CLIP_NORMALS ; Retrieve original triangle's normals. bad_nx# = VertexNX(source_surf,bad_v) bad_ny# = VertexNY(source_surf,bad_v) bad_nz# = VertexNZ(source_surf,bad_v) good1_nx# = VertexNX(source_surf,good1_v) good1_ny# = VertexNY(source_surf,good1_v) good1_nz# = VertexNZ(source_surf,good1_v) good2_nx# = VertexNX(source_surf,good2_v) good2_ny# = VertexNY(source_surf,good2_v) good2_nz# = VertexNZ(source_surf,good2_v) ; Calculate & set normals for the 2 new verts. nx# = good1_nx + (bad_nx-good1_nx) * ratio1 ny# = good1_ny + (bad_ny-good1_ny) * ratio1 nz# = good1_nz + (bad_nz-good1_nz) * ratio1 nl# = Sqr(nx*nx + ny*ny + nz*nz) VertexNormal dest_surf,new1_v,nx/nl,ny/nl,nz/nl nx# = good2_nx + (bad_nx-good2_nx) * ratio2 ny# = good2_ny + (bad_ny-good2_ny) * ratio2 nz# = good2_nz + (bad_nz-good2_nz) * ratio2 nl# = Sqr(nx*nx + ny*ny + nz*nz) VertexNormal dest_surf,new2_v,nx/nl,ny/nl,nz/nl EndIf If vert_info And CLIP_UV_SET0 ; Retrieve original triangle's set 0 UVs. bad_tu# = VertexU(source_surf,bad_v,0) bad_tv# = VertexV(source_surf,bad_v,0) good1_tu# = VertexU(source_surf,good1_v,0) good1_tv# = VertexV(source_surf,good1_v,0) good2_tu# = VertexU(source_surf,good2_v,0) good2_tv# = VertexV(source_surf,good2_v,0) ; Calculate & set set 0 UVs for the 2 new verts. u# = good1_tu + (bad_tu-good1_tu) * ratio1 v# = good1_tv + (bad_tv-good1_tv) * ratio1 VertexTexCoords dest_surf,new1_v, u,v,0, 0 u# = good2_tu + (bad_tu-good2_tu) * ratio2 v# = good2_tv + (bad_tv-good2_tv) * ratio2 VertexTexCoords dest_surf,new2_v, u,v,0, 0 EndIf If vert_info And CLIP_UV_SET1 ; Retrieve original triangle's set 1 UVs. bad_tu# = VertexU(source_surf,bad_v,1) bad_tv# = VertexV(source_surf,bad_v,1) good1_tu# = VertexU(source_surf,good1_v,1) good1_tv# = VertexV(source_surf,good1_v,1) good2_tu# = VertexU(source_surf,good2_v,1) good2_tv# = VertexV(source_surf,good2_v,1) ; Calculate & set set 1 UVs for the 2 new verts. u# = good1_tu + (bad_tu-good1_tu) * ratio1 v# = good1_tv + (bad_tv-good1_tv) * ratio1 VertexTexCoords dest_surf,new1_v, u,v,0, 1 u# = good2_tu + (bad_tu-good2_tu) * ratio2 v# = good2_tv + (bad_tv-good2_tv) * ratio2 VertexTexCoords dest_surf,new2_v, u,v,0, 1 EndIf If vert_info And CLIP_RGBA ; Retrieve original triangle's vert colors. bad_r# = VertexRed(source_surf,bad_v) bad_g# = VertexGreen(source_surf,bad_v) bad_b# = VertexBlue(source_surf,bad_v) good1_r# = VertexRed(source_surf,good1_v) good1_g# = VertexGreen(source_surf,good1_v) good1_b# = VertexBlue(source_surf,good1_v) good2_r# = VertexRed(source_surf,good2_v) good2_g# = VertexGreen(source_surf,good2_v) good2_b# = VertexBlue(source_surf,good2_v) ; Retrieve original triangle's vert alpha. bad_a# = VertexAlpha(source_surf,bad_v) good1_a# = VertexAlpha(source_surf,good1_v) good2_a# = VertexAlpha(source_surf,good2_v) ; Calculate & set color and alpha for the 2 new verts. r# = good1_r + (bad_r-good1_r) * ratio1 g# = good1_g + (bad_g-good1_g) * ratio1 b# = good1_b + (bad_b-good1_b) * ratio1 a# = good1_a + (bad_a-good1_a) * ratio1 VertexColor dest_surf,new1_v,r,g,b,a r# = good2_r + (bad_r-good2_r) * ratio2 g# = good2_g + (bad_g-good2_g) * ratio2 b# = good2_b + (bad_b-good2_b) * ratio2 a# = good2_a + (bad_a-good2_a) * ratio2 VertexColor dest_surf,new2_v,r,g,b,a EndIf End Function ; ; Creates various meshes to demonstrate clipping on. ; Function create_meshes() Dim mesh.infoT(4) ; Textured sphere. mesh(0) = New infoT mesh(0)\mesh = CreateSphere(16) mesh(0)\FX = 16 mesh(0)\vert_info = CLIP_NORMALS+CLIP_UV_SET0 ScaleMesh mesh(0)\mesh,1.2,1.2,1.2 EntityTexture mesh(0)\mesh,tex HideEntity mesh(0)\mesh ; Vertex colored cone. mesh(1) = New infoT mesh(1)\mesh = CreateCone(32,1) mesh(1)\FX = 2+16 mesh(1)\vert_info = CLIP_NORMALS+CLIP_RGBA UpdateNormals mesh(1)\mesh For s=1 To 2 surf = GetSurface(mesh(1)\mesh,s) For v=0 To CountVertices(surf)-1 VertexColor surf,v,Rand(0,255),Rand(0,255),Rand(0,255) Next Next HideEntity mesh(1)\mesh ; Plain cylinder. mesh(2) = New infoT mesh(2)\mesh = CreateCylinder(32,1) mesh(2)\FX = 16 mesh(2)\vert_info = CLIP_NORMALS HideEntity mesh(2)\mesh ; Textured, vertex colored cube. mesh(3) = New infoT mesh(3)\mesh = CreateCube() mesh(3)\FX = 2+16 mesh(3)\vert_info = CLIP_NORMALS+CLIP_UV_SET0+CLIP_RGBA surf = GetSurface(mesh(3)\mesh,1) For v=0 To CountVertices(surf)-1 VertexColor surf,v,Rand(0,255),Rand(0,255),Rand(0,255) Next EntityTexture mesh(3)\mesh,tex HideEntity mesh(3)\mesh ; Textured bars. bar = CreateCylinder(16,1) ScaleMesh bar,.2,1.5,.2 mesh(4) = New infoT mesh(4)\mesh = CreateMesh() AddMesh bar,mesh(4)\mesh PositionMesh bar,.5,0,0 RotateMesh bar,20,0,0 AddMesh bar,mesh(4)\mesh PositionMesh bar,-1,0,0 RotateMesh bar,20,0,0 AddMesh bar,mesh(4)\mesh mesh(4)\FX = 16 mesh(4)\vert_info = CLIP_NORMALS+CLIP_UV_SET0 HideEntity mesh(4)\mesh FreeEntity bar EntityTexture mesh(4)\mesh,tex EntityColor mesh(4)\mesh,200,0,150 EntityShininess mesh(4)\mesh,1 End Function ; ; Displays info. ; Function show_info() If fps_timeout frame_count = frame_count + 1 If MilliSecs() > fps_timeout Then fps_timeout = MilliSecs() + 1000 fps = frame_count frame_count = 0 If fps < slowest_fps Or slowest_fps = 0 Then slowest_fps = fps EndIf If frame_time > slowest_frame Then slowest_frame = frame_time Color 255,255,255 Text 10,10, "Press to toggle:" Text 10,25, "1 - This text" Text 10,40, "2 - Clipping plane" Text 10,55, "3 - Clipping plane rotation" Text 10,70, "4 - Mesh rotation" Text 10,85, "5 - Backface culling" Text 10,100,"6 - Wireframe" Text 10,115,"7 - Slow motion" Text 10,130,"8 - Frame lock" Text 10,160,"Press SPACE to change mesh" Color 255,255,0 Text 10,190,"Millisecs: " + frame_time Text 10,205," Slowest: " + slowest_frame Color 0,255,255 Text 10,220," FPS: " + fps Text 10,235," Worst: " + slowest_fps Else ; First call initialization. fps_timeout = MilliSecs() + 1000 EndIf End Function |