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
|
||||
}
|
||||
|
||||
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() {
|
||||
// Algorithm: Find nearby parts
|
||||
// Make sure parts are not dependant on each other (via primary/secondaryJoints)
|
||||
|
@ -290,6 +310,7 @@ void Part::MakeJoints() {
|
|||
float dot = myWorldNormal.Dot(otherWorldNormal);
|
||||
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 (!checkJointContinuinty(otherPart)) continue;
|
||||
|
||||
SurfaceType mySurface = surfaceFromFace(faceFromNormal(myFace));
|
||||
SurfaceType otherSurface = surfaceFromFace(faceFromNormal(otherFace));
|
||||
|
@ -307,7 +328,7 @@ void Part::MakeJoints() {
|
|||
dataModel().value()->GetService<JointsService>()->AddChild(joint);
|
||||
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>);
|
||||
|
||||
SurfaceType surfaceFromFace(NormalId);
|
||||
bool checkJointContinuinty(std::shared_ptr<Part>);
|
||||
|
||||
friend Snap;
|
||||
|
||||
|
|
|
@ -368,18 +368,18 @@ void MainWindow::connectActionHandlers() {
|
|||
|
||||
connect(ui->actionSave, &QAction::triggered, this, [&]() {
|
||||
std::optional<std::string> path;
|
||||
if (!gDataModel->HasFile())
|
||||
path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptSave, QString::fromStdString("Save " + gDataModel->name));
|
||||
if (!gDataModel->HasFile() && (!path || path == "")) return;
|
||||
if (!editModeDataModel->HasFile())
|
||||
path = openFileDialog("Openblocks Level (*.obl)", ".obl", QFileDialog::AcceptSave, QString::fromStdString("Save " + editModeDataModel->name));
|
||||
if (!editModeDataModel->HasFile() && (!path || path == "")) return;
|
||||
|
||||
gDataModel->SaveToFile(path);
|
||||
editModeDataModel->SaveToFile(path);
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
gDataModel->SaveToFile(path);
|
||||
editModeDataModel->SaveToFile(path);
|
||||
});
|
||||
|
||||
connect(ui->actionOpen, &QAction::triggered, this, [&]() {
|
||||
|
@ -391,6 +391,7 @@ void MainWindow::connectActionHandlers() {
|
|||
|
||||
// simulationInit();
|
||||
std::shared_ptr<DataModel> newModel = DataModel::LoadFromFile(path.value());
|
||||
editModeDataModel = newModel;
|
||||
gDataModel = newModel;
|
||||
newModel->Init();
|
||||
ui->explorerView->updateRoot(newModel);
|
||||
|
|
Loading…
Add table
Reference in a new issue