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

📄 cvselectors.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -