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}, |
242 |
|
normalize(ps); |
243 |
|
} |
244 |
|
|
242 |
– |
smDir_in_cone(sm,ps,id) |
243 |
– |
SM *sm; |
244 |
– |
FVECT ps; |
245 |
– |
int id; |
246 |
– |
{ |
247 |
– |
|
248 |
– |
VSUB(ps,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm)); |
249 |
– |
normalize(ps); |
250 |
– |
} |
251 |
– |
|
245 |
|
smClear_flags(sm,which) |
246 |
|
SM *sm; |
247 |
|
int which; |
438 |
|
|
439 |
|
total_points = n + SM_EXTRA_POINTS; |
440 |
|
|
441 |
< |
max_tris = total_points*4; |
441 |
> |
max_tris = total_points*2; |
442 |
|
/* Now allocate space for mesh vertices and triangles */ |
443 |
|
max_tris = smAlloc_mesh(smMesh, total_points, max_tris); |
444 |
|
|
481 |
|
{ |
482 |
|
int max_vertices; |
483 |
|
|
491 |
– |
|
484 |
|
/* If n <=0, Just clear the existing structures */ |
485 |
|
if(n <= 0) |
486 |
|
{ |
509 |
|
} |
510 |
|
|
511 |
|
|
512 |
< |
smLocator_apply(sm,v0,v1,v2,func) |
512 |
> |
smLocator_apply(sm,v0,v1,v2,func,n) |
513 |
|
SM *sm; |
514 |
|
FVECT v0,v1,v2; |
515 |
|
FUNC func; |
516 |
+ |
int n; |
517 |
|
{ |
518 |
|
STREE *st; |
519 |
|
FVECT tri[3]; |
523 |
|
VSUB(tri[0],v0,SM_VIEW_CENTER(sm)); |
524 |
|
VSUB(tri[1],v1,SM_VIEW_CENTER(sm)); |
525 |
|
VSUB(tri[2],v2,SM_VIEW_CENTER(sm)); |
526 |
< |
stVisit(st,tri,func); |
526 |
> |
stVisit(st,tri,func,n); |
527 |
|
|
528 |
|
} |
529 |
|
|
537 |
– |
|
538 |
– |
/* NEW INSERTION!!! ******************************************************/ |
530 |
|
QUADTREE |
531 |
|
insert_tri(argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale, |
532 |
|
s0,s1,s2,sq0,sq1,sq2,rev,f,n) |
688 |
|
SM_NTH_VERT(sm,v2_id) = t_id; |
689 |
|
|
690 |
|
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); |
691 |
|
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 |
– |
} |
692 |
|
|
693 |
+ |
if(SM_DIR_ID(sm,v0_id) || SM_DIR_ID(sm,v1_id) || SM_DIR_ID(sm,v2_id)) |
694 |
+ |
SM_SET_NTH_T_BG(sm,t_id); |
695 |
+ |
|
696 |
+ |
S_SET_FLAG(T_NTH_V(t,0)); |
697 |
+ |
S_SET_FLAG(T_NTH_V(t,1)); |
698 |
+ |
S_SET_FLAG(T_NTH_V(t,2)); |
699 |
+ |
|
700 |
+ |
SM_SET_NTH_T_ACTIVE(sm,t_id); |
701 |
+ |
SM_SET_NTH_T_NEW(sm,t_id); |
702 |
+ |
|
703 |
+ |
SM_SAMPLE_TRIS(sm)++; |
704 |
+ |
smNew_tri_cnt++; |
705 |
+ |
|
706 |
|
/* return initialized triangle */ |
707 |
|
return(t_id); |
708 |
|
} |
803 |
|
|
804 |
|
remove_from_list(t_id,add_ptr); |
805 |
|
remove_from_list(t1_id,add_ptr); |
806 |
< |
#if 1 |
806 |
> |
|
807 |
|
smDelete_tri(sm,t_id); |
808 |
|
smDelete_tri(sm,t1_id); |
819 |
– |
#else |
820 |
– |
*del_ptr = push_data(*del_ptr,t_id); |
821 |
– |
*del_ptr = push_data(*del_ptr,t1_id); |
822 |
– |
#endif |
809 |
|
|
824 |
– |
|
825 |
– |
|
810 |
|
*tn_id = ta_id; |
811 |
|
*tn1_id = tb_id; |
812 |
|
|
836 |
|
SM *sm; |
837 |
|
LIST *add_list; |
838 |
|
{ |
839 |
< |
int t_id,i; |
839 |
> |
int t_id; |
840 |
|
TRI *t; |
857 |
– |
OBJECT *optr; |
841 |
|
|
842 |
|
while(add_list) |
843 |
|
{ |
857 |
|
FVECT p,p0,p1,p2; |
858 |
|
int e,e1,swapped = 0; |
859 |
|
int t_id,t_opp_id; |
860 |
< |
LIST *del_list=NULL; |
860 |
> |
LIST *del_list=NULL,*lptr; |
861 |
|
|
862 |
|
VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm)); |
863 |
|
while(tlist) |
879 |
|
if(!T_IS_VALID(t_opp)) |
880 |
|
error(CONSISTENCY,"Invalid trismFix_tris()\n"); |
881 |
|
#endif |
882 |
< |
smDir_in_cone(sm,p0,T_NTH_V(t_opp,0)); |
883 |
< |
smDir_in_cone(sm,p1,T_NTH_V(t_opp,1)); |
884 |
< |
smDir_in_cone(sm,p2,T_NTH_V(t_opp,2)); |
882 |
> |
smDir(sm,p0,T_NTH_V(t_opp,0)); |
883 |
> |
smDir(sm,p1,T_NTH_V(t_opp,1)); |
884 |
> |
smDir(sm,p2,T_NTH_V(t_opp,2)); |
885 |
|
if(point_in_cone(p,p0,p1,p2)) |
886 |
|
{ |
887 |
|
swapped = 1; |
894 |
|
tlist = push_data(tlist,t_opp_id); |
895 |
|
} |
896 |
|
} |
897 |
< |
#if 0 |
915 |
< |
while(del_list) |
916 |
< |
{ |
917 |
< |
t_id = pop_list(&del_list); |
918 |
< |
smDelete_tri(sm,t_id); |
919 |
< |
} |
920 |
< |
#endif |
897 |
> |
|
898 |
|
smUpdate_locator(sm,add_list); |
899 |
|
|
900 |
|
return(swapped); |
946 |
|
FVECT npt; |
947 |
|
TRI *tri,*nbr,*topp; |
948 |
|
|
972 |
– |
|
949 |
|
add_list = NULL; |
950 |
|
for(i=0; i<3;i++) |
951 |
|
v_id[i] = T_NTH_V(SM_NTH_TRI(sm,tri_id),i); |
1204 |
|
optr = qtqueryset(qt); |
1205 |
|
tri_id = smTri_in_set(sm,tpt,optr,onptr,whichptr); |
1206 |
|
|
1231 |
– |
#ifdef DEBUG |
1232 |
– |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),0))) || |
1233 |
– |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),1))) || |
1234 |
– |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),2)))) |
1235 |
– |
eputs("Invalid tri nbrs smPointLocateTri()\n"); |
1236 |
– |
#endif |
1207 |
|
return(tri_id); |
1208 |
|
} |
1209 |
|
|
1257 |
|
|
1258 |
|
for(i=0; i<3; i++) |
1259 |
|
{ |
1260 |
< |
if(SM_BASE_ID(sm,vid[i])) |
1261 |
< |
{ |
1262 |
< |
bcnt++; |
1263 |
< |
continue; |
1264 |
< |
} |
1295 |
< |
if(SM_DIR_ID(sm,vid[i])) |
1296 |
< |
dcnt++; |
1297 |
< |
VSUB(diff[i],SM_NTH_WV(sm,vid[i]),p); |
1298 |
< |
/* If same world point: replace */ |
1260 |
> |
if(SM_BASE_ID(sm,vid[i])) |
1261 |
> |
bcnt++; |
1262 |
> |
if(SM_DIR_ID(sm,vid[i])) |
1263 |
> |
dcnt++; |
1264 |
> |
|
1265 |
|
} |
1266 |
|
/* TEST 1: If the new sample is close in ws, and close in the spherical |
1267 |
|
projection to one of the triangle vertex samples |
1268 |
|
*/ |
1269 |
+ |
#if 0 |
1270 |
|
norm = FALSE; |
1304 |
– |
if(bcnt + dcnt != 3) |
1305 |
– |
{ |
1271 |
|
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1272 |
|
ds = DOT(spt,spt); |
1273 |
|
dnear = FHUGE; |
1274 |
|
for(i=0; i<3; i++) |
1275 |
|
{ |
1311 |
– |
if(SM_BASE_ID(sm,vid[i]) || SM_DIR_ID(sm,vid[i])) |
1312 |
– |
continue; |
1276 |
|
d = DOT(diff[i],diff[i])/ds; |
1277 |
|
if(d < dnear) |
1278 |
|
{ |
1281 |
|
} |
1282 |
|
} |
1283 |
|
|
1284 |
< |
if(dnear <= smMinSampDiff*smMinSampDiff) |
1284 |
> |
if(dnear <= SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF) |
1285 |
|
{ |
1286 |
|
/* Pick the point with dir closest to that of the canonical view |
1287 |
|
if it is the new sample: mark existing point for deletion |
1288 |
|
*/ |
1289 |
+ |
if(SM_BASE_ID(sm,nearid)) |
1290 |
+ |
{ |
1291 |
+ |
*rptr = nearid; |
1292 |
+ |
return(TRUE); |
1293 |
+ |
} |
1294 |
+ |
if(SM_DIR_ID(sm,nearid)) |
1295 |
+ |
return(FALSE); |
1296 |
+ |
if(!dir) |
1297 |
+ |
{ |
1298 |
+ |
*rptr = nearid; |
1299 |
+ |
return(TRUE); |
1300 |
+ |
} |
1301 |
|
normalize(spt); |
1302 |
|
norm = TRUE; |
1303 |
|
VSUB(npt,SM_NTH_WV(sm,nearid),SM_VIEW_CENTER(sm)); |
1305 |
|
d = fdir2diff(SM_NTH_W_DIR(sm,nearid), npt); |
1306 |
|
d2 = 2. - 2.*DOT(dir,spt); |
1307 |
|
/* The existing sample is a better sample:punt */ |
1308 |
< |
if(d2 > d) |
1308 |
> |
if(d2 > d) |
1309 |
|
return(FALSE); |
1310 |
< |
else |
1311 |
< |
{ |
1312 |
< |
/* The new sample is better: mark the existing one |
1310 |
> |
else |
1311 |
> |
{ |
1312 |
> |
/* The new sample is better: mark the existing one |
1313 |
|
for deletion after the new one is added*/ |
1314 |
< |
*rptr = nearid; |
1315 |
< |
return(TRUE); |
1341 |
< |
} |
1314 |
> |
*rptr = nearid; |
1315 |
> |
return(TRUE); |
1316 |
|
} |
1317 |
< |
} |
1317 |
> |
} |
1318 |
> |
|
1319 |
|
/* TEST 3: If the spherical projection of new is < S_REPLACE_EPS |
1320 |
|
from a base point: Edge length is constrained to subtend <45 degrees: |
1321 |
|
original base mesh edges are approx 32 degrees- so have about 13 degrees |
1322 |
|
to work in: S_REPLACE_EPS is the square of the radian value |
1323 |
|
*/ |
1324 |
+ |
|
1325 |
|
if(bcnt) |
1326 |
|
{ |
1327 |
|
dnear = FHUGE; |
1352 |
– |
if(bcnt + dcnt ==3) |
1353 |
– |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1328 |
|
if(!norm) |
1329 |
|
normalize(spt); |
1330 |
|
|
1334 |
|
continue; |
1335 |
|
VSUB(npt,SM_NTH_WV(sm,vid[i]),SM_VIEW_CENTER(sm)); |
1336 |
|
d = DIST_SQ(npt,spt); |
1337 |
< |
if(d < S_REPLACE_EPS && d < dnear) |
1337 |
> |
if(dnear <= SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF && d< near) |
1338 |
|
{ |
1339 |
|
dnear = d; |
1340 |
|
nearid = vid[i]; |
1347 |
|
return(TRUE); |
1348 |
|
} |
1349 |
|
} |
1350 |
+ |
#else |
1351 |
+ |
{ |
1352 |
+ |
FVECT nearpt; |
1353 |
+ |
dnear = FHUGE; |
1354 |
+ |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1355 |
+ |
ds = DOT(spt,spt); |
1356 |
+ |
normalize(spt); |
1357 |
+ |
|
1358 |
+ |
for(i=0; i<3; i++) |
1359 |
+ |
{ |
1360 |
|
|
1361 |
+ |
VSUB(npt,SM_NTH_WV(sm,vid[i]),SM_VIEW_CENTER(sm)); |
1362 |
+ |
|
1363 |
+ |
if(!SM_BASE_ID(sm,vid[i]) && !SM_DIR_ID(sm,vid[i])) |
1364 |
+ |
normalize(npt); |
1365 |
+ |
|
1366 |
+ |
d = DIST_SQ(npt,spt); |
1367 |
+ |
if(d < SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF && d < dnear) |
1368 |
+ |
{ |
1369 |
+ |
dnear = d; |
1370 |
+ |
nearid = vid[i]; |
1371 |
+ |
VCOPY(nearpt,npt); |
1372 |
+ |
} |
1373 |
+ |
|
1374 |
+ |
} |
1375 |
+ |
if(dnear != FHUGE) |
1376 |
+ |
{ |
1377 |
+ |
/* Pick the point with dir closest to that of the canonical view |
1378 |
+ |
if it is the new sample: mark existing point for deletion |
1379 |
+ |
*/ |
1380 |
+ |
if(SM_BASE_ID(sm,nearid)) |
1381 |
+ |
{ |
1382 |
+ |
*rptr = nearid; |
1383 |
+ |
return(TRUE); |
1384 |
+ |
} |
1385 |
+ |
if(SM_DIR_ID(sm,nearid)) |
1386 |
+ |
return(FALSE); |
1387 |
+ |
if(!dir) |
1388 |
+ |
{ |
1389 |
+ |
*rptr = nearid; |
1390 |
+ |
return(TRUE); |
1391 |
+ |
} |
1392 |
+ |
d = fdir2diff(SM_NTH_W_DIR(sm,nearid), nearpt); |
1393 |
+ |
d2 = 2. - 2.*DOT(dir,spt); |
1394 |
+ |
/* The existing sample is a better sample:punt */ |
1395 |
+ |
if(d2 > d) |
1396 |
+ |
return(FALSE); |
1397 |
+ |
else |
1398 |
+ |
{ |
1399 |
+ |
/* The new sample is better: mark the existing one |
1400 |
+ |
for deletion after the new one is added*/ |
1401 |
+ |
*rptr = nearid; |
1402 |
+ |
return(TRUE); |
1403 |
+ |
} |
1404 |
+ |
} |
1405 |
+ |
} |
1406 |
+ |
#endif |
1407 |
|
/* TEST 4: |
1408 |
|
If the addition of the new sample point would introduce a "puncture" |
1409 |
|
or cause new triangles with large depth differences:dont add: |
1410 |
|
*/ |
1411 |
|
if(bcnt || dcnt) |
1412 |
|
return(TRUE); |
1413 |
+ |
|
1414 |
|
/* If the new point is in front of the existing points- add */ |
1415 |
|
dv = DIST_SQ(SM_NTH_WV(sm,vid[0]),SM_VIEW_CENTER(sm)); |
1416 |
|
if(ds < dv) |
1417 |
|
return(TRUE); |
1418 |
|
|
1419 |
|
d01 = DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_NTH_WV(sm,vid[0])); |
1420 |
+ |
VSUB(diff[0],SM_NTH_WV(sm,vid[0]),p); |
1421 |
|
s0 = DOT(diff[0],diff[0]); |
1422 |
|
if(s0 < S_REPLACE_SCALE*d01) |
1423 |
|
return(TRUE); |
1424 |
+ |
|
1425 |
|
d12 = DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_NTH_WV(sm,vid[1])); |
1426 |
|
if(s0 < S_REPLACE_SCALE*d12) |
1427 |
|
return(TRUE); |
1429 |
|
if(s0 < S_REPLACE_SCALE*d20) |
1430 |
|
return(TRUE); |
1431 |
|
d = MIN3(d01,d12,d20); |
1432 |
< |
s1 = DOT(diff[1],diff[1]); |
1432 |
> |
VSUB(diff[1],SM_NTH_WV(sm,vid[1]),p); |
1433 |
> |
s1 = DOT(diff[1],diff[1]); |
1434 |
|
if(s1 < S_REPLACE_SCALE*d) |
1435 |
|
return(TRUE); |
1436 |
+ |
VSUB(diff[2],SM_NTH_WV(sm,vid[2]),p); |
1437 |
|
s2 = DOT(diff[2],diff[2]); |
1438 |
|
if(s2 < S_REPLACE_SCALE*d) |
1439 |
|
return(TRUE); |
1450 |
|
return(FALSE); |
1451 |
|
} |
1452 |
|
|
1453 |
< |
|
1419 |
< |
int |
1420 |
< |
smAlloc_samp(sm) |
1453 |
> |
smReplace_base_samp(sm,b_id,s_id,tri,t_id,which) |
1454 |
|
SM *sm; |
1455 |
+ |
int b_id,s_id; |
1456 |
+ |
TRI *tri; |
1457 |
+ |
int t_id,which; |
1458 |
|
{ |
1459 |
< |
int s_id,replaced,cnt; |
1424 |
< |
SAMP *s; |
1425 |
< |
FVECT p; |
1459 |
> |
TRI *t; |
1460 |
|
|
1461 |
< |
s = SM_SAMP(sm); |
1462 |
< |
s_id = sAlloc_samp(s,&replaced); |
1463 |
< |
|
1464 |
< |
cnt=0; |
1465 |
< |
while(replaced) |
1461 |
> |
SM_NTH_VERT(sm,s_id) = t_id; |
1462 |
> |
T_NTH_V(tri,which) = s_id; |
1463 |
> |
if(!(SM_BASE_ID(sm,T_NTH_V(tri,(which+1)%3)) || |
1464 |
> |
SM_BASE_ID(sm,T_NTH_V(tri,(which+2)%3)))) |
1465 |
> |
SM_CLR_NTH_T_BASE(sm,t_id); |
1466 |
> |
if(!SM_IS_NTH_T_NEW(sm,t_id)) |
1467 |
|
{ |
1468 |
< |
if(smRemoveVertex(sm,s_id)) |
1469 |
< |
break; |
1435 |
< |
s_id = sAlloc_samp(s,&replaced); |
1436 |
< |
cnt++; |
1437 |
< |
if(cnt > S_MAX_SAMP(s)) |
1438 |
< |
error(CONSISTENCY,"smAlloc_samp():unable to find free samp\n"); |
1468 |
> |
smNew_tri_cnt++; |
1469 |
> |
SM_SET_NTH_T_NEW(sm,t_id); |
1470 |
|
} |
1471 |
< |
return(s_id); |
1471 |
> |
t_id = smTri_next_ccw_nbr(sm,tri,b_id); |
1472 |
> |
while(t_id != INVALID) |
1473 |
> |
{ |
1474 |
> |
t = SM_NTH_TRI(sm,t_id); |
1475 |
> |
which = T_WHICH_V(t,b_id); |
1476 |
> |
T_NTH_V(t,which) = s_id; |
1477 |
> |
/* Check if still a base triangle */ |
1478 |
> |
if(!(SM_BASE_ID(sm,T_NTH_V(t,(which+1)%3)) || |
1479 |
> |
SM_BASE_ID(sm,T_NTH_V(t,(which+2)%3)))) |
1480 |
> |
SM_CLR_NTH_T_BASE(sm,t_id); |
1481 |
> |
if(!SM_IS_NTH_T_NEW(sm,t_id)) |
1482 |
> |
{ |
1483 |
> |
smNew_tri_cnt++; |
1484 |
> |
SM_SET_NTH_T_NEW(sm,t_id); |
1485 |
> |
} |
1486 |
> |
t_id = smTri_next_ccw_nbr(sm,t,b_id); |
1487 |
> |
} |
1488 |
|
} |
1489 |
|
|
1490 |
|
int |
1494 |
|
FVECT dir,p; |
1495 |
|
int s_id,t_id,o_id,on,which; |
1496 |
|
{ |
1497 |
< |
int tonemap,v_id; |
1497 |
> |
int v_id,tri_id; |
1498 |
|
TRI *t,*tri; |
1499 |
|
|
1500 |
|
tri = SM_NTH_TRI(sm,t_id); |
1503 |
|
/* If it is a base id, need new sample */ |
1504 |
|
if(SM_BASE_ID(sm,v_id)) |
1505 |
|
{ |
1506 |
< |
tonemap = (SM_TONE_MAP(sm) > s_id); |
1507 |
< |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id,tonemap); |
1461 |
< |
SM_NTH_VERT(sm,s_id) = t_id; |
1462 |
< |
T_NTH_V(tri,which) = s_id; |
1463 |
< |
if(!(SM_BASE_ID(sm,T_NTH_V(tri,(which+1)%3)) || |
1464 |
< |
SM_BASE_ID(sm,T_NTH_V(tri,(which+2)%3)))) |
1465 |
< |
SM_CLR_NTH_T_BASE(sm,t_id); |
1466 |
< |
t_id = smTri_next_ccw_nbr(sm,tri,v_id); |
1467 |
< |
while(t_id != INVALID) |
1468 |
< |
{ |
1469 |
< |
t = SM_NTH_TRI(sm,t_id); |
1470 |
< |
which = T_WHICH_V(t,v_id); |
1471 |
< |
T_NTH_V(t,which) = s_id; |
1472 |
< |
/* Check if still a base triangle */ |
1473 |
< |
if(!(SM_BASE_ID(sm,T_NTH_V(t,(which+1)%3)) || |
1474 |
< |
SM_BASE_ID(sm,T_NTH_V(t,(which+2)%3)))) |
1475 |
< |
SM_CLR_NTH_T_BASE(sm,t_id); |
1476 |
< |
t_id = smTri_next_ccw_nbr(sm,t,v_id); |
1477 |
< |
} |
1506 |
> |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id); |
1507 |
> |
smReplace_base_samp(sm,v_id,s_id,tri,t_id,which); |
1508 |
|
return(s_id); |
1509 |
|
} |
1510 |
< |
else |
1511 |
< |
if(on == ON_V || !p) |
1510 |
> |
if(dir) |
1511 |
> |
{ |
1512 |
> |
/* If world point */ |
1513 |
> |
/* if existing point is a dir: leave */ |
1514 |
> |
if(SM_DIR_ID(sm,v_id)) |
1515 |
> |
return(INVALID); |
1516 |
> |
if(on == ON_V) |
1517 |
|
{ |
1518 |
< |
tonemap = (SM_TONE_MAP(sm) > v_id); |
1519 |
< |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id,tonemap); |
1518 |
> |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id); |
1519 |
> |
|
1520 |
> |
if(!SM_IS_NTH_T_NEW(sm,t_id)) |
1521 |
> |
{ |
1522 |
> |
smNew_tri_cnt++; |
1523 |
> |
SM_SET_NTH_T_NEW(sm,t_id); |
1524 |
> |
} |
1525 |
> |
tri_id = smTri_next_ccw_nbr(sm,tri,v_id); |
1526 |
> |
while(tri_id != t_id) |
1527 |
> |
{ |
1528 |
> |
t = SM_NTH_TRI(sm,tri_id); |
1529 |
> |
if(!SM_IS_NTH_T_NEW(sm,tri_id)) |
1530 |
> |
{ |
1531 |
> |
smNew_tri_cnt++; |
1532 |
> |
SM_SET_NTH_T_NEW(sm,tri_id); |
1533 |
> |
} |
1534 |
> |
|
1535 |
> |
tri_id = smTri_next_ccw_nbr(sm,t,v_id); |
1536 |
> |
} |
1537 |
|
return(v_id); |
1538 |
|
} |
1539 |
< |
else /* on == ON_P */ |
1540 |
< |
{ |
1541 |
< |
FVECT spt,npt; |
1542 |
< |
double d,d2; |
1539 |
> |
/* on == ON_P */ |
1540 |
> |
else |
1541 |
> |
{ |
1542 |
> |
FVECT spt,npt; |
1543 |
> |
double d,d2; |
1544 |
|
|
1545 |
< |
/* Need to check which sample is preferable */ |
1546 |
< |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1547 |
< |
normalize(spt); |
1545 |
> |
/* Need to check which sample is preferable */ |
1546 |
> |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1547 |
> |
normalize(spt); |
1548 |
|
|
1549 |
< |
VSUB(npt,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm)); |
1550 |
< |
normalize(npt); |
1551 |
< |
d = fdir2diff(SM_NTH_W_DIR(sm,v_id), npt); |
1552 |
< |
d2 = 2. - 2.*DOT(dir,spt); |
1549 |
> |
VSUB(npt,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm)); |
1550 |
> |
normalize(npt); |
1551 |
> |
d = fdir2diff(SM_NTH_W_DIR(sm,v_id), npt); |
1552 |
> |
d2 = 2. - 2.*DOT(dir,spt); |
1553 |
|
/* The existing sample is a better sample:punt */ |
1554 |
< |
if(d2 < d) |
1555 |
< |
{ |
1556 |
< |
/* The new sample has better information- replace values */ |
1557 |
< |
tonemap = (SM_TONE_MAP(sm) > v_id); |
1558 |
< |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id,tonemap); |
1559 |
< |
} |
1560 |
< |
return(v_id); |
1554 |
> |
if(d2 < d) |
1555 |
> |
{ |
1556 |
> |
/* The new sample has better information- replace values */ |
1557 |
> |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id); |
1558 |
> |
if(!SM_IS_NTH_T_NEW(sm,t_id)) |
1559 |
> |
{ |
1560 |
> |
smNew_tri_cnt++; |
1561 |
> |
SM_SET_NTH_T_NEW(sm,t_id); |
1562 |
> |
} |
1563 |
> |
|
1564 |
> |
tri_id = smTri_next_ccw_nbr(sm,tri,v_id); |
1565 |
> |
while(tri_id != t_id) |
1566 |
> |
{ |
1567 |
> |
t = SM_NTH_TRI(sm,tri_id); |
1568 |
> |
if(!SM_IS_NTH_T_NEW(sm,tri_id)) |
1569 |
> |
{ |
1570 |
> |
smNew_tri_cnt++; |
1571 |
> |
SM_SET_NTH_T_NEW(sm,tri_id); |
1572 |
> |
} |
1573 |
> |
tri_id = smTri_next_ccw_nbr(sm,t,v_id); |
1574 |
> |
} |
1575 |
> |
} |
1576 |
> |
return(v_id); |
1577 |
> |
} |
1578 |
> |
} |
1579 |
> |
else |
1580 |
> |
{ /* New point is a dir */ |
1581 |
> |
return(INVALID); |
1582 |
|
} |
1583 |
|
} |
1584 |
|
|
1585 |
+ |
int |
1586 |
+ |
smAlloc_samp(sm) |
1587 |
+ |
SM *sm; |
1588 |
+ |
{ |
1589 |
+ |
int s_id,replaced,cnt; |
1590 |
+ |
SAMP *s; |
1591 |
+ |
FVECT p; |
1592 |
+ |
|
1593 |
+ |
s = SM_SAMP(sm); |
1594 |
+ |
s_id = sAlloc_samp(s,&replaced); |
1595 |
+ |
|
1596 |
+ |
cnt=0; |
1597 |
+ |
while(replaced) |
1598 |
+ |
{ |
1599 |
+ |
if(smRemoveVertex(sm,s_id)) |
1600 |
+ |
break; |
1601 |
+ |
s_id = sAlloc_samp(s,&replaced); |
1602 |
+ |
cnt++; |
1603 |
+ |
if(cnt > S_MAX_SAMP(s)) |
1604 |
+ |
error(CONSISTENCY,"smAlloc_samp():unable to find free samp\n"); |
1605 |
+ |
} |
1606 |
+ |
return(s_id); |
1607 |
+ |
} |
1608 |
+ |
|
1609 |
+ |
|
1610 |
|
/* Add sample to the mesh: |
1611 |
|
|
1612 |
|
the sample can be a world space or directional point. If o_id !=INVALID, |
1638 |
|
/* If sample is a world space point */ |
1639 |
|
if(p) |
1640 |
|
{ |
1641 |
< |
t_id = smPointLocateTri(sm,p,&on,&which); |
1642 |
< |
if(t_id == INVALID) |
1641 |
> |
while(1) |
1642 |
> |
{ |
1643 |
> |
t_id = smPointLocateTri(sm,p,&on,&which); |
1644 |
> |
if(t_id == INVALID) |
1645 |
|
{ |
1646 |
|
#ifdef DEBUG |
1647 |
< |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
1647 |
> |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
1648 |
|
#endif |
1649 |
+ |
smUnalloc_samp(sm,s_id); |
1650 |
+ |
return(INVALID); |
1651 |
+ |
} |
1652 |
+ |
/* If spherical projection coincides with existing sample: replace */ |
1653 |
+ |
if((on == ON_V || on == ON_P)) |
1654 |
+ |
{ |
1655 |
+ |
n_id = smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which); |
1656 |
+ |
if(n_id!= s_id) |
1657 |
+ |
smUnalloc_samp(sm,s_id); |
1658 |
+ |
return(n_id); |
1659 |
+ |
} |
1660 |
+ |
if((!(smTest_sample(sm,t_id,dir,p,&r_id)))) |
1661 |
+ |
{ |
1662 |
|
smUnalloc_samp(sm,s_id); |
1663 |
|
return(INVALID); |
1664 |
|
} |
1665 |
< |
/* If spherical projection coincides with existing sample: replace */ |
1666 |
< |
if((on == ON_V || on == ON_P)) |
1667 |
< |
{ |
1668 |
< |
if((n_id = smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which))!= s_id) |
1669 |
< |
smUnalloc_samp(sm,s_id); |
1670 |
< |
return(n_id); |
1665 |
> |
if(r_id != INVALID) |
1666 |
> |
{ |
1667 |
> |
smRemoveVertex(sm,r_id); |
1668 |
> |
sDelete_samp(SM_SAMP(sm),r_id); |
1669 |
> |
} |
1670 |
> |
else |
1671 |
> |
break; |
1672 |
|
} |
1558 |
– |
if((!(smTest_sample(sm,t_id,dir,p,&r_id)))) |
1559 |
– |
{ |
1560 |
– |
smUnalloc_samp(sm,s_id); |
1561 |
– |
return(INVALID); |
1562 |
– |
} |
1673 |
|
/* If sample is being added in the middle of the sample array: tone |
1674 |
|
map individually |
1675 |
|
*/ |
1676 |
|
/* Initialize sample */ |
1677 |
< |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id,(SM_TONE_MAP(sm)>s_id)); |
1677 |
> |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id); |
1678 |
|
|
1679 |
|
} |
1680 |
|
/* If sample is a direction vector */ |
1681 |
|
else |
1682 |
|
{ |
1683 |
|
VADD(wpt,dir,SM_VIEW_CENTER(sm)); |
1684 |
< |
t_id = smPointLocateTri(sm,wpt,&on,&which); |
1685 |
< |
if(t_id == INVALID) |
1686 |
< |
{ |
1684 |
> |
while(1) |
1685 |
> |
{ |
1686 |
> |
t_id = smPointLocateTri(sm,wpt,&on,&which); |
1687 |
> |
if(t_id == INVALID) |
1688 |
> |
{ |
1689 |
|
#ifdef DEBUG |
1690 |
< |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
1690 |
> |
eputs("smAddSamp(): can'tlocate tri containing samp\n"); |
1691 |
|
#endif |
1692 |
< |
smUnalloc_samp(sm,s_id); |
1693 |
< |
return(INVALID); |
1692 |
> |
smUnalloc_samp(sm,s_id); |
1693 |
> |
return(INVALID); |
1694 |
> |
} |
1695 |
> |
if(on == ON_V || on == ON_P) |
1696 |
> |
{ |
1697 |
> |
n_id=smReplace_samp(sm,c,NULL,wpt,s_id,t_id,o_id,on,which); |
1698 |
> |
if(n_id !=s_id) |
1699 |
> |
smUnalloc_samp(sm,s_id); |
1700 |
> |
return(n_id); |
1701 |
> |
} |
1702 |
> |
if((!(smTest_sample(sm,t_id,NULL,wpt,&r_id)))) |
1703 |
> |
{ |
1704 |
> |
smUnalloc_samp(sm,s_id); |
1705 |
> |
return(INVALID); |
1706 |
> |
} |
1707 |
> |
if(r_id != INVALID) |
1708 |
> |
{ |
1709 |
> |
smRemoveVertex(sm,r_id); |
1710 |
> |
sDelete_samp(SM_SAMP(sm),r_id); |
1711 |
> |
} |
1712 |
> |
else |
1713 |
> |
break; |
1714 |
|
} |
1583 |
– |
if(on == ON_V || on == ON_P) |
1584 |
– |
{ |
1585 |
– |
if((n_id = smReplace_samp(sm,c,wpt,NULL,s_id,t_id,o_id,on,which))!= s_id) |
1586 |
– |
smUnalloc_samp(sm,s_id); |
1587 |
– |
return(n_id); |
1588 |
– |
} |
1715 |
|
/* Allocate space for a sample and initialize */ |
1716 |
< |
sInit_samp(SM_SAMP(sm),s_id,c,wpt,NULL,o_id,(SM_TONE_MAP(sm)>s_id)); |
1716 |
> |
sInit_samp(SM_SAMP(sm),s_id,c,NULL,wpt,o_id); |
1717 |
|
} |
1718 |
|
if(!SM_DIR_ID(sm,s_id)) |
1719 |
|
{ |
1724 |
|
} |
1725 |
|
smInsert_samp(sm,s_id,t_id,on,which); |
1726 |
|
|
1601 |
– |
/* If new sample replaces existing one- remove that vertex now */ |
1602 |
– |
if(r_id != INVALID) |
1603 |
– |
{ |
1604 |
– |
smRemoveVertex(sm,r_id); |
1605 |
– |
sDelete_samp(SM_SAMP(sm),r_id); |
1606 |
– |
} |
1727 |
|
return(s_id); |
1728 |
|
} |
1729 |
|
|
1746 |
|
{ |
1747 |
|
int s_id; |
1748 |
|
|
1629 |
– |
|
1749 |
|
/* First check if this the first sample: if so initialize mesh */ |
1631 |
– |
|
1750 |
|
if(SM_NUM_SAMP(smMesh) == 0) |
1751 |
|
{ |
1752 |
|
smInit_sm(smMesh,odev.v.vp); |
1820 |
|
|
1821 |
|
} |
1822 |
|
|
1705 |
– |
|
1706 |
– |
int |
1707 |
– |
smNext_tri_flag_set(sm,i,which,b) |
1708 |
– |
SM *sm; |
1709 |
– |
int i,which; |
1710 |
– |
int b; |
1711 |
– |
{ |
1712 |
– |
|
1713 |
– |
for(; i < SM_NUM_TRI(sm);i++) |
1714 |
– |
{ |
1715 |
– |
|
1716 |
– |
if(!T_IS_VALID(SM_NTH_TRI(sm,i))) |
1717 |
– |
continue; |
1718 |
– |
if(!SM_IS_NTH_T_FLAG(sm,i,which)) |
1719 |
– |
continue; |
1720 |
– |
if(!b) |
1721 |
– |
break; |
1722 |
– |
if((b==1) && !SM_BG_TRI(sm,i)) |
1723 |
– |
break; |
1724 |
– |
if((b==2) && SM_BG_TRI(sm,i)) |
1725 |
– |
break; |
1726 |
– |
} |
1727 |
– |
|
1728 |
– |
return(i); |
1729 |
– |
} |
1730 |
– |
|
1731 |
– |
|
1732 |
– |
int |
1733 |
– |
smNext_valid_tri(sm,i) |
1734 |
– |
SM *sm; |
1735 |
– |
int i; |
1736 |
– |
{ |
1737 |
– |
|
1738 |
– |
while( i < SM_NUM_TRI(sm) && !T_IS_VALID(SM_NTH_TRI(sm,i))) |
1739 |
– |
i++; |
1740 |
– |
|
1741 |
– |
return(i); |
1742 |
– |
} |
1743 |
– |
|
1744 |
– |
|
1745 |
– |
|
1746 |
– |
qtTri_from_id(t_id,v0,v1,v2) |
1747 |
– |
int t_id; |
1748 |
– |
FVECT v0,v1,v2; |
1749 |
– |
{ |
1750 |
– |
TRI *t; |
1751 |
– |
|
1752 |
– |
t = SM_NTH_TRI(smMesh,t_id); |
1753 |
– |
if(!T_IS_VALID(t)) |
1754 |
– |
return(0); |
1755 |
– |
VSUB(v0,SM_T_NTH_WV(smMesh,t,0),SM_VIEW_CENTER(smMesh)); |
1756 |
– |
VSUB(v1,SM_T_NTH_WV(smMesh,t,1),SM_VIEW_CENTER(smMesh)); |
1757 |
– |
VSUB(v2,SM_T_NTH_WV(smMesh,t,2),SM_VIEW_CENTER(smMesh)); |
1758 |
– |
return(1); |
1759 |
– |
} |
1760 |
– |
|
1761 |
– |
|
1823 |
|
smRebuild_mesh(sm,v) |
1824 |
|
SM *sm; |
1825 |
|
VIEW *v; |
1831 |
|
#ifdef DEBUG |
1832 |
|
fprintf(stderr,"smRebuild_mesh(): rebuilding...."); |
1833 |
|
#endif |
1834 |
+ |
smCull(sm,v,SM_ALL_LEVELS); |
1835 |
|
/* Clear the mesh- and rebuild using the current sample array */ |
1836 |
|
/* Remember the current number of samples */ |
1837 |
|
cnt = SM_NUM_SAMP(sm); |
1871 |
|
} |
1872 |
|
|
1873 |
|
} |
1812 |
– |
|
1813 |
– |
smNew_tri_cnt = SM_SAMPLE_TRIS(sm); |
1874 |
|
#ifdef DEBUG |
1875 |
|
fprintf(stderr,"smRebuild_mesh():done\n"); |
1876 |
|
#endif |
1893 |
|
{ |
1894 |
|
t_id = QT_SET_NEXT_ELEM(optr); |
1895 |
|
t = SM_NTH_TRI(smMesh,t_id); |
1896 |
< |
if(!T_IS_VALID(t)) |
1896 |
> |
if(!T_IS_VALID(t) || SM_IS_NTH_T_BASE(smMesh,t_id)|| |
1897 |
> |
SM_IS_NTH_T_BG(smMesh,t_id)) |
1898 |
|
continue; |
1899 |
|
pid0 = T_NTH_V(t,0); |
1900 |
|
pid1 = T_NTH_V(t,1); |
1901 |
|
pid2 = T_NTH_V(t,2); |
1841 |
– |
if(base = SM_IS_NTH_T_BASE(smMesh,t_id)) |
1842 |
– |
if(SM_BASE_ID(smMesh,pid0) && SM_BASE_ID(smMesh,pid1) && |
1843 |
– |
SM_BASE_ID(smMesh,pid2)) |
1844 |
– |
continue; |
1902 |
|
VCOPY(p0,SM_NTH_WV(smMesh,pid0)); |
1903 |
|
VCOPY(p1,SM_NTH_WV(smMesh,pid1)); |
1904 |
|
VCOPY(p2,SM_NTH_WV(smMesh,pid2)); |
1905 |
|
if(ray_intersect_tri(orig,dir,p0,p1,p2,p)) |
1906 |
|
{ |
1907 |
< |
if(!base) |
1908 |
< |
{ |
1909 |
< |
d = DIST_SQ(p,p0); |
1910 |
< |
d1 = DIST_SQ(p,p1); |
1911 |
< |
if(d < d1) |
1912 |
< |
{ |
1913 |
< |
d1 = DIST_SQ(p,p2); |
1857 |
< |
id = (d1 < d)?pid2:pid0; |
1858 |
< |
} |
1859 |
< |
else |
1860 |
< |
{ |
1861 |
< |
d = DIST_SQ(p,p2); |
1862 |
< |
id = (d < d1)? pid2:pid1; |
1863 |
< |
} |
1864 |
< |
} |
1907 |
> |
d = DIST_SQ(p,p0); |
1908 |
> |
d1 = DIST_SQ(p,p1); |
1909 |
> |
if(d < d1) |
1910 |
> |
{ |
1911 |
> |
d1 = DIST_SQ(p,p2); |
1912 |
> |
id = (d1 < d)?pid2:pid0; |
1913 |
> |
} |
1914 |
|
else |
1915 |
|
{ |
1916 |
< |
if(SM_BASE_ID(smMesh,pid0)) |
1917 |
< |
{ |
1869 |
< |
if(SM_BASE_ID(smMesh,pid1)) |
1870 |
< |
id = pid2; |
1871 |
< |
else |
1872 |
< |
if(SM_BASE_ID(smMesh,pid2)) |
1873 |
< |
id = pid1; |
1874 |
< |
else |
1875 |
< |
{ |
1876 |
< |
d = DIST_SQ(p,p1); |
1877 |
< |
d1 = DIST_SQ(p,p2); |
1878 |
< |
if(d < d1) |
1879 |
< |
id = pid1; |
1880 |
< |
else |
1881 |
< |
id = pid2; |
1882 |
< |
} |
1883 |
< |
} |
1884 |
< |
else |
1885 |
< |
{ |
1886 |
< |
if(SM_BASE_ID(smMesh,pid1)) |
1887 |
< |
{ |
1888 |
< |
if(SM_BASE_ID(smMesh,pid2)) |
1889 |
< |
id = pid0; |
1890 |
< |
else |
1891 |
< |
{ |
1892 |
< |
d = DIST_SQ(p,p0); |
1893 |
< |
d1 = DIST_SQ(p,p2); |
1894 |
< |
if(d < d1) |
1895 |
< |
id = pid0; |
1896 |
< |
else |
1897 |
< |
id = pid2; |
1898 |
< |
} |
1899 |
< |
} |
1900 |
< |
else |
1901 |
< |
{ |
1902 |
< |
d = DIST_SQ(p,p0); |
1903 |
< |
d1 = DIST_SQ(p,p1); |
1904 |
< |
if(d < d1) |
1905 |
< |
id = pid0; |
1906 |
< |
else |
1907 |
< |
id = pid1; |
1908 |
< |
} |
1909 |
< |
} |
1916 |
> |
d = DIST_SQ(p,p2); |
1917 |
> |
id = (d < d1)? pid2:pid1; |
1918 |
|
} |
1919 |
|
if(pt) |
1920 |
|
VCOPY(pt,p); |
2051 |
|
#ifdef DEBUG_TEST_DRIVER |
2052 |
|
VCOPY(Pick_point[0],p); |
2053 |
|
#endif |
2046 |
– |
#ifdef DEBUG |
2047 |
– |
fprintf(stderr,"Simple pick returning %d\n",s_id); |
2048 |
– |
#endif |
2049 |
– |
|
2054 |
|
return(s_id); |
2055 |
|
} |
2056 |
|
d = point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh)); |
2064 |
|
#ifdef DEBUG_TEST_DRIVER |
2065 |
|
VCOPY(Pick_point[0],p); |
2066 |
|
#endif |
2063 |
– |
#ifdef DEBUG |
2064 |
– |
fprintf(stderr,"Simple pick2 returning %d\n",s_id); |
2065 |
– |
#endif |
2067 |
|
return(s_id); |
2068 |
|
} |
2069 |
|
if(OPP_EQUAL_VEC3(b,dir)) |
2113 |
|
F_ARGS(func) = (int *)(&rt); |
2114 |
|
stTrace_ray(SM_LOCATOR(smMesh),o,dir,func); |
2115 |
|
s_id = rt.t_id; |
2116 |
+ |
|
2117 |
|
} |
2116 |
– |
#ifdef DEBUG |
2117 |
– |
fprintf(stderr,"Trace pick returning %d\n",s_id); |
2118 |
– |
#endif |
2118 |
|
return(s_id); |
2119 |
|
|
2120 |
|
Lerror: |
2125 |
|
|
2126 |
|
} |
2127 |
|
|
2128 |
+ |
null_func(argptr,root,qt,n) |
2129 |
+ |
int *argptr; |
2130 |
+ |
int root; |
2131 |
+ |
QUADTREE qt; |
2132 |
+ |
int n; |
2133 |
+ |
{ |
2134 |
+ |
/* do nothing */ |
2135 |
+ |
} |
2136 |
|
|
2137 |
< |
mark_active_tris(argptr,root,qt) |
2137 |
> |
mark_active_tris(argptr,root,qt,n) |
2138 |
|
int *argptr; |
2139 |
|
int root; |
2140 |
|
QUADTREE qt; |
2141 |
+ |
int n; |
2142 |
|
{ |
2143 |
|
OBJECT *os,*optr; |
2144 |
|
register int i,t_id; |
2155 |
|
t_id = QT_SET_NEXT_ELEM(optr); |
2156 |
|
/* Set the render flag */ |
2157 |
|
tri = SM_NTH_TRI(smMesh,t_id); |
2158 |
< |
if(!T_IS_VALID(tri) || SM_IS_NTH_T_BASE(smMesh,t_id)) |
2158 |
> |
if(!T_IS_VALID(tri)) |
2159 |
|
continue; |
2160 |
|
SM_SET_NTH_T_ACTIVE(smMesh,t_id); |
2161 |
|
/* Set the Active bits of the Vertices */ |
2162 |
|
S_SET_FLAG(T_NTH_V(tri,0)); |
2163 |
|
S_SET_FLAG(T_NTH_V(tri,1)); |
2164 |
|
S_SET_FLAG(T_NTH_V(tri,2)); |
2165 |
< |
} |
2165 |
> |
} |
2166 |
|
} |
2167 |
|
|
2168 |
|
|
2169 |
< |
mark_tris_in_frustum(view) |
2169 |
> |
smCull(sm,view,n) |
2170 |
> |
SM *sm; |
2171 |
|
VIEW *view; |
2172 |
+ |
int n; |
2173 |
|
{ |
2174 |
|
FVECT nr[4],far[4]; |
2175 |
|
FPEQ peq; |
2176 |
|
int debug=0; |
2177 |
|
FUNC f; |
2178 |
|
|
2179 |
< |
F_FUNC(f) = mark_active_tris; |
2180 |
< |
F_ARGS(f) = NULL; |
2179 |
> |
/* First clear all the quadtree node flags */ |
2180 |
> |
qtClearAllFlags(); |
2181 |
|
|
2182 |
+ |
F_ARGS(f) = NULL; |
2183 |
+ |
/* If marking samples down to leaves */ |
2184 |
+ |
if(n == SM_ALL_LEVELS) |
2185 |
+ |
{ |
2186 |
|
/* Mark triangles in approx. view frustum as being active:set |
2187 |
|
LRU counter: for use in discarding samples when out |
2188 |
|
of space |
2189 |
+ |
*/ |
2190 |
+ |
F_FUNC(f) = mark_active_tris; |
2191 |
+ |
smClear_flags(sm,T_ACTIVE_FLAG); |
2192 |
+ |
/* Clear all of the active sample flags*/ |
2193 |
+ |
sClear_all_flags(SM_SAMP(sm)); |
2194 |
+ |
} |
2195 |
+ |
else |
2196 |
+ |
/* Just mark qtree flags */ |
2197 |
+ |
F_FUNC(f) = null_func; |
2198 |
+ |
|
2199 |
+ |
/* calculate the world space coordinates of the view frustum: |
2200 |
|
Radiance often has no far clipping plane: but driver will set |
2201 |
|
dev_zmin,dev_zmax to satisfy OGL |
2202 |
< |
*/ |
2178 |
< |
|
2179 |
< |
/* First clear all the quadtree node and triangle active flags */ |
2180 |
< |
qtClearAllFlags(); |
2181 |
< |
smClear_flags(smMesh,T_ACTIVE_FLAG); |
2182 |
< |
/* Clear all of the active sample flags*/ |
2183 |
< |
sClear_all_flags(SM_SAMP(smMesh)); |
2184 |
< |
|
2185 |
< |
|
2186 |
< |
/* calculate the world space coordinates of the view frustum */ |
2202 |
> |
*/ |
2203 |
|
calculate_view_frustum(view->vp,view->hvec,view->vvec,view->horiz, |
2204 |
|
view->vert, dev_zmin,dev_zmax,nr,far); |
2205 |
|
|
2220 |
|
Also set the triangles LRU clock counter |
2221 |
|
*/ |
2222 |
|
|
2223 |
< |
if(EQUAL_VEC3(view->vp,SM_VIEW_CENTER(smMesh))) |
2223 |
> |
if(EQUAL_VEC3(view->vp,SM_VIEW_CENTER(sm))) |
2224 |
|
{/* Near face triangles */ |
2225 |
|
|
2226 |
< |
smLocator_apply(smMesh,nr[0],nr[2],nr[3],f); |
2227 |
< |
smLocator_apply(smMesh,nr[2],nr[0],nr[1],f); |
2226 |
> |
smLocator_apply(sm,nr[0],nr[2],nr[3],f,n); |
2227 |
> |
smLocator_apply(sm,nr[2],nr[0],nr[1],f,n); |
2228 |
|
return; |
2229 |
|
} |
2230 |
|
/* Test the view against the planes: and swap orientation if inside:*/ |
2231 |
|
tri_plane_equation(nr[0],nr[2],nr[3], &peq,FALSE); |
2232 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2232 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2233 |
|
{/* Near face triangles */ |
2234 |
< |
smLocator_apply(smMesh,nr[3],nr[2],nr[0],f); |
2235 |
< |
smLocator_apply(smMesh,nr[1],nr[0],nr[2],f); |
2234 |
> |
smLocator_apply(sm,nr[3],nr[2],nr[0],f,n); |
2235 |
> |
smLocator_apply(sm,nr[1],nr[0],nr[2],f,n); |
2236 |
|
} |
2237 |
|
else |
2238 |
|
{/* Near face triangles */ |
2239 |
< |
smLocator_apply(smMesh,nr[0],nr[2],nr[3],f); |
2240 |
< |
smLocator_apply(smMesh,nr[2],nr[0],nr[1],f); |
2239 |
> |
smLocator_apply(sm,nr[0],nr[2],nr[3],f,n); |
2240 |
> |
smLocator_apply(sm,nr[2],nr[0],nr[1],f,n); |
2241 |
|
} |
2242 |
|
tri_plane_equation(nr[0],far[3],far[0], &peq,FALSE); |
2243 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2243 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2244 |
|
{ /* Right face triangles */ |
2245 |
< |
smLocator_apply(smMesh,far[0],far[3],nr[0],f); |
2246 |
< |
smLocator_apply(smMesh,nr[3],nr[0],far[3],f); |
2245 |
> |
smLocator_apply(sm,far[0],far[3],nr[0],f,n); |
2246 |
> |
smLocator_apply(sm,nr[3],nr[0],far[3],f,n); |
2247 |
|
} |
2248 |
|
else |
2249 |
|
{/* Right face triangles */ |
2250 |
< |
smLocator_apply(smMesh,nr[0],far[3],far[0],f); |
2251 |
< |
smLocator_apply(smMesh,far[3],nr[0],nr[3],f); |
2250 |
> |
smLocator_apply(sm,nr[0],far[3],far[0],f,n); |
2251 |
> |
smLocator_apply(sm,far[3],nr[0],nr[3],f,n); |
2252 |
|
} |
2253 |
|
|
2254 |
|
tri_plane_equation(nr[1],far[2],nr[2], &peq,FALSE); |
2255 |
|
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2256 |
|
{ /* Left face triangles */ |
2257 |
< |
smLocator_apply(smMesh,nr[2],far[2],nr[1],f); |
2258 |
< |
smLocator_apply(smMesh,far[1],nr[1],far[2],f); |
2257 |
> |
smLocator_apply(sm,nr[2],far[2],nr[1],f,n); |
2258 |
> |
smLocator_apply(sm,far[1],nr[1],far[2],f,n); |
2259 |
|
} |
2260 |
|
else |
2261 |
|
{ /* Left face triangles */ |
2262 |
< |
smLocator_apply(smMesh,nr[1],far[2],nr[2],f); |
2263 |
< |
smLocator_apply(smMesh,far[2],nr[1],far[1],f); |
2262 |
> |
smLocator_apply(sm,nr[1],far[2],nr[2],f,n); |
2263 |
> |
smLocator_apply(sm,far[2],nr[1],far[1],f,n); |
2264 |
|
} |
2265 |
|
tri_plane_equation(nr[0],far[0],nr[1], &peq,FALSE); |
2266 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2266 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2267 |
|
{/* Top face triangles */ |
2268 |
< |
smLocator_apply(smMesh,nr[1],far[0],nr[0],f); |
2269 |
< |
smLocator_apply(smMesh,far[1],far[0],nr[1],f); |
2268 |
> |
smLocator_apply(sm,nr[1],far[0],nr[0],f,n); |
2269 |
> |
smLocator_apply(sm,far[1],far[0],nr[1],f,n); |
2270 |
|
} |
2271 |
|
else |
2272 |
|
{/* Top face triangles */ |
2273 |
< |
smLocator_apply(smMesh,nr[0],far[0],nr[1],f); |
2274 |
< |
smLocator_apply(smMesh,nr[1],far[0],far[1],f); |
2273 |
> |
smLocator_apply(sm,nr[0],far[0],nr[1],f,n); |
2274 |
> |
smLocator_apply(sm,nr[1],far[0],far[1],f,n); |
2275 |
|
} |
2276 |
|
tri_plane_equation(nr[3],nr[2],far[3], &peq,FALSE); |
2277 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2277 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2278 |
|
{/* Bottom face triangles */ |
2279 |
< |
smLocator_apply(smMesh,far[3],nr[2],nr[3],f); |
2280 |
< |
smLocator_apply(smMesh,far[3],far[2],nr[2],f); |
2279 |
> |
smLocator_apply(sm,far[3],nr[2],nr[3],f,n); |
2280 |
> |
smLocator_apply(sm,far[3],far[2],nr[2],f,n); |
2281 |
|
} |
2282 |
|
else |
2283 |
|
{ /* Bottom face triangles */ |
2284 |
< |
smLocator_apply(smMesh,nr[3],nr[2],far[3],f); |
2285 |
< |
smLocator_apply(smMesh,nr[2],far[2],far[3],f); |
2284 |
> |
smLocator_apply(sm,nr[3],nr[2],far[3],f,n); |
2285 |
> |
smLocator_apply(sm,nr[2],far[2],far[3],f,n); |
2286 |
|
} |
2287 |
|
tri_plane_equation(far[2],far[0],far[1], &peq,FALSE); |
2288 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2288 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2289 |
|
{/* Far face triangles */ |
2290 |
< |
smLocator_apply(smMesh,far[0],far[2],far[1],f); |
2291 |
< |
smLocator_apply(smMesh,far[2],far[0],far[3],f); |
2290 |
> |
smLocator_apply(sm,far[0],far[2],far[1],f,n); |
2291 |
> |
smLocator_apply(sm,far[2],far[0],far[3],f,n); |
2292 |
|
} |
2293 |
|
else |
2294 |
|
{/* Far face triangles */ |
2295 |
< |
smLocator_apply(smMesh,far[1],far[2],far[0],f); |
2296 |
< |
smLocator_apply(smMesh,far[3],far[0],far[2],f); |
2295 |
> |
smLocator_apply(sm,far[1],far[2],far[0],f,n); |
2296 |
> |
smLocator_apply(sm,far[3],far[0],far[2],f,n); |
2297 |
|
} |
2298 |
|
|
2299 |
|
} |