Ok, here's this little emergency tool, very custom and inhouseish:
http://www.melog.ch/dl/kill_decorator18_clonetris_src.zip
or copy paste from here:
the required b3dfile.bb include file:
http://www.melog.ch/dl/kill_decorator18_clonetris_src.zip
or copy paste from here:
Graphics3D 640,480,32,2 SetBuffer BackBuffer() ; Sometimes Decorator 1.8 created clone Triangles which have the potential to make a lot ; of troubles. This Program may be used to remove the clone Triangles from a Mesh and ; export the result as a B3D Mesh. Cloned Triangles can be removed easily, but since they use ; individual surfaces, you may have to experiment with the "use_clone" variable to make it ; use the right material/surface! ; Use an optimated Decorator Export as mesh source. alpha, vertex normals and color are ; not supported by now. ; The program also includes Functions to export a lightmapped Mesh, that may be useful ; for some people. ; Version 0.1, released dec. 2005 by CSP GAMES ; init savemesh Include "b3dfile.bb" Global c_surfs Dim c_surf(0) Dim c_brush(0) Dim c_tex(0) Dim c_tex_name$(0) ; eo init stuff Global do_weld=1 ; set this to one if you wish to weld the mesh Global use_clone=1 ; set this to one to use the secondary clones, zero to use the first ones ;(try both if the clone tris are not textured as you wish) mesh_name$="camp2_dec18weld2.b3d" ; load this mesh export_path$="diditest.b3d" ; save this optimized mesh mesh=LoadMesh(mesh_name$) ;Goto test_walk ; use this to skip optimation and save a 1:1 copy of the mesh (for tests only) ; --------------------- first read all surfaces and triangle data to some arrays and banks --------- surfs=CountSurfaces(mesh) Dim s(surfs),s2(surfs),tris(surfs),brush(surfs),texturepath$(surfs,1) Dim same(100000,4) same_count=0 b=1000 seenflag=990 Print "surfaces: "+ surfs For i=1 To surfs s(i)=GetSurface(mesh,i) bru=GetSurfaceBrush(s(i)) brush(i)=bru texture=GetBrushTexture( bru,0) name$=TextureName$(texture) texturepath$(i,0)=name$ FreeTexture texture texture=GetBrushTexture( bru,1) name$=TextureName$(texture) texturepath$(i,1)=name$ FreeTexture texture Print texturepath$(i,0) Print texturepath$(i,1) Print "surface "+i+" has "+CountTriangles(s(i))+" tris" tris(i)=CreateBank(CountTriangles(s(i))*b) total_tris=total_tris+CountTriangles(s(i)) For j=0 To CountTriangles(s(i))-1 PokeFloat tris(i),(j*b)+ 0,VertexX (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+ 4,VertexY (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+ 8,VertexZ (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+ 12,VertexU (s(i),TriangleVertex(s(i),j,0),0) PokeFloat tris(i),(j*b)+ 16,VertexV (s(i),TriangleVertex(s(i),j,0),0) PokeFloat tris(i),(j*b)+ 20,VertexU (s(i),TriangleVertex(s(i),j,0),1) PokeFloat tris(i),(j*b)+ 24,VertexV (s(i),TriangleVertex(s(i),j,0),1) PokeFloat tris(i),(j*b)+ 28,VertexNX (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+ 32,VertexNY (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+ 36,VertexNZ (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+ 40,VertexRed (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+ 44,VertexGreen (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+ 48,VertexBlue (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+ 52,VertexAlpha (s(i),TriangleVertex(s(i),j,0)) PokeFloat tris(i),(j*b)+100,VertexX (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+104,VertexY (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+108,VertexZ (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+112,VertexU (s(i),TriangleVertex(s(i),j,1),0) PokeFloat tris(i),(j*b)+116,VertexV (s(i),TriangleVertex(s(i),j,1),0) PokeFloat tris(i),(j*b)+120,VertexU (s(i),TriangleVertex(s(i),j,1),1) PokeFloat tris(i),(j*b)+124,VertexV (s(i),TriangleVertex(s(i),j,1),1) PokeFloat tris(i),(j*b)+128,VertexNX (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+132,VertexNY (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+136,VertexNZ (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+140,VertexRed (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+144,VertexGreen (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+148,VertexBlue (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+152,VertexAlpha (s(i),TriangleVertex(s(i),j,1)) PokeFloat tris(i),(j*b)+200,VertexX (s(i),TriangleVertex(s(i),j,2)) PokeFloat tris(i),(j*b)+204,VertexY (s(i),TriangleVertex(s(i),j,2)) PokeFloat tris(i),(j*b)+208,VertexZ (s(i),TriangleVertex(s(i),j,2)) PokeFloat tris(i),(j*b)+212,VertexU (s(i),TriangleVertex(s(i),j,2),0) PokeFloat tris(i),(j*b)+216,VertexV (s(i),TriangleVertex(s(i),j,2),0) PokeFloat tris(i),(j*b)+220,VertexU (s(i),TriangleVertex(s(i),j,2),1) PokeFloat tris(i),(j*b)+224,VertexV (s(i),TriangleVertex(s(i),j,2),1) PokeFloat tris(i),(j*b)+228,VertexNX (s(i),TriangleVertex(s(i),j,2)) PokeFloat tris(i),(j*b)+232,VertexNY (s(i),TriangleVertex(s(i),j,2)) PokeFloat tris(i),(j*b)+236,VertexNZ (s(i),TriangleVertex(s(i),j,2)) PokeFloat tris(i),(j*b)+240,VertexRed (s(i),TriangleVertex(s(i),j,2)) PokeFloat tris(i),(j*b)+244,VertexGreen (s(i),TriangleVertex(s(i),j,2)) PokeFloat tris(i),(j*b)+248,VertexBlue (s(i),TriangleVertex(s(i),j,2)) PokeFloat tris(i),(j*b)+252,VertexAlpha (s(i),TriangleVertex(s(i),j,2)) Next Next ;Goto quicky Print "-------------------------" ; --------- then compare every single triangle to all other triangles if they are identical -------- ; this is a brute force thing, may take a minute or so. You can abort end the app with ESC here. AppTitle "Please wait, seeking for Clones..." For i=1 To surfs For j=0 To CountTriangles(s(i))-1 If PeekFloat(tris(i),(j*b)+seenflag)<>-1 x0#=PeekFloat(tris(i),(j*b)+ 0) y0#=PeekFloat(tris(i),(j*b)+ 4) z0#=PeekFloat(tris(i),(j*b)+ 8) x1#=PeekFloat(tris(i),(j*b)+100) y1#=PeekFloat(tris(i),(j*b)+104) z1#=PeekFloat(tris(i),(j*b)+108) x2#=PeekFloat(tris(i),(j*b)+200) y2#=PeekFloat(tris(i),(j*b)+204) z2#=PeekFloat(tris(i),(j*b)+208) For ii=1 To surfs For jj=0 To CountTriangles(s(ii))-1 If (ii<>i) Or (jj<>j); don't compare with myself xx0#=PeekFloat(tris(ii),(jj*b)+ 0) yy0#=PeekFloat(tris(ii),(jj*b)+ 4) zz0#=PeekFloat(tris(ii),(jj*b)+ 8) xx1#=PeekFloat(tris(ii),(jj*b)+100) yy1#=PeekFloat(tris(ii),(jj*b)+104) zz1#=PeekFloat(tris(ii),(jj*b)+108) xx2#=PeekFloat(tris(ii),(jj*b)+200) yy2#=PeekFloat(tris(ii),(jj*b)+204) zz2#=PeekFloat(tris(ii),(jj*b)+208) If (x0=xx0) And (y0=yy0) And (z0=zz0) And (x1=xx1) And (y1=yy1) And (z1=zz1) And (x2=xx2) And (y2=yy2) And (z2=zz2) Print "In surface:"+i+" of "+surfs Print "Found identic Triangle: surf:"+i+" Tri:"+j+" is the same as surf:"+ii+" Tri:"+jj PokeFloat tris(ii),(jj*b)+seenflag,-1 ; set this triangle to "seen" PokeFloat tris(i),(j*b)+seenflag,2 ; set this triangle to "seen" same(same_count,0)=i same(same_count,1)=j same(same_count,2)=ii same(same_count,3)=jj same(same_count,4)=same(same_count,4)+1 ; count number of clones per triangle same_count=same_count+1 EndIf EndIf Next Next EndIf If KeyDown(1)<>0 Then End Next Next AppTitle "Ready" max_clone=0 For i=0 To same_count-1 If same(i,4) > max_clone Then max_clone=same(i,4) EndIf Next Print "double tris: "+same_count Print "highest number of clones of one Triangle: "+max_clone ; should not be higher than 1... Print "total tris in mesh: "+total_tris Print "And I really didn't take any drugs o_O" Print "Press Space for a walktrough test" WaitKey() ; ----------------------------- recreate the mesh without the clone tris! --------------------- .quicky mesh2=CreateMesh() For i=1 To surfs s2(i)=CreateSurface(mesh2,brush(i)) Next For i=1 To surfs For j=0 To CountTriangles(s(i))-1 If PeekFloat(tris(i),(j*b)+seenflag)<>-1 If PeekFloat(tris(i),(j*b)+seenflag)=2 ; has clone(s) i2=i j2=j If use_clone=1 For iii=0 To same_count-1 ; use latest clone that was found If (same(iii,0)=i) And (same(iii,1)=j) i2=same(iii,2) j2=same(iii,3) EndIf Next EndIf x0#= PeekFloat(tris(i2),(j2*b)+0) y0#= PeekFloat(tris(i2),(j2*b)+4) z0#= PeekFloat(tris(i2),(j2*b)+8) ua0#= PeekFloat(tris(i2),(j2*b)+12) va0#= PeekFloat(tris(i2),(j2*b)+16) ub0#= PeekFloat(tris(i2),(j2*b)+20) vb0#= PeekFloat(tris(i2),(j2*b)+24) nx0#= PeekFloat(tris(i2),(j2*b)+28) ny0#= PeekFloat(tris(i2),(j2*b)+32) nz0#= PeekFloat(tris(i2),(j2*b)+36) red0#= PeekFloat(tris(i2),(j2*b)+40) gre0#= PeekFloat(tris(i2),(j2*b)+44) blu0#= PeekFloat(tris(i2),(j2*b)+48) alp0#= PeekFloat(tris(i2),(j2*b)+52) x1#= PeekFloat(tris(i2),(j2*b)+100) y1#= PeekFloat(tris(i2),(j2*b)+104) z1#= PeekFloat(tris(i2),(j2*b)+108) ua1#= PeekFloat(tris(i2),(j2*b)+112) va1#= PeekFloat(tris(i2),(j2*b)+116) ub1#= PeekFloat(tris(i2),(j2*b)+120) vb1#= PeekFloat(tris(i2),(j2*b)+124) nx1#= PeekFloat(tris(i2),(j2*b)+128) ny1#= PeekFloat(tris(i2),(j2*b)+132) nz1#= PeekFloat(tris(i2),(j2*b)+136) red1#= PeekFloat(tris(i2),(j2*b)+140) gre1#= PeekFloat(tris(i2),(j2*b)+144) blu1#= PeekFloat(tris(i2),(j2*b)+148) alp1#= PeekFloat(tris(i2),(j2*b)+152) x2#= PeekFloat(tris(i2),(j2*b)+200) y2#= PeekFloat(tris(i2),(j2*b)+204) z2#= PeekFloat(tris(i2),(j2*b)+208) ua2#= PeekFloat(tris(i2),(j2*b)+212) va2#= PeekFloat(tris(i2),(j2*b)+216) ub2#= PeekFloat(tris(i2),(j2*b)+220) vb2#= PeekFloat(tris(i2),(j2*b)+224) nx2#= PeekFloat(tris(i2),(j2*b)+228) ny2#= PeekFloat(tris(i2),(j2*b)+232) nz2#= PeekFloat(tris(i2),(j2*b)+236) red2#= PeekFloat(tris(i2),(j2*b)+240) gre2#= PeekFloat(tris(i2),(j2*b)+244) blu2#= PeekFloat(tris(i2),(j2*b)+248) alp2#= PeekFloat(tris(i2),(j2*b)+252) vr0=AddVertex (s2(i2),x0,y0,z0) VertexTexCoords s2(i2),vr0,ua0,va0,0,0 VertexTexCoords s2(i2),vr0,ub0,vb0,0,1 VertexNormal s2(i2),vr0,nx0,ny0,nz0 VertexColor s2(i2),vr0,red0,gre0,blu0,alp0 vr1=AddVertex (s2(i2),x1,y1,z1) VertexTexCoords s2(i2),vr1,ua1,va1,0,0 VertexTexCoords s2(i2),vr1,ub1,vb1,0,1 VertexNormal s2(i2),vr1,nx1,ny1,nz1 VertexColor s2(i2),vr1,red1,gre1,blu1,alp1 vr2=AddVertex (s2(i2),x2,y2,z2) VertexTexCoords s2(i2),vr2,ua2,va2,0,0 VertexTexCoords s2(i2),vr2,ub2,vb2,0,1 VertexNormal s2(i2),vr2,nx2,ny2,nz2 VertexColor s2(i2),vr2,red2,gre2,blu2,alp2 AddTriangle (s2(i2),vr0,vr1,vr2) Else ; has no clone x0#= PeekFloat(tris(i),(j*b)+0) y0#= PeekFloat(tris(i),(j*b)+4) z0#= PeekFloat(tris(i),(j*b)+8) ua0#= PeekFloat(tris(i),(j*b)+12) va0#= PeekFloat(tris(i),(j*b)+16) ub0#= PeekFloat(tris(i),(j*b)+20) vb0#= PeekFloat(tris(i),(j*b)+24) nx0#= PeekFloat(tris(i),(j*b)+28) ny0#= PeekFloat(tris(i),(j*b)+32) nz0#= PeekFloat(tris(i),(j*b)+36) red0#= PeekFloat(tris(i),(j*b)+40) gre0#= PeekFloat(tris(i),(j*b)+44) blu0#= PeekFloat(tris(i),(j*b)+48) alp0#= PeekFloat(tris(i),(j*b)+52) x1#= PeekFloat(tris(i),(j*b)+100) y1#= PeekFloat(tris(i),(j*b)+104) z1#= PeekFloat(tris(i),(j*b)+108) ua1#= PeekFloat(tris(i),(j*b)+112) va1#= PeekFloat(tris(i),(j*b)+116) ub1#= PeekFloat(tris(i),(j*b)+120) vb1#= PeekFloat(tris(i),(j*b)+124) nx1#= PeekFloat(tris(i),(j*b)+128) ny1#= PeekFloat(tris(i),(j*b)+132) nz1#= PeekFloat(tris(i),(j*b)+136) red1#= PeekFloat(tris(i),(j*b)+140) gre1#= PeekFloat(tris(i),(j*b)+144) blu1#= PeekFloat(tris(i),(j*b)+148) alp1#= PeekFloat(tris(i),(j*b)+152) x2#= PeekFloat(tris(i),(j*b)+200) y2#= PeekFloat(tris(i),(j*b)+204) z2#= PeekFloat(tris(i),(j*b)+208) ua2#= PeekFloat(tris(i),(j*b)+212) va2#= PeekFloat(tris(i),(j*b)+216) ub2#= PeekFloat(tris(i),(j*b)+220) vb2#= PeekFloat(tris(i),(j*b)+224) nx2#= PeekFloat(tris(i),(j*b)+228) ny2#= PeekFloat(tris(i),(j*b)+232) nz2#= PeekFloat(tris(i),(j*b)+236) red2#= PeekFloat(tris(i),(j*b)+240) gre2#= PeekFloat(tris(i),(j*b)+244) blu2#= PeekFloat(tris(i),(j*b)+248) alp2#= PeekFloat(tris(i),(j*b)+252) vr0=AddVertex (s2(i),x0,y0,z0) VertexTexCoords s2(i),vr0,ua0,va0,0,0 VertexTexCoords s2(i),vr0,ub0,vb0,0,1 VertexNormal s2(i),vr0,nx0,ny0,nz0 VertexColor s2(i),vr0,red0,gre0,blu0,alp0 vr1=AddVertex (s2(i),x1,y1,z1) VertexTexCoords s2(i),vr1,ua1,va1,0,0 VertexTexCoords s2(i),vr1,ub1,vb1,0,1 VertexNormal s2(i),vr1,nx1,ny1,nz1 VertexColor s2(i),vr1,red1,gre1,blu1,alp1 vr2=AddVertex (s2(i),x2,y2,z2) VertexTexCoords s2(i),vr2,ua2,va2,0,0 VertexTexCoords s2(i),vr2,ub2,vb2,0,1 VertexNormal s2(i),vr2,nx2,ny2,nz2 VertexColor s2(i),vr2,red2,gre2,blu2,alp2 AddTriangle (s2(i),vr0,vr1,vr2) EndIf EndIf If KeyDown(1)<>0 Then End Next Next FreeEntity mesh ; original Mesh not needed anymore mesh=mesh2 ; ---------------------------------- a walktrough test code ------------------------------- .test_walk Collisions 1,2,2,2 player=CreatePivot() PositionEntity player,0,100,-1 EntityRadius player,0.2,0.9 EntityType player,1 camera=CreateCamera( player ) CameraRange camera,.1,200 TranslateEntity camera,0,1.8,0 CameraClsColor camera,180,200,255 light=CreateLight() LightColor light,32,32,32 TurnEntity light,45,45,0 EntityFX mesh,1 EntityType mesh,2 sp#=.5 ey#=EntityY(player) ; walktrough loop While Not KeyHit(1) If KeyHit(17) wire=1-wire WireFrame wire EndIf yv#=EntityY(player)-ey ey=EntityY(player) If KeyHit(57) Then jump#=1.0 MoveEntity player,0,-Abs(yv-.005),0 If jump>0 Then jump=jump-.1 If jump<0 Then jump=0 MoveEntity player,0,Sin(jump)*30.0,0 EndIf mxa#=-MouseXSpeed()/4.0 mya#=MouseYSpeed()/4.0 MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 TurnEntity player,0,mxa,0 TurnEntity camera,mya,0,0 If KeyDown(205) MoveEntity player,sp,0,0 If KeyDown(203) MoveEntity player,-sp,0,0 If KeyDown(200) MoveEntity player,0,0,sp If KeyDown(208) MoveEntity player,0,0,-sp UpdateWorld RenderWorld Text 0,0,"Tris rendered: "+TrisRendered() Text 0,16,"Press ESC to save and exit" Flip Wend ExportMesh(export_path$,mesh) End ; ---------------------------------------------------- ; Mesh Saving Functions Function ExportMesh(what_to_save$,mesh) Print If do_weld=1 Print "Welding Mesh" weld(mesh) EndIf c_surfs=CountSurfaces(mesh) Dim c_surf(c_surfs+1) Dim c_brush(c_surfs+1) Dim c_tex(c_surfs+1) Dim c_tex_name$(c_surfs+1) Print "Saving Mesh" For i=1 To c_surfs c_surf(i)= GetSurface(mesh,i) c_brush(i)=GetSurfaceBrush( c_surf(i) ) c_tex(i)=GetBrushTexture( c_brush(i) ) c_tex_name$(i)=Lower$(TextureName$( c_tex(i))) If c_tex_name$(i)="" Then Print "Warning: Surface No."+i+" has no Texture. This may produce non-working Meshes!" c_tex_name$(i)=strippath$(c_tex_name$(i)) If FileType(c_tex_name$(i))<>1 Then Print "Warning: Surface No."+i+" uses nonexistant Texture ("+c_tex_name$(i)+")." Next ; get lightmap details c_tex(0)=GetBrushTexture( c_brush(1),1) c_tex_name$(0)=Lower$(TextureName$( c_tex(0))) c_tex_name$(0)=StripPath$(c_tex_name$(0)) WriteBB3D( what_to_save$,mesh ) For i=1 To c_surfs FreeBrush c_brush(i) FreeTexture c_tex(i) Next End Function Function ExportMesh_wo_lightmap(what_to_save$,mesh) If do_weld=1 Print "Welding Mesh" ;mesh=unweld(mesh) EndIf ; UpdateNormals mesh ; weld(mesh) ; UpdateNormals mesh c_surfs=CountSurfaces(mesh) Dim c_surf(c_surfs+1) Dim c_brush(c_surfs+1) Dim c_tex(c_surfs+1) Dim c_tex_name$(c_surfs+1) Print "Saving Mesh" For i=1 To c_surfs c_surf(i)= GetSurface(mesh,i) c_brush(i)=GetSurfaceBrush( c_surf(i) ) c_tex(i)=GetBrushTexture( c_brush(i) ) c_tex_name$(i)=Lower$(TextureName$( c_tex(i))) c_tex_name$(i)=strippath$(c_tex_name$(i)) Print c_tex_name$(i) If c_tex_name$(i)="" Then Print "Error: Surface No."+i+" has no Texture" If FileType(c_tex_name$(i))<>1 Then Print "Warning: Surface No."+i+" uses nonexistant Texture ("+c_tex_name$(i)+")." Next WriteBB3D_wo_lightmap( what_to_save$,mesh ) For i=1 To c_surfs FreeBrush c_brush(i) FreeTexture c_tex(i) Next End Function Function WriteBB3D_wo_lightmap( f_name$,mesh ) file=WriteFile( f_name$ ) b3dSetFile( file ) b3dBeginChunk( "BB3D" ) b3dWriteInt( 1 ) ;version b3dBeginChunk( "TEXS" ) ; list all textures used by the mesh For i=1 To c_surfs b3dWriteString( c_tex_name$(i) ) ;texture file b3dWriteInt( 1 ) ;flags b3dWriteInt( 2 ) ;blend b3dWriteFloat( 0 ) ;x in tex 0 (hu?) b3dWriteFloat( 0 ) ;y in tex 0 b3dWriteFloat( 1 ) ;x scale 1 b3dWriteFloat( 1 ) ;y scale 1 b3dWriteFloat( 0 ) ;rotation 0 Next b3dEndChunk() ;end of TEXS chunk For i=1 To c_surfs b3dBeginChunk( "BRUS" ) ; describe all brushes used by the mesh b3dWriteInt( 1 ) ;number of textures per brush ; (eg 2 with lightmap) b3dWriteString( "brush"+(i-1) ) ;brushname b3dWriteFloat( 1 ) ;red b3dWriteFloat( 1 ) ;green b3dWriteFloat( 1 ) ;blue b3dWriteFloat( 1 ) ;alpha b3dWriteFloat( 0 ) ;shininess b3dWriteInt( 1 ) ;blendmode b3dWriteInt( 0 ) ;FX b3dWriteInt( i-1 ) ;used texture index ? ; b3dWriteInt( i-1 ) ;additional texture index (eg lightmap), but here we only use 1 (see above) b3dEndChunk() ;end of BRUS chunk Next b3dBeginChunk( "NODE" ) b3dWriteString( "entity_name_here!" ) b3dWriteFloat( 0 ) ;x_pos b3dWriteFloat( 0 ) ;y_pos b3dWriteFloat( 0 ) ;y_pos b3dWriteFloat( 1 ) ;x_scale b3dWriteFloat( 1 ) ;y_scale b3dWriteFloat( 1 ) ;z_scale b3dWriteFloat( 1 ) ;rot_w b3dWriteFloat( 0 ) ;rot_x b3dWriteFloat( 0 ) ;rot_y b3dWriteFloat( 0 ) ;rot_z WriteMESH_wo_lightmap( mesh ) b3dEndChunk() ;end of NODE chunk b3dEndChunk() ;end of BB3D chunk CloseFile file End Function Function WriteMESH_wo_lightmap( mesh ) n_surfs=CountSurfaces( mesh ) b3dBeginChunk( "MESH" ) b3dWriteInt( -1 ) ;no 'entity' brush -1 b3dBeginChunk( "VRTS" ) b3dWriteInt( 0 ) ;flags - 0=no normal/color b3dWriteInt( 1 ) ;number of tex_coord sets (z.B: 2 bei lightmap) b3dWriteInt( 2 ) ;coords per set (u,v,w?) 2 beu uv, 3 bei uvw For k=1 To n_surfs surf=GetSurface( mesh,k ) n_verts=CountVertices( surf )-1 For j=0 To n_verts b3dWriteFloat( VertexX( surf,j ) ) b3dWriteFloat( VertexY( surf,j ) ) b3dWriteFloat( VertexZ( surf,j ) ) b3dWriteFloat( VertexU#( surf,j,0 ) ) b3dWriteFloat( VertexV#( surf,j,0 ) ) ; b3dWriteFloat( VertexW#( surf,j,0 ) ) ;; b3dWriteFloat( VertexU#( surf,j,1 ) ) ; lightmap uv ;; b3dWriteFloat( VertexV#( surf,j,1 ) ) ; lightmap uv ; b3dWriteFloat( VertexW#( surf,j,1 ) ) Next Next b3dEndChunk() ;end of VRTS chunk first_vert=0 For k=1 To n_surfs surf=GetSurface( mesh,k ) n_tris=CountTriangles( surf )-1 b3dBeginChunk( "TRIS" ) b3dWriteInt( k-1 ) ;brush for these triangles (surf -1 !!!) For j=0 To n_tris b3dWriteInt( first_vert+TriangleVertex( surf,j,0 ) ) b3dWriteInt( first_vert+TriangleVertex( surf,j,1 ) ) b3dWriteInt( first_vert+TriangleVertex( surf,j,2 ) ) Next b3dEndChunk() ;end of TRIS chunk first_vert=first_vert+CountVertices( surf ) Next b3dEndChunk() ;end of MESH chunk End Function ; save mesh WITH lightmap funcs: -------------------------------------------------------- Function WriteBB3D( f_name$,mesh ) file=WriteFile( f_name$ ) b3dSetFile( file ) b3dBeginChunk( "BB3D" ) b3dWriteInt( 1 ) ;version b3dBeginChunk( "TEXS" ) ; list all textures used by the mesh ; write lightmap tex limaname$=Left$(f_name$,Len(f_name$)-4)+"_lm.bmp" ; If Upper$(Left$(limaname$,Len(runfromhere$)))=Upper$(runfromhere$) ; limaname$=Right$(limaname$,Len(limaname$)-Len(runfromhere$)) ; EndIf For i=Len(limaname$) To 1 Step -1 If Mid$(limaname$,i,1)="" Then Exit Next If i<1 Then i=1 limaname$=Right$(limaname$,Len(limaname$)-i) CopyFile "ssl_temp_lm.bmp", limaname$ b3dWriteString( c_tex_name$(0) ) ;texture file b3dWriteInt( 1 Or $10000 ) ;flags b3dWriteInt( 2 ) ;blend - 2 b3dWriteFloat( 0 ) ;x in tex 0 (hu?) b3dWriteFloat( 0 ) ;y in tex 0 b3dWriteFloat( 1 ) ;x scale 1 b3dWriteFloat( 1 ) ;y scale 1 b3dWriteFloat( 0 ) ;rotation 0 For i=1 To c_surfs b3dWriteString( c_tex_name$(i) ) ;texture file b3dWriteInt( 1 ) ;flags b3dWriteInt( 2 ) ;blend - 2 b3dWriteFloat( 0 ) ;x in tex 0 (hu?) b3dWriteFloat( 0 ) ;y in tex 0 b3dWriteFloat( 1 ) ;x scale 1 b3dWriteFloat( 1 ) ;y scale 1 b3dWriteFloat( 0 ) ;rotation 0 Next b3dEndChunk() ;end of TEXS chunk For i=1 To c_surfs b3dBeginChunk( "BRUS" ) ; describe all brushes used by the mesh b3dWriteInt( 2 ) ;number of textures per brush ; (eg 2 with lightmap) b3dWriteString( "brush"+(i-1) ) ;brushname b3dWriteFloat( 1 ) ;red b3dWriteFloat( 1 ) ;green b3dWriteFloat( 1 ) ;blue b3dWriteFloat( 1 ) ;alpha b3dWriteFloat( 0 ) ;shininess b3dWriteInt( 1 ) ;blendmode - once 2, mow 1! b3dWriteInt( 1 ) ;FX b3dWriteInt( i ) ;used texture index ? b3dWriteInt( 0 ) ;additional texture index (eg lightmap), but here we only use 1 (see above) b3dEndChunk() ;end of BRUS chunk Next b3dBeginChunk( "NODE" ) b3dWriteString( "whatever" ) b3dWriteFloat( 0 ) ;x_pos b3dWriteFloat( 0 ) ;y_pos b3dWriteFloat( 0 ) ;y_pos b3dWriteFloat( 1 ) ;x_scale b3dWriteFloat( 1 ) ;y_scale b3dWriteFloat( 1 ) ;z_scale b3dWriteFloat( 1 ) ;rot_w b3dWriteFloat( 0 ) ;rot_x b3dWriteFloat( 0 ) ;rot_y b3dWriteFloat( 0 ) ;rot_z WriteMESH( mesh ) b3dEndChunk() ;end of NODE chunk b3dEndChunk() ;end of BB3D chunk CloseFile file End Function Function WriteMESH( mesh ) n_surfs=CountSurfaces( mesh ) b3dBeginChunk( "MESH" ) b3dWriteInt( -1 ) ;no 'entity' brush -1 b3dBeginChunk( "VRTS" ) b3dWriteInt( 0 ) ;flags - 0=no normal/color b3dWriteInt( 2 ) ;number of tex_coord sets (z.B: 2 bei lightmap) b3dWriteInt( 2 ) ;coords per set (u,v,w?) 2 beu uv, 3 bei uvw For k=1 To n_surfs surf=GetSurface( mesh,k ) n_verts=CountVertices( surf )-1 For j=0 To n_verts b3dWriteFloat( VertexX( surf,j ) ) b3dWriteFloat( VertexY( surf,j ) ) b3dWriteFloat( VertexZ( surf,j ) ) b3dWriteFloat( VertexU#( surf,j,0 ) ) b3dWriteFloat( VertexV#( surf,j,0 ) ) ; b3dWriteFloat( VertexW#( surf,j,0 ) ) b3dWriteFloat( VertexU#( surf,j,1 ) ) ; lightmap uv b3dWriteFloat( VertexV#( surf,j,1 ) ) ; lightmap uv ; b3dWriteFloat( VertexW#( surf,j,1 ) ) Next Next b3dEndChunk() ;end of VRTS chunk first_vert=0 For k=1 To n_surfs surf=GetSurface( mesh,k ) n_tris=CountTriangles( surf )-1 b3dBeginChunk( "TRIS" ) b3dWriteInt( k-1 ) ;brush for these triangles (surf -1 !!!) For j=0 To n_tris b3dWriteInt( first_vert+TriangleVertex( surf,j,0 ) ) b3dWriteInt( first_vert+TriangleVertex( surf,j,1 ) ) b3dWriteInt( first_vert+TriangleVertex( surf,j,2 ) ) Next b3dEndChunk() ;end of TRIS chunk first_vert=first_vert+CountVertices( surf ) Next b3dEndChunk() ;end of MESH chunk End Function ;---------------------------------- eo saving mesh functions ------------------------------------ ;-------------------------------------- welding functions --------------------------------------- ; init weld Dim txv(3) Type TRIS Field x0# Field y0# Field z0# Field u0# Field v0# Field U20# Field V20# Field x1# Field y1# Field z1# Field u1# Field v1# Field U21# Field V21# Field x2# Field y2# Field z2# Field u2# Field v2# Field U22# Field V22# Field surface End Type Function Weld(mish) Dim txv(3) For nsurf = 1 To CountSurfaces(mish) su=GetSurface(mish,nsurf) For tq = 0 To CountTriangles(su)-1 txv(0) = TriangleVertex(su,tq,0) txv(1) = TriangleVertex(su,tq,1) txv(2) = TriangleVertex(su,tq,2) vq.TRIS = New TRIS vq\x0# = VertexX(su,txv(0)) vq\y0# = VertexY(su,txv(0)) vq\z0# = VertexZ(su,txv(0)) vq\u0# = VertexU(su,txv(0),0) vq\v0# = VertexV(su,txv(0),0) vq\u20# = VertexU(su,txv(0),1) vq\v20# = VertexV(su,txv(0),1) vq\x1# = VertexX(su,txv(1)) vq\y1# = VertexY(su,txv(1)) vq\z1# = VertexZ(su,txv(1)) vq\u1# = VertexU(su,txv(1),0) vq\v1# = VertexV(su,txv(1),0) vq\u21# = VertexU(su,txv(1),1) vq\v21# = VertexV(su,txv(1),1) vq\x2# = VertexX(su,txv(2)) vq\y2# = VertexY(su,txv(2)) vq\z2# = VertexZ(su,txv(2)) vq\u2# = VertexU(su,txv(2),0) vq\v2# = VertexV(su,txv(2),0) vq\u22# = VertexU(su,txv(2),1) vq\v22# = VertexV(su,txv(2),1) Next ClearSurface su For vq.tris = Each tris vt1=findvert(su,vq\x0#,vq\y0#,vq\z0#,vq\u0#,vq\v0#,vq\u20#,vq\v20#) If vt1=-1 Then vt1=AddVertex(su,vq\x0#,vq\y0#,vq\z0#,vq\u0#,vq\v0#) loc_u#=(vq\u20#) loc_v#=(vq\v20#) ; If loc_u> 1.0 Then loc_u=loc_u-(loc_u-1.0) ; If loc_u<-1.0 Then loc_u=loc_u+(Abs(loc_u)-1.0) ; If loc_v> 1.0 Then loc_v=loc_v-(loc_v-1.0) ; If loc_v<-1.0 Then loc_v=loc_v+(Abs(loc_v)-1.0) VertexTexCoords su,mycount,loc_u,loc_v,0,1 vt1 = mycount mycount = mycount +1 EndIf vt2=findvert(su,vq\x1#,vq\y1#,vq\z1#,vq\u1#,vq\v1#,vq\u21#,vq\v21#) If Vt2=-1 Then vt2=AddVertex( su,vq\x1#,vq\y1#,vq\z1#,vq\u1#,vq\v1#) loc_u#=(vq\u21#) loc_v#=(vq\v21#) ; If loc_u> 1.0 Then loc_u=loc_u-(loc_u-1.0) ; If loc_u<-1.0 Then loc_u=loc_u+(Abs(loc_u)-1.0) ; If loc_v> 1.0 Then loc_v=loc_v-(loc_v-1.0) ; If loc_v<-1.0 Then loc_v=loc_v+(Abs(loc_v)-1.0) VertexTexCoords su,mycount,loc_u,loc_v,0,1 vt2 = mycount mycount = mycount +1 EndIf vt3=findvert(su,vq\x2#,vq\y2#,vq\z2#,vq\u2#,vq\v2#,vq\u22#,vq\v22#) If vt3=-1 Then vt3=AddVertex(su,vq\x2#,vq\y2#,vq\z2#,vq\u2#,vq\v2#) loc_u#=(vq\u22#) loc_v#=(vq\v22#) ; If loc_u> 1.0 Then loc_u=loc_u-(loc_u-1.0) ; If loc_u<-1.0 Then loc_u=loc_u+(Abs(loc_u)-1.0) ; If loc_v> 1.0 Then loc_v=loc_v-(loc_v-1.0) ; If loc_v<-1.0 Then loc_v=loc_v+(Abs(loc_v)-1.0) VertexTexCoords su,mycount,loc_u,loc_v,0,1 vt3 = mycount mycount = mycount +1 EndIf AddTriangle su,vt1,vt2,vt3 Next Delete Each tris mycount=0 Next End Function Function findvert(su,x2#,y2#,z2#,u2#,v2#,u22#,v22#) Local thresh# =0.001 For t=0 To CountVertices(su)-1 If Abs(VertexX(su,t)-x2#)<thresh# Then If Abs(VertexY(su,t)-y2#)<thresh# Then If Abs(VertexZ(su,t)-z2#)<thresh# Then If Abs(VertexU(su,t,0)-u2#)<thresh# Then If Abs(VertexV(su,t,0)-v2#)<thresh# Then If Abs(VertexU(su,t,1)-u22#)<thresh# Then If Abs(VertexV(su,t,1)-v22#)<thresh# Then Return t EndIf EndIf EndIf EndIf EndIf EndIf EndIf Next Return -1 End Function ;----------------------------------- eo welding functions --------------------------------------- Function StripPath$(file$) If Len(file$)>0 For i=Len(file$) To 1 Step -1 mi$=Mid$(file$,i,1) If mi$="" Or mi$="/" Then Return name$ Else name$=mi$+name$ Next EndIf Return name$ End Function
the required b3dfile.bb include file:
; ;b3d file utils to be included ; Dim b3d_stack(100) Global b3d_file,b3d_tos Function b3dSetFile( file ) b3d_tos=0 b3d_file=file End Function ;***** functions for reading from B3D files ***** Function b3dReadByte() Return ReadByte( b3d_file ) End Function Function b3dReadInt() Return ReadInt( b3d_file ) End Function Function b3dReadFloat#() Return ReadFloat( b3d_file ) End Function Function b3dReadString$() Repeat ch=b3dReadByte() If ch=0 Return t$ t$=t$+Chr$(ch) Forever End Function Function b3dReadChunk$() For k=1 To 4 tag$=tag$+Chr$(b3dReadByte()) Next sz=ReadInt( b3d_file ) b3d_tos=b3d_tos+1 b3d_stack(b3d_tos)=FilePos( b3d_file )+sz Return tag$ End Function Function b3dExitChunk() SeekFile b3d_file,b3d_stack(b3d_tos) b3d_tos=b3d_tos-1 End Function Function b3dChunkSize() Return b3d_stack(b3d_tos)-FilePos( b3d_file ) End Function ;***** Functions for writing to B3D files ***** Function b3dWriteByte( n ) WriteByte( b3d_file,n ) End Function Function b3dWriteInt( n ) WriteInt( b3d_file,n ) End Function Function b3dWriteFloat( n# ) WriteFloat( b3d_file,n ) End Function Function b3dWriteString( t$ ) For k=1 To Len( t$ ) ch=Asc(Mid$(t$,k,1)) b3dWriteByte(ch) If ch=0 Return Next b3dWriteByte( 0 ) End Function Function b3dBeginChunk( tag$ ) b3d_tos=b3d_tos+1 For k=1 To 4 b3dWriteByte(Asc(Mid$( tag$,k,1 ))) Next b3dWriteInt( 0 ) b3d_stack(b3d_tos)=FilePos( b3d_file ) End Function Function b3dEndChunk() n=FilePos( b3d_file ) SeekFile b3d_file,b3d_stack(b3d_tos)-4 b3dWriteInt( n-b3d_stack(b3d_tos) ) SeekFile b3d_file,n b3d_tos=b3d_tos-1 End Function