MeshIntersect ( first_mesh,second_mesh[,parent][,tolerance#] )

Parameters

first_mesh - the first solid mesh

second_mesh - the second solid mesh

parent (optional) - parent entity for the new mesh; 0 for none (default)

tolerance# (optional) - how close, in world units, a point must be to a face to count as lying on it; 0.001 (default)

Description

Creates a new mesh from only the space two meshes share.

Use it to trim a shape to a boundary, cut a lens from two spheres, or round off a dice by intersecting a cube with a sphere. Where the meshes do not overlap at all, the result is an empty mesh. MeshUnion joins shapes, and MeshSubtract carves one out of another. Do not confuse it with MeshesIntersect, which only tells you whether two meshes overlap.

The meshes are read where they are now - position, rotation and scale, even uneven or negative scale, and their parents' too. Neither is changed, so you usually hide or free them once you have the result. The new mesh has no position, rotation or scale of its own: its vertices are in world space, or in the parent's space when you give a parent, and it goes into the parent's world, or the selected world.

Both meshes must be closed solids - no gaps, every face pointing outwards, no part passing through itself. Cubes, spheres and solid cylinders and cones are fine, and so are concave shapes, several surfaces and separate pieces in one mesh. Open shapes such as terrains, planes and uncapped cylinders have no inside, so what you get from them is unpredictable.

Only the mesh itself is used: its children, animation pose, morph targets, LODs and shader displacement are ignored, and the result has no animation, physics or entity effects. Materials come across: each surface keeps its brush, textures and shader, the entity's colour and alpha are kept, and UVs, vertex colours and normals carry on smoothly across the cuts. Faces made by a cut take the second mesh's material.

The result is an ordinary mesh: texture it, collide with it, free it with FreeEntity, or feed it into another CSG command. A shape that leaves nothing behind gives a mesh with no surfaces, not 0.

CSG is slow and can multiply the triangle count, so build shapes while a level loads or when the player edits something, not every frame. Choose a tolerance smaller than the smallest detail you want to keep. Call it after Graphics3D; a missing handle, a mesh scaled to nothing or a tolerance that is not positive is a runtime error that leaves both meshes as they were.

Try all three operations side by side in the MeshCSG.bb sample.


See also: MeshUnion, MeshSubtract, MeshesIntersect, CopyMesh.

Example

; MeshIntersect Example
; ---------------------

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

camera=CreateCamera()
PositionEntity camera,0,1,-5

light=CreateLight()
RotateEntity light,45,45,0

; A blue stone block and a gold ball to shape it with
block=CreateCube()
EntityColor block,70,160,235
ball=CreateSphere(16)
ScaleEntity ball,1.25,1.25,1.25
EntityColor ball,240,170,55

; Only the result is drawn; the shapes are read wherever they are
HideEntity block
HideEntity ball

ball_x#=0.8
result=0
spin#=0

While Not KeyDown(1)

    ; [ / ] slide the ball, and build a new result
    If KeyHit(26) And ball_x>-2.5 Then
        ball_x=ball_x-0.25
        FreeEntity result
        result=0
    EndIf
    If KeyHit(27) And ball_x<2.5 Then
        ball_x=ball_x+0.25
        FreeEntity result
        result=0
    EndIf
    If result=0 Then
        PositionEntity ball,ball_x,0,0
        ; Only the space the two shapes share
        result=MeshIntersect(block,ball)
        triangles=0
        For index=1 To CountSurfaces(result)
            triangles=triangles+CountTriangles(GetSurface(result,index))
        Next
    EndIf

    ; The result has no transform of its own, so spin it as it is redrawn
    spin=spin+0.5
    RotateEntity result,15,spin,0

    ; Arrow keys move the camera
    If KeyDown(200) Then MoveEntity camera,0,0,0.1
    If KeyDown(208) Then MoveEntity camera,0,0,-0.1
    If KeyDown(203) Then TurnEntity camera,0,1,0
    If KeyDown(205) Then TurnEntity camera,0,-1,0

    RenderWorld

    Text 0,0,"Arrow keys: move camera   [ / ] : slide the ball   Esc: exit"
    Text 0,20,"MeshIntersect(block,ball)   ball at x="+ball_x
    Text 0,40,"Only where block and ball overlap   triangles: "+triangles
    If CountSurfaces(result)=0 Then Text 0,60,"An empty mesh: block and ball no longer overlap"

    Flip

Wend

End

Index