Problems when rendering objects in Ogre using Assimp

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
User avatar
kestli
Gnoblar
Posts: 2
Joined: Thu Jan 16, 2014 8:29 pm

Problems when rendering objects in Ogre using Assimp

Post by kestli »

When I try to view 3D files (.3ds .dae etc ...), supported by Assimp, they are not displayed correctly. For example, "Jeep1.3ds" displayed me half the bodywork.
All nodes of information, meshes and normal were obtained correctly, and the number of vertices and faces are correct (I think).
Textures not meet the correct coordinates, I guess will be related to the above ...
In the picture you can "appreciate" my result and correct.
Thanks for any help or opinion.

OGRE:

Code: Select all

Ogre::SceneNode *OgreAPP::makeMesh(Ogre::String meshFile,Ogre::String entityName,Ogre::String meshName)
{
    Ogre::MeshPtr Mesh = Ogre::MeshManager::getSingleton().createManual(meshName,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    Ogre::SubMesh *subMesh = Mesh->createSubMesh("subMesh");
    Ogre::VertexDeclaration *vertexDeclaration;
    Ogre::HardwareVertexBufferSharedPtr  vertexBuffer;
    Ogre::HardwareIndexBufferSharedPtr   indexBuffer;
    size_t offset=0;

   // Get file name and extension from the Ogre Resource Manager  
    Ogre::FileInfoListPtr fileInfoListPtr(Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,meshFile,false));
    Ogre::FileInfoList *fileInfoList = fileInfoListPtr.getPointer();
    Ogre::FileInfo &fileInfo = fileInfoList->front();
    stringBuffer << fileInfo.archive->getName().c_str() << meshFile;
   
   // **************   From Assimp code   ***************************
    ModelManager::loadModel(stringBuffer.str());
    ModelManager::processData();
    std::vector<float>    *vData   = ModelManager::getVertexData();
    std::vector<uint16_t> *iData   = ModelManager::getIndexData();
  // ******************************************************************** 

    Mesh->sharedVertexData = new Ogre::VertexData;
    
   // Organizo la memoria de video
    vertexDeclaration = Mesh->sharedVertexData->vertexDeclaration;
    vertexDeclaration->addElement(0,offset,Ogre::VET_FLOAT3,Ogre::VES_POSITION);
    offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

    vertexDeclaration->addElement(0,offset,Ogre::VET_FLOAT3,Ogre::VES_NORMAL);
    offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

    vertexDeclaration->addElement(0,offset,Ogre::VET_FLOAT2,Ogre::VES_TEXTURE_COORDINATES);
    offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

    // Make vertex buffer 
    vertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDeclaration->getVertexSize(0),
                                                                                  vData->size()/8,
                                                                                  Ogre::HardwareBuffer::HBU_STATIC);

    // Write the vertex buffer with the target data of vData->data() located in assimp code
    vertexBuffer.getPointer()->writeData(0,vertexBuffer.getPointer()->getSizeInBytes(),vData->data());

    // Make index buffer
    indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT,
                                                                                iData->size(),
                                                                                Ogre::HardwareBuffer::HBU_STATIC);

    indexBuffer.getPointer()->writeData(0,indexBuffer.getPointer()->getSizeInBytes(),iData->data());

    Mesh->sharedVertexData->vertexBufferBinding->setBinding(0,vertexBuffer);
    Mesh->sharedVertexData->vertexCount = vertexBuffer.getPointer()->getNumVertices();
    Mesh->sharedVertexData->vertexStart = 0;

    subMesh->useSharedVertices = true;
    subMesh->indexData->indexBuffer = indexBuffer;
    subMesh->indexData->indexCount = indexBuffer.getPointer()->getNumIndexes();
    subMesh->indexData->indexStart = 0;

    // I don't get real AABB from object, this is ok for probe 
    Mesh->_setBounds(Ogre::AxisAlignedBox(-100,-100,-100,100,100,100));
    Mesh->load();

    stringBuffer.str("");
    stringBuffer << entityName << "_n";
    oSceneManager->createEntity(entityName,meshName);
    oSceneManager->getEntity(entityName)->setMaterialName("material/textura");
    oSceneManager->getRootSceneNode()->createChildSceneNode(stringBuffer.str().c_str())->attachObject(oSceneManager->getEntity(entityName));
    oSceneManager->getSceneNode(stringBuffer.str().c_str())->setPosition(0,0,0);

    std::cout << "total de vertices: " << vData->size()/8 << "\n";
    std::cout << "total de faces: " <<indexBuffer.getPointer()->getNumIndexes()/3 << "\n";
    return oSceneManager->getSceneNode(stringBuffer.str().c_str());
}

Assimp .CPP

Code: Select all

bool ModelManager::loadModel(std::string &file)
{
    modelScene = importer.ReadFile(file,aiProcess_Triangulate |
                                        aiProcess_GenNormals  |
                                        aiProcess_GenUVCoords);

    if (!modelScene)
    {
        MessageBoxA(NULL,importer.GetErrorString(),"Error: La concha de la lora",MB_ICONERROR);
        return false;
    }

    return true;
}


bool ModelManager::assimpGetMeshData(const aiMesh *mesh)
{
    aiFace *face;

    for (unsigned int v=0;v<mesh->mNumVertices;v++)
     {
        vertexBuff.push_back(mesh->mVertices[v].x);
        vertexBuff.push_back(mesh->mVertices[v].y);
        vertexBuff.push_back(mesh->mVertices[v].z);
        vertexBuff.push_back(mesh->mNormals[v].x);
        vertexBuff.push_back(mesh->mNormals[v].y);
        vertexBuff.push_back(mesh->mNormals[v].z);
        vertexBuff.push_back(mesh->mTextureCoords[0][v].x);
        vertexBuff.push_back(mesh->mTextureCoords[0][v].y);
     }

    for (unsigned int f=0;f<mesh->mNumFaces;f++)
     {
        face = &mesh->mFaces[f];
        indexBuff.push_back(face->mIndices[0]);
        indexBuff.push_back(face->mIndices[1]);
        indexBuff.push_back(face->mIndices[2]);
     }

    return true;
}
bool ModelManager::processData()
{
    bool repeat=true;

    nodeBuff.push_back(modelScene->mRootNode);


   /* if (modelScene->mNumMeshes > 0)
    {
        for (unsigned int m=0;m<modelScene->mNumMeshes;m++)
            this->assimpGetMeshData(modelScene->mMeshes[m]);
    }*/

    // I raise all nodes tree to the root level 
    while (repeat)
    { 
        for (unsigned int a=0;a<nodeBuff.size();a++)
        {
            modelNode = nodeBuff.at(a);
            if (modelNode->mNumChildren > 0)
                for (unsigned int c=0;c<modelNode->mNumChildren;c++)
                       nodeBuff.push_back(modelNode->mChildren[c]);
            else repeat=false;
        }
    }

    // Get node information from the root level (all nodes)
    for (unsigned int a=0;a<nodeBuff.size();a++)
    {
        modelNode = nodeBuff.at(a);

        if (modelNode->mNumMeshes>0)
            for (unsigned int b=0;b<modelNode->mNumMeshes;b++)
                assimpGetMeshData(modelScene->mMeshes[modelNode->mMeshes[b]]);
    }
    return true;
}

std::vector<float> *ModelManager::getVertexData()
{
    return &vertexBuff;
}

std::vector<uint16_t> *ModelManager::getIndexData()
{
    return &indexBuff;
}


Assimp .H

Code: Select all


/* 
        Programmer: Maximiliano Kestli
        maxkaestli@hotmail.com
*/

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <assimp/matrix4x4.h>
#include <assimp/cimport.h>

#include <Windows.h>
#include <iostream>
#include <stdint.h>
#include <vector>

class ModelManager
{
public:
    ModelManager();
    bool loadModel(std::string &);
    bool processData();
    std::vector<float> *getVertexData();
    std::vector<uint16_t> *getIndexData();
private:
    bool assimpGetMeshData(const aiMesh *);
private:
    Assimp::Importer            importer;
    const aiScene               *modelScene;
    const aiNode                *modelNode;
    const aiMesh                *modelMesh;
    const aiFace                *modelFace;
    std::vector<float>          vertexBuff;
    std::vector<uint16_t>       indexBuff;

    std::vector<const aiNode*>  nodeBuff;
    unsigned int                numNodeBuff;
};
Attachments
jeep.jpg
jeep.jpg (39.34 KiB) Viewed 1830 times
User avatar
kestli
Gnoblar
Posts: 2
Joined: Thu Jan 16, 2014 8:29 pm

Re: Problems when rendering objects in Ogre using Assimp

Post by kestli »

Ok ... errors, as they spend most of the time, in practice something small and basic but complex background.
"Simply" switch the coordinate system, when I import the file would have to be specified Assimp flags "aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs" or "aiProcess_ConvertToLeftHanded".
Other than that I missed some transformation matrices (they had not considered), for that I use the flag "aiProcess_PreTransformVertices".
Apparently everything works fine ...

New code

Code: Select all

bool ModelManager::loadModel(std::string &file)
{
    modelScene = importer.ReadFile(file,aiProcess_MakeLeftHanded|aiProcess_FlipWindingOrder|aiProcess_FlipUVs|aiProcess_PreTransformVertices|
                                   aiProcess_CalcTangentSpace|
                                   aiProcess_GenSmoothNormals|
                                   aiProcess_Triangulate|
                                   aiProcess_FixInfacingNormals|
                                   aiProcess_FindInvalidData |
                                   aiProcess_ValidateDataStructure | 0
                                   );

    if (!modelScene)
    {
        MessageBoxA(NULL,importer.GetErrorString(),"Error: La concha de la lora...",MB_ICONERROR);
        return false;
    }

    return true;
}
User avatar
Aiden
Halfling
Posts: 54
Joined: Fri Jul 14, 2017 3:16 pm
x 5

Re: Problems when rendering objects in Ogre using Assimp

Post by Aiden »

Hello i'm now in your footsteps.
I'm also trying to implement an assimp mesh loader.
The last code you added causes the code to crush crush.
User avatar
Aiden
Halfling
Posts: 54
Joined: Fri Jul 14, 2017 3:16 pm
x 5

Re: Problems when rendering objects in Ogre using Assimp

Post by Aiden »

Here is what I get
Image

I use the latest assimp and ogre 1.9 stable release

That is supposed to be sinbad.blend.

My code is

Main

Code: Select all

  void createScene()
    {
        // Set the scene's ambient light
        mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));
       
		stringstream ss;
		std::string name;

		makeMesh(mSceneMgr, "Sinbad.dae", "head", "mesh");

        // Create a Light and set its position
        Ogre::Light* light = mSceneMgr->createLight("MainLight");
        light->setPosition(20.0f, 80.0f, 500.0f);
    }
assimp.h

Code: Select all

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <assimp/matrix4x4.h>
#include <assimp/cimport.h>

#include <Windows.h>
#include <iostream>
#include <stdint.h>
#include <vector>

class ModelManager
{
public:
	bool loadModel(std::string file);
	bool processData();
	std::vector<float> *getVertexData();
	std::vector<uint16_t> *getIndexData();
private:
	bool assimpGetMeshData(const aiMesh *);
private:
	Assimp::Importer            importer;
	const aiScene               *modelScene;
	const aiNode                *modelNode;
	const aiMesh                *modelMesh;
	const aiFace                *modelFace;
	std::vector<float>          vertexBuff;
	std::vector<uint16_t>       indexBuff;

	std::vector<const aiNode*>  nodeBuff;
	unsigned int                numNodeBuff;
};
assimp.cpp

Code: Select all

#include "Assimp.h"

bool ModelManager::loadModel(std::string file)
{
	modelScene = importer.ReadFile(file,
		aiProcess_Triangulate| 
		aiProcess_CalcTangentSpace |
		aiProcess_FlipWindingOrder |
		aiProcess_FlipUVs |
		aiProcess_FixInfacingNormals |
		aiProcess_MakeLeftHanded |
		aiProcess_GenNormals |
		aiProcess_FindInvalidData | 
		aiProcess_ValidateDataStructure |
		aiProcess_GenUVCoords | 0
	);

	if (!modelScene)
	{
		MessageBoxA(NULL, importer.GetErrorString(), "Error: ", MB_ICONERROR);
		return false;
	}

	return true;
}


bool ModelManager::assimpGetMeshData(const aiMesh *mesh)
{
	aiFace *face;

	for (unsigned int v = 0; v<mesh->mNumVertices; v++)
	{
		vertexBuff.push_back(mesh->mVertices[v].x);
		vertexBuff.push_back(mesh->mVertices[v].y);
		vertexBuff.push_back(mesh->mVertices[v].z);
		vertexBuff.push_back(mesh->mNormals[v].x);
		vertexBuff.push_back(mesh->mNormals[v].y);
		vertexBuff.push_back(mesh->mNormals[v].z);
		vertexBuff.push_back(mesh->mTextureCoords[0][v].x);
		vertexBuff.push_back(mesh->mTextureCoords[0][v].y);
	}

	for (unsigned int f = 0; f<mesh->mNumFaces; f++)
	{
		face = &mesh->mFaces[f];
		indexBuff.push_back(face->mIndices[0]);
		indexBuff.push_back(face->mIndices[1]);
		indexBuff.push_back(face->mIndices[2]);
	}

	return true;
}
bool ModelManager::processData()
{
	bool repeat = true;

	nodeBuff.push_back(modelScene->mRootNode);


	/* if (modelScene->mNumMeshes > 0)
	{
	for (unsigned int m=0;m<modelScene->mNumMeshes;m++)
	this->assimpGetMeshData(modelScene->mMeshes[m]);
	}*/

	// I raise all nodes tree to the root level 
	while (repeat)
	{
		for (unsigned int a = 0; a<nodeBuff.size(); a++)
		{
			modelNode = nodeBuff.at(a);
			if (modelNode->mNumChildren > 0)
				for (unsigned int c = 0; c<modelNode->mNumChildren; c++)
					nodeBuff.push_back(modelNode->mChildren[c]);
			else repeat = false;
		}
	}

	// Get node information from the root level (all nodes)
	for (unsigned int a = 0; a<nodeBuff.size(); a++)
	{
		modelNode = nodeBuff.at(a);

		if (modelNode->mNumMeshes>0)
			for (unsigned int b = 0; b<modelNode->mNumMeshes; b++)
				assimpGetMeshData(modelScene->mMeshes[*this->modelNode->mMeshes]);
	}
	return true;
}

std::vector<float> *ModelManager::getVertexData()
{
	return &vertexBuff;
}

std::vector<uint16_t> *ModelManager::getIndexData()
{
	return &indexBuff;
}
and
User avatar
Aiden
Halfling
Posts: 54
Joined: Fri Jul 14, 2017 3:16 pm
x 5

Re: Problems when rendering objects in Ogre using Assimp

Post by Aiden »

Also I noticed that this code distorts other file fomats like obj , not tested other formats.
I you can load textures too, please add your code too.
Post Reply