ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm.c
(Generate patch)

Comparing ray/src/hd/sm.c (file contents):
Revision 3.10 by gwlarson, Mon Dec 28 19:30:27 1998 UTC vs.
Revision 3.14 by gwlarson, Fri Mar 5 16:33:17 1999 UTC

# Line 18 | Line 18 | static char SCCSid[] = "$SunId$ SGI";
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},
# Line 239 | Line 242 | smDir(sm,ps,id)
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;
# Line 445 | Line 438 | smAlloc(max_samples)
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  
# Line 488 | Line 481 | smInit(n)
481   {
482    int max_vertices;
483  
491
484    /* If n <=0, Just clear the existing structures */
485    if(n <= 0)
486    {
# Line 517 | Line 509 | smInit(n)
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];
# Line 530 | Line 523 | smLocator_apply(sm,v0,v1,v2,func)
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)
# Line 568 | Line 559 | insert_tri(argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,
559    /* If the set size is below expansion threshold,or at maximum
560       number of quadtree levels : just add */
561    optr = qtqueryset(qt);
562 <  if(QT_SET_CNT(optr) < QT_SET_THRESHOLD || (n >= QT_MAX_LEVELS))
562 >  if(QT_SET_CNT(optr) < QT_SET_THRESHOLD || (n > (QT_MAX_LEVELS-2)))
563      return(qtadduelem(qt,t_id));
564    /* otherwise: expand node- and insert tri, and reinsert existing tris
565       in set to children of new node
# Line 697 | Line 688 | int v0_id,v1_id,v2_id;
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   }
# Line 769 | Line 759 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_p
759                         !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,1))) ||
760                         !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,2))))
761            goto Ltri_error;
762 +        /*
763          if(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,1)) ||
764             SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) ||
765             SM_NTH_TRI(sm,T_NTH_NBR(ta,1))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) ||
# Line 776 | Line 767 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_p
767             SM_NTH_TRI(sm,T_NTH_NBR(tb,0))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) ||
768             SM_NTH_TRI(sm,T_NTH_NBR(tb,1))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) )
769            goto Ltri_error;
770 +          */
771   #endif
772      /* Reset neighbor pointers of original neighbors */
773      n = SM_NTH_TRI(sm,T_NTH_NBR(t,enext));
# Line 811 | Line 803 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_p
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);
817 #else
818    *del_ptr = push_data(*del_ptr,t_id);
819    *del_ptr = push_data(*del_ptr,t1_id);
820 #endif
809  
822
823
810      *tn_id = ta_id;
811      *tn1_id = tb_id;
812      
# Line 850 | Line 836 | smUpdate_locator(sm,add_list)
836   SM *sm;
837   LIST *add_list;
838   {
839 <  int t_id,i;
839 >  int t_id;
840    TRI *t;
855  OBJECT *optr;
841    
842    while(add_list)
843    {
# Line 872 | Line 857 | LIST *tlist,*add_list;
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)
# Line 894 | Line 879 | LIST *tlist,*add_list;
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;
# Line 909 | Line 894 | LIST *tlist,*add_list;
894              tlist = push_data(tlist,t_opp_id);
895          }
896      }
897 < #if 0
913 <    while(del_list)
914 <    {
915 <      t_id = pop_list(&del_list);
916 <      smDelete_tri(sm,t_id);
917 <    }
918 < #endif
897 >
898      smUpdate_locator(sm,add_list);
899  
900      return(swapped);
# Line 967 | Line 946 | smInsert_samp(sm,s_id,tri_id,on,which)
946      FVECT npt;
947      TRI *tri,*nbr,*topp;
948  
970
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);
# Line 1226 | Line 1204 | int *onptr,*whichptr;
1204    optr = qtqueryset(qt);
1205    tri_id = smTri_in_set(sm,tpt,optr,onptr,whichptr);
1206  
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
1207    return(tri_id);
1208   }
1209  
# Line 1285 | Line 1257 | smTest_sample(sm,tri_id,dir,p,rptr)
1257  
1258      for(i=0; i<3; i++)
1259      {
1260 <        if(SM_BASE_ID(sm,vid[i]))
1261 <        {
1262 <          bcnt++;
1263 <           continue;
1264 <        }
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 */
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;
1302    if(bcnt + dcnt != 3)
1303    {
1271        VSUB(spt,p,SM_VIEW_CENTER(sm));
1272        ds = DOT(spt,spt);
1273        dnear = FHUGE;
1274        for(i=0; i<3; i++)
1275          {
1309          if(SM_BASE_ID(sm,vid[i]) || SM_DIR_ID(sm,vid[i]))
1310            continue;
1276            d = DOT(diff[i],diff[i])/ds;
1277            if(d < dnear)
1278              {
# Line 1316 | Line 1281 | smTest_sample(sm,tri_id,dir,p,rptr)
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));
# Line 1328 | Line 1305 | smTest_sample(sm,tri_id,dir,p,rptr)
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);
1339 <            }
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;
1350        if(bcnt + dcnt ==3)
1351          VSUB(spt,p,SM_VIEW_CENTER(sm));
1328          if(!norm)
1329            normalize(spt);
1330  
# Line 1358 | Line 1334 | smTest_sample(sm,tri_id,dir,p,rptr)
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];
# Line 1371 | Line 1347 | smTest_sample(sm,tri_id,dir,p,rptr)
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);    
# Line 1394 | Line 1429 | smTest_sample(sm,tri_id,dir,p,rptr)
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);    
# Line 1413 | Line 1450 | smTest_sample(sm,tri_id,dir,p,rptr)
1450      return(FALSE);
1451   }
1452  
1453 <
1417 < int
1418 < 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;
1422 <  SAMP *s;
1423 <  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;
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");
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
# Line 1445 | Line 1494 | smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which)
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);
# Line 1454 | Line 1503 | smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which)
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);
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 <    }
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,
# Line 1537 | Line 1638 | smAdd_samp(sm,c,dir,p,o_id)
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      }
1556    if((!(smTest_sample(sm,t_id,dir,p,&r_id))))
1557    {
1558      smUnalloc_samp(sm,s_id);
1559      return(INVALID);
1560    }
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          }
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    }
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      {
# Line 1596 | Line 1724 | smAdd_samp(sm,c,dir,p,o_id)
1724      }
1725      smInsert_samp(sm,s_id,t_id,on,which);
1726  
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    }
1727      return(s_id);
1728   }
1729  
# Line 1624 | Line 1746 | FVECT p;
1746   {
1747      int s_id;
1748  
1627
1749      /* First check if this the first sample: if so initialize mesh */
1629
1750      if(SM_NUM_SAMP(smMesh) == 0)
1751      {
1752        smInit_sm(smMesh,odev.v.vp);
# Line 1700 | Line 1820 | int type;
1820  
1821   }
1822  
1703
1704 int
1705 smNext_tri_flag_set(sm,i,which,b)
1706     SM *sm;
1707     int i,which;
1708     int b;
1709 {
1710
1711  for(; i < SM_NUM_TRI(sm);i++)
1712  {
1713
1714    if(!T_IS_VALID(SM_NTH_TRI(sm,i)))
1715         continue;
1716    if(!SM_IS_NTH_T_FLAG(sm,i,which))
1717        continue;
1718    if(!b)
1719      break;
1720    if((b==1) && !SM_BG_TRI(sm,i))
1721      break;
1722    if((b==2) && SM_BG_TRI(sm,i))
1723      break;
1724  }
1725    
1726  return(i);
1727 }
1728
1729
1730 int
1731 smNext_valid_tri(sm,i)
1732     SM *sm;
1733     int i;
1734 {
1735
1736  while( i < SM_NUM_TRI(sm) && !T_IS_VALID(SM_NTH_TRI(sm,i)))
1737     i++;
1738    
1739  return(i);
1740 }
1741
1742
1743
1744 qtTri_from_id(t_id,v0,v1,v2)
1745 int t_id;
1746 FVECT v0,v1,v2;
1747 {
1748  TRI *t;
1749  
1750  t = SM_NTH_TRI(smMesh,t_id);
1751  if(!T_IS_VALID(t))
1752    return(0);
1753  VSUB(v0,SM_T_NTH_WV(smMesh,t,0),SM_VIEW_CENTER(smMesh));
1754  VSUB(v1,SM_T_NTH_WV(smMesh,t,1),SM_VIEW_CENTER(smMesh));
1755  VSUB(v2,SM_T_NTH_WV(smMesh,t,2),SM_VIEW_CENTER(smMesh));
1756  return(1);
1757 }
1758
1759
1823   smRebuild_mesh(sm,v)
1824     SM *sm;
1825     VIEW *v;
# Line 1768 | Line 1831 | smRebuild_mesh(sm,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);
# Line 1807 | Line 1871 | smRebuild_mesh(sm,v)
1871          }
1872  
1873      }
1810
1811   smNew_tri_cnt = SM_SAMPLE_TRIS(sm);
1874   #ifdef DEBUG
1875      fprintf(stderr,"smRebuild_mesh():done\n");
1876   #endif
# Line 1831 | Line 1893 | intersect_tri_set(t_set,orig,dir,pt)
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);
1839        if(base = SM_IS_NTH_T_BASE(smMesh,t_id))
1840          if(SM_BASE_ID(smMesh,pid0) && SM_BASE_ID(smMesh,pid1) &&
1841             SM_BASE_ID(smMesh,pid2))
1842            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);
1855 <                id = (d1 < d)?pid2:pid0;
1856 <              }
1857 <            else
1858 <              {
1859 <                d = DIST_SQ(p,p2);
1860 <                id = (d < d1)? pid2:pid1;
1861 <              }
1862 <          }
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 <              {
1867 <                if(SM_BASE_ID(smMesh,pid1))
1868 <                  id = pid2;
1869 <                else
1870 <                  if(SM_BASE_ID(smMesh,pid2))
1871 <                    id = pid1;
1872 <                  else
1873 <                  {
1874 <                    d =  DIST_SQ(p,p1);
1875 <                    d1 = DIST_SQ(p,p2);
1876 <                    if(d < d1)
1877 <                      id = pid1;
1878 <                    else
1879 <                      id = pid2;
1880 <                  }
1881 <              }
1882 <              else
1883 <              {
1884 <                if(SM_BASE_ID(smMesh,pid1))
1885 <                {
1886 <                  if(SM_BASE_ID(smMesh,pid2))
1887 <                    id = pid0;
1888 <                  else
1889 <                  {
1890 <                    d =  DIST_SQ(p,p0);
1891 <                    d1 = DIST_SQ(p,p2);
1892 <                    if(d < d1)
1893 <                      id = pid0;
1894 <                    else
1895 <                      id = pid2;
1896 <                  }
1897 <                }
1898 <                else
1899 <                {
1900 <                  d =  DIST_SQ(p,p0);
1901 <                  d1 = DIST_SQ(p,p1);
1902 <                  if(d < d1)
1903 <                    id = pid0;
1904 <                  else
1905 <                    id = pid1;
1906 <                }
1907 <              }
1916 >              d = DIST_SQ(p,p2);
1917 >              id = (d < d1)? pid2:pid1;
1918              }
1919            if(pt)
1920              VCOPY(pt,p);
# Line 2041 | Line 2051 | FVECT orig,dir;
2051   #ifdef DEBUG_TEST_DRIVER
2052      VCOPY(Pick_point[0],p);
2053   #endif
2044 #ifdef DEBUG
2045    fprintf(stderr,"Simple pick returning %d\n",s_id);
2046 #endif
2047
2054      return(s_id);
2055    }
2056    d = point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh));
# Line 2058 | Line 2064 | FVECT orig,dir;
2064   #ifdef DEBUG_TEST_DRIVER
2065          VCOPY(Pick_point[0],p);
2066   #endif
2061 #ifdef DEBUG
2062    fprintf(stderr,"Simple pick2 returning %d\n",s_id);
2063 #endif
2067          return(s_id);
2068    }
2069    if(OPP_EQUAL_VEC3(b,dir))
# Line 2110 | Line 2113 | FVECT orig,dir;
2113      F_ARGS(func) = (int *)(&rt);
2114      stTrace_ray(SM_LOCATOR(smMesh),o,dir,func);
2115      s_id = rt.t_id;
2116 +
2117    }    
2114 #ifdef DEBUG
2115    fprintf(stderr,"Trace pick returning %d\n",s_id);
2116 #endif
2118    return(s_id);
2119  
2120   Lerror:
# Line 2124 | Line 2125 | 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;
# Line 2145 | Line 2155 | mark_active_tris(argptr,root,qt)
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 <     */
2176 <
2177 <     /* First clear all the quadtree node and triangle active flags */
2178 <     qtClearAllFlags();
2179 <     smClear_flags(smMesh,T_ACTIVE_FLAG);
2180 <     /* Clear all of the active sample flags*/
2181 <     sClear_all_flags(SM_SAMP(smMesh));
2182 <
2183 <
2184 <     /* 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  
# Line 2202 | Line 2220 | mark_tris_in_frustum(view)
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   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines