------------------------------------------------------------------------------------------------ Imports the given file into the given scene structure.
| 96 | // ------------------------------------------------------------------------------------------------ |
| 97 | // Imports the given file into the given scene structure. |
| 98 | void TerragenImporter::InternReadFile(const std::string &pFile, |
| 99 | aiScene *pScene, IOSystem *pIOHandler) { |
| 100 | IOStream *file = pIOHandler->Open(pFile, "rb"); |
| 101 | |
| 102 | // Check whether we can read from the file |
| 103 | if (file == nullptr) |
| 104 | throw DeadlyImportError("Failed to open TERRAGEN TERRAIN file ", pFile, "."); |
| 105 | |
| 106 | // Construct a stream reader to read all data in the correct endianness |
| 107 | StreamReaderLE reader(file); |
| 108 | if (reader.GetRemainingSize() < 16) |
| 109 | throw DeadlyImportError("TER: file is too small"); |
| 110 | |
| 111 | // Check for the existence of the two magic strings 'TERRAGEN' and 'TERRAIN ' |
| 112 | if (::strncmp((const char *)reader.GetPtr(), AI_TERR_BASE_STRING, 8)) |
| 113 | throw DeadlyImportError("TER: Magic string \'TERRAGEN\' not found"); |
| 114 | |
| 115 | if (::strncmp((const char *)reader.GetPtr() + 8, AI_TERR_TERRAIN_STRING, 8)) |
| 116 | throw DeadlyImportError("TER: Magic string \'TERRAIN\' not found"); |
| 117 | |
| 118 | unsigned int x = 0, y = 0, mode = 0; |
| 119 | |
| 120 | aiNode *root = pScene->mRootNode = new aiNode(); |
| 121 | root->mName.Set("<TERRAGEN.TERRAIN>"); |
| 122 | |
| 123 | // Default scaling is 30 |
| 124 | root->mTransformation.a1 = root->mTransformation.b2 = root->mTransformation.c3 = 30.f; |
| 125 | |
| 126 | // Now read all chunks until we're finished or an EOF marker is encountered |
| 127 | reader.IncPtr(16); |
| 128 | while (reader.GetRemainingSize() >= 4) { |
| 129 | const char *head = (const char *)reader.GetPtr(); |
| 130 | reader.IncPtr(4); |
| 131 | |
| 132 | // EOF, break in every case |
| 133 | if (!::strncmp(head, AI_TERR_EOF_STRING, 4)) |
| 134 | break; |
| 135 | |
| 136 | // Number of x-data points |
| 137 | if (!::strncmp(head, AI_TERR_CHUNK_XPTS, 4)) { |
| 138 | x = (uint16_t)reader.GetI2(); |
| 139 | } |
| 140 | // Number of y-data points |
| 141 | else if (!::strncmp(head, AI_TERR_CHUNK_YPTS, 4)) { |
| 142 | y = (uint16_t)reader.GetI2(); |
| 143 | } |
| 144 | // Squared terrains width-1. |
| 145 | else if (!::strncmp(head, AI_TERR_CHUNK_SIZE, 4)) { |
| 146 | x = y = (uint16_t)reader.GetI2() + 1; |
| 147 | } |
| 148 | // terrain scaling |
| 149 | else if (!::strncmp(head, AI_TERR_CHUNK_SCAL, 4)) { |
| 150 | root->mTransformation.a1 = reader.GetF4(); |
| 151 | root->mTransformation.b2 = reader.GetF4(); |
| 152 | root->mTransformation.c3 = reader.GetF4(); |
| 153 | } |
| 154 | // mapping == 1: earth radius |
| 155 | else if (!::strncmp(head, AI_TERR_CHUNK_CRAD, 4)) { |
nothing calls this directly
no test coverage detected