载入中...
搜索中...
未找到
Rope3D.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
6
7#include <cstdint>
8#include <vector>
9
10namespace eve::physics {
11
12class DistanceField3D;
13class World3D;
14
17
20 std::uint64_t value = 0;
22 [[nodiscard]] explicit operator bool() const { return value != 0; }
24 friend bool operator==(RopeColliderId, RopeColliderId) = default;
25};
26
29
39public:
41 struct Vec3 {
42 float x = 0.f, y = 0.f, z = 0.f;
43 };
55 Rope3D(int particleCount, float startX, float startY, float startZ, float endX, float endY, float endZ);
56
58 void update(float dt);
59
61 [[nodiscard("check the rope step outcome")]]
63 [[nodiscard]] SimulationObservation observation() const noexcept override { return observation_; }
64 [[nodiscard]] SimulationBackendKind kind() const noexcept override { return SimulationBackendKind::Cpu; }
65 [[nodiscard]] SimulationDeterminism determinism() const noexcept override {
66 return SimulationDeterminism::ToleranceBounded;
67 }
68 [[nodiscard("check rope observation restore")]]
69 eve::Result<void> restoreObservation(const SimulationObservation& observation) override;
70
72 void setGravity(float x, float y, float z);
73 [[nodiscard]] float getGravityX() const { return gravity_.x; }
74 [[nodiscard]] float getGravityY() const { return gravity_.y; }
75 [[nodiscard]] float getGravityZ() const { return gravity_.z; }
76
78 void setStretchCompliance(float compliance);
79 [[nodiscard]] float getStretchCompliance() const noexcept { return stretchCompliance_; }
81 void setDistanceConstraintsEnabled(bool enabled) { distanceConstraintsEnabled_ = enabled; }
82 [[nodiscard]] bool getDistanceConstraintsEnabled() const { return distanceConstraintsEnabled_; }
84 void setBendCompliance(float compliance);
85 [[nodiscard]] float getBendCompliance() const noexcept { return bendCompliance_; }
87 void setBendConstraintsEnabled(bool enabled) { bendConstraintsEnabled_ = enabled; }
88 [[nodiscard]] bool getBendConstraintsEnabled() const { return bendConstraintsEnabled_; }
90 void setMaxBending(float fraction);
91 [[nodiscard]] float getMaxBending() const { return maxBending_; }
93 void setPlasticity(float yield, float creep);
94 [[nodiscard]] float getPlasticYield() const { return plasticYield_; }
95 [[nodiscard]] float getPlasticCreep() const { return plasticCreep_; }
97 [[nodiscard]] float getBendPlasticity(int bendIndex) const;
99 void setMaxCompression(float fraction);
100 [[nodiscard]] float getMaxCompression() const noexcept { return maxCompression_; }
102 void setDamping(float damping);
103 [[nodiscard]] float getDamping() const { return damping_; }
105 void setParticleMass(float mass);
106 [[nodiscard]] float getParticleMass() const { return particleMass_; }
108 void setRadius(float radius);
109 [[nodiscard]] float getRadius() const { return radius_; }
111 void setSelfCollision(bool enabled) { selfCollision_ = enabled; }
112 [[nodiscard]] bool getSelfCollision() const { return selfCollision_; }
113
115 void setBounds(float x, float y, float z, float width, float height, float depth);
117 void clearBounds() { hasBounds_ = false; }
119 void setCollisionFriction(float friction);
120 [[nodiscard]] float getCollisionFriction() const { return collisionFriction_; }
122 [[nodiscard("retain the collider id")]]
123 eve::Result<RopeColliderId> addSphereCollider(float x, float y, float z, float radius);
125 [[nodiscard("retain the collider id")]]
126 eve::Result<RopeColliderId> addPlaneCollider(float x, float y, float z, float nx, float ny, float nz);
128 [[nodiscard("check collider update")]]
129 eve::Result<RopeColliderChange> moveSphereCollider(RopeColliderId id, float x, float y, float z);
131 [[nodiscard("check collider removal")]]
134 void clearColliders() { colliders_.clear(); }
136 void setCollideWorld(World3D* world) { world_ = world; }
138 [[nodiscard]] World3D* getCollideWorld() const { return world_; }
140 void setCollideSdf(DistanceField3D* field) { sdf_ = field; }
142 [[nodiscard]] DistanceField3D* getCollideSdf() const { return sdf_; }
144 void setContinuousCollision(bool enabled) { continuousCollision_ = enabled; }
146 [[nodiscard]] bool getContinuousCollision() const { return continuousCollision_; }
148 void setCollisionRestitution(float restitution);
150 [[nodiscard]] float getCollisionRestitution() const { return collisionRestitution_; }
151
153 [[nodiscard("check whether the attachment changed")]]
154 eve::Result<RopeTopologyChange> pin(int particleIndex);
156 [[nodiscard("check whether the attachment changed")]]
157 eve::Result<RopeTopologyChange> attach(int particleIndex, float x, float y, float z);
159 [[nodiscard("check the attachment target update")]]
160 eve::Result<RopeTopologyChange> moveAttachment(int particleIndex, float x, float y, float z);
162 [[nodiscard("check whether the attachment changed")]]
163 eve::Result<RopeTopologyChange> detach(int particleIndex);
164 [[nodiscard]] bool isAttached(int particleIndex) const;
165
167 void applyForce(float x, float y, float z);
169 [[nodiscard("check the requested rope length")]]
170 eve::Result<RopeTopologyChange> setRestLength(float length);
178 [[nodiscard("check cursor topology change")]]
179 eve::Result<RopeTopologyChange> changeLength(float length, float particleSpacing, bool fromEnd = true);
180 [[nodiscard]] float getRestLength() const;
181 [[nodiscard]] float calculateLength() const;
182
184 [[nodiscard("check the topology change")]]
185 eve::Result<RopeTopologyChange> cut(int elementIndex);
187 [[nodiscard("check the topology change")]]
188 eve::Result<RopeTopologyChange> repair(int elementIndex);
189 [[nodiscard]] bool isElementActive(int elementIndex) const;
190 [[nodiscard]] float getElementForce(int elementIndex) const;
192 [[nodiscard("check the element tearing material update")]]
193 eve::Result<RopeTopologyChange> setElementTearResistance(int elementIndex, float multiplier);
194
196 void setTearing(float resistance, int maxTearsPerStep);
198 void disableTearing() { tearingEnabled_ = false; }
200 [[nodiscard]] std::uint64_t getTopologyRevision() const { return topologyRevision_; }
202 [[nodiscard]] int getLastTornElementCount() const { return static_cast<int>(lastTornElements_.size()); }
204 [[nodiscard]] int getLastTornElement(int eventIndex) const;
205
206 [[nodiscard]] int getParticleCount() const { return static_cast<int>(particles_.size()); }
207 [[nodiscard]] int getElementCount() const { return static_cast<int>(elements_.size()); }
208 [[nodiscard]] float getParticleX(int index) const;
209 [[nodiscard]] float getParticleY(int index) const;
210 [[nodiscard]] float getParticleZ(int index) const;
211 [[nodiscard]] float getParticleVelocityX(int index, float dt) const;
212 [[nodiscard]] float getParticleVelocityY(int index, float dt) const;
213 [[nodiscard]] float getParticleVelocityZ(int index, float dt) const;
215 [[nodiscard]] float getSampleX(float mu) const;
216 [[nodiscard]] float getSampleY(float mu) const;
217 [[nodiscard]] float getSampleZ(float mu) const;
219 [[nodiscard]] float getSampleTangentX(float mu) const;
220 [[nodiscard]] float getSampleTangentY(float mu) const;
221 [[nodiscard]] float getSampleTangentZ(float mu) const;
222
223private:
224 struct Particle {
225 Vec3 position;
226 Vec3 previous;
227 Vec3 attachment;
228 bool attached = false;
229 };
230 struct Element {
231 int a = 0;
232 int b = 0;
233 float restLength = 0.f;
234 float lambda = 0.f;
235 float force = 0.f;
236 float tearResistance = 1.f;
237 bool active = true;
238 };
239 enum class ColliderKind { Sphere, Plane };
240 struct Collider {
241 RopeColliderId id;
242 ColliderKind kind = ColliderKind::Sphere;
243 Vec3 position{};
244 Vec3 normal{};
245 float radius = 0.f;
246 };
247
248 [[nodiscard]] bool validParticle(int index) const noexcept;
249 [[nodiscard]] bool validElement(int index) const noexcept;
250 void integrate(float dt);
251 void solveStretch(float dt);
252 void solveBend(float dt);
253 void updatePlasticity(float dt);
254 void solveSelfCollision();
255 void collideBounds();
256 void solveExternalCollisions();
257 void collideBorrowedSurfaces(float dt);
258 void applyAttachments();
259 void applyTearing();
260 void syncBendState();
261 [[nodiscard]] Vec3 samplePosition(float mu) const;
262 [[nodiscard]] Vec3 sampleTangent(float mu) const;
263
264 std::vector<Particle> particles_;
265 std::vector<Element> elements_;
266 Vec3 gravity_{0.f, -9.81f, 0.f};
267 Vec3 force_{};
268 float stretchCompliance_ = 0.f;
269 bool distanceConstraintsEnabled_ = true;
270 float bendCompliance_ = 0.002f;
271 bool bendConstraintsEnabled_ = true;
272 float maxBending_ = 0.025f;
273 float plasticYield_ = 0.f;
274 float plasticCreep_ = 0.f;
275 std::vector<float> bendPlasticity_;
276 float maxCompression_ = 0.f;
277 float damping_ = 0.01f;
278 float particleMass_ = 0.1f;
279 float radius_ = 0.04f;
280 bool selfCollision_ = true;
281 bool hasBounds_ = false;
282 Vec3 boundsMin_{};
283 Vec3 boundsMax_{};
284 float collisionFriction_ = 0.f;
285 std::uint64_t nextColliderId_ = 1;
286 std::vector<Collider> colliders_;
287 World3D* world_ = nullptr;
288 DistanceField3D* sdf_ = nullptr;
289 bool continuousCollision_ = true;
290 float collisionRestitution_ = 0.f;
291 bool tearingEnabled_ = false;
292 float tearResistance_ = 1000.f;
293 int maxTearsPerStep_ = 1;
294 std::uint64_t topologyRevision_ = 0;
295 std::vector<int> lastTornElements_;
296 SimulationObservation observation_{};
297};
298
299} // namespace eve::physics
bool & active
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
float length
Definition CaveMesh.cpp:94
float nx
float nz
float ny
#define EVENGINE_API_DOMAINS
Definition Export.h:110
std::uint32_t height
std::uint32_t width
TokenKind kind
std::array< float, 3 > position
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
Texture * normal
graphics::Canvas * previous
World3D * world
float radius
std::string id
Definition PlayHost.cpp:108
Backend-neutral, observable fixed-step contract for physics domains.
double restitution
TerrainThermalSettings settings
float step
Definition TreeMesh.cpp:314
uint32_t index
std::uint32_t depth
Move-only operation result carrying either a value or Status.
Definition Result.h:155
Regular 3D signed-distance grid for terrain and voxel collision queries. Negative samples are solid,...
Minimal observable contract for physics simulation providers.
Renderer-independent particle rope with XPBD stretch and bend constraints.
Definition Rope3D.h:38
float getParticleMass() const
Definition Rope3D.h:106
float getCollisionFriction() const
Definition Rope3D.h:120
void setSelfCollision(bool enabled)
Enables non-neighbour particle self collision.
Definition Rope3D.h:111
float getGravityY() const
Definition Rope3D.h:74
std::uint64_t getTopologyRevision() const
Monotonic revision incremented by cut, repair, resize, and automatic tears.
Definition Rope3D.h:200
bool getBendConstraintsEnabled() const
Definition Rope3D.h:88
float getMaxCompression() const noexcept
Definition Rope3D.h:100
float getStretchCompliance() const noexcept
Definition Rope3D.h:79
void setCollideWorld(World3D *world)
Attaches a borrowed rigid-body world for mesh/shape collision and reaction impulses.
Definition Rope3D.h:136
bool getSelfCollision() const
Definition Rope3D.h:112
SimulationObservation observation() const noexcept override
Returns completed-step observables by value.
Definition Rope3D.h:63
float getCollisionRestitution() const
Returns particle/world normal restitution.
Definition Rope3D.h:150
int getLastTornElementCount() const
Number of elements automatically torn by the most recent update/step.
Definition Rope3D.h:202
void setDistanceConstraintsEnabled(bool enabled)
Enables or disables structural distance constraints without changing topology.
Definition Rope3D.h:81
float getDamping() const
Definition Rope3D.h:103
void setContinuousCollision(bool enabled)
Enables swept-sphere continuous collision against World3D and SDF geometry.
Definition Rope3D.h:144
void setCollideSdf(DistanceField3D *field)
Attaches a borrowed signed-distance field for static environment collision.
Definition Rope3D.h:140
void clearColliders()
Removes every rope-owned analytic collider.
Definition Rope3D.h:134
void disableTearing()
Disables automatic tearing.
Definition Rope3D.h:198
SimulationDeterminism determinism() const noexcept override
Returns the provider's replay/determinism guarantee.
Definition Rope3D.h:65
int getParticleCount() const
Definition Rope3D.h:206
SimulationBackendKind kind() const noexcept override
Identifies the provider family.
Definition Rope3D.h:64
float getPlasticYield() const
Definition Rope3D.h:94
DistanceField3D * getCollideSdf() const
Returns the borrowed signed-distance collision field, or null.
Definition Rope3D.h:142
bool getDistanceConstraintsEnabled() const
Definition Rope3D.h:82
float getBendCompliance() const noexcept
Definition Rope3D.h:85
float getGravityZ() const
Definition Rope3D.h:75
float getRadius() const
Definition Rope3D.h:109
float getGravityX() const
Definition Rope3D.h:73
int getElementCount() const
Definition Rope3D.h:207
void clearBounds()
Disables the axis-aligned collision box.
Definition Rope3D.h:117
float getPlasticCreep() const
Definition Rope3D.h:95
float getMaxBending() const
Definition Rope3D.h:91
void setBendConstraintsEnabled(bool enabled)
Enables or disables bend constraints independently from stretch constraints.
Definition Rope3D.h:87
bool getContinuousCollision() const
Reports whether continuous collision is enabled.
Definition Rope3D.h:146
World3D * getCollideWorld() const
Returns the borrowed rigid-body collision world, or null.
Definition Rope3D.h:138
Box3D rigid-body world. Script coordinates are meters (Box3D native), unlike 2D World which uses pixe...
Definition World3D.h:63
Optional physics backend for vehicle mobility and body attach.
Definition Climbing.h:36
SimulationBackendKind
Kind of implementation that owns a simulation step.
SimulationDeterminism
Determinism guarantee made by a simulation backend.
RopeColliderChange
Result of a rope collider mutation.
Definition Rope3D.h:28
RopeTopologyChange
Result of a topology-changing rope operation.
Definition Rope3D.h:16
bool enabled
One deterministic fixed-step emitted by SimulationClock.
Definition Time.h:158
Compact solver vector exposed only as a value type.
Definition Rope3D.h:41
Stable identifier for a rope-owned analytic collider.
Definition Rope3D.h:19
friend bool operator==(RopeColliderId, RopeColliderId)=default
Operator ==.
Observable backend progress shared by CPU and accelerator providers.
Validated solver policy for one simulation step.
std::mutex mu
Definition Graphics.cpp:181