void GetBoneStructureRoots(RootNode *rootNodes, uint32_t count, BoneStructureRoot *boneStructureRoots, FILE *datFile) {
    assert(datFile != NULL);
    for (int i = 0; i < count; ++i)
    {
        RootNode *rootNode = &rootNodes[i];
        fseek(datFile, rootNode->dataOffset+DATA_BLOCK, SEEK_SET);
        BoneStructureRoot *boneStructureRoot = &boneStructureRoots[i];

        fread(&boneStructureRoot->stringOffset, sizeof(boneStructureRoot->stringOffset), 1, datFile);
        fread(&boneStructureRoot->unknownFlags, sizeof(boneStructureRoot->unknownFlags), 1, datFile);
        fread(&boneStructureRoot->childBoneStructOffset, sizeof(boneStructureRoot->childBoneStructOffset), 1, datFile);
        fread(&boneStructureRoot->nextBoneStructOffset, sizeof(boneStructureRoot->nextBoneStructOffset), 1, datFile);
        fread(&boneStructureRoot->objectStructOffset, sizeof(boneStructureRoot->objectStructOffset), 1, datFile);
        fread(&boneStructureRoot->rotation_x, sizeof(boneStructureRoot->rotation_x), 1, datFile);
        fread(&boneStructureRoot->rotation_y, sizeof(boneStructureRoot->rotation_y), 1, datFile);
        fread(&boneStructureRoot->rotation_z, sizeof(boneStructureRoot->rotation_z), 1, datFile);
        fread(&boneStructureRoot->scale_x, sizeof(boneStructureRoot->scale_x), 1, datFile);
        fread(&boneStructureRoot->scale_y, sizeof(boneStructureRoot->scale_y), 1, datFile);
        fread(&boneStructureRoot->scale_z, sizeof(boneStructureRoot->scale_z), 1, datFile);
        fread(&boneStructureRoot->location_x, sizeof(boneStructureRoot->location_x), 1, datFile);
        fread(&boneStructureRoot->location_y, sizeof(boneStructureRoot->location_y), 1, datFile);
        fread(&boneStructureRoot->location_z, sizeof(boneStructureRoot->location_z), 1, datFile);
        fread(&boneStructureRoot->inverseBindMatrixOffset, sizeof(boneStructureRoot->inverseBindMatrixOffset), 1, datFile);
        fread(&boneStructureRoot->pointerUnknown, sizeof(boneStructureRoot->pointerUnknown), 1, datFile);
        
        boneStructureRoot->stringOffset=byteswap32(boneStructureRoot->stringOffset);
        boneStructureRoot->unknownFlags=byteswap32(boneStructureRoot->unknownFlags);
        boneStructureRoot->childBoneStructOffset=byteswap32(boneStructureRoot->childBoneStructOffset);
        boneStructureRoot->nextBoneStructOffset=byteswap32(boneStructureRoot->nextBoneStructOffset);
        boneStructureRoot->objectStructOffset=byteswap32(boneStructureRoot->objectStructOffset);
        float tempFloat;
        tempFloat = boneStructureRoot->rotation_x;
        boneStructureRoot->rotation_x = floatSwap(tempFloat);
        tempFloat = boneStructureRoot->rotation_y;
        boneStructureRoot->rotation_y = floatSwap(tempFloat);
        tempFloat = boneStructureRoot->rotation_z;
        boneStructureRoot->rotation_z = floatSwap(tempFloat);
        tempFloat = boneStructureRoot->scale_x;
        boneStructureRoot->scale_x = floatSwap(tempFloat);
        tempFloat = boneStructureRoot->scale_y;
        boneStructureRoot->scale_y = floatSwap(tempFloat);
        tempFloat = boneStructureRoot->scale_z;
        boneStructureRoot->scale_z = floatSwap(tempFloat);
        tempFloat = boneStructureRoot->location_x;
        boneStructureRoot->location_x = floatSwap(tempFloat);
        tempFloat = boneStructureRoot->location_y;
        boneStructureRoot->location_y = floatSwap(tempFloat);
        tempFloat = boneStructureRoot->location_z;
        boneStructureRoot->location_z = floatSwap(tempFloat);
        boneStructureRoot->inverseBindMatrixOffset=byteswap32(boneStructureRoot->inverseBindMatrixOffset);
        boneStructureRoot->pointerUnknown=byteswap32(boneStructureRoot->pointerUnknown);
    }
}
bool CFaceModel::LoadLandmarks(const std::string &filename, std::vector<float3> &outList, int formatVersion)
{
	char line[1024];
	
	FILE *file = fopen(filename.c_str(), "r");

	if (file == NULL)
		return false;
	
	char toRemove[] = { '\t', ' ', '{', '}', '[', ']', '\"', '\n', ',', 'x', 'y', 'z' };
	const char *toRemoveStrings[] = { "Name", "Confidence", "Position" };
	while (fgets(line, sizeof(line), file))
	{
		bool hasConfidence = strstr(line, "Confidence") != NULL;
		for (int i = 0; i < ARRAYSIZE(toRemoveStrings); i++)
		{
			char *loc = line;
			while (loc = strstr(loc, toRemoveStrings[i]))
			{
				int toRemoveLen = (int)strlen(toRemoveStrings[i]);
				memmove(loc, loc + toRemoveLen, 1 + strlen(loc + toRemoveLen));
			}
		}
		{
			int writeLoc = 0;
			char sLine[1024];
			
			for (int i = 0; i < 1024 && line[i] != 0; i++)
			{
				char c = line[i];
				bool skip = false;
				for (int j = 0; j < ARRAYSIZE(toRemove); j++)
				{
					if (toRemove[j] == c)
						skip = true;
				}
				if (c == ':')
					c = ' ';
				if (!skip)
					sLine[writeLoc++] = c;
			}
			sLine[writeLoc] = 0;

			char landmarkName[256];
			float3 pos;
			int confidence = 100;
			bool scanValid = true;
			if (hasConfidence)
			{
				int result = sscanf_s(sLine, "%s %d %f %f %f", landmarkName, sizeof(landmarkName), &confidence, &pos.x, &pos.y, &pos.z);
				scanValid = result == 5;
			}
			else
			{
				int result = sscanf_s(sLine, "%s %f %f %f", landmarkName, sizeof(landmarkName), &pos.x, &pos.y, &pos.z);
				scanValid = result == 4;
			}
			
			if (scanValid)
			{
				pos += mVertOffset;
				pos *= mVertScale;
				floatSwap(&pos.y, &pos.z);
				outList.push_back(pos);
			}
		}
	}
	fclose(file);
	
	FlagUpdated();

	return outList.size() != 0;
}