1 /** @file modeldef.h 3D model resource definition. 2 * 3 * @authors Copyright © 2003-2017 Jaakko Keränen <jaakko.keranen@iki.fi> 4 * @authors Copyright © 2006-2013 Daniel Swanson <danij@dengine.net> 5 * 6 * @par License 7 * GPL: http://www.gnu.org/licenses/gpl.html 8 * 9 * <small>This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. This program is distributed in the hope that it 13 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 * Public License for more details. You should have received a copy of the GNU 16 * General Public License along with this program; if not, write to the Free 17 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 * 02110-1301 USA</small> 19 */ 20 21 #ifndef DENG_RESOURCE_FRAMEMODELDEF_H 22 #define DENG_RESOURCE_FRAMEMODELDEF_H 23 24 #include <vector> 25 #include <de/Vector> 26 #include <doomsday/defs/ded.h> 27 #include <doomsday/defs/model.h> 28 29 #include "framemodel.h" 30 31 /** 32 * @defgroup modelFrameFlags Model frame flags 33 * @ingroup flags 34 */ 35 ///@{ 36 #define MFF_FULLBRIGHT 0x00000001 37 #define MFF_SHADOW1 0x00000002 38 #define MFF_SHADOW2 0x00000004 39 #define MFF_BRIGHTSHADOW 0x00000008 40 #define MFF_MOVEMENT_PITCH 0x00000010 ///< Pitch aligned to movement. 41 #define MFF_SPIN 0x00000020 ///< Spin around (for bonus items). 42 #define MFF_SKINTRANS 0x00000040 ///< Color translation -> skins. 43 #define MFF_AUTOSCALE 0x00000080 ///< Scale to match sprite height. 44 #define MFF_MOVEMENT_YAW 0x00000100 45 #define MFF_DONT_INTERPOLATE 0x00000200 ///< Don't interpolate from the frame. 46 #define MFF_BRIGHTSHADOW2 0x00000400 47 #define MFF_ALIGN_YAW 0x00000800 48 #define MFF_ALIGN_PITCH 0x00001000 49 #define MFF_DARKSHADOW 0x00002000 50 #define MFF_IDSKIN 0x00004000 ///< Mobj id -> skin in skin range 51 #define MFF_DISABLE_Z_WRITE 0x00008000 52 #define MFF_NO_DISTANCE_CHECK 0x00010000 53 #define MFF_SELSKIN 0x00020000 54 #define MFF_PARTICLE_SUB1 0x00040000 ///< Sub1 center is particle origin. 55 #define MFF_NO_PARTICLES 0x00080000 ///< No particles for this object. 56 #define MFF_SHINY_SPECULAR 0x00100000 ///< Shiny skin rendered as additive. 57 #define MFF_SHINY_LIT 0x00200000 ///< Shiny skin is not fullbright. 58 #define MFF_IDFRAME 0x00400000 ///< Mobj id -> frame in frame range 59 #define MFF_IDANGLE 0x00800000 ///< Mobj id -> static angle offset 60 #define MFF_DIM 0x01000000 ///< Never fullbright. 61 #define MFF_SUBTRACT 0x02000000 ///< Subtract blending. 62 #define MFF_REVERSE_SUBTRACT 0x04000000 ///< Reverse subtract blending. 63 #define MFF_TWO_SIDED 0x08000000 ///< Disable culling. 64 #define MFF_NO_TEXCOMP 0x10000000 ///< Never compress skins. 65 #define MFF_WORLD_TIME_ANIM 0x20000000 66 ///@} 67 68 struct SubmodelDef 69 { 70 modelid_t modelId; 71 short frame; 72 char frameRange; 73 int _flags; 74 short skin; 75 char skinRange; 76 de::Vector3f offset; 77 byte alpha; 78 res::Texture *shinySkin; 79 blendmode_t blendMode; 80 SubmodelDefSubmodelDef81 SubmodelDef() 82 : modelId(0) 83 , frame(0) 84 , frameRange(0) 85 , _flags(0) 86 , skin(0) 87 , skinRange(0) 88 , alpha(0) 89 , shinySkin(0) 90 , blendMode(BM_NORMAL) 91 {} 92 setFlagsSubmodelDef93 void setFlags(int newFlags) 94 { 95 _flags = newFlags; 96 } 97 98 /** 99 * Tests if the flags in @a flag are all set for the submodel. 100 * 101 * @param flag One or more flags. 102 * 103 * @return @c true, if all the flags were set; otherwise @c false. 104 */ testFlagSubmodelDef105 bool testFlag(int flag) const 106 { 107 return (_flags & flag) == flag; 108 } 109 }; 110 111 #define MODELDEF_ID_MAXLEN 32 112 113 struct FrameModelDef 114 { 115 char id[MODELDEF_ID_MAXLEN + 1]; 116 117 /// Pointer to the states list. 118 state_t *state = nullptr; 119 120 int flags = 0; 121 uint group = 0; 122 int select = 0; 123 short skinTics = 0; 124 125 /// [0,1) When is this frame in effect? 126 float interMark = 0; 127 float interRange[2]; 128 de::Vector3f offset; 129 float resize = 0; 130 de::Vector3f scale; 131 132 typedef std::vector<de::Vector3f> PtcOffsets; 133 PtcOffsets _ptcOffset; 134 135 float visualRadius = 0; 136 float shadowRadius = 0; // if zero, visual radius used instead 137 138 defn::Model def; 139 140 /// Points to next inter-frame, or NULL. 141 FrameModelDef *interNext = nullptr; 142 143 /// Points to next selector, or NULL (only for "base" modeldefs). 144 FrameModelDef *selectNext = nullptr; 145 146 /// Submodels. 147 typedef std::vector<SubmodelDef> Subs; 148 Subs _sub; 149 150 FrameModelDef(char const *modelDefId = "") 151 { 152 de::zap(id); 153 de::zap(interRange); 154 strncpy(id, modelDefId, MODELDEF_ID_MAXLEN); 155 } 156 addSubFrameModelDef157 SubmodelDef *addSub() 158 { 159 _sub.push_back(SubmodelDef()); 160 _ptcOffset.push_back(de::Vector3f()); 161 return &_sub.back(); 162 } 163 clearSubsFrameModelDef164 void clearSubs() 165 { 166 _sub.clear(); 167 _ptcOffset.clear(); 168 } 169 subCountFrameModelDef170 uint subCount() const 171 { 172 return uint(_sub.size()); 173 } 174 testSubFlagFrameModelDef175 bool testSubFlag(unsigned int subnum, int flag) const 176 { 177 if(!hasSub(subnum)) return false; 178 return _sub[subnum].testFlag(flag); 179 } 180 subModelIdFrameModelDef181 modelid_t subModelId(unsigned int subnum) const 182 { 183 if(!hasSub(subnum)) return NOMODELID; 184 return _sub[subnum].modelId; 185 } 186 subModelDefFrameModelDef187 SubmodelDef &subModelDef(unsigned int subnum) 188 { 189 DENG2_ASSERT(hasSub(subnum)); 190 return _sub[subnum]; 191 } 192 subModelDefFrameModelDef193 SubmodelDef const &subModelDef(unsigned int subnum) const 194 { 195 DENG2_ASSERT(hasSub(subnum)); 196 return _sub[subnum]; 197 } 198 hasSubFrameModelDef199 bool hasSub(unsigned int subnum) const 200 { 201 return subnum < _sub.size(); 202 } 203 particleOffsetFrameModelDef204 de::Vector3f particleOffset(unsigned int subnum) const 205 { 206 if(hasSub(subnum)) 207 { 208 DENG2_ASSERT(subnum < _ptcOffset.size()); 209 return _ptcOffset[subnum]; 210 } 211 return de::Vector3f(); 212 } 213 setParticleOffsetFrameModelDef214 void setParticleOffset(unsigned int subnum, de::Vector3f const &off) 215 { 216 DENG2_ASSERT(hasSub(subnum)); 217 _ptcOffset[subnum] = off; 218 } 219 }; 220 221 #endif // DENG_RESOURCE_FRAMEMODELDEF_H 222