fix(physics): prevent double-joining
This commit is contained in:
parent
e35c895233
commit
587629fcdd
3 changed files with 30 additions and 7 deletions
|
@ -259,6 +259,26 @@ SurfaceType Part::surfaceFromFace(NormalId face) {
|
||||||
return SurfaceSmooth; // Unreachable
|
return SurfaceSmooth; // Unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Part::checkJointContinuinty(std::shared_ptr<Part> otherPart) {
|
||||||
|
// Make sure that the two parts don't depend on one another
|
||||||
|
|
||||||
|
if (shared<Part>() == otherPart) return false;
|
||||||
|
|
||||||
|
for (auto joint : primaryJoints) {
|
||||||
|
if (joint.expired() || joint.lock()->part1.expired()) continue;
|
||||||
|
if (!joint.lock()->part1.lock()->checkJointContinuinty(otherPart))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto joint : secondaryJoints) {
|
||||||
|
if (joint.expired() || joint.lock()->part0.expired()) continue;
|
||||||
|
if (!joint.lock()->part0.lock()->checkJointContinuinty(otherPart))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Part::MakeJoints() {
|
void Part::MakeJoints() {
|
||||||
// Algorithm: Find nearby parts
|
// Algorithm: Find nearby parts
|
||||||
// Make sure parts are not dependant on each other (via primary/secondaryJoints)
|
// Make sure parts are not dependant on each other (via primary/secondaryJoints)
|
||||||
|
@ -290,6 +310,7 @@ void Part::MakeJoints() {
|
||||||
float dot = myWorldNormal.Dot(otherWorldNormal);
|
float dot = myWorldNormal.Dot(otherWorldNormal);
|
||||||
if (dot > -0.99) continue; // Surface is pointing opposite to ours
|
if (dot > -0.99) continue; // Surface is pointing opposite to ours
|
||||||
if (abs(surfacePointLocalToMyFrame.Z()) > 0.05) continue; // Surfaces are within 0.05 studs of one another
|
if (abs(surfacePointLocalToMyFrame.Z()) > 0.05) continue; // Surfaces are within 0.05 studs of one another
|
||||||
|
if (!checkJointContinuinty(otherPart)) continue;
|
||||||
|
|
||||||
SurfaceType mySurface = surfaceFromFace(faceFromNormal(myFace));
|
SurfaceType mySurface = surfaceFromFace(faceFromNormal(myFace));
|
||||||
SurfaceType otherSurface = surfaceFromFace(faceFromNormal(otherFace));
|
SurfaceType otherSurface = surfaceFromFace(faceFromNormal(otherFace));
|
||||||
|
@ -307,7 +328,7 @@ void Part::MakeJoints() {
|
||||||
dataModel().value()->GetService<JointsService>()->AddChild(joint);
|
dataModel().value()->GetService<JointsService>()->AddChild(joint);
|
||||||
joint->UpdateProperty("Part0");
|
joint->UpdateProperty("Part0");
|
||||||
|
|
||||||
printf("Made joint between %s and %s!\n", name.c_str(), otherPart->name.c_str());
|
Logger::debugf("Made joint between %s and %s!\n", name.c_str(), otherPart->name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ protected:
|
||||||
void untrackJoint(std::shared_ptr<Snap>);
|
void untrackJoint(std::shared_ptr<Snap>);
|
||||||
|
|
||||||
SurfaceType surfaceFromFace(NormalId);
|
SurfaceType surfaceFromFace(NormalId);
|
||||||
|
bool checkJointContinuinty(std::shared_ptr<Part>);
|
||||||
|
|
||||||
friend Snap;
|
friend Snap;
|
||||||
|
|
||||||
|
|
|
@ -368,18 +368,18 @@ void MainWindow::connectActionHandlers() {
|
||||||
|
|
||||||
connect(ui->actionSave, &QAction::triggered, this, [&]() {
|
connect(ui->actionSave, &QAction::triggered, this, [&]() {
|
||||||
std::optional<std::string> path;
|
std::optional<std::string> path;
|
||||||
if (!gDataModel->HasFile())
|
if (!editModeDataModel->HasFile())
|
||||||
path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptSave, QString::fromStdString("Save " + gDataModel->name));
|
path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptSave, QString::fromStdString("Save " + editModeDataModel->name));
|
||||||
if (!gDataModel->HasFile() && (!path || path == "")) return;
|
if (!editModeDataModel->HasFile() && (!path || path == "")) return;
|
||||||
|
|
||||||
gDataModel->SaveToFile(path);
|
editModeDataModel->SaveToFile(path);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->actionSaveAs, &QAction::triggered, this, [&]() {
|
connect(ui->actionSaveAs, &QAction::triggered, this, [&]() {
|
||||||
std::optional<std::string> path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptSave, QString::fromStdString("Save as " + gDataModel->name));
|
std::optional<std::string> path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptSave, QString::fromStdString("Save as " + editModeDataModel->name));
|
||||||
if (!path || path == "") return;
|
if (!path || path == "") return;
|
||||||
|
|
||||||
gDataModel->SaveToFile(path);
|
editModeDataModel->SaveToFile(path);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->actionOpen, &QAction::triggered, this, [&]() {
|
connect(ui->actionOpen, &QAction::triggered, this, [&]() {
|
||||||
|
@ -391,6 +391,7 @@ void MainWindow::connectActionHandlers() {
|
||||||
|
|
||||||
// simulationInit();
|
// simulationInit();
|
||||||
std::shared_ptr<DataModel> newModel = DataModel::LoadFromFile(path.value());
|
std::shared_ptr<DataModel> newModel = DataModel::LoadFromFile(path.value());
|
||||||
|
editModeDataModel = newModel;
|
||||||
gDataModel = newModel;
|
gDataModel = newModel;
|
||||||
newModel->Init();
|
newModel->Init();
|
||||||
ui->explorerView->updateRoot(newModel);
|
ui->explorerView->updateRoot(newModel);
|
||||||
|
|
Loading…
Add table
Reference in a new issue