@@ -619,18 +619,161 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
619619 return new_entry;
620620}
621621
622-
623622// //////////////////////////////////////////////////////////////////
624623// Function: CollisionBox::test_intersection_from_box
625624// Access: Public, Virtual
626625// Description: Double dispatch point for box as a FROM object
627- // NOT Implemented.
628626// //////////////////////////////////////////////////////////////////
629627PT (CollisionEntry) CollisionBox::
630628test_intersection_from_box(const CollisionEntry &entry) const {
631- return NULL ;
632- }
629+ const CollisionBox *box;
630+ DCAST_INTO_R (box, entry.get_from (), 0 );
631+
632+ const LMatrix4 &wrt_mat = entry.get_wrt_mat ();
633+
634+ LPoint3 diff = wrt_mat.xform_point_general (box->get_center ()) - _center;
635+ LVector3 from_extents = box->get_dimensions () * 0 .5f ;
636+ LVector3 into_extents = get_dimensions () * 0 .5f ;
637+
638+ LVecBase3 box_x = wrt_mat.get_row3 (0 );
639+ LVecBase3 box_y = wrt_mat.get_row3 (1 );
640+ LVecBase3 box_z = wrt_mat.get_row3 (2 );
641+
642+ // To make the math simpler, normalize the box basis vectors, instead
643+ // applying the scale to the box dimensions. Note that this doesn't
644+ // work for a non-uniform scales applied after a rotation, since that
645+ // has the possibility of making the box no longer a box.
646+ PN_stdfloat l;
647+ l = box_x.length ();
648+ from_extents[0 ] *= l;
649+ box_x /= l;
650+ l = box_y.length ();
651+ from_extents[1 ] *= l;
652+ box_y /= l;
653+ l = box_z.length ();
654+ from_extents[2 ] *= l;
655+ box_z /= l;
656+
657+ PN_stdfloat r1, r2;
658+
659+ // SAT test for the three axes of the into cube.
660+ r1 = into_extents[0 ];
661+ r2 = cabs (box_x[0 ] * from_extents[0 ]) +
662+ cabs (box_y[0 ] * from_extents[1 ]) +
663+ cabs (box_z[0 ] * from_extents[2 ]);
664+ if (cabs (diff[0 ]) > r1 + r2) {
665+ return NULL ;
666+ }
667+
668+ r1 = into_extents[1 ];
669+ r2 = cabs (box_x[1 ] * from_extents[0 ]) +
670+ cabs (box_y[1 ] * from_extents[1 ]) +
671+ cabs (box_z[1 ] * from_extents[2 ]);
672+ if (cabs (diff[1 ]) > r1 + r2) {
673+ return NULL ;
674+ }
675+
676+ r1 = into_extents[2 ];
677+ r2 = cabs (box_x[2 ] * from_extents[0 ]) +
678+ cabs (box_y[2 ] * from_extents[1 ]) +
679+ cabs (box_z[2 ] * from_extents[2 ]);
680+ if (cabs (diff[2 ]) > r1 + r2) {
681+ return NULL ;
682+ }
683+
684+ // SAT test for the three axes of the from cube.
685+ r1 = cabs (box_x[0 ] * into_extents[0 ]) +
686+ cabs (box_x[1 ] * into_extents[1 ]) +
687+ cabs (box_x[2 ] * into_extents[2 ]);
688+ r2 = from_extents[0 ];
689+ if (cabs (diff.dot (box_x)) > r1 + r2) {
690+ return NULL ;
691+ }
692+
693+ r1 = cabs (box_y[0 ] * into_extents[0 ]) +
694+ cabs (box_y[1 ] * into_extents[1 ]) +
695+ cabs (box_y[2 ] * into_extents[2 ]);
696+ r2 = from_extents[1 ];
697+ if (cabs (diff.dot (box_y)) > r1 + r2) {
698+ return NULL ;
699+ }
700+
701+ r1 = cabs (box_z[0 ] * into_extents[0 ]) +
702+ cabs (box_z[1 ] * into_extents[1 ]) +
703+ cabs (box_z[2 ] * into_extents[2 ]);
704+ r2 = from_extents[2 ];
705+ if (cabs (diff.dot (box_z)) > r1 + r2) {
706+ return NULL ;
707+ }
708+
709+ // SAT test of the nine cross products.
710+ r1 = into_extents[1 ] * cabs (box_x[2 ]) + into_extents[2 ] * cabs (box_x[1 ]);
711+ r2 = from_extents[1 ] * cabs (box_z[0 ]) + from_extents[2 ] * cabs (box_y[0 ]);
712+ if (cabs (diff[2 ] * box_x[1 ] - diff[1 ] * box_x[2 ]) > r1 + r2) {
713+ return NULL ;
714+ }
715+
716+ r1 = into_extents[1 ] * cabs (box_y[2 ]) + into_extents[2 ] * cabs (box_y[1 ]);
717+ r2 = from_extents[0 ] * cabs (box_z[0 ]) + from_extents[2 ] * cabs (box_x[0 ]);
718+ if (cabs (diff[2 ] * box_y[1 ] - diff[1 ] * box_y[2 ]) > r1 + r2) {
719+ return NULL ;
720+ }
633721
722+ r1 = into_extents[1 ] * cabs (box_z[2 ]) + into_extents[2 ] * cabs (box_z[1 ]);
723+ r2 = from_extents[0 ] * cabs (box_y[0 ]) + from_extents[1 ] * cabs (box_x[0 ]);
724+ if (cabs (diff[2 ] * box_z[1 ] - diff[1 ] * box_z[2 ]) > r1 + r2) {
725+ return NULL ;
726+ }
727+
728+ r1 = into_extents[0 ] * cabs (box_x[2 ]) + into_extents[2 ] * cabs (box_x[0 ]);
729+ r2 = from_extents[1 ] * cabs (box_z[1 ]) + from_extents[2 ] * cabs (box_y[1 ]);
730+ if (cabs (diff[0 ] * box_x[2 ] - diff[2 ] * box_x[0 ]) > r1 + r2) {
731+ return NULL ;
732+ }
733+
734+ r1 = into_extents[0 ] * cabs (box_y[2 ]) + into_extents[2 ] * cabs (box_y[0 ]);
735+ r2 = from_extents[0 ] * cabs (box_z[1 ]) + from_extents[2 ] * cabs (box_x[1 ]);
736+ if (cabs (diff[0 ] * box_y[2 ] - diff[2 ] * box_y[0 ]) > r1 + r2) {
737+ return NULL ;
738+ }
739+
740+ r1 = into_extents[0 ] * cabs (box_z[2 ]) + into_extents[2 ] * cabs (box_z[0 ]);
741+ r2 = from_extents[0 ] * cabs (box_y[1 ]) + from_extents[1 ] * cabs (box_x[1 ]);
742+ if (cabs (diff[0 ] * box_z[2 ] - diff[2 ] * box_z[0 ]) > r1 + r2) {
743+ return NULL ;
744+ }
745+
746+ r1 = into_extents[0 ] * cabs (box_x[1 ]) + into_extents[1 ] * cabs (box_x[0 ]);
747+ r2 = from_extents[1 ] * cabs (box_z[2 ]) + from_extents[2 ] * cabs (box_y[2 ]);
748+ if (cabs (diff[1 ] * box_x[0 ] - diff[0 ] * box_x[1 ]) > r1 + r2) {
749+ return NULL ;
750+ }
751+
752+ r1 = into_extents[0 ] * cabs (box_y[1 ]) + into_extents[1 ] * cabs (box_y[0 ]);
753+ r2 = from_extents[0 ] * cabs (box_z[2 ]) + from_extents[2 ] * cabs (box_x[2 ]);
754+ if (cabs (diff[1 ] * box_y[0 ] - diff[0 ] * box_y[1 ]) > r1 + r2) {
755+ return NULL ;
756+ }
757+
758+ r1 = into_extents[0 ] * cabs (box_z[1 ]) + into_extents[1 ] * cabs (box_z[0 ]);
759+ r2 = from_extents[0 ] * cabs (box_y[2 ]) + from_extents[1 ] * cabs (box_x[2 ]);
760+ if (cabs (diff[1 ] * box_z[0 ] - diff[0 ] * box_z[1 ]) > r1 + r2) {
761+ return NULL ;
762+ }
763+
764+ if (collide_cat.is_debug ()) {
765+ collide_cat.debug ()
766+ << " intersection detected from " << entry.get_from_node_path ()
767+ << " into " << entry.get_into_node_path () << " \n " ;
768+ }
769+ PT (CollisionEntry) new_entry = new CollisionEntry (entry);
770+
771+ if (has_effective_normal () && box->get_respect_effective_normal ()) {
772+ new_entry->set_surface_normal (get_effective_normal ());
773+ }
774+
775+ return new_entry;
776+ }
634777
635778// //////////////////////////////////////////////////////////////////
636779// Function: CollisionBox::fill_viz_geom
0 commit comments