载入中...
搜索中...
未找到
Cloth3D.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
7
8#include <cstdint>
9#include <string>
10#include <unordered_map>
11#include <unordered_set>
12#include <vector>
13
14namespace eve::graphics {
15class Graphics;
16class Mesh;
17} // namespace eve::graphics
18
19namespace eve::physics {
20
21class World3D;
22
33public:
43 Cloth3D(int cols, int rows, float spacing, float originX, float originY, float originZ);
55 explicit Cloth3D(const ClothModel& model);
57 ~Cloth3D();
58
59 Cloth3D(const Cloth3D&) = delete;
60 Cloth3D& operator=(const Cloth3D&) = delete;
61
63 void update(float dt);
64
66 [[nodiscard("check the cloth step outcome")]]
69 [[nodiscard]] SimulationObservation observation() const noexcept override { return observation_; }
71 [[nodiscard]] SimulationBackendKind kind() const noexcept override { return SimulationBackendKind::Cpu; }
73 [[nodiscard]] SimulationDeterminism determinism() const noexcept override {
74 return SimulationDeterminism::ToleranceBounded;
75 }
77 [[nodiscard]] std::string getBackendName() const { return "cpu"; }
79 [[nodiscard]] bool supportsFeature(const std::string& feature) const;
81 [[nodiscard("check cloth observation restore")]]
82 eve::Result<void> restoreObservation(const SimulationObservation& observation) override;
83
85 void setGravity(float gx, float gy, float gz);
87 float getGravityX() const { return gravityX_; }
89 float getGravityY() const { return gravityY_; }
91 float getGravityZ() const { return gravityZ_; }
92
94 void setStiffness(float stiffness);
96 float getStiffness() const { return stiffness_; }
97
99 void setStretchCompliance(float compliance);
101 [[nodiscard]] float getStretchCompliance() const;
103 void setShearCompliance(float compliance);
105 [[nodiscard]] float getShearCompliance() const;
107 void setBendCompliance(float compliance);
109 [[nodiscard]] float getBendCompliance() const;
110
112 void setTetherScale(float scale);
114 [[nodiscard]] float getTetherScale() const;
116 void setTetherCompliance(float compliance);
118 [[nodiscard]] float getTetherCompliance() const;
119
121 void setPressure(float pressure);
123 [[nodiscard]] float getPressure() const;
125 void setVolumeCompliance(float compliance);
127 [[nodiscard]] float getVolumeCompliance() const;
129 [[nodiscard]] float getCurrentVolume() const;
130
132 void setIterations(int iterations);
134 int getIterations() const { return iterations_; }
135
137 void setDamping(float damping);
139 float getDamping() const { return damping_; }
140
145 void setParticleSize(float size);
147 float getParticleSize() const { return particleSize_; }
148
155 void setSelfCollision(bool on);
157 bool getSelfCollision() const { return selfCollision_; }
158
163 void setParticleMass(float mass);
165 float getParticleMass() const { return particleMass_; }
166
168 void setFoldStiffness(float k);
170 float getFoldStiffness() const { return foldStiffness_; }
171
178 void setMaxFoldAngle(float degrees);
180 float getMaxFoldAngle() const { return maxFoldAngle_ * 180.f / 3.14159265f; }
181
183 void setBounds(float x, float y, float z, float w, float h, float d);
185 void clearBounds();
186
188 void setCollisionMaterial(float friction, float restitution);
190 [[nodiscard]] float getCollisionFriction() const;
192 [[nodiscard]] float getCollisionRestitution() const;
194 void setCollisionFilter(uint64_t categoryBits, uint64_t maskBits);
196 [[nodiscard]] uint64_t getCollisionCategoryBits() const;
198 [[nodiscard]] uint64_t getCollisionMaskBits() const;
199
201 void setTearThreshold(float strain);
203 [[nodiscard]] float getTearThreshold() const;
205 void setMaxTearsPerStep(int count);
207 [[nodiscard]] int getMaxTearsPerStep() const;
209 void tearConstraint(int particleA, int particleB);
211 [[nodiscard]] int getTornConstraintCount() const;
212
213 void pin(int index);
215 void unpin(int index);
217 void pinTopRow();
219 bool isPinned(int index) const;
221 void setParticleInverseMass(int index, float inverseMass);
223 [[nodiscard]] float getParticleInverseMass(int index) const;
224
226 void setSkinConstraint(int index, float x, float y, float z, float nx, float ny, float nz, float radius,
227 float backstopDistance = -1.f, float backstopRadius = 0.f, float compliance = 0.f);
229 void updateSkinReference(int index, float x, float y, float z, float nx, float ny, float nz);
231 void clearSkinConstraint(int index);
233 [[nodiscard]] bool hasSkinConstraint(int index) const;
234
236 void attachParticle(int index, float x, float y, float z, float compliance = 0.f);
238 void updateAttachment(int index, float x, float y, float z);
240 void detachParticle(int index);
242 [[nodiscard]] bool isAttached(int index) const;
243
248 int grabAt(float x, float y, float z, float radius = 0.3f);
250 void moveGrab(float x, float y, float z);
252 void releaseGrab();
254 bool isGrabbing() const { return grabIndex_ >= 0; }
256 int getGrabIndex() const { return grabIndex_; }
257
260 void applyForce(float fx, float fy, float fz);
261
272 void setWindVelocity(float vx, float vy, float vz);
274 [[nodiscard]] float getWindVelocityX() const;
276 [[nodiscard]] float getWindVelocityY() const;
278 [[nodiscard]] float getWindVelocityZ() const;
279
298 void setAerodynamics(float airDensity, float dragCoefficient, float liftCoefficient);
300 [[nodiscard]] float getAirDensity() const;
302 [[nodiscard]] float getDragCoefficient() const;
304 [[nodiscard]] float getLiftCoefficient() const;
305
310 void interactAt(float x, float y, float z, float radius, float strength);
311
324 void setCollideWorld(World3D* world);
333 World3D* getCollideWorld() const { return world_; }
334
336 void reset();
337
339 void setColor(float r, float g, float b, float a = 1.f);
341 float getColorR() const { return colorR_; }
343 float getColorG() const { return colorG_; }
345 float getColorB() const { return colorB_; }
347 float getColorA() const { return colorA_; }
348
350 void draw(graphics::Graphics* gfx);
351
353 int getCols() const { return cols_; }
355 int getRows() const { return rows_; }
357 int getParticleCount() const { return static_cast<int>(particles_.size()); }
359 [[nodiscard]] int getTriangleCount() const;
361 [[nodiscard]] int getDistanceConstraintCount() const;
363 [[nodiscard]] int getTetherConstraintCount() const;
365 [[nodiscard]] int getSkinConstraintCount() const;
367 [[nodiscard]] int getAttachmentCount() const { return static_cast<int>(attachments_.size()); }
368 float getParticleX(int index) const;
370 float getParticleY(int index) const;
372 float getParticleZ(int index) const;
374 void setParticlePosition(int index, float x, float y, float z);
375
377 float getSpacing() const { return spacing_; }
379 float getOriginX() const { return originX_; }
381 float getOriginY() const { return originY_; }
383 float getOriginZ() const { return originZ_; }
384
386 void destroy();
387
388private:
389 struct Particle {
390 float x = 0.f, y = 0.f, z = 0.f;
391 float px = 0.f, py = 0.f, pz = 0.f;
392 float inverseMass = 1.f;
393 bool pinned = false;
394 };
395 struct Link {
396 int a = 0, b = 0;
397 float rest = 0.f;
398 ClothConstraintKind kind = ClothConstraintKind::Structural;
399 float lambda = 0.f;
400 };
401 struct Tri {
402 int v[3] = {0, 0, 0};
403 };
404 // Dihedral pair: shared edge (a,b), opposite vertices k (tri 1) and l (tri 2).
405 struct FoldPair {
406 int a = 0, b = 0, k = 0, l = 0;
407 };
408 struct Tether {
409 int particle = 0;
410 int anchor = 0;
411 float maxLength = 0.f;
412 float lambda = 0.f;
413 };
414 struct SkinConstraint {
415 int particle = 0;
416 float x = 0.f, y = 0.f, z = 0.f;
417 float nx = 0.f, ny = 1.f, nz = 0.f;
418 float radius = 0.f;
419 float backstopDistance = -1.f;
420 float backstopRadius = 0.f;
421 float compliance = 0.f;
422 float lambda = 0.f;
423 };
424 struct Attachment {
425 int particle = 0;
426 float x = 0.f, y = 0.f, z = 0.f;
427 float compliance = 0.f;
428 float lambda = 0.f;
429 };
430
431 void rebuildLinks();
432 void initializeFromModel(const ClothModel& model);
433 void updateSubsteps(float dt, int substeps);
434 void rebuildTriangles();
435 void buildLinkKeys();
436 bool areLinked(int a, int b) const;
437 void integrate(float dt);
438 void accumulateAerodynamicAcceleration(float dt, std::vector<float>& accelerations) const;
439 void solveConstraints(float dt);
440 void solveTetherConstraints(float dt);
441 void solveVolumeConstraint(float dt);
442 void solveSkinConstraints(float dt);
443 void solveAttachments(float dt);
444 void applyAutomaticTearing();
445 void tearLink(size_t linkIndex);
446 void rebuildFoldPairsFromTriangles();
447 void solveFoldConstraint();
448 void solveSelfCollision();
449 void solveSelfCollisionTriangles();
450 void collideWorld(float dt);
451 void collideBounds();
452 void rebuildHash();
453 bool validIndex(int index) const;
454 int64_t cellKey(int cx, int cy, int cz) const;
455
456 int cols_ = 0;
457 int rows_ = 0;
458 float spacing_ = 0.4f;
459 float originX_ = 0.f, originY_ = 0.f, originZ_ = 0.f;
460
461 float gravityX_ = 0.f;
462 float gravityY_ = -9.8f;
463 float gravityZ_ = 0.f;
464 float stiffness_ = 0.85f;
465 float stretchCompliance_ = 0.f;
466 float shearCompliance_ = 0.f;
467 float bendCompliance_ = 0.f;
468 float tetherScale_ = 0.f;
469 float tetherCompliance_ = 0.f;
470 float pressure_ = 0.f;
471 float volumeCompliance_ = 0.f;
472 float restVolume_ = 0.f;
473 float volumeLambda_ = 0.f;
474 float damping_ = 0.01f;
475 int iterations_ = 4;
476 float particleSize_ = 0.1f;
477 float particleMass_ = 0.1f;
478 bool selfCollision_ = true;
479 float foldStiffness_ = 0.5f;
480 float maxFoldAngle_ = 120.f * 3.14159265f / 180.f;
481 float collisionFriction_ = 0.2f;
482 float collisionRestitution_ = 0.15f;
483 uint64_t collisionCategoryBits_ = ~uint64_t{0};
484 uint64_t collisionMaskBits_ = ~uint64_t{0};
485 float tearThreshold_ = 0.f;
486 int maxTearsPerStep_ = 1;
487 int tornConstraintCount_ = 0;
488
489 bool hasBounds_ = false;
490 float boundX_ = 0.f, boundY_ = 0.f, boundZ_ = 0.f;
491 float boundW_ = 0.f, boundH_ = 0.f, boundD_ = 0.f;
492
493 int grabIndex_ = -1;
494 float grabX_ = 0.f, grabY_ = 0.f, grabZ_ = 0.f;
495 float forceX_ = 0.f, forceY_ = 0.f, forceZ_ = 0.f;
496 float windVelocityX_ = 0.f, windVelocityY_ = 0.f, windVelocityZ_ = 0.f;
497 float airDensity_ = 1.225f;
498 float dragCoefficient_ = 0.f;
499 float liftCoefficient_ = 0.f;
500 float interactX_ = 0.f, interactY_ = 0.f, interactZ_ = 0.f;
501 float interactRadius_ = 0.f;
502 float interactStrength_ = 0.f;
503
504 World3D* world_ = nullptr;
505
506 float colorR_ = 0.75f, colorG_ = 0.82f, colorB_ = 0.95f, colorA_ = 1.f;
507
508 bool destroyed_ = false;
509 SimulationObservation observation_;
510
511 std::vector<Particle> particles_;
512 std::vector<Particle> restParticles_;
513 std::vector<Link> links_;
514 std::vector<Tri> triangles_;
515 std::vector<FoldPair> foldPairs_;
516 std::vector<Tether> tethers_;
517 std::vector<SkinConstraint> skinConstraints_;
518 std::vector<Attachment> attachments_;
519 std::unordered_set<int64_t> linkKeys_;
520 std::unordered_map<int64_t, std::vector<int>> hash_;
521
522 graphics::Mesh* mesh_ = nullptr;
523 int meshVertexCount_ = 0;
524 int meshIndexCount_ = 0;
525};
526
527} // namespace eve::physics
float w
Definition AnimClip.cpp:738
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
float cx
Definition CardTypes.cpp:33
float cy
Definition CardTypes.cpp:34
float degrees
Definition CardTypes.cpp:35
Vec3 anchor
Definition CaveMesh.cpp:90
float py
float nx
float nz
float ny
float pz
#define EVENGINE_API_DOMAINS
Definition Export.h:110
int rows
int cols
tensor::Graph g
Definition GpuGraph.cpp:7
double r
float v
eve::ResourcePin pinned
int h
std::vector< Colorf > px
void(* destroy)(void *)
TokenKind kind
std::array< float, 3 > scale
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
MeshVfxBatchedDraw draw
World3D * world
float radius
float d
glm::mat4 model
Backend-neutral, observable fixed-step contract for physics domains.
std::uint32_t count
double restitution
TerrainThermalSettings settings
int spacing
int iterations
Definition TreeMesh.cpp:311
float step
Definition TreeMesh.cpp:314
float size
Definition TreeMesh.cpp:156
uint32_t index
float vz
float vy
float vx
Move-only operation result carrying either a value or Status.
Definition Result.h:155
Interactive 3D cloth — Verlet particles + distance constraints. Meter space, +Y up,...
Definition Cloth3D.h:32
float getOriginZ() const
Returns the origin z.
Definition Cloth3D.h:383
World3D * getCollideWorld() const
Returns the attached collision world, or null when detached.
Definition Cloth3D.h:333
std::string getBackendName() const
Return stable backend name for scripts and diagnostics.
Definition Cloth3D.h:77
int getRows() const
Returns the rows.
Definition Cloth3D.h:355
SimulationDeterminism determinism() const noexcept override
CPU cloth uses bounded floating-point determinism.
Definition Cloth3D.h:73
float getColorR() const
Returns the color r.
Definition Cloth3D.h:341
Cloth3D & operator=(const Cloth3D &)=delete
float getGravityX() const
Returns the gravity x.
Definition Cloth3D.h:87
int getCols() const
Returns the cols.
Definition Cloth3D.h:353
bool isGrabbing() const
True when grabbing.
Definition Cloth3D.h:254
float getMaxFoldAngle() const
Returns the max fold angle.
Definition Cloth3D.h:180
float getFoldStiffness() const
Returns the fold stiffness.
Definition Cloth3D.h:170
float getColorG() const
Returns the color g.
Definition Cloth3D.h:343
float getParticleSize() const
Returns the particle size.
Definition Cloth3D.h:147
float getOriginY() const
Returns the origin y.
Definition Cloth3D.h:381
float getParticleMass() const
Returns the particle mass.
Definition Cloth3D.h:165
float getColorB() const
Returns the color b.
Definition Cloth3D.h:345
int getIterations() const
Returns the iterations.
Definition Cloth3D.h:134
float getGravityY() const
Returns the gravity y.
Definition Cloth3D.h:89
SimulationObservation observation() const noexcept override
Returns completed tick/time observables.
Definition Cloth3D.h:69
SimulationBackendKind kind() const noexcept override
Identifies this production CPU cloth backend.
Definition Cloth3D.h:71
int getGrabIndex() const
Returns the grab index.
Definition Cloth3D.h:256
float getGravityZ() const
Returns the gravity z.
Definition Cloth3D.h:91
bool getSelfCollision() const
Returns the self collision.
Definition Cloth3D.h:157
float getDamping() const
Returns the damping.
Definition Cloth3D.h:139
int getParticleCount() const
Returns the particle count.
Definition Cloth3D.h:357
float getSpacing() const
Returns the spacing.
Definition Cloth3D.h:377
float getColorA() const
Returns the color a.
Definition Cloth3D.h:347
int getAttachmentCount() const
Return active attachment count.
Definition Cloth3D.h:367
Cloth3D(const Cloth3D &)=delete
float getStiffness() const
Returns the stiffness.
Definition Cloth3D.h:96
float getOriginX() const
Returns the origin x.
Definition Cloth3D.h:379
Reusable, validated cloth simulation asset.
Definition ClothModel.h:73
Minimal observable contract for physics simulation providers.
Box3D rigid-body world. Script coordinates are meters (Box3D native), unlike 2D World which uses pixe...
Definition World3D.h:63
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25
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.
One deterministic fixed-step emitted by SimulationClock.
Definition Time.h:158
Observable backend progress shared by CPU and accelerator providers.
Validated solver policy for one simulation step.