Horde3D

Next-Generation Graphics Engine
It is currently 06.10.2024, 17:20

All times are UTC + 1 hour




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: 21.08.2009, 11:28 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
Hi all,

Hmm, I'm having issues trying to access data from a mesh resource. I need to be able to access the raw vertex data etc. Is there a place somewhere in the codebase I can have a look for an example on how to do it?

Can I access the data from a resource without having a node in the graph? I only want the mesh data loaded so I can generate a navigation mesh from it.

I'm having some issues with various calls that seem weird. For instance, I add a scene resource, then using the same resource handle I do a h3dGetResElemCount with H3DResTypes::SceneGraph as the type and it returns 0!! :)

The documentation on the whole accessing of resources, materials etc is a little bit terse in this regard. It'd be nice to have a little walkthrough of accessing the various underlying data from a resource/mesh/model/material in the wiki?


Top
 Profile  
Reply with quote  
PostPosted: 22.08.2009, 00:03 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
At the moment there is no mesh resource but only geometry and scene graph resources. Geometry resources contain raw vertex data like vertex positions, tex coords and also triangle indices.
A model consisting of meshes and joints is expressed as a scene graph branch. A mesh node points to start and end indices in the model's geometry resource. As discussed in a different thread, this will be refactored a bit in the near future for more efficency.

Since the scene graph resources will be removed anyway, they don't have an implementation for the resource API. However, geometry resources can be accessed. You can read out the vertex data by mapping the geometry resource. Example which modifes the vertex y positions:

Code:
H3DRes myGeoRes = h3dFindResource( H3DResTypes::Geometry, "models/knight/knight.geo" );

int vertCount = h3dGetResParamI( myGeoRes, H3DGeoRes::GeometryElem, 0, H3DGeoRes::GeoVertexCountI );
float *pVertPosData = (float *)h3dMapResStream( myGeoRes, H3DGeoRes::GeometryElem, 0, H3DGeoRes::GeoVertPosStream, true, true );

for( int i = 0; i < vertCount; ++i )
{
    pVertPosData[i * 3 + 1] = pVertPosData[i * 3 + 1] * 2;
}

h3dUnmapResStream( myGeoRes );


To access the geometry of a specific mesh, you can temporarily add a model to the scene graph. You can iterate over all meshes or find a specific mesh by name with h3dFindNodes. The mesh attributes (e.g. the first vertex in the geometry res) can be accessed with h3dGetNodeParamI. This is not optimal at the moment but will be improved soon.

I agree that some more documentation or a sample would be helpful... :)


Top
 Profile  
Reply with quote  
PostPosted: 22.08.2009, 09:07 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
Thanks for that.

I guess the issue is that the interface (getParam) is great in that it is general enough to handle any request without having hundreds of methods for getting specific elements. But it does mean that its less obvious how to pass the correct parameters to get the thing you specifically want. Documentation in these cases is really important. Right now the docs really dont describe in enough detail the range of values that are valid to pass to the getParam methods and the expected result. Your example explains so much but I'm not sure I would have figured them out from the documentation without trying lots of invalid combinations.

I'll give you my use-cases as a way of explaining what might be useful to document:

I need to modify the texture used by a given mesh within a characters scene.

I need to modify the head joint of the same character to do a lookat controller

I need to clone the material used by a given mesh, alter some attribute of it, then update the mesh to use the cloned material (for highlighting a selection during picking)

I need to access the vertex, face and normal data for a mesh to pass onto a navmesh generator

If those kinds of things could be documented on the wiki (and whats better, updated if the API changes) then we'll be cooking.


Top
 Profile  
Reply with quote  
PostPosted: 22.08.2009, 09:11 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
Just out of interest, in your example, you search specifically for the named geometry. Currently I have the resource handle for the overall scene I just loaded. How do I query for the geometry resource loaded by the scene? (or if there are multiples, how do I access the count and each one?).

I'm taking my loaded world scene and stuffing it into my navmesh generator (Recast), so I need to be able to get all geometries for a given scene resource.

Thanks for the help though Nicolas.


Top
 Profile  
Reply with quote  
PostPosted: 22.08.2009, 19:08 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
I hope that the API is more or less logical and not too difficult to use. However, since it is very generic, I fully understand that the usage may not always be obvious for developers that are new to Horde. But I think there are not so many things that need to be explained in text. Some sample code would be enough to help people getting started.

Instead of writing a wiki article which will likely be outdated at some point, I would propose to write a new API Test Sample. This sample would cover common use cases like the ones you presented and show some annotated sample code for them. Additionally, it would check the output/results of the use cases and hence act as unit tests. I think with such test application, we can avoid many smaller bugs in the future, like the ones we had for beta4. What do you think?

It is easy to get the geometry resource for a model for which you have the handle. Just use getNodeParamI with H3DModel::GeoResI. It is probably a good idea to take a quick look at all the enums in the API documentation to understand how things are working. :)


Top
 Profile  
Reply with quote  
PostPosted: 22.08.2009, 19:31 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
I think having some unit tests would really help actually. Plus the idea of a nice little sample would be very useful to explain things.

The interface isnt complex so much as it is obscure.

For instance, I load a resource as a scene from <name>.scene.xml, is that scene when added to a node a scene? Or a model? if its a model, does the getNodeParam for the geometry work?

I think a simple example with some typical game use-cases displayed in it would work brilliantly. As you say, acting as a unit test, a demo and an example at the same time.

It is more likely to stay updated in comparison to a wiki page too. Its a pity the wiki couldnt actually be extracted from markup in the code (doxygen style).


Top
 Profile  
Reply with quote  
PostPosted: 22.08.2009, 19:49 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
Great, then let's do that test sample.

zoombapup wrote:
For instance, I load a resource as a scene from <name>.scene.xml, is that scene when added to a node a scene? Or a model? if its a model, does the getNodeParam for the geometry work?

No, you can load a scene as a resource. So you have a scene graph description as a resource and you can populate the scene graph using that resource. The scene graph resource is just an abstract description of your scene (or rather a part of your scene) and you will only get the concrete scene once you call h3dAddNodes which will create concrete nodes in the scene graph based on the scene graph resource. One speciality of Horde is that (animated) models are scene graph resources as well. However, as mentioned before, this will likely be changed soon, mainly for efficency reasons (see this thread). Let me know when anything regarding that topic is unclear.


Top
 Profile  
Reply with quote  
PostPosted: 22.08.2009, 20:08 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
Ok, so lets turn this around a bit.

I'm trying to read the data from a resource, so I can parse the vertices and shove them into a navmesh. I dont necassarily want to render the scene.

I call:

Code:
H3DRes modelRes = h3dAddResource( H3DResTypes::SceneGraph, xnode.getAttribute("mesh"),0 );
// load the resource
h3dutLoadResourcesFromDisk( path.c_str() );


So the resource for the scene is loaded. But currently it doesnt have a scene node. Does that mean I cannot access any geometry from the modelRes handle in any way?

Basically, I need to be able to parse any and all geometry data associated with this particular resource so I can shove it into the navmesh generator.

What would be the preferred method for that?


Top
 Profile  
Reply with quote  
PostPosted: 22.08.2009, 20:22 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
I see, the issue here is that scene graph resources are currently not supported by the resource API (e.g. by getResParam), so you can't read out any data from them directly. This is a shortcoming of the current horde version that needs to be fixed. The reason why this is not yet supported is that the scene graph resources will be replaced by model resources at some point.

Luckily there is a simple workaround. Just add the scene graph resource temporarily to the scene graph with modelNode = h3dAddNodes. After that you can get the geometry resource with geoRes = h3dGetNodeParamI( modelNode, H3DModel::GeoResI ). Once you have the geometry resource handle, you can remove the model from the scene again using h3dRemoveNode( modelNode ). BTW, even if you remove the scene node, the geometry resource will still stay in memory since it is still referenced by the scene graph resource.


Top
 Profile  
Reply with quote  
PostPosted: 23.08.2009, 09:59 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
So another question to that end. Is there multiple geometries per scene?

What I mean is, say I save a level out in max. I load it up in the usual way. But of course there are multiple meshes. Does that mean there are multiple geometries too? Or is the geometry in one big buffer?

I guess it makes sense to just have one buffer. Especially for the vertices, indices etc.

Hmm, that might be ok than :)

Oh, are the normals available also? I think Recast needed the normals to do its volume checks properly.


Top
 Profile  
Reply with quote  
PostPosted: 23.08.2009, 10:16 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
One max file is considered as one model node which is stored in a scene graph file. A model can have several meshes that share a single geometry resource, so one model has one geometry resource.

Actually the intended usage is that one max file is a single asset, e.g. a character or a single building. Your level is then composed of many of these assets in a separate scene editor. However, it is also ok to store your whole level as a single model as you do it now. It is only that the occlusion culling will be a bit less efficient then since it does not work between meshes of a single model. This means one building would not occlude another building. If the buildings were separate models (not just separate meshes), the occlusion would work.

The normals can be accessed analogous to the sample above using the GeoVertTanStream.


Top
 Profile  
Reply with quote  
PostPosted: 27.08.2009, 20:25 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
Since it will still take some time until the new sample is done (probably after the dynamic geometry support gets improved), I will give a few hints on the presented use cases:

zoombapup wrote:
I need to modify the texture used by a given mesh within a characters scene.

To find the texture that a mesh uses, you first need to get the mesh's material using h3dGetNodeParamI with H3DMesh::MatResI. After that, you can find the desired sampler (e.g. "albedoMap") in the material by using elemIdx = h3dFindResElem( matRes, H3DMatRes::SamplerElem, H3DMatRes::SampNameStr, "albedoMap" ). The texture resource can then be retrieved with texRes = h3dGetResParamI( matRes, H3DMatRes::SamplerElem, elemIdx, SampTexResI ). You can access the texture image data by mapping it, similar to mapping geometry.

zoombapup wrote:
I need to access the vertex, face and normal data for a mesh to pass onto a navmesh generator

See code above.

zoombapup wrote:
I need to modify the head joint of the same character to do a lookat controller

Find the joint (which is a child of the model node) using the scene graph API. You can read/write the transformation using the standard transformation functions.

zoombapup wrote:
I need to clone the material used by a given mesh, alter some attribute of it, then update the mesh to use the cloned material (for highlighting a selection during picking)

You can clone a material using h3dCloneResource. The material properties are accessed as described for the first use case. Exchanging the material of a mesh is done by setting a new mesh material (setNodeParamI with H3DMesh::MatResI).

Hope that helps...


Top
 Profile  
Reply with quote  
PostPosted: 27.08.2009, 20:53 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
Some more detailed info is in the wiki now:

http://horde3d.org/wiki/index.php5?title=Horde3D_Wiki:HOWTO


Top
 Profile  
Reply with quote  
PostPosted: 27.08.2009, 22:26 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
Thanks for that. Although you missed off that you have to have the geometry attached to a node in the scene before you can access its data.


Top
 Profile  
Reply with quote  
PostPosted: 25.01.2024, 08:42 
Offline

Joined: 02.01.2017, 02:59
Posts: 24
this helped a lot thankyou!

marciano wrote:

Code:
H3DRes myGeoRes = h3dFindResource( H3DResTypes::Geometry, "models/knight/knight.geo" );

int vertCount = h3dGetResParamI( myGeoRes, H3DGeoRes::GeometryElem, 0, H3DGeoRes::GeoVertexCountI );
float *pVertPosData = (float *)h3dMapResStream( myGeoRes, H3DGeoRes::GeometryElem, 0, H3DGeoRes::GeoVertPosStream, true, true );

for( int i = 0; i < vertCount; ++i )
{
    pVertPosData[i * 3 + 1] = pVertPosData[i * 3 + 1] * 2;
}

h3dUnmapResStream( myGeoRes );



Looks like that HOWTO page on the wiki was removed, that's a shame because it has a lot of helpful tips.
https://web.archive.org/web/20140111074 ... at_a_point


Also I saw the Alfred video, it's still pretty cool today :D
https://www.youtube.com/watch?v=aCS--pxeXT4


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group