153 lines
4.4 KiB
Text
153 lines
4.4 KiB
Text
|
/**
|
||
|
* PANDA 3D SOFTWARE
|
||
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||
|
*
|
||
|
* All use of this software is subject to the terms of the revised BSD
|
||
|
* license. You should have received a copy of this license along
|
||
|
* with this source code in a file named "LICENSE."
|
||
|
*
|
||
|
* @file collisionSolid.I
|
||
|
* @author drose
|
||
|
* @date 2000-06-27
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Sets the current state of the 'tangible' flag. Set this true to make the
|
||
|
* solid tangible, so that a CollisionHandlerPusher will not allow another
|
||
|
* object to intersect it, or false to make it intangible, so that a
|
||
|
* CollisionHandlerPusher will ignore it except to throw an event.
|
||
|
*/
|
||
|
INLINE void CollisionSolid::
|
||
|
set_tangible(bool tangible) {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
if (tangible) {
|
||
|
_flags |= F_tangible;
|
||
|
} else {
|
||
|
_flags &= ~F_tangible;
|
||
|
}
|
||
|
_flags |= F_viz_geom_stale;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns whether the solid is considered 'tangible' or not. An intangible
|
||
|
* solid has no effect in a CollisionHandlerPusher (except to throw an event);
|
||
|
* it's useful for defining 'trigger' planes and spheres, that cause an effect
|
||
|
* when passed through.
|
||
|
*/
|
||
|
INLINE bool CollisionSolid::
|
||
|
is_tangible() const {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
return do_is_tangible();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Records a false normal for this CollisionSolid that will be reported by the
|
||
|
* collision system with all collisions into it, instead of its actual normal.
|
||
|
* This is useful as a workaround for the problem of an avatar wanting to
|
||
|
* stand on a sloping ground; by storing a false normal, the ground appears to
|
||
|
* be perfectly level, and the avatar does not tend to slide down it.
|
||
|
*/
|
||
|
INLINE void CollisionSolid::
|
||
|
set_effective_normal(const LVector3 &effective_normal) {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
_effective_normal = effective_normal;
|
||
|
_flags |= F_effective_normal;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes the normal previously set by set_effective_normal().
|
||
|
*/
|
||
|
INLINE void CollisionSolid::
|
||
|
clear_effective_normal() {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
_flags &= ~F_effective_normal;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if a special normal was set by set_effective_normal(), false
|
||
|
* otherwise.
|
||
|
*/
|
||
|
INLINE bool CollisionSolid::
|
||
|
has_effective_normal() const {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
return do_has_effective_normal();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the normal that was set by set_effective_normal(). It is an error
|
||
|
* to call this unless has_effective_normal() returns true.
|
||
|
*/
|
||
|
INLINE const LVector3 &CollisionSolid::
|
||
|
get_effective_normal() const {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
nassertr(do_has_effective_normal(), LVector3::zero());
|
||
|
return _effective_normal;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This is only meaningful for CollisionSolids that will be added to a
|
||
|
* traverser as colliders. It is normally true, but if set false, it means
|
||
|
* that this particular solid does not care about the "effective" normal of
|
||
|
* other solids it meets, but rather always uses the true normal.
|
||
|
*/
|
||
|
INLINE void CollisionSolid::
|
||
|
set_respect_effective_normal(bool respect_effective_normal) {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
// For historical reasons, the bit we store is the opposite of the bool flag
|
||
|
// we present.
|
||
|
if (respect_effective_normal) {
|
||
|
_flags &= ~F_ignore_effective_normal;
|
||
|
} else {
|
||
|
_flags |= F_ignore_effective_normal;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* See set_respect_effective_normal().
|
||
|
*/
|
||
|
INLINE bool CollisionSolid::
|
||
|
get_respect_effective_normal() const {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
return (_flags & F_ignore_effective_normal) == 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns whether the solid is considered 'tangible' or not. Assumes the
|
||
|
* lock is already held.
|
||
|
*/
|
||
|
INLINE bool CollisionSolid::
|
||
|
do_is_tangible() const {
|
||
|
return (_flags & F_tangible) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if a special normal was set by set_effective_normal(), false
|
||
|
* otherwise. Assumes the lock is already held.
|
||
|
*/
|
||
|
INLINE bool CollisionSolid::
|
||
|
do_has_effective_normal() const {
|
||
|
return respect_effective_normal && (_flags & F_effective_normal) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Should be called by a derived class to mark the internal bounding volume
|
||
|
* stale, so that recompute_internal_bounds() will be called when the bounding
|
||
|
* volume is next requested.
|
||
|
*/
|
||
|
INLINE void CollisionSolid::
|
||
|
mark_internal_bounds_stale() {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
_flags |= F_internal_bounds_stale;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called internally when the visualization may have been compromised by some
|
||
|
* change to internal state and will need to be recomputed the next time it is
|
||
|
* rendered.
|
||
|
*/
|
||
|
INLINE void CollisionSolid::
|
||
|
mark_viz_stale() {
|
||
|
LightMutexHolder holder(_lock);
|
||
|
_flags |= F_viz_geom_stale;
|
||
|
}
|