コード例 #1
0
ファイル: CSG.cpp プロジェクト: BielBdeLuna/DarkRadiant
void mergeSelectedBrushes(const cmd::ArgumentList& args)
{
	// Get the current selection
	BrushPtrVector brushes = selection::algorithm::getSelectedBrushes();

	if (brushes.empty()) {
		rMessage() << _("CSG Merge: No brushes selected.") << std::endl;
		wxutil::Messagebox::ShowError(_("CSG Merge: No brushes selected."));
		return;
	}

	if (brushes.size() < 2) {
		rMessage() << "CSG Merge: At least two brushes have to be selected.\n";
		wxutil::Messagebox::ShowError("CSG Merge: At least two brushes have to be selected.");
		return;
	}

	rMessage() << "CSG Merge: Merging " << brushes.size() << " brushes." << std::endl;

	UndoableCommand undo("mergeSelectedBrushes");

	// Take the last selected node as reference for layers and parent
	scene::INodePtr merged = GlobalSelectionSystem().ultimateSelected();

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

	// Create a new BrushNode
	scene::INodePtr node = GlobalBrushCreator().createBrush();

	// Insert the newly created brush into the (same) parent entity
	parent->addChildNode(node);

	// Move the new brush to the same layers as the merged one
	node->assignToLayers(merged->getLayers());

	// Get the contained brush
	Brush* brush = Node_getBrush(node);

	// Attempt to merge the selected brushes into the new one
	if (!Brush_merge(*brush, brushes, true))
	{
		rWarning() << "CSG Merge: Failed - result would not be convex." << std::endl;
		return;
	}

	ASSERT_MESSAGE(!brush->empty(), "brush left with no faces after merge");

	// Remove the original brushes
	for (BrushPtrVector::iterator i = brushes.begin(); i != brushes.end(); ++i)
	{
		scene::removeNodeFromParent(*i);
	}

	// Select the new brush
	Node_setSelected(node, true);

	rMessage() << "CSG Merge: Succeeded." << std::endl;
	SceneChangeNotify();
}
コード例 #2
0
void surroundWithMonsterclip(const cmd::ArgumentList& args)
{
	UndoableCommand command("addMonsterclip");	

	// create a ModelFinder and retrieve the modelList
	selection::algorithm::ModelFinder visitor;
	GlobalSelectionSystem().foreachSelected(visitor);

	// Retrieve the list with all the found models from the visitor
	selection::algorithm::ModelFinder::ModelList list = visitor.getList();
	
	selection::algorithm::ModelFinder::ModelList::iterator iter;
	for (iter = list.begin(); iter != list.end(); ++iter)
	{
		// one of the models in the SelectionStack
		const scene::INodePtr& node = *iter;

		// retrieve the AABB
		AABB brushAABB(node->worldAABB());

		// create the brush
		scene::INodePtr brushNode(GlobalBrushCreator().createBrush());

		if (brushNode != NULL) {
			scene::addNodeToContainer(brushNode, GlobalMap().findOrInsertWorldspawn());
			
			Brush* theBrush = Node_getBrush(brushNode);

			std::string clipShader = GlobalRegistry().get(RKEY_MONSTERCLIP_SHADER);

			Scene_BrushResize(*theBrush, brushAABB, clipShader);
		}
	}
}
コード例 #3
0
ファイル: shapes.cpp プロジェクト: clbr/netradiant
void AddFaceWithTexture(scene::Node& brush, vec3_t va, vec3_t vb, vec3_t vc, const char* texture, bool detail)
{
	_QERFaceData faceData;
	FillDefaultTexture(&faceData, va, vb, vc, texture);
	if(detail)
		faceData.contents |= FACE_DETAIL;
  GlobalBrushCreator().Brush_addFace(brush, faceData);
}
コード例 #4
0
ファイル: shapes.cpp プロジェクト: clbr/netradiant
void Build_StairStep(vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, int direction)
{
  NodeSmartReference newBrush(GlobalBrushCreator().createBrush());

	//----- Build Outer Bounds ---------

	vec3_t v1, v2, v3, v5, v6, v7;
	VectorCopy(min, v1);
	VectorCopy(min, v2);
	VectorCopy(min, v3);
	VectorCopy(max, v5);
	VectorCopy(max, v6);
	VectorCopy(max, v7);

	v2[0] = max[0];
	v3[1] = max[1];

	v6[0] = min[0];
	v7[1] = min[1];

	//----------------------------------

	AddFaceWithTexture(newBrush, v6, v5, v7, mainTexture, false);
	// top gets current texture


	if(direction == MOVE_EAST)
		AddFaceWithTexture(newBrush, v1, v3, v6, riserTexture, false);
	else
		AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", false);
	// west facing side, etc...

	
	if(direction == MOVE_NORTH)
		AddFaceWithTexture(newBrush, v1, v7, v2, riserTexture, false);
	else
		AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", false);

	if(direction == MOVE_SOUTH)
		AddFaceWithTexture(newBrush, v3, v5, v6, riserTexture, false);
	else
		AddFaceWithTexture(newBrush, v3, v5, v6, "textures/common/caulk", false);
	
	if(direction == MOVE_WEST)
		AddFaceWithTexture(newBrush, v7, v5, v2, riserTexture, false);
	else
		AddFaceWithTexture(newBrush, v7, v5, v2, "textures/common/caulk", false);


	AddFaceWithTexture(newBrush, v1, v2, v3, "textures/common/caulk", false);
	// base is caulked

	Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(newBrush);
	// finish brush
}
コード例 #5
0
ファイル: shapes.cpp プロジェクト: clbr/netradiant
void AddFaceWithTextureScaled(scene::Node& brush, vec3_t va, vec3_t vb, vec3_t vc, 
							  const char* texture, bool bVertScale, bool bHorScale, 
							  float minX, float minY, float maxX, float maxY)
{
	qtexture_t* pqtTexInfo;

  // TTimo: there used to be a call to pfnHasShader here
  //   this was not necessary. In Radiant everything is shader.
  //   If a texture doesn't have a shader script, a default shader object is used.
  // The IShader object was leaking also
	// collect texture info: sizes, etc
	IShader* i = GlobalShaderSystem().getShaderForName(texture);
  pqtTexInfo = i->getTexture();	// shader width/height doesn't come out properly

	if(pqtTexInfo)
	{
		float scale[2] = {0.5f, 0.5f};
		float shift[2] = {0, 0};

		if(bHorScale)
		{
			float width = maxX - minX;

			scale[0] = width/pqtTexInfo->width;
			shift[0] = -(float)((int)maxX%(int)width)/scale[0];
		}

		if(bVertScale)
		{
			float height = maxY - minY;

			scale[1] = height/pqtTexInfo->height;
			shift[1] = (float)((int)minY%(int)height)/scale[1];
		}

		_QERFaceData addFace;
		FillDefaultTexture(&addFace, va, vb, vc, texture);
		addFace.m_texdef.scale[0] = scale[0];
		addFace.m_texdef.scale[1] = scale[1];
		addFace.m_texdef.shift[0] = shift[0];
		addFace.m_texdef.shift[1] = shift[1];

    GlobalBrushCreator().Brush_addFace(brush, addFace);
	}
	else
	{
		// shouldn't even get here, as default missing texture should be returned if
		// texture doesn't exist, but just in case
		AddFaceWithTexture(brush, va, vb, vc, texture, false);
		globalErrorStream() << "BobToolz::Invalid Texture Name-> " << texture;
	}
  // the IShader is not kept referenced, DecRef it
  i->DecRef();
}
コード例 #6
0
ファイル: xmlparse.cpp プロジェクト: Garux/netradiant-custom
scene::Node& createPrimitive( const char* name ){
	if ( string_equal( name, "brush" ) ) {
		return GlobalBrushCreator().createBrush();
	}
	else if ( string_equal( name, "patch" ) ) {
		return GlobalPatchCreator().createPatch();
	}

	ASSERT_MESSAGE( 0, PARSE_ERROR << ": primitive type not supported: \"" << name << "\"\n" );
	scene::Node* node = 0;
	return *node;
}
コード例 #7
0
ファイル: CSG.cpp プロジェクト: BielBdeLuna/DarkRadiant
void hollowBrush(const BrushNodePtr& sourceBrush, bool makeRoom)
{
	// Hollow the brush using the current grid size
    sourceBrush->getBrush().forEachFace([&] (Face& face)
    {
        if (!face.contributes())
        {
            return;
        }

        scene::INodePtr parent = sourceBrush->getParent();

        scene::INodePtr newNode = GlobalBrushCreator().createBrush();
        BrushNodePtr brushNode = std::dynamic_pointer_cast<BrushNode>(newNode);
        assert(brushNode);

        // Add the child to the same parent as the source brush
        parent->addChildNode(brushNode);

        // Move the child brushes to the same layer as their source
        brushNode->assignToLayers(sourceBrush->getLayers());

        // Copy all faces from the source brush
        brushNode->getBrush().copy(sourceBrush->getBrush());

        Node_setSelected(brushNode, true);

        FacePtr newFace = brushNode->getBrush().addFace(face);

        if (newFace != 0)
        {
            float offset = GlobalGrid().getGridSize();

            newFace->flipWinding();
            newFace->getPlane().offset(offset);
            newFace->planeChanged();

            if (makeRoom)
            {
                // Retrieve the normal vector of the "source" face
                brushNode->getBrush().transform(Matrix4::getTranslation(face.getPlane().getPlane().normal() * offset));
                brushNode->getBrush().freezeTransform();
            }
        }

        brushNode->getBrush().removeEmptyFaces();
    });

	// Now unselect and remove the source brush from the scene
	scene::removeNodeFromParent(sourceBrush);
}
コード例 #8
0
ファイル: shapes.cpp プロジェクト: clbr/netradiant
// internal use only, to get a box without finishing construction
scene::Node& Build_Get_BoundingCube_Selective(vec3_t min, vec3_t max, char* texture, bool* useFaces)
{
  NodeSmartReference newBrush(GlobalBrushCreator().createBrush());

	//----- Build Outer Bounds ---------

	vec3_t v1, v2, v3, v5, v6, v7;
	VectorCopy(min, v1);
	VectorCopy(min, v2);
	VectorCopy(min, v3);
	VectorCopy(max, v5);
	VectorCopy(max, v6);
	VectorCopy(max, v7);

	v2[0] = max[0];
	v3[1] = max[1];

	v6[0] = min[0];
	v7[1] = min[1];

	//----------------------------------

	//----- Add Six Cube Faces ---------

	if(useFaces[0])
		AddFaceWithTexture(newBrush, v1, v2, v3, texture, false);
	if(useFaces[1])
		AddFaceWithTexture(newBrush, v1, v3, v6, texture, false);
	if(useFaces[2])
		AddFaceWithTexture(newBrush, v1, v7, v2, texture, false);

	if(useFaces[3])
		AddFaceWithTexture(newBrush, v5, v6, v3, texture, false);
	if(useFaces[4])
		AddFaceWithTexture(newBrush, v5, v2, v7, texture, false);
	if(useFaces[5])
		AddFaceWithTexture(newBrush, v5, v7, v6, texture, false);

	//----------------------------------

	return newBrush;
}
コード例 #9
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);
	}
}
コード例 #10
0
ファイル: shapes.cpp プロジェクト: clbr/netradiant
void BuildCornerStairs(vec3_t vMin, vec3_t vMax, int nSteps, const char* mainTexture, const char* riserTex)
{
	vec3_t* topPoints = new vec3_t[nSteps+1];
	vec3_t* botPoints = new vec3_t[nSteps+1];

	//bool bFacesUse[6] = {true, true, false, true, false, false};

	vec3_t centre;
	VectorCopy(vMin, centre);
	centre[0] = vMax[0];

	int height = (int)(vMax[2] - vMin[2]) / nSteps;

	vec3_t vTop, vBot;
	VectorCopy(vMax, vTop);
	VectorCopy(vMin, vBot);
	vTop[2] = vMin[2] + height;

  int i;
	for(i = 0; i <= nSteps; i++)
	{
		VectorCopy(centre, topPoints[i]);
		VectorCopy(centre, botPoints[i]);
		
		topPoints[i][2] = vMax[2];
		botPoints[i][2] = vMin[2];

		topPoints[i][0] -= 10 * sinf( Q_PI * i / ( 2 * nSteps ) );
		topPoints[i][1] += 10 * cosf( Q_PI * i / ( 2 * nSteps ) );

		botPoints[i][0] = topPoints[i][0];
		botPoints[i][1] = topPoints[i][1];
	}

	vec3_t tp[3];
	for(int j = 0; j < 3; j++)
		VectorCopy(topPoints[j], tp[j]);

	for(i = 0; i < nSteps; i++)
	{
		NodeSmartReference brush(GlobalBrushCreator().createBrush());
		vec3_t v1, v2, v3, v5, v6, v7;
		VectorCopy(vBot, v1);
		VectorCopy(vBot, v2);
		VectorCopy(vBot, v3);
		VectorCopy(vTop, v5);
		VectorCopy(vTop, v6);
		VectorCopy(vTop, v7);
		
		v2[0] = vTop[0];
		v3[1] = vTop[1];
		
		v6[0] = vBot[0];
		v7[1] = vBot[1];
		
		AddFaceWithTexture(brush, v1, v2, v3, "textures/common/caulk", false);
		AddFaceWithTexture(brush, v1, v3, v6, "textures/common/caulk", false);
		AddFaceWithTexture(brush, v5, v6, v3, "textures/common/caulk", false);
		
		for(int j = 0; j < 3; j++)
			tp[j][2] = vTop[2];

		AddFaceWithTexture(brush, tp[2], tp[1], tp[0], mainTexture, false);

		AddFaceWithTexture(brush, centre, botPoints[i+1], topPoints[i+1], "textures/common/caulk", false);
		AddFaceWithTexture(brush, centre, topPoints[i], botPoints[i], riserTex, false);

		Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(brush);

		vTop[2] += height;
		vBot[2] += height;
	}

	delete[] topPoints;
	delete[] botPoints;

	vMin[2] += height;
	vMax[2] += height;
	MakeBevel(vMin, vMax);
}
コード例 #11
0
ファイル: shapes.cpp プロジェクト: clbr/netradiant
void Build_StairStep_Wedge(int dir, vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, bool detail)
{
  NodeSmartReference newBrush(GlobalBrushCreator().createBrush());

	//----- Build Outer Bounds ---------

	vec3_t v1, v2, v3, v5, v6, v7, v8;
	VectorCopy(min, v1);
	VectorCopy(min, v2);
	VectorCopy(min, v3);
	VectorCopy(max, v5);
	VectorCopy(max, v6);
	VectorCopy(max, v7);
	VectorCopy(max, v8);

	v2[0] = max[0];
	v3[1] = max[1];

	v6[0] = min[0];
	v7[1] = min[1];

	v8[2] = min[2];
	//v8 needed this time, becoz of sloping faces (2-4-6-8)

	//----------------------------------

	AddFaceWithTexture(newBrush, v6, v5, v7, mainTexture, detail);

	if(dir != MOVE_EAST)
	{
		if(dir == MOVE_WEST)
			AddFaceWithTexture(newBrush, v5, v2, v7, riserTexture, detail);
		else
			AddFaceWithTexture(newBrush, v5, v2, v7, "textures/common/caulk", detail);
	}

	if(dir != MOVE_WEST)
	{
		if(dir == MOVE_EAST)
			AddFaceWithTexture(newBrush, v1, v3, v6, riserTexture, detail);
		else
			AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", detail);
	}

	if(dir != MOVE_NORTH)
	{
		if(dir == MOVE_SOUTH)
			AddFaceWithTexture(newBrush, v3, v5, v6, riserTexture, detail);
		else
			AddFaceWithTexture(newBrush, v3, v5, v6, "textures/common/caulk", detail);
	}

	if(dir != MOVE_SOUTH)
	{
		if(dir == MOVE_NORTH)
			AddFaceWithTexture(newBrush, v1, v7, v2, riserTexture, detail);
		else
			AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", detail);
	}

		
	if(dir == MOVE_EAST)
		AddFaceWithTexture(newBrush, v1, v5, v3, "textures/common/caulk", detail);

	if(dir == MOVE_WEST)
		AddFaceWithTexture(newBrush, v2, v8, v6, "textures/common/caulk", detail);

	if(dir == MOVE_NORTH)
		AddFaceWithTexture(newBrush, v1, v5, v6, "textures/common/caulk", detail);

	if(dir == MOVE_SOUTH)
		AddFaceWithTexture(newBrush, v7, v8, v3, "textures/common/caulk", detail);

  Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(newBrush);
}
コード例 #12
0
ファイル: shapes.cpp プロジェクト: clbr/netradiant
void Build_Wedge(int dir, vec3_t min, vec3_t max, bool bUp)
{
  NodeSmartReference newBrush(GlobalBrushCreator().createBrush());

	vec3_t v1, v2, v3, v5, v6, v7, v8;
	VectorCopy(min, v1);
	VectorCopy(min, v2);
	VectorCopy(min, v3);
	VectorCopy(max, v5);
	VectorCopy(max, v6);
	VectorCopy(max, v7);
	VectorCopy(max, v8);

	v2[0] = max[0];
	v3[1] = max[1];

	v6[0] = min[0];
	v7[1] = min[1];
	v8[2] = min[2];

	if(bUp)
	{

		if(dir != MOVE_EAST)
			AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", false);

		if(dir != MOVE_WEST)
			AddFaceWithTexture(newBrush, v7, v5, v8, "textures/common/caulk", false);

		if(dir != MOVE_NORTH)
			AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", false);

		if(dir != MOVE_SOUTH)
			AddFaceWithTexture(newBrush, v3, v8, v6, "textures/common/caulk", false);

		AddFaceWithTexture(newBrush, v1, v2, v3, "textures/common/caulk", false);

		if(dir == MOVE_EAST)
			AddFaceWithTexture(newBrush, v1, v3, v5, "textures/common/caulk", false);

		if(dir == MOVE_WEST)
			AddFaceWithTexture(newBrush, v2, v6, v8, "textures/common/caulk", false);

		if(dir == MOVE_NORTH)
			AddFaceWithTexture(newBrush, v1, v6, v5, "textures/common/caulk", false);

		if(dir == MOVE_SOUTH)
			AddFaceWithTexture(newBrush, v7, v3, v8, "textures/common/caulk", false);
	}
	else
	{
		if(dir != MOVE_WEST)
			AddFaceWithTexture(newBrush, v7, v5, v8, "textures/common/caulk", false);

		if(dir != MOVE_EAST)
			AddFaceWithTexture(newBrush, v1, v3, v6, "textures/common/caulk", false);

		if(dir != MOVE_NORTH)
			AddFaceWithTexture(newBrush, v3, v8, v6, "textures/common/caulk", false);

		if(dir != MOVE_SOUTH)
			AddFaceWithTexture(newBrush, v1, v7, v2, "textures/common/caulk", false);

		
		AddFaceWithTexture(newBrush, v6, v5, v7, "textures/common/caulk", false);

		if(dir == MOVE_WEST)
			AddFaceWithTexture(newBrush, v1, v5, v3, "textures/common/caulk", false);

		if(dir == MOVE_EAST)
			AddFaceWithTexture(newBrush, v2, v8, v6, "textures/common/caulk", false);

		if(dir == MOVE_NORTH)
			AddFaceWithTexture(newBrush, v1, v5, v6, "textures/common/caulk", false);

		if(dir == MOVE_SOUTH)
			AddFaceWithTexture(newBrush, v7, v8, v3, "textures/common/caulk", false);
	}

	Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(newBrush);
}
コード例 #13
0
void BrushByPlaneClipper::split(const BrushPtrVector& brushes)
{
	Plane3 plane(_p0, _p1, _p2);

	if (!plane.isValid())
	{
		return;
	}

	for (BrushPtrVector::const_iterator i = brushes.begin(); i != brushes.end(); ++i)
	{
		const BrushNodePtr& node = *i;

		// Don't clip invisible nodes
		if (!node->visible())
		{
			continue;
		}

		Brush& brush = node->getBrush();

		scene::INodePtr parent = node->getParent();

		if (!parent)
		{
			continue;
		}

		// 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();

				assert(fragmentNode != NULL);

				// Put the fragment in the same layer as the brush it was clipped from
				// Do this before adding the fragment to the parent, since there is an
				// update algorithm setting the visibility of the fragment right there.
				scene::assignNodeToLayers(fragmentNode, node->getLayers());

				// greebo: For copying the texture scale the new node needs to be inserted in the scene
				// otherwise the shaders cannot be captured and the scale is off

				// Insert the child into the designated parent
				scene::addNodeToContainer(fragmentNode, parent);

				// Select the child
				Node_setSelected(fragmentNode, true);

				Brush* fragment = Node_getBrush(fragmentNode);
				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");
			}

			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
			// Remove the node from the scene
			scene::removeNodeFromParent(node);
		}
	}
}
コード例 #14
0
ファイル: BrushDef.cpp プロジェクト: DerSaidin/DarkRadiant
/*
// Example Primitive
{
brushDef
{
( -1216 -464 232 ) ( -1088 -464 232 ) ( -1088 -80 120 ) ( ( 0.031250 0 14 ) ( -0.000009 0.031250 4.471550 ) ) common/caulk 134217728 4 0
( -1088 -464 248 ) ( -1216 -464 248 ) ( -1216 -80 136 ) ( ( 0 -0.031373 -0.147059 ) ( 0.007812 0 0.049020 ) ) common/caulk 134217728 0 0
( -1088 -560 120 ) ( -1088 -560 136 ) ( -1088 -80 136 ) ( ( 0.031250 0 16.500000 ) ( 0 0.031250 0.250000 ) ) common/caulk 134217728 4 0
( -1088 -80 136 ) ( -1216 -80 136 ) ( -1216 -80 8 ) ( ( 0.031250 0 2 ) ( 0 0.031250 0.250000 ) ) common/caulk 134217728 4 0
( -1216 -400 136 ) ( -1216 -400 120 ) ( -1216 -80 120 ) ( ( 0.031250 0 -16.500000 ) ( 0 0.031250 0.250000 ) ) common/caulk 134217728 4 0
( -1088 -464 232 ) ( -1216 -464 232 ) ( -1216 -464 248 ) ( ( 0.031250 0 -2 ) ( 0 0.031250 0.250000 ) ) common/caulk 134217728 4 0
}
}
*/
scene::INodePtr BrushDefParser::parse(parser::DefTokeniser& tok) const
{
	// Create a new brush
	scene::INodePtr node = GlobalBrushCreator().createBrush();

	// Cast the node, this must succeed
	IBrushNodePtr brushNode = boost::dynamic_pointer_cast<IBrushNode>(node);
	assert(brushNode != NULL);

	IBrush& brush = brushNode->getIBrush();

	tok.assertNextToken("{");

	// Parse face tokens until a closing brace is encountered
	while (1)
	{
		std::string token = tok.nextToken();

		// Token should be either a "(" (start of face) or "}" (end of brush)
		if (token == "}")
		{
			break; // end of brush
		}
		else if (token == "(") // FACE
		{
			// Parse three 3D points to construct a plane
			Vector3 p1(string::to_float(tok.nextToken()), string::to_float(tok.nextToken()), string::to_float(tok.nextToken()));
			tok.assertNextToken(")");
			tok.assertNextToken("(");

			Vector3 p2(string::to_float(tok.nextToken()), string::to_float(tok.nextToken()), string::to_float(tok.nextToken()));
			tok.assertNextToken(")");
			tok.assertNextToken("(");

			Vector3 p3(string::to_float(tok.nextToken()), string::to_float(tok.nextToken()), string::to_float(tok.nextToken()));
			tok.assertNextToken(")");

			// Construct the plane from the three points
			Plane3 plane(p1, p2, p3);

			// Parse TexDef
			Matrix4 texdef;
			tok.assertNextToken("(");

			tok.assertNextToken("(");
			texdef.xx() = string::to_float(tok.nextToken());
			texdef.yx() = string::to_float(tok.nextToken());
			texdef.tx() = string::to_float(tok.nextToken());
			tok.assertNextToken(")");

			tok.assertNextToken("(");
			texdef.xy() = string::to_float(tok.nextToken());
			texdef.yy() = string::to_float(tok.nextToken());
			texdef.ty() = string::to_float(tok.nextToken());
			tok.assertNextToken(")");

			tok.assertNextToken(")");

			// Parse Shader, brushDef has an implicit "textures/" not written to the map
			std::string shader = "textures/" + tok.nextToken();

			// Parse Contents Flags (and ignore them)
			tok.skipTokens(3);

			// Finally, add the new face to the brush
			/*IFace& face = */brush.addFace(plane, texdef, shader);
		}
		else
		{
			std::string text = (boost::format(_("BrushDefParser: invalid token '%s'")) % token).str();
			throw parser::ParseException(text);
		}
	}

	// Final outer "}"
	tok.assertNextToken("}");

	return node;
}
コード例 #15
0
ファイル: shapes.cpp プロジェクト: clbr/netradiant
void BuildDoorsX2(vec3_t min, vec3_t max, 
				  bool bSclMainHor, bool bSclMainVert, 
				  bool bSclTrimHor, bool bSclTrimVert,
				  const char* mainTexture, const char* trimTexture,
				  int direction)
{
	int xy;
	if(direction == 0)
		xy = 0;
	else
		xy = 1;

	//----- Build Outer Bounds ---------

	vec3_t v1, v2, v3, v5, v6, v7, ve_1, ve_2, ve_3;
	VectorCopy(min, v1);
	VectorCopy(min, v2);
	VectorCopy(min, v3);
	VectorCopy(max, v5);
	VectorCopy(max, v6);
	VectorCopy(max, v7);

	v2[0] = max[0];
	v3[1] = max[1];

	v6[0] = min[0];
	v7[1] = min[1];

	float width = (max[xy] - min[xy])/2;
	
	if(direction == 0)
	{
		VectorCopy(v1, ve_1);
		VectorCopy(v3, ve_2);
		VectorCopy(v6, ve_3);
	}
	else
	{
		VectorCopy(v7, ve_1);
		VectorCopy(v1, ve_2);
		VectorCopy(v2, ve_3);
	}

	ve_1[xy] += width;
	ve_2[xy] += width;
	ve_3[xy] += width;

	//----------------------------------

  NodeSmartReference newBrush1(GlobalBrushCreator().createBrush());
	NodeSmartReference newBrush2(GlobalBrushCreator().createBrush());

	AddFaceWithTexture(newBrush1, v1, v2, v3, "textures/common/caulk", false);
	AddFaceWithTexture(newBrush1, v5, v7, v6, "textures/common/caulk", false);

	AddFaceWithTexture(newBrush2, v1, v2, v3, "textures/common/caulk", false);
	AddFaceWithTexture(newBrush2, v5, v7, v6, "textures/common/caulk", false);

	if(direction == 0)
	{
		AddFaceWithTexture(newBrush1, v1, v3, v6, "textures/common/caulk", false);
		AddFaceWithTexture(newBrush2, v5, v2, v7, "textures/common/caulk", false);
	}
	else
	{
		AddFaceWithTexture(newBrush1, v1, v7, v2, "textures/common/caulk", false);
		AddFaceWithTexture(newBrush2, v5, v6, v3, "textures/common/caulk", false);
	}

	if(direction == 0)
	{
		AddFaceWithTextureScaled(newBrush1, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
			min[0], min[2], max[0], max[2]);
		AddFaceWithTextureScaled(newBrush1, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
			max[0], min[2], min[0], max[2]);

		
		AddFaceWithTextureScaled(newBrush2, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
			min[0], min[2], max[0], max[2]);
		AddFaceWithTextureScaled(newBrush2, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
			max[0], min[2], min[0], max[2]);	// flip max/min to reverse tex dir


	
		AddFaceWithTextureScaled(newBrush1, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
			min[1], min[2], max[1], max[2]);

		AddFaceWithTextureScaled(newBrush2, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
			max[1], min[2], min[1], max[2]);
	}
	else
	{
		AddFaceWithTextureScaled(newBrush1, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
			min[1], min[2], max[1], max[2]);
		AddFaceWithTextureScaled(newBrush1, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
			max[1], min[2], min[1], max[2]);

		
		AddFaceWithTextureScaled(newBrush2, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
			min[1], min[2], max[1], max[2]);
		AddFaceWithTextureScaled(newBrush2, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
			max[1], min[2], min[1], max[2]);	// flip max/min to reverse tex dir


		AddFaceWithTextureScaled(newBrush1, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
			min[0], min[2], max[0], max[2]);

		AddFaceWithTextureScaled(newBrush2, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
			max[0], min[2], min[0], max[2]);
	}

	//----------------------------------
	

  EntityClass* doorClass = GlobalEntityClassManager().findOrInsert("func_door", true);
  NodeSmartReference pEDoor1(GlobalEntityCreator().createEntity(doorClass));
	NodeSmartReference pEDoor2(GlobalEntityCreator().createEntity(doorClass));

	if(direction == 0)
	{
    Node_getEntity(pEDoor1)->setKeyValue("angle", "180");
    Node_getEntity(pEDoor2)->setKeyValue("angle", "360");
	}
	else
	{
    Node_getEntity(pEDoor1)->setKeyValue("angle", "270");
    Node_getEntity(pEDoor2)->setKeyValue("angle", "90");
	}

	srand((unsigned)time(NULL));

	char teamname[256];
	sprintf(teamname, "t%i", rand());
  Node_getEntity(pEDoor1)->setKeyValue("team", teamname);
  Node_getEntity(pEDoor2)->setKeyValue("team", teamname);

	Node_getTraversable(pEDoor1)->insert(newBrush1);
	Node_getTraversable(pEDoor2)->insert(newBrush2);

  Node_getTraversable(GlobalSceneGraph().root())->insert(pEDoor1);
  Node_getTraversable(GlobalSceneGraph().root())->insert(pEDoor2);

//	ResetCurrentTexture();
}
コード例 #16
0
scene::INodePtr BrushDef3Parser::parse(parser::DefTokeniser& tok) const
{
	// Create a new brush
	scene::INodePtr node = GlobalBrushCreator().createBrush();

	// Cast the node, this must succeed
	IBrushNodePtr brushNode = boost::dynamic_pointer_cast<IBrushNode>(node);
	assert(brushNode != NULL);

	IBrush& brush = brushNode->getIBrush();

	tok.assertNextToken("{");

	// Parse face tokens until a closing brace is encountered
	while (1)
	{
		std::string token = tok.nextToken();

		// Token should be either a "(" (start of face) or "}" (end of brush)
		if (token == "}")
		{
			break; // end of brush
		}
		else if (token == "(") // FACE
		{
			// Construct a plane and parse its values
			Plane3 plane;

			plane.normal().x() = string::to_float(tok.nextToken());
			plane.normal().y() = string::to_float(tok.nextToken());
			plane.normal().z() = string::to_float(tok.nextToken());
			plane.dist() = -string::to_float(tok.nextToken()); // negate d

			tok.assertNextToken(")");

			// Parse TexDef
			Matrix4 texdef;
			tok.assertNextToken("(");

			tok.assertNextToken("(");
			texdef.xx() = string::to_float(tok.nextToken());
			texdef.yx() = string::to_float(tok.nextToken());
			texdef.tx() = string::to_float(tok.nextToken());
			tok.assertNextToken(")");

			tok.assertNextToken("(");
			texdef.xy() = string::to_float(tok.nextToken());
			texdef.yy() = string::to_float(tok.nextToken());
			texdef.ty() = string::to_float(tok.nextToken());
			tok.assertNextToken(")");

			tok.assertNextToken(")");

			// Parse Shader
			std::string shader = tok.nextToken();

			// Parse Flags (usually each brush has all faces detail or all faces structural)
			IBrush::DetailFlag flag = static_cast<IBrush::DetailFlag>(
				string::convert<std::size_t>(tok.nextToken(), IBrush::Structural));
			brush.setDetailFlag(flag);

			// Ignore the other two flags
			tok.skipTokens(2);

			// Finally, add the new face to the brush
			/*IFace& face = */brush.addFace(plane, texdef, shader);
		}
		else {
			std::string text = (boost::format(_("BrushDef3Parser: invalid token '%s'")) % token).str();
			throw parser::ParseException(text);
		}
	}

	// Final outer "}"
	tok.assertNextToken("}");

	return node;
}
コード例 #17
0
ファイル: CSG.cpp プロジェクト: BielBdeLuna/DarkRadiant
	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);
			}
		}
	}