24 TypeHandle CollisionHandlerFloor::_type_handle;
29 CollisionHandlerFloor::
30 CollisionHandlerFloor() {
39 CollisionHandlerFloor::
40 ~CollisionHandlerFloor() {
58 PN_stdfloat CollisionHandlerFloor::
59 set_highest_collision(
const NodePath &target_node_path,
const NodePath &from_node_path,
const Entries &entries) {
66 PN_stdfloat max_height = 0.0f;
67 PN_stdfloat min_height = 0.0f;
71 Entries::const_iterator ei;
72 for (ei = entries.begin(); ei != entries.end(); ++ei) {
74 nassertr(entry !=
nullptr, 0.0f);
79 if (collide_cat.is_debug()) {
81 <<
"Intersection point detected at " << point <<
"\n";
84 PN_stdfloat height = point[2];
85 if (height < _offset + _reach &&
86 (!got_max || height > max_height)) {
91 if (!got_min || height < min_height) {
98 if (!got_max && got_min) {
102 max_height = min_height;
108 cout<<
"\ncolliding with:\n";
109 for (Colliding::const_iterator i = _current_colliding.begin(); i != _current_colliding.end(); ++i) {
110 (**i).write(cout, 2);
112 cout<<
"\nhighest:\n";
113 highest->write(cout, 2);
119 _current_colliding.clear();
135 bool CollisionHandlerFloor::
142 _current_colliding.clear();
144 FromEntries::const_iterator fi;
145 for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) {
146 const NodePath &from_node_path = (*fi).first;
147 const Entries &entries = (*fi).second;
149 Colliders::iterator ci;
150 ci = _colliders.
find(from_node_path);
151 if (ci == _colliders.end()) {
155 << get_type() <<
" doesn't know about "
156 << from_node_path <<
", disabling.\n";
159 ColliderDef &def = (*ci).second;
163 bool got_max =
false;
164 PN_stdfloat max_height = 0.0f;
167 Entries::const_iterator ei;
168 for (ei = entries.begin(); ei != entries.end(); ++ei) {
170 nassertr(entry !=
nullptr,
false);
175 if (collide_cat.is_debug()) {
177 <<
"Intersection point detected at " << point <<
"\n";
180 PN_stdfloat height = point[2];
181 if (!got_max || height > max_height) {
191 _current_colliding.insert(max_entry);
194 PN_stdfloat adjust = max_height + _offset;
196 PN_stdfloat max_height = set_highest_collision(def._target, from_node_path, entries);
199 PN_stdfloat adjust = max_height + _offset;
201 if (!IS_THRESHOLD_ZERO(adjust, 0.001)) {
202 if (collide_cat.is_debug()) {
204 <<
"Adjusting height by " << adjust <<
"\n";
207 if (adjust < 0.0f && _max_velocity != 0.0f) {
208 PN_stdfloat max_adjust =
210 adjust = std::max(adjust, -max_adjust);
214 LVecBase3 pos = trans->get_pos();
216 def._target.set_transform(trans->set_pos(pos));
217 def.updated_transform();
219 apply_linear_force(def, LVector3(0.0f, 0.0f, adjust));
221 if (collide_cat.is_spam()) {
223 <<
"Leaving height unchanged.\n";
236 void CollisionHandlerFloor::
237 apply_linear_force(ColliderDef &def,
const LVector3 &force) {