#ifndef _ITF_ANIMTEXPACKER_PATCH_H_ #define _ITF_ANIMTEXPACKER_PATCH_H_ #ifndef _ITF_PACKEDTEXTUREAREA_H_ #include "AnimTexPacker/PackedTextureArea.h" #endif #ifndef _ITF_TRANSFORM_H_ #include "core/math/transform.h" #endif //_ITF_TRANSFORM_H_ #ifndef _ITF_BV_AABB_H_ #include "core/boundingvolume/AABB.h" #endif //_ITF_BV_AABB_H_ #pragma warning(push) #pragma warning(disable : 4244 4127 4512) #include #include #include #include #include #include #include // NVIDIA has the bad idea to use defines to replace fcts, it's failing compilation #undef sqrt #undef sqrtf #undef acos #undef acosf #undef asin #undef asinf #pragma warning(pop) #ifndef ITF_GFX_MATERIAL_H_ #include "engine/display/material/GFXMaterial.h" #endif //ITF_GFX_MATERIAL_H_ namespace ITF { class AnimBone; class AnimTemplate; class AnimSkeleton; class AnimPatch; class AnimPatchPoint; class AnimPatchBank; #define PATH_HDIV_DEF 2 namespace AnimTexPacker { struct ImageTextureMode { nv::Image m_image; TextureSetSubID m_mode; }; /////////////////////////////////////////////////////////////////////////////////////////// class ChainedBones { public: SafeArray m_AnimBones; }; /////////////////////////////////////////////////////////////////////////////////////////// class BoneExtent { public: BoneExtent() {initEmpty();} void initEmpty() { m_worldExtent.setMin(Vec2d(1,1)); m_worldExtent.setMax(Vec2d(0,0)); m_uvExtent.setMin(Vec2d(1,1)); m_uvExtent.setMax(Vec2d(0,0)); } void grow(const Vec2d &_xy, const Vec2d &_uv) { if (m_worldExtent.isValid()) m_worldExtent.grow(_xy); else m_worldExtent = AABB(_xy,_xy); if (m_uvExtent.isValid()) m_uvExtent.grow(_uv); else m_uvExtent = AABB(_uv,_uv); } AABB m_worldExtent, m_uvExtent; }; class BoneMaxSize { public: BoneMaxSize() {initEmpty();} void initEmpty() { m_worldSize= AABB(Vec2d(0,0)); m_uvSize = AABB(Vec2d(0,0)); } void grow(const Vec2d &_worldSize, const Vec2d &_uvSize) { m_worldSize.grow(_worldSize); m_uvSize.grow(_uvSize); } f32 getMaxWorldSize() const {return Max(m_worldSize.getMax().x(), m_worldSize.getMax().y());} AABB m_worldSize; AABB m_uvSize; }; /////////////////////////////////////////////////////////////////////////////////////////// ///A patch : closed shape containing a texture. More or less an AnimTemplate+texture data+placement, but only 1 independent shape if bone is cut class Patch { public: Patch() : m_UVBox(0,0,0,0) , m_finalPos(0,0,0,0) , m_subImageWidth(0) , m_subImageHeight(0) , m_animTemplate(NULL) , m_initialImageWidth(0) , m_initialImageHeight(0) , m_skeleton(NULL) , m_sourceOfAlias(NULL) , m_uvModified(bfalse) , m_angle(0.f) , m_widthSampling(0) , m_heightSampling(0) { static int currentSerial=0; m_serialNumber = currentSerial; m_uvlocalToRotatedLocalTransform.setIdentity(); m_imageStretchTransform.setIdentity(); currentSerial++; } Patch(const Patch&) {ITF_ASSERT(bfalse);} Patch& operator=(const Patch&) {ITF_ASSERT(bfalse);return *this;} ~Patch(); /////////////////////////////////////////////////////////////////////////////////////////// void setAliasOf(Patch *_sourceOfAlias) {m_sourceOfAlias = _sourceOfAlias;} Patch *getSourceOfAlias() const {return m_sourceOfAlias;} /////////////////////////////////////////////////////////////////////////////////////////// const BoxI &getUVBox() const {return m_UVBox;} /////////////////////////////////////////////////////////////////////////////////////////// void setFinalPos(const BoxI &_finalBox, const Transform2d &_uvTransform); /////////////////////////////////////////////////////////////////////////////////////////// void setFinalPosFromAlias(); /////////////////////////////////////////////////////////////////////////////////////////// const StringID &getTemplateID() const {return m_templateID;} /////////////////////////////////////////////////////////////////////////////////////////// const Path& getImagePath() const {return m_diffuseImagePath;} const StringID & getBankID() const {return m_bankID;} /////////////////////////////////////////////////////////////////////////////////////////// int computePlacementHeuristic(PackedTextureArea *_area, BoxI &b); /////////////////////////////////////////////////////////////////////////////////////////// bbool Place(PackedTextureArea *_area, BoxI &b, bbool &_rotated, Transform2d &_subImageRotation); /////////////////////////////////////////////////////////////////////////////////////////// bbool isEqual(const Patch *_other); /////////////////////////////////////////////////////////////////////////////////////////// ///Initialize from animation data void initialize(const StringID &_bankID, const StringID &_templateID, AnimTemplate *_animTemplate, ChainedBones &_chainedBones, ITF_VECTOR &_imageTab, const Path &_imagePath, AnimSkeleton *_skeleton); int getUVBoundingWidth() const {return m_UVBox.maxx-m_UVBox.minx+1;} int getUVBoundingHeight() const {return m_UVBox.maxy-m_UVBox.miny+1;} u32 getSubImageWidth() const {return m_subImageWidth;} u32 getSubImageHeight() const {return m_subImageHeight;} /////////////////////////////////////////////////////////////////////////////////////////// void extractPixels(nv::Image &_image, u32 idx); const SafeArray &getBoneIndices() const {return m_boneIndices;} const ITF_VECTOR &getBoneIDs() const {return m_boneIDs;} /////////////////////////////////////////////////////////////////////////////////////////// void blitToFinalPos(nv::Image &_destImage, i32 xOffset, i32 yOffset, u32 _idx); /////////////////////////////////////////////////////////////////////////////////////////// void growPatchMaxSize(const BoneMaxSize& _toAdd ); /////////////////////////////////////////////////////////////////////////////////////////// const BoneMaxSize &getPatchMaxSize() const; nv::Color32 getPixel(int _x, int _y, u32 idx) const { int w = (int)getSubImageWidth(); ITF_ASSERT(_x>=0 && _y>=0 && _x=0 && _y>=0 && _x &_alreadyProcessedPoints); /////////////////////////////////////////////////////////////////////////////////////////// AnimTemplate * getAnimTemplate( ) { return m_animTemplate; } /////////////////////////////////////////////////////////////////////////////////////////// AnimSkeleton * getAnimSkeleton( ) { return m_skeleton; } int getInitialImageWidth ( ) { return m_initialImageWidth; } int getInitialImageHeight ( ) { return m_initialImageHeight; } const ITF_VECTOR & getPointList() { return m_pointList; } void setAngle(f32 _angle) { m_angle = _angle; } const Vec2d & getProcessDelta() { return m_processDelta; } void setSample(u32 _width, u32 _height, const SafeArray & _sampling ); static void setSaveInFile(const Path & _fileModel) { m_saveInFile = _fileModel; } static u32 s_patchHdiv; private: /////////////////////////////////////////////////////////////////////////////////////////// bbool computePatchUVAABB(AnimPatch *_patch, AABB &UVs, nv::Image &_image, Vec2d *_ptList); /////////////////////////////////////////////////////////////////////////////////////////// ///compute uv aabb from animation data void computeUVAABB(AnimTemplate *_template, ChainedBones &_chainedBones, nv::Image &_image); /////////////////////////////////////////////////////////////////////////////////////////// static Path m_saveInFile; Path getPixelsTabFileName(u32 _idx); nv::Color32 * savePixelsTab(nv::Color32 * _pixelTab, u32 _idx); nv::Color32 * loadPixelsTab(nv::Color32 * _pixelTab, u32 _idx); AnimTemplate * m_animTemplate; StringID m_bankID; StringID m_templateID; BoxI m_UVBox; BoxI m_finalPos; Vec2d m_processDelta; int m_subImageWidth; int m_subImageHeight; SafeArray m_pixelsTab; Path m_diffuseImagePath; int m_serialNumber; SafeArray m_boneIndices; ITF_VECTOR m_boneIDs; bbool m_uvModified; static const u32 m_PatchsDegree = 4; static const u32 m_PatchsNumberOfCurves = 2; BoneMaxSize m_boneMaxSize; AnimSkeleton *m_skeleton; int m_initialImageWidth; int m_initialImageHeight; Patch *m_sourceOfAlias; //Transforms the m_pPixels in UV coordinates in the same coordinate frame, but with possibly a rotation (eg a 90 deg) Transform2d m_uvlocalToRotatedLocalTransform, m_imageStretchTransform; f32 m_angle; ITF_VECTOR m_pointList; SafeArray m_sampling; u32 m_widthSampling; u32 m_heightSampling; }; /////////////////////////////////////////////////////////////////////////////////////////// /// List of patches class PatchList { public: static u32 CURRENT_SAMPLING; Path m_patchImagePath; AnimPatchBank * m_patchBank; ITF_VECTOR m_usedPatches; ITF_LIST m_patches; StringID m_bankName; u32 m_imgMask; u32 m_imgUseAlphaMask; u32 m_hdDownscaleMask; /////////////////////////////////////////////////////////////////////////////////////////// PatchList() { m_patchBank = NULL; } /////////////////////////////////////////////////////////////////////////////////////////// void destroy(void) { ITF_LIST::iterator iter; for (iter=m_patches.begin(); iter!=m_patches.end(); iter++) { delete *iter; } m_patches.clear(); m_usedPatches.clear(); } }; } } #endif