00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "collisionHandlerFloor.h"
00016 #include "collisionNode.h"
00017 #include "collisionEntry.h"
00018 #include "config_collide.h"
00019
00020 #include "clockObject.h"
00021
00022 TypeHandle CollisionHandlerFloor::_type_handle;
00023
00024
00025
00026
00027
00028
00029 CollisionHandlerFloor::
00030 CollisionHandlerFloor() {
00031 _offset = 0.0f;
00032 _reach = 1.0f;
00033 _max_velocity = 0.0f;
00034 }
00035
00036
00037
00038
00039
00040
00041 CollisionHandlerFloor::
00042 ~CollisionHandlerFloor() {
00043 }
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 PN_stdfloat CollisionHandlerFloor::
00057 set_highest_collision(const NodePath &target_node_path, const NodePath &from_node_path, const Entries &entries) {
00058
00059
00060
00061
00062
00063 bool got_max = false;
00064 bool got_min = false;
00065 PN_stdfloat max_height = 0.0f;
00066 PN_stdfloat min_height = 0.0f;
00067 CollisionEntry *highest = NULL;
00068 CollisionEntry *lowest = NULL;
00069
00070 Entries::const_iterator ei;
00071 for (ei = entries.begin(); ei != entries.end(); ++ei) {
00072 CollisionEntry *entry = (*ei);
00073 nassertr(entry != (CollisionEntry *)NULL, 0.0f);
00074 nassertr(from_node_path == entry->get_from_node_path(), 0.0f);
00075
00076 if (entry->has_surface_point()) {
00077 LPoint3 point = entry->get_surface_point(target_node_path);
00078 if (collide_cat.is_debug()) {
00079 collide_cat.debug()
00080 << "Intersection point detected at " << point << "\n";
00081 }
00082
00083 PN_stdfloat height = point[2];
00084 if (height < _offset + _reach &&
00085 (!got_max || height > max_height)) {
00086 got_max = true;
00087 max_height = height;
00088 highest = entry;
00089 }
00090 if (!got_min || height < min_height) {
00091 got_min = true;
00092 min_height = height;
00093 lowest = entry;
00094 }
00095 }
00096 }
00097 if (!got_max && got_min) {
00098
00099
00100
00101 got_max = true;
00102 max_height = min_height;
00103 highest = lowest;
00104 }
00105
00106
00107 #if 0
00108 cout<<"\ncolliding with:\n";
00109 for (Colliding::const_iterator i = _current_colliding.begin(); i != _current_colliding.end(); ++i) {
00110 (**i).write(cout, 2);
00111 }
00112 cout<<"\nhighest:\n";
00113 highest->write(cout, 2);
00114 cout<<endl;
00115 #endif
00116 #if 1
00117
00118
00119 _current_colliding.clear();
00120
00121 add_entry(highest);
00122 #endif
00123
00124 return max_height;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 bool CollisionHandlerFloor::
00139 handle_entries() {
00140 bool okflag = true;
00141
00142
00143
00144
00145 _current_colliding.clear();
00146
00147 FromEntries::const_iterator fi;
00148 for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) {
00149 const NodePath &from_node_path = (*fi).first;
00150 const Entries &entries = (*fi).second;
00151
00152 Colliders::iterator ci;
00153 ci = _colliders.find(from_node_path);
00154 if (ci == _colliders.end()) {
00155
00156
00157
00158 collide_cat.error()
00159 << get_type() << " doesn't know about "
00160 << from_node_path << ", disabling.\n";
00161 okflag = false;
00162 } else {
00163 ColliderDef &def = (*ci).second;
00164 {
00165 #if 0
00166
00167 bool got_max = false;
00168 PN_stdfloat max_height = 0.0f;
00169 CollisionEntry *max_entry = NULL;
00170
00171 Entries::const_iterator ei;
00172 for (ei = entries.begin(); ei != entries.end(); ++ei) {
00173 CollisionEntry *entry = (*ei);
00174 nassertr(entry != (CollisionEntry *)NULL, false);
00175 nassertr(from_node_path == entry->get_from_node_path(), false);
00176
00177 if (entry->has_surface_point()) {
00178 LPoint3 point = entry->get_surface_point(def._target);
00179 if (collide_cat.is_debug()) {
00180 collide_cat.debug()
00181 << "Intersection point detected at " << point << "\n";
00182 }
00183
00184 PN_stdfloat height = point[2];
00185 if (!got_max || height > max_height) {
00186 got_max = true;
00187 max_height = height;
00188 max_entry = entry;
00189 }
00190 }
00191 }
00192
00193
00194
00195 _current_colliding.insert(max_entry);
00196
00197
00198 PN_stdfloat adjust = max_height + _offset;
00199 #else
00200 PN_stdfloat max_height = set_highest_collision(def._target, from_node_path, entries);
00201
00202
00203 PN_stdfloat adjust = max_height + _offset;
00204 #endif
00205 if (!IS_THRESHOLD_ZERO(adjust, 0.001)) {
00206 if (collide_cat.is_debug()) {
00207 collide_cat.debug()
00208 << "Adjusting height by " << adjust << "\n";
00209 }
00210
00211 if (adjust < 0.0f && _max_velocity != 0.0f) {
00212 PN_stdfloat max_adjust =
00213 _max_velocity * ClockObject::get_global_clock()->get_dt();
00214 adjust = max(adjust, -max_adjust);
00215 }
00216
00217 CPT(TransformState) trans = def._target.get_transform();
00218 LVecBase3 pos = trans->get_pos();
00219 pos[2] += adjust;
00220 def._target.set_transform(trans->set_pos(pos));
00221 def.updated_transform();
00222
00223 apply_linear_force(def, LVector3(0.0f, 0.0f, adjust));
00224 } else {
00225 if (collide_cat.is_spam()) {
00226 collide_cat.spam()
00227 << "Leaving height unchanged.\n";
00228 }
00229 }
00230 }
00231 }
00232 }
00233
00234 return okflag;
00235 }
00236
00237
00238
00239
00240
00241
00242 void CollisionHandlerFloor::
00243 apply_linear_force(ColliderDef &def, const LVector3 &force) {
00244 }