mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -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;
|
||||
float from_radius = length(from_radius_v);
|
||||
|
||||
LPoint3f into_intersection_point;
|
||||
LPoint3f into_intersection_point(from_b);
|
||||
double t1, t2;
|
||||
LPoint3f contact_point(into_intersection_point);
|
||||
float actual_t = 0.0f;
|
||||
|
||||
if (from_a != from_b) {
|
||||
LVector3f from_direction = from_b - from_a;
|
||||
@ -346,6 +348,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
||||
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) {
|
||||
// Point a is within the sphere. The first intersection point is
|
||||
// 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 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_point(into_center + surface_normal * into_radius);
|
||||
new_entry->set_interior_point(from_center - surface_normal * from_radius);
|
||||
new_entry->set_contact_pos(into_intersection_point);
|
||||
new_entry->set_contact_normal(surface_normal);
|
||||
new_entry->set_t(t1);
|
||||
new_entry->set_contact_pos(contact_point);
|
||||
new_entry->set_contact_normal(contact_normal);
|
||||
new_entry->set_t(actual_t);
|
||||
|
||||
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_b = from_a;
|
||||
|
||||
LPoint3f contact_point;
|
||||
float actual_t = 0.0f;
|
||||
|
||||
if (wrt_prev_space != wrt_space) {
|
||||
// If the sphere is moving relative to the tube, it becomes a tube
|
||||
// itself.
|
||||
@ -195,6 +198,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
|
||||
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()) {
|
||||
collide_cat.debug()
|
||||
<< "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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
@ -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
|
||||
// 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.
|
||||
// Description: Calculates a point that is exactly on the surface
|
||||
// of the tube and its corresponding normal, given
|
||||
// a point that is supposedly on the surface of the
|
||||
// tube.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CollisionTube::
|
||||
set_intersection_point(CollisionEntry *new_entry,
|
||||
const LPoint3f &into_intersection_point,
|
||||
double extra_radius) const {
|
||||
calculate_surface_point_and_normal(const LPoint3f &surface_point,
|
||||
double extra_radius,
|
||||
LPoint3f &result_point,
|
||||
LVector3f &result_normal) const {
|
||||
// Convert the point into our canonical space for analysis.
|
||||
LPoint3f point = into_intersection_point * _inv_mat;
|
||||
LPoint3f point = surface_point * _inv_mat;
|
||||
LVector3f normal;
|
||||
|
||||
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.
|
||||
point = point * _mat;
|
||||
normal = normal * _mat;
|
||||
result_point = point * _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()) {
|
||||
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
|
||||
// our collision was tangential.
|
||||
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,
|
||||
const LPoint3f &from, const LVector3f &delta,
|
||||
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,
|
||||
const LPoint3f &into_intersection_point,
|
||||
double extra_radius) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user