我要发帖 回复

正式会员

16

主题

43

积分

0

专家分

死亡骑士

:

私信
发表时间 : 2009-2-6 15:11:00 | 浏览 : 1954    评论 : 2
3ds文件有自己的一套坐标系,用opgl集成一个场景,导入多个3ds文件,对其进行包围盒视锥裁剪,需要将不同3ds文件中的点转换为统一坐标系下的坐标。

遇到这种情况,首先考虑的是平移操作。这个操作很简单。代码如下:
[cpp]void C3DModleManager::CalculateRealCoord(t3DModel &TempModel, CS3dVector pos)
{
        float g_max_x = -100000000;
        float g_min_x = 100000000;
        float g_max_y = -100000000;
        float g_min_y = 100000000;
        float g_max_z = -1000000000;
        float g_min_z = 1000000000;
        for (int i=0; i<TempModel.numOfObjects; i++)
        {
                float max_x = -10000000;
                float min_x = 10000000;
                float max_y = -10000000;
                float min_y = 10000000;
                float max_z = -10000000;
                float min_z = 10000000;

                for (int j=0; j<TempModel.pObject.numOfVerts; j++)
                {
                        CVector3Simple EveryVert = TempModel.pObject.pVerts[j];

                        TempModel.pObject.pVertsGloabal[j].x = TempModel.pObject.pVerts[j].x + (pos.x-TempModel.m_Center.x);
                        TempModel.pObject.pVertsGloabal[j].y = TempModel.pObject.pVerts[j].y + (pos.y-TempModel.m_Center.y);
                        TempModel.pObject.pVertsGloabal[j].z = TempModel.pObject.pVerts[j].z + (pos.z-TempModel.m_Center.z);
                       
                        EveryVert.x = TempModel.pObject.pVertsGloabal[j].x;
                        EveryVert.y = TempModel.pObject.pVertsGloabal[j].y;
                        EveryVert.z = TempModel.pObject.pVertsGloabal[j].z;

                        if(EveryVert.x>g_max_x)
                                g_max_x = EveryVert.x;
                        if(EveryVert.x<g_min_x)
                                g_min_x = EveryVert.x;
                        if(EveryVert.y>g_max_y)
                                g_max_y = EveryVert.y;
                        if(EveryVert.y<g_min_y)
                                g_min_y = EveryVert.y;
                        if(EveryVert.z>g_max_z)
                                g_max_z = EveryVert.z;
                        if(EveryVert.z<g_min_z)
                                g_min_z = EveryVert.z;
                        if(EveryVert.x>max_x)
                                max_x = EveryVert.x;
                        if(EveryVert.x<min_x)
                                min_x = EveryVert.x;
                        if(EveryVert.y>max_y)
                                max_y = EveryVert.y;
                        if(EveryVert.y<min_y)
                                min_y = EveryVert.y;
                        if(EveryVert.z>max_z)
                                max_z = EveryVert.z;
                        if(EveryVert.z<min_z)
                                min_z = EveryVert.z;
                }
                TempModel.pObject.m_BoundaryGlobal.maxx = max_x+1.0;
                TempModel.pObject.m_BoundaryGlobal.maxy = max_y+1.0;
                TempModel.pObject.m_BoundaryGlobal.maxz = max_z+1.0;
                TempModel.pObject.m_BoundaryGlobal.minx = min_x-1.0;
                TempModel.pObject.m_BoundaryGlobal.miny = min_y-1.0;
                TempModel.pObject.m_BoundaryGlobal.minz = min_z-1.0;
        }
        TempModel.m_BoundaryGlobal.maxx = g_max_x;
        TempModel.m_BoundaryGlobal.maxy = g_max_y;
        TempModel.m_BoundaryGlobal.maxz = g_max_z;
        TempModel.m_BoundaryGlobal.miny = g_min_y;
        TempModel.m_BoundaryGlobal.minz = g_min_z;
}
[/cpp]
调用语句为[cpp]my3DSCene.m_3DModle.CalculateRealCoord(my3DSCene.m_3DModle.m_ModelList[Index], my3DSCene.m_3DModle.m_ModelList[Index].m_Postion);[/cpp]

在缩放的时候,用如下函数:
[cpp]void C3DModleManager::CalculateScaleCoord(t3DModel &TempModel, int EditAxis, float fScale)
{
        for (int i=0; i<TempModel.numOfObjects; i++)
        {
                for (int j=0; j<TempModel.pObject.numOfVerts; j++)
                {
                        switch (EditAxis)
                        {
                        case 1:
                                TempModel.pObject.pVerts[j].x = TempModel.pObject.pVerts[j].x * fScale;
                                break;
                        case 2:
                                TempModel.pObject.pVerts[j].y = TempModel.pObject.pVerts[j].y * fScale;
                                break;
                        case 3:
                                TempModel.pObject.pVerts[j].z = TempModel.pObject.pVerts[j].z * fScale;
                                break;
                        case 0:
                                TempModel.pObject.pVerts[j].x = TempModel.pObject.pVerts[j].x * fScale;
                                TempModel.pObject.pVerts[j].y = TempModel.pObject.pVerts[j].y * fScale;
                                TempModel.pObject.pVerts[j].z = TempModel.pObject.pVerts[j].z * fScale;
                                break;
                        default:
                                break;
                        }
                       
                }
        }
}
[/cpp]
之后再将缩放完毕的坐标进行坐标平移转换。

但是问题在于单独进行平移操作,视锥裁剪是正确的。如果进行了缩放之后,再平移,就错误了。我想错误可能是处在缩放的环节。还请高手看看错误在哪里?

最近VR访客

buynowdays 评论于2013-1-4 11:31:50
透视投影后平移会有问题
zyh_2000专家组 评论于2013-1-5 14:08:05
楼主可以把缩放与平移的运算顺序颠倒一下试试效果, 平移是不改变物体各个顶点的位置关系的, 但缩放会改变顶点的位置关系, 如果先缩放再平移可能把物体搞坏, 你可以参考一下OpenGL 红宝书的 第三章 视图模型变换, 对图形运算的顺序和效果都有论述。{:2_66:}

手机版|VR开发网 ( 津ICP备18009691号 ) 统计 网安备12019202000257

GMT+8, 2020-10-26 11:50 PM

返回顶部