22 TypeHandle CollisionHandlerPusher::_type_handle;
40 CollisionHandlerPusher::
41 CollisionHandlerPusher() {
42 _horizontal = pushers_horizontal;
48 CollisionHandlerPusher::
49 ~CollisionHandlerPusher() {
60 bool CollisionHandlerPusher::
64 FromEntries::const_iterator fi;
65 for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) {
66 const NodePath &from_node_path = (*fi).first;
67 const Entries &entries = (*fi).second;
69 Colliders::iterator ci;
70 ci = _colliders.
find(from_node_path);
71 if (ci == _colliders.end()) {
75 <<
"CollisionHandlerPusher doesn't know about "
76 << from_node_path <<
", disabling.\n";
79 ColliderDef &def = (*ci).second;
88 typedef epvector<ShoveData> Shoves;
91 Entries::const_iterator ei;
92 for (ei = entries.begin(); ei != entries.end(); ++ei) {
94 nassertr(entry !=
nullptr,
false);
97 LPoint3 surface_point;
99 LPoint3 interior_point;
101 if (!entry->
get_all(def._target, surface_point, normal, interior_point)) {
103 if (collide_cat.is_debug()) {
105 <<
"Cannot shove on " << from_node_path <<
" for collision into "
111 if (!surface_point.almost_equal(interior_point)) {
122 sd._length = (surface_point - interior_point).length();
127 if (collide_cat.is_debug()) {
129 <<
"Shove on " << from_node_path <<
" from "
131 <<
" times " << sd._length <<
"\n";
135 shoves.push_back(sd);
140 if (!shoves.empty()) {
147 for (si = shoves.begin(); si != shoves.end(); ++si) {
148 ShoveData &sd = (*si);
150 for (sj = shoves.begin(); sj != si; ++sj) {
151 ShoveData &sd2 = (*sj);
153 PN_stdfloat d = sd._vector.dot(sd2._vector);
154 if (collide_cat.is_debug()) {
156 <<
"Considering dot product " << d <<
"\n";
162 if (sd2._length < sd._length) {
176 s1->
is_of_type(CollisionPolygon::get_class_type()) &&
177 s2->
is_of_type(CollisionPolygon::get_class_type()) &&
178 sd._entry->get_into_node_path() ==
179 sd2._entry->get_into_node_path()) {
188 if (collide_cat.is_debug()) {
190 <<
"Discarding shove from convex corner.\n";
199 if (sd2._length < sd._length) {
212 LVector3 net_shove(0.0f, 0.0f, 0.0f);
213 LVector3 force_normal(0.0f, 0.0f, 0.0f);
214 for (si = shoves.begin(); si != shoves.end(); ++si) {
215 const ShoveData &sd = (*si);
217 net_shove += sd._vector * sd._length;
218 force_normal += sd._vector;
223 if (collide_cat.is_debug()) {
225 <<
"Net shove on " << from_node_path <<
" is: "
226 << net_shove <<
"\n";
232 LVecBase3 pos = trans->get_pos();
233 pos += net_shove * trans->get_mat();
234 def._target.set_transform(trans->set_pos(pos));
235 def.updated_transform();
239 apply_net_shove(def, net_shove, force_normal);
240 apply_linear_force(def, force_normal);
253 void CollisionHandlerPusher::
254 apply_net_shove(ColliderDef &def,
const LVector3 &net_shove,
255 const LVector3 &force_normal) {
262 void CollisionHandlerPusher::
263 apply_linear_force(ColliderDef &def,
const LVector3 &force_normal) {