tsMaterialList.cpp
Engine/source/ts/tsMaterialList.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "ts/tsMaterialList.h" 26 27#include "ts/tsShape.h" 28#include "materials/matInstance.h" 29#include "materials/materialManager.h" 30 31 32TSMaterialList::TSMaterialList(U32 materialCount, 33 const char **materialNames, 34 const U32 * materialFlags, 35 const U32 * reflectanceMaps, 36 const U32 * bumpMaps, 37 const U32 * detailMaps, 38 const F32 * detailScales, 39 const F32 * reflectionAmounts) 40 : MaterialList(materialCount,materialNames), 41 mNamesTransformed(false) 42{ 43 VECTOR_SET_ASSOCIATION(mFlags); 44 VECTOR_SET_ASSOCIATION(mReflectanceMaps); 45 VECTOR_SET_ASSOCIATION(mBumpMaps); 46 VECTOR_SET_ASSOCIATION(mDetailMaps); 47 VECTOR_SET_ASSOCIATION(mDetailScales); 48 VECTOR_SET_ASSOCIATION(mReflectionAmounts); 49 50 allocate(materialCount); 51 52 dMemcpy(mFlags.address(),materialFlags,materialCount*sizeof(U32)); 53 dMemcpy(mReflectanceMaps.address(),reflectanceMaps,materialCount*sizeof(U32)); 54 dMemcpy(mBumpMaps.address(),bumpMaps,materialCount*sizeof(U32)); 55 dMemcpy(mDetailMaps.address(),detailMaps,materialCount*sizeof(U32)); 56 dMemcpy(mDetailScales.address(),detailScales,materialCount*sizeof(F32)); 57 dMemcpy(mReflectionAmounts.address(),reflectionAmounts,materialCount*sizeof(F32)); 58} 59 60TSMaterialList::TSMaterialList() 61 : mNamesTransformed(false) 62{ 63 VECTOR_SET_ASSOCIATION(mFlags); 64 VECTOR_SET_ASSOCIATION(mReflectanceMaps); 65 VECTOR_SET_ASSOCIATION(mBumpMaps); 66 VECTOR_SET_ASSOCIATION(mDetailMaps); 67 VECTOR_SET_ASSOCIATION(mDetailScales); 68 VECTOR_SET_ASSOCIATION(mReflectionAmounts); 69} 70 71TSMaterialList::TSMaterialList(const TSMaterialList* pCopy) 72 : MaterialList(pCopy) 73{ 74 VECTOR_SET_ASSOCIATION(mFlags); 75 VECTOR_SET_ASSOCIATION(mReflectanceMaps); 76 VECTOR_SET_ASSOCIATION(mBumpMaps); 77 VECTOR_SET_ASSOCIATION(mDetailMaps); 78 VECTOR_SET_ASSOCIATION(mDetailScales); 79 VECTOR_SET_ASSOCIATION(mReflectionAmounts); 80 81 mFlags = pCopy->mFlags; 82 mReflectanceMaps = pCopy->mReflectanceMaps; 83 mBumpMaps = pCopy->mBumpMaps; 84 mDetailMaps = pCopy->mDetailMaps; 85 mDetailScales = pCopy->mDetailScales; 86 mReflectionAmounts = pCopy->mReflectionAmounts; 87 mNamesTransformed = pCopy->mNamesTransformed; 88} 89 90TSMaterialList::~TSMaterialList() 91{ 92 free(); 93} 94 95void TSMaterialList::free() 96{ 97 // these aren't found on our parent, clear them out here to keep in synch 98 mFlags.clear(); 99 mReflectanceMaps.clear(); 100 mBumpMaps.clear(); 101 mDetailMaps.clear(); 102 mDetailScales.clear(); 103 mReflectionAmounts.clear(); 104 105 Parent::free(); 106} 107 108void TSMaterialList::push_back(const String &name, U32 flags, U32 rMap, U32 bMap, U32 dMap, F32 dScale, F32 emapAmount) 109{ 110 Parent::push_back(name); 111 mFlags.push_back(flags); 112 if (rMap==0xFFFFFFFF) 113 mReflectanceMaps.push_back(size()-1); 114 else 115 mReflectanceMaps.push_back(rMap); 116 mBumpMaps.push_back(bMap); 117 mDetailMaps.push_back(dMap); 118 mDetailScales.push_back(dScale); 119 mReflectionAmounts.push_back(emapAmount); 120} 121 122void TSMaterialList::push_back(const char * name, U32 flags, Material* mat) 123{ 124 Parent::push_back(name, mat); 125 mFlags.push_back(flags); 126 mReflectanceMaps.push_back(size()-1); 127 mBumpMaps.push_back(0xFFFFFFFF); 128 mDetailMaps.push_back(0xFFFFFFFF); 129 mDetailScales.push_back(1.0f); 130 mReflectionAmounts.push_back(1.0f); 131} 132 133void TSMaterialList::allocate(U32 sz) 134{ 135 mFlags.setSize(sz); 136 mReflectanceMaps.setSize(sz); 137 mBumpMaps.setSize(sz); 138 mDetailMaps.setSize(sz); 139 mDetailScales.setSize(sz); 140 mReflectionAmounts.setSize(sz); 141} 142 143U32 TSMaterialList::getFlags(U32 index) 144{ 145 AssertFatal(index < size(),"TSMaterialList::getFlags: index out of range"); 146 return mFlags[index]; 147} 148 149void TSMaterialList::setFlags(U32 index, U32 value) 150{ 151 AssertFatal(index < size(),"TSMaterialList::getFlags: index out of range"); 152 mFlags[index] = value; 153} 154 155bool TSMaterialList::write(Stream & s) 156{ 157 if (!Parent::write(s)) 158 return false; 159 160 U32 i; 161 for (i=0; i<size(); i++) 162 s.write(mFlags[i]); 163 164 for (i=0; i<size(); i++) 165 s.write(mReflectanceMaps[i]); 166 167 for (i=0; i<size(); i++) 168 s.write(mBumpMaps[i]); 169 170 for (i=0; i<size(); i++) 171 s.write(mDetailMaps[i]); 172 173 // MDF - This used to write mLightmaps 174 // We never ended up using it but it is 175 // still part of the version 25 standard 176 if (TSShape::smVersion == 25) 177 { 178 for (i=0; i<size(); i++) 179 s.write(0xFFFFFFFF); 180 } 181 182 for (i=0; i<size(); i++) 183 s.write(mDetailScales[i]); 184 185 for (i=0; i<size(); i++) 186 s.write(mReflectionAmounts[i]); 187 188 return (s.getStatus() == Stream::Ok); 189} 190 191bool TSMaterialList::read(Stream & s) 192{ 193 if (!Parent::read(s)) 194 return false; 195 196 allocate(size()); 197 198 U32 i; 199 if (TSShape::smReadVersion < 2) 200 { 201 for (i=0; i<size(); i++) 202 setFlags(i,S_Wrap</a>|<a href="/coding/class/classtsmateriallist/#classtsmateriallist_1ac5b6fc96f66c62f4381d0ee006754267af580f30fa00dd8cd3ffabdafaaa3efb1">T_Wrap); 203 } 204 else 205 { 206 for (i=0; i<size(); i++) 207 s.read(&mFlags[i]); 208 } 209 210 if (TSShape::smReadVersion < 5) 211 { 212 for (i=0; i<size(); i++) 213 { 214 mReflectanceMaps[i] = i; 215 mBumpMaps[i] = 0xFFFFFFFF; 216 mDetailMaps[i] = 0xFFFFFFFF; 217 } 218 } 219 else 220 { 221 for (i=0; i<size(); i++) 222 s.read(&mReflectanceMaps[i]); 223 for (i=0; i<size(); i++) 224 s.read(&mBumpMaps[i]); 225 for (i=0; i<size(); i++) 226 s.read(&mDetailMaps[i]); 227 228 if (TSShape::smReadVersion == 25) 229 { 230 U32 dummy = 0; 231 232 for (i=0; i<size(); i++) 233 s.read(&dummy); 234 } 235 } 236 237 if (TSShape::smReadVersion > 11) 238 { 239 for (i=0; i<size(); i++) 240 s.read(&mDetailScales[i]); 241 } 242 else 243 { 244 for (i=0; i<size(); i++) 245 mDetailScales[i] = 1.0f; 246 } 247 248 if (TSShape::smReadVersion > 20) 249 { 250 for (i=0; i<size(); i++) 251 s.read(&mReflectionAmounts[i]); 252 } 253 else 254 { 255 for (i=0; i<size(); i++) 256 mReflectionAmounts[i] = 1.0f; 257 } 258 259 if (TSShape::smReadVersion < 16) 260 { 261 // make sure emapping is off for translucent materials on old shapes 262 for (i=0; i<size(); i++) 263 if (mFlags[i] & TSMaterialList::Translucent) 264 mFlags[i] |= TSMaterialList::NeverEnvMap; 265 } 266 267 return (s.getStatus() == Stream::Ok); 268} 269 270//-------------------------------------------------------------------------- 271// Sets the specified material in the list to the specified texture. also 272// remaps mat instances based on the new texture name. Returns false if 273// the specified texture is not valid. 274//-------------------------------------------------------------------------- 275bool TSMaterialList::renameMaterial(U32 i, const String& newName) 276{ 277 if (i > size() || newName.isEmpty()) 278 return false; 279 280 // Check if already using this name 281 if (newName.equal(mMaterialNames[i], String::NoCase)) 282 { 283 // same material, return true since we aren't changing it 284 return true; 285 } 286 287 // Allow the rename if the new name is mapped, or if there is a diffuse texture 288 // available (for which a simple Material can be generated in mapMaterial) 289 String mappedName = MATMGR->getMapEntry(newName); 290 if (mappedName.isEmpty()) 291 { 292 GFXTexHandle texHandle; 293 if (mLookupPath.isEmpty()) 294 { 295 texHandle.set( newName, &GFXStaticTextureSRGBProfile, avar("%s() - handle (line %d)", __FUNCTION__, __LINE__) ); 296 } 297 else 298 { 299 String fullPath = String::ToString( "%s/%s", mLookupPath.c_str(), newName.c_str() ); 300 texHandle.set( fullPath, &GFXStaticTextureSRGBProfile, avar("%s() - handle (line %d)", __FUNCTION__, __LINE__) ); 301 } 302 if (!texHandle.isValid()) 303 return false; 304 } 305 306 // change material name 307 mMaterialNames[i] = newName; 308 309 // Dump the old mat instance and remap the material. 310 if( mMatInstList[ i ] ) 311 SAFE_DELETE( mMatInstList[ i ] ); 312 mapMaterial( i ); 313 314 return true; 315} 316 317void TSMaterialList::mapMaterial( U32 i ) 318{ 319 Parent::mapMaterial( i ); 320 321 BaseMatInstance* matInst = mMatInstList[i]; 322 if (matInst && matInst->getMaterial()->isTranslucent()) 323 mFlags[i] |= Translucent; 324} 325