Support for BMesh

Hi everyone,



today I have made a commit that added support for loading models that use the new (Blender 2.63+) BMesh mode :slight_smile:

BMesh allows to create a faces that have more than 4 vertices.



Hope it will work smoothly.

Let me know if there are any errors with that.



Cheers,

Kaelthas

12 Likes

awesome :slight_smile: thanks!!

Brilliant! :slight_smile: Will check it out soon.

Excellent news!



If I update to nightly tomorrow I should have it?



Does it cope with normals and uv mapping correctly?

@zarch said:
Does it cope with normals and uv mapping correctly?

@Kaelthas said:
Let me know if there are any errors with that.


Vertex normal calculation was severely flawed from the beginning up until now. This can be easily verified by importing the same model with ogre or obj and blender importer and printing out the content of the normal buffer. Wrong normals cause shading artifacts even seams.

The following is mostly for Kaelthas as he knows his code and will understand what I am talking about…

There are three problems with the calculation.

The first one is that the code tries to sum up the face normals here:
[java]
private void addNormal(Vector3f normalToAdd, Map<Vector3f, Vector3f> normalMap, boolean smooth, Vector3f... vertices) {
for (Vector3f v : vertices) {
Vector3f n = normalMap.get(v);
if (!smooth || n == null) {
normalMap.put(v, normalToAdd.clone());
} else {
n.addLocal(normalToAdd).normalizeLocal();
}
}
}
[/java]

However it normalizes the intermediate results, which is wrong. Essentially the resulting vector will be: norm(norm(norm(n1+n2)+n3)+n4) if the vertex belong to 4 faces and n1..n4 are face normals. Probably the intended result would be norm(n1 + n2 + n3 + n4).

The second problem is that the importer calculates triangle face normals but blender uses the tri, quad or ngon face normals in the calculation. For quads the face normal is calculated as:
[java]
private static Vector3f calcQuadFaceNorm(Vector3f v1,Vector3f v2,Vector3f v3,Vector3f v4) {
Vector3f n1,n2,n;

n1 = v1.subtract(v3);
n2 = v2.subtract(v4);

n = n1.cross(n2);
n.normalizeLocal();
return n;
}
[/java]
For ngons the face normal is calculated using Newell's method described for example here (information comes from blender's source code):
http://www.opengl.org/wiki/Calculating_a_Surface_Normal

The third is that blender does not calculate smooth vertex normals by summing up the face normals and normalizing the results. The smooth vertex normal is the weighted sum of the face normals, the weight is calculated as:
fac =acos(-dot(e1, e2));
where e1 and e2 are normalized edge vectors the vertex belongs to on the face.

In blender's source code it is here in the BM_mesh_normals_update function:
http://projects.blender.org/scm/viewvc.php/trunk/blender/source/blender/bmesh/intern/bmesh_mesh.c?view=markup&revision=46677&root=bf-blender

If implementing this is a bit discouraging the blender file contains the vertex normals... as shorts.

The following code snippet will read the vertex normal from a pre-bmesh file (2.62 and earlier):
[java]
DynamicArray<Integer> nors = (DynamicArray<Integer>)mVerts.get(i).getFieldValue("no");
System.out.println("Nor: " +nors.get(0).shortValue()/32767.0f + " " + nors.get(2).shortValue()/32767.0f + " " + nors.get(1).shortValue()/32767.0f);
[/java]
The short values must be converted back to floats.

For BMesh I don't know how to read this info but it is probably there.

Hope this helps resolving this issue.
Regards,
Remorhaz
9 Likes

Thanks a lot for this backup. I’ll definitely recheck my normals building when I get back home :slight_smile:

1 Like

Thanks for working on this @Kaelthas



I just tested the new importer against a non-legacy blend file.



The good news is that the model imported and the mesh seems fine. The bad news is that the UV mapping and normals still seem screwy.



If you’d like me to send you a copy of the blend file and texture so you can see it for yourself I’m happy to do so. It’s entirely possible that it’s my noobish modelling skills causing the problem but something is definitely messed up!

OK I have made a commit today.



Thanks @remorhaz for pointing out the “no” field. I used it in smooth areas. Now the normals should be like the ones in blender.

For flat textures I compute normals from triangles which should be OK.



Once again great thanks for your help :slight_smile:

2 Likes

I’ll try it again tomorrow. Will this also improve the UV mapping?

I didn’t notice any problems with UV mapping so far. But if you feel that something is wrong - link me your model.

1 Like

awesome work :slight_smile: I also seem to be having UV mapping problems. This is from Blender 2.62 using latest jME nightly



Its just a simple cuboid





Texture





Inside blender showing UVs





This is exporting it using OGRE xml





Blender file:

http://dl.dropbox.com/u/53339759/Platform.blend



Loading it using this:

[java]package com.neo3d.util.test;



import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.scene.Spatial;



public class Test extends SimpleApplication {



public static void main(String[] args) {

new Test().start();

}



@Override

public void simpleInitApp() {

Spatial s = assetManager.loadModel(“Models/Platform.j3o”);

Material m = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

m.setTexture(“ColorMap”, assetManager.loadTexture(“Materials/lava.png”));

s.setMaterial(m);

rootNode.attachChild(s);

}



}

[/java]

2 Likes

Those symptoms look basically identical to mine @wezrule, and your model looks considerably simpler. That might be a better example to send to @Kaelthas. Interestingly you are on 2.62 which is before the new mesh structure…while I get the same symptoms on 2.63 with the new mesh structure.

OK I got it :slight_smile:



The problem occured when material with no texture was applied. In such case the UV map was not attached to the model.



I made a temporary fix. When no texture is added the user defined UV’s are attached.

But in future I will take the UV type into consideration. So you will need to explicitly set the type to user defined UV and not Normal or Generated :wink:

2 Likes

Thanks a lot!



That result is interesting, because I think I have had a texture attached and still seen the problem. It’s hard to be sure though as I don’t use j3m files (I attach textures in code) so I have been known to remove the texture in blender to avoid exceptions when I try and import.



I’ll try updating tomorrow and see how it looks :slight_smile:

awesome thx :slight_smile: yh if I attach it explicitly in blender it works fine

I will also try it tomorrow and let you know the result when it is not attached in blender, thanks again

@Kaelthas said:
OK I got it :)

The problem occured when material with no texture was applied. In such case the UV map was not attached to the model.

I made a temporary fix. When no texture is added the user defined UV's are attached.
But in future I will take the UV type into consideration. So you will need to explicitly set the type to user defined UV and not Normal or Generated ;)


I think UV should be always attached. For example, if i assign a texture with JME material.

Yes they should.I attached UV’s when there was no material and when material had textures.

It was actually a bug that they were not attached whenyou used material without textures.

But now it is fixed :wink:

2 Likes

yh works, thanks! :slight_smile:

I just tried it and UV mappings still look out for me. Normals seem a bit better but it’s hard to tell with the textures so scrambled. (When I did an update the nightly SDK only picked up 2 things as changed, is that right?). I’ll send you a link to the model Kaelthas.

@zarch said:
When I did an update the nightly SDK only picked up 2 things as changed, is that right?

If there was only changes in the engine then only the two plugins for the SDK and project engine libraries are updated, yeah.