13 Joint2D *sliderPin, Joint2D *slider,
int ratchetDirection,
14 float engagementTorque)
20 sliderPin_(sliderPin),
22 ratchetDirection_(ratchetDirection),
23 engagementTorque_(engagementTorque) {}
27std::string Mechanism2D::getKind()
const {
29 case Kind::CrankSlider:
return "crankSlider";
30 case Kind::Shaft:
return "shaft";
31 case Kind::Ratchet:
return "ratchet";
36bool Mechanism2D::isValid()
const {
37 if (!world_ || !drive_ || !drive_->isValid())
return false;
38 if (kind_ == Kind::CrankSlider) {
39 return crankPin_ && crankPin_->isValid() && sliderPin_ && sliderPin_->isValid() && slider_ &&
45void Mechanism2D::requireKind(Kind expected,
const char *
operation)
const {
50float Mechanism2D::getDriveAngle()
const {
51 if (!isValid())
throw eve::Exception(
"Mechanism2D.getDriveAngle: mechanism destroyed");
52 return drive_->getRevoluteAngle();
55float Mechanism2D::getSliderTranslation()
const {
56 requireKind(Kind::CrankSlider,
"Mechanism2D.getSliderTranslation");
57 return slider_->getPrismaticTranslation();
60float Mechanism2D::axisSpinSpeed()
const {
61 if (!isValid() || !drive_)
return 0.f;
62 return drive_->getRevoluteSpeed();
65float Mechanism2D::getSpinSpeed()
const {
66 if (!isValid())
throw eve::Exception(
"Mechanism2D.getSpinSpeed: mechanism destroyed");
67 return axisSpinSpeed();
70void Mechanism2D::setDrive(
float speed,
float maxTorque) {
71 if (!isValid())
throw eve::Exception(
"Mechanism2D.setDrive: mechanism destroyed");
72 if (!std::isfinite(speed))
throw eve::Exception(
"Mechanism2D.setDrive: speed must be finite");
73 if (!std::isfinite(maxTorque) || maxTorque < 0.f)
74 throw eve::Exception(
"Mechanism2D.setDrive: maxTorque must be finite and >= 0");
77 driveMaxTorque_ = maxTorque;
78 if (kind_ != Kind::Ratchet) drive_->setRevoluteMotor(
true, speed, maxTorque);
81void Mechanism2D::clearDrive() {
82 if (!isValid())
throw eve::Exception(
"Mechanism2D.clearDrive: mechanism destroyed");
83 driveEnabled_ =
false;
85 driveMaxTorque_ = 0.f;
86 if (kind_ != Kind::Ratchet) drive_->setRevoluteMotor(
false, 0.f, 0.f);
89void Mechanism2D::setRatchetDirection(
int direction) {
90 requireKind(Kind::Ratchet,
"Mechanism2D.setRatchetDirection");
92 throw eve::Exception(
"Mechanism2D.setRatchetDirection: direction must be +1 or -1");
96void Mechanism2D::setRatchetEngagementTorque(
float torque) {
97 requireKind(Kind::Ratchet,
"Mechanism2D.setRatchetEngagementTorque");
98 if (!std::isfinite(torque) || torque < 0.f)
100 "Mechanism2D.setRatchetEngagementTorque: torque must be finite and >= 0");
101 engagementTorque_ = torque;
104void Mechanism2D::syncBeforeStep() {
105 if (kind_ != Kind::Ratchet || !isValid())
return;
106 const float signedSpeed = axisSpinSpeed() *
static_cast<float>(ratchetDirection_);
107 if (signedSpeed < -1e-3f) {
108 drive_->setRevoluteMotor(
true, 0.f, engagementTorque_);
112 const float driveSpeed = std::fabs(driveSpeed_) *
static_cast<float>(ratchetDirection_);
113 drive_->setRevoluteMotor(
true, driveSpeed, driveMaxTorque_);
115 drive_->setRevoluteMotor(
false, 0.f, 0.f);
119void Mechanism2D::invalidate() {
120 if (world_) world_->forgetMechanism(
this);
124 sliderPin_ =
nullptr;
128void Mechanism2D::destroy() {
129 if (drive_ && drive_->isValid()) drive_->destroy();
130 if (crankPin_ && crankPin_->isValid()) crankPin_->destroy();
131 if (sliderPin_ && sliderPin_->isValid()) sliderPin_->destroy();
132 if (slider_ && slider_->isValid()) slider_->destroy();
133 if (world_) world_->forgetMechanism(
this);
ActionParameterOperation operation
RoadLaneDirection direction
EVENGINE_API_FOUNDATION public API.
Mechanism2D(const Mechanism2D &)=delete
Optional physics backend for vehicle mobility and body attach.
ControlEdit slider(const char *label, float &value, float minimum, float maximum, const char *format="%.3f")
Shared immediate renderer for scalar sliders.