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; }
/* 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); } }
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); } }
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); } }
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); } } }