mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -04:00
spheres and tubes working with fluid pusher
This commit is contained in:
parent
30f14e0b2c
commit
3d665f61e0
@ -330,8 +330,10 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||||||
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
|
LVector3f(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
|
||||||
float from_radius = length(from_radius_v);
|
float from_radius = length(from_radius_v);
|
||||||
|
|
||||||
LPoint3f into_intersection_point;
|
LPoint3f into_intersection_point(from_b);
|
||||||
double t1, t2;
|
double t1, t2;
|
||||||
|
LPoint3f contact_point(into_intersection_point);
|
||||||
|
float actual_t = 0.0f;
|
||||||
|
|
||||||
if (from_a != from_b) {
|
if (from_a != from_b) {
|
||||||
LVector3f from_direction = from_b - from_a;
|
LVector3f from_direction = from_b - from_a;
|
||||||
@ -346,6 +348,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual_t = min(1.0f, max(0.0f, t1));
|
||||||
|
contact_point = from_a + actual_t * (from_b - from_a);
|
||||||
|
|
||||||
if (t1 < 0.0) {
|
if (t1 < 0.0) {
|
||||||
// Point a is within the sphere. The first intersection point is
|
// Point a is within the sphere. The first intersection point is
|
||||||
// point a itself.
|
// point a itself.
|
||||||
@ -391,12 +396,24 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||||||
|
|
||||||
LVector3f eff_normal = (has_effective_normal() && sphere->get_respect_effective_normal()) ? get_effective_normal() : surface_normal;
|
LVector3f eff_normal = (has_effective_normal() && sphere->get_respect_effective_normal()) ? get_effective_normal() : surface_normal;
|
||||||
|
|
||||||
|
LVector3f contact_normal;
|
||||||
|
LVector3f v2 = contact_point - into_center;
|
||||||
|
float v2_len = v2.length();
|
||||||
|
if (IS_NEARLY_ZERO(v2_len)) {
|
||||||
|
// If we don't have a collision normal (e.g. the centers are
|
||||||
|
// exactly coincident), then make up an arbitrary normal--any one
|
||||||
|
// is as good as any other.
|
||||||
|
contact_normal.set(1.0, 0.0, 0.0);
|
||||||
|
} else {
|
||||||
|
contact_normal = v2 / v2_len;
|
||||||
|
}
|
||||||
|
|
||||||
new_entry->set_surface_normal(eff_normal);
|
new_entry->set_surface_normal(eff_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);
|
||||||
new_entry->set_contact_pos(into_intersection_point);
|
new_entry->set_contact_pos(contact_point);
|
||||||
new_entry->set_contact_normal(surface_normal);
|
new_entry->set_contact_normal(contact_normal);
|
||||||
new_entry->set_t(t1);
|
new_entry->set_t(actual_t);
|
||||||
|
|
||||||
return new_entry;
|
return new_entry;
|
||||||
}
|
}
|
||||||
|
@ -171,6 +171,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||||||
LPoint3f from_a = sphere->get_center() * wrt_mat;
|
LPoint3f from_a = sphere->get_center() * wrt_mat;
|
||||||
LPoint3f from_b = from_a;
|
LPoint3f from_b = from_a;
|
||||||
|
|
||||||
|
LPoint3f contact_point;
|
||||||
|
float actual_t = 0.0f;
|
||||||
|
|
||||||
if (wrt_prev_space != wrt_space) {
|
if (wrt_prev_space != wrt_space) {
|
||||||
// If the sphere is moving relative to the tube, it becomes a tube
|
// If the sphere is moving relative to the tube, it becomes a tube
|
||||||
// itself.
|
// itself.
|
||||||
@ -195,6 +198,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual_t = min(1.0f, max(0.0f, t1));
|
||||||
|
contact_point = from_a + actual_t * (from_b - from_a);
|
||||||
|
|
||||||
if (collide_cat.is_debug()) {
|
if (collide_cat.is_debug()) {
|
||||||
collide_cat.debug()
|
collide_cat.debug()
|
||||||
<< "intersection detected from " << entry.get_from_node_path() << " into "
|
<< "intersection detected from " << entry.get_from_node_path() << " into "
|
||||||
@ -213,7 +219,16 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
|||||||
into_intersection_point = from_a + t1 * from_direction;
|
into_intersection_point = from_a + t1 * from_direction;
|
||||||
}
|
}
|
||||||
set_intersection_point(new_entry, into_intersection_point, from_radius);
|
set_intersection_point(new_entry, into_intersection_point, from_radius);
|
||||||
new_entry->set_t(t1);
|
|
||||||
|
LPoint3f fake_contact_point;
|
||||||
|
LVector3f contact_normal;
|
||||||
|
calculate_surface_point_and_normal(contact_point,
|
||||||
|
from_radius,
|
||||||
|
fake_contact_point,
|
||||||
|
contact_normal);
|
||||||
|
new_entry->set_contact_pos(contact_point);
|
||||||
|
new_entry->set_contact_normal(contact_normal);
|
||||||
|
new_entry->set_t(actual_t);
|
||||||
|
|
||||||
return new_entry;
|
return new_entry;
|
||||||
}
|
}
|
||||||
@ -758,19 +773,20 @@ sphere_intersects_line(double &t1, double &t2, float center_y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: CollisionTube::set_intersection_point
|
// Function: CollisionTube::calculate_surface_point_and_normal
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: After an intersection has been detected, record the
|
// Description: Calculates a point that is exactly on the surface
|
||||||
// computed intersection point in the CollisionEntry,
|
// of the tube and its corresponding normal, given
|
||||||
// and also compute the relevant normal based on that
|
// a point that is supposedly on the surface of the
|
||||||
// point.
|
// tube.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CollisionTube::
|
void CollisionTube::
|
||||||
set_intersection_point(CollisionEntry *new_entry,
|
calculate_surface_point_and_normal(const LPoint3f &surface_point,
|
||||||
const LPoint3f &into_intersection_point,
|
double extra_radius,
|
||||||
double extra_radius) const {
|
LPoint3f &result_point,
|
||||||
|
LVector3f &result_normal) const {
|
||||||
// Convert the point into our canonical space for analysis.
|
// Convert the point into our canonical space for analysis.
|
||||||
LPoint3f point = into_intersection_point * _inv_mat;
|
LPoint3f point = surface_point * _inv_mat;
|
||||||
LVector3f normal;
|
LVector3f normal;
|
||||||
|
|
||||||
if (point[1] <= 0.0) {
|
if (point[1] <= 0.0) {
|
||||||
@ -801,10 +817,29 @@ set_intersection_point(CollisionEntry *new_entry,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now convert the point and normal back into real space.
|
// Now convert the point and normal back into real space.
|
||||||
point = point * _mat;
|
result_point = point * _mat;
|
||||||
normal = normal * _mat;
|
result_normal = normal * _mat;
|
||||||
|
}
|
||||||
|
|
||||||
LVector3f contact_normal(normal);
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CollisionTube::set_intersection_point
|
||||||
|
// Access: Private
|
||||||
|
// Description: After an intersection has been detected, record the
|
||||||
|
// computed intersection point in the CollisionEntry,
|
||||||
|
// and also compute the relevant normal based on that
|
||||||
|
// point.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CollisionTube::
|
||||||
|
set_intersection_point(CollisionEntry *new_entry,
|
||||||
|
const LPoint3f &into_intersection_point,
|
||||||
|
double extra_radius) const {
|
||||||
|
LPoint3f point;
|
||||||
|
LVector3f normal;
|
||||||
|
|
||||||
|
calculate_surface_point_and_normal(into_intersection_point,
|
||||||
|
extra_radius,
|
||||||
|
point,
|
||||||
|
normal);
|
||||||
|
|
||||||
if (has_effective_normal() && new_entry->get_from()->get_respect_effective_normal()) {
|
if (has_effective_normal() && new_entry->get_from()->get_respect_effective_normal()) {
|
||||||
normal = get_effective_normal();
|
normal = get_effective_normal();
|
||||||
@ -816,8 +851,6 @@ set_intersection_point(CollisionEntry *new_entry,
|
|||||||
// extra_radius, which should put it on the surface of the tube if
|
// extra_radius, which should put it on the surface of the tube if
|
||||||
// our collision was tangential.
|
// our collision was tangential.
|
||||||
new_entry->set_interior_point(into_intersection_point - normal * extra_radius);
|
new_entry->set_interior_point(into_intersection_point - normal * extra_radius);
|
||||||
new_entry->set_contact_pos(into_intersection_point);
|
|
||||||
new_entry->set_contact_normal(contact_normal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -97,6 +97,10 @@ private:
|
|||||||
bool sphere_intersects_line(double &t1, double &t2, float center_y,
|
bool sphere_intersects_line(double &t1, double &t2, float center_y,
|
||||||
const LPoint3f &from, const LVector3f &delta,
|
const LPoint3f &from, const LVector3f &delta,
|
||||||
float inflate_radius) const;
|
float inflate_radius) const;
|
||||||
|
void calculate_surface_point_and_normal(const LPoint3f &surface_point,
|
||||||
|
double extra_radius,
|
||||||
|
LPoint3f &result_point,
|
||||||
|
LVector3f &result_normal) const;
|
||||||
void set_intersection_point(CollisionEntry *new_entry,
|
void set_intersection_point(CollisionEntry *new_entry,
|
||||||
const LPoint3f &into_intersection_point,
|
const LPoint3f &into_intersection_point,
|
||||||
double extra_radius) const;
|
double extra_radius) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user