mirror of
https://github.com/leozide/leocad
synced 2025-02-06 08:46:06 +01:00
365 lines
12 KiB
C++
365 lines
12 KiB
C++
#include "piece.h"
|
|
#include "traintracksystem.h"
|
|
#include "lc_model.h"
|
|
#include "lc_application.h"
|
|
#include "lc_library.h"
|
|
#include <QString>
|
|
|
|
TrainTrackConnectionPoint::TrainTrackConnectionPoint(float angle, float x, float y) {
|
|
this->angle = angle;
|
|
xy_coordinate.x = x;
|
|
xy_coordinate.y = y;
|
|
}
|
|
|
|
|
|
|
|
void TrainTrackType::Load(lcPiecesLibrary* Library, char const* filename) {
|
|
pieceInfo = Library->FindPiece(filename, nullptr, false, false);
|
|
}
|
|
|
|
void TrainTrackType::AddConnection(TrainTrackConnectionPoint *connectionPoint) {
|
|
connectionPoints.push_back(connectionPoint);
|
|
}
|
|
|
|
TrainTrackConnectionPoint* TrainTrackType::GetConnection(int index) {
|
|
return connectionPoints[index];
|
|
}
|
|
|
|
std::vector<TrainTrackConnectionPoint *>& TrainTrackType::GetConnections() {
|
|
return connectionPoints;
|
|
}
|
|
|
|
int TrainTrackType::GetNoOfConnections() {
|
|
return connectionPoints.size();
|
|
}
|
|
|
|
|
|
|
|
TrainTrackSection::TrainTrackSection(TrainTrackType *trackType, enum LC_TTS_TYPES trackTypeId, lcMatrix44 location, int mCurrentStep, int mColorIndex) {
|
|
this->trackType = trackType;
|
|
this->trackTypeId = trackTypeId;
|
|
this->location = location;
|
|
this->mCurrentStep = mCurrentStep;
|
|
this->mColorIndex = mColorIndex;
|
|
}
|
|
|
|
|
|
lcMatrix44 TrainTrackSection::GetConnectionLocation(int connectionNo) {
|
|
|
|
lcMatrix44 mat44;
|
|
lcMatrix44 matOffset;
|
|
|
|
TrainTrackConnectionPoint* connection = trackType->GetConnections()[connectionNo];
|
|
|
|
mat44 = lcMatrix44Identity();
|
|
mat44 = lcMatrix44RotationZ(LC_DTOR * connection->angle);
|
|
|
|
matOffset = lcMatrix44Identity();
|
|
matOffset.SetTranslation(lcVector3(connection->xy_coordinate.x, connection->xy_coordinate.y,0));
|
|
|
|
matOffset = lcMul(mat44, matOffset);
|
|
|
|
return lcMul(matOffset,location);
|
|
}
|
|
|
|
int TrainTrackSection::GetNoOfConnections() {
|
|
return trackType->GetNoOfConnections();
|
|
}
|
|
|
|
int TrainTrackSection::FindConnectionNumber(lcVector3 v3searchLocation) {
|
|
float precisionErrorNumber = 0.001;
|
|
|
|
lcMatrix44 matOffset;
|
|
|
|
for(int con_no = 0; con_no < trackType->GetNoOfConnections(); con_no++) {
|
|
|
|
lcMatrix44 matSelection = GetConnectionLocation(con_no);
|
|
|
|
matOffset = lcMatrix44Identity();
|
|
matOffset.SetTranslation(lcVector3(-10, 0, 8));
|
|
|
|
lcVector3 v3Selection = lcMul(matOffset,matSelection).GetTranslation();
|
|
|
|
if(abs(v3Selection.x - v3searchLocation.x) < precisionErrorNumber &&
|
|
abs(v3Selection.y - v3searchLocation.y) < precisionErrorNumber &&
|
|
abs(v3Selection.z - v3searchLocation.z) < precisionErrorNumber)
|
|
{
|
|
return con_no;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
const char* TrainTrackSystem::mTrackTypeFilenames[LC_TTS_NUMITEMS] =
|
|
{
|
|
"74746.dat", // LC_TTS_STRAIGHT,
|
|
"74747.dat", // LC_TTS_CURVED,
|
|
"32087.dat", // LC_TTS_CROSS,
|
|
"2861c04.dat", // LC_TTS_LEFT_BRANCH,
|
|
"2859c04.dat" // LC_TTS_RIGHT_BRANCH
|
|
};
|
|
|
|
|
|
TrainTrackSystem::TrainTrackSystem()
|
|
: mModel(new lcModel(QString(), nullptr, false))
|
|
{
|
|
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
|
|
|
float xHalfBendOff = sin(LC_DTOR * 11.25) * 800;
|
|
float yHalfBendOff = ((cos(LC_DTOR * 11.25) * 800) - 800);
|
|
|
|
float x_left_branch = 320 + 320 + 0 + (-(sin(LC_DTOR * 22.5)*800));
|
|
float y_left_branch = 0 + 0 + 320 + ((cos(LC_DTOR * 22.5)*800)-800);
|
|
|
|
float x_right_branch = 320 + 320 + 0 + (-(sin(LC_DTOR * 22.5)*800));
|
|
float y_right_branch = 0 + 0 - 320 - ((cos(LC_DTOR * 22.5)*800)-800);
|
|
|
|
TrainTrackType *trackType;
|
|
|
|
trainTrackTypes.reserve(LC_TTS_NUMITEMS);
|
|
|
|
// straight
|
|
trackType = new TrainTrackType();
|
|
trackType->Load(Library,mTrackTypeFilenames[LC_TTS_STRAIGHT]);
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(0,160,0));
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(180,-160,0));
|
|
trainTrackTypes[LC_TTS_STRAIGHT] = trackType;
|
|
|
|
// curved
|
|
trackType = new TrainTrackType();
|
|
trackType->Load(Library,mTrackTypeFilenames[LC_TTS_CURVED]);
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(-11.25,xHalfBendOff,yHalfBendOff));
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(-168.75,-xHalfBendOff,yHalfBendOff));
|
|
trainTrackTypes[LC_TTS_CURVED] = trackType;
|
|
|
|
// Crossing
|
|
trackType = new TrainTrackType();
|
|
trackType->Load(Library,mTrackTypeFilenames[LC_TTS_CROSS]);
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(0,160,0));
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(90,0,160));
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(180,-160,0));
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(-90,0,-160));
|
|
trainTrackTypes[LC_TTS_CROSS] = trackType;
|
|
|
|
// Left branch
|
|
trackType = new TrainTrackType();
|
|
trackType->Load(Library,mTrackTypeFilenames[LC_TTS_LEFT_BRANCH]);
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(0,320,0));
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(22.50,x_left_branch,y_left_branch));
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(180,-320,0));
|
|
trainTrackTypes[LC_TTS_LEFT_BRANCH] = trackType;
|
|
|
|
// Right branch
|
|
trackType = new TrainTrackType();
|
|
trackType->Load(Library,mTrackTypeFilenames[LC_TTS_RIGHT_BRANCH]);
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(0,320,0));
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(180,-320,0));
|
|
trackType->AddConnection(new TrainTrackConnectionPoint(-22.50,x_right_branch,y_right_branch));
|
|
trainTrackTypes[LC_TTS_RIGHT_BRANCH] = trackType;
|
|
|
|
// Create map for lookup track type by name
|
|
for(int i = 0; i < LC_TTS_NUMITEMS; i++) trackTypesByName.insert({mTrackTypeFilenames[i], static_cast<LC_TTS_TYPES>(i)});
|
|
}
|
|
|
|
|
|
TrainTrackSystem::~TrainTrackSystem() {}
|
|
|
|
void TrainTrackSystem::setColorIndex(int mColorIndex) {
|
|
this->mColorIndex = mColorIndex;
|
|
}
|
|
|
|
void TrainTrackSystem::setCurrentStep(int mCurrentStep) {
|
|
this->mCurrentStep = mCurrentStep;
|
|
}
|
|
|
|
void TrainTrackSystem::addFirstTrackSection(lcMatrix44 position, enum LC_TTS_TYPES trackTypeId) {
|
|
TrainTrackType* trainTrackType = trainTrackTypes[trackTypeId];
|
|
trackSections.push_back(new TrainTrackSection(trainTrackType, trackTypeId,position, mCurrentStep, mColorIndex));
|
|
}
|
|
|
|
void TrainTrackSystem::addTrackSection(int fromTrackSectionIdx, int fromTrackSectionConnectionIdx, enum LC_TTS_TYPES toTrackType, int toTrackTypeConnectionIdx)
|
|
{
|
|
TrainTrackSection* fromTrackSection = trackSections[fromTrackSectionIdx];
|
|
TrainTrackType* fromTrack = trainTrackTypes[fromTrackSection->trackTypeId];
|
|
TrainTrackConnectionPoint * fromConnectIdx = fromTrack->GetConnection(fromTrackSectionConnectionIdx);
|
|
TrainTrackType* toTrack = trainTrackTypes[toTrackType];
|
|
TrainTrackConnectionPoint * toConnectIdx = toTrack->GetConnection(toTrackTypeConnectionIdx);
|
|
|
|
lcMatrix44 currentLocation = fromTrackSection->location;
|
|
lcMatrix44 mat44;
|
|
lcMatrix44 matOffset;
|
|
|
|
// calculate position on exiting connection point
|
|
mat44 = lcMatrix44Identity();
|
|
mat44 = lcMatrix44RotationZ(LC_DTOR * fromConnectIdx->angle);
|
|
|
|
matOffset = lcMatrix44Identity();
|
|
matOffset.SetTranslation(lcVector3(fromConnectIdx->xy_coordinate.x, fromConnectIdx->xy_coordinate.y,0));
|
|
|
|
matOffset = lcMul(mat44, matOffset);
|
|
|
|
currentLocation = lcMul(matOffset,currentLocation);
|
|
|
|
// calculate position on entering new track section
|
|
mat44 = lcMatrix44Identity();
|
|
mat44 = lcMatrix44RotationZ(LC_DTOR * (180 - toConnectIdx->angle));
|
|
|
|
matOffset = lcMatrix44Identity();
|
|
matOffset.SetTranslation(lcVector3(-toConnectIdx->xy_coordinate.x, -toConnectIdx->xy_coordinate.y,0));
|
|
|
|
matOffset = lcMul(matOffset,mat44);
|
|
|
|
currentLocation = lcMul(matOffset,currentLocation);
|
|
|
|
trackSections.push_back(new TrainTrackSection(toTrack, toTrackType,currentLocation, mCurrentStep, mColorIndex));
|
|
}
|
|
|
|
|
|
void TrainTrackSystem::addTrackSection(TrainTrackSection* fromTrackSection, int fromTrackSectionConnectionIdx, enum LC_TTS_TYPES toTrackType, int toTrackTypeConnectionIdx)
|
|
{
|
|
TrainTrackType* fromTrack = trainTrackTypes[fromTrackSection->trackTypeId];
|
|
TrainTrackConnectionPoint * fromConnectIdx = fromTrack->GetConnection(fromTrackSectionConnectionIdx);
|
|
TrainTrackType* toTrack = trainTrackTypes[toTrackType];
|
|
TrainTrackConnectionPoint * toConnectIdx = toTrack->GetConnection(toTrackTypeConnectionIdx);
|
|
|
|
lcMatrix44 currentLocation = fromTrackSection->location;
|
|
lcMatrix44 mat44;
|
|
lcMatrix44 matOffset;
|
|
|
|
// calculate position on exiting connection point
|
|
mat44 = lcMatrix44Identity();
|
|
mat44 = lcMatrix44RotationZ(LC_DTOR * fromConnectIdx->angle);
|
|
|
|
matOffset = lcMatrix44Identity();
|
|
matOffset.SetTranslation(lcVector3(fromConnectIdx->xy_coordinate.x, fromConnectIdx->xy_coordinate.y,0));
|
|
|
|
matOffset = lcMul(mat44, matOffset);
|
|
|
|
currentLocation = lcMul(matOffset,currentLocation);
|
|
|
|
// calculate position on entering new track section
|
|
mat44 = lcMatrix44Identity();
|
|
mat44 = lcMatrix44RotationZ(LC_DTOR * (180 - toConnectIdx->angle));
|
|
|
|
matOffset = lcMatrix44Identity();
|
|
matOffset.SetTranslation(lcVector3(-toConnectIdx->xy_coordinate.x, -toConnectIdx->xy_coordinate.y,0));
|
|
|
|
matOffset = lcMul(matOffset,mat44);
|
|
|
|
currentLocation = lcMul(matOffset,currentLocation);
|
|
|
|
trackSections.push_back(new TrainTrackSection(toTrack, toTrackType,currentLocation, mCurrentStep, mColorIndex));
|
|
}
|
|
|
|
bool TrainTrackSystem::deleteTrackSection(lcPiece* piece)
|
|
{
|
|
float precisionErrorNumber = 0.001;
|
|
lcVector3 vec3PieceDel = piece->GetRotationCenter();
|
|
|
|
for(unsigned long i = 0; i < trackSections.size(); i++) {
|
|
|
|
lcVector3 vec3PieceCur = trackSections[i]->location.GetTranslation();
|
|
|
|
if(abs(vec3PieceDel.x - vec3PieceCur.x) < precisionErrorNumber &&
|
|
abs(vec3PieceDel.y - vec3PieceCur.y) < precisionErrorNumber &&
|
|
abs(vec3PieceDel.z - vec3PieceCur.z) < precisionErrorNumber)
|
|
{
|
|
trackSections.erase(trackSections.begin() + i);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
std::vector<PieceInfo *> TrainTrackSystem::getTrackTypes()
|
|
{
|
|
std::vector<PieceInfo*> trackTypes;
|
|
for(int i = 0; i < LC_TTS_NUMITEMS; i++) {
|
|
trackTypes.push_back(trainTrackTypes[i]->pieceInfo);
|
|
}
|
|
return trackTypes;
|
|
}
|
|
|
|
std::vector<TrainTrackSection*> TrainTrackSystem::GetTrackSections()
|
|
{
|
|
return trackSections;
|
|
}
|
|
|
|
std::vector<TrainTrackSection*>* TrainTrackSystem::GetTrackSectionsPtr()
|
|
{
|
|
return &trackSections;
|
|
}
|
|
|
|
std::vector<lcPiece*> TrainTrackSystem::GetPieces()
|
|
{
|
|
std::vector<lcPiece*> pieces;
|
|
PieceInfo* pieceInfo;
|
|
|
|
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
|
PieceInfo* pieceInfoSel = Library->FindPiece("3023.dat", nullptr, false, false);
|
|
|
|
TrainTrackSection* trackSection;
|
|
lcPiece* piece;
|
|
|
|
for(unsigned long i = 0; i < trackSections.size(); i++)
|
|
{
|
|
trackSection = trackSections[i];
|
|
pieceInfo = trainTrackTypes[trackSection->trackTypeId]->pieceInfo;
|
|
piece = new lcPiece(pieceInfo);
|
|
piece->Initialize(trackSection->location, trackSection->mCurrentStep);
|
|
piece->SetColorIndex(trackSection->mColorIndex);
|
|
pieces.push_back(piece);
|
|
|
|
// Add 1 x 2 plate on each connecton point, for detect selection
|
|
lcMatrix44 mat44;
|
|
lcMatrix44 matOffset;
|
|
|
|
for(int con_no = 0; con_no < trackSection->GetNoOfConnections(); con_no++)
|
|
{
|
|
mat44 = trackSection->GetConnectionLocation(con_no);
|
|
|
|
matOffset = lcMatrix44Identity();
|
|
matOffset.SetTranslation(lcVector3(-10, 0, 8));
|
|
|
|
mat44 = lcMul(matOffset,mat44);
|
|
|
|
matOffset = lcMatrix44Identity();
|
|
matOffset = lcMatrix44RotationZ(LC_DTOR * 90);
|
|
|
|
mat44 = lcMul(matOffset,mat44);
|
|
|
|
piece = new lcPiece(pieceInfoSel);
|
|
piece->Initialize(mat44, trackSection->mCurrentStep);
|
|
piece->SetColorIndex(trackSection->mColorIndex);
|
|
//pieces.Add(piece);
|
|
pieces.push_back(piece);
|
|
}
|
|
}
|
|
return pieces;
|
|
}
|
|
|
|
lcModel* TrainTrackSystem::GetModel()
|
|
{
|
|
std::vector<lcPiece*> trackSystem = this->GetPieces();
|
|
mModel->SetTrainTrackSystem(trackSystem);
|
|
return mModel.get();
|
|
}
|
|
|
|
void TrainTrackSystem::SetModel()
|
|
{
|
|
std::vector<lcPiece*> trackSystem = this->GetPieces();
|
|
mModel->SetTrainTrackSystem(trackSystem);
|
|
}
|
|
|
|
|
|
LC_TTS_TYPES TrainTrackSystem::findTrackTypeByString(const char *tracktypeName)
|
|
{
|
|
std::string str_search = tracktypeName;
|
|
std::map<std::string ,LC_TTS_TYPES>::iterator search = trackTypesByName.find(str_search);
|
|
if (search != trackTypesByName.end()) {
|
|
return search->second;
|
|
}
|
|
return static_cast<LC_TTS_TYPES>(-1);
|
|
}
|