Пример #1
0
void stitchTextures(const cmd::ArgumentList& args)
{
	// Get all the selected patches
	PatchPtrVector patchList = selection::algorithm::getSelectedPatches();

	if (patchList.size() == 2)
	{
		UndoableCommand undo("patchStitchTexture");

		// Fetch the instances from the selectionsystem
		const scene::INodePtr& targetNode =
			GlobalSelectionSystem().ultimateSelected();

		const scene::INodePtr& sourceNode =
			GlobalSelectionSystem().penultimateSelected();

		// Cast the instances onto a patch
		Patch* source = Node_getPatch(sourceNode);
		Patch* target = Node_getPatch(targetNode);

		if (source != NULL && target != NULL) {
			// Stitch the texture leaving the source patch intact
			target->stitchTextureFrom(*source);
		}
		else {
			gtkutil::MessageBox::ShowError(_("Cannot stitch textures. \nCould not cast nodes to patches."),
							 GlobalMainFrame().getTopLevelWindow());
		}

		SceneChangeNotify();
		// Update the Texture Tools
		ui::SurfaceInspector::update();
	}
	else
	{
		gtkutil::MessageBox::ShowError(_("Cannot stitch patch textures. \nExactly 2 patches must be selected."),
							 GlobalMainFrame().getTopLevelWindow());
	}
}
Пример #2
0
void constructPrefab(const AABB& aabb, const std::string& shader, EPatchPrefab eType, 
					 EViewType viewType, std::size_t width, std::size_t height)
{
	GlobalSelectionSystem().setSelectedAll(false);

	scene::INodePtr node(GlobalPatchCreator(DEF2).createPatch());
	GlobalMap().findOrInsertWorldspawn()->addChildNode(node);

	Patch* patch = Node_getPatch(node);
	patch->setShader(shader);

	patch->ConstructPrefab(aabb, eType, viewType, width, height);
	patch->controlPointsChanged();

	Node_setSelected(node, true);
}
// This is called if the selection changes, so that the local list of selected nodes can be updated
void RadiantSelectionSystem::onSelectedChanged(const scene::INodePtr& node, const Selectable& selectable) {

    // Cache the selection state
    bool isSelected = selectable.isSelected();
    int delta = isSelected ? +1 : -1;

    _countPrimitive += delta;
    _sigSelectionChanged(selectable);

    _selectionInfo.totalCount += delta;

    if (Node_getPatch(node) != NULL) {
        _selectionInfo.patchCount += delta;
    }
    else if (Node_getBrush(node) != NULL) {
        _selectionInfo.brushCount += delta;
    }
    else {
        _selectionInfo.entityCount += delta;
    }

    // If the selectable is selected, add it to the local selection list, otherwise remove it
    if (isSelected) {
        _selection.append(node);
    }
    else {
        _selection.erase(node);
    }

    // Notify observers, FALSE = primitive selection change
    notifyObservers(node, false);

    // Check if the number of selected primitives in the list matches the value of the selection counter
    ASSERT_MESSAGE(_selection.size() == _countPrimitive, "selection-tracking error");

    // Schedule an idle callback
    requestIdleCallback();

    _requestWorkZoneRecalculation = true;
    _requestSceneGraphChange = true;
}
Пример #4
0
Patch& getLastSelectedPatch() {
	if (GlobalSelectionSystem().getSelectionInfo().totalCount > 0 &&
		GlobalSelectionSystem().getSelectionInfo().patchCount > 0)
	{
		// Retrieve the last selected instance
		const scene::INodePtr& node = GlobalSelectionSystem().ultimateSelected();
		// Try to cast it onto a patch
		Patch* patch = Node_getPatch(node);
				
		// Return or throw
		if (patch != NULL) {
			return *patch;
		}
		else {
			throw selection::InvalidSelectionException(_("No patches selected."));
		}
	}
	else {
		throw selection::InvalidSelectionException(_("No patches selected."));
	}
}
Пример #5
0
void createCaps(Patch& patch, const scene::INodePtr& parent, EPatchCap type, const std::string& shader)
{
	if ((type == eCapEndCap || type == eCapIEndCap) && patch.getWidth() != 5)
	{
		rError() << "cannot create end-cap - patch width != 5" << std::endl;

		gtkutil::MessageBox::ShowError(_("Cannot create end-cap, patch must have a width of 5."),
			GlobalMainFrame().getTopLevelWindow());

		return;
	}

	if ((type == eCapBevel || type == eCapIBevel) && patch.getWidth() != 3)
	{
		gtkutil::MessageBox::ShowError(_("Cannot create bevel-cap, patch must have a width of 3."),
			GlobalMainFrame().getTopLevelWindow());

		rError() << "cannot create bevel-cap - patch width != 3" << std::endl;
		return;

	}

	if (type == eCapCylinder && patch.getWidth() != 9)
	{
		gtkutil::MessageBox::ShowError(_("Cannot create cylinder-cap, patch must have a width of 9."),
			GlobalMainFrame().getTopLevelWindow());

		rError() << "cannot create cylinder-cap - patch width != 9" << std::endl;
		return;
	}

	assert(parent != NULL);

	{
		scene::INodePtr cap(GlobalPatchCreator(DEF2).createPatch());
		parent->addChildNode(cap);

		Patch* capPatch = Node_getPatch(cap);
		assert(capPatch != NULL);

		patch.MakeCap(capPatch, type, ROW, true);
		capPatch->setShader(shader);

		// greebo: Avoid creating "degenerate" patches (all vertices merged in one 3D point)
		if (!capPatch->isDegenerate())
		{
			Node_setSelected(cap, true);
		}
		else
		{
			parent->removeChildNode(cap);
			rWarning() << "Prevented insertion of degenerate patch." << std::endl;
		}
	}

	{
		scene::INodePtr cap(GlobalPatchCreator(DEF2).createPatch());
		parent->addChildNode(cap);

		Patch* capPatch = Node_getPatch(cap);
		assert(capPatch != NULL);

		patch.MakeCap(capPatch, type, ROW, false);
		capPatch->setShader(shader);

		// greebo: Avoid creating "degenerate" patches (all vertices merged in one 3D point)
		if (!capPatch->isDegenerate())
		{
			Node_setSelected(cap, true);
		}
		else
		{
			parent->removeChildNode(cap);
			rWarning() << "Prevented insertion of degenerate patch." << std::endl;
		}
	}
}
Пример #6
0
void thicken(const PatchNodePtr& sourcePatch, float thickness, bool createSeams, int axis)
{
	// Get a shortcut to the patchcreator
	PatchCreator& patchCreator = GlobalPatchCreator(DEF2);

	// Create a new patch node
	scene::INodePtr node(patchCreator.createPatch());

	scene::INodePtr parent = sourcePatch->getParent();
	assert(parent != NULL);

	// Insert the node into the same parent as the existing patch
	parent->addChildNode(node);

	// Retrieve the contained patch from the node
	Patch* targetPatch = Node_getPatch(node);

	// Create the opposite patch with the given thickness = distance
	targetPatch->createThickenedOpposite(sourcePatch->getPatchInternal(), thickness, axis);

	// Select the newly created patch
	Node_setSelected(node, true);

	if (createSeams && thickness > 0.0f)
	{
		// Allocate four new patches
		scene::INodePtr nodes[4] = {
			patchCreator.createPatch(),
			patchCreator.createPatch(),
			patchCreator.createPatch(),
			patchCreator.createPatch()
		};

		// Now create the four walls
		for (int i = 0; i < 4; i++)
		{
			// Insert each node into the same parent as the existing patch
			// It's vital to do this first, otherwise these patches won't have valid shaders
			parent->addChildNode(nodes[i]);

			// Retrieve the contained patch from the node
			Patch* wallPatch = Node_getPatch(nodes[i]);

			// Create the wall patch by passing i as wallIndex
			wallPatch->createThickenedWall(sourcePatch->getPatchInternal(), *targetPatch, i);

			if (!wallPatch->isDegenerate())
			{
				// Now select the newly created patch
				Node_setSelected(nodes[i], true);
			}
			else
			{
				rMessage() << "Thicken: Discarding degenerate patch." << std::endl;

				// Remove again
				parent->removeChildNode(nodes[i]);
			}
		}
	}

	// Invert the target patch so that it faces the opposite direction
	targetPatch->InvertMatrix();
}
Пример #7
0
	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);
		}
	}
Пример #8
0
 void Patch_setShader(scene::Node& patch, const char* shader) const
 {
   Node_getPatch(patch)->SetShader(shader);
 }
Пример #9
0
 const char* Patch_getShader(scene::Node& patch) const
 {
   return Node_getPatch(patch)->GetShader();
 }
Пример #10
0
 void Patch_controlPointsChanged(scene::Node& patch) const
 {
   return Node_getPatch(patch)->controlPointsChanged();
 }
Пример #11
0
 PatchControlMatrix Patch_getControlPoints(scene::Node& node) const
 {
   Patch& patch = *Node_getPatch(node);
   return PatchControlMatrix(patch.getHeight(), patch.getWidth(), patch.getControlPoints().data());
 }
Пример #12
0
 void Patch_resize(scene::Node& patch, std::size_t width, std::size_t height) const
 {
   Node_getPatch(patch)->setDims(width, height);
 }
Пример #13
0
 void Patch_undoSave(scene::Node& patch) const
 {
   Node_getPatch(patch)->undoSave();
 }