physics: fix crash in edge case when PhysicalNode dies before Physical

Also add more assertion checks
This commit is contained in:
rdb 2017-05-24 20:21:48 +02:00
parent 904209b277
commit 257311cc0c
3 changed files with 26 additions and 7 deletions

View File

@ -30,10 +30,10 @@ TypeHandle Physical::_type_handle;
* the speed-vs-overhead deal. * the speed-vs-overhead deal.
*/ */
Physical:: Physical::
Physical(int total_objects, bool pre_alloc) { Physical(int total_objects, bool pre_alloc) :
_viscosity=0.0; _viscosity(0.0),
_physical_node = (PhysicalNode *) NULL; _physics_manager(nullptr),
_physics_manager = (PhysicsManager *) NULL; _physical_node(nullptr) {
if (total_objects == 1) { if (total_objects == 1) {
_phys_body = new PhysicsObject; _phys_body = new PhysicsObject;
@ -55,8 +55,9 @@ Physical(int total_objects, bool pre_alloc) {
* to its template's physicsmanager. * to its template's physicsmanager.
*/ */
Physical:: Physical::
Physical(const Physical& copy) { Physical(const Physical& copy) :
_physics_manager = (PhysicsManager *) NULL; _physics_manager(nullptr),
_physical_node(nullptr) {
// copy the forces. // copy the forces.
LinearForceVector::const_iterator lf_cur; LinearForceVector::const_iterator lf_cur;

View File

@ -16,6 +16,11 @@
*/ */
INLINE void PhysicalNode:: INLINE void PhysicalNode::
clear() { clear() {
PhysicalsVector::iterator it;
for (it = _physicals.begin(); it != _physicals.end(); ++it) {
nassertd((*it)->_physical_node == this) continue;
(*it)->_physical_node = nullptr;
}
_physicals.erase(_physicals.begin(), _physicals.end()); _physicals.erase(_physicals.begin(), _physicals.end());
} }

View File

@ -38,6 +38,15 @@ PhysicalNode(const PhysicalNode &copy) :
*/ */
PhysicalNode:: PhysicalNode::
~PhysicalNode() { ~PhysicalNode() {
PhysicalsVector::iterator it;
for (it = _physicals.begin(); it != _physicals.end(); ++it) {
Physical *physical = *it;
nassertd(physical->_physical_node == this) continue;
physical->_physical_node = nullptr;
if (physical->_physics_manager != nullptr) {
physical->_physics_manager->remove_physical(physical);
}
}
} }
/** /**
@ -83,9 +92,13 @@ remove_physical(Physical *physical) {
pvector< PT(Physical) >::iterator found; pvector< PT(Physical) >::iterator found;
PT(Physical) ptp = physical; PT(Physical) ptp = physical;
found = find(_physicals.begin(), _physicals.end(), ptp); found = find(_physicals.begin(), _physicals.end(), ptp);
if (found == _physicals.end()) if (found == _physicals.end()) {
return; return;
}
_physicals.erase(found); _physicals.erase(found);
nassertv(ptp->_physical_node == this);
ptp->_physical_node = nullptr;
} }
/** /**