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)); } }
/* 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; }
/* 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__ }