22GeomVertexFormat::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)
61void GeomVertexFormat::
65 _animation = copy._animation;
66 _arrays = copy._arrays;
84 Registry *registry = get_registry();
107get_post_animated_format()
const {
110 if (_post_animated_format ==
nullptr) {
112 new_format->remove_column(InternalName::get_transform_blend());
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();
134 return _post_animated_format;
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);
250modify_array(
size_t array) {
252 nassertr(array < _arrays.size(),
nullptr);
259 return _arrays[array];
270 nassertv(array < _arrays.size());
283 nassertv(array < _arrays.size());
284 _arrays.erase(_arrays.begin() + array);
298 size_t new_array = _arrays.size();
313 if (array > _arrays.size()) {
314 array = _arrays.size();
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);
358 size_t num_columns = 0;
359 Arrays::const_iterator ai;
360 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
361 num_columns += (*ai)->get_num_columns();
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();
567void GeomVertexFormat::
568output(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);
584 out <<
", anim " << _animation;
591void GeomVertexFormat::
592write(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);
601 <<
"anim " << _animation <<
"\n";
608void GeomVertexFormat::
609write_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);
653int 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]);
677void GeomVertexFormat::
679 if (_registry ==
nullptr) {
680 _registry =
new Registry;
681 _registry->make_standard_formats();
688void GeomVertexFormat::
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));
772 morph._base = morph._delta->get_ancestor(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;
805void 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;
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);
885void 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);
902GeomVertexFormat::Registry::
909void GeomVertexFormat::Registry::
910make_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();
1046void GeomVertexFormat::Registry::
1049 Formats::iterator fi = _formats.find(format);
1050 nassertv(fi != _formats.end());
1052 format->do_unregister();
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
A class to retrieve the individual data elements previously stored in a Datagram.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
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.
get_animation_type
Returns the type of animation represented by this spec.
int compare_to(const GeomVertexAnimationSpec &other) const
Provides an arbitrary ordering between different animation specs.
void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is called by make_from_bam to read in all of the relevant data from the BamFil...
void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
This defines how a single column is interleaved within a vertex array stored within a Geom.
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
const InternalName * get_name() const
Returns the name of this particular data field, e.g.
Contents get_contents() const
Returns the token representing the semantic meaning of the stored value.
int get_total_bytes() const
Returns the number of bytes used by each element of the column: component_bytes * num_components.
int get_num_components() const
Returns the number of components of the column: the number of instances of the NumericType in each el...
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
Encodes a string name in a hash table, mapping it to a pointer.
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...
get_name
Returns the complete name represented by the InternalName and all of its parents.
Similar to MutexHolder, but for a light reentrant mutex.
void ref() const
Explicitly increments the reference count.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
get_ref_count
Returns the current reference count.
virtual bool unref() const
Explicitly decrements the reference count.
TypeHandle is the identifier used to differentiate C++ class types.
Base class for objects that can be written to and read from Bam files.
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...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
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().
This is our own Panda specialization on the default STL set.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...