// Returns a feature space index for the given x,y position in a display // window, or -1 if the feature is a miss. int IntFeatureSpace::XYToFeatureIndex(int x, int y) const { // Round the x,y position to a feature. Search for a valid theta. INT_FEATURE_STRUCT feature(x, y, 0); int index = -1; for (int theta = 0; theta <= UINT8_MAX && index < 0; ++theta) { feature.Theta = theta; index = Index(feature); } if (index < 0) { tprintf("(%d,%d) does not exist in feature space!\n", x, y); return -1; } feature = PositionFromIndex(index); tprintf("Click at (%d, %d) ->(%d, %d), ->(%d, %d)\n", x, y, feature.X, feature.Y, x - feature.X, y - feature.Y); // Get the relative position of x,y from the rounded feature. x -= feature.X; y -= feature.Y; if (x != 0 || y != 0) { double angle = atan2(static_cast<double>(y), static_cast<double>(x)) + M_PI; angle *= kIntFeatureExtent / (2.0 * M_PI); feature.Theta = static_cast<uint8_t>(angle + 0.5); index = Index(feature); if (index < 0) { tprintf("Feature failed to map to a valid index:"); feature.print(); return -1; } feature = PositionFromIndex(index); } feature.print(); return index; }
TEST_F(RawMeshTest, Load) { EXPECT_TRUE(mesh->Load(config.LoadFromStringAndGetFirstChild(RawMeshNode_Success), assets)); ASSERT_EQ(6, mesh->NumFaces()); EXPECT_TRUE(ExpectVec3Near(Math::Vec3(0, 1, 0), PositionFromIndex(mesh->Faces()[0]))); EXPECT_TRUE(ExpectVec3Near(Math::Vec3(0, 1, 1), PositionFromIndex(mesh->Faces()[1]))); EXPECT_TRUE(ExpectVec3Near(Math::Vec3(1, 1, 0), PositionFromIndex(mesh->Faces()[2]))); EXPECT_TRUE(ExpectVec3Near(Math::Vec3(0, 1, 0), PositionFromIndex(mesh->Faces()[3]))); EXPECT_TRUE(ExpectVec3Near(Math::Vec3(0, 1, 1), PositionFromIndex(mesh->Faces()[4]))); EXPECT_TRUE(ExpectVec3Near(Math::Vec3(1, 1, 1), PositionFromIndex(mesh->Faces()[5]))); for (int i = 0; i < 6; i++) { EXPECT_TRUE(ExpectVec3Near(Math::Vec3(0, -1, 0), NormalFromIndex(mesh->Faces()[i]))); } }
//----------------------------------------------------------------------------- // 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 ); } } } } }