17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 03:59:19 +02:00
Files
maszyna/world/Sweep.h
maj00r d4791f6a29 feat(editor): a model or an include standing by a track bent along it (B, or the Bend along the track section of the toolset): it stays where it stood and follows the track, through the joined tracks as far as it reaches; reference point at its start, origin, middle, end or a point picked on the model, across at its origin, the side facing the track, the far side or its middle, up at its origin, bottom, top or the top of its edge by the track; the blue cross of a bent model dragged for its offset, with Shift for its height and with Ctrl along the track, the values shown at the cursor; a bent model clicked to edit; one step of the undo history; scale of the model kept, parts lit only at night left out; edges of platforms told by the name of the model and by the overhang of their edge over the foot: put 1.725 m from the axis at the height the name gives, turned with the edge to the track when they stood the other way; platforms stand on the plane of the rail heads carried on to their edge (PKP PLK ST-T2), the gauge widening led in from the tracks beyond the ends and from the other path of a switch; gaps between the pieces of a sweep filled with the paths which join them; Platforms and models tab left out of the track editor; laid track eased into the curvature of the one it joins with a transition curve; File > Open scenery... starts the editor again with the scenery picked from a list; the camera saved with the scenery; T and Shift+T turn each turntable to its next and previous position by event launchers written on each save; a turntable track deleted with its template; a scenery with no trainset gets a WMB10 on its first track; vehicle placed where the track is clicked; gauge check takes in the bent models; Polish translation of the editor
2026-10-08 00:51:40 +02:00

184 lines
7.1 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 <array>
#include <string>
#include <vector>
#include <glm/glm.hpp>
#include "utilities/Classes.h"
#include "utilities/Names.h"
#include "scene/scenenode.h"
#include "world/Road.h"
#include "world/Segment.h"
#include "vehicle/DynObj.h"
namespace scene
{
struct scratch_data;
}
// a model laid along a curve: copies of it bent to follow the curve end to end, or set along it at even steps.
// the node isn't drawn itself, it makes ordinary shapes of the copies, so the renderers deal with it as with the rest
// of the scenery. animations, lights and other submodels which aren't plain triangles are left out of the copies.
// scenery entry:
// node <max> <min> <name> sweep <model> <skin> [<property> <values>]... piece <laid out like a path of a track>... endsweep
// properties: mode <bend|repeat>, step <length of a copy along the curve, 0: the length of the model>,
// range <from> <to> (m along the curve, to below 0: up to its end), offset <sideways, + to the right> <up>,
// anchor <origin|near|far|centre> <origin|bottom|top> (what of the model the offset puts there: sideways its origin, its side
// facing the curve, the other side or its middle; up its origin, its bottom or its top),
// axis <x|z> (axis of the model laid along the curve), flip (the model goes the other way), mirror (its sides swapped),
// widen (the offset grows by the widening of the structure gauge in the curves, the way the platforms are set back),
// platform (as widen, and the copies stand on the plane of the rail heads carried on to the edge: lowered on the inner
// side of a canted curve, raised on the outer one),
// noface (the model isn't turned to have its -x side, or -z for one laid along x, facing the curve),
// parameters <count> <values>... (of a template: the model can be an *.inc file, its long models are bent, the others stand
// upright at their places along the curve),
// scale <x> <y> <z> (of the model, along its own axes), point <x> <y> <z> (a point of the model, in its own space, taken by the anchor point),
// anchor sides: origin, near, far, centre, point; heights: origin, bottom, top, edge (the top of the side facing the curve), point,
// tilt (bent copies lean with the cant of the curve; otherwise they stay upright, as the platforms and the walls by a track do,
// at the height the plane of the cant has at their sideways offset)
class sweep_node : public scene::basic_node
{
public:
struct state
{
std::string model;
std::string skin{"none"};
bool bend{true};
double step{0.0};
double from{0.0};
double to{-1.0};
double lateral{0.0};
double height{0.0};
bool along_x{false};
bool flip{false};
bool mirror{false};
bool tilt{false};
bool face{true}; // the model is turned so its -x side (-z for a model laid along x) faces the curve
bool widen{false}; // moved away from the curve by the widening of the structure gauge in the curves
bool platform{false}; // set back as widen does, and its height taken from the plane of the rail heads at its edge
std::vector<std::string> parameters; // of a template (*.inc) laid along the curve
int side_anchor{0}; // 0: origin, 1: the side facing the curve, 2: the far side, 3: the middle, 4: the point
int height_anchor{0}; // 0: origin, 1: bottom, 2: top, 3: top of the side facing the curve, 4: the point
glm::dvec3 point{0.0};
glm::dvec3 scale{1.0};
std::vector<segment_data> pieces;
bool operator==(state const &Other) const;
};
// point of the curve, with the directions the copies are laid out by
struct frame
{
glm::dvec3 position{0.0};
glm::dvec3 forward{0.0, 0.0, 1.0};
glm::dvec3 left{-1.0, 0.0, 0.0};
glm::dvec3 up{0.0, 1.0, 0.0};
double roll{0.0}; // degrees, of the curve there
std::array<double, 2> widening{}; // of the structure gauge, below the platforms: right and left side, metres
std::array<double, 2> cant{}; // metres, positive on the inner side of the curve
};
explicit sweep_node(scene::node_data const &Nodedata);
void import(cParser &Input, glm::dvec3 const &Offset);
void define(state const &State);
state const &definition() const
{
return m_state;
}
// length of the curve, in the plan
double length() const;
frame frame_at(double const Station) const;
// station of the point of the curve nearest to the point in the plan, and how far to the right of the curve it is
double project(glm::dvec3 const &Point, double &Lateral) const;
// stretch of the curve the copies take
double start() const;
double end() const;
// length of a copy along the curve, as the model has it
double model_length() const;
bool bounds(glm::dvec3 &Low, glm::dvec3 &High, glm::dvec3 &Shift) const;
bool edge_far() const;
glm::dvec3 axes(glm::dvec3 const &Vector) const;
double distance_at(double const Station) const;
double station_at(double const Distance) const;
double setback(frame const &At) const;
// height the copies stand at over the points of the curve, less the height of the rail: the head of the rail on their side,
// for a platform the plane of the rail heads carried on to its edge, lower on the inner side of a canted curve
double rise(frame const &At) const;
std::vector<scene::shape_node> create_shapes() const;
// a model of what's laid along the curve, placed in its space
struct item
{
TModel3d *model{nullptr};
material_data skins;
glm::dmat4 transform{1.0};
};
std::vector<item> items() const;
// height of the head of the rail on the side of the offset over the points of the track, less the height of the rail
static double rail_head(double const Roll, double const Lateral);
// puts the copies in the scene as shapes of their own, which can be taken back
void show();
void hide();
void refresh();
bool bridge();
void merged(bool const Merged)
{
m_merged = Merged;
}
bool merged() const
{
return m_merged;
}
bool m_editorremoved{false};
private:
void rebuild_samples();
float radius_() override;
void serialize_(std::ostream &Output) const override;
void deserialize_(std::istream &Input) override;
void export_as_text_(std::ostream &Output) const override;
struct sample
{
double station;
glm::dvec3 position;
glm::dvec3 tangent;
double roll; // degrees
std::array<double, 2> widening;
std::array<double, 2> cant;
};
static void sample_piece(segment_data const &Piece, std::vector<sample> &Samples, double &Station);
static void gauge_along(std::vector<sample> &Samples);
void beside_switches(std::vector<std::pair<double, double>> const &Spans);
state m_state;
std::vector<sample> m_samples;
std::vector<double> m_distances;
mutable bool m_boundsvalid{false};
mutable bool m_boundsfound{false};
mutable bool m_edgefar{false};
mutable glm::dvec3 m_low{0.0}, m_high{0.0}, m_shift{0.0};
bool m_merged{false};
owned_shapes m_shapes;
};
// collection of the models laid along curves present in the scene
class sweep_table : public basic_table<sweep_node>
{
public:
// generates geometry of the copies and puts it in the scene
void create_geometry(scene::scratch_data &Scratchpad);
};