pb_CSG icon indicating copy to clipboard operation
pb_CSG copied to clipboard

Scaling mesh

Open blevesque opened this issue 6 years ago • 3 comments
trafficstars

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 ?

blevesque avatar Jun 18 '19 08:06 blevesque

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.

tuseroni avatar Jan 24 '20 15:01 tuseroni

This is awesome, thank you! Did you ever figure out how to make the object keep it's proportions when rotating?

strangeways-dev avatar May 12 '22 22:05 strangeways-dev

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?

strangeways-dev avatar Jun 13 '23 00:06 strangeways-dev

I solved my issue #28

strangeways-dev avatar Apr 10 '24 09:04 strangeways-dev