Panda3D

materialCollection.cxx

00001 // Filename: materialCollection.cxx
00002 // Created by:  drose (16Mar02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "materialCollection.h"
00016 
00017 #include "indent.h"
00018 
00019 ////////////////////////////////////////////////////////////////////
00020 //     Function: MaterialCollection::Constructor
00021 //       Access: Published
00022 //  Description:
00023 ////////////////////////////////////////////////////////////////////
00024 MaterialCollection::
00025 MaterialCollection() {
00026 }
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: MaterialCollection::Copy Constructor
00030 //       Access: Published
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 MaterialCollection::
00034 MaterialCollection(const MaterialCollection &copy) :
00035   _materials(copy._materials)
00036 {
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: MaterialCollection::Copy Assignment Operator
00041 //       Access: Published
00042 //  Description:
00043 ////////////////////////////////////////////////////////////////////
00044 void MaterialCollection::
00045 operator = (const MaterialCollection &copy) {
00046   _materials = copy._materials;
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: MaterialCollection::add_material
00051 //       Access: Published
00052 //  Description: Adds a new Material to the collection.
00053 ////////////////////////////////////////////////////////////////////
00054 void MaterialCollection::
00055 add_material(Material *node_material) {
00056   // If the pointer to our internal array is shared by any other
00057   // MaterialCollections, we have to copy the array now so we won't
00058   // inadvertently modify any of our brethren MaterialCollection
00059   // objects.
00060 
00061   if (_materials.get_ref_count() > 1) {
00062     Materials old_materials = _materials;
00063     _materials = Materials::empty_array(0);
00064     _materials.v() = old_materials.v();
00065   }
00066 
00067   _materials.push_back(node_material);
00068 }
00069 
00070 ////////////////////////////////////////////////////////////////////
00071 //     Function: MaterialCollection::remove_material
00072 //       Access: Published
00073 //  Description: Removes the indicated Material from the collection.
00074 //               Returns true if the material was removed, false if it was
00075 //               not a member of the collection.
00076 ////////////////////////////////////////////////////////////////////
00077 bool MaterialCollection::
00078 remove_material(Material *node_material) {
00079   int material_index = -1;
00080   for (int i = 0; material_index == -1 && i < (int)_materials.size(); i++) {
00081     if (_materials[i] == node_material) {
00082       material_index = i;
00083     }
00084   }
00085 
00086   if (material_index == -1) {
00087     // The indicated material was not a member of the collection.
00088     return false;
00089   }
00090 
00091   // If the pointer to our internal array is shared by any other
00092   // MaterialCollections, we have to copy the array now so we won't
00093   // inadvertently modify any of our brethren MaterialCollection
00094   // objects.
00095 
00096   if (_materials.get_ref_count() > 1) {
00097     Materials old_materials = _materials;
00098     _materials = Materials::empty_array(0);
00099     _materials.v() = old_materials.v();
00100   }
00101 
00102   _materials.erase(_materials.begin() + material_index);
00103   return true;
00104 }
00105 
00106 ////////////////////////////////////////////////////////////////////
00107 //     Function: MaterialCollection::add_materials_from
00108 //       Access: Published
00109 //  Description: Adds all the Materials indicated in the other
00110 //               collection to this material.  The other materials are simply
00111 //               appended to the end of the materials in this list;
00112 //               duplicates are not automatically removed.
00113 ////////////////////////////////////////////////////////////////////
00114 void MaterialCollection::
00115 add_materials_from(const MaterialCollection &other) {
00116   int other_num_materials = other.get_num_materials();
00117   for (int i = 0; i < other_num_materials; i++) {
00118     add_material(other.get_material(i));
00119   }
00120 }
00121 
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: MaterialCollection::remove_materials_from
00125 //       Access: Published
00126 //  Description: Removes from this collection all of the Materials
00127 //               listed in the other collection.
00128 ////////////////////////////////////////////////////////////////////
00129 void MaterialCollection::
00130 remove_materials_from(const MaterialCollection &other) {
00131   Materials new_materials;
00132   int num_materials = get_num_materials();
00133   for (int i = 0; i < num_materials; i++) {
00134     PT(Material) material = get_material(i);
00135     if (!other.has_material(material)) {
00136       new_materials.push_back(material);
00137     }
00138   }
00139   _materials = new_materials;
00140 }
00141 
00142 ////////////////////////////////////////////////////////////////////
00143 //     Function: MaterialCollection::remove_duplicate_materials
00144 //       Access: Published
00145 //  Description: Removes any duplicate entries of the same Materials
00146 //               on this collection.  If a Material appears multiple
00147 //               times, the first appearance is retained; subsequent
00148 //               appearances are removed.
00149 ////////////////////////////////////////////////////////////////////
00150 void MaterialCollection::
00151 remove_duplicate_materials() {
00152   Materials new_materials;
00153 
00154   int num_materials = get_num_materials();
00155   for (int i = 0; i < num_materials; i++) {
00156     PT(Material) material = get_material(i);
00157     bool duplicated = false;
00158 
00159     for (int j = 0; j < i && !duplicated; j++) {
00160       duplicated = (material == get_material(j));
00161     }
00162 
00163     if (!duplicated) {
00164       new_materials.push_back(material);
00165     }
00166   }
00167 
00168   _materials = new_materials;
00169 }
00170 
00171 ////////////////////////////////////////////////////////////////////
00172 //     Function: MaterialCollection::has_material
00173 //       Access: Published
00174 //  Description: Returns true if the indicated Material appears in
00175 //               this collection, false otherwise.
00176 ////////////////////////////////////////////////////////////////////
00177 bool MaterialCollection::
00178 has_material(Material *material) const {
00179   for (int i = 0; i < get_num_materials(); i++) {
00180     if (material == get_material(i)) {
00181       return true;
00182     }
00183   }
00184   return false;
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //     Function: MaterialCollection::clear
00189 //       Access: Published
00190 //  Description: Removes all Materials from the collection.
00191 ////////////////////////////////////////////////////////////////////
00192 void MaterialCollection::
00193 clear() {
00194   _materials.clear();
00195 }
00196 
00197 ////////////////////////////////////////////////////////////////////
00198 //     Function: MaterialCollection::find_material
00199 //       Access: Published
00200 //  Description: Returns the material in the collection with the
00201 //               indicated name, if any, or NULL if no material has
00202 //               that name.
00203 ////////////////////////////////////////////////////////////////////
00204 Material *MaterialCollection::
00205 find_material(const string &name) const {
00206   int num_materials = get_num_materials();
00207   for (int i = 0; i < num_materials; i++) {
00208     Material *material = get_material(i);
00209     if (material->get_name() == name) {
00210       return material;
00211     }
00212   }
00213   return NULL;
00214 }
00215 
00216 ////////////////////////////////////////////////////////////////////
00217 //     Function: MaterialCollection::get_num_materials
00218 //       Access: Published
00219 //  Description: Returns the number of Materials in the collection.
00220 ////////////////////////////////////////////////////////////////////
00221 int MaterialCollection::
00222 get_num_materials() const {
00223   return _materials.size();
00224 }
00225 
00226 ////////////////////////////////////////////////////////////////////
00227 //     Function: MaterialCollection::get_material
00228 //       Access: Published
00229 //  Description: Returns the nth Material in the collection.
00230 ////////////////////////////////////////////////////////////////////
00231 Material *MaterialCollection::
00232 get_material(int index) const {
00233   nassertr(index >= 0 && index < (int)_materials.size(), NULL);
00234 
00235   return _materials[index];
00236 }
00237 
00238 ////////////////////////////////////////////////////////////////////
00239 //     Function: MaterialCollection::operator []
00240 //       Access: Published
00241 //  Description: Returns the nth Material in the collection.  This is
00242 //               the same as get_material(), but it may be a more
00243 //               convenient way to access it.
00244 ////////////////////////////////////////////////////////////////////
00245 Material *MaterialCollection::
00246 operator [] (int index) const {
00247   nassertr(index >= 0 && index < (int)_materials.size(), NULL);
00248 
00249   return _materials[index];
00250 }
00251 
00252 ////////////////////////////////////////////////////////////////////
00253 //     Function: MaterialCollection::size
00254 //       Access: Published
00255 //  Description: Returns the number of materials in the collection.  This
00256 //               is the same thing as get_num_materials().
00257 ////////////////////////////////////////////////////////////////////
00258 int MaterialCollection::
00259 size() const {
00260   return _materials.size();
00261 }
00262 
00263 ////////////////////////////////////////////////////////////////////
00264 //     Function: MaterialCollection::output
00265 //       Access: Published
00266 //  Description: Writes a brief one-line description of the
00267 //               MaterialCollection to the indicated output stream.
00268 ////////////////////////////////////////////////////////////////////
00269 void MaterialCollection::
00270 output(ostream &out) const {
00271   if (get_num_materials() == 1) {
00272     out << "1 Material";
00273   } else {
00274     out << get_num_materials() << " Materials";
00275   }
00276 }
00277 
00278 ////////////////////////////////////////////////////////////////////
00279 //     Function: MaterialCollection::write
00280 //       Access: Published
00281 //  Description: Writes a complete multi-line description of the
00282 //               MaterialCollection to the indicated output stream.
00283 ////////////////////////////////////////////////////////////////////
00284 void MaterialCollection::
00285 write(ostream &out, int indent_level) const {
00286   for (int i = 0; i < get_num_materials(); i++) {
00287     indent(out, indent_level) << *get_material(i) << "\n";
00288   }
00289 }
 All Classes Functions Variables Enumerations