SmallWord:第一天

来源:互联网 发布:查看网络有几个人用 编辑:程序博客网 时间:2024/06/06 20:39


第二章 虚与实的谐韵


传说,从前有个谁用七天创造了世界,第一天创造了光。Small World里暂时没有光,也没有影,第一天的创建,从简单的实体开始。


在构建实体之前,先粗略的列一下仿真的步骤,能够清晰一下思路:

1.构建实体存储状态信息,如物理参数,空间大小

2.构建一个集合来管理这些物体

3.初始化所有的环境与实体

4.仿真计算物理世界的变化,如施加在物体上的重力

5.计算并更新物理世界,如计算物体的速度,根据仿真时间推进

6.解决仿真过程中发生的问题,如碰撞


有了仿真的大纲,可见实体存放在整个物理世界中,为了方便以后进行碰撞等物理仿真,实体应该组织成一种特殊的结构,如Kd树或是八叉树。所以所有实体由一个EntityTree统一进行管理,也便于以后进行多线程或是GPU加速。实体定义为一个抽象类Entity。由Entity派生出物理世界中各种的子类。为了满足系统对不同物体仿真的需求。定义一下几种基本实体:RigidEntity,最传统的刚体;SoftEntity,软体,如史莱姆形状的物体;HydroEntity,流体,如水流,烟等;StaticEntity,静态物体,如大地。目前不考虑可粉碎,可分裂的物体。因为物理仿真中物体的基本属性是形状,而不同类型的物体可能有相同的形状,所以定义了Entity的一个属性Body,Body的子类有如BoxBody,方形或是PolyBody,多变形(二维),多面体(三维)。Entity与Body之间的关系如下图所示:



Entity包含需要识别的oID,实体形状body和一个可以屏蔽实体属性的标示simMask以及移动的函数:

class Entity{public:Entity(SWID id = ""):simMask(NOMASK),oID(id),body(NULL){}virtual ~Entity(void){if (body != NULL) delete body;}virtual bool operator != (Entity& entity) const{return oID.compare(entity.getID()) != 0;}virtual void  transform(Transform& trans){body->transform(trans);}virtual bool  isMask(int mask){ return (mask & simMask) != NOMASK;} virtual void  setMask(int mask){simMask |= mask;}virtual SWID  getID(){return oID;}virtual Body* getBody(){return body;}virtual AABB  getAABB(){return body->getAABB();}protected:SWID oID;int simMask;Body *body;};

同样对于Body,包括质量,速度等属性,用于之后物体相互作用。

class Body{public:Body(){}~Body(void){}virtual void transform(Transform & trans) = 0;virtual AABB getAABB() = 0;virtual DirectSpeed getSpeed() = 0;virtual double getMass() = 0;};

至于EntityTree,目前就以vector来保存所有Entity,通过全局函数:

Entity* swGetEntity(SWID wid, SWID oid);void swRegisteEntity(SWID wid, Entity *obj);

void swd::swRegisteEntity(SWID wid, Entity *obj){ szSmallWorlds[wid]->registe(obj);}
bool SmallWorld::registe(Entity *obj){entityTree.add(obj);return true;}
void EntityTree::add(Entity *obj){entitys.push_back(obj);}

向ID为wid的物理世界中的EntityTree注册(push_back)实体,每个实体通过上一篇介绍的swUpdateWorld更新各个实体。

void SmallWorld::updateEntitys(){entityTree.update(timer);}void EntityTree::update(Timer &timer){for(unsigned i = 0; i < entitys.size(); ++i){entitys[i]->...}}

第一天过后,这样简单的实体就加入到整个仿真的循环当中了,不过现在还没有实现任何功能,下一篇就是要能够对每个实体施加物理操作,如重力,摩擦力等。


原创粉丝点击