载入中...
搜索中...
未找到
Mechanism3D.cpp
浏览该文件的文档.
2
3#include "physics/Body3D.h"
4#include "physics/Joint3D.h"
5#include "physics/World3D.h"
6#include "common/Exception.h"
7
8#include <cmath>
9
10namespace eve::physics {
11
12Mechanism3D::Mechanism3D(World3D *world, Kind kind, int id, Joint3D *drive, Joint3D *crankPin,
13 Joint3D *sliderPin, Joint3D *slider, float axisX, float axisY, float axisZ,
14 int ratchetDirection, float engagementTorque)
15 : world_(world),
16 kind_(kind),
17 id_(id),
18 drive_(drive),
19 crankPin_(crankPin),
20 sliderPin_(sliderPin),
21 slider_(slider),
22 axisX_(axisX),
23 axisY_(axisY),
24 axisZ_(axisZ),
25 ratchetDirection_(ratchetDirection),
26 engagementTorque_(engagementTorque) {}
27
28Mechanism3D::~Mechanism3D() { destroy(); }
29
30std::string Mechanism3D::getKind() const {
31 switch (kind_) {
32 case Kind::CrankSlider: return "crankSlider";
33 case Kind::Shaft: return "shaft";
34 case Kind::Ratchet: return "ratchet";
35 }
36 return "shaft";
37}
38
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_ &&
43 slider_->isValid();
44 }
45 return true;
46}
47
48void Mechanism3D::requireKind(Kind expected, const char *operation) const {
49 if (!isValid()) throw eve::Exception("%s: mechanism destroyed", operation);
50 if (kind_ != expected) throw eve::Exception("%s: incompatible mechanism kind", operation);
51}
52
53float Mechanism3D::getDriveAngle() const {
54 if (!isValid()) throw eve::Exception("Mechanism3D.getDriveAngle: mechanism destroyed");
55 return drive_->getRevoluteAngle();
56}
57
58float Mechanism3D::getSliderTranslation() const {
59 requireKind(Kind::CrankSlider, "Mechanism3D.getSliderTranslation");
60 return slider_->getPrismaticTranslation();
61}
62
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;
68 const float wx = bodyB->getAngularVelocityX() - bodyA->getAngularVelocityX();
69 const float wy = bodyB->getAngularVelocityY() - bodyA->getAngularVelocityY();
70 const float wz = bodyB->getAngularVelocityZ() - bodyA->getAngularVelocityZ();
71 return wx * axisX_ + wy * axisY_ + wz * axisZ_;
72}
73
74float Mechanism3D::getSpinSpeed() const {
75 if (!isValid()) throw eve::Exception("Mechanism3D.getSpinSpeed: mechanism destroyed");
76 return axisSpinSpeed();
77}
78
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");
84 driveEnabled_ = true;
85 driveSpeed_ = speed;
86 driveMaxTorque_ = maxTorque;
87 if (kind_ != Kind::Ratchet) {
88 drive_->setRevoluteMotor(true, speed, maxTorque);
89 }
90}
91
92void Mechanism3D::clearDrive() {
93 if (!isValid()) throw eve::Exception("Mechanism3D.clearDrive: mechanism destroyed");
94 driveEnabled_ = false;
95 driveSpeed_ = 0.f;
96 driveMaxTorque_ = 0.f;
97 if (kind_ != Kind::Ratchet) {
98 drive_->setRevoluteMotor(false, 0.f, 0.f);
99 }
100}
101
102void Mechanism3D::setRatchetDirection(int direction) {
103 requireKind(Kind::Ratchet, "Mechanism3D.setRatchetDirection");
104 if (direction != 1 && direction != -1)
105 throw eve::Exception("Mechanism3D.setRatchetDirection: direction must be +1 or -1");
106 ratchetDirection_ = direction;
107}
108
109void Mechanism3D::setRatchetEngagementTorque(float torque) {
110 requireKind(Kind::Ratchet, "Mechanism3D.setRatchetEngagementTorque");
111 if (!std::isfinite(torque) || torque < 0.f)
112 throw eve::Exception(
113 "Mechanism3D.setRatchetEngagementTorque: torque must be finite and >= 0");
114 engagementTorque_ = torque;
115}
116
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_);
122 return;
123 }
124 if (driveEnabled_) {
125 const float driveSpeed = std::fabs(driveSpeed_) * static_cast<float>(ratchetDirection_);
126 drive_->setRevoluteMotor(true, driveSpeed, driveMaxTorque_);
127 } else {
128 drive_->setRevoluteMotor(false, 0.f, 0.f);
129 }
130}
131
132void Mechanism3D::invalidate() {
133 if (world_) world_->forgetMechanism(this);
134 world_ = nullptr;
135 drive_ = nullptr;
136 crankPin_ = nullptr;
137 sliderPin_ = nullptr;
138 slider_ = nullptr;
139}
140
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);
147 invalidate();
148}
149
150} // namespace eve::physics
ActionParameterOperation operation
void(* destroy)(void *)
TokenKind kind
World3D * world
std::string id
Definition PlayHost.cpp:108
RoadLaneDirection direction
float axisZ
Definition RockMesh.cpp:22
float axisY
Definition RockMesh.cpp:22
float axisX
Definition RockMesh.cpp:22
float wz
float wx
float wy
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
3D rigid body (Box3D) in meter-space coordinates (+Y up by convention). Owned by a World3D; create pr...
Definition Body3D.h:24
bool isValid() const
True while the underlying Box3D body is still alive.
Definition Body3D.cpp:216
float getAngularVelocityZ() const
Returns the angular velocity z.
Definition Body3D.cpp:351
float getAngularVelocityX() const
Returns the angular velocity x.
Definition Body3D.cpp:341
float getAngularVelocityY() const
Returns the angular velocity y.
Definition Body3D.cpp:346
Mechanism3D(const Mechanism3D &)=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.