物体剔除代码+解析

本文介绍了一种基于球体模型的物体剔除算法,通过计算物体中心点坐标并判断其是否在视锥体内来决定是否绘制该物体,有效减少不必要的渲染过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


/*
     简单介绍一下物体剔除的原理:
    
     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 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值