karl-/pb_CSG

Scaling mesh

Opened this issue · 3 comments

Hi and thanks for your work :)
I am working on a project for architects.
I would like to use pb_CSG to insert elements (like doors, windows etc) in walls.

Walls are "just" Unity Cubes rescaled and elements are 3D Models.
When I use pb_CSG, I get this a very strange result where the result mesh is totally broken, too big (like x100), not at the same position etc

Do you have an idea of a solution ?

i had this same problem, what's happening, as near as i can tell, is that the mesh is taking the scale set by the scale of the gameobject, so if you had a cube of 1x1x1 and you scaled it to 10x10x10 the newly created mesh would be 10x10x10 when you set the mesh of your gameobject this 10x10x10 cube gets scaled up by 10x10x10 and be 100x100x100.

in my case i just scaled it back down before adding it to the mesh:

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;
}
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;

        vertices[i] = vertex;
    }

    mesh.vertices = vertices;
    mesh.RecalculateNormals();
    mesh.RecalculateBounds();
    return mesh;
}
Vector3 getScale(Vector3 orig, Vector3 newVec)
{
    return new Vector3(orig.x / newVec.x, orig.y / newVec.y, orig.z / newVec.z);
}

those are the functions i made to do this, then i do this:

            CSG_Model result = Boolean.Subtract(me, cutter);
            var factor=getScale(MFer.mesh.bounds.extents * 2.0f, result.mesh.bounds.extents * 2.0f);
            var newMesh=scaleMesh(result.mesh, factor);
            Vector3 CentreFactor = MFer.mesh.bounds.center - newMesh.bounds.center;
            newMesh = centreMesh(newMesh, CentreFactor);
            MFer.mesh = newMesh;

where MFer is the meshfilter for the object "me" in the subtract function.

i had this same problem, what's happening, as near as i can tell, is that the mesh is taking the scale set by the scale of the gameobject, so if you had a cube of 1x1x1 and you scaled it to 10x10x10 the newly created mesh would be 10x10x10 when you set the mesh of your gameobject this 10x10x10 cube gets scaled up by 10x10x10 and be 100x100x100.

in my case i just scaled it back down before adding it to the mesh:

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;
}
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;

        vertices[i] = vertex;
    }

    mesh.vertices = vertices;
    mesh.RecalculateNormals();
    mesh.RecalculateBounds();
    return mesh;
}
Vector3 getScale(Vector3 orig, Vector3 newVec)
{
    return new Vector3(orig.x / newVec.x, orig.y / newVec.y, orig.z / newVec.z);
}

those are the functions i made to do this, then i do this:

            CSG_Model result = Boolean.Subtract(me, cutter);
            var factor=getScale(MFer.mesh.bounds.extents * 2.0f, result.mesh.bounds.extents * 2.0f);
            var newMesh=scaleMesh(result.mesh, factor);
            Vector3 CentreFactor = MFer.mesh.bounds.center - newMesh.bounds.center;
            newMesh = centreMesh(newMesh, CentreFactor);
            MFer.mesh = newMesh;

where MFer is the meshfilter for the object "me" in the subtract function.

Did you ever figure out how to make the object keep it's proportions when rotating?

I solved my issue #28