载入中...
搜索中...
未找到
HairDynamicBones.cpp
浏览该文件的文档.
2
5#include "common/Diagnostic.h"
6
8namespace {
9
10Result<int> invalidInt(std::string message, std::string path) {
13}
14
15} // namespace
16
18 if (desc.rootBone.empty() || desc.tipBone.empty())
19 return invalidInt("hair chain requires rootBone and tipBone", "hair.chain");
20 if (desc.stiffness < 0.f || desc.stiffness > 1.f || desc.damping < 0.f || desc.damping > 1.f ||
21 desc.inertia < 0.f || desc.inertia > 1.f || desc.radius < 0.f || desc.iterations < 1)
22 return invalidInt("hair chain parameters out of range", "hair.chain");
23
24 const int chain =
25 solver.addChainByName(desc.rootBone, desc.tipBone, desc.stiffness, desc.damping,
26 desc.inertia, desc.gravityScale, desc.radius, desc.iterations);
27 if (chain < 0)
28 return invalidInt("hair chain bone path cannot be resolved",
29 desc.rootBone + "->" + desc.tipBone);
30
31 solver.setChainSelfCollision(chain, desc.selfCollision);
32 if (desc.endLength > 0.f) solver.setChainEndLength(chain, desc.endLength);
33 return Result<int>::success(chain);
34}
35
36Result<void> setupChains(DynamicBoneSolver &solver, const std::vector<ChainDesc> &chains,
37 bool clearFirst) {
38 if (clearFirst) solver.clearChains();
39 for (size_t i = 0; i < chains.size(); ++i) {
40 auto added = addChain(solver, chains[i]);
41 if (!added) {
42 const Diagnostic *diag = added.status().primaryDiagnostic();
44 Diagnostic::error(DiagnosticCode::InvalidArgument, diag ? std::string(diag->message()) : added.status().describe(), "hair.chains[" + std::to_string(i) + "]"));
45 }
46 }
47 return Result<void>::success();
48}
49
50Result<int> addHeadCollider(DynamicBoneSolver &solver, const std::string &boneName, float radius,
51 float offsetX, float offsetY, float offsetZ) {
52 if (boneName.empty()) return invalidInt("head collider bone name is empty", "hair.headBone");
53 if (!(radius > 0.f))
54 return invalidInt("head collider radius must be positive", "hair.headRadius");
55 AnimSkeleton *skeleton = solver.getSkeleton();
56 if (!skeleton) return invalidInt("dynamic bone solver has no skeleton", "hair.skeleton");
57 const int bone = skeleton->findBone(boneName);
58 if (bone < 0) return invalidInt("head collider bone not found", boneName);
61}
62
63} // namespace eve::animation::hair
Stable, structured diagnostics shared by engine modules.
scene::NodeDesc desc
std::string message
std::uint32_t bone
float radius
std::string path
Definition PlayHost.cpp:110
float offsetX
float offsetY
A structured explanation of a failed, degraded, or noteworthy result.
Definition Diagnostic.h:94
const std::string & message() const noexcept
Human-readable explanation.
Definition Diagnostic.h:147
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
3D bone hierarchy + bind-pose local TRS for skeletal animation. Independent of ik::Skeleton3D (FABRIK...
int findBone(const std::string &name) const
Finds bone.
World-space spring-chain solver that writes results as local bone rotations.
AnimSkeleton * getSkeleton() const
Return the borrowed skeleton, or null. @ownership Borrowed; ownership remains with the animation sour...
void setChainSelfCollision(int chainIndex, bool enabled)
Enable or disable non-adjacent particle self-collision for a chain.
void setChainEndLength(int chainIndex, float length)
Add a virtual particle after the last bone along the animated terminal direction.
void addBoneColliderSphere(int boneIndex, float offsetX, float offsetY, float offsetZ, float radius)
Add a sphere collider following a bone-local offset.
int getColliderCount() const
Return collider count.
void clearChains()
Remove all chains and their simulation state.
int addChainByName(const std::string &rootBone, const std::string &endBone, float stiffness, float damping, float inertia, float gravityScale=1.f, float radius=0.f, int iterations=4)
Name-based addChain variant; returns -1 for invalid input.
Convenience helpers for hair/tail/accessory spring chains on DynamicBoneSolver.
Result< int > addHeadCollider(DynamicBoneSolver &solver, const std::string &boneName, float radius, float offsetX, float offsetY, float offsetZ)
Attach a bone-following sphere collider (typically the head) for hair chains.
Result< void > setupChains(DynamicBoneSolver &solver, const std::vector< ChainDesc > &chains, bool clearFirst)
Replace or append hair chains.
Result< int > addChain(DynamicBoneSolver &solver, const ChainDesc &desc)
Add one hair/tail chain by bone name.
One named spring chain with game-friendly hair defaults.