Jump to content

engine.editor.saveMesh with ObjectMeshDynamic


photo

Recommended Posts

Hello,

 

I have a node file that contains 13755 verticies and 69 surfaces as sepcified in the xml. When saving to a .mesh file using engine.editor.saveMesh, the resulting mesh contains 949095 verticies! This just so happens to be 69 multiplied by 13755. I have created a test scene so you can easily recreate this. On running the .bat file you should get a "the culprit.mesh" file in the test folder to compare aginst the node file.

 

http://dl.dropbox.com/u/12843270/ObjectMeshDynamic%20Mesh%20Save%20Bug.zip

 

Having the mesh files save properly is somewhat essential to us right now so I hope you can find a fix for this.

 

Thanks

Link to comment
  • 1 month later...

Now that the update has come out I have actually been able to try this but the improved features you spoke of do not seem to be there. For example here I have 2 meshes. Both are created with the same 4 shapes using the engine.editor.saveMesh function. One mesh save is created by passing the 4 shapes as ObjectMesh to this function. The second passes the shapes to the function as ObjectMeshDynamic. So both of these shapes should save out the same if ObjectMeshDynamic does truely optimize the verticies, but in practice this is not the case as here I have a vert difference of 294 with the object mesh to 804 with the dynamic mesh objects!

 

ObjectMesh save

http://dl.dropbox.com/u/12843270/ObjectMeshSave.mesh

 

ObjectMeshDynamic save

http://dl.dropbox.com/u/12843270/ObjectMeshDynamicSave.mesh

 

It would be great if you could get these improvements working, as the only reason I need to save to mesh with ObjectMeshDynamic is so I can optimise the surface count by combing surfaces with the same material parameters. But now one optimization causes this unoptimization now I have redundant verts. Also, (and I don't mean to be cheeky here) if you can find a fix, is there any chance of getting this a little sooner than having to wait for next month and however longs update? I can't put the project too much further forward without the runtime created assets being final. Thanks

Link to comment

Optimization is effect. The result, however, directly depends on whether the mesh is smoothed or not. The first mesh (ObjectMeshSave) is smoothed, which means there's one normal at a shared vertex, thus only one vertex can be stored. The second mesh (ObjectMeshDynamicSave) is not smoothed, meaning that there are three normals for a shared vertex, which requires a vertex to be defined three times as three vertices with different normals.

 

If you load a smoothed mesh as ObjectMeshDynamic and save it, you will now see exactly the same number of vertices as in saved ObjectMesh. Now ObjectMeshDynamic also checks if normals match and only one vertex can be stored. But you can never expect smooth and non-smoothed meshes to have an equal number of vertices.

Link to comment

Ok that makes, but where am I going wrong with my surface combine function if the dynamic object is supposed to recognise these matching verts? Are you saying an ObjectMeshSave automatically smooths on saving and that my initial object was non-smoothed? In which case, can I smooth an ObjectMeshDynamic in a similar way before saving to get the vert count the same?

 

ObjectMesh meshNode = CombineSurfaces(add_editor(new ObjectMeshDynamic(meshName)), materialMap, meshName);
ObjectMesh CombineSurfaces(ObjectMeshDynamic object, int materialMap[], string meshName)
{
 ObjectMeshDynamic combinedObject = add_editor(new ObjectMeshDynamic());
 combinedObject.clearSurfaces();
 int surfaces = materialMap.size();
 int surfaceCount = 0;
 string materialNames[0];
 forloop(int surface = 0; surfaces)
 {
  if(!materialMap.check(surface)) continue;
  //extract unique material name to compare against other surfaces
  string materialName = materialMap[surface];
  forloop(int s = surface; surfaces)
  {
if(!materialMap.check(s)) continue;
string compareMaterial = materialMap[s];
if(strlen(materialName) != strlen(compareMaterial) ||
	strncmp(materialName, compareMaterial, strlen(materialName)) != 0) continue;
// Get surface index range
int startIndex = object.getSurfaceBegin(s) * 3;
int endIndex = object.getSurfaceEnd(s) * 3;
// add unallocated indicies
combinedObject.addTriangles(object.getSurfaceEnd(s) - object.getSurfaceBegin(s));
// add verticies
forloop(int i = startIndex; endIndex)
{
	combinedObject.addVertex(object.getVertex(object.getIndex(i)));
	combinedObject.addNormal(object.getNormal(object.getIndex(i)));
	combinedObject.addTexCoord(object.getTexCoord(object.getIndex(i)));
}
// remove surface/material ref as this surface has been added
materialMap.remove(s);
  }

  combinedObject.addSurface(format("surface%i", surfaceCount));
  materialNames.append(materialName);
  surfaceCount++;
 }
 combinedObject.updateIndices();
 //combinedObject.updateNormals();
 //combinedObject.updateTangents();
 //combinedObject.updateBounds();
 Object objects[1] = (combinedObject);
 engine.editor.saveMesh(meshName, objects);
 ObjectMesh finalObject = add_editor(new ObjectMesh(meshName));
 forloop(int x = 0; surfaceCount)
 {
  finalObject.setMaterial(materialNames[x], x);
  finalObject.setProperty("surface_base", x);
 }
 remove_editor(object);
 remove_editor(combinedObject);
 return finalObject;
}

Link to comment

ObjectMesh and ObjectMeshDynamic consist of vertices and indices. You remove optimized vertices on creating combinedObject node. ObjectMeshDynamic::addTriangles() creates raw un-optimized vertices (3 vertices for each triangle). You can optimize your combinedObject via calling ObjectMeshDynamic::updateIndices() method.

Link to comment

Hi,

 

It seems like a bug in ObjectMeshDynamic::updateIndices(). We're investigating now.

 

Update: ObjectMeshDynamic::updateIndices() will weld vertices according to all there rules:

1. If vertex coordinates are the same

2. If vertex normals are the same

3. If vertex texcoords are the same

4. If vertex tangents are the same

 

Your code does not set proper tangents to your vertices. So, before calling ObjectMeshDynamic::updateIndices() you should call ObjectMeshDynamic::updateTangents() and see the magic happens. :)

Link to comment

Seems that I spoke too soon. It works most of the time. When I try to collect and combine some sets of meshes and surfaces, I get bad meshes such as this:

http://dl.dropbox.com/u/12843270/combine%20bug.png

 

This is not necessarily due to a bad object, as I can combine 6 of these gondolas just fine but when I tried combing 18 (as we see in pic) the mesh goes funky! Could this be the bug your investigating into?

Link to comment

Hey Carl,

 

I think I found the problem.

 

ObjectMeshDynamic uses unsigned short for its indexes and got only one index buffer for all surfaces so you can have 65535 vertices at all. The problem is that 18 combined meshes you gave to me have 67284 vertices which is bigger than max index value (65535).

Link to comment
×
×
  • Create New...