• 深入解析OGRE实体的创建流程


      OGRE中一个实体是可以在场景中渲染的物体之一。您可以把实体理解为任何一个3D模型。一个机器人可以是一个实体,一条鱼可以是一个实体,大地草原可以是一个非常大的实体。灯光,摄像机,粒子,广告牌等不能成为实体。但在 Ogre 中你不能够直接将一个实体放入到场景中,而是将实体与场景节点绑在一起,这个场景节点则包括了实体的方位信息,这是OGRE WIKI上对实体的实质描述。实体的创建是通过调用场景管理器来创建的,假设创建一下代码如下:

      Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" ); //创建一个名字为Robot,使用网格robot.mesh

          下面一步一步的解析createEntity是怎么最后达到创建一个ogre中的实体的。

       1.Root类是OGRE系统最重要,最核心的总控制类,类似CEGUI中的System类,也是一个的单例类,在整OGRE系统中只存在一个Root实例。在任何OGRE的其他操作之前必须先创建Root实例。OGRE中采用的抽象工厂模式,通过相应工厂类对象来创建相应的类型对象,在Root类的构造函数有这么一段代码:

     // instantiate and register base movable factories
      mEntityFactory = OGRE_NEW EntityFactory();
      addMovableObjectFactory(mEntityFactory);
      创建了一个实体工厂对象,后续实体的创建就是通过这个工厂类进行创建。  下面代码是EntityFactory类的定义:

      

    /** Factory object for creating Entity instances */
     class _OgreExport EntityFactory : public MovableObjectFactory
     {
     protected:
        MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params);
     public:
        EntityFactory() {}
        ~EntityFactory() {}

        static String FACTORY_TYPE_NAME;

        const String& getType(void) const;
        void destroyInstance( MovableObject* obj);

     };

     String EntityFactory::FACTORY_TYPE_NAME = "Entity";

    FACTORY_TYPE_NAME 静态成员变量用于记录该工厂的类型为"Entity".

    2.应用程序通过调用场景管理器类SceneManager的CreateEntity创建实体实例,代码如下:

         

    Entity* SceneManager::createEntity(
                                       const String& entityName,
                                       const String& meshName )
    {
     // delegate to factory implementation
     NameValuePairList params;
     params["mesh"] = meshName;
     return static_cast<Entity*>(
      createMovableObject(entityName, EntityFactory::FACTORY_TYPE_NAME,
       &params));

    }

    NameValuePairList 是一个map类型,键值对是 ("mesh",网格文件名)定义如下:

    /// Name / value parameter pair (first = name, second = value)
     typedef std::map<String, String> NameValuePairList;

      该方法最后是调用createMovableObject方法,实定义如下:

    MovableObject* SceneManager::createMovableObject(const String& name,
     const String& typeName, const NameValuePairList* params)
    {
     // Nasty hack to make generalised Camera functions work without breaking add-on SMs
     if (typeName == "Camera")
     {
      return createCamera(name);
     }
     MovableObjectFactory* factory =
      Root::getSingleton().getMovableObjectFactory(typeName);
     // Check for duplicate names
     MovableObjectCollection* objectMap = getMovableObjectCollection(typeName);

     {
      OGRE_LOCK_MUTEX(objectMap->mutex)

      if (objectMap->map.find(name) != objectMap->map.end())
      {
       OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
        "An object of type '" + typeName + "' with name '" + name
        + "' already exists.",
        "SceneManager::createMovableObject");
      }

      MovableObject* newObj = factory->createInstance(name, this, params);
      objectMap->map[name] = newObj;
      return newObj;
     }

    }

     其中MovableObjectFactory* factory = Root::getSingleton().getMovableObjectFactory(typeName);,就是通过传入的“Entity”类型,获得相应实体工厂类(EntityFactory),然后通过工厂类的方法创建相应的实例对象:MovableObject* newObj = factory->createInstance(name, this, params);。

    MovableObject是一个抽象类,所以有可移动的实体对象都要继承于它,看一下Entity类的定义:

    class _OgreExport Entity: public MovableObject, public Resource::Listener

    ...省略..

    };

     同样的,MovableObjectFactory也是所有可移动对象工厂的基类,上面列出的EntityFactory类的定义就是继承MovableObjectFactory。

    通过调用工厂类的createInstance方法,该方法调用具体工厂类的createInstanceImpl来创建一下实体,代码如下:

    MovableObject* EntityFactory::createInstanceImpl( const String& name,
      const NameValuePairList* params)
     {
      // must have mesh parameter
      MeshPtr pMesh;
      if (params != 0)
      {
       NameValuePairList::const_iterator ni = params->find("mesh");
       if (ni != params->end())
       {
        // Get mesh (load if required)
        pMesh = MeshManager::getSingleton().load(
         ni->second,
         // autodetect group location
         ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME );
       }

      }
      if (pMesh.isNull())
      {
       OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
        "'mesh' parameter required when constructing an Entity.",
        "EntityFactory::createInstance");
      }

      return OGRE_NEW Entity(name, pMesh);

     }

     MeshManager::getSingleton().load,就是载入相应的网格文件“robot.mesh”,创建一个网格的实例。

     至此,一个实体对象的创建流程大概就是这样。

  • 相关阅读:
    windows7下检测耳机麦克拔插(转)
    windows实时监测热插拔设备的变化(转)
    Windows ToolTips简要介绍(转)
    c /c++变参函数(转)
    SQL的四种连接查询(转)
    CRichEditCtrl 输入字符串长度限制
    MFC 将 '当前工作路径' 改为 'exe所在路径'(转)
    第5章 文本编程
    第4章 简单绘图
    VC++中有关句柄和指针及其转换(转)
  • 原文地址:https://www.cnblogs.com/kundij/p/2431773.html
Copyright © 2020-2023  润新知