Panda3D
fltLocalVertexPool.cxx
1 // Filename: fltLocalVertexPool.cxx
2 // Created by: drose (28Feb01)
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 "fltLocalVertexPool.h"
16 #include "fltRecordReader.h"
17 #include "fltRecordWriter.h"
18 #include "fltHeader.h"
19 #include "fltMaterial.h"
20 
21 TypeHandle FltLocalVertexPool::_type_handle;
22 
23 ////////////////////////////////////////////////////////////////////
24 // Function: FltLocalVertexPool::Constructor
25 // Access: Public
26 // Description:
27 ////////////////////////////////////////////////////////////////////
28 FltLocalVertexPool::
29 FltLocalVertexPool(FltHeader *header) : FltRecord(header) {
30 }
31 
32 ////////////////////////////////////////////////////////////////////
33 // Function: FltLocalVertexPool::extract_record
34 // Access: Protected, Virtual
35 // Description: Fills in the information in this bead based on the
36 // information given in the indicated datagram, whose
37 // opcode has already been read. Returns true on
38 // success, false if the datagram is invalid.
39 ////////////////////////////////////////////////////////////////////
42  if (!FltRecord::extract_record(reader)) {
43  return false;
44  }
45 
46  nassertr(reader.get_opcode() == FO_local_vertex_pool, false);
47  DatagramIterator &iterator = reader.get_iterator();
48 
49  int num_vertices = iterator.get_be_int32();
50  int attributes = iterator.get_be_int32();
51 
52  for (int i = 0; i < num_vertices; i++) {
53  FltVertex *vertex = new FltVertex(_header);
54  _vertices.push_back(vertex);
55 
56  if ((attributes & AM_has_position) != 0) {
57  vertex->_pos[0] = iterator.get_be_float64();
58  vertex->_pos[1] = iterator.get_be_float64();
59  vertex->_pos[2] = iterator.get_be_float64();
60  }
61 
62  if ((attributes & AM_has_color_index) != 0) {
63  vertex->_color_index = iterator.get_be_int32();
64 
65  } else if ((attributes & AM_has_packed_color) != 0) {
66  if (!vertex->_packed_color.extract_record(reader)) {
67  return false;
68  }
69  vertex->_flags |= FltVertex::F_packed_color;
70 
71  } else {
72  vertex->_flags |= FltVertex::F_no_color;
73  }
74 
75  if ((attributes & AM_has_normal) != 0) {
76  vertex->_normal[0] = iterator.get_be_float32();
77  vertex->_normal[1] = iterator.get_be_float32();
78  vertex->_normal[2] = iterator.get_be_float32();
79  vertex->_has_normal = true;
80  }
81 
82  if ((attributes & AM_has_base_uv) != 0) {
83  vertex->_uv[0] = iterator.get_be_float32();
84  vertex->_uv[1] = iterator.get_be_float32();
85  vertex->_has_uv = true;
86  }
87 
88  if ((attributes & AM_has_uv_1) != 0) {
89  iterator.get_be_float32();
90  iterator.get_be_float32();
91  }
92 
93  if ((attributes & AM_has_uv_2) != 0) {
94  iterator.get_be_float32();
95  iterator.get_be_float32();
96  }
97 
98  if ((attributes & AM_has_uv_3) != 0) {
99  iterator.get_be_float32();
100  iterator.get_be_float32();
101  }
102 
103  if ((attributes & AM_has_uv_4) != 0) {
104  iterator.get_be_float32();
105  iterator.get_be_float32();
106  }
107 
108  if ((attributes & AM_has_uv_5) != 0) {
109  iterator.get_be_float32();
110  iterator.get_be_float32();
111  }
112 
113  if ((attributes & AM_has_uv_6) != 0) {
114  iterator.get_be_float32();
115  iterator.get_be_float32();
116  }
117 
118  if ((attributes & AM_has_uv_7) != 0) {
119  iterator.get_be_float32();
120  iterator.get_be_float32();
121  }
122  }
123 
124  check_remaining_size(iterator);
125  return true;
126 }
127 
128 ////////////////////////////////////////////////////////////////////
129 // Function: FltLocalVertexPool::build_record
130 // Access: Protected, Virtual
131 // Description: Fills up the current record on the FltRecordWriter with
132 // data for this record, but does not advance the
133 // writer. Returns true on success, false if there is
134 // some error.
135 ////////////////////////////////////////////////////////////////////
138  if (!FltRecord::build_record(writer)) {
139  return false;
140  }
141 
142  writer.set_opcode(FO_local_vertex_pool);
143  Datagram &datagram = writer.update_datagram();
144 
145  // Determine what kind of vertices we have.
146  int attributes = AM_has_position;
147 
148  Vertices::const_iterator vi;
149  for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
150  FltVertex *vertex = (*vi);
151  if ((vertex->_flags & FltVertex::F_no_color) != 0) {
152  // No color.
153 
154  } else if ((vertex->_flags & FltVertex::F_packed_color) != 0) {
155  // Packed color.
156  attributes |= AM_has_packed_color;
157 
158  } else {
159  // Indexed color.
160  attributes |= AM_has_color_index;
161  }
162 
163  if (vertex->_has_normal) {
164  attributes |= AM_has_normal;
165  }
166 
167  if (vertex->_has_uv) {
168  attributes |= AM_has_base_uv;
169  }
170  }
171 
172  if ((attributes & AM_has_packed_color) != 0 &&
173  (attributes & AM_has_color_index) != 0) {
174  // We cannot have both a packed color and a color index. If we
175  // want both, used packed color.
176  attributes &= ~AM_has_color_index;
177  }
178 
179  datagram.add_be_int32(_vertices.size());
180  datagram.add_be_int32(attributes);
181 
182  // Now write out each vertex.
183  for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
184  FltVertex *vertex = (*vi);
185 
186  if ((attributes & AM_has_position) != 0) {
187  datagram.add_be_float64(vertex->_pos[0]);
188  datagram.add_be_float64(vertex->_pos[1]);
189  datagram.add_be_float64(vertex->_pos[2]);
190  }
191 
192  if ((attributes & AM_has_color_index) != 0) {
193  if ((vertex->_flags & (FltVertex::F_no_color | FltVertex::F_packed_color)) != 0) {
194  // This particular vertex does not have a color index.
195  // Make it white.
196  datagram.add_be_int32(_header->get_closest_rgb(LRGBColor(1.0, 1.0, 1.0)));
197  } else {
198  datagram.add_be_int32(vertex->_color_index);
199  }
200 
201  } else if ((attributes & AM_has_packed_color) != 0) {
202  // We extract our own FltPackedColor instead of writing out the
203  // vertex's _packed_color directly, just in case the vertex is
204  // actually index colored. This bit of code will work
205  // regardless of the kind of color the vertex has.
206 
208  if (vertex->has_color()) {
209  color.set_color(vertex->get_color());
210  } else {
211  // An uncolored vertex. Make it white.
212  color.set_color(LColor(1.0, 1.0, 1.0, 1.0));
213  }
214 
215  if (!color.build_record(writer)) {
216  return false;
217  }
218  }
219 
220  if ((attributes & AM_has_normal) != 0) {
221  if (!vertex->_has_normal) {
222  datagram.add_be_float32(0.0);
223  datagram.add_be_float32(0.0);
224  datagram.add_be_float32(0.0);
225  } else {
226  datagram.add_be_float32(vertex->_normal[0]);
227  datagram.add_be_float32(vertex->_normal[1]);
228  datagram.add_be_float32(vertex->_normal[2]);
229  }
230  }
231 
232  if ((attributes & AM_has_base_uv) != 0) {
233  if (!vertex->_has_uv) {
234  datagram.add_be_float32(0.0);
235  datagram.add_be_float32(0.0);
236  } else {
237  datagram.add_be_float32(vertex->_uv[0]);
238  datagram.add_be_float32(vertex->_uv[1]);
239  }
240  }
241  }
242 
243  return true;
244 }
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...
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
DatagramIterator & get_iterator()
Returns an iterator suitable for extracting data from the current record.
bool has_color() const
Returns true if the vertex has a primary color indicated, false otherwise.
Definition: fltVertex.I:23
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 set_color(const LColor &color)
Sets the color according to the indicated four-component LColor value (including alpha).
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
virtual bool extract_record(FltRecordReader &reader)
Fills in the information in this bead based on the information given in the indicated datagram...
The base class for all kinds of records in a MultiGen OpenFlight file.
Definition: fltRecord.h:40
A packed color record, A, B, G, R.
Represents a single vertex in the vertex palette.
Definition: fltVertex.h:35
void add_be_int32(PN_int32 value)
Adds a signed 32-bit big-endian integer to the datagram.
Definition: datagram.I:267
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.
A class to retrieve the individual data elements previously stored in a Datagram. ...
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
void set_opcode(FltOpcode opcode)
Sets the opcode associated with the current record.
virtual bool build_record(FltRecordWriter &writer) const
Fills up the current record on the FltRecordWriter with data for this record, but does not advance th...
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.