Panda3D
|
00001 // Filename: fltVertex.cxx 00002 // Created by: drose (25Aug00) 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 "fltVertex.h" 00016 #include "fltRecordReader.h" 00017 #include "fltRecordWriter.h" 00018 #include "fltHeader.h" 00019 00020 TypeHandle FltVertex::_type_handle; 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: FltVertex::Constructor 00024 // Access: Public 00025 // Description: 00026 //////////////////////////////////////////////////////////////////// 00027 FltVertex:: 00028 FltVertex(FltHeader *header) : FltRecord(header) { 00029 _color_name_index = 0; 00030 _flags = F_no_color; 00031 _pos.set(0.0, 0.0, 0.0); 00032 _normal.set(0.0, 0.0, 0.0); 00033 _uv.set(0.0, 0.0); 00034 _color_index = 0; 00035 00036 _has_normal = false; 00037 _has_uv = false; 00038 } 00039 00040 //////////////////////////////////////////////////////////////////// 00041 // Function: FltVertex::get_opcode 00042 // Access: Public 00043 // Description: Returns the opcode that this record will be written 00044 // as. 00045 //////////////////////////////////////////////////////////////////// 00046 FltOpcode FltVertex:: 00047 get_opcode() const { 00048 if (_has_normal) { 00049 if (_has_uv) { 00050 return FO_vertex_cnu; 00051 } else { 00052 return FO_vertex_cn; 00053 } 00054 } else { 00055 if (_has_uv) { 00056 return FO_vertex_cu; 00057 } else { 00058 return FO_vertex_c; 00059 } 00060 } 00061 } 00062 00063 //////////////////////////////////////////////////////////////////// 00064 // Function: FltVertex::get_record_length 00065 // Access: Public 00066 // Description: Returns the length of this record in bytes as it will 00067 // be written to the flt file. 00068 //////////////////////////////////////////////////////////////////// 00069 int FltVertex:: 00070 get_record_length() const { 00071 if (_header->get_flt_version() < 1520) { 00072 // Version 14.2 00073 switch (get_opcode()) { 00074 case FO_vertex_c: 00075 return 36; 00076 00077 case FO_vertex_cn: 00078 return 48; 00079 00080 case FO_vertex_cnu: 00081 return 56; 00082 00083 case FO_vertex_cu: 00084 return 44; 00085 00086 default: 00087 nassertr(false, 0); 00088 } 00089 00090 } else { 00091 // Version 15.2 and higher 00092 switch (get_opcode()) { 00093 case FO_vertex_c: 00094 return 40; 00095 00096 case FO_vertex_cn: 00097 return 56; 00098 00099 case FO_vertex_cnu: 00100 return 64; 00101 00102 case FO_vertex_cu: 00103 return 48; 00104 00105 default: 00106 nassertr(false, 0); 00107 } 00108 } 00109 00110 return 0; 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function: FltVertex::get_color 00115 // Access: Public 00116 // Description: If has_color() indicates true, returns the 00117 // color of the vertex, as a four-component value. In 00118 // the case of a vertex, the alpha channel will always 00119 // be 1.0, as MultiGen does not store transparency 00120 // per-vertex. 00121 //////////////////////////////////////////////////////////////////// 00122 LColor FltVertex:: 00123 get_color() const { 00124 nassertr(has_color(), LColor(0.0, 0.0, 0.0, 0.0)); 00125 00126 return _header->get_color(_color_index, (_flags & F_packed_color) != 0, 00127 _packed_color, 0); 00128 } 00129 00130 //////////////////////////////////////////////////////////////////// 00131 // Function: FltVertex::get_rgb 00132 // Access: Public 00133 // Description: If has_color() indicates true, returns the 00134 // color of the vertex, as a three-component value. 00135 //////////////////////////////////////////////////////////////////// 00136 LRGBColor FltVertex:: 00137 get_rgb() const { 00138 nassertr(has_color(), LRGBColor(0.0, 0.0, 0.0)); 00139 00140 return _header->get_rgb(_color_index, (_flags & F_packed_color) != 0, 00141 _packed_color); 00142 } 00143 00144 //////////////////////////////////////////////////////////////////// 00145 // Function: FltVertex::set_rgb 00146 // Access: Public 00147 // Description: Sets the color of the vertex, using the packed 00148 // color convention. 00149 //////////////////////////////////////////////////////////////////// 00150 void FltVertex:: 00151 set_rgb(const LRGBColor &rgb) { 00152 _packed_color.set_rgb(rgb); 00153 _flags = ((_flags & ~F_no_color) | F_packed_color); 00154 } 00155 00156 //////////////////////////////////////////////////////////////////// 00157 // Function: FltVertex::extract_record 00158 // Access: Protected, Virtual 00159 // Description: Fills in the information in this record based on the 00160 // information given in the indicated datagram, whose 00161 // opcode has already been read. Returns true on 00162 // success, false if the datagram is invalid. 00163 //////////////////////////////////////////////////////////////////// 00164 bool FltVertex:: 00165 extract_record(FltRecordReader &reader) { 00166 if (!FltRecord::extract_record(reader)) { 00167 return false; 00168 } 00169 00170 switch (reader.get_opcode()) { 00171 case FO_vertex_c: 00172 _has_normal = false; 00173 _has_uv = false; 00174 break; 00175 00176 case FO_vertex_cn: 00177 _has_normal = true; 00178 _has_uv = false; 00179 break; 00180 00181 case FO_vertex_cnu: 00182 _has_normal = true; 00183 _has_uv = true; 00184 break; 00185 00186 case FO_vertex_cu: 00187 _has_normal = false; 00188 _has_uv = true; 00189 break; 00190 00191 default: 00192 nassertr(false, false); 00193 } 00194 00195 DatagramIterator &iterator = reader.get_iterator(); 00196 00197 _color_name_index = iterator.get_be_int16(); 00198 _flags = iterator.get_be_uint16(); 00199 _pos[0] = iterator.get_be_float64(); 00200 _pos[1] = iterator.get_be_float64(); 00201 _pos[2] = iterator.get_be_float64(); 00202 00203 if (_has_normal) { 00204 _normal[0] = iterator.get_be_float32(); 00205 _normal[1] = iterator.get_be_float32(); 00206 _normal[2] = iterator.get_be_float32(); 00207 } 00208 if (_has_uv) { 00209 _uv[0] = iterator.get_be_float32(); 00210 _uv[1] = iterator.get_be_float32(); 00211 } 00212 00213 if (iterator.get_remaining_size() > 0) { 00214 if (!_packed_color.extract_record(reader)) { 00215 return false; 00216 } 00217 if (_header->get_flt_version() >= 1520) { 00218 _color_index = iterator.get_be_int32(); 00219 00220 if (_has_normal && iterator.get_remaining_size() > 0) { 00221 // If we extracted a normal, our double-word alignment is off; now 00222 // we have a few extra bytes to ignore. 00223 iterator.skip_bytes(4); 00224 } 00225 } 00226 } 00227 00228 check_remaining_size(iterator); 00229 return true; 00230 } 00231 00232 //////////////////////////////////////////////////////////////////// 00233 // Function: FltVertex::build_record 00234 // Access: Protected, Virtual 00235 // Description: Fills up the current record on the FltRecordWriter with 00236 // data for this record, but does not advance the 00237 // writer. Returns true on success, false if there is 00238 // some error. 00239 //////////////////////////////////////////////////////////////////// 00240 bool FltVertex:: 00241 build_record(FltRecordWriter &writer) const { 00242 if (!FltRecord::build_record(writer)) { 00243 return false; 00244 } 00245 00246 writer.set_opcode(get_opcode()); 00247 Datagram &datagram = writer.update_datagram(); 00248 00249 datagram.add_be_int16(_color_name_index); 00250 datagram.add_be_uint16(_flags); 00251 datagram.add_be_float64(_pos[0]); 00252 datagram.add_be_float64(_pos[1]); 00253 datagram.add_be_float64(_pos[2]); 00254 00255 if (_has_normal) { 00256 datagram.add_be_float32(_normal[0]); 00257 datagram.add_be_float32(_normal[1]); 00258 datagram.add_be_float32(_normal[2]); 00259 } 00260 if (_has_uv) { 00261 datagram.add_be_float32(_uv[0]); 00262 datagram.add_be_float32(_uv[1]); 00263 } 00264 00265 if (!_packed_color.build_record(writer)) { 00266 return false; 00267 } 00268 00269 if (_header->get_flt_version() >= 1520) { 00270 // New with 15.2 00271 datagram.add_be_uint32(_color_index); 00272 00273 if (_has_normal) { 00274 // If we added a normal, our double-word alignment is off; now we 00275 // have a few extra bytes to add. 00276 datagram.pad_bytes(4); 00277 } 00278 } 00279 00280 nassertr((int)datagram.get_length() == get_record_length() - 4, true); 00281 return true; 00282 }