// // 从建筑物的行走面数据文件中读取三角形的信息。 // // 参数: std::string strFileName 建筑物行走面的数据文件。 // // return: 0 - 成功。 非0 失败。具体含义根据需要待定。 DWORD FairyEditorFrame::LoadCollisionDataFromFile(std::string strFileName, TRI_INFO_VECTOR &TriInfoVector) { FILE* pFile = NULL; pFile = ::fopen(strFileName.c_str(), "rb"); if(NULL == pFile) { return 1; } DWORD dwVersion = 0; int iTriCount = 0; TRI_INFO triInfo; TriInfoVector.clear(); ::fread(&dwVersion, sizeof(dwVersion), 1, pFile); ::fread(&iTriCount, sizeof(iTriCount), 1, pFile); for(int i = 0; i < iTriCount; i++) { ::fread(&triInfo, sizeof(triInfo), 1, pFile); TriInfoVector.push_back(triInfo); } ::fclose(pFile); return 0; }
// // 从行走面数据文件中读取数据。 // // 参数:行走面数据文件, 包含路径。 UINT CBuildingCollisionMng::LoadCollisionTriInfoFromFile(const char* szFileName) { // 读取新的数据之前, 要清空数据. ClearData(); if(!szFileName || szFileName[0] == '\0') return 1; char* lpAddress = NULL; DWORD dwSize = CGameProcedure::s_pResourceProvider->loadResource(szFileName, lpAddress, "Scene"); if(dwSize > 0) { char* pPoint = lpAddress; //FILE* pFile = NULL; //pFile = ::fopen(szFileName, "rb"); //if(NULL == pFile) //{ // return 1; //} TRI_INFO triInfo; POINT_2D pos; UINT dwVersion = 0; INT iPosCount = 0; INT iTriCount = 0; TRI_INFO_VECTOR triInfoVector; // 读取版本号 //::fread(&dwVersion, sizeof(dwVersion), 1, pFile); memcpy(&dwVersion, pPoint, sizeof(dwVersion)); pPoint+=sizeof(dwVersion); // 读取注册过的三角形的位置的个数 //::fread(&iPosCount, sizeof(iPosCount), 1, pFile); memcpy(&iPosCount, pPoint, sizeof(iPosCount)); pPoint+=sizeof(iPosCount); for(INT i = 0; i < iPosCount; i++) { // 清空三角形信息数组。 triInfoVector.clear(); // 读取位置 //::fread(&pos, sizeof(pos), 1, pFile); memcpy(&pos, pPoint, sizeof(pos)); pPoint+=sizeof(pos); // 读取注册这个位置的三角形的个数 //::fread(&iTriCount, sizeof(iTriCount), 1, pFile); memcpy(&iTriCount, pPoint, sizeof(iTriCount)); pPoint+=sizeof(iTriCount); for(INT j = 0; j < iTriCount; j++) { //::fread(&triInfo, sizeof(triInfo), 1, pFile); memcpy(&triInfo, pPoint, sizeof(triInfo)); pPoint+=sizeof(triInfo); triInfoVector.push_back(triInfo); } if(triInfoVector.size()) { m_triInfoMap[pos] = triInfoVector; } } //::fclose(pFile); CGameProcedure::s_pResourceProvider->unloadResource( lpAddress, dwSize ); } return 0; }
// // 把三角形信息写到地图的三角形与位置的映射表中。 // // 参数1: 三角形列表。 // // 参数2: 三角形的变换矩阵。 // void FairyEditorFrame::WriteCollisionDataToTriMap_Rectangle(TRI_INFO_VECTOR &TriInfoVector, Ogre::Matrix4& TransformMatrix) { int iCount = 0; //每一个物体的行走面三角形个数 POINT_3D Info1; // 行走面的第一个点。 POINT_3D Info2; // 行走面的第二个点。 POINT_3D Info3; // 行走面的第三个点. POINT_3D recP1; // 矩形第一个点。 POINT_3D recP2; // 矩形第二个点。 POINT_3D recP3; // 矩形第三个点. POINT_3D recP4; // 矩形第四个点. float fV1x = 0; // 用来求三角形三条边的参数方程。 float fV1z = 0; // float fV2x = 0; // fV1x = v1.x - v2.x fV1z = v1.z - v2.z float fV2z = 0; // fV2x = v2.x - v3.x fV2y = v2.z - v3.z float fV3x = 0; // fV3x = v3.x - v1.x fV3y = v3.z - v1.z float fV3z = 0; // float fMinX = 0; // 用来求三角形三条边的参数方程。 float fMinZ = 0; // float fMaxX = 0; // fV1x = v1.x - v2.x fV1z = v1.z - v2.z float fMaxZ = 0; // fV2x = v2.x - v3.x fV2y = v2.z - v3.z float ft = 0; // 参数方程比率t int iScanStart = 0; // 扫描线的开始点。 int iScanEnd = 0; // 扫描线的结束点。 float fFindStart = 0; // 每次扫描找到的开始点。 float fFindEnd = 0; // 每次扫描找到的结束点。 float fValue = 0; // 找到的值。 POINT_2D point2DKey; int iFaceCount = TriInfoVector.size(); TRI_INFO Tri; Info1.fx = TriInfoVector[0].f1x; Info1.fy = TriInfoVector[0].f1y; Info1.fz = TriInfoVector[0].f1z; TranslateSceneToGameLogic(Info1.fx, Info1.fy, Info1.fz, TransformMatrix); fMinX = Info1.fx; fMinZ = Info1.fz; fMaxX = Info1.fx; fMaxZ = Info1.fz; for(int i = 0; i < iFaceCount; i++) { // 计算点一 Info1.fx = TriInfoVector[i].f1x; Info1.fy = TriInfoVector[i].f1y; Info1.fz = TriInfoVector[i].f1z; TranslateSceneToGameLogic(Info1.fx, Info1.fy, Info1.fz, TransformMatrix); if(fMinX > Info1.fx) { fMinX = Info1.fx; } if(fMinZ > Info1.fz) { fMinZ = Info1.fz; } if(fMaxX < Info1.fx) { fMaxX = Info1.fx; } if(fMaxZ < Info1.fz) { fMaxZ = Info1.fz; } // 计算点二 Info1.fx = TriInfoVector[i].f2x; Info1.fy = TriInfoVector[i].f2y; Info1.fz = TriInfoVector[i].f2z; TranslateSceneToGameLogic(Info1.fx, Info1.fy, Info1.fz, TransformMatrix); if(fMinX > Info1.fx) { fMinX = Info1.fx; } if(fMinZ > Info1.fz) { fMinZ = Info1.fz; } if(fMaxX < Info1.fx) { fMaxX = Info1.fx; } if(fMaxZ < Info1.fz) { fMaxZ = Info1.fz; } // 计算点三 Info1.fx = TriInfoVector[i].f3x; Info1.fy = TriInfoVector[i].f3y; Info1.fz = TriInfoVector[i].f3z; TranslateSceneToGameLogic(Info1.fx, Info1.fy, Info1.fz, TransformMatrix); if(fMinX > Info1.fx) { fMinX = Info1.fx; } if(fMinZ > Info1.fz) { fMinZ = Info1.fz; } if(fMaxX < Info1.fx) { fMaxX = Info1.fx; } if(fMaxZ < Info1.fz) { fMaxZ = Info1.fz; } }// for(int i = 0; i < iFaceCount; i++) int iMinX = 0; int iMinZ = 0; int iMaxX = 0; int iMaxZ = 0; iMinX = fMinX - 1; iMinZ = fMinZ - 1; iMaxX = fMaxX + 1; iMaxZ = fMaxZ + 1; TRI_INFO_VECTOR newTriInfoVector; for(int x = iMinX; x <= iMaxX; x++) for(int z = iMinZ; z <= iMaxZ; z++) { recP1.fx = x; recP1.fz = z; recP2.fx = x + 1; recP2.fz = z; recP3.fx = x + 1; recP3.fz = z + 1; recP4.fx = x; recP4.fz = z + 1; for(int iFace = 0; iFace < iFaceCount; iFace++) { // 计算点一 Info1.fx = TriInfoVector[iFace].f1x; Info1.fy = TriInfoVector[iFace].f1y; Info1.fz = TriInfoVector[iFace].f1z; TranslateSceneToGameLogic(Info1.fx, Info1.fy, Info1.fz, TransformMatrix); // 计算点二 Info2.fx = TriInfoVector[iFace].f2x; Info2.fy = TriInfoVector[iFace].f2y; Info2.fz = TriInfoVector[iFace].f2z; TranslateSceneToGameLogic(Info2.fx, Info2.fy, Info2.fz, TransformMatrix); // 计算点三 Info3.fx = TriInfoVector[iFace].f3x; Info3.fy = TriInfoVector[iFace].f3y; Info3.fz = TriInfoVector[iFace].f3z; TranslateSceneToGameLogic(Info3.fx, Info3.fy, Info3.fz, TransformMatrix); if(Is_Rectangle_Triangle_Intersect(Info1, Info2, Info3, recP1, recP2, recP3, recP4)) { // 把三角形注册到地图中去 Tri.f1x = Info1.fx; Tri.f1y = Info1.fy; Tri.f1z = Info1.fz; Tri.f2x = Info2.fx; Tri.f2y = Info2.fy; Tri.f2z = Info2.fz; Tri.f3x = Info3.fx; Tri.f3y = Info3.fy; Tri.f3z = Info3.fz; point2DKey.iX = x; point2DKey.iY = z; if(m_TriInMapInfoMap.m_triInfoInMap.count(point2DKey)) { m_TriInMapInfoMap.m_triInfoInMap[point2DKey].push_back(Tri); } else { newTriInfoVector.clear(); newTriInfoVector.push_back(Tri); m_TriInMapInfoMap.m_triInfoInMap[point2DKey] = newTriInfoVector; } }// if(Is_Rectangle_Triangle_Intersect(Info1, Info2, Info3, recP1, recP2, recP3, recP4)) }// for(int iFace = 0; iFace < iFaceCount; iFace++) } //for(int x = iMinX; x < iMaxX; x++) //for(int z = fMinZ; z < fMaxZ; z++) }
// // 把三角形信息写到地图的三角形与位置的映射表中。 // // 参数1: 三角形列表。 // // 参数2: 三角形的变换矩阵。 // void FairyEditorFrame::WriteCollisionDataToTriMap(TRI_INFO_VECTOR &TriInfoVector, Ogre::Matrix4& TransformMatrix) { typedef std::vector<SCANLINE_INFO> SCAN_LINE_VECTOR; SCANLINE_INFO Scanline_info; // 扫描信息. SCAN_LINE_VECTOR ScanLineVector; // 每一个三角形的扫描信息. int iCount = 0; //每一个物体的行走面三角形个数 POINT_3D Info1; // 行走面的第一个点。 POINT_3D Info2; // 行走面的第二个点。 POINT_3D Info3; // 行走面的第三个点. float fV1x; // 用来求三角形三条边的参数方程。 float fV1z; // float fV2x; // fV1x = v1.x - v2.x fV1z = v1.z - v2.z float fV2z; // fV2x = v2.x - v3.x fV2y = v2.z - v3.z float fV3x; // fV3x = v3.x - v1.x fV3y = v3.z - v1.z float fV3z; // float ft; // 参数方程比率t int iScanStart = 0; // 扫描线的开始点。 int iScanEnd = 0; // 扫描线的结束点。 float fFindStart; // 每次扫描找到的开始点。 float fFindEnd; // 每次扫描找到的结束点。 float fMaxX = 0; // 三角形x的取值范围. float fMinX = 0; // float fValue = 0; // 找到的值。 POINT_2D point2DKey; // 需要扫描的三角形。 TRI_INFO tri; int iFaceCount = TriInfoVector.size(); TRI_INFO Tri; for(int i = 0; i < iFaceCount; i++) { ScanLineVector.clear(); Tri = TriInfoVector[i]; Info1.fx = TriInfoVector[i].f1x; Info1.fy = TriInfoVector[i].f1y; Info1.fz = TriInfoVector[i].f1z; TranslateSceneToGameLogic(Info1.fx, Info1.fy, Info1.fz, TransformMatrix); fMinX = Info1.fx; fMaxX = Info1.fx; Info2.fx = TriInfoVector[i].f2x; Info2.fy = TriInfoVector[i].f2y; Info2.fz = TriInfoVector[i].f2z; TranslateSceneToGameLogic(Info2.fx, Info2.fy, Info2.fz, TransformMatrix); //fMinX = min(fMinX, Info2.fx); //fMaxX = max(fMaxX, Info2.fx); if(fMinX > Info2.fx) { fMinX = Info2.fx; } if(fMaxX < Info2.fx) { fMaxX = Info2.fx; } Info3.fx = TriInfoVector[i].f3x; Info3.fy = TriInfoVector[i].f3y; Info3.fz = TriInfoVector[i].f3z; TranslateSceneToGameLogic(Info3.fx, Info3.fy, Info3.fz, TransformMatrix); //fMinX = min(fMinX, Info3.fx); //fMaxX = max(fMaxX, Info3.fx); if(fMinX > Info3.fx) { fMinX = Info3.fx; } if(fMaxX < Info3.fx) { fMaxX = Info3.fx; } // 计算要扫描的三角形。 tri.f1x = Info1.fx; tri.f1y = Info1.fy; tri.f1z = Info1.fz; tri.f2x = Info2.fx; tri.f2y = Info2.fy; tri.f2z = Info2.fz; tri.f3x = Info3.fx; tri.f3y = Info3.fy; tri.f3z = Info3.fz; ////////////////////////////////////////////////////////////////////////////////////////////////// // // 找到所有的扫描线. // // // 扫描第一条边。 fV1x = Info2.fx - Info1.fx; fV1z = Info2.fz - Info1.fz; if(fabs((float)fV1x) < 0.0001) { Scanline_info.iStart = (int)((Info1.fz < Info2.fy) ? Info1.fz : Info2.fz ) - 1; Scanline_info.iEnd = (int)((Info1.fz > Info2.fy) ? Info1.fz : Info2.fz ) + 1; Scanline_info.iScanLine = (int)Info1.fx; ScanLineVector.push_back(Scanline_info); } // 扫描第二条边。 fV2x = Info3.fx - Info2.fx; fV2z = Info3.fz - Info2.fz; if(fabs((float)fV2x) < 0.0001) { Scanline_info.iStart = (int)((Info3.fz < Info2.fz) ? Info3.fz : Info2.fz) - 1; Scanline_info.iEnd = (int)((Info3.fz > Info2.fz) ? Info3.fz : Info2.fz) + 1; Scanline_info.iScanLine = (int)Info2.fx; ScanLineVector.push_back(Scanline_info); } // 扫描第三条边。 fV3x = Info1.fx - Info3.fx; fV3z = Info1.fz - Info3.fz; if(fabs((float)fV3x) < 0.0001) { Scanline_info.iStart = (int)((Info1.fz < Info3.fz) ? Info1.fz : Info3.fz) - 1; Scanline_info.iEnd = (int)((Info1.fz > Info3.fz) ? Info1.fz : Info3.fz) + 1; Scanline_info.iScanLine = (int)Info3.fx; ScanLineVector.push_back(Scanline_info); } iScanStart = (int)fMinX - 1; // 扫描线的开始点。 iScanEnd = (int)fMaxX + 1; // 扫描线的结束点。 for(int k = iScanStart; k <= iScanEnd; k++) {// 循环每一个扫描线. /////////////////////////////////////////////////////// // // 初始化这三个值的意义是第一条直线段可能不在扫描线中 // // fFindStart = 10000.0f; // 这个取值要大于直线方程中可能取到的最大值。 fFindEnd = 0; fValue = -1; if(fabs((float)fV1x) > 0.0001) { ft = (k * 1.0f - Info1.fx) / fV1x; if((ft >= 0)&&(ft <= 1.0)) { fValue = Info1.fz + ft * fV1z; fFindStart = Info1.fz + ft * fV1z; fFindEnd = Info1.fz + ft * fV1z; } } if(fabs((float)fV2x) > 0.0001) { ft = (k * 1.0f - Info2.fx) / fV2x; if((ft >= 0)&&(ft <= 1.0)) { fValue = Info2.fz + ft * fV2z; if(fValue < fFindStart) { fFindStart = fValue; } if(fValue > fFindEnd) { fFindEnd = fValue; } } } if(fabs((float)fV3x) > 0.0001) { ft = (k * 1.0f - Info3.fx) / fV3x; if((ft >= 0)&&(ft <= 1.0)) { fValue = Info3.fz + ft * fV3z; if(fValue < fFindStart) { fFindStart = fValue; } if(fValue > fFindEnd) { fFindEnd = fValue; } } } if(fValue >= 0) { Scanline_info.iStart = (int)(fFindStart) - 1; Scanline_info.iEnd = (int)(fFindEnd) + 1; Scanline_info.iScanLine = (int)k; ScanLineVector.push_back(Scanline_info); } // 循环每一个扫描线结束. }// for(int k = iScanStart; k <= iScanEnd; k++) // 把三角形的三个顶点, 添加到数组 Scanline_info.iStart = (int)(Info1.fz); Scanline_info.iEnd = (int)(Info1.fz); Scanline_info.iScanLine = (int)(Info1.fx); ScanLineVector.push_back(Scanline_info); Scanline_info.iStart = (int)(Info2.fz); Scanline_info.iEnd = (int)(Info2.fz); Scanline_info.iScanLine = (int)(Info2.fx); ScanLineVector.push_back(Scanline_info); Scanline_info.iStart = (int)(Info3.fz); Scanline_info.iEnd = (int)(Info3.fz); Scanline_info.iScanLine = (int)(Info3.fx); ScanLineVector.push_back(Scanline_info); // // 找到所有的扫描线. // // ////////////////////////////////////////////////////////////////////////////////////////////////// // 根据找到的扫描线把三角形注册到地图中。 TRI_INFO_VECTOR newTriInfoVector; for(int j = 0; j < (int)ScanLineVector.size(); j++) { for(int iY = ScanLineVector[j].iStart; iY <= ScanLineVector[j].iEnd; iY++) { point2DKey.iX = ScanLineVector[j].iScanLine; point2DKey.iY = iY; if(m_TriInMapInfoMap.m_triInfoInMap.count(point2DKey)) { m_TriInMapInfoMap.m_triInfoInMap[point2DKey].push_back(tri); } else { newTriInfoVector.clear(); newTriInfoVector.push_back(tri); m_TriInMapInfoMap.m_triInfoInMap[point2DKey] = newTriInfoVector; } } } }// for(int i = 0; i < iFaceCount; i++) }