Subdivisions getSubdivisions() const { IPatchNodePtr patchNode = boost::dynamic_pointer_cast<IPatchNode>(_node.lock()); if (patchNode == NULL) return Subdivisions(); return patchNode->getPatch().getSubdivisions(); }
void createDecals() { for (FaceInstanceList::iterator i = _faceInstances.begin(); i != _faceInstances.end(); ++i) { // Get the winding const Winding& winding = (*i)->getFace().getWinding(); // Create a new decal patch scene::INodePtr patchNode = GlobalPatchCreator(DEF3).createPatch(); if (patchNode == NULL) { gtkutil::errorDialog(_("Could not create patch."), GlobalMainFrame().getTopLevelWindow()); return; } Patch* patch = Node_getPatch(patchNode); assert(patch != NULL); // must not fail // Set the tesselation of that 3x3 patch patch->setDims(3,3); patch->setFixedSubdivisions(true, Subdivisions(1,1)); // Set the coordinates patch->ctrlAt(0,0).vertex = winding[0].vertex; patch->ctrlAt(2,0).vertex = winding[1].vertex; patch->ctrlAt(1,0).vertex = (patch->ctrlAt(0,0).vertex + patch->ctrlAt(2,0).vertex)/2; patch->ctrlAt(0,1).vertex = (winding[0].vertex + winding[3].vertex)/2; patch->ctrlAt(2,1).vertex = (winding[1].vertex + winding[2].vertex)/2; patch->ctrlAt(1,1).vertex = (patch->ctrlAt(0,1).vertex + patch->ctrlAt(2,1).vertex)/2; patch->ctrlAt(2,2).vertex = winding[2].vertex; patch->ctrlAt(0,2).vertex = winding[3].vertex; patch->ctrlAt(1,2).vertex = (patch->ctrlAt(2,2).vertex + patch->ctrlAt(0,2).vertex)/2; // Use the texture in the clipboard, if it's a decal texture Texturable& clipboard = GlobalShaderClipboard().getSource(); if (!clipboard.empty()) { if (clipboard.getShader().find("decals") != std::string::npos) { patch->setShader(clipboard.getShader()); } } // Fit the texture on it patch->SetTextureRepeat(1,1); patch->FlipTexture(1); // Insert the patch into worldspawn scene::INodePtr worldSpawnNode = GlobalMap().getWorldspawn(); assert(worldSpawnNode != NULL); // This must be non-NULL, otherwise we won't have faces worldSpawnNode->addChildNode(patchNode); // Deselect the face instance (*i)->setSelected(SelectionSystem::eFace, false); // Select the patch Node_setSelected(patchNode, true); } }