19 |
|
SM *smMesh = NULL; |
20 |
|
double smDist_sum=0; |
21 |
|
int smNew_tri_cnt=0; |
22 |
< |
double smMinSampDiff = 1e-4; |
22 |
> |
double smMinSampDiff = 1.7e-3; /* min edge length in radians */ |
23 |
|
|
24 |
|
static FVECT smDefault_base[4] = { {SQRT3_INV, SQRT3_INV, SQRT3_INV}, |
25 |
|
{-SQRT3_INV, -SQRT3_INV, SQRT3_INV}, |
26 |
|
{-SQRT3_INV, SQRT3_INV, -SQRT3_INV}, |
27 |
|
{SQRT3_INV, -SQRT3_INV, -SQRT3_INV}}; |
28 |
< |
static int smTri_verts[4][3] = { {2,1,0},{3,2,0},{1,3,0},{2,3,1}}; |
28 |
> |
static int smTri_verts[4][3] = { {0,1,2},{0,2,3},{0,3,1},{1,3,2}}; |
29 |
|
|
30 |
< |
static int smBase_nbrs[4][3] = { {3,2,1},{3,0,2},{3,1,0},{1,2,0}}; |
30 |
> |
static int smBase_nbrs[4][3] = { {3,1,2},{3,2,0},{3,0,1},{1,0,2}}; |
31 |
|
|
32 |
|
#ifdef TEST_DRIVER |
33 |
|
VIEW Current_View = {0,{0,0,0},{0,0,-1},{0,1,0},60,60,0}; |
35 |
|
int Pick_tri = -1,Picking = FALSE,Pick_samp=-1; |
36 |
|
FVECT Pick_point[500],Pick_origin,Pick_dir; |
37 |
|
FVECT Pick_v0[500], Pick_v1[500], Pick_v2[500]; |
38 |
+ |
int Pick_q[500]; |
39 |
|
FVECT P0,P1,P2; |
40 |
|
FVECT FrustumNear[4],FrustumFar[4]; |
41 |
|
double dev_zmin=.01,dev_zmax=1000; |
491 |
|
|
492 |
|
st = SM_LOCATOR(sm); |
493 |
|
|
494 |
+ |
#ifdef DEBUG |
495 |
+ |
if((v0_id == INVALID) || (v1_id == INVALID) || (v2_id == INVALID)) |
496 |
+ |
error(CONSISTENCY,"Invalid ids 1\n"); |
497 |
+ |
#endif |
498 |
|
|
499 |
|
VSUB(v0,SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm)); |
500 |
|
VSUB(v1,SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm)); |
516 |
|
{ |
517 |
|
int t_id; |
518 |
|
TRI *t; |
519 |
< |
|
519 |
> |
#ifdef DEBUG |
520 |
> |
if(v0_id==v1_id || v0_id==v2_id || v1_id==v2_id) |
521 |
> |
{ |
522 |
> |
eputs("smAdd_tri: invalid vertex ids\n"); |
523 |
> |
return(INVALID); |
524 |
> |
} |
525 |
> |
#endif |
526 |
|
t_id = smAlloc_tri(sm); |
527 |
|
|
528 |
|
if(t_id == -1) |
573 |
|
|
574 |
|
{ |
575 |
|
int verts[3],enext,eprev,e1next,e1prev; |
576 |
< |
TRI *n; |
576 |
> |
TRI *n,*ta,*tb,*t,*t1; |
577 |
|
FVECT p1,p2,p3; |
578 |
|
int ta_id,tb_id; |
579 |
< |
/* swap diagonal (e relative to t, and e1 relative to t1) |
580 |
< |
defined by quadrilateral |
570 |
< |
formed by t,t1- swap for the opposite diagonal |
579 |
> |
/* form new diagonal (e relative to t, and e1 relative to t1) |
580 |
> |
defined by quadrilateral formed by t,t1- swap for the opposite diagonal |
581 |
|
*/ |
582 |
|
enext = (e+1)%3; |
583 |
|
eprev = (e+2)%3; |
584 |
|
e1next = (e1+1)%3; |
585 |
|
e1prev = (e1+2)%3; |
586 |
|
verts[e] = T_NTH_V(SM_NTH_TRI(sm,t_id),e); |
587 |
< |
verts[enext] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1prev); |
588 |
< |
verts[eprev] = T_NTH_V(SM_NTH_TRI(sm,t_id),eprev); |
587 |
> |
verts[enext] = T_NTH_V(SM_NTH_TRI(sm,t_id),enext); |
588 |
> |
verts[eprev] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1); |
589 |
|
ta_id = smAdd_tri(sm,verts[0],verts[1],verts[2]); |
590 |
|
*add_ptr = push_data(*add_ptr,ta_id); |
591 |
|
verts[e1] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1); |
592 |
< |
verts[e1next] = T_NTH_V(SM_NTH_TRI(sm,t_id),eprev); |
593 |
< |
verts[e1prev] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1prev); |
592 |
> |
verts[e1next] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1next); |
593 |
> |
verts[e1prev] = T_NTH_V(SM_NTH_TRI(sm,t_id),e); |
594 |
|
tb_id = smAdd_tri(sm,verts[0],verts[1],verts[2]); |
595 |
|
*add_ptr = push_data(*add_ptr,tb_id); |
596 |
|
|
597 |
+ |
ta = SM_NTH_TRI(sm,ta_id); |
598 |
+ |
tb = SM_NTH_TRI(sm,tb_id); |
599 |
+ |
t = SM_NTH_TRI(sm,t_id); |
600 |
+ |
t1 = SM_NTH_TRI(sm,t1_id); |
601 |
|
/* set the neighbors */ |
602 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,ta_id),e) = T_NTH_NBR(SM_NTH_TRI(sm,t1_id),e1next); |
603 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,tb_id),e1) = T_NTH_NBR(SM_NTH_TRI(sm,t_id),enext); |
604 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,ta_id),enext) =tb_id; |
605 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,tb_id),e1next) = ta_id; |
606 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,ta_id),eprev)=T_NTH_NBR(SM_NTH_TRI(sm,t_id),eprev); |
607 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,tb_id),e1prev)= |
594 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),e1prev); |
602 |
> |
T_NTH_NBR(ta,e) = T_NTH_NBR(t1,e1next); |
603 |
> |
T_NTH_NBR(tb,e1) = T_NTH_NBR(t,enext); |
604 |
> |
T_NTH_NBR(ta,enext)= tb_id; |
605 |
> |
T_NTH_NBR(tb,e1next)= ta_id; |
606 |
> |
T_NTH_NBR(ta,eprev)=T_NTH_NBR(t,eprev); |
607 |
> |
T_NTH_NBR(tb,e1prev)=T_NTH_NBR(t1,e1prev); |
608 |
|
|
609 |
|
/* Reset neighbor pointers of original neighbors */ |
610 |
< |
n = SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t_id),enext)); |
610 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t,enext)); |
611 |
|
T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = tb_id; |
612 |
< |
n = SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t_id),eprev)); |
612 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t,eprev)); |
613 |
|
T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = ta_id; |
614 |
|
|
615 |
< |
n = SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t1_id),e1next)); |
615 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,e1next)); |
616 |
|
T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = ta_id; |
617 |
< |
n = SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t1_id),e1prev)); |
617 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,e1prev)); |
618 |
|
T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = tb_id; |
619 |
|
|
620 |
|
/* Delete two parent triangles */ |
668 |
|
QUADTREE *delptr; |
669 |
|
{ |
670 |
|
TRI *t,*t_opp; |
671 |
< |
FVECT p,p1,p2,p3; |
671 |
> |
FVECT p,p0,p1,p2; |
672 |
|
int e,e1,swapped = 0; |
673 |
|
int t_id,t_opp_id; |
674 |
|
|
676 |
|
while(tlist) |
677 |
|
{ |
678 |
|
t_id = pop_list(&tlist); |
679 |
+ |
#ifdef DEBUG |
680 |
+ |
if(t_id==INVALID || t_id > smMesh->num_tri) |
681 |
+ |
error(CONSISTENCY,"Invalid tri id smFix_tris()\n"); |
682 |
+ |
#endif |
683 |
|
t = SM_NTH_TRI(sm,t_id); |
684 |
< |
e = (T_WHICH_V(t,id)+1)%3; |
684 |
> |
e = T_WHICH_V(t,id); |
685 |
|
t_opp_id = T_NTH_NBR(t,e); |
686 |
< |
t_opp = SM_NTH_TRI(sm,t_opp_id); |
687 |
< |
|
688 |
< |
smDir_in_cone(sm,p1,T_NTH_V(t_opp,0)); |
689 |
< |
smDir_in_cone(sm,p2,T_NTH_V(t_opp,1)); |
690 |
< |
smDir_in_cone(sm,p3,T_NTH_V(t_opp,2)); |
691 |
< |
if(point_in_cone(p,p1,p2,p3)) |
686 |
> |
#ifdef DEBUG |
687 |
> |
if(t_opp_id==INVALID || t_opp_id > smMesh->num_tri) |
688 |
> |
error(CONSISTENCY,"Invalid tri id smFix_tris()\n"); |
689 |
> |
#endif |
690 |
> |
t_opp = SM_NTH_TRI(sm,t_opp_id); |
691 |
> |
|
692 |
> |
smDir_in_cone(sm,p0,T_NTH_V(t_opp,0)); |
693 |
> |
smDir_in_cone(sm,p1,T_NTH_V(t_opp,1)); |
694 |
> |
smDir_in_cone(sm,p2,T_NTH_V(t_opp,2)); |
695 |
> |
if(point_in_cone(p,p0,p1,p2)) |
696 |
|
{ |
697 |
|
swapped = 1; |
698 |
|
e1 = T_NTH_NBR_PTR(t_id,t_opp); |
721 |
|
int nbr_id; |
722 |
|
|
723 |
|
/* Want the edge for which "id" is the destination */ |
724 |
< |
t_id = (T_WHICH_V(t,id)+ 2)% 3; |
724 |
> |
t_id = (T_WHICH_V(t,id)+ 1)% 3; |
725 |
|
nbr_id = T_NTH_NBR(t,t_id); |
726 |
|
return(nbr_id); |
727 |
|
} |
772 |
|
tri = SM_NTH_TRI(sm,tri_id); |
773 |
|
|
774 |
|
/* Set the neighbor pointers for the new tris */ |
775 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),0) = t2_id; |
776 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),1) = T_NTH_NBR(tri,0); |
777 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),2) = t1_id; |
778 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),0) = t0_id; |
779 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),1) = T_NTH_NBR(tri,1); |
780 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),2) = t2_id; |
781 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),0) = t1_id; |
782 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),1) = T_NTH_NBR(tri,2); |
783 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),2) = t0_id; |
775 |
> |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),0) = T_NTH_NBR(tri,2); |
776 |
> |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),1) = t1_id; |
777 |
> |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),2) = t2_id; |
778 |
> |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),0) = T_NTH_NBR(tri,0); |
779 |
> |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),1) = t2_id; |
780 |
> |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),2) = t0_id; |
781 |
> |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),0) = T_NTH_NBR(tri,1); |
782 |
> |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),1) = t0_id; |
783 |
> |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),2) = t1_id; |
784 |
|
|
785 |
|
/* Reset the neigbor pointers for the neighbors of the original */ |
786 |
|
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,0)); |
766 |
– |
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t0_id; |
767 |
– |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,1)); |
787 |
|
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t1_id; |
788 |
< |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2)); |
788 |
> |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,1)); |
789 |
|
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id; |
790 |
+ |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2)); |
791 |
+ |
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t0_id; |
792 |
|
|
793 |
|
del_set[0] = 1; del_set[1] = tri_id; |
794 |
|
delnode = qtnewleaf(del_set); |
830 |
|
if(EQUAL_VEC3(v0,p) || EQUAL_VEC3(v1,p) || EQUAL_VEC3(v2,p)) |
831 |
|
return(t_id); |
832 |
|
|
833 |
< |
VCROSS(n,v1,v0); |
833 |
> |
VCROSS(n,v0,v1); |
834 |
|
if(DOT(n,p) >0.0) |
835 |
|
continue; |
836 |
< |
VCROSS(n,v2,v1); |
836 |
> |
VCROSS(n,v1,v2); |
837 |
|
if(DOT(n,p) > 0.0) |
838 |
|
continue; |
839 |
|
|
840 |
< |
VCROSS(n,v0,v2); |
840 |
> |
VCROSS(n,v2,v0); |
841 |
|
if(DOT(n,p) > 0.0) |
842 |
|
continue; |
843 |
|
|
847 |
|
} |
848 |
|
|
849 |
|
int |
850 |
< |
smPointLocateTri(sm,id) |
850 |
> |
smPointLocateTri(sm,p) |
851 |
|
SM *sm; |
852 |
< |
int id; |
852 |
> |
FVECT p; |
853 |
|
{ |
833 |
– |
FVECT tpt; |
854 |
|
QUADTREE qt,*optr; |
855 |
< |
|
856 |
< |
VSUB(tpt,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm)); |
855 |
> |
FVECT tpt; |
856 |
> |
|
857 |
> |
VSUB(tpt,p,SM_VIEW_CENTER(sm)); |
858 |
|
qt = smPointLocateCell(sm,tpt); |
859 |
|
if(QT_IS_EMPTY(qt)) |
860 |
|
return(INVALID); |
896 |
|
This attempts to throw out points that should be occluded |
897 |
|
*/ |
898 |
|
int |
899 |
< |
smTest_sample(sm,tri_id,s_id,dir,rptr) |
899 |
> |
smTest_sample(sm,tri_id,c,dir,p,o_id,rptr) |
900 |
|
SM *sm; |
901 |
< |
int tri_id,s_id; |
902 |
< |
FVECT dir; |
901 |
> |
int tri_id; |
902 |
> |
COLR c; |
903 |
> |
FVECT dir,p; |
904 |
> |
int o_id; |
905 |
|
int *rptr; |
906 |
|
{ |
907 |
|
TRI *tri; |
908 |
|
double d,d2,dnear,dspt,d01,d12,d20,s0,s1,s2,ds,dv; |
909 |
|
int vid[3],i,nearid,norm,dcnt,bcnt; |
910 |
|
FVECT diff[3],spt,npt; |
911 |
< |
FVECT p; |
911 |
> |
int tonemap; |
912 |
|
|
890 |
– |
VCOPY(p,SM_NTH_WV(sm,s_id)); |
913 |
|
*rptr = INVALID; |
914 |
|
bcnt = dcnt = 0; |
915 |
|
tri = SM_NTH_TRI(sm,tri_id); |
931 |
|
dcnt++; |
932 |
|
VSUB(diff[i],SM_NTH_WV(sm,vid[i]),p); |
933 |
|
/* If same world point: replace */ |
934 |
< |
if(ZERO_VEC3(diff[i])) |
934 |
> |
if(FZERO_VEC3(diff[i])) |
935 |
|
{ |
936 |
< |
sReset_samp(SM_SAMP(sm),vid[i],s_id); |
937 |
< |
SM_TONE_MAP(sm) = 0; |
938 |
< |
return(FALSE); |
936 |
> |
tonemap = (SM_TONE_MAP(sm) > vid[i]); |
937 |
> |
sInit_samp(SM_SAMP(sm),vid[i],c,dir,p,o_id,tonemap); |
938 |
> |
return(FALSE); |
939 |
|
} |
940 |
|
} |
941 |
< |
if(SM_DIR_ID(sm,s_id)) |
942 |
< |
return(TRUE); |
941 |
> |
if(!dir) |
942 |
> |
return(TRUE); |
943 |
|
/* TEST 2: If the new sample is close in ws, and close in the spherical |
944 |
|
projection to one of the triangle vertex samples |
945 |
|
*/ |
971 |
|
VSUB(npt,SM_NTH_WV(sm,nearid),SM_VIEW_CENTER(sm)); |
972 |
|
normalize(npt); |
973 |
|
d = fdir2diff(SM_NTH_W_DIR(sm,nearid), npt); |
974 |
< |
if(dir) |
953 |
< |
d2 = 2. - 2.*DOT(dir,spt); |
954 |
< |
else |
955 |
< |
d2 = fdir2diff(SM_NTH_W_DIR(sm,s_id), spt); |
974 |
> |
d2 = 2. - 2.*DOT(dir,spt); |
975 |
|
/* The existing sample is a better sample:punt */ |
976 |
|
if(d2 > d) |
977 |
|
return(FALSE); |
1044 |
|
if(s2 < S_REPLACE_SCALE*d) |
1045 |
|
return(TRUE); |
1046 |
|
|
1047 |
+ |
/* TEST 5: |
1048 |
+ |
Check to see if triangle is relatively large and should therefore |
1049 |
+ |
be subdivided anyway. |
1050 |
+ |
*/ |
1051 |
+ |
dv *= DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_VIEW_CENTER(sm)); |
1052 |
+ |
dv *= DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_VIEW_CENTER(sm)); |
1053 |
+ |
if (d01*d12*d20/dv > S_REPLACE_TRI) |
1054 |
+ |
return(TRUE); |
1055 |
|
|
1056 |
|
return(FALSE); |
1057 |
|
} |
1058 |
|
|
1059 |
|
|
1060 |
|
int |
1061 |
< |
smAlloc_samp(sm,c,dir,pt) |
1061 |
> |
smAlloc_samp(sm,c,dir,pt,o_id) |
1062 |
|
SM *sm; |
1063 |
|
COLR c; |
1064 |
|
FVECT dir,pt; |
1065 |
+ |
int o_id; |
1066 |
|
{ |
1067 |
|
int s_id,replaced,cnt; |
1068 |
|
SAMP *s; |
1074 |
|
cnt=0; |
1075 |
|
while(replaced) |
1076 |
|
{ |
1077 |
< |
if(smMesh_remove_vertex(sm,s_id)) |
1077 |
> |
if(smRemoveVertex(sm,s_id)) |
1078 |
|
break; |
1079 |
|
s_id = sAlloc_samp(s,&replaced); |
1080 |
|
cnt++; |
1082 |
|
error(CONSISTENCY,"smAlloc_samp():unable to find free samp\n"); |
1083 |
|
} |
1084 |
|
|
1085 |
< |
if(pt) |
1086 |
< |
sInit_samp(s,s_id,c,dir,pt); |
1087 |
< |
else |
1088 |
< |
{ |
1089 |
< |
VADD(p,dir,SM_VIEW_CENTER(sm)); |
1090 |
< |
sInit_samp(s,s_id,c,NULL,p); |
1063 |
< |
} |
1085 |
> |
/* If sample is being added in the middle of the sample array: tone |
1086 |
> |
map individually |
1087 |
> |
*/ |
1088 |
> |
/* Initialize sample */ |
1089 |
> |
sInit_samp(s,s_id,c,dir,pt,o_id,(SM_TONE_MAP(sm)>s_id)); |
1090 |
> |
|
1091 |
|
return(s_id); |
1092 |
|
} |
1093 |
|
|
1094 |
|
int |
1095 |
< |
smAdd_samp(sm,s_id,p,dir) |
1095 |
> |
smAdd_samp(sm,c,dir,p,o_id) |
1096 |
|
SM *sm; |
1097 |
< |
int s_id; |
1098 |
< |
FVECT p,dir; |
1097 |
> |
COLR c; |
1098 |
> |
FVECT dir,p; |
1099 |
> |
int o_id; |
1100 |
|
{ |
1101 |
< |
int t_id,r_id,test; |
1102 |
< |
double d; |
1101 |
> |
int t_id,s_id,r_id; |
1102 |
> |
double d; |
1103 |
> |
FVECT wpt; |
1104 |
|
|
1105 |
< |
r_id = INVALID; |
1106 |
< |
t_id = smPointLocateTri(sm,s_id); |
1105 |
> |
r_id = INVALID; |
1106 |
> |
/* If sample is a world space point */ |
1107 |
> |
if(p) |
1108 |
> |
{ |
1109 |
> |
t_id = smPointLocateTri(sm,p); |
1110 |
|
if(t_id == INVALID) |
1111 |
+ |
{ |
1112 |
+ |
#ifdef DEBUG |
1113 |
+ |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
1114 |
+ |
#endif |
1115 |
+ |
return(INVALID); |
1116 |
+ |
} |
1117 |
+ |
/* if not a base id, Test to see if this sample should be added */ |
1118 |
+ |
if(!SM_BASE_ID(sm,o_id)) |
1119 |
|
{ |
1120 |
+ |
if(!smTest_sample(sm,t_id,c,dir,p,o_id,&r_id)) |
1121 |
+ |
return(INVALID); |
1122 |
+ |
/* Allocate space for a sample and initialize */ |
1123 |
+ |
s_id = smAlloc_samp(smMesh,c,dir,p,o_id); |
1124 |
+ |
} |
1125 |
+ |
else |
1126 |
+ |
s_id = o_id; |
1127 |
+ |
} |
1128 |
+ |
/* If sample is a direction vector */ |
1129 |
+ |
else |
1130 |
+ |
{ |
1131 |
+ |
VADD(wpt,dir,SM_VIEW_CENTER(smMesh)); |
1132 |
+ |
t_id = smPointLocateTri(sm,wpt); |
1133 |
+ |
if(t_id == INVALID) |
1134 |
+ |
{ |
1135 |
|
#ifdef DEBUG |
1136 |
< |
eputs("smAdd_samp(): tri not found \n"); |
1136 |
> |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
1137 |
|
#endif |
1138 |
< |
return(FALSE); |
1138 |
> |
return(INVALID); |
1139 |
> |
} |
1140 |
> |
/* Test to see if this sample should be added */ |
1141 |
> |
if(!smTest_sample(sm,t_id,c,NULL,wpt,o_id,&r_id)) |
1142 |
> |
return(INVALID); |
1143 |
> |
/* Allocate space for a sample and initialize */ |
1144 |
> |
s_id = smAlloc_samp(smMesh,c,NULL,wpt,o_id); |
1145 |
|
} |
1146 |
< |
if(!SM_BASE_ID(sm,s_id)) |
1146 |
> |
if(!SM_BASE_ID(sm,s_id) && !SM_DIR_ID(sm,s_id)) |
1147 |
|
{ |
1148 |
< |
if(!smTest_sample(sm,t_id,s_id,dir,&r_id)) |
1149 |
< |
return(FALSE); |
1150 |
< |
/* If not a sky point, add distance from the viewcenter to average*/ |
1151 |
< |
if( !SM_DIR_ID(sm,s_id)) |
1091 |
< |
{ |
1092 |
< |
d = DIST(p,SM_VIEW_CENTER(smMesh)); |
1093 |
< |
smDist_sum += 1.0/d; |
1094 |
< |
} |
1148 |
> |
/* If not a base or sky point, add distance from the |
1149 |
> |
viewcenter to average*/ |
1150 |
> |
d = DIST(SM_NTH_WV(sm,s_id),SM_VIEW_CENTER(smMesh)); |
1151 |
> |
smDist_sum += 1.0/d; |
1152 |
|
} |
1153 |
< |
test = smInsert_samp(smMesh,s_id,t_id); |
1153 |
> |
smInsert_samp(smMesh,s_id,t_id); |
1154 |
|
|
1155 |
< |
if(test && r_id != INVALID) |
1156 |
< |
smMesh_remove_vertex(sm,r_id); |
1157 |
< |
|
1158 |
< |
return(test); |
1155 |
> |
/* If new sample replaces existing one- remove that vertex now */ |
1156 |
> |
if(r_id != INVALID) |
1157 |
> |
{ |
1158 |
> |
smRemoveVertex(sm,r_id); |
1159 |
> |
sDelete_samp(SM_SAMP(sm),r_id); |
1160 |
> |
} |
1161 |
> |
return(s_id); |
1162 |
|
} |
1163 |
|
|
1164 |
|
/* |
1177 |
|
COLR c; |
1178 |
|
FVECT dir; |
1179 |
|
FVECT p; |
1120 |
– |
|
1180 |
|
{ |
1181 |
|
int s_id; |
1182 |
< |
int debug=0; |
1124 |
< |
static FILE *fp; |
1125 |
< |
static int cnt=0,n=3010; |
1182 |
> |
|
1183 |
|
/* First check if this the first sample: if so initialize mesh */ |
1184 |
|
if(SM_NUM_SAMP(smMesh) == 0) |
1185 |
< |
{ |
1186 |
< |
smInit_sm(smMesh,odev.v.vp); |
1187 |
< |
#if 0 |
1131 |
< |
fp = fopen("Debug_data.view","w"); |
1132 |
< |
fprintf(fp,"%d %d %f %f %f ",1280,1024,odev.v.vp[0],odev.v.vp[1], |
1133 |
< |
odev.v.vp[2]); |
1134 |
< |
fprintf(fp,"%f %f %f ",odev.v.vdir[0],odev.v.vdir[1], |
1135 |
< |
odev.v.vdir[2]); |
1136 |
< |
fprintf(fp,"%f %f %f ",odev.v.vup[0],odev.v.vup[1],odev.v.vup[2]); |
1137 |
< |
fprintf(fp,"%f %f ",odev.v.horiz,odev.v.vert); |
1138 |
< |
fclose(fp); |
1139 |
< |
fp = fopen("Debug_data","w"); |
1140 |
< |
#endif |
1141 |
< |
} |
1142 |
< |
#if 0 |
1143 |
< |
fprintf(fp,"%f %f %f %f %f %f ",p[0],p[1],p[2],(float)c[0]/255.0,(float)c[1]/255.0, |
1144 |
< |
(float)c[2]/255.0); |
1145 |
< |
#endif |
1146 |
< |
|
1147 |
< |
/* Allocate space for a sample */ |
1148 |
< |
s_id = smAlloc_samp(smMesh,c,dir,p); |
1149 |
< |
#if 0 |
1150 |
< |
if(cnt==n) |
1151 |
< |
return(-1); |
1152 |
< |
cnt++; |
1153 |
< |
#endif |
1154 |
< |
/* Add the sample to the mesh */ |
1155 |
< |
if(!smAdd_samp(smMesh,s_id,p,dir)) |
1156 |
< |
{ |
1157 |
< |
/* If the sample space was not used: return */ |
1158 |
< |
smUnalloc_samp(smMesh,s_id); |
1159 |
< |
s_id = INVALID; |
1185 |
> |
{ |
1186 |
> |
smInit_sm(smMesh,odev.v.vp); |
1187 |
> |
sClear_all_flags(SM_SAMP(smMesh)); |
1188 |
|
} |
1189 |
+ |
/* Add the sample to the mesh */ |
1190 |
+ |
s_id = smAdd_samp(smMesh,c,dir,p,INVALID); |
1191 |
+ |
|
1192 |
|
return(s_id); |
1193 |
|
|
1194 |
|
} |
1252 |
|
for(nbr_id=0; nbr_id < 3; nbr_id++) |
1253 |
|
T_NTH_NBR(SM_NTH_TRI(sm,ids[tri_id]),nbr_id) = smBase_nbrs[tri_id][nbr_id]; |
1254 |
|
|
1224 |
– |
|
1255 |
|
/* Now add the centroids of the faces */ |
1256 |
|
for(tri_id=0;tri_id < 4; tri_id++) |
1257 |
|
{ |
1263 |
|
normalize(cntr); |
1264 |
|
VADD(cntr,cntr,SM_VIEW_CENTER(sm)); |
1265 |
|
s_id = smAdd_base_vertex(sm,cntr); |
1266 |
< |
smAdd_samp(sm,s_id,NULL,NULL); |
1266 |
> |
smAdd_samp(sm,NULL,NULL,cntr,s_id); |
1267 |
|
} |
1268 |
|
return(1); |
1269 |
|
|
1342 |
|
cnt = SM_NUM_SAMP(sm); |
1343 |
|
/* Calculate the difference between the current and new viewpoint*/ |
1344 |
|
/* Will need to subtract this off of sky points */ |
1345 |
< |
VSUB(ov,v->vp,SM_VIEW_CENTER(sm)); |
1345 |
> |
VCOPY(ov,SM_VIEW_CENTER(sm)); |
1346 |
|
/* Initialize the mesh to 0 samples and the base triangles */ |
1347 |
|
|
1348 |
|
/* Go through all samples and add in if in the new view frustum, and |
1349 |
|
the dir is <= 30 degrees from new view |
1350 |
|
*/ |
1351 |
< |
j=0; |
1351 |
> |
smInit_sm(sm,v->vp); |
1352 |
|
for(i=0; i < cnt; i++) |
1353 |
|
{ |
1354 |
|
/* First check if sample visible(conservative approx: if one of tris |
1361 |
|
{ |
1362 |
|
VSUB(p,SM_NTH_WV(sm,i),v->vp); |
1363 |
|
normalize(p); |
1364 |
< |
d = fdir2diff(SM_NTH_W_DIR(sm,i), p); |
1364 |
> |
decodedir(dir,SM_NTH_W_DIR(sm,i)); |
1365 |
> |
d = 2. - 2.*DOT(dir,p); |
1366 |
|
if (d > MAXDIFF2) |
1367 |
|
continue; |
1368 |
+ |
VCOPY(p,SM_NTH_WV(sm,i)); |
1369 |
+ |
smAdd_samp(sm,NULL,dir,p,i); |
1370 |
|
} |
1371 |
< |
sReset_samp(SM_SAMP(sm),j,i); |
1372 |
< |
j++; |
1371 |
> |
else |
1372 |
> |
{ |
1373 |
> |
VSUB(dir,SM_NTH_WV(sm,i),ov); |
1374 |
> |
smAdd_samp(sm,NULL,dir,NULL,i); |
1375 |
> |
} |
1376 |
> |
|
1377 |
|
} |
1378 |
< |
smInit_sm(sm,v->vp); |
1342 |
< |
for(i=0; i< j; i++) |
1343 |
< |
{ |
1344 |
< |
S_SET_FLAG(i); |
1345 |
< |
VCOPY(p,SM_NTH_WV(sm,i)); |
1346 |
< |
smAdd_samp(sm,i,p,NULL); |
1347 |
< |
} |
1348 |
< |
SM_NUM_SAMP(sm) = j; |
1349 |
< |
smNew_tri_cnt = SM_SAMPLE_TRIS(sm); |
1378 |
> |
smNew_tri_cnt = SM_SAMPLE_TRIS(sm); |
1379 |
|
#ifdef DEBUG |
1380 |
|
eputs("smRebuild_mesh():done\n"); |
1381 |
|
#endif |
1396 |
|
for(i = QT_SET_CNT(t_set); i > 0; i--) |
1397 |
|
{ |
1398 |
|
t_id = QT_SET_NEXT_ELEM(optr); |
1399 |
< |
|
1399 |
> |
if(SM_IS_NTH_T_BASE(smMesh,t_id)) |
1400 |
> |
continue; |
1401 |
|
t = SM_NTH_TRI(smMesh,t_id); |
1402 |
|
if(!T_IS_VALID(t)) |
1403 |
|
continue; |
1374 |
– |
|
1404 |
|
pid0 = T_NTH_V(t,0); |
1405 |
|
pid1 = T_NTH_V(t,1); |
1406 |
|
pid2 = T_NTH_V(t,2); |
1513 |
|
/* orig will be updated-so preserve original value */ |
1514 |
|
if(!smMesh) |
1515 |
|
return; |
1516 |
+ |
#ifdef TEST_DRIVER |
1517 |
+ |
Picking= TRUE; |
1518 |
+ |
#endif |
1519 |
|
point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh)); |
1520 |
|
d = -DOT(b,dir); |
1521 |
|
if(EQUAL_VEC3(orig,SM_VIEW_CENTER(smMesh)) || EQUAL(fabs(d),1.0)) |