Assimp md5 scene with animations "has no animations" - c++

I've been following the tutorials at OGLdev and LearnOpenGL to load assimp files. I can load static objects like the crysis nanosuit and the animated doom3 format model "boblampclean". The problem is that I cant get the animations from the md5 file. When I query whether the file has animations it returns 0 and other calls to get animation related things from it crash. I've tried different versions of assimp - 3.0, 3.1.1, and 3.3.3 built from vcpkg.
For example, if I run this it will return 0 although there is for sure an animation in the file. If I use the 32bit visual studio project from OGLdev it returns 1.
int main(int argc, char *argv[])
{
Assimp::Importer myImporter;
const aiScene *m_scene = NULL;
m_scene = myImporter.ReadFile("C:/users/bergj/desktop/obj/boblampclean.md5mesh", aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenSmoothNormals | aiProcess_JoinIdenticalVertices | aiProcess_CalcTangentSpace);
if (m_scene)
{
cout << "has anim = " << m_scene->HasAnimations() << endl;
}
else
{
cout << "no scene" << endl;
}
return 0;
}

I had to copy the md5anim file into the same folder. Damn.

Related

assimp fail to find the obj. file

I try to use Assimp::Importer.ReadFile() to load my obj.file but it turns out that assimp fail to find the file correctly.
Here is a simple test
#include<string>
#include<assimp/scene.h>
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
using namespace std;
int main(){
Assimp::Importer importer;
string modelPath = "D:\\素材\\nanosuit\\nanosuit.obj";
const aiScene* scene = importer.ReadFile(modelPath, aiProcess_Triangulate | aiProcess_FlipUVs );
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
cout << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
}
else cout << scene;
and the output is following text
ERROR::ASSIMP::Unable to open file "D:\素材\nanosuit\nanosuit.obj".
I haved tried to load different obj.file and it doesn't work too
This is a problem with the unicode name. You need to use a workaround to fix this. Use the Wi32-API-Call
SetCurrentDirectory(L"D:\\素材\\nanosuit\\");
to open the folder and import the asset afterwards:
const aiScene* scene = importer.ReadFile(L"nanosuit.obj", aiProcess_Triangulate | aiProcess_FlipUVs );
There is a design error in the Asset-Importer-Lib. The imported name will be used to name the asset and the asset-name is using ASCII. So unicode names will interpreted as ASCII-names and this will cause your error.

SDL2 Wrapper class complains `Invalid Renderer`

I'm trying to write a C++ wrapper class around some SDL2 classes.
Now I have this working code, which displays a red screen for 5 seconds (as you can see, my wrapper classes are in namespace sdl2cc):
int main(void)
{
if (SDL_Init(SDL_INIT_VIDEO) < 0) return 1;
sdl2cc::Window window{"SDL_RenderClear"s, sdl2cc::Rect{sdl2cc::Point{SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED}, sdl2cc::Dimension{512, 512}}, {}};
sdl2cc::Renderer renderer{window, {}};
renderer.draw_color(sdl2cc::Color{sdl2cc::RGB{255,0,0}, sdl2cc::Alpha{255}});
SDL_RenderClear(renderer.data());
// renderer.clear();
SDL_RenderPresent(renderer.data());
// renderer.present();
SDL_Delay(5000);
SDL_Quit();
}
In the wrapper class of SDL2's SDL_Renderer I have a std::unique_ptr data member renderer_ pointing to an actual SDL_Renderer.
renderer.data() exposes this pointer (return this->renderer_.get();).
I want to get the member functions renderer.clear() and renderer.present() to work. Sadly neither do. This is how they look:
void sdl2cc::Renderer::clear(void)
{
if (SDL_RenderClear(this->data()) < 0)
{
std::cerr << "Couldn't clear rendering target with drawing color:" << ' ' << SDL_GetError() << '\n';
}
}
void sdl2cc::Renderer::present(void)
{
SDL_RenderPresent(this->data());
}
If I just use renderer.clear(), it will print my error message + Invalid renderer.
If I just use renderer.present(), it will show a black screen.
What is wrong?
Why are my own functions and the SDL functions not equivalent?
The problem seems to lie in the function call:
SDL_RenderClear(renderer.data()); // works
// somewhere else:
void sdl2cc::Renderer::clear(SDL_Renderer* r)
{
if (SDL_RenderClear(r) < 0)
{
std::cerr << "Couldn't clear rendering target with drawing color:" << ' ' << SDL_GetError() << '\n';
}
}
renderer.clear(renderer.data()); // doesn't work: Invalid Renderer
But I still don't understand where the problem lies. To me it seems to accomplish the same thing, but somehow one throws an error, the other doesn't.
EDIT:
Another interesting thing, trying to step in at renderer.clear() with lldb goes directly to the next line, without actually stepping in... I don't even.
The problem had to do with multiply linked libraries.
I compiled my own library with the SDL2 libraries and then compiled my executable with my library and the SDL2 libraries.

ASSIMP exporting an imported scene without any changes throws exception

I am working on a project where I import a 3D mesh of an avatar using ASSIMP library, update it and export the updated scene again using the same ASSIMP library. To achieve this, as the first step, I have written a code to import a scene and without making any changes I am passing the reference to the export function. But, the export function throws me an error. The main function is as follows (you can verify that I am not making any changes to the imported scene):
int main(int argc, char** argv)
{
string filename = "../Content/PinocchioMesh/Model1.obj";
Assimp::Importer Importer;
//Importer.
cout << "\tReading file using ASSIMP" << endl;
const aiScene* aiscene = Importer.ReadFile(filename.c_str(), aiProcess_JoinIdenticalVertices | \
aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_SortByPType | aiProcess_Triangulate);
string str = Importer.GetErrorString();
if (!aiscene) {
printf("Error parsing '%s': '%s'\n", filename.c_str(), Importer.GetErrorString());
return false;
}
Assimp::Exporter exporter;
const aiExportFormatDesc* format = exporter.GetExportFormatDescription(0);
int lIndex = filename.find_last_of('/');
//const string path = Filename.substr(0,lIndex+1);
string path = "../Content/PinocchioMesh/";
cout << "\tExport path: " << path << endl;
aiReturn ret = exporter.Export(aiscene, format->id, path, aiscene->mFlags);
cout << exporter.GetErrorString() << endl;
return 0;
}
The error is in the Export() function ans says:
First-chance exception at 0x1052591B (Assimp32.dll) in ImportRigExport.exe: 0xC0000005: Access violation reading location 0x00000000.
If anyone has used assimp to export scenes, please help me.
It seems path doesn't include a file name, only the directory part, so that for export() is unlikely to be able to create an output file. Nevertheless, I agree, Assimp should manage this error case.

GLFW 3 initialized, yet not?

I'm struggling with creating a window with the GLFW 3 function, glfwCreateWindow.
I have set an error callback function, that pretty much just prints out the error number and description, and according to that the GLFW library have not been initialized, even though the glfwInit function just returned success?
Here's an outtake from my code
// Error callback function prints out any errors from GFLW to the console
static void error_callback( int error, const char *description )
{
cout << error << '\t' << description << endl;
}
bool Base::Init()
{
// Set error callback
/*!
* According to the documentation this can be use before glfwInit,
* and removing won't change anything anyway
*/
glfwSetErrorCallback( error_callback );
// Initialize GLFW
/*!
* This return succesfull, but...
*/
if( !glfwInit() )
{
cout << "INITIALIZER: Failed to initialize GLFW!" << endl;
return false;
}
else
{
cout << "INITIALIZER: GLFW Initialized successfully!" << endl;
}
// Create window
/*!
* When this is called, or any other glfw functions, I get a
* "65537 The GLFW library is not initialized" in the console, through
* the error_callback function
*/
window = glfwCreateWindow( 800,
600,
"GLFW Window",
NULL,
NULL );
if( !window )
{
cout << "INITIALIZER: Failed to create window!" << endl;
glfwTerminate();
return false;
}
// Set window to current context
glfwMakeContextCurrent( window );
...
return true;
}
And here's what's printed out in the console
INITIALIZER: GLFW Initialized succesfully!
65537 The GLFW library is not initialized
INITIALIZER: Failed to create window!
I think I'm getting the error because of the setup isn't entirely correct, but I've done the best I can with what I could find around the place
I downloaded the windows 32 from glfw.org and stuck the 2 includes files from it into minGW/include/GLFW, the 2 .a files (from the lib-mingw folder) into minGW/lib and the dll, also from the lib-mingw folder, into Windows/System32
In code::blocks I have, from build options -> linker settings, linked the 2 .a files from the download. I believe I need to link more things, but I can figure out what, or where I should get those things from.
I tried reinstalling codeblocks and mingw, which solved the issue.
Seems like GLFW3 doesn't like having previous versions installed at the same time for some reason, so if anyone else is having a similar problem, you might want to try that.
I experienced similar problems in Cocos 3.8.1 and 3.10.
I have never installed codeblocks or mingw, so it did not make sense to install them for me.
The GLFW.lib file in the cocos directory is out of date.
http://www.glfw.org/download.html, and replace the lib file in your project with the latest one, and it may resolve your error.

FLTK display image

I am making a simple FLTK application (in windows) that needs to display PNG images in FL_Window, load them one after the other from disk. I have this code as a starting point but its not displaying the image which I can confirm is in the same folder as the executable:
int main(int argc, char **argv)
{
Fl_Window *main_window = NULL;
fl_register_images();
flw = new Fl_Window(1680,1050,title);
Fl_Shared_Image *a = Fl_Shared_Image::get("picture.png");
if (a != NULL)
{
cout << "Image loaded" << endl;
}
else
{
cout << "No image loaded" << endl; // <==== This is printed
}
flw->begin();
// add image to window code here, not sure what to write but
// image doesnt even load
flw->end();
main_window->show();
int fl_ret = Fl::run();
return fl_ret;
}
Any help greatly appreciated ..
Fl_Shared_Image class used for
"Find or load an image that can be shared by multiple widgets."
use Fl_PNG_Image class
int main() {
fl_register_images();
Fl_Window win(720,486);
Fl_Box box(10,10,720-20,486-20);
Fl_PNG_Image png("picture.png");
box.image(png);
win.show();
return(Fl::run());
}
You only loaded the image.
Birol's answer loaded and displayed box.image(png); the image.
If you are using an IDE, your IDE might be running an executable in another directory.
Give the absolute address of your image, and it should work.