[2.1] Creating mesh manually

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

[2.1] Creating mesh manually

Post by xrgo »

Hello! I am trying to generate my mesh manually using data from a blender file... I have this working perfectly already for V1 mesh, then I importV1, so I am pretty sure that my "currentBuffer" has the correct values. But Now I want to generate the mesh directly to V2, this is my code so far:

Code: Select all

        // Create the mesh:
        Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual(meshName,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        Ogre::SubMesh* subMesh = mesh->createSubMesh();

        Ogre::RenderSystem* renderSystem = Ogre::Root::getSingleton().getRenderSystem();
        Ogre::VaoManager* vaoManager = renderSystem->getVaoManager();

        Ogre::VertexElement2Vec vertexElements;
        vertexElements.push_back(Ogre::VertexElement2(Ogre::VET_FLOAT3, Ogre::VES_POSITION));
        vertexElements.push_back(Ogre::VertexElement2(Ogre::VET_FLOAT3, Ogre::VES_NORMAL));
        //    //uvs
        //    for(int i=0; i<currentBuffer->uvSetCount; i++){
        //        vertexElements.push_back(Ogre::VertexElement2(Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES));
        //    }

        int vertexCount = currentBuffer->vertexs.size();

        size_t vertexSize = vaoManager->calculateVertexSize(vertexElements);

        Ogre::Real* vertexData = static_cast<Ogre::Real*>( OGRE_MALLOC_SIMD( vertexSize * vertexCount, Ogre::MEMCATEGORY_GEOMETRY ) );
        Ogre::Real* pVertex = reinterpret_cast<Ogre::Real*>(vertexData);


        Ogre::Vector3 minBB(Ogre::Vector3::UNIT_SCALE*FLT_MAX);
        Ogre::Vector3 maxBB(Ogre::Vector3::UNIT_SCALE*-FLT_MAX);

        for(int i=0; i<vertexCount; i++)
        {
            Ogre::Vector3 pos = convertToYup(Ogre::Vector3(currentBuffer->vertexs.at(i).co[0],currentBuffer->vertexs.at(i).co[1],currentBuffer->vertexs.at(i).co[2]));
            //transform to Y-up
            *pVertex++ = pos.x;
            *pVertex++ = pos.y;
            *pVertex++ = pos.z;

            Ogre::Vector3 norm = convertToYup(Ogre::Vector3(currentBuffer->vertexs.at(i).no[0],currentBuffer->vertexs.at(i).no[1],currentBuffer->vertexs.at(i).no[2])).normalisedCopy();
            //Normals
            *pVertex++ = norm.x;
            *pVertex++ = norm.y;
            *pVertex++ = norm.z;

            //        //uvs
            //        for(int j=0; j<currentBuffer->uvSetCount; j++){
            //            *pVertex++ = currentBuffer->vertexs.at(i).uv[j].x;
            //            *pVertex++ = 1.0-currentBuffer->vertexs.at(i).uv[j].y;
            //        }

            //Calc Bounds
            minBB.makeFloor(pos);
            maxBB.makeCeil(pos);

        }

        Ogre::VertexBufferPackedVec vertexBuffers;

        Ogre::VertexBufferPacked *pVertexBuffer = vaoManager->createVertexBuffer( vertexElements, vertexCount, Ogre::BT_IMMUTABLE, vertexData, true );
        vertexBuffers.push_back(pVertexBuffer);



        //Indices

        unsigned int iBufSize = currentBuffer->triangles.size() * 3;

        static const unsigned short index16BitClamp = (0xFFFF) - 1;

        //Index buffer
        Ogre::IndexBufferPacked::IndexType buff_type = (iBufSize > index16BitClamp) ?
                    Ogre::IndexBufferPacked::IT_32BIT : Ogre::IndexBufferPacked::IT_16BIT;

        //Build index items
        bool using32 = buff_type == Ogre::IndexBufferPacked::IT_32BIT;

        Ogre::uint32 *indices32 = 0;
        Ogre::uint16 *indices16 = 0;

        if (!using32)
            indices16 = reinterpret_cast<Ogre::uint16*>( OGRE_MALLOC_SIMD(sizeof(Ogre::uint16) * iBufSize, Ogre::MEMCATEGORY_GEOMETRY ) );
        else
            indices32 = reinterpret_cast<Ogre::uint32*>( OGRE_MALLOC_SIMD(sizeof(Ogre::uint32) * iBufSize, Ogre::MEMCATEGORY_GEOMETRY ) );

        for (unsigned int cur = 0; cur < currentBuffer->triangles.size(); cur++)
        {
            const yTriangleIndex& currentTriangle = currentBuffer->triangles.at(cur);
            for(unsigned int i=0; i<3; i++){
                if(using32)
                    *indices32++ = (Ogre::uint32)currentTriangle.index[i];
                else
                    *indices16++ = (Ogre::uint16)currentTriangle.index[i];
            }
        }

        Ogre::IndexBufferPacked *indexBuffer;
        if(using32){
            indexBuffer = vaoManager->createIndexBuffer( buff_type, iBufSize, Ogre::BT_IMMUTABLE, indices32, true );
        }
        else{
            indexBuffer = vaoManager->createIndexBuffer( buff_type, iBufSize, Ogre::BT_IMMUTABLE, indices16, true );
        }


        Ogre::VertexArrayObject *vao = vaoManager->createVertexArrayObject(
                    vertexBuffers, indexBuffer, Ogre::v1::RenderOperation::OT_TRIANGLE_LIST );

        subMesh->mVao[0].push_back( vao );
        subMesh->mVao[1].push_back( vao );


        Ogre::Aabb bounds;
        bounds.merge(minBB);
        bounds.merge(maxBB);
        mesh->_setBounds(bounds,false);
        mesh->_setBoundingSphereRadius(bounds.getRadius());

        return mesh;
But I only get on screen like some lines, or a couple of triangles, for meshes like cubes or suzannes. Am I missing something?

Thank you!!
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Creating mesh manually

Post by dark_sylinc »

I do not see anything wrong, not at least to the naked eye. Could be some very minor issue blowing everything up.

I did spot something curious: When importing from v1, it is almost certain that mLodValues will be set to:

Code: Select all

mLodValues = MovableObject::c_DefaultLodMesh
However without importing, mLodValues will be initialized to a different in the constructor. Also this value cannot be modified externally which looks like a bug in Ogre.
What happens if you set mLodValues to MovableObject::c_DefaultLodMesh from the very beginning?
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: [2.1] Creating mesh manually

Post by Kojack »

One little thing:

Code: Select all

Ogre::IndexBufferPacked::IndexType buff_type = (iBufSize > index16BitClamp) ?
                    Ogre::IndexBufferPacked::IT_32BIT : Ogre::IndexBufferPacked::IT_16BIT;
iBufSize is how many indices are in the index buffer, but 16 or 32 bit indices are determined by the number of vertices in the vertex buffer, not indices in the index buffer.
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] Creating mesh manually

Post by xrgo »

dark_sylinc wrote:What happens if you set mLodValues to MovableObject::c_DefaultLodMesh from the very beginning?
thank you, I just did this in OgreMesh2.cpp:

Code: Select all

    Mesh::Mesh( ResourceManager* creator, const String& name, ResourceHandle handle,
                const String& group, VaoManager *vaoManager, bool isManual, ManualResourceLoader* loader )
        : Resource(creator, name, handle, group, isManual, loader),
        mBoundRadius( 0.0f ),
        mLodStrategyName( LodStrategyManager::getSingleton().getDefaultStrategy()->getName() ),
        mNumLods( 1 ),
        mVaoManager( vaoManager ),
        mVertexBufferDefaultType( BT_IMMUTABLE ),
        mIndexBufferDefaultType( BT_IMMUTABLE ),
        mVertexBufferShadowBuffer( true ),
        mIndexBufferShadowBuffer( true )
    {
        //mLodValues.push_back( LodStrategyManager::getSingleton().getDefaultStrategy()->getBaseValue() );
        mLodValues = MovableObject::c_DefaultLodMesh;  ////<<<<<<this
    }
and the problem persists
Kojack wrote:One little thing:

Code: Select all

Ogre::IndexBufferPacked::IndexType buff_type = (iBufSize > index16BitClamp) ?
                    Ogre::IndexBufferPacked::IT_32BIT : Ogre::IndexBufferPacked::IT_16BIT;
iBufSize is how many indices are in the index buffer, but 16 or 32 bit indices are determined by the number of vertices in the vertex buffer, not indices in the index buffer.
Thank you so much for that tip, I am going to fix it, however this error just makes me waste vram? (since I am posibly using 32bit when I just need 16bit) or it affects performance? or geometry construction too?

I'll keep digging to find the problem, I am going to try to fill by hand some vertex and indexes to see if ti works
Thanks you!
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] Creating mesh manually

Post by xrgo »

I solved my problem changing the index part to this:

Code: Select all

            static const unsigned short index16BitClamp = (0xFFFF) - 1;

            //Indices

            unsigned int iBufSize = currentBuffer->triangles.size() * 3;

            Ogre::IndexBufferPacked::IndexType buff_type = ( currentBuffer->maxIndex > index16BitClamp) ?
                        Ogre::IndexBufferPacked::IT_32BIT : Ogre::IndexBufferPacked::IT_16BIT;

            Ogre::IndexBufferPacked *indexBuffer = 0;


            //Build index items
            bool using32 = buff_type == Ogre::IndexBufferPacked::IT_32BIT;

            if (!using32){
                Ogre::uint16 *indices16 = reinterpret_cast<Ogre::uint16*>( OGRE_MALLOC_SIMD( sizeof(Ogre::uint16) * iBufSize, Ogre::MEMCATEGORY_GEOMETRY ) );

                std::vector<Ogre::uint16> castedIndices(currentBuffer->indices.begin(), currentBuffer->indices.end());

                memcpy( indices16, &castedIndices[0], sizeof(Ogre::uint16)*castedIndices.size() );

                indexBuffer = vaoManager->createIndexBuffer( Ogre::IndexBufferPacked::IT_16BIT, iBufSize, Ogre::BT_IMMUTABLE, indices16, true );
            }
            else{
                Ogre::uint32 *indices32 = reinterpret_cast<Ogre::uint32*>( OGRE_MALLOC_SIMD( sizeof(Ogre::uint32) * iBufSize, Ogre::MEMCATEGORY_GEOMETRY ) );

                memcpy( indices32, &currentBuffer->indices[0], sizeof(Ogre::uint32)*currentBuffer->indices.size() );

                indexBuffer = vaoManager->createIndexBuffer( Ogre::IndexBufferPacked::IT_32BIT, iBufSize, Ogre::BT_IMMUTABLE, indices32, true );
            }
=D! thank you!
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] Creating mesh manually

Post by xrgo »

but I get this error:
OGRE EXCEPTION(1:InvalidStateException): Renderable can't use normal maps but datablock wants normal maps. Generate Tangents for this mesh to fix the problem or use a datablock without normal maps. in HlmsPbs::calculateHashForPreCreate at /home/sergio/ogre/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp (line 505)
how do I generate tangents? theres no buildtangents like in V1 meshes
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Creating mesh manually

Post by dark_sylinc »

xrgo wrote:how do I generate tangents? theres no buildtangents like in V1 meshes
I'm afraid at the time of writing the only way to generate them using Ogre is to import them to v1 meshes via v1::Mesh::importV2, generate them, then back to v2.

There's a similar thread. The thread was posted before the refactor.
Ideally code would be refactored so that we can reuse as much between v1 & v2 without copy pasting, but admittedly everything that has to do with random vertex manipulation is very tricky or complicated (i.e. it's easier when you're making your own engine and you enforce your own vertex formats and make assumptions). The new dearrangeToInefficient function aims at forcing some assumptions by converting all data back to the same format (e.g. floats for everything, use TBN instead of QTangents, one single buffer for all elements, etc)
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] Creating mesh manually

Post by xrgo »

thank you!
thats sad =(
I think I'll keep my old v1 mesh generation for now, and went back to this topic when I have more time =) many thanks!
123iamking
Gremlin
Posts: 152
Joined: Sat Aug 12, 2017 4:16 pm
x 4

Re: [2.1] Creating mesh manually

Post by 123iamking »

dark_sylinc wrote:
xrgo wrote:how do I generate tangents? theres no buildtangents like in V1 meshes
I'm afraid at the time of writing the only way to generate them using Ogre is to import them to v1 meshes via v1::Mesh::importV2, generate them, then back to v2.

There's a similar thread. The thread was posted before the refactor.
Ideally code would be refactored so that we can reuse as much between v1 & v2 without copy pasting, but admittedly everything that has to do with random vertex manipulation is very tricky or complicated (i.e. it's easier when you're making your own engine and you enforce your own vertex formats and make assumptions). The new dearrangeToInefficient function aims at forcing some assumptions by converting all data back to the same format (e.g. floats for everything, use TBN instead of QTangents, one single buffer for all elements, etc)
I see that the tutorial Sample_V2Mesh in Ogre 2.1 teach how to import mesh from v1 to v2, but I really want to directly create v2 mesh. It's been 2 years - So is it possible now? If it isn't, will Orge's team make it possible? Thanks.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Creating mesh manually

Post by dark_sylinc »

123iamking wrote:I see that the tutorial Sample_V2Mesh in Ogre 2.1 teach how to import mesh from v1 to v2, but I really want to directly create v2 mesh. It's been 2 years - So is it possible now? If it isn't, will Orge's team make it possible? Thanks.
Several users have done this already since a long time.
Just create a Mesh via MeshManager::create; create a SubMesh, and populate Vaos.

If you need sample code, ParallaxCorrectedCubemap::createProxyGeometry in Components/Hlms/Pbs/src/Cubemaps/OgreParallaxCorrectedCubemap.cpp creates a v2 mesh (a cube) at runtime with one submesh and a material.
How to populate/manipulate the vertex buffer and Vaos is the same as in CustomRenderable and DynamicGeometry.

Edit: If you mean about generating the tangents, no, it has not been coded yet so either the tangents are generated in v1 and then imported, or you use alternative methods as already listed; or someone implements it cleanly and submits a PR.
123iamking
Gremlin
Posts: 152
Joined: Sat Aug 12, 2017 4:16 pm
x 4

Re: [2.1] Creating mesh manually

Post by 123iamking »

dark_sylinc wrote: Several users have done this already since a long time.
Just create a Mesh via MeshManager::create; create a SubMesh, and populate Vaos.

If you need sample code, ParallaxCorrectedCubemap::createProxyGeometry in Components/Hlms/Pbs/src/Cubemaps/OgreParallaxCorrectedCubemap.cpp creates a v2 mesh (a cube) at runtime with one submesh and a material.
How to populate/manipulate the vertex buffer and Vaos is the same as in CustomRenderable and DynamicGeometry.

Edit: If you mean about generating the tangents, no, it has not been coded yet so either the tangents are generated in v1 and then imported, or you use alternative methods as already listed; or someone implements it cleanly and submits a PR.
Thank you dark_sylinc, I have tried to read ParallaxCorrectedCubemap::createProxyGeometry but I don't know how to make it work with a mesh file. I'm got scared off by the array Vector3 c_vertices[8] & uint16 c_indexData[3 * 2 * 6]. :cry:
Here what I've done so far (still use the v1 import to v2 method)

Code: Select all

void MeshHelper::CreateMesh(Ogre::String szFileName, Ogre::Vector3* scale)
{
	Ogre::v1::MeshPtr v1Mesh;
	Ogre::MeshPtr v2Mesh;

	/*Create Mesh*/
	v1Mesh = Ogre::v1::MeshManager::getSingleton().load(
		szFileName, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME,
		Ogre::v1::HardwareBuffer::HBU_STATIC, Ogre::v1::HardwareBuffer::HBU_STATIC);

	/*Create empty mesh v2*/
	Ogre::String szImportName = szFileName + " Imported";

	v2Mesh = Ogre::MeshManager::getSingleton().createManual(
		szImportName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	/*Import mesh to v2*/
	bool halfPosition = true;
	bool halfUVs = true;
	bool useQtangents = true;
	v2Mesh->importV1(v1Mesh.get(), halfPosition, halfUVs, useQtangents);

	/*Clean unnecessary things*/
	v1Mesh->unload();

	/*Bring the mesh to scene*/
	m_meshItem = m_sceneManager->createItem(szImportName,
		Ogre::ResourceGroupManager::
		AUTODETECT_RESOURCE_GROUP_NAME,
		Ogre::SCENE_DYNAMIC);
	m_meshSceneNode = m_sceneManager->getRootSceneNode(Ogre::SCENE_DYNAMIC)->
		createChildSceneNode(Ogre::SCENE_DYNAMIC);
	m_meshSceneNode->attachObject(m_meshItem);
	if (nullptr != scale)
		m_meshSceneNode->scale(scale->x, scale->y, scale->z);
}
As you see, with function CreateMesh() above, I can bring a mesh model into my scene.
My goal is to create v2 mesh directly inside the function CreateMesh().
But when I try to use Ogre::MeshManager::getSingleton().create like this

Code: Select all

void MeshHelper::CreateMesh(Ogre::String szFileName, Ogre::Vector3* scale)
{
	Ogre::MeshPtr v2Mesh;

	/*Create Mesh*/
	v2Mesh = Ogre::MeshManager::getSingleton().create(
		szFileName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
...
I got the exception :oops:

Code: Select all

OGRE EXCEPTION(7:InternalErrorException): Cannot find serializer implementation for mesh version [MeshSerializer_v1.100] in MeshSerializer::importMesh at E:..\OgreMain\src\OgreMesh2Serializer.cpp (line 171)
Hrenli
Halfling
Posts: 73
Joined: Tue Jun 14, 2016 12:26 pm
x 19

Re: [2.1] Creating mesh manually

Post by Hrenli »

123iamking wrote:I don't know how to make it work with a mesh file
If you are trying to load a v2 mesh from .mesh file to your scene it's really simple. Either directly as item:

Code: Select all

Ogre::Item *item = sceneManager->createItem("file.mesh", Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, Ogre::SCENE_DYNAMIC);
or a mesh:

Code: Select all

Ogre::MeshPtr v2Mesh = Ogre::MeshManager::getSingleton().load("file.mesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
123iamking
Gremlin
Posts: 152
Joined: Sat Aug 12, 2017 4:16 pm
x 4

Re: [2.1] Creating mesh manually

Post by 123iamking »

Hrenli wrote: If you are trying to load a v2 mesh from .mesh file to your scene it's really simple. Either directly as item:

Code: Select all

Ogre::Item *item = sceneManager->createItem("file.mesh", Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, Ogre::SCENE_DYNAMIC);
I have tried createItem() as you said:

Code: Select all

void MeshHelper::CreateMesh(Ogre::String szFileName, Ogre::Vector3* scale)
{
	/*Bring the mesh to scene*/
	m_meshItem = m_sceneManager->createItem(szFileName,
		Ogre::ResourceGroupManager::
		AUTODETECT_RESOURCE_GROUP_NAME,
		Ogre::SCENE_DYNAMIC);
	m_meshSceneNode = m_sceneManager->getRootSceneNode(Ogre::SCENE_DYNAMIC)->
		createChildSceneNode(Ogre::SCENE_DYNAMIC);
	m_meshSceneNode->attachObject(m_meshItem);
	if (nullptr != scale)
		m_meshSceneNode->scale(scale->x, scale->y, scale->z);
}
Then the program crash

Code: Select all

OGRE EXCEPTION(7:InternalErrorException): Cannot find serializer implementation for mesh version [MeshSerializer_v1.100] in MeshSerializer::importMesh at E:..\OgreMain\src\OgreMesh2Serializer.cpp (line 171)
Hrenli wrote: or a mesh:

Code: Select all

Ogre::MeshPtr v2Mesh = Ogre::MeshManager::getSingleton().load("file.mesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
And I have tried load() as you said:

Code: Select all

void MeshHelper::CreateMesh(Ogre::String szFileName, Ogre::Vector3* scale)
{
	Ogre::MeshPtr v2Mesh;

	/*Create Mesh*/
	v2Mesh = Ogre::MeshManager::getSingleton().load(
		szFileName, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME
		);

	v2Mesh = Ogre::MeshManager::getSingleton().createManual(
		szFileName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	/*Bring the mesh to scene*/
	m_meshItem = m_sceneManager->createItem(szFileName,
		Ogre::ResourceGroupManager::
		AUTODETECT_RESOURCE_GROUP_NAME,
		Ogre::SCENE_DYNAMIC);
	m_meshSceneNode = m_sceneManager->getRootSceneNode(Ogre::SCENE_DYNAMIC)->
		createChildSceneNode(Ogre::SCENE_DYNAMIC);
	m_meshSceneNode->attachObject(m_meshItem);
	if (nullptr != scale)
		m_meshSceneNode->scale(scale->x, scale->y, scale->z);
}
Then the program crash

Code: Select all

OGRE EXCEPTION(7:InternalErrorException): Cannot find serializer implementation for mesh version [MeshSerializer_v1.100] in MeshSerializer::importMesh at E:..\OgreMain\src\OgreMesh2Serializer.cpp (line 171)
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Creating mesh manually

Post by dark_sylinc »

That error is because you're trying to load a v1 mesh file.

See the "V2Mesh" sample to see how to load a v1 mesh file and import it to v2.
Alternatively, you can run

Code: Select all

OgreMeshTool.exe -v2 oldFile.mesh newFile.mesh
And then load newFile.mesh directly instead.
123iamking
Gremlin
Posts: 152
Joined: Sat Aug 12, 2017 4:16 pm
x 4

Re: [2.1] Creating mesh manually

Post by 123iamking »

dark_sylinc wrote:That error is because you're trying to load a v1 mesh file.

See the "V2Mesh" sample to see how to load a v1 mesh file and import it to v2.
Alternatively, you can run

Code: Select all

OgreMeshTool.exe -v2 oldFile.mesh newFile.mesh
And then load newFile.mesh directly instead.
Thank you dark_sylinc, it works :) Why didn't I remember to upgrade the mesh first? :oops:

For future reference's convenience, the code, that works, is

Code: Select all

void MeshHelper::CreateMesh(Ogre::String szFileName, Ogre::Vector3* scale)
{
	/*Bring the mesh to scene*/
	m_meshItem = m_sceneManager->createItem(szFileName,
		Ogre::ResourceGroupManager::
		AUTODETECT_RESOURCE_GROUP_NAME,
		Ogre::SCENE_DYNAMIC);
	m_meshSceneNode = m_sceneManager->getRootSceneNode(Ogre::SCENE_DYNAMIC)->
		createChildSceneNode(Ogre::SCENE_DYNAMIC);
	m_meshSceneNode->attachObject(m_meshItem);
	if (nullptr != scale)
		m_meshSceneNode->scale(scale->x, scale->y, scale->z);
}
Post Reply