174 lines
8.3 KiB
C++
174 lines
8.3 KiB
C++
#pragma once
|
|
#include "CharacterState.h"
|
|
#include "BoneAnimatedModelNew.h"
|
|
#include "render/Renderer.h"
|
|
#include "render/TextureManager.h"
|
|
#include "SparkEmitter.h"
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <map>
|
|
#include <string>
|
|
#include <cstdint>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <utility>
|
|
#include <chrono>
|
|
#include "dialogue/TranslationDatabase.h"
|
|
#include "AudioPlayerAsync.h"
|
|
|
|
namespace FRG {
|
|
|
|
class TextRenderer;
|
|
class IGameServer;
|
|
|
|
class Character {
|
|
public:
|
|
Character(IGameServer& server, std::string locationId, std::string entityId)
|
|
: gameServer_(server), locationId_(std::move(locationId)),
|
|
entityId_(std::move(entityId)) {}
|
|
const std::string& entityId() const { return entityId_; }
|
|
void bindToLocation(std::string locationId) { locationId_ = std::move(locationId); }
|
|
// The aliasing shared_ptr keeps the owning GameSnapshot alive for as long
|
|
// as the returned CharacterState is being read.
|
|
std::shared_ptr<const CharacterState> stateSnapshot() const;
|
|
static constexpr float kAttackRange = 1.25f;
|
|
|
|
// ---- Asset loading ----
|
|
void loadAnimation(AnimationState animState, const std::string& filename, const std::string& zipFile = "");
|
|
void loadBinaryAnimation(AnimationState animState, const std::string& filename, const std::string& zipFile = "");
|
|
|
|
// Assigns a texture to a specific mesh by name.
|
|
void setTexture(const std::string& meshName, std::shared_ptr<Texture> texture);
|
|
// Assigns one texture to every mesh in every loaded animation. Call AFTER loading animations.
|
|
void setTexture(std::shared_ptr<FRG::Texture> texture);
|
|
|
|
// Creates a fully-loaded Character from a CharacterState (including its creationInfo).
|
|
// Loads all animations, textures, and weapon mesh/texture from the paths stored in creationInfo.
|
|
static std::unique_ptr<Character> createFromState(
|
|
const CharacterState& initialState, IGameServer& server,
|
|
const std::string& locationId, const std::string& entityId,
|
|
Renderer& renderer, const char* zipFile);
|
|
|
|
// ---- Per-frame update ----
|
|
// Applies authoritative animation state to runtime resources and consumes
|
|
// presentation-only events emitted by CharacterState::update.
|
|
void update(int64_t deltaMs, const CharacterUpdateEvents* events = nullptr);
|
|
|
|
// ---- Damage ----
|
|
void presentDamage(float hp, float maxHp, const Vec3fp& attackDirection,
|
|
const std::string& attackerId);
|
|
|
|
// ---- Spark setup ----
|
|
void setupHitSparks(std::shared_ptr<Texture> sparkTexture);
|
|
void prepareHitSparksForDraw(const Eigen::Matrix4f& cameraViewMatrix);
|
|
|
|
// ---- HUD overlays ----
|
|
void drawName(TextRenderer& textRenderer,
|
|
const Eigen::Matrix4f& cameraViewMatrix,
|
|
const Eigen::Matrix4f& projectionMatrix);
|
|
void drawPlayerName(TextRenderer& textRenderer,
|
|
const Eigen::Matrix4f& cameraViewMatrix,
|
|
const Eigen::Matrix4f& projectionMatrix,
|
|
const std::string& displayName);
|
|
void drawHealthBar(Renderer& renderer,
|
|
const Eigen::Matrix4f& cameraViewMatrix,
|
|
const Eigen::Matrix4f& projectionMatrix);
|
|
|
|
// ---- Draw passes ----
|
|
void draw(Renderer& renderer);
|
|
void drawShadowDepth(Renderer& renderer);
|
|
void drawWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera);
|
|
void drawNight(Renderer& renderer,
|
|
const float* pointLightPosEye, const float* pointLightDirEye,
|
|
const float* pointLightColors, int pointLightCount,
|
|
const float* pointLightWorldXZ, const float* pointLightLimitXZ,
|
|
const Eigen::Matrix4f& cameraViewInverse,
|
|
const float* ambientColor, const float* fogColor);
|
|
void drawNightWithShadow(Renderer& renderer,
|
|
const float* plPosEye, const float* plDirEye, const float* plColors, int plCount,
|
|
const float* plWorldXZ, const float* plLimitXZ,
|
|
const Eigen::Matrix4f& cameraViewInverse,
|
|
const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex,
|
|
const float* ambientColor, const float* fogColor);
|
|
|
|
// ---- Query helpers (read immutable snapshots) ----
|
|
bool isMoving() const;
|
|
Eigen::Vector3f renderPosition() const;
|
|
float getHp() const;
|
|
|
|
// ---- Weapon rendering data (initialized from state.creationInfo by createFromState) ----
|
|
VertexRenderStruct weaponMesh;
|
|
std::shared_ptr<Texture> weaponTexture;
|
|
Eigen::Matrix3f weaponInitialRotation = Eigen::Matrix3f::Identity();
|
|
Eigen::Vector3f weaponInitialPosition = Eigen::Vector3f::Zero();
|
|
std::string weaponAttachBoneName = "RightHand";
|
|
|
|
SparkEmitter hitSparkEmitter;
|
|
AudioPlayerAsync* audioPlayer = nullptr;
|
|
|
|
static Dialogue::TranslationDatabase nameTranslations;
|
|
|
|
private:
|
|
friend class Game;
|
|
friend class Location;
|
|
friend class ScriptEngine;
|
|
friend class LocationEditor;
|
|
friend class PathVisualization;
|
|
IGameServer& gameServer_;
|
|
std::string locationId_;
|
|
std::string entityId_;
|
|
std::function<void()> onDeathAnimComplete;
|
|
std::function<void(float, float, const std::string&)> onHpChanged;
|
|
std::map<AnimationState, BoneAnimationDataNew> animations;
|
|
VertexRenderStruct modelMutable;
|
|
VertexRenderStruct healthBarMesh;
|
|
std::unordered_map<std::string, std::shared_ptr<Texture>> meshTextures;
|
|
|
|
struct PresentationSample {
|
|
Eigen::Vector3f position = Eigen::Vector3f::Zero();
|
|
float facingAngle = 0.0f;
|
|
float animationFrame = 0.0f;
|
|
AnimationState currentState = AnimationState::STAND;
|
|
bool enabled = true;
|
|
};
|
|
|
|
PresentationSample previousPresentationSample_;
|
|
PresentationSample currentPresentationSample_;
|
|
std::chrono::steady_clock::time_point lastPresentationUpdate_;
|
|
bool hasPresentationSample_ = false;
|
|
|
|
AnimationState resolveActiveState(const CharacterState& state) const;
|
|
CharacterState interpolatedState(const CharacterState& state) const;
|
|
void updateAnimationForRender(const CharacterState& state);
|
|
bool prepareGpuSkinning(const CharacterState& state);
|
|
void drawAttachedWeapon(Renderer& renderer, const CharacterState& state);
|
|
|
|
void drawGpuSkinning(Renderer& renderer, const CharacterState& state);
|
|
void drawShadowDepthGpuSkinning(Renderer& renderer, const CharacterState& state);
|
|
void drawShadowDepthCpu(Renderer& renderer, const CharacterState& state);
|
|
void drawGpuSkinningWithShadow(Renderer& renderer, const CharacterState& state, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera);
|
|
void drawCpuWithShadow(Renderer& renderer, const CharacterState& state, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera);
|
|
void drawNightGpuSkinning(Renderer& renderer,
|
|
const CharacterState& state,
|
|
const float* plPosEye, const float* plDirEye, const float* plColors, int plCount,
|
|
const float* plWorldXZ, const float* plLimitXZ, const Eigen::Matrix4f& cameraViewInverse,
|
|
const float* ambientColor, const float* fogColor);
|
|
void drawNightCpu(Renderer& renderer,
|
|
const CharacterState& state,
|
|
const float* plPosEye, const float* plDirEye, const float* plColors, int plCount,
|
|
const float* plWorldXZ, const float* plLimitXZ, const Eigen::Matrix4f& cameraViewInverse,
|
|
const float* ambientColor, const float* fogColor);
|
|
void drawNightGpuSkinningWithShadow(Renderer& renderer,
|
|
const CharacterState& state,
|
|
const float* plPosEye, const float* plDirEye, const float* plColors, int plCount,
|
|
const float* plWorldXZ, const float* plLimitXZ, const Eigen::Matrix4f& cameraViewInverse,
|
|
const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const float* ambientColor, const float* fogColor);
|
|
void drawNightCpuWithShadow(Renderer& renderer,
|
|
const CharacterState& state,
|
|
const float* plPosEye, const float* plDirEye, const float* plColors, int plCount,
|
|
const float* plWorldXZ, const float* plLimitXZ, const Eigen::Matrix4f& cameraViewInverse,
|
|
const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const float* ambientColor, const float* fogColor);
|
|
};
|
|
|
|
} // namespace FRG
|