pass through but panic
parent
2afeddd5cb
commit
4045466f73
|
@ -344,7 +344,11 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
|||
# Why assimp_qt_viewer/CMakeLists.txt still contain similar check?
|
||||
# Because viewer can be build independently of Assimp.
|
||||
FIND_PACKAGE(Qt5Widgets QUIET)
|
||||
set(CMAKE_MODULE_PATH_BACKUP ${CMAKE_MODULE_PATH})
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
|
||||
FIND_PACKAGE(DevIL QUIET)
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
|
||||
set(CMAKE_MODULE_PATH_BACKUP ${CMAKE_MODULE_PATH})
|
||||
FIND_PACKAGE(OpenGL QUIET)
|
||||
IF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#.rst:
|
||||
# FindDevIL
|
||||
# ---------
|
||||
#
|
||||
#
|
||||
#
|
||||
# This module locates the developer's image library.
|
||||
# http://openil.sourceforge.net/
|
||||
#
|
||||
# This module sets:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# IL_LIBRARIES - the name of the IL library. These include the full path to
|
||||
# the core DevIL library. This one has to be linked into the
|
||||
# application.
|
||||
# ILU_LIBRARIES - the name of the ILU library. Again, the full path. This
|
||||
# library is for filters and effects, not actual loading. It
|
||||
# doesn't have to be linked if the functionality it provides
|
||||
# is not used.
|
||||
# ILUT_LIBRARIES - the name of the ILUT library. Full path. This part of the
|
||||
# library interfaces with OpenGL. It is not strictly needed
|
||||
# in applications.
|
||||
# IL_INCLUDE_DIR - where to find the il.h, ilu.h and ilut.h files.
|
||||
# IL_FOUND - this is set to TRUE if all the above variables were set.
|
||||
# This will be set to false if ILU or ILUT are not found,
|
||||
# even if they are not needed. In most systems, if one
|
||||
# library is found all the others are as well. That's the
|
||||
# way the DevIL developers release it.
|
||||
|
||||
# TODO: Add version support.
|
||||
# Tested under Linux and Windows (MSVC)
|
||||
|
||||
#include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(IL_INCLUDE_DIR il.h
|
||||
PATH_SUFFIXES include IL
|
||||
DOC "The path to the directory that contains il.h"
|
||||
)
|
||||
|
||||
#message("IL_INCLUDE_DIR is ${IL_INCLUDE_DIR}")
|
||||
|
||||
find_library(IL_LIBRARIES
|
||||
NAMES IL DEVIL
|
||||
PATH_SUFFIXES lib64 lib lib32
|
||||
DOC "The file that corresponds to the base il library."
|
||||
)
|
||||
|
||||
#message("IL_LIBRARIES is ${IL_LIBRARIES}")
|
||||
|
||||
find_library(ILUT_LIBRARIES
|
||||
NAMES ILUT
|
||||
PATH_SUFFIXES lib64 lib lib32
|
||||
DOC "The file that corresponds to the il (system?) utility library."
|
||||
)
|
||||
|
||||
#message("ILUT_LIBRARIES is ${ILUT_LIBRARIES}")
|
||||
|
||||
find_library(ILU_LIBRARIES
|
||||
NAMES ILU
|
||||
PATH_SUFFIXES lib64 lib lib32
|
||||
DOC "The file that corresponds to the il utility library."
|
||||
)
|
||||
|
||||
#message("ILU_LIBRARIES is ${ILU_LIBRARIES}")
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(IL DEFAULT_MSG
|
||||
IL_LIBRARIES IL_INCLUDE_DIR)
|
|
@ -0,0 +1,690 @@
|
|||
# This module can find the International Components for Unicode (ICU) libraries
|
||||
#
|
||||
# Requirements:
|
||||
# - CMake >= 2.8.3 (for new version of find_package_handle_standard_args)
|
||||
#
|
||||
# The following variables will be defined for your use:
|
||||
# - ICU_FOUND : were all of your specified components found?
|
||||
# - ICU_INCLUDE_DIRS : ICU include directory
|
||||
# - ICU_LIBRARIES : ICU libraries
|
||||
# - ICU_VERSION : complete version of ICU (x.y.z)
|
||||
# - ICU_VERSION_MAJOR : major version of ICU
|
||||
# - ICU_VERSION_MINOR : minor version of ICU
|
||||
# - ICU_VERSION_PATCH : patch version of ICU
|
||||
# - ICU_<COMPONENT>_FOUND : were <COMPONENT> found? (FALSE for non specified component if it is not a dependency)
|
||||
#
|
||||
# For windows or non standard installation, define ICU_ROOT_DIR variable to point to the root installation of ICU. Two ways:
|
||||
# - run cmake with -DICU_ROOT_DIR=<PATH>
|
||||
# - define an environment variable with the same name before running cmake
|
||||
# With cmake-gui, before pressing "Configure":
|
||||
# 1) Press "Add Entry" button
|
||||
# 2) Add a new entry defined as:
|
||||
# - Name: ICU_ROOT_DIR
|
||||
# - Type: choose PATH in the selection list
|
||||
# - Press "..." button and select the root installation of ICU
|
||||
#
|
||||
# Example Usage:
|
||||
#
|
||||
# 1. Copy this file in the root of your project source directory
|
||||
# 2. Then, tell CMake to search this non-standard module in your project directory by adding to your CMakeLists.txt:
|
||||
# set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
|
||||
# 3. Finally call find_package() once, here are some examples to pick from
|
||||
#
|
||||
# Require ICU 4.4 or later
|
||||
# find_package(ICU 4.4 REQUIRED)
|
||||
#
|
||||
# if(ICU_FOUND)
|
||||
# add_executable(myapp myapp.c)
|
||||
# include_directories(${ICU_INCLUDE_DIRS})
|
||||
# target_link_libraries(myapp ${ICU_LIBRARIES})
|
||||
# # with CMake >= 3.0.0, the last two lines can be replaced by the following
|
||||
# target_link_libraries(myapp ICU::ICU)
|
||||
# endif(ICU_FOUND)
|
||||
|
||||
########## <ICU finding> ##########
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
|
||||
########## Private ##########
|
||||
if(NOT DEFINED ICU_PUBLIC_VAR_NS)
|
||||
set(ICU_PUBLIC_VAR_NS "ICU") # Prefix for all ICU relative public variables
|
||||
endif(NOT DEFINED ICU_PUBLIC_VAR_NS)
|
||||
if(NOT DEFINED ICU_PRIVATE_VAR_NS)
|
||||
set(ICU_PRIVATE_VAR_NS "_${ICU_PUBLIC_VAR_NS}") # Prefix for all ICU relative internal variables
|
||||
endif(NOT DEFINED ICU_PRIVATE_VAR_NS)
|
||||
if(NOT DEFINED PC_ICU_PRIVATE_VAR_NS)
|
||||
set(PC_ICU_PRIVATE_VAR_NS "_PC${ICU_PRIVATE_VAR_NS}") # Prefix for all pkg-config relative internal variables
|
||||
endif(NOT DEFINED PC_ICU_PRIVATE_VAR_NS)
|
||||
|
||||
set(${ICU_PRIVATE_VAR_NS}_HINTS )
|
||||
# <deprecated>
|
||||
# for future removal
|
||||
if(DEFINED ENV{ICU_ROOT})
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_HINTS "$ENV{ICU_ROOT}")
|
||||
message(AUTHOR_WARNING "ENV{ICU_ROOT} is deprecated in favor of ENV{ICU_ROOT_DIR}")
|
||||
endif(DEFINED ENV{ICU_ROOT})
|
||||
if (DEFINED ICU_ROOT)
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_HINTS "${ICU_ROOT}")
|
||||
message(AUTHOR_WARNING "ICU_ROOT is deprecated in favor of ICU_ROOT_DIR")
|
||||
endif(DEFINED ICU_ROOT)
|
||||
# </deprecated>
|
||||
if(DEFINED ENV{ICU_ROOT_DIR})
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_HINTS "$ENV{ICU_ROOT_DIR}")
|
||||
endif(DEFINED ENV{ICU_ROOT_DIR})
|
||||
if (DEFINED ICU_ROOT_DIR)
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_HINTS "${ICU_ROOT_DIR}")
|
||||
endif(DEFINED ICU_ROOT_DIR)
|
||||
|
||||
set(${ICU_PRIVATE_VAR_NS}_COMPONENTS )
|
||||
# <icu component name> <library name 1> ... <library name N>
|
||||
macro(_icu_declare_component _NAME)
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_COMPONENTS ${_NAME})
|
||||
set("${ICU_PRIVATE_VAR_NS}_COMPONENTS_${_NAME}" ${ARGN})
|
||||
endmacro(_icu_declare_component)
|
||||
|
||||
_icu_declare_component(data icudata)
|
||||
_icu_declare_component(uc icuuc) # Common and Data libraries
|
||||
_icu_declare_component(i18n icui18n icuin) # Internationalization library
|
||||
_icu_declare_component(io icuio ustdio) # Stream and I/O Library
|
||||
_icu_declare_component(le icule) # Layout library
|
||||
_icu_declare_component(lx iculx) # Paragraph Layout library
|
||||
|
||||
########## Public ##########
|
||||
set(${ICU_PUBLIC_VAR_NS}_FOUND FALSE)
|
||||
set(${ICU_PUBLIC_VAR_NS}_LIBRARIES )
|
||||
set(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS )
|
||||
set(${ICU_PUBLIC_VAR_NS}_C_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_CXX_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_CPP_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_C_SHARED_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_CXX_SHARED_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_CPP_SHARED_FLAGS "")
|
||||
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PRIVATE_VAR_NS}_COMPONENTS})
|
||||
string(TOUPPER "${${ICU_PRIVATE_VAR_NS}_COMPONENT}" ${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT)
|
||||
set("${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_FOUND" FALSE) # may be done in the _icu_declare_component macro
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
|
||||
# Check components
|
||||
if(NOT ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS) # uc required at least
|
||||
set(${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS uc)
|
||||
else(NOT ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
|
||||
list(APPEND ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS uc)
|
||||
list(REMOVE_DUPLICATES ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
|
||||
if(NOT DEFINED ${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT})
|
||||
message(FATAL_ERROR "Unknown ICU component: ${${ICU_PRIVATE_VAR_NS}_COMPONENT}")
|
||||
endif(NOT DEFINED ${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT})
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
endif(NOT ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
|
||||
|
||||
# if pkg-config is available check components dependencies and append `pkg-config icu-<component> --variable=prefix` to hints
|
||||
if(PKG_CONFIG_FOUND)
|
||||
set(${ICU_PRIVATE_VAR_NS}_COMPONENTS_DUP ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PRIVATE_VAR_NS}_COMPONENTS_DUP})
|
||||
pkg_check_modules(${PC_ICU_PRIVATE_VAR_NS} "icu-${${ICU_PRIVATE_VAR_NS}_COMPONENT}" QUIET)
|
||||
|
||||
if(${PC_ICU_PRIVATE_VAR_NS}_FOUND)
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_HINTS ${${PC_ICU_PRIVATE_VAR_NS}_PREFIX})
|
||||
foreach(${PC_ICU_PRIVATE_VAR_NS}_LIBRARY ${${PC_ICU_PRIVATE_VAR_NS}_LIBRARIES})
|
||||
string(REGEX REPLACE "^icu" "" ${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY ${${PC_ICU_PRIVATE_VAR_NS}_LIBRARY})
|
||||
if(NOT ${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY STREQUAL "data")
|
||||
list(FIND ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS ${${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY} ${ICU_PRIVATE_VAR_NS}_COMPONENT_INDEX)
|
||||
if(${ICU_PRIVATE_VAR_NS}_COMPONENT_INDEX EQUAL -1)
|
||||
message(WARNING "Missing component dependency: ${${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY}. Add it to your find_package(ICU) line as COMPONENTS to fix this warning.")
|
||||
list(APPEND ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS ${${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY})
|
||||
endif(${ICU_PRIVATE_VAR_NS}_COMPONENT_INDEX EQUAL -1)
|
||||
endif(NOT ${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY STREQUAL "data")
|
||||
endforeach(${PC_ICU_PRIVATE_VAR_NS}_LIBRARY)
|
||||
endif(${PC_ICU_PRIVATE_VAR_NS}_FOUND)
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
endif(PKG_CONFIG_FOUND)
|
||||
# list(APPEND ${ICU_PRIVATE_VAR_NS}_HINTS ENV ICU_ROOT_DIR)
|
||||
# message("${ICU_PRIVATE_VAR_NS}_HINTS = ${${ICU_PRIVATE_VAR_NS}_HINTS}")
|
||||
|
||||
# Includes
|
||||
find_path(
|
||||
${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR
|
||||
NAMES unicode/utypes.h utypes.h
|
||||
HINTS ${${ICU_PRIVATE_VAR_NS}_HINTS}
|
||||
PATH_SUFFIXES "include"
|
||||
DOC "Include directories for ICU"
|
||||
)
|
||||
|
||||
if(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR)
|
||||
########## <part to keep synced with tests/version/CMakeLists.txt> ##########
|
||||
if(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}/unicode/uvernum.h") # ICU >= 4.4
|
||||
file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}/unicode/uvernum.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
|
||||
elseif(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}/unicode/uversion.h") # ICU [2;4.4[
|
||||
file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}/unicode/uversion.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
|
||||
elseif(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}/unicode/utypes.h") # ICU [1.4;2[
|
||||
file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}/unicode/utypes.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
|
||||
elseif(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}/utypes.h") # ICU 1.3
|
||||
file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}/utypes.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
|
||||
else()
|
||||
message(FATAL_ERROR "ICU version header not found")
|
||||
endif()
|
||||
|
||||
if(${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS MATCHES ".*# *define *ICU_VERSION *\"([0-9]+)\".*") # ICU 1.3
|
||||
# [1.3;1.4[ as #define ICU_VERSION "3" (no patch version, ie all 1.3.X versions will be detected as 1.3.0)
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_MAJOR "1")
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_MINOR "${CMAKE_MATCH_1}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_PATCH "0")
|
||||
elseif(${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS MATCHES ".*# *define *U_ICU_VERSION_MAJOR_NUM *([0-9]+).*")
|
||||
#
|
||||
# Since version 4.9.1, ICU release version numbering was totaly changed, see:
|
||||
# - http://site.icu-project.org/download/49
|
||||
# - http://userguide.icu-project.org/design#TOC-Version-Numbers-in-ICU
|
||||
#
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
string(REGEX REPLACE ".*# *define *U_ICU_VERSION_MINOR_NUM *([0-9]+).*" "\\1" ${ICU_PUBLIC_VAR_NS}_VERSION_MINOR "${${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS}")
|
||||
string(REGEX REPLACE ".*# *define *U_ICU_VERSION_PATCHLEVEL_NUM *([0-9]+).*" "\\1" ${ICU_PUBLIC_VAR_NS}_VERSION_PATCH "${${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS}")
|
||||
elseif(${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS MATCHES ".*# *define *U_ICU_VERSION *\"(([0-9]+)(\\.[0-9]+)*)\".*") # ICU [1.4;1.8[
|
||||
# [1.4;1.8[ as #define U_ICU_VERSION "1.4.1.2" but it seems that some 1.4.[12](?:\.\d)? have releasing error and appears as 1.4.0
|
||||
set(${ICU_PRIVATE_VAR_NS}_FULL_VERSION "${CMAKE_MATCH_1}") # copy CMAKE_MATCH_1, no longer valid on the following if
|
||||
if(${ICU_PRIVATE_VAR_NS}_FULL_VERSION MATCHES "^([0-9]+)\\.([0-9]+)$")
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_MINOR "${CMAKE_MATCH_2}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_PATCH "0")
|
||||
elseif(${ICU_PRIVATE_VAR_NS}_FULL_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)")
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_MINOR "${CMAKE_MATCH_2}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION_PATCH "${CMAKE_MATCH_3}")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "failed to detect ICU version")
|
||||
endif()
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION "${${ICU_PUBLIC_VAR_NS}_VERSION_MAJOR}.${${ICU_PUBLIC_VAR_NS}_VERSION_MINOR}.${${ICU_PUBLIC_VAR_NS}_VERSION_PATCH}")
|
||||
########## </part to keep synced with tests/version/CMakeLists.txt> ##########
|
||||
endif(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR)
|
||||
|
||||
# Check libraries
|
||||
if(MSVC)
|
||||
include(SelectLibraryConfigurations)
|
||||
endif(MSVC)
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
|
||||
string(TOUPPER "${${ICU_PRIVATE_VAR_NS}_COMPONENT}" ${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT)
|
||||
if(MSVC)
|
||||
set(${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES )
|
||||
set(${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES )
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_BASE_NAME ${${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT}})
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}")
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}d")
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}${${ICU_PUBLIC_VAR_NS}_VERSION_MAJOR}${${ICU_PUBLIC_VAR_NS}_VERSION_MINOR}")
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}${${ICU_PUBLIC_VAR_NS}_VERSION_MAJOR}${${ICU_PUBLIC_VAR_NS}_VERSION_MINOR}d")
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_BASE_NAME)
|
||||
|
||||
find_library(
|
||||
${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY_RELEASE
|
||||
NAMES ${${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES}
|
||||
HINTS ${${ICU_PRIVATE_VAR_NS}_HINTS}
|
||||
DOC "Release library for ICU ${${ICU_PRIVATE_VAR_NS}_COMPONENT} component"
|
||||
)
|
||||
find_library(
|
||||
${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY_DEBUG
|
||||
NAMES ${${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES}
|
||||
HINTS ${${ICU_PRIVATE_VAR_NS}_HINTS}
|
||||
DOC "Debug library for ICU ${${ICU_PRIVATE_VAR_NS}_COMPONENT} component"
|
||||
)
|
||||
|
||||
select_library_configurations("${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}")
|
||||
list(APPEND ${ICU_PUBLIC_VAR_NS}_LIBRARY ${${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY})
|
||||
else(MSVC)
|
||||
find_library(
|
||||
${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY
|
||||
NAMES ${${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT}}
|
||||
PATHS ${${ICU_PRIVATE_VAR_NS}_HINTS}
|
||||
DOC "Library for ICU ${${ICU_PRIVATE_VAR_NS}_COMPONENT} component"
|
||||
)
|
||||
|
||||
if(${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY)
|
||||
set("${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_FOUND" TRUE)
|
||||
list(APPEND ${ICU_PUBLIC_VAR_NS}_LIBRARY ${${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY})
|
||||
endif(${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY)
|
||||
endif(MSVC)
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
|
||||
# Try to find out compiler flags
|
||||
find_program(${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE icu-config HINTS ${${ICU_PRIVATE_VAR_NS}_HINTS})
|
||||
if(${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cflags OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_C_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cxxflags OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CXX_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cppflags OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CPP_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cflags-dynamic OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_C_SHARED_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cxxflags-dynamic OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CXX_SHARED_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cppflags-dynamic OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CPP_SHARED_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif(${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE)
|
||||
|
||||
# Check find_package arguments
|
||||
include(FindPackageHandleStandardArgs)
|
||||
if(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
|
||||
find_package_handle_standard_args(
|
||||
${ICU_PUBLIC_VAR_NS}
|
||||
REQUIRED_VARS ${ICU_PUBLIC_VAR_NS}_LIBRARY ${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR
|
||||
VERSION_VAR ${ICU_PUBLIC_VAR_NS}_VERSION
|
||||
)
|
||||
else(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
|
||||
find_package_handle_standard_args(${ICU_PUBLIC_VAR_NS} "Could NOT find ICU" ${ICU_PUBLIC_VAR_NS}_LIBRARY ${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR)
|
||||
endif(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
|
||||
|
||||
if(${ICU_PUBLIC_VAR_NS}_FOUND)
|
||||
# <deprecated>
|
||||
# for compatibility with previous versions, alias old ICU_(MAJOR|MINOR|PATCH)_VERSION to ICU_VERSION_$1
|
||||
set(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION ${${ICU_PUBLIC_VAR_NS}_VERSION_MAJOR})
|
||||
set(${ICU_PUBLIC_VAR_NS}_MINOR_VERSION ${${ICU_PUBLIC_VAR_NS}_VERSION_MINOR})
|
||||
set(${ICU_PUBLIC_VAR_NS}_PATCH_VERSION ${${ICU_PUBLIC_VAR_NS}_VERSION_PATCH})
|
||||
# </deprecated>
|
||||
set(${ICU_PUBLIC_VAR_NS}_LIBRARIES ${${ICU_PUBLIC_VAR_NS}_LIBRARY})
|
||||
set(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS ${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR})
|
||||
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.0.0")
|
||||
if(NOT TARGET ICU::ICU)
|
||||
add_library(ICU::ICU INTERFACE IMPORTED)
|
||||
endif(NOT TARGET ICU::ICU)
|
||||
set_target_properties(ICU::ICU PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}")
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
|
||||
string(TOUPPER "${${ICU_PRIVATE_VAR_NS}_COMPONENT}" ${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT)
|
||||
add_library("ICU::${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}" UNKNOWN IMPORTED)
|
||||
if(${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY_RELEASE)
|
||||
set_property(TARGET "ICU::${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}" APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties("ICU::${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}" PROPERTIES IMPORTED_LOCATION_RELEASE "${${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY_RELEASE}")
|
||||
endif(${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY_RELEASE)
|
||||
if(${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY_DEBUG)
|
||||
set_property(TARGET "ICU::${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}" APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||
set_target_properties("ICU::${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}" PROPERTIES IMPORTED_LOCATION_DEBUG "${${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY_DEBUG}")
|
||||
endif(${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY_DEBUG)
|
||||
if(${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY)
|
||||
set_target_properties("ICU::${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}" PROPERTIES IMPORTED_LOCATION "${${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY}")
|
||||
endif(${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_LIBRARY)
|
||||
set_property(TARGET ICU::ICU APPEND PROPERTY INTERFACE_LINK_LIBRARIES "ICU::${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}")
|
||||
# set_target_properties("ICU::${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}" PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR}")
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
endif(NOT CMAKE_VERSION VERSION_LESS "3.0.0")
|
||||
endif(${ICU_PUBLIC_VAR_NS}_FOUND)
|
||||
|
||||
mark_as_advanced(
|
||||
${ICU_PUBLIC_VAR_NS}_INCLUDE_DIR
|
||||
${ICU_PUBLIC_VAR_NS}_LIBRARY
|
||||
)
|
||||
|
||||
########## </ICU finding> ##########
|
||||
|
||||
########## <resource bundle support> ##########
|
||||
|
||||
########## Private ##########
|
||||
function(_icu_extract_locale_from_rb _BUNDLE_SOURCE _RETURN_VAR_NAME)
|
||||
file(READ "${_BUNDLE_SOURCE}" _BUNDLE_CONTENTS)
|
||||
string(REGEX REPLACE "//[^\n]*\n" "" _BUNDLE_CONTENTS_WITHOUT_COMMENTS ${_BUNDLE_CONTENTS})
|
||||
string(REGEX REPLACE "[ \t\n]" "" _BUNDLE_CONTENTS_WITHOUT_COMMENTS_AND_SPACES ${_BUNDLE_CONTENTS_WITHOUT_COMMENTS})
|
||||
string(REGEX MATCH "^([a-zA-Z_-]+)(:table)?{" LOCALE_FOUND ${_BUNDLE_CONTENTS_WITHOUT_COMMENTS_AND_SPACES})
|
||||
set("${_RETURN_VAR_NAME}" "${CMAKE_MATCH_1}" PARENT_SCOPE)
|
||||
endfunction(_icu_extract_locale_from_rb)
|
||||
|
||||
########## Public ##########
|
||||
|
||||
#
|
||||
# Prototype:
|
||||
# icu_generate_resource_bundle([NAME <name>] [PACKAGE] [DESTINATION <location>] [FILES <list of files>])
|
||||
#
|
||||
# Common arguments:
|
||||
# - NAME <name> : name of output package and to create dummy targets
|
||||
# - FILES <file 1> ... <file N> : list of resource bundles sources
|
||||
# - DEPENDS <target1> ... <target N> : required to package as library (shared or static), a list of cmake parent targets to link to
|
||||
# Note: only (PREVIOUSLY DECLARED) add_executable and add_library as dependencies
|
||||
# - DESTINATION <location> : optional, directory where to install final binary file(s)
|
||||
# - FORMAT <name> : optional, one of none (ICU4C binary format, default), java (plain java) or xliff (XML), see below
|
||||
#
|
||||
# Arguments depending on FORMAT:
|
||||
# - none (default):
|
||||
# * PACKAGE : if present, package all resource bundles together. Default is to stop after building individual *.res files
|
||||
# * TYPE <name> : one of :
|
||||
# + common or archive (default) : archive all ressource bundles into a single .dat file
|
||||
# + library or dll : assemble all ressource bundles into a separate and loadable library (.dll/.so)
|
||||
# + static : integrate all ressource bundles to targets designed by DEPENDS parameter (as a static library)
|
||||
# * NO_SHARED_FLAGS : only with TYPE in ['library', 'dll', 'static'], do not append ICU_C(XX)_SHARED_FLAGS to targets given as DEPENDS argument
|
||||
# - JAVA:
|
||||
# * BUNDLE <name> : required, prefix for generated classnames
|
||||
# - XLIFF:
|
||||
# (none)
|
||||
#
|
||||
|
||||
#
|
||||
# For an archive, the idea is to generate the following dependencies:
|
||||
#
|
||||
# root.txt => root.res \
|
||||
# |
|
||||
# en.txt => en.res |
|
||||
# | => pkglist.txt => application.dat
|
||||
# fr.txt => fr.res |
|
||||
# |
|
||||
# and so on /
|
||||
#
|
||||
# Lengend: 'A => B' means B depends on A
|
||||
#
|
||||
# Steps (correspond to arrows):
|
||||
# 1) genrb (from .txt to .res)
|
||||
# 2) generate a file text (pkglist.txt) with all .res files to put together
|
||||
# 3) build final archive (from *.res/pkglist.txt to .dat)
|
||||
#
|
||||
|
||||
function(icu_generate_resource_bundle)
|
||||
|
||||
##### <check for pkgdata/genrb availability> #####
|
||||
find_program(${ICU_PUBLIC_VAR_NS}_GENRB_EXECUTABLE genrb HINTS ${${ICU_PRIVATE_VAR_NS}_HINTS})
|
||||
find_program(${ICU_PUBLIC_VAR_NS}_PKGDATA_EXECUTABLE pkgdata HINTS ${${ICU_PRIVATE_VAR_NS}_HINTS})
|
||||
|
||||
if(NOT ${ICU_PUBLIC_VAR_NS}_GENRB_EXECUTABLE)
|
||||
message(FATAL_ERROR "genrb not found")
|
||||
endif(NOT ${ICU_PUBLIC_VAR_NS}_GENRB_EXECUTABLE)
|
||||
if(NOT ${ICU_PUBLIC_VAR_NS}_PKGDATA_EXECUTABLE)
|
||||
message(FATAL_ERROR "pkgdata not found")
|
||||
endif(NOT ${ICU_PUBLIC_VAR_NS}_PKGDATA_EXECUTABLE)
|
||||
##### </check for pkgdata/genrb availability> #####
|
||||
|
||||
##### <constants> #####
|
||||
set(TARGET_SEPARATOR "+")
|
||||
set(__FUNCTION__ "icu_generate_resource_bundle")
|
||||
set(PACKAGE_TARGET_PREFIX "ICU${TARGET_SEPARATOR}PKG")
|
||||
set(RESOURCE_TARGET_PREFIX "ICU${TARGET_SEPARATOR}RB")
|
||||
##### </constants> #####
|
||||
|
||||
##### <hash constants> #####
|
||||
# filename extension of built resource bundle (without dot)
|
||||
set(BUNDLES__SUFFIX "res")
|
||||
set(BUNDLES_JAVA_SUFFIX "java")
|
||||
set(BUNDLES_XLIFF_SUFFIX "xlf")
|
||||
# alias: none (default) = common = archive ; dll = library ; static
|
||||
set(PKGDATA__ALIAS "")
|
||||
set(PKGDATA_COMMON_ALIAS "")
|
||||
set(PKGDATA_ARCHIVE_ALIAS "")
|
||||
set(PKGDATA_DLL_ALIAS "LIBRARY")
|
||||
set(PKGDATA_LIBRARY_ALIAS "LIBRARY")
|
||||
set(PKGDATA_STATIC_ALIAS "STATIC")
|
||||
# filename prefix of built package
|
||||
set(PKGDATA__PREFIX "")
|
||||
set(PKGDATA_LIBRARY_PREFIX "${CMAKE_SHARED_LIBRARY_PREFIX}")
|
||||
set(PKGDATA_STATIC_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
|
||||
# filename extension of built package (with dot)
|
||||
set(PKGDATA__SUFFIX ".dat")
|
||||
set(PKGDATA_LIBRARY_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
set(PKGDATA_STATIC_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
# pkgdata option mode specific
|
||||
set(PKGDATA__OPTIONS "-m" "common")
|
||||
set(PKGDATA_STATIC_OPTIONS "-m" "static")
|
||||
set(PKGDATA_LIBRARY_OPTIONS "-m" "library")
|
||||
# cmake library type for output package
|
||||
set(PKGDATA_LIBRARY__TYPE "")
|
||||
set(PKGDATA_LIBRARY_STATIC_TYPE STATIC)
|
||||
set(PKGDATA_LIBRARY_LIBRARY_TYPE SHARED)
|
||||
##### </hash constants> #####
|
||||
|
||||
include(CMakeParseArguments)
|
||||
cmake_parse_arguments(
|
||||
PARSED_ARGS # output variable name
|
||||
# options (true/false) (default value: false)
|
||||
"PACKAGE;NO_SHARED_FLAGS"
|
||||
# univalued parameters (default value: "")
|
||||
"NAME;DESTINATION;TYPE;FORMAT;BUNDLE"
|
||||
# multivalued parameters (default value: "")
|
||||
"FILES;DEPENDS"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
# assert(${PARSED_ARGS_NAME} != "")
|
||||
if(NOT PARSED_ARGS_NAME)
|
||||
message(FATAL_ERROR "${__FUNCTION__}(): no name given, NAME parameter missing")
|
||||
endif(NOT PARSED_ARGS_NAME)
|
||||
|
||||
# assert(length(PARSED_ARGS_FILES) > 0)
|
||||
list(LENGTH PARSED_ARGS_FILES PARSED_ARGS_FILES_LEN)
|
||||
if(PARSED_ARGS_FILES_LEN LESS 1)
|
||||
message(FATAL_ERROR "${__FUNCTION__}() expects at least 1 resource bundle as FILES argument, 0 given")
|
||||
endif(PARSED_ARGS_FILES_LEN LESS 1)
|
||||
|
||||
string(TOUPPER "${PARSED_ARGS_FORMAT}" UPPER_FORMAT)
|
||||
# assert(${UPPER_FORMAT} in ['', 'java', 'xlif'])
|
||||
if(NOT DEFINED BUNDLES_${UPPER_FORMAT}_SUFFIX)
|
||||
message(FATAL_ERROR "${__FUNCTION__}(): unknown FORMAT '${PARSED_ARGS_FORMAT}'")
|
||||
endif(NOT DEFINED BUNDLES_${UPPER_FORMAT}_SUFFIX)
|
||||
|
||||
if(UPPER_FORMAT STREQUAL "JAVA")
|
||||
# assert(${PARSED_ARGS_BUNDLE} != "")
|
||||
if(NOT PARSED_ARGS_BUNDLE)
|
||||
message(FATAL_ERROR "${__FUNCTION__}(): java bundle name expected, BUNDLE parameter missing")
|
||||
endif(NOT PARSED_ARGS_BUNDLE)
|
||||
endif(UPPER_FORMAT STREQUAL "JAVA")
|
||||
|
||||
if(PARSED_ARGS_PACKAGE)
|
||||
# assert(${PARSED_ARGS_FORMAT} == "")
|
||||
if(PARSED_ARGS_FORMAT)
|
||||
message(FATAL_ERROR "${__FUNCTION__}(): packaging is only supported for binary format, not xlif neither java outputs")
|
||||
endif(PARSED_ARGS_FORMAT)
|
||||
|
||||
string(TOUPPER "${PARSED_ARGS_TYPE}" UPPER_MODE)
|
||||
# assert(${UPPER_MODE} in ['', 'common', 'archive', 'dll', library'])
|
||||
if(NOT DEFINED PKGDATA_${UPPER_MODE}_ALIAS)
|
||||
message(FATAL_ERROR "${__FUNCTION__}(): unknown TYPE '${PARSED_ARGS_TYPE}'")
|
||||
else(NOT DEFINED PKGDATA_${UPPER_MODE}_ALIAS)
|
||||
set(TYPE "${PKGDATA_${UPPER_MODE}_ALIAS}")
|
||||
endif(NOT DEFINED PKGDATA_${UPPER_MODE}_ALIAS)
|
||||
|
||||
# Package name: strip file extension if present
|
||||
get_filename_component(PACKAGE_NAME_WE ${PARSED_ARGS_NAME} NAME_WE)
|
||||
# Target name to build package
|
||||
set(PACKAGE_TARGET_NAME "${PACKAGE_TARGET_PREFIX}${TARGET_SEPARATOR}${PACKAGE_NAME_WE}")
|
||||
# Target name to build intermediate list file
|
||||
set(PACKAGE_LIST_TARGET_NAME "${PACKAGE_TARGET_NAME}${TARGET_SEPARATOR}PKGLIST")
|
||||
# Directory (absolute) to set as "current directory" for genrb (does not include package directory, -p)
|
||||
# We make our "cook" there to prevent any conflict
|
||||
if(DEFINED CMAKE_PLATFORM_ROOT_BIN) # CMake < 2.8.10
|
||||
set(RESOURCE_GENRB_CHDIR_DIR "${CMAKE_PLATFORM_ROOT_BIN}/${PACKAGE_TARGET_NAME}.dir/")
|
||||
else(DEFINED CMAKE_PLATFORM_ROOT_BIN) # CMake >= 2.8.10
|
||||
set(RESOURCE_GENRB_CHDIR_DIR "${CMAKE_PLATFORM_INFO_DIR}/${PACKAGE_TARGET_NAME}.dir/")
|
||||
endif(DEFINED CMAKE_PLATFORM_ROOT_BIN)
|
||||
# Directory (absolute) where resource bundles are built: concatenation of RESOURCE_GENRB_CHDIR_DIR and package name
|
||||
set(RESOURCE_OUTPUT_DIR "${RESOURCE_GENRB_CHDIR_DIR}/${PACKAGE_NAME_WE}/")
|
||||
# Output (relative) path for built package
|
||||
if(MSVC AND TYPE STREQUAL PKGDATA_LIBRARY_ALIAS)
|
||||
set(PACKAGE_OUTPUT_PATH "${RESOURCE_GENRB_CHDIR_DIR}/${PACKAGE_NAME_WE}/${PKGDATA_${TYPE}_PREFIX}${PACKAGE_NAME_WE}${PKGDATA_${TYPE}_SUFFIX}")
|
||||
else(MSVC AND TYPE STREQUAL PKGDATA_LIBRARY_ALIAS)
|
||||
set(PACKAGE_OUTPUT_PATH "${RESOURCE_GENRB_CHDIR_DIR}/${PKGDATA_${TYPE}_PREFIX}${PACKAGE_NAME_WE}${PKGDATA_${TYPE}_SUFFIX}")
|
||||
endif(MSVC AND TYPE STREQUAL PKGDATA_LIBRARY_ALIAS)
|
||||
# Output (absolute) path for the list file
|
||||
set(PACKAGE_LIST_OUTPUT_PATH "${RESOURCE_GENRB_CHDIR_DIR}/pkglist.txt")
|
||||
|
||||
file(MAKE_DIRECTORY "${RESOURCE_OUTPUT_DIR}")
|
||||
else(PARSED_ARGS_PACKAGE)
|
||||
set(RESOURCE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/")
|
||||
# set(RESOURCE_GENRB_CHDIR_DIR "UNUSED")
|
||||
endif(PARSED_ARGS_PACKAGE)
|
||||
|
||||
set(TARGET_RESOURCES )
|
||||
set(COMPILED_RESOURCES_PATH )
|
||||
set(COMPILED_RESOURCES_BASENAME )
|
||||
foreach(RESOURCE_SOURCE ${PARSED_ARGS_FILES})
|
||||
_icu_extract_locale_from_rb(${RESOURCE_SOURCE} RESOURCE_NAME_WE)
|
||||
get_filename_component(SOURCE_BASENAME ${RESOURCE_SOURCE} NAME)
|
||||
get_filename_component(ABSOLUTE_SOURCE ${RESOURCE_SOURCE} ABSOLUTE)
|
||||
|
||||
if(UPPER_FORMAT STREQUAL "XLIFF")
|
||||
if(RESOURCE_NAME_WE STREQUAL "root")
|
||||
set(XLIFF_LANGUAGE "en")
|
||||
else(RESOURCE_NAME_WE STREQUAL "root")
|
||||
string(REGEX REPLACE "[^a-z].*$" "" XLIFF_LANGUAGE "${RESOURCE_NAME_WE}")
|
||||
endif(RESOURCE_NAME_WE STREQUAL "root")
|
||||
endif(UPPER_FORMAT STREQUAL "XLIFF")
|
||||
|
||||
##### <templates> #####
|
||||
set(RESOURCE_TARGET_NAME "${RESOURCE_TARGET_PREFIX}${TARGET_SEPARATOR}${PARSED_ARGS_NAME}${TARGET_SEPARATOR}${RESOURCE_NAME_WE}")
|
||||
|
||||
set(RESOURCE_OUTPUT__PATH "${RESOURCE_NAME_WE}.res")
|
||||
if(RESOURCE_NAME_WE STREQUAL "root")
|
||||
set(RESOURCE_OUTPUT_JAVA_PATH "${PARSED_ARGS_BUNDLE}.java")
|
||||
else(RESOURCE_NAME_WE STREQUAL "root")
|
||||
set(RESOURCE_OUTPUT_JAVA_PATH "${PARSED_ARGS_BUNDLE}_${RESOURCE_NAME_WE}.java")
|
||||
endif(RESOURCE_NAME_WE STREQUAL "root")
|
||||
set(RESOURCE_OUTPUT_XLIFF_PATH "${RESOURCE_NAME_WE}.xlf")
|
||||
|
||||
set(GENRB__OPTIONS "")
|
||||
set(GENRB_JAVA_OPTIONS "-j" "-b" "${PARSED_ARGS_BUNDLE}")
|
||||
set(GENRB_XLIFF_OPTIONS "-x" "-l" "${XLIFF_LANGUAGE}")
|
||||
##### </templates> #####
|
||||
|
||||
# build <locale>.txt from <locale>.res
|
||||
if(PARSED_ARGS_PACKAGE)
|
||||
add_custom_command(
|
||||
OUTPUT "${RESOURCE_OUTPUT_DIR}${RESOURCE_OUTPUT_${UPPER_FORMAT}_PATH}"
|
||||
COMMAND ${CMAKE_COMMAND} -E chdir ${RESOURCE_GENRB_CHDIR_DIR} ${${ICU_PUBLIC_VAR_NS}_GENRB_EXECUTABLE} ${GENRB_${UPPER_FORMAT}_OPTIONS} -d ${PACKAGE_NAME_WE} ${ABSOLUTE_SOURCE}
|
||||
DEPENDS ${RESOURCE_SOURCE}
|
||||
)
|
||||
else(PARSED_ARGS_PACKAGE)
|
||||
add_custom_command(
|
||||
OUTPUT "${RESOURCE_OUTPUT_DIR}${RESOURCE_OUTPUT_${UPPER_FORMAT}_PATH}"
|
||||
COMMAND ${${ICU_PUBLIC_VAR_NS}_GENRB_EXECUTABLE} ${GENRB_${UPPER_FORMAT}_OPTIONS} -d ${RESOURCE_OUTPUT_DIR} ${ABSOLUTE_SOURCE}
|
||||
DEPENDS ${RESOURCE_SOURCE}
|
||||
)
|
||||
endif(PARSED_ARGS_PACKAGE)
|
||||
# dummy target (ICU+RB+<name>+<locale>) for each locale to build the <locale>.res file from its <locale>.txt by the add_custom_command above
|
||||
add_custom_target(
|
||||
"${RESOURCE_TARGET_NAME}" ALL
|
||||
COMMENT ""
|
||||
DEPENDS "${RESOURCE_OUTPUT_DIR}${RESOURCE_OUTPUT_${UPPER_FORMAT}_PATH}"
|
||||
SOURCES ${RESOURCE_SOURCE}
|
||||
)
|
||||
|
||||
if(PARSED_ARGS_DESTINATION AND NOT PARSED_ARGS_PACKAGE)
|
||||
install(FILES "${RESOURCE_OUTPUT_DIR}${RESOURCE_OUTPUT_${UPPER_FORMAT}_PATH}" DESTINATION ${PARSED_ARGS_DESTINATION} PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
|
||||
endif(PARSED_ARGS_DESTINATION AND NOT PARSED_ARGS_PACKAGE)
|
||||
|
||||
list(APPEND TARGET_RESOURCES "${RESOURCE_TARGET_NAME}")
|
||||
list(APPEND COMPILED_RESOURCES_PATH "${RESOURCE_OUTPUT_DIR}${RESOURCE_OUTPUT_${UPPER_FORMAT}_PATH}")
|
||||
list(APPEND COMPILED_RESOURCES_BASENAME "${RESOURCE_NAME_WE}.${BUNDLES_${UPPER_FORMAT}_SUFFIX}")
|
||||
endforeach(RESOURCE_SOURCE)
|
||||
# convert semicolon separated list to a space separated list
|
||||
# NOTE: if the pkglist.txt file starts (or ends?) with a whitespace, pkgdata add an undefined symbol (named <package>_) for it
|
||||
string(REPLACE ";" " " COMPILED_RESOURCES_BASENAME "${COMPILED_RESOURCES_BASENAME}")
|
||||
|
||||
if(PARSED_ARGS_PACKAGE)
|
||||
# create a text file (pkglist.txt) with the list of the *.res to package together
|
||||
add_custom_command(
|
||||
OUTPUT "${PACKAGE_LIST_OUTPUT_PATH}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${COMPILED_RESOURCES_BASENAME}" > "${PACKAGE_LIST_OUTPUT_PATH}"
|
||||
DEPENDS ${COMPILED_RESOURCES_PATH}
|
||||
)
|
||||
# run pkgdata from pkglist.txt
|
||||
add_custom_command(
|
||||
OUTPUT "${PACKAGE_OUTPUT_PATH}"
|
||||
COMMAND ${CMAKE_COMMAND} -E chdir ${RESOURCE_GENRB_CHDIR_DIR} ${${ICU_PUBLIC_VAR_NS}_PKGDATA_EXECUTABLE} -F ${PKGDATA_${TYPE}_OPTIONS} -s ${PACKAGE_NAME_WE} -p ${PACKAGE_NAME_WE} ${PACKAGE_LIST_OUTPUT_PATH}
|
||||
DEPENDS "${PACKAGE_LIST_OUTPUT_PATH}"
|
||||
VERBATIM
|
||||
)
|
||||
if(PKGDATA_LIBRARY_${TYPE}_TYPE)
|
||||
# assert(${PARSED_ARGS_DEPENDS} != "")
|
||||
if(NOT PARSED_ARGS_DEPENDS)
|
||||
message(FATAL_ERROR "${__FUNCTION__}(): static and library mode imply a list of targets to link to, DEPENDS parameter missing")
|
||||
endif(NOT PARSED_ARGS_DEPENDS)
|
||||
add_library(${PACKAGE_TARGET_NAME} ${PKGDATA_LIBRARY_${TYPE}_TYPE} IMPORTED)
|
||||
if(MSVC)
|
||||
string(REGEX REPLACE "${PKGDATA_LIBRARY_SUFFIX}\$" "${CMAKE_IMPORT_LIBRARY_SUFFIX}" PACKAGE_OUTPUT_LIB "${PACKAGE_OUTPUT_PATH}")
|
||||
set_target_properties(${PACKAGE_TARGET_NAME} PROPERTIES IMPORTED_LOCATION ${PACKAGE_OUTPUT_PATH} IMPORTED_IMPLIB ${PACKAGE_OUTPUT_LIB})
|
||||
else(MSVC)
|
||||
set_target_properties(${PACKAGE_TARGET_NAME} PROPERTIES IMPORTED_LOCATION ${PACKAGE_OUTPUT_PATH})
|
||||
endif(MSVC)
|
||||
foreach(DEPENDENCY ${PARSED_ARGS_DEPENDS})
|
||||
target_link_libraries(${DEPENDENCY} ${PACKAGE_TARGET_NAME})
|
||||
if(NOT PARSED_ARGS_NO_SHARED_FLAGS)
|
||||
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
list(LENGTH "${ENABLED_LANGUAGES}" ENABLED_LANGUAGES_LENGTH)
|
||||
if(ENABLED_LANGUAGES_LENGTH GREATER 1)
|
||||
message(WARNING "Project has more than one language enabled, skip automatic shared flags appending")
|
||||
else(ENABLED_LANGUAGES_LENGTH GREATER 1)
|
||||
set_property(TARGET "${DEPENDENCY}" APPEND PROPERTY COMPILE_FLAGS "${${ICU_PUBLIC_VAR_NS}_${ENABLED_LANGUAGES}_SHARED_FLAGS}")
|
||||
endif(ENABLED_LANGUAGES_LENGTH GREATER 1)
|
||||
endif(NOT PARSED_ARGS_NO_SHARED_FLAGS)
|
||||
endforeach(DEPENDENCY)
|
||||
# http://www.mail-archive.com/cmake-commits@cmake.org/msg01135.html
|
||||
set(PACKAGE_INTERMEDIATE_TARGET_NAME "${PACKAGE_TARGET_NAME}${TARGET_SEPARATOR}DUMMY")
|
||||
# dummy intermediate target (ICU+PKG+<name>+DUMMY) to link the package to the produced library by running pkgdata (see add_custom_command above)
|
||||
add_custom_target(
|
||||
${PACKAGE_INTERMEDIATE_TARGET_NAME}
|
||||
COMMENT ""
|
||||
DEPENDS "${PACKAGE_OUTPUT_PATH}"
|
||||
)
|
||||
add_dependencies("${PACKAGE_TARGET_NAME}" "${PACKAGE_INTERMEDIATE_TARGET_NAME}")
|
||||
else(PKGDATA_LIBRARY_${TYPE}_TYPE)
|
||||
# dummy target (ICU+PKG+<name>) to run pkgdata (see add_custom_command above)
|
||||
add_custom_target(
|
||||
"${PACKAGE_TARGET_NAME}" ALL
|
||||
COMMENT ""
|
||||
DEPENDS "${PACKAGE_OUTPUT_PATH}"
|
||||
)
|
||||
endif(PKGDATA_LIBRARY_${TYPE}_TYPE)
|
||||
# dummy target (ICU+PKG+<name>+PKGLIST) to build the file pkglist.txt
|
||||
add_custom_target(
|
||||
"${PACKAGE_LIST_TARGET_NAME}" ALL
|
||||
COMMENT ""
|
||||
DEPENDS "${PACKAGE_LIST_OUTPUT_PATH}"
|
||||
)
|
||||
# package => pkglist.txt
|
||||
add_dependencies("${PACKAGE_TARGET_NAME}" "${PACKAGE_LIST_TARGET_NAME}")
|
||||
# pkglist.txt => *.res
|
||||
add_dependencies("${PACKAGE_LIST_TARGET_NAME}" ${TARGET_RESOURCES})
|
||||
|
||||
if(PARSED_ARGS_DESTINATION)
|
||||
install(FILES "${PACKAGE_OUTPUT_PATH}" DESTINATION ${PARSED_ARGS_DESTINATION} PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
|
||||
endif(PARSED_ARGS_DESTINATION)
|
||||
endif(PARSED_ARGS_PACKAGE)
|
||||
|
||||
endfunction(icu_generate_resource_bundle)
|
||||
|
||||
########## </resource bundle support> ##########
|
||||
|
||||
########## <debug> ##########
|
||||
|
||||
if(${ICU_PUBLIC_VAR_NS}_DEBUG)
|
||||
|
||||
function(icudebug _VARNAME)
|
||||
if(DEFINED ${ICU_PUBLIC_VAR_NS}_${_VARNAME})
|
||||
message("${ICU_PUBLIC_VAR_NS}_${_VARNAME} = ${${ICU_PUBLIC_VAR_NS}_${_VARNAME}}")
|
||||
else(DEFINED ${ICU_PUBLIC_VAR_NS}_${_VARNAME})
|
||||
message("${ICU_PUBLIC_VAR_NS}_${_VARNAME} = <UNDEFINED>")
|
||||
endif(DEFINED ${ICU_PUBLIC_VAR_NS}_${_VARNAME})
|
||||
endfunction(icudebug)
|
||||
|
||||
# IN (args)
|
||||
icudebug("FIND_COMPONENTS")
|
||||
icudebug("FIND_REQUIRED")
|
||||
icudebug("FIND_QUIETLY")
|
||||
icudebug("FIND_VERSION")
|
||||
|
||||
# OUT
|
||||
# Found
|
||||
icudebug("FOUND")
|
||||
# Flags
|
||||
icudebug("C_FLAGS")
|
||||
icudebug("CPP_FLAGS")
|
||||
icudebug("CXX_FLAGS")
|
||||
icudebug("C_SHARED_FLAGS")
|
||||
icudebug("CPP_SHARED_FLAGS")
|
||||
icudebug("CXX_SHARED_FLAGS")
|
||||
# Linking
|
||||
icudebug("INCLUDE_DIRS")
|
||||
icudebug("LIBRARIES")
|
||||
# Version
|
||||
icudebug("VERSION_MAJOR")
|
||||
icudebug("VERSION_MINOR")
|
||||
icudebug("VERSION_PATCH")
|
||||
icudebug("VERSION")
|
||||
# <COMPONENT>_(FOUND|LIBRARY)
|
||||
set(${ICU_PRIVATE_VAR_NS}_COMPONENT_VARIABLES "FOUND" "LIBRARY" "LIBRARY_RELEASE" "LIBRARY_DEBUG")
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PRIVATE_VAR_NS}_COMPONENTS})
|
||||
string(TOUPPER "${${ICU_PRIVATE_VAR_NS}_COMPONENT}" ${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT)
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT_VARIABLE ${${ICU_PRIVATE_VAR_NS}_COMPONENT_VARIABLES})
|
||||
icudebug("${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_${${ICU_PRIVATE_VAR_NS}_COMPONENT_VARIABLE}")
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT_VARIABLE)
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
|
||||
endif(${ICU_PUBLIC_VAR_NS}_DEBUG)
|
||||
|
||||
########## </debug> ##########
|
|
@ -657,6 +657,18 @@ ADD_ASSIMP_IMPORTER( 3MF
|
|||
D3MFOpcPackage.cpp
|
||||
)
|
||||
|
||||
ADD_ASSIMP_IMPORTER( MMD
|
||||
MMDCpp14.h
|
||||
MMDImporter.cpp
|
||||
MMDImporter.h
|
||||
MMDPmdParser.h
|
||||
MMDPmxParser.h
|
||||
MMDPmxParser.cpp
|
||||
MMDVmdParser.h
|
||||
)
|
||||
|
||||
find_package(ICU COMPONENTS uc io REQUIRED)
|
||||
|
||||
SET( Step_SRCS
|
||||
StepExporter.h
|
||||
StepExporter.cpp
|
||||
|
@ -850,9 +862,11 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
|||
INCLUDE_DIRECTORIES(${C4D_INCLUDES})
|
||||
ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||
|
||||
INCLUDE_DIRECTORIES(${ICU_INCLUDE_DIRS})
|
||||
|
||||
ADD_LIBRARY( assimp ${assimp_src} )
|
||||
|
||||
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} )
|
||||
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} ${ICU_LIBRARIES} )
|
||||
|
||||
if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
set(ASSIMP_ANDROID_JNIIOSYSTEM_PATH port/AndroidJNI)
|
||||
|
|
|
@ -188,6 +188,9 @@ corresponding preprocessor flag to selectively disable formats.
|
|||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||
# include "X3DImporter.hpp"
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
||||
# include "MMDImporter.h"
|
||||
#endif
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
|
@ -332,11 +335,14 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
|||
out.push_back( new C4DImporter() );
|
||||
#endif
|
||||
#if ( !defined ASSIMP_BUILD_NO_3MF_IMPORTER )
|
||||
out.push_back(new D3MFImporter() );
|
||||
out.push_back( new D3MFImporter() );
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||
out.push_back( new X3DImporter() );
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
||||
out.push_back( new MMDImporter() );
|
||||
#endif
|
||||
}
|
||||
|
||||
/** will delete all registered importers. */
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef MMD_CPP14_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace std {
|
||||
template<class T> struct _Unique_if {
|
||||
typedef unique_ptr<T> _Single_object;
|
||||
};
|
||||
|
||||
template<class T> struct _Unique_if<T[]> {
|
||||
typedef unique_ptr<T[]> _Unknown_bound;
|
||||
};
|
||||
|
||||
template<class T, size_t N> struct _Unique_if<T[N]> {
|
||||
typedef void _Known_bound;
|
||||
};
|
||||
|
||||
template<class T, class... Args>
|
||||
typename _Unique_if<T>::_Single_object
|
||||
make_unique(Args&&... args) {
|
||||
return unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
typename _Unique_if<T>::_Unknown_bound
|
||||
make_unique(size_t n) {
|
||||
typedef typename remove_extent<T>::type U;
|
||||
return unique_ptr<T>(new U[n]());
|
||||
}
|
||||
|
||||
template<class T, class... Args>
|
||||
typename _Unique_if<T>::_Known_bound
|
||||
make_unique(Args&&...) = delete;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
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
|
||||
OWNER 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.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
||||
|
||||
#include "DefaultIOSystem.h"
|
||||
#include "MMDImporter.h"
|
||||
#include "MMDPmxParser.h"
|
||||
#include "MMDPmdParser.h"
|
||||
#include "MMDVmdParser.h"
|
||||
//#include "IOStreamBuffer.h"
|
||||
#include <memory>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
"MMD Importer",
|
||||
"",
|
||||
"",
|
||||
"surfaces supported?",
|
||||
aiImporterFlags_SupportTextFlavour,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"pmx"
|
||||
};
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
using namespace std;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Default constructor
|
||||
MMDImporter::MMDImporter() :
|
||||
m_Buffer(),
|
||||
//m_pRootObject( NULL ),
|
||||
m_strAbsPath( "" )
|
||||
{
|
||||
DefaultIOSystem io;
|
||||
m_strAbsPath = io.getOsSeparator();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor.
|
||||
MMDImporter::~MMDImporter()
|
||||
{
|
||||
//delete m_pRootObject;
|
||||
//m_pRootObject = NULL;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns true, if file is an pmx file.
|
||||
bool MMDImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const
|
||||
{
|
||||
if(!checkSig) //Check File Extension
|
||||
{
|
||||
return SimpleExtensionCheck(pFile,"pmx");
|
||||
}
|
||||
else //Check file Header
|
||||
{
|
||||
static const char *pTokens[] = { "PMX " };
|
||||
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const aiImporterDesc* MMDImporter::GetInfo () const
|
||||
{
|
||||
return &desc;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// MMD import implementation
|
||||
void MMDImporter::InternReadFile( const std::string &file, aiScene* pScene, IOSystem* pIOHandler)
|
||||
{
|
||||
// Read file by istream
|
||||
std::filebuf fb;
|
||||
if( !fb.open(file, std::ios::in | std::ios::binary ) ) {
|
||||
throw DeadlyImportError( "Failed to open file " + file + "." );
|
||||
}
|
||||
|
||||
std::istream fileStream( &fb );
|
||||
|
||||
// Get the file-size and validate it, throwing an exception when fails
|
||||
fileStream.seekg(0, fileStream.end);
|
||||
size_t fileSize = fileStream.tellg();
|
||||
fileStream.seekg(0, fileStream.beg);
|
||||
|
||||
if( fileSize < sizeof(pmx::PmxModel) ) {
|
||||
throw DeadlyImportError( file + " is too small." );
|
||||
}
|
||||
|
||||
pmx::PmxModel model;
|
||||
model.Read(&fileStream);
|
||||
|
||||
CreateDataFromImport(&model, pScene);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void MMDImporter::CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene)
|
||||
{
|
||||
if( pModel == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
pScene->mRootNode = new aiNode;
|
||||
if ( !pModel->model_name.empty() ) {
|
||||
pScene->mRootNode->mName.Set(pModel->model_name);
|
||||
}
|
||||
else {
|
||||
ai_assert(false);
|
||||
}
|
||||
|
||||
std::cout << pScene->mRootNode->mName.C_Str() << std::endl;
|
||||
|
||||
// workaround, must be deleted
|
||||
pScene->mNumMeshes = 1;
|
||||
pScene->mNumMaterials = 1;
|
||||
pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||
aiMesh *pMesh = new aiMesh;
|
||||
pScene->mRootNode->mMeshes[0] = 100;
|
||||
// workaround
|
||||
|
||||
/*
|
||||
// Create nodes for the whole scene
|
||||
std::vector<aiMesh*> MeshArray;
|
||||
for ( size_t index = 0; index < pModel->bone_count; index++ ) {
|
||||
createNodes( pModel, pModel->bones[i], pScene, MeshArray);
|
||||
}
|
||||
|
||||
if ( pScene->mNumMeshes > 0 ) {
|
||||
pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
|
||||
for ( size_t index = 0; index < MeshArray.size(); index++ ) {
|
||||
pScene->mMeshes[ index ] = MeshArray[ index ];
|
||||
}
|
||||
}
|
||||
|
||||
// Create all materials
|
||||
createMaterials( pModel, pScene );
|
||||
*/
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_MMD_IMPORTER
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
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
|
||||
OWNER 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.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef MMD_FILE_IMPORTER_H_INC
|
||||
#define MMD_FILE_IMPORTER_H_INC
|
||||
|
||||
#include "BaseImporter.h"
|
||||
#include "MMDPmxParser.h"
|
||||
#include <assimp/material.h>
|
||||
#include <vector>
|
||||
|
||||
struct aiMesh;
|
||||
struct aiNode;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
/*
|
||||
namespace MMDFile {
|
||||
struct Object;
|
||||
struct Model;
|
||||
}
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/// \class MMDImporter
|
||||
/// \brief Imports MMD a pmx/pmd/vmd file
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class MMDImporter : public BaseImporter {
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
MMDImporter();
|
||||
|
||||
/// \brief Destructor
|
||||
~MMDImporter();
|
||||
|
||||
public:
|
||||
/// \brief Returns whether the class can handle the format of the given file.
|
||||
/// \remark See BaseImporter::CanRead() for details.
|
||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
||||
|
||||
private:
|
||||
//! \brief Appends the supported extension.
|
||||
const aiImporterDesc* GetInfo () const;
|
||||
|
||||
//! \brief File import implementation.
|
||||
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||
|
||||
//! \brief Create the data from imported content.
|
||||
void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene);
|
||||
|
||||
private:
|
||||
//! Data buffer
|
||||
std::vector<char> m_Buffer;
|
||||
//! Pointer to root object instance
|
||||
//MMDFile::Object *m_pRootObject;
|
||||
//! Absolute pathname of model in file system
|
||||
std::string m_strAbsPath;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif
|
|
@ -0,0 +1,630 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "MMDCpp14.h"
|
||||
|
||||
namespace pmd
|
||||
{
|
||||
/// ヘッダ
|
||||
class PmdHeader
|
||||
{
|
||||
public:
|
||||
/// モデル名
|
||||
std::string name;
|
||||
/// モデル名(英語)
|
||||
std::string name_english;
|
||||
/// コメント
|
||||
std::string comment;
|
||||
/// コメント(英語)
|
||||
std::string comment_english;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
{
|
||||
char buffer[256];
|
||||
stream->read(buffer, 20);
|
||||
name = std::string(buffer);
|
||||
stream->read(buffer, 256);
|
||||
comment = std::string(buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadExtension(std::ifstream* stream)
|
||||
{
|
||||
char buffer[256];
|
||||
stream->read(buffer, 20);
|
||||
name_english = std::string(buffer);
|
||||
stream->read(buffer, 256);
|
||||
comment_english = std::string(buffer);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// 頂点
|
||||
class PmdVertex
|
||||
{
|
||||
public:
|
||||
/// 位置
|
||||
float position[3];
|
||||
|
||||
/// 法線
|
||||
float normal[3];
|
||||
|
||||
/// UV座標
|
||||
float uv[2];
|
||||
|
||||
/// 関連ボーンインデックス
|
||||
uint16_t bone_index[2];
|
||||
|
||||
/// ボーンウェイト
|
||||
uint8_t bone_weight;
|
||||
|
||||
/// エッジ不可視
|
||||
bool edge_invisible;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
{
|
||||
stream->read((char*) position, sizeof(float) * 3);
|
||||
stream->read((char*) normal, sizeof(float) * 3);
|
||||
stream->read((char*) uv, sizeof(float) * 2);
|
||||
stream->read((char*) bone_index, sizeof(uint16_t) * 2);
|
||||
stream->read((char*) &bone_weight, sizeof(uint8_t));
|
||||
stream->read((char*) &edge_invisible, sizeof(uint8_t));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// 材質
|
||||
class PmdMaterial
|
||||
{
|
||||
public:
|
||||
/// 減衰色
|
||||
float diffuse[4];
|
||||
/// 光沢度
|
||||
float power;
|
||||
/// 光沢色
|
||||
float specular[3];
|
||||
/// 環境色
|
||||
float ambient[3];
|
||||
/// トーンインデックス
|
||||
uint8_t toon_index;
|
||||
/// エッジ
|
||||
uint8_t edge_flag;
|
||||
/// インデックス数
|
||||
uint32_t index_count;
|
||||
/// テクスチャファイル名
|
||||
std::string texture_filename;
|
||||
/// スフィアファイル名
|
||||
std::string sphere_filename;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read((char*) &diffuse, sizeof(float) * 4);
|
||||
stream->read((char*) &power, sizeof(float));
|
||||
stream->read((char*) &specular, sizeof(float) * 3);
|
||||
stream->read((char*) &ambient, sizeof(float) * 3);
|
||||
stream->read((char*) &toon_index, sizeof(uint8_t));
|
||||
stream->read((char*) &edge_flag, sizeof(uint8_t));
|
||||
stream->read((char*) &index_count, sizeof(uint32_t));
|
||||
stream->read((char*) &buffer, sizeof(char) * 20);
|
||||
char* pstar = strchr(buffer, '*');
|
||||
if (NULL == pstar)
|
||||
{
|
||||
texture_filename = std::string(buffer);
|
||||
sphere_filename.clear();
|
||||
}
|
||||
else {
|
||||
*pstar = NULL;
|
||||
texture_filename = std::string(buffer);
|
||||
sphere_filename = std::string(pstar+1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
enum class BoneType : uint8_t
|
||||
{
|
||||
Rotation,
|
||||
RotationAndMove,
|
||||
IkEffector,
|
||||
Unknown,
|
||||
IkEffectable,
|
||||
RotationEffectable,
|
||||
IkTarget,
|
||||
Invisible,
|
||||
Twist,
|
||||
RotationMovement
|
||||
};
|
||||
|
||||
/// ボーン
|
||||
class PmdBone
|
||||
{
|
||||
public:
|
||||
/// ボーン名
|
||||
std::string name;
|
||||
/// ボーン名(英語)
|
||||
std::string name_english;
|
||||
/// 親ボーン番号
|
||||
uint16_t parent_bone_index;
|
||||
/// 末端ボーン番号
|
||||
uint16_t tail_pos_bone_index;
|
||||
/// ボーン種類
|
||||
BoneType bone_type;
|
||||
/// IKボーン番号
|
||||
uint16_t ik_parent_bone_index;
|
||||
/// ボーンのヘッドの位置
|
||||
float bone_head_pos[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
name = std::string(buffer);
|
||||
stream->read((char*) &parent_bone_index, sizeof(uint16_t));
|
||||
stream->read((char*) &tail_pos_bone_index, sizeof(uint16_t));
|
||||
stream->read((char*) &bone_type, sizeof(uint8_t));
|
||||
stream->read((char*) &ik_parent_bone_index, sizeof(uint16_t));
|
||||
stream->read((char*) &bone_head_pos, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
void ReadExpantion(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
name_english = std::string(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
/// IK
|
||||
class PmdIk
|
||||
{
|
||||
public:
|
||||
/// IKボーン番号
|
||||
uint16_t ik_bone_index;
|
||||
/// IKターゲットボーン番号
|
||||
uint16_t target_bone_index;
|
||||
/// 再帰回数
|
||||
uint16_t interations;
|
||||
/// 角度制限
|
||||
float angle_limit;
|
||||
/// 影響下ボーン番号
|
||||
std::vector<uint16_t> ik_child_bone_index;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
stream->read((char *) &ik_bone_index, sizeof(uint16_t));
|
||||
stream->read((char *) &target_bone_index, sizeof(uint16_t));
|
||||
uint8_t ik_chain_length;
|
||||
stream->read((char*) &ik_chain_length, sizeof(uint8_t));
|
||||
stream->read((char *) &interations, sizeof(uint16_t));
|
||||
stream->read((char *) &angle_limit, sizeof(float));
|
||||
ik_child_bone_index.resize(ik_chain_length);
|
||||
for (int i = 0; i < ik_chain_length; i++)
|
||||
{
|
||||
stream->read((char *) &ik_child_bone_index[i], sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class PmdFaceVertex
|
||||
{
|
||||
public:
|
||||
int vertex_index;
|
||||
float position[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
stream->read((char *) &vertex_index, sizeof(int));
|
||||
stream->read((char *) position, sizeof(float) * 3);
|
||||
}
|
||||
};
|
||||
|
||||
enum class FaceCategory : uint8_t
|
||||
{
|
||||
Base,
|
||||
Eyebrow,
|
||||
Eye,
|
||||
Mouth,
|
||||
Other
|
||||
};
|
||||
|
||||
class PmdFace
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
FaceCategory type;
|
||||
std::vector<PmdFaceVertex> vertices;
|
||||
std::string name_english;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
name = std::string(buffer);
|
||||
int vertex_count;
|
||||
stream->read((char*) &vertex_count, sizeof(int));
|
||||
stream->read((char*) &type, sizeof(uint8_t));
|
||||
vertices.resize(vertex_count);
|
||||
for (int i = 0; i < vertex_count; i++)
|
||||
{
|
||||
vertices[i].Read(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadExpantion(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
name_english = std::string(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
/// ボーン枠用の枠名
|
||||
class PmdBoneDispName
|
||||
{
|
||||
public:
|
||||
std::string bone_disp_name;
|
||||
std::string bone_disp_name_english;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
char buffer[50];
|
||||
stream->read(buffer, 50);
|
||||
bone_disp_name = std::string(buffer);
|
||||
bone_disp_name_english.clear();
|
||||
}
|
||||
void ReadExpantion(std::istream *stream)
|
||||
{
|
||||
char buffer[50];
|
||||
stream->read(buffer, 50);
|
||||
bone_disp_name_english = std::string(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
class PmdBoneDisp
|
||||
{
|
||||
public:
|
||||
uint16_t bone_index;
|
||||
uint8_t bone_disp_index;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
stream->read((char*) &bone_index, sizeof(uint16_t));
|
||||
stream->read((char*) &bone_disp_index, sizeof(uint8_t));
|
||||
}
|
||||
};
|
||||
|
||||
/// 衝突形状
|
||||
enum class RigidBodyShape : uint8_t
|
||||
{
|
||||
/// 球
|
||||
Sphere = 0,
|
||||
/// 直方体
|
||||
Box = 1,
|
||||
/// カプセル
|
||||
Cpusel = 2
|
||||
};
|
||||
|
||||
/// 剛体タイプ
|
||||
enum class RigidBodyType : uint8_t
|
||||
{
|
||||
/// ボーン追従
|
||||
BoneConnected = 0,
|
||||
/// 物理演算
|
||||
Physics = 1,
|
||||
/// 物理演算(Bone位置合せ)
|
||||
ConnectedPhysics = 2
|
||||
};
|
||||
|
||||
/// 剛体
|
||||
class PmdRigidBody
|
||||
{
|
||||
public:
|
||||
/// 名前
|
||||
std::string name;
|
||||
/// 関連ボーン番号
|
||||
uint16_t related_bone_index;
|
||||
/// グループ番号
|
||||
uint8_t group_index;
|
||||
/// マスク
|
||||
uint16_t mask;
|
||||
/// 形状
|
||||
RigidBodyShape shape;
|
||||
/// 大きさ
|
||||
float size[3];
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[3];
|
||||
/// 質量
|
||||
float weight;
|
||||
/// 移動ダンピング
|
||||
float linear_damping;
|
||||
/// 回転ダンピング
|
||||
float anglar_damping;
|
||||
/// 反発係数
|
||||
float restitution;
|
||||
/// 摩擦係数
|
||||
float friction;
|
||||
/// 演算方法
|
||||
RigidBodyType rigid_type;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read(buffer, sizeof(char) * 20);
|
||||
name = (std::string(buffer));
|
||||
stream->read((char*) &related_bone_index, sizeof(uint16_t));
|
||||
stream->read((char*) &group_index, sizeof(uint8_t));
|
||||
stream->read((char*) &mask, sizeof(uint16_t));
|
||||
stream->read((char*) &shape, sizeof(uint8_t));
|
||||
stream->read((char*) size, sizeof(float) * 3);
|
||||
stream->read((char*) position, sizeof(float) * 3);
|
||||
stream->read((char*) orientation, sizeof(float) * 3);
|
||||
stream->read((char*) &weight, sizeof(float));
|
||||
stream->read((char*) &linear_damping, sizeof(float));
|
||||
stream->read((char*) &anglar_damping, sizeof(float));
|
||||
stream->read((char*) &restitution, sizeof(float));
|
||||
stream->read((char*) &friction, sizeof(float));
|
||||
stream->read((char*) &rigid_type, sizeof(char));
|
||||
}
|
||||
};
|
||||
|
||||
/// 剛体の拘束
|
||||
class PmdConstraint
|
||||
{
|
||||
public:
|
||||
/// 名前
|
||||
std::string name;
|
||||
/// 剛体Aのインデックス
|
||||
uint32_t rigid_body_index_a;
|
||||
/// 剛体Bのインデックス
|
||||
uint32_t rigid_body_index_b;
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[3];
|
||||
/// 最小移動制限
|
||||
float linear_lower_limit[3];
|
||||
/// 最大移動制限
|
||||
float linear_upper_limit[3];
|
||||
/// 最小回転制限
|
||||
float angular_lower_limit[3];
|
||||
/// 最大回転制限
|
||||
float angular_upper_limit[3];
|
||||
/// 移動に対する復元力
|
||||
float linear_stiffness[3];
|
||||
/// 回転に対する復元力
|
||||
float angular_stiffness[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
name = std::string(buffer);
|
||||
stream->read((char *) &rigid_body_index_a, sizeof(uint32_t));
|
||||
stream->read((char *) &rigid_body_index_b, sizeof(uint32_t));
|
||||
stream->read((char *) position, sizeof(float) * 3);
|
||||
stream->read((char *) orientation, sizeof(float) * 3);
|
||||
stream->read((char *) linear_lower_limit, sizeof(float) * 3);
|
||||
stream->read((char *) linear_upper_limit, sizeof(float) * 3);
|
||||
stream->read((char *) angular_lower_limit, sizeof(float) * 3);
|
||||
stream->read((char *) angular_upper_limit, sizeof(float) * 3);
|
||||
stream->read((char *) linear_stiffness, sizeof(float) * 3);
|
||||
stream->read((char *) angular_stiffness, sizeof(float) * 3);
|
||||
}
|
||||
};
|
||||
|
||||
/// PMDモデル
|
||||
class PmdModel
|
||||
{
|
||||
public:
|
||||
float version;
|
||||
PmdHeader header;
|
||||
std::vector<PmdVertex> vertices;
|
||||
std::vector<uint16_t> indices;
|
||||
std::vector<PmdMaterial> materials;
|
||||
std::vector<PmdBone> bones;
|
||||
std::vector<PmdIk> iks;
|
||||
std::vector<PmdFace> faces;
|
||||
std::vector<uint16_t> faces_indices;
|
||||
std::vector<PmdBoneDispName> bone_disp_name;
|
||||
std::vector<PmdBoneDisp> bone_disp;
|
||||
std::vector<std::string> toon_filenames;
|
||||
std::vector<PmdRigidBody> rigid_bodies;
|
||||
std::vector<PmdConstraint> constraints;
|
||||
|
||||
static std::unique_ptr<PmdModel> LoadFromFile(const char *filename)
|
||||
{
|
||||
std::ifstream stream(filename, std::ios::binary);
|
||||
if (stream.fail())
|
||||
{
|
||||
std::cerr << "could not open \"" << filename << "\"" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
auto result = LoadFromStream(&stream);
|
||||
stream.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// ファイルからPmdModelを生成する
|
||||
static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
|
||||
{
|
||||
auto result = std::make_unique<PmdModel>();
|
||||
char buffer[100];
|
||||
|
||||
// magic
|
||||
char magic[3];
|
||||
stream->read(magic, 3);
|
||||
if (magic[0] != 'P' || magic[1] != 'm' || magic[2] != 'd')
|
||||
{
|
||||
std::cerr << "invalid file" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// version
|
||||
stream->read((char*) &(result->version), sizeof(float));
|
||||
if (result ->version != 1.0f)
|
||||
{
|
||||
std::cerr << "invalid version" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// header
|
||||
result->header.Read(stream);
|
||||
|
||||
// vertices
|
||||
uint32_t vertex_num;
|
||||
stream->read((char*) &vertex_num, sizeof(uint32_t));
|
||||
result->vertices.resize(vertex_num);
|
||||
for (uint32_t i = 0; i < vertex_num; i++)
|
||||
{
|
||||
result->vertices[i].Read(stream);
|
||||
}
|
||||
|
||||
// indices
|
||||
uint32_t index_num;
|
||||
stream->read((char*) &index_num, sizeof(uint32_t));
|
||||
result->indices.resize(index_num);
|
||||
for (uint32_t i = 0; i < index_num; i++)
|
||||
{
|
||||
stream->read((char*) &result->indices[i], sizeof(uint16_t));
|
||||
}
|
||||
|
||||
// materials
|
||||
uint32_t material_num;
|
||||
stream->read((char*) &material_num, sizeof(uint32_t));
|
||||
result->materials.resize(material_num);
|
||||
for (uint32_t i = 0; i < material_num; i++)
|
||||
{
|
||||
result->materials[i].Read(stream);
|
||||
}
|
||||
|
||||
// bones
|
||||
uint16_t bone_num;
|
||||
stream->read((char*) &bone_num, sizeof(uint16_t));
|
||||
result->bones.resize(bone_num);
|
||||
for (uint32_t i = 0; i < bone_num; i++)
|
||||
{
|
||||
result->bones[i].Read(stream);
|
||||
}
|
||||
|
||||
// iks
|
||||
uint16_t ik_num;
|
||||
stream->read((char*) &ik_num, sizeof(uint16_t));
|
||||
result->iks.resize(ik_num);
|
||||
for (uint32_t i = 0; i < ik_num; i++)
|
||||
{
|
||||
result->iks[i].Read(stream);
|
||||
}
|
||||
|
||||
// faces
|
||||
uint16_t face_num;
|
||||
stream->read((char*) &face_num, sizeof(uint16_t));
|
||||
result->faces.resize(face_num);
|
||||
for (uint32_t i = 0; i < face_num; i++)
|
||||
{
|
||||
result->faces[i].Read(stream);
|
||||
}
|
||||
|
||||
// face frames
|
||||
uint8_t face_frame_num;
|
||||
stream->read((char*) &face_frame_num, sizeof(uint8_t));
|
||||
result->faces_indices.resize(face_frame_num);
|
||||
for (uint32_t i = 0; i < face_frame_num; i++)
|
||||
{
|
||||
stream->read((char*) &result->faces_indices[i], sizeof(uint16_t));
|
||||
}
|
||||
|
||||
// bone names
|
||||
uint8_t bone_disp_num;
|
||||
stream->read((char*) &bone_disp_num, sizeof(uint8_t));
|
||||
result->bone_disp_name.resize(bone_disp_num);
|
||||
for (uint32_t i = 0; i < bone_disp_num; i++)
|
||||
{
|
||||
result->bone_disp_name[i].Read(stream);
|
||||
}
|
||||
|
||||
// bone frame
|
||||
uint32_t bone_frame_num;
|
||||
stream->read((char*) &bone_frame_num, sizeof(uint32_t));
|
||||
result->bone_disp.resize(bone_frame_num);
|
||||
for (uint32_t i = 0; i < bone_frame_num; i++)
|
||||
{
|
||||
result->bone_disp[i].Read(stream);
|
||||
}
|
||||
|
||||
// english name
|
||||
bool english;
|
||||
stream->read((char*) &english, sizeof(char));
|
||||
if (english)
|
||||
{
|
||||
result->header.ReadExtension(stream);
|
||||
for (uint32_t i = 0; i < bone_num; i++)
|
||||
{
|
||||
result->bones[i].ReadExpantion(stream);
|
||||
}
|
||||
for (uint32_t i = 0; i < face_num; i++)
|
||||
{
|
||||
if (result->faces[i].type == pmd::FaceCategory::Base)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
result->faces[i].ReadExpantion(stream);
|
||||
}
|
||||
for (uint32_t i = 0; i < result->bone_disp_name.size(); i++)
|
||||
{
|
||||
result->bone_disp_name[i].ReadExpantion(stream);
|
||||
}
|
||||
}
|
||||
|
||||
// toon textures
|
||||
if (stream->peek() == std::ios::traits_type::eof())
|
||||
{
|
||||
result->toon_filenames.clear();
|
||||
}
|
||||
else {
|
||||
result->toon_filenames.resize(10);
|
||||
for (uint32_t i = 0; i < 10; i++)
|
||||
{
|
||||
stream->read(buffer, 100);
|
||||
result->toon_filenames[i] = std::string(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// physics
|
||||
if (stream->peek() == std::ios::traits_type::eof())
|
||||
{
|
||||
result->rigid_bodies.clear();
|
||||
result->constraints.clear();
|
||||
}
|
||||
else {
|
||||
uint32_t rigid_body_num;
|
||||
stream->read((char*) &rigid_body_num, sizeof(uint32_t));
|
||||
result->rigid_bodies.resize(rigid_body_num);
|
||||
for (uint32_t i = 0; i < rigid_body_num; i++)
|
||||
{
|
||||
result->rigid_bodies[i].Read(stream);
|
||||
}
|
||||
uint32_t constraint_num;
|
||||
stream->read((char*) &constraint_num, sizeof(uint32_t));
|
||||
result->constraints.resize(constraint_num);
|
||||
for (uint32_t i = 0; i < constraint_num; i++)
|
||||
{
|
||||
result->constraints[i].Read(stream);
|
||||
}
|
||||
}
|
||||
|
||||
if (stream->peek() != std::ios::traits_type::eof())
|
||||
{
|
||||
std::cerr << "there is unknown data" << std::endl;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,625 @@
|
|||
#include <utility>
|
||||
#include "MMDPmxParser.h"
|
||||
#ifndef __unix__
|
||||
#include "EncodingHelper.h"
|
||||
#else
|
||||
#include <unicode/ucnv.h>
|
||||
#endif
|
||||
|
||||
namespace pmx
|
||||
{
|
||||
/// インデックス値を読み込む
|
||||
int ReadIndex(std::istream *stream, int size)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
uint8_t tmp8;
|
||||
stream->read((char*) &tmp8, sizeof(uint8_t));
|
||||
if (255 == tmp8)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return (int) tmp8;
|
||||
}
|
||||
case 2:
|
||||
uint16_t tmp16;
|
||||
stream->read((char*) &tmp16, sizeof(uint16_t));
|
||||
if (65535 == tmp16)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return (int) tmp16;
|
||||
}
|
||||
case 4:
|
||||
int tmp32;
|
||||
stream->read((char*) &tmp32, sizeof(int));
|
||||
return tmp32;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// 文字列を読み込む
|
||||
utfstring ReadString(std::istream *stream, uint8_t encoding)
|
||||
{
|
||||
#ifndef __unix__
|
||||
oguna::EncodingConverter converter = oguna::EncodingConverter();
|
||||
#endif
|
||||
int size;
|
||||
stream->read((char*) &size, sizeof(int));
|
||||
std::vector<char> buffer;
|
||||
if (size == 0)
|
||||
{
|
||||
#ifndef __unix__
|
||||
return utfstring(L"");
|
||||
#else
|
||||
return utfstring("");
|
||||
#endif
|
||||
}
|
||||
buffer.reserve(size);
|
||||
stream->read((char*) buffer.data(), size);
|
||||
if (encoding == 0)
|
||||
{
|
||||
// UTF16
|
||||
#ifndef __unix__
|
||||
return utfstring((wchar_t*) buffer.data(), size / 2);
|
||||
#else
|
||||
utfstring result;
|
||||
std::vector<char> outbuf;
|
||||
outbuf.reserve(size*2);
|
||||
|
||||
// Always remember to set U_ZERO_ERROR before calling ucnv_convert(),
|
||||
// otherwise the function will fail.
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
size = ucnv_convert("UTF-8", "UTF-16LE", (char*)outbuf.data(), outbuf.capacity(), buffer.data(), size, &err);
|
||||
if(!U_SUCCESS(err)) {
|
||||
std::cout << "oops, something wrong?" << std::endl;
|
||||
std::cout << u_errorName(err) << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
result.assign((const char*)outbuf.data(), size);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// UTF8
|
||||
#ifndef __unix__
|
||||
utfstring result;
|
||||
converter.Utf8ToUtf16(buffer.data(), size, &result);
|
||||
return result;
|
||||
#else
|
||||
return utfstring((const char*)buffer.data(), size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void PmxSetting::Read(std::istream *stream)
|
||||
{
|
||||
uint8_t count;
|
||||
stream->read((char*) &count, sizeof(uint8_t));
|
||||
if (count < 8)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
stream->read((char*) &encoding, sizeof(uint8_t));
|
||||
stream->read((char*) &uv, sizeof(uint8_t));
|
||||
stream->read((char*) &vertex_index_size, sizeof(uint8_t));
|
||||
stream->read((char*) &texture_index_size, sizeof(uint8_t));
|
||||
stream->read((char*) &material_index_size, sizeof(uint8_t));
|
||||
stream->read((char*) &bone_index_size, sizeof(uint8_t));
|
||||
stream->read((char*) &morph_index_size, sizeof(uint8_t));
|
||||
stream->read((char*) &rigidbody_index_size, sizeof(uint8_t));
|
||||
uint8_t temp;
|
||||
for (int i = 8; i < count; i++)
|
||||
{
|
||||
stream->read((char*)&temp, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
void PmxVertexSkinningBDEF1::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->bone_index = ReadIndex(stream, setting->bone_index_size);
|
||||
}
|
||||
|
||||
void PmxVertexSkinningBDEF2::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
|
||||
this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &this->bone_weight, sizeof(float));
|
||||
}
|
||||
|
||||
void PmxVertexSkinningBDEF4::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
|
||||
this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
|
||||
this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
|
||||
this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &this->bone_weight1, sizeof(float));
|
||||
stream->read((char*) &this->bone_weight2, sizeof(float));
|
||||
stream->read((char*) &this->bone_weight3, sizeof(float));
|
||||
stream->read((char*) &this->bone_weight4, sizeof(float));
|
||||
}
|
||||
|
||||
void PmxVertexSkinningSDEF::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
|
||||
this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &this->bone_weight, sizeof(float));
|
||||
stream->read((char*) this->sdef_c, sizeof(float) * 3);
|
||||
stream->read((char*) this->sdef_r0, sizeof(float) * 3);
|
||||
stream->read((char*) this->sdef_r1, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
void PmxVertexSkinningQDEF::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
|
||||
this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
|
||||
this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
|
||||
this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &this->bone_weight1, sizeof(float));
|
||||
stream->read((char*) &this->bone_weight2, sizeof(float));
|
||||
stream->read((char*) &this->bone_weight3, sizeof(float));
|
||||
stream->read((char*) &this->bone_weight4, sizeof(float));
|
||||
}
|
||||
|
||||
void PmxVertex::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
stream->read((char*) this->positon, sizeof(float) * 3);
|
||||
stream->read((char*) this->normal, sizeof(float) * 3);
|
||||
stream->read((char*) this->uv, sizeof(float) * 2);
|
||||
for (int i = 0; i < setting->uv; ++i)
|
||||
{
|
||||
stream->read((char*) this->uva[i], sizeof(float) * 4);
|
||||
}
|
||||
stream->read((char*) &this->skinning_type, sizeof(PmxVertexSkinningType));
|
||||
switch (this->skinning_type)
|
||||
{
|
||||
case PmxVertexSkinningType::BDEF1:
|
||||
this->skinning = std::make_unique<PmxVertexSkinningBDEF1>();
|
||||
break;
|
||||
case PmxVertexSkinningType::BDEF2:
|
||||
this->skinning = std::make_unique<PmxVertexSkinningBDEF2>();
|
||||
break;
|
||||
case PmxVertexSkinningType::BDEF4:
|
||||
this->skinning = std::make_unique<PmxVertexSkinningBDEF4>();
|
||||
break;
|
||||
case PmxVertexSkinningType::SDEF:
|
||||
this->skinning = std::make_unique<PmxVertexSkinningSDEF>();
|
||||
break;
|
||||
case PmxVertexSkinningType::QDEF:
|
||||
this->skinning = std::make_unique<PmxVertexSkinningQDEF>();
|
||||
break;
|
||||
default:
|
||||
throw "invalid skinning type";
|
||||
}
|
||||
this->skinning->Read(stream, setting);
|
||||
stream->read((char*) &this->edge, sizeof(float));
|
||||
}
|
||||
|
||||
void PmxMaterial::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->material_name = std::move(ReadString(stream, setting->encoding));
|
||||
this->material_english_name = std::move(ReadString(stream, setting->encoding));
|
||||
stream->read((char*) this->diffuse, sizeof(float) * 4);
|
||||
stream->read((char*) this->specular, sizeof(float) * 3);
|
||||
stream->read((char*) &this->specularlity, sizeof(float));
|
||||
stream->read((char*) this->ambient, sizeof(float) * 3);
|
||||
stream->read((char*) &this->flag, sizeof(uint8_t));
|
||||
stream->read((char*) this->edge_color, sizeof(float) * 4);
|
||||
stream->read((char*) &this->edge_size, sizeof(float));
|
||||
this->diffuse_texture_index = ReadIndex(stream, setting->texture_index_size);
|
||||
this->sphere_texture_index = ReadIndex(stream, setting->texture_index_size);
|
||||
stream->read((char*) &this->sphere_op_mode, sizeof(uint8_t));
|
||||
stream->read((char*) &this->common_toon_flag, sizeof(uint8_t));
|
||||
if (this->common_toon_flag)
|
||||
{
|
||||
stream->read((char*) &this->toon_texture_index, sizeof(uint8_t));
|
||||
}
|
||||
else {
|
||||
this->toon_texture_index = ReadIndex(stream, setting->texture_index_size);
|
||||
}
|
||||
this->memo = std::move(ReadString(stream, setting->encoding));
|
||||
stream->read((char*) &this->index_count, sizeof(int));
|
||||
}
|
||||
|
||||
void PmxIkLink::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->link_target = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &this->angle_lock, sizeof(uint8_t));
|
||||
if (angle_lock == 1)
|
||||
{
|
||||
stream->read((char*) this->max_radian, sizeof(float) * 3);
|
||||
stream->read((char*) this->min_radian, sizeof(float) * 3);
|
||||
}
|
||||
}
|
||||
|
||||
void PmxBone::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->bone_name = std::move(ReadString(stream, setting->encoding));
|
||||
this->bone_english_name = std::move(ReadString(stream, setting->encoding));
|
||||
stream->read((char*) this->position, sizeof(float) * 3);
|
||||
this->parent_index = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &this->level, sizeof(int));
|
||||
stream->read((char*) &this->bone_flag, sizeof(uint16_t));
|
||||
if (this->bone_flag & 0x0001) {
|
||||
this->target_index = ReadIndex(stream, setting->bone_index_size);
|
||||
}
|
||||
else {
|
||||
stream->read((char*)this->offset, sizeof(float) * 3);
|
||||
}
|
||||
if (this->bone_flag & (0x0100 | 0x0200)) {
|
||||
this->grant_parent_index = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &this->grant_weight, sizeof(float));
|
||||
}
|
||||
if (this->bone_flag & 0x0400) {
|
||||
stream->read((char*)this->lock_axis_orientation, sizeof(float) * 3);
|
||||
}
|
||||
if (this->bone_flag & 0x0800) {
|
||||
stream->read((char*)this->local_axis_x_orientation, sizeof(float) * 3);
|
||||
stream->read((char*)this->local_axis_y_orientation, sizeof(float) * 3);
|
||||
}
|
||||
if (this->bone_flag & 0x2000) {
|
||||
stream->read((char*) &this->key, sizeof(int));
|
||||
}
|
||||
if (this->bone_flag & 0x0020) {
|
||||
this->ik_target_bone_index = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &ik_loop, sizeof(int));
|
||||
stream->read((char*) &ik_loop_angle_limit, sizeof(float));
|
||||
stream->read((char*) &ik_link_count, sizeof(int));
|
||||
this->ik_links = std::make_unique<PmxIkLink []>(ik_link_count);
|
||||
for (int i = 0; i < ik_link_count; i++) {
|
||||
ik_links[i].Read(stream, setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PmxMorphVertexOffset::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
|
||||
stream->read((char*)this->position_offset, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
void PmxMorphUVOffset::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
|
||||
stream->read((char*)this->uv_offset, sizeof(float) * 4);
|
||||
}
|
||||
|
||||
void PmxMorphBoneOffset::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->bone_index = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*)this->translation, sizeof(float) * 3);
|
||||
stream->read((char*)this->rotation, sizeof(float) * 4);
|
||||
}
|
||||
|
||||
void PmxMorphMaterialOffset::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->material_index = ReadIndex(stream, setting->material_index_size);
|
||||
stream->read((char*) &this->offset_operation, sizeof(uint8_t));
|
||||
stream->read((char*)this->diffuse, sizeof(float) * 4);
|
||||
stream->read((char*)this->specular, sizeof(float) * 3);
|
||||
stream->read((char*) &this->specularity, sizeof(float));
|
||||
stream->read((char*)this->ambient, sizeof(float) * 3);
|
||||
stream->read((char*)this->edge_color, sizeof(float) * 4);
|
||||
stream->read((char*) &this->edge_size, sizeof(float));
|
||||
stream->read((char*)this->texture_argb, sizeof(float) * 4);
|
||||
stream->read((char*)this->sphere_texture_argb, sizeof(float) * 4);
|
||||
stream->read((char*)this->toon_texture_argb, sizeof(float) * 4);
|
||||
}
|
||||
|
||||
void PmxMorphGroupOffset::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->morph_index = ReadIndex(stream, setting->morph_index_size);
|
||||
stream->read((char*) &this->morph_weight, sizeof(float));
|
||||
}
|
||||
|
||||
void PmxMorphFlipOffset::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->morph_index = ReadIndex(stream, setting->morph_index_size);
|
||||
stream->read((char*) &this->morph_value, sizeof(float));
|
||||
}
|
||||
|
||||
void PmxMorphImplusOffset::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->rigid_body_index = ReadIndex(stream, setting->rigidbody_index_size);
|
||||
stream->read((char*) &this->is_local, sizeof(uint8_t));
|
||||
stream->read((char*)this->velocity, sizeof(float) * 3);
|
||||
stream->read((char*)this->angular_torque, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
void PmxMorph::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->morph_name = ReadString(stream, setting->encoding);
|
||||
this->morph_english_name = ReadString(stream, setting->encoding);
|
||||
stream->read((char*) &category, sizeof(MorphCategory));
|
||||
stream->read((char*) &morph_type, sizeof(MorphType));
|
||||
stream->read((char*) &this->offset_count, sizeof(int));
|
||||
switch (this->morph_type)
|
||||
{
|
||||
case MorphType::Group:
|
||||
group_offsets = std::make_unique<PmxMorphGroupOffset []>(this->offset_count);
|
||||
for (int i = 0; i < offset_count; i++)
|
||||
{
|
||||
group_offsets[i].Read(stream, setting);
|
||||
}
|
||||
break;
|
||||
case MorphType::Vertex:
|
||||
vertex_offsets = std::make_unique<PmxMorphVertexOffset []>(this->offset_count);
|
||||
for (int i = 0; i < offset_count; i++)
|
||||
{
|
||||
vertex_offsets[i].Read(stream, setting);
|
||||
}
|
||||
break;
|
||||
case MorphType::Bone:
|
||||
bone_offsets = std::make_unique<PmxMorphBoneOffset []>(this->offset_count);
|
||||
for (int i = 0; i < offset_count; i++)
|
||||
{
|
||||
bone_offsets[i].Read(stream, setting);
|
||||
}
|
||||
break;
|
||||
case MorphType::Matrial:
|
||||
material_offsets = std::make_unique<PmxMorphMaterialOffset []>(this->offset_count);
|
||||
for (int i = 0; i < offset_count; i++)
|
||||
{
|
||||
material_offsets[i].Read(stream, setting);
|
||||
}
|
||||
break;
|
||||
case MorphType::UV:
|
||||
case MorphType::AdditionalUV1:
|
||||
case MorphType::AdditionalUV2:
|
||||
case MorphType::AdditionalUV3:
|
||||
case MorphType::AdditionalUV4:
|
||||
uv_offsets = std::make_unique<PmxMorphUVOffset []>(this->offset_count);
|
||||
for (int i = 0; i < offset_count; i++)
|
||||
{
|
||||
uv_offsets[i].Read(stream, setting);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void PmxFrameElement::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
stream->read((char*) &this->element_target, sizeof(uint8_t));
|
||||
if (this->element_target == 0x00)
|
||||
{
|
||||
this->index = ReadIndex(stream, setting->bone_index_size);
|
||||
}
|
||||
else {
|
||||
this->index = ReadIndex(stream, setting->morph_index_size);
|
||||
}
|
||||
}
|
||||
|
||||
void PmxFrame::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->frame_name = ReadString(stream, setting->encoding);
|
||||
this->frame_english_name = ReadString(stream, setting->encoding);
|
||||
stream->read((char*) &this->frame_flag, sizeof(uint8_t));
|
||||
stream->read((char*) &this->element_count, sizeof(int));
|
||||
this->elements = std::make_unique<PmxFrameElement []>(this->element_count);
|
||||
for (int i = 0; i < this->element_count; i++)
|
||||
{
|
||||
this->elements[i].Read(stream, setting);
|
||||
}
|
||||
}
|
||||
|
||||
void PmxRigidBody::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->girid_body_name = ReadString(stream, setting->encoding);
|
||||
this->girid_body_english_name = ReadString(stream, setting->encoding);
|
||||
this->target_bone = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &this->group, sizeof(uint8_t));
|
||||
stream->read((char*) &this->mask, sizeof(uint16_t));
|
||||
stream->read((char*) &this->shape, sizeof(uint8_t));
|
||||
stream->read((char*) this->size, sizeof(float) * 3);
|
||||
stream->read((char*) this->position, sizeof(float) * 3);
|
||||
stream->read((char*) this->orientation, sizeof(float) * 3);
|
||||
stream->read((char*) &this->mass, sizeof(float));
|
||||
stream->read((char*) &this->move_attenuation, sizeof(float));
|
||||
stream->read((char*) &this->rotation_attenuation, sizeof(float));
|
||||
stream->read((char*) &this->repulsion, sizeof(float));
|
||||
stream->read((char*) &this->friction, sizeof(float));
|
||||
stream->read((char*) &this->physics_calc_type, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
void PmxJointParam::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->rigid_body1 = ReadIndex(stream, setting->rigidbody_index_size);
|
||||
this->rigid_body2 = ReadIndex(stream, setting->rigidbody_index_size);
|
||||
stream->read((char*) this->position, sizeof(float) * 3);
|
||||
stream->read((char*) this->orientaiton, sizeof(float) * 3);
|
||||
stream->read((char*) this->move_limitation_min, sizeof(float) * 3);
|
||||
stream->read((char*) this->move_limitation_max, sizeof(float) * 3);
|
||||
stream->read((char*) this->rotation_limitation_min, sizeof(float) * 3);
|
||||
stream->read((char*) this->rotation_limitation_max, sizeof(float) * 3);
|
||||
stream->read((char*) this->spring_move_coefficient, sizeof(float) * 3);
|
||||
stream->read((char*) this->spring_rotation_coefficient, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
void PmxJoint::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->joint_name = ReadString(stream, setting->encoding);
|
||||
this->joint_english_name = ReadString(stream, setting->encoding);
|
||||
stream->read((char*) &this->joint_type, sizeof(uint8_t));
|
||||
this->param.Read(stream, setting);
|
||||
}
|
||||
|
||||
void PmxAncherRigidBody::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->related_rigid_body = ReadIndex(stream, setting->rigidbody_index_size);
|
||||
this->related_vertex = ReadIndex(stream, setting->vertex_index_size);
|
||||
stream->read((char*) &this->is_near, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
void PmxSoftBody::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
// 未実装
|
||||
std::cerr << "Not Implemented Exception" << std::endl;
|
||||
throw;
|
||||
}
|
||||
|
||||
void PmxModel::Init()
|
||||
{
|
||||
this->version = 0.0f;
|
||||
this->model_name.clear();
|
||||
this->model_english_name.clear();
|
||||
this->model_comment.clear();
|
||||
this->model_english_comment.clear();
|
||||
this->vertex_count = 0;
|
||||
this->vertices = nullptr;
|
||||
this->index_count = 0;
|
||||
this->indices = nullptr;
|
||||
this->texture_count = 0;
|
||||
this->textures = nullptr;
|
||||
this->material_count = 0;
|
||||
this->materials = nullptr;
|
||||
this->bone_count = 0;
|
||||
this->bones = nullptr;
|
||||
this->morph_count = 0;
|
||||
this->morphs = nullptr;
|
||||
this->frame_count = 0;
|
||||
this->frames = nullptr;
|
||||
this->rigid_body_count = 0;
|
||||
this->rigid_bodies = nullptr;
|
||||
this->joint_count = 0;
|
||||
this->joints = nullptr;
|
||||
this->soft_body_count = 0;
|
||||
this->soft_bodies = nullptr;
|
||||
}
|
||||
|
||||
void PmxModel::Read(std::istream *stream)
|
||||
{
|
||||
// マジック
|
||||
char magic[4];
|
||||
stream->read((char*) magic, sizeof(char) * 4);
|
||||
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
|
||||
{
|
||||
std::cerr << "invalid magic number." << std::endl;
|
||||
throw;
|
||||
}
|
||||
// バージョン
|
||||
stream->read((char*) &version, sizeof(float));
|
||||
if (version != 2.0f && version != 2.1f)
|
||||
{
|
||||
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
|
||||
throw;
|
||||
}
|
||||
// ファイル設定
|
||||
this->setting.Read(stream);
|
||||
|
||||
// モデル情報
|
||||
this->model_name = std::move(ReadString(stream, setting.encoding));
|
||||
this->model_english_name = std::move(ReadString(stream, setting.encoding));
|
||||
this->model_comment = std::move(ReadString(stream, setting.encoding));
|
||||
this->model_english_comment = std::move(ReadString(stream, setting.encoding));
|
||||
|
||||
// 頂点
|
||||
stream->read((char*) &vertex_count, sizeof(int));
|
||||
this->vertices = std::make_unique<PmxVertex []>(vertex_count);
|
||||
for (int i = 0; i < vertex_count; i++)
|
||||
{
|
||||
vertices[i].Read(stream, &setting);
|
||||
}
|
||||
|
||||
// 面
|
||||
stream->read((char*) &index_count, sizeof(int));
|
||||
this->indices = std::make_unique<int []>(index_count);
|
||||
for (int i = 0; i < index_count; i++)
|
||||
{
|
||||
this->indices[i] = ReadIndex(stream, setting.vertex_index_size);
|
||||
}
|
||||
|
||||
// テクスチャ
|
||||
stream->read((char*) &texture_count, sizeof(int));
|
||||
this->textures = std::make_unique<utfstring []>(texture_count);
|
||||
for (int i = 0; i < texture_count; i++)
|
||||
{
|
||||
this->textures[i] = ReadString(stream, setting.encoding);
|
||||
}
|
||||
|
||||
// マテリアル
|
||||
stream->read((char*) &material_count, sizeof(int));
|
||||
this->materials = std::make_unique<PmxMaterial []>(material_count);
|
||||
for (int i = 0; i < material_count; i++)
|
||||
{
|
||||
this->materials[i].Read(stream, &setting);
|
||||
}
|
||||
|
||||
// ボーン
|
||||
stream->read((char*) &this->bone_count, sizeof(int));
|
||||
this->bones = std::make_unique<PmxBone []>(this->bone_count);
|
||||
for (int i = 0; i < this->bone_count; i++)
|
||||
{
|
||||
this->bones[i].Read(stream, &setting);
|
||||
}
|
||||
|
||||
// モーフ
|
||||
stream->read((char*) &this->morph_count, sizeof(int));
|
||||
this->morphs = std::make_unique<PmxMorph []>(this->morph_count);
|
||||
for (int i = 0; i < this->morph_count; i++)
|
||||
{
|
||||
this->morphs[i].Read(stream, &setting);
|
||||
}
|
||||
|
||||
// 表示枠
|
||||
stream->read((char*) &this->frame_count, sizeof(int));
|
||||
this->frames = std::make_unique<PmxFrame []>(this->frame_count);
|
||||
for (int i = 0; i < this->frame_count; i++)
|
||||
{
|
||||
this->frames[i].Read(stream, &setting);
|
||||
}
|
||||
|
||||
// 剛体
|
||||
stream->read((char*) &this->rigid_body_count, sizeof(int));
|
||||
this->rigid_bodies = std::make_unique<PmxRigidBody []>(this->rigid_body_count);
|
||||
for (int i = 0; i < this->rigid_body_count; i++)
|
||||
{
|
||||
this->rigid_bodies[i].Read(stream, &setting);
|
||||
}
|
||||
|
||||
// ジョイント
|
||||
stream->read((char*) &this->joint_count, sizeof(int));
|
||||
this->joints = std::make_unique<PmxJoint []>(this->joint_count);
|
||||
for (int i = 0; i < this->joint_count; i++)
|
||||
{
|
||||
this->joints[i].Read(stream, &setting);
|
||||
}
|
||||
|
||||
//// ソフトボディ
|
||||
//if (this->version == 2.1f)
|
||||
//{
|
||||
// stream->read((char*) &this->soft_body_count, sizeof(int));
|
||||
// this->soft_bodies = std::make_unique<PmxSoftBody []>(this->soft_body_count);
|
||||
// for (int i = 0; i < this->soft_body_count; i++)
|
||||
// {
|
||||
// this->soft_bodies[i].Read(stream, &setting);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
//std::unique_ptr<PmxModel> ReadFromFile(const char *filename)
|
||||
//{
|
||||
// auto stream = std::ifstream(filename, std::ios_base::binary);
|
||||
// auto pmx = PmxModel::ReadFromStream(&stream);
|
||||
// if (!stream.eof())
|
||||
// {
|
||||
// std::cerr << "don't reach the end of file." << std::endl;
|
||||
// }
|
||||
// stream.close();
|
||||
// return pmx;
|
||||
//}
|
||||
|
||||
//std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream)
|
||||
//{
|
||||
// auto pmx = std::make_unique<PmxModel>();
|
||||
// pmx->Read(stream);
|
||||
// return pmx;
|
||||
//}
|
||||
}
|
|
@ -0,0 +1,865 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include "MMDCpp14.h"
|
||||
|
||||
namespace pmx
|
||||
{
|
||||
#ifndef __unix__
|
||||
#define utfstring std::wstring
|
||||
#else
|
||||
#define utfstring std::string
|
||||
#endif
|
||||
/// インデックス設定
|
||||
class PmxSetting
|
||||
{
|
||||
public:
|
||||
PmxSetting()
|
||||
: encoding(0)
|
||||
, uv(0)
|
||||
, vertex_index_size(0)
|
||||
, texture_index_size(0)
|
||||
, material_index_size(0)
|
||||
, bone_index_size(0)
|
||||
, morph_index_size(0)
|
||||
, rigidbody_index_size(0)
|
||||
{}
|
||||
|
||||
/// エンコード方式
|
||||
uint8_t encoding;
|
||||
/// 追加UV数
|
||||
uint8_t uv;
|
||||
/// 頂点インデックスサイズ
|
||||
uint8_t vertex_index_size;
|
||||
/// テクスチャインデックスサイズ
|
||||
uint8_t texture_index_size;
|
||||
/// マテリアルインデックスサイズ
|
||||
uint8_t material_index_size;
|
||||
/// ボーンインデックスサイズ
|
||||
uint8_t bone_index_size;
|
||||
/// モーフインデックスサイズ
|
||||
uint8_t morph_index_size;
|
||||
/// 剛体インデックスサイズ
|
||||
uint8_t rigidbody_index_size;
|
||||
void Read(std::istream *stream);
|
||||
};
|
||||
|
||||
/// 頂点スキニングタイプ
|
||||
enum class PmxVertexSkinningType : uint8_t
|
||||
{
|
||||
BDEF1 = 0,
|
||||
BDEF2 = 1,
|
||||
BDEF4 = 2,
|
||||
SDEF = 3,
|
||||
QDEF = 4,
|
||||
};
|
||||
|
||||
/// 頂点スキニング
|
||||
class PmxVertexSkinning
|
||||
{
|
||||
public:
|
||||
virtual void Read(std::istream *stream, PmxSetting *setting) = 0;
|
||||
};
|
||||
|
||||
class PmxVertexSkinningBDEF1 : public PmxVertexSkinning
|
||||
{
|
||||
public:
|
||||
PmxVertexSkinningBDEF1()
|
||||
: bone_index(0)
|
||||
{}
|
||||
|
||||
int bone_index;
|
||||
void Read(std::istream *stresam, PmxSetting *setting);
|
||||
};
|
||||
|
||||
class PmxVertexSkinningBDEF2 : public PmxVertexSkinning
|
||||
{
|
||||
public:
|
||||
PmxVertexSkinningBDEF2()
|
||||
: bone_index1(0)
|
||||
, bone_index2(0)
|
||||
, bone_weight(0.0f)
|
||||
{}
|
||||
|
||||
int bone_index1;
|
||||
int bone_index2;
|
||||
float bone_weight;
|
||||
void Read(std::istream *stresam, PmxSetting *setting);
|
||||
};
|
||||
|
||||
class PmxVertexSkinningBDEF4 : public PmxVertexSkinning
|
||||
{
|
||||
public:
|
||||
PmxVertexSkinningBDEF4()
|
||||
: bone_index1(0)
|
||||
, bone_index2(0)
|
||||
, bone_index3(0)
|
||||
, bone_index4(0)
|
||||
, bone_weight1(0.0f)
|
||||
, bone_weight2(0.0f)
|
||||
, bone_weight3(0.0f)
|
||||
, bone_weight4(0.0f)
|
||||
{}
|
||||
|
||||
int bone_index1;
|
||||
int bone_index2;
|
||||
int bone_index3;
|
||||
int bone_index4;
|
||||
float bone_weight1;
|
||||
float bone_weight2;
|
||||
float bone_weight3;
|
||||
float bone_weight4;
|
||||
void Read(std::istream *stresam, PmxSetting *setting);
|
||||
};
|
||||
|
||||
class PmxVertexSkinningSDEF : public PmxVertexSkinning
|
||||
{
|
||||
public:
|
||||
PmxVertexSkinningSDEF()
|
||||
: bone_index1(0)
|
||||
, bone_index2(0)
|
||||
, bone_weight(0.0f)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
sdef_c[i] = 0.0f;
|
||||
sdef_r0[i] = 0.0f;
|
||||
sdef_r1[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
int bone_index1;
|
||||
int bone_index2;
|
||||
float bone_weight;
|
||||
float sdef_c[3];
|
||||
float sdef_r0[3];
|
||||
float sdef_r1[3];
|
||||
void Read(std::istream *stresam, PmxSetting *setting);
|
||||
};
|
||||
|
||||
class PmxVertexSkinningQDEF : public PmxVertexSkinning
|
||||
{
|
||||
public:
|
||||
PmxVertexSkinningQDEF()
|
||||
: bone_index1(0)
|
||||
, bone_index2(0)
|
||||
, bone_index3(0)
|
||||
, bone_index4(0)
|
||||
, bone_weight1(0.0f)
|
||||
, bone_weight2(0.0f)
|
||||
, bone_weight3(0.0f)
|
||||
, bone_weight4(0.0f)
|
||||
{}
|
||||
|
||||
int bone_index1;
|
||||
int bone_index2;
|
||||
int bone_index3;
|
||||
int bone_index4;
|
||||
float bone_weight1;
|
||||
float bone_weight2;
|
||||
float bone_weight3;
|
||||
float bone_weight4;
|
||||
void Read(std::istream *stresam, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// 頂点
|
||||
class PmxVertex
|
||||
{
|
||||
public:
|
||||
PmxVertex()
|
||||
: edge(0.0f)
|
||||
{
|
||||
uv[0] = uv[1] = 0.0f;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
positon[i] = 0.0f;
|
||||
normal[i] = 0.0f;
|
||||
}
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
uva[i][k] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 位置
|
||||
float positon[3];
|
||||
/// 法線
|
||||
float normal[3];
|
||||
/// テクスチャ座標
|
||||
float uv[2];
|
||||
/// 追加テクスチャ座標
|
||||
float uva[4][4];
|
||||
/// スキニングタイプ
|
||||
PmxVertexSkinningType skinning_type;
|
||||
/// スキニング
|
||||
std::unique_ptr<PmxVertexSkinning> skinning;
|
||||
/// エッジ倍率
|
||||
float edge;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// マテリアル
|
||||
class PmxMaterial
|
||||
{
|
||||
public:
|
||||
PmxMaterial()
|
||||
: specularlity(0.0f)
|
||||
, flag(0)
|
||||
, edge_size(0.0f)
|
||||
, diffuse_texture_index(0)
|
||||
, sphere_texture_index(0)
|
||||
, sphere_op_mode(0)
|
||||
, common_toon_flag(0)
|
||||
, toon_texture_index(0)
|
||||
, index_count(0)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
specular[i] = 0.0f;
|
||||
ambient[i] = 0.0f;
|
||||
edge_color[i] = 0.0f;
|
||||
}
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
diffuse[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/// モデル名
|
||||
utfstring material_name;
|
||||
/// モデル英名
|
||||
utfstring material_english_name;
|
||||
/// 減衰色
|
||||
float diffuse[4];
|
||||
/// 光沢色
|
||||
float specular[3];
|
||||
/// 光沢度
|
||||
float specularlity;
|
||||
/// 環境色
|
||||
float ambient[3];
|
||||
/// 描画フラグ
|
||||
uint8_t flag;
|
||||
/// エッジ色
|
||||
float edge_color[4];
|
||||
/// エッジサイズ
|
||||
float edge_size;
|
||||
/// アルベドテクスチャインデックス
|
||||
int diffuse_texture_index;
|
||||
/// スフィアテクスチャインデックス
|
||||
int sphere_texture_index;
|
||||
/// スフィアテクスチャ演算モード
|
||||
uint8_t sphere_op_mode;
|
||||
/// 共有トゥーンフラグ
|
||||
uint8_t common_toon_flag;
|
||||
/// トゥーンテクスチャインデックス
|
||||
int toon_texture_index;
|
||||
/// メモ
|
||||
utfstring memo;
|
||||
/// 頂点インデックス数
|
||||
int index_count;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// リンク
|
||||
class PmxIkLink
|
||||
{
|
||||
public:
|
||||
PmxIkLink()
|
||||
: link_target(0)
|
||||
, angle_lock(0)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
max_radian[i] = 0.0f;
|
||||
min_radian[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/// リンクボーンインデックス
|
||||
int link_target;
|
||||
/// 角度制限
|
||||
uint8_t angle_lock;
|
||||
/// 最大制限角度
|
||||
float max_radian[3];
|
||||
/// 最小制限角度
|
||||
float min_radian[3];
|
||||
void Read(std::istream *stream, PmxSetting *settingn);
|
||||
};
|
||||
|
||||
/// ボーン
|
||||
class PmxBone
|
||||
{
|
||||
public:
|
||||
PmxBone()
|
||||
: parent_index(0)
|
||||
, level(0)
|
||||
, bone_flag(0)
|
||||
, target_index(0)
|
||||
, grant_parent_index(0)
|
||||
, grant_weight(0.0f)
|
||||
, key(0)
|
||||
, ik_target_bone_index(0)
|
||||
, ik_loop(0)
|
||||
, ik_loop_angle_limit(0.0f)
|
||||
, ik_link_count(0)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
position[i] = 0.0f;
|
||||
offset[i] = 0.0f;
|
||||
lock_axis_orientation[i] = 0.0f;
|
||||
local_axis_x_orientation[i] = 0.0f;
|
||||
local_axis_y_orientation[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/// ボーン名
|
||||
utfstring bone_name;
|
||||
/// ボーン英名
|
||||
utfstring bone_english_name;
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 親ボーンインデックス
|
||||
int parent_index;
|
||||
/// 階層
|
||||
int level;
|
||||
/// ボーンフラグ
|
||||
uint16_t bone_flag;
|
||||
/// 座標オフセット(has Target)
|
||||
float offset[3];
|
||||
/// 接続先ボーンインデックス(not has Target)
|
||||
int target_index;
|
||||
/// 付与親ボーンインデックス
|
||||
int grant_parent_index;
|
||||
/// 付与率
|
||||
float grant_weight;
|
||||
/// 固定軸の方向
|
||||
float lock_axis_orientation[3];
|
||||
/// ローカル軸のX軸方向
|
||||
float local_axis_x_orientation[3];
|
||||
/// ローカル軸のY軸方向
|
||||
float local_axis_y_orientation[3];
|
||||
/// 外部親変形のkey値
|
||||
int key;
|
||||
/// IKターゲットボーン
|
||||
int ik_target_bone_index;
|
||||
/// IKループ回数
|
||||
int ik_loop;
|
||||
/// IKループ計算時の角度制限(ラジアン)
|
||||
float ik_loop_angle_limit;
|
||||
/// IKリンク数
|
||||
int ik_link_count;
|
||||
/// IKリンク
|
||||
std::unique_ptr<PmxIkLink []> ik_links;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
enum class MorphType : uint8_t
|
||||
{
|
||||
Group = 0,
|
||||
Vertex = 1,
|
||||
Bone = 2,
|
||||
UV = 3,
|
||||
AdditionalUV1 = 4,
|
||||
AdditionalUV2 = 5,
|
||||
AdditionalUV3 = 6,
|
||||
AdditionalUV4 = 7,
|
||||
Matrial = 8,
|
||||
Flip = 9,
|
||||
Implus = 10,
|
||||
};
|
||||
|
||||
enum class MorphCategory : uint8_t
|
||||
{
|
||||
ReservedCategory = 0,
|
||||
Eyebrow = 1,
|
||||
Eye = 2,
|
||||
Mouth = 3,
|
||||
Other = 4,
|
||||
};
|
||||
|
||||
class PmxMorphOffset
|
||||
{
|
||||
public:
|
||||
void virtual Read(std::istream *stream, PmxSetting *setting) = 0;
|
||||
};
|
||||
|
||||
class PmxMorphVertexOffset : public PmxMorphOffset
|
||||
{
|
||||
public:
|
||||
PmxMorphVertexOffset()
|
||||
: vertex_index(0)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
position_offset[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
int vertex_index;
|
||||
float position_offset[3];
|
||||
void Read(std::istream *stream, PmxSetting *setting) override;
|
||||
};
|
||||
|
||||
class PmxMorphUVOffset : public PmxMorphOffset
|
||||
{
|
||||
public:
|
||||
PmxMorphUVOffset()
|
||||
: vertex_index(0)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
uv_offset[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
int vertex_index;
|
||||
float uv_offset[4];
|
||||
void Read(std::istream *stream, PmxSetting *setting) override;
|
||||
};
|
||||
|
||||
class PmxMorphBoneOffset : public PmxMorphOffset
|
||||
{
|
||||
public:
|
||||
PmxMorphBoneOffset()
|
||||
: bone_index(0)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
translation[i] = 0.0f;
|
||||
}
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
rotation[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
int bone_index;
|
||||
float translation[3];
|
||||
float rotation[4];
|
||||
void Read(std::istream *stream, PmxSetting *setting) override;
|
||||
};
|
||||
|
||||
class PmxMorphMaterialOffset : public PmxMorphOffset
|
||||
{
|
||||
public:
|
||||
PmxMorphMaterialOffset()
|
||||
: specularity(0.0f)
|
||||
, edge_size(0.0f)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
specular[i] = 0.0f;
|
||||
ambient[i] = 0.0f;
|
||||
}
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
diffuse[i] = 0.0f;
|
||||
edge_color[i] = 0.0f;
|
||||
texture_argb[i] = 0.0f;
|
||||
sphere_texture_argb[i] = 0.0f;
|
||||
toon_texture_argb[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
int material_index;
|
||||
uint8_t offset_operation;
|
||||
float diffuse[4];
|
||||
float specular[3];
|
||||
float specularity;
|
||||
float ambient[3];
|
||||
float edge_color[4];
|
||||
float edge_size;
|
||||
float texture_argb[4];
|
||||
float sphere_texture_argb[4];
|
||||
float toon_texture_argb[4];
|
||||
void Read(std::istream *stream, PmxSetting *setting) override;
|
||||
};
|
||||
|
||||
class PmxMorphGroupOffset : public PmxMorphOffset
|
||||
{
|
||||
public:
|
||||
PmxMorphGroupOffset()
|
||||
: morph_index(0)
|
||||
, morph_weight(0.0f)
|
||||
{}
|
||||
int morph_index;
|
||||
float morph_weight;
|
||||
void Read(std::istream *stream, PmxSetting *setting) override;
|
||||
};
|
||||
|
||||
class PmxMorphFlipOffset : public PmxMorphOffset
|
||||
{
|
||||
public:
|
||||
PmxMorphFlipOffset()
|
||||
: morph_index(0)
|
||||
, morph_value(0.0f)
|
||||
{}
|
||||
int morph_index;
|
||||
float morph_value;
|
||||
void Read(std::istream *stream, PmxSetting *setting) override;
|
||||
};
|
||||
|
||||
class PmxMorphImplusOffset : public PmxMorphOffset
|
||||
{
|
||||
public:
|
||||
PmxMorphImplusOffset()
|
||||
: rigid_body_index(0)
|
||||
, is_local(0)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
velocity[i] = 0.0f;
|
||||
angular_torque[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
int rigid_body_index;
|
||||
uint8_t is_local;
|
||||
float velocity[3];
|
||||
float angular_torque[3];
|
||||
void Read(std::istream *stream, PmxSetting *setting) override;
|
||||
};
|
||||
|
||||
/// モーフ
|
||||
class PmxMorph
|
||||
{
|
||||
public:
|
||||
PmxMorph()
|
||||
: offset_count(0)
|
||||
{
|
||||
}
|
||||
/// モーフ名
|
||||
utfstring morph_name;
|
||||
/// モーフ英名
|
||||
utfstring morph_english_name;
|
||||
/// カテゴリ
|
||||
MorphCategory category;
|
||||
/// モーフタイプ
|
||||
MorphType morph_type;
|
||||
/// オフセット数
|
||||
int offset_count;
|
||||
/// 頂点モーフ配列
|
||||
std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets;
|
||||
/// UVモーフ配列
|
||||
std::unique_ptr<PmxMorphUVOffset []> uv_offsets;
|
||||
/// ボーンモーフ配列
|
||||
std::unique_ptr<PmxMorphBoneOffset []> bone_offsets;
|
||||
/// マテリアルモーフ配列
|
||||
std::unique_ptr<PmxMorphMaterialOffset []> material_offsets;
|
||||
/// グループモーフ配列
|
||||
std::unique_ptr<PmxMorphGroupOffset []> group_offsets;
|
||||
/// フリップモーフ配列
|
||||
std::unique_ptr<PmxMorphFlipOffset []> flip_offsets;
|
||||
/// インパルスモーフ配列
|
||||
std::unique_ptr<PmxMorphImplusOffset []> implus_offsets;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// 枠内要素
|
||||
class PmxFrameElement
|
||||
{
|
||||
public:
|
||||
PmxFrameElement()
|
||||
: element_target(0)
|
||||
, index(0)
|
||||
{
|
||||
}
|
||||
/// 要素対象
|
||||
uint8_t element_target;
|
||||
/// 要素対象インデックス
|
||||
int index;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// 表示枠
|
||||
class PmxFrame
|
||||
{
|
||||
public:
|
||||
PmxFrame()
|
||||
: frame_flag(0)
|
||||
, element_count(0)
|
||||
{
|
||||
}
|
||||
/// 枠名
|
||||
utfstring frame_name;
|
||||
/// 枠英名
|
||||
utfstring frame_english_name;
|
||||
/// 特殊枠フラグ
|
||||
uint8_t frame_flag;
|
||||
/// 枠内要素数
|
||||
int element_count;
|
||||
/// 枠内要素配列
|
||||
std::unique_ptr<PmxFrameElement []> elements;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
class PmxRigidBody
|
||||
{
|
||||
public:
|
||||
PmxRigidBody()
|
||||
: target_bone(0)
|
||||
, group(0)
|
||||
, mask(0)
|
||||
, shape(0)
|
||||
, mass(0.0f)
|
||||
, move_attenuation(0.0f)
|
||||
, rotation_attenuation(0.0f)
|
||||
, repulsion(0.0f)
|
||||
, friction(0.0f)
|
||||
, physics_calc_type(0)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
size[i] = 0.0f;
|
||||
position[i] = 0.0f;
|
||||
orientation[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
/// 剛体名
|
||||
utfstring girid_body_name;
|
||||
/// 剛体英名
|
||||
utfstring girid_body_english_name;
|
||||
/// 関連ボーンインデックス
|
||||
int target_bone;
|
||||
/// グループ
|
||||
uint8_t group;
|
||||
/// マスク
|
||||
uint16_t mask;
|
||||
/// 形状
|
||||
uint8_t shape;
|
||||
float size[3];
|
||||
float position[3];
|
||||
float orientation[3];
|
||||
float mass;
|
||||
float move_attenuation;
|
||||
float rotation_attenuation;
|
||||
float repulsion;
|
||||
float friction;
|
||||
uint8_t physics_calc_type;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
enum class PmxJointType : uint8_t
|
||||
{
|
||||
Generic6DofSpring = 0,
|
||||
Generic6Dof = 1,
|
||||
Point2Point = 2,
|
||||
ConeTwist = 3,
|
||||
Slider = 5,
|
||||
Hinge = 6
|
||||
};
|
||||
|
||||
class PmxJointParam
|
||||
{
|
||||
public:
|
||||
PmxJointParam()
|
||||
: rigid_body1(0)
|
||||
, rigid_body2(0)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
position[i] = 0.0f;
|
||||
orientaiton[i] = 0.0f;
|
||||
move_limitation_min[i] = 0.0f;
|
||||
move_limitation_max[i] = 0.0f;
|
||||
rotation_limitation_min[i] = 0.0f;
|
||||
rotation_limitation_max[i] = 0.0f;
|
||||
spring_move_coefficient[i] = 0.0f;
|
||||
spring_rotation_coefficient[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
int rigid_body1;
|
||||
int rigid_body2;
|
||||
float position[3];
|
||||
float orientaiton[3];
|
||||
float move_limitation_min[3];
|
||||
float move_limitation_max[3];
|
||||
float rotation_limitation_min[3];
|
||||
float rotation_limitation_max[3];
|
||||
float spring_move_coefficient[3];
|
||||
float spring_rotation_coefficient[3];
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
class PmxJoint
|
||||
{
|
||||
public:
|
||||
utfstring joint_name;
|
||||
utfstring joint_english_name;
|
||||
PmxJointType joint_type;
|
||||
PmxJointParam param;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
enum PmxSoftBodyFlag : uint8_t
|
||||
{
|
||||
BLink = 0x01,
|
||||
Cluster = 0x02,
|
||||
Link = 0x04
|
||||
};
|
||||
|
||||
class PmxAncherRigidBody
|
||||
{
|
||||
public:
|
||||
PmxAncherRigidBody()
|
||||
: related_rigid_body(0)
|
||||
, related_vertex(0)
|
||||
, is_near(false)
|
||||
{}
|
||||
int related_rigid_body;
|
||||
int related_vertex;
|
||||
bool is_near;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
class PmxSoftBody
|
||||
{
|
||||
public:
|
||||
PmxSoftBody()
|
||||
: shape(0)
|
||||
, target_material(0)
|
||||
, group(0)
|
||||
, mask(0)
|
||||
, blink_distance(0)
|
||||
, cluster_count(0)
|
||||
, mass(0.0)
|
||||
, collisioni_margin(0.0)
|
||||
, aero_model(0)
|
||||
, VCF(0.0f)
|
||||
, DP(0.0f)
|
||||
, DG(0.0f)
|
||||
, LF(0.0f)
|
||||
, PR(0.0f)
|
||||
, VC(0.0f)
|
||||
, DF(0.0f)
|
||||
, MT(0.0f)
|
||||
, CHR(0.0f)
|
||||
, KHR(0.0f)
|
||||
, SHR(0.0f)
|
||||
, AHR(0.0f)
|
||||
, SRHR_CL(0.0f)
|
||||
, SKHR_CL(0.0f)
|
||||
, SSHR_CL(0.0f)
|
||||
, SR_SPLT_CL(0.0f)
|
||||
, SK_SPLT_CL(0.0f)
|
||||
, SS_SPLT_CL(0.0f)
|
||||
, V_IT(0)
|
||||
, P_IT(0)
|
||||
, D_IT(0)
|
||||
, C_IT(0)
|
||||
, LST(0.0f)
|
||||
, AST(0.0f)
|
||||
, VST(0.0f)
|
||||
, anchor_count(0)
|
||||
, pin_vertex_count(0)
|
||||
{}
|
||||
utfstring soft_body_name;
|
||||
utfstring soft_body_english_name;
|
||||
uint8_t shape;
|
||||
int target_material;
|
||||
uint8_t group;
|
||||
uint16_t mask;
|
||||
PmxSoftBodyFlag flag;
|
||||
int blink_distance;
|
||||
int cluster_count;
|
||||
float mass;
|
||||
float collisioni_margin;
|
||||
int aero_model;
|
||||
float VCF;
|
||||
float DP;
|
||||
float DG;
|
||||
float LF;
|
||||
float PR;
|
||||
float VC;
|
||||
float DF;
|
||||
float MT;
|
||||
float CHR;
|
||||
float KHR;
|
||||
float SHR;
|
||||
float AHR;
|
||||
float SRHR_CL;
|
||||
float SKHR_CL;
|
||||
float SSHR_CL;
|
||||
float SR_SPLT_CL;
|
||||
float SK_SPLT_CL;
|
||||
float SS_SPLT_CL;
|
||||
int V_IT;
|
||||
int P_IT;
|
||||
int D_IT;
|
||||
int C_IT;
|
||||
float LST;
|
||||
float AST;
|
||||
float VST;
|
||||
int anchor_count;
|
||||
std::unique_ptr<PmxAncherRigidBody []> anchers;
|
||||
int pin_vertex_count;
|
||||
std::unique_ptr<int []> pin_vertices;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// PMXモデル
|
||||
class PmxModel
|
||||
{
|
||||
public:
|
||||
PmxModel()
|
||||
: version(0.0f)
|
||||
, vertex_count(0)
|
||||
, index_count(0)
|
||||
, texture_count(0)
|
||||
, material_count(0)
|
||||
, bone_count(0)
|
||||
, morph_count(0)
|
||||
, frame_count(0)
|
||||
, rigid_body_count(0)
|
||||
, joint_count(0)
|
||||
, soft_body_count(0)
|
||||
{}
|
||||
|
||||
/// バージョン
|
||||
float version;
|
||||
/// 設定
|
||||
PmxSetting setting;
|
||||
/// モデル名
|
||||
utfstring model_name;
|
||||
/// モデル英名
|
||||
utfstring model_english_name;
|
||||
/// コメント
|
||||
utfstring model_comment;
|
||||
/// 英語コメント
|
||||
utfstring model_english_comment;
|
||||
/// 頂点数
|
||||
int vertex_count;
|
||||
/// 頂点配列
|
||||
std::unique_ptr<PmxVertex []> vertices;
|
||||
/// インデックス数
|
||||
int index_count;
|
||||
/// インデックス配列
|
||||
std::unique_ptr<int []> indices;
|
||||
/// テクスチャ数
|
||||
int texture_count;
|
||||
/// テクスチャ配列
|
||||
std::unique_ptr< utfstring []> textures;
|
||||
/// マテリアル数
|
||||
int material_count;
|
||||
/// マテリアル
|
||||
std::unique_ptr<PmxMaterial []> materials;
|
||||
/// ボーン数
|
||||
int bone_count;
|
||||
/// ボーン配列
|
||||
std::unique_ptr<PmxBone []> bones;
|
||||
/// モーフ数
|
||||
int morph_count;
|
||||
/// モーフ配列
|
||||
std::unique_ptr<PmxMorph []> morphs;
|
||||
/// 表示枠数
|
||||
int frame_count;
|
||||
/// 表示枠配列
|
||||
std::unique_ptr<PmxFrame [] > frames;
|
||||
/// 剛体数
|
||||
int rigid_body_count;
|
||||
/// 剛体配列
|
||||
std::unique_ptr<PmxRigidBody []> rigid_bodies;
|
||||
/// ジョイント数
|
||||
int joint_count;
|
||||
/// ジョイント配列
|
||||
std::unique_ptr<PmxJoint []> joints;
|
||||
/// ソフトボディ数
|
||||
int soft_body_count;
|
||||
/// ソフトボディ配列
|
||||
std::unique_ptr<PmxSoftBody []> soft_bodies;
|
||||
/// モデル初期化
|
||||
void Init();
|
||||
/// モデル読み込み
|
||||
void Read(std::istream *stream);
|
||||
///// ファイルからモデルの読み込み
|
||||
//static std::unique_ptr<PmxModel> ReadFromFile(const char *filename);
|
||||
///// 入力ストリームからモデルの読み込み
|
||||
//static std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,367 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <ostream>
|
||||
#include "MMDCpp14.h"
|
||||
|
||||
namespace vmd
|
||||
{
|
||||
/// ボーンフレーム
|
||||
class VmdBoneFrame
|
||||
{
|
||||
public:
|
||||
/// ボーン名
|
||||
std::string name;
|
||||
/// フレーム番号
|
||||
int frame;
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[4];
|
||||
/// 補間曲線
|
||||
char interpolation[4][4][4];
|
||||
|
||||
void Read(std::istream* stream)
|
||||
{
|
||||
char buffer[15];
|
||||
stream->read((char*) buffer, sizeof(char)*15);
|
||||
name = std::string(buffer);
|
||||
stream->read((char*) &frame, sizeof(int));
|
||||
stream->read((char*) position, sizeof(float)*3);
|
||||
stream->read((char*) orientation, sizeof(float)*4);
|
||||
stream->read((char*) interpolation, sizeof(char) * 4 * 4 * 4);
|
||||
}
|
||||
|
||||
void Write(std::ostream* stream)
|
||||
{
|
||||
stream->write((char*)name.c_str(), sizeof(char) * 15);
|
||||
stream->write((char*)&frame, sizeof(int));
|
||||
stream->write((char*)position, sizeof(float) * 3);
|
||||
stream->write((char*)orientation, sizeof(float) * 4);
|
||||
stream->write((char*)interpolation, sizeof(char) * 4 * 4 * 4);
|
||||
}
|
||||
};
|
||||
|
||||
/// 表情フレーム
|
||||
class VmdFaceFrame
|
||||
{
|
||||
public:
|
||||
/// 表情名
|
||||
std::string face_name;
|
||||
/// 表情の重み
|
||||
float weight;
|
||||
/// フレーム番号
|
||||
uint32_t frame;
|
||||
|
||||
void Read(std::istream* stream)
|
||||
{
|
||||
char buffer[15];
|
||||
stream->read((char*) &buffer, sizeof(char) * 15);
|
||||
face_name = std::string(buffer);
|
||||
stream->read((char*) &frame, sizeof(int));
|
||||
stream->read((char*) &weight, sizeof(float));
|
||||
}
|
||||
|
||||
void Write(std::ostream* stream)
|
||||
{
|
||||
stream->write((char*)face_name.c_str(), sizeof(char) * 15);
|
||||
stream->write((char*)&frame, sizeof(int));
|
||||
stream->write((char*)&weight, sizeof(float));
|
||||
}
|
||||
};
|
||||
|
||||
/// カメラフレーム
|
||||
class VmdCameraFrame
|
||||
{
|
||||
public:
|
||||
/// フレーム番号
|
||||
int frame;
|
||||
/// 距離
|
||||
float distance;
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[3];
|
||||
/// 補間曲線
|
||||
char interpolation[6][4];
|
||||
/// 視野角
|
||||
float angle;
|
||||
/// 不明データ
|
||||
char unknown[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
stream->read((char*) &frame, sizeof(int));
|
||||
stream->read((char*) &distance, sizeof(float));
|
||||
stream->read((char*) position, sizeof(float) * 3);
|
||||
stream->read((char*) orientation, sizeof(float) * 3);
|
||||
stream->read((char*) interpolation, sizeof(char) * 24);
|
||||
stream->read((char*) &angle, sizeof(float));
|
||||
stream->read((char*) unknown, sizeof(char) * 3);
|
||||
}
|
||||
|
||||
void Write(std::ostream *stream)
|
||||
{
|
||||
stream->write((char*)&frame, sizeof(int));
|
||||
stream->write((char*)&distance, sizeof(float));
|
||||
stream->write((char*)position, sizeof(float) * 3);
|
||||
stream->write((char*)orientation, sizeof(float) * 3);
|
||||
stream->write((char*)interpolation, sizeof(char) * 24);
|
||||
stream->write((char*)&angle, sizeof(float));
|
||||
stream->write((char*)unknown, sizeof(char) * 3);
|
||||
}
|
||||
};
|
||||
|
||||
/// ライトフレーム
|
||||
class VmdLightFrame
|
||||
{
|
||||
public:
|
||||
/// フレーム番号
|
||||
int frame;
|
||||
/// 色
|
||||
float color[3];
|
||||
/// 位置
|
||||
float position[3];
|
||||
|
||||
void Read(std::istream* stream)
|
||||
{
|
||||
stream->read((char*) &frame, sizeof(int));
|
||||
stream->read((char*) color, sizeof(float) * 3);
|
||||
stream->read((char*) position, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
void Write(std::ostream* stream)
|
||||
{
|
||||
stream->write((char*)&frame, sizeof(int));
|
||||
stream->write((char*)color, sizeof(float) * 3);
|
||||
stream->write((char*)position, sizeof(float) * 3);
|
||||
}
|
||||
};
|
||||
|
||||
/// IKの有効無効
|
||||
class VmdIkEnable
|
||||
{
|
||||
public:
|
||||
std::string ik_name;
|
||||
bool enable;
|
||||
};
|
||||
|
||||
/// IKフレーム
|
||||
class VmdIkFrame
|
||||
{
|
||||
public:
|
||||
int frame;
|
||||
bool display;
|
||||
std::vector<VmdIkEnable> ik_enable;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read((char*) &frame, sizeof(int));
|
||||
stream->read((char*) &display, sizeof(uint8_t));
|
||||
int ik_count;
|
||||
stream->read((char*) &ik_count, sizeof(int));
|
||||
ik_enable.resize(ik_count);
|
||||
for (int i = 0; i < ik_count; i++)
|
||||
{
|
||||
stream->read(buffer, 20);
|
||||
ik_enable[i].ik_name = std::string(buffer);
|
||||
stream->read((char*) &ik_enable[i].enable, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
void Write(std::ostream *stream)
|
||||
{
|
||||
stream->write((char*)&frame, sizeof(int));
|
||||
stream->write((char*)&display, sizeof(uint8_t));
|
||||
int ik_count = static_cast<int>(ik_enable.size());
|
||||
stream->write((char*)&ik_count, sizeof(int));
|
||||
for (int i = 0; i < ik_count; i++)
|
||||
{
|
||||
const VmdIkEnable& ik_enable = this->ik_enable.at(i);
|
||||
stream->write(ik_enable.ik_name.c_str(), 20);
|
||||
stream->write((char*)&ik_enable.enable, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// VMDモーション
|
||||
class VmdMotion
|
||||
{
|
||||
public:
|
||||
/// モデル名
|
||||
std::string model_name;
|
||||
/// バージョン
|
||||
int version;
|
||||
/// ボーンフレーム
|
||||
std::vector<VmdBoneFrame> bone_frames;
|
||||
/// 表情フレーム
|
||||
std::vector<VmdFaceFrame> face_frames;
|
||||
/// カメラフレーム
|
||||
std::vector<VmdCameraFrame> camera_frames;
|
||||
/// ライトフレーム
|
||||
std::vector<VmdLightFrame> light_frames;
|
||||
/// IKフレーム
|
||||
std::vector<VmdIkFrame> ik_frames;
|
||||
|
||||
static std::unique_ptr<VmdMotion> LoadFromFile(char const *filename)
|
||||
{
|
||||
std::ifstream stream(filename, std::ios::binary);
|
||||
auto result = LoadFromStream(&stream);
|
||||
stream.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::unique_ptr<VmdMotion> LoadFromStream(std::ifstream *stream)
|
||||
{
|
||||
|
||||
char buffer[30];
|
||||
auto result = std::make_unique<VmdMotion>();
|
||||
|
||||
// magic and version
|
||||
stream->read((char*) buffer, 30);
|
||||
if (strncmp(buffer, "Vocaloid Motion Data", 20))
|
||||
{
|
||||
std::cerr << "invalid vmd file." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
result->version = std::atoi(buffer + 20);
|
||||
|
||||
// name
|
||||
stream->read(buffer, 20);
|
||||
result->model_name = std::string(buffer);
|
||||
|
||||
// bone frames
|
||||
int bone_frame_num;
|
||||
stream->read((char*) &bone_frame_num, sizeof(int));
|
||||
result->bone_frames.resize(bone_frame_num);
|
||||
for (int i = 0; i < bone_frame_num; i++)
|
||||
{
|
||||
result->bone_frames[i].Read(stream);
|
||||
}
|
||||
|
||||
// face frames
|
||||
int face_frame_num;
|
||||
stream->read((char*) &face_frame_num, sizeof(int));
|
||||
result->face_frames.resize(face_frame_num);
|
||||
for (int i = 0; i < face_frame_num; i++)
|
||||
{
|
||||
result->face_frames[i].Read(stream);
|
||||
}
|
||||
|
||||
// camera frames
|
||||
int camera_frame_num;
|
||||
stream->read((char*) &camera_frame_num, sizeof(int));
|
||||
result->camera_frames.resize(camera_frame_num);
|
||||
for (int i = 0; i < camera_frame_num; i++)
|
||||
{
|
||||
result->camera_frames[i].Read(stream);
|
||||
}
|
||||
|
||||
// light frames
|
||||
int light_frame_num;
|
||||
stream->read((char*) &light_frame_num, sizeof(int));
|
||||
result->light_frames.resize(light_frame_num);
|
||||
for (int i = 0; i < light_frame_num; i++)
|
||||
{
|
||||
result->light_frames[i].Read(stream);
|
||||
}
|
||||
|
||||
// unknown2
|
||||
stream->read(buffer, 4);
|
||||
|
||||
// ik frames
|
||||
if (stream->peek() != std::ios::traits_type::eof())
|
||||
{
|
||||
int ik_num;
|
||||
stream->read((char*) &ik_num, sizeof(int));
|
||||
result->ik_frames.resize(ik_num);
|
||||
for (int i = 0; i < ik_num; i++)
|
||||
{
|
||||
result->ik_frames[i].Read(stream);
|
||||
}
|
||||
}
|
||||
|
||||
if (stream->peek() != std::ios::traits_type::eof())
|
||||
{
|
||||
std::cerr << "vmd stream has unknown data." << std::endl;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SaveToFile(const std::u16string& filename)
|
||||
{
|
||||
// TODO: How to adapt u16string to string?
|
||||
/*
|
||||
std::ofstream stream(filename.c_str(), std::ios::binary);
|
||||
auto result = SaveToStream(&stream);
|
||||
stream.close();
|
||||
return result;
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SaveToStream(std::ofstream *stream)
|
||||
{
|
||||
std::string magic = "Vocaloid Motion Data 0002\0";
|
||||
magic.resize(30);
|
||||
|
||||
// magic and version
|
||||
stream->write(magic.c_str(), 30);
|
||||
|
||||
// name
|
||||
stream->write(model_name.c_str(), 20);
|
||||
|
||||
// bone frames
|
||||
const int bone_frame_num = static_cast<int>(bone_frames.size());
|
||||
stream->write(reinterpret_cast<const char*>(&bone_frame_num), sizeof(int));
|
||||
for (int i = 0; i < bone_frame_num; i++)
|
||||
{
|
||||
bone_frames[i].Write(stream);
|
||||
}
|
||||
|
||||
// face frames
|
||||
const int face_frame_num = static_cast<int>(face_frames.size());
|
||||
stream->write(reinterpret_cast<const char*>(&face_frame_num), sizeof(int));
|
||||
for (int i = 0; i < face_frame_num; i++)
|
||||
{
|
||||
face_frames[i].Write(stream);
|
||||
}
|
||||
|
||||
// camera frames
|
||||
const int camera_frame_num = static_cast<int>(camera_frames.size());
|
||||
stream->write(reinterpret_cast<const char*>(&camera_frame_num), sizeof(int));
|
||||
for (int i = 0; i < camera_frame_num; i++)
|
||||
{
|
||||
camera_frames[i].Write(stream);
|
||||
}
|
||||
|
||||
// light frames
|
||||
const int light_frame_num = static_cast<int>(light_frames.size());
|
||||
stream->write(reinterpret_cast<const char*>(&light_frame_num), sizeof(int));
|
||||
for (int i = 0; i < light_frame_num; i++)
|
||||
{
|
||||
light_frames[i].Write(stream);
|
||||
}
|
||||
|
||||
// self shadow datas
|
||||
const int self_shadow_num = 0;
|
||||
stream->write(reinterpret_cast<const char*>(&self_shadow_num), sizeof(int));
|
||||
|
||||
// ik frames
|
||||
const int ik_num = static_cast<int>(ik_frames.size());
|
||||
stream->write(reinterpret_cast<const char*>(&ik_num), sizeof(int));
|
||||
for (int i = 0; i < ik_num; i++)
|
||||
{
|
||||
ik_frames[i].Write(stream);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -105,6 +105,7 @@ SET( TEST_SRCS
|
|||
unit/utObjImportExport.cpp
|
||||
unit/utPretransformVertices.cpp
|
||||
unit/utPLYImportExport.cpp
|
||||
unit/utPMXImporter.cpp
|
||||
unit/utRemoveComments.cpp
|
||||
unit/utRemoveComponent.cpp
|
||||
unit/utRemoveRedundantMaterials.cpp
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* 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.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
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
|
||||
OWNER 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.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "UnitTestPCH.h"
|
||||
#include "SceneDiffer.h"
|
||||
#include "AbstractImportExportBase.h"
|
||||
#include "MMDImporter.h"
|
||||
|
||||
#include <assimp/Importer.hpp>
|
||||
|
||||
using namespace ::Assimp;
|
||||
|
||||
class utPMXImporter : public AbstractImportExportBase {
|
||||
public:
|
||||
virtual bool importerTest() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/../models-nonbsd/MMD/kawakaze.pmx", 0 );
|
||||
return nullptr != scene;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F( utPMXImporter, importTest ) {
|
||||
EXPECT_TRUE( importerTest() );
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
project(assimp_qt_viewer)
|
||||
set(PROJECT_VERSION "")
|
||||
project(assimp_qt_viewer)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
|
|
Loading…
Reference in New Issue