Panda3D
|
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 ©) : 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 ©) { 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 }