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

📄 cvinstnc.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	#endif

	return this;
}


#if 1

void ChQvGroupInstance::Use(bool boolChildren /*= true */, chuint32 uBump /*= 1*/)
{
	m_iUsage += uBump;
	//TRACE2("Use %lx -> %d (grp)\n", UINT(this), m_iUsage);

	if(boolChildren && !m_children.IsEmpty())
	{
		ChPosition pos = m_children.GetHeadPosition();
		while(pos)
		{
			ChQvInstance *pChild = m_children.GetNext(pos);
			pChild->Use(boolChildren);
		}

	}
}

void ChQvGroupInstance::Release(bool boolChildren /*= true*/, chuint32 uBump /*= 1*/)
{
	m_iUsage -= uBump;
	//TRACE2("Release %lx -> %d (grp)\n", UINT(this), m_iUsage);
	if(boolChildren && !m_children.IsEmpty())
	{
		ChPosition pos = m_children.GetHeadPosition();
		while(pos)
		{
			ChQvInstance *pChild = m_children.GetNext(pos);
			pChild->Release(boolChildren, uBump);
		}

	}
	if(m_iUsage <= 0)
	{
		delete this;
	}
}

#endif
void ChQvGroupInstance::Init(ChQvBuildState *pState)
{
	ChQvInstance::Init(pState);
	ChQvInstanceHasProps::Init(pState, this);
}

void ChQvGroupInstance::RestoreProp(ChQvState &state, QvNode *pProp, QvState::StackIndex stackIndex)
{
    QvElement *elt = new QvElement;					
    elt->data = pProp;							
    state.addElement(stackIndex, elt);
}

ChQvGroupInstance *ChQvGroupInstance::SetupTraversalState(ChQvState &state)
{	

	ChRenderContext *pRC = state.GetView()->GetRenderContext();
	pRC->SetModelTransform(GetTransform());

								///  set up stack to have proper transform instance at top to
								// inherit into subtree 
	ChQvElement *elt = new ChQvElement;					
    elt->data = m_pTransform->GetNode();
    elt->SetInstance(m_pTransform);							
    state.addElement(QvState::TransformationIndex, elt);
							   // Now all the other simpler props
	RestoreProp(state, GetMaterial(), QvState::MaterialIndex );
	RestoreProp(state, GetMaterialBinding(), QvState::MaterialBindingIndex );
	RestoreProp(state, GetNormal(), QvState::NormalIndex );
	RestoreProp(state, GetNormalBinding(), QvState::NormalBindingIndex );
	RestoreProp(state, GetCoordinate3(), QvState::Coordinate3Index );
	RestoreProp(state, GetTextureCoordinate2(), QvState::TextureCoordinate2Index );
	RestoreProp(state, GetTexture2Transform(), QvState::Texture2TransformationIndex);
	RestoreProp(state, GetShapeHints(), QvState::ShapeHintsIndex );
	RestoreProp(state, GetInfo(), QvState::InfoIndex );
	RestoreProp(state, GetFontStyle(), QvState::FontStyleIndex );

	return this;
}

#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
#if (defined(CH_USE_RLAB))
void GroupCallback(ChNrFrame frame, void * arg)
#else
void GroupCallback(ChNrFrame frame, void * arg, float delta)
#endif
{
	#if defined(CH_VRML_EVENTS)
	ChQvGroupInstance *pInst = (ChQvGroupInstance *)arg;
	if(pInst->HasChildrenMarkedForRemoval())pInst->RemoveMarkedChildren();
	#endif
}


void ChQvGroupInstance::CreateFrame()
{
	if(GetParent())
	{
		m_frame = GetContext()->CreateFrame(GetParent()->GetFrame());
	}
	else
	{
		m_frame = GetContext()->CreateFrame(m_pContext->GetFrame());
	}
	// Difference is that we don't do this: ChNrFrameAddTransform(m_frame, CombineBefore, *(GetTransform().GetMatrix()));
	ChNrObjectSetAppData(m_frame, (unsigned long)this);

	// Now add the callback for removing unwanted children
	ChNrFrameAddCallback(m_frame, GroupCallback, this);
	D3DRelease(m_frame);
	InstallScripts();
};

// Callback to collapse mesh while rendering
void CollapseFrameCallback(ChNrFrame frame, void * arg)
{
	#if 0
	ChQvLODInstance *pInst = (ChQvLODInstance *)arg;
	pInst->Collapse();
	ChNrFrameRemoveCallback(frame, CollapseFrameCallback, pInst);
	#endif
}

bool ChQvGroupInstance::Draw(ChRenderContext *pRC, ChDrawIterator *pIterator)
{
	ASSERT(m_frame);
	return true;
}

bool ChQvGroupInstance::Construct(ChRenderContext *pRC, ChConstructionIterator *pIterator)
{
	ASSERT(m_frame);
	#if 0
	// Collapsing causes crashes in RL wehn we add the new mesh - ???
	if(CanCollapse())
	{
		pRC->LockScene();
		ChCanCollapseIterator iterator(pRC);
		iterator.Attach(this);
		iterator.IterateAll();
		if(iterator.CanCollapse())
		{
			ChNrFrameAddCallback(m_frame, CollapseFrameCallback, this);
		}
		pRC->UnlockScene();
	}
	#endif
	return true;
}


void ChQvGroupInstance::Build(ChRenderContext *pRC)
{
	ASSERT(m_frame == 0);
	CreateFrame();
}
void ChQvShapeInstance::Build(ChRenderContext *pRC)
{
	ASSERT(m_frame == 0);
	CreateFrame();
}

#endif

ChQvGroupInstance * ChQvGroupInstance::Add(ChQvInstance *pChild)
{
	CheckAddThread();
	if(pChild->m_pParent)
	{
		m_pParent->Remove(pChild);
	}
	m_children.AddTail(pChild);
	pChild->m_pParent = this;

	// Adjust the child's usage count to match the parent
	// This means any construction threads will decrement 
	// correctly.
	int iUsage = GetUsage() - pChild->GetUsage();
	if(iUsage > 0) pChild->Use(true, chuint32(iUsage));

	return this;
}

bool ChQvGroupInstance::Remove(ChQvInstance *pChild)
{
	CheckAddThread();
	if(m_children.IsEmpty()) return false;
	ChPosition pos = m_children.Find(pChild);
	if(pos)
	{
		m_children.Remove(pos);
		pChild->m_pParent = 0;
	}
	//ASSERT(! m_children.Find(pChild)); // Should only be one copy! 
	return (pos != 0);
}

ChQvInstance* ChQvGroupInstance::GetChild( int iChild)
{
	// result is only valid if all children were instatniated,
	// and none have been deleted yet
	ChQvInstance *pChild = 0;
	if(!m_children.IsEmpty())
	{
		ChPosition pos = m_children.FindIndex(iChild);
		if(pos)
		{
			pChild = m_children.Get(pos);
		}
	}
	return pChild;
}

bool ChQvGroupInstance::Iterate(ChQvInstanceIterator *pIterator)
{
								// Visit self pre
	pIterator->SetVisitType(ChQvInstanceIterator::beforeChildren);
	pIterator->SetDoKids(true); 
	bool boolKeepGoing = pIterator->DoNode(*this);

								// Visit kids if any
	if(pIterator->ShouldDoKids() && !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);
		}
	}
								// Visit self post
	pIterator->SetDoKids(true); 
	if(boolKeepGoing)
	{
		pIterator->SetVisitType(ChQvInstanceIterator::afterChildren);
		boolKeepGoing = pIterator->DoNode(*this);
	}
	return boolKeepGoing;
}

void  ChQvGroupInstance::MarkChildForRemoval(QvNode *pNode)
{
	m_boolChildPendingRemoval = true;

	if(!m_children.IsEmpty())
	{
		ChPosition pos = m_children.GetHeadPosition();
		while(pos)
		{
			ChQvInstance *pChild = m_children.GetNext(pos);
			if( pChild->GetNode() == pNode ) pChild->MarkForRemoval();
		}
	}
}

void ChQvGroupInstance::RemoveMarkedChildren()
{
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	if(!m_children.IsEmpty())
	{
		//	m_pContext->LockConstruction();
		ChPosition pos = m_children.GetHeadPosition();
		TRACE("Removing marked children\n");
		while(pos)
		{
			ChQvInstance *pChild = m_children.GetNext(pos);
			if( pChild->IsMarkedForRemoval() )
			{
				ChNrFrameRemoveChild(m_frame, pChild->GetFrame());
				//delete pChild;
				pChild->Release();
			}
		}
		//	m_pContext->UnlockConstruction();
	}
	#endif
	m_boolChildPendingRemoval = false;
};

ChQvInstance * ChQvGroupInstance::InstantiateChild(QvNode *pNewChild)
{
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	ChQvBuildState bldIt((ChMazeWnd*)(GetContext()->GetWnd()));

	// Alternative idea, setCurrentParent(0), then extract it from
	// state and add to parent??
	bldIt.SetCurrentParent(this);
	SetupTraversalState(bldIt);
	pNewChild->traverse(&bldIt);

	// Now construct them for RLab 
	ChQvInstance *pChildInst = 	(m_children.IsEmpty() ? 0 : m_children.GetTail());
	if(pChildInst)
	{
		GetContext()->StartConstruction(pChildInst);
	}

	return pChildInst;
	#else
	return 0;
	#endif
}

//////////////////////////////////////////////////////////////////////


// Iterators

ChQvInstanceIterator::ChQvInstanceIterator(ChRenderContext * pContext) :
	m_pRoot(0), m_pContext(pContext), m_boolDoKids(true)
{
}

ChQvInstanceIterator::ChQvInstanceIterator(ChRenderContext * pContext, ChQvInstance* pRoot ) :
	m_pRoot(0), m_pContext(pContext), m_boolDoKids(true)
{
	Attach(pRoot);
}

ChQvInstanceIterator::~ChQvInstanceIterator()
{
}

void ChQvInstanceIterator::Attach( ChQvInstance *pInst )
{
	m_pRoot = pInst;
}

bool ChQvInstanceIterator::Iterate()	   // Just those in draw scope; respects lods,etc.
{
	m_type = inDrawScope;
	if(!m_pRoot) return false;
	return m_pRoot->Iterate(this);
}

int ChQvInstanceIterator::IterateAll()  // Exhaustive iteration
{
	m_type = all;
	if(!m_pRoot) return false;
	return m_pRoot->Iterate(this); 
}

int ChDrawIterator::DoNode(ChQvInstance& inst)
{
	bool boolKeepGoing = true;
	if(GetVisitType() == isLeaf || GetVisitType() == afterChildren)
	{
		boolKeepGoing = inst.Draw(m_pContext, this);
	}

	return boolKeepGoing;
}
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))


bool ChDrawIterator::Iterate()	  // Just those in draw scope; respects lods,etc.
{
	m_startTime = ::GetTickCount();
	bool retVal =  ChQvInstanceIterator::Iterate();
	return retVal;
}
	  
bool ChDrawIterator::IterateAll()  // Exhaustive iteration
{
	m_startTime = ::GetTickCount();
	bool retVal = ChQvInstanceIterator::IterateAll();
	return retVal;
}  
#endif

int ChConstructionIterator::DoNode(ChQvInstance& inst)
{
	bool boolKeepGoing = true;
	if(GetVisitType() == isLeaf || GetVisitType() == afterChildren)
	{
		boolKeepGoing = inst.Construct(m_pContext, this);
	}

	if(!boolKeepGoing) m_boolWorkRemains = true;	// halted with work to do
	
	return boolKeepGoing;
}
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))

bool ChConstructionIterator::IsOKToProceed(ChQvInstance *pInst)
{
	if ( GetRenderContext()->ContinueConstruction() && (!pInst || (pInst->GetNode() && pInst->GetRenderData())))
	{ 
		// Must call UnlockScene if this succeeds!
		if(GetRenderContext()->IsThreaded())
		{
			GetRenderContext()->LockScene();
			//GetRenderContext()->LockQv();		   // Lock tree so other threads don't kill our data
		}
		else
		{
			// Check work done and elapsed time, and return false if exceeded
			//#pragma message("nonthreaded not done")
			int iMaxMsgs = 0;
			CWinThread* pThread = AfxGetThread();
			while ( GetRenderContext()->ContinueConstruction() && iMaxMsgs < 100 )
			{
				MSG msg;

				if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
				{

					if ( msg.message == WM_VRML_PARSE_DONE )
					{  // if there is a new scene to load, we should abort
					   // construction for the current scene. The message WM_VRML_PARSE_DONE
					   // should be retrieved from the main message loop, this guarantees that
					   // there is no construction going on.
						return false;
					}

					if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
					{
						iMaxMsgs++; // Num messages processed
						::DispatchMessage(&msg);
					}
					// allow user-interface updates
					pThread->OnIdle(-1);
				}
				else
				{
					break;
				}
			}
			if ( !GetRenderContext()->ContinueConstruction() )
			{
				return false;
			}
		}
		return true;
	}
	else
	{  // Construction has been canceled
		return false;
	}
}

void ChConstructionIterator::DidAShape()
{
	m_workDone ++;

	GetRenderContext()->IncrementShapeCount();

	if(GetRenderContext()->IsThreaded())
	{
		if(::GetTickCount() - m_startTime > TimeToDirty || ::GetTickCount() < m_startTime)
		{
			GetRenderContext()->SetDirty();
			m_startTime = ::GetTickCount();
			SayProgress();
		}
	}
	else
	{
		GetRenderContext()->SetDirty();		  // Set dirty for every piece of work
	}
}

void ChConstructionIterator::SayProgress(bool boolDone)
{
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	ChMazeWnd *pWnd = (ChMazeWnd *)(m_pContext->GetWnd());
	if(boolDone)
	{	 // PRITHAM: Please figure out how to do this
		pWnd->WriteStatus( PROGRESS_MSG_1 );
	}
	else
	{
		pWnd->WriteStatus( PROGRESS_MSG_2 );
	}
	#endif
}

bool ChConstructionIterator::Iterate()	  // Just those in draw scope; respects lods,etc.
{
	m_startTime = ::GetTickCount();
	m_workDone = 0;
	SayProgress();
	bool retVal =  ChQvInstanceIterator::Iterate();
	SayProgress(true);
	return retVal;
}
	  
bool ChConstructionIterator::IterateAll()  // Exhaustive iteration
{
	m_startTime = ::GetTickCount();
	m_workDone = 0;
	SayProgress();
	bool retVal = ChQvInstanceIterator::IterateAll();
	SayProgress(true);		
	return retVal;
}  
#endif

// Pipeline

ChPipeline * ChPipeline::Set(GxTransform3Wf &model, GxTransform3Wf &world2Cam, GxTransform3Wf &cam2Clip, GxTransform3Wf &clip2Screen)
{
	m_model = model;
	m_world2Cam = world2Cam;
	m_cam2Clip = cam2Clip;
	m_clip2Screen = clip2Screen;

	m_model2Clip = cam2Clip;
	m_model2Clip *= world2Cam;
	m_model2Clip *= model;

	return this;
}

GxVec3f ChPipeline::TransformToScreen(GxVec3f& pt)
{
	GxVec3f newPt;
	float w;

	newPt = m_model2Clip.TransformW(pt, w);
	newPt *= 1. / w;
	newPt = m_clip2Screen * newPt;
	//newPt.y() = -newPt.y(); 
	return newPt;
}


GxVec3f ChPipeline::TransformToPort(GxVec3f& pt, bool & boolClipped)
{
	GxVec3f p;
	float w;

	p = m_model2Clip.TransformW(pt, w);
	boolClipped = (p.x() <= -w || p.x() >= w || p.y() <= -w || p.y() >= w || p.z() <= 0. || p.z() >= w);
	p *= 1. / w;
	GxTransform3Wf clip2Port = m_clip2Screen;
	(*(clip2Port.GetMatrix()))[1][1] = -(*(clip2Port.GetMatrix()))[1][1];
	(*(clip2Port.GetMatrix()))[1][3] = -(*(clip2Port.GetMatrix()))[1][3];
	
	p = clip2Port * p;
	return p;
}




// end of file

⌨️ 快捷键说明

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