Panda3D
fltVertex.cxx
1 // Filename: fltVertex.cxx
2 // Created by: drose (25Aug00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "fltVertex.h"
16 #include "fltRecordReader.h"
17 #include "fltRecordWriter.h"
18 #include "fltHeader.h"
19 
20 TypeHandle FltVertex::_type_handle;
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: FltVertex::Constructor
24 // Access: Public
25 // Description:
26 ////////////////////////////////////////////////////////////////////
27 FltVertex::
28 FltVertex(FltHeader *header) : FltRecord(header) {
29  _color_name_index = 0;
30  _flags = F_no_color;
31  _pos.set(0.0, 0.0, 0.0);
32  _normal.set(0.0, 0.0, 0.0);
33  _uv.set(0.0, 0.0);
34  _color_index = 0;
35 
36  _has_normal = false;
37  _has_uv = false;
38 }
39 
40 ////////////////////////////////////////////////////////////////////
41 // Function: FltVertex::get_opcode
42 // Access: Public
43 // Description: Returns the opcode that this record will be written
44 // as.
45 ////////////////////////////////////////////////////////////////////
46 FltOpcode FltVertex::
47 get_opcode() const {
48  if (_has_normal) {
49  if (_has_uv) {
50  return FO_vertex_cnu;
51  } else {
52  return FO_vertex_cn;
53  }
54  } else {
55  if (_has_uv) {
56  return FO_vertex_cu;
57  } else {
58  return FO_vertex_c;
59  }
60  }
61 }
62 
63 ////////////////////////////////////////////////////////////////////
64 // Function: FltVertex::get_record_length
65 // Access: Public
66 // Description: Returns the length of this record in bytes as it will
67 // be written to the flt file.
68 ////////////////////////////////////////////////////////////////////
69 int FltVertex::
71  if (_header->get_flt_version() < 1520) {
72  // Version 14.2
73  switch (get_opcode()) {
74  case FO_vertex_c:
75  return 36;
76 
77  case FO_vertex_cn:
78  return 48;
79 
80  case FO_vertex_cnu:
81  return 56;
82 
83  case FO_vertex_cu:
84  return 44;
85 
86  default:
87  nassertr(false, 0);
88  }
89 
90  } else {
91  // Version 15.2 and higher
92  switch (get_opcode()) {
93  case FO_vertex_c:
94  return 40;
95 
96  case FO_vertex_cn:
97  return 56;
98 
99  case FO_vertex_cnu:
100  return 64;
101 
102  case FO_vertex_cu:
103  return 48;
104 
105  default:
106  nassertr(false, 0);
107  }
108  }
109 
110  return 0;
111 }
112 
113 ////////////////////////////////////////////////////////////////////
114 // Function: FltVertex::get_color
115 // Access: Public
116 // Description: If has_color() indicates true, returns the
117 // color of the vertex, as a four-component value. In
118 // the case of a vertex, the alpha channel will always
119 // be 1.0, as MultiGen does not store transparency
120 // per-vertex.
121 ////////////////////////////////////////////////////////////////////
123 get_color() const {
124  nassertr(has_color(), LColor(0.0, 0.0, 0.0, 0.0));
125 
126  return _header->get_color(_color_index, (_flags & F_packed_color) != 0,
127  _packed_color, 0);
128 }
129 
130 ////////////////////////////////////////////////////////////////////
131 // Function: FltVertex::get_rgb
132 // Access: Public
133 // Description: If has_color() indicates true, returns the
134 // color of the vertex, as a three-component value.
135 ////////////////////////////////////////////////////////////////////
137 get_rgb() const {
138  nassertr(has_color(), LRGBColor(0.0, 0.0, 0.0));
139 
140  return _header->get_rgb(_color_index, (_flags & F_packed_color) != 0,
141  _packed_color);
142 }
143 
144 ////////////////////////////////////////////////////////////////////
145 // Function: FltVertex::set_rgb
146 // Access: Public
147 // Description: Sets the color of the vertex, using the packed
148 // color convention.
149 ////////////////////////////////////////////////////////////////////
150 void FltVertex::
151 set_rgb(const LRGBColor &rgb) {
152  _packed_color.set_rgb(rgb);
153  _flags = ((_flags & ~F_no_color) | F_packed_color);
154 }
155 
156 ////////////////////////////////////////////////////////////////////
157 // Function: FltVertex::extract_record
158 // Access: Protected, Virtual
159 // Description: Fills in the information in this record based on the
160 // information given in the indicated datagram, whose
161 // opcode has already been read. Returns true on
162 // success, false if the datagram is invalid.
163 ////////////////////////////////////////////////////////////////////
164 bool FltVertex::
165 extract_record(FltRecordReader &reader) {
166  if (!FltRecord::extract_record(reader)) {
167  return false;
168  }
169 
170  switch (reader.get_opcode()) {
171  case FO_vertex_c:
172  _has_normal = false;
173  _has_uv = false;
174  break;
175 
176  case FO_vertex_cn:
177  _has_normal = true;
178  _has_uv = false;
179  break;
180 
181  case FO_vertex_cnu:
182  _has_normal = true;
183  _has_uv = true;
184  break;
185 
186  case FO_vertex_cu:
187  _has_normal = false;
188  _has_uv = true;
189  break;
190 
191  default:
192  nassertr(false, false);
193  }
194 
195  DatagramIterator &iterator = reader.get_iterator();
196 
197  _color_name_index = iterator.get_be_int16();
198  _flags = iterator.get_be_uint16();
199  _pos[0] = iterator.get_be_float64();
200  _pos[1] = iterator.get_be_float64();
201  _pos[2] = iterator.get_be_float64();
202 
203  if (_has_normal) {
204  _normal[0] = iterator.get_be_float32();
205  _normal[1] = iterator.get_be_float32();
206  _normal[2] = iterator.get_be_float32();
207  }
208  if (_has_uv) {
209  _uv[0] = iterator.get_be_float32();
210  _uv[1] = iterator.get_be_float32();
211  }
212 
213  if (iterator.get_remaining_size() > 0) {
214  if (!_packed_color.extract_record(reader)) {
215  return false;
216  }
217  if (_header->get_flt_version() >= 1520) {
218  _color_index = iterator.get_be_int32();
219 
220  if (_has_normal && iterator.get_remaining_size() > 0) {
221  // If we extracted a normal, our double-word alignment is off; now
222  // we have a few extra bytes to ignore.
223  iterator.skip_bytes(4);
224  }
225  }
226  }
227 
228  check_remaining_size(iterator);
229  return true;
230 }
231 
232 ////////////////////////////////////////////////////////////////////
233 // Function: FltVertex::build_record
234 // Access: Protected, Virtual
235 // Description: Fills up the current record on the FltRecordWriter with
236 // data for this record, but does not advance the
237 // writer. Returns true on success, false if there is
238 // some error.
239 ////////////////////////////////////////////////////////////////////
240 bool FltVertex::
241 build_record(FltRecordWriter &writer) const {
242  if (!FltRecord::build_record(writer)) {
243  return false;
244  }
245 
246  writer.set_opcode(get_opcode());
247  Datagram &datagram = writer.update_datagram();
248 
249  datagram.add_be_int16(_color_name_index);
250  datagram.add_be_uint16(_flags);
251  datagram.add_be_float64(_pos[0]);
252  datagram.add_be_float64(_pos[1]);
253  datagram.add_be_float64(_pos[2]);
254 
255  if (_has_normal) {
256  datagram.add_be_float32(_normal[0]);
257  datagram.add_be_float32(_normal[1]);
258  datagram.add_be_float32(_normal[2]);
259  }
260  if (_has_uv) {
261  datagram.add_be_float32(_uv[0]);
262  datagram.add_be_float32(_uv[1]);
263  }
264 
265  if (!_packed_color.build_record(writer)) {
266  return false;
267  }
268 
269  if (_header->get_flt_version() >= 1520) {
270  // New with 15.2
271  datagram.add_be_uint32(_color_index);
272 
273  if (_has_normal) {
274  // If we added a normal, our double-word alignment is off; now we
275  // have a few extra bytes to add.
276  datagram.pad_bytes(4);
277  }
278  }
279 
280  nassertr((int)datagram.get_length() == get_record_length() - 4, true);
281  return true;
282 }
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
This class writes a sequence of FltRecords to an ostream, handling opcode and size counts properly...
This class turns an istream into a sequence of FltRecords by reading a sequence of Datagrams and extr...
PN_float64 get_be_float64()
Extracts a 64-bit big-endian floating-point number.
int get_record_length() const
Returns the length of this record in bytes as it will be written to the flt file. ...
Definition: fltVertex.cxx:70
FltOpcode get_opcode() const
Returns the opcode that this record will be written as.
Definition: fltVertex.cxx:47
PN_float32 get_be_float32()
Extracts a 32-bit big-endian single-precision floating-point number.
void check_remaining_size(const DatagramIterator &di, const string &name=string()) const
Checks that the iterator has no bytes left, as it should at the end of a successfully read record...
Definition: fltRecord.cxx:313
LRGBColor get_rgb() const
If has_color() indicates true, returns the color of the vertex, as a three-component value...
Definition: fltVertex.cxx:137
DatagramIterator & get_iterator()
Returns an iterator suitable for extracting data from the current record.
void set_rgb(const LRGBColor &rgb)
Sets the color according to the indicated three-component LRGBColor value, and set the alpha to 1...
bool has_color() const
Returns true if the vertex has a primary color indicated, false otherwise.
Definition: fltVertex.I:23
void set_rgb(const LRGBColor &rgb)
Sets the color of the vertex, using the packed color convention.
Definition: fltVertex.cxx:151
void pad_bytes(size_t size)
Adds the indicated number of zero bytes to the datagram.
Definition: datagram.cxx:111
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition: fltHeader.h:48
void add_be_float64(PN_float64 value)
Adds a 64-bit big-endian floating-point number to the datagram.
Definition: datagram.I:339
void add_be_float32(PN_float32 value)
Adds a 32-bit single-precision big-endian floating-point number to the datagram.
Definition: datagram.I:327
int get_remaining_size() const
Return the bytes left in the datagram.
void skip_bytes(size_t size)
Skips over the indicated number of bytes in the datagram.
The base class for all kinds of records in a MultiGen OpenFlight file.
Definition: fltRecord.h:40
PN_int16 get_be_int16()
Extracts a signed 16-bit big-endian integer.
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
FltOpcode get_opcode() const
Returns the opcode associated with the current record.
void add_be_uint16(PN_uint16 value)
Adds an unsigned 16-bit big-endian integer to the datagram.
Definition: datagram.I:291
A class to retrieve the individual data elements previously stored in a Datagram. ...
void add_be_uint32(PN_uint32 value)
Adds an unsigned 32-bit big-endian integer to the datagram.
Definition: datagram.I:303
LColor get_color() const
If has_color() indicates true, returns the color of the vertex, as a four-component value...
Definition: fltVertex.cxx:123
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
PN_uint16 get_be_uint16()
Extracts an unsigned 16-bit big-endian integer.
void set_opcode(FltOpcode opcode)
Sets the opcode associated with the current record.
Datagram & update_datagram()
Returns a modifiable reference to the datagram associated with the current record.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
PN_int32 get_be_int32()
Extracts a signed 32-bit big-endian integer.
void add_be_int16(PN_int16 value)
Adds a signed 16-bit big-endian integer to the datagram.
Definition: datagram.I:255
size_t get_length() const
Returns the number of bytes in the datagram.
Definition: datagram.I:457