-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial code drop - migrating from internal repo to GitHub (#1)
Initial commit
- Loading branch information
Showing
73 changed files
with
6,279 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,29 @@ | ||
# Microsoft glTF Toolkit | ||
|
||
# Contributing | ||
This project contains a collection of tools and libraries to modify and optimize glTF assets. | ||
|
||
## Features | ||
|
||
The current release includes code for: | ||
- Packing PBR material textures using [DirectXTex](http://github.com/Microsoft/DirectXTex) for use with the [MSFT_packing_occlusionRoughnessMetallic](https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_packing_occlusionRoughnessMetallic) extension. | ||
- Compressing textures as BC3, BC5 and BC7 and generate mip maps using [DirectXTex](http://github.com/Microsoft/DirectXTex) for use with the [MSFT_texture_dds](https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_texture_dds) extension. | ||
- Merging multiple glTF assets into a asset with multiple levels of detail using the [MSFT_lod](https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod) extension. | ||
|
||
It also includes a command line tool that uses these steps in sequence in order to convert a glTF 2.0 core asset for use in the Windows Mixed Reality home, following the published [documentation](https://developer.microsoft.com/en-us/windows/mixed-reality/creating_3d_models_for_use_in_the_windows_mixed_reality_home). | ||
|
||
## Dependencies | ||
|
||
This project consumes the following projects through NuGet packages: | ||
- Microsoft GLTF SDK, licensed under the MIT license | ||
- [DirectXTex](http://github.com/Microsoft/DirectXTex), licensed under the MIT license | ||
- [RapidJSON](https://github.com/Tencent/rapidjson/), licensed under the MIT license | ||
|
||
|
||
## Building | ||
|
||
This project can be built using Visual Studio 2017 Update 4 on Windows 10 Fall Creators Update (16299.0). | ||
|
||
## Contributing | ||
|
||
This project welcomes contributions and suggestions. Most contributions require you to agree to a | ||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us | ||
|
@@ -12,3 +36,9 @@ provided by the bot. You will only need to do this once across all repos using o | |
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). | ||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or | ||
contact [[email protected]](mailto:[email protected]) with any additional questions or comments. | ||
|
||
## License | ||
|
||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
|
||
Licensed under the [MIT License](LICENSE). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. See LICENSE in the project root for license information. | ||
|
||
#include "stdafx.h" | ||
#include "AssetType.h" | ||
|
||
const wchar_t * EXTENSION_GLTF = L".gltf"; | ||
const wchar_t * EXTENSION_GLB = L".glb"; | ||
|
||
AssetType AssetTypeUtils::AssetTypeFromFilePath(const std::wstring& assetPath) | ||
{ | ||
const wchar_t *inputExtensionRaw = nullptr; | ||
if (FAILED(PathCchFindExtension(assetPath.c_str(), assetPath.length() + 1, &inputExtensionRaw))) | ||
{ | ||
throw std::invalid_argument("Invalid input file extension."); | ||
} | ||
|
||
if (_wcsicmp(inputExtensionRaw, EXTENSION_GLTF) == 0) | ||
{ | ||
return AssetType::GLTF; | ||
} | ||
else if (_wcsicmp(inputExtensionRaw, EXTENSION_GLB) == 0) | ||
{ | ||
return AssetType::GLB; | ||
} | ||
else | ||
{ | ||
throw std::invalid_argument("Invalid file, please provide a GLTF or GLB."); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. See LICENSE in the project root for license information. | ||
|
||
#pragma once | ||
|
||
extern const wchar_t * EXTENSION_GLTF; | ||
extern const wchar_t * EXTENSION_GLB; | ||
|
||
enum class AssetType | ||
{ | ||
GLTF, | ||
GLB | ||
}; | ||
|
||
namespace AssetTypeUtils | ||
{ | ||
AssetType AssetTypeFromFilePath(const std::wstring& assetPath); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. See LICENSE in the project root for license information. | ||
|
||
#include "stdafx.h" | ||
#include "CommandLine.h" | ||
#include "FileSystem.h" | ||
|
||
// Constants | ||
const wchar_t * PARAM_OUTFILE = L"-o"; | ||
const wchar_t * PARAM_TMPDIR = L"-temp-directory"; | ||
const wchar_t * PARAM_LOD = L"-lod"; | ||
const wchar_t * PARAM_SCREENCOVERAGE = L"-screen-coverage"; | ||
const wchar_t * PARAM_MAXTEXTURESIZE = L"-max-texture-size"; | ||
const wchar_t * SUFFIX_CONVERTED = L"_converted"; | ||
const wchar_t * CLI_INDENT = L" "; | ||
const size_t MAXTEXTURESIZE_DEFAULT = 512; | ||
const size_t MAXTEXTURESIZE_MAX = 4096; | ||
|
||
enum class CommandLineParsingState | ||
{ | ||
Initial, | ||
InputRead, | ||
ReadOutFile, | ||
ReadTmpDir, | ||
ReadLods, | ||
ReadScreenCoverage, | ||
ReadMaxTextureSize | ||
}; | ||
|
||
void CommandLine::PrintHelp() | ||
{ | ||
auto indent = std::wstring(CLI_INDENT); | ||
std::wcerr << std::endl | ||
<< L"Windows Mixed Reality Asset Converter" << std::endl | ||
<< L"=====================================" << std::endl | ||
<< std::endl | ||
<< L"A command line tool to convert core GLTF 2.0 assets for use in " | ||
<< L"the Windows Mixed Reality home, with the proper texture packing, compression and merged LODs." << std::endl << std::endl | ||
<< L"Usage: WindowsMRAssetConverter <path to GLTF/GLB>" << std::endl | ||
<< std::endl | ||
<< L"Optional arguments:" << std::endl | ||
<< indent << "[" << std::wstring(PARAM_OUTFILE) << L" <output file path>]" << std::endl | ||
<< indent << "[" << std::wstring(PARAM_TMPDIR) << L" <temporary folder, default is the system temp folder for the user>]" << std::endl | ||
<< indent << "[" << std::wstring(PARAM_LOD) << " <path to each lower LOD asset in descending order of quality>]" << std::endl | ||
<< indent << "[" << std::wstring(PARAM_SCREENCOVERAGE) << " <LOD screen coverage values>]" << std::endl | ||
<< indent << "[" << std::wstring(PARAM_MAXTEXTURESIZE) << " <Max texture size in pixels, defaults to 512>]" << std::endl | ||
<< std::endl | ||
<< "Example:" << std::endl | ||
<< indent << "WindowsMRAssetConverter FileToConvert.gltf " | ||
<< std::wstring(PARAM_OUTFILE) << " ConvertedFile.glb " | ||
<< std::wstring(PARAM_LOD) << " Lod1.gltf Lod2.gltf " | ||
<< std::wstring(PARAM_SCREENCOVERAGE) << " 0.5 0.2 0.01" << std::endl | ||
<< std::endl | ||
<< "The above will convert \"FileToConvert.gltf\" into \"ConvertedFile.glb\" in the " | ||
<< "current directory." << std::endl | ||
<< std::endl | ||
<< "If the file is a GLB and the output name is not specified, defaults to the same name as input " | ||
<< "+ \"_converted.glb\"." << std::endl | ||
<< std::endl; | ||
} | ||
|
||
void CommandLine::ParseCommandLineArguments( | ||
int argc, wchar_t *argv[], | ||
std::wstring& inputFilePath, AssetType& inputAssetType, std::wstring& outFilePath, std::wstring& tempDirectory, | ||
std::vector<std::wstring>& lodFilePaths, std::vector<double>& screenCoveragePercentages, size_t& maxTextureSize) | ||
{ | ||
CommandLineParsingState state = CommandLineParsingState::Initial; | ||
|
||
inputFilePath = FileSystem::GetFullPath(std::wstring(argv[1])); | ||
|
||
inputAssetType = AssetTypeUtils::AssetTypeFromFilePath(inputFilePath); | ||
|
||
// Reset input parameters | ||
outFilePath = L""; | ||
tempDirectory = L""; | ||
lodFilePaths.clear(); | ||
screenCoveragePercentages.clear(); | ||
maxTextureSize = MAXTEXTURESIZE_DEFAULT; | ||
|
||
state = CommandLineParsingState::InputRead; | ||
|
||
std::wstring outFile; | ||
std::wstring tmpDir; | ||
for (int i = 2; i < argc; i++) | ||
{ | ||
std::wstring param = argv[i]; | ||
|
||
if (param == PARAM_OUTFILE) | ||
{ | ||
outFile = L""; | ||
state = CommandLineParsingState::ReadOutFile; | ||
} | ||
else if (param == PARAM_TMPDIR) | ||
{ | ||
tmpDir = L""; | ||
state = CommandLineParsingState::ReadTmpDir; | ||
} | ||
else if (param == PARAM_LOD) | ||
{ | ||
lodFilePaths.clear(); | ||
state = CommandLineParsingState::ReadLods; | ||
} | ||
else if (param == PARAM_SCREENCOVERAGE) | ||
{ | ||
screenCoveragePercentages.clear(); | ||
state = CommandLineParsingState::ReadScreenCoverage; | ||
} | ||
else if (param == PARAM_MAXTEXTURESIZE) | ||
{ | ||
maxTextureSize = MAXTEXTURESIZE_DEFAULT; | ||
state = CommandLineParsingState::ReadMaxTextureSize; | ||
} | ||
else | ||
{ | ||
switch (state) | ||
{ | ||
case CommandLineParsingState::ReadOutFile: | ||
outFile = FileSystem::GetFullPath(param); | ||
state = CommandLineParsingState::InputRead; | ||
break; | ||
case CommandLineParsingState::ReadTmpDir: | ||
tmpDir = FileSystem::GetFullPath(param); | ||
state = CommandLineParsingState::InputRead; | ||
break; | ||
case CommandLineParsingState::ReadLods: | ||
lodFilePaths.push_back(FileSystem::GetFullPath(param)); | ||
break; | ||
case CommandLineParsingState::ReadScreenCoverage: | ||
{ | ||
auto paramA = std::string(param.begin(), param.end()); | ||
screenCoveragePercentages.push_back(std::atof(paramA.c_str())); | ||
break; | ||
} | ||
case CommandLineParsingState::ReadMaxTextureSize: | ||
maxTextureSize = std::min(static_cast<size_t>(std::stoul(param.c_str())), MAXTEXTURESIZE_MAX); | ||
break; | ||
case CommandLineParsingState::Initial: | ||
case CommandLineParsingState::InputRead: | ||
default: | ||
// Invalid argument detected | ||
throw std::invalid_argument("Invalid usage. For help, try the command again without parameters."); | ||
} | ||
} | ||
} | ||
|
||
if (outFile.empty()) | ||
{ | ||
std::wstring inputFilePathWithoutExtension = inputFilePath; | ||
if (FAILED(PathCchRemoveExtension(&inputFilePathWithoutExtension[0], inputFilePathWithoutExtension.length() + 1))) | ||
{ | ||
throw std::invalid_argument("Invalid input file extension."); | ||
} | ||
|
||
outFile = std::wstring(&inputFilePathWithoutExtension[0]); | ||
|
||
if (inputAssetType == AssetType::GLB) | ||
{ | ||
outFile += SUFFIX_CONVERTED; | ||
} | ||
|
||
outFile += EXTENSION_GLB; | ||
} | ||
|
||
outFilePath = outFile; | ||
|
||
if (tmpDir.empty()) | ||
{ | ||
tmpDir = FileSystem::CreateTempFolder(); | ||
} | ||
|
||
tempDirectory = tmpDir; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. See LICENSE in the project root for license information. | ||
|
||
#pragma once | ||
|
||
#include <vector> | ||
#include "AssetType.h" | ||
|
||
namespace CommandLine | ||
{ | ||
void PrintHelp(); | ||
|
||
void ParseCommandLineArguments( | ||
int argc, wchar_t *argv[], | ||
std::wstring& inputFilePath, AssetType& inputAssetType, std::wstring& outFilePath, std::wstring& tempDirectory, | ||
std::vector<std::wstring>& lodFilePaths, std::vector<double>& screenCoveragePercentages, size_t& maxTextureSize); | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. See LICENSE in the project root for license information. | ||
|
||
#include "stdafx.h" | ||
#include "FileSystem.h" | ||
|
||
std::wstring FileSystem::GetBasePath(const std::wstring& path) | ||
{ | ||
std::wstring pathCopy(path); | ||
wchar_t *basePath = &pathCopy[0]; | ||
if (FAILED(PathCchRemoveFileSpec(basePath, pathCopy.length() + 1))) | ||
{ | ||
throw std::invalid_argument("Invalid input path."); | ||
} | ||
|
||
return std::move(std::wstring(basePath)); | ||
} | ||
|
||
|
||
std::wstring FileSystem::GetFullPath(const std::wstring& path) | ||
{ | ||
wchar_t fullPath[MAX_PATH]; | ||
if (GetFullPathName(path.c_str(), ARRAYSIZE(fullPath), fullPath, NULL) == 0) | ||
{ | ||
throw std::invalid_argument("Invalid input file path."); | ||
} | ||
return std::move(std::wstring(fullPath)); | ||
} | ||
|
||
std::wstring FileSystem::CreateSubFolder(const std::wstring& parentPath, const std::wstring& subFolderName) | ||
{ | ||
std::wstring errorMessageW = L"Could not create a sub-folder of " + parentPath + L"."; | ||
std::string errorMessage(errorMessageW.begin(), errorMessageW.end()); | ||
|
||
wchar_t subFolderPath[MAX_PATH]; | ||
if (FAILED(PathCchCombine(subFolderPath, ARRAYSIZE(subFolderPath), parentPath.c_str(), (subFolderName + L"\\").c_str()))) | ||
{ | ||
throw std::runtime_error(errorMessage); | ||
} | ||
|
||
if (CreateDirectory(subFolderPath, NULL) == 0 && GetLastError() != ERROR_ALREADY_EXISTS) | ||
{ | ||
throw std::runtime_error(errorMessage); | ||
} | ||
|
||
return std::move(std::wstring(subFolderPath)); | ||
} | ||
|
||
std::wstring FileSystem::CreateTempFolder() | ||
{ | ||
std::wstring errorMessageW = L"Could not get a temporary folder. Try specifying one in the command line."; | ||
std::string errorMessage(errorMessageW.begin(), errorMessageW.end()); | ||
|
||
wchar_t tmpDirRaw[MAX_PATH]; | ||
auto returnValue = GetTempPath(MAX_PATH, tmpDirRaw); | ||
if (returnValue > MAX_PATH || (returnValue == 0)) | ||
{ | ||
throw std::runtime_error(errorMessage); | ||
} | ||
|
||
// Get a random folder to drop the files | ||
GUID guid = { 0 }; | ||
if (FAILED(CoCreateGuid(&guid))) | ||
{ | ||
throw std::runtime_error(errorMessage); | ||
} | ||
|
||
wchar_t guidRaw[MAX_PATH]; | ||
if (StringFromGUID2(guid, guidRaw, ARRAYSIZE(guidRaw)) == 0) | ||
{ | ||
throw std::runtime_error(errorMessage); | ||
} | ||
|
||
return std::move(CreateSubFolder(tmpDirRaw, guidRaw)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. See LICENSE in the project root for license information. | ||
|
||
#pragma once | ||
|
||
namespace FileSystem | ||
{ | ||
std::wstring GetBasePath(const std::wstring& path); | ||
std::wstring GetFullPath(const std::wstring& path); | ||
std::wstring CreateSubFolder(const std::wstring& parentPath, const std::wstring& subFolderName); | ||
std::wstring CreateTempFolder(); | ||
}; | ||
|
Oops, something went wrong.