コード例 #1
0
//==========================================================================
CAABBox CAABBox::transformAABBox(const CMatrix &mat, const CAABBox &box)
{
	// TODO : optimize this a bit if possible...
	CAABBox result;

	/* OMG. Old code was false!!
		if we have ht= M * h
		then CVector(-ht.x, ht.y, ht.z) != M * CVector(-h.x, h.y, h.z) !!!!
	*/
	// compute corners.
	CVector	p[8];
	CVector	min= box.getMin();
	CVector	max= box.getMax();
	p[0].set(min.x, min.y, min.z);
	p[1].set(max.x, min.y, min.z);
	p[2].set(min.x, max.y, min.z);
	p[3].set(max.x, max.y, min.z);
	p[4].set(min.x, min.y, max.z);
	p[5].set(max.x, min.y, max.z);
	p[6].set(min.x, max.y, max.z);
	p[7].set(max.x, max.y, max.z);
	CVector tmp;
	min = max = mat * p[0];
	// transform corners.
	for(uint i=1;i<8;i++)
	{
		tmp= mat * p[i];
		min.minof(min, tmp);
		max.maxof(max, tmp);
	}

	result.setMinMax(min, max);

	return result;
}
コード例 #2
0
CAABBox CAABBox::computeAABBoxUnion(const CAABBox &b1, const CAABBox &b2)
{
	CAABBox result;
	CVector min, max;
	CVector min1 = b1.getMin()
		    ,max1 = b1.getMax()
			,min2 = b2.getMin()
		    ,max2 = b2.getMax();
	max.maxof(max1, max2);
	min.minof(min1, min2);
	result.setMinMax(min, max);
	return result;
}
コード例 #3
0
CAABBox	getZoneBBoxById(uint16 id)
{
	CAABBox		bbox;
	uint		x, y;
	const float	zdim = 160.0f;

	x = id%256;
	y = id/256;
	bbox.setMinMax(CVector(zdim*x,		-zdim*(y+1),	-10000.0f),
				   CVector(zdim*(x+1),	-zdim*y,		+10000.0f));


	return bbox;
}
コード例 #4
0
ファイル: export_skinning.cpp プロジェクト: CCChaos/RyzomCore
bool CExportNel::mirrorPhysiqueSelection(INode &node, TimeValue tvTime, const std::vector<uint> &vertIn, 
		float threshold)
{
	bool	ok;
	uint	i;

	// no vertices selected?
	if(vertIn.empty())
		return true;

	// **** Get all the skeleton node 
	std::vector<INode*>		skeletonNodes;
	INode	*skelRoot= getSkeletonRootBone(node);
	if(!skelRoot)
		return false;
	getObjectNodes(skeletonNodes, tvTime, skelRoot);


	// **** Build the Vector (world) part
	std::vector<CTempSkinVertex>	tempVertex;
	uint	vertCount;

	// Get a pointer on the object's node.
    ObjectState os = node.EvalWorldState(tvTime);
    Object *obj = os.obj;

	// Check if there is an object
	ok= false;
	if (obj)
	{		

		// Object can be converted in triObject ?
		if (obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) 
		{ 
			// Get a triobject from the node
			TriObject *tri = (TriObject*)obj->ConvertToType(tvTime, Class_ID(TRIOBJ_CLASS_ID, 0));
			
			if (tri)
			{
				// Note that the TriObject should only be deleted
				// if the pointer to it is not equal to the object
				// pointer that called ConvertToType()
				bool deleteIt=false;
				if (obj != tri) 
					deleteIt = true;

				// Get the node matrix. TODO: Matrix headhache?
				/*Matrix3 nodeMatrixMax;
				CMatrix nodeMatrix;
				getLocalMatrix (nodeMatrixMax, node, tvTime);
				convertMatrix (nodeMatrix, nodeMatrixMax);*/

				// retrive Position geometry
				vertCount= tri->NumPoints();
				tempVertex.resize(vertCount);
				for(uint i=0;i<vertCount;i++)
				{
					Point3 v= tri->GetPoint(i);
					tempVertex[i].Pos.set(v.x, v.y, v.z);
				}

				// Delete the triObject if we should...
				if (deleteIt)
					tri->MaybeAutoDelete();
				tri = NULL;

				// ok!
				ok= true;
			}
		}
	}
	if(!ok)
		return false;

	// no vertices? abort
	if(vertCount==0)
		return true;


	// **** Mark all Input vertices
	for(i=0;i<vertIn.size();i++)
	{
		nlassert(vertIn[i]<vertCount);
		tempVertex[vertIn[i]].Input= true;
	}


	// **** Build the output vertices
	std::vector<uint>	vertOut;
	vertOut.reserve(tempVertex.size());

	// Build the in bbox
	CAABBox		bbox;
	bbox.setCenter(tempVertex[vertIn[0]].Pos);
	for(i=0;i<vertIn.size();i++)
	{
		bbox.extend(tempVertex[vertIn[i]].Pos);
	}
	bbox.setHalfSize(bbox.getHalfSize()+CVector(threshold, threshold, threshold));

	// mirror in X
	CVector		vMin= bbox.getMin();
	CVector		vMax= bbox.getMax();
	vMin.x= -vMin.x;
	vMax.x= -vMax.x;
	std::swap(vMin.x, vMax.x);
	bbox.setMinMax(vMin, vMax);

	// get all out vertices in the mirrored bbox.
	for(i=0;i<tempVertex.size();i++)
	{
		if(bbox.include(tempVertex[i].Pos))
		{
			vertOut.push_back(i);
		}
	}


	// **** Build the skin information
	// Get the skin modifier
	Modifier* skin=getModifier (&node, PHYSIQUE_CLASS_ID);

	// Found it ?
	ok= false;
	if (skin)
	{
		// Get a com_skin2 interface
		IPhysiqueExport *physiqueInterface=(IPhysiqueExport *)skin->GetInterface (I_PHYINTERFACE);

		// Found com_skin2 ?
		if (physiqueInterface)
		{
			// Get local data
			IPhyContextExport *localData= physiqueInterface->GetContextInterface(&node);

			// Found ?
			if (localData)
			{
				// Use rigid export
				localData->ConvertToRigid (TRUE);

				// Allow blending
				localData->AllowBlending (TRUE);

				// Skinned
				ok=true;

				// TODO?
				nlassert(tempVertex.size()<=(uint)localData->GetNumberVertices());

				// For each vertex
				for (uint vert=0; vert<vertCount; vert++)
				{
					// Get a vertex interface
					IPhyVertexExport *vertexInterface= localData->GetVertexInterface (vert);

					// Check if it is a rigid vertex or a blended vertex
					IPhyRigidVertex			*rigidInterface=NULL;
					IPhyBlendedRigidVertex	*blendedInterface=NULL;
					int type=vertexInterface->GetVertexType ();
					if (type==RIGID_TYPE)
					{
						// this is a rigid vertex
						rigidInterface=(IPhyRigidVertex*)vertexInterface;
					}
					else
					{
						// It must be a blendable vertex
						nlassert (type==RIGID_BLENDED_TYPE);
						blendedInterface=(IPhyBlendedRigidVertex*)vertexInterface;
					}

					// Get bones count for this vertex
					uint boneCount;
					if (blendedInterface)
					{
						// If blenvertex, only one bone
						boneCount=blendedInterface->GetNumberNodes();
					}
					else
					{
						// If rigid vertex, only one bone
						boneCount=1;
					}
					if(boneCount>TEMP_MAX_WEIGHT)
						boneCount= TEMP_MAX_WEIGHT;

					// NB: if input 0, won't be mirrored
					tempVertex[vert].NumWeight= boneCount;
					for(uint bone=0;bone<boneCount;bone++)
					{
						if (blendedInterface)
						{
							tempVertex[vert].Bone[bone]= blendedInterface->GetNode(bone);
							nlassert(tempVertex[vert].Bone[bone]);
							tempVertex[vert].Weight[bone]= blendedInterface->GetWeight(bone);
						}
						else
						{
							tempVertex[vert].Bone[bone]= rigidInterface->GetNode();
							tempVertex[vert].Weight[bone]= 1;
						}
					}

					// Release vertex interfaces
					localData->ReleaseVertexInterface (vertexInterface);
				}

			}

			// release context interface
			physiqueInterface->ReleaseContextInterface(localData);
		}

		// Release the interface
		skin->ReleaseInterface (I_PHYINTERFACE, physiqueInterface);
	}
	if(!ok)
		return false;


	// **** Real Algo stuff:
	// For all vertices wanted to be mirrored
	std::vector<CSortVertex>	sortVert;
	sortVert.reserve(tempVertex.size());
	for(i=0;i<vertIn.size();i++)
	{
		CTempSkinVertex		&svIn= tempVertex[vertIn[i]];
		// if it still has no bones set, skip
		if(svIn.NumWeight==0)
			continue;

		// mirror vert to test
		CVector		vertTest= svIn.Pos;
		vertTest.x*= -1;

		// get the best vertex
		sortVert.clear();

		// Search for all output vertices if ones match
		for(uint j=0;j<vertOut.size();j++)
		{
			uint	dstIdx= vertOut[j];
			nlassert(dstIdx<tempVertex.size());
			CTempSkinVertex	&skinv= tempVertex[dstIdx];
			// take only if not an input, and if not already mirrored
			if(!skinv.Input && !skinv.Mirrored)
			{
				CSortVertex		sortv;
				sortv.Index= dstIdx;
				sortv.SqrDist= (skinv.Pos - vertTest).sqrnorm();
				// Finally, take it only if sufficiently near
				if(sortv.SqrDist <= threshold*threshold)
					sortVert.push_back(sortv);
			}
		}

		// if some found.
		if(!sortVert.empty())
		{
			// sort array.
			std::sort(sortVert.begin(), sortVert.end());

			// take the first, mirror setup
			uint	dstIdx= sortVert[0].Index;
			tempVertex[dstIdx].NumWeight= svIn.NumWeight;
			for(uint k=0;k<svIn.NumWeight;k++)
			{
				tempVertex[dstIdx].Weight[k]= svIn.Weight[k];
				tempVertex[dstIdx].Bone[k]= getMirrorBone( skeletonNodes, svIn.Bone[k] );
			}

			// mark as mirrored!
			tempVertex[dstIdx].Mirrored= true;
		}
	}


	// **** Write the result to the skin.
	ok= false;
	if (skin)
	{
		// Get a com_skin2 interface
		IPhysiqueImport *physiqueInterface=(IPhysiqueImport *)skin->GetInterface (I_PHYIMPORT);

		// Found com_skin2 ?
		if (physiqueInterface)
		{
			// Get local data
			IPhyContextImport *localData= physiqueInterface->GetContextInterface(&node);

			// TODO?
			nlassert(tempVertex.size()<=(uint)localData->GetNumberVertices());

			// Found ?
			if (localData)
			{
				// Skinned
				ok=true;
				
				for(uint i=0;i<tempVertex.size();i++)
				{
					CTempSkinVertex		&sv= tempVertex[i];

					// if its a mirrored output vertex
					if(sv.Mirrored)
					{
						IPhyBlendedRigidVertexImport	*blendedInterface= NULL;
						blendedInterface= (IPhyBlendedRigidVertexImport*)localData->SetVertexInterface(i, RIGID_BLENDED_TYPE);

						if(blendedInterface)
						{
							// set the vertex data
							for(uint bone=0;bone<sv.NumWeight;bone++)
							{
								blendedInterface->SetWeightedNode(sv.Bone[bone], sv.Weight[bone], bone==0);
							}

							// UI bonus: lock it
							blendedInterface->LockVertex(TRUE);

							// release
							localData->ReleaseVertexInterface(blendedInterface);
						}
					}
				}
			}

			// release
			physiqueInterface->ReleaseContextInterface(localData);
		}

		// release
		skin->ReleaseInterface(I_PHYIMPORT, physiqueInterface);
	}


	return ok;
}