void CCOLEntry::parseCollisionMeshFaces(void) { CDataReader *pDataReader = CDataReader::getInstance(); eCOLVersion eCOLVersionValue = getCOLVersion() == nullptr ? COL_UNKNOWN : getCOLVersion()->getVersionId(); vector<TFace>& vecFaces = getCollisionMeshFaces(); for (uint32 i = 0, j = getCollisionMeshFaceCount(); i < j; i++) { TFace face; if (eCOLVersionValue == COL_1) { face.m_uiA = pDataReader->readUint32(); face.m_uiB = pDataReader->readUint32(); face.m_uiC = pDataReader->readUint32(); face.m_surface.m_ucMaterial = pDataReader->readUint8(); face.m_surface.m_ucFlag = pDataReader->readUint8(); face.m_surface.m_ucBrightness = pDataReader->readUint8(); face.m_surface.m_ucLight = pDataReader->readUint8(); } else { face.m_uiA = pDataReader->readUint16(); face.m_uiB = pDataReader->readUint16(); face.m_uiC = pDataReader->readUint16(); face.m_surface.m_ucMaterial = pDataReader->readUint8(); face.m_surface.m_ucFlag = 0; face.m_surface.m_ucBrightness = 0; face.m_surface.m_ucLight = pDataReader->readUint8(); } vecFaces.push_back(face); } }
void CRWSection_Texture::unserialize(void) { CDataReader *pDataReader = CDataReader::getInstance(); m_usFilterFlags = pDataReader->readUint16(); m_usUnknown1 = pDataReader->readUint16(); }
void CCOLEntry::parseShadowMeshFaces(void) { CDataReader *pDataReader = CDataReader::getInstance(); vector<TFace>& vecFaces = getShadowMeshFaces(); for (uint32 i = 0, j = getShadowMeshFaceCount(); i < j; i++) { TFace face; face.m_uiA = pDataReader->readUint16(); face.m_uiB = pDataReader->readUint16(); face.m_uiC = pDataReader->readUint16(); face.m_surface.m_ucMaterial = pDataReader->readUint8(); face.m_surface.m_ucFlag = 0; face.m_surface.m_ucBrightness = 0; face.m_surface.m_ucLight = pDataReader->readUint8(); vecFaces.push_back(face); } }
void CCOLEntry::parseCollisionMeshFaceGroups(void) { CDataReader *pDataReader = CDataReader::getInstance(); vector<TFaceGroup>& vecFaceGroups = getCollisionMeshFaceGroups(); for (uint32 i = 0, j = getCollisionMeshFaceGroupCount(); i < j; i++) { TFaceGroup faceGroup; faceGroup.m_min.m_x = pDataReader->readFloat32(); faceGroup.m_min.m_y = pDataReader->readFloat32(); faceGroup.m_min.m_z = pDataReader->readFloat32(); faceGroup.m_max.m_x = pDataReader->readFloat32(); faceGroup.m_max.m_y = pDataReader->readFloat32(); faceGroup.m_max.m_z = pDataReader->readFloat32(); faceGroup.m_startFace = pDataReader->readUint16(); faceGroup.m_endFace = pDataReader->readUint16(); vecFaceGroups.push_back(faceGroup); } }
void CDATPathFormat::unserializeFastman92(void) { CDataReader *pDataReader = CDataReader::getInstance(); m_uiFileIndex = 0; // uiAreaId; //uint32 uiSeek = 0; //uint32 uiSize; m_header.m_ePathsFormat = DAT_PATH_FASTMAN92; uint32 uiFourCC = pDataReader->readUint32(); // 0xFFFFFFFF string strFormat = pDataReader->readString(4); // FM92 uint8 ucNicknameLength = pDataReader->readUint8(); string strNickname = pDataReader->readString(ucNicknameLength); uint32 uiFormatVersion = pDataReader->readUint32(); m_header.m_uiPathNodeCount = pDataReader->readUint32(); m_header.m_uiVehicleNodeCount = pDataReader->readUint32(); m_header.m_uiPedNodeCount = pDataReader->readUint32(); m_header.m_uiNaviNodeCount = pDataReader->readUint32(); m_header.m_uiLinkCount = pDataReader->readUint32(); //uiSize = pDataReader->getByteCountRead(); //uiSeek += uiSize; m_vecPathNodes.resize(m_header.m_uiPathNodeCount); m_vecNaviNodes.resize(m_header.m_uiNaviNodeCount); m_vecLinks.resize(m_header.m_uiLinkCount); CDATEntry_Paths_Fastman92_PathNode_extended *pPathNodes = new CDATEntry_Paths_Fastman92_PathNode_extended[m_header.m_uiPathNodeCount]; CDATEntry_Paths_Fastman92_NaviNode_extended *pNaviNodes = new CDATEntry_Paths_Fastman92_NaviNode_extended[m_header.m_uiNaviNodeCount]; CDATEntry_Paths_Fastman92_Link *pLinks = new CDATEntry_Paths_Fastman92_Link[m_header.m_uiLinkCount]; CDATEntry_Paths_Fastman92_NaviLink *pNaviLinks = new CDATEntry_Paths_Fastman92_NaviLink[m_header.m_uiLinkCount]; CDATEntry_Paths_Fastman92_LinkLength *pLinkLengths = new CDATEntry_Paths_Fastman92_LinkLength[m_header.m_uiLinkCount]; CDATEntry_Paths_Fastman92_PathIntersectionFlags *pPathIntersectionFlags = new CDATEntry_Paths_Fastman92_PathIntersectionFlags[m_header.m_uiLinkCount]; /* uiSize = pDATFile_Paths->m_header.m_uiPathNodeCount * 40; memcpy(pPathNodes, strFileData.c_str() + uiSeek, uiSize); uiSeek += uiSize; uiSize = pDATFile_Paths->m_header.m_uiNaviNodeCount * 22; memcpy(pNaviNodes, strFileData.c_str() + uiSeek, uiSize); uiSeek += uiSize; uiSize = pDATFile_Paths->m_header.m_uiLinkCount * 4; memcpy(pLinks, strFileData.c_str() + uiSeek, uiSize); uiSeek += uiSize; uiSeek += 768; uiSize = pDATFile_Paths->m_header.m_uiLinkCount * 4; memcpy(pNaviLinks, strFileData.c_str() + uiSeek, uiSize); uiSeek += uiSize; uiSize = pDATFile_Paths->m_header.m_uiLinkCount * 1; memcpy(pLinkLengths, strFileData.c_str() + uiSeek, uiSize); uiSeek += uiSize; */ for (uint32 i = 0, j = m_header.m_uiPathNodeCount; i < j; i++) { CDATEntry_Paths_Fastman92_PathNode_extended *pPathNode_Fastman92 = pPathNodes + i; pPathNode_Fastman92->m_pPrev = 0; pDataReader->readUint32(); pPathNode_Fastman92->m_ppNext = 0; pDataReader->readUint32(); pPathNode_Fastman92->m_posn.x = pDataReader->readUint16(); pPathNode_Fastman92->m_posn.y = pDataReader->readUint16(); pPathNode_Fastman92->m_posn.z = pDataReader->readUint16(); pPathNode_Fastman92->m_wSearchList = pDataReader->readUint16(); pPathNode_Fastman92->m_wConnectedNodesStartId = pDataReader->readUint16(); pPathNode_Fastman92->m_wAreaId = pDataReader->readUint16(); pPathNode_Fastman92->m_wNodeId = pDataReader->readUint16(); pPathNode_Fastman92->m_nPathWidth = pDataReader->readUint8(); pPathNode_Fastman92->m_nNodeType = pDataReader->readUint8(); pPathNode_Fastman92->m_dwFlags = pDataReader->readUint32(); pPathNode_Fastman92->m_extended_posn.x = pDataReader->readUint32(); pPathNode_Fastman92->m_extended_posn.y = pDataReader->readUint32(); pPathNode_Fastman92->m_extended_posn.z = pDataReader->readUint32(); } for (uint32 i = 0, j = m_header.m_uiNaviNodeCount; i < j; i++) { CDATEntry_Paths_Fastman92_NaviNode_extended *pNaviNode_Fastman92 = pNaviNodes + i; pNaviNode_Fastman92->posX = pDataReader->readUint16(); pNaviNode_Fastman92->posY = pDataReader->readUint16(); pNaviNode_Fastman92->info.areaId = pDataReader->readUint16(); pNaviNode_Fastman92->info.nodeId = pDataReader->readUint16(); pNaviNode_Fastman92->dirX = pDataReader->readUint8(); pNaviNode_Fastman92->dirY = pDataReader->readUint8(); pNaviNode_Fastman92->m_dwFlags = pDataReader->readUint32(); pNaviNode_Fastman92->extended_posX = pDataReader->readUint32(); pNaviNode_Fastman92->extended_posY = pDataReader->readUint32(); } for (uint32 i = 0, j = m_header.m_uiLinkCount; i < j; i++) { CDATEntry_Paths_Fastman92_Link *pLink_Fastman92 = pLinks + i; pLink_Fastman92->m_usAreaId = pDataReader->readUint16(); pLink_Fastman92->m_usNodeId = pDataReader->readUint16(); } if (m_header.m_uiLinkCount > 0) { string strFiller1 = pDataReader->readString(768); } for (uint32 i = 0, j = m_header.m_uiLinkCount; i < j; i++) { CDATEntry_Paths_Fastman92_NaviLink *pNaviLink_Fastman92 = pNaviLinks + i; pNaviLink_Fastman92->m_uiData = pDataReader->readUint32(); } for (uint32 i = 0, j = m_header.m_uiLinkCount; i < j; i++) { CDATEntry_Paths_Fastman92_LinkLength *pLinkLength_Fastman92 = pLinkLengths + i; pLinkLength_Fastman92->m_ucLength = pDataReader->readUint8(); } for (uint32 i = 0, j = m_header.m_uiLinkCount; i < j; i++) { CDATEntry_Paths_Fastman92_PathIntersectionFlags *pPathIntersectionFlags_Fastman92 = pPathIntersectionFlags + i; uint8 ucByte = pDataReader->readUint8(); //pPathIntersectionFlags_Fastman92->m_bRoadCross = ucByte & 1; //pPathIntersectionFlags_Fastman92->m_bPedTrafficLight = ucByte & 2; pPathIntersectionFlags_Fastman92->m_ucData = ucByte; } if (m_header.m_uiLinkCount > 0) { string strFiller2 = pDataReader->readString(192); } if (m_header.m_uiLinkCount > 0) { string strFiller3 = pDataReader->readString(192); } string strEOF = pDataReader->readString(4); // //if (strEOF.substr(0, 3) != "EOF") //{ //CDebugger::log("PARSER FAILED on index " + CStringUtility::toString(pDATFile_Paths->m_uiFileIndex) + ", bytes read: " + CStringUtility::toString(pDataReader->getByteCountRead())); //} // // -- for (uint32 i = 0, j = m_header.m_uiPathNodeCount; i < j; i++) { CDATEntry_Paths_Fastman92_PathNode_extended &pPathNode_Fastman92 = *(pPathNodes + i); CDATEntry_Paths_General_PathNode &pPathNode_General = m_vecPathNodes[i]; pPathNode_General.m_bIsVehiclePathNode = i < m_header.m_uiVehicleNodeCount; pPathNode_General.m_pPrev = 0; pPathNode_General.m_ppNext = 0; pPathNode_General.m_vecPosition.x = pPathNode_Fastman92.m_extended_posn.x; pPathNode_General.m_vecPosition.y = pPathNode_Fastman92.m_extended_posn.y; pPathNode_General.m_vecPosition.z = pPathNode_Fastman92.m_extended_posn.z; pPathNode_General.m_wSearchList = pPathNode_Fastman92.m_wSearchList; pPathNode_General.m_wConnectedNodesStartId = pPathNode_Fastman92.m_wConnectedNodesStartId; pPathNode_General.m_wAreaId = pPathNode_Fastman92.m_wAreaId; pPathNode_General.m_wNodeId = pPathNode_Fastman92.m_wNodeId; pPathNode_General.m_ucPathWidth = pPathNode_Fastman92.m_nPathWidth; pPathNode_General.m_ucNodeType = pPathNode_Fastman92.m_nNodeType; pPathNode_General.m_uiFlags = pPathNode_Fastman92.m_dwFlags; } for (uint32 i = 0, j = m_header.m_uiNaviNodeCount; i < j; i++) { CDATEntry_Paths_Fastman92_NaviNode_extended &pNaviNode_Fastman92 = *(pNaviNodes + i); CDATEntry_Paths_General_NaviNode &pNaviNode_General = m_vecNaviNodes[i]; pNaviNode_General.m_iPosition[0] = pNaviNode_Fastman92.extended_posX; pNaviNode_General.m_iPosition[1] = pNaviNode_Fastman92.extended_posY; pNaviNode_General.m_usTargetNode_AreaId = pNaviNode_Fastman92.info.areaId; pNaviNode_General.m_usTargetNode_NodeId = pNaviNode_Fastman92.info.nodeId; pNaviNode_General.m_ucDirection[0] = pNaviNode_Fastman92.dirX; pNaviNode_General.m_ucDirection[1] = pNaviNode_Fastman92.dirY; pNaviNode_General.m_uiFlags = pNaviNode_Fastman92.m_dwFlags; } for (uint32 i = 0, j = m_header.m_uiLinkCount; i < j; i++) { CDATEntry_Paths_Fastman92_Link &pLink_Fastman92 = *(pLinks + i); CDATEntry_Paths_Fastman92_NaviLink &pNaviLink_Fastman92 = *(pNaviLinks + i); CDATEntry_Paths_Fastman92_LinkLength &pLinkLength_Fastman92 = *(pLinkLengths + i); CDATEntry_Paths_Fastman92_PathIntersectionFlags &pPathIntersectionFlags_Fastman92 = *(pPathIntersectionFlags + i); CDATEntry_Paths_General_Link &pLink_General = m_vecLinks[i]; pLink_General.m_usAreaId = pLink_Fastman92.m_usAreaId; pLink_General.m_usNodeId = pLink_Fastman92.m_usNodeId; pLink_General.m_usNaviNodeId = pNaviLink_Fastman92.m_uiData & 0xFFFF; // lower 16 bits pLink_General.m_usNaviAreaId = (pNaviLink_Fastman92.m_uiData >> 16) & 0xFFFF; // upper 16 bits pLink_General.m_ucLength = pLinkLength_Fastman92.m_ucLength; uint8 ucByte = 0; //ucByte |= pPathIntersectionFlags_Fastman92.m_bRoadCross ? 1 : 0; //ucByte |= pPathIntersectionFlags_Fastman92.m_bPedTrafficLight ? 2 : 0; pLink_General.m_ucPathIntersectionFlags = pPathIntersectionFlags_Fastman92.m_ucData; } /* // debug for (auto& pathNode : m_vecPathNodes) { CDebugger::log( "[path node]" + string(" position: ") + CStringUtility::toString((float32)((float32)pathNode.m_vecPosition.x / 8.0)) + " " + CStringUtility::toString((float32)((float32)pathNode.m_vecPosition.y / 8.0)) + " " + CStringUtility::toString((float32)((float32)pathNode.m_vecPosition.z / 8.0)) + " " + " search list: " + CStringUtility::toString(pathNode.m_wSearchList) + " first link id: " + CStringUtility::toString(pathNode.m_wConnectedNodesStartId) + " area id: " + CStringUtility::toString(pathNode.m_wAreaId) + " node id: " + CStringUtility::toString(pathNode.m_wNodeId) + " path width: " + CStringUtility::toString(pathNode.m_ucPathWidth) + " node type: " + CStringUtility::toString(pathNode.m_ucNodeType) + " flags: " + CStringUtility::toString(pathNode.m_uiFlags) ); } for (auto& naviNode : m_vecNaviNodes) { CDebugger::log( "[navi node]" + string(" position: ") + CStringUtility::toString((float32)((float32)naviNode.m_iPosition[0] / 8.0)) + " " + CStringUtility::toString((float32)((float32)naviNode.m_iPosition[1] / 8.0)) + " " + " area id: " + CStringUtility::toString(naviNode.m_usTargetNode_AreaId) + " node id: " + CStringUtility::toString(naviNode.m_usTargetNode_NodeId) + " direction x: " + CStringUtility::toString(naviNode.m_ucDirection[0]) + " direction y " + CStringUtility::toString(naviNode.m_ucDirection[1]) + " flags: " + CStringUtility::toString(naviNode.m_uiFlags) ); } */ // clean up delete[] pPathNodes; delete[] pNaviNodes; delete[] pLinks; delete[] pNaviLinks; delete[] pLinkLengths; delete[] pPathIntersectionFlags; }
void CCOLEntry::unserialize(void) { CDataReader *pDataReader = CDataReader::getInstance(); uint32 uiHeaderStartPosition = pDataReader->getSeek(); setHeaderStartOffset(uiHeaderStartPosition); // COL 1 2 3 & 4 header setCOLVersion(CCOLManager::getCOLVersionFromFourCC(pDataReader->readString(4))); if (getCOLVersion() == nullptr) { throw EXCEPTION_UNKNOWN_FORMAT; } uint32 uiEntrySize = pDataReader->readUint32(); // entry size from after this value setModelName(CStringUtility::rtrimFromLeft(pDataReader->readString(22))); setModelId(pDataReader->readUint16()); parseBoundingObjects(); eCOLVersion eCOLVersionValue = getCOLVersion() == nullptr ? COL_UNKNOWN : getCOLVersion()->getVersionId(); if (eCOLVersionValue == COL_1) { // COL 1 header & body // read collision sphere count setCollisionSphereCount(pDataReader->readUint32()); // read collision spheres array setCollisionSpheresOffset(pDataReader->getSeek()); parseCollisionSpheres(); // read unknown1 count setUnknown1(pDataReader->readUint32()); // number of unknown data (0) // read collision box count setCollisionBoxCount(pDataReader->readUint32()); // read collision boxes array setCollisionBoxesOffset(pDataReader->getSeek()); parseCollisionBoxes(); // read collision mesh vertex count setCollisionMeshVertexCount(pDataReader->readUint32()); // read collision mesh vertices array setCollisionMeshVerticesOffset(pDataReader->getSeek()); parseCollisionMeshVertices(); // read collision mesh face count setCollisionMeshFaceCount(pDataReader->readUint32()); // read collision mesh faces array setCollisionMeshFacesOffset(pDataReader->getSeek()); parseCollisionMeshFaces(); } else { // COL 2 3 & 4 header setCollisionSphereCount(pDataReader->readUint16()); setCollisionBoxCount(pDataReader->readUint16()); setCollisionMeshFaceCount(pDataReader->readUint16()); setCollisionConeCount(pDataReader->readUint8()); uint8 ucPadding1 = pDataReader->readUint8(); // 1 byte padding setFlags(pDataReader->readUint32()); setCollisionSpheresOffset(pDataReader->readUint32()); setCollisionBoxesOffset(pDataReader->readUint32()); setCollisionConesOffset(pDataReader->readUint32()); setCollisionMeshVerticesOffset(pDataReader->readUint32()); setCollisionMeshFacesOffset(pDataReader->readUint32()); setTrianglePlanesOffset(pDataReader->readUint32()); if ((getFlags() & 8) != 0) { // entry does have face groups uint32 uiCurrentSeek = pDataReader->getSeek(); // read face group count uint32 uiFaceGroupCountSeek = (getHeaderStartOffset() + 4 + getCollisionMeshFacesOffset()) - 4; pDataReader->setSeek(uiFaceGroupCountSeek); setCollisionMeshFaceGroupCount(pDataReader->readUint32()); // read face groups offset setCollisionMeshFaceGroupsOffset((getCollisionMeshFacesOffset() - 4) - (28 * getCollisionMeshFaceGroupCount())); // 28 = sizeof(TFaceGroup) // restore parser seek position pDataReader->setSeek(uiCurrentSeek); } else { // entry does not have face groups setCollisionMeshFaceGroupCount(0); setCollisionMeshFaceGroupsOffset(0); } if (eCOLVersionValue == COL_3 || eCOLVersionValue == COL_4) { // COL 3 & 4 header setShadowMeshFaceCount(pDataReader->readUint32()); setShadowMeshVerticesOffset(pDataReader->readUint32()); setShadowMeshFacesOffset(pDataReader->readUint32()); if (eCOLVersionValue == COL_4) { // COL 4 header setUnknown1(pDataReader->readUint32()); } } // calculate vertex counts // COL 2 3 & 4 uint32 uiCollisionMeshVertexCount = calculateCollisionMeshVertexCount(); setCollisionMeshVertexCount(uiCollisionMeshVertexCount); if (eCOLVersionValue == COL_3 || eCOLVersionValue == COL_4) { // COL 3 & 4 uint32 uiShadowMeshVertexCount = calculateShadowMeshVertexCount(); setShadowMeshVertexCount(uiShadowMeshVertexCount); } // COL 2 3 & 4 body pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionSpheresOffset()); parseCollisionSpheres(); pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionBoxesOffset()); parseCollisionBoxes(); pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionMeshVerticesOffset()); parseCollisionMeshVertices(); pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionMeshFaceGroupsOffset()); parseCollisionMeshFaceGroups(); pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionMeshFacesOffset()); parseCollisionMeshFaces(); if (eCOLVersionValue == COL_3 || eCOLVersionValue == COL_4) { // COL 3 & 4 body pDataReader->setSeek(getHeaderStartOffset() + 4 + getShadowMeshVerticesOffset()); parseShadowMeshVertices(); pDataReader->setSeek(getHeaderStartOffset() + 4 + getShadowMeshFacesOffset()); parseShadowMeshFaces(); } } if (!pDataReader->canSeekTo(getHeaderStartOffset() + uiEntrySize + 8)) { // EOF return; } pDataReader->setSeek(getHeaderStartOffset() + uiEntrySize + 8); }
void CRWSection_Geometry::unserialize(void) { CDataReader *pDataReader = CDataReader::getInstance(); m_usFlags = pDataReader->readUint16(); m_ucUVCoordinateCount = pDataReader->readUint8(); if (m_usFlags & 4) { m_ucUVCoordinateCount = 1; } m_ucGeometryNativeFlags = pDataReader->readUint8(); m_uiTriangleCount = pDataReader->readUint32(); m_uiVertexCount = pDataReader->readUint32(); m_uiFrameCount = pDataReader->readUint32(); if (m_uiSectionRWVersion < 0x1003FFFF) { m_uiAmbientColour = pDataReader->readUint32(); m_uiDiffuseColour = pDataReader->readUint32(); m_uiSpecularColour = pDataReader->readUint32(); } else { m_uiAmbientColour = 1; m_uiDiffuseColour = 1; m_uiSpecularColour = 1; } if (!m_ucGeometryNativeFlags) { if (m_usFlags & 8) { m_vecVertexColours = pDataReader->readVector4ui8ArrayAsStdVector(m_uiVertexCount); } if (m_usFlags & 4) { m_vecTextureCoordinates = pDataReader->readVector2DArrayAsStdVector(m_uiVertexCount); } if (m_usFlags & 128) { for (uint32 i = 0, j = m_ucUVCoordinateCount; i < j; i++) { m_vecTextureCoordinates = pDataReader->readVector2DArrayAsStdVector(m_uiVertexCount); } } m_vecVertexIndices = pDataReader->readVector4ui16ArrayAsStdVector(m_uiTriangleCount); } m_boundingInfo.setCenter(pDataReader->readVector3D()); m_boundingInfo.setCenterRadius(pDataReader->readFloat32()); m_boundingInfo.setHasPosition(pDataReader->readUint32() != 0); m_boundingInfo.setHasNormals(pDataReader->readUint32() != 0); if (!m_ucGeometryNativeFlags) { if ((m_usFlags & 2) || m_boundingInfo.doesHavePosition() /* || true */) { m_vecTextureCoordinates = pDataReader->readVector2DArrayAsStdVector(m_uiVertexCount); // todo - store multiple texture coordinates so data loss doesn't occur } if ((m_usFlags & 16) || m_boundingInfo.doesHaveNormals()) { m_vecVertexNormals = pDataReader->readVector3DArrayAsStdVector(m_uiVertexCount); } } }