Initial copy from internal repository.

This commit is contained in:
Adam Gritt 2018-05-16 17:53:21 -07:00
Родитель 55bea33d6b
Коммит e061a37d75
238 изменённых файлов: 38513 добавлений и 0 удалений

6
.gitignore поставляемый
Просмотреть файл

@ -328,3 +328,9 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# glTF-SDK ignores
Built/
# VS Code
.vscode/

Просмотреть файл

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.9)
if (NOT GLTFSDK_FOUND)
set(GLTFSDK_FOUND TRUE)
add_library(GLTFSDK STATIC IMPORTED GLOBAL)
set_target_properties(GLTFSDK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/build/native/include")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/arm64-v8a/Debug/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/arm64-v8a/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/arm64-v8a/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_MINSIZEREL "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/arm64-v8a/Release/static/libGLTFSDK.a")
# Default location for other build configurations defaults to Debug
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/arm64-v8a/Debug/static/libGLTFSDK.a")
endif()

Просмотреть файл

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.9)
if (NOT GLTFSDK_FOUND)
set(GLTFSDK_FOUND TRUE)
add_library(GLTFSDK STATIC IMPORTED GLOBAL)
set_target_properties(GLTFSDK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/build/native/include")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/armeabi-v7a/Debug/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/armeabi-v7a/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/armeabi-v7a/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_MINSIZEREL "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/armeabi-v7a/Release/static/libGLTFSDK.a")
# Default location for other build configurations defaults to Debug
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/armeabi-v7a/Debug/static/libGLTFSDK.a")
endif()

Просмотреть файл

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.9)
if (NOT GLTFSDK_FOUND)
set(GLTFSDK_FOUND TRUE)
add_library(GLTFSDK STATIC IMPORTED GLOBAL)
set_target_properties(GLTFSDK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/build/native/include")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86/Debug/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_MINSIZEREL "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86/Release/static/libGLTFSDK.a")
# Default location for other build configurations defaults to Debug
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86/Debug/static/libGLTFSDK.a")
endif()

Просмотреть файл

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.9)
if (NOT GLTFSDK_FOUND)
set(GLTFSDK_FOUND TRUE)
add_library(GLTFSDK STATIC IMPORTED GLOBAL)
set_target_properties(GLTFSDK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/build/native/include")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86_64/Debug/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86_64/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86_64/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_MINSIZEREL "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86_64/Release/static/libGLTFSDK.a")
# Default location for other build configurations defaults to Debug
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x86_64/Debug/static/libGLTFSDK.a")
endif()

Просмотреть файл

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.9)
if (NOT GLTFSDK_FOUND)
set(GLTFSDK_FOUND TRUE)
add_library(GLTFSDK STATIC IMPORTED GLOBAL)
set_target_properties(GLTFSDK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/build/native/include")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOS/Debug/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOS/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOS/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_MINSIZEREL "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOS/Release/static/libGLTFSDK.a")
# Default location for other build configurations defaults to Debug
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOS/Debug/static/libGLTFSDK.a")
endif()

Просмотреть файл

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.9)
if (NOT GLTFSDK_FOUND)
set(GLTFSDK_FOUND TRUE)
add_library(GLTFSDK STATIC IMPORTED GLOBAL)
set_target_properties(GLTFSDK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/build/native/include")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOSSimulator64/Debug/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOSSimulator64/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOSSimulator64/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_MINSIZEREL "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOSSimulator64/Release/static/libGLTFSDK.a")
# Default location for other build configurations defaults to Debug
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/iOSSimulator64/Debug/static/libGLTFSDK.a")
endif()

Просмотреть файл

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.9)
if (NOT GLTFSDK_FOUND)
set(GLTFSDK_FOUND TRUE)
add_library(GLTFSDK STATIC IMPORTED GLOBAL)
set_target_properties(GLTFSDK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/build/native/include")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x64/Debug/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x64/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x64/Release/static/libGLTFSDK.a")
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION_MINSIZEREL "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x64/Release/static/libGLTFSDK.a")
# Default location for other build configurations defaults to Debug
set_target_properties(GLTFSDK PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/build/native/lib/x64/Debug/static/libGLTFSDK.a")
endif()

Просмотреть файл

@ -0,0 +1,117 @@
###############################################################################
# Sets the name of the platform in the variable named by 'outPlatform'
# Possible values are "iOS", "iOSSimulator", "iOSSimulator64", "appleTV", "appleTVSimulator"
# Android values are of the form "android_<ANDROID_ABI>".
# Possible values of ANDROID_ABIs are found here : https://developer.android.com/ndk/guides/abis
###############################################################################
function (GetGLTFPlatform outPlatform)
if(ANDROID_OS_PLATFORM)
if(ANDROID_OS_PLATFORM STREQUAL "ANDROID")
if( (ANDROID_ABI STREQUAL "x86") OR
(ANDROID_ABI STREQUAL "x86_64") OR
(ANDROID_ABI STREQUAL "arm64-v8a") OR
(ANDROID_ABI STREQUAL "armeabi-v7a"))
set(${outPlatform} "android_${ANDROID_ABI}" PARENT_SCOPE)
else()
message(FATAL_ERROR "Invalid ANDROID_ABI: ${ANDROID_ABI}")
endif()
else()
message(FATAL_ERROR "Invalid ANDROID_OS_PLATFORM: ${ANDROID_OS_PLATFORM}")
endif()
elseif (IOS_PLATFORM)
if (IOS_PLATFORM STREQUAL "OS")
set(${outPlatform} iOS PARENT_SCOPE)
elseif (IOS_PLATFORM STREQUAL "SIMULATOR")
set(${outPlatform} iOSSimulator PARENT_SCOPE)
elseif(IOS_PLATFORM STREQUAL "SIMULATOR64")
set(${outPlatform} iOSSimulator64 PARENT_SCOPE)
elseif (IOS_PLATFORM STREQUAL "TVOS" PARENT_SCOPE)
set(${outPlatform} appleTV PARENT_SCOPE)
elseif (IOS_PLATFORM STREQUAL "SIMULATOR_TVOS")
set(${outPlatform} appleTVSimulator PARENT_SCOPE)
else()
message(FATAL_ERROR "Invalid IOS_PLATFORM: ${IOS_PLATFORM}")
endif()
elseif (MSVC)
if (CMAKE_GENERATOR_PLATFORM STREQUAL "Win32")
set(${outPlatform} windows_win32 PARENT_SCOPE)
elseif (CMAKE_GENERATOR_PLATFORM STREQUAL "x64")
set(${outPlatform} windows_x64 PARENT_SCOPE)
elseif (CMAKE_GENERATOR_PLATFORM STREQUAL "ARM")
set(${outPlatform} windows_arm PARENT_SCOPE)
else()
error ("Unknown CMAKE_GENERATOR_PLATFORM " ${CMAKE_GENERATOR_PLATFORM})
endif()
else()
# MacOS
set(${outPlatform} macOS PARENT_SCOPE)
endif()
endfunction(GetGLTFPlatform)
###############################################################################
# Set the default install TARGETS (Built/Out/<Platform>/<Config>/<Project>)
# for the ARCHIVE, LIBRARY, RUNTIME, and BUNDLE folders
###############################################################################
function(CreateGLTFInstallTargets target platform)
install(TARGETS ${target}
ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/Built/Out/${platform}/$<CONFIG>/${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_SOURCE_DIR}/Built/Out/${platform}/$<CONFIG>/${PROJECT_NAME}
RUNTIME DESTINATION ${CMAKE_SOURCE_DIR}/Built/Out/${platform}/$<CONFIG>/${PROJECT_NAME}
BUNDLE DESTINATION ${CMAKE_SOURCE_DIR}/Built/Out/${platform}/$<CONFIG>/${PROJECT_NAME}
)
if (MSVC)
install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/$<CONFIG>/${PROJECT_NAME}.pdb DESTINATION ${CMAKE_SOURCE_DIR}/Built/Out/${platform}/$<CONFIG>/${PROJECT_NAME})
endif()
endfunction(CreateGLTFInstallTargets)
###############################################################################
# Add the required properties and libraries to create an iOS Application
# Assumes that the Info.plist is in the same folder as the caller
###############################################################################
function(AddGLTFIOSAppProperties target)
if(IOS_PLATFORM)
# Locate system libraries on iOS
find_library(UIKIT UIKit)
find_library(FOUNDATION Foundation)
find_library(MOBILECORESERVICES MobileCoreServices)
find_library(CFNETWORK CFNetwork)
find_library(SYSTEMCONFIGURATION SystemConfiguration)
# link the frameworks located above
target_link_libraries(${target} ${UIKIT})
target_link_libraries(${target} ${FOUNDATION})
target_link_libraries(${target} ${MOBILECORESERVICES})
target_link_libraries(${target} ${CFNETWORK})
target_link_libraries(${target} ${SYSTEMCONFIGURATION})
set_target_properties(${target} PROPERTIES
MACOSX_BUNDLE true
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/Info.plist"
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET 9.0
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
# This is a temporary value that is a personal team (kaokuda) to confirm that these settings are working
# When we get a real "Team" for development that we can all share then this should be changed.
# Change this locally to your personal Team to simplify the build process.
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "BKXU2T37Q4"
)
endif()
endfunction(AddGLTFIOSAppProperties)

Просмотреть файл

@ -0,0 +1,351 @@
# This file is part of the ios-cmake project. It was retrieved from
# https://github.com/cristeab/ios-cmake.git, which is a fork of
# https://code.google.com/p/ios-cmake/. Which in turn is based off of
# the Platform/Darwin.cmake and Platform/UnixPaths.cmake files which
# are included with CMake 2.8.4
#
# The ios-cmake project is licensed under the new BSD license.
#
# Copyright (c) 2014, Bogdan Cristea and LTE Engineering Software,
# Kitware, Inc., Insight Software Consortium. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# This file is based off of the Platform/Darwin.cmake and
# Platform/UnixPaths.cmake files which are included with CMake 2.8.4
# It has been altered for iOS development.
#
# Updated by Alex Stewart (alexs.mac@gmail.com).
# The following variables control the behaviour of this toolchain:
#
# IOS_PLATFORM: OS (default) or SIMULATOR or SIMULATOR64 or TVOS or SIMULATOR_TVOS
# OS = Build for iPhoneOS.
# SIMULATOR = Build for x86 i386 iPhone Simulator.
# SIMULATOR64 = Build for x86 x86_64 iPhone Simulator.
# TVOS = Build for AppleTVOS.
# SIMULATOR_TVOS = Build for x86_64 AppleTV Simulator.
# CMAKE_OSX_SYSROOT: Path to the iOS SDK to use. By default this is
# automatically determined from IOS_PLATFORM and xcodebuild, but
# can also be manually specified (although this should not be required).
# CMAKE_IOS_DEVELOPER_ROOT: Path to the Developer directory for the iOS platform
# being compiled for. By default this is automatically determined from
# CMAKE_OSX_SYSROOT, but can also be manually specified (although this should
# not be required).
# ENABLE_BITCODE: (true|false) Enables or disables bitcode support. Default true
#
# This toolchain defines the following variables for use externally:
#
# XCODE_VERSION: Version number (not including Build version) of Xcode detected.
# IOS_SDK_VERSION: Version of iOS SDK being used.
# CMAKE_OSX_ARCHITECTURES: Architectures being compiled for (generated from
# IOS_PLATFORM).
#
# This toolchain defines the following macros for use externally:
#
# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE XCODE_VARIANT)
# A convenience macro for setting xcode specific properties on targets.
# Available variants are: All, Release, RelWithDebInfo, Debug, MinSizeRel
# example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1" "all").
#
# find_host_package (PROGRAM ARGS)
# A macro used to find executable programs on the host system, not within the
# iOS environment. Thanks to the android-cmake project for providing the
# command.
# Fix for PThread library not in path
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
set(CMAKE_USE_PTHREADS_INIT 1)
# Get the Xcode version being used.
execute_process(COMMAND xcodebuild -version
OUTPUT_VARIABLE XCODE_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION "${XCODE_VERSION}")
string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION "${XCODE_VERSION}")
message(STATUS "Building with Xcode version: ${XCODE_VERSION}")
# Default to building for iPhoneOS if not specified otherwise, and we cannot
# determine the platform from the CMAKE_OSX_ARCHITECTURES variable. The use
# of CMAKE_OSX_ARCHITECTURES is such that try_compile() projects can correctly
# determine the value of IOS_PLATFORM from the root project, as
# CMAKE_OSX_ARCHITECTURES is propagated to them by CMake.
if (NOT DEFINED IOS_PLATFORM)
if (CMAKE_OSX_ARCHITECTURES)
if (CMAKE_OSX_ARCHITECTURES MATCHES ".*arm.*")
set(IOS_PLATFORM "OS")
elseif (CMAKE_OSX_ARCHITECTURES MATCHES "i386")
set(IOS_PLATFORM "SIMULATOR")
elseif (CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
set(IOS_PLATFORM "SIMULATOR64")
endif()
endif()
if (NOT IOS_PLATFORM)
set(IOS_PLATFORM "OS")
endif()
endif()
set(IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING
"Type of iOS platform for which to build.")
# Determine the platform name and architectures for use in xcodebuild commands
# from the specified IOS_PLATFORM name.
if (IOS_PLATFORM STREQUAL "OS")
set(XCODE_IOS_PLATFORM iphoneos)
set(IOS_ARCH armv7 armv7s arm64)
elseif (IOS_PLATFORM STREQUAL "SIMULATOR")
set(XCODE_IOS_PLATFORM iphonesimulator)
set(IOS_ARCH i386)
elseif(IOS_PLATFORM STREQUAL "SIMULATOR64")
set(XCODE_IOS_PLATFORM iphonesimulator)
set(IOS_ARCH x86_64)
elseif (IOS_PLATFORM STREQUAL "TVOS")
set(XCODE_IOS_PLATFORM appletvos)
set(IOS_ARCH arm64)
elseif (IOS_PLATFORM STREQUAL "SIMULATOR_TVOS")
set(XCODE_IOS_PLATFORM appletvsimulator)
set(IOS_ARCH x86_64)
else()
message(FATAL_ERROR "Invalid IOS_PLATFORM: ${IOS_PLATFORM}")
endif()
message(STATUS "Configuring iOS build for platform: ${IOS_PLATFORM}, "
"architecture(s): ${IOS_ARCH}")
# If user did not specify the SDK root to use, then query xcodebuild for it.
if (NOT CMAKE_OSX_SYSROOT)
execute_process(COMMAND xcodebuild -version -sdk ${XCODE_IOS_PLATFORM} Path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using SDK: ${CMAKE_OSX_SYSROOT} for platform: ${IOS_PLATFORM}")
endif()
if (NOT EXISTS ${CMAKE_OSX_SYSROOT})
message(FATAL_ERROR "Invalid CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT} "
"does not exist.")
endif()
# Specify minimum version of deployment target.
if (NOT DEFINED IOS_DEPLOYMENT_TARGET)
# Unless specified, SDK version 8.0 is used by default as minimum target version.
set(IOS_DEPLOYMENT_TARGET "8.0"
CACHE STRING "Minimum iOS version to build for." )
message(STATUS "Using the default min-version since IOS_DEPLOYMENT_TARGET not provided!")
endif()
# Use bitcode or not
if (NOT DEFINED ENABLE_BITCODE)
# Unless specified, enable bitcode support by default
set(ENABLE_BITCODE TRUE CACHE BOOL "Wheter or not to enable bitcode")
message(STATUS "Enabling bitcode support by default. ENABLE_BITCODE not provided!")
endif()
# Get the SDK version information.
execute_process(COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version SDKVersion
OUTPUT_VARIABLE IOS_SDK_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Find the Developer root for the specific iOS platform being compiled for
# from CMAKE_OSX_SYSROOT. Should be ../../ from SDK specified in
# CMAKE_OSX_SYSROOT. There does not appear to be a direct way to obtain
# this information from xcrun or xcodebuild.
if (NOT CMAKE_IOS_DEVELOPER_ROOT)
get_filename_component(IOS_PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT} PATH)
get_filename_component(CMAKE_IOS_DEVELOPER_ROOT ${IOS_PLATFORM_SDK_DIR} PATH)
endif()
if (NOT EXISTS ${CMAKE_IOS_DEVELOPER_ROOT})
message(FATAL_ERROR "Invalid CMAKE_IOS_DEVELOPER_ROOT: "
"${CMAKE_IOS_DEVELOPER_ROOT} does not exist.")
endif()
# Find the C & C++ compilers for the specified SDK.
if (NOT CMAKE_C_COMPILER)
execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang
OUTPUT_VARIABLE CMAKE_C_COMPILER
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using C compiler: ${CMAKE_C_COMPILER}")
endif()
if (NOT CMAKE_CXX_COMPILER)
execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang++
OUTPUT_VARIABLE CMAKE_CXX_COMPILER
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}")
endif()
# Find (Apple's) libtool.
execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find libtool
OUTPUT_VARIABLE IOS_LIBTOOL
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using libtool: ${IOS_LIBTOOL}")
# Configure libtool to be used instead of ar + ranlib to build static libraries.
# This is required on Xcode 7+, but should also work on previous versions of
# Xcode.
set(CMAKE_C_CREATE_STATIC_LIBRARY
"${IOS_LIBTOOL} -static -o <TARGET> <LINK_FLAGS> <OBJECTS> ")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY
"${IOS_LIBTOOL} -static -o <TARGET> <LINK_FLAGS> <OBJECTS> ")
# Get the version of Darwin (OS X) of the host.
execute_process(COMMAND uname -r
OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Standard settings.
set(CMAKE_SYSTEM_NAME Darwin CACHE INTERNAL "")
set(CMAKE_SYSTEM_VERSION ${IOS_SDK_VERSION} CACHE INTERNAL "")
set(UNIX TRUE CACHE BOOL "")
set(APPLE TRUE CACHE BOOL "")
set(IOS TRUE CACHE BOOL "")
set(CMAKE_AR ar CACHE FILEPATH "" FORCE)
set(CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE)
# Force unset of OS X-specific deployment target (otherwise autopopulated),
# required as of cmake 2.8.10.
set(CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING
"Must be empty for iOS builds." FORCE)
# Set the architectures for which to build.
set(CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS")
# Skip the platform compiler checks for cross compiling.
set(CMAKE_CXX_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_C_COMPILER_WORKS TRUE)
# All iOS/Darwin specific settings - some may be redundant.
set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
set(CMAKE_SHARED_MODULE_PREFIX "lib")
set(CMAKE_SHARED_MODULE_SUFFIX ".so")
set(CMAKE_MODULE_EXISTS 1)
set(CMAKE_DL_LIBS "")
set(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ")
set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}")
set(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}")
message(STATUS "Building for minimum iOS version: ${IOS_DEPLOYMENT_TARGET}"
" (SDK version: ${IOS_SDK_VERSION})")
# Note that only Xcode 7+ supports the newer more specific:
# -m${XCODE_IOS_PLATFORM}-version-min flags, older versions of Xcode use:
# -m(ios/ios-simulator)-version-min instead.
if (IOS_PLATFORM STREQUAL "OS")
if (XCODE_VERSION VERSION_LESS 7.0)
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-mios-version-min=${IOS_DEPLOYMENT_TARGET}")
else()
# Xcode 7.0+ uses flags we can build directly from XCODE_IOS_PLATFORM.
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-m${XCODE_IOS_PLATFORM}-version-min=${IOS_DEPLOYMENT_TARGET}")
endif()
elseif (IOS_PLATFORM STREQUAL "TVOS")
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-mtvos-version-min=${IOS_DEPLOYMENT_TARGET}")
elseif (IOS_PLATFORM STREQUAL "SIMULATOR_TVOS")
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-mtvos-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
else()
# SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min.
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-mios-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
endif()
message(STATUS "Version flags set to: ${XCODE_IOS_PLATFORM_VERSION_FLAGS}")
if (ENABLE_BITCODE)
set(BITCODE "-fembed-bitcode")
message(STATUS "Enabling bitcode support.")
else()
set(BITCODE "")
message(STATUS "Disabling bitcode support.")
endif()
set(CMAKE_C_FLAGS
"${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE} -fobjc-abi-version=2 -fobjc-arc ${CMAKE_C_FLAGS}")
# Hidden visibilty is required for C++ on iOS.
set(CMAKE_CXX_FLAGS
"${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE} -fvisibility=hidden -fvisibility-inlines-hidden -fobjc-abi-version=2 -fobjc-arc ${CMAKE_CXX_FLAGS}")
# kaokuda : Removed -fomit-frame-pointer as it was generating a compile warning on Release iOS (arm7)
#set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -fomit-frame-pointer -ffast-math ${BITCODE} ${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -ffast-math ${BITCODE} ${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_C_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}")
set(CMAKE_CXX_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}")
# In order to ensure that the updated compiler flags are used in try_compile()
# tests, we have to forcibly set them in the CMake cache, not merely set them
# in the local scope.
list(APPEND VARS_TO_FORCE_IN_CACHE
CMAKE_C_FLAGS
CMAKE_CXX_FLAGS
CMAKE_CXX_RELEASE
CMAKE_C_LINK_FLAGS
CMAKE_CXX_LINK_FLAGS)
foreach(VAR_TO_FORCE ${VARS_TO_FORCE_IN_CACHE})
set(${VAR_TO_FORCE} "${${VAR_TO_FORCE}}" CACHE STRING "" FORCE)
endforeach()
set(CMAKE_PLATFORM_HAS_INSTALLNAME 1)
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -headerpad_max_install_names")
set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -headerpad_max_install_names")
set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,")
set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
# Hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old
# build tree (where install_name_tool was hardcoded) and where
# CMAKE_INSTALL_NAME_TOOL isn't in the cache and still cmake didn't fail in
# CMakeFindBinUtils.cmake (because it isn't rerun) hardcode
# CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did
# before, Alex.
if (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
find_program(CMAKE_INSTALL_NAME_TOOL install_name_tool)
endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
# Set the find root to the iOS developer roots and to user defined paths.
set(CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_OSX_SYSROOT}
${CMAKE_PREFIX_PATH} CACHE string "iOS find search path root" FORCE)
# Default to searching for frameworks first.
set(CMAKE_FIND_FRAMEWORK FIRST)
# Set up the default search directories for frameworks.
set(CMAKE_SYSTEM_FRAMEWORK_PATH
${CMAKE_OSX_SYSROOT}/System/Library/Frameworks
${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks
${CMAKE_OSX_SYSROOT}/Developer/Library/Frameworks)
# Only search the specified iOS SDK, not the remainder of the host filesystem.
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# This little macro lets you set any XCode specific property.
macro(set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE XCODE_RELVERSION)
set(XCODE_RELVERSION_I "${XCODE_RELVERSION}")
if (XCODE_RELVERSION_I STREQUAL "All")
set_property(TARGET ${TARGET} PROPERTY
XCODE_ATTRIBUTE_${XCODE_PROPERTY} "${XCODE_VALUE}")
else()
set_property(TARGET ${TARGET} PROPERTY
XCODE_ATTRIBUTE_${XCODE_PROPERTY}[variant=${XCODE_RELVERSION_I}] "${XCODE_VALUE}")
endif()
endmacro(set_xcode_property)
# This macro lets you find executable programs on the host system.
macro(find_host_package)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
set(IOS FALSE)
find_package(${ARGN})
set(IOS TRUE)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endmacro(find_host_package)

Просмотреть файл

@ -0,0 +1,26 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
<#
.SYNOPSIS
Gets Git.exe location.
.DESCRIPTION
Looks for git.exe in multiple program file locations.
.PARAMETER GitLocations
Additional locations in which to search for git.exe
#>
[CmdletBinding()]
Param(
[Parameter()]
[string[]]$GitLocations
)
function main {
$searchLocations = $GitLocations + @("git", "${env:ProgramFiles(x86)}\Git\bin\git.exe", "${env:ProgramFiles}\Git\bin\git.exe", "${env:ProgramW6432}\Git\bin\git.exe")
return ($searchLocations | ? { Get-Command $_ -ErrorAction SilentlyContinue } | Select -First 1)
}
main

Просмотреть файл

@ -0,0 +1,55 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
<#
.SYNOPSIS
Creates a new annotated git tag using a VSTS RESTful API call.
.DESCRIPTION
Constructs and invokes the following RESTful API call:
https://www.visualstudio.com/en-us/docs/integrate/api/git/annotatedtags#create-annotated-tag
We do things this way rather than using git directly because of auth issues.
Git repos cloned through automatic builds aren't set up to authenticate against
their remotes, so we can't make any git calls that affect the central repo.
REST calls are very easy to authenticate against from build definitions.
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
[String]$TagName,
[Parameter(Mandatory)]
[String]$TagMessage,
[Parameter()]
[String]$RepoName = $Env:BUILD_REPOSITORY_NAME,
[Parameter()]
[String]$Sha1 = $Env:BUILD_SOURCEVERSION
)
$ErrorActionPreference = "stop"
$Verbose = [bool]$PSBoundParameters["Verbose"]
function main {
if (! $RepoName) {
Write-Error "Must provide a RepoName if this isn't invoked through VSTS"
}
elseif (! $Sha1) {
Write-Error "Must provide a Sha1 if this isn't invoked through VSTS"
}
else
{
$uri = "https://microsoft.visualstudio.com/DefaultCollection/Apps/_apis/git/repositories/$RepoName/annotatedTags"
$body = @{
"name" = "$TagName"
"message" = "$TagMessage"
"taggedObject" = @{
"objectId" = "$Sha1"
}
}
&"$PSScriptRoot\..\..\XplatScripts\NuGet.macOS\Invoke-VstsRestMethod.ps1" -Uri "$uri" -Body $body -Method "Post" -ApiVersion "4.0-preview" -Verbose
}
}
main

Просмотреть файл

@ -0,0 +1,187 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
function CheckTextForReleaseNotesTags
{
Param(
[Parameter()]
[String[]]$FormattedText
)
$definedTags = GetDefinedTags
$allTags = @()
foreach ($line in $FormattedText)
{
$tags = @()
while ($line -match "^\s*\[(\w+)\](.+)*$")
{
$tag,$line = $matches[1,2]
$tags += $tag
}
if (!$tags)
{
Write-Verbose @"
No tags in line:
$line
"@
continue
}
if ($tags -contains $definedTags.noReleaseTag)
{
Write-Verbose "The `"No Release Notes`" tag was detected - this PR won't generate release notes"
# if there's only one tag in the entire line, the length will return the string length instead of 1
if ($tags.count -gt 1)
{
Write-Host $tags.count
Write-Host "Additional tags detected after [NORELEASENOTES] tag that will not be used: $($tags[1..($tags.length-1)])"
return $false
}
return $true
}
$containsSectionTag = $false
# make sure the tags contain only one sectionTags
foreach ($tag in $tags)
{
if ($definedTags.sectionTags -contains $tag)
{
if ($containsSectionTag)
{
Write-Host "Each Release Note line must contain only 1 section tag: $($definedTags.sectionTags). The following line has more than one valid section tag: `n$line"
return $false
}
$containsSectionTag = $true
}
else
{
Write-Host "Invalid tag provided: $tag. Each release note line must contain exactly one section tag: $($definedTags.sectionTags). To instead have no release notes for this PR, use: $NoReleaseTag"
return $false
}
}
if (!$containsSectionTag)
{
Write-Host "Each Release Note line must contain 1 section tag: $($definedTags.sectionTags). The following line is missing a valid section tag: `n$line"
return $false
}
Write-Verbose @"
Found Tags: $tags in line:
$line
"@
if ($line -notmatch "[\d\w]+")
{
Write-Host @"
Each Release Notes line must contain release note text after the tags, on the same line. For example:
[Minor] This text is the release note line that will get added to the release notes file :)
"@
return $false
}
$allTags += $tags
}
if (!$allTags)
{
Write-Host "No tags found - please tag your PR title or description appropriately for release notes."
return $false
}
return $true
}
function GetDefinedTags
{
Param(
[Parameter()]
[String]$DefinedTagsFile
)
if (! $DefinedTagsFile) {
$DefinedTagsFile = (Join-Path $PSScriptRoot "ReleaseNotesTags.json")
}
Write-Verbose "Reading defined tags from $DefinedTagsFile"
if (!(Test-Path $DefinedTagsFile))
{
Write-Error "Cannot read in $DefinedTagsFile file containing standard tag names"
}
$tagFile = Get-Content -Path $DefinedTagsFile | ConvertFrom-Json
Write-Verbose ($tagFile | Format-Table -Wrap | Out-String)
return $tagFile
}
function GetCommitInfoObject
{
Param(
[Parameter(Mandatory=$true)]
[String]$sha1
)
$GitCommand = . (Join-Path $PSScriptRoot "GetGitCommand.ps1")
if (!$GitCommand)
{
Write-Error "Unable to find git"
}
$commitInfo = & $GitCommand show -s --format='%B' $sha1
$descriptionLines = @()
foreach ($line in $commitInfo)
{
if ($line -match "Merged PR ([\d]+):(.+|$)")
{
$prNum = $matches[1]
if ($matches[2])
{
$descriptionLines += $matches[2].Trimstart(' ')
}
Write-Verbose "PR number found: $prNum with title: $descriptionLines"
}
# Related work items
elseif ($line -match "^Related work items: #(.+)")
{
$WorkItems = $Matches[1] -split ', #'
Write-Verbose "Work Items found: $WorkItems"
}
# Release note line
else
{
$descriptionLines += $line
Write-Verbose "Adding description line: $line"
}
}
return [PSObject]@{
PRNum = $prNum;
WorkItems = $workItems;
Description = $descriptionLines;
}
}
function ReadOverrideFile
{
[CmdletBinding()]
Param(
[Parameter()]
[String]$overrideFileName = "\\bp-fs1\CANVAS\Builds\Native\ReleaseNotes\ReleaseNotesOverrides.json"
)
$overrides = @{}
Write-Host "Getting overrides from $overrideFileName"
if (Test-Path $overrideFileName)
{
$psObjOverrides = Get-Content -Path $overrideFileName | ConvertFrom-Json
$psObjOverrides.psobject.properties | Foreach {$overrides[$_.Name] = $_.Value }
}
# Later: fail if no overrides file found
return $overrides
}
Export-ModuleMember -Function 'GetDefinedTags'
Export-ModuleMember -Function 'CheckTextForReleaseNotesTags'
Export-ModuleMember -Function 'GetCommitInfoObject'
Export-ModuleMember -Function 'ReadOverrideFile'

Просмотреть файл

@ -0,0 +1,140 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
<# .SYNOPSIS
Checks a Pull Request to make sure it is formatted to automatically generate release notes.
.DESCRIPTION
Given a Pull Request's ID number, checks the PR's title and description to ensure it contains correctly formatted release notes.
This is only a format checker, it does not generate release notes from the Pull Request.
.PARAMETER PullRequestID
Optional. The ID number of the Pull Request. This is defaulted to env:SYSTEM_PULLREQUEST_PULLREQUESTID, which is set when invoked from a PR build.
.PARAMETER RepoName
Optional. The git repository name, this is defaulted to env:BUILD_REPOSITORY_NAME, which is set when invoked from a PR build.
.PARAMETER DefinedTagsFilePath
Optional. The .json file containing the defined valid tags we use to generate release notes. The path should be relative to this script.
.PARAMETER LocalPATLocation
Optional. The location of a local PAT token to make authorized VSTS REST calls to get info for the given PR and repo.
For use when running locally, as this script will use env:SYSTEM_ACCESSTOKEN by default, which is set when invoked from a PR build.
#>
[CmdletBinding()]
Param(
[Parameter()]
[String]$PullRequestID = $env:SYSTEM_PULLREQUEST_PULLREQUESTID,
[Parameter()]
[String]$RepoName = $env:BUILD_REPOSITORY_NAME,
[Parameter()]
[String]$LocalPATLocation
)
$ErrorActionPreference = "Stop"
function Main
{
Import-Module (Join-Path $PSScriptRoot "ReleaseNotesHelper.psm1")
PrintReleaseNoteFormatInfo
if (!$PullRequestID)
{
Write-Error "Pull Request ID cannot be null."
}
$prInfo = GetPRInfo
$validFormat = CheckTextForReleaseNotesTags $prInfo
if (!$validFormat)
{
Write-Error "Please tag your PR title or description appropriately for release notes."
}
Write-Verbose "Finished checking - the PR is in a correct format to generate release notes"
}
function PrintReleaseNoteFormatInfo
{
Write-Host @"
This script will check the format of the PR to ensure it will work with the automated release notes system.
Your PR must contain at least one formatted release note entry, either within the PR's title or the PR's description.
The format of this release note entry must begin with tags.
If your PR does not involve any changes that should generate release notes, use the [NORELEASENOTES] tag.
To generate release notes, put each release note line on a single line each, and prefix it with tags to describe the file and section.
Within each release note file, you must define what kind of change was made. For each release note line, specify one (and only one) section tag. The project tag values are:
[FEATURE]
[BREAKING]
[MINOR]
[BUG]
As an example, here is a PR description you may have:
[FEATURE] Adding new feature that does something and everything. This is a very long release note line that must not contain any line breaks.
[BUG] Fixed hang in ViewerApp
And if I were to type text in my PR title or description, without any tags in front, they won't be included in the release notes.
Pull Request ID provided for this build: $PullRequestID
"@
}
# Use REST apis to get the current Pull Request information
function GetPRInfo()
{
# edits to a PR title/description happens extremely quickly, GET calls get updated info.
$url = "https://microsoft.visualstudio.com/DefaultCollection/Apps/_apis/git/repositories/$RepoName/pullRequests/$PullRequestID" + "?api-version=3.0"
$result = Rest $url
Write-Verbose $result
$prInfo = @($result.title)
$prInfo += $result.description -split '\n'
Write-Verbose "PR text: $prInfo"
if (!$prInfo)
{
Write-Error "PR title and description are empty for PR id: $PullRequestID"
}
return $prInfo
}
function Rest($url)
{
if ($env:SYSTEM_ACCESSTOKEN)
{
$authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
# Running locally
else
{
Write-Host "No SYSTEM_ACCESSTOKEN environment variable found. Getting local PAT token at location $LocalPATLocation"
$encodedPat = getEncodedPat
$authorization = "Basic $encodedPat"
}
return Invoke-RestMethod $url -Headers @{Authorization = $authorization}
}
# Decrypt a secure string, and then convert to base64 (expected by auth headers)
# Taken from https://github.com/DarqueWarrior/team/blob/master/src/team.psm1
function getEncodedPat()
{
if (!$LocalPATLocation)
{
Write-Error "No local pat provided, and no value in `$env:SYSTEM_ACCESSTOKEN."
}
[SecureString]$encryptedPat = Get-Content $LocalPATLocation | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PSCredential "foo",$encryptedPat
$decryptedPat = $credential.GetNetworkCredential().Password
return [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$decryptedPat"))
}
Main

Просмотреть файл

@ -0,0 +1,6 @@
{
"NoReleaseTag": "NoReleaseNotes",
"SectionTags": [
"Feature", "Breaking", "Minor", "Bug"
]
}

Просмотреть файл

@ -0,0 +1,14 @@
#!/usr/local/bin/powershell
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
pushd $PSScriptRoot
$ScriptPath = "$PSScriptRoot/../../XPlatScripts/NuGet.macOS/NuGetRestore.ps1"
$Args = "-Verbose -PackagesConfigRoot ../../ -NuGetConfig ../../NuGet.Config -PackagesPath ../../packages"
Invoke-Expression "& $ScriptPath $Args"
popd

Просмотреть файл

@ -0,0 +1,36 @@
[{
"name": "Release",
"reasons": ["Release"],
"config": {
"PublishNuGet": "true",
"PublishMarkdownDocs": "true"
}
}, {
"name": "CI",
"reasons": ["IndividualCI", "BatchedCI"],
"config": {
"PublishNuGet": "true",
"PublishMarkdownDocs": "true"
}
}, {
"name": "Nightly",
"reasons": ["Schedule"],
"config": {
"PublishNuGet": "false",
"PublishMarkdownDocs": "false"
}
}, {
"name": "PullRequest",
"reasons": ["PullRequest"],
"config": {
"PublishNuGet": "false",
"PublishMarkdownDocs": "false"
}
}, {
"name": "Manual",
"reasons": ["Manual"],
"config": {
"PublishNuGet": "false",
"PublishMarkdownDocs": "false"
}
}]

Просмотреть файл

@ -0,0 +1,75 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
# Based on the build reason, modify the build output location and set some
# default VSTS variables that will control behavior. If these variables have
# been explicitly set this script won't override them.
# See build.reason at: https://www.visualstudio.com/en-us/docs/build/define/variables
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
[String]$BuildDefinitionBase,
[Parameter()]
[String]$BuildReason
)
$ErrorActionPreference = "Stop"
if (! $BuildReason) {
$BuildReason = $Env:BUILD_REASON
if (! $BuildReason) {
Write-Error "BuildReason must be provided if this script wasn't invoked from VSTS"
}
}
function main {
$buildConfig = getConfigForBuildReason $BuildReason
# XES_DFSDROP locations are at \\edge-svcs\release\BigPark\<definition name>\<build number>
# We want to update <definition name> to be $base.$qualifier so e.g. PR builds go to a
# separate path. We are actually updating the reserved variable that indicates the build
# definition name, but it doesn't seem to have any adverse effects.
setVstsVariable "Build.DefinitionName" "${BuildDefinitionBase}.$($buildConfig.name)"
setDefaultVariables $buildConfig.config
}
function getConfigForBuildReason([String]$buildReason) {
$allConfig = Get-Content "$PSScriptRoot\SetBuildVariables.json" | ConvertFrom-Json
foreach ($config in $allConfig) {
foreach ($reason in $config.reasons) {
if ($reason -match $buildReason) {
Write-Verbose "Reason '$buildReason' matches $($config | ConvertTo-Json)"
return $config
}
}
Write-Verbose "Reason '$buildReason' does not match $($config | ConvertTo-Json)"
}
Write-Error "Unable to find a config matching reason $buildReason."
}
function setDefaultVariables([PSCustomObject]$config) {
foreach ($configEntry in $config.PSObject.Properties) {
setDefaultVstsVariable $configEntry.Name $configEntry.Value
}
}
function setDefaultVstsVariable([String]$name, [String]$value) {
$setValue = (Get-Item -ErrorAction SilentlyContinue "Env:$name").value
if ($setValue) {
Write-Verbose "Variable $name is already set to $setValue; not overriding it."
return
}
setVstsVariable $name $value
}
# https://github.com/Microsoft/vsts-tasks/blob/master/docs/authoring/commands.md
function setVstsVariable([String]$name, [String]$value) {
Write-Verbose "Setting $name to $value"
Write-Host "##vso[task.setvariable variable=$name;]$value"
}
main

Просмотреть файл

@ -0,0 +1,11 @@
{
"relativeRoot": "../..",
"tests": [{
"Name": "GLTFSDK.Test",
"Framework": "androidEmulator",
"Path": "Built/Out/android_<abi>/<configuration>/GLTFSDK.Test/GLTFSDK.Test",
"Tags": "emulator",
"Configurations": ["Debug"],
"Platforms": ["x86"]
}]
}

Просмотреть файл

@ -0,0 +1,265 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
<#
.SYNOPSIS
Determines the build/package version based on the most recent tags in the git branch hierarchy, or a provided override version number.
.DESCRIPTION
Determines the next version number either for release or pre-release, with the ability to override all version numbers.
It will use git describe and the branch name in combination with the version overrides to determine the new version.
MASTER branch:
- Branch name "master". By default, will +1 to the last found tag's patch number, unless overrides are provided
PATCH branch:
- Branch name "Release/a.b", overrided version must match a.b
- By default, will +1 to the last found tag's patch number, unless overrides are provided
HOTFIX branch:
- Branch name "Release/a.b.c", overrided version numbers must match a.b.c
- By default, will +1 to the last found tag's hotfix number, unless overrides are provided
.PARAMETER SourceDirectory
Optional. The root source tree to scan, which must be a valid git repo with current branch master, or a patch/hotfix branch
.PARAMETER VersionOverride
Optional. The version number to override with, in format "vMajor.vMinor.vPatch.vHotfix". Must be either all overrided
with numbers, or must be left null let the script decide the next version.
.PARAMETER GenerateReleaseVersion
Optional. Defaults to pre-release (false). If true, generates release version number instead
.PARAMETER PackageSource
Optional. The path to the package source, a nuget index.json file
.EXAMPLE
VersionNumberGenerator.ps1 -SourceDirectory "D:\Build vNext\Builds\cb11432a\Infrastructure\Code" -VersionOverride "1.2.3.4" -GenerateReleaseVersion True
.RESULT EXAMPLE
1.2.3.4 for release
<Major>.<Minor>.<Patch>.<Hotfix>
1.2.3.4-b05-g94f7eb5 for prerelease
<Major>.<Minor>.<Patch>.<Hotfix>-b<2-digit-#-commits>-<SHA1-gitcommit-hash>
CoApp follows semver 1.0.0 so the part after <Hotfix> cannot include periods.
#>
[CmdletBinding()]
param(
[string]$SourceDirectory,
[string]$VersionOverride,
[string]$GenerateReleaseVersion = $false,
[string]$PackageSource
)
$ErrorActionPreference = "Stop"
# TO DO: comparing if versionoverride is a string of $null is a workaround
# to deal with Command Line build step that doesn't allow passing in empty parameters
if ($VersionOverride -eq '$null')
{
$VersionOverride = $null
}
# Initialize global params
if (!$SourceDirectory)
{
$SourceDirectory = (Get-Item $PSScriptRoot).Parent.Parent.FullName
}
$GitCommand = . (Join-Path $PSScriptRoot "GetGitCommand.ps1")
if (!$GitCommand)
{
Write-Error "Unable to find git"
}
if (!$PackageSource)
{
$PackageSource = "https://microsoft.pkgs.visualstudio.com/_packaging/BigPark/nuget/v3/index.json"
}
[Boolean]$GenerateReleaseVersion = [System.Convert]::ToBoolean($GenerateReleaseVersion)
Enum BranchType
{
Master
Patch
Hotfix
}
function Main
{
Write-Verbose "Begin script VersionNumberGenerator.ps1"
Write-Verbose "Source Directory = $SourceDirectory"
Write-Verbose "GenerateReleaseVersion = $GenerateReleaseVersion"
Write-Verbose "VersionOverride = $VersionOverride"
$overridedVerNumbers = ParseVersionOverride $VersionOverride
Push-Location $SourceDirectory
$gitTraceOriginal = $env:GIT_TRACE
try
{
$env:GIT_TRACE = 1
$tagInfo = GetLastTagInfo
if ($overridedVerNumbers)
{
$versionNums = $overridedVerNumbers
}
else
{
$branchObject = GetBranchInfo
# deep copy
$versionNums = $tagInfo.VerNums | foreach { $_ }
if ($branchObject.Type -eq [BranchType]::Master)
{
$versionNums[2] = [int]($versionNums[2]) + 1
$versionNums[3] = 0
}
else
{
$verNumLength = $branchObject.VerNums.length
# if git describe doesn't match branch name, use the branch name and set remaining numbers to 0
if ($branchObject.VerNums[0..$verNumLength] | where { $versionNums[0..$verNumLength] -notcontains $_})
{
Write-Verbose "Last tag doesn't match branch name - using branch name version instead"
[array]::copy($branchObject.VerNums, $versionNums, $verNumLength)
if ($branchObject.Type -eq [BranchType]::Hotfix -or $branchObject.Type -eq [BranchType]::Patch)
{
$versionNums[3] = 0
}
if ($branchObject.Type -eq [BranchType]::Patch)
{
$versionNums[2] = 0
}
}
else
{
if ($branchObject.Type -eq [BranchType]::Hotfix)
{
$versionNums[3] = [int]($versionNums[3]) + 1
}
elseif ($branchObject.Type -eq [BranchType]::Patch)
{
$versionNums[2] = [int]($versionNums[2]) + 1
$versionNums[3] = 0
}
}
}
}
$versionString = FormatVersionNumsIntoString $versionNums $GenerateReleaseVersion $tagInfo.CommitInfo
Write-Host "##vso[task.setvariable variable=GLTFSDKVersionNumber;]$versionString"
Write-Verbose "New version number is: $versionString"
Write-Verbose "Set GLTFSDKVersionNumber to $versionString"
Write-Verbose "Exiting script VersionNumberGenerator.ps1"
}
finally
{
Pop-Location
$env:GIT_TRACE = $gitTraceOriginal
}
return $versionString
}
# Checks that the provided override version is valid and returns a string array containing the separate version parts.
function ParseVersionOverride($VersionOverride)
{
if ($VersionOverride -match "^(\d+)\.(\d+)\.(\d+)\.(\d+)$")
{
return $Matches[1..4]
}
elseif (!$VersionOverride)
{
return $null
}
Write-Error "Version Override is not valid: must be empty or a 4-part version number, ex. 1.4.6.0"
}
function GetBranchInfo()
{
# If this is a PR build, derive versions using the branch we're merging to
if ($Env:SYSTEM_PULLREQUEST_TARGETBRANCH) {
$gitBranchName = $Env:SYSTEM_PULLREQUEST_TARGETBRANCH
# If this is a central build that isn't a PR, use the branch we're building on
} elseif ($Env:BUILD_SOURCEBRANCH) {
$gitBranchName = $Env:BUILD_SOURCEBRANCH
# Otherwise, just make git calls to see if there's a branch on the commit we're building
} else {
$gitBranchName = & $GitCommand name-rev --name-only HEAD
}
if ($gitBranchName -match "^refs/heads/(.+)$") {
$gitBranchName = $matches[1]
}
Write-Verbose "Branch name: $gitBranchName"
$info = [PSObject]@{ Type=""; VerNums=""}
if ($gitBranchName -match "^Release/(\d+)\.(\d+).(\d+)$")
{
$info.Type = [BranchType]::Hotfix
$info.VerNums = $Matches[1..3]
}
elseif ($gitBranchName -match "^Release/(\d+)\.(\d+)$")
{
$info.Type = [BranchType]::Patch
$info.VerNums = $Matches[1..2]
}
else
{
$info.Type = [BranchType]::Master
}
Write-Verbose "$($info.Type) branch detected"
return $info
}
# Formats the given array of version numbers into a final version string
# Pre-release versions are suffixed with additional commit information
function FormatVersionNumsIntoString($versionNums, $generateRelease, $commitInfo)
{
$result = $versionNums -join '.'
if (!$generateRelease)
{
$result += "-b"
$result += $commitInfo
}
return $result
}
# Calls git describe to find the last tag, given overrided version numbers. If there is no tag found, it will error or continue depending on $noMatchShouldError
# Note: the [0-9]* in the git match will look for a single digit and then wildcard, so "1a" would match even though it is an invalid version number.
# So, immediately afterwards, we make sure it uses only digits using more powerful regex matching
function GetLastTagInfo
{
$lastTag = & $GitCommand describe --tags --long --dirty --always --first-parent --match "[rv][0-9]*.[0-9]*.[0-9]"
Write-Verbose "Git describe result: $lastTag"
if ($lastTag -match "[rv](\d+)\.(\d+)\.(\d+)\.(\d+)-(\d+)(-g\S{7})\S*$")
{
$info = [PSObject]@{ VerNums=""; CommitInfo=""}
$info.VerNums = $Matches[1..4]
$info.CommitInfo = ("{0:D2}" -f [int]$Matches[5]) + $Matches[6]
return $info
}
Write-Error "No tag found with format: $formatString. Erroring out."
}
Main

Просмотреть файл

@ -0,0 +1,32 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
# Based on the build reason, modify the build output location and set some
# default VSTS variables that will control behavior. If these variables have
# been explicitly set this script won't override them.
# See build.reason at: https://www.visualstudio.com/en-us/docs/build/define/variables
[CmdletBinding()]
param(
[string]$SourceDirectory = $env:BUILD_SOURCESDIRECTORY,
[string]$CommitId = $env:BUILD_SOURCEVERSION,
[string]$BranchName = $env:BUILD_SOURCEBRANCH,
[string]$VersionOverride,
[string]$GenerateReleaseVersion = $false,
[string]$PackageSource,
[string]$ModifyWindowsStoreApps = $true,
[string]$ModifyCoAppPackages = $true,
[string]$ModifyNuGetPackages = $true,
[string]$WriteVersionHeader = $true,
[string]$ExcludeFolders
)
$ErrorActionPreference = "Stop"
function Main
{
$versionString = . "$PSScriptRoot\VersionGenerator.ps1" -SourceDirectory $SourceDirectory -VersionOverride $VersionOverride -GenerateReleaseVersion $GenerateReleaseVersion -PackageSource $PackageSource -Verbose
. "$PSScriptRoot\VersionModifier.ps1" -SourceDirectory $SourceDirectory -CommitId $CommitId -BranchName $BranchName -ExcludeFolders $ExcludeFolders -VersionString $versionString -ModifyWindowsStoreApps $ModifyWindowsStoreApps -ModifyCoAppPackages $ModifyCoAppPackages -ModifyNuGetPackages $ModifyNuGetPackages -WriteVersionHeader $WriteVersionHeader -Verbose
}
Main

Просмотреть файл

@ -0,0 +1,251 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
<#
.SYNOPSIS
Scans the source tree for various file types and modifies their version numbers to all be the same
depending on the version of the build
.DESCRIPTION
Scans the source tree for Windows Store App package.appxmanifest files, CoApp autopkg files and NuGet nuspec files.
For each one modifies the version information stored in the package metadata appropriately.
Nuget and CoApp builds (ie based on autopkg or nuspec files) have their version (xml) tag replaced directly by the
version string. AppxManifest files only have the X.Y.Z modified because they cannot contain any other semantic
information within their version information.
.PARAMETER SourceDirectory
MANDATORY. The root source tree to scan.
.PARAMETER ModifyWindowsStoreApps
Whether or not to modify the package.appxmanifest files for Windows Store Apps.
.PARAMETER ModifyCoAppPackages
Whether or not to modify the autopkg files for c++ nuget packages generated with CoApp.
.PARAMETER ModifyNuGetPackages
Whether or not to modify the nuspec files for non-c++ nuget packages.
.PARAMETER WriteVersionHeader
Whether or not to modify the SpectreVersionInternal.h header file that is compiled into the Spectre::Utils::GetPackageVersion() method.
.PARAMETER ExcludeFolders
A semi-colon delimited list of folder patterns to ignore.
.PARAMETER VersionString
The version number we will use.
.EXAMPLE
VersionModifier.ps1 -VersionString "1.2.3.4" -SourceDirectory "D:\Build vNext\Builds\cb11432a\Infrastructure\Code" -ModifyWindowsStoreApps true -ExcludeFolders "Microsoft.Lift.WorkflowActivities.Tests"
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory)][string]$VersionString,
[string]$SourceDirectory = $env:BUILD_SOURCESDIRECTORY,
[string]$CommitId = $env:BUILD_SOURCEVERSION,
[string]$BranchName = $env:BUILD_SOURCEBRANCH,
[string]$ModifyWindowsStoreApps = $true,
[string]$ModifyCoAppPackages = $true,
[string]$ModifyNuGetPackages = $true,
[string]$WriteVersionHeader = $true,
[string]$ExcludeFolders
)
$ErrorActionPreference = "Stop"
# Initialize global params
if (!$SourceDirectory)
{
$SourceDirectory = (Get-Item $PSScriptRoot).Parent.Parent.FullName
}
[Boolean]$ModifyWindowsStoreApps = [System.Convert]::ToBoolean($ModifyWindowsStoreApps)
[Boolean]$ModifyCoAppPackages = [System.Convert]::ToBoolean($ModifyCoAppPackages)
[Boolean]$ModifyNuGetPackages = [System.Convert]::ToBoolean($ModifyNuGetPackages)
[Boolean]$WriteVersionHeader = [System.Convert]::ToBoolean($WriteVersionHeader)
[Boolean]$IsReleaseVersion = [System.Convert]::ToBoolean($IsReleaseVersion)
function Main
{
if ($VersionString -notmatch "^((\d+)\.(\d+)\.(\d+)\.(\d+))")
{
Write-Error "Version string $VersionString must include 4 digits separated by ."
}
$versionNumString = $Matches[1]
Write-Verbose "Entering script VersionModifier.ps1"
Write-Verbose "Source Directory = $SourceDirectory"
Write-Verbose "Full version string is: $VersionString, version numbers are $versionNumString"
$buildInfo = "Built from git commit $($CommitId) ($BranchName) on build machine $(hostname) at $(Get-Date), version $VersionString"
Write-Verbose "Build info: $buildInfo"
if ($ModifyWindowsStoreApps)
{
ModifyPackageAppxManifest $versionNumString
}
if ($ModifyCoAppPackages)
{
ModifyAutoPkgFiles $buildInfo
}
if ($ModifyNuGetPackages)
{
ModifyNuSpecPackages $buildInfo
}
if ($WriteVersionHeader)
{
WriteVersionHeader
}
Write-Verbose "Exiting script VersionModifier.ps1"
}
<#make sure the reference apps still build
We aren't going to be publishing any of these (Although it'd be nice if we could, because then we could just run WACK tests real easy)
So, make sure that the version number in the appxmanifest still allows it to build, check if dashes are allowed and letters
Want to try to keep the hash in the release version if possible.
Use our release version, not this funky logic here
Version in appxmanifest must be in format: "Major.Minor.Build.Revision". Value must contain a valid four-part version number.
# Reads the version number from the given package.appxmanifest
# Modifies the version numbers in package.appxmanifest files
#>
function ModifyPackageAppxManifest
{
Foreach ($file in GetFileWrapper "*.appxmanifest")
{
Write-Verbose $file
[xml]$appxData = Get-Content $file
Write-Verbose "Replacing $($appxData.Package.Identity.Version) with $VersionString"
$appxData.Package.Identity.Version = $VersionString
$appxData.Save($file)
}
}
# Reads various properties from the given nuspec file and returns them in a hash-table
# Writes the new version number, tags and releaseNotes (the build info) into the nuSpec file
# Modifies the version numbers in nuspec files
function ModifyNuSpecPackages($buildInfo)
{
Foreach ($file in GetFileWrapper "*.nuspec")
{
Write-Verbose $file
[xml]$nuspecData = Get-Content $file
Write-Verbose "Replacing version $($nuspecData.package.metadata.version) with $VersionString"
Write-Verbose "Replacing release notes with: $buildInfo"
$nuspecData.package.metadata.version = $VersionString
$nuspecData.package.metadata.releaseNotes = $buildInfo
foreach ($dependency in $nuspecData.package.metadata.dependencies.dependency) {
if (IsPackageNameInternal $dependency.id) {
Write-Verbose "Replacing dependency $($dependency.id) version $($dependency.version) with $VersionString"
$dependency.version = $VersionString
}
}
$nuspecData.Save($file)
}
}
# Modifies the version numbers in autopkg files
function ModifyAutoPkgFiles($buildInfo)
{
Foreach ($file in GetFileWrapper "*.autopkg")
{
Write-Verbose $file
$newContent = ""
Foreach ($line in Get-Content $file)
{
# Match line of the form "<whitespace?>version<whitespace?>:<whitespace?><versionString><whitespace?><semicolon>"
if ($line -match "(\s+)?(version)(\s+)?:(\s+)?([\S\.]+)(\s+)?;")
{
Write-Verbose "Replacing $oldVersion with $VersionString"
$line = $line.Replace($matches[5], $VersionString)
}
# Match dependency line of the form "Microsoft.Lift.*/<version>;" or "Microsoft.Lift.*/<version>,"
elseif ($line -match "^\s+(\S+?)\/([0-9\.]+)[;,]$" -and (IsPackageNameInternal $matches[1]))
{
$packageName = $matches[1]
$oldVersion = $matches[2]
Write-Verbose "Replacing dependency $packageName version $oldVersion with $VersionString"
$line = $line.Replace($oldVersion, $VersionString)
}
# Match "releaseNotes" line which uses a string enclosed in double-quotes with an optional at symbol at the start
elseif ($line -match "(\s+)?(releaseNotes)(\s+)?:(\s+)?(@)?\""(.*)\""(\s+)?;")
{
# Replace releaseNotes with new value (the build info). We don't do a blind replace of the old release notes with the new because that fails if
# the existing release notes are a substring that is found elsewhere in the line. Instead we reconstruct the string, including whitespace and
# optional @ symbol, but replacing the current release notes section with the new one.
Write-Verbose "Replacing release notes with: $buildInfo"
$line = "$($matches[1])$($matches[2])$($matches[3]):$($matches[4])$($matches[5])""$buildInfo""$($matches[7]);"
}
$newContent += "$line`n"
}
Set-Content $file $newContent
}
}
function IsPackageNameInternal([String]$packageName) {
return $packageName.StartsWith("Microsoft.Lift")
}
# Writes Version.h file in nuspec files
# [void] prevents stringBuilder.Append from outputting capacity/length information
function WriteVersionHeader
{
$outPath = $SourceDirectory + "\Built\Int\";
$outFile = $outPath + "SpectreVersionInternal.h";
# This just writes SpectreVersionInternal.h into the intermediate folder
Write-Verbose "Writing $outFile with SPECTRE_PACKAGE_VERSION = $VersionString"
# just overwrite the whole .h file
$stringBuilder = New-Object System.Text.StringBuilder
[void]$stringBuilder.Append("// Copyright (c) Microsoft Corporation. All rights reserved." + [Environment]::NewLine)
[void]$stringBuilder.Append("// Licensed under the MIT License." + [Environment]::NewLine)
[void]$stringBuilder.Append([Environment]::NewLine)
[void]$stringBuilder.Append("#pragma once" + [Environment]::NewLine)
[void]$stringBuilder.Append([Environment]::NewLine)
[void]$stringBuilder.Append("// This file is autogenerated by VersionModifier.ps1" + [Environment]::NewLine)
[void]$stringBuilder.Append([Environment]::NewLine)
[void]$stringBuilder.Append("#define SPECTRE_PACKAGE_VERSION " + '"' + $VersionString + '"' + [Environment]::NewLine)
$item = New-Item $outPath -ItemType Directory -Force
Out-File -encoding "UTF8" -filepath $outFile -inputobject $stringBuilder.ToString() -force
}
# This function is a wrapper around Get-ChildItem so we can mock the return
function GetFileWrapper($searchPattern)
{
$files = Get-ChildItem $SourceDirectory -Recurse -Include $searchPattern
$fileNames = $files | Foreach-Object { $_.FullName }
return $fileNames | Where-Object { ! (ShouldIgnoreFile $_) }
}
function ShouldIgnoreFile($fileName)
{
foreach ($excludeFolder in ($ExcludeFolders.Split(";") | Where-Object { $_ }))
{
if ($fileName.Contains($excludeFolder))
{
Write-Verbose "Ignoring $fileName due to exclusion folder $ignore"
return $true
}
}
return $false
}
Main

Просмотреть файл

@ -0,0 +1,92 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
<#
.SYNOPSIS
Build the Windows solutions from the command line.
.DESCRIPTION
Builds the Visual Studio projects generated by wininit.ps1
.PARAMETER NoNuGet
Disable build of NuGet packages
.EXAMPLE
winbuild.ps1
#>
[CmdletBinding()]
param(
[switch]$NoNuGet,
[switch]$NoArm,
[switch]$Nox64,
[switch]$NoWin32,
[switch]$NoDebug,
[switch]$NoRelease
)
$ErrorActionPreference = "stop"
function BuildPlatform($folder)
{
Write-Host "Build $folder"
Push-Location "$PSScriptRoot/../../Built/Int/$folder"
try
{
if (!$NoDebug)
{
cmake --build . --target install --config Debug
}
if (!$NoRelease)
{
cmake --build . --target install --config Release
}
}
finally
{
Pop-Location
}
}
function BuildNuGet()
{
#nuget pack $PSScriptRoot/GLTFSDK/GLTFSDK.macOS.CPP.nuspec -OutputDirectory $PSScriptRoot/Built/Out/NuGet
try
{
# You must install CoApp for this to work.
# See http://coapp.org/tutorials/installation.html
# Also, if it still doesn't work, try this https://github.com/appveyor/ci/issues/1446
Write-NuGetPackage $PSScriptRoot/../../GLTFSDK/GLTFSDK.Windows.CPP.autopkg
}
catch
{
Write-Error "Unable to generate NuGet package. Check that you have CoApp installed."
}
}
function Main()
{
if (!$NoWin32)
{
BuildPlatform "cmake_win32"
}
if (!$Nox64)
{
BuildPlatform "cmake_x64"
}
if (!$NoArm)
{
BuildPlatform "cmake_arm"
}
if (!$NoNuGet)
{
BuildNuGet
}
}
Main

79
Build/Scripts/wininit.ps1 Normal file
Просмотреть файл

@ -0,0 +1,79 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
<#
.SYNOPSIS
Setup the Visual Studio solution for building on Windows.
This should be run after every git pull or clean and should be safe to run any time.
.DESCRIPTION
Runs the cmake build required to generate the solutions for building all variants of the GLTFSDK on Windows.
Regenerates SpectreVersionInternal.h
.PARAMETER Clean
Clean the output folders before building
.EXAMPLE
wininit.ps1
#>
[CmdletBinding()]
param(
[switch]$Clean,
[switch]$NoArm,
[switch]$Nox64,
[switch]$NoWin32
)
$ErrorActionPreference = "stop"
function CleanFiles()
{
Remove-Item "$PSScriptRoot/../../Built" -Recurse -Force -ErrorAction Ignore | Write-Host
Remove-Item "$PSScriptRoot/../../packages" -Recurse -Force -ErrorAction Ignore | Write-Host
}
function GeneratePlatform($platform, $path)
{
Write-Host "Generate $platform Solution"
New-Item -Path "$PSScriptRoot/../../Built/Int" -Name $path -ItemType Directory -Force | Out-Null
Push-Location "$PSScriptRoot/../../Built/Int/$path" | Out-Null
try
{
$argList = @(
"-G", "Visual Studio 15 2017",
"-A", "$platform"
)
& cmake $argList "..\..\.."
}
finally
{
Pop-Location | Out-Null
}
}
function Main()
{
if ($Clean)
{
CleanFiles
}
if (!$NoWin32)
{
GeneratePlatform "Win32" "cmake_win32"
}
if (!$Nox64)
{
GeneratePlatform "x64" "cmake_x64"
}
if (!$NoArm)
{
GeneratePlatform "ARM" "cmake_arm"
}
}
Main

Просмотреть файл

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="rapidjson.tempRelease" version="0.0.2.20" targetFramework="native" />
</packages>

21
CMakeLists.txt Normal file
Просмотреть файл

@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.5)
project (GLTFSDK)
option(ENABLE_UNIT_TESTS "ENABLE_UNIT_TESTS" ON)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -D_DEBUG -DFEATURE_ASSERTS_ENABLED")
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.11)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Build/CMake/Modules")
add_subdirectory(External/RapidJSON)
add_subdirectory(External/googletest)
add_subdirectory(GLTFSDK)
if(ENABLE_UNIT_TESTS)
add_subdirectory(GLTFSDK.TestUtils)
add_subdirectory(GLTFSDK.Test)
endif()

28
External/RapidJSON/CMakeLists.txt поставляемый Normal file
Просмотреть файл

@ -0,0 +1,28 @@
# Download and unpack RapidJSON at configure time
configure_file(CMakeRapidJSONDownload.txt.in ${CMAKE_BINARY_DIR}/RapidJSON-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/RapidJSON-download )
if(result)
message(FATAL_ERROR "CMake step for RapidJSON failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/RapidJSON-download )
if(result)
message(FATAL_ERROR "Build step for RapidJSON failed: ${result}")
endif()
SET(RAPIDJSON_BUILD_TESTS OFF CACHE BOOL "Build rapidjson perftests and unittests." FORCE)
# Add RapidJSON directly to our build.
add_subdirectory(${CMAKE_BINARY_DIR}/RapidJSON-src
${CMAKE_BINARY_DIR}/RapidJSON-build
EXCLUDE_FROM_ALL)
# Set the RapidJSONConfig.cmake path and make find_package to work in config mode explicitly.
set(RapidJSON_DIR "${CMAKE_BINARY_DIR}/RapidJSON-build" CACHE LOCATION "Specific configuration file location")
find_package(RapidJSON REQUIRED CONFIG)
add_library(RapidJSON INTERFACE IMPORTED GLOBAL)
set_target_properties(RapidJSON PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${RapidJSON_INCLUDE_DIRS})

15
External/RapidJSON/CMakeRapidJSONDownload.txt.in поставляемый Normal file
Просмотреть файл

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 2.8.2)
project(RapidJSON-download NONE)
include(ExternalProject)
ExternalProject_Add(RapidJSON
GIT_REPOSITORY https://github.com/fergsatwork/rapidjson
GIT_TAG 631df504108378589c17ee7a1ff9b52790a537d8
SOURCE_DIR "${CMAKE_BINARY_DIR}/RapidJSON-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/RapidJSON-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

15
External/googletest/CMakeGoogleTestDownload.txt.in поставляемый Normal file
Просмотреть файл

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.8.0
SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

31
External/googletest/CMakeLists.txt поставляемый Normal file
Просмотреть файл

@ -0,0 +1,31 @@
# Download and unpack googletest at configure time
configure_file(CMakeGoogleTestDownload.txt.in ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
# Prevent overriding the parent project's compiler/linker
# settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src
${CMAKE_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
# The gtest/gtest_main targets carry header search path
# dependencies automatically when using CMake 2.8.11 or
# later. Otherwise we have to add them here ourselves.
if (CMAKE_VERSION VERSION_LESS 2.8.11)
include_directories("${gtest_SOURCE_DIR}/include")
endif()

Просмотреть файл

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<ItemsProjectGuid>{45d41acc-2c3c-43d2-bc10-02aa73ffc7c7}</ItemsProjectGuid>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectCapability Include="SourceItemsFromImports" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\AnimationUtils.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\BufferBuilder.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Color.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Deserialize.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Document.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Extension.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\ExtensionHandlers.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\ExtensionsKHR.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\GLBResourceReader.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\GLBResourceWriter.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\GLTFResourceWriter.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Math.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\MeshPrimitiveUtils.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\MicrosoftGeneratorVersion.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\PBRUtils.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\ResourceWriter.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Serialize.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Validation.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Version.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\AnimationUtils.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\BufferBuilder.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Color.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Constants.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Deserialize.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Document.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Exceptions.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Extension.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ExtensionHandlers.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ExtensionsKHR.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ExtrasDocument.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLBResourceReader.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLBResourceWriter.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLTF.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLTFResourceReader.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLTFResourceWriter.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\IStreamCache.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\IStreamReader.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\IStreamWriter.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\IndexedContainer.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Math.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\MeshPrimitiveUtils.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\MicrosoftGeneratorVersion.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\PBRUtils.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\RapidJsonUtils.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ResourceReaderUtils.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ResourceWriter.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Schema.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Serialize.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\StreamCache.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\StreamCacheLRU.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\StreamUtils.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Traverse.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Validation.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Version.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Visitor.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\SchemaValidation.h" />
</ItemGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\accessor.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\accessor.sparse.indices.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\accessor.sparse.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\accessor.sparse.values.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\animation.channel.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\animation.channel.target.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\animation.sampler.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\animation.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\asset.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\buffer.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\bufferView.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\camera.orthographic.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\camera.perspective.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\camera.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\extension.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\extras.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\glTF.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\glTFChildOfRootProperty.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\glTFProperty.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\glTFid.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\image.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\material.normalTextureInfo.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\material.occlusionTextureInfo.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\material.pbrMetallicRoughness.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\material.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\mesh.primitive.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\mesh.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\node.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\sampler.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\scene.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\skin.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\texture.schema.json" />
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\textureInfo.schema.json" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,299 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{5a13d977-5e8b-49dd-b668-963625ef9f63}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\GLTFSDK">
<UniqueIdentifier>{a70fdcf2-7d10-4464-92b9-354dca3e5455}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{aced3b92-d8be-4cbb-b67e-2fd30a9cf404}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\GLTFSDK">
<UniqueIdentifier>{2d9c059f-2d4b-4972-959d-466c338929c7}</UniqueIdentifier>
</Filter>
<Filter Include="Schema">
<UniqueIdentifier>{b291fdfc-80fc-4b07-9b60-64a6373f5409}</UniqueIdentifier>
</Filter>
<Filter Include="Schema\Extension">
<UniqueIdentifier>{f49e18b0-39bc-4049-8304-ab9683888d6f}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Private">
<UniqueIdentifier>{816bea1d-efce-4079-b7cf-2b5d838c9149}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\AnimationUtils.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\BufferBuilder.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Color.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Deserialize.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Document.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Extension.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\ExtensionHandlers.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\ExtensionsKHR.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\GLBResourceReader.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\GLBResourceWriter.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\GLTFResourceWriter.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Math.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\MeshPrimitiveUtils.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\MicrosoftGeneratorVersion.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\PBRUtils.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\ResourceWriter.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Serialize.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Validation.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\Version.cpp">
<Filter>Source Files\GLTFSDK</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\AnimationUtils.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Color.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Constants.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\BufferBuilder.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Deserialize.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Document.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Exceptions.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Extension.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ExtensionHandlers.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ExtensionsKHR.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ExtrasDocument.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLBResourceReader.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLBResourceWriter.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLTF.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLTFResourceReader.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\GLTFResourceWriter.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\IndexedContainer.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\IStreamReader.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\IStreamCache.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\IStreamWriter.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Math.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\MeshPrimitiveUtils.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\MicrosoftGeneratorVersion.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\PBRUtils.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\RapidJsonUtils.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ResourceReaderUtils.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\ResourceWriter.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Schema.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Serialize.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\StreamCache.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\StreamCacheLRU.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\StreamUtils.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Traverse.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Visitor.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Validation.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Source\SchemaValidation.h">
<Filter>Header Files\Private</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK\Inc\GLTFSDK\Version.h">
<Filter>Header Files\GLTFSDK</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\accessor.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\accessor.sparse.indices.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\accessor.sparse.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\accessor.sparse.values.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\animation.channel.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\animation.channel.target.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\animation.sampler.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\animation.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\asset.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\buffer.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\bufferView.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\camera.orthographic.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\camera.perspective.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\camera.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\extension.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\extras.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\glTF.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\glTFChildOfRootProperty.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\glTFProperty.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\glTFid.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\image.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\material.normalTextureInfo.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\material.occlusionTextureInfo.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\material.pbrMetallicRoughness.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\material.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\mesh.primitive.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\mesh.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\node.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\sampler.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\scene.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\skin.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\texture.schema.json">
<Filter>Schema</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)..\GLTFSDK\schema\textureInfo.schema.json">
<Filter>Schema</Filter>
</None>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,52 @@
cmake_minimum_required(VERSION 3.5)
project (GLTFSDK.Test)
include(GLTFPlatform)
GetGLTFPlatform(Platform)
file(GLOB source_files
"${CMAKE_CURRENT_LIST_DIR}/Source/*"
"${CMAKE_CURRENT_LIST_DIR}/*.h"
)
add_executable(GLTFSDK.Test ${source_files})
if (MSVC)
# Generate PDB files in all configurations, not just Debug (/Zi)
# Set warning level to 4 (/W4)
target_compile_options(GLTFSDK.Test PRIVATE "/Zi;/W4;/EHsc")
# Make sure that all PDB files on Windows are installed to the output folder. By default, only the debug build does this.
set_target_properties(GLTFSDK.Test PROPERTIES COMPILE_PDB_NAME "GLTFSDK.Test" COMPILE_PDB_OUTPUT_DIRECTORY "${RUNTIME_OUTPUT_DIRECTORY}")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(GLTFSDK.Test
PRIVATE "-Wunguarded-availability"
PRIVATE "-Wall"
PRIVATE "-Werror"
PUBLIC "-Wno-unknown-pragmas")
endif()
target_include_directories(GLTFSDK.Test
PUBLIC "${CMAKE_CURRENT_LIST_DIR}/Inc"
PRIVATE "${CMAKE_SOURCE_DIR}/Built/Int"
PRIVATE "${CMAKE_CURRENT_LIST_DIR}"
)
target_link_libraries(GLTFSDK.Test
GLTFSDK
gtest_main
RapidJSON
GLTFSDK.TestUtils
)
add_custom_command(TARGET GLTFSDK.Test
POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_LIST_DIR}/Resources" "${PROJECT_BINARY_DIR}/$<CONFIG>/Resources/"
)
AddGLTFIOSAppProperties(GLTFSDK.Test)
CreateGLTFInstallTargets(GLTFSDK.Test ${Platform})
install(FILES ${PROJECT_BINARY_DIR}/$<CONFIG>/Resources/ DESTINATION ${CMAKE_SOURCE_DIR}/Built/Out/${Platform}/$<CONFIG>/${PROJECT_NAME}/Resources)

Просмотреть файл

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F170B140-6AB9-4014-97D9-D897E0493CEC}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>GLTFSDKTest</RootNamespace>
<WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion>
<ProjectName>GLTFSDK.Test</ProjectName>
<TargetPlatform>$(Platform)</TargetPlatform>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries Condition="'$(Configuration)'=='Debug'">true</UseDebugLibraries>
<UseDebugLibraries Condition="'$(Configuration)'=='Release'">false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<GeneratedFilesDir>$(SolutionDir)Built\Int\$(PlatformToolset)\$(Platform)\$(Configuration)\$(MSBuildProjectName)\GeneratedFiles\</GeneratedFilesDir>
<LibPath>$(SolutionDir)Built\Out\$(PlatformToolset)\$(Platform)\$(Configuration)\</LibPath>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<UseOfMfc>false</UseOfMfc>
<WindowsAppContainer>false</WindowsAppContainer>
<CLRSupport>false</CLRSupport>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
</ImportGroup>
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<PropertyGroup>
<OutDir>$(SolutionDir)Built\Out\$(PlatformToolset)\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutDir>
<IntDir>$(SolutionDir)Built\Int\$(PlatformToolset)\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</IntDir>
</PropertyGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions Condition="'$(Platform)'=='ARM'">_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>USE_GOOGLE_TEST=0;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization Condition="'$(Configuration)'=='Release'">MaxSpeed</Optimization>
<FunctionLevelLinking Condition="'$(Configuration)'=='Release'">true</FunctionLevelLinking>
<IntrinsicFunctions Condition="'$(Configuration)'=='Release'">true</IntrinsicFunctions>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;$(ProjectDir);$(ProjectDir)Source\;$(IntermediateOutputPath);$(SolutionDir)GLTFSDK\Inc;$(SolutionDir)GLTFSDK.TestUtils;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<UseFullPaths>true</UseFullPaths>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<AdditionalOptions>/permissive- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding Condition="'$(Configuration)'=='Release'">true</EnableCOMDATFolding>
<OptimizeReferences Condition="'$(Configuration)'=='Release'">true</OptimizeReferences>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Source\TestResources.h" />
<ClInclude Include="Source\TestUtils.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Source\AnimationUtilsTests.cpp" />
<ClCompile Include="Source\ColorTests.cpp" />
<ClCompile Include="Source\ExtrasDocumentTests.cpp" />
<ClCompile Include="Source\GLTFExtensionsTests.cpp" />
<ClCompile Include="Source\glTFPropertyTests.cpp" />
<ClCompile Include="Source\GLTFResourceReaderTests.cpp" />
<ClCompile Include="Source\GLTFResourceWriterTests.cpp" />
<ClCompile Include="Source\GLTFSerializerTests.cpp" />
<ClCompile Include="Source\GLTFTests.cpp" />
<ClCompile Include="Source\IndexedContainerTests.cpp" />
<ClCompile Include="Source\MeshPrimitiveUtilsTests.cpp" />
<ClCompile Include="Source\MicrosoftGeneratorVersionTests.cpp" />
<ClCompile Include="Source\PBRUtilsTests.cpp" />
<ClCompile Include="Source\ResourceReaderUtilsTests.cpp" />
<ClCompile Include="Source\SerializeTests.cpp" />
<ClCompile Include="Source\StreamCacheTests.cpp" />
<ClCompile Include="Source\ValidationUnitTests.cpp" />
<ClCompile Include="Source\VersionTests.cpp" />
<ClCompile Include="Source\VisitorTests.cpp" />
<ClCompile Include="Source\stdafx.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Resources\glb\BoxInterleaved.glb" />
<None Include="Resources\glb\CubeInvalidAccessorByteLength.glb" />
<None Include="Resources\glb\CubeInvalidAccessorByteOffset.glb" />
<None Include="Resources\glb\CubeInvalidBufferViewLength.glb" />
<None Include="Resources\glb\CubeMissingTextureRef.glb" />
<None Include="Resources\glb\DuckMissingMaterialRef.glb" />
<None Include="Resources\glb\WrongBinHeaderLength.glb" />
<None Include="Resources\glb\WrongJsonLength.glb" />
<None Include="Resources\glb\WrongReportedLength.glb" />
<None Include="Resources\gltf\AnimatedMorphCube.gltf" />
<None Include="Resources\gltf\AnimatedTriangle.gltf" />
<None Include="Resources\gltf\CameraInvalidPerspective.gltf" />
<None Include="Resources\gltf\CameraInvalidProjection.gltf" />
<None Include="Resources\gltf\CameraMissingProperties.gltf" />
<None Include="Resources\gltf\CartoonCurse01Fbx.gltf" />
<None Include="Resources\gltf\Cube.gltf" />
<None Include="Resources\gltf\CubeWithLOD.gltf" />
<None Include="Resources\gltf\DoubleNodes.gltf" />
<None Include="Resources\gltf\DoubleTriangle.gltf" />
<None Include="Resources\gltf\DracoBox.gltf" />
<None Include="Resources\gltf\DuplicateNodes.gltf" />
<None Include="Resources\gltf\Mesh_PrimitivesUV_04.gltf" />
<None Include="Resources\gltf\MissingDefaultScene.gltf" />
<None Include="Resources\gltf\MissingMeshRef.gltf" />
<None Include="Resources\gltf\MissingNodeRef.gltf" />
<None Include="Resources\gltf\ReciprocatingSaw.gltf" />
<None Include="Resources\gltf\RiggedSimple.gltf" />
<None Include="Resources\gltf\SimpleSparseAccessor.gltf" />
<None Include="Resources\gltf\SinglePolyWithNormals.gltf" />
<None Include="Resources\gltf\SingleTriangle.gltf" />
<None Include="Resources\gltf\SingleTriangleWithTexture.gltf" />
<None Include="Resources\gltf\Transforms.gltf" />
<None Include="Resources\gltf\TriangleWithoutIndices.gltf" />
<None Include="Resources\gltf\TriangleWithoutIndices_Matrix.gltf" />
<None Include="Resources\gltf\TriangleWithoutIndices_TRS.gltf" />
<None Include="Resources\gltf\ValidCamera.gltf" />
<None Include="Resources\gltf\ValidCameraWithExtensions.gltf" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GLTFSDK\GLTFSDK.vcxproj">
<Project>{f656c078-7f2a-4753-9b92-5e959af80e26}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\rapidjson.tempRelease.0.0.2.20\build\native\rapidjson.tempRelease.targets" Condition="Exists('..\packages\rapidjson.tempRelease.0.0.2.20\build\native\rapidjson.tempRelease.targets')" />
<Import Project="..\packages\googletest.redist.1.8.2\build\native\googletest.redist.targets" Condition="Exists('..\packages\googletest.redist.1.8.2\build\native\googletest.redist.targets')" />
<Import Project="..\packages\googletest.1.8.2\build\native\googletest.targets" Condition="Exists('..\packages\googletest.1.8.2\build\native\googletest.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\rapidjson.tempRelease.0.0.2.20\build\native\rapidjson.tempRelease.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\rapidjson.tempRelease.0.0.2.20\build\native\rapidjson.tempRelease.targets'))" />
<Error Condition="!Exists('..\packages\googletest.redist.1.8.2\build\native\googletest.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\googletest.redist.1.8.2\build\native\googletest.redist.targets'))" />
<Error Condition="!Exists('..\packages\googletest.1.8.2\build\native\googletest.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\googletest.1.8.2\build\native\googletest.targets'))" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Source\TestResources.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="Source\TestUtils.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Source\AnimationUtilsTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\ExtrasDocumentTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\GLTFExtensionsTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\GLTFResourceReaderTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\GLTFResourceWriterTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\GLTFSerializerTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\GLTFTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\IndexedContainerTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\MeshPrimitiveUtilsTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\MicrosoftGeneratorVersionTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\PBRUtilsTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\ResourceReaderUtilsTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\SerializeTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\StreamCacheTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\ValidationUnitTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\VisitorTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\glTFPropertyTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\ColorTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Source\VersionTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Resources\gltf\ReciprocatingSaw.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\RiggedSimple.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\glb\BoxInterleaved.glb">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\glb\CubeInvalidAccessorByteLength.glb">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\glb\CubeInvalidAccessorByteOffset.glb">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\glb\CubeInvalidBufferViewLength.glb">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\glb\CubeMissingTextureRef.glb">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\glb\DuckMissingMaterialRef.glb">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\AnimatedMorphCube.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\AnimatedTriangle.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\CameraInvalidPerspective.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\CameraInvalidProjection.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\CameraMissingProperties.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\CartoonCurse01Fbx.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\CubeWithLOD.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\Cube.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\DoubleNodes.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\DoubleTriangle.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\DracoBox.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\DuplicateNodes.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\Mesh_PrimitivesUV_04.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\MissingDefaultScene.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\MissingMeshRef.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\MissingNodeRef.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\ReciprocatingSaw.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\RiggedSimple.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\SimpleSparseAccessor.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\SinglePolyWithNormals.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\SingleTriangle.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\SingleTriangleWithTexture.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\Transforms.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\TriangleWithoutIndices.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\TriangleWithoutIndices_TRS.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\TriangleWithoutIndices_Matrix.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\ValidCamera.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\gltf\ValidCameraWithExtensions.gltf">
<Filter>Resource Files</Filter>
</None>
<None Include="packages.config" />
<None Include="Resources\glb\WrongBinHeaderLength.glb" />
<None Include="Resources\glb\WrongJsonLength.glb" />
<None Include="Resources\glb\WrongReportedLength.glb" />
</ItemGroup>
</Project>

41
GLTFSDK.Test/Info.plist Normal file
Просмотреть файл

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.microsoft.GLTFSDK.Test</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

Двоичные данные
GLTFSDK.Test/Resources/glb/BoxInterleaved.glb Normal file

Двоичный файл не отображается.

Двоичные данные
GLTFSDK.Test/Resources/glb/CubeInvalidAccessorByteLength.glb Normal file

Двоичный файл не отображается.

Двоичные данные
GLTFSDK.Test/Resources/glb/CubeInvalidAccessorByteOffset.glb Normal file

Двоичный файл не отображается.

Двоичные данные
GLTFSDK.Test/Resources/glb/CubeInvalidBufferViewLength.glb Normal file

Двоичный файл не отображается.

Двоичные данные
GLTFSDK.Test/Resources/glb/CubeMissingTextureRef.glb Normal file

Двоичный файл не отображается.

Двоичные данные
GLTFSDK.Test/Resources/glb/DuckMissingMaterialRef.glb Normal file

Двоичный файл не отображается.

Двоичные данные
GLTFSDK.Test/Resources/glb/WrongBinHeaderLength.glb Normal file

Двоичный файл не отображается.

Двоичные данные
GLTFSDK.Test/Resources/glb/WrongJsonLength.glb Normal file

Двоичный файл не отображается.

Двоичные данные
GLTFSDK.Test/Resources/glb/WrongReportedLength.glb Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,282 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 24,
"type": "VEC3"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 24,
"type": "VEC4"
},
{
"bufferView": 2,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"max": [
0.0100000035,
0.0100000035,
0.01
],
"min": [
-0.0100000044,
-0.0100000054,
-0.01
]
},
{
"bufferView": 3,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"name": "thin"
},
{
"bufferView": 4,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"max": [
0.0,
0.01893253,
0.0
],
"min": [
0.0,
0.0,
0.0
],
"name": "thin"
},
{
"bufferView": 5,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"name": "thin"
},
{
"bufferView": 6,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"name": "angle"
},
{
"bufferView": 7,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"max": [
0.0,
0.0198908355,
0.0
],
"min": [
0.0,
0.0,
0.0
],
"name": "angle"
},
{
"bufferView": 8,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"name": "angle"
},
{
"bufferView": 9,
"componentType": 5123,
"count": 36,
"type": "SCALAR"
},
{
"bufferView": 10,
"componentType": 5126,
"count": 127,
"type": "SCALAR",
"max": [
4.19999743
],
"min": [
0.0
]
},
{
"bufferView": 11,
"componentType": 5126,
"count": 254,
"type": "SCALAR"
}
],
"animations": [
{
"channels": [
{
"sampler": 0,
"target": {
"node": 0,
"path": "weights"
}
}
],
"samplers": [
{
"input": 10,
"interpolation": "LINEAR",
"output": 11
}
],
"name": "Square"
}
],
"asset": {
"generator": "glTF Tools for Unity",
"version": "2.0"
},
"bufferViews": [
{
"buffer": 0,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 288,
"byteLength": 384
},
{
"buffer": 0,
"byteOffset": 672,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 960,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 1248,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 1536,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 1824,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 2112,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 2400,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 2688,
"byteLength": 72
},
{
"buffer": 0,
"byteOffset": 2760,
"byteLength": 508
},
{
"buffer": 0,
"byteOffset": 3268,
"byteLength": 1016
}
],
"buffers": [
{
"uri": "AnimatedMorphCube.bin",
"byteLength": 4284
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"NORMAL": 0,
"TANGENT": 1,
"POSITION": 2
},
"indices": 9,
"material": 0,
"targets": [
{
"NORMAL": 3,
"POSITION": 4,
"TANGENT": 5
},
{
"NORMAL": 6,
"POSITION": 7,
"TANGENT": 8
}
]
}
],
"weights": [
0.0,
0.0
],
"name": "Cube"
}
],
"materials": [
{
"pbrMetallicRoughness": {
"baseColorFactor": [
0.6038274,
0.6038274,
0.6038274,
1.0
],
"metallicFactor": 0.0,
"roughnessFactor": 0.5
},
"name": "Material"
}
],
"nodes": [
{
"mesh": 0,
"rotation": [
0.7071068,
0.0,
0.0,
0.7071067
],
"scale": [
100.0,
100.0,
100.0
],
"name": "AnimatedMorphCube"
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

Просмотреть файл

@ -0,0 +1,117 @@
{
"scenes" : [
{
"nodes" : [ 0 ]
}
],
"nodes" : [
{
"mesh" : 0,
"rotation" : [ 0.0, 0.0, 0.0, 1.0 ]
}
],
"meshes" : [
{
"primitives" : [ {
"attributes" : {
"POSITION" : 1
},
"indices" : 0
} ]
}
],
"animations": [
{
"samplers" : [
{
"input" : 2,
"interpolation" : "LINEAR",
"output" : 3
}
],
"channels" : [ {
"sampler" : 0,
"target" : {
"node" : 0,
"path" : "rotation"
}
} ]
}
],
"buffers" : [
{
"uri" : "simpleTriangle.bin",
"byteLength" : 44
},
{
"uri" : "animation.bin",
"byteLength" : 100
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 6,
"target" : 34963
},
{
"buffer" : 0,
"byteOffset" : 8,
"byteLength" : 36,
"target" : 34962
},
{
"buffer" : 1,
"byteOffset" : 0,
"byteLength" : 100
}
],
"accessors" : [
{
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 3,
"type" : "SCALAR",
"max" : [ 2 ],
"min" : [ 0 ]
},
{
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 3,
"type" : "VEC3",
"max" : [ 1.0, 1.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ]
},
{
"bufferView" : 2,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 5,
"type" : "SCALAR",
"max" : [ 1.0 ],
"min" : [ 0.0 ]
},
{
"bufferView" : 2,
"byteOffset" : 20,
"componentType" : 5126,
"count" : 5,
"type" : "VEC4",
"max" : [ 0.0, 0.0, 1.0, 1.0 ],
"min" : [ 0.0, 0.0, 0.0, -0.707 ]
}
],
"asset": {
"version": "2.0"
}
}

Просмотреть файл

@ -0,0 +1,59 @@
{
"scenes": [{"nodes": [0]}],
"scene": 0,
"nodes": [
{
"mesh": 0,
"translation": [1.1, 1.2, 1.3],
"rotation": [0.4, 0.5, 0.6, 0.7],
"scale": [1.8, 1.9, 2.0],
"camera": 0
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"cameras": [
{
"type": "perspective",
"perspective": {
"aspectRatio": 1.0,
"yfov": 0.7,
"zfar": 0.1,
"znear": 100.0
}
}
],
"asset": {"version": "2.0"}
}

Просмотреть файл

@ -0,0 +1,52 @@
{
"scenes": [{"nodes": [0]}],
"nodes": [
{
"mesh": 0,
"translation": [1.1, 1.2, 1.3],
"rotation": [0.4, 0.5, 0.6, 0.7],
"scale": [1.8, 1.9, 2.0],
"camera": 0
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"cameras": [
{
"type": "abc"
}
],
"asset": {"version": "2.0"}
}

Просмотреть файл

@ -0,0 +1,57 @@
{
"scenes": [{"nodes": [0]}],
"nodes": [
{
"mesh": 0,
"translation": [1.1, 1.2, 1.3],
"rotation": [0.4, 0.5, 0.6, 0.7],
"scale": [1.8, 1.9, 2.0],
"camera": 0
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"cameras": [
{
"type": "perspective",
"perspective": {
"aspectRatio": 1.0,
"yfov": 0.7,
"zfar": 100
}
}
],
"asset": {"version": "2.0"}
}

Просмотреть файл

@ -0,0 +1,208 @@
{
"asset": {
"version": "2.0",
"generator": "Microsoft GLTF Exporter 2.1.2-b21"
},
"accessors": [{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 8400,
"type": "SCALAR",
"max": [3267.0],
"min": [0.0]
}, {
"bufferView": 1,
"byteOffset": 0,
"componentType": 5126,
"count": 3268,
"type": "VEC3",
"max": [27.79158592224121, 32.51239013671875, 0.41070622205734255],
"min": [3.1008143424987795, 20.216293334960939, -0.010736359283328057]
}, {
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 3268,
"type": "VEC3",
"max": [0.9999998807907105, 0.9999997019767761, 1.0],
"min": [-0.9999969601631165, -0.9999884366989136, -1.0]
}, {
"bufferView": 3,
"byteOffset": 0,
"componentType": 5126,
"count": 3268,
"type": "VEC2",
"max": [0.9979999661445618, 0.9980000257492065],
"min": [0.0020000000949949028, 0.017852306365966798]
}
],
"bufferViews": [{
"buffer": 0,
"byteLength": 16800,
"byteOffset": 0,
"target": 34963
}, {
"buffer": 0,
"byteLength": 39216,
"byteOffset": 16800,
"target": 34962
}, {
"buffer": 0,
"byteLength": 39216,
"byteOffset": 56016,
"target": 34962
}, {
"buffer": 0,
"byteLength": 26144,
"byteOffset": 95232,
"target": 34962
}, {
"buffer": 0,
"byteLength": 160,
"byteOffset": 121376,
"target": 34962
}, {
"buffer": 0,
"byteLength": 151,
"byteOffset": 121536,
"target": 34962
}, {
"buffer": 0,
"byteLength": 151,
"byteOffset": 121687,
"target": 34962
}
],
"buffers": [{
"byteLength": 121838
}
],
"images": [{
"bufferView": 4,
"mimeType": "image/png"
}, {
"bufferView": 5,
"mimeType": "image/png"
}, {
"bufferView": 5,
"mimeType": "image/png"
}
],
"materials": [{
"pbrMetallicRoughness": {
"baseColorFactor": [1.0, 1.0, 1.0, 1.0],
"baseColorTexture": {
"index": 0
},
"metallicFactor": 0.0
},
"emissiveFactor": [0.0, 0.0, 0.0],
"name": "224570388",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseTexture": {
"index": 0
},
"specularFactor": [0.0, 0.0, 0.0],
"glossinessFactor": 0.0
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [1.0, 1.0, 1.0, 1.0],
"baseColorTexture": {
"index": 1
},
"metallicFactor": 0.0
},
"emissiveFactor": [0.0, 0.0, 0.0],
"name": "224570388",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseTexture": {
"index": 1
},
"specularFactor": [0.0, 0.0, 0.0],
"glossinessFactor": 0.0
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [1.0, 1.0, 1.0, 1.0],
"baseColorTexture": {
"index": 1
},
"metallicFactor": 0.0
},
"emissiveFactor": [0.0, 0.0, 0.0],
"name": "224570388",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseTexture": {
"index": 1
},
"specularFactor": [0.0, 0.0, 0.0],
"glossinessFactor": 0.0
}
}
}
],
"meshes": [{
"name": "mesh_id1002661519",
"primitives": [{
"attributes": {
"NORMAL": 2,
"POSITION": 1,
"TEXCOORD_0": 3
},
"indices": 0,
"material": 0,
"mode": 4
}
]
}
],
"nodes": [{
"children": [1],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "root"
}, {
"children": [3],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "node_id2706243136"
}, {
"matrix": [0.961675226688385, 1.534207266523736e-31, 3.509856737494502e-24, 0.0, 0.0, 0.961675226688385, -3.879194481506672e-15, 0.0, -3.649731636751502e-24, 4.033787735259475e-15, 0.9999998807907105, 0.0, -15.837821960449219, -37.99123001098633, -0.1999843865633011, 1.0],
"mesh": 0,
"name": "mesh_id1002661519"
}, {
"children": [2],
"matrix": [0.016822300851345063, 1.0026872665491738e-9, 6.139688401597998e-26, 0.0, -1.0026872665491738e-9, 0.016822300851345063, 7.353261333165051e-10, 0.0, 4.3828852970391818e-17, -7.353261333165051e-10, 0.016822300851345063, 0.0, 0.016546307131648065, 0.212588369846344, -1.2662132923639048e-41, 1.0],
"name": "node_id4156599471"
}
],
"samplers": [{
"minFilter": 9985
}
],
"scenes": [{
"nodes": [0]
}
],
"scene": 0,
"textures": [{
"name": "texture4066492519",
"sampler": 0,
"source": 0
}, {
"name": "texture4066492519",
"sampler": 0,
"source": 1
}, {
"name": "texture4066492519",
"sampler": 0,
"source": 1
}
],
"extensionsUsed": ["KHR_materials_pbrSpecularGlossiness"]
}

Просмотреть файл

@ -0,0 +1,124 @@
{
"asset": {
"version": "2.0",
"generator": "Microsoft GLTF Exporter 2.1.2-b21"
},
"accessors": [{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 36,
"type": "SCALAR",
"max": [23.0],
"min": [0.0]
}, {
"bufferView": 1,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"max": [1.0, 1.0, 1.0],
"min": [0.0, 0.0, 0.0]
}, {
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"max": [1.0, 1.0, 0.0],
"min": [-1.0, -1.0, -1.0]
}
],
"bufferViews": [{
"buffer": 0,
"byteLength": 72,
"byteOffset": 0,
"target": 34963
}, {
"buffer": 0,
"byteLength": 288,
"byteOffset": 72,
"target": 34962
}, {
"buffer": 0,
"byteLength": 288,
"byteOffset": 360,
"target": 34962
}
],
"buffers": [{
"byteLength": 648
}
],
"materials": [{
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}
],
"meshes": [{
"name": "polygon",
"primitives": [{
"attributes": {
"NORMAL": 2,
"POSITION": 1
},
"indices": 0,
"material": 0,
"mode": 4
}
]
}
],
"nodes": [{
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"mesh": 0,
"name": "polygon"
}, {
"children": [0],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "root"
}
],
"scenes": [{
"nodes": [1]
}
],
"scene": 0,
"extensionsUsed": ["KHR_materials_pbrSpecularGlossiness"]
}

Просмотреть файл

@ -0,0 +1,101 @@
{
"asset": {
"version": "2.0",
"generator": "Microsoft GLTF Exporter 2.1.2-b21"
},
"accessors": [{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 36,
"type": "SCALAR"
}, {
"bufferView": 1,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"type": "VEC3"
}, {
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"type": "VEC3"
}
],
"bufferViews": [{
"buffer": 0,
"byteLength": 72,
"byteOffset": 0,
"target": 34963
}, {
"buffer": 0,
"byteLength": 288,
"byteOffset": 72,
"target": 34962
}, {
"buffer": 0,
"byteLength": 288,
"byteOffset": 360,
"target": 34962
}
],
"buffers": [{
"byteLength": 648
}
],
"materials": [{
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}
],
"meshes": [{
"name": "polygon",
"primitives": [{
"attributes": {
"NORMAL": 2,
"POSITION": 1
},
"indices": 0,
"material": 0,
"mode": 4
}
]
}
],
"nodes": [{
"mesh": 0,
"name": "polygon"
}, {
"children": [0],
"name": "root",
"extensions": {
"MSFT_lod": {
"ids": [ 3 ]
}
}
}, {
"mesh": 0,
"name": "polygon_lod1"
}, {
"children": [2],
"name": "root_lod1"
}
],
"scenes": [{
"nodes": [1]
}
],
"scene": 0,
"extensionsUsed": ["KHR_materials_pbrSpecularGlossiness", "MSFT_lod"]
}

Просмотреть файл

@ -0,0 +1,211 @@
{
"asset": {
"version": "2.0",
"generator": "Microsoft GLTF Exporter 2.1.2-b21"
},
"accessors": [{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 3,
"type": "SCALAR",
"max": [2.0],
"min": [0.0]
}, {
"bufferView": 0,
"byteOffset": 6,
"componentType": 5123,
"count": 3,
"type": "SCALAR",
"max": [2.0],
"min": [0.0]
}, {
"bufferView": 1,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [1.0, 1.0, 1.0],
"min": [0.0, 0.0, 0.0]
}, {
"bufferView": 1,
"byteOffset": 36,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [4.0, 4.0, 4.0],
"min": [3.0, 3.0, 3.0]
}, {
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095],
"min": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095]
}, {
"bufferView": 2,
"byteOffset": 36,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095],
"min": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095]
}
],
"bufferViews": [{
"buffer": 0,
"byteLength": 12,
"byteOffset": 0,
"target": 34963
}, {
"buffer": 0,
"byteLength": 72,
"byteOffset": 12,
"target": 34962
}, {
"buffer": 0,
"byteLength": 72,
"byteOffset": 84,
"target": 34962
}
],
"buffers": [{
"byteLength": 156
}
],
"materials": [{
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material1",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material1",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material1",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material2",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material2",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material2",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}
],
"meshes": [{
"name": "triangle1",
"primitives": [{
"attributes": {
"NORMAL": 4,
"POSITION": 2
},
"indices": 0,
"material": 0,
"mode": 4
}
]
}, {
"name": "triangle2",
"primitives": [{
"attributes": {
"NORMAL": 5,
"POSITION": 3
},
"indices": 1,
"material": 3,
"mode": 4
}
]
}
],
"nodes": [{
"children": [2, 4],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "root"
}, {
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"mesh": 0,
"name": "triangle1"
}, {
"children": [1],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "node1"
}, {
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"mesh": 1,
"name": "triangle2"
}, {
"children": [3],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "node2"
}
],
"scenes": [{
"nodes": [0]
}
],
"scene": 0,
"extensionsUsed": ["KHR_materials_pbrSpecularGlossiness"]
}

Просмотреть файл

@ -0,0 +1,203 @@
{
"asset": {
"version": "2.0",
"generator": "Microsoft GLTF Exporter 2.1.2-b21"
},
"accessors": [{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 3,
"type": "SCALAR",
"max": [2.0],
"min": [0.0]
}, {
"bufferView": 0,
"byteOffset": 6,
"componentType": 5123,
"count": 3,
"type": "SCALAR",
"max": [2.0],
"min": [0.0]
}, {
"bufferView": 1,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [1.0, 1.0, 1.0],
"min": [0.0, 0.0, 0.0]
}, {
"bufferView": 1,
"byteOffset": 36,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [4.0, 4.0, 4.0],
"min": [3.0, 3.0, 3.0]
}, {
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095],
"min": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095]
}, {
"bufferView": 2,
"byteOffset": 36,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095],
"min": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095]
}
],
"bufferViews": [{
"buffer": 0,
"byteLength": 12,
"byteOffset": 0,
"target": 34963
}, {
"buffer": 0,
"byteLength": 72,
"byteOffset": 12,
"target": 34962
}, {
"buffer": 0,
"byteLength": 72,
"byteOffset": 84,
"target": 34962
}
],
"buffers": [{
"byteLength": 156
}
],
"materials": [{
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material1",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material1",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material1",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material2",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material2",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "Material2",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}
],
"meshes": [{
"name": "triangle1",
"primitives": [{
"attributes": {
"NORMAL": 4,
"POSITION": 2
},
"indices": 0,
"material": 0,
"mode": 4
}
]
}, {
"name": "triangle2",
"primitives": [{
"attributes": {
"NORMAL": 5,
"POSITION": 3
},
"indices": 1,
"material": 3,
"mode": 4
}
]
}
],
"nodes": [{
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"mesh": 0,
"name": "triangle1"
}, {
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"mesh": 1,
"name": "triangle2"
}, {
"children": [0, 1],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "root"
}
],
"scenes": [{
"nodes": [2]
}
],
"scene": 0,
"extensionsUsed": ["KHR_materials_pbrSpecularGlossiness"]
}

Просмотреть файл

@ -0,0 +1,143 @@
{
"asset": {
"generator": "COLLADA2GLTF",
"version": "2.0"
},
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"children": [
1
],
"matrix": [
1,
0,
0,
0,
0,
0,
-1,
0,
0,
1,
0,
0,
0,
0,
0,
1
]
},
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"NORMAL": 1,
"POSITION": 2
},
"indices": 0,
"mode": 4,
"material": 0,
"extensions": {
"KHR_draco_mesh_compression": {
"bufferView": 0,
"attributes": {
"NORMAL": 0,
"POSITION": 1
}
}
}
}
],
"name": "Mesh"
}
],
"accessors": [
{
"componentType": 5123,
"count": 36,
"max": [
23
],
"min": [
0
],
"type": "SCALAR"
},
{
"componentType": 5126,
"count": 24,
"max": [
1,
1,
1
],
"min": [
-1,
-1,
-1
],
"type": "VEC3"
},
{
"componentType": 5126,
"count": 24,
"max": [
0.5,
0.5,
0.5
],
"min": [
-0.5,
-0.5,
-0.5
],
"type": "VEC3"
}
],
"materials": [
{
"pbrMetallicRoughness": {
"baseColorFactor": [
0.800000011920929,
0,
0,
1
],
"metallicFactor": 0
},
"name": "Red"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 118
}
],
"buffers": [
{
"byteLength": 118,
"uri": "0.bin"
}
],
"extensionsRequired": [
"KHR_draco_mesh_compression"
],
"extensionsUsed": [
"KHR_draco_mesh_compression"
]
}

Просмотреть файл

@ -0,0 +1,34 @@
{
"nodes": [
{
"children": [0],
"meshes": [],
"matrix": [
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0
]
}
],
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 0
}

Просмотреть файл

@ -0,0 +1,222 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"name": "Normals Accessor"
},
{
"bufferView": 2,
"componentType": 5126,
"count": 3,
"type": "VEC4",
"name": "Tangents Accessor"
},
{
"bufferView": 3,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"name": "Colors Accessor"
},
{
"bufferView": 4,
"componentType": 5126,
"count": 3,
"type": "VEC2",
"name": "UV Accessor 0"
},
{
"bufferView": 5,
"componentType": 5126,
"count": 3,
"type": "VEC2",
"name": "UV Accessor 1"
},
{
"bufferView": 6,
"componentType": 5125,
"count": 3,
"type": "SCALAR",
"name": "Indices Accessor"
},
{
"bufferView": 7,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 8,
"componentType": 5125,
"count": 3,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0",
"extras": {
"Attributes": "Primitives_Split1 - Primitive0VertexUV0 - Primitive0VertexUV1 - VertexNormal - VertexTangent - VertexColor_Vector4_Float - NormalTexture - BaseColorTexture"
}
},
"buffers": [
{
"uri": "Mesh_PrimitivesUV_04.bin",
"byteLength": 264
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 36,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 36,
"byteLength": 36,
"name": "Normals"
},
{
"buffer": 0,
"byteOffset": 72,
"byteLength": 48,
"name": "Tangents"
},
{
"buffer": 0,
"byteOffset": 120,
"byteLength": 36,
"name": "Colors"
},
{
"buffer": 0,
"byteOffset": 156,
"byteLength": 24,
"name": "Texture Coords 0"
},
{
"buffer": 0,
"byteOffset": 180,
"byteLength": 24,
"name": "Texture Coords 1"
},
{
"buffer": 0,
"byteOffset": 204,
"byteLength": 12,
"name": "Indices"
},
{
"buffer": 0,
"byteOffset": 216,
"byteLength": 36,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 252,
"byteLength": 12,
"name": "Indices"
}
],
"images": [
{
"uri": "Textures/BaseColor_Plane.png"
},
{
"uri": "Textures/Normal_Plane.png"
}
],
"materials": [
{
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 0,
"texCoord": 1
}
},
"normalTexture": {
"index": 1,
"texCoord": 1
}
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0,
"NORMAL": 1,
"TANGENT": 2,
"COLOR_0": 3,
"TEXCOORD_0": 4,
"TEXCOORD_1": 5
},
"indices": 6,
"material": 0
},
{
"attributes": {
"POSITION": 7
},
"indices": 8
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"textures": [
{
"source": 0
},
{
"source": 1
}
]
}

Просмотреть файл

@ -0,0 +1,32 @@
{
"nodes": [
{
"matrix": [
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0
]
}
],
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 1
}

Просмотреть файл

@ -0,0 +1,33 @@
{
"nodes": [
{
"meshes": [0],
"matrix": [
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0
]
}
],
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 0
}

Просмотреть файл

@ -0,0 +1,34 @@
{
"nodes": [
{
"children": [1],
"meshes": [],
"matrix": [
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0
]
}
],
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 0
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,539 @@
{
"asset": {
"generator": "COLLADA2GLTF",
"version": "2.0"
},
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"children": [
4,
1
],
"matrix": [
1.0,
0.0,
0.0,
0.0,
0.0,
0.0,
-1.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
0.0,
1.0
]
},
{
"mesh": 0,
"skin": 0
},
{
"children": [
3
],
"translation": [
0.0,
-3.156060017772689e-7,
-4.1803297996521
],
"rotation": [
-0.7047404050827026,
-0.0,
-0.0,
-0.7094652056694031
],
"scale": [
1.0,
0.9999998807907105,
0.9999998807907105
]
},
{
"translation": [
0.0,
4.18717098236084,
0.0
],
"rotation": [
-0.0020521103870123626,
-9.94789530750495e-8,
-0.00029137087403796613,
-0.999997854232788
],
"scale": [
1.0,
1.0,
1.0000001192092896
]
},
{
"children": [
2
]
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"JOINTS_0": 1,
"NORMAL": 2,
"POSITION": 3,
"WEIGHTS_0": 4
},
"indices": 0,
"mode": 4,
"material": 0
}
],
"name": "Cylinder"
}
],
"animations": [
{
"channels": [
{
"sampler": 0,
"target": {
"node": 2,
"path": "translation"
}
},
{
"sampler": 1,
"target": {
"node": 2,
"path": "rotation"
}
},
{
"sampler": 2,
"target": {
"node": 2,
"path": "scale"
}
}
],
"samplers": [
{
"input": 5,
"interpolation": "LINEAR",
"output": 6
},
{
"input": 5,
"interpolation": "LINEAR",
"output": 7
},
{
"input": 5,
"interpolation": "LINEAR",
"output": 8
}
]
},
{
"channels": [
{
"sampler": 0,
"target": {
"node": 3,
"path": "translation"
}
},
{
"sampler": 1,
"target": {
"node": 3,
"path": "rotation"
}
},
{
"sampler": 2,
"target": {
"node": 3,
"path": "scale"
}
}
],
"samplers": [
{
"input": 9,
"interpolation": "LINEAR",
"output": 10
},
{
"input": 9,
"interpolation": "LINEAR",
"output": 11
},
{
"input": 9,
"interpolation": "LINEAR",
"output": 12
}
]
}
],
"skins": [
{
"inverseBindMatrices": 13,
"skeleton": 2,
"joints": [
2,
3
],
"name": "Armature"
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 564,
"max": [
95
],
"min": [
0
],
"type": "SCALAR"
},
{
"bufferView": 1,
"byteOffset": 0,
"componentType": 5123,
"count": 96,
"max": [
1,
1,
0,
0
],
"min": [
0,
0,
0,
0
],
"type": "VEC4"
},
{
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 96,
"max": [
0.998198390007019,
0.998198390007019,
0.6888381242752075
],
"min": [
-0.998198390007019,
-0.998198390007019,
-0.644473135471344
],
"type": "VEC3"
},
{
"bufferView": 2,
"byteOffset": 1152,
"componentType": 5126,
"count": 96,
"max": [
1.0,
1.0,
4.575077056884766
],
"min": [
-1.0,
-0.9999995827674866,
-4.575077056884766
],
"type": "VEC3"
},
{
"bufferView": 3,
"byteOffset": 0,
"componentType": 5126,
"count": 96,
"max": [
1.0,
0.261398196220398,
0.0,
0.0
],
"min": [
0.738601803779602,
0.0,
0.0,
0.0
],
"type": "VEC4"
},
{
"bufferView": 4,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"max": [
2.083333015441895
],
"min": [
0.04166661947965622
],
"type": "SCALAR"
},
{
"bufferView": 5,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"max": [
0.0,
-3.156060017772689e-7,
-4.1803297996521
],
"min": [
0.0,
-3.156060017772689e-7,
-4.1803297996521
],
"type": "VEC3"
},
{
"bufferView": 6,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"max": [
-0.7047404050827026,
-0.0,
-0.0,
-0.7094652056694031
],
"min": [
-0.7047404050827026,
-0.0,
-0.0,
-0.7094652056694031
],
"type": "VEC4"
},
{
"bufferView": 5,
"byteOffset": 36,
"componentType": 5126,
"count": 3,
"max": [
1.0,
0.9999998807907105,
0.9999998807907105
],
"min": [
1.0,
0.9999998807907105,
0.9999998807907105
],
"type": "VEC3"
},
{
"bufferView": 4,
"byteOffset": 12,
"componentType": 5126,
"count": 3,
"max": [
2.083333015441895
],
"min": [
0.04166661947965622
],
"type": "SCALAR"
},
{
"bufferView": 5,
"byteOffset": 72,
"componentType": 5126,
"count": 3,
"max": [
0.0,
4.18717098236084,
0.0
],
"min": [
0.0,
4.18717098236084,
0.0
],
"type": "VEC3"
},
{
"bufferView": 6,
"byteOffset": 48,
"componentType": 5126,
"count": 3,
"max": [
0.2933785021305084,
-9.94789530750495e-8,
-0.0002783441450446844,
-0.9559963345527648
],
"min": [
-0.0020521103870123626,
-0.00008614854596089572,
-0.00029137087403796613,
-0.999997854232788
],
"type": "VEC4"
},
{
"bufferView": 5,
"byteOffset": 108,
"componentType": 5126,
"count": 3,
"max": [
1.0,
1.0,
1.0000001192092896
],
"min": [
1.0,
1.0,
1.0000001192092896
],
"type": "VEC3"
},
{
"bufferView": 7,
"byteOffset": 0,
"componentType": 5126,
"count": 2,
"max": [
1.0,
0.0,
0.000001394809942212305,
0.0,
0.000002896920022976701,
0.006681859027594328,
-0.9999778270721436,
0.0,
0.0005827349959872663,
0.9999966025352478,
0.006681739818304777,
0.0,
0.0,
4.18023681640625,
0.02795993909239769,
1.0
],
"min": [
0.9999999403953552,
-0.0005827400018461049,
0.0,
0.0,
0.0,
0.002577662002295256,
-0.9999967217445374,
0.0,
0.0,
0.999977707862854,
0.002577601931989193,
0.0,
-0.000004012620138382772,
-0.006818830035626888,
0.027931740507483484,
1.0
],
"type": "MAT4"
}
],
"materials": [
{
"pbrMetallicRoughness": {
"baseColorFactor": [
0.27963539958000185,
0.6399999856948853,
0.21094390749931336,
1.0
],
"metallicFactor": 0.0
},
"emissiveFactor": [
0.0,
0.0,
0.0
],
"name": "Material_001-effect"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 5000,
"byteLength": 1128,
"target": 34963
},
{
"buffer": 0,
"byteOffset": 4208,
"byteLength": 768,
"byteStride": 8,
"target": 34962
},
{
"buffer": 0,
"byteOffset": 1904,
"byteLength": 2304,
"byteStride": 12,
"target": 34962
},
{
"buffer": 0,
"byteOffset": 224,
"byteLength": 1536,
"byteStride": 16,
"target": 34962
},
{
"buffer": 0,
"byteOffset": 4976,
"byteLength": 24
},
{
"buffer": 0,
"byteOffset": 1760,
"byteLength": 144
},
{
"buffer": 0,
"byteOffset": 128,
"byteLength": 96
},
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 128
}
],
"buffers": [
{
"byteLength": 6128,
"uri": "RiggedSimple0.bin"
}
]
}

Просмотреть файл

@ -0,0 +1,76 @@
{
"scenes" : [ {
"nodes" : [ 0 ]
} ],
"nodes" : [ {
"mesh" : 0
} ],
"meshes" : [ {
"primitives" : [ {
"attributes" : {
"POSITION" : 1
},
"indices" : 0
} ]
} ],
"buffers" : [ {
"uri" : "data:application/gltf-buffer;base64,AAAIAAcAAAABAAgAAQAJAAgAAQACAAkAAgAKAAkAAgADAAoAAwALAAoAAwAEAAsABAAMAAsABAAFAAwABQANAAwABQAGAA0AAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAQAAAAAAAAAAAAABAQAAAAAAAAAAAAACAQAAAAAAAAAAAAACgQAAAAAAAAAAAAADAQAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAQAAAgD8AAAAAAABAQAAAgD8AAAAAAACAQAAAgD8AAAAAAACgQAAAgD8AAAAAAADAQAAAgD8AAAAACAAKAAwAAAAAAIA/AAAAQAAAAAAAAEBAAABAQAAAAAAAAKBAAACAQAAAAAA=",
"byteLength" : 284
} ],
"bufferViews" : [ {
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 72,
"target" : 34963
}, {
"buffer" : 0,
"byteOffset" : 72,
"byteLength" : 168
}, {
"buffer" : 0,
"byteOffset" : 240,
"byteLength" : 6
}, {
"buffer" : 0,
"byteOffset" : 248,
"byteLength" : 36
} ],
"accessors" : [ {
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 36,
"type" : "SCALAR",
"max" : [ 13 ],
"min" : [ 0 ]
}, {
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 14,
"type" : "VEC3",
"max" : [ 6.0, 4.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ],
"sparse" : {
"count" : 3,
"indices" : {
"bufferView" : 2,
"byteOffset" : 0,
"componentType" : 5123
},
"values" : {
"bufferView" : 3,
"byteOffset" : 0
}
}
} ],
"asset" : {
"version" : "2.0"
}
}

Просмотреть файл

@ -0,0 +1,124 @@
{
"asset": {
"version": "2.0",
"generator": "Microsoft GLTF Exporter 2.1.2-b21"
},
"accessors": [{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 6,
"type": "SCALAR",
"max": [3.0],
"min": [0.0]
}, {
"bufferView": 1,
"byteOffset": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [1.0, 1.0, 1.0],
"min": [0.0, 0.0, 0.0]
}, {
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [0.5773502588272095, 0.5773502588272095, 0.5773502588272095],
"min": [0.0, 0.0, 0.0]
}
],
"bufferViews": [{
"buffer": 0,
"byteLength": 12,
"byteOffset": 0,
"target": 34963
}, {
"buffer": 0,
"byteLength": 48,
"byteOffset": 12,
"target": 34962
}, {
"buffer": 0,
"byteLength": 48,
"byteOffset": 60,
"target": 34962
}
],
"buffers": [{
"byteLength": 108
}
],
"materials": [{
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}
],
"meshes": [{
"name": "triangle",
"primitives": [{
"attributes": {
"NORMAL": 2,
"POSITION": 1
},
"indices": 0,
"material": 0,
"mode": 4
}
]
}
],
"nodes": [{
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"mesh": 0,
"name": "triangle"
}, {
"children": [0],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "root"
}
],
"scenes": [{
"nodes": [1]
}
],
"scene": 0,
"extensionsUsed": ["KHR_materials_pbrSpecularGlossiness"]
}

Просмотреть файл

@ -0,0 +1,124 @@
{
"asset": {
"version": "2.0",
"generator": "Microsoft GLTF Exporter 2.1.2-b21"
},
"accessors": [{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 3,
"type": "SCALAR",
"max": [2.0],
"min": [0.0]
}, {
"bufferView": 1,
"byteOffset": 2,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [1.0, 1.0, 1.0],
"min": [0.0, 0.0, 0.0]
}, {
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095],
"min": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095]
}
],
"bufferViews": [{
"buffer": 0,
"byteLength": 6,
"byteOffset": 0,
"target": 34963
}, {
"buffer": 0,
"byteLength": 38,
"byteOffset": 6,
"target": 34962
}, {
"buffer": 0,
"byteLength": 36,
"byteOffset": 44,
"target": 34962
}
],
"buffers": [{
"byteLength": 80
}
],
"materials": [{
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"specularFactor": [0.0, 0.0, 0.0]
}
}
}
],
"meshes": [{
"name": "triangle",
"primitives": [{
"attributes": {
"NORMAL": 2,
"POSITION": 1
},
"indices": 0,
"material": 0,
"mode": 4
}
]
}
],
"nodes": [{
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"mesh": 0,
"name": "triangle"
}, {
"children": [0],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "root"
}
],
"scenes": [{
"nodes": [1]
}
],
"scene": 0,
"extensionsUsed": ["KHR_materials_pbrSpecularGlossiness"]
}

Просмотреть файл

@ -0,0 +1,186 @@
{
"asset": {
"version": "2.0",
"generator": "Microsoft GLTF Exporter 2.1.2-b21"
},
"accessors": [{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 3,
"type": "SCALAR",
"max": [2.0],
"min": [0.0]
}, {
"bufferView": 1,
"byteOffset": 2,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [1.0, 1.0, 1.0],
"min": [0.0, 0.0, 0.0]
}, {
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3",
"max": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095],
"min": [-0.5773502588272095, -0.5773502588272095, -0.5773502588272095]
}
],
"bufferViews": [{
"buffer": 0,
"byteLength": 6,
"byteOffset": 0,
"target": 34963
}, {
"buffer": 0,
"byteLength": 38,
"byteOffset": 6,
"target": 34962
}, {
"buffer": 0,
"byteLength": 36,
"byteOffset": 44,
"target": 34962
}, {
"buffer": 0,
"byteLength": 205,
"byteOffset": 80,
"target": 34962
}, {
"buffer": 0,
"byteLength": 241,
"byteOffset": 285,
"target": 34962
}, {
"buffer": 0,
"byteLength": 181,
"byteOffset": 526,
"target": 34962
}
],
"buffers": [{
"byteLength": 707
}
],
"images": [{
"bufferView": 3,
"mimeType": "image/png"
}, {
"bufferView": 4,
"mimeType": "image/png"
}, {
"bufferView": 5,
"mimeType": "image/png"
}
],
"materials": [{
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"baseColorTexture": {
"index": 0
},
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"diffuseTexture": {
"index": 0
},
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"baseColorTexture": {
"index": 1
},
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"diffuseTexture": {
"index": 1
},
"specularFactor": [0.0, 0.0, 0.0]
}
}
}, {
"pbrMetallicRoughness": {
"baseColorFactor": [0.5187909007072449, 0.5187909007072449, 0.5187909007072449, 1.0],
"baseColorTexture": {
"index": 2
},
"metallicFactor": 0.0,
"roughnessFactor": 0.0
},
"name": "DefaultMaterial",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [0.49803921580314639, 0.49803921580314639, 0.49803921580314639, 1.0],
"diffuseTexture": {
"index": 2
},
"specularFactor": [0.0, 0.0, 0.0]
}
}
}
],
"meshes": [{
"name": "triangle",
"primitives": [{
"attributes": {
"NORMAL": 2,
"POSITION": 1
},
"indices": 0,
"material": 0,
"mode": 4
}
]
}
],
"nodes": [{
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"mesh": 0,
"name": "triangle"
}, {
"children": [0],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "root"
}
],
"samplers": [{
"minFilter": 9985
}
],
"scenes": [{
"nodes": [1]
}
],
"scene": 0,
"textures": [{
"name": "DefaultTexture",
"sampler": 0,
"source": 0
}, {
"name": "DefaultTexture",
"sampler": 0,
"source": 1
}, {
"name": "DefaultTexture",
"sampler": 0,
"source": 2
}
],
"extensionsUsed": ["KHR_materials_pbrSpecularGlossiness"]
}

Просмотреть файл

@ -0,0 +1,36 @@
{
"asset": {
"version": "2.0",
"generator": "Microsoft GLTF Exporter 2.1.2-b21"
},
"buffers": [{
"byteLength": 1
}
],
"nodes": [{
"children": [1],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "root"
}, {
"children": [2],
"matrix": [5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "Node#2"
}, {
"children": [3],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "Node#3"
}, {
"children": [4],
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0, 2.0, 2.0, 1.0],
"name": "Node#4"
}, {
"matrix": [1.0, 0.0, 0.0, 0.0, 0.0, -1.1920928955078126e-7, 0.9999998807907105, 0.0, 0.0, -0.9999998807907105, -1.1920928955078126e-7, 0.0, 0.0, 0.0, 0.0, 1.0],
"name": "Node#5"
}
],
"scenes": [{
"nodes": [0]
}
],
"scene": 0
}

Просмотреть файл

@ -0,0 +1,39 @@
{
"scenes": [{"nodes": [0]}],
"nodes": [{"mesh": 0}],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"asset": {"version": "2.0"}
}

Просмотреть файл

@ -0,0 +1,61 @@
{
"scenes": [{"nodes": [0]}],
"nodes": [
{
"mesh": 0,
"matrix": [
0.25001201033592226,
0.0,
0.0,
0.0,
0.0,
0.0,
-0.25001201033592226,
0.0,
0.0,
0.25001201033592226,
0.0,
0.0,
-0.004999999888241291,
0.0,
0.015750300139188768,
1.0
]
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"asset": {"version": "2.0"}
}

Просмотреть файл

@ -0,0 +1,46 @@
{
"scenes": [{"nodes": [0]}],
"nodes": [
{
"mesh": 0,
"translation": [1.1, 1.2, 1.3],
"rotation": [0.4, 0.5, 0.6, 0.7],
"scale": [1.8, 1.9, 2.0]
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"asset": {"version": "2.0"}
}

Просмотреть файл

@ -0,0 +1,71 @@
{
"scenes": [{"nodes": [0, 1]}],
"scene": 0,
"nodes": [
{
"mesh": 0,
"translation": [1.1, 1.2, 1.3],
"rotation": [0.4, 0.5, 0.6, 0.7],
"scale": [1.8, 1.9, 2.0],
"camera": 0
},
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"cameras": [
{
"type": "perspective",
"perspective": {
"aspectRatio": 1.0,
"yfov": 0.7,
"zfar": 100,
"znear": 0.01
}
},
{
"type": "orthographic",
"orthographic": {
"xmag": 1.0,
"ymag": 1.0,
"zfar": 100,
"znear": 0.01
}
}
],
"asset": {"version": "2.0"}
}

Просмотреть файл

@ -0,0 +1,80 @@
{
"scenes": [{"nodes": [0, 1]}],
"scene": 0,
"nodes": [
{
"mesh": 0,
"translation": [1.1, 1.2, 1.3],
"rotation": [0.4, 0.5, 0.6, 0.7],
"scale": [1.8, 1.9, 2.0],
"camera": 0
},
{
"mesh": 0,
"camera": 0
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"cameras": [
{
"type": "perspective",
"perspective": {
"yfov": 0.7,
"znear": 0.01,
"extensions": {
"abc": {
"diffuseTexture": {
"index": 1
},
"specularFactor": [0.0, 0.0, 0.0],
"glossinessFactor": 0.0
}
}
},
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseTexture": {
"index": 1
},
"specularFactor": [0.0, 0.0, 0.0],
"glossinessFactor": 0.0
}
}
}
],
"asset": {"version": "2.0"},
"extensionsUsed": ["abc", "KHR_materials_pbrSpecularGlossiness"]
}

Просмотреть файл

@ -0,0 +1,230 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <typeinfo>
#include <map>
#include <GLTFSDK/AnimationUtils.h>
#include <GLTFSDK/BufferBuilder.h>
#include <GLTFSDK/GLTF.h>
#include <GLTFSDK/GLTFResourceReader.h>
#include <GLTFSDK/GLTFResourceWriter.h>
#include "TestUtils.h"
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(AnimationUtilsTests)
{
GLTFSDK_TEST_METHOD(AnimationUtilsTests, AnimationUtils_Test_GetKeyframeTimes_Scalar_Float)
{
auto readerWriter = std::make_shared<const StreamReaderWriter>();
auto bufferBuilder = BufferBuilder(std::make_unique<GLTFResourceWriter>(readerWriter));
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
std::vector<float> input = { 0.000f, 0.100f, 0.200f, 0.300f };
auto accessor = bufferBuilder.AddAccessor(input, { TYPE_SCALAR, COMPONENT_FLOAT });
Document doc;
bufferBuilder.Output(doc);
GLTFResourceReader reader(readerWriter);
auto output = AnimationUtils::GetKeyframeTimes(doc, reader, accessor);
AreEqual(input, output);
}
GLTFSDK_TEST_METHOD(AnimationUtilsTests, AnimationUtils_Test_GetInverseBindMatrices_Mat4_Float)
{
auto readerWriter = std::make_shared<const StreamReaderWriter>();
auto bufferBuilder = BufferBuilder(std::make_unique<GLTFResourceWriter>(readerWriter));
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
std::vector<float> input = {
0.213941514f, 0.963860869f, -0.158749819f, 0.000000000f,
0.0374440104f, -0.170484781f, -0.984648883f, 0.000000000f,
-0.976128876f, 0.204712942f, -0.0725645721f, 0.000000000f,
-10.2514353f, -38.3263512f, 89.1614075f, 1.00000000f
};
auto accessor = bufferBuilder.AddAccessor(input, { TYPE_MAT4, COMPONENT_FLOAT });
Document doc;
bufferBuilder.Output(doc);
GLTFResourceReader reader(readerWriter);
auto output = AnimationUtils::GetInverseBindMatrices(doc, reader, accessor);
AreEqual(input, output);
}
GLTFSDK_TEST_METHOD(AnimationUtilsTests, AnimationUtils_Test_GetTranslations_Vec3_Float)
{
auto readerWriter = std::make_shared<const StreamReaderWriter>();
auto bufferBuilder = BufferBuilder(std::make_unique<GLTFResourceWriter>(readerWriter));
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
std::vector<float> input = {
0.213941514f, 0.963860869f, -0.158749819f
};
auto accessor = bufferBuilder.AddAccessor(input, { TYPE_VEC3, COMPONENT_FLOAT });
Document doc;
bufferBuilder.Output(doc);
// Accessor
GLTFResourceReader reader(readerWriter);
auto output = AnimationUtils::GetTranslations(doc, reader, accessor);
AreEqual(input, output);
// Sampler
AnimationSampler animationSampler;
animationSampler.outputAccessorId = accessor.id;
output = AnimationUtils::GetTranslations(doc, reader, animationSampler);
AreEqual(input, output);
}
GLTFSDK_TEST_METHOD(AnimationUtilsTests, AnimationUtils_Test_GetRotations_Vec4_Float)
{
auto readerWriter = std::make_shared<const StreamReaderWriter>();
auto bufferBuilder = BufferBuilder(std::make_unique<GLTFResourceWriter>(readerWriter));
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
std::vector<float> input = {
0.213941514f, 0.963860869f, -0.158749819f, 0.204712942f
};
auto accessor = bufferBuilder.AddAccessor(input, { TYPE_VEC4, COMPONENT_FLOAT });
Document doc;
bufferBuilder.Output(doc);
// Accessor
GLTFResourceReader reader(readerWriter);
auto output = AnimationUtils::GetRotations(doc, reader, accessor);
AreEqual(input, output);
// Sampler
AnimationSampler animationSampler;
animationSampler.outputAccessorId = accessor.id;
output = AnimationUtils::GetRotations(doc, reader, animationSampler);
AreEqual(input, output);
}
GLTFSDK_TEST_METHOD(AnimationUtilsTests, AnimationUtils_Test_GetScales_Vec3_Float)
{
auto readerWriter = std::make_shared<const StreamReaderWriter>();
auto bufferBuilder = BufferBuilder(std::make_unique<GLTFResourceWriter>(readerWriter));
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
std::vector<float> input = {
0.213941514f, 0.963860869f, 0.204712942f
};
auto accessor = bufferBuilder.AddAccessor(input, { TYPE_VEC3, COMPONENT_FLOAT });
Document doc;
bufferBuilder.Output(doc);
// Accessor
GLTFResourceReader reader(readerWriter);
auto output = AnimationUtils::GetScales(doc, reader, accessor);
AreEqual(input, output);
// Sampler
AnimationSampler animationSampler;
animationSampler.outputAccessorId = accessor.id;
output = AnimationUtils::GetScales(doc, reader, animationSampler);
AreEqual(input, output);
}
// Utility for verifying GetMorphWeights
template<typename T>
void VerifyGetMorphWeights()
{
std::map< std::type_index, ComponentType> componentTypeMap =
{
{ std::type_index(typeid(float)), COMPONENT_FLOAT },
{ std::type_index(typeid(int8_t)), COMPONENT_BYTE },
{ std::type_index(typeid(uint8_t)), COMPONENT_UNSIGNED_BYTE },
{ std::type_index(typeid(int16_t)), COMPONENT_SHORT },
{ std::type_index(typeid(uint16_t)), COMPONENT_UNSIGNED_SHORT }
};
std::vector<float> testValues = { 0.0f, 0.11f, 0.22f, 0.33f, 0.44f, 0.55f, 1.0f };
auto readerWriter = std::make_shared<const StreamReaderWriter>();
auto bufferBuilder = BufferBuilder(std::make_unique<GLTFResourceWriter>(readerWriter));
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
std::vector<T> input;
std::vector<float> expectedOutput;
for (auto& v : testValues)
{
auto c = AnimationUtils::FloatToComponent<T>(v);
input.push_back(c);
expectedOutput.push_back(AnimationUtils::ComponentToFloat(c));
}
auto accessor = bufferBuilder.AddAccessor(input, { TYPE_SCALAR, componentTypeMap[std::type_index(typeid(T))] });
Document doc;
bufferBuilder.Output(doc);
// Verify that we read back what's expected
std::stringstream ss;
ss << "Error extracting weights for component type " << typeid(T).name();
std::string s = ss.str();
std::wstring msg(s.begin(), s.end());
// Accessor
GLTFResourceReader reader(readerWriter);
auto output = AnimationUtils::GetMorphWeights(doc, reader, accessor);
AreEqual(expectedOutput, output, msg.c_str());
// Sampler
AnimationSampler animationSampler;
animationSampler.outputAccessorId = accessor.id;
output = AnimationUtils::GetMorphWeights(doc, reader, animationSampler);
AreEqual(expectedOutput, output, msg.c_str());
}
// Verify GetWeights for all possible component types
GLTFSDK_TEST_METHOD(AnimationUtilsTests, AnimationUtils_Test_GetMorphWeights)
{
VerifyGetMorphWeights<float>();
VerifyGetMorphWeights<int8_t>();
VerifyGetMorphWeights<uint8_t>();
VerifyGetMorphWeights<int16_t>();
VerifyGetMorphWeights<uint16_t>();
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,288 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/Color.h>
#include <cmath>
using namespace glTF::UnitTest;
namespace Microsoft
{
namespace glTF
{
std::wstring ToString(const Color3& color)
{
std::wstringstream ss;
ss << L"{ r = " << color.r;
ss << L", g = " << color.g;
ss << L", b = " << color.b << " }";
return ss.str();
}
std::wstring ToString(const Color4& color)
{
std::wstringstream ss;
ss << L"{ r = " << color.r;
ss << L", g = " << color.g;
ss << L", b = " << color.b;
ss << L", a = " << color.a << " }";
return ss.str();
}
namespace Test
{
GLTFSDK_TEST_CLASS(ColorTests)
{
GLTFSDK_TEST_METHOD(ColorTests, Color3Lerp)
{
const Color3 c1 = { 0.0f, 0.0f, 0.0f };
const Color3 c2 = { 1.0f, 1.0f, 1.0f };
{
Color3 cRes = Color3::Lerp(c1, c2, 0.0f);
Assert::AreEqual(c1, cRes, L"Color3::Lerp with interpolation amount of zero didn't equal the start value");
}
{
Color3 cRes = Color3::Lerp(c1, c2, 1.0f);
Assert::AreEqual(c2, cRes, L"Color3::Lerp with interpolation amount of one didn't equal the end value");
}
{
Color3 cRes = Color3::Lerp(c1, c2, 0.5f);
Assert::AreEqual({ 0.5f, 0.5f, 0.5f }, cRes, L"Color3::Lerp with interpolation amount of half didn't produce the expected result");
}
}
GLTFSDK_TEST_METHOD(ColorTests, Color4Lerp)
{
const Color4 c1 = { 0.0f, 0.0f, 0.0f, 0.0f };
const Color4 c2 = { 1.0f, 1.0f, 1.0f, 1.0f };
{
Color4 cRes = Color4::Lerp(c1, c2, 0.0f);
Assert::AreEqual(c1, cRes, L"Color4::Lerp with interpolation amount of zero didn't equal the start value");
}
{
Color4 cRes = Color4::Lerp(c1, c2, 1.0f);
Assert::AreEqual(c2, cRes, L"Color4::Lerp with interpolation amount of one didn't equal the end value");
}
{
Color4 cRes = Color4::Lerp(c1, c2, 0.5f);
Assert::AreEqual({ 0.5f, 0.5f, 0.5f, 0.5f }, cRes, L"Color4::Lerp with interpolation amount of half didn't produce the expected result");
}
}
GLTFSDK_TEST_METHOD(ColorTests, OperatorMultiply)
{
const Color3 c1 = { 0.0f, 1.0f, 2.0f };
const Color3 c2 = { 2.0f, 2.0f, 2.0f };
{
Color3 cRes = c1 * c2;
Assert::AreEqual({ 0.0f, 2.0f, 4.0f }, cRes, L"Operator: operator*(const Color3&, const Color3&) didn't produce the expected result");
}
{
Color3 cRes = c2 * c1; // Ensure operator is commutative
Assert::AreEqual({ 0.0f, 2.0f, 4.0f }, cRes, L"Operator: operator*(const Color3&, const Color3&) didn't produce the expected result");
}
{
Color3 cRes = c1 * 2.0f;
Assert::AreEqual({ 0.0f, 2.0f, 4.0f }, cRes, L"Operator: operator*(Color3, float) didn't produce the expected result");
}
{
Color3 cRes = 2.0f * c1;
Assert::AreEqual({ 0.0f, 2.0f, 4.0f }, cRes, L"Operator: operator*(float, Color3) didn't produce the expected result");
}
}
GLTFSDK_TEST_METHOD(ColorTests, OperatorDivide)
{
const Color3 c1 = { 0.0f, 1.0f, 2.0f };
const Color3 c2 = { 2.0f, 2.0f, 2.0f };
auto fnListsEqual = [](const std::initializer_list<float>& lhs, const std::initializer_list<float>& rhs)
{
return std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs), std::end(rhs));
};
{
Color3 cRes = c1 / c2;
Assert::AreEqual({ 0.0f, 0.5f, 1.0f }, cRes, L"Operator: operator/(const Color3&, const Color3&) didn't produce the expected result");
}
{
Color3 cRes = c2 / c1;
Assert::IsTrue(std::isinf(cRes.r)); // Test the red channel separately
Assert::IsTrue(fnListsEqual({ 2.0f, 1.0f }, { cRes.g, cRes.b }), L"Operator: operator/(const Color3&, const Color3&) didn't produce the expected result");
}
{
Color3 cRes = c1 / 2.0f;
Assert::AreEqual({ 0.0f, 0.5f, 1.0f }, cRes, L"Operator: operator/(Color3, float) didn't produce the expected result");
}
{
Color3 cRes = 2.0f / c1;
Assert::IsTrue(std::isinf(cRes.r)); // Test the red channel separately
Assert::IsTrue(fnListsEqual({ 2.0f, 1.0f }, { cRes.g, cRes.b }), L"Operator: operator/(float, Color3) didn't produce the expected result");
}
}
GLTFSDK_TEST_METHOD(ColorTests, OperatorAdd)
{
const Color3 c1 = { 0.0f, 1.0f, 2.0f };
const Color3 c2 = { 2.0f, 2.0f, 2.0f };
{
Color3 cRes = c1 + c2;
Assert::AreEqual({ 2.0f, 3.0f, 4.0f }, cRes, L"Operator: operator+(const Color3&, const Color3&) didn't produce the expected result");
}
{
Color3 cRes = c2 + c1; // Ensure operator is commutative
Assert::AreEqual({ 2.0f, 3.0f, 4.0f }, cRes, L"Operator: operator+(const Color3&, const Color3&) didn't produce the expected result");
}
{
Color3 cRes = c1 + 2.0f;
Assert::AreEqual({ 2.0f, 3.0f, 4.0f }, cRes, L"Operator: operator+(Color3, float) didn't produce the expected result");
}
{
Color3 cRes = 2.0f + c1;
Assert::AreEqual({ 2.0f, 3.0f, 4.0f }, cRes, L"Operator: operator+(float, Color3) didn't produce the expected result");
}
}
GLTFSDK_TEST_METHOD(ColorTests, OperatorSubtract)
{
const Color3 c1 = { 0.0f, 1.0f, 2.0f };
const Color3 c2 = { 2.0f, 2.0f, 2.0f };
{
Color3 cRes = c1 - c2;
Assert::AreEqual({ -2.0f, -1.0f, 0.0f }, cRes, L"Operator: operator-(const Color3&, const Color3&) didn't produce the expected result");
}
{
Color3 cRes = c2 - c1;
Assert::AreEqual({ 2.0f, 1.0f, 0.0f }, cRes, L"Operator: operator-(const Color3&, const Color3&) didn't produce the expected result");
}
{
Color3 cRes = c1 - 2.0f;
Assert::AreEqual({ -2.0f, -1.0f, 0.0f }, cRes, L"Operator: operator-(Color3, float) didn't produce the expected result");
}
{
Color3 cRes = 2.0f - c1;
Assert::AreEqual({ 2.0f, 1.0f, 0.0f }, cRes, L"Operator: operator-(float, Color3) didn't produce the expected result");
}
}
GLTFSDK_TEST_METHOD(ColorTests, Color3Clamp)
{
const Color3 c = { -1.0f, 0.0f, +1.0f };
{
Color3 cRes = Color3::Clamp(c, 0.0f, +1.0f);
Assert::AreEqual({ 0.0f, 0.0f, +1.0f }, cRes);
}
{
Color3 cRes = Color3::Clamp(c, -1.0f, 0.0f);
Assert::AreEqual({ -1.0f, 0.0f, 0.0f }, cRes);
}
{
Color3 cRes = Color3::Clamp(c, -0.5f, +0.5f);
Assert::AreEqual({ -0.5f, 0.0f, +0.5f }, cRes);
}
}
GLTFSDK_TEST_METHOD(ColorTests, Color4Clamp)
{
const Color4 c = { -1.0f, 0.0f, 0.0f, +1.0f };
{
Color4 cRes = Color4::Clamp(c, 0.0f, +1.0f);
Assert::AreEqual({ 0.0f, 0.0f, 0.0f, +1.0f }, cRes);
}
{
Color4 cRes = Color4::Clamp(c, -1.0f, 0.0f);
Assert::AreEqual({ -1.0f, 0.0f, 0.0f, 0.0f }, cRes);
}
{
Color4 cRes = Color4::Clamp(c, -0.5f, +0.5f);
Assert::AreEqual({ -0.5f, 0.0f, 0.0f, +0.5f }, cRes);
}
}
GLTFSDK_TEST_METHOD(ColorTests, Color3Uint32RGBA)
{
const Color3 cIn = {
static_cast<uint8_t>(0x3F),
static_cast<uint8_t>(0x1F),
static_cast<uint8_t>(0x0F)
};
const auto cValue = cIn.AsUint32RGBA(); // Alpha channel (MSB) is assigned 0xFF
Assert::AreEqual(0xFF0F1F3Fu, cValue);
const Color3 cOut = Color3::FromUint32RGBA(cValue);
Assert::AreEqual(cIn, cOut);
}
GLTFSDK_TEST_METHOD(ColorTests, Color4Uint32RGBA)
{
const Color4 cIn = {
static_cast<uint8_t>(0x7F),
static_cast<uint8_t>(0x3F),
static_cast<uint8_t>(0x1F),
static_cast<uint8_t>(0x0F)
};
const auto cValue = cIn.AsUint32RGBA();
Assert::AreEqual(0x0F1F3F7Fu, cValue);
const Color4 cOut = Color4::FromUint32RGBA(cValue);
Assert::AreEqual(cIn, cOut);
}
GLTFSDK_TEST_METHOD(ColorTests, Color3AsColor4)
{
{
const Color3 c3(0.25f, 0.35f, 0.45f);
const Color4 c4 = c3.AsColor4(); // The alpha channel should default to 1.0f
Assert::AreEqual({ 0.25f, 0.35f, 0.45f, 1.0f }, c4);
}
{
const Color3 c3(0.25f, 0.35f, 0.45f);
const Color4 c4 = c3.AsColor4(0.55f);
Assert::AreEqual({ 0.25f, 0.35f, 0.45f, 0.55f }, c4);
}
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,246 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/ExtrasDocument.h>
#include <GLTFSDK/Deserialize.h>
#include <GLTFSDK/Document.h>
#include <GLTFSDK/Serialize.h>
using namespace glTF::UnitTest;
namespace
{
static const char test_json_extras_object[] = R"(
{
"asset":
{
"version": "2.0"
},
"extras":
{
"propertyA": 1,
"propertyB": 1.23,
"propertyC": ["test1", "test2"]
}
}
)";
static const char test_json_extras_value[] = R"(
{
"asset":
{
"version": "2.0"
},
"extras": "testValue"
}
)";
static const char test_json_extras_none[] = R"(
{
"asset":
{
"version": "2.0"
}
}
)";
static const char test_json_extras_set_member[] = R"({"prop1":1,"prop2":"value","prop3":true})";
static const char test_json_extras_set_pointer[] = R"({"array":[true],"prop":{"propChild":1.23}})";
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(GLTFExtrasDocumentTests)
{
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentTest)
{
Document gltfDoc = Deserialize(test_json_extras_object);
ExtrasDocument extrasDoc(gltfDoc.extras.c_str());
const auto propValueA = extrasDoc.GetMemberValueOrDefault<uint32_t>("propertyA");
const auto propValueB = extrasDoc.GetMemberValueOrDefault<float>("propertyB");
const auto propValueC = extrasDoc.GetMemberValueOrDefault<float>("propertyMissing", 888.8f);
Assert::AreEqual(1U, propValueA);
Assert::AreEqual(1.23f, propValueB);
Assert::AreEqual(888.8f, propValueC);
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentPointer)
{
Document gltfDoc = Deserialize(test_json_extras_object);
ExtrasDocument extrasDoc(gltfDoc.extras.c_str());
const auto propValueA = extrasDoc.GetPointerValueOrDefault<std::string>("/propertyC/0");
const auto propValueB = extrasDoc.GetPointerValueOrDefault<std::string>("/propertyC/1");
const auto propValueC = extrasDoc.GetPointerValueOrDefault<std::string>("/propertyMissing/1", "missing!");
Assert::AreEqual("test1", propValueA.c_str());
Assert::AreEqual("test2", propValueB.c_str());
Assert::AreEqual("missing!", propValueC.c_str());
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentValue)
{
Document gltfDoc = Deserialize(test_json_extras_value);
ExtrasDocument extrasDoc(gltfDoc.extras.c_str());
const auto extraValue = extrasDoc.GetValueOrDefault<std::string>();
const auto extraMissing = extrasDoc.GetValueOrDefault<float>(444.4f);
Assert::AreEqual("testValue", extraValue.c_str());
Assert::AreEqual(444.4f, extraMissing);
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentNone)
{
Document gltfDoc = Deserialize(test_json_extras_none);
Assert::ExpectException<GLTFException>([&gltfDoc]()
{
ExtrasDocument extrasDoc(gltfDoc.extras.c_str());
}, L"Expected GLTFException to be thrown for an empty extras string");
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentSetValue)
{
{
ExtrasDocument extrasDoc;
extrasDoc.SetValue(1); // Integer value
Assert::AreEqual("1", Serialize(extrasDoc.GetDocument()).c_str());
}
{
ExtrasDocument extrasDoc;
extrasDoc.SetValue(1U); // Unsigned value
Assert::AreEqual("1", Serialize(extrasDoc.GetDocument()).c_str());
}
{
ExtrasDocument extrasDoc;
extrasDoc.SetValue(1.0f); // Float value
Assert::AreEqual("1.0", Serialize(extrasDoc.GetDocument()).c_str());
}
{
ExtrasDocument extrasDoc;
extrasDoc.SetValue(false); // Boolean value
Assert::AreEqual("false", Serialize(extrasDoc.GetDocument()).c_str());
}
{
ExtrasDocument extrasDoc;
extrasDoc.SetValue<const char*>("Test String"); // C-string value
Assert::AreEqual("\"Test String\"", Serialize(extrasDoc.GetDocument()).c_str());
}
{
ExtrasDocument extrasDoc;
extrasDoc.SetValue(std::string("Test String")); // std::string value
Assert::AreEqual("\"Test String\"", Serialize(extrasDoc.GetDocument()).c_str());
}
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentSetValueMultiple)
{
ExtrasDocument extrasDoc;
extrasDoc.SetValue(1);
extrasDoc.SetValue(2);
Assert::AreEqual("2", Serialize(extrasDoc.GetDocument()).c_str());
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentSetValueInvalidType)
{
ExtrasDocument extrasDoc;
Assert::ExpectException<GLTFException>([&extrasDoc]()
{
extrasDoc.SetValue(1);
extrasDoc.SetValue(false);
});
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentSetMemberValue)
{
ExtrasDocument extrasDoc;
extrasDoc.SetMemberValue("prop1", 1);
extrasDoc.SetMemberValue("prop2", std::string("value"));
extrasDoc.SetMemberValue("prop3", true);
Assert::AreEqual(test_json_extras_set_member, Serialize(extrasDoc.GetDocument()).c_str());
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentSetMemberValueMultiple)
{
ExtrasDocument extrasDoc;
extrasDoc.SetMemberValue("prop", 1);
extrasDoc.SetMemberValue("prop", 2);
Assert::AreEqual("{\"prop\":2}", Serialize(extrasDoc.GetDocument()).c_str());
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentSetMemberValueInvalidType)
{
ExtrasDocument extrasDoc;
Assert::ExpectException<GLTFException>([&extrasDoc]()
{
extrasDoc.SetValue(1);
extrasDoc.SetMemberValue("prop1", 1);
});
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentSetPointerValue)
{
ExtrasDocument extrasDoc;
extrasDoc.SetPointerValue("/array/0", true);
extrasDoc.SetPointerValue("/prop/propChild", 1.23);
Assert::AreEqual(test_json_extras_set_pointer, Serialize(extrasDoc.GetDocument()).c_str());
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentSetPointerValueMultiple)
{
ExtrasDocument extrasDoc;
extrasDoc.SetPointerValue("/prop", 1.23);
extrasDoc.SetPointerValue("/prop", 4.56);
Assert::AreEqual("{\"prop\":4.56}", Serialize(extrasDoc.GetDocument()).c_str());
}
GLTFSDK_TEST_METHOD(GLTFExtrasDocumentTests, ExtrasDocumentSetPointerValueInvalidType)
{
ExtrasDocument extrasDoc;
Assert::ExpectException<GLTFException>([&extrasDoc]()
{
extrasDoc.SetPointerValue("/prop", 1);
extrasDoc.SetPointerValue("/prop", false);
});
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,355 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/Deserialize.h>
#include <GLTFSDK/Extension.h>
#include <GLTFSDK/ExtensionHandlers.h>
#include <GLTFSDK/ExtensionsKHR.h>
#include <GLTFSDK/RapidJsonUtils.h>
#include <GLTFSDK/Serialize.h>
#include "TestResources.h"
#include "TestUtils.h"
#include <fstream>
using namespace glTF::UnitTest;
namespace
{
using namespace Microsoft::glTF;
constexpr static const char TestExtensionName[] = "TestExtension";
struct TestExtension : Extension
{
TestExtension(bool flag) : flag(flag) {}
std::unique_ptr<Extension> Clone() const override
{
return std::make_unique<TestExtension>(*this);
}
bool IsEqual(const Extension& rhs) const override
{
bool isEqual = false;
if (auto other = dynamic_cast<const TestExtension*>(&rhs))
{
isEqual = other->flag == flag;
}
return isEqual;
}
bool flag;
};
struct FakeExtension : Extension
{
std::unique_ptr<Extension> Clone() const override
{
throw GLTFException("Not implemented");
}
bool IsEqual(const Extension&) const override
{
throw GLTFException("Not implemented");
}
};
std::string SerializeTestExtension(const TestExtension& extension)
{
rapidjson::Document doc;
doc.SetObject();
doc.AddMember("flag", extension.flag, doc.GetAllocator());
rapidjson::StringBuffer sb;
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
doc.Accept(writer);
return sb.GetString();
}
std::unique_ptr<Extension> DeserializeTestExtension(const std::string& json)
{
return std::make_unique<TestExtension>(RapidJsonUtils::CreateDocumentFromString(json)["flag"].GetBool());
}
constexpr const char expectedExtensionAddHandler[] =
R"({
"asset": {
"version": "2.0"
},
"nodes": [
{
"extensions": {
"TestExtension": {
"flag": true
}
}
}
],
"scenes": [
{
"nodes": [
0
],
"extensions": {
"TestExtension": {
"flag": true
}
}
}
],
"scene": 0,
"extensions": {
"TestExtension": {
"flag": false
}
},
"extensionsUsed": [
"TestExtension"
]
})";
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(ExtensionsTests)
{
GLTFSDK_TEST_METHOD(ExtensionsTests, Extensions_Test_RoundTrip_And_Equality)
{
const auto inputJson = ReadLocalJson(c_cubeJson);
const auto extensionDeserializer = KHR::GetKHRExtensionDeserializer();
const auto extensionSerializer = KHR::GetKHRExtensionSerializer();
auto doc = Deserialize(inputJson, extensionDeserializer);
// Serialize Document back to json
auto outputJson = Serialize(doc, extensionSerializer);
auto outputDoc = Deserialize(outputJson, extensionDeserializer);
// Compare input and output Documents
Assert::IsTrue(doc == outputDoc, L"Input gltf and output gltf are not equal");
}
GLTFSDK_TEST_METHOD(ExtensionsTests, Extensions_Test_RoundTrip_And_Equality_Draco)
{
const auto inputJson = ReadLocalJson(c_dracoBox);
const auto extensionDeserializer = KHR::GetKHRExtensionDeserializer();
const auto extensionSerializer = KHR::GetKHRExtensionSerializer();
auto doc = Deserialize(inputJson, extensionDeserializer);
Assert::AreEqual(doc.meshes.Size(), size_t(1));
Assert::AreEqual(doc.meshes[0].primitives.size(), size_t(1));
Assert::AreEqual(doc.meshes[0].primitives[0].GetExtensions().size(), size_t(1));
auto draco = doc.meshes[0].primitives[0].GetExtension<KHR::MeshPrimitives::DracoMeshCompression>();
Assert::AreEqual<std::string>(draco.bufferViewId, "0");
Assert::AreEqual<size_t>(draco.attributes.size(), 2);
Assert::AreEqual<size_t>(draco.attributes[ACCESSOR_POSITION], 1);
Assert::AreEqual<size_t>(draco.attributes[ACCESSOR_NORMAL], 0);
// Serialize GLTFDocument back to json
auto outputJson = Serialize(doc, extensionSerializer);
auto outputDoc = Deserialize(outputJson, extensionDeserializer);
// Compare input and output GLTFDocuments
Assert::IsTrue(doc == outputDoc, L"Input gltf and output gltf are not equal");
}
GLTFSDK_TEST_METHOD(ExtensionsTests, Extensions_Test_GetExtension)
{
const auto inputJson = ReadLocalJson(c_cubeJson);
const auto extensionDeserializer = KHR::GetKHRExtensionDeserializer();
auto doc = Deserialize(inputJson, extensionDeserializer);
Assert::AreEqual(doc.materials.Size(), size_t(3));
Assert::AreEqual(doc.materials[0].extensions.size(), size_t(0));
Assert::AreEqual(doc.materials[0].GetExtensions().size(), size_t(1));
auto specGloss = doc.materials[0].GetExtension<KHR::Materials::PBRSpecularGlossiness>();
Assert::IsTrue(specGloss.specularFactor == Color3(.0f, .0f, .0f));
Assert::IsTrue(specGloss.diffuseFactor == Color4(.49803921580314639f, .49803921580314639f, .49803921580314639f, 1.0f));
}
GLTFSDK_TEST_METHOD(ExtensionsTests, Extensions_Test_RemoveExtension)
{
const auto inputJson = ReadLocalJson(c_cubeJson);
const auto extensionDeserializer = KHR::GetKHRExtensionDeserializer();
auto doc = Deserialize(inputJson, extensionDeserializer);
Assert::AreEqual(doc.materials.Size(), size_t(3));
Assert::AreEqual(doc.materials[0].extensions.size(), size_t(0));
Assert::AreEqual(doc.materials[0].GetExtensions().size(), size_t(1));
Material mat = doc.materials[0];
Assert::AreEqual(mat.GetExtensions().size(), size_t(1));
mat.RemoveExtension<KHR::Materials::PBRSpecularGlossiness>();
doc.materials.Replace(mat);
Assert::AreEqual(doc.materials[0].GetExtensions().size(), size_t(0));
}
GLTFSDK_TEST_METHOD(ExtensionsTests, Extensions_Test_HasExtension)
{
const auto inputJson = ReadLocalJson(c_cubeJson);
const auto extensionDeserializer = KHR::GetKHRExtensionDeserializer();
auto doc = Deserialize(inputJson, extensionDeserializer);
Assert::AreEqual(doc.materials.Size(), size_t(3));
Assert::AreEqual(doc.materials[0].extensions.size(), size_t(0));
Assert::AreEqual(doc.materials[0].GetExtensions().size(), size_t(1));
Assert::IsTrue(doc.materials[0].HasExtension<KHR::Materials::PBRSpecularGlossiness>());
Assert::IsFalse(doc.materials[0].HasExtension<FakeExtension>());
}
GLTFSDK_TEST_METHOD(ExtensionsTests, Extensions_Test_HasSpecGlossExtension)
{
const auto inputJson = ReadLocalJson(c_singleTriangleWithTextureJson);
const auto extensionDeserializer = KHR::GetKHRExtensionDeserializer();
auto doc = Deserialize(inputJson, extensionDeserializer);
Assert::IsTrue(doc.materials[0].HasExtension<KHR::Materials::PBRSpecularGlossiness>());
auto& specGloss = doc.materials[0].GetExtension<KHR::Materials::PBRSpecularGlossiness>();
Assert::AreEqual(specGloss.diffuseTexture.textureId.c_str(), "0");
Assert::IsTrue(specGloss.specularFactor == Color3(.0f, .0f, .0f));
}
GLTFSDK_TEST_METHOD(ExtensionsTests, ExtensionSerializerAddHandler)
{
Node node;
node.id = "0";
node.SetExtension<TestExtension>(true);
Scene scene;
scene.nodes.push_back(node.id);
scene.SetExtension<TestExtension>(true);
Document document;
document.nodes.Append(std::move(node));
document.SetDefaultScene(std::move(scene), AppendIdPolicy::GenerateOnEmpty);
document.SetExtension<TestExtension>(false);
document.extensionsUsed.emplace(TestExtensionName);
ExtensionSerializer extensionSerializer;
size_t handlerCountDocument = 0;
size_t handlerCountScene = 0;
size_t handlerCountAll = 0;
extensionSerializer.AddHandler<TestExtension, Document>(TestExtensionName,
[&handlerCountDocument](const TestExtension& extension, const Document&)
{
++handlerCountDocument;
return SerializeTestExtension(extension);
});
extensionSerializer.AddHandler<TestExtension, Scene>(TestExtensionName,
[&handlerCountScene](const TestExtension& extension, const Document&)
{
++handlerCountScene;
return SerializeTestExtension(extension);
});
// The 'all properties' handler will process the Node's extension
extensionSerializer.AddHandler<TestExtension>(TestExtensionName,
[&handlerCountAll](const TestExtension& extension, const Document&)
{
++handlerCountAll;
return SerializeTestExtension(extension);
});
Assert::IsTrue(extensionSerializer.HasHandler<TestExtension, Document>());
Assert::IsTrue(extensionSerializer.HasHandler<TestExtension, Scene>());
Assert::IsTrue(extensionSerializer.HasHandler<TestExtension>());
const auto actual = Serialize(document, extensionSerializer, SerializeFlags::Pretty);
Assert::AreEqual(size_t(1), handlerCountDocument, L"Document extension serializer handler called an unexpected number of times");
Assert::AreEqual(size_t(1), handlerCountScene, L"Scene extension serializer handler called an unexpected number of times");
Assert::AreEqual(size_t(1), handlerCountAll, L"Generic extension serializer handler called an unexpected number of times");
Assert::AreEqual(expectedExtensionAddHandler, actual.c_str(), L"Document and Scene extension serialization did not produce the expected output");
}
GLTFSDK_TEST_METHOD(ExtensionsTests, ExtensionDeserializerAddHandler)
{
ExtensionDeserializer extensionDeserializer;
size_t handlerCountDocument = 0;
size_t handlerCountScene = 0;
size_t handlerCountAll = 0;
extensionDeserializer.AddHandler<TestExtension, Document>(TestExtensionName,
[&handlerCountDocument](const std::string& json)
{
++handlerCountDocument;
return DeserializeTestExtension(json);
});
extensionDeserializer.AddHandler<TestExtension, Scene>(TestExtensionName,
[&handlerCountScene](const std::string& json)
{
++handlerCountScene;
return DeserializeTestExtension(json);
});
// The 'all properties' handler will process the Node's extension
extensionDeserializer.AddHandler<TestExtension>(TestExtensionName,
[&handlerCountAll](const std::string& json)
{
++handlerCountAll;
return DeserializeTestExtension(json);
});
Assert::IsTrue(extensionDeserializer.HasHandler<TestExtension, Document>());
Assert::IsTrue(extensionDeserializer.HasHandler<TestExtension, Scene>());
Assert::IsTrue(extensionDeserializer.HasHandler<TestExtension>());
const Document document = Deserialize(expectedExtensionAddHandler, extensionDeserializer);
Assert::AreEqual(size_t(1), handlerCountDocument, L"Document extension serializer handler called an unexpected number of times");
Assert::AreEqual(size_t(1), handlerCountScene, L"Scene extension serializer handler called an unexpected number of times");
Assert::AreEqual(size_t(1), handlerCountAll, L"Generic extension serializer handler called an unexpected number of times");
Assert::IsTrue(document.HasExtension<TestExtension>(), L"Document is missing TestExtension instance");
Assert::IsFalse(document.GetExtension<TestExtension>().flag, L"Document's TestExtension's flag property expected to be false");
const Scene& scene = document.GetDefaultScene();
Assert::IsTrue(scene.HasExtension<TestExtension>(), L"Scene is missing TestExtension instance");
Assert::IsTrue(scene.GetExtension<TestExtension>().flag, L"Scene's TestExtension's flag property expected to be true");
const Node& node = document.nodes.Get(scene.nodes.front());
Assert::IsTrue(node.HasExtension<TestExtension>(), L"Node is missing TestExtension instance");
Assert::IsTrue(node.GetExtension<TestExtension>().flag, L"Node's TestExtension's flag property expected to be true");
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,582 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/Deserialize.h>
#include <GLTFSDK/GLTFResourceReader.h>
#include "TestUtils.h"
using namespace glTF::UnitTest;
namespace
{
static const char test_json[] = R"(
{
"asset":
{
"version": "2.0"
},
"buffers": [
{
"byteLength": 8,
"uri": "buffer.bin"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 8,
"byteOffset": 0
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 1,
"type": "VEC2",
"max": [100.0, 100.0],
"min": [0.0, 0.0]
}
]
}
)";
static const char base64_json[] = R"(
{
"asset":
{
"version": "2.0"
},
"buffers": [
{
"byteLength": 18,
"uri": "data:application/octet-stream;base64,abcdagyhubcd+bzdtbcdab+d"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 8,
"byteOffset": 0
},
{
"buffer": 0,
"byteLength": 4,
"byteOffset": 12
}
],
"images": [
{
"bufferView": 1,
"mimeType": "image/jpeg"
},
{
"bufferView": 0,
"mimeType": "image/png"
}
]
}
)";
static const char sparse_json_uint8[] = R"(
{
"asset":
{
"version": "2.0"
},
"buffers": [
{
"byteLength": 16,
"uri": "buffer.bin"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 4
},
{
"buffer": 0,
"byteLength": 2,
"byteOffset": 4
},
{
"buffer": 0,
"byteLength": 10,
"byteOffset": 6
}
],
"accessors": [
{
"bufferView": 2,
"componentType": 5121,
"count": 5,
"type": "VEC2",
"max": [100.0, 100.0],
"min": [0.0, 0.0],
"sparse": {
"count": 2,
"indices": {
"bufferView": 1,
"componentType": 5121
},
"values": {
"bufferView": 0,
"byteOffset": 0
}
}
}
]
}
)";
static const char sparse_json_uint16[] = R"(
{
"asset":
{
"version": "2.0"
},
"buffers": [
{
"byteLength": 32,
"uri": "buffer.bin"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 8
},
{
"buffer": 0,
"byteLength": 4,
"byteOffset": 8
},
{
"buffer": 0,
"byteLength": 20,
"byteOffset": 12
}
],
"accessors": [
{
"bufferView": 2,
"componentType": 5123,
"count": 5,
"type": "VEC2",
"max": [100.0, 100.0],
"min": [0.0, 0.0],
"sparse": {
"count": 2,
"indices": {
"bufferView": 1,
"componentType": 5123
},
"values": {
"bufferView": 0
}
}
}
]
}
)";
static const char sparse_json_uint32[] = R"(
{
"asset":
{
"version": "2.0"
},
"buffers": [
{
"byteLength": 64,
"uri": "buffer.bin"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 16
},
{
"buffer": 0,
"byteLength": 8,
"byteOffset": 16
},
{
"buffer": 0,
"byteLength": 40,
"byteOffset": 24
}
],
"accessors": [
{
"bufferView": 2,
"componentType": 5125,
"count": 5,
"type": "VEC2",
"max": [100.0, 100.0],
"min": [0.0, 0.0],
"sparse": {
"count": 2,
"indices": {
"bufferView": 1,
"componentType": 5125
},
"values": {
"bufferView": 0
}
}
}
]
}
)";
static const char sparse_json_float[] = R"(
{
"asset":
{
"version": "2.0"
},
"buffers": [
{
"byteLength": 64,
"uri": "buffer.bin"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 16
},
{
"buffer": 0,
"byteLength": 8,
"byteOffset": 16
},
{
"buffer": 0,
"byteLength": 40,
"byteOffset": 24
}
],
"accessors": [
{
"bufferView": 2,
"componentType": 5126,
"count": 5,
"type": "VEC2",
"max": [100.0, 100.0],
"min": [0.0, 0.0],
"sparse": {
"count": 2,
"indices": {
"bufferView": 1,
"componentType": 5125
},
"values": {
"bufferView": 0
}
}
}
]
}
)";
static const char sparse_json_interleaved[] = R"(
{
"asset":
{
"version": "2.0"
},
"buffers": [
{
"byteLength": 32,
"uri": "buffer.bin"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 8,
"byteStride": 4
},
{
"buffer": 0,
"byteLength": 8,
"byteOffset": 8,
"byteStride": 4
},
{
"buffer": 0,
"byteLength": 16,
"byteOffset": 16,
"byteStride": 4
}
],
"accessors": [
{
"bufferView": 2,
"componentType": 5121,
"count": 4,
"type": "VEC2",
"max": [100.0, 100.0],
"min": [0.0, 0.0],
"sparse": {
"count": 2,
"indices": {
"bufferView": 1,
"componentType": 5121
},
"values": {
"bufferView": 0,
"byteOffset": 0
}
}
}
]
}
)";
static const char sparse_emptybufferview_json[] = R"(
{
"asset":
{
"version": "2.0"
},
"buffers": [
{
"byteLength": 6,
"uri": "buffer.bin"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 4
},
{
"buffer": 0,
"byteLength": 2,
"byteOffset": 4
}
],
"accessors": [
{
"componentType": 5121,
"count": 5,
"type": "VEC2",
"max": [100.0, 100.0],
"min": [0.0, 0.0],
"sparse": {
"count": 2,
"indices": {
"bufferView": 1,
"componentType": 5121
},
"values": {
"bufferView": 0,
"byteOffset": 0
}
}
}
]
}
)";
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(GLTFResourceReaderTests)
{
GLTFSDK_TEST_METHOD(GLTFResourceReaderTests, TestReadBinaryDataAccessor)
{
float f1 = 1.0f, f2 = 10.0f;
auto stream = std::make_shared<StreamReaderWriter>();
auto streamOutput = stream->GetOutputStream("buffer.bin");
streamOutput->write(reinterpret_cast<char*>(&f1), sizeof(f1));
streamOutput->write(reinterpret_cast<char*>(&f2), sizeof(f2));
Document gltfDoc = Deserialize(test_json);
auto gltfResourceReader = std::make_unique<GLTFResourceReader>(stream);
auto accessor = gltfDoc.accessors.Get("0");
auto accessorData = gltfResourceReader->ReadBinaryData<float>(gltfDoc, accessor);
Assert::AreEqual<size_t>(2U, accessorData.size());
Assert::AreEqual<float>(f1, accessorData[0]);
Assert::AreEqual<float>(f2, accessorData[1]);
}
GLTFSDK_TEST_METHOD(GLTFResourceReaderTests, TestReadBase64Image)
{
auto stream = std::make_shared<StreamReaderWriter>();
Document gltfDoc = Deserialize(base64_json);
auto gltfResourceReader = std::make_unique<GLTFResourceReader>(stream);
auto img1 = gltfResourceReader->ReadBinaryData(gltfDoc, gltfDoc.images.Get("0"));
auto img2 = gltfResourceReader->ReadBinaryData(gltfDoc, gltfDoc.images.Get("1"));
Assert::IsTrue(img1 == std::vector<uint8_t>{181, 183, 29, 105});
Assert::IsTrue(img2 == std::vector<uint8_t>{105, 183, 29, 106, 12, 161, 185, 183});
}
GLTFSDK_TEST_METHOD(GLTFResourceReaderTests, TestReadSparseAccessorUint8)
{
uint8_t inputBuffer[16] = { 3U, 3U, 3U, 3U, // the sparse values
1U, 3U, // the sparse indices
1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U }; // base bufferview
// expected sparse replacement output
std::vector<uint8_t> expectedReadOutput = { 1U, 1U, 3U, 3U, 1U, 1U, 3U, 3U, 1U, 1U };
auto stream = std::make_shared<StreamReaderWriter>();
auto streamOutput = stream->GetOutputStream("buffer.bin");
streamOutput->write(reinterpret_cast<char*>(&inputBuffer), 16);
Document gltfDoc = Deserialize(sparse_json_uint8);
auto gltfResourceReader = std::make_unique<GLTFResourceReader>(stream);
auto accessor = gltfDoc.accessors.Get("0");
auto output = gltfResourceReader->ReadBinaryData<uint8_t>(gltfDoc, accessor);
Assert::IsTrue(output == expectedReadOutput);
}
GLTFSDK_TEST_METHOD(GLTFResourceReaderTests, TestReadSparseAccessorUint16)
{
uint16_t inputBuffer[16] = { 3U, 3U, 3U, 3U, // the sparse values
1U, 3U, // the sparse indices
1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U }; // base bufferview
// expected sparse replacement output
std::vector<uint16_t> expectedReadOutput = { 1U, 1U, 3U, 3U, 1U, 1U, 3U, 3U, 1U, 1U };;
auto streamReaderWriter = std::make_shared<StreamReaderWriter>();
auto streamOutput = streamReaderWriter->GetOutputStream("buffer.bin");
streamOutput->write(reinterpret_cast<char*>(&inputBuffer), 32);
Document gltfDoc = Deserialize(sparse_json_uint16);
auto gltfResourceReader = std::make_unique<GLTFResourceReader>(streamReaderWriter);
auto accessor = gltfDoc.accessors.Get("0");
auto output = gltfResourceReader->ReadBinaryData<uint16_t>(gltfDoc, accessor);
Assert::IsTrue(output == expectedReadOutput);
}
GLTFSDK_TEST_METHOD(GLTFResourceReaderTests, TestReadSparseAccessorUint32)
{
uint32_t inputBuffer[16] = { 3U, 3U, 3U, 3U, // the sparse values
1U, 3U, // the sparse indices
1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U }; // base bufferview
std::vector<uint32_t> expectedReadOutput = { 1U, 1U, 3U, 3U, 1U, 1U, 3U, 3U, 1U, 1U };;
auto stream = std::make_shared<StreamReaderWriter>();
auto streamOutput = stream->GetOutputStream("buffer.bin");
streamOutput->write(reinterpret_cast<char*>(&inputBuffer), 64);
Document gltfDoc = Deserialize(sparse_json_uint32);
auto gltfResourceReader = std::make_unique<GLTFResourceReader>(stream);
auto accessor = gltfDoc.accessors.Get("0");
auto output = gltfResourceReader->ReadBinaryData<uint32_t>(gltfDoc, accessor);
Assert::IsTrue(output == expectedReadOutput);
}
GLTFSDK_TEST_METHOD(GLTFResourceReaderTests, TestReadSparseAccessorFloat)
{
auto stream = std::make_shared<StreamReaderWriter>();
auto streamOutput = stream->GetOutputStream("buffer.bin");
float valuesBuffer[4] = { 3.0, 3.0, 3.0, 3.0,}; // the sparse indices
streamOutput->write(reinterpret_cast<char*>(&valuesBuffer), 16);
uint32_t indicesBuffer[2] = {1U, 3U }; // the sparse indices
streamOutput->write(reinterpret_cast<char*>(&indicesBuffer), 8);
float floatInputBuffer[10] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
streamOutput->write(reinterpret_cast<char*>(&floatInputBuffer), 40);
// expected sparse replacement output
std::vector<float> expectedReadOutput = { 1.0, 1.0, 3.0, 3.0, 1.0, 1.0, 3.0, 3.0, 1.0, 1.0 };
Document gltfDoc = Deserialize(sparse_json_float);
auto gltfResourceReader = std::make_unique<GLTFResourceReader>(stream);
auto accessor = gltfDoc.accessors.Get("0");
auto output = gltfResourceReader->ReadBinaryData<float>(gltfDoc, accessor);
Assert::IsTrue(output == expectedReadOutput);
}
GLTFSDK_TEST_METHOD(GLTFResourceReaderTests, TestReadSparseAccessorInterleaved)
{
uint8_t inputBuffer[32] = { 3U, 3U, 0U, 0U, 3U, 3U, 0U, 0U,// the sparse values
1U, 0U, 0U, 0U, 3U, 0U, 0U, 0U,// the sparse indices
1U, 1U, 0U, 0U, 1U, 1U, 0U, 0U, 1U, 1U, 0U, 0U, 1U, 1U, 0U, 0U, }; // base bufferview
// expected sparse replacement output
std::vector<uint8_t> expectedReadOutput = { 1U, 1U, 3U, 3U, 1U, 1U, 3U, 3U};
auto stream = std::make_shared<StreamReaderWriter>();
auto streamOutput = stream->GetOutputStream("buffer.bin");
streamOutput->write(reinterpret_cast<char*>(&inputBuffer), 32);
Document gltfDoc = Deserialize(sparse_json_interleaved);
auto gltfResourceReader = std::make_unique<GLTFResourceReader>(stream);
auto accessor = gltfDoc.accessors.Get("0");
auto output = gltfResourceReader->ReadBinaryData<uint8_t>(gltfDoc, accessor);
Assert::IsTrue(output == expectedReadOutput);
}
GLTFSDK_TEST_METHOD(GLTFResourceReaderTests, TestReadSparseEmptyBufferViewAccessor)
{
uint8_t inputBuffer[6] = { 3U, 3U, 0U, 1U, // the sparse values
1U, 3U }; // the sparse indices
// expected sparse replacement output
std::vector<uint8_t> expectedReadOutput = { 0U, 0U, 3U, 3U, 0U, 0U, 0U, 1U, 0U, 0U };
auto stream = std::make_shared<StreamReaderWriter>();
auto streamOutput = stream->GetOutputStream("buffer.bin");
streamOutput->write(reinterpret_cast<char*>(&inputBuffer), 6);
Document gltfDoc = Deserialize(sparse_emptybufferview_json);
auto gltfResourceReader = std::make_unique<GLTFResourceReader>(stream);
auto accessor = gltfDoc.accessors.Get("0");
auto output = gltfResourceReader->ReadBinaryData<uint8_t>(gltfDoc, accessor);
Assert::IsTrue(output == expectedReadOutput);
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,780 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/BufferBuilder.h>
#include <GLTFSDK/Deserialize.h>
#include <GLTFSDK/GLTFResourceWriter.h>
#include <GLTFSDK/MeshPrimitiveUtils.h>
#include <GLTFSDK/Serialize.h>
#include "TestUtils.h"
#include <map>
using namespace glTF::UnitTest;
namespace
{
using namespace Microsoft::glTF;
template <typename T, size_t N>
static constexpr size_t ArrayCount(T(&)[N]) { return N; }
struct NullStreamBuf : std::streambuf
{
int overflow(int ch) override
{
++m_size; return traits_type::not_eof(ch);
}
size_t m_size = {};
};
struct NullStream : std::ostream
{
NullStream() : std::ostream(&m_streamBuf) {}
NullStreamBuf m_streamBuf;
};
struct TestStreamWriter : IStreamWriter
{
std::shared_ptr<std::ostream> GetOutputStream(const std::string& uri) const override
{
return m_streamMap.emplace(uri, std::make_shared<NullStream>()).first->second;
}
size_t GetBufferCount() const
{
return m_streamMap.size();
}
size_t GetBufferLength(size_t idx) const
{
auto mapIt = std::next(m_streamMap.begin(), idx);
return mapIt->second->m_streamBuf.m_size;
}
const std::string& GetBufferUri(size_t idx) const
{
auto mapIt = std::next(m_streamMap.begin(), idx);
return mapIt->first;
}
mutable std::map<std::string, std::shared_ptr<NullStream>> m_streamMap;
};
static const char expectedBufferBuilder[] =
R"({
"asset": {
"version": "2.0"
},
"accessors": [
{
"bufferView": 0,
"componentType": 5123,
"count": 3,
"type": "SCALAR"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 3,
"type": "VEC3"
},
{
"bufferView": 1,
"byteOffset": 36,
"componentType": 5126,
"count": 2,
"type": "VEC2"
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 6,
"target": 34963
},
{
"buffer": 0,
"byteOffset": 8,
"byteLength": 52,
"target": 34962
}
],
"buffers": [
{
"byteLength": 60,
"uri": "0.bin"
}
]
})";
static const char expectedBufferBuilderMultiple[] =
R"({
"asset": {
"version": "2.0"
},
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 4
},
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 4
}
],
"buffers": [
{
"byteLength": 4,
"uri": "0.bin"
},
{
"byteLength": 4,
"uri": "1.bin"
}
]
})";
static const char expectedBufferBuilderMultipleAccessor[] =
R"({
"asset": {
"version": "2.0"
},
"accessors": [
{
"bufferView": 0,
"componentType": 5121,
"count": 6,
"type": "SCALAR",
"max": [
3.0
],
"min": [
0.0
]
},
{
"bufferView": 1,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
1.0,
1.0,
0.0
],
"min": [
-1.0,
-1.0,
0.0
]
},
{
"bufferView": 1,
"byteOffset": 12,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.0,
0.0,
-1.0
],
"min": [
0.0,
0.0,
-1.0
]
},
{
"bufferView": 1,
"byteOffset": 24,
"componentType": 5126,
"count": 4,
"type": "VEC2",
"max": [
1.0,
1.0
],
"min": [
0.0,
0.0
]
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 6,
"target": 34963
},
{
"buffer": 0,
"byteOffset": 8,
"byteLength": 128,
"byteStride": 32,
"target": 34962
}
],
"buffers": [
{
"byteLength": 136,
"uri": "0.bin"
}
]
})";
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(GLTFResourceWriterTests)
{
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteBufferView)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<uint32_t> data = { 0U, 1U, 2U, 3U };
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 0;
bufferView.byteLength = data.size() * sizeof(uint32_t);
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
writer.Write(bufferView, data.data());
bufferView.id = "1";
bufferView.byteOffset = 16U;
writer.Write(bufferView, data.data());
Assert::AreEqual(static_cast<size_t>(1), streamWriter->GetBufferCount(), L"Unexpected number of buffers");
Assert::AreEqual(static_cast<size_t>(32), streamWriter->GetBufferLength(0U), L"Unexpected number of bytes written to buffer");
Assert::AreEqual("0.bin", streamWriter->GetBufferUri(0U).c_str(), L"Unexpected buffer uri");
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteBufferViewWithOffset)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<uint32_t> data(4, 0);
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 0;
bufferView.byteLength = data.size() * sizeof(uint32_t);
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
writer.Write(bufferView, data.data());
bufferView.id = "1";
bufferView.byteOffset = 16U + 8U;// Add an 8-byte offset so the GLTFResourceWriter must seek forward
writer.Write(bufferView, data.data());
Assert::AreEqual(static_cast<size_t>(1), streamWriter->GetBufferCount(), L"Unexpected number of buffers");
Assert::AreEqual(static_cast<size_t>(40), streamWriter->GetBufferLength(0U), L"Unexpected number of bytes written to buffer");
Assert::AreEqual("0.bin", streamWriter->GetBufferUri(0U).c_str(), L"Unexpected buffer uri");
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteBufferViewInvalidOffset)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<uint32_t> data(4, 0);
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 0;
bufferView.byteLength = data.size() * sizeof(uint32_t);
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
writer.Write(bufferView, data.data());
bufferView.id = "1";
bufferView.byteOffset = 0U;// Invalid offset- should be 16 (or greater)
Assert::ExpectException<InvalidGLTFException>([&]()
{
writer.Write(bufferView, data.data());
});
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteBufferViewMultipleBuffers)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<uint32_t> data1(4, 0);
std::vector<uint32_t> data2(8, 0);
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 0;
bufferView.byteLength = data1.size() * sizeof(uint32_t);
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
writer.Write(bufferView, data1.data());
bufferView.id = "1";
bufferView.bufferId = "1";
bufferView.byteLength = data2.size() * sizeof(uint32_t);
writer.Write(bufferView, data2.data());
Assert::AreEqual(static_cast<size_t>(2), streamWriter->GetBufferCount(), L"Unexpected number of buffers");
Assert::AreEqual(static_cast<size_t>(16), streamWriter->GetBufferLength(0U), L"Unexpected number of bytes written to buffer");
Assert::AreEqual(static_cast<size_t>(32), streamWriter->GetBufferLength(1U), L"Unexpected number of bytes written to buffer");
Assert::AreEqual("0.bin", streamWriter->GetBufferUri(0U).c_str(), L"Unexpected buffer uri");
Assert::AreEqual("1.bin", streamWriter->GetBufferUri(1U).c_str(), L"Unexpected buffer uri");
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteAccessor)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<float> data(4, 0.0);
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 0;
bufferView.byteLength = data.size() * sizeof(float);
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
Accessor accessor;
accessor.id = "0";
accessor.bufferViewId = "0";
accessor.byteOffset = 0;
accessor.componentType = ComponentType::COMPONENT_FLOAT;
accessor.type = AccessorType::TYPE_VEC4;
accessor.count = 1U;
writer.Write(bufferView, data.data(), accessor);
bufferView.id = "1";
bufferView.bufferId = "0";
bufferView.byteOffset = 16U;
accessor.id = "1";
accessor.bufferViewId = "1";
writer.Write(bufferView, data.data(), accessor);
Assert::AreEqual(static_cast<size_t>(1), streamWriter->GetBufferCount(), L"Unexpected number of buffers");
Assert::AreEqual(static_cast<size_t>(32), streamWriter->GetBufferLength(0U), L"Unexpected number of bytes written to buffer");
Assert::AreEqual("0.bin", streamWriter->GetBufferUri(0U).c_str(), L"Unexpected buffer uri");
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteAccessorWithOffset)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<float> data(4, 0.0);
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 0;
bufferView.byteLength = data.size() * sizeof(float);
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
Accessor accessor;
accessor.id = "0";
accessor.bufferViewId = "0";
accessor.byteOffset = 0;
accessor.componentType = ComponentType::COMPONENT_FLOAT;
accessor.type = AccessorType::TYPE_VEC2;
accessor.count = 1U;
writer.Write(bufferView, data.data(), accessor);
accessor.id = "1";
accessor.byteOffset = accessor.GetByteLength();// Offset the 2nd accessor by the size of the 1st
writer.Write(bufferView, data.data(), accessor);
Assert::AreEqual(static_cast<size_t>(1), streamWriter->GetBufferCount(), L"Unexpected number of buffers");
Assert::AreEqual(static_cast<size_t>(16), streamWriter->GetBufferLength(0U), L"Unexpected number of bytes written to buffer");
Assert::AreEqual("0.bin", streamWriter->GetBufferUri(0U).c_str(), L"Unexpected buffer uri");
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteAccessorWithAlignment)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<uint8_t> data1(3, 0);// 3 bytes - no alignment requirements
std::vector<uint16_t> data2(3, 0);// 6 bytes - must be 2-byte aligned -> 1 byte of padding needed (2 - (3 % 2) == 1)
std::vector<uint32_t> data3(3, 0);// 12 bytes - must be 4-byte aligned -> 2 bytes of padding needed (4 - ((3 + 6 + 1) % 4) == 2)
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 0;
bufferView.byteLength = data1.size() * sizeof(uint8_t);
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
Accessor accessor;
accessor.id = "0";
accessor.bufferViewId = "0";
accessor.byteOffset = 0;
accessor.componentType = ComponentType::COMPONENT_UNSIGNED_BYTE;
accessor.type = AccessorType::TYPE_VEC3;
accessor.count = 1U;
writer.Write(bufferView, data1.data(), accessor);
bufferView.id = "1";
bufferView.bufferId = "0";
bufferView.byteOffset = bufferView.byteOffset + bufferView.byteLength + 1U;// Add 1 byte of padding to ensure 2-byte alignment
bufferView.byteLength = data2.size() * sizeof(uint16_t);
accessor.id = "1";
accessor.bufferViewId = "1";
accessor.componentType = ComponentType::COMPONENT_UNSIGNED_SHORT;
writer.Write(bufferView, data2.data(), accessor);
bufferView.id = "2";
bufferView.bufferId = "0";
bufferView.byteOffset = bufferView.byteOffset + bufferView.byteLength + 2U;// Add 2 bytes of padding to ensure 4-byte alignment
bufferView.byteLength = data3.size() * sizeof(uint32_t);
accessor.id = "2";
accessor.bufferViewId = "2";
accessor.componentType = ComponentType::COMPONENT_UNSIGNED_INT;
writer.Write(bufferView, data3.data(), accessor);
Assert::AreEqual(static_cast<size_t>(1), streamWriter->GetBufferCount(), L"Unexpected number of buffers");
Assert::AreEqual(static_cast<size_t>(24), streamWriter->GetBufferLength(0U), L"Unexpected number of bytes written to buffer");
Assert::AreEqual("0.bin", streamWriter->GetBufferUri(0U).c_str(), L"Unexpected buffer uri");
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteAccessorWithOffsetAndAlignment)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<uint8_t> data1(2, 0);// 2 bytes - no alignment requirements
std::vector<uint32_t> data2(4, 0);// 16 bytes - must be 4-byte aligned -> 2 bytes of padding needed (4 - (2 % 4) == 2)
std::vector<uint32_t> data3(4, 0);// 16 bytes - must be 4-byte aligned -> 0 bytes of padding needed (4 - ((2 + 16 + 2) % 4) == 0)
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 0;
bufferView.byteLength = data1.size() * sizeof(uint8_t);
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
Accessor accessor;
accessor.id = "0";
accessor.bufferViewId = "0";
accessor.byteOffset = 0;
accessor.componentType = ComponentType::COMPONENT_UNSIGNED_BYTE;
accessor.type = AccessorType::TYPE_VEC2;
accessor.count = 1U;
writer.Write(bufferView, data1.data(), accessor);
bufferView.id = "1";
bufferView.bufferId = "0";
bufferView.byteOffset = bufferView.byteOffset + bufferView.byteLength + 2U;// Add 2 bytes of padding to ensure 4-byte alignment
bufferView.byteLength = (data2.size() * sizeof(uint32_t)) + (data3.size() * sizeof(uint32_t));// Pack accessors '1' & '2' into buffer view '1'
accessor.id = "1";
accessor.bufferViewId = "1";
accessor.componentType = ComponentType::COMPONENT_UNSIGNED_INT;
accessor.type = AccessorType::TYPE_VEC4;
writer.Write(bufferView, data2.data(), accessor);
accessor.id = "2";
accessor.bufferViewId = "1";
accessor.byteOffset = accessor.GetByteLength();// Offset the 2nd accessor by the size of the 1st
writer.Write(bufferView, data3.data(), accessor);
Assert::AreEqual(static_cast<size_t>(1), streamWriter->GetBufferCount(), L"Unexpected number of buffers");
Assert::AreEqual(static_cast<size_t>(36), streamWriter->GetBufferLength(0U), L"Unexpected number of bytes written to buffer");
Assert::AreEqual("0.bin", streamWriter->GetBufferUri(0U).c_str(), L"Unexpected buffer uri");
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteAccessorInvalidOffset)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<uint32_t> data(4, 0);
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 0;
bufferView.byteLength = data.size() * sizeof(uint32_t) + 1U;// Add an additional byte as the accessor's byteOffset is 1;
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
Accessor accessor;
accessor.id = "0";
accessor.bufferViewId = "0";
accessor.byteOffset = 1U;
accessor.componentType = ComponentType::COMPONENT_UNSIGNED_INT;
accessor.type = AccessorType::TYPE_SCALAR;
accessor.count = data.size();
Assert::ExpectException<InvalidGLTFException>([&]()
{
writer.Write(bufferView, data.data(), accessor);
});
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, WriteAccessorInvalidTotalOffset)
{
auto streamWriter = std::make_shared<const TestStreamWriter>();
GLTFResourceWriter writer(streamWriter);
std::vector<uint32_t> data(4, 0);
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferView.byteOffset = 1U;
bufferView.byteLength = data.size() * sizeof(uint32_t) + 5U;// Add an additional 5 bytes as the bufferView and accessor's byteOffsets are 1 and 4 respectively;
bufferView.target = BufferViewTarget::UNKNOWN_BUFFER;
Accessor accessor;
accessor.id = "0";
accessor.bufferViewId = "0";
accessor.byteOffset = sizeof(uint32_t);
accessor.componentType = ComponentType::COMPONENT_UNSIGNED_INT;
accessor.type = AccessorType::TYPE_SCALAR;
accessor.count = data.size();
Assert::ExpectException<InvalidGLTFException>([&]()
{
writer.Write(bufferView, data.data(), accessor);
});
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, BufferBuilderMultiple)
{
Document gltfDocument;
{
std::vector<char> data(4, '!');
BufferBuilder bufferBuilder(std::make_unique<GLTFResourceWriter>(std::make_unique<TestStreamWriter>()),
[&gltfDocument](const BufferBuilder& builder) { return std::to_string(gltfDocument.buffers.Size() + builder.GetBufferCount()); },
[&gltfDocument](const BufferBuilder& builder) { return std::to_string(gltfDocument.bufferViews.Size() + builder.GetBufferViewCount()); },
[&gltfDocument](const BufferBuilder& builder) { return std::to_string(gltfDocument.accessors.Size() + builder.GetAccessorCount()); });
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(data);
bufferBuilder.Output(gltfDocument);
}
{
std::vector<char> data(4, '?');
BufferBuilder bufferBuilder(std::make_unique<GLTFResourceWriter>(std::make_unique<TestStreamWriter>()),
[&gltfDocument](const BufferBuilder& builder) { return std::to_string(gltfDocument.buffers.Size() + builder.GetBufferCount()); },
[&gltfDocument](const BufferBuilder& builder) { return std::to_string(gltfDocument.bufferViews.Size() + builder.GetBufferViewCount()); },
[&gltfDocument](const BufferBuilder& builder) { return std::to_string(gltfDocument.accessors.Size() + builder.GetAccessorCount()); });
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(data);
bufferBuilder.Output(gltfDocument);
}
const std::string gltfManifest = Serialize(gltfDocument, SerializeFlags::Pretty);
Assert::AreEqual(expectedBufferBuilderMultiple, gltfManifest.c_str());
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, BufferBuilderAccessor)
{
auto bufferBuilder = BufferBuilder(std::make_unique<GLTFResourceWriter>(std::make_shared<const StreamReaderWriter>()));
std::vector<uint16_t> indices = { 0, 1, 2 };
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ELEMENT_ARRAY_BUFFER);
bufferBuilder.AddAccessor(indices, { TYPE_SCALAR, COMPONENT_UNSIGNED_SHORT });
std::vector<float> positions = { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f };
std::vector<float> texCoords = { 0.0f, 0.0f, 1.0f, 1.0f };
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
bufferBuilder.AddAccessor(positions.data(), positions.size() / 3U, { TYPE_VEC3, COMPONENT_FLOAT });
bufferBuilder.AddAccessor(texCoords.data(), texCoords.size() / 2U, { TYPE_VEC2, COMPONENT_FLOAT });
Document gltfDocument;
bufferBuilder.Output(gltfDocument);
const std::string gltfManifest = Serialize(gltfDocument, SerializeFlags::Pretty);
Assert::AreEqual(expectedBufferBuilder, gltfManifest.c_str());
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, BufferBuilderAccessorUriPrefix)
{
auto resourceWriter = std::make_unique<GLTFResourceWriter>(std::make_unique<TestStreamWriter>());
resourceWriter->SetUriPrefix("foo");
BufferBuilder bufferBuilder(std::move(resourceWriter));
std::vector<uint16_t> indices = { 0, 1, 2 };
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ELEMENT_ARRAY_BUFFER);
bufferBuilder.AddAccessor(indices, { TYPE_SCALAR, COMPONENT_UNSIGNED_SHORT });
std::vector<float> positions = { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f };
std::vector<float> texCoords = { 0.0f, 0.0f, 1.0f, 1.0f };
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
bufferBuilder.AddAccessor(positions.data(), positions.size() / 3U, { TYPE_VEC3, COMPONENT_FLOAT });
bufferBuilder.AddAccessor(texCoords.data(), texCoords.size() / 2U, { TYPE_VEC2, COMPONENT_FLOAT });
Document gltfDocument;
bufferBuilder.Output(gltfDocument);
Assert::AreEqual(gltfDocument.buffers[0].uri.c_str(), "foo0.bin");
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, InvalidMaxMinBufferBuilderAccessor)
{
auto bufferBuilder = BufferBuilder(std::make_unique<GLTFResourceWriter>(std::make_shared<const StreamReaderWriter>()));
BufferView bufferView;
bufferView.id = "0";
bufferView.bufferId = "0";
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ELEMENT_ARRAY_BUFFER);
std::vector<float> keyframeTimes = { 0.0f , 0.0f, 0.0f, 0.0f, 0.0f };
std::vector<float> minValues = { 0.0f, 0.0f, 0.0f, 0.0f };
std::vector<float> maxValues = { 0.0f, 0.0f, 0.0f };
Assert::ExpectException<InvalidGLTFException>([&]()
{
bufferBuilder.AddAccessor(keyframeTimes, { TYPE_SCALAR, COMPONENT_FLOAT, false, minValues, maxValues });
});
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, BufferBuilderMultipleAccessor)
{
auto bufferBuilder = BufferBuilder(std::make_unique<GLTFResourceWriter>(std::make_shared<const StreamReaderWriter>()));
std::vector<uint8_t> indices ={ 0, 1, 2, 3, 2, 1 };
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ELEMENT_ARRAY_BUFFER);
bufferBuilder.AddAccessor(indices, { TYPE_SCALAR, COMPONENT_UNSIGNED_BYTE, false, { 0 }, { 3 } });
std::vector<float> vertices ={
-1.0f, 1.0f, 0.0f, // pos0
0.0f, 0.0f, -1.0f, // norm0
0.0f, 0.0f, // uv0
1.0f, 1.0f, 0.0f, // pos1
0.0f, 0.0f, -1.0f, // norm1
1.0f, 0.0f, // uv1
-1.0f, -1.0f, 0.0f, // pos2
0.0f, 0.0f, -1.0f, // norm2
0.0f, 1.0f, // uv2
1.0f, -1.0f, 0.0f, // pos3
0.0f, 0.0f, -1.0f, // norm3
1.0f, 1.0f, // uv3
};
const size_t componentSize = sizeof(decltype(vertices)::value_type);
const size_t stride = (3 + 3 + 2) * componentSize;
const size_t count = vertices.size() * componentSize / stride;
AccessorDesc descs[3] =
{
{ TYPE_VEC3, COMPONENT_FLOAT, false, { -1.0f, -1.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, 0 },
{ TYPE_VEC3, COMPONENT_FLOAT, false, { 0.0f, 0.0f, -1.0f },{ 0.0f, 0.0f, -1.0f }, 12 },
{ TYPE_VEC2, COMPONENT_FLOAT, false, { 0.0f, 0.0f },{ 1.0f, 1.0f }, 24 },
};
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
bufferBuilder.AddAccessors(vertices.data(), count, stride, descs, ArrayCount(descs), nullptr);
Document gltfDocument;
bufferBuilder.Output(gltfDocument);
const std::string gltfManifest = Serialize(gltfDocument, SerializeFlags::Pretty);
Assert::AreEqual(expectedBufferBuilderMultipleAccessor, gltfManifest.c_str());
}
GLTFSDK_TEST_METHOD(GLTFResourceWriterTests, BufferBuilderSharedReadWriter)
{
auto streamReaderWriter = std::make_shared<const StreamReaderWriter>();
const std::string filename = "foo.gltf";
{
BufferBuilder bufferBuilder(std::make_unique<GLTFResourceWriter>(streamReaderWriter));
bufferBuilder.AddBuffer();
bufferBuilder.AddBufferView(BufferViewTarget::ARRAY_BUFFER);
std::vector<uint8_t> indices = { 0, 1, 2, 3, 4, 5, 6, UINT8_MAX };
auto accessor = bufferBuilder.AddAccessor(indices, { TYPE_SCALAR, COMPONENT_UNSIGNED_BYTE });
Document doc;
bufferBuilder.Output(doc);
const auto gltfManifest = Serialize(doc);
bufferBuilder.GetResourceWriter().WriteExternal(filename, gltfManifest.c_str(), gltfManifest.length());
}
{
auto inputStream = std::dynamic_pointer_cast<std::stringstream>(streamReaderWriter->GetInputStream(filename));
auto resourceReader = GLTFResourceReader(streamReaderWriter);
auto doc = Deserialize(inputStream->str());
auto output = MeshPrimitiveUtils::GetIndices16(doc, resourceReader, doc.accessors[0]);
std::vector<uint16_t> expected = { 0, 1, 2, 3, 4, 5, 6, UINT8_MAX };
AreEqual(expected, output);
}
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,429 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/Deserialize.h>
#include <GLTFSDK/Serialize.h>
#include <GLTFSDK/Validation.h>
#include <memory>
using namespace glTF::UnitTest;
namespace
{
using namespace Microsoft::glTF;
void TestBadGLTFSerializeToJson(const Document& doc)
{
Assert::ExpectException<GLTFException>([&doc]
{
Serialize(doc);
}, L"Expected exception was not thrown");
}
void TestBadGLTFDeserializeToDocument(const char* data)
{
Assert::ExpectException<GLTFException>([&data]
{
Deserialize(data);
}, L"Expected exception was not thrown");
}
void TestDocumentValidationFail(const char* data)
{
Assert::ExpectException<ValidationException>([&data]
{
auto doc = Deserialize(data);
Validation::Validate(doc);
}, L"Expected exception was not thrown");
}
const char* c_invalidPrimitiveAccessorComponentType = R"({
"scenes": [{"nodes": [0]}],
"nodes": [{"mesh": 0}],
"meshes": [
{
"primitives": [
{
"attributes": {
"COLOR_0": 0,
"POSITION": 1
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 72
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 72,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5120,
"count": 3,
"type": "VEC3"
},
{
"bufferView": 0,
"byteOffset": 36,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"asset": {"version": "2.0"}
}
)";
const char* c_validPrimitiveNoIndices = R"({
"scenes": [{"nodes": [0]}],
"nodes": [{"mesh": 0}],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC3"
}
],
"asset": {"version": "2.0"}
}
)";
const char* c_invalidPrimitiveAccessorType = R"({
"scenes": [{"nodes": [0]}],
"nodes": [{"mesh": 0}],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"buffers": [
{
"uri": "triangleWithoutIndices.bin",
"byteLength": 36
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 36,
"target": 34962
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5126,
"count": 3,
"type": "VEC2"
}
],
"asset": {"version": "2.0"}
}
)";
const char* c_negativeAccessorOffset = R"({
"accessors": {
"accessor_21": {
"bufferView": "bufferView_29",
"byteOffset": -10,
"componentType": 5123,
"count": 12636,
"type": "SCALAR"
}
}
}
)";
const char* c_negativeAccessorCount = R"({
"accessors": {
"accessor_21": {
"bufferView": "bufferView_29",
"byteOffset": 10,
"componentType": 5123,
"count": -12636,
"type": "SCALAR"
}
}
}
)";
const char* c_negativeBufferLength = R"({
"buffers": {
"Duck": {
"byteLength": -102040,
"type": "arraybuffer",
"uri": "Duck.bin"
}
}
}
)";
const char* c_negativeBufferViewOffset = R"({
"bufferViews": {
"bufferView_29": {
"buffer": "Duck",
"byteLength": 25272,
"byteOffset": -10,
"target": 34963
}
}
}
)";
const char* c_negativeBufferViewLength = R"({
"bufferViews": {
"bufferView_29": {
"buffer": "Duck",
"byteLength": -25272,
"byteOffset": 10,
"target": 34963
}
}
}
)";
const char* c_invalidAccessorComponentType = R"({
"accessors": {
"accessor_21": {
"bufferView": "bufferView_29",
"byteOffset": 0,
"componentType": 1337,
"count": 12636,
"type": "SCALAR"
}
}
}
)";
const char* c_extraFieldsJson = R"({
"accessors": {},
"accessors-extra": {}
}
)";
const char* c_expectedDefaultDocument = R"({
"asset": {
"version": "2.0"
}
})";
const char* c_expectedDefaultDocumentAndScene = R"({
"asset": {
"version": "2.0"
},
"scenes": [
{}
]
})";
const char* c_expectedDefaultDocumentAndSceneAsDefault = R"({
"asset": {
"version": "2.0"
},
"scenes": [
{}
],
"scene": 0
})";
const char* c_expectedDefaultDocumentAndNonDefaultScene = R"({
"asset": {
"version": "2.0"
},
"scenes": [
{}
]
})";
const char* c_expectedDefaultDocumentAndNonDefaultSceneAsDefault = R"({
"asset": {
"version": "2.0"
},
"scenes": [
{}
],
"scene": 0
})";
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(SerializerGLTFTests)
{
BEGIN_TEST_CLASS_ATTRIBUTE()
TEST_CLASS_ATTRIBUTE(L"Priority", L"1")
TEST_CLASS_ATTRIBUTE(L"Category", L"Unit-Integration")
END_TEST_CLASS_ATTRIBUTE()
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_ValidPrimitiveNoIndices)
{
auto doc = Deserialize(c_validPrimitiveNoIndices);
Validation::Validate(doc);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_InvalidPrimitiveAccessorComponentType)
{
TestDocumentValidationFail(c_invalidPrimitiveAccessorComponentType);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_InvalidPrimitiveAccessorType)
{
TestDocumentValidationFail(c_invalidPrimitiveAccessorType);
}
// following test cases are only checked while deserializing to gltfdocument
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_NegativeAccessorOffset)
{
TestBadGLTFDeserializeToDocument(c_negativeAccessorOffset);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_NegativeBufferViewOffset)
{
TestBadGLTFDeserializeToDocument(c_negativeBufferViewOffset);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_NegativeBufferLength)
{
TestBadGLTFDeserializeToDocument(c_negativeBufferLength);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_NegativeBufferViewLength)
{
TestBadGLTFDeserializeToDocument(c_negativeBufferViewLength);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_NegativeAccessorCount)
{
TestBadGLTFDeserializeToDocument(c_negativeAccessorCount);
}
// TODO: Add NegativeBufferViewByteStride test
// TODO: Add TooLargeBufferViewByteStride test
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_InvalidAccessorComponentType)
{
TestBadGLTFDeserializeToDocument(c_invalidAccessorComponentType);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_ExtraRootFields)
{
TestBadGLTFDeserializeToDocument(c_extraFieldsJson);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_DefaultDocument)
{
Document doc;
const auto output = Serialize(doc, SerializeFlags::Pretty);
Assert::AreEqual(output.c_str(), c_expectedDefaultDocument);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_DefaultDocumentAndScene)
{
Document doc;
doc.scenes.Append(Scene(), AppendIdPolicy::GenerateOnEmpty);
const auto output = Serialize(doc, SerializeFlags::Pretty);
Assert::AreEqual(output.c_str(), c_expectedDefaultDocumentAndScene);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_DefaultDocumentAndSceneAsDefault)
{
Document doc;
doc.SetDefaultScene(Scene(), AppendIdPolicy::GenerateOnEmpty);
const auto output = Serialize(doc, SerializeFlags::Pretty);
Assert::AreEqual(output.c_str(), c_expectedDefaultDocumentAndSceneAsDefault);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_DefaultDocumentAndNonDefaultScene)
{
Document doc;
Scene scene;
scene.id = "foo";
doc.scenes.Append(std::move(scene));
const auto output = Serialize(doc, SerializeFlags::Pretty);
Assert::AreEqual(output.c_str(), c_expectedDefaultDocumentAndNonDefaultScene);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_DefaultDocumentAndNonDefaultSceneAsDefault)
{
Document doc;
Scene scene;
scene.id = "foo";
doc.SetDefaultScene(std::move(scene));
const auto output = Serialize(doc, SerializeFlags::Pretty);
Assert::AreEqual(output.c_str(), c_expectedDefaultDocumentAndNonDefaultSceneAsDefault);
}
GLTFSDK_TEST_METHOD(SerializerGLTFTests, SerializerGLTFTests_InvalidDefaultScene)
{
Document doc;
Scene scene;
scene.id = "foo";
doc.scenes.Append(std::move(scene));
doc.defaultSceneId = "bar";
TestBadGLTFSerializeToJson(doc);
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,631 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/Constants.h>
#include <GLTFSDK/Deserialize.h>
#include <GLTFSDK/ExtensionsKHR.h>
#include <GLTFSDK/GLBResourceReader.h>
#include <GLTFSDK/GLBResourceWriter.h>
#include <GLTFSDK/MeshPrimitiveUtils.h>
#include <GLTFSDK/Serialize.h>
#include "TestResources.h"
#include "TestUtils.h"
#include <locale>
#include <string>
#include <memory>
#include <mutex>
#include <string>
using namespace glTF::UnitTest;
namespace
{
using namespace Microsoft::glTF;
using namespace Microsoft::glTF::Test;
Document ImportAndParseGLB(std::shared_ptr<IStreamReader> streamReader, const std::shared_ptr<std::istream>& glbStream)
{
GLBResourceReader resourceReader(streamReader, glbStream);
auto json = resourceReader.GetJson();
auto doc = Deserialize(json);
return doc;
}
Document ImportAndParseGLTF(std::shared_ptr<IStreamReader> streamReader, const std::shared_ptr<std::istream>& stream)
{
GLTFResourceReader resourceReader(streamReader);
auto json = std::string(std::istreambuf_iterator<char>(*stream), std::istreambuf_iterator<char>());
auto doc = Deserialize(json);
return doc;
}
void TestBufferViewOffsetAlignment(const char* data,
size_t indicesBufferViewLength,
size_t positionsBufferViewOffset,
size_t positionsBufferViewLength,
size_t normalsBufferViewOffset,
size_t normalsBufferViewLength)
{
auto input = std::make_shared<std::stringstream>(data);
auto streamWriter = std::make_shared<StreamReaderWriter>();
auto doc = ImportAndParseGLTF(streamWriter, input);
// We're only checking the offsets for mesh 0 for the purpose of this test. Feel free to add support
// for multiple meshes if necessary.
auto mesh = doc.meshes[0];
auto primitive = mesh.primitives[0];
auto indicesAccessor = doc.accessors.Get(primitive.indicesAccessorId);
auto positionsAccessor = doc.accessors.Get(primitive.attributes.at(ACCESSOR_POSITION));
auto normalsAccessor = doc.accessors.Get(primitive.attributes.at(ACCESSOR_NORMAL));
auto indicesBufferView = doc.bufferViews.Get(indicesAccessor.bufferViewId);
auto positionsBufferView = doc.bufferViews.Get(positionsAccessor.bufferViewId);
auto normalsBufferView = doc.bufferViews.Get(normalsAccessor.bufferViewId);
Assert::AreEqual(indicesBufferView.byteOffset, size_t(0));
Assert::AreEqual(indicesBufferView.byteLength, indicesBufferViewLength);
Assert::AreEqual(positionsBufferView.byteOffset, positionsBufferViewOffset);
Assert::AreEqual(positionsBufferView.byteLength, positionsBufferViewLength);
Assert::AreEqual(normalsBufferView.byteOffset, normalsBufferViewOffset);
Assert::AreEqual(normalsBufferView.byteLength, normalsBufferViewLength);
}
void TestGLTFRoundTrip(const std::string& dataStr)
{
// Deserialize JSON string -> Document
auto originalDoc = Deserialize(dataStr);
// Serialize Document -> JSON string
auto reserializedJson = Serialize(originalDoc);
// Deserialize JSON string -> Document
auto roundtrippedDoc = Deserialize(reserializedJson);
// Compare input and output Documents
Assert::IsTrue(originalDoc == roundtrippedDoc, L"Input gltf and output gltf are not equal");
}
Document TestDeserializeValidGLTFFile(const char* resourcePath)
{
auto input = ReadLocalAsset(resourcePath);
auto readwriter = std::make_shared<StreamReaderWriter>();
auto doc = ImportAndParseGLTF(readwriter, input);
Validation::Validate(doc);
return doc;
}
void TestDeserializeInvalidGLTF(std::shared_ptr<std::istream> input)
{
Assert::ExpectException<GLTFException>([&input]
{
auto readwriter = std::make_shared<StreamReaderWriter>();
ImportAndParseGLTF(readwriter, input);
}, L"Expected exception was not thrown");
}
void TestDeserializeInvalidGLTF(const char* data)
{
auto stream = std::make_shared<std::stringstream>(data);
TestDeserializeInvalidGLTF(stream);
}
void TestDeserializeInvalidGLBFile(const char* resourcePath)
{
Assert::ExpectException<GLTFException>([&resourcePath]
{
auto input = ReadLocalAsset(resourcePath);
auto readwriter = std::make_shared<StreamReaderWriter>();
ImportAndParseGLB(readwriter, input);
}, L"Expected exception was not thrown");
}
Document TestDeserializeValidGLBFile(const char* resourcePath)
{
auto input = ReadLocalAsset(resourcePath);
auto readwriter = std::make_shared<StreamReaderWriter>();
auto doc = ImportAndParseGLB(readwriter, input);
Validation::Validate(doc);
return doc;
}
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(GLTFTests)
{
BEGIN_TEST_CLASS_ATTRIBUTE()
TEST_CLASS_ATTRIBUTE(L"Priority", L"1")
TEST_CLASS_ATTRIBUTE(L"Category", L"Unit-Integration")
END_TEST_CLASS_ATTRIBUTE()
GLTFSDK_TEST_METHOD(GLTFTests, GLB_Deserialize_Valid)
{
TestDeserializeValidGLBFile(c_glbSampleBoxInterleaved);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_RoundTrip_ValidCamera)
{
TestGLTFRoundTrip(ReadLocalJson(c_validCameraJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_RoundTrip_ValidCameraWithExtensions)
{
TestGLTFRoundTrip(ReadLocalJson(c_cameraWithExtensions));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_RoundTrip_ReciprocatingSaw)
{
TestGLTFRoundTrip(ReadLocalJson(c_reciprocatingSaw));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_CameraMissingProperty)
{
TestDeserializeInvalidGLTF(ReadLocalJson(c_cameraMissingProperties).c_str());
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_CameraInvalidPerspective)
{
TestDeserializeInvalidGLTF(ReadLocalJson(c_cameraInvalidPerspective).c_str());
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_CameraInvalidProjection)
{
TestDeserializeInvalidGLTF(ReadLocalJson(c_cameraInvalidProjectionJson).c_str());
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_SingleTriangle)
{
TestGLTFRoundTrip(ReadLocalJson(c_singleTriangleJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_Cube)
{
TestGLTFRoundTrip(ReadLocalJson(c_cubeJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_CubeWithLOD)
{
TestGLTFRoundTrip(ReadLocalJson(c_cubeWithLODJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_MultipleMeshes)
{
TestGLTFRoundTrip(ReadLocalJson(c_doubleTriangleJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_SingleTriangleTextured)
{
TestGLTFRoundTrip(ReadLocalJson(c_singleTriangleWithTextureJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_SinglePolygonNormals)
{
TestGLTFRoundTrip(ReadLocalJson(c_singlePolyWithNormalsJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_MultipleNodes)
{
TestGLTFRoundTrip(ReadLocalJson(c_doubleNodesJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_Transforms)
{
TestGLTFRoundTrip(ReadLocalJson(c_transformsJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_ComplexTexture)
{
TestGLTFRoundTrip(ReadLocalJson(c_cartoonCurse01FbxJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_AnimatedTriangle)
{
// Node animation test
TestGLTFRoundTrip(ReadLocalJson(c_animatedTriangleJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_SimpleSkin)
{
// Skinned animation test
TestGLTFRoundTrip(ReadLocalJson(c_riggedSimpleJson));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_TriangleWithoutIndices)
{
TestGLTFRoundTrip(ReadLocalJson(c_validTriangleWithoutIndices));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_TriangleTRS)
{
TestGLTFRoundTrip(ReadLocalJson(c_validTriangleTRS));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_TriangleMatrix)
{
TestGLTFRoundTrip(ReadLocalJson(c_validTriangleMatrix));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_RoundTrip_MorphTarget)
{
TestGLTFRoundTrip(ReadLocalJson(c_validMorphTarget));
}
// following test cases are only checked while deserializing to GLTF
GLTFSDK_TEST_METHOD(GLTFTests, GLB_MissingDefaultSceneReference)
{
TestDeserializeInvalidGLTF(ReadLocalJson(c_missingDefaultSceneJson).c_str());
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_MissingMeshReference)
{
TestDeserializeInvalidGLTF(ReadLocalJson(c_missingMeshRefJson).c_str());
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_MissingNodeReference)
{
TestDeserializeInvalidGLTF(ReadLocalJson(c_missingNodeRefJson).c_str());
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_CircularNodeReference)
{
TestDeserializeInvalidGLTF(ReadLocalJson(c_duplicateNodesJson).c_str());
}
// following test cases are stored in files because right now as material and textures create fairly complex files
GLTFSDK_TEST_METHOD(GLTFTests, GLB_MissingMaterialReference)
{
TestDeserializeInvalidGLBFile(c_glbDuckMissingMaterialRef);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_MissingTextureReference)
{
TestDeserializeInvalidGLBFile(c_glbCubeMissingTextureRef);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_InvalidAccessorByteLength)
{
TestDeserializeInvalidGLBFile(c_glbCubeInvalidAccessorByteLength);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_InvalidAccessorByteOffset)
{
TestDeserializeInvalidGLBFile(c_glbCubeInvalidAccessorByteOffset);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_InvalidBufferViewLength)
{
TestDeserializeInvalidGLBFile(c_glbCubeInvalidBufferViewLength);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_AccessorMinMax)
{
std::string assetName = "test";
std::string filename = assetName + "." + GLB_EXTENSION;
auto input = std::make_shared<std::stringstream>(ReadLocalJson(c_cubeJson).c_str());
auto readwriter = std::make_shared<StreamReaderWriter>();
auto doc = ImportAndParseGLTF(readwriter, input);
auto mesh = doc.meshes[0];
auto primitive = mesh.primitives[0];
auto indicesAccessor = doc.accessors.Get(primitive.indicesAccessorId);
auto positionsAccessor = doc.accessors.Get(primitive.attributes.at(ACCESSOR_POSITION));
auto normalsAccessor = doc.accessors.Get(primitive.attributes.at(ACCESSOR_NORMAL));
Assert::AreEqual(0.f, indicesAccessor.min[0]);
Assert::AreEqual(23.f, indicesAccessor.max[0]);
// use IsTrue because AreEqual doesn't support comparing vectors
Assert::IsTrue(std::vector<float> {0.f, 0.f, 0.f} == positionsAccessor.min);
Assert::IsTrue(std::vector<float> {1.f, 1.f, 1.f} == positionsAccessor.max);
Assert::IsTrue(std::vector<float> {-1.f, -1.f, -1.f } == normalsAccessor.min);
Assert::IsTrue(std::vector<float> {1.f, 1.f, 0.f} == normalsAccessor.max);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_OffsetAlignment_SingleTriangle)
{
// offset length
//indices 0 6
//positions 8 36
//normals 44 36
TestBufferViewOffsetAlignment(ReadLocalJson(c_singleTriangleJson).c_str(), 6, 6, 38, 44, 36);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_OffsetAlignment_TwoTriangles)
{
// offset length
//indices_1 0 6
//indices_2 6 6
//positions_1 12 36
//positions_2 48 36
//normals_1 84 36
//normals_2 120 36
// Only testing mesh1 which is sufficient for the purpose of this test.
// Besides, if the offsets in mesh2 are wrong, some of the offsets in mesh1 would also be wrong.
TestBufferViewOffsetAlignment(ReadLocalJson(c_doubleTriangleJson).c_str(), 12, 12, 72, 84, 72);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_WrongReportedLength)
{
TestDeserializeInvalidGLBFile(c_glbWrongReportedLength);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_WrongJsonLength)
{
TestDeserializeInvalidGLBFile(c_glbWrongJsonLength);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_WrongBinHeaderLength)
{
TestDeserializeInvalidGLBFile(c_glbWrongBinHeaderLength);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLB_TextureComparison)
{
Material::OcclusionTextureInfo occ1;
occ1.textureId = "foo1";
Material::OcclusionTextureInfo occ2;
occ2.textureId = "foo2";
Assert::IsFalse(occ1 == occ2);
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_TestNoDefaultScene)
{
// Verify that trying to access the default scene in a document
// which has no scenes, throws the expected exception.
auto GetScene = [] { Document().GetDefaultScene(); };
Assert::ExpectException<DocumentException>( GetScene, L"Expected DocumentException was not thrown" );
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_DeserializeTexCoord1)
{
auto doc = TestDeserializeValidGLTFFile(c_meshPrimitivesUV04);
// Check for expected values in document
Assert::AreEqual<size_t>(doc.materials[0].metallicRoughness.baseColorTexture.texCoord, 1);
Assert::AreEqual<size_t>(doc.materials[0].normalTexture.texCoord, 1);
Assert::AreEqual<std::string>(doc.meshes[0].primitives[0].attributes.at(ACCESSOR_TEXCOORD_1), "5");
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_DeserializeExtensionsUsed)
{
auto doc = TestDeserializeValidGLTFFile(c_cubeJson);
// Check for expected values in document
Assert::IsTrue(doc.IsExtensionUsed(KHR::Materials::PBRSPECULARGLOSSINESS_NAME));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_RoundTripTexCoord1)
{
TestGLTFRoundTrip(ReadLocalJson(c_meshPrimitivesUV04));
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_DeserializeNodeAnimation)
{
auto doc = TestDeserializeValidGLTFFile(c_animatedTriangleJson);
// Check for expected values in document
Assert::AreEqual<std::string>(doc.animations.Get("0").channels[0].samplerId, "0");
Assert::AreEqual<std::string>(doc.animations.Get("0").channels[0].target.nodeId, "0");
Assert::IsTrue(doc.animations.Get("0").channels[0].target.path == TARGET_ROTATION);
Assert::AreEqual<std::string>(doc.animations.Get("0").samplers[0].inputAccessorId, "2");
Assert::IsTrue(doc.animations.Get("0").samplers[0].interpolation == INTERPOLATION_LINEAR);
Assert::AreEqual<std::string>(doc.animations.Get("0").samplers[0].outputAccessorId, "3");
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_DeserializeSkinnedAnimation)
{
auto doc = TestDeserializeValidGLTFFile(c_riggedSimpleJson);
// Check for expected values in document
Assert::AreEqual<std::string>(doc.skins.Get("0").inverseBindMatricesAccessorId, "13");
Assert::AreEqual<std::string>(doc.skins.Get("0").skeletonId, "2");
Assert::IsTrue(doc.skins.Get("0").jointIds.size() == 2);
Assert::AreEqual<std::string>(doc.skins.Get("0").jointIds[0], "2");
Assert::AreEqual<std::string>(doc.skins.Get("0").jointIds[1], "3");
Assert::AreEqual<std::string>(doc.animations.Get("0").channels[0].samplerId, "0");
Assert::AreEqual<std::string>(doc.animations.Get("0").channels[0].target.nodeId, "2");
Assert::IsTrue(doc.animations.Get("0").channels[0].target.path == TARGET_TRANSLATION);
Assert::AreEqual<std::string>(doc.animations.Get("1").channels[2].samplerId, "2");
Assert::AreEqual<std::string>(doc.animations.Get("1").channels[2].target.nodeId, "3");
Assert::IsTrue(doc.animations.Get("1").channels[2].target.path == TARGET_SCALE);
Assert::AreEqual<std::string>(doc.animations.Get("1").samplers[1].inputAccessorId, "9");
Assert::IsTrue(doc.animations.Get("0").samplers[0].interpolation == INTERPOLATION_LINEAR);
Assert::AreEqual<std::string>(doc.animations.Get("1").samplers[1].outputAccessorId, "11");
Assert::AreEqual<std::string>(doc.meshes.Get("0").primitives[0].attributes.at(ACCESSOR_JOINTS_0), "1");
Assert::AreEqual<std::string>(doc.meshes.Get("0").primitives[0].attributes.at(ACCESSOR_WEIGHTS_0), "4");
}
GLTFSDK_TEST_METHOD(GLTFTests, GLTF_Deserialize_Positions_Vec3_Float_Interleaved)
{
auto input = ReadLocalAsset(c_glbSampleBoxInterleaved);
auto readwriter = std::make_shared<StreamReaderWriter>();
GLBResourceReader resourceReader(readwriter, input);
auto json = resourceReader.GetJson();
auto doc = Deserialize(json);
auto output = MeshPrimitiveUtils::GetPositions(doc, resourceReader, doc.accessors.Get("2"));
std::vector<float> expected = {
-0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f,
0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
};
AreEqual(expected, output);
}
GLTFSDK_TEST_METHOD(GLTFTests, SerializeSparseAccessorRoundTrip)
{
TestGLTFRoundTrip(ReadLocalJson(c_simpleSparseAccessor));
}
GLTFSDK_TEST_METHOD(GLTFTests, Verify_Extensions_In_ExtensionsUsed)
{
// Add an extension to extensions and add it to extensionsUsed
Document doc;
doc.extensions.emplace("MyExtension", "{}");
doc.extensionsUsed.emplace("MyExtension");
auto reserializedJson = Serialize(doc);
// Add an extension to extensions without adding it to extensionsUsed
Assert::ExpectException<GLTFException>(
[]()
{
Document doc;
doc.extensions.emplace("MyExtension", "{}");
auto reserializedJson = Serialize(doc);
}, L"missing extensionsUsed value should have thrown an exception.");
}
GLTFSDK_TEST_METHOD(GLTFTests, Verify_ExtensionsRequired_In_ExtensionsUsed)
{
// Add an extension to extensionsRequired and add it to extensionsUsed
Document doc;
doc.extensions.emplace("MyExtension", "{}");
doc.extensionsUsed.emplace("MyExtension");
doc.extensionsRequired.emplace("MyExtension");
auto reserializedJson = Serialize(doc);
// Add an extension to extensionsRequired without adding it to extensionsUsed
Assert::ExpectException<GLTFException>(
[]()
{
Document doc;
doc.extensions.emplace("MyExtension", "{}");
doc.extensionsRequired.emplace("MyExtension");
auto reserializedJson = Serialize(doc);
}, L"missing extensionsUsed value should have thrown an exception.");
}
GLTFSDK_TEST_METHOD(GLTFTests, Verify_MeshPrimitive_Attributes_RoundTrip)
{
Document doc;
MeshPrimitive primitive;
primitive.mode = MESH_TRIANGLES;
primitive.attributes["EXTRA_ATTRIBUTE"] = "0";
primitive.attributes[ACCESSOR_POSITION] = "1";
Mesh mesh;
mesh.id = "0";
mesh.primitives.push_back(primitive);
doc.meshes.Append(mesh);
Accessor accessor0;
accessor0.id = "0";
accessor0.type = TYPE_SCALAR;
accessor0.componentType = COMPONENT_FLOAT;
accessor0.count = 1;
doc.accessors.Append(accessor0);
Accessor accessor1;
accessor1.id = "1";
accessor1.type = TYPE_SCALAR;
accessor1.componentType = COMPONENT_FLOAT;
accessor1.count = 1;
doc.accessors.Append(accessor1);
auto serializedJson = Serialize(doc);
Document doc2 = Deserialize(serializedJson);
Assert::AreEqual<size_t>(doc2.meshes.Size(), 1);
Assert::AreEqual<size_t>(doc2.meshes[0].primitives.size(), 1);
Assert::AreEqual<size_t>(doc2.meshes[0].primitives[0].attributes.size(), 2);
Assert::AreEqual<std::string>(doc2.meshes[0].primitives[0].attributes.at("EXTRA_ATTRIBUTE"), "0");
Assert::AreEqual<std::string>(doc2.meshes[0].primitives[0].attributes.at(ACCESSOR_POSITION), "1");
Assert::IsTrue(doc == doc2, L"Input gltf and output gltf are not equal");
}
GLTFSDK_TEST_METHOD(GLTFTests, UnicodeByteOrderMark)
{
constexpr static const char assetBom[] = "\xEF\xBB\xBF";
constexpr static const char asset[] = R"(
{
"asset": {
"version": "2.0",
"generator": "glTF SDK Unit Tests"
}
})";
// Test the overload of Deserialize that accepts a string
{
std::stringstream ss;
ss << assetBom;
ss << asset;
auto documentWithBom = Deserialize(ss.str(), DeserializeFlags::IgnoreByteOrderMark);
auto documentWithoutBom = Deserialize(asset);
Assert::IsTrue(documentWithBom == documentWithoutBom, L"Deserialized asset with utf8 BOM doesn't match asset without utf8 BOM");
}
// Test the overload of Deserialize that accepts a stream
{
std::stringstream ss;
ss << assetBom;
ss << asset;
auto documentWithBom = Deserialize(ss, DeserializeFlags::IgnoreByteOrderMark); // Note that the stringstream was passed to Deserialize
auto documentWithoutBom = Deserialize(asset);
Assert::IsTrue(documentWithBom == documentWithoutBom, L"Deserialized asset with utf8 BOM doesn't match asset without utf8 BOM");
}
// Test the overload of Deserialize that accepts a string
Assert::ExpectException<GLTFException>([]
{
std::stringstream ss;
ss << assetBom;
ss << asset;
// If the IgnoreByteOrderMark flag isn't specified then a BOM should result in Deserialize throwing an exception
Deserialize(ss.str(), DeserializeFlags::None);
});
// Test the overload of Deserialize that accepts a stream
Assert::ExpectException<GLTFException>([]
{
std::stringstream ss;
ss << assetBom;
ss << asset;
// If the IgnoreByteOrderMark flag isn't specified then a BOM should result in Deserialize throwing an exception
Deserialize(ss, DeserializeFlags::None);
});
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,338 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/Exceptions.h>
#include <GLTFSDK/IndexedContainer.h>
using namespace glTF::UnitTest;
namespace
{
using namespace Microsoft::glTF;
struct Uint8WithId
{
std::string id;
uint8_t value = 0;
bool operator==(const Uint8WithId& rhs) const
{
if (id == rhs.id && value == rhs.value)
{
return true;
}
return false;
}
};
IndexedContainer<Uint8WithId> GetSampleContainer()
{
IndexedContainer<Uint8WithId> container;
container.Append({ "foo0", 0 });
container.Append({ "foo2", 2 });
container.Append({ "foo4", 4 });
container.Append({ "foo6", 6 });
container.Append({ "foo8", 8 });
container.Append({ "foo10", 10 });
return container;
}
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(IndexedContainerTests)
{
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Operator_At_SizeT)
{
auto container = GetSampleContainer();
Assert::IsTrue(container[2].value == 4);
Assert::ExpectException<GLTFException>([&container]()
{
container[10];
});
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Operator_At_String)
{
auto container = GetSampleContainer();
Assert::IsTrue(container["foo4"].value == 4);
Assert::ExpectException<GLTFException>([&container]()
{
container["foo100"];
});
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Operator_Equals)
{
IndexedContainer<Uint8WithId> container;
container.Append({ "foo0", 0 });
container.Append({ "foo2", 2 });
container.Append({ "foo4", 4 });
container.Append({ "foo6", 6 });
container.Append({ "foo8", 8 });
container.Append({ "foo10", 10 });
Assert::IsTrue(GetSampleContainer() == container);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Operator_NotEquals)
{
IndexedContainer<Uint8WithId> container;
container.Append({ "foo0", 0 });
container.Append({ "foo2", 2 });
container.Append({ "foo4", 4 });
container.Append({ "foo6", 6 });
container.Append({ "foo8", 8 });
Assert::IsTrue(GetSampleContainer() != container);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Append)
{
auto container = GetSampleContainer();
Assert::ExpectException<GLTFException>([&container]()
{
container["foo100"];
});
Uint8WithId bar{ "bar", 99 };
container.Append(bar);
container.Append({ "foo100", 100 });
Assert::IsTrue(container["bar"].value == 99);
Assert::IsTrue(container["foo100"].value == 100);
Assert::ExpectException<GLTFException>([&container, &bar]()
{
container.Append(bar);
});
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Clear)
{
auto container = GetSampleContainer();
Assert::IsTrue(container.Size() > 0);
container.Clear();
Assert::IsTrue(container.Size() == 0);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Elements)
{
auto container = GetSampleContainer();
auto elements = container.Elements();
Assert::IsTrue(elements[0].value == 0);
Assert::IsTrue(elements[1].value == 2);
Assert::IsTrue(elements[2].value == 4);
Assert::IsTrue(elements[3].value == 6);
Assert::IsTrue(elements[4].value == 8);
Assert::IsTrue(elements[5].value == 10);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Get_SizeT)
{
auto container = GetSampleContainer();
Assert::IsTrue(container.Get(2).value == 4);
Assert::ExpectException<GLTFException>([&container]()
{
container.Get(10);
});
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Get_String)
{
auto container = GetSampleContainer();
Assert::IsTrue(container.Get("foo4").value == 4);
Assert::ExpectException<GLTFException>([&container]()
{
container.Get("foo100");
});
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_GetIndex)
{
auto container = GetSampleContainer();
Assert::IsTrue(container.GetIndex("foo4") == 2);
Assert::ExpectException<GLTFException>([&container]()
{
container.GetIndex("foo100");
});
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Has)
{
auto container = GetSampleContainer();
Assert::IsTrue(container.Has("foo4"));
Assert::IsTrue(container.Has("foo100") == false);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Remove)
{
auto container = GetSampleContainer();
Assert::IsTrue(container[0].value == 0);
Assert::IsTrue(container[1].value == 2);
Assert::IsTrue(container[2].value == 4);
Assert::IsTrue(container[3].value == 6);
Assert::IsTrue(container[4].value == 8);
Assert::IsTrue(container[5].value == 10);
container.Remove("foo4");
Assert::IsTrue(container[0].value == 0);
Assert::IsTrue(container[1].value == 2);
Assert::IsTrue(container[2].value == 6);
Assert::IsTrue(container[3].value == 8);
Assert::IsTrue(container[4].value == 10);
Assert::ExpectException<GLTFException>([&container]()
{
container.GetIndex("foo100");
});
Assert::IsTrue(container[0].value == 0);
Assert::IsTrue(container[1].value == 2);
Assert::IsTrue(container[2].value == 6);
Assert::IsTrue(container[3].value == 8);
Assert::IsTrue(container[4].value == 10);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Replace)
{
auto container = GetSampleContainer();
Assert::IsTrue(container[2].value == 4);
container.Replace({ "foo4", 40 });
Assert::IsTrue(container[2].value == 40);
Uint8WithId foo6{ "foo6", 60 };
container.Replace(foo6);
Assert::IsTrue(container[3].value == 60);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Replace_Rvalue_Reference)
{
auto container = GetSampleContainer();
Uint8WithId foo4{ "foo4", 40 };
Uint8WithId foo6{ "foo6", 60 };
Assert::IsTrue(container[2].value == 4);
container.Replace(std::move(foo4)); // Move
Assert::IsTrue(foo4.id.empty());
Assert::IsTrue(container[2].value == 40);
container.Replace(foo6); // Copy
Assert::IsTrue(foo6.id == "foo6");
Assert::IsTrue(container[3].value == 60);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Reserve)
{
auto container = GetSampleContainer();
auto capacity = container.Elements().capacity();
Assert::IsTrue(container.Elements().capacity() == capacity);
container.Reserve(capacity + 10);
Assert::IsTrue(container.Elements().capacity() > capacity);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Size)
{
auto container = GetSampleContainer();
Assert::IsTrue(container.Size() == 6);
container.Remove("foo4");
Assert::IsTrue(container.Size() == 5);
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Append_ThrowOnEmpty)
{
Assert::ExpectException<GLTFException>([]
{
IndexedContainer<const Uint8WithId> container;
container.Append({}, AppendIdPolicy::ThrowOnEmpty);
}, L"IndexedContainer did not throw the expected exception when appending an item with an empty string id");
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Append_GenerateOnEmpty)
{
IndexedContainer<const Uint8WithId> container;
{
auto& item = container.Append({}, AppendIdPolicy::GenerateOnEmpty);
Assert::AreEqual("0", item.id.c_str(), L"The expected item id was not generated when specifying the GenerateOnEmpty append policy");
}
{
auto& item = container.Append({}, AppendIdPolicy::GenerateOnEmpty);
Assert::AreEqual("1", item.id.c_str(), L"The expected item id was not generated when specifying the GenerateOnEmpty append policy");
}
container.Clear();
{
auto& item = container.Append({}, AppendIdPolicy::GenerateOnEmpty);
Assert::AreEqual("0", item.id.c_str(), L"The expected item id was not generated when specifying the GenerateOnEmpty append policy");
}
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Append_GenerateOnEmpty_Unique)
{
IndexedContainer<const Uint8WithId> container;
container.Append({ "2", 0 }, AppendIdPolicy::ThrowOnEmpty);
container.Append({ "2+", 0 }, AppendIdPolicy::ThrowOnEmpty);
{
auto& item = container.Append({}, AppendIdPolicy::GenerateOnEmpty);
Assert::AreEqual("2++", item.id.c_str(), L"The expected item id was not generated when specifying the GenerateOnEmpty append policy");
}
}
GLTFSDK_TEST_METHOD(IndexedContainerTests, IndexedContainer_Test_Append_GenerateOnEmpty_Duplicate)
{
IndexedContainer<const Uint8WithId> container;
container.Append({ "2", 0 });
Assert::ExpectException<GLTFException>([&container]
{
container.Append({ "2", 0 }, AppendIdPolicy::GenerateOnEmpty);
}, L"IndexedContainer did not throw the expected exception when appending an item with a duplicate string id");
}
};
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,130 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/MicrosoftGeneratorVersion.h>
#include <functional>
#include <locale>
#include <memory>
#include <regex>
#include <string>
using namespace glTF::UnitTest;
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(MicrosoftGeneratorVersionTests)
{
BEGIN_TEST_CLASS_ATTRIBUTE()
TEST_CLASS_ATTRIBUTE(L"Priority", L"1")
TEST_CLASS_ATTRIBUTE(L"Category", L"Unit-Integration")
END_TEST_CLASS_ATTRIBUTE()
struct MicrosoftGeneratorVersionTestStruct
{
std::string version;
std::string testValue;
bool isMicrosoftGeneratorValue;
std::function<bool(const MicrosoftGeneratorVersion& srcVersion, const MicrosoftGeneratorVersion& currentVersion)> testFunction;
MicrosoftGeneratorVersionTestStruct(const std::string& inVersion, const std::string& inTestValue,
bool inIsMicrosoftGeneratorValue,
const std::function<bool(const MicrosoftGeneratorVersion& srcVersion, const MicrosoftGeneratorVersion& currentVersion)>& testFunc
)
{
version = inVersion;
testValue = inTestValue;
isMicrosoftGeneratorValue = inIsMicrosoftGeneratorValue;
testFunction = testFunc;
}
};
GLTFSDK_TEST_METHOD(MicrosoftGeneratorVersionTests, MicrosoftGeneratorVersionTests_ParseTest)
{
const std::string threeValues("1.1.1");
const std::string fourValues("1.1.1.1");
const std::string threeValuesPre("1.1.1-b23");
const std::string fourValuesPre("1.1.1.1-b23");
std::vector<MicrosoftGeneratorVersionTestStruct> testVersions =
{
//IsMicrosoftGenerator == false
MicrosoftGeneratorVersionTestStruct("1.1.2-b2", threeValues, false, std::greater<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Some Other Exporter 1.1.1.1-b39-g0ef2ed0", fourValues, false, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("1.0.1-b2", threeValues, false, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Some Other Exporter 1.1.1.0-b39-g0ef2ed0", fourValues, false, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Some Other Exporter 1.1.1.0-b39-g0ef2ed0", fourValues, false, std::less_equal<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Some Other Exporter 1.1.1.1-b39-g0ef2ed0", fourValues, false, std::less<MicrosoftGeneratorVersion>()),
//IsMicrosoftGenerator == true
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1", threeValues, true, std::equal_to<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1 ", threeValues, true, std::equal_to<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.1", fourValues, true, std::equal_to<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.1 ", fourValues, true, std::equal_to<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.2 ", fourValues, true, std::greater<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.2.1 ", fourValues, true, std::greater<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.2.1.1 ", fourValues, true, std::greater_equal<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.2.1.1 ", fourValues, true, std::not_equal_to<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 2.1.1", threeValues, true, std::not_equal_to<MicrosoftGeneratorVersion>()),
//less than
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.0", threeValues, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.0.1", threeValues, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 0.1.1", threeValues, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.0.1-b2", threeValues, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.0.1-b2 ", threeValues, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.0.1-b39-g0ef2ed0", fourValues, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.0.1-b39-g0ef2ed0 ", fourValues, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.0.0.1", fourValues, true, std::less<MicrosoftGeneratorVersion>()),
//pre-release
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.2-b2", threeValues, true, std::greater<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1-b2", threeValues, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1-b2", threeValues, true, std::not_equal_to<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.2-b2", threeValuesPre, true, std::greater<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.2-b2", threeValuesPre, true, std::greater_equal<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1-b2", threeValuesPre, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1", threeValuesPre, true, std::greater<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1", threeValuesPre, true, std::greater_equal<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.0", threeValuesPre, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.0", threeValuesPre, true, std::less_equal<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1-b2", threeValuesPre, true, std::less_equal<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1-b23", threeValuesPre, true, std::equal_to<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.2-b2", fourValues, true, std::greater<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.1-b2", fourValues, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.1-b2", fourValues, true, std::not_equal_to<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.2-b2", fourValues, true, std::greater<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.2-b2", fourValuesPre, true, std::greater_equal<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.1-b2", fourValuesPre, true, std::less<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.1-b2", fourValuesPre, true, std::less_equal<MicrosoftGeneratorVersion>()),
MicrosoftGeneratorVersionTestStruct("Microsoft GLTF Exporter 1.1.1.1-b23", fourValuesPre, true, std::equal_to<MicrosoftGeneratorVersion>()),
};
std::not_equal_to<MicrosoftGeneratorVersion> notEqual;
MicrosoftGeneratorVersion zeroVersion("0.0.0.0");
for (auto s : testVersions)
{
MicrosoftGeneratorVersion testVersion(s.version);
MicrosoftGeneratorVersion testValue(s.testValue);
Assert::IsTrue(notEqual(testVersion, zeroVersion)); //this should not happen. If testVersion is 0.0.0.0 then regex parse error
Assert::IsTrue(testVersion.IsMicrosoftGenerator() == s.isMicrosoftGeneratorValue);
Assert::IsTrue(s.testFunction(testVersion, testValue));
}
//test empty version strings
auto nostring = MicrosoftGeneratorVersion("");
auto noversion = MicrosoftGeneratorVersion("Some Other Exporter");
Assert::IsTrue(nostring == zeroVersion);
Assert::IsTrue(noversion == zeroVersion);
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,128 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/PBRUtils.h>
using namespace glTF::UnitTest;
namespace
{
float Random(float a = 0.0f, float b = 1.0f)
{
return a + (b - a) * (static_cast<float>(rand()) / RAND_MAX);
}
bool FuzzyEqual(float a, float b, float epsilon = std::numeric_limits<float>::epsilon())
{
return fabs(a - b) < epsilon;
}
bool FuzzyEqual(Microsoft::glTF::Color3 a, Microsoft::glTF::Color3 b, float epsilon = std::numeric_limits<float>::epsilon())
{
return
FuzzyEqual(a.r, b.r, epsilon) &&
FuzzyEqual(a.g, b.g, epsilon) &&
FuzzyEqual(a.b, b.b, epsilon);
}
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(PBRUtilsTests)
{
GLTFSDK_TEST_METHOD(PBRUtilsTests, MRToSG_Dieletric)
{
MetallicRoughnessValue mr;
mr.base = Color3(0.5f, 0.1f, 0.2f);
mr.opacity = 1.0f;
mr.metallic = 0.0f;
mr.roughness = 0.5f;
SpecularGlossinessValue sg = MRToSG(mr);
Assert::IsTrue(FuzzyEqual(sg.diffuse, mr.base));
Assert::IsTrue(FuzzyEqual(sg.opacity, mr.opacity));
Assert::IsTrue(FuzzyEqual(sg.specular, Detail::DIELECTRIC_SPECULAR<Color3>));
Assert::IsTrue(FuzzyEqual(sg.glossiness, 1.0f - mr.roughness));
}
GLTFSDK_TEST_METHOD(PBRUtilsTests, MRToSG_Metallic)
{
MetallicRoughnessValue mr;
mr.base = Color3(0.5f, 0.1f, 0.2f);
mr.opacity = 1.0f;
mr.metallic = 1.0f;
mr.roughness = 0.5f;
SpecularGlossinessValue sg = MRToSG(mr);
Assert::IsTrue(FuzzyEqual(sg.diffuse, Detail::BLACK<Color3>));
Assert::IsTrue(FuzzyEqual(sg.opacity, mr.opacity));
Assert::IsTrue(FuzzyEqual(sg.specular, mr.base));
Assert::IsTrue(FuzzyEqual(sg.glossiness, 1.0f - mr.roughness));
}
GLTFSDK_TEST_METHOD(PBRUtilsTests, SGToMR_Dielectric)
{
SpecularGlossinessValue sg;
sg.diffuse = Color3(0.5f, 0.1f, 0.2f);
sg.opacity = 1.0f;
sg.specular = Detail::DIELECTRIC_SPECULAR<Color3>;
sg.glossiness = 0.5;
MetallicRoughnessValue mr = SGToMR(sg);
Assert::IsTrue(FuzzyEqual(mr.base, sg.diffuse));
Assert::IsTrue(FuzzyEqual(mr.opacity, 1.0f));
Assert::IsTrue(FuzzyEqual(mr.metallic, 0.0f));
Assert::IsTrue(FuzzyEqual(mr.roughness, 1.0f - sg.glossiness));
}
GLTFSDK_TEST_METHOD(PBRUtilsTests, SGToMR_Metallic)
{
SpecularGlossinessValue sg;
sg.diffuse = Detail::BLACK<Color3>;
sg.opacity = 1.0f;
sg.specular = Color3(0.5f, 0.1f, 0.2f);
sg.glossiness = 0.5;
MetallicRoughnessValue mr = SGToMR(sg);
Assert::IsTrue(FuzzyEqual(mr.base, sg.specular));
Assert::IsTrue(FuzzyEqual(mr.opacity, 1.0f));
Assert::IsTrue(FuzzyEqual(mr.metallic, 1.0f));
Assert::IsTrue(FuzzyEqual(mr.roughness, 1.0f - sg.glossiness));
}
GLTFSDK_TEST_METHOD(PBRUtilsTests, RoundTrip)
{
// Initialize from a fixed seed.
srand(1234);
for (int i = 0; i < 100; i++)
{
// Don't test colors lower than 0.04 to avoid larger deltas due to numerical issues.
MetallicRoughnessValue mrBefore;
mrBefore.base = Color3(Random(0.04f), Random(0.04f), Random(0.04f));
mrBefore.opacity = Random();
mrBefore.metallic = Random();
mrBefore.roughness = Random();
MetallicRoughnessValue mrAfter = SGToMR(MRToSG(mrBefore));
// 0.04 is derived from the max delta after 10000 iterations.
const float epsilon = 0.04f;
Assert::IsTrue(FuzzyEqual(mrBefore.base, mrAfter.base, epsilon));
Assert::IsTrue(FuzzyEqual(mrBefore.metallic, mrAfter.metallic, epsilon));
// Opacity and roughness should be exact.
Assert::IsTrue(FuzzyEqual(mrBefore.opacity, mrAfter.opacity));
Assert::IsTrue(FuzzyEqual(mrBefore.roughness, mrAfter.roughness));
}
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,333 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/GLTF.h>
#include <GLTFSDK/GLTFResourceReader.h>
#include <GLTFSDK/ResourceReaderUtils.h>
#include "TestUtils.h"
#include <memory>
#include <string>
using namespace glTF::UnitTest;
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(ResourceReaderUtilsTest)
{
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64UriRanges)
{
static const std::pair<std::vector<uint8_t>, std::string> tests[] = {
{ {}, "" },// 0 bytes -> empty string
{ { 0x0 }, "AA" },// 1 byte (0 blocks + 8 bits) -> 2 chars (0 blocks + 12 bits)
{ { 0x0 }, "AA==" },
{ { 0x0, 0x1 }, "AAE" },// 2 bytes (0 blocks + 16 bits) -> 3 chars (0 blocks + 18 bits)
{ { 0x0, 0x1 }, "AAE=" },
{ { 0x0, 0x1, 0x2 }, "AAEC" },// 3 bytes (1 block + 0 bits) -> 4 chars (1 block + 0 bits)
//{ { 0x0, 0x1, 0x2 }, "AAEC" },
{ { 0x0, 0x1, 0x2, 0x3 }, "AAECAw" },// 4 bytes (1 block + 8 bits) -> 6 chars (1 block + 12 bits)
{ { 0x0, 0x1, 0x2, 0x3 }, "AAECAw==" },
{ { 0x0, 0x1, 0x2, 0x3, 0x4 }, "AAECAwQ" },// 5 bytes (1 block + 16 bits) -> 7 chars (1 block + 18 bits)
{ { 0x0, 0x1, 0x2, 0x3, 0x4 }, "AAECAwQ=" },
{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5 }, "AAECAwQF" },// 6 bytes (2 blocks + 0 bits) -> 8 chars (2 blocks + 0 bits)
//{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5 }, "AAECAwQF" },
{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }, "AAECAwQFBg"},// 7 bytes (2 blocks + 8 bits) -> 10 chars (2 blocks + 12 bits)
{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }, "AAECAwQFBg=="},
{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }, "AAECAwQFBgc" },// 8 bytes (2 blocks + 16 bits) -> 11 chars (2 blocks + 18 bits)
{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }, "AAECAwQFBgc=" },
{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 }, "AAECAwQFBgcI" },// 9 bytes (3 blocks + 0 bits) -> 12 chars (3 blocks + 0 bits)
//{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 }, "AAECAwQFBgcI" },
{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9 }, "AAECAwQFBgcICQ" },// 10 bytes (3 blocks + 8 bits) -> 14 chars (3 blocks + 12 bits)
{ { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9 }, "AAECAwQFBgcICQ==" },
{ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, "////////////////" },// 12 bytes (4 blocks + 0 bits) -> 16 chars (4 blocks + 0 bits)
{ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, "/////////////////w" },// 13 bytes (4 blocks + 8 bits) -> 18 chars (4 blocks + 12 bits)
{ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, "//////////////////8" }// 14 bytes (4 blocks + 16 bits) -> 19 chars (4 blocks + 18 bits)
};
GLTFResourceReader gltfResourceReader(std::make_shared<StreamReaderWriter>());
for (auto& test : tests)
{
Microsoft::glTF::Buffer buffer;
buffer.id = "buffer";
buffer.uri = "data:application/octet-stream;base64," + test.second;
buffer.byteLength = test.first.size();
std::string::const_iterator itBegin, itEnd;
Assert::IsTrue(IsUriBase64(buffer.uri, itBegin, itEnd), L"Data uri was not recognized as such");
Assert::IsTrue(Base64Decode(test.second) == test.first, L"Decoded data uri doesn't match expected values");
Document gltfDocument;
gltfDocument.buffers.Append(buffer);
for (size_t i = 0; i < test.first.size(); ++i)
{
for (size_t j = i + 1U; j <= test.first.size(); ++j)
{
Microsoft::glTF::BufferView bufferView;
bufferView.bufferId = buffer.id;
bufferView.byteOffset = i;
bufferView.byteLength = j - i;
auto resultExpected = std::vector<uint8_t>(test.first.begin() + i, test.first.begin() + j);
auto resultActual = gltfResourceReader.ReadBinaryData<uint8_t>(gltfDocument, bufferView);
Assert::IsTrue(resultExpected == resultActual, L"Decoded data uri range doesn't match expected values");
}
}
}
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64UriFinal2Chars)
{
const auto data = Base64Decode("YW55IGNhcm5hbCBwbGVhcw");
const std::string decodedString(data.begin(), data.end());
const std::string encodedString = "any carnal pleas";
Assert::AreEqual(encodedString.c_str(), decodedString.c_str(), L"Incorrect decoded string");
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64UriFinal3Chars)
{
const auto data = Base64Decode("YW55IGNhcm5hbCBwbGVhc3U");
const std::string decodedString(data.begin(), data.end());
const std::string encodedString = "any carnal pleasu";
Assert::AreEqual(encodedString.c_str(), decodedString.c_str(), L"Incorrect decoded string");
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestBase64UriInterleaved)
{
Buffer buffer;
buffer.id = "buffer1";
buffer.uri = "data:application/octet-stream;base64,MTIzNDEyMzQxMjM0MTIzNA==";// Data uri stores the ASCII string: "1234123412341234"
buffer.byteLength = 16;
BufferView bufferView;
bufferView.id = "bufferView1";
bufferView.bufferId = buffer.id;
bufferView.byteLength = buffer.byteLength;
bufferView.byteStride = 4;
Accessor accessor1;
accessor1.id = "accessor1";
accessor1.bufferViewId = bufferView.id;
accessor1.byteOffset = 0;
accessor1.count = 4;
accessor1.componentType = ComponentType::COMPONENT_BYTE;
accessor1.type = AccessorType::TYPE_SCALAR;
Accessor accessor2;
accessor2.id = "accessor2";
accessor2.bufferViewId = bufferView.id;
accessor2.byteOffset = 1;
accessor2.count = 4;
accessor2.componentType = ComponentType::COMPONENT_BYTE;
accessor2.type = AccessorType::TYPE_SCALAR;
Accessor accessor3;
accessor3.id = "accessor3";
accessor3.bufferViewId = bufferView.id;
accessor3.byteOffset = 2;
accessor3.count = 4;
accessor3.componentType = ComponentType::COMPONENT_BYTE;
accessor3.type = AccessorType::TYPE_SCALAR;
Accessor accessor4;
accessor4.id = "accessor4";
accessor4.bufferViewId = bufferView.id;
accessor4.byteOffset = 3;
accessor4.count = 4;
accessor4.componentType = ComponentType::COMPONENT_BYTE;
accessor4.type = AccessorType::TYPE_SCALAR;
Document gltfDocument;
gltfDocument.buffers.Append(buffer);
gltfDocument.bufferViews.Append(bufferView);
gltfDocument.accessors.Append(accessor1);
gltfDocument.accessors.Append(accessor2);
gltfDocument.accessors.Append(accessor3);
gltfDocument.accessors.Append(accessor4);
GLTFResourceReader resourceReader(std::make_shared<StreamReaderWriter>());
auto a1Actual = resourceReader.ReadBinaryData<int8_t>(gltfDocument, accessor1);
auto a1Expected = std::vector<int8_t>{ '1', '1', '1', '1' };
Assert::IsTrue(a1Expected == a1Actual, L"Unexpected result reading interleaved accessor data from base64 encoded data uri");
auto a2Actual = resourceReader.ReadBinaryData<int8_t>(gltfDocument, accessor2);
auto a2Expected = std::vector<int8_t>{ '2', '2', '2', '2' };
Assert::IsTrue(a2Expected == a2Actual, L"Unexpected result reading interleaved accessor data from base64 encoded data uri");
auto a3Actual = resourceReader.ReadBinaryData<int8_t>(gltfDocument, accessor3);
auto a3Expected = std::vector<int8_t>{ '3', '3', '3', '3' };
Assert::IsTrue(a3Expected == a3Actual, L"Unexpected result reading interleaved accessor data from base64 encoded data uri");
auto a4Actual = resourceReader.ReadBinaryData<int8_t>(gltfDocument, accessor4);
auto a4Expected = std::vector<int8_t>{ '4', '4', '4', '4' };
Assert::IsTrue(a4Expected == a4Actual, L"Unexpected result reading interleaved accessor data from base64 encoded data uri");
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64UriFinal4Chars)
{
const auto data = Base64Decode("YW55IGNhcm5hbCBwbGVhc3Vy");
const std::string decodedString(data.begin(), data.end());
const std::string encodedString = "any carnal pleasur";
Assert::AreEqual(encodedString.c_str(), decodedString.c_str(), L"");
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64Uri_noPadding1)
{
std::string encoded_string = "a9TA";
Assert::IsTrue(std::vector<uint8_t>{ (uint8_t)0x6B, (uint8_t)0xD4, (uint8_t)0xC0 } == Base64Decode(encoded_string));
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64Uri_onePadding1)
{
const std::string encoded_string = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"
"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg"
"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu"
"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo"
"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=";
const std::string decoded_string = "Man is distinguished, not only by his reason, but by this singular passion from "
"other animals, which is a lust of the mind, that by a perseverance of delight "
"in the continued and indefatigable generation of knowledge, exceeds the short "
"vehemence of any carnal pleasure.";
Assert::IsTrue(std::vector<uint8_t>(decoded_string.begin(), decoded_string.end()) == Base64Decode(encoded_string));
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64Uri_twoPadding1)
{
const std::string encoded_string = "/+==";
Assert::IsTrue(std::vector<uint8_t>{ 0xFF } == Base64Decode(encoded_string));
}
// Randomly generated strings tested against other decoders
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64Uri_noPadding2)
{
const std::string encoded_string = "FyMP";
std::string expected = "\x17\x23\x0f";
Assert::IsTrue(std::vector<uint8_t>(expected.begin(), expected.end()) == Base64Decode(encoded_string));
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64Uri_twoPadding2)
{
const std::string encoded_string = "UpRSREKIOvh9DUlSc8PvywTI7d1f99eKJ0v3l4VtK1eVQwL4mqmKGHVoovwe21QsB3oKyFZpDFA8vVT3mzsWGakiHukw1a4qk4lRfx9Dhlw6INlWGeKcaxo+/i6dj2/MaAOXUFqEMeWYDeqdt1njqUIF3SZtmPMaLXKh5IHyt4ZdIRKVD+szeL==";
std::string expected = "\x52\x94\x52\x44\x42\x88\x3a\xf8\x7d\x0d\x49\x52\x73\xc3\xef\xcb\x04\xc8\xed\xdd\x5f\xf7\xd7\x8a\x27\x4b\xf7\x97\x85\x6d\x2b\x57\x95\x43\x02\xf8\x9a\xa9\x8a\x18\x75\x68\xa2\xfc\x1e\xdb\x54\x2c\x07\x7a\x0a\xc8\x56\x69\x0c\x50\x3c\xbd\x54\xf7\x9b\x3b\x16\x19\xa9\x22\x1e\xe9\x30\xd5\xae\x2a\x93\x89\x51\x7f\x1f\x43\x86\x5c\x3a\x20\xd9\x56\x19\xe2\x9c\x6b\x1a\x3e\xfe\x2e\x9d\x8f\x6f\xcc\x68\x03\x97\x50\x5a\x84\x31\xe5\x98\x0d\xea\x9d\xb7\x59\xe3\xa9\x42\x05\xdd\x26\x6d\x98\xf3\x1a\x2d\x72\xa1\xe4\x81\xf2\xb7\x86\x5d\x21\x12\x95\x0f\xeb\x33\x78";
Assert::IsTrue(std::vector<uint8_t>(expected.begin(), expected.end()) == Base64Decode(encoded_string));
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64Uri_noPadding3)
{
const std::string encoded_string = "+ZHqpntIdgEB52E9Xq6iS/usFvCAUed9xMJVYOabc/Rcmz/z7suY9R851bJMPSUjm4gBCEdsfREDxYDSkcakokFYtub3";
std::string expected = "\xf9\x91\xea\xa6\x7b\x48\x76\x01\x01\xe7\x61\x3d\x5e\xae\xa2\x4b\xfb\xac\x16\xf0\x80\x51\xe7\x7d\xc4\xc2\x55\x60\xe6\x9b\x73\xf4\x5c\x9b\x3f\xf3\xee\xcb\x98\xf5\x1f\x39\xd5\xb2\x4c\x3d\x25\x23\x9b\x88\x01\x08\x47\x6c\x7d\x11\x03\xc5\x80\xd2\x91\xc6\xa4\xa2\x41\x58\xb6\xe6\xf7";
Assert::IsTrue(std::vector<uint8_t>(expected.begin(), expected.end()) == Base64Decode(encoded_string));
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64Uri_onePadding2)
{
const std::string encoded_string = "i2FmFUWwv9jv/mdgNWBcgHtbhPy2Q/qx2MM4bs9p4DpTv/T+6Apri9ccxjvXp/No2dflixe1I3mTLXMQHLyXIDZ16J2=";
std::string expected = "\x8b\x61\x66\x15\x45\xb0\xbf\xd8\xef\xfe\x67\x60\x35\x60\x5c\x80\x7b\x5b\x84\xfc\xb6\x43\xfa\xb1\xd8\xc3\x38\x6e\xcf\x69\xe0\x3a\x53\xbf\xf4\xfe\xe8\x0a\x6b\x8b\xd7\x1c\xc6\x3b\xd7\xa7\xf3\x68\xd9\xd7\xe5\x8b\x17\xb5\x23\x79\x93\x2d\x73\x10\x1c\xbc\x97\x20\x36\x75\xe8\x9d";
Assert::IsTrue(std::vector<uint8_t>(expected.begin(), expected.end()) == Base64Decode(encoded_string));
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64Uri_twoPadding3)
{
const std::string encoded_string = "hhHYLzn0CsgdGhB461xgd9Dq8jLumIvChuBJbUMtjisoZIjJjjq1igFsljaNcqDdPtiEPJ1Yteqer20OwneXA6fjqMvcE1avUoTQQaK+JnBIjxbQIK2PdU6Z1myiFybCZl71FP0mdEZtoCAWTTZkj1+Vt5LoJpvdEtD8VwbYT+bVkxMo5Mve4nSg6Mg13i9I+I==";
std::string expected = "\x86\x11\xd8\x2f\x39\xf4\x0a\xc8\x1d\x1a\x10\x78\xeb\x5c\x60\x77\xd0\xea\xf2\x32\xee\x98\x8b\xc2\x86\xe0\x49\x6d\x43\x2d\x8e\x2b\x28\x64\x88\xc9\x8e\x3a\xb5\x8a\x01\x6c\x96\x36\x8d\x72\xa0\xdd\x3e\xd8\x84\x3c\x9d\x58\xb5\xea\x9e\xaf\x6d\x0e\xc2\x77\x97\x03\xa7\xe3\xa8\xcb\xdc\x13\x56\xaf\x52\x84\xd0\x41\xa2\xbe\x26\x70\x48\x8f\x16\xd0\x20\xad\x8f\x75\x4e\x99\xd6\x6c\xa2\x17\x26\xc2\x66\x5e\xf5\x14\xfd\x26\x74\x46\x6d\xa0\x20\x16\x4d\x36\x64\x8f\x5f\x95\xb7\x92\xe8\x26\x9b\xdd\x12\xd0\xfc\x57\x06\xd8\x4f\xe6\xd5\x93\x13\x28\xe4\xcb\xde\xe2\x74\xa0\xe8\xc8\x35\xde\x2f\x48\xf8";
Assert::IsTrue(std::vector<uint8_t>(expected.begin(), expected.end()) == Base64Decode(encoded_string));
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestValidBase64Uri_Empty)
{
const std::string encoded_string = "";
Assert::IsTrue(Base64Decode(encoded_string) == std::vector<uint8_t>());
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestInvalidBase64Uri_SpecialChar1)
{
Assert::ExpectException<GLTFException>([]()
{
const std::string encoded_string = "aaa\t";
Base64Decode(encoded_string);
});
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestInvalidBase64Uri_SpecialChar2)
{
Assert::ExpectException<GLTFException>([]()
{
const std::string encoded_string = "aa/\\";
Base64Decode(encoded_string);
});
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestInvalidBase64Uri_BadPadding)
{
Assert::ExpectException<GLTFException>([]()
{
const std::string encoded_string = "lfjoi=a=";
Base64Decode(encoded_string);
});
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestAllAsciiChar)
{
const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
constexpr uint8_t NUM_ASCII_CHARS = 128;
for (uint8_t i = 0; i < NUM_ASCII_CHARS; i++)
{
char c = static_cast<char>(i);
std::string encoded_string = { c, 'A', '=', '=' };
if (base64_chars.find(c) == std::string::npos)
{
Assert::ExpectException<GLTFException>([encoded_string]()
{
Base64Decode(encoded_string);
});
}
else
{
int decodedByte = (int)base64_chars.find(c) << 2;
auto decoded_string = Base64Decode(encoded_string);
Assert::IsTrue(decoded_string == std::vector<uint8_t>{ (uint8_t)decodedByte });
}
}
}
GLTFSDK_TEST_METHOD(ResourceReaderUtilsTest, TestIsUriBase64)
{
std::string::const_iterator itBegin;
std::string::const_iterator itEnd;
Assert::IsTrue(IsUriBase64("data:image/png;base64,/+==", itBegin, itEnd));
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,125 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/BufferBuilder.h>
#include <GLTFSDK/Deserialize.h>
#include <GLTFSDK/GLTF.h>
#include <GLTFSDK/GLTFResourceWriter.h>
#include <GLTFSDK/MeshPrimitiveUtils.h>
#include <GLTFSDK/Serialize.h>
using namespace glTF::UnitTest;
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(SerializeUnitTest)
{
GLTFSDK_TEST_METHOD(SerializeUnitTest, SerializeNodeMatrixTransform)
{
Document originalDoc;
Scene sc; sc.id = "0";
sc.nodes = { "0" };
originalDoc.SetDefaultScene(std::move(sc));
std::array<float, 16> matrixData; std::fill(matrixData.begin(), matrixData.end(), 1.0f);
Matrix4 mat4; mat4.values = matrixData;
Node matrixNode; matrixNode.id = "0"; matrixNode.name = "matrixNode";
matrixNode.matrix = mat4;
originalDoc.nodes.Append(std::move(matrixNode));
auto outputString = Serialize(originalDoc);
auto twoPassDoc = Deserialize(outputString);
Assert::IsTrue(twoPassDoc == originalDoc);
}
GLTFSDK_TEST_METHOD(SerializeUnitTest, SerializeNodeTRSTransform)
{
Document originalDoc;
Scene sc; sc.id = "0";
sc.nodes = { "0" };
originalDoc.SetDefaultScene(std::move(sc));
Vector3 translation = { 1.0f, 1.0f, 1.0f };
Vector3 scaling = { 0.1f, 0.42f, 0.133f };
Node trsNode; trsNode.id = "0"; trsNode.name = "trsNode";
trsNode.translation = translation;
trsNode.scale = scaling;
originalDoc.nodes.Append(std::move(trsNode));
auto outputString = Serialize(originalDoc);
auto twoPassDoc = Deserialize(outputString);
Assert::IsTrue(twoPassDoc == originalDoc);
}
GLTFSDK_TEST_METHOD(SerializeUnitTest, SerializeNodeInvalidTransform)
{
Assert::ExpectException<DocumentException>([]()
{
Document originalDoc;
Scene sc; sc.id = "0";
sc.nodes = { "0" };
originalDoc.SetDefaultScene(std::move(sc));
Vector3 translation = { 1.0f, 1.0f, 1.0f };
Vector3 scaling = { 0.1f, 0.42f, 0.133f };
std::array<float, 16> matrixData; std::fill(matrixData.begin(), matrixData.end(), 1.0f);
Matrix4 mat4; mat4.values = matrixData;
Node badNode; badNode.id = "0"; badNode.name = "badNode";
badNode.translation = translation;
badNode.scale = scaling;
badNode.matrix = mat4;
originalDoc.nodes.Append(std::move(badNode));
auto outputString = Serialize(originalDoc);
});
}
GLTFSDK_TEST_METHOD(SerializeUnitTest, MatrixNodeTest)
{
Node matrixNode;
std::array<float, 16> matrixData; std::fill(matrixData.begin(), matrixData.end(), 1.0f);
Matrix4 mat4; mat4.values = matrixData;
matrixNode.matrix = mat4;
Assert::IsTrue(matrixNode.GetTransformationType() == TransformationType::TRANSFORMATION_MATRIX);
}
GLTFSDK_TEST_METHOD(SerializeUnitTest, NoTransformTest)
{
Node defaultNode;
Assert::IsTrue(defaultNode.GetTransformationType() == TransformationType::TRANSFORMATION_IDENTITY);
}
GLTFSDK_TEST_METHOD(SerializeUnitTest, TRSNodeTest)
{
Node trsNode;
Vector3 scale = { 2.0f, 1.1f, 4.0f };
trsNode.scale = scale;
Assert::IsTrue(trsNode.GetTransformationType() == TransformationType::TRANSFORMATION_TRS);
}
GLTFSDK_TEST_METHOD(SerializeUnitTest, InvalidNodeTest)
{
Node badNode;
std::array<float, 16> matrixData; std::fill(matrixData.begin(), matrixData.end(), 1.0f);
Matrix4 mat4; mat4.values = matrixData;
Vector3 scale = { 2.0f, 1.1f, 4.0f };
badNode.matrix = mat4;
badNode.scale = scale;
Assert::IsFalse(badNode.HasValidTransformType());
}
GLTFSDK_TEST_METHOD(SerializeUnitTest, ValidNodeTest)
{
Node node;
Assert::IsTrue(node.HasValidTransformType());
}
GLTFSDK_TEST_METHOD(SerializeUnitTest, PerspectiveCameraTest)
{
Camera cam("0", "", std::make_unique<Perspective>(0.1f, 10.0f, 1.2f, 0.5f));
Assert::IsTrue(cam.projection->GetProjectionType() == ProjectionType::PERSPECTIVE);
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,220 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/StreamCacheLRU.h>
using namespace glTF::UnitTest;
namespace
{
class TestStreamReader : public Microsoft::glTF::IStreamReader
{
public:
std::shared_ptr<std::istream> GetInputStream(const std::string& uri) const override
{
auto it = m_counts.find(uri);
if (it == m_counts.end())
{
m_counts.insert({ uri, 1U });
}
else
{
it->second++;
}
return std::make_shared<std::stringstream>();
}
mutable std::unordered_map<std::string, size_t> m_counts;
};
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(StreamCacheTest)
{
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheGet)
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCache>(streamReader);
auto stream = streamCache->Get("1");// Should populate the cache with a new stream
Assert::IsTrue(static_cast<bool>(stream));
Assert::AreEqual(size_t(1), streamReader->m_counts.size());
Assert::AreEqual(size_t(1), streamReader->m_counts["1"]);
}
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheGetMultiple)
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCache>(streamReader);
const std::string uri = "1";
auto stream1 = streamCache->Get(uri);// Should populate the cache with a new stream
Assert::AreEqual(size_t(1), streamCache->Size());
Assert::AreEqual(size_t(1), streamReader->m_counts[uri]);
auto stream2 = streamCache->Get(uri);// Should return the stream previously added to the cache - stream reader shouldn't be called
Assert::AreEqual(size_t(1), streamCache->Size());
Assert::AreEqual(size_t(1), streamReader->m_counts[uri]);
Assert::IsTrue(stream1 == stream2);
}
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheSetGet)
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCache>(streamReader);
auto stream1 = std::make_shared<std::stringstream>("Stream");
streamCache->Set("1", stream1);
auto stream2 = streamCache->Get("1");
Assert::IsTrue(stream1 == stream2);
Assert::IsTrue(streamReader->m_counts.empty());// Stream reader should not have been called
}
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheSetMultiple)
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCache>(streamReader);
auto streamDog = std::make_shared<std::stringstream>("Dog");
streamCache->Set("1", streamDog);
auto streamCat = std::make_shared<std::stringstream>("Cat");
streamCache->Set("2", streamCat);
Assert::AreEqual(size_t(2), streamCache->Size());
Assert::IsTrue(streamReader->m_counts.empty());
auto ssCached1 = std::dynamic_pointer_cast<std::stringstream>(streamCache->Get("1"));
Assert::IsTrue(ssCached1 == streamDog);
Assert::IsTrue(ssCached1->str() == "Dog");
Assert::IsTrue(streamReader->m_counts.empty());
auto ssCached2 = std::dynamic_pointer_cast<std::stringstream>(streamCache->Get("2"));
Assert::IsTrue(ssCached2 == streamCat);
Assert::IsTrue(ssCached2->str() == "Cat");
Assert::IsTrue(streamReader->m_counts.empty());
}
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheErase)
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCache>(streamReader);
streamCache->Get("1");
Assert::AreEqual(size_t(1), streamCache->Size());
streamCache->Erase("1");
Assert::AreEqual(size_t(0), streamCache->Size());
streamCache->Get("1");
Assert::AreEqual(size_t(1), streamCache->Size());
Assert::AreEqual(size_t(2), streamReader->m_counts["1"]);
}
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheEraseFail)
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCache>(streamReader);
Assert::ExpectException<GLTFException>([&streamCache]() { streamCache->Erase("1"); });
}
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheLRUSetDuplicateKey)
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCacheLRU>(streamReader);
auto ssOriginal = std::make_shared<std::stringstream>("Red");
auto ssDuplicate = std::make_shared<std::stringstream>("Yellow");
streamCache->Set("1", ssOriginal);
streamCache->Set("1", ssDuplicate);
auto ssCached = std::dynamic_pointer_cast<std::stringstream>(streamCache->Get("1"));
Assert::IsTrue(ssCached == ssDuplicate);
Assert::IsTrue(ssCached->str() == "Yellow");
}
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheLRUSetMaxSize0)
{
Assert::ExpectException<GLTFException>([]()
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCacheLRU>(streamReader, 0U);
});
}
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheLRUSetMaxSize1)
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCacheLRU>(streamReader, 1U);
auto stream1 = streamCache->Get("1");
Assert::AreEqual(size_t(1), streamReader->m_counts["1"]);
Assert::AreEqual(size_t(1), streamCache->Size());
auto stream2 = streamCache->Get("2");
Assert::AreEqual(size_t(1), streamReader->m_counts["2"]);
Assert::AreEqual(size_t(1), streamCache->Size());
auto stream3 = streamCache->Get("1");
Assert::AreEqual(size_t(2), streamReader->m_counts["1"]);
Assert::AreEqual(size_t(1), streamCache->Size());
Assert::IsFalse(stream1 == stream3);// The returned streams should be different as the cache can only hold a single entry
}
GLTFSDK_TEST_METHOD(StreamCacheTest, StreamReaderCacheLRUSetMaxSize2)
{
auto streamReader = std::make_shared<TestStreamReader>();
auto streamCache = MakeStreamReaderCache<StreamReaderCacheLRU>(streamReader, 2U);
auto ss1 = std::make_shared<std::stringstream>("Apple");
auto ss2 = std::make_shared<std::stringstream>("Orange");
auto ss3 = std::make_shared<std::stringstream>("Pear");
streamCache->Set("1", ss1);
streamCache->Set("2", ss2);
streamCache->Set("3", ss3);
{
auto ss3Cached = std::dynamic_pointer_cast<std::stringstream>(streamCache->Get("3"));
Assert::IsTrue(ss3 == ss3Cached);
Assert::IsTrue(ss3Cached->str() == "Pear");
}
{
auto ss2Cached = std::dynamic_pointer_cast<std::stringstream>(streamCache->Get("2"));
Assert::IsTrue(ss2 == ss2Cached);
Assert::IsTrue(ss2Cached->str() == "Orange");
}
{
auto ss1Cached = std::dynamic_pointer_cast<std::stringstream>(streamCache->Get("1"));
Assert::IsTrue(ss1 != ss1Cached); // The max cache size is 2 - the 'Apple' stream should have been evicted from the cache
Assert::IsTrue(ss1Cached->str().empty());
}
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace Microsoft
{
namespace glTF
{
namespace Test
{
// NOTE: Make sure the names of resource files here exactly matches the actual file names
// as file/path names are case-sensitive in Android.
constexpr const char* c_glbSampleBoxInterleaved = "Resources\\glb\\BoxInterleaved.glb";
constexpr const char* c_glbCubeInvalidAccessorByteLength = "Resources\\glb\\CubeInvalidAccessorByteLength.glb";
constexpr const char* c_glbCubeInvalidAccessorByteOffset = "Resources\\glb\\CubeInvalidAccessorByteOffset.glb";
constexpr const char* c_glbCubeInvalidBufferViewLength = "Resources\\glb\\CubeInvalidBufferViewLength.glb";
constexpr const char* c_glbCubeMissingTextureRef = "Resources\\glb\\CubeMissingTextureRef.glb";
constexpr const char* c_glbDuckMissingMaterialRef = "Resources\\glb\\DuckMissingMaterialRef.glb";
constexpr const char* c_glbWrongBinHeaderLength = "Resources\\glb\\WrongBinHeaderLength.glb";
constexpr const char* c_glbWrongJsonLength = "Resources\\glb\\WrongJsonLength.glb";
constexpr const char* c_glbWrongReportedLength = "Resources\\glb\\WrongReportedLength.glb";
constexpr const char* c_validMorphTarget = "Resources\\gltf\\AnimatedMorphCube.gltf";
constexpr const char* c_animatedTriangleJson = "Resources\\gltf\\AnimatedTriangle.gltf";
constexpr const char* c_cameraInvalidPerspective = "Resources\\gltf\\CameraInvalidPerspective.gltf";
constexpr const char* c_cameraInvalidProjectionJson = "Resources\\gltf\\CameraInvalidProjection.gltf";
constexpr const char* c_cameraMissingProperties = "Resources\\gltf\\CameraMissingProperties.gltf";
constexpr const char* c_cartoonCurse01FbxJson = "Resources\\gltf\\CartoonCurse01Fbx.gltf";
constexpr const char* c_cubeJson = "Resources\\gltf\\Cube.gltf";
constexpr const char* c_cubeWithLODJson = "Resources\\gltf\\CubeWithLOD.gltf";
constexpr const char* c_doubleNodesJson = "Resources\\gltf\\DoubleNodes.gltf";
constexpr const char* c_doubleTriangleJson = "Resources\\gltf\\DoubleTriangle.gltf";
constexpr const char* c_dracoBox = "Resources\\gltf\\DracoBox.gltf";
constexpr const char* c_duplicateNodesJson = "Resources\\gltf\\DuplicateNodes.gltf";
constexpr const char* c_meshPrimitivesUV04 = "Resources\\gltf\\Mesh_PrimitivesUV_04.gltf";
constexpr const char* c_missingDefaultSceneJson = "Resources\\gltf\\MissingDefaultScene.gltf";
constexpr const char* c_missingMeshRefJson = "Resources\\gltf\\MissingMeshRef.gltf";
constexpr const char* c_missingNodeRefJson = "Resources\\gltf\\MissingNodeRef.gltf";
constexpr const char* c_reciprocatingSaw = "Resources\\gltf\\ReciprocatingSaw.gltf";
constexpr const char* c_riggedSimpleJson = "Resources\\gltf\\RiggedSimple.gltf";
constexpr const char* c_simpleSparseAccessor = "Resources\\gltf\\SimpleSparseAccessor.gltf";
constexpr const char* c_singlePolyWithNormalsJson = "Resources\\gltf\\SinglePolyWithNormals.gltf";
constexpr const char* c_singleTriangleJson = "Resources\\gltf\\SingleTriangle.gltf";
constexpr const char* c_singleTriangleWithTextureJson = "Resources\\gltf\\SingleTriangleWithTexture.gltf";
constexpr const char* c_transformsJson = "Resources\\gltf\\Transforms.gltf";
constexpr const char* c_validTriangleWithoutIndices = "Resources\\gltf\\TriangleWithoutIndices.gltf";
constexpr const char* c_validTriangleMatrix = "Resources\\gltf\\TriangleWithoutIndices_Matrix.gltf";
constexpr const char* c_validTriangleTRS = "Resources\\gltf\\TriangleWithoutIndices_TRS.gltf";
constexpr const char* c_validCameraJson = "Resources\\gltf\\ValidCamera.gltf";
constexpr const char* c_cameraWithExtensions = "Resources\\gltf\\ValidCameraWithExtensions.gltf";
}
}
}

Просмотреть файл

@ -0,0 +1,140 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include <GLTFSDK/BufferBuilder.h>
#include <GLTFSDK/GLTFResourceReader.h>
#include <GLTFSDK/GLTFResourceWriter.h>
#include <GLTFSDK/IStreamReader.h>
#include <GLTFSDK/IStreamWriter.h>
#include <fstream>
#include <memory>
#include <unordered_map>
#include <sstream>
using namespace glTF::UnitTest;
namespace Microsoft
{
namespace glTF
{
namespace Test
{
template <typename T>
static void AreEqual(const std::vector<T>& a, const std::vector<T>& b, wchar_t const* message = nullptr)
{
Assert::IsTrue(a == b, message);
}
class StreamReaderWriter : public Microsoft::glTF::IStreamWriter, public Microsoft::glTF::IStreamReader
{
public:
StreamReaderWriter()
: m_streams()
{
}
std::shared_ptr<std::ostream> GetOutputStream(const std::string& uri) const override
{
return GetStream(uri);
}
std::shared_ptr<std::istream> GetInputStream(const std::string& uri) const override
{
return GetStream(uri);
}
private:
std::shared_ptr<std::iostream> GetStream(const std::string& uri) const
{
if (m_streams.find(uri) == m_streams.end())
{
m_streams[uri] = std::make_shared<std::stringstream>();
}
return m_streams[uri];
}
mutable std::unordered_map<std::string, std::shared_ptr<std::stringstream>> m_streams;
};
inline std::string GetAbsolutePath(const char * relativePath)
{
#ifndef _WIN32
// Leaving Win32 alone (below), but macOS and Android requires working directory to be set
std::string finalPath(relativePath);
std::replace(finalPath.begin(), finalPath.end(), '\\', '/');
return finalPath;
#else
std::string currentPath = __FILE__;
std::string sourcePath = currentPath.substr(0, currentPath.rfind('\\'));
std::string resourcePath = sourcePath.substr(0, sourcePath.rfind('\\'));
std::string finalPath = resourcePath + "\\" + relativePath;
return finalPath;
#endif
}
inline std::shared_ptr<std::stringstream> ReadLocalAsset(const std::string& relativePath)
{
auto filename = GetAbsolutePath(relativePath.c_str());
// Read local file
int64_t m_readPosition = 0;
std::shared_ptr<const std::vector<int8_t>> m_buffer;
std::ifstream ifs;
ifs.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
if (ifs.is_open())
{
std::streampos start = ifs.tellg();
ifs.seekg(0, std::ios::end);
m_buffer = std::make_shared<const std::vector<int8_t>>(static_cast<unsigned int>(ifs.tellg() - start));
ifs.seekg(0, std::ios::beg);
ifs.read(reinterpret_cast<char*>(const_cast<int8_t*>(m_buffer->data())), m_buffer->size());
ifs.close();
}
else
{
throw std::runtime_error("Could not open the file for reading");
}
// To IStream
unsigned long writeBufferLength = 4096L * 1024L;
auto tempStream = std::make_shared<std::stringstream>();
auto tempBuffer = new char[writeBufferLength];
// Read the file for as long as we can fill the buffer completely.
// This means there is more content to be read.
unsigned long bytesRead;
do
{
auto bytesAvailable = m_buffer->size() - m_readPosition;
unsigned long br = std::min(static_cast<unsigned long>(bytesAvailable), writeBufferLength);
#ifdef _WIN32
memcpy_s(tempBuffer, br, m_buffer->data() + m_readPosition, br);
#else
memcpy(tempBuffer, m_buffer->data() + m_readPosition, br);
#endif
m_readPosition += br;
bytesRead = br;
tempStream->write(tempBuffer, bytesRead);
} while (bytesRead == writeBufferLength);
delete[] tempBuffer;
if (tempStream.get()->bad())
{
throw std::runtime_error("Bad std::stringstream after copying the file");
}
return tempStream;
}
inline std::string ReadLocalJson(const char * relativePath)
{
auto input = ReadLocalAsset(relativePath);
auto json = std::string(std::istreambuf_iterator<char>(*input), std::istreambuf_iterator<char>());
return json;
}
}
}
}

Просмотреть файл

@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/Validation.h>
#include <cmath>
using namespace glTF::UnitTest;
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(ValidationUnitTests)
{
GLTFSDK_TEST_METHOD(ValidationUnitTests, TestAddition_size_t_NoOverflow)
{
size_t a = std::numeric_limits<size_t>::max() - 500;
size_t b = 42;
size_t t;
Assert::IsTrue(Validation::SafeAddition(a, b, t) && t == (a + b));
}
GLTFSDK_TEST_METHOD(ValidationUnitTests, TestAddition_size_t_MaxNoOverflow)
{
size_t a = std::numeric_limits<size_t>::max() - 1;
size_t b = 1;
size_t t;
Assert::IsTrue(Validation::SafeAddition(a, b, t) && t == (a + b));
}
GLTFSDK_TEST_METHOD(ValidationUnitTests, TestAddition_size_t_MinOverflow)
{
size_t a = std::numeric_limits<size_t>::max();
size_t b = 1;
size_t t;
Assert::IsFalse(Validation::SafeAddition(a, b, t));
}
GLTFSDK_TEST_METHOD(ValidationUnitTests, TestAddition_size_t_Overflow)
{
size_t a = std::numeric_limits<size_t>::max();
size_t b = 42;
size_t t;
Assert::IsFalse(Validation::SafeAddition(a, b, t));
}
GLTFSDK_TEST_METHOD(ValidationUnitTests, TestMultiplication_size_t_NoOverflow)
{
size_t a = 42;
size_t b = 42;
size_t t;
Assert::IsTrue(Validation::SafeMultiplication(a, b, t) && t == a * b);
}
GLTFSDK_TEST_METHOD(ValidationUnitTests, TestMultiplication_size_t_MaxNoOverflow)
{
size_t a = std::numeric_limits<size_t>::max() >> 1;
size_t b = 2;
size_t t;
Assert::IsTrue(Validation::SafeMultiplication(a, b, t) && t == (a * b));
}
GLTFSDK_TEST_METHOD(ValidationUnitTests, TestMultiplication_size_t_MinOverflow)
{
size_t a = std::numeric_limits<size_t>::max() >> (sizeof(size_t) / 2);
size_t b = a;
size_t t;
Assert::IsFalse(Validation::SafeMultiplication(a, b, t));
}
GLTFSDK_TEST_METHOD(ValidationUnitTests, TestMultiplication_size_t_Overflow)
{
size_t a = std::numeric_limits<size_t>::max();
size_t b = std::numeric_limits<size_t>::max();
size_t t;
Assert::IsFalse(Validation::SafeMultiplication(a, b, t));
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,142 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/Version.h>
#include <GLTFSDK/Constants.h>
#include <GLTFSDK/Exceptions.h>
using namespace glTF::UnitTest;
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(VersionTests)
{
GLTFSDK_TEST_METHOD(VersionTests, VersionAsString)
{
auto version = Version(2U, 0U);
auto versionStr = version.AsString();
Assert::AreEqual(GLTF_VERSION_2_0, versionStr.c_str(), L"Unexpected version string");
}
GLTFSDK_TEST_METHOD(VersionTests, VersionAsTupleSuccess)
{
Version versionDefault = Version::AsTuple(GLTF_VERSION_2_0);
Assert::AreEqual(2U, static_cast<unsigned int>(versionDefault.major), L"Unexpected major version number");
Assert::AreEqual(0U, static_cast<unsigned int>(versionDefault.minor), L"Unexpected minor version number");
}
GLTFSDK_TEST_METHOD(VersionTests, VersionAsTupleSuccessMultiDigit)
{
Version versionDefault = Version::AsTuple("777.888");
Assert::AreEqual(777U, static_cast<unsigned int>(versionDefault.major), L"Unexpected major version number");
Assert::AreEqual(888U, static_cast<unsigned int>(versionDefault.minor), L"Unexpected minor version number");
}
GLTFSDK_TEST_METHOD(VersionTests, VersionAsTupleInvalid)
{
Assert::ExpectException<GLTFException>([] {Version::AsTuple(""); }); // Empty string is invalid
Assert::ExpectException<GLTFException>([] {Version::AsTuple("0"); }); // Single number
Assert::ExpectException<GLTFException>([] {Version::AsTuple("."); }); // Missing major & minor version numbers
Assert::ExpectException<GLTFException>([] {Version::AsTuple(".0"); }); // Missing major version number
Assert::ExpectException<GLTFException>([] {Version::AsTuple("0."); }); // Missing minor version number
Assert::ExpectException<GLTFException>([] {Version::AsTuple("0.0.0"); }); // Unexpected use of major, minor and patch numbers
Assert::ExpectException<GLTFException>([] {Version::AsTuple("A.0"); }); // Non-numeric major version number
Assert::ExpectException<GLTFException>([] {Version::AsTuple("0.A"); }); // Non-numeric minor version number
Assert::ExpectException<GLTFException>([] {Version::AsTuple("+0.0"); }); // Unexpected prefix
Assert::ExpectException<GLTFException>([] {Version::AsTuple("0.0+"); }); // Unexpected postfix
Assert::ExpectException<GLTFException>([] {Version::AsTuple("-0.0"); }); // Unexpected prefix
Assert::ExpectException<GLTFException>([] {Version::AsTuple("0.0-"); }); // Unexpected postfix
Assert::ExpectException<GLTFException>([] {Version::AsTuple("0x0.0"); }); // Unexpected major number base prefix (hex)
Assert::ExpectException<GLTFException>([] {Version::AsTuple("0.0x0"); }); // Unexpected minor number base prefix (hex)
Assert::ExpectException<GLTFException>([] {Version::AsTuple("9876543210.0"); }); // Large major number (outside 32bit range)
Assert::ExpectException<GLTFException>([] {Version::AsTuple("0.9876543210"); }); // Large minor number (outside 32bit range)
Assert::ExpectException<GLTFException>([] {Version::AsTuple("9876543210.9876543210"); }); // Large numbers (outside 32bit range)
Assert::ExpectException<GLTFException>([] {Version::AsTuple(nullptr); }); // nullptr is invalid
}
GLTFSDK_TEST_METHOD(VersionTests, IsMinVersionRequirementSatisfiedDefault)
{
Assert::IsTrue(IsMinVersionRequirementSatisfied(GLTF_VERSION_2_0));
}
GLTFSDK_TEST_METHOD(VersionTests, IsMinVersionRequirementSatisfiedEmptyVersion)
{
Assert::IsTrue(IsMinVersionRequirementSatisfied({}));
}
GLTFSDK_TEST_METHOD(VersionTests, IsMinVersionRequirementSatisfiedEmptySupported)
{
Assert::ExpectException<GLTFException>([] { IsMinVersionRequirementSatisfied({}, {}); }); // Exception due to empty 'supported' list has precedence over empty min version success
}
GLTFSDK_TEST_METHOD(VersionTests, IsMinVersionRequirementSatisfiedMultipleMinorVersions)
{
// 2.1 support isn't explicitly listed but is implied by inclusion of 2.2 and 2.3
auto supportedVersions = {
Version(2U, 0U),
Version(2U, 2U),
Version(2U, 3U)
};
// Supported
Assert::IsTrue(IsMinVersionRequirementSatisfied("2.0", supportedVersions));
Assert::IsTrue(IsMinVersionRequirementSatisfied("2.1", supportedVersions));
Assert::IsTrue(IsMinVersionRequirementSatisfied("2.2", supportedVersions));
Assert::IsTrue(IsMinVersionRequirementSatisfied("2.3", supportedVersions));
// Not supported
Assert::IsFalse(IsMinVersionRequirementSatisfied("2.4", supportedVersions));
}
GLTFSDK_TEST_METHOD(VersionTests, IsMinVersionRequirementSatisfiedMajorMultipleMajorVersions)
{
// 1.x -> no support
// 2.x -> supports 2.0, 2.1 and 2.2
// 3.x -> supports 3.0 and 3.1
// 4.x -> supports 4.0
auto supportedVersions = {
Version(2U, 2U),
Version(3U, 1U),
Version(4U, 0U)
};
// 1.0 -> not supported
Assert::IsFalse(IsMinVersionRequirementSatisfied("1.0", supportedVersions));
// 2.0 -> supported
// 2.1 -> supported
// 2.2 -> supported
// 2.3 -> not supported
Assert::IsTrue( IsMinVersionRequirementSatisfied("2.0", supportedVersions));
Assert::IsTrue( IsMinVersionRequirementSatisfied("2.1", supportedVersions));
Assert::IsTrue( IsMinVersionRequirementSatisfied("2.2", supportedVersions));
Assert::IsFalse(IsMinVersionRequirementSatisfied("2.3", supportedVersions));
// 3.0 -> supported
// 3.1 -> supported
// 3.2 -> not supported
Assert::IsTrue( IsMinVersionRequirementSatisfied("3.0", supportedVersions));
Assert::IsTrue( IsMinVersionRequirementSatisfied("3.1", supportedVersions));
Assert::IsFalse(IsMinVersionRequirementSatisfied("3.2", supportedVersions));
// 4.0 -> supported
// 4.1 -> not supported
Assert::IsTrue( IsMinVersionRequirementSatisfied("4.0", supportedVersions));
Assert::IsFalse(IsMinVersionRequirementSatisfied("4.1", supportedVersions));
// 5.0 -> not supported
Assert::IsFalse(IsMinVersionRequirementSatisfied("5.0", supportedVersions));
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,402 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/Deserialize.h>
#include <GLTFSDK/ExtensionsKHR.h>
#include <GLTFSDK/Visitor.h>
using namespace glTF::UnitTest;
namespace
{
static const char testVisitorJson[] = R"(
{
"asset":
{
"version": "2.0"
},
"scenes": [
{
"nodes": [0, 1]
}
],
"nodes": [
{
"children": [2],
"name": "parent_node0"
},
{
"children": [3],
"name": "parent_node1"
},
{
"mesh": 0,
"name": "child_node0"
},
{
"mesh": 0,
"name": "child_node1"
}
],
"meshes": [
{
"primitives": [
{
"attributes":
{
"POSITION": 0
},
"mode": 4
}
],
"name": "test_mesh"
}
]
}
)";
static const char testVisitorDefaultActionSpecGlossJson[] = R"(
{
"asset":
{
"version": "2.0"
},
"scenes": [
{
"nodes": [0]
}
],
"nodes": [
{
"mesh": 0
}
],
"meshes": [
{
"primitives": [
{
"attributes":
{
"POSITION": 0
},
"material": 0
}
],
"name": "test_mesh"
}
],
"materials": [
{
"extensions":
{
"KHR_materials_pbrSpecularGlossiness":
{
"diffuseTexture":
{
"index": 0
},
"specularGlossinessTexture":
{
"index": 1
}
}
},
"pbrMetallicRoughness":
{
"baseColorTexture":
{
"index": 0
}
}
}
],
"textures": [
{
"source": 0
},
{
"source": 0
}
],
"images": [
{
"uri": "http://test"
}
]
}
)";
static const char testTraversalJson[] = R"(
{
"asset":
{
"version": "2.0"
},
"scenes": [
{
"nodes": [0]
}
],
"nodes": [
{
"children": [1, 2],
"name": "parent_node0"
},
{
"children": [3, 4],
"name": "parent_node1"
},
{
"children": [5, 6],
"name": "parent_node3"
},
{
"mesh": 0,
"name": "child_node0"
},
{
"mesh": 0,
"name": "child_node1"
},
{
"mesh": 0,
"name": "child_node2"
},
{
"mesh": 0,
"name": "child_node3"
}
],
"meshes": [
{
"primitives": [
{
"attributes":
{
"POSITION": 0
},
"mode": 4
}
],
"name": "test_mesh"
}
]
}
)";
}
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(VisitorTests)
{
GLTFSDK_TEST_METHOD(VisitorTests, TestVisitor)
{
Document gltfDoc = Deserialize(testVisitorJson);
size_t countNode = 0;
size_t countNodeRoot = 0;
size_t countMesh = 0;
size_t countMeshInstances = 0;
size_t countMeshPrimitive = 0;
size_t countMeshPrimitiveInstances = 0;
Visit(gltfDoc, DefaultSceneIndex,
[&countNode, &countNodeRoot](const Node&, const Node* nodeParent)
{
countNode++;
countNodeRoot += nodeParent ? 1 : 0;
},
[&countMesh, &countMeshInstances](const Mesh&, VisitState visitState)
{
countMesh += (visitState == VisitState::New) ? 1 : 0;
countMeshInstances++;
},
[&countMeshPrimitive, &countMeshPrimitiveInstances](const MeshPrimitive&, VisitState visitState)
{
countMeshPrimitive += (visitState == VisitState::New) ? 1 : 0;
countMeshPrimitiveInstances++;
});
Assert::AreEqual<size_t>(4UL, countNode);
Assert::AreEqual<size_t>(2UL, countNodeRoot);
Assert::AreEqual<size_t>(1UL, countMesh);
Assert::AreEqual<size_t>(2UL, countMeshInstances);
Assert::AreEqual<size_t>(1UL, countMeshPrimitive);
Assert::AreEqual<size_t>(2UL, countMeshPrimitiveInstances);
}
GLTFSDK_TEST_METHOD(VisitorTests, TestVisitorDefaultAction)
{
Document gltfDoc = Deserialize(testVisitorJson);
size_t countNode = 0;
size_t countNodeRoot = 0;
size_t countMesh = 0;
size_t countMeshInstances = 0;
size_t countMeshPrimitive = 0;
size_t countMeshPrimitiveInstances = 0;
Visit(gltfDoc, DefaultSceneIndex,
[&countNode, &countNodeRoot](const Node&, const Node* nodeParent)
{
countNode++;
countNodeRoot += nodeParent ? 1 : 0;
},
[&countMesh, &countMeshInstances](const Mesh&, VisitState visitState, const VisitDefaultAction&)
{
countMesh += (visitState == VisitState::New) ? 1 : 0;
countMeshInstances++;
},
[&countMeshPrimitive, &countMeshPrimitiveInstances](const MeshPrimitive&, VisitState visitState, const VisitDefaultAction&)
{
countMeshPrimitive += (visitState == VisitState::New) ? 1 : 0;
countMeshPrimitiveInstances++;
});
Assert::AreEqual<size_t>(4UL, countNode);
Assert::AreEqual<size_t>(2UL, countNodeRoot);
Assert::AreEqual<size_t>(1UL, countMesh);
Assert::AreEqual<size_t>(2UL, countMeshInstances);
Assert::AreEqual<size_t>(1UL, countMeshPrimitive);
Assert::AreEqual<size_t>(2UL, countMeshPrimitiveInstances);
}
GLTFSDK_TEST_METHOD(VisitorTests, TestVisitorDefaultActionSpecGloss)
{
Document gltfDoc = Deserialize(testVisitorDefaultActionSpecGlossJson, KHR::GetKHRExtensionDeserializer());
enum class TextureTypeExt : std::underlying_type_t<TextureType>
{
Diffuse = static_cast<std::underlying_type_t<TextureType>>(TextureType::Emissive) + 1,
SpecularGlossiness
};
TextureType textureTypeExpected = TextureType::BaseColor;
size_t countTexture = 0;
size_t countTextureInstances = 0;
size_t countImage = 0;
size_t countImageInstances = 0;
Visit(gltfDoc, DefaultSceneIndex,
[&gltfDoc, &textureTypeExpected](const Material& material, VisitState visitState, const VisitDefaultAction& visitDefaultAction)
{
if (visitState == VisitState::New)
{
if (material.HasExtension<KHR::Materials::PBRSpecularGlossiness>())
{
const auto& specGloss = material.GetExtension<KHR::Materials::PBRSpecularGlossiness>();
if (!specGloss.diffuseTexture.textureId.empty())
{
textureTypeExpected = static_cast<TextureType>(TextureTypeExt::Diffuse);
visitDefaultAction.Visit(gltfDoc.textures.Get(specGloss.diffuseTexture.textureId), textureTypeExpected);
}
if (!specGloss.specularGlossinessTexture.textureId.empty())
{
textureTypeExpected = static_cast<TextureType>(TextureTypeExt::SpecularGlossiness);
visitDefaultAction.Visit(gltfDoc.textures.Get(specGloss.specularGlossinessTexture.textureId), textureTypeExpected);
}
}
if (!material.metallicRoughness.baseColorTexture.textureId.empty())
{
textureTypeExpected = TextureType::BaseColor;
}
}
},
[&countTexture, &countTextureInstances, &textureTypeExpected](const Texture&, TextureType textureType, VisitState visitState)
{
countTexture += (visitState == VisitState::New) ? 1 : 0;
countTextureInstances++;
Assert::IsTrue(textureTypeExpected == textureType);
},
[&countImage, &countImageInstances](const Image&, VisitState visitState)
{
countImage += (visitState == VisitState::New) ? 1 : 0;
countImageInstances++;
});
Assert::AreEqual<size_t>(2UL, countTexture);
Assert::AreEqual<size_t>(3UL, countTextureInstances);
Assert::AreEqual<size_t>(1UL, countImage);
Assert::AreEqual<size_t>(3UL, countImageInstances);
}
GLTFSDK_TEST_METHOD(VisitorTests, TestVisitorTraversalDepthFirst)
{
Document gltfDoc = Deserialize(testTraversalJson);
std::vector<std::string> ids;
Visit<DepthFirst>(gltfDoc, DefaultSceneIndex,
[&ids](const Node& node, const Node*)
{
ids.push_back(node.id);
});
std::string idsExpected[] = { "0", "1", "3", "4", "2", "5", "6" };
Assert::IsTrue(std::equal(std::begin(idsExpected), std::end(idsExpected), ids.begin()));
}
GLTFSDK_TEST_METHOD(VisitorTests, TestVisitorTraversalBreadthFirst)
{
Document gltfDoc = Deserialize(testTraversalJson);
std::vector<std::string> ids;
Visit<BreadthFirst>(gltfDoc, DefaultSceneIndex,
[&ids](const Node& node, const Node*)
{
ids.push_back(node.id);
});
std::string idsExpected[] = { "0", "1", "2", "3", "4", "5", "6" };
Assert::IsTrue(std::equal(std::begin(idsExpected), std::end(idsExpected), ids.begin()));
}
GLTFSDK_TEST_METHOD(VisitorTests, TestVisitorFunctionPointer)
{
static bool g_isVisited = false;
struct VisitorFunctions
{
static void MeshPrimitiveCallback(const MeshPrimitive&, VisitState)
{
g_isVisited = true;
}
};
Document gltfDoc = Deserialize(testVisitorJson);
Visit(gltfDoc, DefaultSceneIndex, &VisitorFunctions::MeshPrimitiveCallback);
Assert::IsTrue(g_isVisited);
// Reset back to false - just in case the test is run multiple times by the same process
g_isVisited = false;
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,83 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "stdafx.h"
#include <GLTFSDK/GLTF.h>
namespace
{
template<typename TDerived>
class TestExtensionBase : public Microsoft::glTF::Extension
{
public:
std::unique_ptr<Microsoft::glTF::Extension> Clone() const override
{
return std::make_unique<TDerived>(static_cast<const TDerived&>(*this));
}
bool IsEqual(const Microsoft::glTF::Extension& rhs) const override
{
return dynamic_cast<const TDerived*>(&rhs) != nullptr;
}
protected:
TestExtensionBase() = default;
};
template<int N>
class TestExtension : public TestExtensionBase<TestExtension<N>> {};
}
using namespace glTF::UnitTest;
namespace Microsoft
{
namespace glTF
{
namespace Test
{
GLTFSDK_TEST_CLASS(glTFPropertyTests)
{
GLTFSDK_TEST_METHOD(glTFPropertyTests, RegisteredExtensionEqualsTrue)
{
Node node1;
node1.SetExtension<TestExtension<0>>();
node1.SetExtension<TestExtension<1>>();
node1.SetExtension<TestExtension<2>>();
// Adding same extensions in a different order - nodes should be considered equal
Node node2;
node2.SetExtension<TestExtension<2>>();
node2.SetExtension<TestExtension<1>>();
node2.SetExtension<TestExtension<0>>();
Assert::IsTrue(node1 == node2);
}
GLTFSDK_TEST_METHOD(glTFPropertyTests, RegisteredExtensionEqualsFalse)
{
Node node1;
node1.SetExtension<TestExtension<0>>();
node1.SetExtension<TestExtension<1>>();
node1.SetExtension<TestExtension<2>>();
// Adding different types of extensions - nodes should not be considered equal
Node node2;
node2.SetExtension<TestExtension<3>>();
node2.SetExtension<TestExtension<4>>();
node2.SetExtension<TestExtension<5>>();
Assert::IsFalse(node1 == node2);
// Adding different numbers of extensions - nodes should not be considered equal
Node node3;
node3.SetExtension<TestExtension<0>>();
node3.SetExtension<TestExtension<1>>();
Assert::IsFalse(node1 == node3);
}
};
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// stdafx.cpp : source file that includes just the standard includes
// GLTFSDK.Test.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="googletest" version="1.8.2" targetFramework="native" />
<package id="googletest.redist" version="1.8.2" targetFramework="native" />
<package id="rapidjson.tempRelease" version="0.0.2.20" targetFramework="native" />
</packages>

15
GLTFSDK.Test/stdafx.h Normal file
Просмотреть файл

@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#ifdef _WIN32
#include "targetver.h"
#endif
#include <TestUtilsCommon/UnitTestBridge.h>

11
GLTFSDK.Test/targetver.h Normal file
Просмотреть файл

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

Просмотреть файл

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.5)
project (GLTFSDK.TestUtils)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -D_DEBUG -DFEATURE_ASSERTS_ENABLED")
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.11)
add_library(GLTFSDK.TestUtils INTERFACE IMPORTED GLOBAL)
set_target_properties(GLTFSDK.TestUtils PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}")

Просмотреть файл

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<ItemsProjectGuid>{f4fd814f-0664-49ae-a41d-99f1bb24f0ce}</ItemsProjectGuid>
<ItemsProjectName>GLTFSDK.TestUtils</ItemsProjectName>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectCapability Include="SourceItemsFromImports" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(MSBuildThisFileDirectory)..\GLTFSDK.TestUtils\TestUtilsCommon\UnitTestBridge.h" />
</ItemGroup>
</Project>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше