Static geometry

Nowec

04-03-2006 23:55:03

I might just have missed something, but shouldn't there be support for static objects in the oSceneLoaderLib?

I added some code and got it working, not the most beautiful code maybe, but I'm also pretty new to both Ogre and the StaticGeometry.

This is what I did:
- Added a new property to the <entity>-element called "Static" which I set to yes/no
- Also added a "StaticGroup" as a property to <entity>
- Added a new method (addSceneNodeToStaticGeometry) that took care of adding the SceneNode to the static geometry group specified in "StaticGroup"
- Added a check in createNode() and called on addSceneNodeToStaticGeometry if "Static" was set to "yes"
- Did a build() on all StaticGeometrys for the sceneManager we created when loading the osm-file

I'm sure there's a lot left to do... don't even know if this is a good solution.
But I thought it was important enough to make a post about it.

You would of course need to add the possibility to set objects as static in 3dsmax before you export. :)

Lioric

05-03-2006 02:42:42

That is great news, excellent job :D

Static Geometry support is planned for a later release, but if you need it (and it seems you need it :D ) we will add a preliminary support in the next update this week along with static region settings

Nowec

05-03-2006 09:37:35

Thanks a lot for the feedback!
Would be great if you could add that support :)

My suggestion is that you add something like
<static static="yes" group="groupName" /> to the entity-element.
I guess that would look better than adding them as properties for <entity>?

Also don't know if lights can be static, but there's not really much work to be done if they can.

Nowec

05-03-2006 12:43:29

So this is what I did to get the static geometry working.

First I added <static /> to the entity in my osm-file
<oe_scene>
<sceneManager type="1" worldGeometry="terrain.cfg" />
<bkgcolor r="0" g="0" b="1" />
<lightColor r="0.5" g="0.5" b="0.5" />
<shadowTechnique type="0" tex_size="512" tex_count="1">
<color r="0" g="0" b="0" />
</shadowTechnique>
<entities>
<entity name="ThirdHead" hidden="false" filename="OgreHead.mesh" CastShadows="yes" ReceiveShadows="yes">
<position x="0" y="0" z="0" />
<rotation x="0" y="0" z="0" w="-1" />
<scale x="1" y="1" z="1" />
<static isStatic="yes" group="someGroup" />
</entity>
</entities>
</oe_scene>


When we're done adding static objects to the StaticGeometrys in our sceneManager we will need to build them, so I had to store the ones I used somewhere. I guess that there's some way to get a list of the StaticGeometrys from a SceneManager, but I couldn't find it, so I added a queue to OSMScene
std::queue<Ogre::StaticGeometry*> mStaticGeometrys;

Also added a new method to OSMScene that will add a SceneNode to the StaticGeometry group that we specified with "group" in <static />.
This method will also add the StaticGeometry to our SceneManger if it doesn't already exist.
When it does it will also add that StaticGeometry to the queue of StaticGeometrys

// Add a scene node to a static geometry in this->mSceneMgr
void OSMScene::addSceneNodeToStaticGeometry(const char* pStaticGeometryGroupName, Ogre::SceneNode* pSceneNode)
{
// Check that we actually got a string, and that it's not empty
if (pStaticGeometryGroupName == NULL || *pStaticGeometryGroupName == '\0')
{
pStaticGeometryGroupName = "default";
}

try
{
this->mSceneMgr->getStaticGeometry(pStaticGeometryGroupName)->addSceneNode(pSceneNode);
}
catch (...)
{
// There was no StaticGeometry with that name. Create one and then try again.
// The SGs are stored in a queue so that they can be used when we're done adding.
this->mStaticGeometrys.push(this->mSceneMgr->createStaticGeometry(pStaticGeometryGroupName));
this->mSceneMgr->getStaticGeometry(pStaticGeometryGroupName)->addSceneNode(pSceneNode);
}
}


Then I added this code to OSMScene::createNode() (added it between //Rotation and //Notify)
This is the code that will look for <static /> in our osm-file.
If it's found it will check the properties, if not it will just move on to //Notify
// Static
TiXmlElement* staticElem = pElem->FirstChildElement("static");
if (staticElem)
{
try
{
std::string staticIsStatic = staticElem->Attribute("isStatic");

if (staticIsStatic == "yes")
{
const char* ptrStaticGroup = staticElem->Attribute("group");
this->addSceneNodeToStaticGeometry(ptrStaticGroup, pNode);
}
}
catch (...)
{
// Empty catch, isStatic couldn't be found
}
}


Ok, we're almost done! We just need to build all the StaticGeometrys now. Our static SceneNodes won't show if we don't build them, so it's a pretty important part of the progress ;)
Remember that we stored all the StaticGeometrys we used in a queue called mStaticGeometrys? That's what we'll use now.
We don't want to build them before all SceneNodes are added, so we do it in OSMScene::createScene(), right before we "return true;".
// Build all the static geometrys we've stored objects in while we loaded them
while (!this->mStaticGeometrys.empty())
{
StaticGeometry* tempSg = this->mStaticGeometrys.front();
this->mStaticGeometrys.pop();
tempSg->build();
}


I hope some of this might be useful for someone else too, but as I said earlier - there's more to do, I don't know if some lights should be static too...