add CollisionSolid::set_effective_normal

This commit is contained in:
David Rose 2003-11-11 05:24:56 +00:00
parent bfd4e276c3
commit 2536db25f4
15 changed files with 176 additions and 100 deletions

View File

@ -54,8 +54,7 @@ make_copy() {
void CollisionPlane:: void CollisionPlane::
xform(const LMatrix4f &mat) { xform(const LMatrix4f &mat) {
_plane = _plane * mat; _plane = _plane * mat;
mark_viz_stale(); CollisionSolid::xform(mat);
mark_bound_stale();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -130,7 +129,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
LVector3f from_normal = get_normal() * entry.get_inv_wrt_mat(); LVector3f from_normal = get_normal() * entry.get_inv_wrt_mat();
new_entry->set_surface_normal(get_normal()); new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : get_normal());
new_entry->set_surface_point(from_center - get_normal() * dist); new_entry->set_surface_point(from_center - get_normal() * dist);
new_entry->set_interior_point(from_center - get_normal() * from_radius); new_entry->set_interior_point(from_center - get_normal() * from_radius);
@ -171,7 +170,7 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
PT(CollisionEntry) new_entry = new CollisionEntry(entry); PT(CollisionEntry) new_entry = new CollisionEntry(entry);
LPoint3f into_intersection_point = from_origin + t * from_direction; LPoint3f into_intersection_point = from_origin + t * from_direction;
new_entry->set_surface_normal(get_normal()); new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : get_normal());
new_entry->set_surface_point(into_intersection_point); new_entry->set_surface_point(into_intersection_point);
return new_entry; return new_entry;

View File

@ -228,8 +228,7 @@ xform(const LMatrix4f &mat) {
setup_points(verts_begin, verts_end); setup_points(verts_begin, verts_end);
} }
mark_viz_stale(); CollisionSolid::xform(mat);
mark_bound_stale();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -513,7 +512,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
into_depth = from_radius - dist_to_plane(orig_center); into_depth = from_radius - dist_to_plane(orig_center);
} }
new_entry->set_surface_normal(get_normal()); new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : get_normal());
new_entry->set_surface_point(from_center - get_normal() * dist); new_entry->set_surface_point(from_center - get_normal() * dist);
new_entry->set_interior_point(from_center - get_normal() * (dist + into_depth)); new_entry->set_interior_point(from_center - get_normal() * (dist + into_depth));
@ -581,7 +580,7 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
} }
PT(CollisionEntry) new_entry = new CollisionEntry(entry); PT(CollisionEntry) new_entry = new CollisionEntry(entry);
new_entry->set_surface_normal(get_normal()); new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : get_normal());
new_entry->set_surface_point(plane_point); new_entry->set_surface_point(plane_point);
return new_entry; return new_entry;
@ -650,7 +649,7 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
} }
PT(CollisionEntry) new_entry = new CollisionEntry(entry); PT(CollisionEntry) new_entry = new CollisionEntry(entry);
new_entry->set_surface_normal(get_normal()); new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : get_normal());
new_entry->set_surface_point(plane_point); new_entry->set_surface_point(plane_point);
return new_entry; return new_entry;

View File

@ -63,8 +63,8 @@ void CollisionRay::
xform(const LMatrix4f &mat) { xform(const LMatrix4f &mat) {
_origin = _origin * mat; _origin = _origin * mat;
_direction = _direction * mat; _direction = _direction * mat;
mark_viz_stale();
mark_bound_stale(); CollisionSolid::xform(mat);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -65,8 +65,8 @@ void CollisionSegment::
xform(const LMatrix4f &mat) { xform(const LMatrix4f &mat) {
_a = _a * mat; _a = _a * mat;
_b = _b * mat; _b = _b * mat;
mark_viz_stale();
mark_bound_stale(); CollisionSolid::xform(mat);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -19,7 +19,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::set_tangible // Function: CollisionSolid::set_tangible
// Access: Public // Access: Published
// Description: Sets the current state of the 'tangible' flag. Set // Description: Sets the current state of the 'tangible' flag. Set
// this true to make the solid tangible, so that a // this true to make the solid tangible, so that a
// CollisionHandlerPusher will not allow another object // CollisionHandlerPusher will not allow another object
@ -29,15 +29,17 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void CollisionSolid:: INLINE void CollisionSolid::
set_tangible(bool tangible) { set_tangible(bool tangible) {
if (tangible != _tangible) { if (tangible) {
_tangible = tangible; _flags |= F_tangible;
mark_viz_stale(); } else {
_flags &= ~F_tangible;
} }
mark_viz_stale();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::is_tangible // Function: CollisionSolid::is_tangible
// Access: Public // Access: Published
// Description: Returns whether the solid is considered 'tangible' or // Description: Returns whether the solid is considered 'tangible' or
// not. An intangible solid has no effect in a // not. An intangible solid has no effect in a
// CollisionHandlerPusher (except to throw an event); // CollisionHandlerPusher (except to throw an event);
@ -46,7 +48,60 @@ set_tangible(bool tangible) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE bool CollisionSolid:: INLINE bool CollisionSolid::
is_tangible() const { is_tangible() const {
return _tangible; return (_flags & F_tangible) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::set_effective_normal
// Access: Published
// Description: 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 LVector3f &effective_normal) {
_effective_normal = effective_normal;
_flags |= F_effective_normal;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::clear_effective_normal
// Access: Published
// Description: Removes the normal previously set by
// set_effective_normal().
////////////////////////////////////////////////////////////////////
INLINE void CollisionSolid::
clear_effective_normal() {
_flags &= ~F_effective_normal;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::has_effective_normal
// Access: Published
// Description: Returns true if a special normal was set by
// set_effective_normal(), false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionSolid::
has_effective_normal() const {
return (_flags & F_effective_normal) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::get_effective_normal
// Access: Published
// Description: 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 LVector3f &CollisionSolid::
get_effective_normal() const {
nassertr(has_effective_normal(), LVector3f::zero());
return _effective_normal;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -59,5 +114,5 @@ is_tangible() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void CollisionSolid:: INLINE void CollisionSolid::
mark_viz_stale() { mark_viz_stale() {
_viz_geom_stale = true; _flags |= F_viz_geom_stale;
} }

View File

@ -16,7 +16,6 @@
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include "collisionSolid.h" #include "collisionSolid.h"
#include "config_collide.h" #include "config_collide.h"
#include "collisionSphere.h" #include "collisionSphere.h"
@ -43,8 +42,7 @@ TypeHandle CollisionSolid::_type_handle;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CollisionSolid:: CollisionSolid::
CollisionSolid() { CollisionSolid() {
_viz_geom_stale = true; _flags = F_viz_geom_stale | F_tangible;
_tangible = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -54,10 +52,10 @@ CollisionSolid() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CollisionSolid:: CollisionSolid::
CollisionSolid(const CollisionSolid &copy) : CollisionSolid(const CollisionSolid &copy) :
_tangible(copy._tangible) _effective_normal(copy._effective_normal),
_flags(copy._flags)
{ {
// Actually, there's not a whole lot here we want to copy. _flags &= ~F_viz_geom_stale;
_viz_geom_stale = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -84,6 +82,21 @@ test_intersection(const CollisionEntry &) const {
return NULL; return NULL;
} }
////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::xform
// Access: Public, Virtual
// Description: Transforms the solid by the indicated matrix.
////////////////////////////////////////////////////////////////////
void CollisionSolid::
xform(const LMatrix4f &mat) {
if (has_effective_normal()) {
_effective_normal = _effective_normal * mat;
}
mark_viz_stale();
mark_bound_stale();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionSolid::get_viz // Function: CollisionSolid::get_viz
// Access: Public, Virtual // Access: Public, Virtual
@ -94,14 +107,14 @@ test_intersection(const CollisionEntry &) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
PT(PandaNode) CollisionSolid:: PT(PandaNode) CollisionSolid::
get_viz(const CullTraverserData &) const { get_viz(const CullTraverserData &) const {
if (_viz_geom_stale) { if ((_flags & F_viz_geom_stale) != 0) {
if (_viz_geom == (GeomNode *)NULL) { if (_viz_geom == (GeomNode *)NULL) {
((CollisionSolid *)this)->_viz_geom = new GeomNode("viz"); ((CollisionSolid *)this)->_viz_geom = new GeomNode("viz");
} else { } else {
_viz_geom->remove_all_geoms(); _viz_geom->remove_all_geoms();
} }
((CollisionSolid *)this)->fill_viz_geom(); ((CollisionSolid *)this)->fill_viz_geom();
((CollisionSolid *)this)->_viz_geom_stale = false; ((CollisionSolid *)this)->_flags &= ~F_viz_geom_stale;
} }
return _viz_geom.p(); return _viz_geom.p();
} }
@ -246,9 +259,13 @@ report_undefined_from_intersection(TypeHandle from_type) {
// the particular object to a Datagram // the particular object to a Datagram
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionSolid:: void CollisionSolid::
write_datagram(BamWriter *, Datagram &me) write_datagram(BamWriter *, Datagram &me) {
{ // For now, we need only 8 bits of flags. If we need to expand this
me.add_uint8(_tangible); // later, we will have to increase the bam version.
me.add_uint8(_flags);
if ((_flags & F_effective_normal) != 0) {
_effective_normal.write_datagram(me);
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -260,9 +277,11 @@ write_datagram(BamWriter *, Datagram &me)
// place // place
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionSolid:: void CollisionSolid::
fillin(DatagramIterator& scan, BamReader*) fillin(DatagramIterator &scan, BamReader*) {
{ _flags = scan.get_uint8();
_tangible = (scan.get_uint8() != 0); if ((_flags & F_effective_normal) != 0) {
_effective_normal.read_datagram(scan);
}
} }
@ -296,21 +315,29 @@ get_solid_viz_state() {
TransparencyAttrib::make(TransparencyAttrib::M_alpha)); TransparencyAttrib::make(TransparencyAttrib::M_alpha));
} }
if (_tangible) { if (!is_tangible()) {
static CPT(RenderState) tangible_state = (const RenderState *)NULL;
if (tangible_state == (const RenderState *)NULL) {
tangible_state = base_state->add_attrib
(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 0.5f)));
}
return tangible_state;
} else {
static CPT(RenderState) intangible_state = (const RenderState *)NULL; static CPT(RenderState) intangible_state = (const RenderState *)NULL;
if (intangible_state == (const RenderState *)NULL) { if (intangible_state == (const RenderState *)NULL) {
intangible_state = base_state->add_attrib intangible_state = base_state->add_attrib
(ColorAttrib::make_flat(Colorf(1.0f, 0.3f, 0.5f, 0.5f))); (ColorAttrib::make_flat(Colorf(1.0f, 0.3f, 0.5f, 0.5f)));
} }
return intangible_state; return intangible_state;
} else if (has_effective_normal()) {
static CPT(RenderState) fakenormal_state = (const RenderState *)NULL;
if (fakenormal_state == (const RenderState *)NULL) {
fakenormal_state = base_state->add_attrib
(ColorAttrib::make_flat(Colorf(0.5f, 0.5f, 1.0f, 0.5f)));
}
return fakenormal_state;
} else {
static CPT(RenderState) tangible_state = (const RenderState *)NULL;
if (tangible_state == (const RenderState *)NULL) {
tangible_state = base_state->add_attrib
(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 0.5f)));
}
return tangible_state;
} }
} }
@ -335,7 +362,7 @@ get_wireframe_viz_state() {
TransparencyAttrib::make(TransparencyAttrib::M_none)); TransparencyAttrib::make(TransparencyAttrib::M_none));
} }
if (_tangible) { if (is_tangible()) {
static CPT(RenderState) tangible_state = (const RenderState *)NULL; static CPT(RenderState) tangible_state = (const RenderState *)NULL;
if (tangible_state == (const RenderState *)NULL) { if (tangible_state == (const RenderState *)NULL) {
tangible_state = base_state->add_attrib tangible_state = base_state->add_attrib

View File

@ -62,11 +62,16 @@ PUBLISHED:
INLINE void set_tangible(bool tangible); INLINE void set_tangible(bool tangible);
INLINE bool is_tangible() const; INLINE bool is_tangible() const;
INLINE void set_effective_normal(const LVector3f &effective_normal);
INLINE void clear_effective_normal();
INLINE bool has_effective_normal() const;
INLINE const LVector3f &get_effective_normal() const;
public: public:
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection(const CollisionEntry &entry) const; test_intersection(const CollisionEntry &entry) const;
virtual void xform(const LMatrix4f &mat)=0; virtual void xform(const LMatrix4f &mat);
virtual PT(PandaNode) get_viz(const CullTraverserData &data) const; virtual PT(PandaNode) get_viz(const CullTraverserData &data) const;
@ -94,8 +99,16 @@ protected:
CPT(RenderState) get_other_viz_state(); CPT(RenderState) get_other_viz_state();
PT(GeomNode) _viz_geom; PT(GeomNode) _viz_geom;
bool _viz_geom_stale;
bool _tangible; private:
LVector3f _effective_normal;
enum Flags {
F_tangible = 0x01,
F_effective_normal = 0x02,
F_viz_geom_stale = 0x04,
};
int _flags;
public: public:
virtual void write_datagram(BamWriter* manager, Datagram &me); virtual void write_datagram(BamWriter* manager, Datagram &me);

View File

@ -67,7 +67,6 @@ xform(const LMatrix4f &mat) {
// non-uniform scale. // non-uniform scale.
LVector3f radius_v = LVector3f(_radius, 0.0f, 0.0f) * mat; LVector3f radius_v = LVector3f(_radius, 0.0f, 0.0f) * mat;
_radius = length(radius_v); _radius = length(radius_v);
mark_viz_stale(); mark_viz_stale();
mark_bound_stale(); mark_bound_stale();
} }
@ -156,7 +155,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
surface_normal = vec / vec_length; surface_normal = vec / vec_length;
} }
new_entry->set_surface_normal(surface_normal); new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : surface_normal);
new_entry->set_surface_point(into_center + surface_normal * into_radius); new_entry->set_surface_point(into_center + surface_normal * into_radius);
new_entry->set_interior_point(from_center - surface_normal * from_radius); new_entry->set_interior_point(from_center - surface_normal * from_radius);

View File

@ -62,6 +62,7 @@ xform(const LMatrix4f &mat) {
_radius = length(radius_v); _radius = length(radius_v);
recalc_internals(); recalc_internals();
CollisionSolid::xform(mat);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -367,9 +368,6 @@ recalc_internals() {
look_at(_mat, direction, LVector3f(0.0f, 0.0f, 1.0f), CS_zup_right); look_at(_mat, direction, LVector3f(0.0f, 0.0f, 1.0f), CS_zup_right);
_mat.set_row(3, _a); _mat.set_row(3, _a);
_inv_mat.invert_from(_mat); _inv_mat.invert_from(_mat);
mark_viz_stale();
mark_bound_stale();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -693,8 +691,8 @@ set_intersection_point(CollisionEntry *new_entry,
// our collision was tangential. // our collision was tangential.
LPoint3f orig_point = into_intersection_point - normal * extra_radius; LPoint3f orig_point = into_intersection_point - normal * extra_radius;
new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : normal);
new_entry->set_surface_point(point); new_entry->set_surface_point(point);
new_entry->set_surface_normal(normal);
new_entry->set_interior_point(orig_point); new_entry->set_interior_point(orig_point);
} }

View File

@ -146,19 +146,20 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
const CollisionSolid *solid = (*si).first; const CollisionSolid *solid = (*si).first;
const SolidInfo &solid_info = (*si).second; const SolidInfo &solid_info = (*si).second;
PT(PandaNode) node = solid->get_viz(xform_data); PT(PandaNode) node = solid->get_viz(xform_data);
if (node != (PandaNode *)NULL) {
CullTraverserData next_data(xform_data, node);
CullTraverserData next_data(xform_data, node); // We don't want to inherit the render state from above for
// these guys. Instead, we choose the state according to
// whether a collision was detected or not.
if (solid_info._detected_count > 0) {
next_data._state = get_detected_state();
} else {
next_data._state = get_tested_state();
}
// We don't want to inherit the render state from above for trav->traverse(next_data);
// these guys. Instead, we choose the state according to
// whether a collision was detected or not.
if (solid_info._detected_count > 0) {
next_data._state = get_detected_state();
} else {
next_data._state = get_tested_state();
} }
trav->traverse(next_data);
} }
// Now draw all of the detected points. // Now draw all of the detected points.

View File

@ -971,19 +971,6 @@ GROUPING ENTRIES
The geometry represents a sphere. The vertices in the group are The geometry represents a sphere. The vertices in the group are
averaged together to determine the sphere's center and radius. averaged together to determine the sphere's center and radius.
InverseSphere
The geometry represents a sphere with the normal inverted, to
make a hollow spherical shell.
Geode
The geometry is not a collision surface after all, but is in
fact true geometry. This is intended to be used in conjunction
with one or more flags to define collision properties for normal
geometry.
The flags may be any zero or more of: The flags may be any zero or more of:
@ -1038,6 +1025,13 @@ GROUPING ENTRIES
can go forwards but not back. Presently, this is only can go forwards but not back. Presently, this is only
implemented for planes, polygons, and polysets. implemented for planes, polygons, and polysets.
level
Stores a special effective normal with the collision solid that
points up, regardless of the actual shape or orientation of the
solid. This can be used to allow an avatar to stand on a
sloping surface without having a tendency to slide downward.
<ObjectType> { type } <ObjectType> { type }

View File

@ -781,10 +781,6 @@ string_cs_type(const string &string) {
return CST_polyset; return CST_polyset;
} else if (cmp_nocase_uh(string, "sphere") == 0) { } else if (cmp_nocase_uh(string, "sphere") == 0) {
return CST_sphere; return CST_sphere;
} else if (cmp_nocase_uh(string, "inversesphere") == 0) {
return CST_inverse_sphere;
} else if (cmp_nocase_uh(string, "geode") == 0) {
return CST_geode;
} else if (cmp_nocase_uh(string, "tube") == 0) { } else if (cmp_nocase_uh(string, "tube") == 0) {
return CST_tube; return CST_tube;
} else { } else {
@ -817,6 +813,8 @@ string_collide_flags(const string &string) {
return CF_center; return CF_center;
} else if (cmp_nocase_uh(string, "turnstile") == 0) { } else if (cmp_nocase_uh(string, "turnstile") == 0) {
return CF_turnstile; return CF_turnstile;
} else if (cmp_nocase_uh(string, "level") == 0) {
return CF_level;
} else { } else {
return CF_none; return CF_none;
} }
@ -1155,10 +1153,6 @@ ostream &operator << (ostream &out, EggGroup::CollisionSolidType t) {
return out << "Polyset"; return out << "Polyset";
case EggGroup::CST_sphere: case EggGroup::CST_sphere:
return out << "Sphere"; return out << "Sphere";
case EggGroup::CST_inverse_sphere:
return out << "InverseSphere";
case EggGroup::CST_geode:
return out << "Geode";
case EggGroup::CST_tube: case EggGroup::CST_tube:
return out << "Tube"; return out << "Tube";
} }
@ -1206,5 +1200,9 @@ ostream &operator << (ostream &out, EggGroup::CollideFlags t) {
out << space << "turnstile"; out << space << "turnstile";
space = " "; space = " ";
} }
if (bits & EggGroup::CF_level) {
out << space << "level";
space = " ";
}
return out; return out;
} }

View File

@ -78,9 +78,7 @@ PUBLISHED:
CST_polygon = 0x00020000, CST_polygon = 0x00020000,
CST_polyset = 0x00030000, CST_polyset = 0x00030000,
CST_sphere = 0x00040000, CST_sphere = 0x00040000,
CST_inverse_sphere = 0x00050000, CST_tube = 0x00050000,
CST_geode = 0x00060000,
CST_tube = 0x00070000,
}; };
enum CollideFlags { enum CollideFlags {
// The bits here must correspond to those in Flags, below. // The bits here must correspond to those in Flags, below.
@ -92,6 +90,7 @@ PUBLISHED:
CF_solid = 0x00800000, CF_solid = 0x00800000,
CF_center = 0x01000000, CF_center = 0x01000000,
CF_turnstile = 0x02000000, CF_turnstile = 0x02000000,
CF_level = 0x04000000,
}; };
EggGroup(const string &name = ""); EggGroup(const string &name = "");
@ -256,7 +255,7 @@ private:
F_decal_flag = 0x00002000, F_decal_flag = 0x00002000,
F_direct_flag = 0x00004000, F_direct_flag = 0x00004000,
F_cs_type = 0x00070000, F_cs_type = 0x00070000,
F_collide_flags = 0x03f80000, F_collide_flags = 0x07f80000,
}; };
enum Flags2 { enum Flags2 {
F2_collide_mask = 0x00000001, F2_collide_mask = 0x00000001,

View File

@ -1555,8 +1555,7 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
CharacterMaker char_maker(egg_group, *this); CharacterMaker char_maker(egg_group, *this);
node = char_maker.make_node(); node = char_maker.make_node();
} else if (egg_group->get_cs_type() != EggGroup::CST_none && } else if (egg_group->get_cs_type() != EggGroup::CST_none) {
egg_group->get_cs_type() != EggGroup::CST_geode) {
// A collision group: create collision geometry. // A collision group: create collision geometry.
node = new CollisionNode(egg_group->get_name()); node = new CollisionNode(egg_group->get_name());
@ -1771,18 +1770,9 @@ make_collision_solids(EggGroup *start_group, EggGroup *egg_group,
switch (start_group->get_cs_type()) { switch (start_group->get_cs_type()) {
case EggGroup::CST_none: case EggGroup::CST_none:
case EggGroup::CST_geode:
// No collision flags; do nothing. Don't even traverse further. // No collision flags; do nothing. Don't even traverse further.
return; return;
case EggGroup::CST_inverse_sphere:
// These aren't presently supported.
egg2pg_cat.error()
<< "Not presently supported: <Collide> { "
<< egg_group->get_cs_type() << " }\n";
_error = true;
break;
case EggGroup::CST_plane: case EggGroup::CST_plane:
make_collision_plane(egg_group, cnode, start_group->get_collide_flags()); make_collision_plane(egg_group, cnode, start_group->get_collide_flags());
break; break;
@ -2159,6 +2149,9 @@ apply_collision_flags(CollisionSolid *solid,
if ((flags & EggGroup::CF_intangible) != 0) { if ((flags & EggGroup::CF_intangible) != 0) {
solid->set_tangible(false); solid->set_tangible(false);
} }
if ((flags & EggGroup::CF_level) != 0) {
solid->set_effective_normal(LVector3f::up());
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -34,13 +34,14 @@ static const unsigned short _bam_major_ver = 4;
// Bumped to major version 3 on 12/8/00 to change float64's to float32's. // Bumped to major version 3 on 12/8/00 to change float64's to float32's.
// Bumped to major version 4 on 4/10/02 to store new scene graph. // Bumped to major version 4 on 4/10/02 to store new scene graph.
static const unsigned short _bam_minor_ver = 6; static const unsigned short _bam_minor_ver = 7;
// Bumped to minor version 1 on 4/10/03 to add CullFaceAttrib::reverse. // Bumped to minor version 1 on 4/10/03 to add CullFaceAttrib::reverse.
// Bumped to minor version 2 on 4/12/03 to add num_components to texture. // Bumped to minor version 2 on 4/12/03 to add num_components to texture.
// Bumped to minor version 3 on 4/15/03 to add ImageBuffer::_alpha_file_channel // Bumped to minor version 3 on 4/15/03 to add ImageBuffer::_alpha_file_channel
// Bumped to minor version 4 on 6/12/03 to add PandaNode::set_tag(). // Bumped to minor version 4 on 6/12/03 to add PandaNode::set_tag().
// Bumped to minor version 5 on 7/09/03 to add rawdata mode to texture. // Bumped to minor version 5 on 7/09/03 to add rawdata mode to texture.
// Bumped to minor version 6 on 7/22/03 to add shear to scene graph and animation data. // Bumped to minor version 6 on 7/22/03 to add shear to scene graph and animation data.
// Bumped to minor version 7 on 11/10/03 to add CollisionSolid::_effective_normal
#endif #endif