void InfoFileExporter::visit(const scene::INodePtr& node)
{
    // Don't export the layer settings for models and particles, as they are not there
    // at map load/parse time - these shouldn't even be passed in here
    assert(node && !Node_isModel(node) && !particles::isParticleNode(node));

    // Open a Node block
    _stream << "\t\t" << InfoFile::NODE << " { ";

    scene::LayerList layers = node->getLayers();

    // Write a space-separated list of node IDs
    for (scene::LayerList::const_iterator i = layers.begin(); i != layers.end(); ++i)
    {
        _stream << *i << " ";
    }
    
    // Close the Node block
    _stream << "}";

    // Write additional node info, for easier debugging of layer issues
    _stream << " // " << getNodeInfo(node);

    _stream << std::endl;

    _layerInfoCount++;
}
void BrushByPlaneClipper::visit(const scene::INodePtr& node) const
{
	// Don't clip invisible nodes
	if (!node->visible())
	{
		return;
	}

	// Try to cast the instance onto a brush
	Brush* brush = Node_getBrush(node);

	// Return if not brush
	if (brush == NULL)
	{
		return;
	}

	Plane3 plane(_p0, _p1, _p2);

	if (!plane.isValid())
	{
		return;
	}

	// greebo: Analyse the brush to find out which shader is the most used one
	getMostUsedTexturing(*brush);

	BrushSplitType split = Brush_classifyPlane(*brush, _split == eFront ? -plane : plane);

	if (split.counts[ePlaneBack] && split.counts[ePlaneFront])
	{
		// the plane intersects this brush
		if (_split == eFrontAndBack)
		{
			scene::INodePtr fragmentNode = GlobalBrushCreator().createBrush();

			// greebo: For copying the texture scale the new node needs a valid rendersystem
			fragmentNode->setRenderSystem(node->getRenderSystem());

			assert(fragmentNode != NULL);

			Brush* fragment = Node_getBrush(fragmentNode);
			assert(fragment != NULL);
			fragment->copy(*brush);

			// Put the fragment in the same layer as the brush it was clipped from
			scene::assignNodeToLayers(fragmentNode, node->getLayers());

			FacePtr newFace = fragment->addPlane(_p0, _p1, _p2, _mostUsedShader, _mostUsedProjection);

			if (newFace != NULL && _split != eFront)
			{
				newFace->flipWinding();
			}

			fragment->removeEmptyFaces();
			ASSERT_MESSAGE(!fragment->empty(), "brush left with no faces after split");

			// Mark this brush for insertion
			_insertList.insert(InsertMap::value_type(fragmentNode, node->getParent()));
		}

		FacePtr newFace = brush->addPlane(_p0, _p1, _p2, _mostUsedShader, _mostUsedProjection);

		if (newFace != NULL && _split == eFront) {
			newFace->flipWinding();
		}

		brush->removeEmptyFaces();
		ASSERT_MESSAGE(!brush->empty(), "brush left with no faces after split");
	}
	// the plane does not intersect this brush
	else if (_split != eFrontAndBack && split.counts[ePlaneBack] != 0)
	{
		// the brush is "behind" the plane
		_deleteList.insert(node);
	}
}
Exemple #3
0
	void post(const scene::INodePtr& node) {
		if (!node->visible()) {
			return;
		}

		Brush* brush = Node_getBrush(node);

		if (brush != NULL && !Node_isSelected(node))
		{
			BrushNodePtr brushNode = std::dynamic_pointer_cast<BrushNode>(node);

			// Get the parent of this brush
			scene::INodePtr parent = node->getParent();
			assert(parent != NULL); // parent should not be NULL

			BrushPtrVector buffer[2];
			std::size_t swap = 0;

			BrushNodePtr original = std::dynamic_pointer_cast<BrushNode>(brushNode->clone());

			//Brush* original = new Brush(*brush);
			buffer[swap].push_back(original);

			// Iterate over all selected brushes
			for (BrushPtrVector::const_iterator i(_brushlist.begin()); i != _brushlist.end(); ++i)
			{
				for (BrushPtrVector::iterator j(buffer[swap].begin());
					 j != buffer[swap].end(); ++j)
				{
					if (Brush_subtract(*j, (*i)->getBrush(), buffer[1 - swap]))
					{
						// greebo: Delete not necessary, nodes get deleted automatically by clear() below
						// delete (*j);
					}
					else
					{
						buffer[1 - swap].push_back(*j);
					}
				}

				buffer[swap].clear();
				swap = 1 - swap;
			}

			BrushPtrVector& out = buffer[swap];

			if (out.size() == 1 && out.back() == original)
			{
				// greebo: shared_ptr is taking care of this
				//delete original;
			}
			else
			{
				_before++;

				for (BrushPtrVector::const_iterator i = out.begin(); i != out.end(); ++i)
				{
					_after++;

					scene::INodePtr newBrush = GlobalBrushCreator().createBrush();

					parent->addChildNode(newBrush);

					// Move the new Brush to the same layers as the source node
					newBrush->assignToLayers(node->getLayers());

					(*i)->getBrush().removeEmptyFaces();
					ASSERT_MESSAGE(!(*i)->getBrush().empty(), "brush left with no faces after subtract");

					Node_getBrush(newBrush)->copy((*i)->getBrush());
				}

			    _deleteList.push_back(node);
			}
		}
	}