286 |
|
OBJECT tset[QT_MAXSET+1],*optr; |
287 |
|
int i,id,found; |
288 |
|
FVECT v0,v1,v2; |
289 |
< |
|
289 |
> |
TRI *tri; |
290 |
|
#ifdef DEBUG_TEST_DRIVER |
291 |
|
Pick_tri = t_id; |
292 |
|
Picking = TRUE; |
323 |
|
for(optr = QT_SET_PTR(tset),i=QT_SET_CNT(tset); i > 0; i--) |
324 |
|
{ |
325 |
|
id = QT_SET_NEXT_ELEM(optr); |
326 |
< |
qtTri_from_id(id,NULL,NULL,NULL,v0,v1,v2,NULL,NULL,NULL); |
327 |
< |
found=qtAdd_tri(qtptr,q0,q1,q2,v0,v1,v2,id,n); |
326 |
> |
tri = SM_NTH_TRI(smMesh,id); |
327 |
> |
VSUB(v0,SM_T_NTH_WV(smMesh,tri,0),SM_VIEW_CENTER(smMesh)); |
328 |
> |
VSUB(v1,SM_T_NTH_WV(smMesh,tri,1),SM_VIEW_CENTER(smMesh)); |
329 |
> |
VSUB(v2,SM_T_NTH_WV(smMesh,tri,2),SM_VIEW_CENTER(smMesh)); |
330 |
> |
found = qtAdd_tri(qtptr,q0,q1,q2,v0,v1,v2,id,n); |
331 |
|
#ifdef DEBUG |
332 |
|
if(!found) |
333 |
|
eputs("add_tri_expand():Reinsert\n"); |
634 |
|
/* Delete two parent triangles */ |
635 |
|
|
636 |
|
*del = push_data(*del,t_id); |
637 |
< |
if(SM_IS_NTH_T_NEW(sm,t_id)) |
635 |
< |
SM_CLEAR_NTH_T_NEW(sm,t_id); |
636 |
< |
else |
637 |
< |
SM_CLEAR_NTH_T_BASE(sm,t_id); |
637 |
> |
T_VALID_FLAG(t) = -1; |
638 |
|
*del = push_data(*del,t1_id); |
639 |
< |
if(SM_IS_NTH_T_NEW(sm,t1_id)) |
640 |
< |
SM_CLEAR_NTH_T_NEW(sm,t1_id); |
641 |
< |
else |
642 |
< |
SM_CLEAR_NTH_T_BASE(sm,t1_id); |
639 |
> |
T_VALID_FLAG(t1) = -1; |
640 |
|
*tn_id = ta_id; |
641 |
|
*tn1_id = tb_id; |
642 |
|
} |
650 |
|
while(add_list) |
651 |
|
{ |
652 |
|
t_id = pop_list(&add_list); |
653 |
< |
if(!SM_IS_NTH_T_NEW(sm,t_id) && !SM_IS_NTH_T_BASE(sm,t_id)) |
653 |
> |
t = SM_NTH_TRI(sm,t_id); |
654 |
> |
if(!T_IS_VALID(t)) |
655 |
|
{ |
656 |
< |
SM_SET_NTH_T_NEW(sm,t_id); |
659 |
< |
smNew_tri_cnt--; |
656 |
> |
T_VALID_FLAG(t) = 1; |
657 |
|
continue; |
658 |
|
} |
662 |
– |
t = SM_NTH_TRI(sm,t_id); |
659 |
|
smLocator_add_tri(sm,t_id,T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2)); |
660 |
|
} |
661 |
|
|
662 |
|
while(del_list) |
663 |
|
{ |
664 |
|
t_id = pop_list(&del_list); |
665 |
< |
if(SM_IS_NTH_T_NEW(sm,t_id)) |
666 |
< |
{ |
667 |
< |
smDelete_tri(sm,t_id); |
668 |
< |
continue; |
665 |
> |
t = SM_NTH_TRI(sm,t_id); |
666 |
> |
if(!T_IS_VALID(t)) |
667 |
> |
{ |
668 |
> |
smLocator_remove_tri(sm,t_id); |
669 |
|
} |
674 |
– |
smLocator_remove_tri(sm,t_id); |
670 |
|
smDelete_tri(sm,t_id); |
671 |
|
} |
672 |
|
} |
673 |
|
/* MUST add check for constrained edges */ |
674 |
|
int |
675 |
< |
smFix_tris(sm,id,tlist) |
675 |
> |
smFix_tris(sm,id,tlist,add_list,del_list) |
676 |
|
SM *sm; |
677 |
|
int id; |
678 |
|
LIST *tlist; |
679 |
+ |
LIST *add_list,*del_list; |
680 |
|
{ |
681 |
|
TRI *t,*t_opp; |
682 |
|
FVECT p,p1,p2,p3; |
683 |
|
int e,e1,swapped = 0; |
684 |
|
int t_id,t_opp_id; |
689 |
– |
LIST *add_list,*del_list; |
685 |
|
|
686 |
|
|
692 |
– |
add_list = del_list = NULL; |
687 |
|
VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm)); |
688 |
|
while(tlist) |
689 |
|
{ |
692 |
|
e = (T_WHICH_V(t,id)+1)%3; |
693 |
|
t_opp_id = T_NTH_NBR(t,e); |
694 |
|
t_opp = SM_NTH_TRI(sm,t_opp_id); |
695 |
< |
|
695 |
> |
/* |
696 |
> |
VSUB(p1,SM_T_NTH_WV(sm,t_opp,0),SM_VIEW_CENTER(sm)); |
697 |
> |
VSUB(p2,SM_T_NTH_WV(sm,t_opp,1),SM_VIEW_CENTER(sm)); |
698 |
> |
VSUB(p3,SM_T_NTH_WV(sm,t_opp,2),SM_VIEW_CENTER(sm)); |
699 |
> |
*/ |
700 |
|
smDir(sm,p1,T_NTH_V(t_opp,0)); |
701 |
|
smDir(sm,p2,T_NTH_V(t_opp,1)); |
702 |
|
smDir(sm,p3,T_NTH_V(t_opp,2)); |
821 |
|
TRI *tri,*t0,*t1,*t2,*nbr; |
822 |
|
int v0_id,v1_id,v2_id,n_id; |
823 |
|
int t0_id,t1_id,t2_id; |
824 |
< |
LIST *tlist; |
824 |
> |
LIST *tlist,*add_list,*del_list; |
825 |
|
FVECT npt; |
826 |
|
|
827 |
+ |
add_list = del_list = NULL; |
828 |
|
if(s_id == SM_INVALID) |
829 |
|
s_id = smAdd_sample_point(sm,c,dir,p); |
830 |
|
|
845 |
|
} |
846 |
|
t0_id = smAdd_tri(sm,s_id,v0_id,v1_id,&t0); |
847 |
|
/* Add triangle to the locator */ |
848 |
< |
smLocator_add_tri(sm,t0_id,s_id,v0_id,v1_id); |
848 |
> |
|
849 |
> |
add_list = push_data(add_list,t0_id); |
850 |
|
|
851 |
|
t1_id = smAdd_tri(sm,s_id,v1_id,v2_id,&t1); |
852 |
< |
smLocator_add_tri(sm,t1_id,s_id,v1_id,v2_id); |
852 |
> |
add_list = push_data(add_list,t1_id); |
853 |
> |
|
854 |
|
t2_id = smAdd_tri(sm,s_id,v2_id,v0_id,&t2); |
855 |
< |
smLocator_add_tri(sm,t2_id,s_id,v2_id,v0_id); |
855 |
> |
add_list = push_data(add_list,t2_id); |
856 |
|
|
857 |
|
/* Set the neighbor pointers for the new tris */ |
858 |
|
T_NTH_NBR(t0,0) = t2_id; |
873 |
|
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2)); |
874 |
|
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id; |
875 |
|
|
876 |
< |
smLocator_remove_tri(sm,tri_id); |
877 |
< |
smDelete_tri(sm,tri_id); |
878 |
< |
|
876 |
> |
del_list = push_data(del_list,tri_id); |
877 |
> |
T_VALID_FLAG(tri) = -1; |
878 |
> |
|
879 |
|
/* Fix up the new triangles*/ |
880 |
|
tlist = push_data(NULL,t0_id); |
881 |
|
tlist = push_data(tlist,t1_id); |
882 |
|
tlist = push_data(tlist,t2_id); |
883 |
|
|
884 |
< |
smFix_tris(sm,s_id,tlist); |
884 |
> |
smFix_tris(sm,s_id,tlist,add_list,del_list); |
885 |
|
|
886 |
|
if(n_id != -1) |
887 |
|
smDelete_point(sm,n_id); |
1114 |
|
cntr[0] += .01; |
1115 |
|
cntr[1] += .02; |
1116 |
|
cntr[2] += .03; |
1117 |
< |
VADD(cntr,cntr,SM_VIEW_CENTER(sm)); |
1118 |
< |
point_on_sphere(d,cntr,SM_VIEW_CENTER(sm)); |
1119 |
< |
id = smAdd_base_vertex(sm,cntr,d); |
1117 |
> |
VADD(cntr,cntr,SM_VIEW_CENTER(sm)); |
1118 |
> |
/* WONT use dir */ |
1119 |
> |
point_on_sphere(d,cntr,SM_VIEW_CENTER(sm)); |
1120 |
> |
id = smAdd_base_vertex(sm,cntr,d); |
1121 |
|
/* test to make sure vertex allocated */ |
1122 |
|
if(id != -1) |
1123 |
|
p[i] = id; |
1226 |
|
* Find the closest sample to the given ray. Returns sample id, -1 on failure. |
1227 |
|
* "dir" is assumed to be normalized |
1228 |
|
*/ |
1227 |
– |
int |
1228 |
– |
smFindSamp(orig,dir) |
1229 |
– |
FVECT orig,dir; |
1230 |
– |
{ |
1231 |
– |
FVECT r,v0,v1,v2,a,b,p; |
1232 |
– |
OBJECT os[QT_MAXCSET+1],t_set[QT_MAXSET+1],*ts; |
1233 |
– |
QUADTREE qt; |
1234 |
– |
int s_id; |
1235 |
– |
double d; |
1229 |
|
|
1237 |
– |
/* r is the normalized vector from the view center to the current |
1238 |
– |
* ray point ( starting with "orig"). Find the cell that r falls in, |
1239 |
– |
* and test the ray against all triangles stored in the cell. If |
1240 |
– |
* the test fails, trace the projection of the ray across to the |
1241 |
– |
* next cell it intersects: iterate until either an intersection |
1242 |
– |
* is found, or the projection ray is // to the direction. The sample |
1243 |
– |
* corresponding to the triangle vertex closest to the intersection |
1244 |
– |
* point is returned. |
1245 |
– |
*/ |
1230 |
|
|
1247 |
– |
/* First test if "orig" coincides with the View_center or if "dir" is |
1248 |
– |
parallel to r formed by projecting "orig" on the sphere. In |
1249 |
– |
either case, do a single test against the cell containing the |
1250 |
– |
intersection of "dir" and the sphere |
1251 |
– |
*/ |
1252 |
– |
point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh)); |
1253 |
– |
d = -DOT(b,dir); |
1254 |
– |
if(EQUAL_VEC3(orig,SM_VIEW_CENTER(smMesh)) || EQUAL(fabs(d),1.0)) |
1255 |
– |
{ |
1256 |
– |
qt = smPointLocateCell(smMesh,dir,FALSE,NULL,NULL,NULL); |
1257 |
– |
/* Test triangles in the set for intersection with Ray:returns |
1258 |
– |
first found |
1259 |
– |
*/ |
1260 |
– |
ts = qtqueryset(qt); |
1261 |
– |
s_id = intersect_tri_set(ts,orig,dir,p); |
1262 |
– |
#ifdef DEBUG_TEST_DRIVER |
1263 |
– |
VCOPY(Pick_point[0],p); |
1264 |
– |
#endif |
1265 |
– |
return(s_id); |
1266 |
– |
} |
1267 |
– |
else |
1268 |
– |
{ |
1269 |
– |
/* Starting with orig, Walk along projection of ray onto sphere */ |
1270 |
– |
point_on_sphere(r,orig,SM_VIEW_CENTER(smMesh)); |
1271 |
– |
qt = smPointLocateCell(smMesh,r,FALSE,v0,v1,v2); |
1272 |
– |
/* os will contain all triangles seen thus far */ |
1273 |
– |
qtgetset(t_set,qt); |
1274 |
– |
setcopy(os,t_set); |
1231 |
|
|
1276 |
– |
/* Calculate ray perpendicular to dir: when projection ray is // to dir, |
1277 |
– |
the dot product will become negative. |
1278 |
– |
*/ |
1279 |
– |
VSUM(a,b,dir,d); |
1280 |
– |
d = DOT(a,b); |
1281 |
– |
while(d > 0) |
1282 |
– |
{ |
1283 |
– |
s_id = intersect_tri_set(t_set,orig,dir,p); |
1284 |
– |
#ifdef DEBUG_TEST_DRIVER |
1285 |
– |
VCOPY(Pick_point[0],p); |
1286 |
– |
#endif |
1287 |
– |
if(s_id != EMPTY) |
1288 |
– |
return(s_id); |
1289 |
– |
/* Find next cell that projection of ray intersects */ |
1290 |
– |
traceRay(r,dir,v0,v1,v2,r); |
1291 |
– |
qt = smPointLocateCell(smMesh,r,FALSE,v0,v1,v2); |
1292 |
– |
qtgetset(t_set,qt); |
1293 |
– |
/* Check triangles in set against those seen so far(os):only |
1294 |
– |
check new triangles for intersection (t_set') |
1295 |
– |
*/ |
1296 |
– |
check_set(t_set,os); |
1297 |
– |
d = DOT(a,r); |
1298 |
– |
} |
1299 |
– |
} |
1300 |
– |
#ifdef DEBUG |
1301 |
– |
eputs("smFindSamp():Pick Ray did not intersect mesh"); |
1302 |
– |
#endif |
1303 |
– |
return(EMPTY); |
1304 |
– |
} |
1305 |
– |
|
1306 |
– |
|
1232 |
|
smRebuild_mesh(sm,vp) |
1233 |
|
SM *sm; |
1234 |
|
FVECT vp; |
1322 |
|
} |
1323 |
|
|
1324 |
|
int |
1325 |
< |
smFindSamp_opt(orig,dir) |
1325 |
> |
smFindSamp(orig,dir) |
1326 |
|
FVECT orig,dir; |
1327 |
|
{ |
1328 |
|
FVECT b,p,o; |