17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 06:19:19 +02:00
Files
maszyna/editor/editorTrack.hpp

137 lines
6.0 KiB
C++

/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <string>
#include <utility>
#include <vector>
#include <glm/glm.hpp>
#include "world/Segment.h"
#include "utilities/Classes.h"
class TTrack;
// Editing of paths (tracks, roads, rivers) loaded from the scenery.
//
// The source of truth for path geometry is TTrack::m_paths (the same data the scenery export writes).
// Edits modify m_paths and then commit() rebuilds everything derived from it: the segments, placement
// in the scene cells, connections with neighbouring paths and the render geometry.
class editor_track
{
public:
// identifies an editable point of a path
enum class point_kind { start, control1, control2, end };
struct point_ref
{
int path{-1}; // index into TTrack::m_paths
point_kind kind{point_kind::start};
bool valid() const { return path >= 0; }
bool operator==(point_ref const &Other) const { return path == Other.path && kind == Other.kind; }
};
// snapshot of the editable state of a path, used by the undo history
struct state
{
std::vector<segment_data> paths;
double velocity{-1.0};
float switchvelocity{-1.f};
float width{1.435f};
float friction{0.15f};
float sounddistance{-1.f};
int quality{20};
int damage{0};
int environment{0};
material_handle material1{0};
material_handle material2{0};
material_handle material3{0};
float texlength{4.f};
float texheight{0.6f};
float texwidth{0.9f};
float texslope{0.9f};
};
static state capture(TTrack const &Track);
// restores provided state; follow with commit() to rebuild the path
static void apply(TTrack &Track, state const &State);
// checks whether geometry of the path can be modified. returns: true if it can, otherwise false and the reason
static bool can_edit_geometry(TTrack const &Track, std::string &Reason);
// checks whether the path type is supported by the editor at all
static bool is_supported(TTrack const &Track);
// rebuilds provided paths after modification of their source data (m_paths): segments, placement in the region,
// connections with neighbours and render geometry of the paths and all their old and new neighbours
static void commit(std::vector<TTrack *> const &Tracks);
// rebuilds the path after change of parameters which don't affect its course (width, textures, etc)
static void commit_parameters(TTrack &Track);
// world position of specified point. for control points it's the absolute position of the handle;
// a zero (straight) control vector is presented at 1/3 of the chord so it can be grabbed
static glm::dvec3 point_position(TTrack const &Track, point_ref const &Point);
// moves specified point to provided world position. moving an end point carries its control vector along.
// switches keep the start points of both their paths together
static void move_point(TTrack &Track, point_ref const &Point, glm::dvec3 const &Position);
// moves the whole path by provided offset
static void translate(TTrack &Track, glm::dvec3 const &Offset);
// rotates the whole path around vertical axis going through provided pivot point
static void rotate_y(TTrack &Track, glm::dvec3 const &Pivot, double const Angle);
// pivot used for rotation of the whole path
static glm::dvec3 pivot(TTrack const &Track);
// lists paths currently connected to provided path
static std::vector<TTrack *> neighbours(TTrack const &Track);
// lists end points of other paths connected to the end point located at provided position,
// as pairs of the neighbour and its matching point
static std::vector<std::pair<TTrack *, point_ref>> connected_points(TTrack const &Track, glm::dvec3 const &Position);
// checks whether end point located at provided position is connected to another path
static bool is_connected(TTrack const &Track, point_ref const &Point);
// candidate to connect a dragged end point with
struct snap_target
{
TTrack *track{nullptr};
point_ref point;
glm::dvec3 position{0.0};
glm::dvec3 direction{0.0}; // direction from the point into the target path
double distance{0.0};
};
// finds the nearest free end point of another path of the same category as provided path, within specified radius.
// paths listed in Exclude are skipped, and connections to them don't count as occupying an end point
static snap_target find_snap_target(TTrack const &Track, glm::dvec3 const &Position, double const Radius, std::vector<TTrack const *> const &Exclude);
// places the point at the target and optionally aligns the control vector with the target path
static void snap_point(TTrack &Track, point_ref const &Point, snap_target const &Target, bool const Aligntangent);
// names of the materials used by the path; "none" for missing ones
static std::string material_name(material_handle const Material);
static material_handle fetch_material(std::string const &Name);
// height of the trackbed edge as written in the scenery (without roll fix adjustment)
static float texture_height(TTrack const &Track);
static void texture_height(TTrack &Track, float const Height);
static double velocity(TTrack const &Track);
static void velocity(TTrack &Track, double const Velocity);
static void damage(TTrack &Track, int const Damage);
private:
// unlinks the path from all its neighbours
static void disconnect(TTrack &Track);
// links the path with paths whose free end points match its own free end points
static void join(TTrack &Track);
// links specified end of a regular path with matching end of another path
static void connect(TTrack &Track, bool const Prevside, TTrack *Other, int const Endpointid);
// recalculates the trackbed transition flag
static void update_transition(TTrack &Track);
// sets active connections of a switch to specified path, without moving the blades
static void bind_switch_path(TTrack &Switch, int const Path);
static void store_switch_path(TTrack &Switch, int const Path);
// rebuilds render geometry of the path in the bank of the section it's placed in
static void rebuild_geometry(TTrack &Track);
};