物体剔除代码+解析

来源:互联网 发布:知乎 西方哲学史 编辑:程序博客网 时间:2024/04/30 05:31

/*
     简单介绍一下物体剔除的原理:
    
     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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 门过梁搭接不够怎么办 华为g7开不了机怎么办 警务通手机丢了怎么办 手机被伪基站覆盖怎么办 听了高频率声音怎么办 qq音乐签到没了怎么办 手机qq音乐不能播放怎么办 台式电脑放歌没有声音怎么办 微信图片上传大愎怎么办 行车记录仪内存卡丢了怎么办 投资项目失败lp的钱怎么办 无线网无ip分配怎么办 为什么电脑的暴风影音打不开怎么办 电枪充电板进水怎么办 捡到一颗子弹该怎么办 防弹衣只保护身体那手臂怎么办? 被子被宝宝尿湿怎么办 眼睛被子弹打了怎么办 gta5买了2套衣服怎么办 gta5车被摧毁了怎么办 gta5车被损坏了怎么办 头盔玻璃磨花了怎么办 浇花喷水壶坏了怎么办 电力专用光缆撞了怎么办 国防电缆挖断了怎么办 国防光缆挖断了怎么办 房门前乱挂光纤线影响住户怎么办 挂断低于限高的光缆怎么办 开大车挂住光缆怎么办 风把树枝挂断压到车该怎么办 货车柴油冻住了怎么办 尖头鞋老是折尖怎么办 打 氟氯西林疼怎么办 多余的十字绣线怎么办 硅胶类的东西沾到蓝药水怎么办? ph计斜率不到90怎么办 ph计斜率低于90怎么办 顾客说衣服起球怎么办 买的手机壳太滑怎么办 硅胶手机壳太滑怎么办 磨砂手机壳太滑怎么办