karl-/pb_CSG

Cut mesh returns warped and out of position if it has rotation AND uneqal scale values

Opened this issue · 1 comments

1 works as expected
2 rotation works as expected
3 uneqal scale and rotation doesnt work
4 warped demonstration

worth mentioning that the mesh returns and cuts as expected with unequal scale values IF there is no rotation

It's been a long time but I came back to it and finally have a solution so I thought I may aswell share.

You're going to need this code

private Mesh scaleMesh(Mesh mesh, Vector3 scale) {
            var baseVertices = mesh.vertices;
            var vertices = new Vector3[baseVertices.Length];

            for (var i = 0; i < vertices.Length; i++) {
                var vertex = baseVertices[i];
                vertex.x = vertex.x * scale.x;
                vertex.y = vertex.y * scale.y;
                vertex.z = vertex.z * scale.z;

                vertices[i] = vertex;
            }

            mesh.vertices = vertices;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
            return mesh;
}

private Mesh centreMesh(Mesh mesh, Vector3 centre) {
    var baseVertices = mesh.vertices;
    var vertices = new Vector3[baseVertices.Length];

    for (var i = 0; i < vertices.Length; i++) {
        var vertex = baseVertices[i];
        vertex.x = vertex.x + centre.x;
        vertex.y = vertex.y + centre.y;
        vertex.z = vertex.z + centre.z;

        vertex = Quaternion.Inverse(transform.rotation) * vertex;

        vertices[i] = vertex;
    }

    mesh.vertices = vertices;
    mesh.RecalculateNormals();
    mesh.RecalculateBounds();
    return mesh;
}

private Vector3 getScale(Vector3 orig, Vector3 newVec) {
    return new Vector3(orig.x / newVec.x, orig.y / newVec.y, orig.z / newVec.z);
}

And create the new mesh with

result = CSG.Subtract(subtractee_GO, subtractor_GO);
Mesh _newMesh = centreMesh(result.mesh, -transform.position);
var _scale = getScale(_meshFilter.sharedMesh.bounds.extents * 2.0f, _newMesh.bounds.extents * 2.0f);
_newMesh = scaleMesh(_newMesh, _scale);
_newMesh.name = $"{transform.name} Copy";

// Swap to new mesh
csgComposite_MeshFilter.sharedMesh = _newMesh;
csgComposite_MeshRenderer.sharedMaterials = result.materials.ToArray();

I've made quite a few changes to the rest of the code to fix most bugs, there's only one bug left which I think is caused by a float point error, playing with the epsilon value in CSG.cs seems to fix it in some cases so I've been playing around with that.

I'm going to post my own repo with all the bug fixes and my implementations so we can try and revive this thing.
I think with a bit of teamwork we can get this thing bug free, I will post the link to my repo here shortly.

EDIT: here's the link to the repo
https://github.com/strangeways-dev/sw_CSG