载入中...
搜索中...
未找到
DynamicBoneSolver.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
5#include <string>
6#include <vector>
7
8namespace eve::animation {
9
10class AnimPose;
11class AnimSkeleton;
12
15public:
17 virtual ~DynamicBoneForceField() = default;
19 virtual void sampleForce(float x, float y, float z, float time, float &outX, float &outY, float &outZ) const = 0;
20};
21
23struct DynamicBoneDebugParticle { int chain=0,particle=0; float x=0.f,y=0.f,z=0.f,radius=0.f; bool sleeping=false; };
25struct DynamicBoneDebugCollider { float startX=0.f,startY=0.f,startZ=0.f,endX=0.f,endY=0.f,endZ=0.f,radius=0.f; bool capsule=false,inside=false,enabled=true; };
27struct DynamicBoneDebugSnapshot { std::vector<DynamicBoneDebugParticle> particles; std::vector<DynamicBoneDebugCollider> colliders; };
30
38public:
40 explicit DynamicBoneSolver(AnimSkeleton *skeleton);
47
49 void setSkeleton(AnimSkeleton *skeleton);
55 AnimSkeleton *getSkeleton() const { return skeleton_; }
56
69 int addChain(int rootBone, int endBone, float stiffness, float damping, float inertia,
70 float gravityScale = 1.f, float radius = 0.f, int iterations = 4);
72 int addChainByName(const std::string &rootBone, const std::string &endBone, float stiffness,
73 float damping, float inertia, float gravityScale = 1.f, float radius = 0.f,
74 int iterations = 4);
76 int getChainCount() const;
78 void clearChains();
80 void setChainEnabled(int chainIndex, bool enabled);
82 bool isChainEnabled(int chainIndex) const;
84 void setChainFreezeAxis(int chainIndex, int axis);
86 void setChainSelfCollision(int chainIndex, bool enabled);
88 void setChainParticleParameters(int chainIndex, int particleIndex, float stiffness, float damping, float inertia,
89 float gravityScale, float radius);
91 void setChainEndLength(int chainIndex, float length);
93 void setChainEndOffset(int chainIndex, float x, float y, float z);
95 void clearChainEnd(int chainIndex);
96
98 void setGlobalGravity(float x, float y, float z);
100 void setExternalForce(float x, float y, float z);
106 void setForceField(const DynamicBoneForceField *forceField) { forceField_ = forceField; }
112 const DynamicBoneForceField *getForceField() const { return forceField_; }
114 float getGlobalGravityX() const { return globalGravityX_; }
116 float getGlobalGravityY() const { return globalGravityY_; }
118 float getGlobalGravityZ() const { return globalGravityZ_; }
120 void setWeight(float weight);
122 float getWeight() const { return weight_; }
124 void setUpdateRate(float updatesPerSecond);
126 float getUpdateRate() const { return updateRate_; }
128 void setTeleportThreshold(float distance);
130 float getTeleportThreshold() const { return teleportThreshold_; }
132 void setObjectMoveResponse(float value);
134 float getObjectMoveResponse() const { return objectMoveResponse_; }
136 void setDistanceReference(float x, float y, float z);
138 void setDistanceLimit(float value);
140 bool isChainSleeping(int chainIndex) const;
141
143 void addColliderSphere(float centerX, float centerY, float centerZ, float radius);
145 void addBoneColliderSphere(int boneIndex, float offsetX, float offsetY, float offsetZ, float radius);
147 void addColliderCapsule(float startX, float startY, float startZ, float endX, float endY, float endZ,
148 float radius);
150 void addBoneColliderCapsule(int boneIndex, float startX, float startY, float startZ, float endX, float endY,
151 float endZ, float radius);
153 void clearColliders();
155 int getColliderCount() const;
157 void removeCollider(int index);
159 void setColliderEnabled(int index, bool enabled);
161 void setColliderInside(int index, bool inside);
163 void setColliderRadius(int index, float radius);
165 void reset();
167 void update(AnimPose *pose, float dt);
169 DynamicBoneDebugSnapshot debugSnapshot() const;
171 DynamicBoneUpdateStats getLastUpdateStats() const { return lastUpdateStats_; }
172
173private:
174 struct Vec3 { float x = 0.f, y = 0.f, z = 0.f; };
175 struct Collider {
176 int bone = -1;
177 Vec3 offset;
178 Vec3 endOffset;
179 Vec3 center;
180 Vec3 end;
181 float radius = 0.f;
182 bool capsule = false;
183 bool enabled = true;
184 bool inside = false;
185 };
186 struct Chain {
189 float stiffness = 0.5f, damping = 0.7f, inertia = 0.9f;
190 float gravityScale = 1.f, radius = 0.f;
191 };
192 std::vector<int> bones;
193 std::vector<float> restLength;
194 std::vector<Vec3> current, previous, target;
195 std::vector<ParticleParameters> particleParameters;
196 float stiffness = 0.5f, damping = 0.7f, inertia = 0.9f;
197 int freezeAxis = 0;
198 float gravityScale = 1.f, radius = 0.f;
199 float endLength = 0.f;
200 Vec3 endOffset;
201 int endMode = 0;
202 int iterations = 4;
203 bool enabled = true, initialized = false, sleeping = false, selfCollision = false;
204 };
205
206 std::vector<int> buildChainByIndexes(int rootBone, int endBone) const;
207 bool validateChain(const std::vector<int> &bones) const;
208 void captureTargets(Chain &chain, const AnimPose &pose);
209 void initializeChain(Chain &chain);
210 void simulateChain(Chain &chain, float dt);
211 void constrainSegment(Chain &chain, size_t particleIndex) const;
212 void writeChainRotations(const Chain &chain, AnimPose &pose) const;
213 void updateColliderCenters(const AnimPose &pose);
214 bool resolveCollider(const Collider &collider, float particleRadius, Vec3 &point) const;
215
216 AnimSkeleton *skeleton_ = nullptr;
217 float globalGravityX_ = 0.f, globalGravityY_ = -9.8f, globalGravityZ_ = 0.f;
218 float externalForceX_ = 0.f, externalForceY_ = 0.f, externalForceZ_ = 0.f;
219 float weight_ = 1.f, updateRate_ = 60.f, teleportThreshold_ = 2.f;
220 float objectMoveResponse_ = 1.f, distanceLimit_ = 0.f;
221 Vec3 distanceReference_;
222 const DynamicBoneForceField *forceField_ = nullptr;
223 float simulationTime_ = 0.f;
224 DynamicBoneUpdateStats lastUpdateStats_;
225 std::vector<Chain> chains_;
226 std::vector<Collider> colliders_;
227};
228
229} // namespace eve::animation
LogicalId target
double value
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
eve::EntitySpatialPose pose
float length
Definition CaveMesh.cpp:94
#define EVENGINE_API_WORLD
Definition Export.h:109
size_t offset
std::vector< Bone > bones
std::uint32_t bone
float distance
graphics::Canvas * previous
float radius
double current
float offsetX
float offsetY
float inertia
Definition TreeMesh.cpp:309
int iterations
Definition TreeMesh.cpp:311
uint32_t index
std::vector< char > inside
glm::vec3 point
Evaluated local (and optional world) pose for an AnimSkeleton. Script type: AnimPose.
Definition AnimPose.h:17
3D bone hierarchy + bind-pose local TRS for skeletal animation. Independent of ik::Skeleton3D (FABRIK...
Read-only spatial force provider sampled by dynamic bone particles.
virtual ~DynamicBoneForceField()=default
Releases DynamicBoneForceField resources.
virtual void sampleForce(float x, float y, float z, float time, float &outX, float &outY, float &outZ) const =0
Sample model-space acceleration.
World-space spring-chain solver that writes results as local bone rotations.
DynamicBoneSolver & operator=(const DynamicBoneSolver &)=default
Operator =.
float getUpdateRate() const
Return preferred simulation frequency.
float getGlobalGravityX() const
Return gravity X.
float getWeight() const
Return final rotation blend weight.
void setForceField(const DynamicBoneForceField *forceField)
Set an optional spatial force field sampled on the calling thread. @ownership Borrowed; ownership rem...
const DynamicBoneForceField * getForceField() const
Return the borrowed spatial force field, or null. @ownership Borrowed; ownership remains with the cal...
float getTeleportThreshold() const
Return teleport reset distance; zero disables it.
float getObjectMoveResponse() const
Return root translation response.
DynamicBoneUpdateStats getLastUpdateStats() const
Return counters captured by the most recent update.
AnimSkeleton * getSkeleton() const
Return the borrowed skeleton, or null. @ownership Borrowed; ownership remains with the animation sour...
~DynamicBoneSolver()
Dynamic bone solver.
float getGlobalGravityY() const
Return gravity Y.
DynamicBoneSolver(const DynamicBoneSolver &)=default
Dynamic bone solver.
float getGlobalGravityZ() const
Return gravity Z.
bool enabled
One immutable model-space collider in a dynamic-bone debug snapshot.
One immutable model-space particle in a dynamic-bone debug snapshot.
Owning renderer-neutral snapshot safe after the solver changes.
std::vector< DynamicBoneDebugParticle > particles
std::vector< DynamicBoneDebugCollider > colliders
Last-update counters for profiling and distance-culling verification.