00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "collisionEntry.h"
00016 #include "dcast.h"
00017 #include "indent.h"
00018
00019 TypeHandle CollisionEntry::_type_handle;
00020
00021
00022
00023
00024
00025
00026 CollisionEntry::
00027 CollisionEntry(const CollisionEntry ©) :
00028 _from(copy._from),
00029 _into(copy._into),
00030 _from_node(copy._from_node),
00031 _into_node(copy._into_node),
00032 _from_node_path(copy._from_node_path),
00033 _into_node_path(copy._into_node_path),
00034 _into_clip_planes(copy._into_clip_planes),
00035 _t(copy._t),
00036 _flags(copy._flags),
00037 _surface_point(copy._surface_point),
00038 _surface_normal(copy._surface_normal),
00039 _interior_point(copy._interior_point),
00040 _contact_pos(copy._contact_pos),
00041 _contact_normal(copy._contact_normal)
00042 {
00043 }
00044
00045
00046
00047
00048
00049
00050 void CollisionEntry::
00051 operator = (const CollisionEntry ©) {
00052 _from = copy._from;
00053 _into = copy._into;
00054 _from_node = copy._from_node;
00055 _into_node = copy._into_node;
00056 _from_node_path = copy._from_node_path;
00057 _into_node_path = copy._into_node_path;
00058 _into_clip_planes = copy._into_clip_planes;
00059 _t = copy._t;
00060 _flags = copy._flags;
00061 _surface_point = copy._surface_point;
00062 _surface_normal = copy._surface_normal;
00063 _interior_point = copy._interior_point;
00064 _contact_pos = copy._contact_pos;
00065 _contact_normal = copy._contact_normal;
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 LPoint3 CollisionEntry::
00081 get_surface_point(const NodePath &space) const {
00082 nassertr(has_surface_point(), LPoint3::zero());
00083 CPT(TransformState) transform = _into_node_path.get_transform(space);
00084 return _surface_point * transform->get_mat();
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 LVector3 CollisionEntry::
00097 get_surface_normal(const NodePath &space) const {
00098 nassertr(has_surface_normal(), LVector3::zero());
00099 CPT(TransformState) transform = _into_node_path.get_transform(space);
00100 return _surface_normal * transform->get_mat();
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 LPoint3 CollisionEntry::
00118 get_interior_point(const NodePath &space) const {
00119 if (!has_interior_point()) {
00120 return get_surface_point(space);
00121 }
00122 CPT(TransformState) transform = _into_node_path.get_transform(space);
00123 return _interior_point * transform->get_mat();
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 bool CollisionEntry::
00137 get_all(const NodePath &space, LPoint3 &surface_point,
00138 LVector3 &surface_normal, LPoint3 &interior_point) const {
00139 CPT(TransformState) transform = _into_node_path.get_transform(space);
00140 const LMatrix4 &mat = transform->get_mat();
00141 bool all_ok = true;
00142
00143 if (!has_surface_point()) {
00144 surface_point = LPoint3::zero();
00145 all_ok = false;
00146 } else {
00147 surface_point = _surface_point * mat;
00148 }
00149
00150 if (!has_surface_normal()) {
00151 surface_normal = LVector3::zero();
00152 all_ok = false;
00153 } else {
00154 surface_normal = _surface_normal * mat;
00155 }
00156
00157 if (!has_interior_point()) {
00158 interior_point = surface_point;
00159 all_ok = false;
00160 } else {
00161 interior_point = _interior_point * mat;
00162 }
00163
00164 return all_ok;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 LPoint3 CollisionEntry::
00177 get_contact_pos(const NodePath &space) const {
00178 nassertr(has_contact_pos(), LPoint3::zero());
00179 CPT(TransformState) transform = _into_node_path.get_transform(space);
00180 return _contact_pos * transform->get_mat();
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 LVector3 CollisionEntry::
00193 get_contact_normal(const NodePath &space) const {
00194 nassertr(has_contact_normal(), LVector3::zero());
00195 CPT(TransformState) transform = _into_node_path.get_transform(space);
00196 return _contact_normal * transform->get_mat();
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 bool CollisionEntry::
00210 get_all_contact_info(const NodePath &space, LPoint3 &contact_pos,
00211 LVector3 &contact_normal) const {
00212 CPT(TransformState) transform = _into_node_path.get_transform(space);
00213 const LMatrix4 &mat = transform->get_mat();
00214 bool all_ok = true;
00215
00216 if (!has_contact_pos()) {
00217 contact_pos = LPoint3::zero();
00218 all_ok = false;
00219 } else {
00220 contact_pos = _contact_pos * mat;
00221 }
00222
00223 if (!has_contact_normal()) {
00224 contact_normal = LVector3::zero();
00225 all_ok = false;
00226 } else {
00227 contact_normal = _contact_normal * mat;
00228 }
00229
00230 return all_ok;
00231 }
00232
00233
00234
00235
00236
00237
00238 void CollisionEntry::
00239 output(ostream &out) const {
00240 out << _from_node_path;
00241 if (!_into_node_path.is_empty()) {
00242 out << " into " << _into_node_path;
00243 }
00244 if (has_surface_point()) {
00245 out << " at " << get_surface_point(NodePath());
00246 }
00247 }
00248
00249
00250
00251
00252
00253
00254 void CollisionEntry::
00255 write(ostream &out, int indent_level) const {
00256 indent(out, indent_level)
00257 << "CollisionEntry:\n";
00258 if (!_from_node_path.is_empty()) {
00259 indent(out, indent_level + 2)
00260 << "from " << _from_node_path << "\n";
00261 }
00262 if (!_into_node_path.is_empty()) {
00263 indent(out, indent_level + 2)
00264 << "into " << _into_node_path;
00265
00266 out << " [";
00267 _into_node_path.node()->list_tags(out, ", ");
00268 out << "]";
00269
00270 const ClipPlaneAttrib *cpa = get_into_clip_planes();
00271 if (cpa != (ClipPlaneAttrib *)NULL) {
00272 out << " (clipped)";
00273 }
00274 out << "\n";
00275 }
00276 if (has_surface_point()) {
00277 indent(out, indent_level + 2)
00278 << "at " << get_surface_point(NodePath()) << "\n";
00279 }
00280 if (has_surface_normal()) {
00281 indent(out, indent_level + 2)
00282 << "normal " << get_surface_normal(NodePath()) << "\n";
00283 }
00284 if (has_interior_point()) {
00285 indent(out, indent_level + 2)
00286 << "interior " << get_interior_point(NodePath())
00287 << " (depth "
00288 << (get_interior_point(NodePath()) - get_surface_point(NodePath())).length()
00289 << ")\n";
00290 }
00291 indent(out, indent_level + 2)
00292 << "respect_prev_transform = " << get_respect_prev_transform() << "\n";
00293 }
00294
00295
00296
00297
00298
00299
00300
00301 void CollisionEntry::
00302 check_clip_planes() {
00303 _into_clip_planes = DCAST(ClipPlaneAttrib, _into_node_path.get_net_state()->get_attrib(ClipPlaneAttrib::get_class_slot()));
00304 _flags |= F_checked_clip_planes;
00305 }