--- a/trunk/contrib/brl/bseg/boxm2/volm/cl/generalized_volm_obj_based_matching_with_orient.cl
+++ b/trunk/contrib/brl/bseg/boxm2/volm/cl/generalized_volm_obj_based_matching_with_orient.cl
@@ -5,6 +5,8 @@
                                                               __global unsigned*                grd_id,         // query -- ground index id
                                                               __global unsigned*            grd_offset,         // query -- ground array offset indicator
                                                               __global unsigned char*         grd_dist,         // query -- ground query distance   (single float)
+                                                              __global unsigned char*         grd_land,         // query -- ground query land fallback category (4 uchar per ray)
+                                                              __global float*             grd_land_wgt,         // query -- ground query land fallback category weight (4 floats per ray)
                                                               __global float*               grd_weight,         // query -- ground weight parameter (single float)
                                                               __global float*            grd_wgt_attri,         // query -- ground weight parameters for different attributes (3 floats)
                                                               __global unsigned*                sky_id,         // query -- sky index id
@@ -14,12 +16,16 @@
                                                               __global unsigned*            obj_offset,         // query -- object array offset indicator
                                                               __global unsigned char*     obj_min_dist,         // query -- object query minimium distance
                                                               __global unsigned char*       obj_orient,         // query -- object query orientation
+                                                              __global unsigned char*         obj_land,         // query -- object query land fallback category (4 uchar per ray)
+                                                              __global float*             obj_land_wgt,         // query -- object query land fallback category weight (4 float per ray)
                                                               __global float*               obj_weight,         // query -- object weight parameter array (n_obj floats)
                                                               __global float*            obj_wgt_attri,         // query -- object wieght parameter array (4*n_obj floats)
                                                               __global unsigned*                 n_ind,         // index -- number of indices passed into device (single unsigned)
                                                               __global unsigned*            layer_size,         // index -- size of spherical shell container (single unsigned)
+                                                              __global unsigned char*    fallback_size,         // index -- number of the possible land type store in fallback land category
                                                               __global unsigned char*            index,         // index -- index depth array
                                                               __global unsigned char*     index_orient,         // index -- index orientation array (0,100 invalid, 1 -- horizontal, 2 - 9 vertical, 254 -- sky)
+                                                              __global unsigned char*       index_land,         // index -- index land array
                                                               __global float*                    score,         // score array (score per index per camera)
                                                               __global float*                       mu,         // average depth array for index
                                                               __global float*           depth_interval,         // depth_interval
@@ -27,6 +33,8 @@
                                                               __global float*                    debug,         // debug array
                                                               __local unsigned char*    local_min_dist,         // query -- object minimimu distance on local memory
                                                               __local unsigned char*  local_obj_orient,         // query -- object orientation on local memory
+                                                              __local unsigned char*    local_obj_land,         // query -- object land fallback category on local memory
+                                                              __local float*        local_obj_land_wgt,         // query -- object land fallback category weight on local memory
                                                               __local float*          local_obj_weight,         // query -- object weight parameters on local memory
                                                               __local float*       local_obj_wgt_attri,         // query -- object weight parameters (for attributes) on local memory
                                                               __local float*       local_grd_wgt_attri,         // query -- object wieght parameters (for attributes) on local memory
@@ -42,6 +50,7 @@
 
   // passing necessary values from global to the local memory
   __local unsigned ln_cam, ln_obj, ln_ind, ln_layer_size, ln_depth_size;
+  __local unsigned char l_fs;
   __local float l_grd_weight, l_sky_weight;
 
   if (llid == 0) {
@@ -49,6 +58,7 @@
     ln_obj = *n_obj;
     ln_ind = *n_ind;
     ln_layer_size = *layer_size;
+    l_fs = *fallback_size;
     l_grd_weight = *grd_weight;
     l_sky_weight = *sky_weight;
     ln_depth_size = *depth_length;
@@ -69,6 +79,8 @@
 
   if (llid < ln_obj*4) {
     local_obj_wgt_attri[llid] = obj_wgt_attri[llid];
+    local_obj_land[llid] = obj_land[llid];
+    local_obj_land_wgt[llid] = obj_land_wgt[llid];
   }
   barrier(CLK_LOCAL_MEM_FENCE);
 
@@ -102,22 +114,40 @@
     unsigned char alt_ratio = 2;
     unsigned start_grd = grd_offset[cam_id];
     unsigned end_grd = grd_offset[cam_id+1];
-    unsigned grd_count = 0;
-    unsigned grd_count_ori = 0;
+    unsigned score_grd_dst = 0;
+    unsigned score_grd_ori = 0;
+    float    score_grd_lnd = 0.0;
     for (unsigned k = start_grd; k < end_grd; ++k) {
       unsigned id = start_ind + grd_id[k];
+      // ground distance score
       if (index[id] < ln_depth_size && grd_dist[k] < ln_depth_size ) {
         float ind_d = local_depth_interval[index[id]];
         float grd_d = local_depth_interval[grd_dist[k]];
         float delta_d = alt_ratio * grd_d;
         if ( ind_d >= (grd_d - delta_d) && ind_d <= (grd_d+delta_d) )
-          grd_count += 1;
+          score_grd_dst += 1;
       }
+      // ground orientation score
       if (index_orient[id] == 1) // ground should always be horizontal
-       grd_count_ori += 1;
+       score_grd_ori += 1;
+      // ground land type score
+      unsigned char ind_lnd = index_land[id];
+      unsigned lnd_start = k * l_fs;
+      if (ind_lnd != 0 && ind_lnd != 254) {
+        for (unsigned ii = 0; ii < l_fs; ii++) {
+          unsigned l_id = lnd_start + ii;
+          if (ind_lnd == grd_land[l_id]) {
+            score_grd_lnd += grd_land_wgt[l_id];
+            break;
+          }
+        }
+      }
     }
     float score_grd;
-    score_grd = (float)(local_grd_wgt_attri[2] * grd_count + local_grd_wgt_attri[0] * grd_count_ori); // ground score is composed by distance and orientation
+    score_grd = local_grd_wgt_attri[0]*score_grd_ori + 
+                local_grd_wgt_attri[1]*score_grd_lnd +
+                local_grd_wgt_attri[2]*score_grd_dst;
+    
     score_grd = (end_grd != start_grd) ? score_grd / (end_grd-start_grd) : 0;
     score_grd = score_grd * l_grd_weight;
 
@@ -153,29 +183,35 @@
       unsigned offset_id = k + ln_obj * cam_id;
       unsigned start_obj = obj_offset[offset_id];
       unsigned end_obj = obj_offset[offset_id+1];
+      unsigned lnd_start = k*l_fs;
+      unsigned lnd_end = (k+1)*l_fs;
       float score_k_ord = 0.0f;
       float score_k_min = 0.0f;
       float score_k_ori = 0.0f;
+      float score_k_lnd = 0.0f;
       for (unsigned i = start_obj; i < end_obj; ++i) {
         unsigned id = start_ind + obj_id[i];
         unsigned d = index[id];
         unsigned s_vox_ord = 1;
         unsigned s_vox_min = 0;
         unsigned s_vox_ori = 0;
+
+        // calculate order and distance score
         if (d < 253 && d < ln_depth_size) {
           // calculate order score for voxel i
           for (unsigned mu_id = 0; (s_vox_ord && mu_id < k); ++mu_id)
-            if (mu[mu_id+mu_start_id] != 0)
-              s_vox_ord = s_vox_ord * (local_depth_interval[d] >= mu[mu_id + mu_start_id]);
+            if (mu[mu_id+mu_start_id]*mu[mu_id+mu_start_id] > 1E-7)
+              s_vox_ord = s_vox_ord * (local_depth_interval[d] - mu[mu_id + mu_start_id] > -1E-5);
           for (unsigned mu_id = k+1; (s_vox_ord && mu_id < ln_obj); ++mu_id)
-            if (mu[mu_id+mu_start_id] != 0)
-              s_vox_ord = s_vox_ord * (local_depth_interval[d] <= mu[mu_id + mu_start_id]);
+            if (mu[mu_id+mu_start_id]*mu[mu_id+mu_start_id] > 1E-7)
+              s_vox_ord = s_vox_ord * (local_depth_interval[d] - mu[mu_id + mu_start_id] < 1E-5);
           // calculate min_distance socre for voxel i
           s_vox_min = (d > local_min_dist[k]) ? 1 : 0;
         }
         else {
           s_vox_ord = 0;
         }
+
         // calculate orientation of object
         unsigned char ind_ori = index_orient[id];
         if (ind_ori > 0 && ind_ori < 10) {  // check whether index orientation is meaningful
@@ -187,12 +223,29 @@
           // ind_ori == 2 and query_ori == 2  ---> all exactly vertical (front-parallel)
           // ind_ori == 3-9 and query_ori == 2 --> index is heading to 8 different direction, e.g, southwest, but transfer to vertical
         }
+        
+        // calculate land_type score
+        unsigned char ind_lnd = index_land[id];
+        if (ind_lnd != 0 && ind_lnd != 254) {
+          for (unsigned ii = lnd_start; ii < lnd_end; ii++) {
+            if (ind_lnd == local_obj_land[ii]) {
+              score_k_lnd += local_obj_land_wgt[ii];
+              break;
+            }
+          }
+        }
         score_k_ord += (float)s_vox_ord;
         score_k_min += (float)s_vox_min;
         score_k_ori += (float)s_vox_ori;
-      }
+      }  // finish object k
+
       // normalized the score for object k
-      float score_k = local_obj_wgt_attri[k*4+3]*score_k_ord + local_obj_wgt_attri[k*4+2]*score_k_min + local_obj_wgt_attri[k*4]*score_k_ori;  // object score is composed by relative order, depth, and orientation
+      unsigned att_s = k*4;
+      float score_k = local_obj_wgt_attri[att_s] * score_k_ori +
+                      local_obj_wgt_attri[att_s+1] * score_k_lnd +
+                      local_obj_wgt_attri[att_s+2] * score_k_min +
+                      local_obj_wgt_attri[att_s+3] * score_k_ord;
+
       score_k = (end_obj != start_obj) ? score_k/(end_obj-start_obj) : 0;
       score_k *= local_obj_weight[k];
       // summerize the object score
@@ -200,7 +253,7 @@
     }
 
 #if 0
-    if ( cam_id == 3 && ind_id == 8 ) {
+    if ( cam_id == 0 && ind_id == 6 ) {
        debug[0] = cam_id;
        debug[1] = ind_id;
        debug[2] = local_grd_wgt_attri[0];
@@ -212,7 +265,6 @@
        debug[8] = score_obj;
     }
 #endif
-
     // summerize the scores
     unsigned score_id = cam_id + ind_id*ln_cam;
     score[score_id] = score_sky + score_grd + score_obj;