visualfx

01-22-2008, 06:57 PM

Hey,

Just interested to see if anyone else has hit this issue before, as I find it hard to believe that we are the first to notice it! And if so, how have you dealt with the problem?

Basically, what we are seeing is the introduction of undesirable detail in polygon mesh objects that are deformed more than a few thousand units from the origin.

Here is a simple scenario - Create 2 polygon spheres (30x30). Cluster one of the spheres, and translate the cluster 5000 units along any axis. Translate the other sphere (via transform) to the same location. Smooth both spheres to a level of 4. If you look closely at each sphere individually, you should notice the deformed sphere has some high frequency detail that is not apparent on the translated sphere.

Run this mel code to recreate the test case I've described...it will even print comparative vertex world positions, just in case you were thinking this could be a display issue.

file -f -new;

string $sphere[] = `polySphere -r 1 -sx 30 -sy 30 -ax 0 1 0 -cuv 2 -ch 0 -n "deformedSphere"`;

string $cluster[] = `newCluster " -envelope 1"`;

string $smooth[] = `polySmooth -mth 0 -dv 1 -c 1 -kb 0 -ksb 0 -khe 0 -kt 1 -kmb 1 -suv 1 -sl 1 -dpe 1 -ps 0.1 -ro 1 -ch 1 $sphere[0]`;

move -a 5000 0 0 $cluster[1];

setAttr ($smooth[0]+".divisions") 4;

string $sphere_2[] = `polySphere -r 1 -sx 30 -sy 30 -ax 0 1 0 -cuv 2 -ch 0 -n "translatedSphere"`;

string $smooth_2[] = `polySmooth -mth 0 -dv 1 -c 1 -kb 0 -ksb 0 -khe 0 -kt 1 -kmb 1 -suv 1 -sl 1 -dpe 1 -ps 0.1 -ro 1 -ch 1 $sphere_2[0]`;

move -a 5000 0 0 $sphere_2[0];

setAttr ($smooth_2[0]+".divisions") 4;

float $deformedPoint[] = `pointPosition deformedSphere.vtx[198412]`;

float $translatedPoint[] = `pointPosition translatedSphere.vtx[198412]`;

print("\n\n");

print("X position:\ndeformed = " + $deformedPoint[0] + "\ntranslated = " + $translatedPoint[0] + "\n\n");

print("Y position:\ndeformed = " + $deformedPoint[1] + "\ntranslated = " + $translatedPoint[1] + "\n\n");

print("Z position:\ndeformed = " + $deformedPoint[2] + "\ntranslated = " + $translatedPoint[2] + "\n\n");

From this test, it shows that at 5000 units, the deformed mesh is only accurate to within 100th's of a unit compared to the translated mesh. Try the same test with skinClusters, lattice, wrap and wire deformers...Even translating the vertices of the mesh directly, by the same unit amounts, yields the same result.

The way the issue has been described to me is this - Polygons in Maya are kept light by using a float based representation. Whereas deformers use double precision. There is a loss in precision when going from 64 bit floating point representation to a 32 bit float that is being amplified by the smoothing operation.

One work around that comes to mind is to perform any gross deformations through the transform of the object (eg. constraints, etc.), while minimizing actual deformations by keeping them relative to the transform. This becomes a little cumbersome when working with skinClusters, as you would then need to keep all the bindPreMatrix values updated to avoid double transformations.

Is it totally unreasonable to expect to be able to deform polygons with standard maya deformers more than a few thousand units without this loss of precision??

Not really looking for workarounds here...just interested to see if anyone else thinks this is as big a problem as we do??

Just interested to see if anyone else has hit this issue before, as I find it hard to believe that we are the first to notice it! And if so, how have you dealt with the problem?

Basically, what we are seeing is the introduction of undesirable detail in polygon mesh objects that are deformed more than a few thousand units from the origin.

Here is a simple scenario - Create 2 polygon spheres (30x30). Cluster one of the spheres, and translate the cluster 5000 units along any axis. Translate the other sphere (via transform) to the same location. Smooth both spheres to a level of 4. If you look closely at each sphere individually, you should notice the deformed sphere has some high frequency detail that is not apparent on the translated sphere.

Run this mel code to recreate the test case I've described...it will even print comparative vertex world positions, just in case you were thinking this could be a display issue.

file -f -new;

string $sphere[] = `polySphere -r 1 -sx 30 -sy 30 -ax 0 1 0 -cuv 2 -ch 0 -n "deformedSphere"`;

string $cluster[] = `newCluster " -envelope 1"`;

string $smooth[] = `polySmooth -mth 0 -dv 1 -c 1 -kb 0 -ksb 0 -khe 0 -kt 1 -kmb 1 -suv 1 -sl 1 -dpe 1 -ps 0.1 -ro 1 -ch 1 $sphere[0]`;

move -a 5000 0 0 $cluster[1];

setAttr ($smooth[0]+".divisions") 4;

string $sphere_2[] = `polySphere -r 1 -sx 30 -sy 30 -ax 0 1 0 -cuv 2 -ch 0 -n "translatedSphere"`;

string $smooth_2[] = `polySmooth -mth 0 -dv 1 -c 1 -kb 0 -ksb 0 -khe 0 -kt 1 -kmb 1 -suv 1 -sl 1 -dpe 1 -ps 0.1 -ro 1 -ch 1 $sphere_2[0]`;

move -a 5000 0 0 $sphere_2[0];

setAttr ($smooth_2[0]+".divisions") 4;

float $deformedPoint[] = `pointPosition deformedSphere.vtx[198412]`;

float $translatedPoint[] = `pointPosition translatedSphere.vtx[198412]`;

print("\n\n");

print("X position:\ndeformed = " + $deformedPoint[0] + "\ntranslated = " + $translatedPoint[0] + "\n\n");

print("Y position:\ndeformed = " + $deformedPoint[1] + "\ntranslated = " + $translatedPoint[1] + "\n\n");

print("Z position:\ndeformed = " + $deformedPoint[2] + "\ntranslated = " + $translatedPoint[2] + "\n\n");

From this test, it shows that at 5000 units, the deformed mesh is only accurate to within 100th's of a unit compared to the translated mesh. Try the same test with skinClusters, lattice, wrap and wire deformers...Even translating the vertices of the mesh directly, by the same unit amounts, yields the same result.

The way the issue has been described to me is this - Polygons in Maya are kept light by using a float based representation. Whereas deformers use double precision. There is a loss in precision when going from 64 bit floating point representation to a 32 bit float that is being amplified by the smoothing operation.

One work around that comes to mind is to perform any gross deformations through the transform of the object (eg. constraints, etc.), while minimizing actual deformations by keeping them relative to the transform. This becomes a little cumbersome when working with skinClusters, as you would then need to keep all the bindPreMatrix values updated to avoid double transformations.

Is it totally unreasonable to expect to be able to deform polygons with standard maya deformers more than a few thousand units without this loss of precision??

Not really looking for workarounds here...just interested to see if anyone else thinks this is as big a problem as we do??