mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-15 00:43:52 +00:00
feat(rendering): implement spell visual effects with bone-tracked ribbons and particles
Add complete spell visual pipeline resolving the DBC chain (Spell → SpellVisual → SpellVisualKit → SpellVisualEffectName → M2) with precast/cast/impact phases, bone-attached positioning, and automatic dual-hand mirroring. Ribbon rendering fixes: - Parse visibility track as uint8 (was read as float, suppressing all ribbon edges due to ~1.4e-45 failing the >0.5 check) - Filter garbage emitters with bone=UINT_MAX unconditionally - Guard against NaN spine positions from corrupt bone data - Resolve ribbon textures via direct index, not textureLookup table - Fall back to bone 0 when ribbon bone index is out of range Particle rendering fixes: - Reduce spell particle scale from 5x to 1.5x (was oversized) - Exempt spell effect instances from position-based deduplication Spell handler integration: - Trigger precast visuals on SMSG_SPELL_START with server castTimeMs - Trigger cast/impact visuals on SMSG_SPELL_GO - Cancel precast visuals on cast interrupt/failure/movement M2 classifier expansion: - Add AmbientEmitterType enum for sound system integration - Add 20+ foliage tokens, 4 spell effect tokens, isSmallFoliage flag - Add markModelAsSpellEffect() to override disableAnimation DBC layouts: - Add SpellVisualID field to Spell.dbc for all expansion configs Signed-off-by: Pavel Okhlopkov <pavel.okhlopkov@flant.com>
This commit is contained in:
parent
0a33e3081c
commit
b79d9b8fea
18 changed files with 803 additions and 90 deletions
|
|
@ -12,14 +12,16 @@ namespace pipeline { class AssetManager; }
|
|||
namespace rendering {
|
||||
|
||||
class M2Renderer;
|
||||
class Renderer;
|
||||
class CharacterRenderer;
|
||||
|
||||
class SpellVisualSystem {
|
||||
public:
|
||||
SpellVisualSystem() = default;
|
||||
~SpellVisualSystem() = default;
|
||||
|
||||
// Initialize with references to the M2 renderer (for model loading/instance spawning)
|
||||
void initialize(M2Renderer* m2Renderer);
|
||||
// Initialize with references to the M2 renderer and parent renderer
|
||||
void initialize(M2Renderer* m2Renderer, Renderer* renderer);
|
||||
void shutdown();
|
||||
|
||||
// Spawn a spell visual at a world position.
|
||||
|
|
@ -27,9 +29,17 @@ public:
|
|||
void playSpellVisual(uint32_t visualId, const glm::vec3& worldPosition,
|
||||
bool useImpactKit = false);
|
||||
|
||||
// Spawn a precast visual effect at a world position.
|
||||
// castTimeMs: server cast time in milliseconds (0 = use anim duration).
|
||||
void playSpellVisualPrecast(uint32_t visualId, const glm::vec3& worldPosition,
|
||||
uint32_t castTimeMs = 0);
|
||||
|
||||
// Advance lifetime timers and remove expired instances.
|
||||
void update(float deltaTime);
|
||||
|
||||
// Remove all active precast visual instances (cast canceled/interrupted).
|
||||
void cancelAllPrecastVisuals();
|
||||
|
||||
// Remove all active spell visual instances and reset caches.
|
||||
// Called on map change / combat reset.
|
||||
void reset();
|
||||
|
|
@ -40,14 +50,18 @@ private:
|
|||
uint32_t instanceId;
|
||||
float elapsed;
|
||||
float duration; // per-instance lifetime in seconds (from M2 anim or default)
|
||||
bool isPrecast; // true for precast effects (removed on cancel/interrupt)
|
||||
uint32_t attachmentId; // character attachment point to track (0=none/static)
|
||||
};
|
||||
|
||||
void loadSpellVisualDbc();
|
||||
|
||||
M2Renderer* m2Renderer_ = nullptr;
|
||||
Renderer* renderer_ = nullptr;
|
||||
pipeline::AssetManager* cachedAssetManager_ = nullptr;
|
||||
|
||||
std::vector<SpellVisualInstance> activeSpellVisuals_;
|
||||
std::unordered_map<uint32_t, std::string> spellVisualPrecastPath_; // visualId → precast M2 path
|
||||
std::unordered_map<uint32_t, std::string> spellVisualCastPath_; // visualId → cast M2 path
|
||||
std::unordered_map<uint32_t, std::string> spellVisualImpactPath_; // visualId → impact M2 path
|
||||
std::unordered_map<std::string, uint32_t> spellVisualModelIds_; // M2 path → M2Renderer modelId
|
||||
|
|
@ -56,6 +70,12 @@ private:
|
|||
bool spellVisualDbcLoaded_ = false;
|
||||
static constexpr float SPELL_VISUAL_MAX_DURATION = 5.0f;
|
||||
static constexpr float SPELL_VISUAL_DEFAULT_DURATION = 2.0f;
|
||||
|
||||
// Determine character attachment point from model path keywords
|
||||
static uint32_t classifyAttachmentId(const std::string& modelPath);
|
||||
|
||||
// Apply height offset based on model path keywords (Hand → hands, Chest → chest, Base → ground)
|
||||
static glm::vec3 applyEffectHeightOffset(const glm::vec3& basePos, const std::string& modelPath);
|
||||
};
|
||||
|
||||
} // namespace rendering
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue