1 /* bzflag
2  * Copyright (c) 1993-2021 Tim Riker
3  *
4  * This package is free software;  you can redistribute it and/or
5  * modify it under the terms of the license found in the file
6  * named COPYING that should have accompanied this file.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 #include <string.h>
14 
15 #include "BzMaterial.h"
16 #include "TextureMatrix.h"
17 #include "DynamicColor.h"
18 #include "Pack.h"
19 
20 
21 /****************************************************************************/
22 //
23 // BzMaterialManager
24 //
25 
26 BzMaterialManager MATERIALMGR;
27 
28 
BzMaterialManager()29 BzMaterialManager::BzMaterialManager()
30 {
31     return;
32 }
33 
34 
~BzMaterialManager()35 BzMaterialManager::~BzMaterialManager()
36 {
37     clear();
38     return;
39 }
40 
41 
clear()42 void BzMaterialManager::clear()
43 {
44     for (unsigned int i = 0; i < materials.size(); i++)
45         delete materials[i];
46     materials.clear();
47     return;
48 }
49 
50 
addMaterial(const BzMaterial * material)51 const BzMaterial* BzMaterialManager::addMaterial(const BzMaterial* material)
52 {
53     for (unsigned int i = 0; i < materials.size(); i++)
54     {
55         if (*material == *(materials[i]))
56         {
57             const std::string& name = material->getName();
58             if (name.size() > 0)
59                 materials[i]->addAlias(name);
60             return materials[i];
61         }
62     }
63     BzMaterial* newMat = new BzMaterial(*material);
64     if (findMaterial(newMat->getName()) != NULL)
65         newMat->setName("");
66     materials.push_back(newMat);
67     return newMat;
68 }
69 
70 
findMaterial(const std::string & target) const71 const BzMaterial* BzMaterialManager::findMaterial(const std::string& target) const
72 {
73     if (target.size() <= 0)
74         return NULL;
75     else if ((target[0] >= '0') && (target[0] <= '9'))
76     {
77         int index = atoi (target.c_str());
78         if ((index < 0) || (index >= (int)materials.size()))
79             return NULL;
80         else
81             return materials[index];
82     }
83     else
84     {
85         for (unsigned int i = 0; i < materials.size(); i++)
86         {
87             const BzMaterial* mat = materials[i];
88             // check the base name
89             if (target == mat->getName())
90                 return mat;
91             // check the aliases
92             const std::vector<std::string>& aliases = mat->getAliases();
93             for (unsigned int j = 0; j < aliases.size(); j++)
94             {
95                 if (target == aliases[j])
96                     return mat;
97             }
98         }
99         return NULL;
100     }
101 }
102 
103 
getMaterial(int id) const104 const BzMaterial* BzMaterialManager::getMaterial(int id) const
105 {
106     if ((id < 0) || (id >= (int)materials.size()))
107         return BzMaterial::getDefault();
108     return materials[id];
109 }
110 
111 
getIndex(const BzMaterial * material) const112 int BzMaterialManager::getIndex(const BzMaterial* material) const
113 {
114     for (unsigned int i = 0; i < materials.size(); i++)
115     {
116         if (material == materials[i])
117             return i;
118     }
119     return -1;
120 }
121 
122 
pack(void * buf)123 void* BzMaterialManager::pack(void* buf)
124 {
125     buf = nboPackUInt(buf, (unsigned int)materials.size());
126     for (unsigned int i = 0; i < materials.size(); i++)
127         buf = materials[i]->pack(buf);
128 
129     return buf;
130 }
131 
132 
unpack(const void * buf)133 const void* BzMaterialManager::unpack(const void* buf)
134 {
135     unsigned int i;
136     uint32_t count;
137     buf = nboUnpackUInt (buf, count);
138     for (i = 0; i < count; i++)
139     {
140         BzMaterial* mat = new BzMaterial;
141         buf = mat->unpack(buf);
142         materials.push_back(mat);
143     }
144     return buf;
145 }
146 
147 
packSize()148 int BzMaterialManager::packSize()
149 {
150     int fullSize = sizeof (uint32_t);
151     for (unsigned int i = 0; i < materials.size(); i++)
152         fullSize += materials[i]->packSize();
153     return fullSize;
154 }
155 
156 
print(std::ostream & out,const std::string & indent) const157 void BzMaterialManager::print(std::ostream& out, const std::string& indent) const
158 {
159     for (unsigned int i = 0; i < materials.size(); i++)
160         materials[i]->print(out, indent);
161     return;
162 }
163 
164 
printMTL(std::ostream & out,const std::string & indent) const165 void BzMaterialManager::printMTL(std::ostream& out, const std::string& indent) const
166 {
167     for (unsigned int i = 0; i < materials.size(); i++)
168         materials[i]->printMTL(out, indent);
169     return;
170 }
171 
172 
printReference(std::ostream & out,const BzMaterial * mat) const173 void BzMaterialManager::printReference(std::ostream& out,
174                                        const BzMaterial* mat) const
175 {
176     if (mat == NULL)
177     {
178         out << "-1";
179         return;
180     }
181     int index = getIndex(mat);
182     if (index == -1)
183     {
184         out << "-1";
185         return;
186     }
187     if (mat->getName().size() > 0)
188     {
189         out << mat->getName();
190         return;
191     }
192     else
193     {
194         out << index;
195         return;
196     }
197 }
198 
199 
makeTextureList(TextureSet & set,bool referenced) const200 void BzMaterialManager::makeTextureList(TextureSet& set, bool referenced) const
201 {
202     set.clear();
203     for (unsigned int i = 0; i < materials.size(); i++)
204     {
205         const BzMaterial* mat = materials[i];
206         for (int j = 0; j < mat->getTextureCount(); j++)
207         {
208             if (mat->getReference() || !referenced)
209                 set.insert(mat->getTexture(j));
210         }
211     }
212     return;
213 }
214 
215 
setTextureLocal(const std::string & url,const std::string & local)216 void BzMaterialManager::setTextureLocal(const std::string& url,
217                                         const std::string& local)
218 {
219     for (unsigned int i = 0; i < materials.size(); i++)
220     {
221         BzMaterial* mat = materials[i];
222         for (int j = 0; j < mat->getTextureCount(); j++)
223         {
224             if (mat->getTexture(j) == url)
225                 mat->setTextureLocal(j, local);
226         }
227     }
228     return;
229 }
230 
231 
232 /****************************************************************************/
233 //
234 // BzMaterial
235 //
236 
237 BzMaterial BzMaterial::defaultMaterial;
238 std::string BzMaterial::nullString = "";
239 
240 
reset()241 void BzMaterial::reset()
242 {
243     dynamicColor = -1;
244     const float defAmbient[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
245     const float defDiffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
246     const float defSpecular[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
247     const float defEmission[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
248     memcpy (ambient, defAmbient, sizeof(ambient));
249     memcpy (diffuse, defDiffuse, sizeof(diffuse));
250     memcpy (specular, defSpecular, sizeof(specular));
251     memcpy (emission, defEmission, sizeof(emission));
252     shininess = 0.0f;
253     alphaThreshold = 0.0f;
254     occluder = false;
255     groupAlpha = false;
256     noRadar = false;
257     noShadow = false;
258     noCulling = false;
259     noSorting = false;
260     noLighting = false;
261 
262     delete[] textures;
263     textures = NULL;
264     textureCount = 0;
265 
266     delete[] shaders;
267     shaders = NULL;
268     shaderCount = 0;
269 
270     referenced = false;
271 
272     return;
273 }
274 
275 
BzMaterial()276 BzMaterial::BzMaterial()
277 {
278     textures = NULL;
279     shaders = NULL;
280     reset();
281     return;
282 }
283 
284 
~BzMaterial()285 BzMaterial::~BzMaterial()
286 {
287     delete[] textures;
288     delete[] shaders;
289     return;
290 }
291 
292 
BzMaterial(const BzMaterial & m)293 BzMaterial::BzMaterial(const BzMaterial& m)
294 {
295     textures = NULL;
296     shaders = NULL;
297     *this = m;
298     return;
299 }
300 
301 
operator =(const BzMaterial & m)302 BzMaterial& BzMaterial::operator=(const BzMaterial& m)
303 {
304     int i;
305 
306     referenced = false;
307 
308     name = m.name;
309     aliases = m.aliases;
310 
311     dynamicColor = m.dynamicColor;
312     memcpy (ambient, m.ambient, sizeof(ambient));
313     memcpy (diffuse, m.diffuse, sizeof(diffuse));
314     memcpy (specular, m.specular, sizeof(specular));
315     memcpy (emission, m.emission, sizeof(emission));
316     shininess = m.shininess;
317     alphaThreshold = m.alphaThreshold;
318     occluder = m.occluder;
319     groupAlpha = m.groupAlpha;
320     noRadar = m.noRadar;
321     noShadow = m.noShadow;
322     noCulling = m.noCulling;
323     noSorting = m.noSorting;
324     noLighting = m.noLighting;
325 
326     delete[] textures;
327     textureCount = m.textureCount;
328     if (textureCount > 0)
329         textures = new TextureInfo[textureCount];
330     else
331         textures = NULL;
332     for (i = 0; i < textureCount; i++)
333         textures[i] = m.textures[i];
334 
335     delete[] shaders;
336     shaderCount = m.shaderCount;
337     if (shaderCount > 0)
338         shaders = new ShaderInfo[shaderCount];
339     else
340         shaders = NULL;
341     for (i = 0; i < shaderCount; i++)
342         shaders[i] = m.shaders[i];
343 
344     return *this;
345 }
346 
347 
operator ==(const BzMaterial & m) const348 bool BzMaterial::operator==(const BzMaterial& m) const
349 {
350     int i;
351 
352     if ((dynamicColor != m.dynamicColor) ||
353             (memcmp (ambient, m.ambient, sizeof(float[4])) != 0) ||
354             (memcmp (diffuse, m.diffuse, sizeof(float[4])) != 0) ||
355             (memcmp (specular, m.specular, sizeof(float[4])) != 0) ||
356             (memcmp (emission, m.emission, sizeof(float[4])) != 0) ||
357             (shininess != m.shininess) || (alphaThreshold != m.alphaThreshold) ||
358             (occluder != m.occluder) || (groupAlpha != m.groupAlpha) ||
359             (noRadar != m.noRadar) || (noShadow != m.noShadow) ||
360             (noCulling != m.noCulling) || (noSorting != m.noSorting) ||
361             (noLighting != m.noLighting))
362         return false;
363 
364     if (textureCount != m.textureCount)
365         return false;
366     for (i = 0; i < textureCount; i++)
367     {
368         if ((textures[i].name != m.textures[i].name) ||
369                 (textures[i].matrix != m.textures[i].matrix) ||
370                 (textures[i].combineMode != m.textures[i].combineMode) ||
371                 (textures[i].useAlpha != m.textures[i].useAlpha) ||
372                 (textures[i].useColor != m.textures[i].useColor) ||
373                 (textures[i].useSphereMap != m.textures[i].useSphereMap))
374             return false;
375     }
376 
377     if (shaderCount != m.shaderCount)
378         return false;
379     for (i = 0; i < shaderCount; i++)
380     {
381         if (shaders[i].name != m.shaders[i].name)
382             return false;
383     }
384 
385     return true;
386 }
387 
388 
pack4Float(void * buf,const float values[4])389 static void* pack4Float(void *buf, const float values[4])
390 {
391     int i;
392     for (i = 0; i < 4; i++)
393         buf = nboPackFloat(buf, values[i]);
394     return buf;
395 }
396 
397 
unpack4Float(const void * buf,float values[4])398 static const void* unpack4Float(const void *buf, float values[4])
399 {
400     int i;
401     for (i = 0; i < 4; i++)
402         buf = nboUnpackFloat(buf, values[i]);
403     return buf;
404 }
405 
406 
pack(void * buf) const407 void* BzMaterial::pack(void* buf) const
408 {
409     int i;
410 
411     buf = nboPackStdString(buf, name);
412 
413     uint8_t modeByte = 0;
414     if (noCulling)    modeByte |= (1 << 0);
415     if (noSorting)    modeByte |= (1 << 1);
416     if (noRadar)      modeByte |= (1 << 2);
417     if (noShadow)     modeByte |= (1 << 3);
418     if (occluder)  modeByte |= (1 << 4);
419     if (groupAlpha)       modeByte |= (1 << 5);
420     if (noLighting)       modeByte |= (1 << 6);
421     buf = nboPackUByte(buf, modeByte);
422 
423     buf = nboPackInt(buf, dynamicColor);
424     buf = pack4Float(buf, ambient);
425     buf = pack4Float(buf, diffuse);
426     buf = pack4Float(buf, specular);
427     buf = pack4Float(buf, emission);
428     buf = nboPackFloat(buf, shininess);
429     buf = nboPackFloat(buf, alphaThreshold);
430 
431     buf = nboPackUByte(buf, textureCount);
432     for (i = 0; i < textureCount; i++)
433     {
434         const TextureInfo* texinfo = &textures[i];
435 
436         buf = nboPackStdString(buf, texinfo->name);
437         buf = nboPackInt(buf, texinfo->matrix);
438         buf = nboPackInt(buf, texinfo->combineMode);
439         unsigned char stateByte = 0;
440         if (texinfo->useAlpha)
441             stateByte = stateByte | (1 << 0);
442         if (texinfo->useColor)
443             stateByte = stateByte | (1 << 1);
444         if (texinfo->useSphereMap)
445             stateByte = stateByte | (1 << 2);
446         buf = nboPackUByte(buf, stateByte);
447     }
448 
449     buf = nboPackUByte(buf, shaderCount);
450     for (i = 0; i < shaderCount; i++)
451         buf = nboPackStdString(buf, shaders[i].name);
452 
453     return buf;
454 }
455 
456 
unpack(const void * buf)457 const void* BzMaterial::unpack(const void* buf)
458 {
459     int i;
460     int32_t inTmp;
461 
462     buf = nboUnpackStdString(buf, name);
463 
464     uint8_t modeByte;
465     buf = nboUnpackUByte(buf, modeByte);
466     noCulling = (modeByte & (1 << 0)) != 0;
467     noSorting = (modeByte & (1 << 1)) != 0;
468     noRadar   = (modeByte & (1 << 2)) != 0;
469     noShadow  = (modeByte & (1 << 3)) != 0;
470     occluder  = (modeByte & (1 << 4)) != 0;
471     groupAlpha    = (modeByte & (1 << 5)) != 0;
472     noLighting    = (modeByte & (1 << 6)) != 0;
473 
474     buf = nboUnpackInt(buf, inTmp);
475     dynamicColor = int(inTmp);
476     buf = unpack4Float(buf, ambient);
477     buf = unpack4Float(buf, diffuse);
478     buf = unpack4Float(buf, specular);
479     buf = unpack4Float(buf, emission);
480     buf = nboUnpackFloat(buf, shininess);
481     buf = nboUnpackFloat(buf, alphaThreshold);
482 
483     unsigned char tCount;
484     buf = nboUnpackUByte(buf, tCount);
485     textureCount = tCount;
486     textures = new TextureInfo[textureCount];
487     for (i = 0; i < textureCount; i++)
488     {
489         TextureInfo* texinfo = &textures[i];
490         buf = nboUnpackStdString(buf, texinfo->name);
491         texinfo->localname = texinfo->name;
492         buf = nboUnpackInt(buf, inTmp);
493         texinfo->matrix = int(inTmp);
494         buf = nboUnpackInt(buf, inTmp);
495         texinfo->combineMode = int(inTmp);
496         texinfo->useAlpha = false;
497         texinfo->useColor = false;
498         texinfo->useSphereMap = false;
499         unsigned char stateByte;
500         buf = nboUnpackUByte(buf, stateByte);
501         if (stateByte & (1 << 0))
502             texinfo->useAlpha = true;
503         if (stateByte & (1 << 1))
504             texinfo->useColor = true;
505         if (stateByte & (1 << 2))
506             texinfo->useSphereMap = true;
507     }
508 
509     unsigned char sCount;
510     buf = nboUnpackUByte(buf, sCount);
511     shaderCount = sCount;
512     shaders = new ShaderInfo[shaderCount];
513     for (i = 0; i < shaderCount; i++)
514         buf = nboUnpackStdString(buf, shaders[i].name);
515 
516     return buf;
517 }
518 
519 
packSize() const520 int BzMaterial::packSize() const
521 {
522     int i;
523 
524     const int modeSize = sizeof(uint8_t);
525 
526     const int colorSize = sizeof(int32_t) + (4 * sizeof(float[4])) +
527                           sizeof(float) + sizeof(float);
528 
529     int textureSize = sizeof(unsigned char);
530     for (i = 0; i < textureCount; i++)
531     {
532         textureSize += nboStdStringPackSize(textures[i].name);
533         textureSize += sizeof(int32_t);
534         textureSize += sizeof(int32_t);
535         textureSize += sizeof(unsigned char);
536     }
537 
538     int shaderSize = sizeof(unsigned char);
539     for (i = 0; i < shaderCount; i++)
540         shaderSize += nboStdStringPackSize(shaders[i].name);
541 
542     return nboStdStringPackSize(name) + modeSize + colorSize + textureSize + shaderSize;
543 }
544 
545 
printColor(std::ostream & out,const char * name,const float color[4],const float reference[4])546 static void printColor(std::ostream& out, const char *name,
547                        const float color[4], const float reference[4])
548 {
549     if (memcmp(color, reference, sizeof(float[4])) != 0)
550     {
551         out << name << color[0] << " " << color[1] << " "
552             << color[2] << " " << color[3] << std::endl;
553     }
554     return;
555 }
556 
557 
print(std::ostream & out,const std::string & indent) const558 void BzMaterial::print(std::ostream& out, const std::string& indent) const
559 {
560     int i;
561 
562     out << indent << "material" << std::endl;
563 
564     if (name.size() > 0)
565         out << indent << "  name " << name << std::endl;
566 
567     if (dynamicColor != defaultMaterial.dynamicColor)
568     {
569         out << indent << "  dyncol ";
570         const DynamicColor* dyncol = DYNCOLORMGR.getColor(dynamicColor);
571         if ((dyncol != NULL) && (dyncol->getName().size() > 0))
572             out << dyncol->getName();
573         else
574             out << dynamicColor;
575         out << std::endl;
576     }
577     printColor(out, "  ambient ",  ambient,  defaultMaterial.ambient);
578     printColor(out, "  diffuse ",  diffuse,  defaultMaterial.diffuse);
579     printColor(out, "  specular ", specular, defaultMaterial.specular);
580     printColor(out, "  emission ", emission, defaultMaterial.emission);
581     if (shininess != defaultMaterial.shininess)
582         out << indent << "  shininess " << shininess << std::endl;
583     if (alphaThreshold != defaultMaterial.alphaThreshold)
584         out << indent << "  alphathresh " << alphaThreshold << std::endl;
585     if (occluder)
586         out << indent << "  occluder" << std::endl;
587     if (groupAlpha)
588         out << indent << "  groupAlpha" << std::endl;
589     if (noRadar)
590         out << indent << "  noradar" << std::endl;
591     if (noShadow)
592         out << indent << "  noshadow" << std::endl;
593     if (noCulling)
594         out << indent << "  noculling" << std::endl;
595     if (noSorting)
596         out << indent << "  nosorting" << std::endl;
597     if (noLighting)
598         out << indent << "  nolighting" << std::endl;
599 
600     for (i = 0; i < textureCount; i++)
601     {
602         const TextureInfo* texinfo = &textures[i];
603         out << indent << "  addtexture " << texinfo->name << std::endl;
604         if (texinfo->matrix != -1)
605         {
606             out << indent << "    texmat ";
607             const TextureMatrix* texmat = TEXMATRIXMGR.getMatrix(texinfo->matrix);
608             if ((texmat != NULL) && (texmat->getName().size() > 0))
609                 out << texmat->getName();
610             else
611                 out << texinfo->matrix;
612             out << std::endl;
613         }
614 
615         if (!texinfo->useAlpha)
616             out << indent << "    notexalpha" << std::endl;
617         if (!texinfo->useColor)
618             out << indent << "    notexcolor" << std::endl;
619         if (texinfo->useSphereMap)
620             out << indent << "    spheremap" << std::endl;
621     }
622 
623     for (i = 0; i < shaderCount; i++)
624     {
625         const ShaderInfo* shdinfo = &shaders[i];
626         out << indent << "  addshader " << shdinfo->name << std::endl;
627     }
628 
629     out << indent << "end" << std::endl << std::endl;
630 
631     return;
632 }
633 
634 
printMTL(std::ostream & out,const std::string & UNUSED (indent)) const635 void BzMaterial::printMTL(std::ostream& out, const std::string& UNUSED(indent)) const
636 {
637     out << "newmtl ";
638     if (name.size() > 0)
639         out << name << std::endl;
640     else
641         out << MATERIALMGR.getIndex(this) << std::endl;
642     if (noLighting)
643         out << "illum 0" << std::endl;
644     else
645         out << "illum 2" << std::endl;
646     out << "d " << diffuse[3] << std::endl;
647     const float* c;
648     c = ambient; // not really used
649     out << "#Ka " << c[0] << " " << c[1] << " " << c[2] << std::endl;
650     c = diffuse;
651     out << "Kd " << c[0] << " " << c[1] << " " << c[2] << std::endl;
652     c = emission;
653     out << "Ke " << c[0] << " " << c[1] << " " << c[2] << std::endl;
654     c = specular;
655     out << "Ks " << c[0] << " " << c[1] << " " << c[2] << std::endl;
656     out << "Ns " << (1000.0f * (shininess / 128.0f)) << std::endl;
657     if (textureCount > 0)
658     {
659         const TextureInfo* ti = &textures[0];
660         const unsigned int nlen = (unsigned int)ti->name.size();
661         if (nlen > 0)
662         {
663             std::string texname = ti->name;
664             const char* cname = texname.c_str();
665             if ((nlen < 4) || (strcasecmp(cname + (nlen - 4), ".png") != 0))
666                 texname += ".png";
667             out << "map_Kd " << texname << std::endl;
668         }
669     }
670     out << std::endl;
671     return;
672 }
673 
674 
675 /****************************************************************************/
676 //
677 // Parameter setting
678 //
679 
setName(const std::string & matname)680 bool BzMaterial::setName(const std::string& matname)
681 {
682     if (matname.size() <= 0)
683     {
684         name = "";
685         return false;
686     }
687     else if ((matname[0] >= '0') && (matname[0] <= '9'))
688     {
689         name = "";
690         return false;
691     }
692     else
693         name = matname;
694     return true;
695 }
696 
addAlias(const std::string & alias)697 bool BzMaterial::addAlias(const std::string& alias)
698 {
699     if (alias.size() <= 0)
700     {
701         name = "";
702         return false;
703     }
704     else if ((alias[0] >= '0') && (alias[0] <= '9'))
705     {
706         name = "";
707         return false;
708     }
709     else
710     {
711         for ( unsigned int i = 0; i < (unsigned int)aliases.size(); i++)
712         {
713             if ( aliases[i] == alias )
714                 return true;
715         }
716         aliases.push_back(alias); // only add it if it's new
717     }
718     return true;
719 }
720 
setDynamicColor(int dyncol)721 void BzMaterial::setDynamicColor(int dyncol)
722 {
723     dynamicColor = dyncol;
724     return;
725 }
726 
setAmbient(const float color[4])727 void BzMaterial::setAmbient(const float color[4])
728 {
729     memcpy (ambient, color, sizeof(float[4]));
730     return;
731 }
732 
setDiffuse(const float color[4])733 void BzMaterial::setDiffuse(const float color[4])
734 {
735     memcpy (diffuse, color, sizeof(float[4]));
736     return;
737 }
738 
setSpecular(const float color[4])739 void BzMaterial::setSpecular(const float color[4])
740 {
741     memcpy (specular, color, sizeof(float[4]));
742     return;
743 }
744 
setEmission(const float color[4])745 void BzMaterial::setEmission(const float color[4])
746 {
747     memcpy (emission, color, sizeof(float[4]));
748     return;
749 }
750 
setShininess(const float shine)751 void BzMaterial::setShininess(const float shine)
752 {
753     shininess = shine;
754     return;
755 }
756 
setAlphaThreshold(const float thresh)757 void BzMaterial::setAlphaThreshold(const float thresh)
758 {
759     alphaThreshold = thresh;
760     return;
761 }
762 
setOccluder(bool value)763 void BzMaterial::setOccluder(bool value)
764 {
765     occluder = value;
766     return;
767 }
768 
setGroupAlpha(bool value)769 void BzMaterial::setGroupAlpha(bool value)
770 {
771     groupAlpha = value;
772     return;
773 }
774 
setNoRadar(bool value)775 void BzMaterial::setNoRadar(bool value)
776 {
777     noRadar = value;
778     return;
779 }
780 
setNoShadow(bool value)781 void BzMaterial::setNoShadow(bool value)
782 {
783     noShadow = value;
784     return;
785 }
786 
setNoCulling(bool value)787 void BzMaterial::setNoCulling(bool value)
788 {
789     noCulling = value;
790     return;
791 }
792 
setNoSorting(bool value)793 void BzMaterial::setNoSorting(bool value)
794 {
795     noSorting = value;
796     return;
797 }
798 
setNoLighting(bool value)799 void BzMaterial::setNoLighting(bool value)
800 {
801     noLighting = value;
802     return;
803 }
804 
805 
addTexture(const std::string & texname)806 void BzMaterial::addTexture(const std::string& texname)
807 {
808     textureCount++;
809     TextureInfo* tmpinfo = new TextureInfo[textureCount];
810     for (int i = 0; i < (textureCount - 1); i++)
811         tmpinfo[i] = textures[i];
812     delete[] textures;
813     textures = tmpinfo;
814 
815     TextureInfo* texinfo = &textures[textureCount - 1];
816     texinfo->name = texname;
817     texinfo->localname = texname;
818     texinfo->matrix = -1;
819     texinfo->combineMode = decal;
820     texinfo->useAlpha = true;
821     texinfo->useColor = true;
822     texinfo->useSphereMap = false;
823 
824     return;
825 }
826 
setTexture(const std::string & texname)827 void BzMaterial::setTexture(const std::string& texname)
828 {
829     if (textureCount <= 0)
830         addTexture(texname);
831     else
832         textures[textureCount - 1].name = texname;
833 
834     return;
835 }
836 
setTextureLocal(int texid,const std::string & localname)837 void BzMaterial::setTextureLocal(int texid, const std::string& localname)
838 {
839     if ((texid >= 0) && (texid < textureCount))
840         textures[texid].localname = localname;
841     return;
842 }
843 
setTextureMatrix(int matrix)844 void BzMaterial::setTextureMatrix(int matrix)
845 {
846     if (textureCount > 0)
847         textures[textureCount - 1].matrix = matrix;
848     return;
849 }
850 
setCombineMode(int mode)851 void BzMaterial::setCombineMode(int mode)
852 {
853     if (textureCount > 0)
854         textures[textureCount - 1].combineMode = mode;
855     return;
856 }
857 
setUseTextureAlpha(bool value)858 void BzMaterial::setUseTextureAlpha(bool value)
859 {
860     if (textureCount > 0)
861         textures[textureCount - 1].useAlpha = value;
862     return;
863 }
864 
setUseColorOnTexture(bool value)865 void BzMaterial::setUseColorOnTexture(bool value)
866 {
867     if (textureCount > 0)
868         textures[textureCount - 1].useColor = value;
869     return;
870 }
871 
setUseSphereMap(bool value)872 void BzMaterial::setUseSphereMap(bool value)
873 {
874     if (textureCount > 0)
875         textures[textureCount - 1].useSphereMap = value;
876     return;
877 }
878 
879 
clearTextures()880 void BzMaterial::clearTextures()
881 {
882     delete[] textures;
883     textures = NULL;
884     textureCount = 0;
885     return;
886 }
887 
888 
setShader(const std::string & shadername)889 void BzMaterial::setShader(const std::string& shadername)
890 {
891     if (shaderCount <= 0)
892         addShader(shadername);
893     else
894         shaders[shaderCount - 1].name = shadername;
895 
896     return;
897 }
898 
addShader(const std::string & shaderName)899 void BzMaterial::addShader(const std::string& shaderName)
900 {
901     shaderCount++;
902     ShaderInfo* tmpinfo = new ShaderInfo[shaderCount];
903     for (int i = 0; i < (shaderCount - 1); i++)
904         tmpinfo[i] = shaders[i];
905     delete[] shaders;
906     shaders = tmpinfo;
907     shaders[shaderCount - 1].name = shaderName;
908     return;
909 }
910 
911 
clearShaders()912 void BzMaterial::clearShaders()
913 {
914     delete[] shaders;
915     shaders = NULL;
916     shaderCount = 0;
917     return;
918 }
919 
920 
921 /****************************************************************************/
922 //
923 // Parameter retrieval
924 //
925 
getName() const926 const std::string& BzMaterial::getName() const
927 {
928     return name;
929 }
930 
getAliases() const931 const std::vector<std::string>& BzMaterial::getAliases() const
932 {
933     return aliases;
934 }
935 
getDynamicColor() const936 int BzMaterial::getDynamicColor() const
937 {
938     return dynamicColor;
939 }
940 
getAmbient() const941 const float* BzMaterial::getAmbient() const
942 {
943     return ambient;
944 }
945 
getDiffuse() const946 const float* BzMaterial::getDiffuse() const
947 {
948     return diffuse;
949 }
950 
getSpecular() const951 const float* BzMaterial::getSpecular() const
952 {
953     return specular;
954 }
955 
getEmission() const956 const float* BzMaterial::getEmission() const
957 {
958     return emission;
959 }
960 
getShininess() const961 float BzMaterial::getShininess() const
962 {
963     return shininess;
964 }
965 
getAlphaThreshold() const966 float BzMaterial::getAlphaThreshold() const
967 {
968     return alphaThreshold;
969 }
970 
getOccluder() const971 bool BzMaterial::getOccluder() const
972 {
973     return occluder;
974 }
975 
getGroupAlpha() const976 bool BzMaterial::getGroupAlpha() const
977 {
978     return groupAlpha;
979 }
980 
getNoRadar() const981 bool BzMaterial::getNoRadar() const
982 {
983     return noRadar;
984 }
985 
getNoShadow() const986 bool BzMaterial::getNoShadow() const
987 {
988     return noShadow;
989 }
990 
getNoCulling() const991 bool BzMaterial::getNoCulling() const
992 {
993     return noCulling;
994 }
995 
getNoSorting() const996 bool BzMaterial::getNoSorting() const
997 {
998     return noSorting;
999 }
1000 
getNoLighting() const1001 bool BzMaterial::getNoLighting() const
1002 {
1003     return noLighting;
1004 }
1005 
1006 
getTextureCount() const1007 int BzMaterial::getTextureCount() const
1008 {
1009     return textureCount;
1010 }
1011 
getTexture(int texid) const1012 const std::string& BzMaterial::getTexture(int texid) const
1013 {
1014     if ((texid >= 0) && (texid < textureCount))
1015         return textures[texid].name;
1016     else
1017         return nullString;
1018 }
1019 
getTextureLocal(int texid) const1020 const std::string& BzMaterial::getTextureLocal(int texid) const
1021 {
1022     if ((texid >= 0) && (texid < textureCount))
1023         return textures[texid].localname;
1024     else
1025         return nullString;
1026 }
1027 
getTextureMatrix(int texid) const1028 int BzMaterial::getTextureMatrix(int texid) const
1029 {
1030     if ((texid >= 0) && (texid < textureCount))
1031         return textures[texid].matrix;
1032     else
1033         return -1;
1034 }
1035 
getCombineMode(int texid) const1036 int BzMaterial::getCombineMode(int texid) const
1037 {
1038     if ((texid >= 0) && (texid < textureCount))
1039         return textures[texid].combineMode;
1040     else
1041         return -1;
1042 }
1043 
getUseTextureAlpha(int texid) const1044 bool BzMaterial::getUseTextureAlpha(int texid) const
1045 {
1046     if ((texid >= 0) && (texid < textureCount))
1047         return textures[texid].useAlpha;
1048     else
1049         return false;
1050 }
1051 
getUseColorOnTexture(int texid) const1052 bool BzMaterial::getUseColorOnTexture(int texid) const
1053 {
1054     if ((texid >= 0) && (texid < textureCount))
1055         return textures[texid].useColor;
1056     else
1057         return false;
1058 }
1059 
getUseSphereMap(int texid) const1060 bool BzMaterial::getUseSphereMap(int texid) const
1061 {
1062     if ((texid >= 0) && (texid < textureCount))
1063         return textures[texid].useSphereMap;
1064     else
1065         return false;
1066 }
1067 
1068 
getShaderCount() const1069 int BzMaterial::getShaderCount() const
1070 {
1071     return shaderCount;
1072 }
1073 
getShader(int shdid) const1074 const std::string& BzMaterial::getShader(int shdid) const
1075 {
1076     if ((shdid >= 0) && (shdid < shaderCount))
1077         return shaders[shdid].name;
1078     else
1079         return nullString;
1080 }
1081 
1082 
isInvisible() const1083 bool BzMaterial::isInvisible() const
1084 {
1085     const DynamicColor* dyncol = DYNCOLORMGR.getColor(dynamicColor);
1086     if ((diffuse[3] == 0.0f) && (dyncol == NULL) &&
1087             !((textureCount > 0) && !textures[0].useColor))
1088         return true;
1089     return false;
1090 }
1091 
1092 
1093 // Local Variables: ***
1094 // mode: C++ ***
1095 // tab-width: 4 ***
1096 // c-basic-offset: 4 ***
1097 // indent-tabs-mode: nil ***
1098 // End: ***
1099 // ex: shiftwidth=4 tabstop=4
1100