From: <vo...@us...> - 2008-05-28 19:46:59
|
Revision: 752 http://opde.svn.sourceforge.net/opde/?rev=752&view=rev Author: volca Date: 2008-05-28 12:47:06 -0700 (Wed, 28 May 2008) Log Message: ----------- Preparing for DarkGeometry (it already works under linux, but commented out to be sure) Modified Paths: -------------- trunk/src/services/worldrep/WRCell.cpp trunk/src/services/worldrep/WRCell.h trunk/src/services/worldrep/WorldRepService.cpp trunk/src/services/worldrep/WorldRepService.h Modified: trunk/src/services/worldrep/WRCell.cpp =================================================================== --- trunk/src/services/worldrep/WRCell.cpp 2008-05-28 19:13:47 UTC (rev 751) +++ trunk/src/services/worldrep/WRCell.cpp 2008-05-28 19:47:06 UTC (rev 752) @@ -40,7 +40,7 @@ namespace Opde { //------------------------------------------------------------------------------------ - WRCell::WRCell(WorldRepService* owner) : cellNum(-1), atlased(false), loaded(false), portalsDone(false), mOwner(owner) { + WRCell::WRCell(WorldRepService* owner, Ogre::DarkGeometry* targetGeom) : cellNum(-1), atlased(false), loaded(false), portalsDone(false), mOwner(owner), mLevelGeometry(targetGeom) { bspNode = NULL; } @@ -237,8 +237,9 @@ tmp << txtName.str(); // directly name after the original. This will cause the material to be found } else { // !NLM! + // tmp << txtName.str(); tmp << "Shader" << texture << "#" << atlasnum; - // tmp << txtName.str(); + } } std::string shaderName = tmp.str(); @@ -815,7 +816,6 @@ StringUtil::StrStreamType modelName; modelName << "cell_" << cellNum; - // Attach the resulting object to the node with the center in the center vertex of the mesh... SceneNode* meshNode = sceneMgr->createSceneNode(modelName.str()); meshNode->setPosition(nodeCenter); @@ -912,7 +912,107 @@ return meshNode; } + + //------------------------------------------------------------------------------------ + void WRCell::createCellGeometry() { + // some checks on the status. These are hard mistakes + assert(loaded); + assert(atlased); + int portalStart = header.num_polygons - header.num_portals; + + // Contains material name -> polygon list + std::map<std::string, std::vector<int> > matToPolys; + // polygon index to txt Dimensions + std::map<int, std::pair<uint,uint> > polyToDim; + + // int faceCount = header.num_polygons - header.num_portals; + int faceCount = header.num_textured; + + // Cell is recentered with this + wr_coord_t cellCenter = header.center; + Vector3 nodeCenter = Vector3(cellCenter.x, cellCenter.y, cellCenter.z); + + // Now let's iterate over the materials + // Prepare the object's name + StringUtil::StrStreamType modelName; + modelName << "cell_" << cellNum; + + // Attach the resulting object to the node with the center in the center vertex of the mesh... + if (faceCount <= 0) { + LOG_INFO("A geometry - less cell encountered, skipping the mesh generation"); + return; + } + + // Step one. Map materials and polygons to iterate over + for (int polyNum = 0; polyNum < faceCount; polyNum++) { + std::pair< Ogre::uint, Ogre::uint > dimensions; + + std::string matname = getMaterialName(face_infos[polyNum].txt, lightMaps[polyNum]->getAtlasIndex(), dimensions, face_maps[polyNum].flags); + + // insert the poly index into the list of that material + std::pair< std::map<std::string, std::vector<int> >::iterator, bool > res = matToPolys.insert(make_pair(matname, std::vector<int>())); + res.first->second.push_back(polyNum); + + // Could be rather per material. But well. just for test anyway + polyToDim.insert(make_pair(polyNum, dimensions)); + } + + + std::map<std::string, std::vector<int> >::iterator it = matToPolys.begin(); + + for (; it != matToPolys.end(); it++) { + DarkFragment* frag = mLevelGeometry->createFragment(cellNum, MaterialManager::getSingleton().getByName(it->first)); + + std::vector<int>::iterator pi = it->second.begin(); + + // each of those polygons + for (; pi != it->second.end(); pi++) { + // Iterate through the faces, and add all the triangles we can construct using the polygons defined + std::pair< Ogre::uint, Ogre::uint > dimensions; + + int polyNum = *pi; + + std::map<int, std::pair<uint, uint> >::iterator dimi = polyToDim.find(polyNum); + + if (dimi == polyToDim.end()) + OPDE_EXCEPT("Missing polygon texture dimensions!", "WrCell::constructCellMesh"); + + dimensions = dimi->second; + + Vector2 displacement = calcLightmapDisplacement(polyNum); + + // for each vertex, insert into the model + uint32_t *idxmap = new uint32_t[face_maps[polyNum].count]; + + for (int vert = 0; vert < face_maps[polyNum].count; vert++) { + wr_coord_t vrelative = vertices[ poly_indices[polyNum][vert] ]; + + // insertTexturedVertex(manual, polyNum, vrelative, displacement, dimensions, nodeCenter); + BspVertex vtx; + constructBspVertex(polyNum, vrelative, displacement, dimensions, &vtx); + + idxmap[vert] = frag->vertex( + Vector3(vtx.position[0], vtx.position[1], vtx.position[2]), + Vector3(vtx.normal[0], vtx.normal[0], vtx.normal[0]), + Vector2(vtx.texcoords[0], vtx.texcoords[1]), + Vector2(vtx.lightmap[0], vtx.lightmap[1]) ); + } + + // now feed the indexes + for (int t = 1; t < face_maps[polyNum].count - 1; t++) { + // push back the indexes + frag->index(idxmap[0]); + frag->index(idxmap[t + 1]); + frag->index(idxmap[t]); + } + + delete[] idxmap; + } + } + } + + //------------------------------------------------------------------------------------ void WRCell::setBspNode(Ogre::BspNode* tgtNode) { bspNode = tgtNode; Modified: trunk/src/services/worldrep/WRCell.h =================================================================== --- trunk/src/services/worldrep/WRCell.h 2008-05-28 19:13:47 UTC (rev 751) +++ trunk/src/services/worldrep/WRCell.h 2008-05-28 19:47:06 UTC (rev 752) @@ -30,6 +30,7 @@ #include "DarkPortal.h" #include "DarkBspNode.h" #include "DarkSceneManager.h" +#include "DarkGeometry.h" #include <OgreMaterial.h> #include <OgreStaticFaceGroup.h> @@ -137,10 +138,15 @@ /** Owner service of this cell */ WorldRepService* mOwner; + + /** Geometry holder to fill */ + Ogre::DarkGeometry* mLevelGeometry; public: /** Default constructor. */ - WRCell(WorldRepService* owner); + WRCell(WorldRepService* owner, Ogre::DarkGeometry* targetGeom); + + /** destructor */ ~WRCell(); /** Load the cell data from the given chunk. @@ -164,6 +170,9 @@ /// Creates a scene node with all non-portal geometry attached as a mesh Ogre::SceneNode* createSceneNode(Ogre::SceneManager *sceneMgr); + /// creates the geometry for the cell in the DarkGeometry given in constructor + void createCellGeometry(); + /** Return the exact vertex count needed to set-up the vertex buffer with the cell data. * @note The vertex count is not a plain vertex list count, but the count of vertices which are counted as the resulting polygons total vertex sum (The reason is the vertex here is in fact a Vertex-Normal pair) Modified: trunk/src/services/worldrep/WorldRepService.cpp =================================================================== --- trunk/src/services/worldrep/WorldRepService.cpp 2008-05-28 19:13:47 UTC (rev 751) +++ trunk/src/services/worldrep/WorldRepService.cpp 2008-05-28 19:47:06 UTC (rev 752) @@ -43,6 +43,7 @@ using namespace Ogre; +#define __SG namespace Opde { // Implementation of the WorldRep service @@ -163,6 +164,7 @@ void WorldRepService::unload() { mIndexes.setNull(); + mSceneMgr->clearScene(); mTxtScaleMap.clear(); @@ -234,8 +236,10 @@ mCells = new WRCell*[header.num_cells]; + mWorldGeometry = mSceneMgr->createGeometry("LEVEL_GEOMETRY"); // will be deleted on clear_scene + for (uint32_t i = 0; i<header.num_cells; i++) { - mCells[i] = new WRCell(this); + mCells[i] = new WRCell(this, mWorldGeometry); } unsigned int idx; @@ -295,6 +299,7 @@ // -------------------------------------------------------------------------------- // Now construct the static geometry +#ifdef __SG Ogre::StaticGeometry* sg = mSceneMgr->createStaticGeometry("MISSION_GEOMETRY"); // 100 units per sg region @@ -313,22 +318,28 @@ sg->setOrigin(Vector3(0, 0, 0)); std::vector< std::string > nodesToDestroy; +#endif //TODO: Portal meshes need to be constructed. This will guarantee the other meshes can be attached if this one works ok // Hmm. Actually, it renders quite a lot of the meshes that should not be seen. for (idx=0; idx < header.num_cells; idx++) { mCells[idx]->constructPortalMeshes(mSceneMgr); + +#ifdef __SG Ogre::SceneNode* node = mCells[idx]->createSceneNode(mSceneMgr); // Non - sg rendering - slower - // mSceneMgr->getRootSceneNode()->addChild(node); sg->addSceneNode(node); - // mSceneMgr->destroySceneNode(node->getName()); nodesToDestroy.push_back(node->getName()); +#else + // mSceneMgr->getRootSceneNode()->addChild(node); + mCells[idx]->createCellGeometry(); +#endif } +#ifdef __SG LOG_DEBUG("Worldrep: Building static geometry..."); sg->setCastShadows(false); @@ -342,7 +353,12 @@ // render SG before everything else sg->setRenderQueueGroup(RENDER_QUEUE_MAIN - 1); +#else + mWorldGeometry->build(); + mSceneMgr->setActiveGeometry(mWorldGeometry); +#endif + // -------------------------------------------------------------------------------- // We have done all we could, bringing the level data to the SceneManager. Now delete the used data LOG_DEBUG("Worldrep: Freeing temporary buffers"); Modified: trunk/src/services/worldrep/WorldRepService.h =================================================================== --- trunk/src/services/worldrep/WorldRepService.h 2008-05-28 19:13:47 UTC (rev 751) +++ trunk/src/services/worldrep/WorldRepService.h 2008-05-28 19:47:06 UTC (rev 752) @@ -177,6 +177,9 @@ MaterialList mLoadedMaterials; TxtScaleMap mTxtScaleMap; + + /// holder of the level geometry + Ogre::DarkGeometry* mWorldGeometry; }; /// Shared pointer to worldrep service This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |