⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgcdlodnode.cpp

📁 《3D游戏引擎设计》的源码
💻 CPP
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf

#include "MgcDLodNode.h"
#include "MgcRenderer.h"

MgcImplementRTTI(MgcDLodNode,MgcSwitchNode);
MgcImplementStream(MgcDLodNode);

//----------------------------------------------------------------------------
MgcDLodNode::MgcDLodNode (unsigned int uiQuantity, unsigned int uiGrowBy)
    :
    MgcSwitchNode(uiQuantity,uiGrowBy),
    m_afModelMinSqrDist(uiQuantity),
    m_afModelMaxSqrDist(uiQuantity),
    m_afWorldMinSqrDist(uiQuantity),
    m_afWorldMaxSqrDist(uiQuantity)
{
    m_fLastUpdateTime = -MgcMath::INFINITY;
}
//----------------------------------------------------------------------------
void MgcDLodNode::SetModelMinSqrDistance (unsigned int uiIndex,
    MgcReal fMinSqrDist)
{
    unsigned int uiQuantity = m_afModelMinSqrDist.GetQuantity();
    if ( uiIndex >= uiQuantity )
    {
        m_afModelMinSqrDist.SetQuantity(uiQuantity+1,true);
        m_afWorldMinSqrDist.SetQuantity(uiQuantity+1,true);
    }

    m_afModelMinSqrDist[uiIndex] = fMinSqrDist;
}
//----------------------------------------------------------------------------
void MgcDLodNode::SetModelMaxSqrDistance (unsigned int uiIndex,
    MgcReal fMaxSqrDist)
{
    unsigned int uiQuantity = m_afModelMaxSqrDist.GetQuantity();
    if ( uiIndex >= uiQuantity )
    {
        m_afModelMaxSqrDist.SetQuantity(uiQuantity+1,true);
        m_afWorldMaxSqrDist.SetQuantity(uiQuantity+1,true);
    }

    m_afModelMaxSqrDist[uiIndex] = fMaxSqrDist;
}
//----------------------------------------------------------------------------
void MgcDLodNode::SetModelSqrDistance (unsigned int uiIndex,
    MgcReal fMinSqrDist, MgcReal fMaxSqrDist)
{
    unsigned int uiQuantity = m_afModelMinSqrDist.GetQuantity();
    if ( uiIndex >= uiQuantity )
    {
        m_afModelMinSqrDist.SetQuantity(uiQuantity+1,true);
        m_afWorldMinSqrDist.SetQuantity(uiQuantity+1,true);
    }

    uiQuantity = m_afModelMaxSqrDist.GetQuantity();
    if ( uiIndex >= uiQuantity )
    {
        m_afModelMaxSqrDist.SetQuantity(uiQuantity+1,true);
        m_afWorldMaxSqrDist.SetQuantity(uiQuantity+1,true);
    }

    m_afModelMinSqrDist[uiIndex] = fMinSqrDist;
    m_afModelMaxSqrDist[uiIndex] = fMaxSqrDist;
}
//----------------------------------------------------------------------------
void MgcDLodNode::SelectLevelOfDetail (const MgcCamera* pkCamera)
{
    // ASSERT:  The child array of an MgcDLodNode is compacted, that is,
    // there are no empty slots in the array and the number of children
    // is GetQuantity().  Moreover, it is assumed that all model squared
    // distance values were set for these children.

    MgcSwitchNode::UpdateWorldData(m_fLastUpdateTime);

    // compute world LOD center
    m_kWorldLodCenter = m_kWorldTranslate + m_fWorldScale*(
        m_kWorldRotate*m_kModelLodCenter);

    // compute world squared distance intervals
    MgcReal fWorldSqrScale = m_fWorldScale*m_fWorldScale;
    for (unsigned int uiI = 0; uiI < m_aspkChild.GetQuantity(); uiI++)
    {
        MgcReal fValue = m_afModelMinSqrDist[uiI];
        m_afWorldMinSqrDist[uiI] = fWorldSqrScale*fValue*fValue;

        fValue = m_afModelMaxSqrDist[uiI];
        m_afWorldMaxSqrDist[uiI] = fWorldSqrScale*fValue*fValue;
    }

    // select the LOD child
    SetActiveChild(SN_INVALID_CHILD);
    if ( m_aspkChild.GetQuantity() > 0 )
    {
        MgcVector3 kDiff = m_kWorldLodCenter - pkCamera->GetLocation();
        MgcReal fSqrDist = kDiff.SquaredLength();

        for (unsigned int uiI = 0; uiI < m_aspkChild.GetQuantity(); uiI++) 
        {
            if ( m_afWorldMinSqrDist[uiI] <= fSqrDist
            &&   fSqrDist < m_afWorldMaxSqrDist[uiI] )
            {
                SetActiveChild(uiI);
                break;
            }
        }
    }
}
//----------------------------------------------------------------------------
void MgcDLodNode::UpdateWorldData (MgcReal fAppTime)
{
    // Save the update time.  The update is deferred until Draw so that the
    // selected LOD child is visible .  At this time the update time is
    // needed to pass to the UpdateGS call.
    m_fLastUpdateTime = fAppTime;

    // The deferred update means that none of the children world data is
    // computed by a recursive traversal.  Just compute the world bound.
    UpdateWorldBound();
}
//----------------------------------------------------------------------------
void MgcDLodNode::Draw (MgcRenderer& rkRenderer)
{
    SelectLevelOfDetail(rkRenderer.GetCamera());
    MgcSwitchNode::Draw(rkRenderer);
}
//----------------------------------------------------------------------------

//---------------------------------------------------------------------------
// streaming
//---------------------------------------------------------------------------
MgcObject* MgcDLodNode::Factory (MgcStream& rkStream)
{
    MgcDLodNode* pkObject = new MgcDLodNode;
    MgcStream::Link* pkLink = new MgcStream::Link(pkObject);
    pkObject->Load(rkStream,pkLink);
    return pkObject;
}
//---------------------------------------------------------------------------
void MgcDLodNode::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcSwitchNode::Load(rkStream,pkLink);
}
//---------------------------------------------------------------------------
void MgcDLodNode::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcSwitchNode::Link(rkStream,pkLink);
}
//---------------------------------------------------------------------------
bool MgcDLodNode::Register (MgcStream& rkStream)
{
    return MgcSwitchNode::Register(rkStream);
}
//---------------------------------------------------------------------------
void MgcDLodNode::Save (MgcStream& rkStream)
{
    MgcSwitchNode::Save(rkStream);
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -