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

📄 cvinstnc.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------------
                        _                              _ _       
        /\             | |                            | (_)      
       /  \   _ __   __| |_ __ ___  _ __ ___   ___  __| |_  __ _ 
      / /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
     / ____ \| | | | (_| | | | (_) | | | | | |  __/ (_| | | (_| |
    /_/    \_\_| |_|\__,_|_|  \___/|_| |_| |_|\___|\__,_|_|\__,_|

    The contents of this file are subject to the Andromedia Public
	License Version 1.0 (the "License"); you may not use this file
	except in compliance with the License. You may obtain a copy of
	the License at http://www.andromedia.com/APL/

    Software distributed under the License is distributed on an
	"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
	implied. See the License for the specific language governing
	rights and limitations under the License.

    The Original Code is Pueblo client code, released November 4, 1998.

    The Initial Developer of the Original Code is Andromedia Incorporated.
	Portions created by Andromedia are Copyright (C) 1998 Andromedia
	Incorporated.  All Rights Reserved.

	Andromedia Incorporated                         415.365.6700
	818 Mission Street - 2nd Floor                  415.365.6701 fax
	San Francisco, CA 94103

    Contributor(s):
	--------------------------------------------------------------------------
	   Chaco team:  Dan Greening, Glenn Crocker, Jim Doubek,
	                Coyote Lussier, Pritham Shetty.

					Wrote and designed original codebase.

------------------------------------------------------------------------------

	Implementation for the ChQvInstance class for  Intel 3DR.

----------------------------------------------------------------------------*/

// $Header: /home/cvs/chaco/modules/client/msw/ChGraphx/CvInstnc.cpp,v 2.35 1996/06/30 19:44:15 jimd Exp $

#include "grheader.h"

#include "CvInstnc.h"
#include <QvInfo.h>
#include <QvState.h>
#include "ChMaze.h"
#include "ChRenderData.h"
#include "ChScriptData.h"
#include "ChMazDep.h"
#include "CvTrnsfm.h"
#include "CvNormal.h"
#include "CvBound.h"
#include "CvConvrt.h"
#include "CvHitTst.h"
#include "imode.h"

//#define VERIFY_NO_THREAD_CONFLICT	1
#if defined(VERIFY_NO_THREAD_CONFLICT)
static HANDLE ghCurrentAddThread = 0;
#define CheckAddThread()	\
	{if(0 == ghCurrentAddThread) ghCurrentAddThread =  GetCurrentThread();\
	ASSERT(ghCurrentAddThread == GetCurrentThread());}
#else
#define CheckAddThread()

#endif


#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
class ChCanCollapseIterator : public ChQvInstanceIterator
{

	public:
		ChCanCollapseIterator(ChRenderContext * pContext) : 
			ChQvInstanceIterator(pContext), m_boolCanCollapse(true)
			{};

		virtual ~ChCanCollapseIterator() {};

		virtual int DoNode(ChQvInstance& inst)
		{
			if(!inst.CanCollapse())
			{
				m_boolCanCollapse = true;
				return false;
			}
			return true;
		};

		bool CanCollapse() {return m_boolCanCollapse;};

   protected:

		bool		m_boolCanCollapse;	 

   private:
											/* Disable copy constructor and
												assignment operator */

      inline ChCanCollapseIterator( const ChDrawIterator& ) : ChQvInstanceIterator(0) {}
      inline ChCanCollapseIterator& operator=( const ChDrawIterator& )
      			{
      				return *this;
      			}
};
#endif
//#define COUNT_INSTANCES	1
#if defined(COUNT_INSTANCES)
static int iInstCount = 0;
#endif

/////////////////////////////////////////////////////////////////////////////////////////////
ChQvInstance::ChQvInstance() :
		m_pNode(0),
		m_pParent(0),
		m_pRenderData(0),
		m_pBounds(0),
		m_pTransform(0),
		#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
		m_frame(0),
		m_boolConstructed(0),
		#endif
		m_pContext(0),
		m_boolBoundsDirty(true),
		m_boolRenderDirty(true),
		m_boolDeleteMe(false),
		m_iUsage(1)

{
#if defined(COUNT_INSTANCES)
	iInstCount ++;
	TRACE1("Instance count = %d\n", iInstCount);
#endif
}

ChQvInstance::~ChQvInstance()
{
#if defined(COUNT_INSTANCES)
	iInstCount --;
#endif
	if(m_pRenderData)
	{		   // TODO more graceful destruction
		if(m_pRenderData) m_pRenderData->Remove(this);
		m_pRenderData = 0;
	}
	if(m_pParent)
	{
		m_pParent->Remove(this);
		m_pParent = 0;
	}
	m_pNode=0;
	delete m_pBounds;
	m_pBounds = 0;

	if(m_pTransform)
	{
		m_pTransform->RemoveDependent(this);
	}

}

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

void ChQvInstance::Release(bool boolChildren /*= true*/ , chuint32 uBump /*= 1*/)
{
	m_iUsage -= uBump;
	//TRACE2("Release %lx -> %d\n", UINT(this), m_iUsage);
	if(m_iUsage <= 0)
	{
		//TRACE1("Delete %lx\n", UINT(this));
		delete this;
	}
}

#endif
bool ChQvInstance::GetBounds(ChQvBounds& bounds)
{
	if(m_boolBoundsDirty)
	{
		ComputeBounds();
	}
	if(m_pBounds)
	{
		m_pBounds->SetTransform(GetTransform());	// cached transform might be out of date?
		bounds = *m_pBounds;
	}
	else
	{
		bounds.SetTransform(GetTransform());	// cached transform might be out of date?
	}

	return (m_pBounds != 0);
}

ChQvInstance* ChQvInstance::Attach(QvNode *pNode, ChQvBuildState *pState)
{
	m_pNode = pNode;
	ChQvRenderBaseData *pRenderData =  (ChQvRenderBaseData *)(pNode->GetRenderData());
	// Hook us together
	m_pRenderData = pRenderData;
	pRenderData->Add(this);
	ChQvGroupInstance *pParent =	pState->GetCurrentParent();
	if(pParent) pParent->Add(this);

	Init(pState);
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	Build(GetContext());
	#endif

	return this;
}

bool ChQvInstance::Iterate(ChQvInstanceIterator *pIterator)
{
	ChQvInstanceIterator::whenVisiting visit = pIterator->GetVisitType();
	pIterator->SetVisitType(ChQvInstanceIterator::isLeaf);
	bool boolKeepGoing = pIterator->DoNode(*this);
	pIterator->SetVisitType(visit);
	return boolKeepGoing;
}

void ChQvInstance::Init(ChQvBuildState *pState)
{                                                                         
	ChRenderContext *pRC = pState->GetView()->GetRenderContext();
	//SetTransform(pRC->GetModelTransform());							 
	m_pContext = pRC;

	ChQvElement *pElt = (ChQvElement *)(pState->getTopElement(QvState::TransformationIndex));
	if(pElt)
	{
		ASSERT(pElt->GetInstance());
		m_pTransform = (ChQvTransformationInstance*)(pElt->GetInstance());
		m_pTransform->AddDependent(this);
	}
	else
	{
		m_pTransform = pRC->GetDefaultTransform();
		m_pTransform->AddDependent(this);
	}
}

GxVec3f ChQvInstance::Transform(const GxVec3f& v)
{
	return GetTransform() * v;
};

GxVec3f ChQvInstance::TransformWorldToModel(const GxVec3f& v)
{
	return GetTransform().Inverse() * v;
};

GxTransform3Wf&  ChQvInstance::GetTransform() 
{ 
	return m_pTransform->GetTransform();
};

ChQvInstance* ChQvInstance::SetTransform(ChQvTransformationInstance	*pTransform)
{
	m_pTransform = pTransform;
	return this;
}


ChQvInstance * ChQvInstance::GetPipeline(ChRenderContext *pRC, ChPipeline &pipeline)
{
	GxTransform3Wf modelCamera = pRC->GetWorldToCameraTransform();	// world to camera
	GxTransform3Wf cameraToClip = pRC->GetCameraToClipTransform();
	GxTransform3Wf clipToScreen = pRC->GetClipToScreenTransform();

	pipeline.Set(GetTransform(), modelCamera, cameraToClip, clipToScreen);
	return this;
}

void ChQvInstance::Term()
{
	// placeholder 
}

bool ChQvInstance::ComputeBounds()
{
	// Every class needs to do their own. Maybe this should be pure virtual
	return false;
}

#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
void ChQvInstance::CreateFrame()
{
	if(GetParent())
	{
		m_frame = GetContext()->CreateFrame(GetParent()->GetFrame());
	}
	else
	{
		m_frame = GetContext()->CreateFrame(m_pContext->GetFrame());
	}
	ChNrFrameAddTransform(m_frame, CombineBefore, *(GetTransform().GetMatrix()));
	ChNrObjectSetAppData(m_frame, (unsigned long)this);
	D3DRelease(m_frame);
	InstallScripts();
};

ChNrFrame ChQvInstance::GetParentFrame()
{
	ChNrFrame	frame = 0;
	if(GetParent())
	{
		frame = GetParent()->GetFrame();
	}
	if(!frame)
	{
		frame = m_pContext->GetFrame();
	}
	
	return frame;
};

bool ChQvInstance::CanCollapse()
{
	if(GetParent() == 0) return false;	 // never collapse the root
	return true;
};

bool ChQvInstance::Collapse()
{
	#if 0	 // not needed for now
	if(m_frame)
	{
		ChNrFrame *pFrames;
		int count;

		ChNrFrameGetChildren(m_frame, &count, &pFrames);
		if(count)
		{
			ChNrMesh mesh;
			mesh = ChNrFrameBuildMesh(m_frame);

			for(int j=0; j < count; j++)
			{
				ChNrFrame child = pFrames[j];
				ChNrFrameRemoveChild(m_frame, child);
			}
			ChNrFrameAddVisual(m_frame, mesh);
			ChNrObjectSetAppData(mesh, (unsigned long)this);
		}
		RLFree(pFrames);
	}
	#endif
	return true;
}

#endif


void ChQvInstance::InstallScripts()
{
	ChQvRenderBaseData *pData =  (ChQvRenderBaseData *)(GetNode()->GetRenderData());
	if(pData)
	{
		MyInstallScriptIterator	iterator(*pData, this);
		iterator.IterateScripts();
	}
}

bool ChQvInstance::SetTexture(ChQvTextureRenderData *pTextureData, ChNrMesh mesh)
{
	return false;	// false says nothing happened
}


void ChQvInstance::MarkForRemoval(bool boolDelete /*= true*/)
{
	m_boolDeleteMe = boolDelete;
	m_pNode = 0;		// break the link with the Node, it's probably going away
}


string& ChQvInstance::GetRelativeURL()
{
	if(GetParent()) return GetParent()->GetRelativeURL();

	return (((ChMazeWnd *)(GetContext()->GetWnd()))->GetCurrentURL());
}

// Transformation Instance Classes
ChQvTransformationInstance::ChQvTransformationInstance() : ChQvInstance(), m_pPredecessor(0)
{}

ChQvTransformationInstance::~ChQvTransformationInstance()
{
	while(!m_dependents.IsEmpty())
	{
		ChQvInstance *pDependent = m_dependents.RemoveHead();
		if(pDependent) pDependent->SetTransform( 0 );
	}

}

void ChQvTransformationInstance::Init(ChQvBuildState *pState)
{
	// Don't do the usual stuff...	 
	ChQvElement *pElt = (ChQvElement *)(pState->getTopElement(QvState::TransformationIndex));
	// Top is us, we go one deeper for who we depend on
	if(pElt->next)
	{
				// Make this a dependent of instance that -was- top
		ChQvElement *pPrevTop = (ChQvElement *)(pElt->next);
		m_pPredecessor = ((ChQvTransformationInstance*)(pPrevTop->GetInstance()));
		m_pPredecessor->AddDependent(this);
	}
	m_pTransform = m_pPredecessor;
	ChRenderContext *pRC = pState->GetView()->GetRenderContext();
	m_pContext = pRC;
	SetTransform(pRC->GetModelTransform());
}

ChQvInstance* ChQvTransformationInstance::Attach(QvNode *pNode, ChQvBuildState *pState)
{	  // TODO zap this, unnecessary	????
	//ChQvInstance::Attach(pNode, pState); 
	m_pNode = pNode;
	ChQvRenderBaseData *pRenderData =  (ChQvRenderBaseData *)(pNode->GetRenderData());
	// Hook us together
	m_pRenderData = pRenderData;
	pRenderData->Add(this);
	ChQvGroupInstance *pParent =	pState->GetCurrentParent();
	//if(pParent) pParent->Add(this);

	Init(pState);


	return this;
}

ChQvInstance* ChQvTransformationInstance::SetTransformDirty(bool boolDirty)
{	 
	// recurse to force recompute of all dependents
	if(boolDirty)
	{
		if(m_pPredecessor)
		{
			m_ModelTransform = m_pPredecessor->m_ModelTransform.Compose(m_SelfTransform);	// ?????????
			//m_ModelTransform = m_SelfTransform.Compose(m_pPredecessor->m_ModelTransform);	// ?????????
			//m_ModelTransform = m_pPredecessor->m_ModelTransform * m_SelfTransform;	// ?????????
		}
		else
		{
			m_ModelTransform =  m_SelfTransform;
		}
	}
	if(!m_dependents.IsEmpty())
	{
		ChPosition pos = m_dependents.GetHeadPosition();
		while(pos)
		{
			ChQvInstance *pInst = m_dependents.GetNext(pos);
			pInst->SetTransformDirty(boolDirty);
		}
	}
	return this;
}

ChQvTransformationInstance* ChQvTransformationInstance::SetTransform(const GxTransform3Wf& modelTransform)
{
	m_ModelTransform = modelTransform;
	return this;
}

ChQvTransformationInstance* ChQvTransformationInstance::SetSelfTransform(const GxTransform3Wf& transform)
{
	m_SelfTransform = transform;
	return this;
}

ChQvTransformationInstance* ChQvTransformationInstance::AddDependent(ChQvInstance *pDependent)
{
	CheckAddThread();
	m_dependents.AddTail(pDependent);
	return this;
}

ChQvTransformationInstance* ChQvTransformationInstance::RemoveDependent(ChQvInstance *pDependent)
{
	CheckAddThread();	
	if(!m_dependents.IsEmpty())
	{

		ChPosition pos = m_dependents.Find(pDependent);
		if(pos){
			m_dependents.Remove(pos);
		}
		pDependent->SetTransform( 0 );
	}
	return this;
}

//	ChQvGroupInstance
ChQvGroupInstance::ChQvGroupInstance() : ChQvInstance(), m_boolChildPendingRemoval(false)
{
}

ChQvGroupInstance::~ChQvGroupInstance()
{
	// Delete children
	CheckAddThread();
	while(!m_children.IsEmpty())
	{
		ChQvInstance* pChild = m_children.RemoveHead();
		//delete pChild;
		//pChild->SetParent(0);
		//if(pChild) pChild->Release();		YIKES!!!!!!!!!!		DOUBLE DELETE!!
		if(pChild) pChild->m_pParent = 0;		
	}
	ChQvInstanceHasProps::Term(this);
}

ChQvInstance* ChQvGroupInstance::Attach(QvNode *pNode, ChQvBuildState *pState)
{
	ChQvInstance::Attach(pNode, pState); 

	// Add the group's transform instance onto the stack
	ChQvElement *elt = new ChQvElement;					      
	elt->data = pNode;							      
	elt->type = QvElement::Transform;					      
	pState->addElement(QvState::TransformationIndex, elt);
	ChQvTransformationInstance *pTransformInstance = GetTransformInstance();
	pTransformInstance->Attach(pNode, pState, this);
	
	GxTransform3Wf mat;
	pTransformInstance->SetSelfTransform(mat);

	elt->SetInstance(pTransformInstance);


	return this;
}

ChQvTransformationInstance* ChQvTransformationInstance::Attach(QvNode *pNode, ChQvBuildState *pState, ChQvGroupInstance *pOwner)
{
	m_pNode = pNode;
	ChQvRenderBaseData *pRenderData =  (ChQvRenderBaseData *)(pNode->GetRenderData());
	// Hook us together
	//m_pRenderData = pRenderData;
	m_pRenderData = 0;
	// We don't add to renderdata or parent, because we are not an instance of Group

	Init(pState);
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	Build(GetContext());

⌨️ 快捷键说明

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