现在的位置: 首页 > 综合 > 正文

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

2018年01月16日 ⁄ 综合 ⁄ 共 3666字 ⁄ 字号 评论关闭

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”,创建一个网格的实例。

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

抱歉!评论已关闭.