Auto mesh hull generation

Just thought I’d pass on some info, and then ask a question.

I’m sure most of you know about the PhysX plugin for Max that lets you run physics simulations in the viewport using the PhysX runtime library. But I’ve found that a more practical use for the plugin is for quickly generating physics hulls from complex mesh objects.

Once you have the runtimes and plugin installed, you can use maxScript to call the function used by the PhysX utility to create the hull.

(v8.04.25 of the PhysX runtime supports software processing)

px_convertToConvex <node> <max verts> <inflate hull>

Now for my question, does anyone know of an equally fast (or almost so) way of creating a non-convex hull mesh? Basically, something for generating collision meshes that is more than just a poly-reduction tool, but creates the shrink-wrapped version of a complex mesh object. I’ve seen some white papers on the subject, but no actual software.

[QUOTE=JHaywood;815]
a non-convex hull mesh[/QUOTE]

Do you mean concave? Just clarifying.

Yes. I said non-convex because technically, parts of the mesh will be concave and parts will be convex. A completely concave mesh would either be open or just a convex one with its normals flipped.

Do you have any images illustrating what you have in mind?

I follow what you’re saying, but in my mind when I picture a shrink-wrapped mesh that still has some concavities, it looks just like what an edge-collapse LOD method would generate.

Picture a torus knot (my favorite test object). Instead of having all the open space in the middle where the loops intertwine, I’d want a solid object “shrink wrapped” around it.

Or take a group of objects with inter penetrating geometry. Instead of reducing the face count and still having faces intersecting other faces, there would be one piece of geometry that just kind of rode overt the outer surface of all the objects.

Maybe an LOD would be the best way of handling the first case, and a boolean operation following by LODing would be best for the second, but I was just kind of wondering out loud of there was anything out there already that would do what I’m describing automatically.

True. Gotta love semantics. :):

The only one I know of was a research project for generating concave meshes based on surface features from IEEE Computer Graphics that specifically dealt in Max. I’ll see if I can hunt it up, although it may not be what you’re after.

I wonder if a Marching Cubes algorithm approach would work for what you are after?

http://www.exaflop.org/docs/marchcubes/

Here’s a little hacked together experiment which may or (probably) may not help!

Basically this generates a mesh point cloud around the object based off a conformToShape lattice. The only reason it does verts only is because i’ll be damned if I know how to calculate the faces. I’ll let the more experienced mesh-monkeys work it out.

It only works on a selected mesh or primitive.


--create box lattice and conform it to the selected object
fn latticeObject obj dim  = 
(
	local boxLattice = FFDBox()
	addModifier obj boxLattice
	setDimensions boxLattice dim
	conformToShape boxLattice
	animateAll boxLattice
	boxLattice
)

fn meshFromLattice obj verts objTM modTM=
(
	local objProps = getPropNames obj #dynamicOnly
	local modBBMin=getModContextBBoxMin $ obj
	local modBBMax=getModContextBBoxMax $ obj
	
	local cPConv = #()
	for i = 2 to (verts+1) do
	(
		cPoint = getProperty obj objProps[i]
		cPConv[i-1]=(modBBMin+(cPoint*(modBBMax-modBBMin)) * (inverse modTM) * objTM)
	)
	
	objMesh = mesh vertices: cPConv faces:#()
	
)

controlVerts = [4,4,4] --change this for lattice density
objTM = $.objecttransform

ncLattice = latticeObject $ controlVerts --make the lattice
modTM = (getModContextTM $ ncLattice)*ncLattice.lattice_transform.value

newMesh = meshFromLattice ncLattice (controlVerts[1]*controlVerts[2]*controlVerts[3]) objTM modTM --create the mesh


You can change the amount of controlVerts to get more lattice points, and thus more mesh verts.

As I said, this is probably worthless, but it might give you a starting point, or at the very least a smirk. :):

EDIT: for some reason the mxs highlight wrapper is screwing the code in arrays:


--create box lattice and conform it to the selected object
fn latticeObject obj dim  = 
(
	local boxLattice = FFDBox()
	addModifier obj boxLattice
	setDimensions boxLattice dim
	conformToShape boxLattice
	animateAll boxLattice
	boxLattice
)

fn meshFromLattice obj verts objTM modTM=
(
	local objProps = getPropNames obj #dynamicOnly
	local modBBMin=getModContextBBoxMin $ obj
	local modBBMax=getModContextBBoxMax $ obj
	
	local cPConv = #()
	for i = 2 to (verts+1) do
	(
		cPoint = getProperty obj objProps[i]
		cPConv[i-1]=(modBBMin+(cPoint*(modBBMax-modBBMin)) * (inverse modTM) * objTM)
	)
	
	objMesh = mesh vertices: cPConv faces:#()
	
)

controlVerts = [4,4,4] --change this for lattice density
objTM = $.objecttransform

ncLattice = latticeObject $ controlVerts --make the lattice
modTM = (getModContextTM $ ncLattice)*ncLattice.lattice_transform.value

newMesh = meshFromLattice ncLattice (controlVerts[1]*controlVerts[2]*controlVerts[3]) objTM modTM --create the mesh