Ok, here's this little emergency tool, very custom and inhouseish:
http://www.melog.ch/dl/kill_decorator18_clonetris_src.zipor 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