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

📄 chrenderdata.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	if(boolSuccess)
	{
		if((axis[0] != pRotation->axis[0]) ||
			(axis[1] != pRotation->axis[1]) ||
			(axis[2] != pRotation->axis[2]) ||
			(angle != pRotation->angle))
		{
			pRotation->axis[0] = axis[0];
			pRotation->axis[1] = axis[1];
			pRotation->axis[2] = axis[2];
			pRotation->angle = angle;
			//SetDirty();

			MyTransformDirtyIterator iterator(*this);

			iterator.Iterate();
		}

	}
#endif

	return boolSuccess;
}

bool ChQvTransformationRenderData::OnSetScaleFactor(ChRenderContext *pRC, ChApplet * pApplet, ChIVrmlEvent *pEventList)
{
	bool boolSuccess = false;
#if defined(CH_VRML_EVENTS)
	// Apply based on transform type - eventually this gets merged into
	// the containing separator in 2.0 - if we were going to keep this node, 
	// we'd split out the classes, but for now just hack it
	string strType;
	float scale[3];
	ChVec3fEvent *pEvent = (ChVec3fEvent *)pEventList;
	pEvent->GetValue(scale);
	QvSFVec3f *pScale = 0;

	if(m_pNode->GetType(strType) == typeQvScale)
	{
		QvScale *pNode = (QvScale *)m_pNode;
		pScale = &(pNode->scaleFactor);
		boolSuccess = true;
	}
	else if(m_pNode->GetType(strType) == typeQvTransform)
	{
		QvTransform *pNode = (QvTransform *)m_pNode;
		pScale = &(pNode->scaleFactor);
		boolSuccess = true;
	}

	if(boolSuccess)
	{
		if((scale[0] != pScale->value[0]) ||
			(scale[1] != pScale->value[1]) ||
			(scale[2] != pScale->value[2]))
		{
			pScale->value[0] = scale[0];
			pScale->value[1] = scale[1];
			pScale->value[2] = scale[2];

			MyTransformDirtyIterator iterator(*this);

			iterator.Iterate();
		}

	}
#endif

	return boolSuccess;
}
										  
bool ChQvTransformationRenderData::OnSetTranslation(ChRenderContext *pRC, ChApplet * pApplet, ChIVrmlEvent *pEventList)
{
	bool boolSuccess = false;
#if defined(CH_VRML_EVENTS)
	// Apply based on transform type - eventually this gets merged into
	// the containing separator in 2.0 - if we were going to keep this node, 
	// we'd split out the classes, but for now just hack it
	string strType;
	float translation[3];
	ChVec3fEvent *pEvent = (ChVec3fEvent *)pEventList;
	pEvent->GetValue(translation);
	QvSFVec3f *pTranslation = 0;

	if(m_pNode->GetType(strType) == typeQvTranslation)
	{
		QvTranslation *pNode = (QvTranslation *)m_pNode;
		pTranslation = &(pNode->translation);
		boolSuccess = true;
	}
	else if(m_pNode->GetType(strType) == typeQvTransform)
	{
		QvTransform *pNode = (QvTransform *)m_pNode;
		pTranslation = &(pNode->translation);
		boolSuccess = true;
	}

	if(boolSuccess)
	{
		if((translation[0] != pTranslation->value[0]) ||
			(translation[1] != pTranslation->value[1]) ||
			(translation[2] != pTranslation->value[2]))
		{
			pTranslation->value[0] = translation[0];
			pTranslation->value[1] = translation[1];
			pTranslation->value[2] = translation[2];

			MyTransformDirtyIterator iterator(*this);

			iterator.Iterate();
		}

	}
#endif

	return boolSuccess;
}
bool ChQvTransformationRenderData::OnSetScaleOrientation(ChRenderContext *pRC, ChApplet * pApplet, ChIVrmlEvent *pEventList)
{
	bool boolSuccess = false;
#if defined(CH_VRML_EVENTS)
	// Apply based on transform type - eventually this gets merged into
	// the containing separator in 2.0 - if we were going to keep this node, 
	// we'd split out the classes, but for now just hack it
	string strType;
	float axis[3];
	float angle;
	ChRotationEvent *pEvent = (ChRotationEvent *)pEventList;
	pEvent->GetValue(axis, angle);
	QvSFRotation *pRotation = 0;

	if(m_pNode->GetType(strType) == typeQvTransform)
	{
		QvTransform *pNode = (QvTransform *)m_pNode;
		pRotation = &(pNode->scaleOrientation);
		boolSuccess = true;
	}

	if(boolSuccess)
	{
		if((axis[0] != pRotation->axis[0]) ||
			(axis[1] != pRotation->axis[1]) ||
			(axis[2] != pRotation->axis[2]) ||
			(angle != pRotation->angle))
		{
			pRotation->axis[0] = axis[0];
			pRotation->axis[1] = axis[1];
			pRotation->axis[2] = axis[2];
			pRotation->angle = angle;
			//SetDirty();

			MyTransformDirtyIterator iterator(*this);

			iterator.Iterate();
		}

	}
#endif

	return boolSuccess;
}
bool ChQvTransformationRenderData::OnSetCenter(ChRenderContext *pRC, ChApplet * pApplet, ChIVrmlEvent *pEventList)
{
	bool boolSuccess = false;
#if defined(CH_VRML_EVENTS)
	// Apply based on transform type - eventually this gets merged into
	// the containing separator in 2.0 - if we were going to keep this node, 
	// we'd split out the classes, but for now just hack it
	string strType;
	float center[3];
	ChVec3fEvent *pEvent = (ChVec3fEvent *)pEventList;
	pEvent->GetValue(center);
	QvSFVec3f *pCenter = 0;

	if(m_pNode->GetType(strType) == typeQvTransform)
	{
		QvTransform *pNode = (QvTransform *)m_pNode;
		pCenter = &(pNode->scaleFactor);
		boolSuccess = true;
	}

	if(boolSuccess)
	{
		if((center[0] != pCenter->value[0]) ||
			(center[1] != pCenter->value[1]) ||
			(center[2] != pCenter->value[2]))
		{
			pCenter->value[0] = center[0];
			pCenter->value[1] = center[1];
			pCenter->value[2] = center[2];

			MyTransformDirtyIterator iterator(*this);

			iterator.Iterate();
		}

	}
#endif

	return boolSuccess;
}

/////////////////////////////////////////////////////////////////////////////////
ChQvGroupRenderData::ChQvGroupRenderData(QvNode* pNode) : 
	ChQvRenderBaseData(pNode)
{
#if defined(CH_VRML_EVENTS)
	if(!m_pDispatcher)
	{
		m_pDispatcher = new	ChVrmlDispatcher;
		Init();
	}
#endif
};


void ChQvGroupRenderData::Init()
{
	ChQvRenderBaseData::Init();
#if defined(CH_VRML_EVENTS)

	AddVrmlDispatcher("add_children", SFNode, OnAddChildren);
	AddVrmlDispatcher("add_children", MFNode, OnAddChildren);
	AddVrmlDispatcher("remove_children", SFNode, OnRemoveChildren);

#endif

};

ChQvGroupRenderData::~ChQvGroupRenderData()
{
}

void ChQvGroupRenderData::Term()
{
#if defined(CH_VRML_EVENTS)
	delete m_pDispatcher;
	m_pDispatcher = 0;
#endif
}

bool ChQvGroupRenderData::IsNodeRemovable(QvNode *pChild)
{
	return IsNodeAddable( pChild);
}

bool ChQvGroupRenderData::IsNodeAddable(QvNode *pChild)
{
	bool boolAddable = true;
	string strType;
	int theType = pChild->GetType(strType);
	switch(theType)
	{
		case typeQvBackground:
		case typeQvBaseColor:
		case typeQvEnvironment:
		case typeQvGroup:
		case typeQvCoordinate3:
		case typeQvInfo:
		case typeQvFontStyle:
		case typeQvMaterial:
		case typeQvMaterialBinding:
		case typeQvMatrixTransform:
		case typeQvNormal:
		case typeQvNormalBinding:
		case typeQvRotation:
		case typeQvScale:
		case typeQvShapeHints:
 		case typeQvTexture2:
		case typeQvTexture2Transform:
		case typeQvTextureCoordinate2:
		case typeQvTransform:
		case typeQvTranslation:
		case typeQvUnknownNode:
			boolAddable = false;
			break;


		case typeQvCone:
		case typeQvCube:
		case typeQvCylinder:
		case typeQvIndexedFaceSet:
		case typeQvIndexedLineSet:
		case typeQvLOD:	
		case typeQvSeparator:
		case typeQvTransformSeparator:
		case typeQvSwitch:			
		case typeQvAsciiText:
		case typeQvDirectionalLight:
		case typeQvOrthographicCamera:
		case typeQvPerspectiveCamera:
		case typeQvPointLight:
		case typeQvPointSet:	
		case typeQvSphere:	
		case typeQvSpin:
		case typeQvSpinGroup:
		case typeQvSpotLight:
		case typeQvWWWAnchor:		
		case typeQvWWWInline:
			break;
	
	}
	return boolAddable;
}

// VRML 2.0 Event Handlers

bool ChQvGroupRenderData::OnAddChildren(ChRenderContext *pRC, ChApplet * pApplet, ChIVrmlEvent *pEventList)
{
	bool boolSuccess = false;
#if defined(CH_VRML_EVENTS)
	// Append a child to the group node.
	ChNode*	pChild = 0;
	ChNodeEvent *pEvent = (ChNodeEvent *)pEventList;
	pEvent->GetValue(pChild);

	QvGroup *pNode = (QvGroup *)m_pNode;
	if(pChild)
	{
		if(IsNodeAddable((QvNode*)pChild))
		{
			boolSuccess = true;
		}
		else
		{
			// Not allowable - allow it to be thrown it away by not using it
			string strType;
			((QvNode*)pChild)->GetType(strType);
			TRACE1("Attempt to add_children node of type %s rejected.\n", LPCTSTR(strType) );
			// Now tell the user
			string strMsg;
			strMsg.Format("VRML: Event add_children for child node of type %s is not permitted.\n", LPCTSTR(strType) );
			((ChMazeWnd*)pRC->GetWnd())->OnError( CH_MAZE_ROUTE_ERROR_INVALID_ADD, strMsg, ChMazeWnd::traceError);
		}
	}

	if(boolSuccess)
	{
		((QvNode*)pChild)->Use();
		pNode->getChildren()->append((QvNode*)pChild);
		// Now launch a constructtion thread, just like this was
		// an inline
		Instantiate( (ChMazeWnd *)(pRC->GetWnd()), (QvNode*)pChild);

		// Spawn for new requests
		ChQvSpawnState state((ChMazeWnd *)(pRC->GetWnd()), ((ChMazeWnd *)(pRC->GetWnd()))->GetCurrentURL());
    	((QvNode*)pChild)->traverse(&state);

		// Set it dirty, for redraw, etc.
		pRC->SetDirty();

	}
#endif

	return boolSuccess;
}

class MyChildRemovalIterator: public 	  ChQvRenderBaseDataIterator
{
	public:
		MyChildRemovalIterator( const ChQvGroupRenderData& rbd, QvNode *pNode) : 
			ChQvRenderBaseDataIterator(rbd),
			m_pNode(pNode)
			 {};


		virtual int DoInstance(ChQvInstance& inst)
		{
			ChQvGroupInstance*pInst = (ChQvGroupInstance*)&inst;
			pInst->MarkChildForRemoval(m_pNode);

			return true;
		};


   protected:
		QvNode *m_pNode;
};

bool ChQvGroupRenderData::OnRemoveChildren(ChRenderContext *pRC, ChApplet * pApplet, ChIVrmlEvent *pEventList)
{
	bool boolSuccess = false;
#if defined(CH_VRML_EVENTS)
	// Delete a child or children from the group node.
	ChNode*	pChild = 0;
	ChNodeEvent *pEvent = (ChNodeEvent *)pEventList;
	QvGroup *pNode = (QvGroup *)m_pNode;

	int iNumToRemove = pEvent->GetCount();

	//pRC->LockScene();	   // Lock scene so we don't conflict with construction
	for(int j = 0; j < iNumToRemove; j++)
	{
		pEvent->GetValue(j, pChild);

		if(pChild)			
		{	
			if(IsNodeRemovable((QvNode*)pChild))
			{
				boolSuccess = true;
				bool boolRemoved = false;
				for ( int i = pNode->getNumChildren() - 1; i >= 0; i--)
				{
					if(	pNode->getChild(i) == (QvNode*)pChild)
					{
						pRC->LockQv();		   // Lock tree so parse and stream threads don't barf
						MyChildRemovalIterator iterator(*this, (QvNode*)pChild);
						iterator.Iterate();
						pNode->getChildren()->remove(i);

						((QvNode*)pChild)->Release(); // This is where the subtree is deleted
						pRC->UnlockQv();
						boolRemoved = true;
					}
				}
				if(!boolRemoved)
				{
					string strMsg;
					string strParent(pNode->getName().getString());
					string strChild(((QvNode*)pChild)->getName().getString());
					if(strParent.IsEmpty()) strParent = "<Unnamed>";
					if(strChild.IsEmpty()) strChild = "<Unnamed>";
					strMsg.Format("VRML: Event remove_children - node %s not a child of %s.\n", 
						LPCTSTR(strChild), LPCTSTR(strParent));
					((ChMazeWnd*)pRC->GetWnd())->OnError( CH_MAZE_ROUTE_ERROR_NODE_NOTFOUND, strMsg, ChMazeWnd::traceError);
				}
			}
			else
			{
				string strType;
				((QvNode*)pChild)->GetType(strType);
				TRACE1("Attempt to remove_children node of type %s rejected.\n", LPCTSTR(strType) );
				// Now tell the user
				string strMsg;
				strMsg.Format("VRML: Event remove_children for child node of type %s is not permitted.\n", LPCTSTR(strType) );
				((ChMazeWnd*)pRC->GetWnd())->OnError( CH_MAZE_ROUTE_ERROR_INVALID_REMOVE, strMsg, ChMazeWnd::traceError);
			}

		}
	}
	//pRC->UnlockScene();

#endif

	return boolSuccess;
}


// End handlers

ChQvGroupRenderData* ChQvGroupRenderData::Instantiate(ChMazeWnd * pWnd, QvNode *pNewChild)
{
	// Walk the list of the group's instances, instantiating the new subtree that came in
	if (!m_instances.IsEmpty())
	{
		ChPosition pos = m_instances.GetHeadPosition();
		while(pos)
		{
			ChQvGroupInstance *pInst = (ChQvGroupInstance *)(m_instances.GetNext(pos));
			ChQvBuildState bldIt(pWnd);
			bldIt.SetCurrentParent(pInst);
			pInst->SetupTraversalState(bldIt);
			pNewChild->traverse(&bldIt);

			// Now construct them for RLab 
			#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
			pWnd->GetRenderContext()->StartConstruction(pInst);
			#endif
		}
	}
	return this;
}

// //////////////////////////////////////////
ChQvIFSRenderData::ChQvIFSRenderData(QvIndexedFaceSet* ifs, QvState* state)
	 : ChQvRenderBaseData(ifs), m_pNormals(0)
{
	CheckValid(ifs, state);
	if(m_boolValid) m_pNormals = new ChQvIndexedFaceSetNormals(ifs, state);
	SetDirty(false);
}

ChQvIFSRenderData::~ChQvIFSRenderData()
{ 
	delete m_pNormals; 
}

void ChQvIFSRenderData::Init(QvIndexedFaceSet* ifs, QvState* state)
{
	CheckValid(ifs, state);
	delete m_pNormals;
	m_pNormals = 0;
	if(m_boolValid) m_pNormals = new ChQvIndexedFaceSetNormals(ifs, state);
	SetDirty(false);
}

inline int VertCount(long *values, int num)
{
	int i = 0;
	while(values[i] != QV_END_FACE_INDEX) i++;
	return i;
}

bool ChQvIFSRenderData::CheckValid(QvIndexedFaceSet* ifs, QvState* state)
{
							/* Validate the coordinate indices of an ifs. Check for

⌨️ 快捷键说明

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