Fix incorrect transformation of CollisionBox loaded from .egg file

This commit is contained in:
rdb 2015-02-09 20:43:04 +01:00
parent bd7d86ba9e
commit 79d025e9a8
2 changed files with 74 additions and 46 deletions

View File

@ -29,7 +29,7 @@
#include "cmath.h" #include "cmath.h"
#include "mathNumbers.h" #include "mathNumbers.h"
#include "geom.h" #include "geom.h"
#include "geomTrifans.h" #include "geomTriangles.h"
#include "geomVertexWriter.h" #include "geomVertexWriter.h"
#include "config_mathutil.h" #include "config_mathutil.h"
#include "dcast.h" #include "dcast.h"
@ -80,7 +80,7 @@ setup_box(){
// Function: CollisionBox::setup_points // Function: CollisionBox::setup_points
// Access: Private // Access: Private
// Description: Computes the plane and 2d projection of points that // Description: Computes the plane and 2d projection of points that
// make up this side // make up this side.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionBox:: void CollisionBox::
setup_points(const LPoint3 *begin, const LPoint3 *end, int plane) { setup_points(const LPoint3 *begin, const LPoint3 *end, int plane) {
@ -552,7 +552,7 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
PN_stdfloat near_t = 0.0; PN_stdfloat near_t = 0.0;
bool intersect; bool intersect;
LPlane plane; LPlane plane;
LPlane near_plane; LPlane near_plane;
//Returns the details about the first plane of the box that the //Returns the details about the first plane of the box that the
//segment intersects. //segment intersects.
@ -589,7 +589,6 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
} }
++j; ++j;
} }
if(!intersect) { if(!intersect) {
//No intersection with ANY of the box's planes has been detected //No intersection with ANY of the box's planes has been detected
@ -645,22 +644,50 @@ fill_viz_geom() {
PT(GeomVertexData) vdata = new GeomVertexData PT(GeomVertexData) vdata = new GeomVertexData
("collision", GeomVertexFormat::get_v3(), ("collision", GeomVertexFormat::get_v3(),
Geom::UH_static); Geom::UH_static);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
for(int i = 0; i < 6; i++) {
for(int j = 0; j < 4; j++)
vertex.add_data3(get_point(plane_def[i][j]));
PT(GeomTrifans) body = new GeomTrifans(Geom::UH_static); vdata->unclean_set_num_rows(8);
body->add_consecutive_vertices(i*4, 4);
body->close_primitive();
PT(Geom) geom = new Geom(vdata); {
geom->add_primitive(body); GeomVertexWriter vertex(vdata, InternalName::get_vertex());
vertex.set_data3(_min[0], _min[1], _min[2]);
vertex.set_data3(_min[0], _max[1], _min[2]);
vertex.set_data3(_max[0], _max[1], _min[2]);
vertex.set_data3(_max[0], _min[1], _min[2]);
_viz_geom->add_geom(geom, get_solid_viz_state()); vertex.set_data3(_min[0], _min[1], _max[2]);
_bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state()); vertex.set_data3(_min[0], _max[1], _max[2]);
vertex.set_data3(_max[0], _max[1], _max[2]);
vertex.set_data3(_max[0], _min[1], _max[2]);
} }
PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static);
// Bottom
tris->add_vertices(0, 1, 2);
tris->add_vertices(2, 3, 0);
// Top
tris->add_vertices(4, 7, 6);
tris->add_vertices(6, 5, 4);
// Sides
tris->add_vertices(0, 4, 1);
tris->add_vertices(1, 4, 5);
tris->add_vertices(1, 5, 2);
tris->add_vertices(2, 5, 6);
tris->add_vertices(2, 6, 3);
tris->add_vertices(3, 6, 7);
tris->add_vertices(3, 7, 0);
tris->add_vertices(0, 7, 4);
PT(Geom) geom = new Geom(vdata);
geom->add_primitive(tris);
_viz_geom->add_geom(geom, get_solid_viz_state());
_bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -675,7 +702,7 @@ fill_viz_geom() {
// planes), or false otherwise. // planes), or false otherwise.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool CollisionBox:: bool CollisionBox::
apply_clip_plane(CollisionBox::Points &new_points, apply_clip_plane(CollisionBox::Points &new_points,
const ClipPlaneAttrib *cpa, const ClipPlaneAttrib *cpa,
const TransformState *net_transform, int plane_no) const { const TransformState *net_transform, int plane_no) const {
bool all_in = true; bool all_in = true;
@ -687,9 +714,9 @@ apply_clip_plane(CollisionBox::Points &new_points,
NodePath plane_path = cpa->get_on_plane(i); NodePath plane_path = cpa->get_on_plane(i);
PlaneNode *plane_node = DCAST(PlaneNode, plane_path.node()); PlaneNode *plane_node = DCAST(PlaneNode, plane_path.node());
if ((plane_node->get_clip_effect() & PlaneNode::CE_collision) != 0) { if ((plane_node->get_clip_effect() & PlaneNode::CE_collision) != 0) {
CPT(TransformState) new_transform = CPT(TransformState) new_transform =
net_transform->invert_compose(plane_path.get_net_transform()); net_transform->invert_compose(plane_path.get_net_transform());
LPlane plane = plane_node->get_plane() * new_transform->get_mat(); LPlane plane = plane_node->get_plane() * new_transform->get_mat();
if (first_plane) { if (first_plane) {
first_plane = false; first_plane = false;

View File

@ -2855,9 +2855,8 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
// This box is used by make_collision_box. // This box is used by make_collision_box.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool EggLoader:: bool EggLoader::
make_box(EggGroup *egg_group, EggGroup::CollideFlags flags, make_box(EggGroup *egg_group, EggGroup::CollideFlags flags,
LPoint3 &min_p, LPoint3 &max_p, LColor &color) { LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
bool success = false;
EggGroup *geom_group = find_collision_geometry(egg_group, flags); EggGroup *geom_group = find_collision_geometry(egg_group, flags);
if (geom_group != (EggGroup *)NULL) { if (geom_group != (EggGroup *)NULL) {
// Collect all of the vertices. // Collect all of the vertices.
@ -2875,36 +2874,38 @@ make_box(EggGroup *egg_group, EggGroup::CollideFlags flags,
} }
// Now find the min/max points // Now find the min/max points
int num_vertices = 0;
bool first = true;
pset<EggVertex *>::const_iterator vi; pset<EggVertex *>::const_iterator vi;
for (vi = vertices.begin(); vi != vertices.end(); ++vi) { vi = vertices.begin();
EggVertex *vtx = (*vi);
LVertex pos = LCAST(PN_stdfloat, vtx->get_pos3());
if (first) { if (vi == vertices.end()) {
min_p.set(pos[0], pos[1], pos[2]); // No vertices, no bounding box.
max_p.set(pos[0], pos[1], pos[2]); min_p.set(0, 0, 0);
first = false; max_p.set(0, 0, 0);
} else { return false;
min_p.set(min(min_p[0], pos[0]),
min(min_p[1], pos[1]),
min(min_p[2], pos[2]));
max_p.set(max(max_p[0], pos[0]),
max(max_p[1], pos[1]),
max(max_p[2], pos[2]));
}
num_vertices++;
} }
if (num_vertices > 1) { EggVertex *vertex = (*vi);
vi = vertices.begin(); LVertexd min_pd = vertex->get_pos3();
EggVertex *clr_vtx = (*vi); LVertexd max_pd = min_pd;
color = clr_vtx->get_color(); color = vertex->get_color();
success = true;
for (++vi; vi != vertices.end(); ++vi) {
vertex = (*vi);
const LVertexd &pos = vertex->get_pos3();
min_pd.set(min(min_pd[0], pos[0]),
min(min_pd[1], pos[1]),
min(min_pd[2], pos[2]));
max_pd.set(max(max_pd[0], pos[0]),
max(max_pd[1], pos[1]),
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);
return (min_pd != max_pd);
} }
return success; return false;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////