22 GeomVertexFormat::Registry *GeomVertexFormat::_registry =
nullptr;
30 _is_registered(false),
31 _post_animated_format(nullptr)
40 _is_registered(false),
41 _post_animated_format(nullptr)
43 add_array(array_format);
51 _is_registered(false),
52 _animation(copy._animation),
53 _arrays(copy._arrays),
54 _post_animated_format(nullptr)
61 void GeomVertexFormat::
63 nassertv(!is_registered());
65 _animation = copy._animation;
66 _arrays = copy._arrays;
75 nassertv(!is_registered());
84 Registry *registry = get_registry();
91 if (is_registered()) {
107 get_post_animated_format()
const {
108 nassertr(is_registered(),
nullptr);
110 if (_post_animated_format ==
nullptr) {
112 new_format->remove_column(InternalName::get_transform_blend());
114 int num_morphs = get_num_morphs();
115 for (
int mi = 0; mi < num_morphs; mi++) {
117 new_format->remove_column(delta_name);
120 new_format->_animation.set_none();
123 GeomVertexFormat::register_format(new_format);
125 if (_post_animated_format !=
this) {
128 _post_animated_format->ref();
132 _post_animated_format->test_ref_count_integrity();
134 return _post_animated_format;
148 nassertr(is_registered() && other->
is_registered(),
nullptr);
155 if (_animation.get_animation_type() != AT_none) {
163 ColumnNames column_names;
176 size_t num_arrays = std::max(_arrays.size(), other->_arrays.size());
177 for (
size_t ai = 0; ai < num_arrays; ++ai) {
181 if (ai < _arrays.size()) {
184 for (
size_t i = 0; i < num_columns; ++i) {
186 bool inserted = column_names.insert(column_a->
get_name()).second;
189 if (column_b !=
nullptr &&
192 new_array->add_column(column_b->
get_name(),
198 new_array->add_column(column_a->
get_name(),
208 if (ai < other->_arrays.size()) {
211 for (
size_t i = 0; i < num_columns; ++i) {
213 bool inserted = column_names.insert(column_a->
get_name()).second;
216 if (column_b !=
nullptr &&
219 new_array->add_column(column_b->
get_name(),
225 new_array->add_column(column_a->
get_name(),
234 if (new_array->get_num_columns() != 0) {
235 new_format->add_array(new_array);
240 return GeomVertexFormat::register_format(new_format);
250 modify_array(
size_t array) {
251 nassertr(!is_registered(),
nullptr);
252 nassertr(array < _arrays.size(),
nullptr);
254 if (_arrays[array]->is_registered() ||
255 _arrays[array]->get_ref_count() > 1) {
259 return _arrays[array];
269 nassertv(!is_registered());
270 nassertv(array < _arrays.size());
281 nassertv(!is_registered());
283 nassertv(array < _arrays.size());
284 _arrays.erase(_arrays.begin() + array);
296 nassertr(!is_registered(), 0);
298 size_t new_array = _arrays.size();
312 nassertv(!is_registered());
313 if (array > _arrays.size()) {
314 array = _arrays.size();
327 nassertv(!is_registered());
339 nassertv(!is_registered());
342 orig_arrays.swap(_arrays);
343 Arrays::const_iterator ai;
344 for (ai = orig_arrays.begin(); ai != orig_arrays.end(); ++ai) {
347 _arrays.push_back(array_format);
356 size_t GeomVertexFormat::
357 get_num_columns()
const {
358 size_t num_columns = 0;
359 Arrays::const_iterator ai;
360 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
371 Arrays::const_iterator ai;
372 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
373 if (i < (
size_t)(*ai)->get_num_columns()) {
374 return (*ai)->get_column(i);
376 i -= (*ai)->get_num_columns();
387 Arrays::const_iterator ai;
388 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
389 if (i < (
size_t)(*ai)->get_num_columns()) {
390 return (*ai)->get_column(i)->get_name();
392 i -= (*ai)->get_num_columns();
408 for (array_index = 0; array_index < (int)_arrays.size(); array_index++) {
409 if (i < (
size_t)_arrays[array_index]->get_num_columns()) {
412 i -= _arrays[array_index]->get_num_columns();
430 nassertr(_is_registered, -1);
432 DataTypesByName::const_iterator ai;
433 ai = _columns_by_name.find(name);
434 if (ai != _columns_by_name.end()) {
435 return (*ai).second._array_index;
447 if (!_is_registered) {
450 Arrays::const_iterator ai;
451 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
453 if (column !=
nullptr) {
463 DataTypesByName::const_iterator ai;
464 ai = _columns_by_name.find(name);
465 if (ai != _columns_by_name.end()) {
466 int array_index = (*ai).second._array_index;
467 int column_index = (*ai).second._column_index;
469 nassertr(array_index >= 0 && array_index < (
int)_arrays.size(),
nullptr);
470 return _arrays[array_index]->get_column(column_index);
486 nassertv(!_is_registered);
491 for (
int array = 0; array < (int)_arrays.size(); ++array) {
494 if (array_format->
get_column(name) !=
nullptr) {
500 array_format = _arrays[array];
523 nassertv(!_is_registered);
525 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
526 if ((*ai)->is_registered()) {
529 (*ai)->pack_columns();
542 nassertv(!_is_registered);
544 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
545 if ((*ai)->is_registered()) {
548 (*ai)->align_columns_for_animation();
559 if (_animation.get_animation_type() == AT_panda && vertex_animation_align_16) {
560 align_columns_for_animation();
567 void GeomVertexFormat::
568 output(std::ostream &out)
const {
569 if (_arrays.empty()) {
573 Arrays::const_iterator ai;
574 ai = _arrays.begin();
577 while (ai != _arrays.end()) {
578 out <<
", " << *(*ai);
583 if (_animation.get_animation_type() != AT_none) {
584 out <<
", anim " << _animation;
591 void GeomVertexFormat::
592 write(std::ostream &out,
int indent_level)
const {
593 for (
size_t i = 0; i < _arrays.size(); i++) {
595 <<
"Array " << i <<
":\n";
596 _arrays[i]->write(out, indent_level + 2);
599 if (_animation.get_animation_type() != AT_none) {
601 <<
"anim " << _animation <<
"\n";
608 void GeomVertexFormat::
609 write_with_data(std::ostream &out,
int indent_level,
612 << data->get_num_rows() <<
" rows.\n";
613 for (
size_t i = 0; i < _arrays.size(); i++) {
615 const unsigned char *array_data = handle->get_read_pointer(
true);
617 <<
"Array " << i <<
" (" << (
void *)array_data <<
", " 618 << *_arrays[i] <<
"):\n";
619 _arrays[i]->write_with_data(out, indent_level + 2, data->get_array(i));
634 nassertr(_is_registered,
false);
636 DataTypesByName::const_iterator ai;
637 ai = _columns_by_name.find(name);
638 if (ai != _columns_by_name.end()) {
639 array_index = (*ai).second._array_index;
640 column = _arrays[array_index]->get_column((*ai).second._column_index);
653 int GeomVertexFormat::
655 int compare = _animation.
compare_to(other._animation);
660 if (_arrays.size() != other._arrays.size()) {
661 return (
int)_arrays.size() - (int)other._arrays.size();
664 for (
size_t i = 0; i < _arrays.size(); i++) {
665 int compare = _arrays[i]->compare_to(*other._arrays[i]);
677 void GeomVertexFormat::
679 if (_registry ==
nullptr) {
680 _registry =
new Registry;
681 _registry->make_standard_formats();
688 void GeomVertexFormat::
690 nassertv(!is_registered());
691 nassertv(_columns_by_name.empty());
694 orig_arrays.swap(_arrays);
695 Arrays::const_iterator ai;
696 for (ai = orig_arrays.begin(); ai != orig_arrays.end(); ++ai) {
699 array_format = GeomVertexArrayFormat::register_format(array_format);
708 <<
"Dropping empty array from GeomVertexFormat.\n";
712 int array = (int)_arrays.size();
717 for (
int i = 0; i < num_columns; i++) {
719 std::pair<DataTypesByName::iterator, bool> result;
720 result = _columns_by_name.insert(DataTypesByName::value_type(column->
get_name(), DataTypeRecord()));
721 if (!result.second) {
723 <<
"Column " << *column->
get_name() <<
" repeated in format.\n";
725 DataTypeRecord &record = (*result.first).second;
726 record._array_index = array;
727 record._column_index = i;
734 DataTypesByName::iterator ni;
735 for (ni = _columns_by_name.begin();
736 ni != _columns_by_name.end();
738 const DataTypeRecord &record = (*ni).second;
739 const GeomVertexColumn *column = _arrays[record._array_index]->get_column(record._column_index);
744 _points.push_back(column->
get_name());
750 _vectors.push_back(column->
get_name());
755 _texcoords.push_back(column->
get_name());
768 <<
"vertex format defines " << *column->
get_name()
769 <<
", which is stored as a C_morph_delta, but its name does not include \"morph\".\n";
771 morph._slider = InternalName::make(morph._delta->get_net_basename(n - 1));
774 if (_columns_by_name.find(morph._base) == _columns_by_name.end()) {
776 <<
"vertex format defines " 777 << *column->
get_name() <<
" but does not define " 778 << *morph._base <<
"\n";
780 _morphs.push_back(morph);
792 _is_registered =
true;
794 get_array_info(InternalName::get_vertex(), _vertex_array_index,
796 get_array_info(InternalName::get_normal(), _normal_array_index,
798 get_array_info(InternalName::get_color(), _color_array_index,
805 void GeomVertexFormat::
807 nassertv(_is_registered);
808 _is_registered =
false;
810 _columns_by_name.clear();
816 if (_post_animated_format !=
nullptr &&
817 _post_animated_format !=
this) {
820 _post_animated_format =
nullptr;
839 _animation.write_datagram(manager, dg);
842 Arrays::const_iterator ai;
843 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
857 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
876 object->fillin(scan, manager);
885 void GeomVertexFormat::
889 _animation.fillin(scan, manager);
892 _arrays.reserve(num_arrays);
893 for (
int i = 0; i < num_arrays; i++) {
895 _arrays.push_back(
nullptr);
902 GeomVertexFormat::Registry::
909 void GeomVertexFormat::Registry::
910 make_standard_formats() {
914 (InternalName::get_vertex(), 3,
915 NT_stdfloat, C_point));
918 (InternalName::get_vertex(), 3,
919 NT_stdfloat, C_point,
920 InternalName::get_normal(), 3,
921 NT_stdfloat, C_normal));
924 (InternalName::get_vertex(), 3,
925 NT_stdfloat, C_point,
926 InternalName::get_texcoord(), 2,
927 NT_stdfloat, C_texcoord));
930 (InternalName::get_vertex(), 3,
931 NT_stdfloat, C_point,
932 InternalName::get_normal(), 3,
933 NT_stdfloat, C_normal,
934 InternalName::get_texcoord(), 2,
935 NT_stdfloat, C_texcoord));
939 (InternalName::get_vertex(), 3,
940 NT_stdfloat, C_point,
941 InternalName::get_color(), 1,
942 NT_packed_dabc, C_color));
945 (InternalName::get_vertex(), 3,
946 NT_stdfloat, C_point,
947 InternalName::get_normal(), 3,
948 NT_stdfloat, C_normal,
949 InternalName::get_color(), 1,
950 NT_packed_dabc, C_color));
953 (InternalName::get_vertex(), 3,
954 NT_stdfloat, C_point,
955 InternalName::get_color(), 1,
956 NT_packed_dabc, C_color,
957 InternalName::get_texcoord(), 2,
958 NT_stdfloat, C_texcoord));
961 (InternalName::get_vertex(), 3,
962 NT_stdfloat, C_point,
963 InternalName::get_normal(), 3,
964 NT_stdfloat, C_normal,
965 InternalName::get_color(), 1,
966 NT_packed_dabc, C_color,
967 InternalName::get_texcoord(), 2,
968 NT_stdfloat, C_texcoord));
974 (InternalName::get_vertex(), 3,
975 NT_stdfloat, C_point,
976 InternalName::get_color(), 4,
980 (InternalName::get_vertex(), 3,
981 NT_stdfloat, C_point,
982 InternalName::get_normal(), 3,
983 NT_stdfloat, C_normal,
984 InternalName::get_color(), 4,
988 (InternalName::get_vertex(), 3,
989 NT_stdfloat, C_point,
990 InternalName::get_color(), 4,
992 InternalName::get_texcoord(), 2,
993 NT_stdfloat, C_texcoord));
996 (InternalName::get_vertex(), 3,
997 NT_stdfloat, C_point,
998 InternalName::get_normal(), 3,
999 NT_stdfloat, C_normal,
1000 InternalName::get_color(), 4,
1002 InternalName::get_texcoord(), 2,
1003 NT_stdfloat, C_texcoord));
1030 Formats::iterator fi = _formats.insert(format).first;
1033 new_format->do_register();
1046 void GeomVertexFormat::Registry::
1049 Formats::iterator fi = _formats.find(format);
1050 nassertv(fi != _formats.end());
1052 format->do_unregister();
get_ref_count
Returns the current reference count.
Contents get_contents() const
Returns the token representing the semantic meaning of the stored value.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
Base class for objects that can be written to and read from Bam files.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
This defines how a single column is interleaved within a vertex array stored within a Geom.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
const InternalName * get_ancestor(int n) const
Returns the ancestor with the indicated index number.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Similar to MutexHolder, but for a light reentrant mutex.
Encodes a string name in a hash table, mapping it to a pointer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
int find_ancestor(const std::string &basename) const
Returns the index of the ancestor with the indicated basename, or -1 if no ancestor has that basename...
This is our own Panda specialization on the default STL set.
A class to retrieve the individual data elements previously stored in a Datagram.
const InternalName * get_name() const
Returns the name of this particular data field, e.g.
int get_total_bytes() const
Returns the number of bytes used by each element of the column: component_bytes * num_components.
TypeHandle is the identifier used to differentiate C++ class types.
int get_num_components() const
Returns the number of components of the column: the number of instances of the NumericType in each el...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool unref() const
Explicitly decrements the reference count.
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int compare_to(const GeomVertexColumn &other) const
This is used to unquify columns, and hence formats, for the GeomVertexFormat registry.