I'm trying to import *.x files to my engine and animate them using OpenGL (without shaders for now, but that isn't really relevant right now). I've found the format reference at MSDN, but it doesn't help much in the problem.
So - basically - I've created a file containing a simple animation of a demon-like being with 7 bones (main, 2 for the tail, and 4 for the legs), from which only 2 (the ones in the right leg) are animated at the moment. I've tested the mesh in the DXViewer, and it seems to work perfectly there, so the problem must be the side of my code.
When I export the mesh, I get a file containing lots of information, from which there are 3 important places for the skeletal animation (all the below matrices are for the RLeg2 bone):
SkinWeights - matrixOffset
-0.361238, -0.932141, -0.024957, 0.000000,
0.081428, -0.004872, -0.996669, 0.000000,
0.928913, -0.362066, 0.077663, 0.000000,
0.139213, -0.057892, -0.009323, 1.000000
FrameTransformMatrix
0.913144, 0.000000, -0.407637, 0.000000,
0.069999, 0.985146, 0.156804, 0.000000,
0.401582, -0.171719, 0.899580, 0.000000,
0.000000, -0.000000, 0.398344, 1.000000
AnimationKey matrix in bind pose
0.913144, 0.000000, -0.407637, 0.000000,
0.069999, 0.985146, 0.156804, 0.000000,
0.401582, -0.171719, 0.899580, 0.000000,
0.000000, -0.000000, 0.398344, 1.000000
My question is - what do I exactly do with these matrices? I've found an equation on the Newcastle University site (http://research.ncl.ac.uk/game/mastersdegree/graphicsforgames/skeletalanimation/), but there's only 1 matrix there. The question is - how do I combine these matrices to get the vertex transform matrix?
This post is not pretend to be a full answer, but a set of helpful links.
How to get all information needed for animation
The question is how do you import your mesh, and why do you do this. You can fight with .x meshes for a months, but this doesn't make any sense, because .x is a very basic, old and really not good enough format. You don't find many fans of .x format on StackOverflow. =)
.x file stores animation data in a tricky way. It was intended to load via set of D3DX*() functions. But, to get bones and weights from it manually, you must preprocess loaded data. Much things to code. Here is a big post, explaining how to:
Loading and displaying .X files without DirectX
Good way to do things is just switch to some mesh loading library. The most popular and universal one is Assimp. At least, look at their docs and/or source code, on how they handle loading and preprocessing, and what whey have as output. Also, here is a good explanation:
Tutorial 38 - Skeletal Animation With Assimp
So, with assimp you can stop fighting and begin animating right now. And maybe later, when you'll find idea on how it's works, you can write your own loader.
When you've got all information needed for animation
Skeletal animation is a basic topic that explained in details all around the web.
You can find basic vertex shader for animation here:
OpenGL Wiki: Skeletal Animation
Here is a explanation of how all works (but implemented in fixed-function style): Basic Bones System
Hope it helps!
Since Drop provided links that talk about the problem, and give clues on how to solve it, but don't quite provide a simple answer, i feel obliged to leave the solution here, in case someone else stumbles on the same problem.
To get the new vertex position in "bind pose"
v'(i) = v(i)*Σ(transform(bone)*W(bone,i))
where:
v'(i) - new vertex position,
v(i) - old vertex position, and
W(bone,i) - weight of the transformation.
(and of course Σ is the sum from 0 to the amount of bones in the skeleton)
The transform(bone) is equal to sw(bone) * cM(bone), where sw is the matrix found inside the SkinWeights tag, and cM(bone) is calculated using a recursive function:
cM(bone)
{
if(bone->parent)
return localTransform*cM(bone->parent);
else
return localTransform;
}
The localTransform is the matrix located inside the FrameTransformMatrix tag.
To get the new vertex position in a certain animation frame
Do the exact same operation as mentioned above, but instead of the matrix in FrameTransformMatrix, use one of the matrices inside the appropriate AnimationKey tag. Note that when an animation is playing, the matrix inside the FrameTransformMatrix tag becomes unused. Which means, you'll probably end up ignoring it most of the time.
Related
I am trying a different Pipeline without success until now.
The Idea is to use the classic pipeline (as in the Explorer Example) but additionally to use the last ColorImage for the texutre.
So the idea (after clicking SAVE MESH):
Save current Image as BMP
Get the current transformation [m_pVolume->GetCurrentWorldToCameraTransform(&m_worldToCameraTransform);] .. lets call it M
Transform all Mesh vertices v in the last Camera Space Coordinate System ( M * v )
Now the current m_pMapper refers to the latest Frame which we want to use [ m_pMapper->MapCameraPointToColorSpace(camPoint, &colorPoint); ]
In theory I should have now every Point of the fusion mesh as a texture coordinate.. I want to use them to export as OBJ File (with texture and not only color).
What am I doing wrong?
The 3D Transformations seem to be correct.. when I visualize the resulting OBJ file in MeshLab I can see that the transformation is correct.. the WorldCoordinateSystem is Equal to the latest recorded position.
Only the texture is not set correctly.
I would be very very very very happy if anyone could help me. I am trying already for a long time :/
Thank you very much :)
I want to load a mesh file using TetGen library in C++ but I don't know the right procedure or what switches to activate in my code in order to show the Constrained Delaunay mesh.
I tried something basic loading of a dinosaur mesh (from rocq.inria.fr) with default behavior:
tetgenio in, out;
in.firstnumber = 0;
in.load_medit("TetGen\\parasaur1_cut.mesh",0);
tetgenbehavior *b = new tetgenbehavior();
tetrahedralize(b, &in, &out);
The shape is supposed to be like this:
When using TetView it works perfectly. But with my code I got the following result:
I tried to activate the Piecewise Linear Complex (plc) property for Delaunay Constraint:
b->plc = 1;
and I got just a few parts from the mesh:
Maybe there are more parts but I don't know how to get them.
That looks a lot like you might be loading a quad mesh as a triangle mesh or vice versa. One thing is clear, you are getting the floats from the file, since the boundaries of the object look roughly correct. Make certain you are loading a strictly triangle or quad-based mesh. If it is a format that you can load into Blender, I'd recommend loading it, triangulating it, and re-exporting it, just in case a poly snuck into there.
Another possibility is an indexing off by one error. Are you sure you are getting each triangle/quad in the correct order? Which is to say -- make sure you are loading triangles 123 123 123 and NOT 1 231 231 231.
One other possibility, if this format indexes all of the vertices, and then lists the indexes of the vertices, you might be loading all of the vertices correctly, and then getting the indexes of the triangles/quads messed up, as described in the previous two paragraphs. I'm thinking this is the case, since it looks like all of your points are correct, but the lines connecting them are way wrong.
I need to use Marching Cubes based on Radial Basis Function so I looked up this algorithm implemented in PCL.
Actually I'm using PCL v1.6 so the function is:
pcl::MarchingCubesRBF
The problem is that it doesn't work, that is it doesn't create any triangles: sometimes the output is '0 triangles created', at times running blocks my machine.
Anyway my implementation is:
pcl::MarchingCubesRBF<pcl::PointNormal> mc;
pcl::PolygonMesh::Ptr triangles(new pcl::PolygonMesh);
mc.setInputCloud (cloud_with_normals);
mc.setSearchMethod (tree);
mc.reconstruct (*triangles);
I tried with different files like input but neither of them works. One of it is https://github.com/FabiApfelkern/cloudfinish/blob/master/cat.pcd
I found there was a bug about the implementation in pcl: http://dev.pointclouds.org/issues/768
However I don't understand if it is solved in pcl v1.6. Let me know how could I solve if it is possible.
I'm using C++ with VS2010
I had the same problem and I fixed it setting the grid resolution:
mc.setGridResolution (100, 100, 100);
mc.reconstruct (*triangles);
The grid resolution is the amount of voxels used in x, y and z directions. So if you set it to 1, 1, 1, there will be only one voxel - and thus not a very good representation of your point cloud. The higher the resolution, the more expensive it will be, but it also improves the quality of the resulting mesh.
I most recently had great progress in getting Vertex buffer objects to work.
So I moved on to Element arrays and I figured with such implemented I could then load vertices and face data from an obj.
I'm not too good at reading files in c++ so I wrote a python doc to parse the obj and write 2 separate txts to give me a vertex array and face indices and pasted them directly in my code. Which is like 6000 lines but it works (without compiling errors).
And Here's what it looks like
.
I think they're wrong. I'm not sure. The order of the vertices and faces aren't changed just extracted from the obj because I don't have normals or textures working for buffer objects yet. I kinda do if you look at the cube but not really.
Heres the render code
void Mesh_handle::DrawTri(){
glBindBuffer(GL_ARRAY_BUFFER,vertexbufferid);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elementbufferid);
int index1=glGetAttribLocation(bound_program,"inputvertex");
int index2=glGetAttribLocation(bound_program,"inputcolor");
int index3=glGetAttribLocation(bound_program,"inputtexcoord");
glEnableVertexAttribArray(index1);
glVertexAttribPointer(index1,3,GL_FLOAT,GL_FALSE,9*sizeof(float),0);
glEnableVertexAttribArray(index2);
glVertexAttribPointer(index2,4,GL_FLOAT,GL_FALSE,9*sizeof(float),(void*)(3*sizeof(float)));
glEnableVertexAttribArray(index3);
glVertexAttribPointer(index3,2,GL_FLOAT,GL_FALSE,9*sizeof(float),(void*)(7*sizeof(float)));
glDrawArrays(GL_TRIANGLE_STRIP,0,elementcount);
//glDrawElements(GL_TRIANGLE_STRIP,elementcount,GL_UNSIGNED_INT,0);
}
My python parser which just writes the info into a file: source
The object is Ezreal from League of Legends
I'm not sure if I'm reading the faces wrong or if their not even what I thought they were. Am I suppose to use GL_TRIANGLE_STRIP or something else. Any hints or request more info.
Indices in obj-files are 1 based, so you have to subtract 1 from all indices in order to use them with OpenGL.
First, as Andreas stated, .obj files use 1-based indices, so you need to convert them to 0-based indices.
Second:
glDrawArrays(GL_TRIANGLE_STRIP,0,elementcount);
//glDrawElements(GL_TRIANGLE_STRIP,elementcount,GL_UNSIGNED_INT,0);
Unless you did some special work to turn the face list you were given in your .obj file into a triangle strip, you don't have triangle strips. You should be rendering GL_TRIANGLES, not strips.
From the image for sure your verticies are messed up. It looks like you specified a stride of 9*sizeof(float) in your glGetAttribLocation but from what I can tell from your code your array is tightly packed.
glEnableVertexAttribArray(index1);
glVertexAttribPointer(index1,3,GL_FLOAT,GL_FALSE,0,0);
Also remove stride from color/texture coords.
I was studying Perlin's Noise through some examples # http://dindinx.net/OpenGL/index.php?menu=exemples&submenu=shaders and couldn't help to notice that his make3DNoiseTexture() in perlin.c uses noise3(ni) instead of PerlinNoise3D(...)
Now why is that? Isn't Perlin's Noise supposed to be a summation of different noise frequencies and amplitudes?
Qestion 2 is what does ni, inci, incj, inck stand for? Why use ni instead of x,y coordinates? Why is ni incremented with
ni[0]+=inci;
inci = 1.0 / (Noise3DTexSize / frequency);
I see Hugo Elias created his Perlin2D with x,y coordinates, and so does PerlinNoise3D(...).
Thanks in advance :)
I now understand why and am going to answer my own question in hopes that it helps other people.
Perlin's Noise is actually a synthesis of gradient noises. In its production process, we must compute the dot product of a vector pointing from one of the corners flooring the input point to the input point itself with the random-generated gradient vector.
Now if the input point were a whole number, such as the xyz coordinates of a texture you want to create, the dot product would always return 0, which would give you a flat noise. So instead, we use inci, incj, inck as an alternative index. Yep, just an index, nothing else.
Now returning to question 1, there are two methods to implement Perlin's Noise:
1.Calculate the noise values separately and store them in the RGBA slots in the texture
2.Synthesize the noises up before-hand and store them in one of the RGBA slots in the texture
noise3(ni) is the actual implementation of method 1, while PerlinNoise3D(...) suggests the latter.
In my personal opinion, method 1 is much better because you have much more flexibility over how you use each octave in your shaders.
My guess on the reason for using noise3(ni) in make3DNoiseTexture() instead if PerlinNoise3D(...) is that when you use that noise texture in your shader you want to be able to replicate and modify the functionality of PerlinNoise3D(...) directly in the shader.
My guess for the reasoning behind ni, inci, incj, inck is that using x,y,z of the volume directly don't give a good result so by scaling the the noise with the frequency instead it is possible to adjust the resolution of the noise independently from the volume size.