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