csg voxel construction representation (Constructive Solid Geometry)

The full name of csg is Constructive Solid Geometry, which is the voxel construction representation. There is support in the godot engine. It is mainly used for the combination of some shapes to form a new mesh body through the operations of union, intersection and subtraction. This technique also has a corresponding application in the shape distance recognition of the signed distance field. Prototyping levels with CSG — Godot Engine (stable) documentation in English

The core method is mergeBrushes

intersectsInclusive

intersectsInclusive will first check whether the a-side and the b-side intersect aabb, and if they intersect, it will enter the specific intersection calculation, which will also enter updateFaces.

Focus 1: updateFaces

updateFaces will remove some vertices that are very close, and updateFaces mainly depends on the intersection situation, first through isPointOver and hasPoint to see if they intersect, where isPointOver is the judgment (n.dot(point) > d); that is, if the number is 3, it means The three vertices of side B are all on the other side of side A, so there will be no intersection.

Then check whether it intersects by the axis separation method of sat.

SAT:

sat is based on the axis separation to determine whether two convex polygons intersect. The method here is to cross-multiply all the sides of the two triangles, and the result of the cross-multiplication is then multiplied by the sides of the two triangles just taken out to find the projection. position, and then subtract the two projection distances to get the maximum offset and minimum offset of the projection. If the maximum offset is still less than 0 or the minimum offset is greater than 0, it means that the two triangles do not intersect.

 

The specific principle is written here, vector operation realizes the collision system - llsansun's blog - CSDN blog

add a new face if it intersects,

 

insertFace:

Here we mainly look at insertFace,

 

Here, first check whether the A side contains the point of the B side, if it contains the direct add point, if not, if the two points are on the same side of the surface, it will not be added, and if it is not and they have an intersecting distance, the point will be added.

findEdgeIntersections和addVertexIdxSorted

Then use findEdgeIntersections to find out whether it is an edge intersection. If it is an edge intersection, special processing will be required, otherwise there will be defects. For example, if the edge is deleted, the shape of the entire mesh will be inconsistent with the original shape. If there is an edge, a face should be added. to make up. Check if the edge exists, by checking if the intersecting segment is parallel to the edge. If the pair is on a segment, add its index to the segment index as well. Create two new faces around the new edge and delete the face.  

mergeFaces:

Then execute mergeFaces, where he will remove the adjacent vertices, otherwise he will add to the face, the flat multi-vertex face will also be removed, and if it is an edge, create two new faces around the new edge and delete the noodle.  

addFace:

Then add the point and uv to the meshMerge by addingFacesToMesh and addFace, and record the merge information of the vertices. Then add it to the faces. This faces is used for stepping the normal direction of the following faces to see if there are other faces that intersect, specifically in markInsideFaces.

Focus 2: markInsideFaces

Then execute markInsideFaces, here is the key merge record, create a binary tree of hierarchical data structure through createBvh, and then traverse all faces, intersectsInclusive to see if the face of a and the face of b intersect.

bvhInside

Enter the specific bvhInside judgment only when there is an intersection. The judgment of bvhInside here is to traverse all the faces, and then pass through the faces in the current bvh and then execute intersectsRay, traverse the current center position of the A face and the normal to see if there is any intersection belonging to another source The triangle of the face (that is, the face of fromA is compared with the face of fromB, if both are fromA or both are fromB, they will not be compared), but intersectsRay is only for the judgment of AABB.

Then use isPointInTriangle to check whether the two faces are coplanar.

rayIntersectsTriangle

Then if there is an intersection, then execute rayIntersectsTriangle to determine whether the center point of the specific triangle and the normal direction of another source triangle have an intersection. If there is, it means that it is a triangle inside, and the record inside is true.

Finally, he judges that if the normal in the face intersects other faces an odd number of times, it is considered a collision.

Focus 3: inside

Then use the inside to combine the triangles when CSGBrushOperation::mergeBrushes is detected.

OPERATION_UNION

If it is OPERATION_UNION then if inside is true then it will not be combined into vertex and uv.

OPERATION_INTERSECTION

If it is OPERATION_INTERSECTION and inside is false, the vertex and uv will not be combined, that is, the part that does not intersect will not be added to the triangle, only the intersection will be added.

OPERATION_SUBTRACTION

If it is OPERATION_SUBTRACTION then if the face comes from the union of the b face and is not inside, the vertex and uv are not joined, if not from the b face but the intersection is not joined. It means that if the a and b faces are on the same face and intersect, the vertex should be recorded.

Finally return mergedBrush this CSGBrush.

Guess you like

Origin blog.csdn.net/llsansun/article/details/122763737