18 |
|
|
19 |
|
SM *smMesh = NULL; |
20 |
|
double smDist_sum=0; |
21 |
+ |
#define S_INC 1000 |
22 |
|
int smNew_tri_cnt=0; |
23 |
< |
double smMinSampDiff = 4.25e-4; /* min edge length in radians */ |
23 |
> |
int smNew_tri_size=0; |
24 |
|
|
25 |
+ |
#define SM_MIN_SAMP_DIFF 1e-4/* min edge length in radians */ |
26 |
+ |
|
27 |
|
/* Each edge extends .5536 radians - 31.72 degrees */ |
28 |
|
static FVECT icosa_verts[162] = |
29 |
|
{{-0.018096,0.495400,0.868477},{0.018614,-0.554780,0.831789}, |
448 |
|
|
449 |
|
total_points = n + SM_EXTRA_POINTS; |
450 |
|
|
451 |
< |
max_tris = total_points*4; |
451 |
> |
max_tris = total_points*2; |
452 |
|
/* Now allocate space for mesh vertices and triangles */ |
453 |
|
max_tris = smAlloc_mesh(smMesh, total_points, max_tris); |
454 |
|
|
571 |
|
/* If the set size is below expansion threshold,or at maximum |
572 |
|
number of quadtree levels : just add */ |
573 |
|
optr = qtqueryset(qt); |
574 |
< |
if(QT_SET_CNT(optr) < QT_SET_THRESHOLD || (n >= QT_MAX_LEVELS)) |
574 |
> |
if(QT_SET_CNT(optr) < QT_SET_THRESHOLD || (n > (QT_MAX_LEVELS-2))) |
575 |
|
return(qtadduelem(qt,t_id)); |
576 |
|
/* otherwise: expand node- and insert tri, and reinsert existing tris |
577 |
|
in set to children of new node |
700 |
|
SM_NTH_VERT(sm,v2_id) = t_id; |
701 |
|
|
702 |
|
if(SM_BASE_ID(sm,v0_id) || SM_BASE_ID(sm,v1_id) || SM_BASE_ID(sm,v2_id)) |
700 |
– |
{ |
701 |
– |
smClear_tri_flags(sm,t_id); |
703 |
|
SM_SET_NTH_T_BASE(sm,t_id); |
703 |
– |
} |
704 |
|
else |
705 |
< |
{ |
706 |
< |
SM_CLR_NTH_T_BASE(sm,t_id); |
707 |
< |
SM_SET_NTH_T_ACTIVE(sm,t_id); |
708 |
< |
SM_SET_NTH_T_NEW(sm,t_id); |
709 |
< |
S_SET_FLAG(T_NTH_V(t,0)); |
710 |
< |
S_SET_FLAG(T_NTH_V(t,1)); |
711 |
< |
S_SET_FLAG(T_NTH_V(t,2)); |
712 |
< |
SM_SAMPLE_TRIS(sm)++; |
713 |
< |
smNew_tri_cnt++; |
714 |
< |
} |
705 |
> |
if(SM_DIR_ID(sm,v0_id) && SM_DIR_ID(sm,v1_id) && SM_DIR_ID(sm,v2_id)) |
706 |
> |
SM_SET_NTH_T_BG(sm,t_id); |
707 |
|
|
708 |
+ |
S_SET_FLAG(T_NTH_V(t,0)); |
709 |
+ |
S_SET_FLAG(T_NTH_V(t,1)); |
710 |
+ |
S_SET_FLAG(T_NTH_V(t,2)); |
711 |
+ |
|
712 |
+ |
SM_SET_NTH_T_ACTIVE(sm,t_id); |
713 |
+ |
SM_SET_NTH_T_NEW(sm,t_id); |
714 |
+ |
|
715 |
+ |
SM_SAMPLE_TRIS(sm)++; |
716 |
+ |
smNew_tri_cnt++; |
717 |
+ |
|
718 |
|
/* return initialized triangle */ |
719 |
|
return(t_id); |
720 |
|
} |
771 |
|
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,1))) || |
772 |
|
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,2)))) |
773 |
|
goto Ltri_error; |
774 |
+ |
/* |
775 |
|
if(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,1)) || |
776 |
|
SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) || |
777 |
|
SM_NTH_TRI(sm,T_NTH_NBR(ta,1))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) || |
779 |
|
SM_NTH_TRI(sm,T_NTH_NBR(tb,0))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) || |
780 |
|
SM_NTH_TRI(sm,T_NTH_NBR(tb,1))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) ) |
781 |
|
goto Ltri_error; |
782 |
+ |
*/ |
783 |
|
#endif |
784 |
|
/* Reset neighbor pointers of original neighbors */ |
785 |
|
n = SM_NTH_TRI(sm,T_NTH_NBR(t,enext)); |
815 |
|
|
816 |
|
remove_from_list(t_id,add_ptr); |
817 |
|
remove_from_list(t1_id,add_ptr); |
818 |
< |
#if 1 |
818 |
> |
|
819 |
|
smDelete_tri(sm,t_id); |
820 |
|
smDelete_tri(sm,t1_id); |
817 |
– |
#else |
818 |
– |
*del_ptr = push_data(*del_ptr,t_id); |
819 |
– |
*del_ptr = push_data(*del_ptr,t1_id); |
820 |
– |
#endif |
821 |
|
|
822 |
– |
|
823 |
– |
|
822 |
|
*tn_id = ta_id; |
823 |
|
*tn1_id = tb_id; |
824 |
|
|
848 |
|
SM *sm; |
849 |
|
LIST *add_list; |
850 |
|
{ |
851 |
< |
int t_id,i; |
851 |
> |
int t_id; |
852 |
|
TRI *t; |
855 |
– |
OBJECT *optr; |
853 |
|
|
854 |
|
while(add_list) |
855 |
|
{ |
869 |
|
FVECT p,p0,p1,p2; |
870 |
|
int e,e1,swapped = 0; |
871 |
|
int t_id,t_opp_id; |
872 |
< |
LIST *del_list=NULL; |
872 |
> |
LIST *del_list=NULL,*lptr; |
873 |
|
|
874 |
|
VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm)); |
875 |
|
while(tlist) |
906 |
|
tlist = push_data(tlist,t_opp_id); |
907 |
|
} |
908 |
|
} |
909 |
< |
#if 0 |
913 |
< |
while(del_list) |
914 |
< |
{ |
915 |
< |
t_id = pop_list(&del_list); |
916 |
< |
smDelete_tri(sm,t_id); |
917 |
< |
} |
918 |
< |
#endif |
909 |
> |
|
910 |
|
smUpdate_locator(sm,add_list); |
911 |
|
|
912 |
|
return(swapped); |
958 |
|
FVECT npt; |
959 |
|
TRI *tri,*nbr,*topp; |
960 |
|
|
970 |
– |
|
961 |
|
add_list = NULL; |
962 |
|
for(i=0; i<3;i++) |
963 |
|
v_id[i] = T_NTH_V(SM_NTH_TRI(sm,tri_id),i); |
1216 |
|
optr = qtqueryset(qt); |
1217 |
|
tri_id = smTri_in_set(sm,tpt,optr,onptr,whichptr); |
1218 |
|
|
1229 |
– |
#ifdef DEBUG |
1230 |
– |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),0))) || |
1231 |
– |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),1))) || |
1232 |
– |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),2)))) |
1233 |
– |
eputs("Invalid tri nbrs smPointLocateTri()\n"); |
1234 |
– |
#endif |
1219 |
|
return(tri_id); |
1220 |
|
} |
1221 |
|
|
1269 |
|
|
1270 |
|
for(i=0; i<3; i++) |
1271 |
|
{ |
1272 |
< |
if(SM_BASE_ID(sm,vid[i])) |
1273 |
< |
{ |
1274 |
< |
bcnt++; |
1275 |
< |
continue; |
1276 |
< |
} |
1293 |
< |
if(SM_DIR_ID(sm,vid[i])) |
1294 |
< |
dcnt++; |
1295 |
< |
VSUB(diff[i],SM_NTH_WV(sm,vid[i]),p); |
1296 |
< |
/* If same world point: replace */ |
1272 |
> |
if(SM_BASE_ID(sm,vid[i])) |
1273 |
> |
bcnt++; |
1274 |
> |
if(SM_DIR_ID(sm,vid[i])) |
1275 |
> |
dcnt++; |
1276 |
> |
|
1277 |
|
} |
1278 |
|
/* TEST 1: If the new sample is close in ws, and close in the spherical |
1279 |
|
projection to one of the triangle vertex samples |
1280 |
|
*/ |
1281 |
+ |
#if 0 |
1282 |
|
norm = FALSE; |
1302 |
– |
if(bcnt + dcnt != 3) |
1303 |
– |
{ |
1283 |
|
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1284 |
|
ds = DOT(spt,spt); |
1285 |
|
dnear = FHUGE; |
1286 |
|
for(i=0; i<3; i++) |
1287 |
|
{ |
1309 |
– |
if(SM_BASE_ID(sm,vid[i]) || SM_DIR_ID(sm,vid[i])) |
1310 |
– |
continue; |
1288 |
|
d = DOT(diff[i],diff[i])/ds; |
1289 |
|
if(d < dnear) |
1290 |
|
{ |
1293 |
|
} |
1294 |
|
} |
1295 |
|
|
1296 |
< |
if(dnear <= smMinSampDiff*smMinSampDiff) |
1296 |
> |
if(dnear <= SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF) |
1297 |
|
{ |
1298 |
|
/* Pick the point with dir closest to that of the canonical view |
1299 |
|
if it is the new sample: mark existing point for deletion |
1300 |
|
*/ |
1301 |
+ |
if(SM_BASE_ID(sm,nearid)) |
1302 |
+ |
{ |
1303 |
+ |
*rptr = nearid; |
1304 |
+ |
return(TRUE); |
1305 |
+ |
} |
1306 |
+ |
if(SM_DIR_ID(sm,nearid)) |
1307 |
+ |
return(FALSE); |
1308 |
+ |
if(!dir) |
1309 |
+ |
{ |
1310 |
+ |
*rptr = nearid; |
1311 |
+ |
return(TRUE); |
1312 |
+ |
} |
1313 |
|
normalize(spt); |
1314 |
|
norm = TRUE; |
1315 |
|
VSUB(npt,SM_NTH_WV(sm,nearid),SM_VIEW_CENTER(sm)); |
1317 |
|
d = fdir2diff(SM_NTH_W_DIR(sm,nearid), npt); |
1318 |
|
d2 = 2. - 2.*DOT(dir,spt); |
1319 |
|
/* The existing sample is a better sample:punt */ |
1320 |
< |
if(d2 > d) |
1320 |
> |
if(d2 > d) |
1321 |
|
return(FALSE); |
1322 |
< |
else |
1323 |
< |
{ |
1324 |
< |
/* The new sample is better: mark the existing one |
1322 |
> |
else |
1323 |
> |
{ |
1324 |
> |
/* The new sample is better: mark the existing one |
1325 |
|
for deletion after the new one is added*/ |
1326 |
< |
*rptr = nearid; |
1327 |
< |
return(TRUE); |
1339 |
< |
} |
1326 |
> |
*rptr = nearid; |
1327 |
> |
return(TRUE); |
1328 |
|
} |
1329 |
< |
} |
1329 |
> |
} |
1330 |
> |
|
1331 |
|
/* TEST 3: If the spherical projection of new is < S_REPLACE_EPS |
1332 |
|
from a base point: Edge length is constrained to subtend <45 degrees: |
1333 |
|
original base mesh edges are approx 32 degrees- so have about 13 degrees |
1334 |
|
to work in: S_REPLACE_EPS is the square of the radian value |
1335 |
|
*/ |
1336 |
+ |
|
1337 |
|
if(bcnt) |
1338 |
|
{ |
1339 |
|
dnear = FHUGE; |
1350 |
– |
if(bcnt + dcnt ==3) |
1351 |
– |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1340 |
|
if(!norm) |
1341 |
|
normalize(spt); |
1342 |
|
|
1346 |
|
continue; |
1347 |
|
VSUB(npt,SM_NTH_WV(sm,vid[i]),SM_VIEW_CENTER(sm)); |
1348 |
|
d = DIST_SQ(npt,spt); |
1349 |
< |
if(d < S_REPLACE_EPS && d < dnear) |
1349 |
> |
if(dnear <= SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF && d< near) |
1350 |
|
{ |
1351 |
|
dnear = d; |
1352 |
|
nearid = vid[i]; |
1359 |
|
return(TRUE); |
1360 |
|
} |
1361 |
|
} |
1362 |
+ |
#else |
1363 |
+ |
{ |
1364 |
+ |
FVECT nearpt; |
1365 |
+ |
dnear = FHUGE; |
1366 |
+ |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1367 |
+ |
ds = DOT(spt,spt); |
1368 |
+ |
normalize(spt); |
1369 |
+ |
|
1370 |
+ |
for(i=0; i<3; i++) |
1371 |
+ |
{ |
1372 |
|
|
1373 |
+ |
VSUB(npt,SM_NTH_WV(sm,vid[i]),SM_VIEW_CENTER(sm)); |
1374 |
+ |
|
1375 |
+ |
if(!SM_BASE_ID(sm,vid[i]) && !SM_DIR_ID(sm,vid[i])) |
1376 |
+ |
normalize(npt); |
1377 |
+ |
|
1378 |
+ |
d = DIST_SQ(npt,spt); |
1379 |
+ |
if(d < SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF && d < dnear) |
1380 |
+ |
{ |
1381 |
+ |
dnear = d; |
1382 |
+ |
nearid = vid[i]; |
1383 |
+ |
VCOPY(nearpt,npt); |
1384 |
+ |
} |
1385 |
+ |
|
1386 |
+ |
} |
1387 |
+ |
if(dnear != FHUGE) |
1388 |
+ |
{ |
1389 |
+ |
/* Pick the point with dir closest to that of the canonical view |
1390 |
+ |
if it is the new sample: mark existing point for deletion |
1391 |
+ |
*/ |
1392 |
+ |
if(SM_BASE_ID(sm,nearid)) |
1393 |
+ |
{ |
1394 |
+ |
*rptr = nearid; |
1395 |
+ |
return(TRUE); |
1396 |
+ |
} |
1397 |
+ |
if(SM_DIR_ID(sm,nearid)) |
1398 |
+ |
return(FALSE); |
1399 |
+ |
if(!dir) |
1400 |
+ |
{ |
1401 |
+ |
*rptr = nearid; |
1402 |
+ |
return(TRUE); |
1403 |
+ |
} |
1404 |
+ |
d = fdir2diff(SM_NTH_W_DIR(sm,nearid), nearpt); |
1405 |
+ |
d2 = 2. - 2.*DOT(dir,spt); |
1406 |
+ |
/* The existing sample is a better sample:punt */ |
1407 |
+ |
if(d2 > d) |
1408 |
+ |
return(FALSE); |
1409 |
+ |
else |
1410 |
+ |
{ |
1411 |
+ |
/* The new sample is better: mark the existing one |
1412 |
+ |
for deletion after the new one is added*/ |
1413 |
+ |
*rptr = nearid; |
1414 |
+ |
return(TRUE); |
1415 |
+ |
} |
1416 |
+ |
} |
1417 |
+ |
} |
1418 |
+ |
#endif |
1419 |
|
/* TEST 4: |
1420 |
|
If the addition of the new sample point would introduce a "puncture" |
1421 |
|
or cause new triangles with large depth differences:dont add: |
1422 |
|
*/ |
1423 |
|
if(bcnt || dcnt) |
1424 |
|
return(TRUE); |
1425 |
+ |
|
1426 |
|
/* If the new point is in front of the existing points- add */ |
1427 |
|
dv = DIST_SQ(SM_NTH_WV(sm,vid[0]),SM_VIEW_CENTER(sm)); |
1428 |
|
if(ds < dv) |
1429 |
|
return(TRUE); |
1430 |
|
|
1431 |
|
d01 = DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_NTH_WV(sm,vid[0])); |
1432 |
+ |
VSUB(diff[0],SM_NTH_WV(sm,vid[0]),p); |
1433 |
|
s0 = DOT(diff[0],diff[0]); |
1434 |
|
if(s0 < S_REPLACE_SCALE*d01) |
1435 |
|
return(TRUE); |
1436 |
+ |
|
1437 |
|
d12 = DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_NTH_WV(sm,vid[1])); |
1438 |
|
if(s0 < S_REPLACE_SCALE*d12) |
1439 |
|
return(TRUE); |
1441 |
|
if(s0 < S_REPLACE_SCALE*d20) |
1442 |
|
return(TRUE); |
1443 |
|
d = MIN3(d01,d12,d20); |
1444 |
< |
s1 = DOT(diff[1],diff[1]); |
1444 |
> |
VSUB(diff[1],SM_NTH_WV(sm,vid[1]),p); |
1445 |
> |
s1 = DOT(diff[1],diff[1]); |
1446 |
|
if(s1 < S_REPLACE_SCALE*d) |
1447 |
|
return(TRUE); |
1448 |
+ |
VSUB(diff[2],SM_NTH_WV(sm,vid[2]),p); |
1449 |
|
s2 = DOT(diff[2],diff[2]); |
1450 |
|
if(s2 < S_REPLACE_SCALE*d) |
1451 |
|
return(TRUE); |
1462 |
|
return(FALSE); |
1463 |
|
} |
1464 |
|
|
1465 |
< |
|
1417 |
< |
int |
1418 |
< |
smAlloc_samp(sm) |
1465 |
> |
smReplace_base_samp(sm,b_id,s_id,tri,t_id,which) |
1466 |
|
SM *sm; |
1467 |
+ |
int b_id,s_id; |
1468 |
+ |
TRI *tri; |
1469 |
+ |
int t_id,which; |
1470 |
|
{ |
1471 |
< |
int s_id,replaced,cnt; |
1422 |
< |
SAMP *s; |
1423 |
< |
FVECT p; |
1471 |
> |
TRI *t; |
1472 |
|
|
1473 |
< |
s = SM_SAMP(sm); |
1474 |
< |
s_id = sAlloc_samp(s,&replaced); |
1475 |
< |
|
1476 |
< |
cnt=0; |
1477 |
< |
while(replaced) |
1473 |
> |
SM_NTH_VERT(sm,s_id) = t_id; |
1474 |
> |
T_NTH_V(tri,which) = s_id; |
1475 |
> |
if(!(SM_BASE_ID(sm,T_NTH_V(tri,(which+1)%3)) || |
1476 |
> |
SM_BASE_ID(sm,T_NTH_V(tri,(which+2)%3)))) |
1477 |
> |
SM_CLR_NTH_T_BASE(sm,t_id); |
1478 |
> |
if(!SM_IS_NTH_T_NEW(sm,t_id)) |
1479 |
|
{ |
1480 |
< |
if(smRemoveVertex(sm,s_id)) |
1481 |
< |
break; |
1433 |
< |
s_id = sAlloc_samp(s,&replaced); |
1434 |
< |
cnt++; |
1435 |
< |
if(cnt > S_MAX_SAMP(s)) |
1436 |
< |
error(CONSISTENCY,"smAlloc_samp():unable to find free samp\n"); |
1480 |
> |
smNew_tri_cnt++; |
1481 |
> |
SM_SET_NTH_T_NEW(sm,t_id); |
1482 |
|
} |
1483 |
< |
return(s_id); |
1483 |
> |
t_id = smTri_next_ccw_nbr(sm,tri,b_id); |
1484 |
> |
while(t_id != INVALID) |
1485 |
> |
{ |
1486 |
> |
t = SM_NTH_TRI(sm,t_id); |
1487 |
> |
which = T_WHICH_V(t,b_id); |
1488 |
> |
T_NTH_V(t,which) = s_id; |
1489 |
> |
/* Check if still a base triangle */ |
1490 |
> |
if(!(SM_BASE_ID(sm,T_NTH_V(t,(which+1)%3)) || |
1491 |
> |
SM_BASE_ID(sm,T_NTH_V(t,(which+2)%3)))) |
1492 |
> |
SM_CLR_NTH_T_BASE(sm,t_id); |
1493 |
> |
if(!SM_IS_NTH_T_NEW(sm,t_id)) |
1494 |
> |
{ |
1495 |
> |
smNew_tri_cnt++; |
1496 |
> |
SM_SET_NTH_T_NEW(sm,t_id); |
1497 |
> |
} |
1498 |
> |
t_id = smTri_next_ccw_nbr(sm,t,b_id); |
1499 |
> |
} |
1500 |
|
} |
1501 |
|
|
1502 |
|
int |
1506 |
|
FVECT dir,p; |
1507 |
|
int s_id,t_id,o_id,on,which; |
1508 |
|
{ |
1509 |
< |
int tonemap,v_id; |
1509 |
> |
int v_id,tri_id; |
1510 |
|
TRI *t,*tri; |
1511 |
|
|
1512 |
|
tri = SM_NTH_TRI(sm,t_id); |
1515 |
|
/* If it is a base id, need new sample */ |
1516 |
|
if(SM_BASE_ID(sm,v_id)) |
1517 |
|
{ |
1518 |
< |
tonemap = (SM_TONE_MAP(sm) > s_id); |
1519 |
< |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id,tonemap); |
1459 |
< |
SM_NTH_VERT(sm,s_id) = t_id; |
1460 |
< |
T_NTH_V(tri,which) = s_id; |
1461 |
< |
if(!(SM_BASE_ID(sm,T_NTH_V(tri,(which+1)%3)) || |
1462 |
< |
SM_BASE_ID(sm,T_NTH_V(tri,(which+2)%3)))) |
1463 |
< |
SM_CLR_NTH_T_BASE(sm,t_id); |
1464 |
< |
t_id = smTri_next_ccw_nbr(sm,tri,v_id); |
1465 |
< |
while(t_id != INVALID) |
1466 |
< |
{ |
1467 |
< |
t = SM_NTH_TRI(sm,t_id); |
1468 |
< |
which = T_WHICH_V(t,v_id); |
1469 |
< |
T_NTH_V(t,which) = s_id; |
1470 |
< |
/* Check if still a base triangle */ |
1471 |
< |
if(!(SM_BASE_ID(sm,T_NTH_V(t,(which+1)%3)) || |
1472 |
< |
SM_BASE_ID(sm,T_NTH_V(t,(which+2)%3)))) |
1473 |
< |
SM_CLR_NTH_T_BASE(sm,t_id); |
1474 |
< |
t_id = smTri_next_ccw_nbr(sm,t,v_id); |
1475 |
< |
} |
1518 |
> |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id); |
1519 |
> |
smReplace_base_samp(sm,v_id,s_id,tri,t_id,which); |
1520 |
|
return(s_id); |
1521 |
|
} |
1522 |
< |
else |
1523 |
< |
if(on == ON_V || !p) |
1522 |
> |
if(dir) |
1523 |
> |
{ |
1524 |
> |
/* If world point */ |
1525 |
> |
/* if existing point is a dir: leave */ |
1526 |
> |
if(SM_DIR_ID(sm,v_id)) |
1527 |
> |
return(INVALID); |
1528 |
> |
if(on == ON_V) |
1529 |
|
{ |
1530 |
< |
tonemap = (SM_TONE_MAP(sm) > v_id); |
1531 |
< |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id,tonemap); |
1530 |
> |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id); |
1531 |
> |
|
1532 |
> |
if(!SM_IS_NTH_T_NEW(sm,t_id)) |
1533 |
> |
{ |
1534 |
> |
smNew_tri_cnt++; |
1535 |
> |
SM_SET_NTH_T_NEW(sm,t_id); |
1536 |
> |
} |
1537 |
> |
tri_id = smTri_next_ccw_nbr(sm,tri,v_id); |
1538 |
> |
while(tri_id != t_id) |
1539 |
> |
{ |
1540 |
> |
t = SM_NTH_TRI(sm,tri_id); |
1541 |
> |
if(!SM_IS_NTH_T_NEW(sm,tri_id)) |
1542 |
> |
{ |
1543 |
> |
smNew_tri_cnt++; |
1544 |
> |
SM_SET_NTH_T_NEW(sm,tri_id); |
1545 |
> |
} |
1546 |
> |
|
1547 |
> |
tri_id = smTri_next_ccw_nbr(sm,t,v_id); |
1548 |
> |
} |
1549 |
|
return(v_id); |
1550 |
|
} |
1551 |
< |
else /* on == ON_P */ |
1552 |
< |
{ |
1553 |
< |
FVECT spt,npt; |
1554 |
< |
double d,d2; |
1551 |
> |
/* on == ON_P */ |
1552 |
> |
else |
1553 |
> |
{ |
1554 |
> |
FVECT spt,npt; |
1555 |
> |
double d,d2; |
1556 |
|
|
1557 |
< |
/* Need to check which sample is preferable */ |
1558 |
< |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1559 |
< |
normalize(spt); |
1557 |
> |
/* Need to check which sample is preferable */ |
1558 |
> |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1559 |
> |
normalize(spt); |
1560 |
|
|
1561 |
< |
VSUB(npt,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm)); |
1562 |
< |
normalize(npt); |
1563 |
< |
d = fdir2diff(SM_NTH_W_DIR(sm,v_id), npt); |
1564 |
< |
d2 = 2. - 2.*DOT(dir,spt); |
1561 |
> |
VSUB(npt,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm)); |
1562 |
> |
normalize(npt); |
1563 |
> |
d = fdir2diff(SM_NTH_W_DIR(sm,v_id), npt); |
1564 |
> |
d2 = 2. - 2.*DOT(dir,spt); |
1565 |
|
/* The existing sample is a better sample:punt */ |
1566 |
< |
if(d2 < d) |
1567 |
< |
{ |
1568 |
< |
/* The new sample has better information- replace values */ |
1569 |
< |
tonemap = (SM_TONE_MAP(sm) > v_id); |
1570 |
< |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id,tonemap); |
1571 |
< |
} |
1572 |
< |
return(v_id); |
1566 |
> |
if(d2 < d) |
1567 |
> |
{ |
1568 |
> |
/* The new sample has better information- replace values */ |
1569 |
> |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id); |
1570 |
> |
if(!SM_IS_NTH_T_NEW(sm,t_id)) |
1571 |
> |
{ |
1572 |
> |
smNew_tri_cnt++; |
1573 |
> |
SM_SET_NTH_T_NEW(sm,t_id); |
1574 |
> |
} |
1575 |
> |
|
1576 |
> |
tri_id = smTri_next_ccw_nbr(sm,tri,v_id); |
1577 |
> |
while(tri_id != t_id) |
1578 |
> |
{ |
1579 |
> |
t = SM_NTH_TRI(sm,tri_id); |
1580 |
> |
if(!SM_IS_NTH_T_NEW(sm,tri_id)) |
1581 |
> |
{ |
1582 |
> |
smNew_tri_cnt++; |
1583 |
> |
SM_SET_NTH_T_NEW(sm,tri_id); |
1584 |
> |
} |
1585 |
> |
tri_id = smTri_next_ccw_nbr(sm,t,v_id); |
1586 |
> |
} |
1587 |
> |
} |
1588 |
> |
return(v_id); |
1589 |
> |
} |
1590 |
> |
} |
1591 |
> |
else |
1592 |
> |
{ /* New point is a dir */ |
1593 |
> |
return(INVALID); |
1594 |
|
} |
1595 |
|
} |
1596 |
|
|
1597 |
+ |
int |
1598 |
+ |
smAlloc_samp(sm) |
1599 |
+ |
SM *sm; |
1600 |
+ |
{ |
1601 |
+ |
int s_id,replaced,cnt; |
1602 |
+ |
SAMP *s; |
1603 |
+ |
FVECT p; |
1604 |
+ |
|
1605 |
+ |
s = SM_SAMP(sm); |
1606 |
+ |
s_id = sAlloc_samp(s,&replaced); |
1607 |
+ |
|
1608 |
+ |
cnt=0; |
1609 |
+ |
while(replaced) |
1610 |
+ |
{ |
1611 |
+ |
if(smRemoveVertex(sm,s_id)) |
1612 |
+ |
break; |
1613 |
+ |
s_id = sAlloc_samp(s,&replaced); |
1614 |
+ |
cnt++; |
1615 |
+ |
if(cnt > S_MAX_SAMP(s)) |
1616 |
+ |
error(CONSISTENCY,"smAlloc_samp():unable to find free samp\n"); |
1617 |
+ |
} |
1618 |
+ |
return(s_id); |
1619 |
+ |
} |
1620 |
+ |
|
1621 |
+ |
|
1622 |
|
/* Add sample to the mesh: |
1623 |
|
|
1624 |
|
the sample can be a world space or directional point. If o_id !=INVALID, |
1650 |
|
/* If sample is a world space point */ |
1651 |
|
if(p) |
1652 |
|
{ |
1653 |
< |
t_id = smPointLocateTri(sm,p,&on,&which); |
1654 |
< |
if(t_id == INVALID) |
1653 |
> |
while(1) |
1654 |
> |
{ |
1655 |
> |
t_id = smPointLocateTri(sm,p,&on,&which); |
1656 |
> |
if(t_id == INVALID) |
1657 |
|
{ |
1658 |
|
#ifdef DEBUG |
1659 |
< |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
1659 |
> |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
1660 |
|
#endif |
1661 |
+ |
smUnalloc_samp(sm,s_id); |
1662 |
+ |
return(INVALID); |
1663 |
+ |
} |
1664 |
+ |
/* If spherical projection coincides with existing sample: replace */ |
1665 |
+ |
if((on == ON_V || on == ON_P)) |
1666 |
+ |
{ |
1667 |
+ |
n_id = smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which); |
1668 |
+ |
if(n_id!= s_id) |
1669 |
+ |
smUnalloc_samp(sm,s_id); |
1670 |
+ |
return(n_id); |
1671 |
+ |
} |
1672 |
+ |
if((!(smTest_sample(sm,t_id,dir,p,&r_id)))) |
1673 |
+ |
{ |
1674 |
|
smUnalloc_samp(sm,s_id); |
1675 |
|
return(INVALID); |
1676 |
|
} |
1677 |
< |
/* If spherical projection coincides with existing sample: replace */ |
1678 |
< |
if((on == ON_V || on == ON_P)) |
1679 |
< |
{ |
1680 |
< |
if((n_id = smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which))!= s_id) |
1681 |
< |
smUnalloc_samp(sm,s_id); |
1682 |
< |
return(n_id); |
1677 |
> |
if(r_id != INVALID) |
1678 |
> |
{ |
1679 |
> |
smRemoveVertex(sm,r_id); |
1680 |
> |
sDelete_samp(SM_SAMP(sm),r_id); |
1681 |
> |
} |
1682 |
> |
else |
1683 |
> |
break; |
1684 |
|
} |
1556 |
– |
if((!(smTest_sample(sm,t_id,dir,p,&r_id)))) |
1557 |
– |
{ |
1558 |
– |
smUnalloc_samp(sm,s_id); |
1559 |
– |
return(INVALID); |
1560 |
– |
} |
1685 |
|
/* If sample is being added in the middle of the sample array: tone |
1686 |
|
map individually |
1687 |
|
*/ |
1688 |
|
/* Initialize sample */ |
1689 |
< |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id,(SM_TONE_MAP(sm)>s_id)); |
1689 |
> |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id); |
1690 |
|
|
1691 |
|
} |
1692 |
|
/* If sample is a direction vector */ |
1693 |
|
else |
1694 |
|
{ |
1695 |
|
VADD(wpt,dir,SM_VIEW_CENTER(sm)); |
1696 |
< |
t_id = smPointLocateTri(sm,wpt,&on,&which); |
1697 |
< |
if(t_id == INVALID) |
1698 |
< |
{ |
1696 |
> |
while(1) |
1697 |
> |
{ |
1698 |
> |
t_id = smPointLocateTri(sm,wpt,&on,&which); |
1699 |
> |
if(t_id == INVALID) |
1700 |
> |
{ |
1701 |
|
#ifdef DEBUG |
1702 |
< |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
1702 |
> |
eputs("smAddSamp(): can'tlocate tri containing samp\n"); |
1703 |
|
#endif |
1704 |
< |
smUnalloc_samp(sm,s_id); |
1705 |
< |
return(INVALID); |
1704 |
> |
smUnalloc_samp(sm,s_id); |
1705 |
> |
return(INVALID); |
1706 |
> |
} |
1707 |
> |
if(on == ON_V || on == ON_P) |
1708 |
> |
{ |
1709 |
> |
n_id=smReplace_samp(sm,c,NULL,wpt,s_id,t_id,o_id,on,which); |
1710 |
> |
if(n_id !=s_id) |
1711 |
> |
smUnalloc_samp(sm,s_id); |
1712 |
> |
return(n_id); |
1713 |
> |
} |
1714 |
> |
if((!(smTest_sample(sm,t_id,NULL,wpt,&r_id)))) |
1715 |
> |
{ |
1716 |
> |
smUnalloc_samp(sm,s_id); |
1717 |
> |
return(INVALID); |
1718 |
> |
} |
1719 |
> |
if(r_id != INVALID) |
1720 |
> |
{ |
1721 |
> |
smRemoveVertex(sm,r_id); |
1722 |
> |
sDelete_samp(SM_SAMP(sm),r_id); |
1723 |
> |
} |
1724 |
> |
else |
1725 |
> |
break; |
1726 |
|
} |
1581 |
– |
if(on == ON_V || on == ON_P) |
1582 |
– |
{ |
1583 |
– |
if((n_id = smReplace_samp(sm,c,wpt,NULL,s_id,t_id,o_id,on,which))!= s_id) |
1584 |
– |
smUnalloc_samp(sm,s_id); |
1585 |
– |
return(n_id); |
1586 |
– |
} |
1727 |
|
/* Allocate space for a sample and initialize */ |
1728 |
< |
sInit_samp(SM_SAMP(sm),s_id,c,wpt,NULL,o_id,(SM_TONE_MAP(sm)>s_id)); |
1728 |
> |
sInit_samp(SM_SAMP(sm),s_id,c,NULL,wpt,o_id); |
1729 |
|
} |
1730 |
|
if(!SM_DIR_ID(sm,s_id)) |
1731 |
|
{ |
1736 |
|
} |
1737 |
|
smInsert_samp(sm,s_id,t_id,on,which); |
1738 |
|
|
1599 |
– |
/* If new sample replaces existing one- remove that vertex now */ |
1600 |
– |
if(r_id != INVALID) |
1601 |
– |
{ |
1602 |
– |
smRemoveVertex(sm,r_id); |
1603 |
– |
sDelete_samp(SM_SAMP(sm),r_id); |
1604 |
– |
} |
1739 |
|
return(s_id); |
1740 |
|
} |
1741 |
|
|
1758 |
|
{ |
1759 |
|
int s_id; |
1760 |
|
|
1627 |
– |
|
1761 |
|
/* First check if this the first sample: if so initialize mesh */ |
1629 |
– |
|
1762 |
|
if(SM_NUM_SAMP(smMesh) == 0) |
1763 |
|
{ |
1764 |
|
smInit_sm(smMesh,odev.v.vp); |
1859 |
|
} |
1860 |
|
|
1861 |
|
|
1862 |
+ |
|
1863 |
|
int |
1864 |
|
smNext_valid_tri(sm,i) |
1865 |
|
SM *sm; |
1940 |
|
} |
1941 |
|
|
1942 |
|
} |
1810 |
– |
|
1811 |
– |
smNew_tri_cnt = SM_SAMPLE_TRIS(sm); |
1943 |
|
#ifdef DEBUG |
1944 |
|
fprintf(stderr,"smRebuild_mesh():done\n"); |
1945 |
|
#endif |
2276 |
|
t_id = QT_SET_NEXT_ELEM(optr); |
2277 |
|
/* Set the render flag */ |
2278 |
|
tri = SM_NTH_TRI(smMesh,t_id); |
2279 |
< |
if(!T_IS_VALID(tri) || SM_IS_NTH_T_BASE(smMesh,t_id)) |
2279 |
> |
if(!T_IS_VALID(tri)) |
2280 |
|
continue; |
2281 |
|
SM_SET_NTH_T_ACTIVE(smMesh,t_id); |
2282 |
|
/* Set the Active bits of the Vertices */ |
2283 |
|
S_SET_FLAG(T_NTH_V(tri,0)); |
2284 |
|
S_SET_FLAG(T_NTH_V(tri,1)); |
2285 |
|
S_SET_FLAG(T_NTH_V(tri,2)); |
2286 |
< |
} |
2286 |
> |
} |
2287 |
|
} |
2288 |
|
|
2289 |
|
|