code.twobrained.com Rotating Header Image

Papervision3D Development Note 1: Accessing Materials on Collada Meshes

Two days lost, but not entirely wasted. I have been trying to figure out how to change the material of a mesh object imported into a Papervision3D scene graph as part of a Collada 4.1.1 scene that I had exported from Maya. No matter what I tried, I could not change the material for an individual mesh object at run time. I was using all the provided methods with no luck. For example, the one that should do the the trick is:

1
dae.getChildByName("COLLADA_Scene").getChildByName(meshName).replaceMaterialByName(new ColorMaterial, materialName);

(dae is a DAE object; meshName is the string name of the mesh in the collada scene whose material you want to change, and materialName is the string name of the material you want to replace)

But no go. The strange thing was that I could print the list of materials that I had imported from the Collada file by using:

1
2
3
for (var name:String in dae.materials.materialsByName){
trace(dae.materials.getMaterialByName(name).toString());
}

Whats more, the materials (BitmapFileMaterials in my case) loaded fine onto the meshes and were visible when the program ran (e.g., see previous post). But there seemed no way to access those materials once the program was running. There seemed to be no accessible references between the material list for the scene and the individual meshes in the scene.

So, I dug into the most recent version of DAE.as class from Papervision3D. And what did I find: The materials are applied to each of the individual triangles in your mesh (I am assuming that your mesh was triangulated during Collada file creation, so lines 1442-1461 in the DAE.as file holds the relevant code) but not to the object as a whole. So, while the mesh object has no record of its material, each of the individual triangles of the mesh do. Still, there seems to be no reference from the main materials list for the DAE object to these triangles; because changing the material in the main materials list has no effect on the rendered scene. So: What to do?

The first solution I thought of was to write a function for swapping the material of a mesh object on a triangle per triangle basis. What follows is a functional but very simple version, without the desirable checks for nulls:

1
2
3
4
5
6
public static function swapObjectMaterials(dae:DAE, objectName:String, material:MaterialObject3D):void{
var length:int = dae.getChildByName("COLLADA_Scene").getChildByName(objectName).geometry.faces.length;
for (var i:int = 0; i < length; i++){
Triangle3D(dae.getChildByName("COLLADA_Scene").getChildByName(objectName).geometry.faces[i]).material = material;
}
}

That is all you need to fix this problem (well, it fixed it for me).

The better solution would be to fix the load of the DAE object so that there remains a reference between the main materials list and the individual triangle meshes, such that changing a member of the materials list changes that material on each of the individual triangles. Time permitting, that should be done within the next couple of weeks.

From a design perspective, it makes perfect sense to apply the materials on a per-triangle-face basis in order to conserve any uv mapping that was done in your modelling program; still, the reference issue needs fixing.

As an endnote: Having fixed the above problem, I ran into another problem. I had been interested in swapping a BitmapFileMaterial with a texture for a MovieMaterial. While the above function swapped them, the uv mapping was conserved such that the new MovieMaterial was applied with the old uv coordinates. I fixed that problem too…stay tuned for when I have some more writing time.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • NewsVine
  • Reddit
  • StumbleUpon
  • Google Bookmarks
  • Yahoo! Buzz
  • Twitter
  • Technorati
  • Live
  • LinkedIn
  • MySpace
  • MySpace

Possibly Related Posts:

1,456 views

Leave a Reply

Powered by WP Hashcash

Security Code: