mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-12 07:43:51 +00:00
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>
124 lines
5.9 KiB
C++
124 lines
5.9 KiB
C++
#pragma once
|
|
|
|
#include <glm/glm.hpp>
|
|
#include <string>
|
|
#include <cstddef>
|
|
|
|
namespace wowee {
|
|
namespace rendering {
|
|
|
|
/// Ambient sound emitter type for doodad models (fire, water, etc.).
|
|
enum class AmbientEmitterType : uint8_t {
|
|
None = 0,
|
|
FireplaceSmall = 1, ///< Small fire / campfire
|
|
FireplaceLarge = 2, ///< Large brazier / bonfire
|
|
Torch = 3, ///< Wall torch / standing torch
|
|
Fountain = 4, ///< Fountain water loop
|
|
Waterfall = 5, ///< Waterfall ambient
|
|
Forge = 6, ///< Forge / anvil fire
|
|
};
|
|
|
|
/**
|
|
* Output of classifyM2Model(): all name/geometry-based flags for an M2 model.
|
|
* Pure data — no Vulkan, GPU, or asset-manager dependencies.
|
|
*/
|
|
struct M2ClassificationResult {
|
|
// --- Collision shape selectors ---
|
|
bool collisionNoBlock = false; ///< Foliage/soft-trees/rugs: no blocking
|
|
bool collisionBridge = false; ///< Walk-on-top bridge/plank/walkway
|
|
bool collisionPlanter = false; ///< Low stepped planter/curb
|
|
bool collisionSteppedFountain = false; ///< Stepped fountain base
|
|
bool collisionSteppedLowPlatform = false; ///< Low stepped platform (curb/planter/bridge)
|
|
bool collisionStatue = false; ///< Statue/monument/sculpture
|
|
bool collisionSmallSolidProp = false; ///< Blockable solid prop (crate/chest/barrel)
|
|
bool collisionNarrowVerticalProp = false; ///< Narrow tall prop (lamp/post/pole)
|
|
bool collisionTreeTrunk = false; ///< Tree trunk cylinder
|
|
|
|
// --- Rendering / effect classification ---
|
|
bool isFoliageLike = false; ///< Foliage or tree (wind sway, disabled animation)
|
|
bool isSmallFoliage = false; ///< Small bush/grass/plant (skip during taxi/flight)
|
|
bool isSpellEffect = false; ///< Spell effect / particle-dominated visual
|
|
bool isLavaModel = false; ///< Lava surface (UV scroll animation)
|
|
bool isInstancePortal = false; ///< Instance portal (additive, spin, no collision)
|
|
bool isWaterVegetation = false; ///< Aquatic vegetation (cattails, kelp, reeds, etc.)
|
|
bool isFireflyEffect = false; ///< Ambient creature (exempt from particle dampeners)
|
|
bool isElvenLike = false; ///< Night elf / Blood elf themed model
|
|
bool isLanternLike = false; ///< Lantern/lamp/light model
|
|
bool isKoboldFlame = false; ///< Kobold candle/torch model
|
|
bool isGroundDetail = false; ///< Ground-clutter detail doodad (always non-blocking)
|
|
bool isInvisibleTrap = false; ///< Event-object invisible trap (no render, no collision)
|
|
bool isSmoke = false; ///< Smoke model (UV scroll animation)
|
|
bool isWaterfall = false; ///< Waterfall model (ambient sound + splash particles)
|
|
bool isBrazierOrFire = false; ///< Brazier / campfire / bonfire model
|
|
bool isTorch = false; ///< Wall-mounted or standing torch
|
|
|
|
// --- Ambient emitter type (for sound system) ---
|
|
AmbientEmitterType ambientEmitterType = AmbientEmitterType::None;
|
|
|
|
// --- Animation flags ---
|
|
bool disableAnimation = false; ///< Keep visually stable (foliage, chest lids, etc.)
|
|
bool shadowWindFoliage = false; ///< Apply wind sway in shadow pass for foliage/trees
|
|
};
|
|
|
|
/**
|
|
* Classify an M2 model by name and geometry.
|
|
*
|
|
* Pure function — no Vulkan, VkContext, or AssetManager dependencies.
|
|
* All results are derived solely from the model name string and tight vertex bounds.
|
|
*
|
|
* @param name Full model path/name from the M2 header (any case)
|
|
* @param boundsMin Per-vertex tight bounding-box minimum
|
|
* @param boundsMax Per-vertex tight bounding-box maximum
|
|
* @param vertexCount Number of mesh vertices
|
|
* @param emitterCount Number of particle emitters
|
|
*/
|
|
M2ClassificationResult classifyM2Model(
|
|
const std::string& name,
|
|
const glm::vec3& boundsMin,
|
|
const glm::vec3& boundsMax,
|
|
std::size_t vertexCount,
|
|
std::size_t emitterCount);
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Batch texture classification
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Per-batch texture key classification — glow / tint token flags.
|
|
* Input must be a lowercased, backslash-normalised texture path (as stored in
|
|
* M2Renderer's textureKeysLower vector). Pure data — no Vulkan dependencies.
|
|
*/
|
|
struct M2BatchTexClassification {
|
|
bool exactLanternGlowTex = false; ///< One of the known exact lantern-glow texture paths
|
|
bool hasGlowToken = false; ///< glow / flare / halo / light
|
|
bool hasFlameToken = false; ///< flame / fire / flamelick / ember
|
|
bool hasGlowCardToken = false; ///< glow / flamelick / lensflare / t_vfx / lightbeam / glowball / genericglow
|
|
bool likelyFlame = false; ///< fire / flame / torch
|
|
bool lanternFamily = false; ///< lantern / lamp / elf / silvermoon / quel / thalas
|
|
int glowTint = 0; ///< 0 = neutral, 1 = cool (blue/arcane), 2 = warm (red/scarlet)
|
|
};
|
|
|
|
/**
|
|
* Classify a batch texture by its lowercased path for glow/tint hinting.
|
|
*
|
|
* Pure function — no Vulkan, VkContext, or AssetManager dependencies.
|
|
*
|
|
* @param lowerTexKey Lowercased, backslash-normalised texture path (may be empty)
|
|
*/
|
|
M2BatchTexClassification classifyBatchTexture(const std::string& lowerTexKey);
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Lightweight ambient emitter classification (name-only, no geometry needed)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Classify an M2 model path for ambient sound emitter type.
|
|
* Faster than the full classifyM2Model() when only the emitter type is needed.
|
|
*
|
|
* @param lowerName Lowercased model path/name
|
|
* @return AmbientEmitterType::None if the model is not an ambient emitter source
|
|
*/
|
|
AmbientEmitterType classifyAmbientEmitter(const std::string& lowerName);
|
|
|
|
} // namespace rendering
|
|
} // namespace wowee
|