最开始设计这个编辑器时,其中一个要求就是能在运行过程中,通过UI来更新各对象,这样我们就能明确每个Ogre对象更新其属性影响的渲染效果.比如点光源,方向光源,聚光灯各属性与效果,深度测试开启与关闭,深度比较方式影响的效果等等.如下先看效果图:

Ogre 编辑器三(自动生成与更新Ogre对象编辑界面)

  这个位置没有用上一篇天龙的场景,主要是图片大小限制,场景复杂后,生成的gif图片太大.

  这个功能当时我主界面完成后,就准备做的,但是当时一时想不到好的方案,如果针对每个Ogre属性来生成UI,然后关联每个对象,再想想后续如果要修改其中的字段属性或是位置,这个工作量让我不得不先想一个方案能够避免这些问题.在完成第二篇天龙场景的加载时,顺便在空闲时间想出现在的这种解决方法,不说这方法好,但是工作量少,简洁,易修改,避免很多BUG.灵活性高,只有二个Ogre之间有关联,就可以显示在一起.如上面的Entity,他显示出他父节点SceneNode,以及他的父类MovableObject的各属性.

  这个方案简单来说,分成三个部分,一个部分主要是XML文件,XML文件包含每个Ogre对象要关联的对象,字段,关联字段等.第二个部分是自动生成控件界面,根据第一部分的信息来生成各个界面.第三部分是根据Ogre对象更新各个控件,以及更新控件上的值更新后反馈给对应Ogre对象.如下是三个部分代码图,VS中C++代码生成的代码关联图中,聚合关系不能显示出来,所以一些聚合信息在上面没有显示出来.

Ogre 编辑器三(自动生成与更新Ogre对象编辑界面)

XML文件与基本类

  这个部分主要有二方面,一方面是XML文件保存的信息,包含每个Ogre对象关联的对象,每个对象更新的字段,字段的项选择,如下图:

 Ogre 编辑器三(自动生成与更新Ogre对象编辑界面)

   然后就是如第一张图中的类OgreStyle,我们可以看到,这个类三个部分都有引用到,也是我们的这解决方法的核心类,这个类是一个树型结构,这个结构在这主要有二个好处,一是容易添加在树型控件里.二是可以得到父节点信息与子节点信息.其中我们设计在删除节点时,所有子节点全删除.如下是OgreStyle代码.

namespace Ogre3DX
{
    typedef std::vector<string> VectorString;
    class OgreStyle;
    typedef std::vector<OgreStyle*> OgreStyleVector;

    class OgreStyle
    {
    public:
        //ResourceType,SceneType
        int type = 0;
        std::string ogreName = "";
        std::string ogreSecond = "";
        std::string ogreText = "";

        OgreStyle* parent = nullptr;
        OgreStyleVector childs;        
    public:
        OgreStyle()
        {
            childs.clear();
        }

        std::string getText()
        {
            if (ogreText.empty())
                return ogreName;
            return ogreText;
        }

        void add(OgreStyle* child)
        {
            if (!check(child))
            {
                throw exception("child is parent.");
            }
            if (child->parent != nullptr)
            {
                auto index = find(child->parent->childs.begin(), child->parent->childs.end(), child);
                child->parent->childs.erase(index);
            }
            child->parent = this;
            childs.push_back(child);
        }

        void remove(OgreStyle* child)
        {
            remove(child, true);
        }

        void removeAll()
        {
            //删除所有子节点
            while (!childs.empty())
            {
                auto child = childs.back();
                childs.pop_back();
                //这句 避免递归时重复delete
                child->parent = nullptr;
                if (child != nullptr)
                {
                    delete child;
                    child = nullptr;
                }
            }
        }

        OgreStyle* findChild(int type)
        {
            if (childs.empty())
                return nullptr;
            for (auto child : this->childs)
            {
                if (child->type == type)
                    return child;
            }
            return nullptr;
        }

        OgreStyle* findChild(std::string name)
        {
            if (childs.empty())
                return nullptr;
            for (auto child : this->childs)
            {
                if (child->ogreName == name)
                    return child;
            }
            return nullptr;
        }

        bool check(OgreStyle* style)
        {
            OgreStyle* parent = this->parent;
            while (parent != nullptr)
            {
                if (parent == style)
                    return false;
                parent = parent->parent;
            }
            return true;
        }

        ~OgreStyle()
        {
            if (parent != nullptr)
                parent->remove(this, false);
            
            //删除所有子节点
            while (!childs.empty())
            {
                auto child = childs.back();
                childs.pop_back();
                //这句 避免递归时重复delete
                child->parent = nullptr;
                if (child != nullptr)
                {
                    delete child;
                    child = nullptr;
                }

            }
        }

    private:
        void remove(OgreStyle* child, bool bDelete)
        {
            if (child->parent != nullptr)
            {
                auto index = find(child->parent->childs.begin(), child->parent->childs.end(), child);
                child->parent->childs.erase(index);
            }
            child->parent = nullptr;
            if (bDelete)
            {
                delete child;
                child = nullptr;
            }
        }
    };
}
OgreStyle

相关文章:

  • 2022-12-23
  • 2021-10-06
  • 2022-01-31
  • 2022-12-23
  • 2022-01-04
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-12-21
  • 2022-01-25
  • 2022-12-23
  • 2022-01-08
  • 2021-05-15
  • 2022-01-27
相关资源
相似解决方案