本节主要内容
- 粒子实例创建的情形
- 如何创建粒子实例
- 粒子实例的更新
实例创建的情形
在粒子系统中,一般来说有如下需要创建粒子实例的场景:
- 根据粒子的发射速率创建粒子并发射
- 父粒子创建子粒子
- 碰撞产生粒子
以1-1效果为例,是一个拖尾效果,每个父节点的实例粒子都有两个拖尾。在该效果中涉及到的主要实例类如下所示
图1-1所示,包含了1,2情况。白色圆点是普通发射粒子,红色和蓝色为父粒子创建的拖尾子粒子。碰撞粒子暂不纳入考虑范围,因为这个系统暂时还没有做物理的碰撞检测之类的。。。。。。
如何创建粒子实例
1,effekseer粒子系统中为了节省时间开销对粒子实例Intance对象做了两种处理,分别将其物理内存管理与逻辑管理进行分离。通过预先创建大内存块来降低粒子创建开销,通过树结构+链表结构来维护粒子状态。
2,构建了一个空的rootIntance对象,将第一种粒子产生的情况变成了第二种父粒子产生子粒子的情况。
其中Intancechunk表示所有实例的物理内存区域;而IntanceContainer和IntanceGroup构成了实例的逻辑区域。IntanceGroup与IntanceContainer负责粒子实例的逻辑渲染以及update,Intancechunk负责粒子实例的构建及析构。每次建立manager时,会首先创建一个超大内存块(20*max粒子数量),也就是IntanceChunks,之后由manager管理器调用update时,通过逻辑结构对全部涉及到的实例进行更新(状态,位置,大小,生命周期变化等)
rootIntance实例对象
属于root节点,不进行渲染
intanceGlobal实例对象
实例通用对象,记录当前效果的粒子总数,当前帧,root容器等
childGroups组对象
在Intance对象中存在一个childGroups的组对象。其主要维护的是子实例对象所构成的链表(即只有当存在父子节点关系时该成员才有意义)下图简单抽象了图1-1效果中的父子结构关系,并对childGroups对象进行了简单说明
图1-3绿色框表示某一个小圆点的拖尾实例构成的组(其所有的拖尾实例均在该组中,也即是说拖尾效果中的spawnCount就是该组最大实例容量,这个拖尾实例组链表是再父实例构建时创建的)。红色箭头指示的链表表示的是intance的childgroup中的nextusedbyIntance链表,蓝色箭头表示的是intance的childgroup中的nextusedbyContainer链表。
在intance的构建中,其通过遍历节点全部的子节点来创建属于自己的子组链表(childGroups),通过调用子节点对应的容器来创建组,可以将创建好的组同时放入到容器所包含的实例组链表中
Instance::Instance(Manager* pManager, EffectNode* pEffectNode, InstanceContainer* pContainer, InstanceGroup* pGroup)
{
.....
InstanceGroup* group = NULL;
for( int i = 0; i < m_pEffectNode->GetChildrenCount(); i++ )
{
InstanceContainer* childContainer = m_pContainer->GetChild( i );
if( group != NULL )
{
group->NextUsedByInstance = childContainer->CreateInstanceGroup();
group = group->NextUsedByInstance;
}
else
{
group = childContainer->CreateInstanceGroup();
childrenGroups_ = group;
}
}
......
}
粒子实例的更新
主要包括(顶点位置,UV,color)信息更新。
1.初始化更新
void Instance::Initialize( Instance* parent, int32_t instanceNumber, int32_t parentTime, const Mat43f& globalMatrix){
初始化父粒子
状态设为INSTANCE_STATE_ACTIVE
已存在时间=0;
生命周期根据配置计算;
SRT矩阵
}
2.定期更新
网友评论