物体剔除代码+解析


/*
     简单介绍一下物体剔除的原理:
    
     1 , 计算物体中心点坐标
     2 , 以物体中心点作为球体圆点, max_radius为半径。
     3 , 对于Z轴来说,需要比较球体是否在远截面和近截面内部
     4 , 对于X轴来说, 首先需要在透视明面上计算x的边界值
  公式如下 : float x_test = 0.5f * lpCamera3D->viewplant_width * sphere_pos.z / lpCamera3D->view_dist_h                 
               那么为什么之后还要进行x_test += (lpObject3D->max_radius); 请看下图
               

(槽图 +槽字,有时间会提高图片质量,见谅啦 :))

               由于在程序中一般默认的相机视野角是90度,那么当物体进行横向偏移的时候,物体侧面会出现在视野内, 那么这个侧面出现的视野X长度是多少呢?由上图可见, 最大值就是max_radius的值
               所以为了保证当物体正好移除视野时,程序就能捕捉到,而不会浪费循环去绘制已经不再视野范围内的物体,则需要将x_test + max_radius

               对于y 道理是一样的。唯一需要提及的是,由于有的程序他的屏幕宽高比并不是1:1,那么这个时候,他侧面所出现的长度就不会是max_radius, 而是max_dius * (1/lpCamera3D->ratio)

                用这种方式计算 x, y轴边界物体剔除问题,效果不错, 笔者测试了一下, 当物体刚刚移出视野,则程序就会捕捉到,而不会浪费系统循环区绘制已经不在视野内的物体。
*/

int   C3DENGINE   ::   Cull_Object   (   __LPOBJECT3D   lpObject3D   ,   __LPCAMERA3D   lpCamera3D ) {
               if ( NULL   ==   lpObject3D ) {
                           CLOG_MARKER ( "error"   ,   "C3DENGINE :: Cull_Object" );
                           CLOG_GETOBJECT ( "error"   )-> write (   "ERROR: illegal [in]parameter -> lpObject3D is NULL!" );
                           exit (-1);
            }
               __POINT3DF   sphere_pos   ;
               /*
                        lpObject3D->world_pos 物体世界坐标
                        lpCamera3D->mcam          相机旋转平移矩阵
                        sphere_pos,                         物体中心点坐标
            */
            Mult_VM3D(sphere_pos, lpObject3D->   world_pos ,   lpCamera3D   -> mcam );

               /*
                                    lpCamera3D->far_clip                    相机远截面
                                    lpCamera3D->near_clip                  相机近截面
                                    lpObject3D->max_radius                  以sphere_pos为中心点的球体半径
            */
               if (sphere_pos.z - lpObject3D->max_radius > lpCamera3D->far_clip ||
                        sphere_pos.   z   + lpObject3D-> max_radius   < lpCamera3D-> near_clip ) {
                                    lpObject3D->   bCulled   =   TRUE   ;
                                       //write error log
                                       return   _CULL_MODE_Z   ;
            }

               float   x_test = 0.5f * lpCamera3D->viewplant_width *   sphere_pos .z / lpCamera3D-> view_dis_h ;
               x_test   += ( lpObject3D   -> max_radius );
               if (sphere_pos. x   -   lpObject3D ->max_radius >   x_test   ||
                           sphere_pos .x + lpObject3D->max_radius < - x_test   ) {
                                    lpObject3D->bCulled =   TRUE ;
                                       //write error log
                                       return   _CULL_MODE_X   ;
            }

               float   y_test = 0.5f * lpCamera3D->viewplant_height *   sphere_pos .z / lpCamera3D-> view_dis_h ;
               y_test   += (( lpObject3D   -> max_radius )*(1/lpCamera3D->   ratio ));
               if ( sphere_pos   .y -lpObject3D-> max_radius   > y_test ||
                           sphere_pos .y + lpObject3D-> max_radius   < - y_test ) {
                                    lpObject3D->bCulled =   TRUE ;
                                       //write error log
                                       return   _CULL_MODE_Y   ;
            }
               return   _CULL_MODE_NONE   ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值