13 Joint3D *sliderPin, Joint3D *slider,
float axisX,
float axisY,
float axisZ,
14 int ratchetDirection,
float engagementTorque)
20 sliderPin_(sliderPin),
25 ratchetDirection_(ratchetDirection),
26 engagementTorque_(engagementTorque) {}
30std::string Mechanism3D::getKind()
const {
32 case Kind::CrankSlider:
return "crankSlider";
33 case Kind::Shaft:
return "shaft";
34 case Kind::Ratchet:
return "ratchet";
39bool Mechanism3D::isValid()
const {
40 if (!world_ || !drive_ || !drive_->isValid())
return false;
41 if (kind_ == Kind::CrankSlider) {
42 return crankPin_ && crankPin_->isValid() && sliderPin_ && sliderPin_->isValid() && slider_ &&
48void Mechanism3D::requireKind(Kind expected,
const char *
operation)
const {
53float Mechanism3D::getDriveAngle()
const {
54 if (!isValid())
throw eve::Exception(
"Mechanism3D.getDriveAngle: mechanism destroyed");
55 return drive_->getRevoluteAngle();
58float Mechanism3D::getSliderTranslation()
const {
59 requireKind(Kind::CrankSlider,
"Mechanism3D.getSliderTranslation");
60 return slider_->getPrismaticTranslation();
63float Mechanism3D::axisSpinSpeed()
const {
64 if (!isValid() || !drive_)
return 0.f;
65 Body3D *bodyA = world_ ? world_->findBodyById(drive_->getBodyAId()) :
nullptr;
66 Body3D *bodyB = world_ ? world_->findBodyById(drive_->getBodyBId()) :
nullptr;
67 if (!bodyA || !bodyB || !bodyA->
isValid() || !bodyB->
isValid())
return 0.f;
71 return wx * axisX_ +
wy * axisY_ +
wz * axisZ_;
74float Mechanism3D::getSpinSpeed()
const {
75 if (!isValid())
throw eve::Exception(
"Mechanism3D.getSpinSpeed: mechanism destroyed");
76 return axisSpinSpeed();
79void Mechanism3D::setDrive(
float speed,
float maxTorque) {
80 if (!isValid())
throw eve::Exception(
"Mechanism3D.setDrive: mechanism destroyed");
81 if (!std::isfinite(speed))
throw eve::Exception(
"Mechanism3D.setDrive: speed must be finite");
82 if (!std::isfinite(maxTorque) || maxTorque < 0.f)
83 throw eve::Exception(
"Mechanism3D.setDrive: maxTorque must be finite and >= 0");
86 driveMaxTorque_ = maxTorque;
87 if (kind_ != Kind::Ratchet) {
88 drive_->setRevoluteMotor(
true, speed, maxTorque);
92void Mechanism3D::clearDrive() {
93 if (!isValid())
throw eve::Exception(
"Mechanism3D.clearDrive: mechanism destroyed");
94 driveEnabled_ =
false;
96 driveMaxTorque_ = 0.f;
97 if (kind_ != Kind::Ratchet) {
98 drive_->setRevoluteMotor(
false, 0.f, 0.f);
103 requireKind(Kind::Ratchet,
"Mechanism3D.setRatchetDirection");
105 throw eve::Exception(
"Mechanism3D.setRatchetDirection: direction must be +1 or -1");
109void Mechanism3D::setRatchetEngagementTorque(
float torque) {
110 requireKind(Kind::Ratchet,
"Mechanism3D.setRatchetEngagementTorque");
111 if (!std::isfinite(torque) || torque < 0.f)
113 "Mechanism3D.setRatchetEngagementTorque: torque must be finite and >= 0");
114 engagementTorque_ = torque;
117void Mechanism3D::syncBeforeStep() {
118 if (kind_ != Kind::Ratchet || !isValid())
return;
119 const float signedSpeed = axisSpinSpeed() *
static_cast<float>(ratchetDirection_);
120 if (signedSpeed < -1e-3f) {
121 drive_->setRevoluteMotor(
true, 0.f, engagementTorque_);
125 const float driveSpeed = std::fabs(driveSpeed_) *
static_cast<float>(ratchetDirection_);
126 drive_->setRevoluteMotor(
true, driveSpeed, driveMaxTorque_);
128 drive_->setRevoluteMotor(
false, 0.f, 0.f);
132void Mechanism3D::invalidate() {
133 if (world_) world_->forgetMechanism(
this);
137 sliderPin_ =
nullptr;
141void Mechanism3D::destroy() {
142 if (drive_ && drive_->isValid()) drive_->destroy();
143 if (crankPin_ && crankPin_->isValid()) crankPin_->destroy();
144 if (sliderPin_ && sliderPin_->isValid()) sliderPin_->destroy();
145 if (slider_ && slider_->isValid()) slider_->destroy();
146 if (world_) world_->forgetMechanism(
this);
ActionParameterOperation operation
RoadLaneDirection direction
EVENGINE_API_FOUNDATION public API.
3D rigid body (Box3D) in meter-space coordinates (+Y up by convention). Owned by a World3D; create pr...
bool isValid() const
True while the underlying Box3D body is still alive.
float getAngularVelocityZ() const
Returns the angular velocity z.
float getAngularVelocityX() const
Returns the angular velocity x.
float getAngularVelocityY() const
Returns the angular velocity y.
Mechanism3D(const Mechanism3D &)=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.