#pragma once #include #include "textureid.h" #include "i_modelvertexbuffer.h" #include "matrix.h" #include "palettecontainer.h" #include "TRS.h" #include "tarray.h" #include "name.h" class DBoneComponents; class FModelRenderer; class FGameTexture; class IModelVertexBuffer; class FModel; struct FSpriteModelFrame; FTextureID LoadSkin(const char* path, const char* fn); void FlushModels(); extern TDeletingArray Models; extern TArray SpriteModelFrames; extern TMap BaseSpriteModelFrames; #define MD3_MAX_SURFACES 32 #define MIN_MODELS 4 struct FSpriteModelFrame { uint8_t modelsAmount = 0; TArray modelIDs; TArray skinIDs; TArray surfaceskinIDs; TArray modelframes; TArray animationIDs; float xscale, yscale, zscale; // [BB] Added zoffset, rotation parameters and flags. // Added xoffset, yoffset float xoffset, yoffset, zoffset; float xrotate, yrotate, zrotate; float rotationCenterX, rotationCenterY, rotationCenterZ; float rotationSpeed; private: unsigned int flags; public: const void* type; // used for hashing, must point to something usable as identifier for the model's owner. short sprite; short frame; int hashnext; float angleoffset; // added pithoffset, rolloffset. float pitchoffset, rolloffset; // I don't want to bother with type transformations, so I made this variables float. bool isVoxel; unsigned int getFlags(class DActorModelData * defs) const; friend void InitModels(); friend void ParseModelDefLump(int Lump); }; enum ModelRendererType { GLModelRendererType, SWModelRendererType, PolyModelRendererType, NumModelRendererTypes }; enum EFrameError { FErr_NotFound = -1, FErr_Voxel = -2, FErr_Singleframe = -3 }; class FModel { public: FModel(); virtual ~FModel(); virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0; virtual int FindFrame(const char * name, bool nodefault = false) = 0; // [RL0] these are used for decoupled iqm animations virtual int FindFirstFrame(FName name) { return FErr_NotFound; } virtual int FindLastFrame(FName name) { return FErr_NotFound; } virtual double FindFramerate(FName name) { return FErr_NotFound; } virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition) = 0; virtual void BuildVertexBuffer(FModelRenderer *renderer) = 0; virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) = 0; virtual float getAspectFactor(float vscale) { return 1.f; } virtual const TArray* AttachAnimationData() { return nullptr; }; virtual const TArray CalculateBones(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const TArray* animationData, DBoneComponents* bones, int index) { return {}; }; void SetVertexBuffer(int type, IModelVertexBuffer *buffer) { mVBuf[type] = buffer; } IModelVertexBuffer *GetVertexBuffer(int type) const { return mVBuf[type]; } void DestroyVertexBuffer(); bool hasSurfaces = false; FString mFileName; std::pair mFilePath; FSpriteModelFrame *baseFrame; private: IModelVertexBuffer *mVBuf[NumModelRendererTypes]; }; int ModelFrameHash(FSpriteModelFrame* smf); unsigned FindModel(const char* path, const char* modelfile, bool silent = false);