00001 // Filename: textureStageCollection.cxx 00002 // Created by: drose (23Jul04) 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 "textureStageCollection.h" 00016 00017 #include "indent.h" 00018 #include "indirectLess.h" 00019 #include <algorithm> 00020 00021 //////////////////////////////////////////////////////////////////// 00022 // Function: TextureStageCollection::Constructor 00023 // Access: Published 00024 // Description: 00025 //////////////////////////////////////////////////////////////////// 00026 TextureStageCollection:: 00027 TextureStageCollection() { 00028 } 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: TextureStageCollection::Copy Constructor 00032 // Access: Published 00033 // Description: 00034 //////////////////////////////////////////////////////////////////// 00035 TextureStageCollection:: 00036 TextureStageCollection(const TextureStageCollection ©) : 00037 _texture_stages(copy._texture_stages) 00038 { 00039 } 00040 00041 //////////////////////////////////////////////////////////////////// 00042 // Function: TextureStageCollection::Copy Assignment Operator 00043 // Access: Published 00044 // Description: 00045 //////////////////////////////////////////////////////////////////// 00046 void TextureStageCollection:: 00047 operator = (const TextureStageCollection ©) { 00048 _texture_stages = copy._texture_stages; 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function: TextureStageCollection::add_texture_stage 00053 // Access: Published 00054 // Description: Adds a new TextureStage to the collection. 00055 //////////////////////////////////////////////////////////////////// 00056 void TextureStageCollection:: 00057 add_texture_stage(TextureStage *node_texture_stage) { 00058 // If the pointer to our internal array is shared by any other 00059 // TextureStageCollections, we have to copy the array now so we won't 00060 // inadvertently modify any of our brethren TextureStageCollection 00061 // objects. 00062 00063 if (_texture_stages.get_ref_count() > 1) { 00064 TextureStages old_texture_stages = _texture_stages; 00065 _texture_stages = TextureStages::empty_array(0); 00066 _texture_stages.v() = old_texture_stages.v(); 00067 } 00068 00069 _texture_stages.push_back(node_texture_stage); 00070 } 00071 00072 //////////////////////////////////////////////////////////////////// 00073 // Function: TextureStageCollection::remove_texture_stage 00074 // Access: Published 00075 // Description: Removes the indicated TextureStage from the collection. 00076 // Returns true if the texture_stage was removed, false if it was 00077 // not a member of the collection. 00078 //////////////////////////////////////////////////////////////////// 00079 bool TextureStageCollection:: 00080 remove_texture_stage(TextureStage *node_texture_stage) { 00081 int texture_stage_index = -1; 00082 for (int i = 0; texture_stage_index == -1 && i < (int)_texture_stages.size(); i++) { 00083 if (_texture_stages[i] == node_texture_stage) { 00084 texture_stage_index = i; 00085 } 00086 } 00087 00088 if (texture_stage_index == -1) { 00089 // The indicated texture_stage was not a member of the collection. 00090 return false; 00091 } 00092 00093 // If the pointer to our internal array is shared by any other 00094 // TextureStageCollections, we have to copy the array now so we won't 00095 // inadvertently modify any of our brethren TextureStageCollection 00096 // objects. 00097 00098 if (_texture_stages.get_ref_count() > 1) { 00099 TextureStages old_texture_stages = _texture_stages; 00100 _texture_stages = TextureStages::empty_array(0); 00101 _texture_stages.v() = old_texture_stages.v(); 00102 } 00103 00104 _texture_stages.erase(_texture_stages.begin() + texture_stage_index); 00105 return true; 00106 } 00107 00108 //////////////////////////////////////////////////////////////////// 00109 // Function: TextureStageCollection::add_texture_stages_from 00110 // Access: Published 00111 // Description: Adds all the TextureStages indicated in the other 00112 // collection to this texture_stage. The other texture_stages are simply 00113 // appended to the end of the texture_stages in this list; 00114 // duplicates are not automatically removed. 00115 //////////////////////////////////////////////////////////////////// 00116 void TextureStageCollection:: 00117 add_texture_stages_from(const TextureStageCollection &other) { 00118 int other_num_texture_stages = other.get_num_texture_stages(); 00119 for (int i = 0; i < other_num_texture_stages; i++) { 00120 add_texture_stage(other.get_texture_stage(i)); 00121 } 00122 } 00123 00124 00125 //////////////////////////////////////////////////////////////////// 00126 // Function: TextureStageCollection::remove_texture_stages_from 00127 // Access: Published 00128 // Description: Removes from this collection all of the TextureStages 00129 // listed in the other collection. 00130 //////////////////////////////////////////////////////////////////// 00131 void TextureStageCollection:: 00132 remove_texture_stages_from(const TextureStageCollection &other) { 00133 TextureStages new_texture_stages; 00134 int num_texture_stages = get_num_texture_stages(); 00135 for (int i = 0; i < num_texture_stages; i++) { 00136 PT(TextureStage) texture_stage = get_texture_stage(i); 00137 if (!other.has_texture_stage(texture_stage)) { 00138 new_texture_stages.push_back(texture_stage); 00139 } 00140 } 00141 _texture_stages = new_texture_stages; 00142 } 00143 00144 //////////////////////////////////////////////////////////////////// 00145 // Function: TextureStageCollection::remove_duplicate_texture_stages 00146 // Access: Published 00147 // Description: Removes any duplicate entries of the same TextureStages 00148 // on this collection. If a TextureStage appears multiple 00149 // times, the first appearance is retained; subsequent 00150 // appearances are removed. 00151 //////////////////////////////////////////////////////////////////// 00152 void TextureStageCollection:: 00153 remove_duplicate_texture_stages() { 00154 TextureStages new_texture_stages; 00155 00156 int num_texture_stages = get_num_texture_stages(); 00157 for (int i = 0; i < num_texture_stages; i++) { 00158 PT(TextureStage) texture_stage = get_texture_stage(i); 00159 bool duplicated = false; 00160 00161 for (int j = 0; j < i && !duplicated; j++) { 00162 duplicated = (texture_stage == get_texture_stage(j)); 00163 } 00164 00165 if (!duplicated) { 00166 new_texture_stages.push_back(texture_stage); 00167 } 00168 } 00169 00170 _texture_stages = new_texture_stages; 00171 } 00172 00173 //////////////////////////////////////////////////////////////////// 00174 // Function: TextureStageCollection::has_texture_stage 00175 // Access: Published 00176 // Description: Returns true if the indicated TextureStage appears in 00177 // this collection, false otherwise. 00178 //////////////////////////////////////////////////////////////////// 00179 bool TextureStageCollection:: 00180 has_texture_stage(TextureStage *texture_stage) const { 00181 for (int i = 0; i < get_num_texture_stages(); i++) { 00182 if (texture_stage == get_texture_stage(i)) { 00183 return true; 00184 } 00185 } 00186 return false; 00187 } 00188 00189 //////////////////////////////////////////////////////////////////// 00190 // Function: TextureStageCollection::clear 00191 // Access: Published 00192 // Description: Removes all TextureStages from the collection. 00193 //////////////////////////////////////////////////////////////////// 00194 void TextureStageCollection:: 00195 clear() { 00196 _texture_stages.clear(); 00197 } 00198 00199 //////////////////////////////////////////////////////////////////// 00200 // Function: TextureStageCollection::find_texture_stage 00201 // Access: Published 00202 // Description: Returns the texture_stage in the collection with the 00203 // indicated name, if any, or NULL if no texture_stage has 00204 // that name. 00205 //////////////////////////////////////////////////////////////////// 00206 TextureStage *TextureStageCollection:: 00207 find_texture_stage(const string &name) const { 00208 int num_texture_stages = get_num_texture_stages(); 00209 for (int i = 0; i < num_texture_stages; i++) { 00210 TextureStage *texture_stage = get_texture_stage(i); 00211 if (texture_stage->get_name() == name) { 00212 return texture_stage; 00213 } 00214 } 00215 return NULL; 00216 } 00217 00218 //////////////////////////////////////////////////////////////////// 00219 // Function: TextureStageCollection::get_num_texture_stages 00220 // Access: Published 00221 // Description: Returns the number of TextureStages in the collection. 00222 //////////////////////////////////////////////////////////////////// 00223 int TextureStageCollection:: 00224 get_num_texture_stages() const { 00225 return _texture_stages.size(); 00226 } 00227 00228 //////////////////////////////////////////////////////////////////// 00229 // Function: TextureStageCollection::get_texture_stage 00230 // Access: Published 00231 // Description: Returns the nth TextureStage in the collection. 00232 //////////////////////////////////////////////////////////////////// 00233 TextureStage *TextureStageCollection:: 00234 get_texture_stage(int index) const { 00235 nassertr(index >= 0 && index < (int)_texture_stages.size(), NULL); 00236 00237 return _texture_stages[index]; 00238 } 00239 00240 //////////////////////////////////////////////////////////////////// 00241 // Function: TextureStageCollection::operator [] 00242 // Access: Published 00243 // Description: Returns the nth TextureStage in the collection. This is 00244 // the same as get_texture_stage(), but it may be a more 00245 // convenient way to access it. 00246 //////////////////////////////////////////////////////////////////// 00247 TextureStage *TextureStageCollection:: 00248 operator [] (int index) const { 00249 nassertr(index >= 0 && index < (int)_texture_stages.size(), NULL); 00250 00251 return _texture_stages[index]; 00252 } 00253 00254 //////////////////////////////////////////////////////////////////// 00255 // Function: TextureStageCollection::size 00256 // Access: Published 00257 // Description: Returns the number of texture stages in the 00258 // collection. This is the same thing as 00259 // get_num_texture_stages(). 00260 //////////////////////////////////////////////////////////////////// 00261 int TextureStageCollection:: 00262 size() const { 00263 return _texture_stages.size(); 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: TextureStageCollection::sort 00268 // Access: Published 00269 // Description: Sorts the TextureStages in this collection into order 00270 // by TextureStage::sort(), from lowest to highest. 00271 //////////////////////////////////////////////////////////////////// 00272 void TextureStageCollection:: 00273 sort() { 00274 ::sort(_texture_stages.begin(), _texture_stages.end(), 00275 CompareTextureStageSort()); 00276 } 00277 00278 //////////////////////////////////////////////////////////////////// 00279 // Function: TextureStageCollection::output 00280 // Access: Published 00281 // Description: Writes a brief one-line description of the 00282 // TextureStageCollection to the indicated output stream. 00283 //////////////////////////////////////////////////////////////////// 00284 void TextureStageCollection:: 00285 output(ostream &out) const { 00286 if (get_num_texture_stages() == 1) { 00287 out << "1 TextureStage"; 00288 } else { 00289 out << get_num_texture_stages() << " TextureStages"; 00290 } 00291 } 00292 00293 //////////////////////////////////////////////////////////////////// 00294 // Function: TextureStageCollection::write 00295 // Access: Published 00296 // Description: Writes a complete multi-line description of the 00297 // TextureStageCollection to the indicated output stream. 00298 //////////////////////////////////////////////////////////////////// 00299 void TextureStageCollection:: 00300 write(ostream &out, int indent_level) const { 00301 for (int i = 0; i < get_num_texture_stages(); i++) { 00302 indent(out, indent_level) << *get_texture_stage(i) << "\n"; 00303 } 00304 }