Пример #1
0
void MapSpecials::applyLineSlopeThing(SLADEMap* map, MapThing* thing)
{
	int lineid = thing->intProperty("arg0");
	if (!lineid)
	{
		LOG_MESSAGE(1, "Ignoring line slope thing %d with no lineid argument", thing->getIndex());
		return;
	}

	// These are computed on first use, to avoid extra work if no lines match
	MapSector* containing_sector = nullptr;
	double thingz;

	vector<MapLine*> lines;
	map->getLinesById(lineid, lines);
	for (unsigned b = 0; b < lines.size(); b++)
	{
		MapLine* line = lines[b];

		// Line slope things only affect the sector on the side of the line
		// that faces the thing
		double side = MathStuff::lineSide(thing->point(), line->seg());
		MapSector* target = nullptr;
		if (side < 0)
			target = line->backSector();
		else if (side > 0)
			target = line->frontSector();
		if (!target)
			continue;

		// Need to know the containing sector's height to find the thing's true height
		if (!containing_sector)
		{
			int containing_sector_idx = map->sectorAt(thing->point());
			if (containing_sector_idx < 0)
				return;
			containing_sector = map->getSector(containing_sector_idx);
			thingz = (
				containing_sector->getPlane<p>().height_at(thing->point())
				+ thing->floatProperty("height")
			);
		}

		// Three points: endpoints of the line, and the thing itself
		plane_t target_plane = target->getPlane<p>();
		fpoint3_t p1(lines[b]->x1(), lines[b]->y1(), target_plane.height_at(lines[b]->point1()));
		fpoint3_t p2(lines[b]->x2(), lines[b]->y2(), target_plane.height_at(lines[b]->point2()));
		fpoint3_t p3(thing->xPos(), thing->yPos(), thingz);
		target->setPlane<p>(MathStuff::planeFromTriangle(p1, p2, p3));
	}
}
Пример #2
0
/* MapSector::isWithin
 * Returns true if the point is inside the sector
 *******************************************************************/
bool MapSector::isWithin(fpoint2_t point)
{
	// Check with bbox first
	if (!boundingBox().contains(point))
		return false;

	// Find nearest line in the sector
	double dist;
	double min_dist = 999999;
	MapLine* nline = nullptr;
	for (unsigned a = 0; a < connected_sides.size(); a++)
	{
		// Calculate distance to line
		//if (connected_sides[a] == NULL) {
		//	LOG_MESSAGE(3, "Warning: connected side #%i is a NULL pointer!", a);
		//	continue;
		//} else if (connected_sides[a]->getParentLine() == NULL) {
		//	LOG_MESSAGE(3, "Warning: connected side #%i has a NULL pointer parent line!", connected_sides[a]->getIndex());
		//	continue;
		//}
		dist = connected_sides[a]->getParentLine()->distanceTo(point);

		// Check distance
		if (dist < min_dist)
		{
			nline = connected_sides[a]->getParentLine();
			min_dist = dist;
		}
	}

	// No nearest (shouldn't happen)
	if (!nline)
		return false;

	// Check the side of the nearest line
	double side = MathStuff::lineSide(point, nline->seg());
	if (side >= 0 && nline->frontSector() == this)
		return true;
	else if (side < 0 && nline->backSector() == this)
		return true;
	else
		return false;
}
Пример #3
0
/* MapCanvas::onKeyDown
 * Called when a key is pressed within the canvas
 *******************************************************************/
void MapCanvas::onKeyDown(wxKeyEvent& e)
{
	// Send to editor
	context_->input().updateKeyModifiersWx(e.GetModifiers());
	context_->input().keyDown(KeyBind::keyName(e.GetKeyCode()));

	// Testing
	if (Global::debug)
	{
		if (e.GetKeyCode() == WXK_F6)
		{
			Polygon2D poly;
			sf::Clock clock;
			LOG_MESSAGE(1, "Generating polygons...");
			for (unsigned a = 0; a < context_->map().nSectors(); a++)
			{
				if (!poly.openSector(context_->map().getSector(a)))
					LOG_MESSAGE(1, "Splitting failed for sector %d", a);
			}
			//int ms = clock.GetElapsedTime() * 1000;
			//LOG_MESSAGE(1, "Polygon generation took %dms", ms);
		}
		if (e.GetKeyCode() == WXK_F7)
		{
			// Get nearest line
			int nearest = context_->map().nearestLine(context_->input().mousePosMap(), 999999);
			MapLine* line = context_->map().getLine(nearest);
			if (line)
			{
				SectorBuilder sbuilder;

				// Determine line side
				double side = MathStuff::lineSide(context_->input().mousePosMap(), line->seg());
				if (side >= 0)
					sbuilder.traceSector(&(context_->map()), line, true);
				else
					sbuilder.traceSector(&(context_->map()), line, false);
			}
		}
		if (e.GetKeyCode() == WXK_F5)
		{
			// Get nearest line
			int nearest = context_->map().nearestLine(context_->input().mousePosMap(), 999999);
			MapLine* line = context_->map().getLine(nearest);

			// Get sectors
			MapSector* sec1 = context_->map().getLineSideSector(line, true);
			MapSector* sec2 = context_->map().getLineSideSector(line, false);
			int i1 = -1;
			int i2 = -1;
			if (sec1) i1 = sec1->getIndex();
			if (sec2) i2 = sec2->getIndex();

			context_->addEditorMessage(S_FMT("Front %d Back %d", i1, i2));
		}
		if (e.GetKeyCode() == WXK_F5 && context_->editMode() == Mode::Sectors)
		{
			PolygonSplitter splitter;
			splitter.setVerbose(true);
			splitter.openSector(context_->selection().hilightedSector());
			Polygon2D temp;
			splitter.doSplitting(&temp);
		}
	}

	// Update cursor in object edit mode
	//if (mouse_state == Input::MouseState::ObjectEdit)
	//	determineObjectEditState();

#ifndef __WXMAC__
	// Skipping events on OS X doesn't do anything but causes
	// sound alert (a.k.a. error beep) on every key press
	if (e.GetKeyCode() != WXK_UP &&
		e.GetKeyCode() != WXK_DOWN &&
		e.GetKeyCode() != WXK_LEFT &&
		e.GetKeyCode() != WXK_RIGHT &&
		e.GetKeyCode() != WXK_NUMPAD_UP &&
		e.GetKeyCode() != WXK_NUMPAD_DOWN &&
		e.GetKeyCode() != WXK_NUMPAD_LEFT &&
		e.GetKeyCode() != WXK_NUMPAD_RIGHT)
		e.Skip();
#endif // !__WXMAC__
}