Code archives/3D Graphics - Mesh/CSG Bmax + B3d Edition
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| Just a Port from Blitz3d to Bmax + B3dsdk for Markus Rauch + Starfox's CSG operations. | |||||
' MR 02.11.2003
'####################################################################################################
'Csg Engine
'Thanks To David Dawkins(Starfox) For the bb code example '-)
'MR 19.01.2003
'tuned And optimized , now by cube subtract sphere 2 seconds + :-)
'MR 25.01.2003
'add uvmapping :-) slow down but works
'MR 26.01.2003
'Multiple Surfaces :-)
'MR 02.11.2003
'Repaint target Surfaces , need BB 3D => V 1.85 !
'Features: Union, Subtraction, Intersect, Fast enough, Removes bad triangles
'Call the CSG(mesha,meshb,booltype) To do the actual functions
'Limits: Not To fast with many tris
'It works only If all bbEntity have no Pickmode !
'What CSG() returns is the result mesh, Not the actual meshes you send To it
'so you might want To Delete those.
'NOTE:AddMesh add no surfaces :-( , And with CopyMesh you became only 1 surface :-(
'####################################################################################################
'Here are the globals
Global csgscale#=1,csgpiv 'The world scale (1- Normal, 2-2x Normal)
Global csgmesh[2] 'Different surface holders For different opereations
Global CSGVectorType_list:TList = CreateList()
Global CSGTriangleTYPE_list:TList = CreateList()
'-----------------------
Type CSGVectorType Extends TBBType
Method New()
Add(CSGVectorType_list)
End Method
Method After:CSGVectorType()
Local t:TLink
t=_link.NextLink()
If t Return CSGVectorType(t.Value())
End Method
Method Before:CSGVectorType()
Local t:TLink
t=_link.PrevLink()
If t Return CSGVectorType(t.Value())
End Method
Field x#
Field y#
Field z#
Field u# 'Texture Coords !
Field v#
Field w#
End Type
'-----------------------
Type CSGTriangleTYPE Extends TBBType
Method New()
Add(CSGTriangleTYPE_list)
End Method
Method After:CSGTriangleTYPE()
Local t:TLink
t=_link.NextLink()
If t Return CSGTriangleTYPE(t.Value())
End Method
Method Before:CSGTriangleTYPE()
Local t:TLink
t=_link.PrevLink()
If t Return CSGTriangleTYPE(t.Value())
End Method
Field id
Field tarid 'See Split
Field del 'Can be deleted
Field mindex 'Mesh Index (Not a Handle)
Field sindex 'Surface Index
Field tindex 'Triangle Index
Field v1x# 'Edge Vertex 1
Field v1y#
Field v1z#
Field u1#
Field v1#
Field w1#
Field v2x# 'Edge Vertex 2
Field v2y#
Field v2z#
Field u2#
Field v2#
Field w2#
Field v3x# 'Edge Vertex 3
Field v3y#
Field v3z#
Field u3#
Field v3#
Field w3#
Field mix# 'Middle Vector from all Edge Vertices
Field miy#
Field miz#
Field normx# 'Normal of Triangle
Field normy#
Field normz#
End Type
'###############################################################################################
'.CSGTestIt
'Commend the two lines If you Include this CSG file !
'CSGExample()
'End
'###############################################################################################
Function CSG(mesh1,mesh2,mode=2)
'MR 02.11.2003
'mode 1 - Union, mode 2 - Subtraction, mode 3 - Intersection
Local x1#,y1#,z1#
Local x2#,y2#,z2#
Local x3#,y3#,z3#
Local vi1,vi2,vi3 'Only VertexIndex
'-------------------------------------------------------------------------------------- Memory Position And Angles
Local ex#,ey#,ez#
ex=bbEntityX(mesh1,1)
ey=bbEntityY(mesh1,1)
ez=bbEntityZ(mesh1,1)
Local epitch#,eyaw#,eroll#
epitch=bbEntityPitch(mesh1,1)
eyaw =bbEntityYaw (mesh1,1)
eroll =bbEntityRoll (mesh1,1)
'--------------------------------------------------------------------------------------
Local curmesh
Local mindex
Local surf,sindex
Local SurfaceBrush
Local tindex
Local idstate=0
Local t:CSGTriangleTYPE
Local t1:CSGTriangleTYPE
Local t2:CSGTriangleTYPE
Local ve1:CSGVectorType
Local ve2:CSGVectorType
Local ve3:CSGVectorType
For mindex = 1 To 4
If mindex = 1 Then curmesh = mesh1
If mindex = 2 Then curmesh = mesh2
If mindex = 3 Then curmesh = mesh1
If mindex = 4 Then curmesh = mesh2
'Now copy all 4 Meshes To Buffer
For sindex = 1 To bbCountSurfaces(curmesh)
'DebugLog "sindex "+sindex
surf = bbGetSurface(curmesh,sindex)
For tindex = 0 To bbCountTriangles(surf)-1
'---------------------------------------
vi1 = bbTriangleVertex(surf,tindex,0)
vi2 = bbTriangleVertex(surf,tindex,1)
vi3 = bbTriangleVertex(surf,tindex,2)
ve1=CSGGetVertexRealPosition(curmesh,surf,vi1)
ve2=CSGGetVertexRealPosition(curmesh,surf,vi2)
ve3=CSGGetVertexRealPosition(curmesh,surf,vi3)
t=CSGTriAdd(ve1,ve2,ve3)
t.mindex = mindex
t.sindex = sindex
t.tindex = tindex
t.tarid = -1
'---------------------------------------
Next 'Triangles
Next 'Surfaces
Next '1-4
CSGTriRemoveDel
'--------------------------------------------------------------------------------------
'Create the reuse objects
csgmesh[0] = bbCreateMesh()
surf = bbCreateSurface(csgmesh[0])
vi1 = bbAddVertex(surf,-1,0,1)
vi2 = bbAddVertex(surf,1,0,1)
vi3 = bbAddVertex(surf,1,0,-1)
bbAddTriangle(surf,vi1,vi2,vi3)
'----------------------------------------
csgmesh[1] = bbCreateMesh()
surf = bbCreateSurface(csgmesh[1])
vi1 = bbAddVertex(surf,-1,0,1)
vi2 = bbAddVertex(surf,1,0,1)
vi3 = bbAddVertex(surf,1,0,-1)
bbAddTriangle(surf,vi1,vi2,vi3)
'----------------------------------------
csgmesh[2] = bbCreateCube()
bbScaleMesh csgmesh[2],100000*csgscale,0,100000*csgscale '<--- mesh vertices must be in range of Float !
'----------------------------------------
'Time To split the a polys
For t1:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t1.mindex = 2
For t2:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t2.mindex = 1 And t2.tarid <> t1.id
If t2.del = 0
If CSGTrisIntersect(t1,t2) = 1
CSGSplit t1,t2
EndIf
EndIf
EndIf
Next
EndIf
Next
'----------------------------------------
'Now split the b poly's
For t1:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t1.mindex = 3
For t2:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t2.mindex = 2 And t2.tarid <> t1.id
If t2.del = 0
If CSGTrisIntersect(t1,t2) = 1
CSGSplit t1,t2
EndIf
EndIf
EndIf
Next
EndIf
Next
'----------------------------------------
'Step 2 of reuse
surf = bbGetSurface(csgmesh[0],1)
bbAddTriangle(surf,2,1,0)
bbFreeEntity csgmesh[1]
bbFreeEntity csgmesh[2]
csgpiv = bbCreatePivot()
'----------------------------------------
'Setting a flag To Delete all the triangles without normals
For t1:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t1.normx = 0.0 And t1.normy = 0.0 And t1.normz = 0.0 'And t1.del = 0
'DebugLog "NORM=0 : "+t1.normx+" "+t1.normy+" "+t1.normz+" MIndex="+t1.mindex
CSGTriangleTYPE_list.remove t1
t1.Remove()
EndIf
Next
'----------------------------------------
Local epsilon#=0.000001
'MeshA
For t1:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t1.mindex = 1 And t1.del = 0
cosangle# = -1
inter = 0
intermode = 0 '1 - inside, 2 - shared, 3 - Not inside
quickdist# = 100000
For t2:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t2.mindex = 4
res = CSGRayIntersect(t2,t1)
If res = 1
intx# = bbPickedX()
inty# = bbPickedY()
intz# = bbPickedZ()
dist# = Sqr((intx-t1.mix)*(intx-t1.mix)+(inty-t1.miy)*(inty-t1.miy)+(intz-t1.miz)*(intz-t1.miz))
If dist < quickdist
quickdist = dist
inter = 1
cosangle# = (t1.normx*t2.normx)+(t1.normy*t2.normy)+(t1.normz*t2.normz)
EndIf
EndIf
EndIf
Next
If inter = 1
If cosangle > 0 Then intermode = 1
If cosangle < 0 Then intermode = 3
If quickdist < epsilon 'If the triangle is shared
intermode = 2
EndIf
Else
intermode = 3
EndIf
Select mode
Case 2
If intermode = 1 Or intermode = 2
t1.del = 1
EndIf
Case 1
If intermode = 1 Or intermode = 2
t1.del = 1
EndIf
Case 3
If intermode = 3 Or intermode = 2
t1.del = 1
EndIf
End Select
If t1.del=1 Then
CSGTriangleTYPE_list.remove t1
t1.Remove()
EndIf
EndIf 'Mesh A
Next 'Tri
'----------------------------------------
'MeshB
For t:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t.mindex = 2 And t.del = 0
cosangle = -1
inter = 0
intermode = 0'1 - inside, 2 - shared, 3 - Not inside
quickdist# = 100000
For tr:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If tr.mindex = 3
res = CSGRayIntersect(tr,t)
If res = 1
intx# = bbPickedX()
inty# = bbPickedY()
intz# = bbPickedZ()
dist# = Sqr((intx-t.mix)*(intx-t.mix)+(inty-t.miy)*(inty-t.miy)+(intz-t.miz)*(intz-t.miz))
If dist < quickdist
quickdist = dist
inter = 1
cosangle# = (t.normx*tr.normx)+(t.normy*tr.normy)+(t.normz*tr.normz)
EndIf
EndIf
EndIf
Next
If inter = 1
If cosangle > 0 Then intermode = 1
If cosangle < 0 Then intermode = 3
If quickdist < epsilon
intermode = 2
EndIf
Else
intermode = 3
EndIf
If mode = 2
If intermode = 3 Or intermode = 2
t.del = 1
EndIf
ElseIf mode = 1
If intermode = 1
t.del = 1
EndIf
ElseIf mode = 3
If intermode = 3
t.del = 1
EndIf
EndIf
If t.del=1 Then
CSGTriangleTYPE_list.remove t1
t1.Remove()
EndIf
EndIf
Next
'----------------------------------------
bbFreeEntity csgpiv
bbFreeEntity csgmesh[0]
'----------------------------------------
'Now Delete the polys that don't belong(loose polys)
CSGClearlTris 1
CSGClearlTris 2
'----------------------------------------------- New Mesh
Local mesh=CSGMakeNewMesh()
CSGAddTheTriangles mesh,1
'Now add Mesh 2 To Mesh 1
If mode = 2
CSGAddTheTriangles mesh,2,True 'Flips all the triangles in a mesh
Else
CSGAddTheTriangles mesh,2,False
EndIf
'----------------------------------------------- Repaint !
CSGRepaint mesh,mesh1,mesh2
'----------------------------------------------- Reposition Mesh
bbPositionMesh mesh,-ex,-ey,-ez
bbPositionEntity mesh, ex, ey, ez
bbRotateMesh mesh, 0,-eyaw,0
bbRotateMesh mesh,-epitch, 0,0
bbRotateMesh mesh, 0, 0,-eroll
bbRotateEntity mesh,epitch,eyaw,eroll
'-----------------------------------------------
For t1:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
CSGTriangleTYPE_list.remove t1
t1.Remove()
Next
'Free the whole Triangle Collection
Return mesh
End Function
'###############################################################################################
Function CSGVec:CSGVectorType(x#,y#,z#,u#,v#,w#)
'MR 25.01.2003
'Simple Return a Vector as Type :-)
Local ve:CSGVectorType = New CSGVectorType
ve.x=x#
ve.y=y#
ve.z=z#
ve.u=u#
ve.v=v#
ve.w=w#
Return ve
End Function
'###############################################################################################
Function CSGTriAdd:CSGTriangleTYPE(v1:CSGVectorType,v2:CSGVectorType,v3:CSGVectorType)
'MR 02.11.2003
Local newid=0
Local tr:CSGTriangleTYPE = CSGTriangleTYPE(CSGTriangleTYPE_list.Last())
If tr<>Null Then newid = tr.id + 1
'------------------------------------------
t:CSGTriangleTYPE = New CSGTriangleTYPE
t.id = newid
'------------------------------------------ Copy Parameters V1,V2,V3
t.v1x = v1.x
t.v1y = v1.y
t.v1z = v1.z
t.v2x = v2.x
t.v2y = v2.y
t.v2z = v2.z
t.v3x = v3.x
t.v3y = v3.y
t.v3z = v3.z
'------------------------------------------ Memory UVW For Vertex V1,V2,V3
t.u1 = v1.u
t.v1 = v1.v
t.w1 = v1.w
t.u2 = v2.u
t.v2 = v2.v
t.w2 = v2.w
t.u3 = v3.u
t.v3 = v3.v
t.w3 = v3.w
'------------------------------------------ Middle
t.mix = (t.v1x + t.v2x + t.v3x) / 3.0
t.miy = (t.v1y + t.v2y + t.v3y) / 3.0
t.miz = (t.v1z + t.v2z + t.v3z) / 3.0
'------------------------------------------ Normal
Local ax#,ay#,az#
Local bx#,by#,bz#
ax#=t.v2x-t.v1x
ay#=t.v2y-t.v1y
az#=t.v2z-t.v1z
bx#=t.v3x-t.v2x
by#=t.v3y-t.v2y
bz#=t.v3z-t.v2z
t.normx=(ay#*bz#)-(az#*by#)
t.normy=(az#*bx#)-(ax#*bz#)
t.normz=(ax#*by#)-(ay#*bx#)
Local normlen# = Sqr((t.normx*t.normx)+(t.normy*t.normy)+(t.normz*t.normz))
If normlen# > 0.0
t.normx = t.normx/normlen
t.normy = t.normy/normlen
t.normz = t.normz/normlen
Else
t.del = 1
EndIf
'------------------------------------------
Return t
End Function
'###############################################################################################
Function CSGTrisIntersect(t1:CSGTriangleTYPE,t2:CSGTriangleTYPE)
'MR 19.01.2003
'If one triangle in another triangle
Local surf
surf = bbGetSurface(csgmesh[0],1) 'Dummy Mesh with one triangle :-)
bbVertexCoords(surf,0,t1.v1x,t1.v1y,t1.v1z)
bbVertexCoords(surf,1,t1.v2x,t1.v2y,t1.v2z)
bbVertexCoords(surf,2,t1.v3x,t1.v3y,t1.v3z)
surf = bbGetSurface(csgmesh[1],1)
bbVertexCoords(surf,0,t2.v1x,t2.v1y,t2.v1z)
bbVertexCoords(surf,1,t2.v2x,t2.v2y,t2.v2z)
bbVertexCoords(surf,2,t2.v3x,t2.v3y,t2.v3z)
Return bbMeshesIntersect(csgmesh[0],csgmesh[1])
End Function
'###############################################################################################
Function CSGRayIntersect(t1:CSGTriangleTYPE,t2:CSGTriangleTYPE)
'MR 02.11.2003
'i think it used To find the triangles that can be deleted
Local surf = bbGetSurface(csgmesh[0],1) 'Dummy Mesh with one triangle :-)
bbVertexCoords(surf,0,t1.v1x,t1.v1y,t1.v1z)
bbVertexCoords(surf,1,t1.v2x,t1.v2y,t1.v2z)
bbVertexCoords(surf,2,t1.v3x,t1.v3y,t1.v3z)
Local piv = csgpiv
bbRotateEntity piv,0,0,0 '!?
bbPositionEntity(piv,t2.mix ,t2.miy ,t2.miz)
bbAlignToVector (piv,t2.normx,t2.normy,t2.normz,3)
bbMoveEntity piv,0,0,100000.0*csgscale '<--- !
bbEntityPickMode csgmesh[0],2
Local distx# = bbEntityX(piv)-t2.mix
Local disty# = bbEntityY(piv)-t2.miy
Local distz# = bbEntityZ(piv)-t2.miz
Local picked = bbLinePick(t2.mix,t2.miy,t2.miz,distx,disty,distz)
bbEntityPickMode csgmesh[0],0
If picked Then
Return 1
Else
Return 0
EndIf
End Function
'###############################################################################################
Function CSGSplit(t1:CSGTriangleTYPE,t2:CSGTriangleTYPE)
'MR 02.11.2003
'If CSGTrisIntersect = True than split it To New triangles
'now the New triangles are in menory triangle Type collection !
If t1 = Null Or t2 = Null Then Return 0
'------------------------------------------------------------
Local newvx#[3]
Local newvy#[3]
Local newvz#[3]
Local newu#[3]
Local newv#[3]
Local neww#[3]
Local v:CSGVectorType
Local edge1,edge2,edge3
Local epsilon#=0.000001
'------------------------------------------------------------
Local cube = csgmesh[2]
bbEntityPickMode cube,2
bbPositionEntity cube,t1.mix,t1.miy,t1.miz
bbRotateEntity cube,0,0,0
bbAlignToVector(cube,t1.normx,t1.normy,t1.normz,2)
'------------------------------------------------------------
'Edge1 To 2
distx# = t2.v1x-t2.v2x
disty# = t2.v1y-t2.v2y
distz# = t2.v1z-t2.v2z
picked = bbLinePick(t2.v2x,t2.v2y,t2.v2z,distx,disty,distz)
If picked = cube
newvx[1] = bbPickedX()
newvy[1] = bbPickedY()
newvz[1] = bbPickedZ()
v=CSGPickedUVW(t2)
newu[1]=v.u
newv[1]=v.v
neww[1]=v.w
distx# = newvx[1] - t2.v2x
disty# = newvy[1] - t2.v2y
distz# = newvz[1] - t2.v2z
cdist# = Sqr(distx*distx + disty*disty + distz*distz)
If cdist <= epsilon
edge1 = False
Else
edge1 = True
EndIf
EndIf
'------------------------------------------------------------
'Edge2 To 3
distx# = t2.v2x-t2.v3x
disty# = t2.v2y-t2.v3y
distz# = t2.v2z-t2.v3z
picked = bbLinePick(t2.v3x,t2.v3y,t2.v3z,distx,disty,distz)
If picked = cube
newvx[2] = bbPickedX()
newvy[2] = bbPickedY()
newvz[2] = bbPickedZ()
v=CSGPickedUVW(t2)
newu[2]=v.u
newv[2]=v.v
neww[2]=v.w
distx# = newvx[2] - t2.v3x
disty# = newvy[2] - t2.v3y
distz# = newvz[2] - t2.v3z
cdist# = Sqr(distx*distx + disty*disty + distz*distz)
If cdist <= epsilon
edge2 = False
Else
edge2 = True
EndIf
EndIf
'------------------------------------------------------------
'Edge3 To 1
distx# = t2.v3x-t2.v1x
disty# = t2.v3y-t2.v1y
distz# = t2.v3z-t2.v1z
picked = bbLinePick(t2.v1x,t2.v1y,t2.v1z,distx,disty,distz)
If picked = cube
newvx[3] = bbPickedX()
newvy[3] = bbPickedY()
newvz[3] = bbPickedZ()
v=CSGPickedUVW(t2)
newu[3]=v.u
newv[3]=v.v
neww[3]=v.w
distx# = newvx[3] - t2.v1x
disty# = newvy[3] - t2.v1y
distz# = newvz[3] - t2.v1z
cdist# = Sqr(distx*distx + disty*disty + distz*distz)
If cdist <= epsilon
edge3 = False
Else
edge3 = True
EndIf
EndIf
'------------------------------------------------------------
bbEntityPickMode cube,0
If edge1=0 And edge2=0 And edge3=0 Then Return 0
'------------------------------------------------------------
Local v1:CSGVectorType = New CSGVectorType
Local v2:CSGVectorType = New CSGVectorType
Local v3:CSGVectorType = New CSGVectorType
Local v4:CSGVectorType = New CSGVectorType
Local v5:CSGVectorType = New CSGVectorType
Local mindex = t2.mindex
Local sindex = t2.sindex
Local tm:CSGTriangleTYPE
'------------------------------------------------------------
If edge1 And edge2
t2.del = 1
v1 = CSGVec(t2.v1x,t2.v1y,t2.v1z,t2.u1,t2.v1,t2.w1)
v2 = CSGVec(newvx[1],newvy[1],newvz[1],newu[1],newv[1],neww[1])
v3 = CSGVec(t2.v2x,t2.v2y,t2.v2z,t2.u2,t2.v2,t2.w2)
v4 = CSGVec(newvx[2],newvy[2],newvz[2],newu[2],newv[2],neww[2])
v5 = CSGVec(t2.v3x,t2.v3y,t2.v3z,t2.u3,t2.v3,t2.w3)
tm = CSGTriAdd(v1,v2,v5)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
tm = CSGTriAdd(v2,v4,v5)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
tm = CSGTriAdd(v2,v3,v4)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
ElseIf edge1 And edge3
t2.del = 1
v1 = CSGVec(t2.v1x,t2.v1y,t2.v1z,t2.u1,t2.v1,t2.w1)
v2 = CSGVec(newvx[1],newvy[1],newvz[1],newu[1],newv[1],neww[1])
v3 = CSGVec(t2.v2x,t2.v2y,t2.v2z,t2.u2,t2.v2,t2.w2)
v4 = CSGVec(t2.v3x,t2.v3y,t2.v3z,t2.u3,t2.v3,t2.w3)
v5 = CSGVec(newvx[3],newvy[3],newvz[3],newu[3],newv[3],neww[3])
tm = CSGTriAdd(v1,v2,v5) '1,2,5
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
tm = CSGTriAdd(v2,v4,v5)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
tm = CSGTriAdd(v2,v3,v4)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
ElseIf edge2 And edge3
t2.del = 1
v1 = CSGVec(t2.v1x,t2.v1y,t2.v1z,t2.u1,t2.v1,t2.w1)
v2 = CSGVec(t2.v2x,t2.v2y,t2.v2z,t2.u2,t2.v2,t2.w2)
v3 = CSGVec(newvx[2],newvy[2],newvz[2],newu[2],newv[2],neww[2])
v4 = CSGVec(t2.v3x,t2.v3y,t2.v3z,t2.u3,t2.v3,t2.w3)
v5 = CSGVec(newvx[3],newvy[3],newvz[3],newu[3],newv[3],neww[3])
tm = CSGTriAdd(v1,v2,v5)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
tm = CSGTriAdd(v2,v3,v5)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
tm = CSGTriAdd(v3,v4,v5)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
ElseIf edge2
t2.del = 1
v1 = CSGVec(t2.v1x,t2.v1y,t2.v1z,t2.u1,t2.v1,t2.w1)
v2 = CSGVec(t2.v2x,t2.v2y,t2.v2z,t2.u2,t2.v2,t2.w2)
v3 = CSGVec(newvx[2],newvy[2],newvz[2],newu[2],newv[2],neww[2])
v4 = CSGVec(t2.v3x,t2.v3y,t2.v3z,t2.u3,t2.v3,t2.w3)
tm = CSGTriAdd(v1,v2,v3)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
tm = CSGTriAdd(v1,v3,v4)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
ElseIf edge1
t2.del = 1
v1 = CSGVec(t2.v1x,t2.v1y,t2.v1z,t2.u1,t2.v1,t2.w1)
v2 = CSGVec(newvx[1],newvy[1],newvz[1],newu[1],newv[1],neww[1])
v3 = CSGVec(t2.v2x,t2.v2y,t2.v2z,t2.u2,t2.v2,t2.w2)
v4 = CSGVec(t2.v3x,t2.v3y,t2.v3z,t2.u3,t2.v3,t2.w3)
tm = CSGTriAdd(v1,v2,v4)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
tm = CSGTriAdd(v2,v3,v4)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
ElseIf edge3
t2.del = 1
v1 = CSGVec(t2.v1x,t2.v1y,t2.v1z,t2.u1,t2.v1,t2.w1)
v2 = CSGVec(t2.v2x,t2.v2y,t2.v2z,t2.u2,t2.v2,t2.w2)
v3 = CSGVec(t2.v3x,t2.v3y,t2.v3z,t2.u3,t2.v3,t2.w3)
v4 = CSGVec(newvx[3],newvy[3],newvz[3],newu[3],newv[3],neww[3])
tm = CSGTriAdd(v1,v2,v4)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
tm = CSGTriAdd(v2,v3,v4)
tm.mindex= mindex
tm.sindex= sindex
tm.tarid = t1.id
EndIf
If t2.del=1 Then
CSGTriangleTYPE_list.remove t2
t2.Remove()
EndIf
End Function
'###############################################################################################
Function CSGTriRemoveDel()
'MR 19.01.2003
'-----------------------------------------------
For t:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t.del=1 Then
CSGTriangleTYPE_list.remove t
t.Remove()
EndIf
Next
End Function
'###############################################################################################
Function CSGMakeNewMesh()
'MR 26.01.2003
'----------------------------------------------- New Mesh
Local m=bbCreateMesh()
'----------------------------------------------- Find Max Surfaces For Mesh 1
Local smax1=0
For t:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t.mindex=1 Then
If t.sindex>smax1 Then smax1=t.sindex
EndIf
Next
'----------------------------------------------- Find Max Surfaces For Mesh 2
Local smax2=0
For t:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t.mindex=2 Then
If t.sindex>smax2 Then smax2=t.sindex
EndIf
Next
'----------------------------------------------- Add Max Surface Index from Mesh 1 To Mesh 2
For t:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t.mindex=2 Then
t.sindex=t.sindex+smax1
EndIf
Next
'----------------------------------------------- Create all Surfaces
Local smax=smax1+smax2 'all needed surfaces
Local si
Local surf
For si=1 To smax
surf=bbCreateSurface(m)
Next
'-----------------------------------------------
Return m
End Function
'###############################################################################################
Function CSGAddTheTriangles(m,mindex,FlipTriangles=0)
'MR 02.11.2003
'----------------------------------------------- Bring Triangle To Surface
Local v1,v2,v3 'VertexIndex
Local surf=0
Local si
'-----------------------------------------------
For si=1 To bbCountSurfaces(m)
For t:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t.del=0 And t.mindex=mindex And t.sindex=si Then
surf=bbGetSurface(m,si)
v1=bbAddVertex(surf,t.v1x,t.v1y,t.v1z)
v2=bbAddVertex(surf,t.v2x,t.v2y,t.v2z)
v3=bbAddVertex(surf,t.v3x,t.v3y,t.v3z)
bbVertexNormal surf,v1,t.normx,t.normy,t.normz
bbVertexNormal surf,v2,t.normx,t.normy,t.normz
bbVertexNormal surf,v3,t.normx,t.normy,t.normz
bbVertexTexCoords surf,v1,t.u1,t.v1,t.w1 'Set UV Coords !
bbVertexTexCoords surf,v2,t.u2,t.v2,t.w2
bbVertexTexCoords surf,v3,t.u3,t.v3,t.w3
If FlipTriangles=0 Then
bbAddTriangle surf,v1,v2,v3
Else
bbAddTriangle surf,v3,v2,v1
EndIf
CSGTriangleTYPE_list.remove t
t.Remove()
'Remove the Triangle from Collection !
EndIf
Next
Next 'All Surfaces
'-----------------------------------------------
bbUpdateNormals m
End Function
'###############################################################################################
Function CSGRepaint(meshnew,mesh1,mesh2)
'MR 02.11.2003
'Repaint all Surfaces :-)
'----------------------------------------------------------------------------------------------
Local cc1=0 'New SurfaceCount !
Local c1
'Paint New Surfaces from Mesh A
If bbCountSurfaces (mesh1)=>1 Then
For c1=1 To bbCountSurfaces(mesh1)
cc1=cc1+1
If bbCountSurfaces(meshnew)=>cc1 Then
bbPaintSurface bbGetSurface(meshnew,cc1),bbGetSurfaceBrush(bbGetSurface(mesh1,c1))
EndIf
Next
EndIf 'bbCountSurfaces=>1
'----------------------------------------------------------------------------------------------
'Paint New Surfaces from Mesh B
If bbCountSurfaces(mesh2)=>1 Then
For c1=1 To bbCountSurfaces(mesh2)
cc1=cc1+1
If bbCountSurfaces(meshnew)=>cc1 Then
bbPaintSurface bbGetSurface(meshnew,cc1),bbGetSurfaceBrush(bbGetSurface(mesh2,c1))
EndIf
Next
EndIf 'bbCountSurfaces=>1
'----------------------------------------------------------------------------------------------
End Function
'###############################################################################################
Function CSGClearLTris(mindex)
'MR 26.01.2003
'Clears the triangles that have no partners
Local epsilon#=0.000001
Local count=0
Local full
Local car
Local distx#
Local disty#
Local distz#
Local cdist#
Local vax#
Local vay#
Local vaz#
Local vbx#
Local vby#
Local vbz#
For t:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t.mindex = mindex And t.del = 0
count=0
For full = 0 To 2
Select full
Case 0
vax#=t.v1x
vay#=t.v1y
vaz#=t.v1z
Case 1
vax#=t.v2x
vay#=t.v2y
vaz#=t.v2z
Case 2
vax#=t.v3x
vay#=t.v3y
vaz#=t.v3z
End Select
For tom:CSGTriangleTYPE = EachIn CSGTriangleTYPE_list
If t.id<>tom.id And tom.del = 0 And tom.mindex = mindex
cdist = 0
For car = 0 To 2
Select car
Case 0
vbx#=tom.v1x
vby#=tom.v1y
vbz#=tom.v1z
Case 1
vbx#=tom.v2x
vby#=tom.v2y
vbz#=tom.v2z
Case 2
vbx#=tom.v3x
vby#=tom.v3y
vbz#=tom.v3z
End Select
distx# = vbx - vax
disty# = vby - vay
distz# = vbz - vaz
cdist# = Sqr(distx*distx + disty*disty + distz*distz)
If cdist <= epsilon Then Exit
Next
If cdist >= 0.0 Then
count = count + 1
Exit
EndIf
EndIf
Next
Next
If count < 3
CSGTriangleTYPE_list.remove t
t.Remove()
EndIf
EndIf
Next
End Function
'############################################################################################################
Function CSGGetVertexRealPosition:CSGVectorType(bbEntity,surf,vindex)
Local pivot1=bbCreatePivot()
Local pivot2=bbCreatePivot(pivot1)
Local vreal:CSGVectorType =New CSGVectorType
bbPositionEntity pivot1,0,0,0
bbPositionEntity pivot2,bbVertexX(surf,vindex),bbVertexY(surf,vindex),bbVertexZ(surf,vindex)
bbRotateEntity pivot1,bbEntityPitch(bbEntity,True),bbEntityYaw(bbEntity,True),bbEntityRoll(bbEntity,True)
vreal.x=bbEntityX(pivot2,True)+bbEntityX(bbEntity,True)
vreal.y=bbEntityY(pivot2,True)+bbEntityY(bbEntity,True)
vreal.z=bbEntityZ(pivot2,True)+bbEntityZ(bbEntity,True)
vreal.u=bbVertexU(surf,vindex)
vreal.v=bbVertexV(surf,vindex)
vreal.w=bbVertexW(surf,vindex)
bbFreeEntity pivot2
bbFreeEntity pivot1
Return vreal
End Function
'#################################################################################################### UVW
Function CSGPickedUVW:CSGVectorType(t2:CSGTriangleTYPE)
'MR 25.01.2003
Local ve:CSGVectorType = New CSGVectorType
Local px#=bbPickedX()
Local py#=bbPickedY()
Local pz#=bbPickedZ()
Local pnx#=t2.normx
Local pny#=t2.normy
Local pnz#=t2.normz
'DebugLog "Picked XYZ "+px+" "+py+" "+pz
' Select which component of xyz coordinates To ignore
Local coords = 3
If Abs(PNX) > Abs(PNY)
If Abs(PNX)>Abs(PNZ) Then coords = 1
Else
If Abs(PNY)>Abs(PNZ) Then coords = 2
EndIf
'DebugLog "coords "+coords
Local a0#,a1#,b0#,b1#,c0#,c1#
If (coords = 3)
'xy components
' edge 1
a0# = t2.v2x - t2.v1x
a1# = t2.v2y - t2.v1y
' edge 2
b0# = t2.v3x - t2.v1x
b1# = t2.v3y - t2.v1y
' picked offset from triangle vertex 1
c0# = px - t2.v1x
c1# = py - t2.v1y
Else
If (coords = 2)
' xz components
' edge 1
a0# = t2.v2x - t2.v1x
a1# = t2.v2z - t2.v1z
' edge 2
b0# = t2.v3x - t2.v1x
b1# = t2.v3z - t2.v1z
' picked offset from triangle vertex 1
c0# = px - t2.v1x
c1# = pz - t2.v1z
Else
' yz components
' edge 1
a0# = t2.v2y - t2.v1y
a1# = t2.v2z - t2.v1z
' edge 2
b0# = t2.v3y - t2.v1y
b1# = t2.v3z - t2.v1z
' picked offset from triangle vertex 1
c0# = py - t2.v1y
c1# = pz - t2.v1z
End If
End If
'
' u And v are offsets from vertex 0 along edge 0 And edge 1
' using these it is possible To calculate the Texture UVW coordinates
' of the picked XYZ location
'
' a0*u + b0*v = c0
' a1*u + b1*v = c1
'
' solve equation (standard equation with 2 unknown quantities)
' check a math book To see why the following is True
'
Local u# = (c0*b1 - b0*c1) / (a0*b1 - b0*a1)
Local v# = (a0*c1 - c0*a1) / (a0*b1 - b0*a1)
'DebugLog "U "+u+" V "+v
' Calculate picked uvw's
ve.u = (t2.u1 + ((t2.u2 - t2.u1) * u) + ((t2.u3 - t2.u1) * v))
ve.v = (t2.v1 + ((t2.v2 - t2.v1) * u) + ((t2.v3 - t2.v1) * v))
ve.w = (t2.w1 + ((t2.w2 - t2.w1) * u) + ((t2.w3 - t2.w1) * v))
'DebugLog "U "+ve.u+" V "+ve.v
Return ve
End Function
'###############################################################################################
'Function CSGExample()
'MR 02.11.2003
' AppTitle "CSG Test"
' Graphics3D 640,480
'---------------------------------------------------------------------------------------
' Local texture=LoadTexture("ch1.bmp")
' Local brush=CreateBrush(255,255,255)
' BrushTexture brush,texture
'cube =CSGAddMyMeshCubeX( 0,0,0,0,20, 4,20,1,1,1,brush,brush,brush,brush,brush,brush)
'cube =CSGAddMyMeshCubeX(cube,0,0,0,10,10,10,1,1,1,brush,brush,brush,brush,brush,brush)
' cube = bbCreateCube()
' bbScaleMesh cube,10,2,10
' For s=1 To bbCountSurfaces(cube)
' bbPaintSurface bbGetSurface(cube,s),brush
' Next
' bbEntityFX cube,16
'TurnbbEntity cube,90,0,0
'bbMoveEntity cube,0,5,0
'---------------------------------------------------------------------------------------
' Local tex2=CreateTexture(64,64)
' SetBuffer TextureBuffer(tex2)
' Color 128,0,0
' Rect 0,0,64,64
' Color 255,0,0
' Rect 0,0,32,32
' Rect 32,32,32,32
' SetBuffer BackBuffer()
' Local br2=CreateBrush()
' BrushTexture br2,tex2
' ScaleTexture tex2,.25,.25
'cube2 = CreateSphere(8)
'cube2 = bbCreateCube()
' cube2 = CreateCylinder(16)
' bbScaleMesh cube2,6,6,6
' For s=1 To bbCountSurfaces(cube2)
' bbPaintSurface bbGetSurface(cube2,s),br2
' Next
'---------------------------------------------------------------------------------------
' cam = CreateCamera()
' bbMoveEntity cam,0,10,-20
' PointbbEntity cam,cube2
' CameraClsColor cam,0,0,80
' CameraRange cam,1,2000
'
'---------------------------------------------------------------------------------------
' Local light=CreateLight()
' TurnbbEntity light,45,1,0
' LightRange light,50
' bbPositionEntity light,0,50,-50
'---------------------------------------------------------------------------------------
' bbUpdateNormals cube
' bbUpdateNormals cube2
' bbEntityAlpha cube2,.5
'---------------------------------------------------------------------------------------
' Local wire=0
' Local Mode=2
' Color 255,255,255
' While Not KeyHit(1) 'ESC
' If KeyHit(2) Then Mode=1 '1
' If KeyHit(3) Then Mode=2 '2
' If KeyHit(4) Then Mode=3 '3
' If KeyDown(205) Then TranslatebbEntity cube2,.1,0,0
' If KeyDown(203) Then TranslatebbEntity cube2,-.1,0,0
' If KeyDown(30) Then TranslatebbEntity cube2,0,0,.1
' If KeyDown(44) Then TranslatebbEntity cube2,0,0,-.1 'Y German
' If KeyDown(200) Then TranslatebbEntity cube2,0,.1,0
' If KeyDown(208) Then TranslatebbEntity cube2,0,-.1,0
' If KeyDown(37) Then 'K
' 'ClearSurface bbGetSurface(cube,7),True,True 'TEST
' EndIf
' If KeyDown(18) Then 'E
' TurnbbEntity cube,-1,0,0
' EndIf
' If KeyDown(19) Then 'R
' TurnbbEntity cube,0,-1,0
' EndIf
' If KeyDown(20) Then 'T
' TurnbbEntity cube,0,0,-1
' EndIf
' If KeyHit(21) Then 'Z German
' TurnbbEntity cube2,-45,0,0
' EndIf
' If KeyHit(31) Then 'S = Screenshot
' SaveBuffer FrontBuffer(),"screenshot.bmp"
' EndIf
' If KeyHit(17) 'W
' wire = 1 - wire
' WireFrame wire
' EndIf
' If KeyHit(57) 'Space
' Cls
' RenderWorld
' Text 0,0,"Wait ..."
' Flip
' e = MilliSecs()
' man = csg(cube,cube2,Mode) '1 Add , 2 Sub , 3 Diff
' e = MilliSecs() -e
' bbFreeEntity cube
' cube = man
' 'PaintbbEntity cube,brush
' bbEntityFX cube,16
' FlushKeys
' EndIf
' UpdateWorld
' RenderWorld
' Text 0,0,"Time: "+e+" ms"
' Text 0,15*1,"Arrows to Move Left/Right/Up/Down"
' Text 0,15*2,"A/Z to move Forward and Back"
' Text 0,15*3,"Tris All : "+TrisRendered()
' Text 0,15*4,"Tris 1 : "+CSGCountAllTriangles(cube )+" Surfaces : " +bbCountSurfaces(cube)
' Text 0,15*5,"Tris 2 : "+CSGCountAllTriangles(cube2)
' Text 0,15*6,"Mode: "+Mode
' Text 0,15*7,"E,R,T Rotate Obj. 1"
' Text 0,15*8,"Y Rotate Obj. 2"
' Text 0,15*9,"S Screenshot"
' Flip
' Wend
'End Function
'####################################################################################################
Function CSGCountAllTriangles(mesh) 'only For example
'without child bbEntitys
Local si
If mesh=0 Then Return 0
Local c=0
For si=1 To bbCountSurfaces(mesh)
c=c+bbCountTriangles(bbGetSurface(mesh,si))
Next
Return c
End Function
'####################################################################################################
Function CSGAddMyMeshCubeX(m,x1#,y1#,z1#,x2#,y2#,z2#,cx,cy,cz,br_top,br_bottom,br_left,br_right,br_front,br_back,o_top=1,o_bottom=1,o_left=1,o_right=1,o_front=1,o_back=1)
'MR 31.10.2002
'Create a Cube centered
'm =bbEntity Handle 0=Create a New one :-)
'x1,x2 =From X1 To X2
'cx,cy,cy=Center
'br_ =Brush Handle
'o_ =Optional 1=Create 0=No Create
Local w#,h#,d#
'w#=witdh (X)
'h#=height (Y)
'd#=depth (Z)
w#=x2#-x1#
h#=y2#-y1#
d#=z2#-z1#
'--------------------- Center ?
If cx=1 Then
x1=x1-w/2.0
x2=x2-w/2.0
EndIf
If cy=1 Then
y1=y1-h/2.0
y2=y2-h/2.0
EndIf
If cz=1 Then
z1=z1-d/2.0
z2=z2-d/2.0
EndIf
'-----------------------------
If m=0 Then
m=bbCreateMesh()
EndIf
'-----------------------------
'top face
If o_top=1 Then
s=bbCreateSurface( m , Br_Top)
bbAddVertex s,x1,y2,z2,0,1
bbAddVertex s,x2,y2,z2,0,0
bbAddVertex s,x2,y2,z1,1,0
bbAddVertex s,x1,y2,z1,1,1
bbAddTriangle s,0,1,2
bbAddTriangle s,0,2,3
EndIf
'bottom face
If o_bottom=1 Then
s=bbCreateSurface( m , Br_Bottom)
bbAddVertex s,x1,y1,z1,1,0
bbAddVertex s,x2,y1,z1,1,1
bbAddVertex s,x2,y1,z2,0,1
bbAddVertex s,x1,y1,z2,0,0
bbAddTriangle s,0,1,2
bbAddTriangle s,0,2,3
EndIf
'Left face
If o_left=1 Then
s=bbCreateSurface( m , Br_Left)
bbAddVertex s,x1,y2,z2,0,0
bbAddVertex s,x1,y2,z1,1,0
bbAddVertex s,x1,y1,z1,1,1
bbAddVertex s,x1,y1,z2,0,1
bbAddTriangle s,0,1,2
bbAddTriangle s,0,2,3
EndIf
'Right face
If o_right=1 Then
s=bbCreateSurface( m , Br_Right)
bbAddVertex s,x2,y2,z1,0,0
bbAddVertex s,x2,y2,z2,1,0
bbAddVertex s,x2,y1,z2,1,1
bbAddVertex s,x2,y1,z1,0,1
bbAddTriangle s,0,1,2
bbAddTriangle s,0,2,3
EndIf
'front face
If o_front=1 Then
s=bbCreateSurface( m , Br_Front)
bbAddVertex s,x1,y2,z1,0,0
bbAddVertex s,x2,y2,z1,1,0
bbAddVertex s,x2,y1,z1,1,1
bbAddVertex s,x1,y1,z1,0,1
bbAddTriangle s,0,1,2
bbAddTriangle s,0,2,3
EndIf
'back face
If o_back=1 Then
s=bbCreateSurface( m , Br_Back)
bbAddVertex s,x2,y2,z2,0,0
bbAddVertex s,x1,y2,z2,1,0
bbAddVertex s,x1,y1,z2,1,1
bbAddVertex s,x2,y1,z2,0,1
bbAddTriangle s,0,1,2
bbAddTriangle s,0,2,3
EndIf
bbUpdateNormals m
'bbEntityPickMode m,2 'Poly
Return m
End Function
'#################################################################################################### |
Comments
None.
Code Archives Forum