About Store Forum Documentation Contact



Post Reply 
Mesh render data
Author Message
JonathonA Offline
Member

Post: #1
Mesh render data
Hey everyone,

I am attempting to integrate an occlusion library which requires access to a meshes GPU vertex and index buffer data. Primarily it requires only the vertex position data, the rest (normals, texture mapping coords etc) doesn't matter.

I started out by accessing the MeshRender version of my meshes and getting the vertex buffer as follows (removed occlusion library code):

Code:
FREPA(mesh().parts)
{
   VtxFull* vtxBuffer = reinterpret_cast<VtxFull*>(mesh().parts(i).render.vtxLock(LOCK_READ));
   Int posOffset = mesh().parts(i).render.vtxOfs(VTX_POS);
   // call occlusion library code
   mesh().parts(i).render.vtxUnlock();
}

The vertex data looked fine, but I noticed the source code comment for vtxOfs(...) says: "currently you should use it only for 'VTX_POS' as 'Vec', 'VTX_TEX' as 'Vec2' and 'VTX_COLOR' as 'Color' components, as others may be stored in compressed format"

That would explain why some of the VtxFull data looked odd, containing denormalized numbers and NaNs, but the positional information seemed okay and as that comment states, you can use vtxOfs(...) with the VTX_POS parameter.

The problem is this: how can I access the index buffer data? I can't offset to it, it doesn't appear to be a member of the VtxFull structure and I need access to the GPU version and not the CPU version (MeshBase) of it. The Wiki shows that the MeshRender is made from Triangles which contain Vertex Indexes (http://www.esenthel.com/wiki/index.php?title=Mesh) but I cannot find a way to access that data. I tried casting the data returned from vtxLock(...) to other types, but it doesn't produce any valid data except in the case of casting to VtxFull.
Any pointers would be really appreciated.
(This post was last modified: 08-14-2013 08:10 AM by JonathonA.)
08-13-2013 06:31 PM
Visit this user's website Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #2
RE: Mesh render data
Hi,

First please keep in mind that the vtxLock does not return a VtxFull object, it will return a continuous vtx binary data, which layout is different based on what the vtx actually contains.
the size of each vtx is MeshRender.vtxSize() (I am writing from my memory)
so you should do
Byte *data=vtxLock();
Int vtx_size=vtxSize();
Int pos_ofs=vtxOfs(VTX_POS);
Vec pos_i=*(Vec*)(data+pos_ofs+i*vtx_size);
triangle indexes are not stored in the vtxLock vtx data, and currently cannot be read directly from the MeshRender.
Why can't you just use MeshBase which has all the data provided in a convenient format?
Please let me know, thanks
08-14-2013 09:41 PM
Find all posts by this user Quote this message in a reply
JonathonA Offline
Member

Post: #3
RE: Mesh render data
Hello Greg, welcome back from your holidays and thanks for the explaination about the vertex data.

It was a requirement for the occlusion library I want to integrate to use the GPU version which is why I have been trying to work with the MeshRender version instead of MeshBase. I don't have a definite answer from the occlusion library developer about why the GPU version is required, maybe the vertices have undergone transformation since much of the library code is working in world space.

The MeshBase vertex positions are in local space?
08-15-2013 12:04 AM
Visit this user's website Find all posts by this user Quote this message in a reply
Zervox Offline
Member

Post: #4
RE: Mesh render data
Depends on how the MeshBase is created, but if they are localspace you will just have to offset them object.pos.x+(area.xz*World.areaSize()), object.pos.z+(area.xz*World.areaSize())before applying them to the occlusion library.
or before applying the MeshBase to the occlusion library you could do
meshbase.move(objects matrix position);

Just curious what Occlusion library are you implementing?
(This post was last modified: 08-15-2013 04:11 AM by Zervox.)
08-15-2013 12:36 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #5
RE: Mesh render data
MeshBase gives the same transformation as MeshRender, but in much easier way to read the data.
08-16-2013 03:34 AM
Find all posts by this user Quote this message in a reply
JonathonA Offline
Member

Post: #6
RE: Mesh render data
Thank you both for your input.

@Zervox The occlusion library is not accessible in the public domain yet but the creator offered us an evaluation copy which I'm attempting to integrate into Esenthel. I've used the demo and it is really fantastic smile

Anyway, I have used the MeshBase data instead and I am now figuring out how to generate a View Matrix from the Esenthel camera matrix and Projection Matrix (as you would when using DirectX or OpenGL APIs).

Now, if I am correct, the View Matrix is the inverse of the Cameras Matrix and to generate the Projection Matrix, I used this:

xScale 0 0 0
0 yScale 0 0
0 0 zf/(zf-zn) 1
0 0 -zn*zf/(zf-zn) 0
where:
yScale = cot(fovY/2)
xScale = yScale / aspect ratio
zf = far clipping plane distance
zn = near clipping plane distance

Which can be found at: http://msdn.microsoft.com/en-us/library/...s.85).aspx

My code for creating the Projection Matrix (simply for testing) is this:

Code:
Matrix4(Matrix(Vec(Ctg(D.viewFovY()/2)/D.aspectDisplay(), Ctg(D.viewFovY()/2), D.viewRange()/(D.viewRange()-D.viewFrom())), Vec(0, 0, (-D.viewFrom()*D.viewRange())/(D.viewRange()-D.viewFrom()))));

Reason for needing those matrices is that, you have to set up a camera for the occlusion library and they are required.

Now, I have tested the above and it doesn't appear to be working so I think my view matrix is the problem because projection matrices don't rely on the camera?
08-17-2013 01:07 AM
Visit this user's website Find all posts by this user Quote this message in a reply
Zervox Offline
Member

Post: #7
RE: Mesh render data
Well, another tip is, I believe as occlusion libraries likes bounding volumes(faster to process), I'd think you would create a MeshBase from PhysPart(collision volume), as it is alot less triangles but still remains the proper shape/volume to surround your objects, atleast most occlusion libraries usually use things like capsules,box,ball etc instead of the raw mesh data.
08-17-2013 04:51 AM
Find all posts by this user Quote this message in a reply
JonathonA Offline
Member

Post: #8
RE: Mesh render data
(08-17-2013 04:43 AM)aceio76 Wrote:  This is very nice to see! If you guys beat Esenthel in putting in this sort of occlusion, it would be quite an accomplishment given that you have beaten the engine's creator with implementing it. Very excited to see what you guys can come up with!

Thanks for the vote of confidence aceio. But, Greg is its creator, he knows it inside and out so ultimately, he will develop an optimal solution that integrates beautifully with Esenthel Engine. Unfortunately I do not have full source so my solution is only going to be built off the SDK which will be sub optimal otherwise, I would try integration into the engine itself and maybe save Greg some time since he's got a lot on his plate.

If this works out, it will work really well. Had tens of thousands of objects in the demo and the culling was fantastic.

(08-17-2013 04:51 AM)Zervox Wrote:  Well, another tip is, I believe as occlusion libraries likes bounding volumes(faster to process), I'd think you would create a MeshBase from PhysPart(collision volume), as it is alot less triangles but still remains the proper shape/volume to surround your objects, atleast most occlusion libraries usually use things like capsules,box,ball etc instead of the raw mesh data.

Interesting, I didn't know that Zervox, thank you. As I mentioned in the previous post, I am using MeshBase now following the comments from yourself and Greg and that part seems to be okay but I won't know until I get the camera sorted. I will double check that we are creating our meshes from collision volumes, can't think from memory.
(This post was last modified: 08-17-2013 07:50 AM by JonathonA.)
08-17-2013 07:47 AM
Visit this user's website Find all posts by this user Quote this message in a reply
Zervox Offline
Member

Post: #9
RE: Mesh render data
Well, you can always send him your integration work if you feel like it when you're done, that is what I did with my recast implementation, atleast it worked as a intergration sample even if he didn't copy it. ; )

I'd very much too like to see the end results of this, too bad you can't say the name of the library yet. ; )
I did some tests with Umbra and EE and it worked very well, although Umbra has so much in it and I couldn't share integration samples, nor is it easy to get rights to implement it as a module for a Engine.
(This post was last modified: 08-17-2013 08:22 AM by Zervox.)
08-17-2013 08:20 AM
Find all posts by this user Quote this message in a reply
JonathonA Offline
Member

Post: #10
RE: Mesh render data
(08-17-2013 08:20 AM)Zervox Wrote:  Well, you can always send him your integration work if you feel like it when you're done, that is what I did with my recast implementation, atleast it worked as a intergration sample even if he didn't copy it. ; )

I'd very much too like to see the end results of this, too bad you can't say the name of the library yet. ; )
I did some tests with Umbra and EE and it worked very well, although Umbra has so much in it and I couldn't share integration samples, nor is it easy to get rights to implement it as a module for a Engine.

Interesting you mention Umbra since that was the other option but I wanted to have a look at this library first since the licensing for Umbra is pretty expensive :/

So I am pretty sure I've got the vertex and index data sorted using MeshBase using the following (the sample world I created for the project contains hundreds of tavern objects):

Code:
Game::ObjParamsPtr tavern = Game::Objs("Obj/Static/Tavern/0.obj");
   if(tavern) {
        EE::Mesh& fullMesh = tavern()->mesh()->joinAll(false,false,false); // get vertex/index data for parts of the mesh
        Int* idx = reinterpret_cast<Int*>(fullMesh.parts[0].base.tri.ind()); // occlusion lib takes arrays of values
        Int idxCnt = fullMesh.parts[0].base.tri.elms()*3; // 3 elements per index
        Flt* vtx = reinterpret_cast<Flt*>(fullMesh.parts[0].base.vtx.pos()); // occlusion lib requires vertex position only
        Int vtxCnt = fullMesh.parts[0].base.vtx.elms()*3; // 3 elements per vertex pos

// MeshUpdate for the occlusion library takes a Mesh handle which is unique, we have to create one per mesh of every game object and associate with it basic data about the mesh resource. We only need to supply vertex positions and indexes, nothing else. This function looks similar to some DX DrawPrimitive functions; the last parameter is a 'stride' or 'step' between the vertex positions in the 'vtx' data.
        MeshUpdate(Mesh, EPT_TRIANGLES_INDEXED, &idx[0], idxCnt*sizeof(Int), EIT_U32, &vtx[0], vtxCnt*sizeof(Flt), 3*sizeof(Flt));

Basically the library wants unique handles for every game mesh because we then have to create instances of it for the library to use and determine what to cull. We create instances based on what objects are loaded/being drawn in the Esenthel game world.

To create the instances, we have to supply 4x4 matrices that represent the objects position. I wrote a quick and dirty function that maps a Matrix4 to a Flt array. I couldn't find a function to do this in Esenthel SDK?

Here's part of the code that does it:
Code:
            Matrix& m = Statics[i].matrix(); // get tavern matrix
            Matrix4& M = Matrix4(m); // make a 4x4 mat out of it
            Flt mat[16]; Matrix4ToArray(M, mat); // map Matrix4 elements to array. [0] to [3] contain 'right' axis, [4] to [7] contain 'up' axis, [8] to [11] contain 'forward' axis and [12] to [15] contain position.

Pretty sure that is working correctly, camera code still not certain about because occlusion library works directly with DX library and I find it difficult to understand how to do the same in Esenthel. Projection transform code I posted earlier, View transform I tried using the Cam matrix, but is that used for transforming objects from world to camera space or is it simply the cameras orientation?
08-18-2013 01:32 PM
Visit this user's website Find all posts by this user Quote this message in a reply
JonathonA Offline
Member

Post: #11
RE: Mesh render data
Okay, sorted out the projection matrix after having a chat with the occlusion libraries developer. Made one typo error by setting the last component in the projection matrix to 1 instead of 0 which he thankfully pointed out to me.

Using the inverse of the Cam matrix as the View Transform which works fine.

The second issue which is now resolved is that, I was using the normalized objects matrix instead of the scaled matrix.

Finishing up the implementation in the test project and hopefully will have something to show very soon smile
08-28-2013 12:35 AM
Visit this user's website Find all posts by this user Quote this message in a reply
Zervox Offline
Member

Post: #12
RE: Mesh render data
Very interesting. : )
(This post was last modified: 08-28-2013 02:33 AM by Zervox.)
08-28-2013 02:33 AM
Find all posts by this user Quote this message in a reply
Post Reply