mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 20:26:48 +00:00 
			
		
		
		
	Add text key loading
This commit is contained in:
		
							parent
							
								
									6219a7bbfc
								
							
						
					
					
						commit
						6d85444d26
					
				
					 3 changed files with 76 additions and 28 deletions
				
			
		|  | @ -111,7 +111,6 @@ int main(int argc, char** argv) | |||
| 
 | ||||
| 
 | ||||
|     //osgDB::writeNodeFile(*newNode, "out.osg");
 | ||||
| 
 | ||||
|     osg::Group* newNode = new osg::Group; | ||||
|     NifOsg::Loader loader; | ||||
|     loader.resourceManager = &resourceMgr; | ||||
|  |  | |||
|  | @ -302,12 +302,50 @@ namespace | |||
|         } | ||||
|         return morphGeom; | ||||
|     } | ||||
| 
 | ||||
|     void extractTextKeys(const Nif::NiTextKeyExtraData *tk, NifOsg::TextKeyMap &textkeys) | ||||
|     { | ||||
|         for(size_t i = 0;i < tk->list.size();i++) | ||||
|         { | ||||
|             const std::string &str = tk->list[i].text; | ||||
|             std::string::size_type pos = 0; | ||||
|             while(pos < str.length()) | ||||
|             { | ||||
|                 if(::isspace(str[pos])) | ||||
|                 { | ||||
|                     pos++; | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 std::string::size_type nextpos = std::min(str.find('\r', pos), str.find('\n', pos)); | ||||
|                 if(nextpos != std::string::npos) | ||||
|                 { | ||||
|                     do { | ||||
|                         nextpos--; | ||||
|                     } while(nextpos > pos && ::isspace(str[nextpos])); | ||||
|                     nextpos++; | ||||
|                 } | ||||
|                 else if(::isspace(*str.rbegin())) | ||||
|                 { | ||||
|                     std::string::const_iterator last = str.end(); | ||||
|                     do { | ||||
|                         --last; | ||||
|                     } while(last != str.begin() && ::isspace(*last)); | ||||
|                     nextpos = std::distance(str.begin(), ++last); | ||||
|                 } | ||||
|                 std::string result = str.substr(pos, nextpos-pos); | ||||
|                 textkeys.insert(std::make_pair(tk->list[i].time, Misc::StringUtils::toLower(result))); | ||||
| 
 | ||||
|                 pos = nextpos; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| namespace NifOsg | ||||
| { | ||||
| 
 | ||||
|     void Loader::loadKf(Nif::NIFFilePtr nif, osg::Node *rootNode, int sourceIndex) | ||||
|     void Loader::loadKf(Nif::NIFFilePtr nif, osg::Node *rootNode, int sourceIndex, TextKeyMap& textKeys) | ||||
|     { | ||||
|         if(nif->numRoots() < 1) | ||||
|         { | ||||
|  | @ -334,7 +372,7 @@ namespace NifOsg | |||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         //extractTextKeys(static_cast<const Nif::NiTextKeyExtraData*>(extra.getPtr()), textKeys);
 | ||||
|         extractTextKeys(static_cast<const Nif::NiTextKeyExtraData*>(extra.getPtr()), textKeys); | ||||
| 
 | ||||
|         std::map<std::string, const Nif::NiKeyframeController*> controllerMap; | ||||
| 
 | ||||
|  | @ -364,55 +402,45 @@ namespace NifOsg | |||
|         rootNode->accept(visitor); | ||||
|     } | ||||
| 
 | ||||
|     osg::Node* Loader::load(Nif::NIFFilePtr nif, osg::Group *parentNode) | ||||
|     osg::Node* Loader::load(Nif::NIFFilePtr nif, osg::Group *parentNode, TextKeyMap* textKeys) | ||||
|     { | ||||
|         mNif = nif; | ||||
| 
 | ||||
|         if (nif->numRoots() < 1) | ||||
|         { | ||||
|             nif->fail("Found no root nodes"); | ||||
|         } | ||||
| 
 | ||||
|         const Nif::Record* r = nif->getRoot(0); | ||||
| 
 | ||||
|         const Nif::Node* nifNode = dynamic_cast<const Nif::Node*>(r); | ||||
|         if (nifNode == NULL) | ||||
|         { | ||||
|             nif->fail("First root was not a node, but a " + r->recName); | ||||
|         } | ||||
| 
 | ||||
|         mRootNode = parentNode; | ||||
| 
 | ||||
|         osg::Node* created = handleNode(nifNode, parentNode, false, std::map<int, int>(), 0, 0); | ||||
|         osg::Node* created = handleNode(nifNode, parentNode, false, std::map<int, int>(), 0, 0, false, textKeys); | ||||
|         return created; | ||||
|     } | ||||
| 
 | ||||
|     osg::Node* Loader::loadAsSkeleton(Nif::NIFFilePtr nif, osg::Group *parentNode) | ||||
|     osg::Node* Loader::loadAsSkeleton(Nif::NIFFilePtr nif, osg::Group *parentNode, TextKeyMap* textKeys) | ||||
|     { | ||||
|         mNif = nif; | ||||
| 
 | ||||
|         if (nif->numRoots() < 1) | ||||
|         { | ||||
|             //nif->warn("Found no root nodes");
 | ||||
|             nif->fail("Found no root nodes"); | ||||
|         } | ||||
| 
 | ||||
|         const Nif::Record* r = nif->getRoot(0); | ||||
|         assert(r != NULL); | ||||
| 
 | ||||
|         const Nif::Node* nifNode = dynamic_cast<const Nif::Node*>(r); | ||||
|         if (nifNode == NULL) | ||||
|         { | ||||
|             //nif->warn("First root was not a node, but a " + r->recName);
 | ||||
|             nif->fail("First root was not a node, but a " + r->recName); | ||||
|         } | ||||
| 
 | ||||
|         osg::ref_ptr<osgAnimation::Skeleton> skel = new osgAnimation::Skeleton; | ||||
|         parentNode->addChild(skel); | ||||
| 
 | ||||
|         mRootNode = parentNode; | ||||
| 
 | ||||
|         handleNode(nifNode, skel, true, std::map<int, int>(), 0, 0); | ||||
|         handleNode(nifNode, skel, true, std::map<int, int>(), 0, 0, false, textKeys); | ||||
| 
 | ||||
|         return skel; | ||||
|     } | ||||
|  | @ -437,7 +465,7 @@ namespace NifOsg | |||
|     } | ||||
| 
 | ||||
|     osg::Node* Loader::handleNode(const Nif::Node* nifNode, osg::Group* parentNode, bool createSkeleton, | ||||
|                             std::map<int, int> boundTextures, int animflags, int particleflags, bool collisionNode) | ||||
|                             std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys) | ||||
|     { | ||||
|         osg::ref_ptr<osg::MatrixTransform> transformNode; | ||||
|         if (nifNode->recType == Nif::RC_NiBillboardNode) | ||||
|  | @ -458,6 +486,9 @@ namespace NifOsg | |||
|         } | ||||
|         // Ignoring name for non-bone nodes for now. We might need it later in isolated cases, e.g. AttachLight.
 | ||||
| 
 | ||||
|         // Insert bones at position 0 to prevent update order problems (see comment in osg Skeleton.cpp)
 | ||||
|         parentNode->insertChild(0, transformNode); | ||||
| 
 | ||||
|         // UserData used for a variety of features:
 | ||||
|         // - finding the correct emitter node for a particle system
 | ||||
|         // - establishing connections to the animated collision shapes, which are handled in a separate loader
 | ||||
|  | @ -467,6 +498,27 @@ namespace NifOsg | |||
|         transformNode->getOrCreateUserDataContainer()->addUserObject( | ||||
|             new NodeUserData(nifNode->recIndex, nifNode->trafo.scale, nifNode->trafo.rotation)); | ||||
| 
 | ||||
|         for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->extra) | ||||
|         { | ||||
|             if(e->recType == Nif::RC_NiTextKeyExtraData && textKeys) | ||||
|             { | ||||
|                 const Nif::NiTextKeyExtraData *tk = static_cast<const Nif::NiTextKeyExtraData*>(e.getPtr()); | ||||
|                 extractTextKeys(tk, *textKeys); | ||||
|             } | ||||
|             else if(e->recType == Nif::RC_NiStringExtraData) | ||||
|             { | ||||
|                 const Nif::NiStringExtraData *sd = static_cast<const Nif::NiStringExtraData*>(e.getPtr()); | ||||
|                 // String markers may contain important information
 | ||||
|                 // affecting the entire subtree of this obj
 | ||||
|                 // TODO: implement show markers flag
 | ||||
|                 if(sd->string == "MRK" /*&& !sShowMarkers*/) | ||||
|                 { | ||||
|                     // Marker objects. These meshes are only visible in the editor.
 | ||||
|                     skipMeshes = true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (nifNode->recType == Nif::RC_NiBSAnimationNode) | ||||
|             animflags |= nifNode->flags; | ||||
|         if (nifNode->recType == Nif::RC_NiBSParticleNode) | ||||
|  | @ -476,7 +528,7 @@ namespace NifOsg | |||
|         // We still need to animate the hidden bones so the physics system can access them
 | ||||
|         if (nifNode->recType == Nif::RC_RootCollisionNode) | ||||
|         { | ||||
|             collisionNode = true; | ||||
|             skipMeshes = true; | ||||
|             // Leave mask for UpdateVisitor enabled
 | ||||
|             transformNode->setNodeMask(0x1); | ||||
|         } | ||||
|  | @ -486,12 +538,9 @@ namespace NifOsg | |||
|         if (nifNode->flags & Nif::NiNode::Flag_Hidden) | ||||
|             transformNode->setNodeMask(0x1); // Leave mask for UpdateVisitor enabled
 | ||||
| 
 | ||||
|         // Insert bones at position 0 to prevent update order problems (see comment in osg Skeleton.cpp)
 | ||||
|         parentNode->insertChild(0, transformNode); | ||||
| 
 | ||||
|         applyNodeProperties(nifNode, transformNode, boundTextures, animflags); | ||||
| 
 | ||||
|         if (nifNode->recType == Nif::RC_NiTriShape && !collisionNode) | ||||
|         if (nifNode->recType == Nif::RC_NiTriShape && !skipMeshes) | ||||
|         { | ||||
|             const Nif::NiTriShape* triShape = static_cast<const Nif::NiTriShape*>(nifNode); | ||||
|             if (!createSkeleton || triShape->skin.empty()) | ||||
|  | @ -520,7 +569,7 @@ namespace NifOsg | |||
|             for(size_t i = 0;i < children.length();++i) | ||||
|             { | ||||
|                 if(!children[i].empty()) | ||||
|                     handleNode(children[i].getPtr(), transformNode, createSkeleton, boundTextures, animflags, particleflags, collisionNode); | ||||
|                     handleNode(children[i].getPtr(), transformNode, createSkeleton, boundTextures, animflags, particleflags, skipMeshes, textKeys); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -40,15 +40,15 @@ namespace NifOsg | |||
|         // though, when assembling from several files, i.e. equipment parts
 | ||||
|         /// Create a scene graph for the given NIF. Assumes no skinning is used.
 | ||||
|         /// @param node The parent of the new root node for the created scene graph.
 | ||||
|         osg::Node* load(Nif::NIFFilePtr file, osg::Group* parentNode); | ||||
|         osg::Node* load(Nif::NIFFilePtr file, osg::Group* parentNode, TextKeyMap* textKeys = NULL); | ||||
| 
 | ||||
|         /// Create a scene graph for the given NIF. Assumes skinning will be used.
 | ||||
|         osg::Node* loadAsSkeleton(Nif::NIFFilePtr file, osg::Group* parentNode); | ||||
|         osg::Node* loadAsSkeleton(Nif::NIFFilePtr file, osg::Group* parentNode, TextKeyMap* textKeys = NULL); | ||||
| 
 | ||||
|         /// Load keyframe controllers from the given kf file onto the given scene graph.
 | ||||
|         /// @param sourceIndex The source index for this animation source, used for identifying
 | ||||
|         ///        which animation source a keyframe controller came from.
 | ||||
|         void loadKf(Nif::NIFFilePtr kf, osg::Node* rootNode, int sourceIndex); | ||||
|         void loadKf(Nif::NIFFilePtr kf, osg::Node* rootNode, int sourceIndex, TextKeyMap &textKeys); | ||||
| 
 | ||||
|         const VFS::Manager* resourceManager; | ||||
| 
 | ||||
|  | @ -56,7 +56,7 @@ namespace NifOsg | |||
| 
 | ||||
|         /// @param createSkeleton If true, use an osgAnimation::Bone for NIF nodes, otherwise an osg::MatrixTransform.
 | ||||
|         osg::Node* handleNode(const Nif::Node* nifNode, osg::Group* parentNode, bool createSkeleton, | ||||
|                         std::map<int, int> boundTextures, int animflags, int particleflags, bool collisionNode=false); | ||||
|                         std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys); | ||||
| 
 | ||||
|         void handleMeshControllers(const Nif::Node* nifNode, osg::MatrixTransform* transformNode, const std::map<int, int>& boundTextures, int animflags); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue