Пример #1
0
/*---------------------------------------------------------------------------*/
unsigned int NifCollisionUtility::getGeometryFromPackedNiTriStrips(bhkPackedNiTriStripsShapeRef pShape, vector<hkGeometry>& geometryMap, vector<Matrix44>& transformAry)
{
	hkPackedNiTriStripsDataRef	pData (DynamicCast<hkPackedNiTriStripsData>(pShape->GetData()));
	float						factor(0.1f);

	//@TODO:  modify factor depending on _nifVersion if necessary

	if (pData != NULL)
	{
		hkGeometry						tmpGeo;
		hkArray<hkVector4>&				vertAry  (tmpGeo.m_vertices);
		hkArray<hkGeometry::Triangle>&	triAry   (tmpGeo.m_triangles);
		vector<OblivionSubShape>		subShapes(pData->GetSubShapes());
		vector<Vector3>					vertices (pData->GetVertices());
		vector<hkTriangle>				triangles(pData->GetHavokTriangles());
		hkTriangle&						triangle (triangles[0]);
		Vector3							tVector;
		unsigned int					verOffset(0);
		unsigned int					triIndex (0);
		unsigned int					material (_defaultMaterial);

		//  convert each sub-shape
		for (auto pIter=subShapes.begin(), pEnd=subShapes.end(); pIter != pEnd; ++pIter)
		{
			//  reset arrays
			vertAry.clear();
			triAry.clear();

			//  get vertices
			for (unsigned int idx(verOffset), idxMax(verOffset+pIter->numVertices); idx < idxMax; ++idx)
			{
				tVector = vertices[idx];

				//  scale final vertex
				tVector *= factor;

				//  add vertex to tmp. array
				vertAry.pushBack(hkVector4(tVector.x, tVector.y, tVector.z));

			}  //  for (unsigned int idx(verOffset), idxMax(verOffset+pIter->numVertices); idx < idxMax; ++idx)

			//  get triangles
			for (; triIndex < triangles.size(); ++triIndex)
			{
				//  check vertex bounds
				triangle = triangles[triIndex];
				if ((triangle.triangle.v1 >= (pIter->numVertices + verOffset)) ||
					(triangle.triangle.v2 >= (pIter->numVertices + verOffset)) ||
					(triangle.triangle.v3 >= (pIter->numVertices + verOffset))
				   )
				{
					break;
				}
			
				hkGeometry::Triangle	tTri;

				tTri.set(triangle.triangle.v1-verOffset, triangle.triangle.v2-verOffset, triangle.triangle.v3-verOffset, material);
				triAry.pushBack(tTri);

			}  //  for (; triIndex < triangles.size(); ++triIndex)

			//  re-order triangles points to match same winding
			if (_reorderTriangles)
			{
				reorderTriangles(triAry);
			}

			//  add geometry to result array
			geometryMap.push_back(tmpGeo);

			//  increase vertex offset
			verOffset += pIter->numVertices;

		}  //  for (auto pIter=subShapes.begin(), pEnd=subShapes.end(); pIter != pEnd; ++pIter)
	}  //  if (pData != NULL)

	return geometryMap.size();
}
Пример #2
0
bool CollisionImport::ImportPackedNiTriStripsShape(INode *rbody, bhkRigidBodyRef body, bhkPackedNiTriStripsShapeRef shape, INode *parent, Matrix3& tm)
{
	if (hkPackedNiTriStripsDataRef data = shape->GetData())
	{
		Matrix3 ltm(true);
		vector<Vector3> verts = data->GetVertices();
		vector<Triangle> tris = data->GetTriangles();
		vector<Vector3> norms = data->GetNormals();

		vector<Niflib::OblivionSubShape> subshapes = (ni.IsFallout3() || ni.IsSkyrim()) ? shape->GetSubShapes() : data->GetSubShapes();
		if (subshapes.size() == 0)
		{
			// Is this possible?
			INode *inode = ImportCollisionMesh(verts, tris, norms, tm, parent);
			CreatebhkCollisionModifier(inode, bv_type_packed, HavokMaterial(NP_DEFAULT_HVK_MATERIAL), OL_UNIDENTIFIED, 0);
			ImportBase(body, shape, parent, inode, ltm);
			AddShape(rbody, inode);
		}
		else
		{
			unsigned int voff = 0;
			unsigned int toff = 0;

			INodeTab nodes;
			for (int i = 0, n = subshapes.size(); i<n; ++i) {
				Niflib::OblivionSubShape& s = subshapes[i];
				
				vector<Vector3> subverts;
				vector<Triangle> subtris;
				vector<Vector3> subnorms;
				
				subverts.reserve(s.numVertices);
				for (unsigned int v=voff; v < (voff + s.numVertices); ++v) {
					subverts.push_back( verts[v] );
				}
				unsigned int vend = (voff + s.numVertices );

				// TODO: Fix algorithm.  I do not know how to split the triangles here
				//       Basically, greedily take all triangles until next subshape
				//       This is not correct but seems to work with most meshes tested.
				subtris.reserve( s.numVertices / 2 );
				subnorms.reserve( s.numVertices / 2 );
				while ( toff < tris.size() ){
					Triangle t = tris[toff];
					if ( t.v1 >= vend || t.v2 >= vend || t.v3 >= vend )
						break;
					// remove offset for mesh
					t.v1 -= voff; t.v2 -= voff; t.v3 -= voff;
					subtris.push_back( t );	
					subnorms.push_back( norms[toff] );	
					++toff;
				}
				voff += s.numVertices;

				INode *inode = ImportCollisionMesh(subverts, subtris, subnorms, tm, parent);

				CreatebhkCollisionModifier(inode, bv_type_packed, HavokMaterial(s.material), s.layer, s.colFilter);
				ImportBase(body, shape, parent, inode, ltm);

				if (n > 1)
					inode->SetName( FormatText("%s:%d", "OblivionSubShape", i).data() );

				nodes.Append(1, &inode);
			}
			// TODO: Group nodes on import
			if (  nodes.Count() > 1 )
			{
				TSTR shapeName = "bhkPackedNiTriStripsShape";
				INode *group = ni.gi->GroupNodes(&nodes, &shapeName, 0);			
				AddShape(rbody, group);
			}
			else if (  nodes.Count() == 1 )
			{
				AddShape(rbody, nodes[0]);
			}
		}
		return true;
	}

	return false;
}