Split a mesh with an arbitrary plane! (Example)

Blitz3D Forums/Blitz3D Programming/Split a mesh with an arbitrary plane! (Example)

JoshK(Posted 2003) [#1]
This requires my 3D math library, available at www.leadwerks.com/code. It will split any mesh along an arbitrary plane, creating two new meshes. Triangle normals are retained, but the new mesh will be pretty segmented. A WeldMesh() function is coming next to merge the vertices back into an optimized mesh.

This is useful for CSG, BSP, and I myself am going to be using this for real-time shadows.

nx#=0.5
ny#=-0.5
nz#=1
d#=0

Graphics3D 800,600,16,2

Global resulta,resultb

cam=CreateCamera()
CameraClsColor cam,255,255,255
TurnEntity cam,45,45,0
MoveEntity cam,0,0,-15

m=LoadMesh("car.x")
EntityColor m,255,0,0

sliceplane=CreateCube()
ScaleMesh sliceplane,6,6,0
EntityAlpha sliceplane,0.5
EntityColor sliceplane,200,200,200
EntityFX sliceplane,1
AlignToVector sliceplane,nx,ny,nz,3

CreateLight()
RenderWorld
Flip
WaitKey

splitmesh m,nx,ny,nz,d

FreeEntity m
EntityColor resulta,0,255,0
EntityColor resultb,0,0,255

EntityParent resulta,sliceplane
EntityParent resultb,sliceplane

While Not KeyHit(1)
	TurnEntity sliceplane,0,1,0,True
	MoveEntity resulta,0,0,0.01
	MoveEntity resultb,0,0,-0.01
	RenderWorld
	Text 0,0,split
	Flip
	Wend

Function SplitMesh(m,nx#,ny#,nz#,d#)
resulta=CreateMesh()
resultb=CreateMesh()
For s=1 To CountSurfaces(m)
	surf=GetSurface(m,s)
	surfa=CreateSurface(resulta)
	surfb=CreateSurface(resultb)
	SplitSurface(surf,surfa,surfb,nx,ny,nz,d)
	Next
End Function

Function SplitSurface(surf,surfa,surfb,nx#,ny#,nz#,d#)
For t=0 To CountTriangles(surf)-1
	A=TriangleVertex(surf,t,0)
	B=TriangleVertex(surf,t,1)
	C=TriangleVertex(surf,t,2)
	SplitTriangle(surfa,surfb,VertexX(surf,A),VertexY(surf,A),VertexZ(surf,A),VertexX(surf,B),VertexY(surf,B),VertexZ(surf,B),VertexX(surf,C),VertexY(surf,C),VertexZ(surf,C),nx,ny,nz,d)
	Next
End Function

Function SplitTriangle(surfa,surfb,Ax#,Ay#,Az#,Bx#,By#,Bz#,Cx#,Cy#,Cz#,nx#,ny#,nz#,d#)
pa#=PointOnPlane(ax,ay,az,nx,ny,nz,d)
pb#=PointOnPlane(bx,by,bz,nx,ny,nz,d)
pc#=PointOnPlane(cx,cy,cz,nx,ny,nz,d)
If Sgn(pa)=Sgn(pb) And Sgn(pb)=Sgn(pc)
	If pa>0.0
		A=AddVertex(surfa,ax,ay,az)
		B=AddVertex(surfa,bx,by,bz)
		C=AddVertex(surfa,cx,cy,cz)
		AddTriangle surfa,a,b,c		
		Else
		A=AddVertex(surfb,ax,ay,az)
		B=AddVertex(surfb,bx,by,bz)
		C=AddVertex(surfb,cx,cy,cz)
		AddTriangle surfb,a,b,c
		EndIf
	Return False
	EndIf
If Sgn(pa)=Sgn(pb);AB|C
	If pa<0.0
		surf=surfa
		surfa=surfb
		surfb=surf
		EndIf
	RayIntersectsPlane(ax,ay,az,cx,cy,cz,nx,ny,nz,d)
	dx#=VectorX()
	dy#=VectorY()
	dz#=VectorZ()
	RayIntersectsPlane(bx,by,bz,cx,cy,cz,nx,ny,nz,d)
	ex#=VectorX()
	ey#=VectorY()
	ez#=VectorZ()
	A=AddVertex(surfa,ax,ay,az)
	B=AddVertex(surfa,bx,by,bz)
	C=AddVertex(surfb,cx,cy,cz)
	D=AddVertex(surfa,Dx,Dy,Dz)
	E=AddVertex(surfa,Ex,Ey,Ez)
	AddTriangle surfa,D,A,B
	AddTriangle surfa,D,B,E
	D=AddVertex(surfb,Dx,Dy,Dz)
	E=AddVertex(surfb,Ex,Ey,Ez)
	AddTriangle surfb,C,D,E
	ElseIf Sgn(pa)=Sgn(pc);AC|B
	If pa<0.0
		surf=surfa
		surfa=surfb
		surfb=surf
		EndIf
	RayIntersectsPlane(ax,ay,az,bx,by,bz,nx,ny,nz,d)
	dx#=VectorX()
	dy#=VectorY()
	dz#=VectorZ()	
	RayIntersectsPlane(bx,by,bz,cx,cy,cz,nx,ny,nz,d)	
	ex#=VectorX()
	ey#=VectorY()
	ez#=VectorZ()
	A=AddVertex(surfa,ax,ay,az)
	B=AddVertex(surfb,bx,by,bz)
	C=AddVertex(surfa,cx,cy,cz)
	D=AddVertex(surfa,Dx,Dy,Dz)
	E=AddVertex(surfa,Ex,Ey,Ez)
	AddTriangle surfa,A,D,C
	AddTriangle surfa,D,E,C
	D=AddVertex(surfb,Dx,Dy,Dz)
	E=AddVertex(surfb,Ex,Ey,Ez)
	AddTriangle surfb,B,E,D
	ElseIf Sgn(pb)=Sgn(pc);BC|A
	If pa>0.0
		surf=surfa
		surfa=surfb
		surfb=surf
		EndIf
	RayIntersectsPlane(ax,ay,az,cx,cy,cz,nx,ny,nz,d)
	dx#=VectorX()
	dy#=VectorY()
	dz#=VectorZ()	
	RayIntersectsPlane(bx,by,bz,ax,ay,az,nx,ny,nz,d)
	ex#=VectorX()
	ey#=VectorY()
	ez#=VectorZ()	
	A=AddVertex(surfb,ax,ay,az)
	B=AddVertex(surfa,bx,by,bz)
	C=AddVertex(surfa,cx,cy,cz)
	D=AddVertex(surfa,Dx,Dy,Dz)
	E=AddVertex(surfa,Ex,Ey,Ez)
	AddTriangle surfa,B,C,D
	AddTriangle surfa,B,D,E
	D=AddVertex(surfb,Dx,Dy,Dz)
	E=AddVertex(surfb,Ex,Ey,Ez)
	AddTriangle surfb,A,E,D
	EndIf
Return True
End Function



SSS(Posted 2003) [#2]
do i need a lib to run it, it doesnt work


Mathieu A(Posted 2003) [#3]
@SSS

Yes you need the math3d library from Halo that you put into the userlibs directory.

@Halo

Wow it's really great! I'm sur that it will be very useful for lots of thing


sswift(Posted 2003) [#4]
So I guess you decided that you do NOT want to trade Cartography shop for my shaodw system?

You could AT LEAST have gotten BACK to me once you decided that you want to just implement animated shadows yourself. :-)

I knew I shouldn't have told ya that trick about just rotating the texture and using static shadows. :-)

I guess Halo just doesn't want levels created by a professional level designer in Cartography shop to show off what a great tool it can be. :-)

Oh and when Halo says he'll be using it for "real time shadows" what he means is rotating lightmaps of fans and other things.

You won't get TRUE realtime shadows like my shadow system produces if you're splitting and welding polygons. :-)


SabataRH(Posted 2003) [#5]

I guess Halo just doesn't want levels created by a professional level designer in Cartography shop to show off what a great tool it can be.



I could use one of those, any ideas where I can find one?


sswift(Posted 2003) [#6]
Hmph! :-)


SabataRH(Posted 2003) [#7]
:)>>


Warren(Posted 2003) [#8]
sswift

You've used up your emoticon budget for the month.


sswift(Posted 2003) [#9]
Ha! I have not yet begun to emote! :-)


JoshK(Posted 2003) [#10]
I recommend using this function, and then using the weldmesh() function to untriangulate the mesh. This needs to be redone so that the mesh doesn't get triangulated.