예제 #1
0
void SpritePackerHelper::EnumerateSpritesForParticleEmitter(ParticleEmitter* emitter, Map<String, Sprite *> &sprites)
{
	if (!emitter)
	{
		return;
	}
	
	Vector<ParticleLayer*> & layers = emitter->GetLayers();
	int32 layersCount = layers.size();
	for (int il = 0; il < layersCount; ++il)
	{
		ParticleLayer* curLayer = layers[il];
		Sprite *sprite = curLayer->GetSprite();
		if (sprite)
		{
			sprites[sprite->GetRelativePathname().GetAbsolutePathname()] = sprite;
		}
		
		// Superemitter layers might have inner emitter with its own sprites.
		if (curLayer->GetInnerEmitter())
		{
			EnumerateSpritesForParticleEmitter(curLayer->GetInnerEmitter(), sprites);
		}
	}
}
void ParticlesEditorSceneModelHelper::SynchronizeInnerEmitterNode(LayerParticleEditorNode* node,
																  SceneGraphItem* layerNodeItem,
																  SceneGraphModel* sceneGraphModel)
{
	if (!node)
    {
        return;
    }
    
    ParticleLayer* layer = node->GetLayer();
    if (!layer)
    {
        return;
    }

	ParticleEmitter* innerEmitter = layer->GetInnerEmitter();
	int32 innerEmittersCountInLayerNode = node->GetInnerEmittersCount();
	
	bool needAddInnerEmitter = ((layer->type == ParticleLayer::TYPE_SUPEREMITTER_PARTICLES) &&
								innerEmitter &&
								(innerEmittersCountInLayerNode == 0));
	
	if (needAddInnerEmitter)
	{
		// There is inner emitter defined, but it doesn't exist in the Layer.
		// Need to add it.
		InnerEmitterParticleEditorNode* innerEmitterEditorNode = new InnerEmitterParticleEditorNode(node);
		
		node->AddNode(innerEmitterEditorNode);

		// Also update the Scene Graph, if requested.
		if (layerNodeItem && sceneGraphModel)
		{
			SceneGraphItem* childItem = new SceneGraphItem();
			childItem->SetExtraUserData(innerEmitterEditorNode);
			sceneGraphModel->AddNodeToTree(layerNodeItem, childItem);
		}

		return;
	}

	bool needRemoveInnerEmitter = ((layer->type != ParticleLayer::TYPE_SUPEREMITTER_PARTICLES &&
									innerEmittersCountInLayerNode > 0));
	if (needRemoveInnerEmitter)
	{
		// Update the Scene Graph, if needed.
		if (layerNodeItem && sceneGraphModel)
		{
			int childrenCount = layerNodeItem->ChildrenCount();
			List<GraphItem*> childItemsToRemove;

			// Two-step pass is needed - first one is to find all the children to remove,
			// second one is to do actual remove.
			for (int i = 0; i < childrenCount; i ++)
			{
				GraphItem* childItem = layerNodeItem->Child(i);
				SceneGraphItem* childSceneGraphItem = dynamic_cast<SceneGraphItem*>(childItem);
				ExtraUserData* extraUserData = childSceneGraphItem->GetExtraUserData();

				if (childSceneGraphItem && extraUserData &&
					dynamic_cast<InnerEmitterParticleEditorNode*>(extraUserData))
				{
					childItemsToRemove.push_back(childItem);
				}
			}

			for (List<GraphItem*>::iterator iter = childItemsToRemove.begin();
				 iter != childItemsToRemove.end(); iter ++)
			{
				GraphItem* childItem = (*iter);
				sceneGraphModel->RemoveNodeFromTree(layerNodeItem, childItem);
			}
		}

		// AFTER the Scene Graph was updated - do the actual remove.
		BaseParticleEditorNode::PARTICLEEDITORNODESLIST nodesToRemove;
		for (BaseParticleEditorNode::PARTICLEEDITORNODESLIST::const_iterator iter = node->GetChildren().begin();
			 iter != node->GetChildren().end(); iter ++)
		{
			if (dynamic_cast<InnerEmitterParticleEditorNode*>(*iter))
			{
				nodesToRemove.push_back(*iter);
			}
		}
		
		for (BaseParticleEditorNode::PARTICLEEDITORNODESLIST::iterator removeIter = nodesToRemove.begin();
			 removeIter != nodesToRemove.end(); removeIter ++)
		{
			node->RemoveNode(*removeIter);
		}
	}
}