Assimp Error when loading model in the browser ( WASM ) - c++

I am trying to load a .glb 3d model (glb is the binary version of gltf) using Assimp ... in a browser.
I am using cmake.
Assimp is built with the following Options :
SET(ASSIMP_INSTALL ON CACHE BOOL "" FORCE)
SET(ASSIMP_BUILD_TESTS OFF CACHE BOOL "" FORCE)
SET(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
SET(ASSIMP_NO_EXPORT ON CACHE BOOL "" FORCE)
SET(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT OFF CACHE BOOL "" FORCE)
SET(ASSIMP_BUILD_GLTF_IMPORTER ON CACHE BOOL "" FORCE)
add_subdirectory(vendor/assimp)
include_directories(vendor/assimp/include)
target_link_libraries(${PROJECT_NAME} assimp ${ASSIMP_LIBRARIES})
if(EMSCRIPTEN)
set(CMAKE_CXX_FLAGS "-O3")
target_link_options(
${PROJECT_NAME} PUBLIC
"-sMIN_WEBGL_VERSION=2"
"-sLLD_REPORT_UNDEFINED=1"
"-sFORCE_FILESYSTEM=1"
"-sALLOW_MEMORY_GROWTH=1"
"-sTOTAL_MEMORY=60MB"
"-sUSE_GLFW=3"
"-sUSE_WEBGL2=1"
)
set_target_properties(${PROJECT_NAME}
PROPERTIES SUFFIX ".js"
LINK_FLAGS "--bind --embed-file ../Resources"
)
endif()
The project build goes fine with both Windows and Emscripten.
Windows .exe loads the model correctly, but the browser version throws this pretty non descript error
Uncaught 13062512
the .glb file is in the /Resources directory that I "embed" at linking stage. Other resources ( textures mainly) are correctly loaded from this directory too. So this is not a file access issue.
I have also tried loading the file asynchronously using emscripten_async_wget() function, but I get the same error.
Note that I am already able to load binary 3d meshes, but only in a very basic custom format of mine.
Assimp would be a big step up from that.
(...After some reading on Assimp docs)
There a method : Assimp::Importer::SetIOHandler which might be able to help me ? Apparently I would need to provide a custom implementation of IOSystem ,IOFile and IOStream. Which looks like a daunting task to me...
Could this even solve my problem ?

Related

cmake + VS = "Microsoft.VisualStudio.ProjectSystem.References.UnresolvedBuildDependencyProjectReference"

I have a very simple CMake solution with one shared library and one executable.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
project(Test)
add_subdirectory(A)
add_subdirectory(B)
A/CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(A)
file(GLOB_RECURSE Hdr CONFIGURE_DEPENDS inc/*)
file(GLOB_RECURSE Src CONFIGURE_DEPENDS src/*)
add_library(${PROJECT_NAME} SHARED ${Hdr} ${Src})
target_include_directories(${PROJECT_NAME} BEFORE PUBLIC inc PRIVATE src)
set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY PUBLIC_HEADER ${Hdr})
A/CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(B)
file(GLOB_RECURSE Src CONFIGURE_DEPENDS src/*)
add_executable(${PROJECT_NAME} ${Hdr} ${Src})
target_include_directories(${PROJECT_NAME} BEFORE PUBLIC inc PRIVATE src)
target_link_libraries(${PROJECT_NAME} PRIVATE A)
I use all these to generate a VS2022 solution and open it:
cmake.exe -S . -B tmp
start tmp\Test.sln
The CMake target "A" seems to be taken into consideration because I see the public headers folder (A/inc) amongst "Additional Include Directories" of VS project "B".
When I navigate in VS to B/References I see a reference to project "A" as expected:
but when I double-click it or try to see its properties , I get:
"Microsoft.VisualStudio.ProjectSystem.References.UnresolvedBuildDependencyProjectReference"
Is there a CMake+VS bug? or I do something wrong?
NOTE: if I create the entire solution by hand from Visual Studio (without CMake), it works fine!
I'm using CMake 3.24.1 and VS2019 and I'm facing the same problem. From what I see on my PC, I can conclude it's certainly not a CMake issue. That's because, after having used CMake to generate my VS Solution, I'm able to get rid of the problem by simply modifying the vcxproj file(s) inside my solution. However, there still is one thing I don't understand yet and what makes me to suspect VS having some kind of problem. Here is what I see/do.
My CMake generated solution contains one console application that depends on a number of static library projects: the projects are added to the application's References section. Now, when I double click on one of them I get the following message:
The Full Path property of the referenced project inside the Properties pane shows the same message.
To fix this I open the console application's vcxproj file and look for the following entry:
I remove the complete ProjectReferences element for each configuration, save the vcxproj file and restart my solution. In my case the problem is then solved: no more annoying message and the Full path property resolves to a valid path. But ...
Since I removed this ProjectReferences element the Link Library Dependencies property now defaults to Yes. I can verify this by opening the Property window and check the proper field. It shows Yes.
Now, I my case CMake generated a solution in which LinkLibraryDependencies was set to false. Therefore, I again open my console application's Property pane and set the Link Library Dependencies property back to false. I close the Property window and try rebuilding my project: no problem. Running the application: no problem.
When, after updating the Link Library Dependencies property with false inside the Property pane, I save my project and then open the vcxproj file using a text editor, I notice the ProjectReferences element has been added again. It's set to false. That is as expected. But, when close and I re-open the solution the initial problem is back again. However, when I change the ProjectReferences property value from false to true inside the vcxproj file using a text editor, the problem stays away after opening the solution!!
Based on the experience with my VS Solution, I come to the following conclusion:
I can get rid of the problem by removing the complete ProjectReferences element from the vcxproj file (use text editor) and then re-open the solution. But then the Link Library Dependencies property defaults to Yes
I can then change the Link Library Dependencies property back and forth to Yes and No without the problem shows up again. (Note: what I find strange is that the vcxproj file is not updated when I modify some properties and close the Property window.
When the application's project is saved to disk (vcxproj file gets updated), re-opening the solution will bring back the problem but only in case the Link Library Dependencies property was saved as false.
Maybe I overlook something, but this looks as a VS problem to me. Not a showstopper but annoying it is.

OpenSceneGraph plugin not included in Conan?

I'm trying to do simple mesh viewer using OpenSceneGraph and I want to use Conan for dependencies.
The compilation is working well in both debug and release mode (I'm compiling on Windows for now with msvc toolchain).
As soon as I try to load any kind of mesh, the osgDB::readNodeFiles just fail. Looks like the plugin are not linked to the final binary.
I checked in the Conan's package, the plugin list of .lib exists and are supposed to be linked I guess.
What could I miss ?
There is my conanfile.txt :
[requires]
openscenegraph/3.6.5
[generators]
cmake
The CMakeLists.txt is also straightforward :
cmake_minimum_required(VERSION 3.17)
# Set a default build type if none was specified
set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
set(PROJECT_NAME 3D_radio)
project(${PROJECT_NAME})
if(EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
set(CMAKE_CONFIGURATION_TYPES ${CONAN_CONFIGURATION_TYPES})
else()
message(WARNING "The file conanbuildinfo.cmake doesn't exist, you have to run conan install first")
endif()
# get all source files
file(GLOB all_SRCS
"include/*.h"
"source/*.cpp"
)
# add executable and addShader libraries
add_executable(${PROJECT_NAME} ${all_SRCS} source/main.cpp include/main.h)
target_include_directories(${PROJECT_NAME} PRIVATE
include
${CONAN_INCLUDE_DIRS}
)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
And the code is also very simple :
int main(int argc, char **argv) {
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
// read the scene from the list of file specified commandline args.
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
// if not loaded assume no arguments passed in, try use default mode instead.
if (!loadedModel) loadedModel = osgDB::readNodeFile("cow.osgt");
// if no model has been successfully loaded report failure.
if (!loadedModel)
{
std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
return 1;
}
}
The console output :
C:\...\cmake-build-release\bin\program.exe C:\...\first.obj
C:\...\cmake-build-release\bin\program.exe: No data loaded
Error reading file C:\...\first.obj: read error (Could not find plugin to read objects from file "C:\...\first.obj".)
Error reading file cow.osgt: read error (Could not find plugin to read objects from file "cow.osgt".)
I have no problem to open those files in Paint 3D for example. So I know they are correct. The problem looks to come from linking. Any idea ?
I found the solution.
I'm compiling statically the program, the plugins are linked to the final binary but the plugin registry look for a dynamic library (osgdb_obj.dll for example).
If you have the same problem, you have to register manually the plugin :
USE_OSGPLUGIN(obj)
USE_GRAPHICSWINDOW() // and you may want this to get a window
The "plugin list of .lib" which you highlighted are, unlike static libs, import libraries which will introduce a dynamic DLL dependency in the final link. The plugin DLLs still have to be present somewhere from where the linker can then load them off, at runtime. OSG plugins are typically loaded relative to the value of OSG_LIBRARY_PATH env variable. Setting this to the folder holding the, say "osgPlugins-3.6.5" directory, should successfully load the plugins.
SET OSG_LIBRARY_PATH=C:\TOOLS\vcpkg\installed\x64-windows\debug\plugins\
Few things which could still break this are: Debug/Release plugins mismatch and some spurious space in the OSG_LIBRARY_PATH env variable, like this one (logged via SET OSG_NOTIFY_LEVEL=DEBUG)
FindFileInPath() : trying C:\TOOLS\vcpkg\installed\x64-windows\debug\plugins\ \osgPlugins-3.6.5\osgdb_osgd.dll
The space above was present in the OSG_LIBRARY_PATH env

Qt resources not displaying when building with cmake (windows)

I have a Visual Studio Qt solution that I am moving to Cmake.
Everything is compiling and working fine, except all icons (.png) that I have in *.qrc file are not displayed at all.
My CMakeLists.txt is standard for a Qt project:
...
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(SOURCE_FILES ...)
set(HEADER_FILES ...)
set(UI_FILES ...)
set(RESOURCE_FILES resources/res.qrc)
add_executable(project WIN32 ${SOURCE_FILES} ${HEADER_FILES} ${UI_FILES} ${RESOURCE_FILES})
find_package(Qt5 REQUIRED COMPONENTS ...)
target_link_libraries(project PRIVATE Qt5::Core etc...)
I think that all icons are in fact embedded into .exe, because:
1. If I remove all paths from the qrc file and recompile, the .exe size is decreased by the icons size
2. I checked the qrc_*.cpp generated by AUTORCC and all the images are there.
But when I am iterating over all my resources using this code snippet
QDirIterator it(":", QDirIterator::Subdirectories);
while (it.hasNext()) {
qDebug() << it.next();
}
the icons are NOT there.
I have tried an alternative approach with qt5_add_resources() instead of AUTORCC and the result is the same.
I also have all the iconengines, imageformats, platforms, styles folders on the same path as .exe.
Edit:
Added the whole Cmake part of the project to github.
Considering the discussion we had in your post comment, CMake works as expected and the resources are loaded into your application.
As you mentioned "When I run my app from clion it shows the images. If I copy the exe to a folder with *.dll etc it doesn't.", so either:
Some files are missing when you copy them, you should try to use windeployqt to correctly copy what's needed at runtime
Or the problem comes from the way the qrc is neing loaded, then, I suggest that you debug the content of qrc_*.cpp files (your can debug it after you copied it outside clion) and see why it fails to load the resource
Anyway this looks more like a deployment issue than a configuration/compilation issue.

Cmake on windows, loading static library

I'm preparing windows build for my qt5 application and I have problem with loading static library .lib.
My application is using 3d engine and originally was build on linux (gcc+cmake), now on windows I'm trying to use msvc+cmake. 3d engine static lib is called engined.lib. To load library I do something like that:
SET(CMAKE_FIND_LIBRARY_PREFIXES "")
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll")
find_library(engine NAMES engined PATHS path_to_lib)
target_link_libraries(${PROJECT_NAME}
Qt5::Widgets
Qt5::OpenGL
Qt5::Xml
engine)
But during process compilation there are erros for example in my cpp file I'm loading headers:
#include "engine/Engine.h"
but, msvc do not see .h file and I have error. I'm doing something wrong?
You are linking against the library, but you still need to configure CMake so that the engine's headers are found. One way to do this is to set the location of the headers through a cache variable:
# CMakeLists.txt
set(ENGINE_INCLUDE_DIR "" CACHE PATH "Include directory")
target_include_directories(engine PRIVATE ${ENGINE_INCLUDE_DIR})
And set the variable when configuring your build directory:
cmake -DENGINE_INCLUDE_DIR=/path/to/include/dir /path/to/project

Missing header file when CMake-ing glog

I wanted to use logging in my app. In the CMake file I made (the relevant part see below) for a while everything runs smoothly, gflags seems to be installed OK. However, when compiling glog, I receive the error message:
fatal error:
'gflags/gflags.h' file not found
The missing file is found in the generated code, so I guess that some switches/options are set in some incorrect way. Or, the other thing that I download the files from a wrong site. (I found and downloaded several pathched glog files, they all present me error messages, with different ones.) How can I fix it? (I would prefer a non-manual patch)
# Download and install GoogleFlags
ExternalProject_Add(
gflags
URL https://github.com/gflags/gflags/archive/master.zip
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gflags
INSTALL_COMMAND ""
)
# Create a libgflags target to be used as a dependency by test programs
add_library(libgflags IMPORTED STATIC GLOBAL)
add_dependencies(libgflags gflags)
# Set gflag properties
ExternalProject_Get_Property(gflags source_dir binary_dir)
set_target_properties(libgflags PROPERTIES
"IMPORTED_LOCATION" "${binary_dir}/libgflags.a"
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
)
include_directories("${source_dir}/include")
# Download and install GoogleLog
ExternalProject_Add(
glog
URL https://github.com/emzeat/google-glog/archive/master.zip
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/glog
INSTALL_COMMAND ""
)
# Create a libglog target to be used as a dependency by test programs
add_library(libglog IMPORTED STATIC GLOBAL)
add_dependencies(libglog glog)
# Set glog properties
ExternalProject_Get_Property(glog source_dir binary_dir)
set_target_properties(libglog PROPERTIES
"IMPORTED_LOCATION" "${binary_dir}/libglog.a"
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
# "INTERFACE_INCLUDE_DIRECTORIES" "${source_dir}/include"
)
# I couldn't make it work with INTERFACE_INCLUDE_DIRECTORIES
include_directories("${source_dir}/include")