Hello greenskins,
I'm attempting a shenanigan: To load a mesh without blend indices/weights, add those on-the-fly, then manually create skeleton/bones and make it work together. The purpose is to replace an existing (crude and inefficient) mesh deformation system in Rigs of Rods. I'm using software skinning.
I seem to be able to augment the mesh and also get the skeleton working (no assert()s, no Exceptions). However, I get a crash within Ogre::OptimisedUtilSSE
. Note I've only tried with OGRE 1.11.6 which the project is presently stuck with. I'll try to test in a OGRE14 porting branch later.
The error I get is "Exception thrown: read access violation. Ogre::TransformBase::operator[](...) returned 0xFFFFFFFFFFFFFFFF.
" which feels like the transform matrices aren't set up right. I noticed there's a Ogre::Mesh::prepareMatricesForVertexBlend()
function, but that appears to be called by Ogre::Entity::updateAnimation()
which is in my callstack, so I should be good.
This is my stack trace (a screenshot of the debugger view is attached):
Code: Select all
OgreMain_d.dll!Ogre::SoftwareVertexSkinning_SSE_PosNorm_Separated_Packed<1,1,1,1>::apply(const float * pSrcPos, float * pDestPos, const float * pSrcNorm, float * pDestNorm, const float * pBlendWeight, const unsigned char * pBlendIndex, const Ogre::Affine3 * const * blendMatrices, unsigned __int64 blendWeightStride, unsigned __int64 blendIndexStride, unsigned __int64 numWeightsPerVertex, unsigned __int64 numIterations) Line 787 C++
OgreMain_d.dll!Ogre::softwareVertexSkinning_SSE_PosNorm_Separated_Packed(const float * pSrcPos, float * pDestPos, const float * pSrcNorm, float * pDestNorm, const float * pBlendWeight, const unsigned char * pBlendIndex, const Ogre::Affine3 * const * blendMatrices, unsigned __int64 blendWeightStride, unsigned __int64 blendIndexStride, unsigned __int64 numWeightsPerVertex, unsigned __int64 numIterations) Line 907 C++
OgreMain_d.dll!Ogre::OptimisedUtilSSE::softwareVertexSkinning(const float * pSrcPos, float * pDestPos, const float * pSrcNorm, float * pDestNorm, const float * pBlendWeight, const unsigned char * pBlendIndex, const Ogre::Affine3 * const * blendMatrices, unsigned __int64 srcPosStride, unsigned __int64 destPosStride, unsigned __int64 srcNormStride, unsigned __int64 destNormStride, unsigned __int64 blendWeightStride, unsigned __int64 blendIndexStride, unsigned __int64 numWeightsPerVertex, unsigned __int64 numVertices) Line 1189 C++
OgreMain_d.dll!Ogre::Mesh::softwareVertexBlend(const Ogre::VertexData * sourceVertexData, const Ogre::VertexData * targetVertexData, const Ogre::Affine3 * const * blendMatrices, unsigned __int64 numMatrices, bool blendNormals) Line 2040 C++
OgreMain_d.dll!Ogre::Entity::updateAnimation() Line 948 C++
OgreMain_d.dll!Ogre::Entity::_updateRenderQueue(Ogre::RenderQueue * queue) Line 704 C++
OgreMain_d.dll!Ogre::RenderQueue::processVisibleObject(Ogre::MovableObject * mo, Ogre::Camera * cam, bool onlyShadowCasters, Ogre::VisibleObjectsBoundsInfo * visibleBounds) Line 254 C++
OgreMain_d.dll!Ogre::SceneNode::_findVisibleObjects(Ogre::Camera * cam, Ogre::RenderQueue * queue, Ogre::VisibleObjectsBoundsInfo * visibleBounds, bool includeChildren, bool displayNodes, bool onlyShadowCasters) Line 274 C++
OgreMain_d.dll!Ogre::SceneNode::_findVisibleObjects(Ogre::Camera * cam, Ogre::RenderQueue * queue, Ogre::VisibleObjectsBoundsInfo * visibleBounds, bool includeChildren, bool displayNodes, bool onlyShadowCasters) Line 285 C++
OgreMain_d.dll!Ogre::SceneManager::_findVisibleObjects(Ogre::Camera * cam, Ogre::VisibleObjectsBoundsInfo * visibleBounds, bool onlyShadowCasters) Line 1700 C++
OgreMain_d.dll!Ogre::SceneManager::_renderScene(Ogre::Camera * camera, Ogre::Viewport * vp, bool includeOverlays) Line 1434 C++
OgreMain_d.dll!Ogre::Camera::_renderScene(Ogre::Viewport * vp, bool includeOverlays) Line 421 C++
OgreMain_d.dll!Ogre::Viewport::update() Line 222 C++
OgreMain_d.dll!Ogre::RenderTarget::_updateViewport(Ogre::Viewport * viewport, bool updateStatistics) Line 204 C++
RenderSystem_Direct3D9_d.dll!Ogre::D3D9RenderWindow::_updateViewport(Ogre::Viewport * viewport, bool updateStatistics) Line 852 C++
OgreMain_d.dll!Ogre::RenderTarget::_updateAutoUpdatedViewports(bool updateStatistics) Line 183 C++
OgreMain_d.dll!Ogre::RenderTarget::updateImpl() Line 159 C++
OgreMain_d.dll!Ogre::RenderTarget::update(bool swap) Line 574 C++
OgreMain_d.dll!Ogre::RenderSystem::_updateAllRenderTargets(bool swapBuffers) Line 122 C++
OgreMain_d.dll!Ogre::Root::_updateAllRenderTargets() Line 1297 C++
OgreMain_d.dll!Ogre::Root::renderOneFrame() Line 876 C++
RoR.exe!main(int argc, char * * argv) Line 1704 C++
RoR.exe!WinMain(HINSTANCE__ * hInst, HINSTANCE__ * __formal, char * strCmdLine, int __formal) Line 1735 C++
This is my code (abridged):
Code: Select all
m_skeleton = Ogre::SkeletonManager::getSingleton().create(skeleton_name, GetResourceGroup());
assert(m_skeleton->getGroup() == m_mesh_clone->getGroup());
m_mesh_clone->_notifySkeleton(m_skeleton); // Cannot use `setSkeletonName()` because that attempts to load _directly_ from file.
Ogre::Bone* root_bone = m_skeleton->createBone("root", 0);
root_bone->setManuallyControlled(true);
for (...)
{
Ogre::Bone* bone = m_skeleton->createBone(fmt::format("bone{}", bone_index), bone_index);
bone->setManuallyControlled(true);
root_bone->addChild(bone);
bone->setPosition(...);
for (...)
{
mesh->addBoneAssignment(vba); // 1-based boneIndex (0 is the root bone)
}
}
m_skeleton->setBindingPose();
mesh->_compileBoneAssignments();
// create entity...
My questions are:
- Can I somehow disable the SSE-optimized vertex blending? I'm assuming there's some simple blending implementation that may give me more insight.
- Is there something I'm doing apparently wrong in the code above?
Thanks.