Panda3D
|
00001 // Filename: fltGeometry.cxx 00002 // Created by: drose (28Feb01) 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 "fltGeometry.h" 00016 #include "fltRecordReader.h" 00017 #include "fltRecordWriter.h" 00018 #include "fltHeader.h" 00019 #include "fltMaterial.h" 00020 00021 TypeHandle FltGeometry::_type_handle; 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: FltGeometry::Constructor 00025 // Access: Public 00026 // Description: 00027 //////////////////////////////////////////////////////////////////// 00028 FltGeometry:: 00029 FltGeometry(FltHeader *header) : FltBeadID(header) { 00030 _ir_color = 0; 00031 _relative_priority = 0; 00032 _draw_type = DT_solid_cull_backface; 00033 _texwhite = false; 00034 _color_name_index = 0; 00035 _alt_color_name_index = 0; 00036 _billboard_type = BT_none; 00037 _detail_texture_index = -1; 00038 _texture_index = -1; 00039 _material_index = -1; 00040 _dfad_material_code = 0; 00041 _dfad_feature_id = 0; 00042 _ir_material_code = 0; 00043 _transparency = 0; 00044 _lod_generation_control = 0; 00045 _line_style_index = 0; 00046 _flags = F_no_color; 00047 _light_mode = LM_face_no_normal; 00048 _texture_mapping_index = 0; 00049 _color_index = 0; 00050 _alt_color_index = 0; 00051 } 00052 00053 00054 //////////////////////////////////////////////////////////////////// 00055 // Function: FltGeometry::get_color 00056 // Access: Public 00057 // Description: Returns the primary color of the face, as a 00058 // four-component value (including alpha as the 00059 // transparency channel). 00060 // 00061 // If has_color() is false, the result is white, but 00062 // still reflects the transparency correctly. 00063 //////////////////////////////////////////////////////////////////// 00064 LColor FltGeometry:: 00065 get_color() const { 00066 LColor color; 00067 00068 if (!has_color() || (_texwhite && has_texture())) { 00069 // Force this one white. 00070 color.set(1.0, 1.0, 1.0, 1.0); 00071 00072 } else if (has_material()) { 00073 // If we have a material, that replaces the color. 00074 FltMaterial *material = get_material(); 00075 color.set(material->_diffuse[0], 00076 material->_diffuse[1], 00077 material->_diffuse[2], 00078 material->_alpha); 00079 } else { 00080 LRGBColor rgb = 00081 _header->get_rgb(_color_index, (_flags & F_packed_color) != 0, 00082 _packed_color); 00083 color.set(rgb[0], rgb[1], rgb[2], 1.0); 00084 } 00085 00086 // Modify the whole thing by our transparency. 00087 PN_stdfloat alpha = 1.0 - (_transparency / 65535.0); 00088 color[3] *= alpha; 00089 00090 return color; 00091 } 00092 00093 //////////////////////////////////////////////////////////////////// 00094 // Function: FltGeometry::set_color 00095 // Access: Public 00096 // Description: Sets the primary color of the face, using the packed 00097 // color convention. 00098 //////////////////////////////////////////////////////////////////// 00099 void FltGeometry:: 00100 set_color(const LColor &color) { 00101 set_rgb(LRGBColor(color[0], color[1], color[2])); 00102 _transparency = (int)floor((1.0 - color[3]) * 65535.0); 00103 } 00104 00105 //////////////////////////////////////////////////////////////////// 00106 // Function: FltGeometry::get_rgb 00107 // Access: Public 00108 // Description: Returns the primary color of the face, as a 00109 // three-component value ignoring transparency. 00110 //////////////////////////////////////////////////////////////////// 00111 LRGBColor FltGeometry:: 00112 get_rgb() const { 00113 if (!has_color() || (_texwhite && has_texture())) { 00114 // Force this one white. 00115 return LRGBColor(1.0, 1.0, 1.0); 00116 } 00117 00118 if (has_material()) { 00119 // If we have a material, that replaces the color. 00120 FltMaterial *material = get_material(); 00121 return material->_diffuse; 00122 } 00123 00124 return _header->get_rgb(_color_index, (_flags & F_packed_color) != 0, 00125 _packed_color); 00126 } 00127 00128 //////////////////////////////////////////////////////////////////// 00129 // Function: FltGeometry::set_rgb 00130 // Access: Public 00131 // Description: Sets the primary color of the face, using the packed 00132 // color convention; does not affect transparency. 00133 //////////////////////////////////////////////////////////////////// 00134 void FltGeometry:: 00135 set_rgb(const LRGBColor &rgb) { 00136 _packed_color.set_rgb(rgb); 00137 _flags = ((_flags & ~F_no_color) | F_packed_color); 00138 00139 // If we have a color, we can't have a material. 00140 _material_index = -1; 00141 _texwhite = false; 00142 } 00143 00144 //////////////////////////////////////////////////////////////////// 00145 // Function: FltGeometry::has_alt_color 00146 // Access: Public 00147 // Description: Returns true if the face has an alternate color 00148 // indicated, false otherwise. 00149 //////////////////////////////////////////////////////////////////// 00150 bool FltGeometry:: 00151 has_alt_color() const { 00152 return (_flags & F_no_alt_color) == 0; 00153 } 00154 00155 //////////////////////////////////////////////////////////////////// 00156 // Function: FltGeometry::get_alt_color 00157 // Access: Public 00158 // Description: If has_alt_color() indicates true, returns the alternate 00159 // color of the face, as a four-component value 00160 // (including alpha as the transparency channel). 00161 //////////////////////////////////////////////////////////////////// 00162 LColor FltGeometry:: 00163 get_alt_color() const { 00164 nassertr(has_alt_color(), LColor(0.0, 0.0, 0.0, 0.0)); 00165 00166 return _header->get_color(_alt_color_index, (_flags & F_packed_color) != 0, 00167 _alt_packed_color, _transparency); 00168 } 00169 00170 //////////////////////////////////////////////////////////////////// 00171 // Function: FltGeometry::get_alt_rgb 00172 // Access: Public 00173 // Description: If has_alt_color() indicates true, returns the alternate 00174 // color of the face, as a three-component value 00175 // ignoring transparency. 00176 //////////////////////////////////////////////////////////////////// 00177 LRGBColor FltGeometry:: 00178 get_alt_rgb() const { 00179 nassertr(has_alt_color(), LRGBColor(0.0, 0.0, 0.0)); 00180 00181 return _header->get_rgb(_alt_color_index, (_flags & F_packed_color) != 0, 00182 _alt_packed_color); 00183 } 00184 00185 //////////////////////////////////////////////////////////////////// 00186 // Function: FltGeometry::extract_record 00187 // Access: Protected, Virtual 00188 // Description: Fills in the information in this bead based on the 00189 // information given in the indicated datagram, whose 00190 // opcode has already been read. Returns true on 00191 // success, false if the datagram is invalid. 00192 //////////////////////////////////////////////////////////////////// 00193 bool FltGeometry:: 00194 extract_record(FltRecordReader &reader) { 00195 DatagramIterator &iterator = reader.get_iterator(); 00196 00197 _ir_color = iterator.get_be_int32(); 00198 _relative_priority = iterator.get_be_int16(); 00199 _draw_type = (DrawType)iterator.get_int8(); 00200 _texwhite = (iterator.get_int8() != 0); 00201 _color_name_index = iterator.get_be_int16(); 00202 _alt_color_name_index = iterator.get_be_int16(); 00203 iterator.skip_bytes(1); 00204 _billboard_type = (BillboardType)iterator.get_int8(); 00205 _detail_texture_index = iterator.get_be_int16(); 00206 _texture_index = iterator.get_be_int16(); 00207 _material_index = iterator.get_be_int16(); 00208 _dfad_material_code = iterator.get_be_int16(); 00209 _dfad_feature_id = iterator.get_be_int16(); 00210 _ir_material_code = iterator.get_be_int32(); 00211 _transparency = iterator.get_be_uint16(); 00212 _lod_generation_control = iterator.get_uint8(); 00213 _line_style_index = iterator.get_uint8(); 00214 if (_header->get_flt_version() >= 1420) { 00215 _flags = iterator.get_be_uint32(); 00216 _light_mode = (LightMode)iterator.get_uint8(); 00217 iterator.skip_bytes(1 + 4); 00218 iterator.skip_bytes(2); // Undocumented padding. 00219 00220 if (!_packed_color.extract_record(reader)) { 00221 return false; 00222 } 00223 if (!_alt_packed_color.extract_record(reader)) { 00224 return false; 00225 } 00226 00227 if (_header->get_flt_version() >= 1520) { 00228 _texture_mapping_index = iterator.get_be_int16(); 00229 iterator.skip_bytes(2); 00230 _color_index = iterator.get_be_int32(); 00231 _alt_color_index = iterator.get_be_int32(); 00232 iterator.skip_bytes(2 + 2); 00233 } 00234 } 00235 00236 return true; 00237 } 00238 00239 //////////////////////////////////////////////////////////////////// 00240 // Function: FltGeometry::build_record 00241 // Access: Protected, Virtual 00242 // Description: Fills up the current record on the FltRecordWriter with 00243 // data for this record, but does not advance the 00244 // writer. Returns true on success, false if there is 00245 // some error. 00246 //////////////////////////////////////////////////////////////////// 00247 bool FltGeometry:: 00248 build_record(FltRecordWriter &writer) const { 00249 Datagram &datagram = writer.update_datagram(); 00250 00251 datagram.add_be_int32(_ir_color); 00252 datagram.add_be_int16(_relative_priority); 00253 datagram.add_int8(_draw_type); 00254 datagram.add_int8(_texwhite); 00255 datagram.add_be_uint16(_color_name_index); 00256 datagram.add_be_uint16(_alt_color_name_index); 00257 datagram.pad_bytes(1); 00258 datagram.add_int8(_billboard_type); 00259 datagram.add_be_int16(_detail_texture_index); 00260 datagram.add_be_int16(_texture_index); 00261 datagram.add_be_int16(_material_index); 00262 datagram.add_be_int16(_dfad_material_code); 00263 datagram.add_be_int16(_dfad_feature_id); 00264 datagram.add_be_int32(_ir_material_code); 00265 datagram.add_be_uint16(_transparency); 00266 datagram.add_uint8(_lod_generation_control); 00267 datagram.add_uint8(_line_style_index); 00268 datagram.add_be_uint32(_flags); 00269 datagram.add_uint8(_light_mode); 00270 datagram.pad_bytes(1 + 4); 00271 datagram.pad_bytes(2); // Undocumented padding. 00272 00273 if (!_packed_color.build_record(writer)) { 00274 return false; 00275 } 00276 if (!_alt_packed_color.build_record(writer)) { 00277 return false; 00278 } 00279 00280 if (_header->get_flt_version() >= 1520) { 00281 // New with 15.2 00282 datagram.add_be_int16(_texture_mapping_index); 00283 datagram.pad_bytes(2); 00284 datagram.add_be_int32(_color_index); 00285 datagram.add_be_int32(_alt_color_index); 00286 datagram.pad_bytes(2 + 2); 00287 } 00288 00289 return true; 00290 }