📄 cvselectors.cpp
字号:
if( pIterator->GetVisitType() == ChQvInstanceIterator::afterChildren)
{
bool boolKeepGoing = true;
if(!m_children.IsEmpty())
{
ChPosition pos = m_children.GetHeadPosition();
while(pos && boolKeepGoing)
{
pIterator->SetVisitType(ChQvInstanceIterator::isLeaf);
ChQvInstance *pChild = m_children.GetNext(pos);
boolKeepGoing = pChild->Iterate(pIterator);
}
}
if(boolKeepGoing)
{
SetUpKids(pRC);
}
return boolKeepGoing;
}
return true;
}
bool ChQvLODInstance::Draw(ChRenderContext *pRC, ChDrawIterator *pIterator)
{
ChQvGroupInstance::Draw(pRC, pIterator);
return true;
}
#endif
//////////////////////////////////////////////////////////
ChQvSwitchInstance::ChQvSwitchInstance() : ChQvGroupInstance(),
m_pFrames(0), m_iCurrentChild(-1)
{
}
ChQvSwitchInstance::~ChQvSwitchInstance()
{
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
delete [] m_pFrames;
m_pFrames = 0;
if(!m_children.IsEmpty())
{
ChPosition pos = m_children.GetHeadPosition();
while(pos)
{
ChQvInstance *pChild = m_children.GetNext(pos);
ChNrFrame frame = pChild->GetFrame();
if (frame) ChNrObjectDestroy(frame);
}
}
#endif
}
bool ChQvSwitchInstance::Iterate(ChQvInstanceIterator *pIterator)
{
if( pIterator->GetIterationType() == ChQvInstanceIterator::inDrawScope)
{
int iChild;
if(m_pNode)
{
iChild = int(((QvSwitch*)GetNode())->whichChild.value);
}
else
{
iChild = QV_SWITCH_ALL;
}
bool boolKeepGoing = true;
if (iChild == QV_SWITCH_ALL)
{
return ChQvGroupInstance::Iterate(pIterator); // VRML 1.0 only; 1.1 does away with it
}
else
{
pIterator->SetVisitType(ChQvInstanceIterator::beforeChildren);
pIterator->SetDoKids(true);
bool boolKeepGoing = pIterator->DoNode(*this);
if(pIterator->ShouldDoKids() && !m_children.IsEmpty() && boolKeepGoing)
{
if(iChild >= 0) // i.e., not QV_SWITCH_NONE or QV_SWITCH_ALL
{
ChPosition pos = m_children.FindIndex(iChild);
if(pos)
{
pIterator->SetVisitType(ChQvInstanceIterator::isLeaf);
ChQvInstance *pChild = m_children.Get(pos);
boolKeepGoing = pChild->Iterate(pIterator);
}
}
}
pIterator->SetDoKids(true);
if(boolKeepGoing)
{
pIterator->SetVisitType(ChQvInstanceIterator::afterChildren);
boolKeepGoing = pIterator->DoNode(*this);
}
return boolKeepGoing;
}
}
else
{
return ChQvGroupInstance::Iterate(pIterator);
}
}
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
// Callback to choose child while rendering
#if (defined(CH_USE_RLAB))
void SwitchFrameCallback(ChNrFrame frame, void * arg)
#else
void SwitchFrameCallback(ChNrFrame frame, void * arg, float delta)
#endif
{
ChQvSwitchInstance *pInst = (ChQvSwitchInstance *)arg;
if(pInst) pInst->PickAChild();
}
void ChQvSwitchInstance::RemoveChildFrames()
{
ChNrFrameArray frames;
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
int count;
ChNrFrameGetChildren(m_frame, &count, &frames);
#if defined(CH_USE_D3D)
count = frames->GetSize();
#endif
ChNrFrame elt;
for( int i = 0; i < count; i++)
{
ChNrFrameRemoveChild(m_frame, GetElement(frames, (unsigned int)i, elt));
D3DRelease(elt);
}
#else
#pragma message("D3D Switch implementation Not done!")
#endif
ChNrFree(frames);
}
int ChQvSwitchInstance::LookupChild()
{
// Get a -valid- whichChild value
int iChild = ((QvSwitch*)GetNode())->whichChild.value;
int iChildCount = ((QvGroup*)GetNode())->getNumChildren();
iChild = min(iChild, iChildCount - 1); // Out of range, use last
if(iChild < 0 && iChild != QV_SWITCH_ALL && iChild != QV_SWITCH_NONE) iChild = QV_SWITCH_NONE;
if(iChildCount <= 0) iChild = QV_SWITCH_NONE;
return iChild;
}
void ChQvSwitchInstance::PickAChild()
{
int iChild = LookupChild();
int iChildCount = ((QvGroup*)GetNode())->getNumChildren();
if(iChild != m_iCurrentChild)
{
switch(iChild)
{
case QV_SWITCH_ALL:
{
// No need to remove any, just add all not currently added, and
// request construction on the unconstructed
RemoveChildFrames();
ChQvInstance *pChild = 0;
for(int i = 0; i < iChildCount; i++)
{
ChNrFrameAddChild(m_frame, m_pFrames[i]);
pChild = GetChild(i);
if(!pChild->IsConstructed())
{
GetContext()->StartConstruction(pChild);
// Spawn for new requests
ChQvSpawnState state((ChMazeWnd *)(GetContext()->GetWnd()), GetRelativeURL());
pChild->GetNode()->traverse(&state);
}
}
m_iCurrentChild = iChild;
break;
}
case QV_SWITCH_NONE:
{
// Just remove all and be done with it
RemoveChildFrames();
m_iCurrentChild = iChild;
break;
}
default:
{
ChQvInstance *pChild = 0;
if(iChild >= 0)
{
pChild = GetChild(iChild);
if(pChild)
{
if(pChild->IsConstructed())
{
if(m_iCurrentChild >= 0)
{
ChNrFrameRemoveChild(m_frame, m_pFrames[m_iCurrentChild]);
}
else if(m_iCurrentChild == QV_SWITCH_ALL)
{
// Remove all children
RemoveChildFrames();
}
ChNrFrameAddChild(m_frame, m_pFrames[iChild]);
m_iCurrentChild = iChild;
}
else
{
// Request the new one
// Start construction
// Explicitly do -not- set m_iCurrentChild
// Wait until it's complete to copy in as current
// Note that this may fire off unneeded construction threads
GetContext()->StartConstruction(pChild);
// Spawn for new requests
ChQvSpawnState state((ChMazeWnd *)(GetContext()->GetWnd()), GetRelativeURL());
pChild->GetNode()->traverse(&state);
// try this instead...
RemoveChildFrames();
ChNrFrameAddChild(m_frame, m_pFrames[iChild]);
m_iCurrentChild = iChild;
}
}
}
}
}
#if 0
//debris
// Add the child's new frame to our array, and remove it from us
m_pFrames[iChild] = pChildInst->GetFrame();
ChNrObjectReference(m_pFrames[iChild]);
ChNrFrameRemoveChild(m_frame, m_pFrames[iChild]);
// Spawn for new requests
ChQvSpawnState state((ChMazeWnd *)(GetContext()->GetWnd()), GetRelativeURL());
pChild->traverse(&state);
// Now get rid of unwanted stuff
//Purge(iChild, 100); // purge all but current and iChild
#endif
}
};
#endif
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
bool ChQvSwitchInstance::Construct(ChRenderContext *pRC, ChConstructionIterator *pIterator)
{
if( m_pNode && pIterator->GetVisitType() == ChQvInstanceIterator::afterChildren)
{
SetUpKids(pRC);
}
return true;
}
bool ChQvSwitchInstance::Draw(ChRenderContext *pRC, ChDrawIterator *pIterator)
{
ChQvGroupInstance::Draw(pRC, pIterator);
return true;
}
#endif
void ChQvSwitchInstance::SetUpKids(ChRenderContext* pContext)
{
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
QvSwitch *pNode = (QvSwitch *)GetNode();
int numKids = pNode->getNumChildren();
//TRACE("Reallocating child frames! That's a leak!!\n");
if(!m_pFrames)
{
m_pFrames = new ChNrFrame[numKids ? numKids : 1];
for(int j = 0; j < numKids; j++) m_pFrames[j] = 0;
pContext->LockScene();
m_iCurrentChild = LookupChild();
if(!m_children.IsEmpty())
{
int i = 0;
ChPosition pos = m_children.GetHeadPosition();
while(pos)
{
ChQvInstance *pChild = m_children.GetNext(pos);
m_pFrames[i] = pChild->GetFrame();
ChNrObjectReference(m_pFrames[i]);
if(i != m_iCurrentChild && m_iCurrentChild != QV_SWITCH_ALL)
{
ChNrFrameRemoveChild(m_frame, m_pFrames[i]);
}
i++;
}
}
ChNrFrameAddCallback(m_frame, SwitchFrameCallback, this);
pContext->UnlockScene();
}
#endif
}
///////////////////////////////////////////////////////////////////////////////
// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -