mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
Fix bug with Collide flag "polyset" and nested <Transform> elements
This commit is contained in:
parent
46ddd46c5c
commit
8dbe681143
@ -144,15 +144,19 @@ test_intersection(const CollisionEntry &entry) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CollisionBox::
|
||||
xform(const LMatrix4 &mat) {
|
||||
_min = _min * mat;
|
||||
_max = _max * mat;
|
||||
_center = _center * mat;
|
||||
for(int v = 0; v < 8; v++)
|
||||
for(int v = 0; v < 8; v++) {
|
||||
_vertex[v] = _vertex[v] * mat;
|
||||
for(int p = 0; p < 6 ; p++)
|
||||
}
|
||||
for(int p = 0; p < 6 ; p++) {
|
||||
_planes[p] = set_plane(p);
|
||||
_x = _vertex[0].get_x()-_center.get_x();
|
||||
_y = _vertex[0].get_y()-_center.get_y();
|
||||
_z = _vertex[0].get_z()-_center.get_z();
|
||||
_radius = sqrt( _x*_x + _y*_y + _z*_z );
|
||||
}
|
||||
_x = _vertex[0].get_x() - _center.get_x();
|
||||
_y = _vertex[0].get_y() - _center.get_y();
|
||||
_z = _vertex[0].get_z() - _center.get_z();
|
||||
_radius = sqrt(_x * _x + _y * _y + _z * _z);
|
||||
setup_box();
|
||||
mark_viz_stale();
|
||||
mark_internal_bounds_stale();
|
||||
|
@ -1865,6 +1865,10 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
|
||||
node = new CollisionNode(egg_group->get_name());
|
||||
|
||||
make_collision_solids(egg_group, egg_group, (CollisionNode *)node.p());
|
||||
|
||||
// Transform all of the collision solids into local space.
|
||||
node->xform(LCAST(PN_stdfloat, egg_group->get_vertex_to_node()));
|
||||
|
||||
if ((egg_group->get_collide_flags() & EggGroup::CF_keep) != 0) {
|
||||
// If we also specified to keep the geometry, continue the
|
||||
// traversal. In this case, we create a new PandaNode to be the
|
||||
@ -1925,8 +1929,11 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
|
||||
pnode->set_pos(center);
|
||||
pnode->set_color(color);
|
||||
pnode->set_radius(radius);
|
||||
|
||||
pnode->xform(LCAST(PN_stdfloat, egg_group->get_vertex_to_node()));
|
||||
|
||||
node = pnode;
|
||||
|
||||
|
||||
} else if (egg_group->get_switch_flag()) {
|
||||
if (egg_group->get_switch_fps() != 0.0) {
|
||||
// Create a sequence node.
|
||||
@ -2790,7 +2797,6 @@ find_first_polygon(EggGroup *egg_group) {
|
||||
bool EggLoader::
|
||||
make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
|
||||
LPoint3 ¢er, PN_stdfloat &radius, LColor &color) {
|
||||
bool success=false;
|
||||
EggGroup *geom_group = find_collision_geometry(egg_group, flags);
|
||||
if (geom_group != (EggGroup *)NULL) {
|
||||
// Collect all of the vertices.
|
||||
@ -2822,15 +2828,12 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
|
||||
d_center /= (double)num_vertices;
|
||||
//egg2pg_cat.debug() << "make_sphere d_center: " << d_center << "\n";
|
||||
|
||||
LMatrix4d mat = egg_group->get_vertex_to_node();
|
||||
d_center = d_center * mat;
|
||||
|
||||
// And the furthest vertex determines the radius.
|
||||
double radius2 = 0.0;
|
||||
for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
|
||||
EggVertex *vtx = (*vi);
|
||||
LPoint3d p3 = vtx->get_pos3();
|
||||
LVector3d v = p3 * mat - d_center;
|
||||
LVector3d v = p3 - d_center;
|
||||
radius2 = max(radius2, v.length_squared());
|
||||
}
|
||||
|
||||
@ -2841,10 +2844,10 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
|
||||
vi = vertices.begin();
|
||||
EggVertex *clr_vtx = (*vi);
|
||||
color = clr_vtx->get_color();
|
||||
success = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -2900,9 +2903,8 @@ make_box(EggGroup *egg_group, EggGroup::CollideFlags flags,
|
||||
max(max_pd[2], pos[2]));
|
||||
}
|
||||
|
||||
LMatrix4d mat = egg_group->get_vertex_to_node();
|
||||
min_p = LCAST(PN_stdfloat, min_pd * mat);
|
||||
max_p = LCAST(PN_stdfloat, max_pd * mat);
|
||||
min_p = LCAST(PN_stdfloat, min_pd);
|
||||
max_p = LCAST(PN_stdfloat, max_pd);
|
||||
return (min_pd != max_pd);
|
||||
}
|
||||
return false;
|
||||
@ -3170,7 +3172,6 @@ make_collision_tube(EggGroup *egg_group, CollisionNode *cnode,
|
||||
// also determine the centroid). We compute this in node space.
|
||||
size_t num_vertices = vertices.size();
|
||||
if (num_vertices != 0) {
|
||||
LMatrix4d mat = egg_group->get_vertex_to_node();
|
||||
pvector<LPoint3d> vpos;
|
||||
vpos.reserve(num_vertices);
|
||||
|
||||
@ -3178,7 +3179,7 @@ make_collision_tube(EggGroup *egg_group, CollisionNode *cnode,
|
||||
pset<EggVertex *>::const_iterator vi;
|
||||
for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
|
||||
EggVertex *vtx = (*vi);
|
||||
LPoint3d pos = vtx->get_pos3() * mat;
|
||||
const LPoint3d &pos = vtx->get_pos3();
|
||||
vpos.push_back(pos);
|
||||
center += pos;
|
||||
}
|
||||
@ -3420,20 +3421,18 @@ create_collision_plane(EggPolygon *egg_poly, EggGroup *parent_group) {
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
LMatrix4d mat = egg_poly->get_vertex_to_node();
|
||||
|
||||
pvector<LVertex> vertices;
|
||||
if (!egg_poly->empty()) {
|
||||
EggPolygon::const_iterator vi;
|
||||
vi = egg_poly->begin();
|
||||
|
||||
LVertexd vert = (*vi)->get_pos3() * mat;
|
||||
LVertexd vert = (*vi)->get_pos3();
|
||||
vertices.push_back(LCAST(PN_stdfloat, vert));
|
||||
|
||||
LVertexd last_vert = vert;
|
||||
++vi;
|
||||
while (vi != egg_poly->end()) {
|
||||
vert = (*vi)->get_pos3() * mat;
|
||||
vert = (*vi)->get_pos3();
|
||||
if (!vert.almost_equal(last_vert)) {
|
||||
vertices.push_back(LCAST(PN_stdfloat, vert));
|
||||
}
|
||||
@ -3461,7 +3460,6 @@ void EggLoader::
|
||||
create_collision_polygons(CollisionNode *cnode, EggPolygon *egg_poly,
|
||||
EggGroup *parent_group,
|
||||
EggGroup::CollideFlags flags) {
|
||||
LMatrix4d mat = egg_poly->get_vertex_to_node();
|
||||
|
||||
PT(EggGroup) group = new EggGroup;
|
||||
|
||||
@ -3489,13 +3487,13 @@ create_collision_polygons(CollisionNode *cnode, EggPolygon *egg_poly,
|
||||
EggPolygon::const_iterator vi;
|
||||
vi = poly->begin();
|
||||
|
||||
LVertexd vert = (*vi)->get_pos3() * mat;
|
||||
LVertexd vert = (*vi)->get_pos3();
|
||||
vertices.push_back(LCAST(PN_stdfloat, vert));
|
||||
|
||||
LVertexd last_vert = vert;
|
||||
++vi;
|
||||
while (vi != poly->end()) {
|
||||
vert = (*vi)->get_pos3() * mat;
|
||||
vert = (*vi)->get_pos3();
|
||||
if (!vert.almost_equal(last_vert)) {
|
||||
vertices.push_back(LCAST(PN_stdfloat, vert));
|
||||
}
|
||||
@ -3513,12 +3511,11 @@ create_collision_polygons(CollisionNode *cnode, EggPolygon *egg_poly,
|
||||
if (cspoly->is_valid()) {
|
||||
apply_collision_flags(cspoly, flags);
|
||||
cnode->add_solid(cspoly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLoader::create_collision_floor_mesh
|
||||
// Access: Private
|
||||
|
@ -85,11 +85,10 @@ disable(){
|
||||
// Description: Set this light's position
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PolylightNode::
|
||||
set_pos(const LVecBase3 &position){
|
||||
set_pos(const LPoint3 &position) {
|
||||
_position = position;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PolylightNode::set_pos
|
||||
// Access: Published
|
||||
@ -107,7 +106,7 @@ set_pos(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z){
|
||||
// Access: Published
|
||||
// Description: Returns position as a LPoint3
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LVecBase3 PolylightNode::
|
||||
INLINE LPoint3 PolylightNode::
|
||||
get_pos() const {
|
||||
return _position;
|
||||
}
|
||||
|
@ -65,6 +65,30 @@ make_copy() const {
|
||||
return new PolylightNode(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PolylightNode::xform
|
||||
// Access: Public, Virtual
|
||||
// Description: Transforms the contents of this node by the indicated
|
||||
// matrix, if it means anything to do so. For most
|
||||
// kinds of nodes, this does nothing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PolylightNode::
|
||||
xform(const LMatrix4 &mat) {
|
||||
nassertv(!mat.is_nan());
|
||||
|
||||
if (mat.almost_equal(LMatrix4::ident_mat())) {
|
||||
return;
|
||||
}
|
||||
|
||||
_position = _position * mat;
|
||||
|
||||
// This is a little cheesy and fails miserably in the presence of a
|
||||
// non-uniform scale.
|
||||
LVector3 radius_v = LVector3(_radius, 0.0f, 0.0f) * mat;
|
||||
_radius = length(radius_v);
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PolylightNode::Constructor
|
||||
// Access: Public
|
||||
|
@ -58,9 +58,9 @@ PUBLISHED:
|
||||
PolylightNode(const string &name);
|
||||
INLINE void enable();
|
||||
INLINE void disable();
|
||||
INLINE void set_pos(const LVecBase3 &position);
|
||||
INLINE void set_pos(const LPoint3 &position);
|
||||
INLINE void set_pos(PN_stdfloat x,PN_stdfloat y, PN_stdfloat z);
|
||||
INLINE LVecBase3 get_pos() const;
|
||||
INLINE LPoint3 get_pos() const;
|
||||
INLINE void set_color(const LColor &color);
|
||||
INLINE void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b);
|
||||
INLINE LColor get_color() const;
|
||||
@ -100,11 +100,11 @@ PUBLISHED:
|
||||
public:
|
||||
LColor flicker() const;
|
||||
virtual PandaNode *make_copy() const;
|
||||
virtual void xform(const LMatrix4 &mat);
|
||||
|
||||
|
||||
private:
|
||||
bool _enabled;
|
||||
LVecBase3 _position;
|
||||
LPoint3 _position;
|
||||
LColor _color;
|
||||
PN_stdfloat _radius;
|
||||
Attenuation_Type _attenuation_type;
|
||||
|
Loading…
x
Reference in New Issue
Block a user