📄 mgcdlodnode.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 + -