174 |
|
tri_plane_equation(v0,v1,v2,n,&pd,FALSE); |
175 |
|
intersect_vector_plane(pt,n,pd,NULL,i_pt); |
176 |
|
|
177 |
< |
i = max_index(n); |
177 |
> |
i = max_index(n,NULL); |
178 |
|
x = (i+1)%3; |
179 |
|
y = (i+2)%3; |
180 |
|
/* Calculate barycentric coordinates of i_pt */ |
374 |
|
for(optr = QT_SET_PTR(os),i = QT_SET_CNT(os); i > 0; i--) |
375 |
|
{ |
376 |
|
id = QT_SET_NEXT_ELEM(optr); |
377 |
< |
qtTri_from_id(id,NULL,NULL,NULL,r0,r1,r2,NULL,NULL,NULL); |
377 |
> |
qtTri_from_id(id,r0,r1,r2,NULL,NULL,NULL,NULL,NULL,NULL); |
378 |
|
found=qtAdd_tri(qtptr,q0,q1,q2,r0,r1,r2,id,n); |
379 |
|
#ifdef DEBUG |
380 |
|
if(!found) |
527 |
|
} |
528 |
|
|
529 |
|
int |
530 |
– |
qtTrace_edge(qtptr,b,db,orig,dir,max_t,func,arg1,arg2) |
531 |
– |
QUADTREE *qtptr; |
532 |
– |
double b[3],db[3]; |
533 |
– |
FVECT orig,dir; |
534 |
– |
double max_t; |
535 |
– |
int (*func)(); |
536 |
– |
int *arg1,arg2; |
537 |
– |
{ |
538 |
– |
|
539 |
– |
int i,found; |
540 |
– |
QUADTREE *child; |
541 |
– |
int nbr,next; |
542 |
– |
double t; |
543 |
– |
#ifdef DEBUG_TEST_DRIVER |
544 |
– |
|
545 |
– |
FVECT a1,b1,c1; |
546 |
– |
int Pick_parent = Pick_cnt-1; |
547 |
– |
qtSubdivide_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent], |
548 |
– |
Pick_v2[Pick_parent],a1,b1,c1); |
549 |
– |
|
550 |
– |
#endif |
551 |
– |
if(QT_IS_TREE(*qtptr)) |
552 |
– |
{ |
553 |
– |
/* Find the appropriate child and reset the coord */ |
554 |
– |
i = bary_child(b); |
555 |
– |
|
556 |
– |
QT_SET_FLAG(*qtptr); |
557 |
– |
|
558 |
– |
for(;;) |
559 |
– |
{ |
560 |
– |
child = QT_NTH_CHILD_PTR(*qtptr,i); |
561 |
– |
|
562 |
– |
if(i != 3) |
563 |
– |
{ |
564 |
– |
|
565 |
– |
db[0] *= 2.0;db[1] *= 2.0; db[2] *= 2.0; |
566 |
– |
nbr = qtTrace_edge(child,b,db,orig,dir,max_t,func,arg1,arg2); |
567 |
– |
db[0] *= 0.5;db[1] *= 0.5; db[2] *= 0.5; |
568 |
– |
} |
569 |
– |
else |
570 |
– |
{ |
571 |
– |
db[0] *=-2.0;db[1] *= -2.0; db[2] *= -2.0; |
572 |
– |
/* If the center cell- must flip direction signs */ |
573 |
– |
nbr = qtTrace_edge(child,b,db,orig,dir,max_t,func,arg1,arg2); |
574 |
– |
db[0] *=-0.5;db[1] *= -0.5; db[2] *= -0.5; |
575 |
– |
} |
576 |
– |
if(nbr == QT_DONE) |
577 |
– |
return(nbr); |
578 |
– |
|
579 |
– |
/* If in same block: traverse */ |
580 |
– |
if(i==3) |
581 |
– |
next = nbr; |
582 |
– |
else |
583 |
– |
if(nbr == i) |
584 |
– |
next = 3; |
585 |
– |
else |
586 |
– |
{ |
587 |
– |
/* reset the barycentric coordinates in the parents*/ |
588 |
– |
bary_parent(b,i); |
589 |
– |
/* Else pop up to parent and traverse from there */ |
590 |
– |
return(nbr); |
591 |
– |
} |
592 |
– |
bary_from_child(b,i,next); |
593 |
– |
i = next; |
594 |
– |
} |
595 |
– |
} |
596 |
– |
else |
597 |
– |
{ |
598 |
– |
#ifdef DEBUG_TEST_DRIVER |
599 |
– |
qtNth_child_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent], |
600 |
– |
Pick_v2[Pick_parent],a1,b1,c1,i, |
601 |
– |
Pick_v0[Pick_cnt],Pick_v1[Pick_cnt], |
602 |
– |
Pick_v2[Pick_cnt]); |
603 |
– |
Pick_cnt++; |
604 |
– |
#endif |
605 |
– |
|
606 |
– |
if(func(qtptr,arg1,arg2) == QT_DONE) |
607 |
– |
return(QT_DONE); |
608 |
– |
|
609 |
– |
/* Advance to next node */ |
610 |
– |
/* NOTE: Optimize: should only have to check 1/2 */ |
611 |
– |
nbr = move_to_nbr(b,db[0],db[1],db[2],&t); |
612 |
– |
|
613 |
– |
if(t >= max_t) |
614 |
– |
return(QT_DONE); |
615 |
– |
if(nbr != -1) |
616 |
– |
{ |
617 |
– |
b[0] += t * db[0]; |
618 |
– |
b[1] += t * db[1]; |
619 |
– |
b[2] += t * db[2]; |
620 |
– |
db[0] *= (1.0 - t); |
621 |
– |
db[1] *= (1.0 - t); |
622 |
– |
db[2] *= (1.0 - t); |
623 |
– |
} |
624 |
– |
return(nbr); |
625 |
– |
} |
626 |
– |
|
627 |
– |
} |
628 |
– |
|
629 |
– |
|
630 |
– |
int |
530 |
|
qtTrace_ray(qtptr,b,db0,db1,db2,orig,dir,func,arg1,arg2) |
531 |
|
QUADTREE *qtptr; |
532 |
|
double b[3],db0,db1,db2; |
645 |
|
intersect_vector_plane(c,n,pd,&t,c); |
646 |
|
|
647 |
|
/* map to 2d by dropping maximum magnitude component of normal */ |
648 |
< |
i = max_index(n); |
648 |
> |
i = max_index(n,NULL); |
649 |
|
x = (i+1)%3; |
650 |
|
y = (i+2)%3; |
651 |
|
/* Calculate barycentric coordinates of orig */ |
671 |
|
|
672 |
|
} |
673 |
|
|
674 |
< |
|
776 |
< |
int |
777 |
< |
qtRoot_trace_edge(qtptr,q0,q1,q2,orig,dir,max_t,func,arg1,arg2) |
674 |
> |
qtVisit_tri_interior(qtptr,q0,q1,q2,t0,t1,t2,n,func,arg1,arg2,arg3) |
675 |
|
QUADTREE *qtptr; |
676 |
|
FVECT q0,q1,q2; |
780 |
– |
FVECT orig,dir; |
781 |
– |
double max_t; |
782 |
– |
int (*func)(); |
783 |
– |
int *arg1,arg2; |
784 |
– |
{ |
785 |
– |
int i,x,y,nbr; |
786 |
– |
QUADTREE *child; |
787 |
– |
FVECT n,c,i_pt,d; |
788 |
– |
double pd,b[3],db[3],t; |
789 |
– |
/* Determine if point lies within pyramid (and therefore |
790 |
– |
inside a spherical quadtree cell):GT_INTERIOR, on one of the |
791 |
– |
pyramid sides (and on cell edge):GT_EDGE(1,2 or 3), |
792 |
– |
or on pyramid vertex (and on cell vertex):GT_VERTEX(1,2, or 3). |
793 |
– |
For each triangle edge: compare the |
794 |
– |
point against the plane formed by the edge and the view center |
795 |
– |
*/ |
796 |
– |
i = point_in_stri(q0,q1,q2,orig); |
797 |
– |
|
798 |
– |
/* Not in this triangle */ |
799 |
– |
if(!i) |
800 |
– |
return(-1); |
801 |
– |
/* Project the origin onto the root node plane */ |
802 |
– |
|
803 |
– |
/* Find the intersection point of the origin */ |
804 |
– |
tri_plane_equation(q0,q1,q2,n,&pd,FALSE); |
805 |
– |
intersect_vector_plane(orig,n,pd,NULL,i_pt); |
806 |
– |
/* project the dir as well */ |
807 |
– |
VADD(c,orig,dir); |
808 |
– |
intersect_vector_plane(c,n,pd,&t,c); |
809 |
– |
|
810 |
– |
/* map to 2d by dropping maximum magnitude component of normal */ |
811 |
– |
i = max_index(n); |
812 |
– |
x = (i+1)%3; |
813 |
– |
y = (i+2)%3; |
814 |
– |
/* Calculate barycentric coordinates of orig */ |
815 |
– |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b); |
816 |
– |
/* Calculate barycentric coordinates of dir */ |
817 |
– |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],c[x],c[y],db); |
818 |
– |
if(t < 0.0) |
819 |
– |
VSUB(db,b,db); |
820 |
– |
else |
821 |
– |
VSUB(db,db,b); |
822 |
– |
|
823 |
– |
|
824 |
– |
#ifdef DEBUG_TEST_DRIVER |
825 |
– |
VCOPY(Pick_v0[Pick_cnt],q0); |
826 |
– |
VCOPY(Pick_v1[Pick_cnt],q1); |
827 |
– |
VCOPY(Pick_v2[Pick_cnt],q2); |
828 |
– |
Pick_cnt++; |
829 |
– |
#endif |
830 |
– |
/* trace the ray starting with this node */ |
831 |
– |
nbr = qtTrace_edge(qtptr,b,db,orig,d,max_t,func,arg1,arg2); |
832 |
– |
return(nbr); |
833 |
– |
|
834 |
– |
} |
835 |
– |
|
836 |
– |
|
837 |
– |
qtVisit_tri_interior(qtptr,q0,q1,q2,t0,t1,t2,n,func,arg1,arg2) |
838 |
– |
QUADTREE *qtptr; |
839 |
– |
FVECT q0,q1,q2; |
677 |
|
FVECT t0,t1,t2; |
678 |
|
int n; |
679 |
|
int (*func)(); |
680 |
< |
int *arg1,arg2; |
680 |
> |
int *arg1,arg2,*arg3; |
681 |
|
{ |
682 |
|
int i,found,test; |
683 |
|
QUADTREE *child; |
700 |
|
child = QT_NTH_CHILD_PTR(*qtptr,i); |
701 |
|
qtNth_child_tri(q0,q1,q2,a,b,c,i,c0,c1,c2); |
702 |
|
qtVisit_tri_interior(child,c0,c1,c2,t0,t1,t2,n+1, |
703 |
< |
func,arg1,arg2); |
703 |
> |
func,arg1,arg2,arg3); |
704 |
|
} |
705 |
|
} |
706 |
|
} |
710 |
|
if(!QT_IS_EMPTY(*qtptr)) |
711 |
|
{ |
712 |
|
if(qtinset(*qtptr,arg2)) |
713 |
< |
if(func(qtptr,q0,q1,q2,t0,t1,t2,n,arg1,arg2)==QT_MODIFIED) |
713 |
> |
if(func(qtptr,q0,q1,q2,t0,t1,t2,n,arg1,arg2,arg3)==QT_MODIFIED) |
714 |
|
goto tree_modified; |
715 |
|
else |
716 |
|
return; |
717 |
|
} |
718 |
|
if(point_in_stri(t0,t1,t2,q0) ) |
719 |
< |
if(func(qtptr,q0,q1,q2,t0,t1,t2,n,arg1,arg2)==QT_MODIFIED) |
719 |
> |
if(func(qtptr,q0,q1,q2,t0,t1,t2,n,arg1,arg2,arg3)==QT_MODIFIED) |
720 |
|
goto tree_modified; |
721 |
|
} |
722 |
|
} |
726 |
|
|
727 |
|
|
728 |
|
|
729 |
+ |
/* NOTE: SINCE DIR could be unit: then we could use integer math */ |
730 |
|
int |
731 |
< |
qtVisit_tri_edges(qtptr,b,db,wptr,sfactor,func,arg1,arg2) |
731 |
> |
qtVisit_tri_edges(qtptr,b,db0,db1,db2, |
732 |
> |
db,wptr,t,sign,sfactor,func,arg1,arg2,arg3) |
733 |
|
QUADTREE *qtptr; |
734 |
< |
double b[3],db[3][3]; |
734 |
> |
double b[3],db0,db1,db2,db[3][3]; |
735 |
|
int *wptr; |
736 |
+ |
double t[3]; |
737 |
+ |
int sign; |
738 |
|
double sfactor; |
739 |
|
int (*func)(); |
740 |
< |
int *arg1,arg2; |
740 |
> |
int *arg1,arg2,*arg3; |
741 |
|
{ |
742 |
|
int i,found; |
743 |
|
QUADTREE *child; |
744 |
|
int nbr,next,w; |
745 |
< |
double t; |
745 |
> |
double t_l,t_g; |
746 |
|
#ifdef DEBUG_TEST_DRIVER |
747 |
|
FVECT a1,b1,c1; |
748 |
|
int Pick_parent = Pick_cnt-1; |
749 |
|
qtSubdivide_tri(Pick_v0[Pick_parent],Pick_v1[Pick_parent], |
750 |
|
Pick_v2[Pick_parent],a1,b1,c1); |
751 |
|
#endif |
911 |
– |
|
752 |
|
if(QT_IS_TREE(*qtptr)) |
753 |
|
{ |
754 |
|
/* Find the appropriate child and reset the coord */ |
762 |
|
child = QT_NTH_CHILD_PTR(*qtptr,i); |
763 |
|
|
764 |
|
if(i != 3) |
765 |
< |
{ |
766 |
< |
|
767 |
< |
db[w][0] *= 2.0;db[w][1] *= 2.0; db[w][2] *= 2.0; |
928 |
< |
nbr = qtVisit_tri_edges(child,b,db,wptr,sfactor*2.0, |
929 |
< |
func,arg1,arg2); |
930 |
< |
w = *wptr; |
931 |
< |
db[w][0] *= 0.5;db[w][1] *= 0.5; db[w][2] *= 0.5; |
932 |
< |
} |
765 |
> |
nbr = qtVisit_tri_edges(child,b,db0,db1,db2, |
766 |
> |
db,wptr,t,sign, |
767 |
> |
sfactor*2.0,func,arg1,arg2,arg3); |
768 |
|
else |
769 |
< |
{ |
770 |
< |
db[w][0] *=-2.0;db[w][1] *= -2.0; db[w][2] *= -2.0; |
771 |
< |
/* If the center cell- must flip direction signs */ |
772 |
< |
nbr = qtVisit_tri_edges(child,b,db,wptr,sfactor*(-2.0), |
938 |
< |
func,arg1,arg2); |
939 |
< |
w = *wptr; |
940 |
< |
db[w][0] *=-0.5;db[w][1] *= -0.5; db[w][2] *= -0.5; |
941 |
< |
} |
942 |
< |
if(nbr == QT_DONE) |
943 |
< |
return(nbr); |
769 |
> |
/* If the center cell- must flip direction signs */ |
770 |
> |
nbr = qtVisit_tri_edges(child,b,-db0,-db1,-db2, |
771 |
> |
db,wptr,t,1-sign, |
772 |
> |
sfactor*2.0,func,arg1,arg2,arg3); |
773 |
|
|
774 |
+ |
if(nbr == QT_DONE) |
775 |
+ |
return(nbr); |
776 |
+ |
if(*wptr != w) |
777 |
+ |
{ |
778 |
+ |
w = *wptr; |
779 |
+ |
db0 = db[w][0];db1 = db[w][1];db2 = db[w][2]; |
780 |
+ |
if(sign) |
781 |
+ |
{ db0 *= -1.0;db1 *= -1.0; db2 *= -1.0;} |
782 |
+ |
} |
783 |
|
/* If in same block: traverse */ |
784 |
|
if(i==3) |
785 |
|
next = nbr; |
793 |
|
/* Else pop up to parent and traverse from there */ |
794 |
|
return(nbr); |
795 |
|
} |
796 |
< |
bary_from_child(b,i,next); |
797 |
< |
i = next; |
798 |
< |
} |
796 |
> |
bary_from_child(b,i,next); |
797 |
> |
i = next; |
798 |
> |
} |
799 |
|
} |
800 |
|
else |
801 |
|
{ |
806 |
|
Pick_cnt++; |
807 |
|
#endif |
808 |
|
|
809 |
< |
if(func(qtptr,arg1,arg2) == QT_DONE) |
809 |
> |
if(func(qtptr,arg1,arg2,arg3) == QT_DONE) |
810 |
|
return(QT_DONE); |
811 |
|
|
812 |
|
/* Advance to next node */ |
975 |
– |
/* NOTE: Optimize: should only have to check 1/2 */ |
813 |
|
w = *wptr; |
814 |
|
while(1) |
815 |
|
{ |
816 |
< |
nbr = move_to_nbr(b,db[w][0],db[w][1],db[w][2],&t); |
816 |
> |
nbr = move_to_nbr(b,db0,db1,db2,&t_l); |
817 |
|
|
818 |
< |
if(t >= 1.0) |
819 |
< |
{ |
818 |
> |
t_g = t_l/sfactor; |
819 |
> |
#ifdef DEBUG |
820 |
> |
if(t[w] <= 0.0) |
821 |
> |
eputs("qtVisit_tri_edges():negative t\n"); |
822 |
> |
#endif |
823 |
> |
if(t_g >= t[w]) |
824 |
> |
{ |
825 |
|
if(w == 2) |
826 |
|
return(QT_DONE); |
827 |
< |
b[0] += db[w][0]; |
828 |
< |
b[1] += db[w][1]; |
829 |
< |
b[2] += db[w][2]; |
827 |
> |
|
828 |
> |
b[0] += (t[w])*sfactor*db0; |
829 |
> |
b[1] += (t[w])*sfactor*db1; |
830 |
> |
b[2] += (t[w])*sfactor*db2; |
831 |
|
w++; |
832 |
< |
db[w][0] *= sfactor; |
833 |
< |
db[w][1] *= sfactor; |
834 |
< |
db[w][2] *= sfactor; |
832 |
> |
db0 = db[w][0]; |
833 |
> |
db1 = db[w][1]; |
834 |
> |
db2 = db[w][2]; |
835 |
> |
if(sign) |
836 |
> |
{ db0 *= -1.0;db1 *= -1.0; db2 *= -1.0;} |
837 |
|
} |
838 |
|
else |
839 |
|
if(nbr != INVALID) |
840 |
|
{ |
841 |
< |
b[0] += t * db[w][0]; |
842 |
< |
b[1] += t * db[w][1]; |
843 |
< |
b[2] += t * db[w][2]; |
844 |
< |
db[w][0] *= (1.0 - t); |
845 |
< |
db[w][1] *= (1.0 - t); |
1001 |
< |
db[w][2] *= (1.0 - t); |
841 |
> |
b[0] += t_l * db0; |
842 |
> |
b[1] += t_l * db1; |
843 |
> |
b[2] += t_l * db2; |
844 |
> |
|
845 |
> |
t[w] -= t_g; |
846 |
|
*wptr = w; |
847 |
|
return(nbr); |
848 |
|
} |
855 |
|
|
856 |
|
|
857 |
|
int |
858 |
< |
qtRoot_visit_tri_edges(qtptr,q0,q1,q2,tri,dir,wptr,func,arg1,arg2) |
858 |
> |
qtRoot_visit_tri_edges(qtptr,q0,q1,q2,tri,i_pt,wptr,func,arg1,arg2,arg3) |
859 |
|
QUADTREE *qtptr; |
860 |
|
FVECT q0,q1,q2; |
861 |
< |
FVECT tri[3],dir[3]; |
861 |
> |
FVECT tri[3],i_pt; |
862 |
|
int *wptr; |
863 |
|
int (*func)(); |
864 |
< |
int *arg1,arg2; |
864 |
> |
int *arg1,arg2,*arg3; |
865 |
|
{ |
866 |
< |
int i,x,y,nbr,w; |
866 |
> |
int x,y,z,nbr,w,i,j; |
867 |
|
QUADTREE *child; |
868 |
< |
FVECT n,c,i_pt,d; |
869 |
< |
double pd,b[3][3],db[3][3],t; |
868 |
> |
FVECT n,c,d,v[3]; |
869 |
> |
double pd,b[4][3],db[3][3],et[3],t[3],exit_pt; |
870 |
|
|
871 |
|
w = *wptr; |
872 |
|
|
875 |
|
/* Find the intersection point of the origin */ |
876 |
|
tri_plane_equation(q0,q1,q2,n,&pd,FALSE); |
877 |
|
/* map to 2d by dropping maximum magnitude component of normal */ |
878 |
< |
i = max_index(n); |
879 |
< |
x = (i+1)%3; |
880 |
< |
y = (i+2)%3; |
878 |
> |
z = max_index(n,NULL); |
879 |
> |
x = (z+1)%3; |
880 |
> |
y = (z+2)%3; |
881 |
|
/* Calculate barycentric coordinates for current vertex */ |
882 |
< |
|
1039 |
< |
for(i=0;i < 3; i++) |
882 |
> |
if(w != -1) |
883 |
|
{ |
884 |
< |
/* If processing 3rd edge-dont need info for t1 */ |
885 |
< |
if(i==1 && w==2) |
886 |
< |
continue; |
1044 |
< |
/* project the dir as well */ |
1045 |
< |
intersect_vector_plane(tri[i],n,pd,NULL,i_pt); |
1046 |
< |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b[i]); |
1047 |
< |
VADD(c,tri[i],dir[i]); |
1048 |
< |
intersect_vector_plane(c,n,pd,&t,c); |
1049 |
< |
/* Calculate barycentric coordinates of dir */ |
1050 |
< |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],c[x],c[y],db[i]); |
1051 |
< |
if(t < 0.0) |
1052 |
< |
VSUB(db[i],b[i],db[i]); |
1053 |
< |
else |
1054 |
< |
VSUB(db[i],db[i],b[i]); |
884 |
> |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],i_pt[x],i_pt[y],b[3]); |
885 |
> |
intersect_vector_plane(tri[w],n,pd,&(et[w]),v[w]); |
886 |
> |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[w][x],v[w][y],b[w]); |
887 |
|
} |
888 |
< |
#ifdef DEBUG_TEST_DRIVER |
889 |
< |
VCOPY(Pick_v0[Pick_cnt],q0); |
890 |
< |
VCOPY(Pick_v1[Pick_cnt],q1); |
891 |
< |
VCOPY(Pick_v2[Pick_cnt],q2); |
892 |
< |
Pick_cnt++; |
893 |
< |
#endif |
894 |
< |
/* trace the ray starting with this node */ |
895 |
< |
nbr = qtVisit_tri_edges(qtptr,b[w],db,wptr,1.0,func,arg1,arg2); |
888 |
> |
else |
889 |
> |
/* Just starting: b[0] is the origin point: guaranteed to be valid b*/ |
890 |
> |
{ |
891 |
> |
w = 0; |
892 |
> |
intersect_vector_plane(tri[0],n,pd,&(et[0]),v[0]); |
893 |
> |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[0][x],v[0][y],b[0]); |
894 |
> |
VCOPY(b[3],b[0]); |
895 |
> |
} |
896 |
> |
|
897 |
> |
|
898 |
> |
j = (w+1)%3; |
899 |
> |
intersect_vector_plane(tri[j],n,pd,&(et[j]),v[j]); |
900 |
> |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[j][x],v[j][y],b[j]); |
901 |
> |
if(et[j] < 0.0) |
902 |
> |
{ |
903 |
> |
VSUB(db[w],b[3],b[j]); |
904 |
> |
t[w] = FHUGE; |
905 |
> |
} |
906 |
> |
else |
907 |
> |
{ |
908 |
> |
/* NOTE: for stability: do not increment with ipt- use full dir and |
909 |
> |
calculate t: but for wrap around case: could get same problem? |
910 |
> |
*/ |
911 |
> |
VSUB(db[w],b[j],b[3]); |
912 |
> |
t[w] = 1.0; |
913 |
> |
move_to_nbr(b[3],db[w][0],db[w][1],db[w][2],&exit_pt); |
914 |
> |
if(exit_pt >= 1.0) |
915 |
> |
{ |
916 |
> |
for(;j < 3;j++) |
917 |
> |
{ |
918 |
> |
i = (j+1)%3; |
919 |
> |
if(i!= w) |
920 |
> |
{ |
921 |
> |
intersect_vector_plane(tri[i],n,pd,&(et[i]),v[i]); |
922 |
> |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[i][x], |
923 |
> |
v[i][y],b[i]); |
924 |
> |
} |
925 |
> |
if(et[i] < 0.0) |
926 |
> |
{ |
927 |
> |
VSUB(db[j],b[j],b[i]); |
928 |
> |
t[j] = FHUGE; |
929 |
> |
break; |
930 |
> |
} |
931 |
> |
else |
932 |
> |
{ |
933 |
> |
VSUB(db[j],b[i],b[j]); |
934 |
> |
t[j] = 1.0; |
935 |
> |
} |
936 |
> |
move_to_nbr(b[j],db[j][0],db[j][1],db[j][2],&exit_pt); |
937 |
> |
if(exit_pt < 1.0) |
938 |
> |
break; |
939 |
> |
} |
940 |
> |
} |
941 |
> |
} |
942 |
> |
*wptr = w; |
943 |
> |
/* trace the ray starting with this node */ |
944 |
> |
nbr = qtVisit_tri_edges(qtptr,b[3],db[w][0],db[w][1],db[w][2], |
945 |
> |
db,wptr,t,0,1.0,func,arg1,arg2,arg3); |
946 |
> |
if(nbr != INVALID && nbr != QT_DONE) |
947 |
> |
{ |
948 |
> |
i_pt[x] = b[3][0]*q0[x] + b[3][1]*q1[x] + b[3][2]*q2[x]; |
949 |
> |
i_pt[y] = b[3][0]*q0[y] + b[3][1]*q1[y] + b[3][2]*q2[y]; |
950 |
> |
i_pt[z] = (-n[x]*i_pt[x] - n[y]*i_pt[y] -pd)/n[z]; |
951 |
> |
} |
952 |
|
return(nbr); |
953 |
|
|
954 |
|
} |
955 |
|
|
956 |
< |
|
957 |
< |
|
958 |
< |
|
956 |
> |
int |
957 |
> |
move_to_nbri(b,db0,db1,db2,tptr) |
958 |
> |
BCOORD b[3]; |
959 |
> |
BDIR db0,db1,db2; |
960 |
> |
TINT *tptr; |
961 |
> |
{ |
962 |
> |
TINT t,dt; |
963 |
> |
BCOORD bc; |
964 |
> |
int nbr; |
965 |
> |
|
966 |
> |
nbr = -1; |
967 |
> |
/* Advance to next node */ |
968 |
> |
if(db0 < 0) |
969 |
> |
{ |
970 |
> |
bc = MAXBCOORD*b[0]; |
971 |
> |
t = bc/-db0; |
972 |
> |
nbr = 0; |
973 |
> |
} |
974 |
> |
else |
975 |
> |
t = HUGET; |
976 |
> |
if(db1 < 0) |
977 |
> |
{ |
978 |
> |
bc = MAXBCOORD*b[1]; |
979 |
> |
dt = bc/-db1; |
980 |
> |
if( dt < t) |
981 |
> |
{ |
982 |
> |
t = dt; |
983 |
> |
nbr = 1; |
984 |
> |
} |
985 |
> |
} |
986 |
> |
if(db2 < 0) |
987 |
> |
{ |
988 |
> |
bc = MAXBCOORD*b[2]; |
989 |
> |
dt = bc/-db2; |
990 |
> |
if( dt < t) |
991 |
> |
{ |
992 |
> |
t = dt; |
993 |
> |
nbr = 2; |
994 |
> |
} |
995 |
> |
} |
996 |
> |
*tptr = t; |
997 |
> |
return(nbr); |
998 |
> |
} |
999 |
|
/* NOTE: SINCE DIR could be unit: then we could use integer math */ |
1000 |
|
int |
1001 |
< |
qtVisit_tri_edges2(qtptr,b,db0,db1,db2, |
1002 |
< |
db,wptr,t,sign,sfactor,func,arg1,arg2) |
1001 |
> |
qtVisit_tri_edgesi(qtptr,b,db0,db1,db2, |
1002 |
> |
db,wptr,t,sign,sfactor,func,arg1,arg2,arg3) |
1003 |
|
QUADTREE *qtptr; |
1004 |
< |
double b[3],db0,db1,db2,db[3][3]; |
1004 |
> |
BCOORD b[3]; |
1005 |
> |
BDIR db0,db1,db2,db[3][3]; |
1006 |
|
int *wptr; |
1007 |
< |
double t[3]; |
1007 |
> |
TINT t[3]; |
1008 |
|
int sign; |
1009 |
< |
double sfactor; |
1009 |
> |
int sfactor; |
1010 |
|
int (*func)(); |
1011 |
< |
int *arg1,arg2; |
1011 |
> |
int *arg1,arg2,*arg3; |
1012 |
|
{ |
1013 |
|
int i,found; |
1014 |
|
QUADTREE *child; |
1015 |
|
int nbr,next,w; |
1016 |
< |
double t_l,t_g; |
1016 |
> |
TINT t_g,t_l,t_i; |
1017 |
|
#ifdef DEBUG_TEST_DRIVER |
1018 |
|
FVECT a1,b1,c1; |
1019 |
|
int Pick_parent = Pick_cnt-1; |
1023 |
|
if(QT_IS_TREE(*qtptr)) |
1024 |
|
{ |
1025 |
|
/* Find the appropriate child and reset the coord */ |
1026 |
< |
i = bary_child(b); |
1026 |
> |
i = baryi_child(b); |
1027 |
|
|
1028 |
|
QT_SET_FLAG(*qtptr); |
1029 |
|
|
1033 |
|
child = QT_NTH_CHILD_PTR(*qtptr,i); |
1034 |
|
|
1035 |
|
if(i != 3) |
1036 |
< |
nbr = qtVisit_tri_edges2(child,b,db0,db1,db2, |
1036 |
> |
nbr = qtVisit_tri_edgesi(child,b,db0,db1,db2, |
1037 |
|
db,wptr,t,sign, |
1038 |
< |
sfactor*2.0,func,arg1,arg2); |
1038 |
> |
sfactor+1,func,arg1,arg2,arg3); |
1039 |
|
else |
1040 |
|
/* If the center cell- must flip direction signs */ |
1041 |
< |
nbr = qtVisit_tri_edges2(child,b,-db0,-db1,-db2, |
1041 |
> |
nbr = qtVisit_tri_edgesi(child,b,-db0,-db1,-db2, |
1042 |
|
db,wptr,t,1-sign, |
1043 |
< |
sfactor*2.0,func,arg1,arg2); |
1043 |
> |
sfactor+1,func,arg1,arg2,arg3); |
1044 |
|
|
1045 |
|
if(nbr == QT_DONE) |
1046 |
|
return(nbr); |
1049 |
|
w = *wptr; |
1050 |
|
db0 = db[w][0];db1 = db[w][1];db2 = db[w][2]; |
1051 |
|
if(sign) |
1052 |
< |
{ db0 *= -1.0;db1 *= -1.0; db2 *= -1.0;} |
1052 |
> |
{ db0 *= -1;db1 *= -1; db2 *= -1;} |
1053 |
|
} |
1054 |
|
/* If in same block: traverse */ |
1055 |
|
if(i==3) |
1060 |
|
else |
1061 |
|
{ |
1062 |
|
/* reset the barycentric coordinates in the parents*/ |
1063 |
< |
bary_parent(b,i); |
1063 |
> |
baryi_parent(b,i); |
1064 |
|
/* Else pop up to parent and traverse from there */ |
1065 |
|
return(nbr); |
1066 |
|
} |
1067 |
< |
bary_from_child(b,i,next); |
1067 |
> |
baryi_from_child(b,i,next); |
1068 |
|
i = next; |
1069 |
|
} |
1070 |
|
} |
1077 |
|
Pick_cnt++; |
1078 |
|
#endif |
1079 |
|
|
1080 |
< |
if(func(qtptr,arg1,arg2) == QT_DONE) |
1080 |
> |
if(func(qtptr,arg1,arg2,arg3) == QT_DONE) |
1081 |
|
return(QT_DONE); |
1082 |
|
|
1083 |
|
/* Advance to next node */ |
1084 |
|
w = *wptr; |
1085 |
|
while(1) |
1086 |
|
{ |
1087 |
< |
nbr = move_to_nbr(b,db0,db1,db2,&t_l); |
1087 |
> |
nbr = move_to_nbri(b,db0,db1,db2,&t_i); |
1088 |
|
|
1089 |
< |
t_g = t_l/sfactor; |
1090 |
< |
#ifdef DEBUG |
1162 |
< |
if(t[w] <= 0.0) |
1163 |
< |
eputs("qtVisit_tri_edges2():negative t\n"); |
1164 |
< |
#endif |
1089 |
> |
t_g = t_i >> sfactor; |
1090 |
> |
|
1091 |
|
if(t_g >= t[w]) |
1092 |
|
{ |
1093 |
|
if(w == 2) |
1094 |
|
return(QT_DONE); |
1095 |
|
|
1096 |
< |
b[0] += (t[w])*sfactor*db0; |
1097 |
< |
b[1] += (t[w])*sfactor*db1; |
1098 |
< |
b[2] += (t[w])*sfactor*db2; |
1096 |
> |
/* The edge fits in the cell- therefore the result of shifting db by |
1097 |
> |
sfactor is guaranteed to be less than MAXBCOORD |
1098 |
> |
*/ |
1099 |
> |
/* Caution: (t[w]*db) must occur before divide by MAXBCOORD |
1100 |
> |
since t[w] will always be < MAXBCOORD |
1101 |
> |
*/ |
1102 |
> |
b[0] = b[0] + (t[w]*db0*(1 << sfactor))/MAXBCOORD; |
1103 |
> |
b[1] = b[1] + (t[w]*db1*(1 << sfactor))/MAXBCOORD; |
1104 |
> |
b[2] = b[2] + (t[w]*db2*(1 << sfactor))/MAXBCOORD; |
1105 |
|
w++; |
1106 |
< |
db0 = db[w][0]; |
1175 |
< |
db1 = db[w][1]; |
1176 |
< |
db2 = db[w][2]; |
1106 |
> |
db0 = db[w][0]; db1 = db[w][1]; db2 = db[w][2]; |
1107 |
|
if(sign) |
1108 |
< |
{ db0 *= -1.0;db1 *= -1.0; db2 *= -1.0;} |
1108 |
> |
{ db0 *= -1;db1 *= -1; db2 *= -1;} |
1109 |
|
} |
1110 |
|
else |
1111 |
|
if(nbr != INVALID) |
1112 |
|
{ |
1113 |
< |
b[0] += t_l * db0; |
1114 |
< |
b[1] += t_l * db1; |
1115 |
< |
b[2] += t_l * db2; |
1113 |
> |
/* Caution: (t_i*db) must occur before divide by MAXBCOORD |
1114 |
> |
since t_i will always be < MAXBCOORD |
1115 |
> |
*/ |
1116 |
> |
b[0] = b[0] + (t_i *db0) / MAXBCOORD; |
1117 |
> |
b[1] = b[1] + (t_i *db1) / MAXBCOORD; |
1118 |
> |
b[2] = b[2] + (t_i *db2) / MAXBCOORD; |
1119 |
|
|
1120 |
|
t[w] -= t_g; |
1121 |
|
*wptr = w; |
1124 |
|
else |
1125 |
|
return(INVALID); |
1126 |
|
} |
1127 |
< |
} |
1195 |
< |
|
1127 |
> |
} |
1128 |
|
} |
1129 |
|
|
1130 |
|
|
1131 |
|
int |
1132 |
< |
qtRoot_visit_tri_edges2(qtptr,q0,q1,q2,tri,i_pt,wptr,func,arg1,arg2) |
1132 |
> |
qtRoot_visit_tri_edgesi(qtptr,q0,q1,q2,tri,i_pt,wptr,func,arg1,arg2,arg3) |
1133 |
|
QUADTREE *qtptr; |
1134 |
|
FVECT q0,q1,q2; |
1135 |
|
FVECT tri[3],i_pt; |
1136 |
|
int *wptr; |
1137 |
|
int (*func)(); |
1138 |
< |
int *arg1,arg2; |
1138 |
> |
int *arg1,arg2,*arg3; |
1139 |
|
{ |
1140 |
|
int x,y,z,nbr,w,i,j; |
1141 |
|
QUADTREE *child; |
1142 |
|
FVECT n,c,d,v[3]; |
1143 |
< |
double pd,b[4][3],db[3][3],et[3],t[3],exit_pt; |
1144 |
< |
|
1143 |
> |
double pd,b[4][3],db[3][3],et[3],exit_pt; |
1144 |
> |
BCOORD bi[3]; |
1145 |
> |
TINT t[3]; |
1146 |
> |
BDIR dbi[3][3]; |
1147 |
|
w = *wptr; |
1148 |
|
|
1149 |
|
/* Project the origin onto the root node plane */ |
1150 |
|
|
1151 |
+ |
t[0] = t[1] = t[2] = 0; |
1152 |
|
/* Find the intersection point of the origin */ |
1153 |
|
tri_plane_equation(q0,q1,q2,n,&pd,FALSE); |
1154 |
|
/* map to 2d by dropping maximum magnitude component of normal */ |
1155 |
< |
z = max_index(n); |
1155 |
> |
z = max_index(n,NULL); |
1156 |
|
x = (z+1)%3; |
1157 |
|
y = (z+2)%3; |
1158 |
|
/* Calculate barycentric coordinates for current vertex */ |
1178 |
|
if(et[j] < 0.0) |
1179 |
|
{ |
1180 |
|
VSUB(db[w],b[3],b[j]); |
1181 |
< |
t[w] = FHUGE; |
1181 |
> |
t[w] = HUGET; |
1182 |
|
} |
1183 |
|
else |
1184 |
|
{ |
1186 |
|
calculate t: but for wrap around case: could get same problem? |
1187 |
|
*/ |
1188 |
|
VSUB(db[w],b[j],b[3]); |
1189 |
< |
t[w] = 1.0; |
1190 |
< |
move_to_nbr(b[3],db[w][0],db[w][1],db[w][2],&exit_pt); |
1191 |
< |
if(exit_pt >= 1.0) |
1189 |
> |
/* Check if the point is out side of the triangle: if so t[w] =HUGET */ |
1190 |
> |
if((fabs(b[j][0])>(FTINY+1.0)) ||(fabs(b[j][1])>(FTINY+1.0)) || |
1191 |
> |
(fabs(b[j][2])>(FTINY+1.0))) |
1192 |
> |
t[w] = HUGET; |
1193 |
> |
else |
1194 |
|
{ |
1195 |
< |
for(;j < 3;j++) |
1196 |
< |
{ |
1197 |
< |
i = (j+1)%3; |
1198 |
< |
if(i!= w) |
1199 |
< |
{ |
1200 |
< |
intersect_vector_plane(tri[i],n,pd,&(et[i]),v[i]); |
1264 |
< |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[i][x], |
1265 |
< |
v[i][y],b[i]); |
1266 |
< |
} |
1267 |
< |
if(et[i] < 0.0) |
1195 |
> |
/* The next point is in the triangle- so db values will be in valid |
1196 |
> |
range and t[w]= MAXT |
1197 |
> |
*/ |
1198 |
> |
t[w] = MAXT; |
1199 |
> |
if(j != 0) |
1200 |
> |
for(;j < 3;j++) |
1201 |
|
{ |
1202 |
< |
VSUB(db[j],b[j],b[i]); |
1203 |
< |
t[j] = FHUGE; |
1204 |
< |
break; |
1202 |
> |
i = (j+1)%3; |
1203 |
> |
if(i!= w) |
1204 |
> |
{ |
1205 |
> |
intersect_vector_plane(tri[i],n,pd,&(et[i]),v[i]); |
1206 |
> |
bary2d(q0[x],q0[y],q1[x],q1[y],q2[x],q2[y],v[i][x], |
1207 |
> |
v[i][y],b[i]); |
1208 |
> |
} |
1209 |
> |
if(et[i] < 0.0) |
1210 |
> |
{ |
1211 |
> |
VSUB(db[j],b[j],b[i]); |
1212 |
> |
t[j] = HUGET; |
1213 |
> |
break; |
1214 |
> |
} |
1215 |
> |
else |
1216 |
> |
{ |
1217 |
> |
VSUB(db[j],b[i],b[j]); |
1218 |
> |
if((fabs(b[j][0])>(FTINY+1.0)) || |
1219 |
> |
(fabs(b[j][1])>(FTINY+1.0)) || |
1220 |
> |
(fabs(b[j][2])>(FTINY+1.0))) |
1221 |
> |
{ |
1222 |
> |
t[j] = HUGET; |
1223 |
> |
break; |
1224 |
> |
} |
1225 |
> |
else |
1226 |
> |
t[j] = MAXT; |
1227 |
> |
} |
1228 |
|
} |
1273 |
– |
else |
1274 |
– |
{ |
1275 |
– |
VSUB(db[j],b[i],b[j]); |
1276 |
– |
t[j] = 1.0; |
1277 |
– |
} |
1278 |
– |
move_to_nbr(b[j],db[j][0],db[j][1],db[j][2],&exit_pt); |
1279 |
– |
if(exit_pt < 1.0) |
1280 |
– |
break; |
1281 |
– |
} |
1229 |
|
} |
1230 |
< |
} |
1230 |
> |
} |
1231 |
|
*wptr = w; |
1232 |
+ |
bary_dtol(b[3],db,bi,dbi,t); |
1233 |
+ |
|
1234 |
|
/* trace the ray starting with this node */ |
1235 |
< |
nbr = qtVisit_tri_edges2(qtptr,b[3],db[w][0],db[w][1],db[w][2], |
1236 |
< |
db,wptr,t,0,1.0,func,arg1,arg2); |
1235 |
> |
nbr = qtVisit_tri_edgesi(qtptr,bi,dbi[w][0],dbi[w][1],dbi[w][2], |
1236 |
> |
dbi,wptr,t,0,0,func,arg1,arg2,arg3); |
1237 |
|
if(nbr != INVALID && nbr != QT_DONE) |
1238 |
|
{ |
1239 |
< |
i_pt[x] = b[3][0]*q0[x] + b[3][1]*q1[x] + b[3][2]*q2[x]; |
1240 |
< |
i_pt[y] = b[3][0]*q0[y] + b[3][1]*q1[y] + b[3][2]*q2[y]; |
1241 |
< |
i_pt[z] = (-n[x]*i_pt[x] - n[y]*i_pt[y] -pd)/n[z]; |
1239 |
> |
b[3][0] = (double)bi[0]/(double)MAXBCOORD; |
1240 |
> |
b[3][1] = (double)bi[1]/(double)MAXBCOORD; |
1241 |
> |
b[3][2] = (double)bi[2]/(double)MAXBCOORD; |
1242 |
> |
i_pt[x] = b[3][0]*q0[x] + b[3][1]*q1[x] + b[3][2]*q2[x]; |
1243 |
> |
i_pt[y] = b[3][0]*q0[y] + b[3][1]*q1[y] + b[3][2]*q2[y]; |
1244 |
> |
i_pt[z] = (-n[x]*i_pt[x] - n[y]*i_pt[y] -pd)/n[z]; |
1245 |
|
} |
1246 |
|
return(nbr); |
1247 |
|
|
1248 |
|
} |
1297 |
– |
|
1298 |
– |
|
1249 |
|
|
1250 |
|
|
1251 |
|
|