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

📄 cvbound.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Instance Bounds computers - the wave of the future

// First the helpers - these are pretty local
bool GetBoundingCube(QvMFLong *pCoordIndex, QvCoordinate3 *pC3, GxVec3f &lower, GxVec3f &upper, GxVec3f &center ) 
{
	lower.set(BIGGIE, BIGGIE, BIGGIE);
	upper.set(-BIGGIE, -BIGGIE, -BIGGIE);
	center.set(0., 0., 0.);
	int count = 0;

	for( int j = 0; j< pCoordIndex->num; j++)
	{
		if (pCoordIndex->values[j] != QV_END_FACE_INDEX)
		{ 
			int index = pCoordIndex->values[j] * 3;
			#if 1
			// Should be faster this way!
			GxVec3f *p = (GxVec3f*)(pC3->point.values+index);	// ASSUMES ALIGNMENT!!
			lower.minimum(*p);
			upper.maximum(*p);
	 		center += *p;

			#else

			lower.x() = min(lower.x(), pC3->point.values[index]);
			lower.y() = min(lower.y(), pC3->point.values[index+1]); 
			lower.z() = min(lower.z(), pC3->point.values[index+2]); 

			upper.x() = max(upper.x(), pC3->point.values[index]);
			upper.y() = max(upper.y(), pC3->point.values[index+1]); 
			upper.z() = max(upper.z(), pC3->point.values[index+2]);
			
			center.x() += pC3->point.values[index]; 
			center.y() += pC3->point.values[index+1];
			center.z() += pC3->point.values[index+2];
			#endif
			count++;
		}
 
	}

	if(count>0)
	{
		center.x() /= count;
		center.y() /= count;
		center.z() /= count;
	}
	return true;
}



// Then the Node Instances

bool ChQvIFSInstance::ComputeBounds()
{	
	if(!m_pBounds) m_pBounds = new ChQvBounds;
	GxVec3f upper, lower, center;
	QvCoordinate3 *pC3 = GetCoordinate3();
	GetBoundingCube( &(((QvIndexedFaceSet*)GetNode())->coordIndex), pC3, lower, upper, center);

	m_pBounds->SetBounds(lower, upper);
	m_pBounds->SetCenter(center);
	m_pBounds->SetTransform(GetTransform());
	m_boolBoundsDirty = false;   
	return true;
};
 
bool ChQvILSInstance::ComputeBounds()
{
	if(!m_pBounds) m_pBounds = new ChQvBounds;
	GxVec3f upper, lower, center;
	QvCoordinate3 *pC3 = GetCoordinate3();
	GetBoundingCube( &(((QvIndexedLineSet*)GetNode())->coordIndex), pC3, lower, upper, center);

	m_pBounds->SetBounds(lower, upper);
	m_pBounds->SetCenter(center);
	m_pBounds->SetTransform(GetTransform());
	m_boolBoundsDirty = false;   
	   
	return true;
}; 

bool ChQvCubeInstance::ComputeBounds()
{
	if(!m_pBounds) m_pBounds = new ChQvBounds;
	GxVec3f lower, upper, center(0.,0.,0);
	QvCube * pCube = (QvCube *)GetNode();

	lower.x() = -pCube->width.value / 2.;   
	lower.y() = -pCube->height.value / 2.;  
	lower.z() = -pCube->depth.value / 2.;   
	upper.x() =  pCube->width.value / 2.;   
	upper.y() =  pCube->height.value / 2.;  
	upper.z() =  pCube->depth.value / 2.;
	
	m_pBounds->SetBounds(lower, upper);
	m_pBounds->SetCenter(center);
	m_pBounds->SetTransform(GetTransform());
	m_boolBoundsDirty = false;   
	   
	return 1;
}; 

int ChQvConeInstance::ComputeBounds()
{
	if(!m_pBounds) m_pBounds = new ChQvBounds;
	GxVec3f lower, upper, center(0.,0.,0);
 	QvCone * pCone = (QvCone *)GetNode();

	lower.x() = -pCone->bottomRadius.value;   
	lower.y() = -pCone->height.value / 2.;  
	lower.z() = -pCone->bottomRadius.value;   
	upper.x() =  pCone->bottomRadius.value;   
	upper.y() =  pCone->height.value / 2.;  
	upper.z() =  pCone->bottomRadius.value;
	
	m_pBounds->SetBounds(lower, upper);
	m_pBounds->SetCenter(center);
	m_pBounds->SetTransform(GetTransform());
	m_boolBoundsDirty = false;   
	   
	return 1;
}; 

int ChQvSphereInstance::ComputeBounds()
{
	if(m_boolBoundsDirty)
	{
		if(!m_pBounds) m_pBounds = new ChQvBounds;
		GxVec3f lower, upper, center(0.,0.,0);
	  	QvSphere * pSphere = (QvSphere *)GetNode();

		lower.x() = -pSphere->radius.value;   
		lower.y() = -pSphere->radius.value;  
		lower.z() = -pSphere->radius.value;   
		upper.x() =  pSphere->radius.value;   
		upper.y() =  pSphere->radius.value;  
		upper.z() =  pSphere->radius.value;
	
		m_pBounds->SetBounds(lower, upper);
		m_pBounds->SetCenter(center);
		m_pBounds->SetTransform(GetTransform());
		m_boolBoundsDirty = false;   
		m_boolBoundsDirty = false;   
	}   
	return 1;
}; 

const float fMinInlineBox = 1.0e-6;

int ChQvWWWInlineInstance::ComputeBounds()
{
	if(!m_pBounds) m_pBounds = new ChQvBounds;
	QvWWWInline * pWWWInline = (QvWWWInline *)GetNode();
	GxVec3f lower, upper, center;

	float fHalfWidth = pWWWInline->bboxSize.value[0] / 2.0;
	float fHalfHeight = pWWWInline->bboxSize.value[1] / 2.0;
	float fHalfDepth = pWWWInline->bboxSize.value[2] / 2.0;
	if(fHalfWidth <= 0.0) fHalfWidth = fMinInlineBox;
	if(fHalfHeight <= 0.0) fHalfHeight = fMinInlineBox;
	if(fHalfDepth <= 0.0) fHalfDepth = fMinInlineBox;
	upper.x() = fHalfWidth;
	upper.y() = fHalfHeight;
	upper.z() = fHalfDepth;
	lower.x() = -fHalfWidth;
	lower.y() = -fHalfHeight;
	lower.z() = -fHalfDepth;
	center.x() = pWWWInline->bboxCenter.value[0];
	center.y() = pWWWInline->bboxCenter.value[1];
	center.z() = pWWWInline->bboxCenter.value[2];

	m_pBounds->SetBounds(lower, upper);
	m_pBounds->SetCenter(center);
	m_pBounds->SetTransform(GetTransform());
	m_boolBoundsDirty = false;   

	return 1;
};

int ChQvCylinderInstance::ComputeBounds()
{
	if(!m_pBounds) m_pBounds = new ChQvBounds;
	GxVec3f lower, upper, center(0.,0.,0);
  	QvCylinder * pCylinder = (QvCylinder *)GetNode();

	lower.x() = -pCylinder->radius.value;   
	lower.y() = -pCylinder->height.value / 2.;  
	lower.z() = -pCylinder->radius.value;   
	upper.x() =  pCylinder->radius.value;   
	upper.y() =  pCylinder->height.value / 2.;  
	upper.z() =  pCylinder->radius.value;
	
	m_pBounds->SetBounds(lower, upper);
 	m_pBounds->SetCenter(center);
	m_pBounds->SetTransform(GetTransform());
	m_boolBoundsDirty = false;   
	   
	return 1;
};

int ChQvAsciiTextInstance::ComputeBounds()
{
	if(!m_pBounds) m_pBounds = new ChQvBounds;
	QvAsciiText *pNode = (QvAsciiText *)m_pNode;
	if(!m_pBounds) m_pBounds = new ChQvBounds;

	GxVec3f lower, upper, center(0.,0.,0);

	HFONT hFont = CreateFont(100);
	float maxWidth = 0.0;
	for(int line = 0; line < pNode->string.num; line++)
	{
		float width = GetTextWidth(hFont, line);
		maxWidth = max(width, maxWidth);
	}
	switch(pNode->justification.value)
	{
		case QvAsciiText::LEFT:
			 lower.x() = 0.;	
			break;
		case QvAsciiText::RIGHT:
			lower.x() = -maxWidth;
			break;
		case QvAsciiText::CENTER:
			lower.x() = -maxWidth / 2;
			break;
	}
	upper.x() = lower.x() + maxWidth;
	upper.y() = -GetBaselineOffset() - line * pNode->spacing.value * GetFontStyle()->size.value;
	lower.y() = upper.y() - GetTextHeight();
	upper.z() = 0.0;
	lower.z() = -.01;	// give it a bit of depth, for safety

	center = lower;
	center += upper;
	center *= .5;

	DeleteObject(hFont);
	
	m_pBounds->SetBounds(lower, upper);
	m_pBounds->SetCenter(center);
	m_pBounds->SetTransform(GetTransform());
	m_boolBoundsDirty = false;   

	return 1;
};

int ChQvPointSetInstance::ComputeBounds()
{
	if(!m_pBounds) m_pBounds = new ChQvBounds;
	QvPointSet *pNode = (QvPointSet *)GetNode();
	QvCoordinate3 *pC3 = GetCoordinate3();
	GxVec3f lower, upper, center(0.,0.,0);

	lower.set(BIGGIE, BIGGIE, BIGGIE);
	upper.set(-BIGGIE, -BIGGIE, -BIGGIE);
	center.set(0., 0., 0.);
	int count = 0;

	int numPoints = pNode->numPoints.value;
	if(numPoints < 0)
	{
		numPoints = pC3->point.num - pNode->startIndex.value;
	}
	for(int j = pNode->startIndex.value; j < numPoints + pNode->startIndex.value; j++)	  
	{

		int index = j * 3;
		lower.x() = min(lower.x(), pC3->point.values[index]);
		lower.y() = min(lower.y(), pC3->point.values[index+1]); 
		lower.z() = min(lower.z(), pC3->point.values[index+2]); 

		upper.x() = max(upper.x(), pC3->point.values[index]);
		upper.y() = max(upper.y(), pC3->point.values[index+1]); 
		upper.z() = max(upper.z(), pC3->point.values[index+2]);
		
		center.x() += pC3->point.values[index]; 
		center.y() += pC3->point.values[index+1];
		center.z() += pC3->point.values[index+2];
		
		count++;
	}
 

	if(count>0)
	{
		center.x() /= count;
		center.y() /= count;
		center.z() /= count;
	}

	m_pBounds->SetBounds(lower, upper);
 	m_pBounds->SetCenter(center);
	m_pBounds->SetTransform(GetTransform());
	   
	m_boolBoundsDirty = false;   
	return 1;
};

void ChBoundsIterator::Push()
{	
	ChBoundsStack *pStack = new ChBoundsStack(m_upper, m_lower, m_center, m_childBoundsCount, m_inverseTransform);
	m_stack.AddHead(pStack);
}

bool ChBoundsIterator::Pop()
{
	if(m_stack.IsEmpty()) return false;
	ChBoundsStack *pStack = m_stack.RemoveHead();
	
	m_upper = pStack->m_upper;
	m_lower = pStack->m_lower;
	m_center = pStack->m_center;
	m_inverseTransform = pStack->m_inverseTransform;
	m_childBoundsCount = pStack->m_childBoundsCount;
	delete pStack;
	return true; 
}
 
ChBoundsIterator* ChBoundsIterator::LocalReset()
{
	m_upper.set(0.,0.,0.);
	m_lower.set(0.,0.,0.);
	m_center.set(0.,0.,0.);
	m_childBoundsCount = 0;
	m_inverseTransform.Identity();
	return this; 
}

bool ChBoundsIterator::DoNode(ChQvInstance& inst)
{
	switch(GetVisitType())
	{
		case beforeChildren:
		{
			Push();
			LocalReset();
			// set the inverse transform
			m_inverseTransform = inst.GetTransform().Inverse();
			#if 0
			if(!inst.IsBoundsDirty()) 	SetDoKids(false); 
			#endif

			break;
		}
		case afterChildren:
		{
		 	if(m_childBoundsCount)
			{
				m_center.x() /= m_childBoundsCount;
				m_center.y() /= m_childBoundsCount;
				m_center.z() /= m_childBoundsCount;
			}
			m_pBounds->SetBounds(m_lower, m_upper);
		 	m_pBounds->SetCenter(m_center);
			m_pBounds->SetTransform(inst.GetTransform());
			Pop();					
			Accumulate();
			// Get the bounds of group nodes, which are never
			// called with VisitType "isLeaf".
			if(inst.GetBounds(*GetBounds()))
			{
				Accumulate();
			}
			break;
		}
		case isLeaf:
		{
			if(inst.GetBounds(*GetBounds()))
			{
				Accumulate();
			}

			break;
		}
	}
	return true;

}

void ChBoundsIterator::Accumulate()
{
	if(!m_pBounds->IsEmpty())
	{
		m_childBoundsCount++;
		GxTransform3Wf	childMat;
		GxVec3f childLower, childUpper;
		m_pBounds->GetBounds(childLower, childUpper, childMat);
		
		#if defined(CH_USE_3DR)			 
		childMat = m_inverseTransform * childMat;	// Get the child into the current object coord system
		#else
		childMat = childMat * m_inverseTransform;	// Get the child into the current object coord system
		#endif
		//childMat = childMat.Compose(m_inverseTransform);	// Get the child into the current object coord system
		m_pBounds->GetTransformedBounds(childLower, childUpper, childMat);
		if(m_childBoundsCount > 1)
		{
			m_lower.x() = min(m_lower.x(), childLower.x());
			m_lower.y() = min(m_lower.y(), childLower.y()); 
			m_lower.z() = min(m_lower.z(), childLower.z()); 
			m_upper.x() = max(m_upper.x(), childUpper.x());
			m_upper.y() = max(m_upper.y(), childUpper.y()); 
			m_upper.z() = max(m_upper.z(), childUpper.z());
		}
		else
		{
			m_lower = childLower;
			m_upper = childUpper;
		}
		GxVec3f childCenter;
		m_pBounds->GetCenter(childCenter);
		childCenter = childMat * childCenter;
		m_center += childCenter;	
	}
}

// end of file

⌨️ 快捷键说明

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