Normal maps and Normals are two different things: Normals are a geometric property of any mesh/surface its use is not exclusive for shading and lighting calculations but have actually many other uses for example in physics. Normal maps are textures that encode alternative normal vectors used in computer graphics to simulate bumps.
Multiple texture coordinates per mesh what is their purpose?
Multiple texture coordinates set can be used to achieve different texture mapping per mesh, this helps achieve different visual effects that are otherwise hard to accomplish and may require multi-pass rendering.
What scenario would these be present?
For example Reflection mapping usually uses ...
If you were using assimp's implementation (AssimpViewer source) as reference, then you probably too missed the fact that Assimp's and glm use reverse matrix multiplication order. To clarify, we are talking about matrix-matrix multiplication, and the order is reverse relative to each other
And we know that matrix multiplication is not commutative.
So the ...
Why does the dll perform slower in VC++ debugging? I compiled it in
release mode without debugging information.
This is because windows use debug heap whenever you run your code from a debugger, note that this is different from CRT heap that is set in your project settings as Debug/Release.
In order to disable system heap debug you need to use ...
Well i dont know how, but i have solved my problems and for now i can load and render my model (except i need to work on shaders now:P ). Probably my error was in import pre/post-process flags of assimp. Now they are:
unsigned int processFlags =
aiProcess_CalcTangentSpace | // calculate tangents and bitangents if possible
Note that this is the 38th tutorial in a series. If you go back to part 22, you can see m_Entries is defined as follows:
The m_Entries member of the Mesh class is a vector of the MeshEntry
struct where each structure corresponds to one mesh structure in the
aiScene object. That structure contains the vertex buffer, index
buffer and the index of the ...
All of my issues boiled down to misusing the model's index array.
At first I purposely avoided using the model's indices because I wanted to have per vertex normals rather than per face normals. However, I completely forgot that the vertex list may not correspond to the correct rendering order, which lead to the results in my opening post.
On my way to ...
Finally I found the solution. Problem was in vertices. aiBone structure contain, among other things, vertices weights. My 3D model has too few weights and exists bones that don't affect vertices, so Assimp didn't loaded bones that affected 0 vertices.
So I took a look through the MonoGame content pipeline code to see how it works and turns out its using AssImpNET. So importing your models via the MonoGame pipeline is a solution to your question.
Just from reading the AssImp documentation it looks like this code could handle formats other than ".fbx", ".x" dictated by the annotation. Issues would arise ...
Reposting comment as answer.
In the for loop below you are only ever reading from the first mesh in the scene. Depending on how you've modeled it, it may be composed of multiple meshes. I have fixed the loop below replacing scene->mMeshes with scene->mMeshes[m_i] to ensure that all meshes' positions are added to the vertex buffer.
for(uint m_i = ...
First thing I see is that you shouldn't read the quaternion in reverse order.
Also you shouldn't use glm::mix, use glm::slerp instead.
And here is how I construct the bone transform:
mat = glm::mat4_cast( currentrotation );
mat *= currentscale.x; mat *= currentscale.x; mat *= currentscale.x;
mat *= currentscale.y; mat *= ...
There can be multiple reasons for the Debug mode being slower.
One of the most likely ones(that affect performance the most) is that you are still linking with a dll that has Optimization off(you can still generate debug info, but make sure to turn Optimization on)
The second is because when debugging there is a special memory allocator used, that is ...
A (triangular) face is created using tree or more vertices. An aiModel contains a list of all vertices in the model and a list of faces. Each aiFace contains the indices to vertices that make up this (triangle) face. An index is the position in the list of vertices where the vertex we want is.
Here is some pseudo code that retrieves the thee vertices of the ...
Read this through and my best guess is that there is something wrong here:
root->finalMatrix = root->animationMatrix * root->offsetMatrix;
How is offsetMatrix calculated? And what is it supposed to do (I know somekind of offset).
Would also like to see these calculations:
glm::mat4 R = ... //calculate rotation matrix based on time
A common problem exchanging 3D data between different programs is the axis directions. The cause of the issue comes when deciding the direction of each axis, blender uses the right handed cartesian system which is also common among cad modelling systems, while many other 3D programs have the y-axis pointing upwards with the z-axis pointing to the back, which ...
It is actually easier than you think. The way this works is really simple, it is a lot like video.
So, when you watch a video(I am sure you know this already but just as a reminder) you are not actually watching a moving image, instead you are watch a lot of images getting displayed one after the other REALLY fast, faster than your eye can see(There is a ...
I was implementing the skeletal animation code recently, while not for Collada, I did it for GLTF, which is similar to Collada (also from Khronos), although it uses JSON + binary data rather than XML.
The understanding is the most important part. Once you understand the theory, the code will flow naturally. For skeletal animation, you need a mesh and a set ...
It looks like that tutorial doesn't include all of the source code but I did find a link to it on the main page, here: http://ogldev.atspace.co.uk/
The Mesh class appears to have an m_BoneMapping member, which the tutorial describes as the following:
The m_BoneMapping array maps a node name to the index that we generate
and we use that index to as an ...
You must multiply each node by it's parent's transform (and the parent's node parent's transform, etc), to get the local transform for that node.
Why is it not pre-multiplied? Because it gives you the option to rebuild the hierarchy at run-time after applying transformations to any point of the hierarchy.
There are several solutions to this problem:
build assimp as a static library. When doing this make sure to link all dependencies into the library (you have to change the project properties for this, Properties->Linker->Link Library Dependencies). This way you get a proper static library (thats the way I did it). Then just link it with your Universal App.
The problem is probably the exporter.
According to official docs:
The name of the animation.
If the modeling package this data was exported from does support only
a single animation channel, this name is usually empty (length is
Try to find one which does support multiple animations channel.
The animation data provided by the assimp library is expressed as absolute values, relative to the node/bone's parent; you just set the translation/rotation/scale specified by the animation directly on the node or bone being animated -- don't try to "combine" it with the initial orientation or any other value.
More detail in the assimp library ...
Try turning off Boost: http://assimp.sourceforge.net/FAQ.html
ENABLE_BOOST_WORKAROUND = ON
As explained there its not really required, and its big. When we build Boost for Qt3D 1.0 we didn't use Boost because of compile issues.
I don't know how to exactly configure Assimp to build it with MinGW, but I have successfully build this library (as static lib) from source code of the OpenGL Tutorial's examples. You can use it as well. Just download the source code (I was using exactly this version) and do standard CMake build:
cmake -G "MinGW Makefiles" ../
you problem is with the following call:
glDrawArrays(GL_TRIANGLES, 0, pObj->Meshes[x]->vertices.size());
you need to pass in the amount of vertices you are drawing aka pObj->Meshes[x]->vertices.size() / 3
There are two possibilities, as far as I know:
Draw your geometry using one of the GL_LINE* topologies: GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES.
Use a fragment shader and some math to define the wireframe on-the-fly, without changing the topology. See this very nice example using WebGL: Wireframe display with barycentric coordinates.
Make sure that the culling order is correct. This depends on whether you're using LR or RH. If you're not sure, then just try both GraphicsDevice.RasterizerStates.CullFront and GraphicsDevice.RasterizerStates.CullBack to see which one looks correct.
Also, you might want to try rendering with your camera's world matrix through Matrix.Transpose.
Your problem and a possible solution is supplied by chipgw.
But there is an alternate solution, which is an importer flag, which will pre-transform everything for you.
So you can simply add this flag to your importer: aiProcess_PreTransformVertices.
But note that this has a huge negative: It drops all animations.(Although the node tree is kept)
As Stephen said in the comments there is transformation data that you are missing. This data is not stored in aiMesh, but in aiNode. Instead of iterating over scene->mMeshes iterate recursively over scene->mRootNode and it's mChildren. Then you iterate over node->mMeshes and use them as the index of scene->mMeshes[index]. Lastly, you need to ...