载入中...
搜索中...
未找到
Mechanism2D.cpp
浏览该文件的文档.
2
3#include "physics/Body.h"
4#include "physics/Joint2D.h"
5#include "physics/World.h"
6#include "common/Exception.h"
7
8#include <cmath>
9
10namespace eve::physics {
11
12Mechanism2D::Mechanism2D(World *world, Kind kind, int id, Joint2D *drive, Joint2D *crankPin,
13 Joint2D *sliderPin, Joint2D *slider, int ratchetDirection,
14 float engagementTorque)
15 : world_(world),
16 kind_(kind),
17 id_(id),
18 drive_(drive),
19 crankPin_(crankPin),
20 sliderPin_(sliderPin),
21 slider_(slider),
22 ratchetDirection_(ratchetDirection),
23 engagementTorque_(engagementTorque) {}
24
25Mechanism2D::~Mechanism2D() { destroy(); }
26
27std::string Mechanism2D::getKind() const {
28 switch (kind_) {
29 case Kind::CrankSlider: return "crankSlider";
30 case Kind::Shaft: return "shaft";
31 case Kind::Ratchet: return "ratchet";
32 }
33 return "shaft";
34}
35
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_ &&
40 slider_->isValid();
41 }
42 return true;
43}
44
45void Mechanism2D::requireKind(Kind expected, const char *operation) const {
46 if (!isValid()) throw eve::Exception("%s: mechanism destroyed", operation);
47 if (kind_ != expected) throw eve::Exception("%s: incompatible mechanism kind", operation);
48}
49
50float Mechanism2D::getDriveAngle() const {
51 if (!isValid()) throw eve::Exception("Mechanism2D.getDriveAngle: mechanism destroyed");
52 return drive_->getRevoluteAngle();
53}
54
55float Mechanism2D::getSliderTranslation() const {
56 requireKind(Kind::CrankSlider, "Mechanism2D.getSliderTranslation");
57 return slider_->getPrismaticTranslation();
58}
59
60float Mechanism2D::axisSpinSpeed() const {
61 if (!isValid() || !drive_) return 0.f;
62 return drive_->getRevoluteSpeed();
63}
64
65float Mechanism2D::getSpinSpeed() const {
66 if (!isValid()) throw eve::Exception("Mechanism2D.getSpinSpeed: mechanism destroyed");
67 return axisSpinSpeed();
68}
69
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");
75 driveEnabled_ = true;
76 driveSpeed_ = speed;
77 driveMaxTorque_ = maxTorque;
78 if (kind_ != Kind::Ratchet) drive_->setRevoluteMotor(true, speed, maxTorque);
79}
80
81void Mechanism2D::clearDrive() {
82 if (!isValid()) throw eve::Exception("Mechanism2D.clearDrive: mechanism destroyed");
83 driveEnabled_ = false;
84 driveSpeed_ = 0.f;
85 driveMaxTorque_ = 0.f;
86 if (kind_ != Kind::Ratchet) drive_->setRevoluteMotor(false, 0.f, 0.f);
87}
88
89void Mechanism2D::setRatchetDirection(int direction) {
90 requireKind(Kind::Ratchet, "Mechanism2D.setRatchetDirection");
91 if (direction != 1 && direction != -1)
92 throw eve::Exception("Mechanism2D.setRatchetDirection: direction must be +1 or -1");
93 ratchetDirection_ = direction;
94}
95
96void Mechanism2D::setRatchetEngagementTorque(float torque) {
97 requireKind(Kind::Ratchet, "Mechanism2D.setRatchetEngagementTorque");
98 if (!std::isfinite(torque) || torque < 0.f)
99 throw eve::Exception(
100 "Mechanism2D.setRatchetEngagementTorque: torque must be finite and >= 0");
101 engagementTorque_ = torque;
102}
103
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_);
109 return;
110 }
111 if (driveEnabled_) {
112 const float driveSpeed = std::fabs(driveSpeed_) * static_cast<float>(ratchetDirection_);
113 drive_->setRevoluteMotor(true, driveSpeed, driveMaxTorque_);
114 } else {
115 drive_->setRevoluteMotor(false, 0.f, 0.f);
116 }
117}
118
119void Mechanism2D::invalidate() {
120 if (world_) world_->forgetMechanism(this);
121 world_ = nullptr;
122 drive_ = nullptr;
123 crankPin_ = nullptr;
124 sliderPin_ = nullptr;
125 slider_ = nullptr;
126}
127
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);
134 invalidate();
135}
136
137} // namespace eve::physics
ActionParameterOperation operation
void(* destroy)(void *)
TokenKind kind
World3D * world
std::string id
Definition PlayHost.cpp:108
RoadLaneDirection direction
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
Mechanism2D(const Mechanism2D &)=delete
Optional physics backend for vehicle mobility and body attach.
Definition Climbing.h:36
ControlEdit slider(const char *label, float &value, float minimum, float maximum, const char *format="%.3f")
Shared immediate renderer for scalar sliders.