diff --git a/BACKERS.md b/BACKERS.md index 82715b9749..7f34cbabbe 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -10,11 +10,12 @@ This is a list of all the people who are contributing financially to Panda3D. I ## Bronze Sponsors -![Bronze Sponsors](https://opencollective.com/panda3d/tiers/bronze-sponsor.svg?avatarHeight=48&width=600) +[ChangeCrab](https://changecrab.com/) ![Bronze Sponsors](https://opencollective.com/panda3d/tiers/bronze-sponsor.svg?avatarHeight=48&width=600) * [Mitchell Stokes](https://opencollective.com/mitchell-stokes) * [Daniel Stokes](https://opencollective.com/daniel-stokes) * [David Rose](https://opencollective.com/david-rose) +* [ChangeCrab](https://changecrab.com) ## Benefactors diff --git a/dtool/src/prc/configPageManager.h b/dtool/src/prc/configPageManager.h index 5afba59796..9a775f7b63 100644 --- a/dtool/src/prc/configPageManager.h +++ b/dtool/src/prc/configPageManager.h @@ -63,6 +63,16 @@ PUBLISHED: static ConfigPageManager *get_global_ptr(); +PUBLISHED: + MAKE_PROPERTY(search_path, get_search_path); + + MAKE_SEQ_PROPERTY(prc_patterns, get_num_prc_patterns, get_prc_pattern); + MAKE_SEQ_PROPERTY(prc_encrypted_patterns, get_num_prc_encrypted_patterns, get_prc_encrypted_pattern); + MAKE_SEQ_PROPERTY(prc_executable_patterns, get_num_prc_executable_patterns, get_prc_executable_pattern); + + MAKE_SEQ_PROPERTY(implicit_pages, get_num_implicit_pages, get_implicit_page); + MAKE_SEQ_PROPERTY(explicit_pages, get_num_explicit_pages, get_explicit_page); + public: INLINE void mark_unsorted(); diff --git a/panda/src/bullet/bulletGhostNode.cxx b/panda/src/bullet/bulletGhostNode.cxx index d3dcb7aaf5..d86dd59598 100644 --- a/panda/src/bullet/bulletGhostNode.cxx +++ b/panda/src/bullet/bulletGhostNode.cxx @@ -41,6 +41,39 @@ BulletGhostNode(const char *name) : BulletBodyNode(name) { _ghost->setCollisionShape(_shape); } +/** + * Do not call the copy constructor directly; instead, use make_copy() or + * copy_subgraph() to make a copy of a node. + */ +BulletGhostNode:: +BulletGhostNode(const BulletGhostNode ©) : + BulletBodyNode(copy), + _sync(TransformState::make_identity()), + _sync_disable(false), + _sync_local(false) +{ + // Initial transform - the node has no parent yet, so this is the local one + btTransform trans = TransformState_to_btTrans(get_transform()); + + // Ghost object + _ghost = new btPairCachingGhostObject(); + _ghost->setUserPointer(this); + _ghost->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE); + _ghost->setWorldTransform(trans); + _ghost->setInterpolationWorldTransform(trans); + _ghost->setCollisionShape(_shape); +} + +/** + * Returns a newly-allocated PandaNode that is a shallow copy of this one. It + * will be a different pointer, but its internal data may or may not be shared + * with that of the original PandaNode. No children will be copied. + */ +PandaNode *BulletGhostNode:: +make_copy() const { + return new BulletGhostNode(*this); +} + /** * */ @@ -171,3 +204,27 @@ do_sync_b2p() { _sync_disable = false; } } + +/** + * Tells the BamReader how to create objects of type BulletGhostNode. + */ +void BulletGhostNode:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +/** + * This function is called by the BamReader's factory when a new object of + * this type is encountered in the Bam file. It should create the ghost node. + */ +TypedWritable *BulletGhostNode:: +make_from_bam(const FactoryParams ¶ms) { + BulletGhostNode *param = new BulletGhostNode; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + param->fillin(scan, manager); + + return param; +} diff --git a/panda/src/bullet/bulletGhostNode.h b/panda/src/bullet/bulletGhostNode.h index 74eed65a56..ddec79641a 100644 --- a/panda/src/bullet/bulletGhostNode.h +++ b/panda/src/bullet/bulletGhostNode.h @@ -59,6 +59,14 @@ private: void do_transform_changed(); +public: + static void register_with_read_factory(); + virtual PandaNode *make_copy() const; + +protected: + BulletGhostNode(const BulletGhostNode ©); + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/bullet/config_bullet.cxx b/panda/src/bullet/config_bullet.cxx index 140c7d0efc..e4627c931e 100644 --- a/panda/src/bullet/config_bullet.cxx +++ b/panda/src/bullet/config_bullet.cxx @@ -189,6 +189,7 @@ init_libbullet() { BulletDebugNode::register_with_read_factory(); BulletPlaneShape::register_with_read_factory(); BulletRigidBodyNode::register_with_read_factory(); + BulletGhostNode::register_with_read_factory(); BulletSphereShape::register_with_read_factory(); BulletTriangleMesh::register_with_read_factory(); BulletTriangleMeshShape::register_with_read_factory(); diff --git a/panda/src/collide/collisionBox.cxx b/panda/src/collide/collisionBox.cxx index 84a8e39817..e44f8834bf 100644 --- a/panda/src/collide/collisionBox.cxx +++ b/panda/src/collide/collisionBox.cxx @@ -30,6 +30,7 @@ #include "cmath.h" #include "mathNumbers.h" #include "geom.h" +#include "geomLines.h" #include "geomTriangles.h" #include "geomVertexWriter.h" #include "config_mathutil.h" @@ -1024,11 +1025,37 @@ fill_viz_geom() { tris->add_vertices(3, 7, 0); tris->add_vertices(0, 7, 4); - PT(Geom) geom = new Geom(vdata); - geom->add_primitive(tris); + PT(GeomLines) lines = new GeomLines(Geom::UH_static); - _viz_geom->add_geom(geom, get_solid_viz_state()); - _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state()); + // Bottom + lines->add_vertices(0, 1); + lines->add_vertices(1, 2); + lines->add_vertices(0, 3); + lines->add_vertices(2, 3); + + // Top + lines->add_vertices(4, 5); + lines->add_vertices(5, 6); + lines->add_vertices(4, 7); + lines->add_vertices(6, 7); + + // Sides + lines->add_vertices(0, 4); + lines->add_vertices(1, 5); + lines->add_vertices(2, 6); + lines->add_vertices(3, 7); + + PT(Geom) geom1 = new Geom(vdata); + geom1->add_primitive(tris); + + PT(Geom) geom2 = new Geom(vdata); + geom2->add_primitive(lines); + + _viz_geom->add_geom(geom1, get_solid_viz_state()); + _viz_geom->add_geom(geom2, get_wireframe_viz_state()); + + _bounds_viz_geom->add_geom(geom1, get_solid_bounds_viz_state()); + _bounds_viz_geom->add_geom(geom2, get_wireframe_viz_state()); } /** diff --git a/panda/src/event/asyncFuture_ext.cxx b/panda/src/event/asyncFuture_ext.cxx index f47abdf7db..7f0ab9d658 100644 --- a/panda/src/event/asyncFuture_ext.cxx +++ b/panda/src/event/asyncFuture_ext.cxx @@ -205,6 +205,9 @@ result(PyObject *timeout) const { exc_type = PyObject_GetAttrString(module, "TimeoutError"); Py_DECREF(module); } + else { + PyErr_Clear(); + } // If we can't get that, we should pretend and make our own. if (exc_type == nullptr) { #if PY_VERSION_HEX >= 0x03080000 @@ -315,6 +318,10 @@ get_cancelled_error_type() { exc_type = PyObject_GetAttrString(module, "CancelledError"); Py_DECREF(module); } + else { + PyErr_Clear(); + } + // If we can't get that, we should pretend and make our own. if (exc_type == nullptr) { #if PY_VERSION_HEX >= 0x03080000 diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index d80d2623bb..0ea627fdd2 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1039,8 +1039,10 @@ reset() { #endif _supports_tex_storage = true; +#ifndef OPENGLES _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC) get_extension_func("glTexStorage1D"); +#endif _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) get_extension_func("glTexStorage2D"); _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) @@ -1050,8 +1052,6 @@ reset() { else if (has_extension("GL_EXT_texture_storage")) { _supports_tex_storage = true; - _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC) - get_extension_func("glTexStorage1DEXT"); _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) get_extension_func("glTexStorage2DEXT"); _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) @@ -1060,7 +1060,11 @@ reset() { #endif if (_supports_tex_storage) { - if (_glTexStorage1D == nullptr || _glTexStorage2D == nullptr || _glTexStorage3D == nullptr) { + if ( +#ifndef OPENGLES + _glTexStorage1D == nullptr || +#endif + _glTexStorage2D == nullptr || _glTexStorage3D == nullptr) { GLCAT.warning() << "Immutable texture storage advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n"; _supports_tex_storage = false; @@ -13230,8 +13234,10 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { case Texture::TT_buffer_texture: // Won't get here, but squelch compiler warning case Texture::TT_1d_texture: +#ifndef OPENGLES _glTexStorage1D(target, num_levels, internal_format, width); break; +#endif case Texture::TT_2d_texture: case Texture::TT_cube_map: case Texture::TT_1d_texture_array: diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 32d5240f16..4a56f6beda 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -789,7 +789,9 @@ public: #endif bool _supports_tex_storage; +#ifndef OPENGLES PFNGLTEXSTORAGE1DPROC _glTexStorage1D; +#endif PFNGLTEXSTORAGE2DPROC _glTexStorage2D; PFNGLTEXSTORAGE3DPROC _glTexStorage3D; diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index dbba4c7bee..de7874ec55 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1017,6 +1017,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { else if (noprefix.compare(7, string::npos, "Emission") == 0) { bind._part = Shader::STO_stage_emission_i; } + else { + GLCAT.error() + << "Unrecognized shader input name: p3d_" << noprefix << "\n"; + } for (bind._stage = 0; bind._stage < param_size; ++bind._stage) { _glgsg->_glUniform1i(p + bind._stage, _shader->_tex_spec.size()); diff --git a/panda/src/gobj/geomVertexArrayData.cxx b/panda/src/gobj/geomVertexArrayData.cxx index 4ab1baf165..75a9a5db20 100644 --- a/panda/src/gobj/geomVertexArrayData.cxx +++ b/panda/src/gobj/geomVertexArrayData.cxx @@ -59,8 +59,10 @@ ALLOC_DELETED_CHAIN_DEF(GeomVertexArrayDataHandle); * file. */ GeomVertexArrayData:: -GeomVertexArrayData() : SimpleLruPage(0) { - _contexts = nullptr; +GeomVertexArrayData() : + SimpleLruPage(0), + _array_format(nullptr), + _contexts(nullptr) { // Can't put it in the LRU until it has been read in and made valid. } @@ -180,7 +182,8 @@ set_usage_hint(GeomVertexArrayData::UsageHint usage_hint) { */ void GeomVertexArrayData:: output(std::ostream &out) const { - out << get_num_rows() << " rows: " << *get_array_format(); + nassertv(_array_format != nullptr); + out << get_num_rows() << " rows: " << *_array_format; } /** @@ -188,6 +191,7 @@ output(std::ostream &out) const { */ void GeomVertexArrayData:: write(std::ostream &out, int indent_level) const { + nassertv(_array_format != nullptr); _array_format->write_with_data(out, indent_level, this); } diff --git a/panda/src/gobj/geomVertexData.I b/panda/src/gobj/geomVertexData.I index 5f27f3b322..66f8a44b93 100644 --- a/panda/src/gobj/geomVertexData.I +++ b/panda/src/gobj/geomVertexData.I @@ -605,6 +605,7 @@ CacheEntry(GeomVertexData *source, CacheKey &&key) noexcept : */ INLINE GeomVertexData::CData:: CData() : + _format(nullptr), _usage_hint(UH_unspecified) { } diff --git a/panda/src/gobj/geomVertexData.cxx b/panda/src/gobj/geomVertexData.cxx index 378e49415b..65dd962902 100644 --- a/panda/src/gobj/geomVertexData.cxx +++ b/panda/src/gobj/geomVertexData.cxx @@ -1268,7 +1268,9 @@ output(ostream &out) const { if (!get_name().empty()) { out << get_name() << " "; } - out << get_num_rows() << " rows: " << *get_format(); + const GeomVertexFormat *format = get_format(); + nassertv(format != nullptr); + out << get_num_rows() << " rows: " << *format; } /** @@ -1279,8 +1281,15 @@ write(ostream &out, int indent_level) const { if (!get_name().empty()) { indent(out, indent_level) << get_name() << "\n"; } - get_format()->write_with_data(out, indent_level + 2, this); - CPT(TransformBlendTable) table = get_transform_blend_table(); + CPT(TransformBlendTable) table; + const GeomVertexFormat *format = nullptr; + { + CDReader cdata(_cycler); + format = cdata->_format; + table = cdata->_transform_blend_table.get_read_pointer(); + } + nassertv(format != nullptr); + format->write_with_data(out, indent_level + 2, this); if (table != nullptr) { indent(out, indent_level) << "Transform blend table:\n"; diff --git a/tests/bullet/test_bullet_bam.py b/tests/bullet/test_bullet_bam.py index 386e044f9f..ae20f2d47a 100644 --- a/tests/bullet/test_bullet_bam.py +++ b/tests/bullet/test_bullet_bam.py @@ -131,3 +131,12 @@ def test_sphere_shape(): assert shape.margin == shape2.margin assert shape.name == shape2.name assert shape.radius == shape2.radius + + +def test_ghost(): + node = bullet.BulletGhostNode("some ghost node") + + node2 = reconstruct(node) + + assert type(node) is type(node2) + assert node.name == node2.name