Would be extremely useful for any game that requires calculation of the center of mass of something, e.g. Kerbal Space Program styled games.
I bet they already do this internally. Maybe someone like @zeuxcg would know?
I know I’d use this.
You could approximate this yourself with some painful calculations but this would be a REALLY cool thing.
It’s really not that difficult to do yourself assuming you treat unions as blocks. The main issue is that it’s performance heavy if you need to constantly check for positions, sizes, and densities of objects.
I’m not sure if OP means actual detailed analysis of union centers of mass, but if so then that’s def something I’d like to see as well.
I think he may mean unions & meshparts too
Unions is more useful, as you can calculate the CoM of Wedges/Corner parts with a bit of trouble, but for an arbitrary union I don’t think there’s a way to do it purely by code. (Unless you can look at the union’s component parts via a script?) But again this is performance intensive and unnecessary for something that I’m sure will exist in the engine somewhere.
You could draw rays and estimate.
But that’s some mad scientist unreliable stuff lmao.
THEY CALLED ME MAD MUAAHAHAHAHAAA! But even running with the madness, it would only work for convex shapes.
For baseparts (not unions) this is really easy
This here takes the center of mass from a table of parts
function GetMass(t)
local mass = 0
for _, child in pairs(t) do
if child:IsA("BasePart") then
mass = mass + child:GetMass()
end
end
return mass
end
function CenterOfMass(t)
local totalMass = GetMass(t)
local p = Vector3.new()
for _, part in pairs(t) do
local eq = (part.CFrame.p * part:GetMass()) / totalMass
p = p + eq
end
return p, totalMass
end
Firstly, cool feature request!
All game and simulation physics engines do this work, and whether or not it’s an approximation depends on how the model is constructed (mesh, primitives, CSG/“boolean” operations, etc), if it has to be a real-time solver (i.e. for a model that animates, distorts with morph targets, etc.), and what level of realism is required.
Roblox primitives are easy, since they are simple geometric shapes with uniform density that you can just Google the centroid formula for. If you have a nice file mesh with no overlapping geometry, this is more complex, but still also a solved problem that you can Google the solution to and even get open-source code for. In a nutshell, you break your model into convex pieces (convex decomposition) if it’s not already convex, then divide each piece into tetrahedrons that you can sum over to get an exact solution. It’s basically the 3D equivalent of triangle fan triangulation in 2D. You could write tool to do this (a python script for example). You could even export Roblox unions to OBJ and process them this way.
Where things get ugly is with meshes that have overlapping volumes, which is unfortunately quite common in un-optimized models. The best way to deal with this is to use whatever CSG and optimization tools your 3D modeling software has to optimize away overlap such that your model ends up as a nice, optimal hull. You should do this anyways for any model you want to use in a real-time 3D game, because internal vertices are just waste (for opaque models anyways), and intersecting or overlapping triangle faces can cause weird z-fighting rendering issues. If you can’t do that, or want to make a tool that can handle even nasty overlapping-part meshes, you have the much larger task of implementing a CSG intersection solver.
There are also A LOT of ways you can approximate the centroid, mass, and volume calculations, with arbitrary precision, which are marginally easier maths than the exact solution. All the usual numerical integration methods can be applied, such as slicing the model up along one axis and fitting simple bounding shapes to the slices, using a voxel grid, Monte Carlo methods, etc.
I just looked over this properly and I don’t think this will correctly find the center of mass for anything with Wedge or Corner Wedge parts in, as the Center of Mass of these parts is not equal to their position.
The problem is not finding the center of mass of an arbitrary set of blocks, that, as you demonstrated, is easy. It’s finding the center of mass of a single part that is not a cuboid, spheroid or cylindrical, as the center of mass of these parts will not be the same as their position. BaseParts as simple geometric shapes can still be calculated correctly with some maths, but it is impossible for unions without separating the part in studio, calculating it using the individual parts, and then storing it in some big table somewhere. (Or another method which basically amounts to using studio or some other program to find it then storing it somewhere.
Does CollisionFidelity affect the CoM?
I’m not entirely sure Unions even have a proper CoM, based on this balancing act…
And to clarify this is in test in window, with the union being dropped about 0.1 studs onto the 0.1x0.1 45 degree brick. It is balancing there perfectly with Roblox physics.
Even so, this one took me by surprise. What’s going on there for it to be able to balance!? Is the CoM just the center of the cuboid bounding box, no matter the shape or collision fidelity?