├── .BlendShapeBuilder
├── Assets
│ ├── BlendShapeBuilderPackaging.cs
│ ├── BlendShapeBuilderPackaging.cs.meta
│ ├── UTJ.meta
│ └── UTJ
│ │ ├── BlendShapeBuilder
│ │ ├── BlendShapeBuilder.meta
│ │ ├── VertexTweaker
│ │ └── VertexTweaker.meta
├── Packages
│ └── manifest.json
├── Plugin
│ ├── CMakeLists.txt
│ ├── External
│ │ ├── 7z
│ │ │ └── 7za.exe
│ │ └── make_archive.bat
│ ├── MeshUtils.vcxproj
│ ├── MeshUtils.vcxproj.filters
│ ├── MeshUtils
│ │ ├── CMakeLists.txt
│ │ ├── MeshUtils.cpp
│ │ ├── MeshUtils.h
│ │ ├── MeshUtilsCore.ispc
│ │ ├── MeshUtils_impl.h
│ │ ├── ampmath.h
│ │ ├── ampmath_impl.h
│ │ ├── ispcmath.h
│ │ ├── mikktspace.c
│ │ ├── mikktspace.h
│ │ ├── muAllocator.cpp
│ │ ├── muAllocator.h
│ │ ├── muConcurrency.h
│ │ ├── muConfig.h
│ │ ├── muIntrusiveArray.h
│ │ ├── muIterator.h
│ │ ├── muMath.cpp
│ │ ├── muMath.h
│ │ ├── muMeshRefiner.cpp
│ │ ├── muMeshRefiner.h
│ │ ├── muMisc.cpp
│ │ ├── muMisc.h
│ │ ├── muRawVector.h
│ │ ├── muSIMD.cpp
│ │ ├── muSIMD.h
│ │ ├── muSIMDConfig.h
│ │ ├── muTLS.h
│ │ ├── muVertex.cpp
│ │ ├── muVertex.h
│ │ ├── pch.cpp
│ │ └── pch.h
│ ├── NatvisFile.natvis
│ ├── VertexTweaker
│ │ ├── CMakeLists.txt
│ │ ├── VertexTweaker.cpp
│ │ ├── VertexTweaker.h
│ │ ├── pch.cpp
│ │ └── pch.h
│ ├── VertexTweakerCore.sln
│ ├── VertexTweakerCore.vcxproj
│ ├── VertexTweakerCore.vcxproj.filters
│ ├── build.bat
│ ├── cmake
│ │ ├── AddPlugin.cmake
│ │ ├── FindOpenEXR.cmake
│ │ ├── FindTBB.cmake
│ │ └── ISPC.cmake
│ ├── setup.bat
│ ├── setup.vcxproj
│ └── toolchan.bat
└── ProjectSettings
│ ├── AudioManager.asset
│ ├── ClusterInputManager.asset
│ ├── DynamicsManager.asset
│ ├── EditorBuildSettings.asset
│ ├── EditorSettings.asset
│ ├── GraphicsSettings.asset
│ ├── InputManager.asset
│ ├── NavMeshAreas.asset
│ ├── NetworkManager.asset
│ ├── Physics2DSettings.asset
│ ├── PresetManager.asset
│ ├── ProjectSettings.asset
│ ├── ProjectVersion.txt
│ ├── QualitySettings.asset
│ ├── TagManager.asset
│ ├── TimeManager.asset
│ ├── UnityConnectSettings.asset
│ ├── VFXManager.asset
│ └── XRSettings.asset
├── .gitattributes
├── .gitignore
├── Assets
├── BlendShapeBuilder.meta
├── BlendShapeBuilder
│ ├── Editor.meta
│ ├── Editor
│ │ ├── BlendShapeBuilderEditor.cs
│ │ ├── BlendShapeBuilderEditor.cs.meta
│ │ ├── BlendShapeBuilderWindow.cs
│ │ ├── BlendShapeBuilderWindow.cs.meta
│ │ ├── BlendShapeInspectorWindow.cs
│ │ ├── BlendShapeInspectorWindow.cs.meta
│ │ ├── UTJ.BlendShapeBuilderEditor.asmdef
│ │ └── UTJ.BlendShapeBuilderEditor.asmdef.meta
│ ├── Runtime.meta
│ └── Runtime
│ │ ├── Scripts.meta
│ │ ├── Scripts
│ │ ├── BlendShapeBuilder.cs
│ │ ├── BlendShapeBuilder.cs.meta
│ │ ├── BlendShapeBuilderData.cs
│ │ └── BlendShapeBuilderData.cs.meta
│ │ ├── UTJ.BlendShapeBuilder.asmdef
│ │ └── UTJ.BlendShapeBuilder.asmdef.meta
├── VertexTweaker.meta
└── VertexTweaker
│ ├── Editor.meta
│ ├── Editor
│ ├── ObjExporter.cs
│ ├── ObjExporter.cs.meta
│ ├── UTJ.VertexTweakerEditor.asmdef
│ ├── UTJ.VertexTweakerEditor.asmdef.meta
│ ├── VertexTweakerEditor.cs
│ ├── VertexTweakerEditor.cs.meta
│ ├── VertexTweakerWindow.cs
│ └── VertexTweakerWindow.cs.meta
│ ├── Runtime.meta
│ └── Runtime
│ ├── Data.meta
│ ├── Data
│ ├── DefaultSettings.asset
│ └── DefaultSettings.asset.meta
│ ├── Plugins.meta
│ ├── Plugins
│ ├── x86_64.meta
│ └── x86_64
│ │ ├── VertexTweakerCore.bundle.meta
│ │ ├── VertexTweakerCore.bundle
│ │ ├── Contents.meta
│ │ └── Contents
│ │ │ ├── Info.plist
│ │ │ ├── Info.plist.meta
│ │ │ ├── MacOS.meta
│ │ │ └── MacOS
│ │ │ ├── VertexTweakerCore
│ │ │ └── VertexTweakerCore.meta
│ │ ├── VertexTweakerCore.dll
│ │ ├── VertexTweakerCore.dll.meta
│ │ ├── libVertexTweakerCore.so
│ │ └── libVertexTweakerCore.so.meta
│ ├── Scripts.meta
│ ├── Scripts
│ ├── PinnedArray.cs
│ ├── PinnedArray.cs.meta
│ ├── Utils.cs
│ ├── Utils.cs.meta
│ ├── VertexHandles.cs
│ ├── VertexHandles.cs.meta
│ ├── VertexTweaker.cs
│ ├── VertexTweaker.cs.meta
│ ├── VertexTweakerSettings.cs
│ ├── VertexTweakerSettings.cs.meta
│ ├── VertexTweaker_impl.cs
│ └── VertexTweaker_impl.cs.meta
│ ├── Shaders.meta
│ ├── Shaders
│ ├── BrushShape.shader
│ ├── BrushShape.shader.meta
│ ├── Overlay.shader
│ ├── Overlay.shader.meta
│ ├── Visualizer.shader
│ └── Visualizer.shader.meta
│ ├── UTJ.VertexTweaker.asmdef
│ └── UTJ.VertexTweaker.asmdef.meta
├── LICENSE.txt
├── LICENSE.txt.meta
├── Readme.md
├── Readme.md.meta
├── Readme_EN.md
├── Readme_EN.md.meta
├── package.json
└── package.json.meta
/.BlendShapeBuilder/Assets/BlendShapeBuilderPackaging.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_EDITOR
2 | using UnityEngine;
3 | using UnityEditor;
4 |
5 |
6 | public class BlendShapeBuilderPackaging
7 | {
8 | [MenuItem("Assets/Make BlendShapeBuilder.unitypackage")]
9 | public static void MakePackage()
10 | {
11 | string[] files = new string[]
12 | {
13 | "Assets/UTJ/BlendShapeBuilder",
14 | "Assets/UTJ/VertexTweaker",
15 | };
16 | AssetDatabase.ExportPackage(files, "BlendShapeBuilder.unitypackage", ExportPackageOptions.Recurse);
17 | }
18 |
19 | }
20 | #endif // UNITY_EDITOR
21 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Assets/BlendShapeBuilderPackaging.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3e200a0c64b232b40b5fc2383c2605b6
3 | timeCreated: 1513672709
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Assets/UTJ.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 309764e37b40ce04da4b3229bd8229ee
3 | folderAsset: yes
4 | timeCreated: 1484424680
5 | licenseType: Pro
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Assets/UTJ/BlendShapeBuilder:
--------------------------------------------------------------------------------
1 | ../../../Assets/BlendShapeBuilder
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Assets/UTJ/BlendShapeBuilder.meta:
--------------------------------------------------------------------------------
1 | ../../../Assets/BlendShapeBuilder.meta
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Assets/UTJ/VertexTweaker:
--------------------------------------------------------------------------------
1 | ../../../Assets/VertexTweaker
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Assets/UTJ/VertexTweaker.meta:
--------------------------------------------------------------------------------
1 | ../../../Assets/VertexTweaker.meta
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Packages/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "com.unity.ads": "2.3.1",
4 | "com.unity.analytics": "3.3.2",
5 | "com.unity.collab-proxy": "1.2.16",
6 | "com.unity.multiplayer-hlapi": "1.0.2",
7 | "com.unity.package-manager-ui": "2.1.2",
8 | "com.unity.purchasing": "2.0.6",
9 | "com.unity.textmeshpro": "2.0.0",
10 | "com.unity.timeline": "1.0.0",
11 | "com.unity.xr.legacyinputhelpers": "2.0.2",
12 | "com.unity.modules.ai": "1.0.0",
13 | "com.unity.modules.animation": "1.0.0",
14 | "com.unity.modules.assetbundle": "1.0.0",
15 | "com.unity.modules.audio": "1.0.0",
16 | "com.unity.modules.cloth": "1.0.0",
17 | "com.unity.modules.director": "1.0.0",
18 | "com.unity.modules.imageconversion": "1.0.0",
19 | "com.unity.modules.imgui": "1.0.0",
20 | "com.unity.modules.jsonserialize": "1.0.0",
21 | "com.unity.modules.particlesystem": "1.0.0",
22 | "com.unity.modules.physics": "1.0.0",
23 | "com.unity.modules.physics2d": "1.0.0",
24 | "com.unity.modules.screencapture": "1.0.0",
25 | "com.unity.modules.terrain": "1.0.0",
26 | "com.unity.modules.terrainphysics": "1.0.0",
27 | "com.unity.modules.tilemap": "1.0.0",
28 | "com.unity.modules.ui": "1.0.0",
29 | "com.unity.modules.uielements": "1.0.0",
30 | "com.unity.modules.umbra": "1.0.0",
31 | "com.unity.modules.unityanalytics": "1.0.0",
32 | "com.unity.modules.unitywebrequest": "1.0.0",
33 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0",
34 | "com.unity.modules.unitywebrequestaudio": "1.0.0",
35 | "com.unity.modules.unitywebrequesttexture": "1.0.0",
36 | "com.unity.modules.unitywebrequestwww": "1.0.0",
37 | "com.unity.modules.vehicles": "1.0.0",
38 | "com.unity.modules.video": "1.0.0",
39 | "com.unity.modules.vr": "1.0.0",
40 | "com.unity.modules.wind": "1.0.0",
41 | "com.unity.modules.xr": "1.0.0"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 | project(VertexTweakerCore)
3 |
4 | set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
5 | include(ISPC)
6 | include(AddPlugin)
7 |
8 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++11")
10 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
11 | include_directories(${CMAKE_SOURCE_DIR})
12 |
13 | add_subdirectory(MeshUtils)
14 | add_subdirectory(VertexTweaker)
15 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/External/7z/7za.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unity3d-jp/BlendShapeBuilder/bf04aceb946c20ec18fa9aa437b9b35102d92867/.BlendShapeBuilder/Plugin/External/7z/7za.exe
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/External/make_archive.bat:
--------------------------------------------------------------------------------
1 | 7z\7za.exe a -mx=9 External.7z^
2 | libs^
3 | ispc.exe
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | NotUsing
48 |
49 |
50 |
51 | Create
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Document
61 | External\ispc %(FullPath) -o $(IntDir)%(Filename).obj -h $(IntDir)%(Filename).h --target=sse4-i32x4,avx1-i32x8,avx512skx-i32x16 --arch=x86-64 --opt=fast-masked-vload --opt=fast-math
62 | External\ispc %(FullPath) -o $(IntDir)%(Filename).obj -h $(IntDir)%(Filename).h --target=sse4-i32x4,avx1-i32x8,avx512skx-i32x16 --arch=x86 --opt=fast-masked-vload --opt=fast-math
63 | $(IntDir)%(Filename).obj;$(IntDir)%(Filename)_sse4.obj;$(IntDir)%(Filename)_avx.obj;$(IntDir)%(Filename)_avx512skx.obj
64 | $(SolutionDir)MeshUtils\ispcmath.h;$(SolutionDir)MeshUtils\muSIMDConfig.h
65 |
66 |
67 |
68 |
69 | {1c5de91b-7ae9-4304-9fa1-0de1aba8c02d}
70 |
71 |
72 |
73 | {FD3FE1FF-ABE5-40DB-B867-144E9DD9B23C}
74 | Win32Proj
75 | 10.0.17763.0
76 |
77 |
78 |
79 | StaticLibrary
80 | v141
81 | Unicode
82 | true
83 |
84 |
85 | StaticLibrary
86 | v141
87 | Unicode
88 |
89 |
90 |
91 |
92 |
93 |
94 | <_ProjectFileVersion>12.0.21005.1
95 |
96 |
97 | $(SolutionDir);$(SolutionDir)External\include;$(IncludePath)
98 | $(SolutionDir)_out\$(Platform)_$(Configuration)\
99 | $(SolutionDir)_tmp\$(ProjectName)_$(Platform)_$(Configuration)\
100 |
101 |
102 |
103 | Disabled
104 | %(PreprocessorDefinitions)
105 | EnableFastChecks
106 | MultiThreadedDLL
107 | Use
108 | Level4
109 | ProgramDatabase
110 | true
111 | pch.h
112 | true
113 | $(IntDir)
114 |
115 |
116 | true
117 | Windows
118 | false
119 | true
120 |
121 |
122 |
123 |
124 | Full
125 | true
126 | %(PreprocessorDefinitions)
127 | MultiThreadedDLL
128 | true
129 | Use
130 | Level4
131 | ProgramDatabase
132 | pch.h
133 | AnySuitable
134 | Speed
135 | false
136 | Fast
137 | true
138 | true
139 | false
140 | false
141 | false
142 | $(IntDir)
143 |
144 |
145 | true
146 | Windows
147 | true
148 | true
149 | false
150 |
151 |
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | MeshUtils
6 |
7 |
8 | MeshUtils
9 |
10 |
11 | MeshUtils
12 |
13 |
14 | MeshUtils
15 |
16 |
17 | MeshUtils
18 |
19 |
20 | MeshUtils
21 |
22 |
23 | MeshUtils
24 |
25 |
26 | MeshUtils
27 |
28 |
29 | MeshUtils
30 |
31 |
32 | MeshUtils
33 |
34 |
35 | MeshUtils
36 |
37 |
38 | MeshUtils
39 |
40 |
41 | MeshUtils
42 |
43 |
44 | MeshUtils
45 |
46 |
47 | MeshUtils
48 |
49 |
50 | MeshUtils
51 |
52 |
53 | MeshUtils
54 |
55 |
56 | MeshUtils
57 |
58 |
59 | MeshUtils
60 |
61 |
62 | MeshUtils
63 |
64 |
65 |
66 |
67 | {7c7e8a56-7f18-4fed-967a-dd734cc4db8a}
68 |
69 |
70 |
71 |
72 | MeshUtils
73 |
74 |
75 | MeshUtils
76 |
77 |
78 | MeshUtils
79 |
80 |
81 | MeshUtils
82 |
83 |
84 | MeshUtils
85 |
86 |
87 | MeshUtils
88 |
89 |
90 | MeshUtils
91 |
92 |
93 | MeshUtils
94 |
95 |
96 | MeshUtils
97 |
98 |
99 |
100 |
101 | MeshUtils
102 |
103 |
104 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | option(ENABLE_TBB "Use Intel TBB." OFF)
2 | option(ENABLE_HALF "Use half." OFF)
3 |
4 | if(ENABLE_ISPC)
5 | setup_ispc()
6 |
7 | set(MUISPC_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}/ISPC)
8 | set(MUISPC_HEADERS
9 | "${CMAKE_CURRENT_SOURCE_DIR}/ispcmath.h"
10 | "${CMAKE_CURRENT_SOURCE_DIR}/muSIMDConfig.h"
11 | )
12 | file(GLOB MUISPC_SOURCES *.ispc)
13 | add_ispc_targets(SOURCES ${MUISPC_SOURCES} HEADERS ${MUISPC_HEADERS} OUTDIR ${MUISPC_OUTDIR})
14 | set(MUISPC_OUTPUTS ${_ispc_outputs})
15 | endif()
16 |
17 | file(GLOB sources *.cpp *.c *.h)
18 | add_library(MeshUtils STATIC ${sources} ${MUISPC_OUTPUTS})
19 | install(TARGETS MeshUtils DESTINATION .)
20 |
21 | if(ENABLE_ISPC)
22 | add_definitions(-DmuEnableISPC)
23 | target_include_directories(MeshUtils PUBLIC ${MUISPC_OUTDIR})
24 | endif()
25 | if(ENABLE_TBB)
26 | find_package(TBB QUIET)
27 | add_definitions(-DmuEnableTBB)
28 | include_directories(${TBB_INCLUDE_DIRS})
29 | list(APPEND EXTERNAL_LIBS ${TBB_LIBRARIES})
30 | endif()
31 | if(ENABLE_HALF)
32 | find_package(OpenEXR QUIET)
33 | add_definitions(-DmuEnableHalf)
34 | include_directories(${OPENEXR_INCLUDE_DIR})
35 | list(APPEND EXTERNAL_LIBS ${OPENEXR_Half_LIBRARY})
36 | endif()
37 | set(EXTERNAL_LIBS ${EXTERNAL_LIBS} PARENT_SCOPE)
38 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/ampmath.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 |
8 | // fast math
9 | namespace apm {
10 | using namespace concurrency;
11 | using namespace concurrency::graphics;
12 | using namespace concurrency::fast_math;
13 | #include "ampmath_impl.h"
14 | } // namespace apm
15 |
16 |
17 | // precise math
18 | namespace afm {
19 | using namespace concurrency;
20 | using namespace concurrency::graphics;
21 | using namespace concurrency::precise_math;
22 | #include "ampmath_impl.h"
23 | } // namespace afm
24 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/ampmath_impl.h:
--------------------------------------------------------------------------------
1 |
2 | inline bool device_available()
3 | {
4 | static bool value = !Concurrency::accelerator().get_is_emulated();
5 | return value;
6 | }
7 |
8 |
9 | #define Def1A(A,F) \
10 | template::size == 2>* = nullptr>\
11 | inline T A(T v) restrict(amp) { \
12 | return { F(v.x), F(v.y) }; \
13 | } \
14 | template::size == 3>* = nullptr>\
15 | inline T A(T l, T r) restrict(amp) { \
16 | return { F(v.x), F(v.y), F(v.z) }; \
17 | } \
18 | template::size == 4>* = nullptr>\
19 | inline T A(T l, T r) restrict(amp) { \
20 | return { F(v.x), F(v.y), F(v.z), F(v.w) }; \
21 | }
22 |
23 | #define Def2A(A,F) \
24 | template::size == 2>* = nullptr>\
25 | inline T A(T a, T b) restrict(amp) { \
26 | return { F(a.x, b.x), F(a.y, b.y )}; \
27 | } \
28 | template::size == 3>* = nullptr>\
29 | inline T A(T a, T b) restrict(amp) { \
30 | return { F(a.x, b.x), F(a.y, b.y), F(a.z, b.z) }; \
31 | } \
32 | template::size == 4>* = nullptr>\
33 | inline T A(T a, T b) restrict(amp) { \
34 | return { F(a.x, b.x), F(a.y, b.y), F(a.z, b.z), F(a.w, b.w) }; \
35 | }
36 |
37 | #define Def1(F) Def1A(F,F)
38 | #define Def2(F) Def2A(F,F)
39 |
40 | Def1A(abs, fabs)
41 | Def1(round)
42 | Def1(floor)
43 | Def1(ceil)
44 | Def2(min)
45 | Def2(max)
46 | Def1(rcp)
47 | Def1A(sqrt, sqrtf)
48 | Def1A(rsqrt, rsqrtf)
49 | Def1(sin)
50 | Def1(cos)
51 | Def1(tan)
52 | Def1(asin)
53 | Def1(acos)
54 | Def1(atan)
55 | Def2(atan2)
56 | Def1(exp)
57 | Def1(log)
58 | Def2(pow)
59 | Def2(mod)
60 | Def1(frac)
61 |
62 | #undef Def2
63 | #undef Def1
64 |
65 | inline float abs(float v) restrict(amp) { return fabs(v); }
66 | inline float sqrt(float v) restrict(amp) { return sqrtf(v); }
67 | inline float rsqrt(float v) restrict(amp) { return rsqrtf(v); }
68 |
69 | template::size == 2>* = nullptr>
70 | inline typename short_vector_traits::value_type dot(T l, T r) restrict(amp) {
71 | return l.x * r.x + l.y * r.y;
72 | }
73 | template::size == 3>* = nullptr>
74 | inline typename short_vector_traits::value_type dot(T l, T r) restrict(amp) {
75 | return l.x * r.x + l.y * r.y + l.z * r.z;
76 | }
77 | template::size == 4>* = nullptr>
78 | inline typename short_vector_traits::value_type dot(T l, T r) restrict(amp) {
79 | return l.x * r.x + l.y * r.y + l.z * r.z + l.w * r.w;
80 | }
81 |
82 | template::size == 3>* = nullptr>
83 | inline T cross(T l, T r) restrict(amp) {
84 | return {
85 | l.y * r.z - l.z * r.y,
86 | l.z * r.x - l.x * r.z,
87 | l.x * r.y - l.y * r.x };
88 | }
89 |
90 | template
91 | inline typename short_vector_traits::value_type length_sq(T v) restrict(amp) {
92 | return dot(v, v);
93 | }
94 |
95 | template
96 | inline typename short_vector_traits::value_type length(T v) restrict(amp) {
97 | return sqrt(dot(v, v));
98 | }
99 |
100 | template
101 | inline T normalize(T v) restrict(amp) {
102 | return v * rsqrt(dot(v, v));
103 | }
104 |
105 |
106 | inline bool ray_triangle_intersection(float_3 pos, float_3 dir, float_3 p1, float_3 p2, float_3 p3, float& distance) restrict(amp)
107 | {
108 | const float epsdet = 1e-10f;
109 | const float eps = 1e-4f;
110 |
111 | float_3 e1 = p2 - p1;
112 | float_3 e2 = p3 - p1;
113 | float_3 p = cross(dir, e2);
114 | float det = dot(e1, p);
115 | if (abs(det) < epsdet) return false;
116 | float inv_det = 1.0f / det;
117 | float_3 t = pos - p1;
118 | float u = dot(t, p) * inv_det;
119 | if (u < -eps || u > 1+ eps) return false;
120 | float_3 q = cross(t, e1);
121 | float v = dot(dir, q) * inv_det;
122 | if (v < -eps || u + v > 1+ eps) return false;
123 |
124 | distance = dot(e2, q) * inv_det;
125 | return distance >= 0.0f;
126 | }
127 | inline bool ray_triangle_intersection(float_3 pos, float_3 dir, float_4 p1, float_4 p2, float_4 p3, float& distance) restrict(amp)
128 | {
129 | return ray_triangle_intersection(pos, dir,
130 | { p1.x, p1.y, p1.z },
131 | { p2.x, p2.y, p2.z },
132 | { p3.x, p3.y, p3.z }, distance);
133 | }
134 |
135 | template
136 | inline T triangle_interpolation(float_3 pos, float_3 p1, float_3 p2, float_3 p3, T x1, T x2, T x3) restrict(amp)
137 | {
138 | float_3 f1 = p1 - pos;
139 | float_3 f2 = p2 - pos;
140 | float_3 f3 = p3 - pos;
141 | float a = 1.0f / length(cross(p1 - p2, p1 - p3));
142 | float a1 = length(cross(f2, f3)) * a;
143 | float a2 = length(cross(f3, f1)) * a;
144 | float a3 = length(cross(f1, f2)) * a;
145 | return x1 * a1 + x2 * a2 + x3 * a3;
146 | }
147 | template
148 | inline T triangle_interpolation(float_3 pos, float_4 p1, float_4 p2, float_4 p3, T x1, T x2, T x3) restrict(amp)
149 | {
150 | return triangle_interpolation(pos,
151 | { p1.x, p1.y, p1.z },
152 | { p2.x, p2.y, p2.z },
153 | { p3.x, p3.y, p3.z },
154 | x1, x2, x3);
155 | }
156 |
157 | inline float ray_point_distance(float_3 pos, float_3 dir, float_3 p) restrict(amp)
158 | {
159 | return length(cross(dir, p - pos));
160 | }
161 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/mikktspace.h:
--------------------------------------------------------------------------------
1 | /** \file mikktspace/mikktspace.h
2 | * \ingroup mikktspace
3 | */
4 | /**
5 | * Copyright (C) 2011 by Morten S. Mikkelsen
6 | *
7 | * This software is provided 'as-is', without any express or implied
8 | * warranty. In no event will the authors be held liable for any damages
9 | * arising from the use of this software.
10 | *
11 | * Permission is granted to anyone to use this software for any purpose,
12 | * including commercial applications, and to alter it and redistribute it
13 | * freely, subject to the following restrictions:
14 | *
15 | * 1. The origin of this software must not be misrepresented; you must not
16 | * claim that you wrote the original software. If you use this software
17 | * in a product, an acknowledgment in the product documentation would be
18 | * appreciated but is not required.
19 | * 2. Altered source versions must be plainly marked as such, and must not be
20 | * misrepresented as being the original software.
21 | * 3. This notice may not be removed or altered from any source distribution.
22 | */
23 |
24 | #ifndef __MIKKTSPACE_H__
25 | #define __MIKKTSPACE_H__
26 |
27 |
28 | #ifdef __cplusplus
29 | extern "C" {
30 | #endif
31 |
32 | /* Author: Morten S. Mikkelsen
33 | * Version: 1.0
34 | *
35 | * The files mikktspace.h and mikktspace.c are designed to be
36 | * stand-alone files and it is important that they are kept this way.
37 | * Not having dependencies on structures/classes/libraries specific
38 | * to the program, in which they are used, allows them to be copied
39 | * and used as is into any tool, program or plugin.
40 | * The code is designed to consistently generate the same
41 | * tangent spaces, for a given mesh, in any tool in which it is used.
42 | * This is done by performing an internal welding step and subsequently an order-independent evaluation
43 | * of tangent space for meshes consisting of triangles and quads.
44 | * This means faces can be received in any order and the same is true for
45 | * the order of vertices of each face. The generated result will not be affected
46 | * by such reordering. Additionally, whether degenerate (vertices or texture coordinates)
47 | * primitives are present or not will not affect the generated results either.
48 | * Once tangent space calculation is done the vertices of degenerate primitives will simply
49 | * inherit tangent space from neighboring non degenerate primitives.
50 | * The analysis behind this implementation can be found in my master's thesis
51 | * which is available for download --> http://image.diku.dk/projects/media/morten.mikkelsen.08.pdf
52 | * Note that though the tangent spaces at the vertices are generated in an order-independent way,
53 | * by this implementation, the interpolated tangent space is still affected by which diagonal is
54 | * chosen to split each quad. A sensible solution is to have your tools pipeline always
55 | * split quads by the shortest diagonal. This choice is order-independent and works with mirroring.
56 | * If these have the same length then compare the diagonals defined by the texture coordinates.
57 | * XNormal which is a tool for baking normal maps allows you to write your own tangent space plugin
58 | * and also quad triangulator plugin.
59 | */
60 |
61 |
62 | typedef int tbool;
63 | typedef struct SMikkTSpaceContext SMikkTSpaceContext;
64 |
65 | typedef struct {
66 | // Returns the number of faces (triangles/quads) on the mesh to be processed.
67 | int (*m_getNumFaces)(const SMikkTSpaceContext * pContext);
68 |
69 | // Returns the number of vertices on face number iFace
70 | // iFace is a number in the range {0, 1, ..., getNumFaces()-1}
71 | int (*m_getNumVerticesOfFace)(const SMikkTSpaceContext * pContext, const int iFace);
72 |
73 | // returns the position/normal/texcoord of the referenced face of vertex number iVert.
74 | // iVert is in the range {0,1,2} for triangles and {0,1,2,3} for quads.
75 | void (*m_getPosition)(const SMikkTSpaceContext * pContext, float fvPosOut[], const int iFace, const int iVert);
76 | void (*m_getNormal)(const SMikkTSpaceContext * pContext, float fvNormOut[], const int iFace, const int iVert);
77 | void (*m_getTexCoord)(const SMikkTSpaceContext * pContext, float fvTexcOut[], const int iFace, const int iVert);
78 |
79 | // either (or both) of the two setTSpace callbacks can be set.
80 | // The call-back m_setTSpaceBasic() is sufficient for basic normal mapping.
81 |
82 | // This function is used to return the tangent and fSign to the application.
83 | // fvTangent is a unit length vector.
84 | // For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
85 | // bitangent = fSign * cross(vN, tangent);
86 | // Note that the results are returned unindexed. It is possible to generate a new index list
87 | // But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
88 | // DO NOT! use an already existing index list.
89 | void (*m_setTSpaceBasic)(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert);
90 |
91 | // This function is used to return tangent space results to the application.
92 | // fvTangent and fvBiTangent are unit length vectors and fMagS and fMagT are their
93 | // true magnitudes which can be used for relief mapping effects.
94 | // fvBiTangent is the "real" bitangent and thus may not be perpendicular to fvTangent.
95 | // However, both are perpendicular to the vertex normal.
96 | // For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
97 | // fSign = bIsOrientationPreserving ? 1.0f : (-1.0f);
98 | // bitangent = fSign * cross(vN, tangent);
99 | // Note that the results are returned unindexed. It is possible to generate a new index list
100 | // But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
101 | // DO NOT! use an already existing index list.
102 | void (*m_setTSpace)(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
103 | const tbool bIsOrientationPreserving, const int iFace, const int iVert);
104 | } SMikkTSpaceInterface;
105 |
106 | struct SMikkTSpaceContext
107 | {
108 | SMikkTSpaceInterface * m_pInterface; // initialized with callback functions
109 | void * m_pUserData; // pointer to client side mesh data etc. (passed as the first parameter with every interface call)
110 | };
111 |
112 | // these are both thread safe!
113 | tbool genTangSpaceDefault(const SMikkTSpaceContext * pContext); // Default (recommended) fAngularThreshold is 180 degrees (which means threshold disabled)
114 | tbool genTangSpace(const SMikkTSpaceContext * pContext, const float fAngularThreshold);
115 |
116 |
117 | // To avoid visual errors (distortions/unwanted hard edges in lighting), when using sampled normal maps, the
118 | // normal map sampler must use the exact inverse of the pixel shader transformation.
119 | // The most efficient transformation we can possibly do in the pixel shader is
120 | // achieved by using, directly, the "unnormalized" interpolated tangent, bitangent and vertex normal: vT, vB and vN.
121 | // pixel shader (fast transform out)
122 | // vNout = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
123 | // where vNt is the tangent space normal. The normal map sampler must likewise use the
124 | // interpolated and "unnormalized" tangent, bitangent and vertex normal to be compliant with the pixel shader.
125 | // sampler does (exact inverse of pixel shader):
126 | // float3 row0 = cross(vB, vN);
127 | // float3 row1 = cross(vN, vT);
128 | // float3 row2 = cross(vT, vB);
129 | // float fSign = dot(vT, row0)<0 ? -1 : 1;
130 | // vNt = normalize( fSign * float3(dot(vNout,row0), dot(vNout,row1), dot(vNout,row2)) );
131 | // where vNout is the sampled normal in some chosen 3D space.
132 | //
133 | // Should you choose to reconstruct the bitangent in the pixel shader instead
134 | // of the vertex shader, as explained earlier, then be sure to do this in the normal map sampler also.
135 | // Finally, beware of quad triangulations. If the normal map sampler doesn't use the same triangulation of
136 | // quads as your renderer then problems will occur since the interpolated tangent spaces will differ
137 | // eventhough the vertex level tangent spaces match. This can be solved either by triangulating before
138 | // sampling/exporting or by using the order-independent choice of diagonal for splitting quads suggested earlier.
139 | // However, this must be used both by the sampler and your tools/rendering pipeline.
140 |
141 | #ifdef __cplusplus
142 | }
143 | #endif
144 |
145 | #endif
146 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muAllocator.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "muAllocator.h"
3 |
4 | void* AlignedMalloc(size_t size, size_t alignment)
5 | {
6 | size_t mask = alignment - 1;
7 | size = (size + mask) & (~mask);
8 | #ifdef _WIN32
9 | return _mm_malloc(size, alignment);
10 | #else
11 | void *ret = nullptr;
12 | posix_memalign(&ret, alignment, size);
13 | return ret;
14 | #endif
15 | }
16 |
17 | void AlignedFree(void *addr)
18 | {
19 | #ifdef _WIN32
20 | _mm_free(addr);
21 | #else
22 | free(addr);
23 | #endif
24 | }
25 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muAllocator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | void* AlignedMalloc(size_t size, size_t alignment);
4 | void AlignedFree(void *addr);
5 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muConcurrency.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "muConfig.h"
4 | #if defined(muEnablePPL)
5 | #include
6 | #elif defined(muEnableTBB)
7 | #include
8 | #endif
9 |
10 | namespace mu {
11 |
12 | template
13 | inline void parallel_for(Index begin, Index end, const Body& body)
14 | {
15 | #if defined(muEnablePPL)
16 | concurrency::parallel_for(begin, end, body);
17 | #elif defined(muEnableTBB)
18 | tbb::parallel_for(begin, end, body);
19 | #else
20 | for (; begin != end; ++begin) { body(begin); }
21 | #endif
22 | }
23 |
24 | #if defined(muEnablePPL) || defined(muEnableTBB)
25 | template
26 | inline void parallel_for_blocked(int begin, int end, int granularity, const Body& body)
27 | {
28 | int num_elements = end - begin;
29 | int num_blocks = ceildiv(num_elements, granularity);
30 | parallel_for(0, num_blocks, [&](int i) {
31 | int begin = granularity * i;
32 | int end = std::min(granularity * (i + 1), num_elements);
33 | body(begin, end);
34 | });
35 | }
36 | #else
37 | template
38 | inline void parallel_for_blocked(int begin, int end, int /*granularity*/, const Body& body)
39 | {
40 | body(begin, end);
41 | }
42 | #endif
43 |
44 | template
45 | inline void parallel_for_each(Iter begin, Iter end, const Body& body)
46 | {
47 | #if defined(muEnablePPL)
48 | concurrency::parallel_for_each(begin, end, body);
49 | #elif defined(muEnableTBB)
50 | tbb::parallel_for_each(begin, end, body);
51 | #else
52 | for (; begin != end; ++begin) { body(*begin); }
53 | #endif
54 | }
55 |
56 |
57 | #if defined(muEnablePPL)
58 |
59 | template
60 | inline void parallel_invoke(Bodies... bodies) { concurrency::parallel_invoke(bodies...); }
61 |
62 | #elif defined(muEnableTBB)
63 |
64 | template
65 | inline void parallel_invoke(Bodies... bodies) { tbb::parallel_invoke(bodies...); }
66 |
67 | #else
68 |
69 | template
70 | inline void parallel_invoke(const Body& body) { body(); }
71 |
72 | template
73 | void parallel_invoke(const Body& first, Args... args) {
74 | first();
75 | parallel_invoke(args...);
76 | }
77 |
78 | #endif
79 |
80 | } // namespace ms
81 |
82 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muConfig.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // available options:
4 | // muEnablePPL
5 | // muEnableTBB
6 | // muEnableISPC
7 | // muEnableAMP
8 | // muEnableSymbol
9 |
10 | #ifdef _WIN32
11 | #define muEnablePPL
12 | #define muEnableISPC
13 | #define muEnableAMP
14 |
15 | #define muEnableSymbol
16 | #endif
17 |
18 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muIntrusiveArray.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "muIterator.h"
4 |
5 | template
6 | class IntrusiveArray
7 | {
8 | public:
9 | using value_type = T;
10 | using reference = T&;
11 | using const_reference = const T&;
12 | using pointer = T*;
13 | using const_pointer = const T*;
14 | using iterator = pointer;
15 | using const_iterator = const_pointer;
16 |
17 | IntrusiveArray() {}
18 | IntrusiveArray(const T *d, size_t s) : m_data(const_cast(d)), m_size(s) {}
19 | IntrusiveArray(const IntrusiveArray& v) : m_data(const_cast(v.m_data)), m_size(v.m_size) {}
20 | template
21 | IntrusiveArray(const T(&v)[N]) : m_data(const_cast(v)), m_size(N) {}
22 | template
23 | IntrusiveArray(const Container& v) : m_data(const_cast(v.data())), m_size(v.size()) {}
24 | IntrusiveArray& operator=(const IntrusiveArray& v) { m_data = const_cast(v.m_data); m_size = v.m_size; return *this; }
25 |
26 | void reset(T *d, size_t s)
27 | {
28 | m_data = d;
29 | m_size = s;
30 | }
31 |
32 | bool empty() const { return m_size == 0; }
33 | size_t size() const { return m_size; }
34 |
35 | T* data() { return m_data; }
36 | const T* data() const { return m_data; }
37 |
38 | T& operator[](size_t i) { return m_data[i]; }
39 | const T& operator[](size_t i) const { return m_data[i]; }
40 |
41 | iterator begin() { return m_data; }
42 | const_iterator begin() const { return m_data; }
43 | iterator end() { return m_data + m_size; }
44 | const_iterator end() const { return m_data + m_size; }
45 |
46 | void zeroclear()
47 | {
48 | memset(m_data, 0, sizeof(T)*m_size);
49 | }
50 | void copy_to(pointer dst)
51 | {
52 | memcpy(dst, m_data, sizeof(value_type) * m_size);
53 | }
54 | void copy_to(pointer dst, size_t num_elements)
55 | {
56 | memcpy(dst, m_data, sizeof(value_type) * num_elements);
57 | }
58 |
59 | private:
60 | T *m_data = nullptr;
61 | size_t m_size = 0;
62 | };
63 |
64 |
65 | template
66 | class IntrusiveIndexedArray
67 | {
68 | public:
69 | using value_type = T;
70 | using reference = T&;
71 | using const_reference = const T&;
72 | using pointer = T*;
73 | using const_pointer = const T*;
74 | using iterator = indexed_iterator;
75 | using const_iterator = indexed_iterator;
76 |
77 | IntrusiveIndexedArray() {}
78 | IntrusiveIndexedArray(const I *i, const T *d, size_t s) : m_index(const_cast(i)), m_data(const_cast(d)), m_size(s) {}
79 | IntrusiveIndexedArray(const IntrusiveIndexedArray& v) : m_index(const_cast(v.m_index)), m_data(const_cast(v.m_data)), m_size(v.m_size) {}
80 | template
81 | IntrusiveIndexedArray(const IContainer& i, const VContainer& v) : m_index(const_cast(i.data())), m_data(const_cast(v.data())), m_size(i.size()) {}
82 | IntrusiveIndexedArray& operator=(const IntrusiveIndexedArray& v)
83 | {
84 | m_index = const_cast(v.m_index);
85 | m_data = const_cast(v.m_data);
86 | m_size = v.m_size;
87 | return *this;
88 | }
89 |
90 | void reset(I *i, T *d, size_t s)
91 | {
92 | m_index = i;
93 | m_data = d;
94 | m_size = s;
95 | }
96 |
97 | bool empty() const { return m_size == 0; }
98 | size_t size() const { return m_size; }
99 |
100 | I* index() { return m_index; }
101 | const I* index() const { return m_index; }
102 |
103 | T* data() { return m_data; }
104 | const T* data() const { return m_data; }
105 |
106 | T& operator[](size_t i) { return m_data[m_index[i]]; }
107 | const T& operator[](size_t i) const { return m_data[m_index[i]]; }
108 |
109 | iterator begin() { return { m_data, m_index }; }
110 | const_iterator begin() const { return { m_data, m_index }; }
111 | iterator end() { return { m_data, m_index + m_size }; }
112 | const_iterator end() const { return { m_data, m_index + m_size }; }
113 |
114 | private:
115 | I *m_index = nullptr;
116 | T *m_data = nullptr;
117 | size_t m_size = 0;
118 | };
119 |
120 | template using IArray = IntrusiveArray;
121 | template using IIArray = IntrusiveIndexedArray;
122 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muIterator.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define Boilerplate(I, V) \
4 | using this_t = I; \
5 | using difference_type = std::ptrdiff_t; \
6 | using value_type = typename std::iterator_traits::value_type; \
7 | using reference = typename std::iterator_traits::reference; \
8 | using pointer = typename std::iterator_traits::pointer; \
9 | using iterator_category = std::random_access_iterator_tag; \
10 |
11 |
12 | template
13 | struct strided_iterator
14 | {
15 | Boilerplate(strided_iterator, T);
16 | static const int stride = Stride;
17 |
18 | uint8_t *data;
19 |
20 | reference operator*() { return *(T*)data; }
21 | pointer operator->() { return &(T*)data; }
22 | this_t operator+(size_t v) { return data + stride*v; }
23 | this_t operator-(size_t v) { return data + stride*v; }
24 | this_t& operator+=(size_t v) { data += stride*v; return *this; }
25 | this_t& operator-=(size_t v) { data -= stride*v; return *this; }
26 | this_t& operator++() { data += stride; return *this; }
27 | this_t& operator++(int) { data += stride; return *this; }
28 | this_t& operator--() { data -= stride; return *this; }
29 | this_t& operator--(int) { data -= stride; return *this; }
30 | bool operator==(const this_t& v) const { return data == data; }
31 | bool operator!=(const this_t& v) const { return data != data; }
32 |
33 | };
34 |
35 | template
36 | struct strided_iterator
37 | {
38 | Boilerplate(strided_iterator, T)
39 |
40 | uint8_t *data;
41 | size_t stride;
42 |
43 | reference operator*() { return *(T*)data; }
44 | pointer operator->() { return &(T*)data; }
45 | this_t operator+(size_t v) { return data + stride*v; }
46 | this_t operator-(size_t v) { return data + stride*v; }
47 | this_t& operator+=(size_t v) { data += stride*v; return *this; }
48 | this_t& operator-=(size_t v) { data -= stride*v; return *this; }
49 | this_t& operator++() { data += stride; return *this; }
50 | this_t& operator++(int) { data += stride; return *this; }
51 | this_t& operator--() { data -= stride; return *this; }
52 | this_t& operator--(int) { data -= stride; return *this; }
53 | bool operator==(const this_t& v) const { return data == data; }
54 | bool operator!=(const this_t& v) const { return data != data; }
55 | };
56 |
57 |
58 | template
59 | struct indexed_iterator
60 | {
61 | Boilerplate(indexed_iterator, VIter)
62 |
63 | VIter data;
64 | IIter index;
65 |
66 | reference operator*() { return data[*index]; }
67 | pointer operator->() { return &data[*index]; }
68 | this_t operator+(size_t v) { return { data, index + v }; }
69 | this_t operator-(size_t v) { return { data, index - v }; }
70 | this_t& operator+=(size_t v){ index += v; return *this; }
71 | this_t& operator-=(size_t v){ index -= v; return *this; }
72 | this_t& operator++() { ++index; return *this; }
73 | this_t& operator++(int) { ++index; return *this; }
74 | this_t& operator--() { --index; return *this; }
75 | this_t& operator--(int) { --index; return *this; }
76 | bool operator==(const this_t& v) const { return v.data == data && v.index == index; }
77 | bool operator!=(const this_t& v) const { return v.data != data || v.index != index; }
78 | };
79 |
80 | template
81 | struct indexed_iterator_s
82 | {
83 | Boilerplate(indexed_iterator_s, VIter)
84 |
85 | VIter data;
86 | IIter index;
87 |
88 | reference operator*() { return index ? data[*index] : *data; }
89 | pointer operator->() { return index ? &data[*index] : data; }
90 | this_t operator+(size_t v) { return index ? this_t{ data, index + v } : this_t{ data + v, nullptr }; }
91 | this_t operator-(size_t v) { return index ? this_t{ data, index - v } : this_t{ data - v, nullptr }; }
92 | this_t& operator+=(size_t v){ if (index) index += v; else data += v; return *this; }
93 | this_t& operator-=(size_t v){ if (index) index -= v; else data -= v; return *this; }
94 | this_t& operator++() { if (index) ++index; else ++data; return *this; }
95 | this_t& operator++(int) { if (index) ++index; else ++data; return *this; }
96 | this_t& operator--() { if (index) --index; else --data; return *this; }
97 | this_t& operator--(int) { if (index) --index; else --data; return *this; }
98 | bool operator==(const this_t& v) const { return v.data == data && v.index == index; }
99 | bool operator!=(const this_t& v) const { return v.data != data || v.index != index; }
100 | };
101 |
102 | #undef Boilerplate
103 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muMeshRefiner.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace mu {
4 |
5 | struct MeshRefiner
6 | {
7 | struct Submesh
8 | {
9 | int num_indices_tri = 0;
10 | int materialID = 0;
11 | int* faces_to_write = nullptr;
12 | };
13 |
14 | struct Split
15 | {
16 | int offset_faces = 0;
17 | int offset_indices = 0;
18 | int offset_vertices = 0;
19 | int num_faces = 0;
20 | int num_vertices = 0;
21 | int num_indices = 0;
22 | int num_indices_triangulated = 0;
23 | int num_submeshes = 0;
24 | };
25 |
26 | int split_unit = 0; // 0 == no split
27 | bool triangulate = true;
28 | bool swap_faces = false;
29 |
30 | IArray counts;
31 | IArray indices;
32 | IArray points;
33 | IArray normals;
34 | IArray uv;
35 | IArray colors;
36 | RawVector submeshes;
37 | RawVector splits;
38 |
39 | RawVector old2new_indices; // indices to new indices
40 | RawVector new2old_vertices; // indices to old vertices
41 |
42 | private:
43 | RawVector counts_tmp;
44 | RawVector offsets;
45 | ConnectionData connection;
46 | RawVector face_normals;
47 | RawVector normals_tmp;
48 | RawVector tangents_tmp;
49 |
50 | RawVector new_points;
51 | RawVector new_normals;
52 | RawVector new_tangents;
53 | RawVector new_uv;
54 | RawVector new_colors;
55 | RawVector new_indices;
56 | RawVector new_indices_triangulated;
57 | RawVector new_indices_submeshes;
58 | RawVector dummy_materialIDs;
59 | int num_indices_tri = 0;
60 |
61 | public:
62 | void prepare(const IArray& counts, const IArray& indices, const IArray& points);
63 | void genNormals(bool flip);
64 | void genNormalsWithSmoothAngle(float smooth_angle, bool flip);
65 | void genTangents();
66 |
67 | bool refine(bool optimize);
68 |
69 | // should be called after refine(), and only valid for triangulated meshes
70 | bool genSubmesh(IArray materialIDs);
71 |
72 | void swapNewData(
73 | RawVector& p,
74 | RawVector& n,
75 | RawVector& t,
76 | RawVector& u,
77 | RawVector& c,
78 | RawVector& idx);
79 |
80 | private:
81 | bool refineDumb();
82 | bool refineWithOptimization();
83 | void buildConnection();
84 |
85 | template void doRefine(const Body& body);
86 | int findOrAddVertexPNTUC(int vi, const float3& p, const float3& n, const float4& t, const float2& u, const float4& c);
87 | int findOrAddVertexPNTU(int vi, const float3& p, const float3& n, const float4& t, const float2& u);
88 | int findOrAddVertexPNU(int vi, const float3& p, const float3& n, const float2& u);
89 | int findOrAddVertexPN(int vi, const float3& p, const float3& n);
90 | int findOrAddVertexPU(int vi, const float3& p, const float2& u);
91 | };
92 |
93 | } // namespace mu
94 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muMisc.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "muMisc.h"
3 | #ifdef _WIN32
4 | #include
5 | #include
6 | #pragma comment(lib, "dbghelp.lib")
7 | #else
8 | #include
9 | #include
10 | #endif
11 |
12 | namespace mu {
13 |
14 | nanosec Now()
15 | {
16 | using namespace std::chrono;
17 | return duration_cast(steady_clock::now().time_since_epoch()).count();
18 | }
19 |
20 | void Print(const char *fmt, ...)
21 | {
22 | va_list args;
23 | va_start(args, fmt);
24 | #ifdef _WIN32
25 | char buf[1024];
26 | vsnprintf(buf, sizeof(buf), fmt, args);
27 | ::OutputDebugStringA(buf);
28 | #else
29 | vprintf(fmt, args);
30 | #endif
31 | va_end(args);
32 | }
33 |
34 | void Print(const wchar_t *fmt, ...)
35 | {
36 | va_list args;
37 | va_start(args, fmt);
38 | #ifdef _WIN32
39 | wchar_t buf[1024];
40 | _vsnwprintf(buf, sizeof(buf), fmt, args);
41 | ::OutputDebugStringW(buf);
42 | #else
43 | vwprintf(fmt, args);
44 | #endif
45 | va_end(args);
46 | }
47 |
48 | #ifdef _WIN32
49 | std::string ToUTF8(const char *src)
50 | {
51 | // to UTF-16
52 | const int wsize = ::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, nullptr, 0);
53 | std::wstring ws;
54 | ws.resize(wsize);
55 | ::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, (LPWSTR)ws.data(), wsize);
56 |
57 | // to UTF-8
58 | const int u8size = ::WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)ws.data(), -1, nullptr, 0, nullptr, nullptr);
59 | std::string u8s;
60 | u8s.resize(u8size);
61 | ::WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)ws.data(), -1, (LPSTR)u8s.data(), u8size, nullptr, nullptr);
62 | return u8s;
63 | }
64 | std::string ToUTF8(const std::string& src)
65 | {
66 | return ToUTF8(src.c_str());
67 | }
68 |
69 | std::string ToANSI(const char *src)
70 | {
71 | // to UTF-16
72 | const int wsize = ::MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)src, -1, nullptr, 0);
73 | std::wstring ws;
74 | ws.resize(wsize);
75 | ::MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)src, -1, (LPWSTR)ws.data(), wsize);
76 |
77 | // to ANSI
78 | const int u8size = ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ws.data(), -1, nullptr, 0, nullptr, nullptr);
79 | std::string u8s;
80 | u8s.resize(u8size);
81 | ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ws.data(), -1, (LPSTR)u8s.data(), u8size, nullptr, nullptr);
82 | return u8s;
83 | }
84 | std::string ToANSI(const std::string& src)
85 | {
86 | return ToANSI(src.c_str());
87 | }
88 | #endif
89 |
90 |
91 |
92 | void AddDLLSearchPath(const char *v)
93 | {
94 | #if defined(_WIN32)
95 | #define LIBRARY_PATH "PATH"
96 | #elif defined(__APPLE__)
97 | #define LIBRARY_PATH "DYLD_LIBRARY_PATH"
98 | #else
99 | #define LIBRARY_PATH "LD_LIBRARY_PATH"
100 | #endif
101 | #ifdef _WIN32
102 | std::string path;
103 | {
104 | DWORD size = ::GetEnvironmentVariableA(LIBRARY_PATH, nullptr, 0);
105 | if (size > 0) {
106 | path.resize(size);
107 | ::GetEnvironmentVariableA(LIBRARY_PATH, &path[0], (DWORD)path.size());
108 | path.pop_back(); // delete last '\0'
109 | }
110 | }
111 | if (path.find(v) == std::string::npos) {
112 | auto pos = path.size();
113 | path = std::string(v) + ";" + path;
114 | for (size_t i = pos; i < path.size(); ++i) {
115 | char& c = path[i];
116 | if (c == '/') { c = '\\'; }
117 | }
118 | ::SetEnvironmentVariableA(LIBRARY_PATH, path.c_str());
119 | }
120 | #else
121 | std::string path;
122 | if (auto path_ = ::getenv(LIBRARY_PATH)) {
123 | path = path_;
124 | }
125 | if (path.find(v) == std::string::npos) {
126 | if (!path.empty()) { path += ":"; }
127 | auto pos = path.size();
128 | path += v;
129 | for (size_t i = pos; i < path.size(); ++i) {
130 | char& c = path[i];
131 | if (c == '\\') { c = '/'; }
132 | }
133 | ::setenv(LIBRARY_PATH, path.c_str(), 1);
134 | }
135 | #endif
136 | #undef LIBRARY_PATH
137 | }
138 |
139 |
140 |
141 | bool ResolveImports(void *module)
142 | {
143 | #ifdef _WIN32
144 | bool ret = true;
145 | EnumerateDLLImports((HMODULE)module, [&](const char *dll, const char *funcname, DWORD ordinal, void *&addr) {
146 | auto mod = ::GetModuleHandleA(dll);
147 | if (!mod) { mod = ::LoadLibraryA(dll); }
148 | if (!mod) {
149 | ret = false; return;
150 | }
151 | if (funcname) {
152 | ForceWrite(&addr, ::GetProcAddress(mod, funcname));
153 | }
154 | else {
155 | ForceWrite(&addr, ::GetProcAddress(mod, MAKEINTRESOURCEA(ordinal)));
156 | }
157 | });
158 | return ret;
159 | #else // _WIN32
160 | return false;
161 | #endif //_WIN32
162 | }
163 |
164 | void* LoadModule(const char *path)
165 | {
166 | #ifdef _WIN32
167 | return ::LoadLibraryA(path);
168 | #else // _WIN32
169 | return nullptr;
170 | #endif //_WIN32
171 | }
172 |
173 | void* GetModule(const char *module_name)
174 | {
175 | #ifdef _WIN32
176 | return ::GetModuleHandleA(module_name);
177 | #else // _WIN32
178 | return nullptr;
179 | #endif //_WIN32
180 | }
181 |
182 |
183 | void InitializeSymbols(const char *path)
184 | {
185 | #ifdef _WIN32
186 | char tmp[MAX_PATH];
187 | if (!path) {
188 | auto ret = ::GetModuleFileNameA(::GetModuleHandleA(nullptr), (LPSTR)tmp, sizeof(tmp));
189 | for (int i = ret - 1; i > 0; --i) {
190 | if (tmp[i] == '\\') {
191 | tmp[i] = '\0';
192 | break;
193 | }
194 | }
195 | path = tmp;
196 | }
197 |
198 | DWORD opt = ::SymGetOptions();
199 | opt |= SYMOPT_DEBUG;
200 | opt |= SYMOPT_DEFERRED_LOADS;
201 | opt &= ~SYMOPT_UNDNAME;
202 | ::SymSetOptions(opt);
203 | ::SymInitialize(::GetCurrentProcess(), path, TRUE);
204 | #else // _WIN32
205 | #endif //_WIN32
206 | }
207 |
208 | void* FindSymbolByName(const char *name)
209 | {
210 | #ifdef _WIN32
211 | char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
212 | PSYMBOL_INFO sinfo = (PSYMBOL_INFO)buf;
213 | sinfo->SizeOfStruct = sizeof(SYMBOL_INFO);
214 | sinfo->MaxNameLen = MAX_SYM_NAME;
215 | if (::SymFromName(::GetCurrentProcess(), name, sinfo) == FALSE) {
216 | return nullptr;
217 | }
218 | return (void*)sinfo->Address;
219 | #else // _WIN32
220 | return nullptr;
221 | #endif //_WIN32
222 | }
223 |
224 |
225 | #ifdef _WIN32
226 | struct cbEnumSymbolsCtx
227 | {
228 | const char *name;
229 | void *ret;
230 | };
231 | BOOL CALLBACK cbEnumSymbols(PCSTR SymbolName, DWORD64 SymbolAddress, ULONG /*SymbolSize*/, PVOID UserContext)
232 | {
233 | auto ctx = (cbEnumSymbolsCtx*)UserContext;
234 | if (strcmp(SymbolName, ctx->name) == 0) {
235 | ctx->ret = (void*)SymbolAddress;
236 | return FALSE;
237 | }
238 | return TRUE;
239 |
240 | }
241 |
242 | #endif //_WIN32
243 |
244 | void* FindSymbolByName(const char *name, const char *module_name)
245 | {
246 | #ifdef _WIN32
247 | cbEnumSymbolsCtx ctx{ name, nullptr };
248 | SymEnumerateSymbols64(::GetCurrentProcess(), (ULONG64)GetModuleHandleA(module_name), cbEnumSymbols, &ctx);
249 | return ctx.ret;
250 | #else // _WIN32
251 | return nullptr;
252 | #endif //_WIN32
253 | }
254 |
255 | void SetMemoryProtection(void *addr, size_t size, MemoryFlags flags)
256 | {
257 | #ifdef _WIN32
258 | DWORD flag = 0;
259 | switch (flags) {
260 | case MemoryFlags::ReadWrite: flag = PAGE_READWRITE; break;
261 | case MemoryFlags::ExecuteRead: flag = PAGE_EXECUTE_READ; break;
262 | case MemoryFlags::ExecuteReadWrite: flag = PAGE_EXECUTE_READWRITE; break;
263 | }
264 | DWORD old_flag;
265 | VirtualProtect(addr, size, flag, &old_flag);
266 | #else
267 | int flag = 0;
268 | switch (flags) {
269 | case MemoryFlags::ReadWrite: flag = PROT_READ | PROT_WRITE; break;
270 | case MemoryFlags::ExecuteRead: flag = PROT_EXEC | PROT_READ; break;
271 | case MemoryFlags::ExecuteReadWrite: flag = PROT_EXEC | PROT_READ | PROT_WRITE; break;
272 | }
273 | void *page = (void*)((size_t)addr - ((size_t)addr % getpagesize()));
274 | mprotect(page, size, flag);
275 | #endif
276 | }
277 |
278 |
279 | } // namespace mu
280 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muMisc.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace mu {
4 |
5 | template < typename T, size_t N >
6 | size_t countof(T(&arr)[N]) { return std::extent< T[N] >::value; }
7 |
8 | using nanosec = uint64_t;
9 | nanosec Now();
10 | inline float NS2MS(nanosec ns) { return (float)((double)ns / 1000000.0); }
11 |
12 | void Print(const char *fmt, ...);
13 | void Print(const wchar_t *fmt, ...);
14 |
15 | std::string ToUTF8(const char *src);
16 | std::string ToUTF8(const std::string& src);
17 | std::string ToANSI(const char *src);
18 | std::string ToANSI(const std::string& src);
19 |
20 |
21 | void AddDLLSearchPath(const char *v);
22 | void* LoadModule(const char *path);
23 | void* GetModule(const char *module_name);
24 | bool ResolveImports(void *module);
25 |
26 | void InitializeSymbols(const char *path = nullptr);
27 | void* FindSymbolByName(const char *name);
28 | void* FindSymbolByName(const char *name, const char *module_name);
29 |
30 |
31 | enum class MemoryFlags
32 | {
33 | ExecuteRead,
34 | ReadWrite,
35 | ExecuteReadWrite,
36 | };
37 | void SetMemoryProtection(void *addr, size_t size, MemoryFlags flags);
38 |
39 | template
40 | inline void ForceWrite(void *dst, const T &src)
41 | {
42 | SetMemoryProtection(dst, sizeof(T), MemoryFlags::ExecuteReadWrite);
43 | memcpy(dst, &src, sizeof(T));
44 | SetMemoryProtection(dst, sizeof(T), MemoryFlags::ExecuteRead);
45 | }
46 |
47 |
48 | #ifdef _WIN32
49 | // F: [](const char *dllname, const char *funcname, DWORD ordinal, void *import_address) -> void
50 | template
51 | inline void EnumerateDLLImports(HMODULE module, const F &f)
52 | {
53 | if (module == NULL) { return; }
54 |
55 | size_t ImageBase = (size_t)module;
56 | auto pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
57 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return; }
58 |
59 | auto pNTHeader = (PIMAGE_NT_HEADERS)(ImageBase + pDosHeader->e_lfanew);
60 | DWORD RVAImports = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
61 | if (RVAImports == 0) { return; }
62 |
63 | auto *pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)(ImageBase + RVAImports);
64 | while (pImportDesc->Name != 0) {
65 | const char *pDLLName = (const char*)(ImageBase + pImportDesc->Name);
66 | auto* pThunkOrig = (IMAGE_THUNK_DATA*)(ImageBase + pImportDesc->OriginalFirstThunk);
67 | auto* pThunk = (IMAGE_THUNK_DATA*)(ImageBase + pImportDesc->FirstThunk);
68 | while (pThunkOrig->u1.AddressOfData != 0) {
69 | const char *name = nullptr;
70 | DWORD ordinal = 0;
71 |
72 | #ifdef _WIN64
73 | if (pThunkOrig->u1.Ordinal & IMAGE_ORDINAL_FLAG64) {
74 | ordinal = IMAGE_ORDINAL64(pThunkOrig->u1.Ordinal);
75 | }
76 | #else
77 | if (pThunkOrig->u1.Ordinal & IMAGE_ORDINAL_FLAG32) {
78 | ordinal = IMAGE_ORDINAL32(pThunkOrig->u1.Ordinal);
79 | }
80 | #endif
81 | else {
82 | auto* pIBN = (IMAGE_IMPORT_BY_NAME*)(ImageBase + pThunkOrig->u1.AddressOfData);
83 | name = pIBN->Name;
84 | }
85 | f(pDLLName, name, ordinal, *(void**)pThunk);
86 | ++pThunkOrig;
87 | ++pThunk;
88 | }
89 | ++pImportDesc;
90 | }
91 | return;
92 | }
93 | #endif //_WIN32
94 | } // namespace mu
95 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muRawVector.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include "muAllocator.h"
6 |
7 | template
8 | class RawVector
9 | {
10 | public:
11 | using value_type = T;
12 | using reference = T&;
13 | using const_reference = const T&;
14 | using pointer = T*;
15 | using const_pointer = const T*;
16 | using iterator = pointer;
17 | using const_iterator = const_pointer;
18 | static const int alignment = Align;
19 |
20 | RawVector() {}
21 | RawVector(const RawVector& v)
22 | {
23 | operator=(v);
24 | }
25 | RawVector(RawVector&& v)
26 | {
27 | v.swap(*this);
28 | }
29 | RawVector(std::initializer_list v)
30 | {
31 | operator=(v);
32 | }
33 | explicit RawVector(size_t initial_size) { resize(initial_size); }
34 | RawVector& operator=(const RawVector& v)
35 | {
36 | assign(v.begin(), v.end());
37 | return *this;
38 | }
39 | RawVector& operator=(RawVector&& v)
40 | {
41 | v.swap(*this);
42 | return *this;
43 | }
44 | RawVector& operator=(std::initializer_list v)
45 | {
46 | assign(v.begin(), v.end());
47 | return *this;
48 | }
49 |
50 | ~RawVector()
51 | {
52 | clear();
53 | shrink_to_fit();
54 | }
55 |
56 | bool empty() const { return m_size == 0; }
57 | size_t size() const { return m_size; }
58 | size_t capacity() const { return m_capacity; }
59 |
60 | T* data() { return m_data; }
61 | const T* data() const { return m_data; }
62 | const T* cdata() const { return m_data; }
63 |
64 | T& at(size_t i) { return m_data[i]; }
65 | const T& at(size_t i) const { return m_data[i]; }
66 | T& operator[](size_t i) { return at(i); }
67 | const T& operator[](size_t i) const { return at(i); }
68 |
69 | T& front() { return m_data[0]; }
70 | const T& front() const { return m_data[0]; }
71 | T& back() { return m_data[m_size - 1]; }
72 | const T& back() const { return m_data[m_size - 1]; }
73 |
74 | iterator begin() { return m_data; }
75 | const_iterator begin() const { return m_data; }
76 | iterator end() { return m_data + m_size; }
77 | const_iterator end() const { return m_data + m_size; }
78 |
79 | static void* allocate(size_t size) { return AlignedMalloc(size, alignment); }
80 | static void deallocate(void *addr, size_t /*size*/) { AlignedFree(addr); }
81 |
82 | void reserve(size_t s)
83 | {
84 | if (s > m_capacity) {
85 | s = std::max(s, m_size * 2);
86 | size_t newsize = sizeof(T) * s;
87 | size_t oldsize = sizeof(T) * m_size;
88 |
89 | T *newdata = (T*)allocate(newsize);
90 | memcpy(newdata, m_data, oldsize);
91 | deallocate(m_data, oldsize);
92 | m_data = newdata;
93 | m_capacity = s;
94 | }
95 | }
96 |
97 | void reserve_discard(size_t s)
98 | {
99 | if (s > m_capacity) {
100 | s = std::max(s, m_size * 2);
101 | size_t newsize = sizeof(T) * s;
102 | size_t oldsize = sizeof(T) * m_size;
103 |
104 | deallocate(m_data, oldsize);
105 | m_data = (T*)allocate(newsize);
106 | m_capacity = s;
107 | }
108 | }
109 |
110 | void shrink_to_fit()
111 | {
112 | if (m_size == 0) {
113 | deallocate(m_data, m_size);
114 | m_size = m_capacity = 0;
115 | }
116 | else if (m_size == m_capacity) {
117 | // nothing to do
118 | return;
119 | }
120 | else {
121 | size_t newsize = sizeof(T) * m_size;
122 | size_t oldsize = sizeof(T) * m_capacity;
123 | T *newdata = (T*)allocate(newsize);
124 | memcpy(newdata, m_data, newsize);
125 | deallocate(m_data, oldsize);
126 | m_data = newdata;
127 | m_capacity = m_size;
128 | }
129 | }
130 |
131 | void resize(size_t s)
132 | {
133 | reserve(s);
134 | m_size = s;
135 | }
136 |
137 | void resize_discard(size_t s)
138 | {
139 | reserve_discard(s);
140 | m_size = s;
141 | }
142 |
143 | void resize_zeroclear(size_t s)
144 | {
145 | resize_discard(s);
146 | zeroclear();
147 | }
148 |
149 | void resize(size_t s, const T& v)
150 | {
151 | size_t pos = size();
152 | resize(s);
153 | // std::fill() can be significantly slower than plain copy
154 | for (size_t i = pos; i < s; ++i) {
155 | m_data[i] = v;
156 | }
157 | }
158 |
159 | void clear()
160 | {
161 | m_size = 0;
162 | }
163 |
164 | void swap(RawVector &other)
165 | {
166 | std::swap(m_data, other.m_data);
167 | std::swap(m_size, other.m_size);
168 | std::swap(m_capacity, other.m_capacity);
169 | }
170 |
171 | template
172 | void assign(FwdIter first, FwdIter last)
173 | {
174 | resize(std::distance(first, last));
175 | std::copy(first, last, begin());
176 | }
177 | void assign(const_pointer first, const_pointer last)
178 | {
179 | resize(std::distance(first, last));
180 | // sadly, memcpy() can way faster than std::copy()
181 | memcpy(m_data, first, sizeof(value_type) * m_size);
182 | }
183 |
184 | template
185 | void insert(iterator pos, ForwardIter first, ForwardIter last)
186 | {
187 | size_t d = std::distance(begin(), pos);
188 | size_t s = std::distance(first, last);
189 | resize(d + s);
190 | std::copy(first, last, begin() + pos);
191 | }
192 | void insert(iterator pos, const_pointer first, const_pointer last)
193 | {
194 | size_t d = std::distance(begin(), pos);
195 | size_t s = std::distance(first, last);
196 | resize(d + s);
197 | memcpy(m_data + d, first, sizeof(value_type) * s);
198 | }
199 |
200 | void insert(iterator pos, const_reference v)
201 | {
202 | insert(pos, &v, &v + 1);
203 | }
204 |
205 | void erase(iterator first, iterator last)
206 | {
207 | size_t s = std::distance(first, last);
208 | std::copy(last, end(), first);
209 | m_size -= s;
210 | }
211 |
212 | void erase(iterator pos)
213 | {
214 | erase(pos, pos + 1);
215 | }
216 |
217 | void push_back(const T& v)
218 | {
219 | resize(m_size + 1);
220 | back() = v;
221 | }
222 | void push_back(T&& v)
223 | {
224 | resize(m_size + 1);
225 | back() = v;
226 | }
227 |
228 |
229 | void pop_back()
230 | {
231 | --m_size;
232 | }
233 |
234 | bool operator == (const RawVector& other) const
235 | {
236 | return m_size == other.m_size && memcmp(m_data, other.m_data, sizeof(T)*m_size) == 0;
237 | }
238 |
239 | bool operator != (const RawVector& other) const
240 | {
241 | return !(*this == other);
242 | }
243 |
244 | void zeroclear()
245 | {
246 | memset(m_data, 0, sizeof(T)*m_size);
247 | }
248 |
249 | void copy_to(pointer dst)
250 | {
251 | memcpy(dst, m_data, sizeof(value_type) * m_size);
252 | }
253 | void copy_to(pointer dst, size_t length, size_t offset = 0)
254 | {
255 | memcpy(dst, m_data + offset, sizeof(value_type) * length);
256 | }
257 |
258 | private:
259 | T *m_data = nullptr;
260 | size_t m_size = 0;
261 | size_t m_capacity = 0;
262 | };
263 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muSIMDConfig.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | //#define muSIMD_FloatToHalf
4 | //#define muSIMD_HalfToFloat
5 |
6 | //#define muSIMD_InvertX3
7 | //#define muSIMD_InvertX4
8 | //#define muSIMD_Scale
9 | #define muSIMD_Normalize
10 | //#define muSIMD_Lerp
11 | #define muSIMD_NearEqual
12 |
13 | #define muSIMD_MinMax2
14 | //#define muSIMD_MinMax3
15 |
16 | //#define muSIMD_MulVectors3
17 | //#define muSIMD_MulPoints3
18 |
19 | #define muSIMD_RayTrianglesIntersectionIndexed
20 | //#define muSIMD_RayTrianglesIntersectionFlattened
21 | #define muSIMD_RayTrianglesIntersectionSoA
22 |
23 | //#define muSIMD_PolyInside
24 | #define muSIMD_PolyInsideSoA
25 |
26 | #define muSIMD_GenerateNormalsTriangleIndexed
27 | //#define muSIMD_GenerateNormalsTriangleFlattened
28 | //#define muSIMD_GenerateNormalsTriangleSoA
29 |
30 | #define muSIMD_GenerateTangentsTriangleIndexed
31 | //#define muSIMD_GenerateTangentsTriangleFlattened
32 | //#define muSIMD_GenerateTangentsTriangleSoA
33 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muTLS.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #if _WIN32
6 | #define NOMINMAX
7 | #include
8 | #else
9 | #include
10 | #endif
11 |
12 |
13 | class tls_base
14 | {
15 | public:
16 | #if _WIN32
17 | using tls_key_t = DWORD;
18 | #if WindowsStoreApp
19 | tls_base() { m_key = ::FlsAlloc(nullptr); }
20 | ~tls_base() { ::FlsFree(m_key); }
21 | void set_value(void *value) { ::FlsSetValue(m_key, value); }
22 | void* get_value() { return (void *)::FlsGetValue(m_key); }
23 | #else
24 | tls_base() { m_key = ::TlsAlloc(); }
25 | ~tls_base() { ::TlsFree(m_key); }
26 | void set_value(void *value) { ::TlsSetValue(m_key, value); }
27 | void* get_value() const { return (void *)::TlsGetValue(m_key); }
28 | #endif
29 | #else
30 | using tls_key_t = pthread_key_t;
31 | tls_base() { pthread_key_create(&m_key, nullptr); }
32 | ~tls_base() { pthread_key_delete(m_key); }
33 | void set_value(void *value) { pthread_setspecific(m_key, value); }
34 | void* get_value() const { return pthread_getspecific(m_key); }
35 | #endif
36 | private:
37 | tls_key_t m_key;
38 | };
39 |
40 | template
41 | class tls : private tls_base
42 | {
43 | public:
44 | tls() {}
45 |
46 | ~tls()
47 | {
48 | std::unique_lock lock(m_mutex);
49 | for (auto p : m_locals) { delete p; }
50 | m_locals.clear();
51 | }
52 |
53 | T& local()
54 | {
55 | return local([](T&) {});
56 | }
57 |
58 | template
59 | T& local(const OnFirst& on_first)
60 | {
61 | void *value = get_value();
62 | if (value == nullptr) {
63 | T *v = new T();
64 | set_value(v);
65 | value = v;
66 |
67 | {
68 | std::unique_lock lock(m_mutex);
69 | m_locals.push_back(v);
70 | }
71 | on_first(*v);
72 | }
73 | return *(T*)value;
74 | }
75 |
76 | template
77 | void each(const Body& body)
78 | {
79 | std::unique_lock lock(m_mutex);
80 | for (auto p : m_locals) { body(*p); }
81 | }
82 |
83 | protected:
84 | std::mutex m_mutex;
85 | std::vector m_locals;
86 | };
87 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muVertex.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "muMath.h"
3 | #include "muVertex.h"
4 |
5 | namespace mu {
6 |
7 | template static inline void InterleaveImpl(VertexT *dst, const typename VertexT::arrays_t& src, size_t i);
8 |
9 | template<> inline void InterleaveImpl(vertex_v3n3 *dst, const vertex_v3n3::arrays_t& src, size_t i)
10 | {
11 | dst[i].p = src.points[i];
12 | dst[i].n = src.normals[i];
13 | }
14 | template<> inline void InterleaveImpl(vertex_v3n3c4 *dst, const vertex_v3n3c4::arrays_t& src, size_t i)
15 | {
16 | dst[i].p = src.points[i];
17 | dst[i].n = src.normals[i];
18 | dst[i].c = src.colors[i];
19 | }
20 | template<> inline void InterleaveImpl(vertex_v3n3u2 *dst, const vertex_v3n3u2::arrays_t& src, size_t i)
21 | {
22 | dst[i].p = src.points[i];
23 | dst[i].n = src.normals[i];
24 | dst[i].u = src.uvs[i];
25 | }
26 | template<> inline void InterleaveImpl(vertex_v3n3c4u2 *dst, const vertex_v3n3c4u2::arrays_t& src, size_t i)
27 | {
28 | dst[i].p = src.points[i];
29 | dst[i].n = src.normals[i];
30 | dst[i].c = src.colors[i];
31 | dst[i].u = src.uvs[i];
32 | }
33 | template<> inline void InterleaveImpl(vertex_v3n3u2t4 *dst, const vertex_v3n3u2t4::arrays_t& src, size_t i)
34 | {
35 | dst[i].p = src.points[i];
36 | dst[i].n = src.normals[i];
37 | dst[i].u = src.uvs[i];
38 | dst[i].t = src.tangents[i];
39 | }
40 | template<> inline void InterleaveImpl(vertex_v3n3c4u2t4 *dst, const vertex_v3n3c4u2t4::arrays_t& src, size_t i)
41 | {
42 | dst[i].p = src.points[i];
43 | dst[i].n = src.normals[i];
44 | dst[i].c = src.colors[i];
45 | dst[i].u = src.uvs[i];
46 | dst[i].t = src.tangents[i];
47 | }
48 |
49 | template
50 | void TInterleave(VertexT *dst, const typename VertexT::arrays_t& src, size_t num)
51 | {
52 | for (size_t i = 0; i < num; ++i) {
53 | InterleaveImpl(dst, src, i);
54 | }
55 | }
56 |
57 | VertexFormat GuessVertexFormat(
58 | const float3 *points,
59 | const float3 *normals,
60 | const float4 *colors,
61 | const float2 *uvs,
62 | const float4 *tangents
63 | )
64 | {
65 | if (points && normals) {
66 | if (colors && uvs && tangents) { return VertexFormat::V3N3C4U2T4; }
67 | if (colors && uvs) { return VertexFormat::V3N3C4U2; }
68 | if (uvs && tangents) { return VertexFormat::V3N3U2T4; }
69 | if (uvs) { return VertexFormat::V3N3U2; }
70 | if (colors) { return VertexFormat::V3N3C4; }
71 | return VertexFormat::V3N3;
72 | }
73 | return VertexFormat::Unknown;
74 | }
75 |
76 | size_t GetVertexSize(VertexFormat format)
77 | {
78 | switch (format) {
79 | case VertexFormat::V3N3: return sizeof(vertex_v3n3);
80 | case VertexFormat::V3N3C4: return sizeof(vertex_v3n3c4);
81 | case VertexFormat::V3N3U2: return sizeof(vertex_v3n3u2);
82 | case VertexFormat::V3N3C4U2: return sizeof(vertex_v3n3c4u2);
83 | case VertexFormat::V3N3U2T4: return sizeof(vertex_v3n3u2t4);
84 | case VertexFormat::V3N3C4U2T4: return sizeof(vertex_v3n3c4u2t4);
85 | default: return 0;
86 | }
87 | }
88 |
89 | void Interleave(void *dst, VertexFormat format, size_t num,
90 | const float3 *points,
91 | const float3 *normals,
92 | const float4 *colors,
93 | const float2 *uvs,
94 | const float4 *tangents
95 | )
96 | {
97 | switch (format) {
98 | case VertexFormat::V3N3: TInterleave((vertex_v3n3*)dst, {points, normals}, num); break;
99 | case VertexFormat::V3N3C4: TInterleave((vertex_v3n3c4*)dst, { points, normals, colors }, num); break;
100 | case VertexFormat::V3N3U2: TInterleave((vertex_v3n3u2*)dst, { points, normals, uvs }, num); break;
101 | case VertexFormat::V3N3C4U2: TInterleave((vertex_v3n3c4u2*)dst, { points, normals, colors, uvs }, num); break;
102 | case VertexFormat::V3N3U2T4: TInterleave((vertex_v3n3u2t4*)dst, { points, normals, uvs, tangents }, num); break;
103 | case VertexFormat::V3N3C4U2T4: TInterleave((vertex_v3n3c4u2t4*)dst, { points, normals, colors, uvs, tangents }, num); break;
104 | default: break;
105 | }
106 | }
107 |
108 | } // namespace mu
109 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/muVertex.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace mu {
4 |
5 | template
6 | struct Weights
7 | {
8 | float weights[N] = {};
9 | int indices[N] = {};
10 | };
11 | using Weights4 = Weights<4>;
12 | using Weights8 = Weights<8>;
13 |
14 |
15 | // vertex interleave
16 |
17 | enum class VertexFormat
18 | {
19 | Unknown,
20 | V3N3,
21 | V3N3C4,
22 | V3N3U2,
23 | V3N3C4U2,
24 | V3N3U2T4,
25 | V3N3C4U2T4,
26 | };
27 |
28 | struct vertex_v3n3;
29 | struct vertex_v3n3_arrays;
30 | struct vertex_v3n3c4;
31 | struct vertex_v3n3c4_arrays;
32 | struct vertex_v3n3u2;
33 | struct vertex_v3n3u2_arrays;
34 | struct vertex_v3n3c4u2;
35 | struct vertex_v3n3c4u2_arrays;
36 | struct vertex_v3n3u2t4;
37 | struct vertex_v3n3u2t4_arrays;
38 | struct vertex_v3n3c4u2t4;
39 | struct vertex_v3n3c4u2t4_arrays;
40 |
41 | #define DefTraits(T, ID)\
42 | static const VertexFormat tid = VertexFormat::ID;\
43 | using vertex_t = T;\
44 | using arrays_t = T##_arrays;
45 |
46 |
47 | struct vertex_v3n3_arrays
48 | {
49 | DefTraits(vertex_v3n3, V3N3)
50 | const float3 *points;
51 | const float3 *normals;
52 | };
53 | struct vertex_v3n3
54 | {
55 | DefTraits(vertex_v3n3, V3N3)
56 | float3 p;
57 | float3 n;
58 | };
59 |
60 | struct vertex_v3n3c4_arrays
61 | {
62 | DefTraits(vertex_v3n3c4, V3N3C4)
63 | const float3 *points;
64 | const float3 *normals;
65 | const float4 *colors;
66 | };
67 | struct vertex_v3n3c4
68 | {
69 | DefTraits(vertex_v3n3c4, V3N3C4)
70 | float3 p;
71 | float3 n;
72 | float4 c;
73 | };
74 |
75 |
76 | struct vertex_v3n3u2_arrays
77 | {
78 | DefTraits(vertex_v3n3u2, V3N3U2)
79 | const float3 *points;
80 | const float3 *normals;
81 | const float2 *uvs;
82 | };
83 | struct vertex_v3n3u2
84 | {
85 | DefTraits(vertex_v3n3u2, V3N3U2)
86 | float3 p;
87 | float3 n;
88 | float2 u;
89 | };
90 |
91 | struct vertex_v3n3c4u2_arrays
92 | {
93 | DefTraits(vertex_v3n3c4u2, V3N3C4U2)
94 | const float3 *points;
95 | const float3 *normals;
96 | const float4 *colors;
97 | const float2 *uvs;
98 | };
99 | struct vertex_v3n3c4u2
100 | {
101 | DefTraits(vertex_v3n3c4u2, V3N3C4U2)
102 | float3 p;
103 | float3 n;
104 | float4 c;
105 | float2 u;
106 | };
107 |
108 | struct vertex_v3n3u2t4_arrays
109 | {
110 | DefTraits(vertex_v3n3u2t4, V3N3U2T4)
111 | const float3 *points;
112 | const float3 *normals;
113 | const float2 *uvs;
114 | const float4 *tangents;
115 | };
116 | struct vertex_v3n3u2t4
117 | {
118 | DefTraits(vertex_v3n3u2t4, V3N3U2T4)
119 | float3 p;
120 | float3 n;
121 | float2 u;
122 | float4 t;
123 | };
124 |
125 | struct vertex_v3n3c4u2t4_arrays
126 | {
127 | DefTraits(vertex_v3n3u2t4, V3N3C4U2T4)
128 | const float3 *points;
129 | const float3 *normals;
130 | const float4 *colors;
131 | const float2 *uvs;
132 | const float4 *tangents;
133 | };
134 | struct vertex_v3n3c4u2t4
135 | {
136 | DefTraits(vertex_v3n3c4u2t4, V3N3C4U2T4)
137 | float3 p;
138 | float3 n;
139 | float4 c;
140 | float2 u;
141 | float4 t;
142 | };
143 | #undef DefTraits
144 |
145 | VertexFormat GuessVertexFormat(
146 | const float3 *points,
147 | const float3 *normals,
148 | const float4 *colors,
149 | const float2 *uvs,
150 | const float4 *tangents
151 | );
152 |
153 | size_t GetVertexSize(VertexFormat format);
154 |
155 | void Interleave(void *dst, VertexFormat format, size_t num,
156 | const float3 *points,
157 | const float3 *normals,
158 | const float4 *colors,
159 | const float2 *uvs,
160 | const float4 *tangents
161 | );
162 |
163 | template void Interleave_Generic(VertexT *dst, const typename VertexT::source_t& src, size_t num);
164 |
165 | } // namespace mu
166 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/pch.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/MeshUtils/pch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef _WIN32
4 | #pragma warning(disable:4996)
5 | #define NOMINMAX
6 | #include
7 | #else
8 | #endif
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "muConfig.h"
22 | #ifdef muEnableHalf
23 | #include
24 | #endif // muEnableHalf
25 |
26 | #define muImpl
27 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/NatvisFile.natvis:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ size={m_size} }}
5 |
6 | - m_size
7 | - m_capacity
8 |
9 | m_size
10 | m_data
11 |
12 |
13 |
14 |
15 | {{ size={m_size} }}
16 |
17 | - m_size
18 |
19 | m_size
20 | m_data
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/VertexTweaker/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | file(GLOB sources *.cpp *.h)
2 | set(plugins_dir "${CMAKE_SOURCE_DIR}/../Assets/UTJ/VertexTweaker/Runtime/Plugins/x86_64")
3 | add_plugin(VertexTweakerCore SOURCES ${sources} PLUGINS_DIR ${plugins_dir})
4 |
5 | add_dependencies(VertexTweakerCore MeshUtils)
6 | target_link_libraries(VertexTweakerCore MeshUtils ${EXTERNAL_LIBS})
7 | install(TARGETS VertexTweakerCore DESTINATION .)
8 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/VertexTweaker/VertexTweaker.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef _WIN32
4 | #define npAPI extern "C" __declspec(dllexport)
5 | //#define npEnablePenTablet
6 | #else
7 | #define npAPI extern "C"
8 | #endif
9 |
10 | #include "MeshUtils/MeshUtils.h"
11 | using namespace mu;
12 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/VertexTweaker/pch.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 |
--------------------------------------------------------------------------------
/.BlendShapeBuilder/Plugin/VertexTweaker/pch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include