I don't see any obvious way to do what you want without making chanes to the library. The
IShaderConstantSetCallBack doesn't get any information about the
ISceneNode or geometry being rendered.
If you only need to do this for one scene node, you could put an
ISceneNode* in your
IShaderConstantSetCallBack derived class. When the
OnSetConstants() function is called, you'd just use that pointer.
If you need to do this for multiple nodes, you could hijack one of the
MaterialTypeParam fields and treat that as a scene node ID. This would assume that
f32 is the same size as
s32, which should be safe if the type names reflect the actual implementation.
So your code would look something like this...
Code: Select all
class MyShaderCallback : public video::IShaderConstantSetCallback
{
public:
MyShaderCallback (scene::ISceneManager* smgr)
: SceneManager (smgr)
, ActiveSceneNode (0)
{
}
virtual void OnSetMaterial(const video::SMaterial& m);
virtual void OnSetConstants(video::IMaterialRenderServices* s, s32 userData);
private:
scene::ISceneManager* SceneManager;
scene::ISceneNode* ActiveNode;
};
void MyShaderCallback::OnSetMaterial (const SMaterial& m)
{
// abuse MaterialTypeParam2 as the scene node id
const s32 nodeID = *(s32*)&m.MaterialTypeParam2;
// find the scene node that has the given id
ActiveSceneNode = SceneManager->getSceneNodeFromId(nodeID);
}
void MyShaderCallback::OnSetConstants (IMaterialRenderServices* s, s32 userData)
{
if (ActiveSceneNode)
{
core::aabbox3df bbox = ActiveNode->getBoundingBox();
ActiveNode->getAbsoluteTransformation().transformBoxEx(bbox);
// do whatever you need to do
}
}
Then, when setting the material you'd do this...
Code: Select all
const s32 nodeID = node->getID();
for (u32 i = 0; i < node->getMaterialCount(); ++i)
{
video::SMaterial& mat = node->getMaterial(i);
mat.MaterialType = (video::E_MATERIAL_TYPE)matID;
mat.MaterialTypeParam2 = *(f32*)&nodeID;
}
Travis