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();
92 registry->unregister_format((GeomVertexFormat *)
this);
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();
122 CPT(GeomVertexFormat) registered =
123 GeomVertexFormat::register_format(new_format);
124 ((GeomVertexFormat *)
this)->_post_animated_format = registered;
125 if (_post_animated_format !=
this) {
128 _post_animated_format->ref();
132 _post_animated_format->test_ref_count_integrity();
134 return _post_animated_format;
150 PT(GeomVertexFormat) new_format =
new GeomVertexFormat;
155 if (_animation.get_animation_type() != AT_none) {
156 new_format->set_animation(_animation);
162 typedef pset< CPT(InternalName) > ColumnNames;
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) {
178 PT(GeomVertexArrayFormat) new_array =
new GeomVertexArrayFormat;
181 if (ai < _arrays.size()) {
182 GeomVertexArrayFormat *array_format = _arrays[ai];
184 for (
size_t i = 0; i < num_columns; ++i) {
185 const GeomVertexColumn *column_a = array_format->
get_column(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()) {
209 GeomVertexArrayFormat *array_format = other->_arrays[ai];
211 for (
size_t i = 0; i < num_columns; ++i) {
212 const GeomVertexColumn *column_a = array_format->
get_column(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);
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();
317 _arrays.insert(_arrays.begin() + array, (GeomVertexArrayFormat *)array_format);
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++) {
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);
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) {
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);
583 if (_animation.get_animation_type() != AT_none) {
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);
599 if (_animation.get_animation_type() != AT_none) {
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++) {
614 CPT(GeomVertexArrayDataHandle) handle = data->get_array(i)->get_handle();
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) {
697 CPT(GeomVertexArrayFormat) array_format = (*ai);
699 array_format = GeomVertexArrayFormat::register_format(array_format);
708 <<
"Dropping empty array from GeomVertexFormat.\n";
712 int array = (int)_arrays.size();
713 _arrays.push_back((GeomVertexArrayFormat *)array_format.p());
717 for (
int i = 0; i < num_columns; i++) {
718 const GeomVertexColumn *column = array_format->
get_column(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;
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);
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() {
911 _empty = register_format(
new GeomVertexFormat);
913 _v3 = register_format(
new GeomVertexArrayFormat
914 (InternalName::get_vertex(), 3,
915 NT_stdfloat, C_point));
917 _v3n3 = register_format(
new GeomVertexArrayFormat
918 (InternalName::get_vertex(), 3,
919 NT_stdfloat, C_point,
920 InternalName::get_normal(), 3,
921 NT_stdfloat, C_normal));
923 _v3t2 = register_format(
new GeomVertexArrayFormat
924 (InternalName::get_vertex(), 3,
925 NT_stdfloat, C_point,
926 InternalName::get_texcoord(), 2,
927 NT_stdfloat, C_texcoord));
929 _v3n3t2 = register_format(
new GeomVertexArrayFormat
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));
938 _v3cp = register_format(
new GeomVertexArrayFormat
939 (InternalName::get_vertex(), 3,
940 NT_stdfloat, C_point,
941 InternalName::get_color(), 1,
942 NT_packed_dabc, C_color));
944 _v3n3cp = register_format(
new GeomVertexArrayFormat
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));
952 _v3cpt2 = register_format(
new GeomVertexArrayFormat
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));
960 _v3n3cpt2 = register_format(
new GeomVertexArrayFormat
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));
973 _v3c4 = register_format(
new GeomVertexArrayFormat
974 (InternalName::get_vertex(), 3,
975 NT_stdfloat, C_point,
976 InternalName::get_color(), 4,
979 _v3n3c4 = register_format(
new GeomVertexArrayFormat
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,
987 _v3c4t2 = register_format(
new GeomVertexArrayFormat
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));
995 _v3n3c4t2 = register_format(
new GeomVertexArrayFormat
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));
1016CPT(GeomVertexFormat) GeomVertexFormat::Registry::
1017register_format(GeomVertexFormat *format) {
1025 PT(GeomVertexFormat) pt_format = format;
1027 GeomVertexFormat *new_format;
1029 LightReMutexHolder holder(_lock);
1030 Formats::iterator fi = _formats.insert(format).first;
1033 new_format->do_register();
1046void GeomVertexFormat::Registry::
1047unregister_format(GeomVertexFormat *format) {
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.
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.
int compare_to(const GeomVertexAnimationSpec &other) const
Provides an arbitrary ordering between different animation specs.
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...
Similar to MutexHolder, but for a light reentrant mutex.
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().
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...