예제 #1
0
	bool pre(const scene::INodePtr& node) {
		// Don't traverse hidden nodes
		if (!node->visible()) {
			return false;
		}
		
		SelectablePtr selectable = Node_getSelectable(node);

		// ignore worldspawn
		Entity* entity = Node_getEntity(node);
		if (entity != NULL) {
			if (entity->getKeyValue("classname") == "worldspawn") {
				return true;
			}
		}
    
    	bool selected = false;
    
		if (selectable != NULL && node->getParent() != NULL && !node->isRoot()) {
			for (std::size_t i = 0; i < _count; ++i) {
				// Check if the selectable passes the AABB test
				if (policy.evaluate(_aabbs[i], node)) {
					selectable->setSelected(true);
					selected = true;
					break;
				}
			}
		}
	
		// Only traverse the children of this node, if the node itself couldn't be selected
		return !selected;
	}
예제 #2
0
    /* SelectionSystem::Visitor implementation */
	void visit(const scene::INodePtr& node) const 
    {
		// Check for selected nodes whose parent is not NULL and are not root
		if (node->getParent() != NULL && !node->isRoot()) 
        {
			// Found a candidate
			_eraseList.insert(node);
		}
	}
예제 #3
0
	void post(const scene::INodePtr& node)
	{
		if (node->isRoot())
		{
			return;
		}

		if (Node_isSelected(node))
		{
			// Clone the current node
			scene::INodePtr clone = map::Node_Clone(node);

			// Add the cloned node and its parent to the list
			_cloned.insert(Map::value_type(clone, node->getParent()));

			// Insert this node in the root
			_cloneRoot->addChildNode(clone);
		}
	}
예제 #4
0
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 brushNode = GlobalBrushCreator().createBrush();

			assert(brushNode != NULL);

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

			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(brushNode, 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);
	}
}
예제 #5
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);
			}
		}
	}