//-----------------------------------------------------------------------------
// Computes a convex hull from a studio mesh
//-----------------------------------------------------------------------------
static void AddMeshToPolysoup( CPhysPolysoup* pSoup, mstudiomesh_t* pMesh, OptimizedModel::MeshHeader_t* pVtxMesh )
{
	Vector v[3];

	for (int i = 0; i < pVtxMesh->numStripGroups; ++i )
	{
		OptimizedModel::StripGroupHeader_t* pStripGroup = pVtxMesh->pStripGroup(i);

		if (pStripGroup->flags & OptimizedModel::STRIP_IS_TRILIST)
		{
			for (int j = 0; j < pStripGroup->numStrips; ++j )
			{
				OptimizedModel::StripHeader_t* pStrip = pStripGroup->pStrip(i);

				int numTri = pStrip->numIndices / 3;
				unsigned short* pIdx = pStripGroup->pIndex(pStrip->indexOffset);
				for (int k = 0; k < numTri; ++k)
				{
					v[0] = *PositionFromIndex( pMesh, pStripGroup, pIdx[3*k] );
					v[1] = *PositionFromIndex( pMesh, pStripGroup, pIdx[3*k+1] );
					v[2] = *PositionFromIndex( pMesh, pStripGroup, pIdx[3*k+2] );
					s_pPhysCollision->PolysoupAddTriangle( pSoup, v[0], v[1], v[2], 0 );
				}
			}
		}
		else
		{
			for (int j = 0; j < pStripGroup->numStrips; ++j )
			{
				OptimizedModel::StripHeader_t* pStrip = pStripGroup->pStrip(i);

				int numTri = pStrip->numIndices - 2;
				unsigned short* pIdx = pStripGroup->pIndex(pStrip->indexOffset);
				for (int k = 0; k < numTri; ++k)
				{
					v[0] = *PositionFromIndex( pMesh, pStripGroup, pIdx[k] );
					bool winding = ( (k & 0x1) == 0 );
					v[2 - winding] = *PositionFromIndex( pMesh, pStripGroup, pIdx[k+1] );
					v[1 + winding] = *PositionFromIndex( pMesh, pStripGroup, pIdx[k+2] );
					s_pPhysCollision->PolysoupAddTriangle( pSoup, v[0], v[1], v[2], 0 );
				}
			}
		}
	}
}
Esempio n. 2
0
//-----------------------------------------------------------------------------
// Adds all static prop polys to the ray trace store.
//-----------------------------------------------------------------------------
void CVradStaticPropMgr::AddPolysForRayTrace( void )
{
	int count = m_StaticProps.Count();
	if ( !count )
	{
		// nothing to do
		return;
	}

	for ( int nProp = 0; nProp < count; ++nProp )
	{
		CStaticProp &prop = m_StaticProps[nProp];
		if ( prop.m_Flags & STATIC_PROP_NO_SHADOW )
			continue;

		StaticPropDict_t &dict = m_StaticPropDict[prop.m_ModelIdx];
		studiohdr_t	*pStudioHdr = dict.m_pStudioHdr;
		OptimizedModel::FileHeader_t *pVtxHdr = (OptimizedModel::FileHeader_t *)dict.m_VtxBuf.Base();
		if ( !pStudioHdr || !pVtxHdr )
		{
			// must have model and its verts for decoding triangles
			return;
		}

		// for access to this model's vertexes
		SetCurrentModel( pStudioHdr );
	
		// meshes are deeply hierarchial, divided between three stores, follow the white rabbit
		// body parts -> models -> lod meshes -> strip groups -> strips
		// the vertices and indices are pooled, the trick is knowing the offset to determine your indexed base 
		for ( int bodyID = 0; bodyID < pStudioHdr->numbodyparts; ++bodyID )
		{
			OptimizedModel::BodyPartHeader_t* pVtxBodyPart = pVtxHdr->pBodyPart( bodyID );
			mstudiobodyparts_t *pBodyPart = pStudioHdr->pBodypart( bodyID );

			for ( int modelID = 0; modelID < pBodyPart->nummodels; ++modelID )
			{
				OptimizedModel::ModelHeader_t* pVtxModel = pVtxBodyPart->pModel( modelID );
				mstudiomodel_t *pStudioModel = pBodyPart->pModel( modelID );

				// assuming lod 0, could iterate if required
				int nLod = 0;
				OptimizedModel::ModelLODHeader_t *pVtxLOD = pVtxModel->pLOD( nLod );

				for ( int nMesh = 0; nMesh < pStudioModel->nummeshes; ++nMesh )
				{
					mstudiomesh_t* pMesh = pStudioModel->pMesh( nMesh );
					OptimizedModel::MeshHeader_t* pVtxMesh = pVtxLOD->pMesh( nMesh );
					const mstudio_meshvertexdata_t *vertData = pMesh->GetVertexData();

					for ( int nGroup = 0; nGroup < pVtxMesh->numStripGroups; ++nGroup )
					{
						OptimizedModel::StripGroupHeader_t* pStripGroup = pVtxMesh->pStripGroup( nGroup );

						int nStrip;
						for ( nStrip = 0; nStrip < pStripGroup->numStrips; nStrip++ )
						{
							OptimizedModel::StripHeader_t *pStrip = pStripGroup->pStrip( nStrip );

							if ( pStrip->flags & OptimizedModel::STRIP_IS_TRILIST )
							{
								for ( int i = 0; i < pStrip->numIndices; i += 3 )
								{
									int idx = pStrip->indexOffset + i;

									unsigned short i1 = *pStripGroup->pIndex( idx );
									unsigned short i2 = *pStripGroup->pIndex( idx + 1 );
									unsigned short i3 = *pStripGroup->pIndex( idx + 2 );

									int vertex1 = pStripGroup->pVertex( i1 )->origMeshVertID;
									int vertex2 = pStripGroup->pVertex( i2 )->origMeshVertID;
									int vertex3 = pStripGroup->pVertex( i3 )->origMeshVertID;

									// transform position into world coordinate system
									matrix3x4_t	matrix;
									AngleMatrix( prop.m_Angles, prop.m_Origin, matrix );

									Vector position1;
									Vector position2;
									Vector position3;
									VectorTransform( *vertData->Position( vertex1 ), matrix, position1 );
									VectorTransform( *vertData->Position( vertex2 ), matrix, position2 );
									VectorTransform( *vertData->Position( vertex3 ), matrix, position3 );
// 		printf( "\ngl 3\n" );
// 		printf( "gl %6.3f %6.3f %6.3f 1 0 0\n", XYZ(position1));
// 		printf( "gl %6.3f %6.3f %6.3f 0 1 0\n", XYZ(position2));
// 		printf( "gl %6.3f %6.3f %6.3f 0 0 1\n", XYZ(position3));
									g_RtEnv.AddTriangle( nProp,
														 position1, position2, position3,
														 Vector(0,0,0));
								}
							}
							else
							{
								// all tris expected to be discrete tri lists
								// must fixme if stripping ever occurs
								printf("unexpected strips found\n");
								Assert( 0 );
								return;
							}
						}
					}
				}
			}
		}
	}
}