├── .gitignore ├── LICENSE ├── README.md └── src ├── ModelMerger ├── App.config ├── ModelMerger.csproj ├── ModelMerger.sln ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── icon.ico └── icon.png ├── PhilLibX ├── Animation.cs ├── Bytes.cs ├── Cryptography │ └── Hash │ │ ├── CRC32.cs │ │ ├── DJB.cs │ │ ├── FNV1a.cs │ │ ├── MurMur3.cs │ │ └── SDBM.cs ├── EnumerableExtensions.cs ├── IO │ ├── BinaryReaderExtensions.cs │ ├── BinaryWriterExtensions.cs │ ├── MemoryUtility.cs │ ├── ProcessReader.cs │ └── ProcessWriter.cs ├── Imaging │ └── BitmapX.cs ├── Logger.cs ├── Mathematics │ ├── MathUtility.cs │ ├── Matrix.cs │ ├── Quaternion.cs │ ├── Vector2.cs │ ├── Vector3.cs │ └── Vector4.cs ├── Model.cs ├── NativeMethods.cs ├── Oodle.cs ├── PhilLibX.csproj ├── Printer.cs └── Properties │ └── AssemblyInfo.cs └── SELibDotNet ├── .gitignore ├── README.md └── src ├── DebugUtil ├── App.config ├── DebugUtil.csproj ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── SELib.sln ├── SELib ├── Properties │ └── AssemblyInfo.cs ├── SEAnim.cs ├── SELib.csproj ├── SEModel.cs └── Utilities │ ├── ExtendedBinaryReader.cs │ ├── ExtendedBinaryWriter.cs │ └── ExtendedMath.cs └── UnitTests ├── App.config ├── Program.cs ├── Properties └── AssemblyInfo.cs └── UnitTests.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.vspscc 94 | *.vssscc 95 | .builds 96 | *.pidb 97 | *.svclog 98 | *.scc 99 | 100 | # Chutzpah Test files 101 | _Chutzpah* 102 | 103 | # Visual C++ cache files 104 | ipch/ 105 | *.aps 106 | *.ncb 107 | *.opendb 108 | *.opensdf 109 | *.sdf 110 | *.cachefile 111 | *.VC.db 112 | *.VC.VC.opendb 113 | 114 | # Visual Studio profiler 115 | *.psess 116 | *.vsp 117 | *.vspx 118 | *.sap 119 | 120 | # Visual Studio Trace Files 121 | *.e2e 122 | 123 | # TFS 2012 Local Workspace 124 | $tf/ 125 | 126 | # Guidance Automation Toolkit 127 | *.gpState 128 | 129 | # ReSharper is a .NET coding add-in 130 | _ReSharper*/ 131 | *.[Rr]e[Ss]harper 132 | *.DotSettings.user 133 | 134 | # TeamCity is a build add-in 135 | _TeamCity* 136 | 137 | # DotCover is a Code Coverage Tool 138 | *.dotCover 139 | 140 | # AxoCover is a Code Coverage Tool 141 | .axoCover/* 142 | !.axoCover/settings.json 143 | 144 | # Coverlet is a free, cross platform Code Coverage Tool 145 | coverage*[.json, .xml, .info] 146 | 147 | # Visual Studio code coverage results 148 | *.coverage 149 | *.coveragexml 150 | 151 | # NCrunch 152 | _NCrunch_* 153 | .*crunch*.local.xml 154 | nCrunchTemp_* 155 | 156 | # MightyMoose 157 | *.mm.* 158 | AutoTest.Net/ 159 | 160 | # Web workbench (sass) 161 | .sass-cache/ 162 | 163 | # Installshield output folder 164 | [Ee]xpress/ 165 | 166 | # DocProject is a documentation generator add-in 167 | DocProject/buildhelp/ 168 | DocProject/Help/*.HxT 169 | DocProject/Help/*.HxC 170 | DocProject/Help/*.hhc 171 | DocProject/Help/*.hhk 172 | DocProject/Help/*.hhp 173 | DocProject/Help/Html2 174 | DocProject/Help/html 175 | 176 | # Click-Once directory 177 | publish/ 178 | 179 | # Publish Web Output 180 | *.[Pp]ublish.xml 181 | *.azurePubxml 182 | # Note: Comment the next line if you want to checkin your web deploy settings, 183 | # but database connection strings (with potential passwords) will be unencrypted 184 | *.pubxml 185 | *.publishproj 186 | 187 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 188 | # checkin your Azure Web App publish settings, but sensitive information contained 189 | # in these scripts will be unencrypted 190 | PublishScripts/ 191 | 192 | # NuGet Packages 193 | *.nupkg 194 | # NuGet Symbol Packages 195 | *.snupkg 196 | # The packages folder can be ignored because of Package Restore 197 | **/[Pp]ackages/* 198 | # except build/, which is used as an MSBuild target. 199 | !**/[Pp]ackages/build/ 200 | # Uncomment if necessary however generally it will be regenerated when needed 201 | #!**/[Pp]ackages/repositories.config 202 | # NuGet v3's project.json files produces more ignorable files 203 | *.nuget.props 204 | *.nuget.targets 205 | 206 | # Microsoft Azure Build Output 207 | csx/ 208 | *.build.csdef 209 | 210 | # Microsoft Azure Emulator 211 | ecf/ 212 | rcf/ 213 | 214 | # Windows Store app package directories and files 215 | AppPackages/ 216 | BundleArtifacts/ 217 | Package.StoreAssociation.xml 218 | _pkginfo.txt 219 | *.appx 220 | *.appxbundle 221 | *.appxupload 222 | 223 | # Visual Studio cache files 224 | # files ending in .cache can be ignored 225 | *.[Cc]ache 226 | # but keep track of directories ending in .cache 227 | !?*.[Cc]ache/ 228 | 229 | # Others 230 | ClientBin/ 231 | ~$* 232 | *~ 233 | *.dbmdl 234 | *.dbproj.schemaview 235 | *.jfm 236 | *.pfx 237 | *.publishsettings 238 | orleans.codegen.cs 239 | 240 | # Including strong name files can present a security risk 241 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 242 | #*.snk 243 | 244 | # Since there are multiple workflows, uncomment next line to ignore bower_components 245 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 246 | #bower_components/ 247 | 248 | # RIA/Silverlight projects 249 | Generated_Code/ 250 | 251 | # Backup & report files from converting an old project file 252 | # to a newer Visual Studio version. Backup files are not needed, 253 | # because we have git ;-) 254 | _UpgradeReport_Files/ 255 | Backup*/ 256 | UpgradeLog*.XML 257 | UpgradeLog*.htm 258 | ServiceFabricBackup/ 259 | *.rptproj.bak 260 | 261 | # SQL Server files 262 | *.mdf 263 | *.ldf 264 | *.ndf 265 | 266 | # Business Intelligence projects 267 | *.rdl.data 268 | *.bim.layout 269 | *.bim_*.settings 270 | *.rptproj.rsuser 271 | *- [Bb]ackup.rdl 272 | *- [Bb]ackup ([0-9]).rdl 273 | *- [Bb]ackup ([0-9][0-9]).rdl 274 | 275 | # Microsoft Fakes 276 | FakesAssemblies/ 277 | 278 | # GhostDoc plugin setting file 279 | *.GhostDoc.xml 280 | 281 | # Node.js Tools for Visual Studio 282 | .ntvs_analysis.dat 283 | node_modules/ 284 | 285 | # Visual Studio 6 build log 286 | *.plg 287 | 288 | # Visual Studio 6 workspace options file 289 | *.opt 290 | 291 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 292 | *.vbw 293 | 294 | # Visual Studio LightSwitch build output 295 | **/*.HTMLClient/GeneratedArtifacts 296 | **/*.DesktopClient/GeneratedArtifacts 297 | **/*.DesktopClient/ModelManifest.xml 298 | **/*.Server/GeneratedArtifacts 299 | **/*.Server/ModelManifest.xml 300 | _Pvt_Extensions 301 | 302 | # Paket dependency manager 303 | .paket/paket.exe 304 | paket-files/ 305 | 306 | # FAKE - F# Make 307 | .fake/ 308 | 309 | # CodeRush personal settings 310 | .cr/personal 311 | 312 | # Python Tools for Visual Studio (PTVS) 313 | __pycache__/ 314 | *.pyc 315 | 316 | # Cake - Uncomment if you are using it 317 | # tools/** 318 | # !tools/packages.config 319 | 320 | # Tabs Studio 321 | *.tss 322 | 323 | # Telerik's JustMock configuration file 324 | *.jmconfig 325 | 326 | # BizTalk build output 327 | *.btp.cs 328 | *.btm.cs 329 | *.odx.cs 330 | *.xsd.cs 331 | 332 | # OpenCover UI analysis results 333 | OpenCover/ 334 | 335 | # Azure Stream Analytics local run output 336 | ASALocalRun/ 337 | 338 | # MSBuild Binary and Structured Log 339 | *.binlog 340 | 341 | # NVidia Nsight GPU debugger configuration file 342 | *.nvuser 343 | 344 | # MFractors (Xamarin productivity tool) working folder 345 | .mfractor/ 346 | 347 | # Local History for Visual Studio 348 | .localhistory/ 349 | 350 | # BeatPulse healthcheck temp database 351 | healthchecksdb 352 | 353 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 354 | MigrationBackup/ 355 | 356 | # Ionide (cross platform F# VS Code tools) working folder 357 | .ionide/ 358 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Philip 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ModelMerger 2 | 3 | A simple tool to merge models together, currently supports the following formats: 4 | 5 | * SEModel 6 | 7 | With other formats planned on request or by how many people use it. 8 | 9 | # Using 10 | 11 | Simply drag and drop supported model files onto the tool and it will attempt to merge them together, this includes moving the models to the new origins which makes it useful for weapons and characters exported from games. 12 | 13 | The tool will first sort the given models by names, and then attempt to locate the first model that cannot be connected to any other model, if not found, it will use the first model. It is recommended to use models designed to be used with each other i.e. character body + head, weapon parts, etc. 14 | 15 | # License 16 | 17 | MIT License 18 | 19 | Copyright (c) 2020 Philip 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | -------------------------------------------------------------------------------- /src/ModelMerger/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/ModelMerger/ModelMerger.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA} 8 | Exe 9 | ModelMerger 10 | ModelMerger 11 | v4.8 12 | 512 13 | true 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | icon.ico 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {0f468d5b-2f30-42f5-9043-920040d83d9d} 62 | PhilLibX 63 | 64 | 65 | {e03da150-718d-4ea9-afca-d3e17a7df3e8} 66 | SELib 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/ModelMerger/ModelMerger.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31919.166 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModelMerger", "ModelMerger.csproj", "{0AC36128-5FCA-4D89-A1AE-9614412CD3FA}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SELib", "..\SELibDotNet\src\SELib\SELib.csproj", "{E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhilLibX", "..\PhilLibX\PhilLibX.csproj", "{0F468D5B-2F30-42F5-9043-920040D83D9D}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|Any CPU = Release|Any CPU 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Debug|x64.ActiveCfg = Debug|Any CPU 25 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Debug|x64.Build.0 = Debug|Any CPU 26 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Debug|x86.ActiveCfg = Debug|Any CPU 27 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Debug|x86.Build.0 = Debug|Any CPU 28 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Release|x64.ActiveCfg = Release|Any CPU 31 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Release|x64.Build.0 = Release|Any CPU 32 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Release|x86.ActiveCfg = Release|Any CPU 33 | {0AC36128-5FCA-4D89-A1AE-9614412CD3FA}.Release|x86.Build.0 = Release|Any CPU 34 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Debug|x64.ActiveCfg = Debug|Any CPU 37 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Debug|x64.Build.0 = Debug|Any CPU 38 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Debug|x86.ActiveCfg = Debug|Any CPU 39 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Debug|x86.Build.0 = Debug|Any CPU 40 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Release|x64.ActiveCfg = Release|Any CPU 43 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Release|x64.Build.0 = Release|Any CPU 44 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Release|x86.ActiveCfg = Release|Any CPU 45 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Release|x86.Build.0 = Release|Any CPU 46 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Debug|x64.ActiveCfg = Debug|x64 49 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Debug|x64.Build.0 = Debug|x64 50 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Debug|x86.ActiveCfg = Debug|x86 51 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Debug|x86.Build.0 = Debug|x86 52 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Release|x64.ActiveCfg = Release|x64 55 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Release|x64.Build.0 = Release|x64 56 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Release|x86.ActiveCfg = Release|x86 57 | {0F468D5B-2F30-42F5-9043-920040D83D9D}.Release|x86.Build.0 = Release|x86 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(ExtensibilityGlobals) = postSolution 63 | SolutionGuid = {AD2EB45C-CBA4-435E-980E-DB67A74269BB} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /src/ModelMerger/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ModelMerger")] 9 | [assembly: AssemblyDescription("Model File Merger")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Philip/Scobalula")] 12 | [assembly: AssemblyProduct("ModelMerger")] 13 | [assembly: AssemblyCopyright("Copyright © Philip/Scobalula 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0ac36128-5fca-4d89-a1ae-9614412cd3fa")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.0.1.3")] 36 | [assembly: AssemblyFileVersion("0.0.1.3")] 37 | -------------------------------------------------------------------------------- /src/ModelMerger/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Scobalula/ModelMerger/b6ebc4fa7fc11902b59deee4fba1415ce376d59f/src/ModelMerger/icon.ico -------------------------------------------------------------------------------- /src/ModelMerger/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Scobalula/ModelMerger/b6ebc4fa7fc11902b59deee4fba1415ce376d59f/src/ModelMerger/icon.png -------------------------------------------------------------------------------- /src/PhilLibX/Bytes.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Bytes.cs 24 | // Author: Philip/Scobalula 25 | // Description: Utilities for working with Bytes and Bits 26 | using System; 27 | using System.Collections.Generic; 28 | using System.Runtime.InteropServices; 29 | using System.Text; 30 | 31 | namespace PhilLibX 32 | { 33 | /// 34 | /// Utilities for working with Bytes and Bits 35 | /// 36 | public static class Bytes 37 | { 38 | /// 39 | /// Reads a null terminated string from a byte array 40 | /// 41 | /// Byte Array input 42 | /// Start Index 43 | /// Resulting string 44 | public static string ReadNullTerminatedString(byte[] input, int startIndex) 45 | { 46 | List result = new List(); 47 | 48 | for (int i = startIndex; i < input.Length && input[i] != 0; i++) 49 | result.Add(input[i]); 50 | 51 | return Encoding.ASCII.GetString(result.ToArray()); 52 | } 53 | 54 | /// 55 | /// Gets the value of the bit at the given position 56 | /// 57 | /// Integer Input 58 | /// Position 59 | /// Result 60 | public static byte GetBit(long input, int bit) 61 | { 62 | return (byte)((input >> bit) & 1); 63 | } 64 | 65 | /// 66 | /// Converts an array of bytes to a struct 67 | /// 68 | /// Struct Type 69 | /// Raw data 70 | /// Resulting Structure 71 | public static T BytesToStruct(byte[] data) 72 | { 73 | // Get handles 74 | GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); 75 | T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); 76 | handle.Free(); 77 | // Return result 78 | return structure; 79 | } 80 | 81 | /// 82 | /// Converts an array of bytes to a struct 83 | /// 84 | /// Struct Type 85 | /// Raw data 86 | /// Start index to convert from 87 | /// Resulting Structure 88 | public static T BytesToStruct(byte[] data, int startIndex) 89 | { 90 | // Size of Struct 91 | int size = Marshal.SizeOf(); 92 | byte[] buffer = new byte[size]; 93 | Buffer.BlockCopy(data, startIndex, buffer, 0, size); 94 | // Return result 95 | return BytesToStruct(buffer); 96 | } 97 | 98 | /// 99 | /// Converts a structure to an array of bytes 100 | /// 101 | /// Struct Type 102 | /// Structure to convert 103 | /// Resulting byte array 104 | public static byte[] StructToBytes(T structure) 105 | { 106 | // Size of Struct 107 | int size = Marshal.SizeOf(); 108 | byte[] buffer = new byte[size]; 109 | IntPtr handle = Marshal.AllocHGlobal(size); 110 | Marshal.StructureToPtr(structure, handle, false); 111 | Marshal.Copy(handle, buffer, 0, size); 112 | Marshal.FreeHGlobal(handle); 113 | // Return result 114 | return buffer; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/PhilLibX/Cryptography/Hash/CRC32.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Cryptograhpy/Hash/CRC32.cs 24 | // Author: Philip/Scobalula 25 | // Description: Class to handle calculating CRC32 (While not exactly a "hash" algorithm, I have left it in here) 26 | using System.Text; 27 | 28 | namespace PhilLibX.Cryptography.Hash 29 | { 30 | /// 31 | /// Class to handle calculating CRC32 32 | /// 33 | public static class CRC32 34 | { 35 | /// 36 | /// CRC32 Table 37 | /// 38 | private static readonly uint[] CRC32Table = { 39 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 40 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 41 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 42 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 43 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 44 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 45 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 46 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 47 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 48 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 49 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 50 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 51 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 52 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 53 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 54 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 55 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 56 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 57 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 58 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 59 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 60 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 61 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 62 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 63 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 64 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 65 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 66 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 67 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 68 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 69 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 70 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 71 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 72 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 73 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 74 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 75 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 76 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 77 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 78 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 79 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 80 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 81 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; 82 | 83 | /// 84 | /// Calculates CRC32 for a given string. 85 | /// 86 | /// String to generate a hash from 87 | /// Resulting Unsigned CRC32 Value 88 | public static uint Calculate(string value) 89 | { 90 | return Calculate(Encoding.ASCII.GetBytes(value)); 91 | } 92 | 93 | /// 94 | /// Calculates CRC32 for a sequence of bytes. 95 | /// 96 | /// Bytes to generate a hash from 97 | /// Resulting Unsigned CRC32 Value 98 | public static uint Calculate(byte[] value) 99 | { 100 | // Resulting CRC32 101 | uint result = 0xFFFFFFFF; 102 | 103 | // Loop Bytes 104 | for(int i = 0; i < value.Length; i++) 105 | result = CRC32Table[(result ^ value[i]) & 0xff] ^ ((result) >> 8); 106 | 107 | // Return 108 | return ~result; 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/PhilLibX/Cryptography/Hash/DJB.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Cryptograhpy/Hash/DJB.cs 24 | // Author: Philip/Scobalula 25 | // Description: Class to handle calculating DJB Hash 26 | using System.Text; 27 | 28 | namespace PhilLibX.Cryptography.Hash 29 | { 30 | /// 31 | /// Class to handle calculating DJB Hash 32 | /// 33 | public static class DJB 34 | { 35 | /// 36 | /// Calculates DJB Hash for the given string. 37 | /// 38 | /// String to generate a hash from 39 | /// Initial Hash Value (Defaults to 0x1505/5381) 40 | /// Resulting Unsigned Hash Value 41 | public static uint Calculate(string value, uint initial = 0x1505) 42 | { 43 | return Calculate(Encoding.ASCII.GetBytes(value), initial); 44 | } 45 | 46 | /// 47 | /// Calculates DJB Hash for a sequence of bytes. 48 | /// 49 | /// Bytes to generate a hash from 50 | /// Initial Hash Value (Defaults to 0x1505/5381) 51 | /// Resulting Unsigned Hash Value 52 | public static uint Calculate(byte[] value, uint initial = 0x1505) 53 | { 54 | // Set INitial Value 55 | uint hash = initial; 56 | 57 | // Loop Bytes 58 | for (int i = 0; i < value.Length; i++) 59 | hash = ((hash << 5) + hash) + value[i]; 60 | 61 | // Result 62 | return hash; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/PhilLibX/Cryptography/Hash/FNV1a.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Cryptograhpy/Hash/FNV1a.cs 24 | // Author: Philip/Scobalula 25 | // Description: Class to handle calculating FNV1a Hash 26 | using System.Text; 27 | 28 | namespace PhilLibX.Cryptography.Hash 29 | { 30 | /// 31 | /// Class to handle calculating FNV1a Hash 32 | /// 33 | public static class FNV1a 34 | { 35 | /// 36 | /// Offset Basis for calculating 32bit FNV1a Hashes 37 | /// 38 | public const uint OffsetBasis32 = 0x811C9DC5; 39 | 40 | /// 41 | /// Offset Basis for calculating 64bit FNV1a Hashes 42 | /// 43 | public const ulong OffsetBasis64 = 0xCBF29CE484222325; 44 | 45 | 46 | /// 47 | /// Calculates 32Bit FNV1a Hash for a given string 48 | /// 49 | /// String to generate a hash from 50 | /// Initial Hash Value (Defaults to OffsetBasis32)) 51 | /// Resulting Unsigned Hash Value 52 | public static uint Calculate32(string value, uint initial = OffsetBasis32) 53 | { 54 | return Calculate32(Encoding.ASCII.GetBytes(value), initial); 55 | } 56 | 57 | /// 58 | /// Calculates 32Bit FNV1a Hash for a given string 59 | /// 60 | /// String to generate a hash from 61 | /// Initial Hash Value (Defaults to OffsetBasis32)) 62 | /// Resulting Unsigned Hash Value 63 | public static ulong Calculate64(string value, ulong initial = OffsetBasis64) 64 | { 65 | return Calculate64(Encoding.ASCII.GetBytes(value), initial); 66 | } 67 | 68 | /// 69 | /// Calculates 32Bit FNV1a Hash for a sequence of bytes. 70 | /// 71 | /// Bytes to generate a hash from 72 | /// Initial Hash Value (Defaults to OffsetBasis32)) 73 | /// Resulting Unsigned Hash Value 74 | public static uint Calculate32(byte[] value, uint initial = OffsetBasis32) 75 | { 76 | // Set Initial Value 77 | uint hash = initial; 78 | 79 | // Loop Bytes 80 | for (int i = 0; i < value.Length; i++) 81 | { 82 | hash ^= value[i]; 83 | hash *= 0x1000193; 84 | } 85 | 86 | // Return 87 | return hash; 88 | } 89 | 90 | /// 91 | /// Calculates 64Bit FNV1a Hash for a sequence of bytes. 92 | /// 93 | /// Bytes to generate a hash from 94 | /// Initial Hash Value (Defaults to OffsetBasis64)) 95 | /// Resulting Unsigned Hash Value 96 | public static ulong Calculate64(byte[] value, ulong initial = OffsetBasis64) 97 | { 98 | // Set Initial Value 99 | ulong hash = initial; 100 | 101 | // Loop Bytes 102 | for (int i = 0; i < value.Length; i++) 103 | { 104 | hash ^= value[i]; 105 | hash *= 0x100000001B3; 106 | } 107 | 108 | // Return 109 | return hash; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/PhilLibX/Cryptography/Hash/MurMur3.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Cryptograhpy/Hash/MurMur3.cs 24 | // Author: Philip/Scobalula 25 | // Description: Class to handle calculating MurMur3 Hash 26 | using System.IO; 27 | using System.Text; 28 | 29 | namespace PhilLibX.Cryptography.Hash 30 | { 31 | /// 32 | /// Class to handle calculating SDBM Hash 33 | /// 34 | public static class MurMur3 35 | { 36 | #region HelperFunctions 37 | private static uint Hash(Stream stream, uint seed) 38 | { 39 | const uint c1 = 0xcc9e2d51; 40 | const uint c2 = 0x1b873593; 41 | 42 | uint h1 = seed; 43 | uint k1 = 0; 44 | uint streamLength = 0; 45 | 46 | using (BinaryReader reader = new BinaryReader(stream)) 47 | { 48 | byte[] chunk = reader.ReadBytes(4); 49 | while (chunk.Length > 0) 50 | { 51 | streamLength += (uint)chunk.Length; 52 | switch (chunk.Length) 53 | { 54 | case 4: 55 | /* Get four bytes from the input into an uint */ 56 | k1 = (uint) 57 | (chunk[0] 58 | | chunk[1] << 8 59 | | chunk[2] << 16 60 | | chunk[3] << 24); 61 | 62 | /* bitmagic hash */ 63 | k1 *= c1; 64 | k1 = rotl32(k1, 15); 65 | k1 *= c2; 66 | 67 | h1 ^= k1; 68 | h1 = rotl32(h1, 13); 69 | h1 = h1 * 5 + 0xe6546b64; 70 | break; 71 | case 3: 72 | k1 = (uint) 73 | (chunk[0] 74 | | chunk[1] << 8 75 | | chunk[2] << 16); 76 | k1 *= c1; 77 | k1 = rotl32(k1, 15); 78 | k1 *= c2; 79 | h1 ^= k1; 80 | break; 81 | case 2: 82 | k1 = (uint) 83 | (chunk[0] 84 | | chunk[1] << 8); 85 | k1 *= c1; 86 | k1 = rotl32(k1, 15); 87 | k1 *= c2; 88 | h1 ^= k1; 89 | break; 90 | case 1: 91 | k1 = (uint)(chunk[0]); 92 | k1 *= c1; 93 | k1 = rotl32(k1, 15); 94 | k1 *= c2; 95 | h1 ^= k1; 96 | break; 97 | 98 | } 99 | chunk = reader.ReadBytes(4); 100 | } 101 | } 102 | 103 | // finalization, magic chants to wrap it all up 104 | h1 ^= streamLength; 105 | h1 = fmix(h1); 106 | 107 | return h1; 108 | } 109 | 110 | private static uint rotl32(uint x, byte r) 111 | { 112 | return (x << r) | (x >> (32 - r)); 113 | } 114 | 115 | private static uint fmix(uint h) 116 | { 117 | h ^= h >> 16; 118 | h *= 0x85ebca6b; 119 | h ^= h >> 13; 120 | h *= 0xc2b2ae35; 121 | h ^= h >> 16; 122 | return h; 123 | } 124 | #endregion 125 | 126 | /// 127 | /// Calculates MurMur3 Hash for the given string. 128 | /// 129 | /// String to generate a hash from 130 | /// Initial Hash Value (0) 131 | /// Resulting Unsigned Hash Value 132 | public static uint Calculate(string value, uint seed = 0xFFFFFFFF) 133 | { 134 | return Calculate(Encoding.ASCII.GetBytes(value), seed); 135 | } 136 | 137 | /// 138 | /// Calculates MurMur3 Hash for a sequence of bytes. 139 | /// 140 | /// Bytes to generate a hash from 141 | /// Initial Hash Value (Defaults to 0)) 142 | /// Resulting Unsigned Hash Value 143 | public static uint Calculate(byte[] value, uint seed = 0xFFFFFFFF) 144 | { 145 | // Return 146 | return Hash(new MemoryStream(value), seed); 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/PhilLibX/Cryptography/Hash/SDBM.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Cryptograhpy/Hash/SDBM.cs 24 | // Author: Philip/Scobalula 25 | // Description: Class to handle calculating SDBM Hash 26 | using System.Text; 27 | 28 | namespace PhilLibX.Cryptography.Hash 29 | { 30 | /// 31 | /// Class to handle calculating SDBM Hash 32 | /// 33 | public static class SDBM 34 | { 35 | /// 36 | /// Calculates SDBM Hash for the given string. 37 | /// 38 | /// String to generate a hash from 39 | /// Initial Hash Value (0) 40 | /// Resulting Unsigned Hash Value 41 | public static uint Calculate(string value, uint initial = 0) 42 | { 43 | return Calculate(Encoding.ASCII.GetBytes(value), initial); 44 | } 45 | 46 | /// 47 | /// Calculates SDBM Hash for a sequence of bytes. 48 | /// 49 | /// Bytes to generate a hash from 50 | /// Initial Hash Value (Defaults to 0)) 51 | /// Resulting Unsigned Hash Value 52 | public static uint Calculate(byte[] value, uint initial = 0) 53 | { 54 | // Set INitial Value 55 | uint hash = initial; 56 | 57 | // Loop Bytes 58 | for (int i = 0; i < value.Length; i++) 59 | hash = value[i] + (hash << 6) + (hash << 16) - hash; 60 | 61 | // Return 62 | return hash; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/PhilLibX/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace PhilLibX 8 | { 9 | /// 10 | /// A class with Enumerable Extensions 11 | /// 12 | public static class EnumerableExtensions 13 | { 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | /// 21 | public static TSource FirstOrDefault(this IEnumerable source, TSource start, Func predicate) 22 | { 23 | if (source == null) throw new ArgumentNullException("source"); 24 | if (predicate == null) throw new ArgumentNullException("predicate"); 25 | 26 | foreach (TSource element in source) 27 | if (predicate(element)) return element; 28 | 29 | return start; 30 | } 31 | 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// 37 | /// 38 | /// 39 | public static TSource LastOrDefault(this IEnumerable source, TSource defaultVal, Func predicate) 40 | { 41 | if (source == null) throw new ArgumentNullException("source"); 42 | if (predicate == null) throw new ArgumentNullException("predicate"); 43 | 44 | TSource result = defaultVal; 45 | 46 | foreach (TSource element in source) 47 | { 48 | if (predicate(element)) 49 | { 50 | result = element; 51 | } 52 | } 53 | 54 | return result; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/PhilLibX/IO/BinaryReaderExtensions.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: IO/BinaryReaderExtensions.cs 24 | // Author: Philip/Scobalula 25 | // Description: BinaryReader extensions for reading null terminated strings, scanning files, etc. 26 | using System; 27 | using System.Collections.Generic; 28 | using System.IO; 29 | using System.Runtime.InteropServices; 30 | using System.Text; 31 | 32 | namespace PhilLibX.IO 33 | { 34 | /// 35 | /// IO Utilities/Extensions 36 | /// 37 | public static class BinaryReaderExtensions 38 | { 39 | /// 40 | /// Reads a string terminated by a null byte 41 | /// 42 | /// Read String 43 | public static string ReadNullTerminatedString(this BinaryReader br, int maxSize = -1) 44 | { 45 | // Create String Builder 46 | StringBuilder str = new StringBuilder(); 47 | // Current Byte Read 48 | int byteRead; 49 | // Size of String 50 | int size = 0; 51 | // Loop Until we hit terminating null character 52 | while ((byteRead = br.BaseStream.ReadByte()) != 0x0 && size++ != maxSize) 53 | str.Append(Convert.ToChar(byteRead)); 54 | // Ship back Result 55 | return str.ToString(); 56 | } 57 | 58 | /// 59 | /// Reads a string terminated by a null byte 60 | /// 61 | /// Reader 62 | /// Absolute offset of the string 63 | /// Max size of the string to read 64 | /// Resulting string 65 | public static string ReadNullTerminatedString(this BinaryReader br, long offset, int maxSize = -1) 66 | { 67 | long currentOffset = br.BaseStream.Position; 68 | br.BaseStream.Position = offset; 69 | var result = br.ReadNullTerminatedString(maxSize); 70 | br.BaseStream.Position = currentOffset; 71 | return result; 72 | } 73 | 74 | 75 | /// 76 | /// Reads a UTF16 string terminated by a null byte 77 | /// 78 | /// Read String 79 | public static string ReadUTF16NullTerminatedString(this BinaryReader br, int maxSize = -1) 80 | { 81 | // Create String Builder 82 | StringBuilder str = new StringBuilder(); 83 | // Current Byte Read 84 | ushort byteRead; 85 | // Size of String 86 | int size = 0; 87 | // Loop Until we hit terminating null character 88 | while ((byteRead = br.ReadUInt16()) != 0x0 && size++ != maxSize) 89 | str.Append(Convert.ToChar(byteRead)); 90 | // Ship back Result 91 | return str.ToString(); 92 | } 93 | 94 | /// 95 | /// Reads a UTF16 string terminated by a null byte 96 | /// 97 | /// Reader 98 | /// Absolute offset of the string 99 | /// Max size of the string to read 100 | /// Resulting string 101 | public static string ReadUTF16NullTerminatedString(this BinaryReader br, long offset, int maxSize = -1) 102 | { 103 | long currentOffset = br.BaseStream.Position; 104 | br.BaseStream.Position = offset; 105 | var result = br.ReadUTF16NullTerminatedString(maxSize); 106 | br.BaseStream.Position = currentOffset; 107 | return result; 108 | } 109 | 110 | /// 111 | /// Reads a string of fixed size 112 | /// 113 | /// Reader 114 | /// Size of string in bytes 115 | /// Read String 116 | public static string ReadFixedString(this BinaryReader br, int numBytes) 117 | { 118 | // Purge Null Bytes and Return 119 | return Encoding.ASCII.GetString(br.ReadBytes(numBytes)).TrimEnd('\0'); 120 | } 121 | 122 | /// 123 | /// Reads a string of fixed size 124 | /// 125 | /// Reader 126 | /// Absolute offset of the string 127 | /// Size of string in bytes 128 | /// Read String 129 | public static string ReadFixedString(this BinaryReader br, long offset, int numBytes) 130 | { 131 | long currentOffset = br.BaseStream.Position; 132 | br.BaseStream.Position = offset; 133 | var result = br.ReadFixedString(numBytes); 134 | br.BaseStream.Position = currentOffset; 135 | return result; 136 | } 137 | 138 | /// 139 | /// Reads an array of the given type 140 | /// 141 | /// Type 142 | /// Reader 143 | /// Number of items 144 | /// Resulting array 145 | public static T[] ReadArray(this BinaryReader br, int count) 146 | { 147 | // Get Byte Count 148 | var size = count * Marshal.SizeOf(); 149 | // Allocate Array 150 | var result = new T[count]; 151 | // Check for primitives, we can use BlockCopy for them 152 | if (typeof(T).IsPrimitive) 153 | { 154 | // Copy 155 | Buffer.BlockCopy(br.ReadBytes(size), 0, result, 0, size); 156 | } 157 | // Slightly more complex structures, we can use the struct functs 158 | else 159 | { 160 | // Loop through 161 | for (int i = 0; i < count; i++) 162 | { 163 | // Read it into result 164 | result[i] = br.ReadStruct(); 165 | } 166 | } 167 | // Done 168 | return result; 169 | } 170 | 171 | /// 172 | /// Reads an array of the given type 173 | /// 174 | /// Type 175 | /// Reader 176 | /// Absolute offset of the string 177 | /// Number of items 178 | /// Resulting array 179 | public static T[] ReadArray(this BinaryReader br, long offset, int count) 180 | { 181 | long currentOffset = br.BaseStream.Position; 182 | br.BaseStream.Position = offset; 183 | var result = br.ReadArray(count); 184 | br.BaseStream.Position = currentOffset; 185 | return result; 186 | } 187 | 188 | /// 189 | /// Reads the given structure from the reader 190 | /// 191 | /// 192 | /// 193 | /// 194 | public static T ReadStruct(this BinaryReader br) 195 | { 196 | byte[] data = br.ReadBytes(Marshal.SizeOf()); 197 | GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); 198 | T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); 199 | handle.Free(); 200 | return theStructure; 201 | } 202 | 203 | /// 204 | /// Reads the given structure from the reader 205 | /// 206 | /// Absolute offset of the string 207 | /// 208 | /// 209 | /// 210 | public static T ReadStruct(this BinaryReader br, long offset) 211 | { 212 | long currentOffset = br.BaseStream.Position; 213 | br.BaseStream.Position = offset; 214 | var result = br.ReadStruct(); 215 | br.BaseStream.Position = currentOffset; 216 | return result; 217 | } 218 | 219 | /// 220 | /// Sets the position of the Base Stream 221 | /// 222 | /// 223 | /// Offset to seek to. 224 | /// Seek Origin 225 | public static void Seek(this BinaryReader br, long offset, SeekOrigin seekOrigin) 226 | { 227 | // Set stream position 228 | br.BaseStream.Seek(offset, seekOrigin); 229 | } 230 | 231 | /// 232 | /// Finds occurences of a string in the stream 233 | /// 234 | /// Reader to use for scanning 235 | /// String Needle to search for 236 | /// Stops at first result 237 | /// Resulting offsets 238 | public static long[] FindString(this BinaryReader br, string needle, bool firstOccurence = false) 239 | { 240 | // Convert to bytes and scan 241 | return br.FindBytes(Encoding.ASCII.GetBytes(needle), firstOccurence); 242 | } 243 | 244 | /// 245 | /// Reads a 4-byte big endian signed integer from the current stream and advances the current position of the stream by four bytes. 246 | /// 247 | /// Reader 248 | /// Resulting 32Bit Integer 249 | public static int ReadBEInt32(this BinaryReader br) 250 | { 251 | // Read bytes 252 | byte[] buffer = br.ReadBytes(4); 253 | // Return resulting 4 byte int 254 | return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; 255 | } 256 | 257 | /// 258 | /// Reads a 3-byte big endian signed integer from the current stream and advances the current position of the stream by three bytes. 259 | /// 260 | /// Reader 261 | /// Resulting 32Bit Integer 262 | public static int ReadBEInt24(this BinaryReader br) 263 | { 264 | // Read bytes 265 | byte[] buffer = br.ReadBytes(3); 266 | // Return resulting 3 byte int 267 | return (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]); 268 | } 269 | 270 | /// 271 | /// Reads a variable length integer from the current stream 272 | /// 273 | /// Reader 274 | /// Resulting 32Bit Integer 275 | public static int Read7BitEncodedInt(this BinaryReader br) 276 | { 277 | int result = 0; 278 | int shift = 0; 279 | 280 | // Loop until the high bit is 0 281 | while (true) 282 | { 283 | byte value = br.ReadByte(); 284 | result |= (value & 0x7F) << shift; 285 | 286 | if ((value & 0x80) == 0) return result; 287 | 288 | shift += 7; 289 | } 290 | } 291 | 292 | /// 293 | /// Finds occurences of bytes 294 | /// 295 | /// Reader 296 | /// Byte Array Needle to search for 297 | /// Stops at first result 298 | /// Resulting offsets 299 | public static long[] FindBytes(this BinaryReader br, byte[] needle, bool firstOccurence = false) 300 | { 301 | // List of offsets in file. 302 | List offsets = new List(); 303 | 304 | // Buffer 305 | byte[] buffer = new byte[1048576]; 306 | 307 | // Bytes Read 308 | int bytesRead = 0; 309 | 310 | // Starting Offset 311 | long readBegin = br.BaseStream.Position; 312 | 313 | // Needle Index 314 | int needleIndex = 0; 315 | 316 | // Byte Array Index 317 | int bufferIndex = 0; 318 | 319 | // Read chunk of file 320 | while ((bytesRead = br.BaseStream.Read(buffer, 0, buffer.Length)) != 0) 321 | { 322 | // Loop through byte array 323 | for (bufferIndex = 0; bufferIndex < bytesRead; bufferIndex++) 324 | { 325 | // Check if current bytes match 326 | if (needle[needleIndex] == buffer[bufferIndex]) 327 | { 328 | // Increment 329 | needleIndex++; 330 | 331 | // Check if we have a match 332 | if (needleIndex == needle.Length) 333 | { 334 | // Add Offset 335 | offsets.Add(readBegin + bufferIndex + 1 - needle.Length); 336 | 337 | // Reset Index 338 | needleIndex = 0; 339 | 340 | // If only first occurence, end search 341 | if (firstOccurence) 342 | return offsets.ToArray(); 343 | } 344 | } 345 | else 346 | { 347 | // Reset Index 348 | needleIndex = 0; 349 | } 350 | } 351 | // Set next offset 352 | readBegin += bytesRead; 353 | } 354 | // Return offsets as an array 355 | return offsets.ToArray(); 356 | } 357 | } 358 | } 359 | -------------------------------------------------------------------------------- /src/PhilLibX/IO/BinaryWriterExtensions.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: IO/BinaryWriterExtensions.cs 24 | // Author: Philip/Scobalula 25 | // Description: BinaryReader extensions for writing null terminated strings, structures, etc. 26 | using System; 27 | using System.Collections.Generic; 28 | using System.IO; 29 | using System.Runtime.InteropServices; 30 | using System.Text; 31 | 32 | namespace PhilLibX.IO 33 | { 34 | /// 35 | /// IO Utilities/Extensions 36 | /// 37 | public static class BinaryWriterExtensions 38 | { 39 | /// 40 | /// Writes a null terminated string 41 | /// 42 | /// Output Stream 43 | /// Value to write 44 | public static void WriteNullTerminatedString(this BinaryWriter bw, string value) 45 | { 46 | bw.Write(Encoding.UTF8.GetBytes(value)); 47 | bw.Write((byte)0); 48 | } 49 | 50 | /// 51 | /// Writes a UTF16 null terminated string 52 | /// 53 | /// Output Stream 54 | /// Value to write 55 | public static void WriteNullTerminatedUTF16String(this BinaryWriter bw, string value) 56 | { 57 | bw.Write(Encoding.Unicode.GetBytes(value)); 58 | bw.Write((byte)0); 59 | } 60 | 61 | /// 62 | /// Writes the given structure 63 | /// 64 | /// 65 | /// 66 | /// 67 | public static void WriteStruct(this BinaryWriter bw, T value) 68 | { 69 | bw.Write(Bytes.StructToBytes(value)); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/PhilLibX/IO/MemoryUtility.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: IO/MemoryUtil.cs 24 | // Author: Philip/Scobalula 25 | // Description: Utilities for Reading/Writing to/from Process Memory 26 | using System; 27 | using System.Collections.Generic; 28 | using System.ComponentModel; 29 | using System.Runtime.CompilerServices; 30 | using System.Runtime.InteropServices; 31 | using System.Text; 32 | using System.Xml.XPath; 33 | 34 | namespace PhilLibX.IO 35 | { 36 | /// 37 | /// Utilities for Reading/Writing to/from Process Memory 38 | /// 39 | public static class MemoryUtil 40 | { 41 | /// 42 | /// Required to read memory in a process using ReadProcessMemory. 43 | /// 44 | public const int ProcessVMRead = 0x0010; 45 | 46 | /// 47 | /// Required to write to memory in a process using WriteProcessMemory. 48 | /// 49 | public const int ProcessVMWrite = 0x0020; 50 | 51 | /// 52 | /// Required to perform an operation on the address space of a process 53 | /// 54 | public const int ProcessVMOperation = 0x0008; 55 | 56 | /// 57 | /// Reads bytes from a Processes Memory and returns a byte array of read data. 58 | /// 59 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 60 | /// The address of the data to be read. 61 | /// The number of bytes to be read from the specified process. 62 | /// Bytes read 63 | public static byte[] ReadBytes(IntPtr processHandle, long address, int numBytes) 64 | { 65 | // Resulting buffer 66 | byte[] buffer = new byte[numBytes]; 67 | // Request ReadProcessMemory 68 | NativeMethods.ReadProcessMemory((int)processHandle, address, buffer, buffer.Length, out int bytesRead); 69 | // Return result 70 | return buffer; 71 | } 72 | 73 | /// 74 | /// Reads bytes from a Processes Memory and returns a byte array of read data. 75 | /// 76 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 77 | /// The address of the data to be read. 78 | /// The number of bytes to be read from the specified process. 79 | /// The number of bytes to be read from the specified process. 80 | /// Bytes read 81 | public unsafe static void ReadBytes(IntPtr processHandle, long address, int numBytes, byte* buffer) 82 | { 83 | // Request ReadProcessMemory 84 | NativeMethods.ReadProcessMemory((int)processHandle, address, buffer, numBytes, out int bytesRead); 85 | } 86 | 87 | /// 88 | /// Reads a 64Bit Integer from a Processes Memory 89 | /// 90 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 91 | /// The address of the data to be read. 92 | /// Resulting Data 93 | public static long ReadInt64(IntPtr processHandle, long address) 94 | { 95 | return BitConverter.ToInt64(ReadBytes(processHandle, address, 8), 0); 96 | } 97 | 98 | /// 99 | /// Reads an unsigned 64Bit Integer from a Processes Memory 100 | /// 101 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 102 | /// The address of the data to be read. 103 | /// Resulting Data 104 | public static ulong ReadUInt64(IntPtr processHandle, long address) 105 | { 106 | return BitConverter.ToUInt64(ReadBytes(processHandle, address, 8), 0); 107 | } 108 | 109 | /// 110 | /// Reads a 32Bit Integer from a Processes Memory 111 | /// 112 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 113 | /// The address of the data to be read. 114 | /// Resulting Data 115 | public static int ReadInt32(IntPtr processHandle, long address) 116 | { 117 | return BitConverter.ToInt32(ReadBytes(processHandle, address, 4), 0); 118 | } 119 | 120 | /// 121 | /// Reads an unsigned 32Bit Integer from a Processes Memory 122 | /// 123 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 124 | /// The address of the data to be read. 125 | /// Resulting Data 126 | public static uint ReadUInt32(IntPtr processHandle, long address) 127 | { 128 | return BitConverter.ToUInt32(ReadBytes(processHandle, address, 4), 0); 129 | } 130 | 131 | /// 132 | /// Reads a 16Bit Integer from a Processes Memory 133 | /// 134 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 135 | /// The address of the data to be read. 136 | /// Resulting Data 137 | public static short ReadInt16(IntPtr processHandle, long address) 138 | { 139 | return BitConverter.ToInt16(ReadBytes(processHandle, address, 4), 0); 140 | } 141 | 142 | /// 143 | /// Reads an unsigned 16Bit Integer from a Processes Memory 144 | /// 145 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 146 | /// The address of the data to be read. 147 | /// Resulting Data 148 | public static ushort ReadUInt16(IntPtr processHandle, long address) 149 | { 150 | return BitConverter.ToUInt16(ReadBytes(processHandle, address, 2), 0); 151 | } 152 | 153 | /// 154 | /// Reads a 4 byte single precision floating point number from a Processes Memory 155 | /// 156 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 157 | /// The address of the data to be read. 158 | /// Resulting Data 159 | public static float ReadSingle(IntPtr processHandle, long address) 160 | { 161 | return BitConverter.ToSingle(ReadBytes(processHandle, address, 4), 0); 162 | } 163 | 164 | /// 165 | /// Reads an 8 byte double precision floating point number from a Processes Memory 166 | /// 167 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 168 | /// The address of the data to be read. 169 | /// Resulting Data 170 | public static double ReadDouble(IntPtr processHandle, long address) 171 | { 172 | return BitConverter.ToDouble(ReadBytes(processHandle, address, 8), 0); 173 | } 174 | 175 | /// 176 | /// Reads a string from a processes' memory terminated by a null byte. 177 | /// 178 | /// Process Handle Pointer 179 | /// Memory Address 180 | /// Buffer Read Size 181 | /// Resulting String 182 | public unsafe static string ReadNullTerminatedString(IntPtr processHandle, long address, int bufferSize = 512) 183 | { 184 | var result = stackalloc byte[bufferSize]; 185 | ReadBytes(processHandle, address, bufferSize, (byte*)result); 186 | int sizeOf; 187 | for(sizeOf = 0; sizeOf < bufferSize; sizeOf++) 188 | { 189 | if (result[sizeOf] == 0x0) 190 | break; 191 | } 192 | return Encoding.ASCII.GetString(result, sizeOf); 193 | } 194 | 195 | /// 196 | /// Reads a struct from a Processes Memory 197 | /// 198 | /// Struct Type 199 | /// Process Handle Pointer 200 | /// Memory Address 201 | /// Resulting Struct 202 | public static T ReadStruct(IntPtr processHandle, long address) 203 | { 204 | byte[] data = ReadBytes(processHandle, address, Marshal.SizeOf()); 205 | GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); 206 | T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); 207 | handle.Free(); 208 | return theStructure; 209 | } 210 | 211 | /// 212 | /// Searches for bytes in a processes memory. 213 | /// 214 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 215 | /// Byte Sequence to scan for. 216 | /// Address to start the search at. 217 | /// Address to end the search at. 218 | /// Byte Buffer Size 219 | /// If we should stop the search at the first result. 220 | /// 221 | public unsafe static long[] FindBytes(IntPtr processHandle, byte?[] needle, long startAddress, long endAddress, bool firstMatch = false, int bufferSize = 0xFFFF) 222 | { 223 | List results = new List(); 224 | long searchAddress = startAddress; 225 | 226 | int needleIndex = 0; 227 | int bufferIndex = 0; 228 | 229 | while (true) 230 | { 231 | try 232 | { 233 | byte[] buffer = ReadBytes(processHandle, searchAddress, bufferSize); 234 | 235 | fixed(byte* p = buffer) 236 | { 237 | for (bufferIndex = 0; bufferIndex < buffer.Length; bufferIndex++) 238 | { 239 | if (needle[needleIndex] == null) 240 | { 241 | needleIndex++; 242 | continue; 243 | } 244 | 245 | if (needle[needleIndex] == p[bufferIndex]) 246 | { 247 | needleIndex++; 248 | 249 | if (needleIndex == needle.Length) 250 | { 251 | results.Add(searchAddress + bufferIndex - needle.Length + 1); 252 | 253 | if (firstMatch) 254 | return results.ToArray(); 255 | 256 | needleIndex = 0; 257 | } 258 | } 259 | else 260 | { 261 | needleIndex = 0; 262 | } 263 | } 264 | } 265 | } 266 | catch 267 | { 268 | break; 269 | } 270 | 271 | searchAddress += bufferSize; 272 | 273 | if (searchAddress > endAddress) 274 | break; 275 | } 276 | 277 | return results.ToArray(); 278 | } 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /src/PhilLibX/IO/ProcessWriter.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: IO/ProcessWriter.cs 24 | // Author: Philip/Scobalula 25 | // Description: A class to help with writing to the memory of other processes. 26 | using System; 27 | using System.ComponentModel; 28 | using System.Diagnostics; 29 | using System.Runtime.InteropServices; 30 | 31 | // TODO: Extend on this 32 | 33 | namespace PhilLibX.IO 34 | { 35 | /// 36 | /// A class to help with writing to the memory of other processes. 37 | /// 38 | public class ProcessWriter 39 | { 40 | /// 41 | /// Internal Process Property 42 | /// 43 | private Process _Process { get; set; } 44 | 45 | /// 46 | /// Internal Handle Property 47 | /// 48 | private IntPtr _Handle { get; set; } 49 | 50 | /// 51 | /// Active Process 52 | /// 53 | public Process ActiveProcess 54 | { 55 | get { return _Process; } 56 | set 57 | { 58 | _Process = value; 59 | _Handle = NativeMethods.OpenProcess(MemoryUtil.ProcessVMOperation | MemoryUtil.ProcessVMWrite, false, _Process.Id); 60 | } 61 | } 62 | 63 | /// 64 | /// Active Process Handle 65 | /// 66 | public IntPtr Handle { get { return _Handle; } } 67 | 68 | /// 69 | /// Initalizes a Process Reader with a Process 70 | /// 71 | public ProcessWriter(Process process) 72 | { 73 | ActiveProcess = process; 74 | } 75 | 76 | /// 77 | /// Writes bytes to the processes' memory 78 | /// 79 | /// 80 | /// 81 | public void WriteBytes(long address, byte[] buffer) 82 | { 83 | if (!NativeMethods.WriteProcessMemory((int)Handle, address, buffer, buffer.Length, out int bytesRead)) 84 | { 85 | // throw new ArgumentException(new Win32Exception(Marshal.GetLastWin32Error()).Message); 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/PhilLibX/Imaging/BitmapX.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Imaging/BitmapX.cs 24 | // Author: Philip/Scobalula 25 | // Description: Faster Bitmap Processing 26 | using System; 27 | using System.Drawing; 28 | using System.Drawing.Imaging; 29 | using System.IO; 30 | using System.Linq; 31 | using System.Runtime.InteropServices; 32 | 33 | namespace PhilLibX.Imaging 34 | { 35 | /// 36 | /// Faster Bitmap Processing 37 | /// 38 | public class BitmapX : IDisposable 39 | { 40 | /// 41 | /// Accepted Bits Per Pixel (for now we only support 24 and 32bpp 42 | /// 43 | public static readonly int[] AcceptedBitsPerPixel = 44 | { 45 | 24, 46 | 32, 47 | }; 48 | 49 | /// 50 | /// Pixel Data Pointer 51 | /// 52 | private IntPtr PixelDataPointer { get; set; } 53 | 54 | /// 55 | /// Raw Pixel Data 56 | /// 57 | private byte[] Pixels { get; set; } 58 | 59 | /// 60 | /// Source Bitmap Object 61 | /// 62 | private Bitmap BitmapSource { get; set; } 63 | 64 | /// 65 | /// Source Bitmap Data Object 66 | /// 67 | private BitmapData BitmapDataSource { get; set; } 68 | 69 | /// 70 | /// Internal Bits Per Pizel Value 71 | /// 72 | private int _BitsPerPixel { get; set; } 73 | 74 | /// 75 | /// Internal Bitmap Width Value 76 | /// 77 | private int _Width { get; set; } 78 | 79 | /// 80 | /// Internal Bitmap Height Value 81 | /// 82 | private int _Height { get; set; } 83 | 84 | /// 85 | /// Bitmap Width 86 | /// 87 | public int Width { get { return _Width; } } 88 | 89 | /// 90 | /// Bitmap Height 91 | /// 92 | public int Height { get { return _Height; } } 93 | 94 | /// 95 | /// Number of bits per pixel. (24, 96 | /// 97 | public int BitsPerPixel { get { return _BitsPerPixel; } } 98 | 99 | /// 100 | /// Number of bits per pixel. (24, 101 | /// 102 | public int BytesPerPixel { get { return BitsPerPixel / 8; } } 103 | 104 | /// 105 | /// Pixel Count 106 | /// 107 | public int PixelCount { get { return Width * Height; } } 108 | 109 | /// 110 | /// Initializes BitmapX with a new Bitmap 111 | /// 112 | /// Pixel Width 113 | /// Pixel Height 114 | /// Pixel Format (32bpp ARGB by Default) 115 | public BitmapX(int width, int height, PixelFormat pixelFormat = PixelFormat.Format32bppArgb) 116 | { 117 | LoadBitmap(new Bitmap(width, height, pixelFormat)); 118 | } 119 | 120 | /// 121 | /// Initializes BitmapX with a file 122 | /// 123 | /// Path to image file 124 | public BitmapX(string fileName) 125 | { 126 | LoadBitmap(new Bitmap(fileName)); 127 | } 128 | 129 | /// 130 | /// Initializes BitmapX with an Image 131 | /// 132 | /// Existing Image Object 133 | public BitmapX(Image image) 134 | { 135 | LoadBitmap(new Bitmap(image)); 136 | } 137 | 138 | /// 139 | /// Initializes BitmapX with a Stream 140 | /// 141 | /// Stream with Image data 142 | public BitmapX(Stream stream) 143 | { 144 | LoadBitmap(new Bitmap(stream)); 145 | } 146 | 147 | /// 148 | /// Initializes BitmapX with a Bitmap 149 | /// 150 | /// Bitmap Source 151 | public BitmapX(Bitmap bitmap) 152 | { 153 | LoadBitmap(bitmap); 154 | } 155 | 156 | /// 157 | /// Loads a Bitmap into the BitmapX 158 | /// 159 | /// Bitmap Source 160 | public void LoadBitmap(Bitmap bitmap) 161 | { 162 | // Dispose the Original if exists 163 | BitmapSource?.Dispose(); 164 | 165 | // Get Bpp 166 | _BitsPerPixel = Image.GetPixelFormatSize(bitmap.PixelFormat); 167 | 168 | // Check for supported Bpp 169 | if (!AcceptedBitsPerPixel.Contains(BitsPerPixel)) 170 | throw new ArgumentException("Unsupported Bitmap Pixel Size: " + BitsPerPixel.ToString()); 171 | 172 | // Set Bitmap 173 | BitmapSource = bitmap; 174 | 175 | // Set Width + Height 176 | _Width = BitmapSource.Width; 177 | _Height = BitmapSource.Height; 178 | 179 | LockBits(); 180 | } 181 | 182 | /// 183 | /// Locks the Bits of the Source Bitmap 184 | /// 185 | public void LockBits() 186 | { 187 | // Lock the Bits 188 | BitmapDataSource = BitmapSource.LockBits( 189 | new Rectangle(0, 0, BitmapSource.Width, BitmapSource.Height), 190 | ImageLockMode.ReadWrite, 191 | BitmapSource.PixelFormat); 192 | 193 | // Set Pixel Array 194 | Pixels = new byte[PixelCount * BytesPerPixel]; 195 | 196 | // Set Pixel Pointer 197 | PixelDataPointer = BitmapDataSource.Scan0; 198 | 199 | // Copy the Data, maintain safe code using Marshal instead of accessing the raw pointer 200 | Marshal.Copy(PixelDataPointer, Pixels, 0, Pixels.Length); 201 | } 202 | 203 | /// 204 | /// Unlocks the Bits of the Source Image 205 | /// 206 | public void UnlockBits() 207 | { 208 | // Copy the Data, maintain safe code using Marshal instead of accessing the raw pointer 209 | Marshal.Copy(Pixels, 0, PixelDataPointer, Pixels.Length); 210 | 211 | // Unlock bitmap data 212 | BitmapSource.UnlockBits(BitmapDataSource); 213 | } 214 | 215 | /// 216 | /// Gets Color at the given Pixel 217 | /// 218 | /// X Coordinate 219 | /// Y Coordinate 220 | /// Resulting Color 221 | public Color GetPixel(int x, int y) 222 | { 223 | // Get Position of the Pixe, based off Bpp 224 | int pixelIndex = ((y * Width) + x) * BytesPerPixel; 225 | 226 | // Convert to Color, only take Alpha if we're 32Bpp 227 | Color result = Color.FromArgb( 228 | // Alpha 229 | BitsPerPixel == 32 ? Pixels[pixelIndex + 3] : 255, 230 | // Red 231 | Pixels[pixelIndex + 2], 232 | // Green 233 | Pixels[pixelIndex + 1], 234 | // Blue 235 | Pixels[pixelIndex]); 236 | 237 | // Ship back the result 238 | return result; 239 | } 240 | 241 | /// 242 | /// Sets Color at the given Pixel 243 | /// 244 | /// X Coordinate 245 | /// Y Coordinate 246 | /// Color to set 247 | public void SetPixel(int x, int y, Color color) 248 | { 249 | // Get Position of the Pixe, based off Bpp 250 | int pixelIndex = ((y * Width) + x) * BytesPerPixel; 251 | 252 | // Set Pixel Data 253 | // Blue 254 | Pixels[pixelIndex] = color.B; 255 | // Green 256 | Pixels[pixelIndex + 1] = color.G; 257 | // Red 258 | Pixels[pixelIndex + 2] = color.R; 259 | 260 | // Set Alpha only if we're 32Bpp 261 | if (BitsPerPixel == 32) 262 | Pixels[pixelIndex + 3] = color.A; 263 | } 264 | 265 | /// 266 | /// Saves the BitmapX to the given path 267 | /// 268 | /// File path to save to 269 | /// Whether or not to relock the bits after unlocking 270 | public void Save(string filePath, bool relockBits = true) 271 | { 272 | // Unlock the Bits 273 | UnlockBits(); 274 | 275 | 276 | // Save the Bitmap 277 | BitmapSource.Save(filePath); 278 | 279 | 280 | // Check if we must relock the bits 281 | if (relockBits) LockBits(); 282 | } 283 | 284 | /// 285 | /// Checks if this image is 1 color 286 | /// 287 | /// False if has pixel differences, otherwise True 288 | public bool IsSingleColor() 289 | { 290 | // Color trackers 291 | int previousColor = 0; 292 | int pixel; 293 | 294 | // Get initial pixel 295 | for (int i = 0; i < BytesPerPixel; i++) 296 | previousColor += Pixels[i]; 297 | 298 | // Loop pixels 299 | for (int i = 0; i < PixelCount; i += BytesPerPixel) 300 | { 301 | // Initial Value 302 | pixel = 0; 303 | 304 | // Sum values 305 | for (int j = 0; j < BytesPerPixel; j++) 306 | pixel += Pixels[i + j]; 307 | 308 | // Compare 309 | if (previousColor != pixel) 310 | return false; 311 | 312 | // Set for next comparison 313 | previousColor = pixel; 314 | } 315 | 316 | // All 1 color if we got here 317 | return true; 318 | } 319 | 320 | /// 321 | /// Checks if this image has colors greater than the given values 322 | /// 323 | /// 324 | /// 325 | /// 326 | /// 327 | public bool HasColorsGreaterThan(int rValue, int bValue, int gValue) 328 | { 329 | // Color Values to compare 330 | int[] colorCheck = 331 | { 332 | rValue, 333 | bValue, 334 | gValue 335 | }; 336 | 337 | // Loop pixels 338 | for (int i = 0; i < Pixels.Length; i += BytesPerPixel) 339 | for (int j = 0; j < 3; j++) 340 | if (Pixels[i + j] >= colorCheck[j]) 341 | return true; 342 | 343 | // All 1 color if we got here 344 | return false; 345 | } 346 | 347 | /// 348 | /// Checks if this image is monochrome 349 | /// 350 | /// False if has pixel differences, otherwise True 351 | public bool IsMonochrome() 352 | { 353 | // Loop pixels 354 | for (int i = 0; i < PixelCount; i += BytesPerPixel) 355 | { 356 | // We only care about actual color values 357 | if ( 358 | Pixels[i] != Pixels[i + 1] || 359 | Pixels[i] != Pixels[i + 2] || 360 | Pixels[i + 1] != Pixels[i + 2]) 361 | return false; 362 | } 363 | 364 | // All 1 color if we got here 365 | return true; 366 | } 367 | 368 | /// 369 | /// Disposes of the BitmapX Object 370 | /// 371 | public void Dispose() 372 | { 373 | // Dispose the Bitmap 374 | BitmapSource?.Dispose(); 375 | } 376 | } 377 | } 378 | -------------------------------------------------------------------------------- /src/PhilLibX/Logger.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Logger.cs 24 | // Author: Philip/Scobalula 25 | // Description: Basic Logging Utilities 26 | using System; 27 | using System.IO; 28 | using System.Text; 29 | 30 | namespace PhilLibX 31 | { 32 | /// 33 | /// Basic Logging Class 34 | /// 35 | public class Logger : IDisposable 36 | { 37 | /// 38 | /// Message Types for logging 39 | /// 40 | public enum MessageType 41 | { 42 | INFO, 43 | WARNING, 44 | ERROR, 45 | } 46 | 47 | /// 48 | /// Log File Name 49 | /// 50 | public string LogFile { get; set; } 51 | 52 | /// 53 | /// Current Log Name 54 | /// 55 | private string LogName { get; set; } 56 | 57 | /// 58 | /// Active Stream 59 | /// 60 | private StringBuilder Buffer = new StringBuilder(); 61 | 62 | /// 63 | /// Initiate Logger 64 | /// 65 | /// Log Name 66 | /// Log File Name 67 | public Logger(string logName, string fileName) 68 | { 69 | // Set properties 70 | LogFile = fileName; 71 | LogName = logName; 72 | 73 | // Write Initial 74 | Write(LogName, MessageType.INFO); 75 | 76 | // Close 77 | Flush(); 78 | } 79 | 80 | /// 81 | /// Writes a message to the log 82 | /// 83 | /// 84 | /// 85 | public void Write(object message, MessageType messageType) 86 | { 87 | // Write to file 88 | lock(Buffer) 89 | { 90 | Buffer.AppendLine(string.Format("{0} [ {1} ] {2}", DateTime.Now.ToString("dd-MM-yyyy - HH:mm:ss"), messageType, message)); 91 | } 92 | } 93 | 94 | /// 95 | /// Closes current Streamwriter 96 | /// 97 | public void Flush() 98 | { 99 | // Dump buffer 100 | using (var output = new StreamWriter(LogFile, true)) 101 | output.WriteLine(Buffer.ToString()); 102 | // Reset 103 | Buffer = new StringBuilder(); 104 | } 105 | 106 | /// 107 | /// Disposes of the Logger and its Streamwriter 108 | /// 109 | public void Dispose() 110 | { 111 | // Close stream 112 | Flush(); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/PhilLibX/Mathematics/MathUtility.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Mathematics/MathUtilities.cs 24 | // Author: Philip/Scobalula 25 | // Description: Mathematic Utilities 26 | using System; 27 | 28 | namespace PhilLibX 29 | { 30 | /// 31 | /// Mathematic Utilities 32 | /// 33 | public static class MathUtilities 34 | { 35 | /// 36 | /// Clamps Value to a range. 37 | /// 38 | /// Value to Clamp 39 | /// Max value 40 | /// Min value 41 | /// Clamped Value 42 | public static T Clamp(T value, T max, T min) where T : IComparable 43 | { 44 | return value.CompareTo(min) < 0 ? min : value.CompareTo(max) > 0 ? max : value; 45 | } 46 | 47 | /// 48 | /// Converts CM to Inch 49 | /// 50 | /// CM Value 51 | /// Value in inches 52 | public static double CMToInch(double value) 53 | { 54 | return value * 0.3937007874015748031496062992126; 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/PhilLibX/Mathematics/Matrix.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Mathematics/Matrixs/Matrix.cs 24 | // Author: Philip/Scobalula 25 | // Description: A class to hold a Matrix 26 | using System; 27 | 28 | namespace PhilLibX.Mathematics 29 | { 30 | /// 31 | /// A class to hold and manipulate a Matrix 32 | /// 33 | public class Matrix 34 | { 35 | /// 36 | /// Gets or Sets the Values 37 | /// 38 | public float[,] Values { get; set; } 39 | 40 | /// 41 | /// Initializes a Matrix of the given dimension 42 | /// 43 | public Matrix(int dimension) 44 | { 45 | Values = new float[dimension, dimension]; 46 | } 47 | 48 | /// 49 | /// Subtracts two given Matrixs 50 | /// 51 | public static Matrix operator -(Matrix a, Matrix b) 52 | { 53 | var result = new Matrix(a.Values.GetLength(0)); 54 | 55 | for(int x = 0; x < a.Values.GetLength(0); x++) 56 | { 57 | for(int y = 0; y < a.Values.GetLength(1); y++) 58 | { 59 | result.Values[x, y] = a.Values[x, y] - b.Values[x, y]; 60 | } 61 | } 62 | 63 | return result; 64 | } 65 | 66 | /// 67 | /// Subtracts the given value from the Matrix 68 | /// 69 | public static Matrix operator -(Matrix a, float value) 70 | { 71 | var result = new Matrix(a.Values.GetLength(0)); 72 | 73 | for (int x = 0; x < a.Values.GetLength(0); x++) 74 | { 75 | for (int y = 0; y < a.Values.GetLength(1); y++) 76 | { 77 | result.Values[x, y] = a.Values[x, y] - value; 78 | } 79 | } 80 | 81 | return result; 82 | } 83 | 84 | /// 85 | /// Adds two given Matrixs 86 | /// 87 | public static Matrix operator +(Matrix a, Matrix b) 88 | { 89 | var result = new Matrix(a.Values.GetLength(0)); 90 | 91 | for (int x = 0; x < a.Values.GetLength(0); x++) 92 | { 93 | for (int y = 0; y < a.Values.GetLength(1); y++) 94 | { 95 | result.Values[x, y] = a.Values[x, y] + b.Values[x, y]; 96 | } 97 | } 98 | 99 | return result; 100 | } 101 | 102 | /// 103 | /// Adds the given value to the Matrix 104 | /// 105 | public static Matrix operator +(Matrix a, float value) 106 | { 107 | var result = new Matrix(a.Values.GetLength(0)); 108 | 109 | for (int x = 0; x < a.Values.GetLength(0); x++) 110 | { 111 | for (int y = 0; y < a.Values.GetLength(1); y++) 112 | { 113 | result.Values[x, y] = a.Values[x, y] + value; 114 | } 115 | } 116 | 117 | return result; 118 | } 119 | 120 | /// 121 | /// Multiplies two given Matrixs 122 | /// 123 | public static Matrix operator *(Matrix a, Matrix b) 124 | { 125 | var result = new Matrix(a.Values.GetLength(0)); 126 | 127 | for (int x = 0; x < a.Values.GetLength(0); x++) 128 | { 129 | for (int y = 0; y < a.Values.GetLength(1); y++) 130 | { 131 | result.Values[x, y] = a.Values[x, y] * b.Values[x, y]; 132 | } 133 | } 134 | 135 | return result; 136 | } 137 | 138 | /// 139 | /// Multiplies the Matrix by the given value 140 | /// 141 | public static Matrix operator *(Matrix a, float value) 142 | { 143 | var result = new Matrix(a.Values.GetLength(0)); 144 | 145 | for (int x = 0; x < a.Values.GetLength(0); x++) 146 | { 147 | for (int y = 0; y < a.Values.GetLength(1); y++) 148 | { 149 | result.Values[x, y] = a.Values[x, y] * value; 150 | } 151 | } 152 | 153 | return result; 154 | } 155 | 156 | /// 157 | /// Divides two given Matrixs 158 | /// 159 | public static Matrix operator /(Matrix a, Matrix b) 160 | { 161 | var result = new Matrix(a.Values.GetLength(0)); 162 | 163 | for (int x = 0; x < a.Values.GetLength(0); x++) 164 | { 165 | for (int y = 0; y < a.Values.GetLength(1); y++) 166 | { 167 | result.Values[x, y] = a.Values[x, y] / b.Values[x, y]; 168 | } 169 | } 170 | 171 | return result; 172 | } 173 | 174 | /// 175 | /// Divides the Matrix by the given value 176 | /// 177 | public static Matrix operator /(Matrix a, float value) 178 | { 179 | var result = new Matrix(a.Values.GetLength(0)); 180 | 181 | for (int x = 0; x < a.Values.GetLength(0); x++) 182 | { 183 | for (int y = 0; y < a.Values.GetLength(1); y++) 184 | { 185 | result.Values[x, y] = a.Values[x, y] / value; 186 | } 187 | } 188 | 189 | return result; 190 | } 191 | 192 | /// 193 | /// Transforms the Vector by the Matrix 194 | /// 195 | /// Vector To Transform 196 | /// Resulting Vector 197 | public Vector3 TransformVector(Vector3 vector) 198 | { 199 | return new Vector3( 200 | vector.DotProduct(new Vector3(Values[0, 0], Values[0, 1], Values[0, 2])), 201 | vector.DotProduct(new Vector3(Values[1, 0], Values[1, 1], Values[1, 2])), 202 | vector.DotProduct(new Vector3(Values[2, 0], Values[2, 1], Values[2, 2])) 203 | ); 204 | } 205 | 206 | /// 207 | /// Gets a string representation of the Matrix 208 | /// 209 | /// String representation of the Matrix 210 | public override string ToString() 211 | { 212 | var result = ""; 213 | 214 | for (int x = 0; x < Values.GetLength(0); x++) 215 | { 216 | for (int y = 0; y < Values.GetLength(1); y++) 217 | { 218 | result += Values[x, y].ToString() + " "; 219 | } 220 | 221 | result += "\n"; 222 | } 223 | 224 | return result; 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /src/PhilLibX/Mathematics/Quaternion.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Mathematics/Quaternions/cs 24 | // Author: Philip/Scobalula 25 | // Description: A class to hold a Quaternion 26 | using System; 27 | 28 | namespace PhilLibX.Mathematics 29 | { 30 | /// 31 | /// A class to hold and manipulate a Quaternion 32 | /// 33 | public struct Quaternion 34 | { 35 | /// 36 | /// X Value 37 | /// 38 | public float X { get; set; } 39 | 40 | /// 41 | /// Y Value 42 | /// 43 | public float Y { get; set; } 44 | 45 | /// 46 | /// Z Value 47 | /// 48 | public float Z { get; set; } 49 | 50 | /// 51 | /// W Value 52 | /// 53 | public float W { get; set; } 54 | 55 | /// 56 | /// Initializes a 4-Dimensional Quaternion with the given values 57 | /// 58 | /// X Value 59 | /// Y Value 60 | /// Z Value 61 | /// W Value 62 | public Quaternion(float x, float y, float z, float w) 63 | { 64 | X = x; 65 | Y = y; 66 | Z = z; 67 | W = w; 68 | } 69 | 70 | /// 71 | /// Subtracts two given Quaternions 72 | /// 73 | public static Quaternion operator -(Quaternion a, Quaternion b) 74 | { 75 | return new Quaternion(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W); 76 | } 77 | 78 | /// 79 | /// Subtracts the given value from the Quaternion 80 | /// 81 | public static Quaternion operator -(Quaternion a, float value) 82 | { 83 | return new Quaternion(a.X - value, a.Y - value, a.Z - value, a.W - value); 84 | } 85 | 86 | /// 87 | /// Adds two given Quaternions 88 | /// 89 | public static Quaternion operator +(Quaternion a, Quaternion b) 90 | { 91 | return new Quaternion(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W); 92 | } 93 | 94 | /// 95 | /// Adds the given value to the Quaternion 96 | /// 97 | public static Quaternion operator +(Quaternion a, float value) 98 | { 99 | return new Quaternion(a.X + value, a.Y + value, a.Z + value, a.W + value); 100 | } 101 | 102 | /// 103 | /// Multiplies two given Quaternions 104 | /// 105 | public static Quaternion operator *(Quaternion a, Quaternion b) 106 | { 107 | return new Quaternion( 108 | a.W * b.X + a.X * b.W + a.Y * b.Z - a.Z * b.Y, 109 | a.W * b.Y + a.Y * b.W + a.Z * b.X - a.X * b.Z, 110 | a.W * b.Z + a.Z * b.W + a.X * b.Y - a.Y * b.X, 111 | a.W * b.W - a.X * b.X - a.Y * b.Y - a.Z * b.Z); 112 | } 113 | 114 | /// 115 | /// Multiplies the Quaternion by the given value 116 | /// 117 | public static Quaternion operator *(Quaternion a, float value) 118 | { 119 | return new Quaternion(a.X * value, a.Y * value, a.Z * value, a.W * value); 120 | } 121 | 122 | /// 123 | /// Divides two given Quaternions 124 | /// 125 | public static Quaternion operator /(Quaternion a, Quaternion b) 126 | { 127 | return new Quaternion(a.X / b.X, a.Y / b.Y, a.Z / b.Z, a.W / b.W); 128 | } 129 | 130 | /// 131 | /// Divides the Quaternion by the given value 132 | /// 133 | public static Quaternion operator /(Quaternion a, float value) 134 | { 135 | return new Quaternion(a.X / value, a.Y / value, a.Z / value, a.W / value); 136 | } 137 | 138 | /// 139 | /// Returns an inverse of the Quaternion 140 | /// 141 | public Quaternion Inverse() 142 | { 143 | return new Quaternion(-X, -Y, -Z, W); 144 | } 145 | 146 | /// 147 | /// Returns the linear interpolation of Quat with coefficient 148 | /// 149 | /// Max/End Value 150 | /// Coefficient 151 | /// Resulting Quat 152 | public Quaternion SLerp(Quaternion max, float coefficient) 153 | { 154 | // Calculate angle between them. 155 | float cos_half_theta = X * max.X + Y * max.Y + Z * max.Z + W * max.W; 156 | 157 | // If _a=_b or _a=-_b then theta = 0 and we can return _a. 158 | if (Math.Abs(cos_half_theta) >= .999f) 159 | return this; 160 | 161 | // Calculate temporary values. 162 | float half_theta = (float)Math.Acos(cos_half_theta); 163 | float sin_half_theta = (float)Math.Sqrt(1.0f - cos_half_theta * cos_half_theta); 164 | 165 | if (sin_half_theta < .001f) 166 | { 167 | return new Quaternion( 168 | (X + max.X) * .5f, (Y + max.Y) * .5f, 169 | (Z + max.Z) * .5f, (W + max.W) * .5f); 170 | } 171 | 172 | float ratio_a = (float)Math.Sin((1.0f - coefficient) * half_theta) / sin_half_theta; 173 | float ratio_b = (float)Math.Sin(coefficient * half_theta) / sin_half_theta; 174 | 175 | // Calculate Quaternion. 176 | return new Quaternion( 177 | ratio_a * X + ratio_b * max.X, ratio_a * Y + ratio_b * max.Y, 178 | ratio_a * Z + ratio_b * max.Z, ratio_a * W + ratio_b * max.W); 179 | } 180 | 181 | /// 182 | /// Returns the linear interpolation of Quat with coefficient 183 | /// 184 | /// Max/End Value 185 | /// Coefficient 186 | /// Resulting Quat 187 | public Quaternion Lerp(Quaternion max, float coefficient) 188 | { 189 | return new Quaternion( 190 | ((max.X - X) * coefficient) + X, 191 | ((max.Y - Y) * coefficient) + Y, 192 | ((max.Z - Z) * coefficient) + Z, 193 | ((max.W - W) * coefficient) + W); 194 | } 195 | 196 | /// 197 | /// Converts the Quaternion to a 3-Dimensional Matrix 198 | /// 199 | /// 3-D Matrix 200 | public Matrix ToMatrix() 201 | { 202 | // https://en.wikipedia.org/wiki/Quaternionsand_spatial_rotation#Quaternion-derived_rotation_matrix 203 | var result = new Matrix(3); 204 | 205 | var xx = X * X; 206 | var yy = Y * Y; 207 | var zz = Z * Z; 208 | var xy = X * Y; 209 | var xz = X * Z; 210 | var xw = X * W; 211 | var yz = Y * Z; 212 | var yw = Y * W; 213 | var zw = Z * W; 214 | 215 | 216 | result.Values[0, 0] = 1 - 2 * (yy + zz); 217 | result.Values[0, 1] = 2 * (xy - zw); 218 | result.Values[0, 2] = 2 * (xz + yw); 219 | 220 | result.Values[1, 0] = 2 * (xy + zw); 221 | result.Values[1, 1] = 1 - 2 * (xx + zz); 222 | result.Values[1, 2] = 2 * (yz - xw); 223 | 224 | result.Values[2, 0] = 2 * (xz - yw); 225 | result.Values[2, 1] = 2 * (yz + xw); 226 | result.Values[2, 2] = 1 - 2 * (xx + yy); 227 | 228 | return result; 229 | } 230 | 231 | /// 232 | /// Converts the Quaternion to an Euler vector 233 | /// 234 | /// Euler vector 235 | public Vector3 ToEuler() 236 | { 237 | 238 | Vector3 result = new Vector3(); 239 | 240 | double t0 = 2.0 * (W * X + Y * Z); 241 | double t1 = 1.0 - 2.0 * (X * X + Y * Y); 242 | 243 | result.X = (float)Math.Atan2(t0, t1); 244 | 245 | 246 | double t2 = 2.0 * (W * Y - Z * X); 247 | 248 | t2 = t2 > 1.0 ? 1.0 : t2; 249 | t2 = t2 < -1.0 ? -1.0 : t2; 250 | result.Y = (float)Math.Asin(t2); 251 | 252 | 253 | double t3 = +2.0 * (W * Z + X * Y); 254 | double t4 = +1.0 - 2.0 * (Y * Y + Z * Z); 255 | 256 | result.Z = (float)Math.Atan2(t3, t4); 257 | 258 | return result; 259 | } 260 | 261 | /// 262 | /// Gets a string representation of the Quaternion 263 | /// 264 | /// 265 | /// String representation of the Quaternion 266 | public override string ToString() 267 | { 268 | return string.Format(" {0}, {1}, {2}, {3}", X, Y, Z, W); 269 | } 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /src/PhilLibX/Mathematics/Vector2.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Mathematics/Vectors/Vector2.cs 24 | // Author: Philip/Scobalula 25 | // Description: A class to hold a 2-Dimensional Vector 26 | using System; 27 | 28 | namespace PhilLibX.Mathematics 29 | { 30 | /// 31 | /// A class to hold a 2-Dimensional Vector 32 | /// 33 | public struct Vector2 34 | { 35 | /// 36 | /// X Value 37 | /// 38 | public float X { get; set; } 39 | 40 | /// 41 | /// Y Value 42 | /// 43 | public float Y { get; set; } 44 | 45 | /// 46 | /// Initializes a 2-Dimensional Vector with the given values 47 | /// 48 | /// X Value 49 | /// Y Value 50 | public Vector2(float x, float y) 51 | { 52 | X = x; 53 | Y = y; 54 | } 55 | 56 | /// 57 | /// Returns the dot product of the 2 vectors 58 | /// 59 | /// Input vector 60 | /// Single result 61 | public float DotProduct(Vector2 input) 62 | { 63 | return (X * input.X) + (Y * input.Y); 64 | } 65 | 66 | /// 67 | /// Subtracts two given vectors 68 | /// 69 | public static Vector2 operator -(Vector2 a, Vector2 b) 70 | { 71 | return new Vector2(a.X - b.X, a.Y - b.Y); 72 | } 73 | 74 | /// 75 | /// Subtracts the given value from the vector 76 | /// 77 | public static Vector2 operator -(Vector2 a, float value) 78 | { 79 | return new Vector2(a.X - value, a.Y - value); 80 | } 81 | 82 | /// 83 | /// Adds two given vectors 84 | /// 85 | public static Vector2 operator +(Vector2 a, Vector2 b) 86 | { 87 | return new Vector2(a.X + b.X, a.Y + b.Y); 88 | } 89 | 90 | /// 91 | /// Adds the given value to the vector 92 | /// 93 | public static Vector2 operator +(Vector2 a, float value) 94 | { 95 | return new Vector2(a.X + value, a.Y + value); 96 | } 97 | 98 | /// 99 | /// Multiplies two given vectors 100 | /// 101 | public static Vector2 operator *(Vector2 a, Vector2 b) 102 | { 103 | return new Vector2(a.X * b.X, a.Y * b.Y); 104 | } 105 | 106 | /// 107 | /// Multiplies the vector by the given value 108 | /// 109 | public static Vector2 operator *(Vector2 a, float value) 110 | { 111 | return new Vector2(a.X * value, a.Y * value); 112 | } 113 | 114 | /// 115 | /// Divides two given vectors 116 | /// 117 | public static Vector2 operator /(Vector2 a, Vector2 b) 118 | { 119 | return new Vector2(a.X / b.X, a.Y / b.Y); 120 | } 121 | 122 | /// 123 | /// Divides the vector by the given value 124 | /// 125 | public static Vector2 operator /(Vector2 a, float value) 126 | { 127 | return new Vector2(a.X / value, a.Y / value); 128 | } 129 | 130 | /// 131 | /// Normalizes the Vector 132 | /// 133 | /// Normalized Vector 134 | public Vector2 Normalize() 135 | { 136 | float length = (float)Math.Sqrt(DotProduct(this)); 137 | return new Vector2(X / length, Y / length); 138 | } 139 | 140 | /// 141 | /// Gets a string representation of the vector 142 | /// 143 | /// String representation of the vector 144 | public override string ToString() 145 | { 146 | return string.Format(" {0}, {1}", X, Y); 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/PhilLibX/Mathematics/Vector3.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Mathematics/Vectors/Vector3.cs 24 | // Author: Philip/Scobalula 25 | // Description: A class to hold a 3-Dimensional Vector 26 | using System; 27 | 28 | namespace PhilLibX.Mathematics 29 | { 30 | /// 31 | /// A class to hold a 3-Dimensional Vector 32 | /// 33 | public struct Vector3 34 | { 35 | /// 36 | /// X Value 37 | /// 38 | public float X { get; set; } 39 | 40 | /// 41 | /// Y Value 42 | /// 43 | public float Y { get; set; } 44 | 45 | /// 46 | /// Z Value 47 | /// 48 | public float Z { get; set; } 49 | 50 | /// 51 | /// Initializes a 3-Dimensional Vector with the given values 52 | /// 53 | /// X Value 54 | /// Y Value 55 | /// Z Value 56 | public Vector3(float x, float y, float z) 57 | { 58 | X = x; 59 | Y = y; 60 | Z = z; 61 | } 62 | 63 | /// 64 | /// Returns the dot product of the 2 vectors 65 | /// 66 | /// Input vector 67 | /// Single result 68 | public float DotProduct(Vector3 input) 69 | { 70 | return (X * input.X) + (Y * input.Y) + (Z * input.Z); 71 | } 72 | 73 | /// 74 | /// Returns the cross product of the 2 vectors 75 | /// 76 | /// Input vector 77 | /// Single result 78 | public Vector3 CrossProduct(Vector3 input) 79 | { 80 | float a = Y * input.Z - Z * input.Y; 81 | float b = Z * input.X - X * input.Z; 82 | float c = X * input.Y - Y * input.X; 83 | 84 | return new Vector3(a, b, c); 85 | } 86 | 87 | /// 88 | /// Subtracts two given vectors 89 | /// 90 | public static Vector3 operator -(Vector3 a, Vector3 b) 91 | { 92 | return new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z); 93 | } 94 | 95 | /// 96 | /// Subtracts the given value from the vector 97 | /// 98 | public static Vector3 operator -(Vector3 a, float value) 99 | { 100 | return new Vector3(a.X - value, a.Y - value, a.Z - value); 101 | } 102 | 103 | /// 104 | /// Adds two given vectors 105 | /// 106 | public static Vector3 operator +(Vector3 a, Vector3 b) 107 | { 108 | return new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z); 109 | } 110 | 111 | /// 112 | /// Adds the given value to the vector 113 | /// 114 | public static Vector3 operator +(Vector3 a, float value) 115 | { 116 | return new Vector3(a.X + value, a.Y + value, a.Z + value); 117 | } 118 | 119 | /// 120 | /// Multiplies two given vectors 121 | /// 122 | public static Vector3 operator *(Vector3 a, Vector3 b) 123 | { 124 | return new Vector3(a.X * b.X, a.Y * b.Y, a.Z * b.Z); 125 | } 126 | 127 | /// 128 | /// Multiplies the vector by the given value 129 | /// 130 | public static Vector3 operator *(Vector3 a, float value) 131 | { 132 | return new Vector3(a.X * value, a.Y * value, a.Z * value); 133 | } 134 | 135 | /// 136 | /// Divides two given vectors 137 | /// 138 | public static Vector3 operator /(Vector3 a, Vector3 b) 139 | { 140 | return new Vector3(a.X / b.X, a.Y / b.Y, a.Z / b.Z); 141 | } 142 | 143 | /// 144 | /// Divides the vector by the given value 145 | /// 146 | public static Vector3 operator /(Vector3 a, float value) 147 | { 148 | return new Vector3(a.X / value, a.Y / value, a.Z / value); 149 | } 150 | 151 | /// 152 | /// Normalizes the Vector 153 | /// 154 | /// Normalized Vector 155 | public Vector3 Normalize() 156 | { 157 | float length = (float)Math.Sqrt(DotProduct(this)); 158 | return new Vector3(X / length, Y / length, Z / length); 159 | } 160 | 161 | /// 162 | /// Returns the linear interpolation of Vector with coefficient 163 | /// 164 | /// Max/End Value 165 | /// Coefficient 166 | /// Resulting Vector 167 | public Vector3 Lerp(Vector3 max, float coefficient) 168 | { 169 | return new Vector3( 170 | (max.X - X) * coefficient + X, 171 | (max.Y - Y) * coefficient + Y, 172 | (max.Z - Z) * coefficient + Z); 173 | } 174 | 175 | /// 176 | /// Gets a string representation of the vector 177 | /// 178 | /// String representation of the vector 179 | public override string ToString() 180 | { 181 | return string.Format("{0} {1} {2}", X, Y, Z); 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/PhilLibX/Mathematics/Vector4.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Mathematics/Vectors/Vector4.cs 24 | // Author: Philip/Scobalula 25 | // Description: A class to hold a 4-Dimensional Vector 26 | using System; 27 | 28 | namespace PhilLibX.Mathematics 29 | { 30 | /// 31 | /// A class to hold a 4-Dimensional Vector 32 | /// 33 | public struct Vector4 34 | { 35 | /// 36 | /// X Value 37 | /// 38 | public float X { get; set; } 39 | 40 | /// 41 | /// Y Value 42 | /// 43 | public float Y { get; set; } 44 | 45 | /// 46 | /// Z Value 47 | /// 48 | public float Z { get; set; } 49 | 50 | /// 51 | /// W Value 52 | /// 53 | public float W { get; set; } 54 | 55 | /// 56 | /// Initializes a 4-Dimensional Vector with the given values 57 | /// 58 | /// X Value 59 | /// Y Value 60 | /// Z Value 61 | /// W Value 62 | public Vector4(float x, float y, float z, float w) 63 | { 64 | X = x; 65 | Y = y; 66 | Z = z; 67 | W = w; 68 | } 69 | 70 | /// 71 | /// Returns the dot product of the 2 vectors 72 | /// 73 | /// Input vector 74 | /// Single result 75 | public float DotProduct(Vector4 input) 76 | { 77 | return (X * input.X) + (Y * input.Y) + (Z * input.Z) + (W * input.W); 78 | } 79 | 80 | /// 81 | /// Subtracts two given vectors 82 | /// 83 | public static Vector4 operator -(Vector4 a, Vector4 b) 84 | { 85 | return new Vector4(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W); 86 | } 87 | 88 | /// 89 | /// Subtracts the given value from the vector 90 | /// 91 | public static Vector4 operator -(Vector4 a, float value) 92 | { 93 | return new Vector4(a.X - value, a.Y - value, a.Z - value, a.W - value); 94 | } 95 | 96 | /// 97 | /// Adds two given vectors 98 | /// 99 | public static Vector4 operator +(Vector4 a, Vector4 b) 100 | { 101 | return new Vector4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W); 102 | } 103 | 104 | /// 105 | /// Adds the given value to the vector 106 | /// 107 | public static Vector4 operator +(Vector4 a, float value) 108 | { 109 | return new Vector4(a.X + value, a.Y + value, a.Z + value, a.W + value); 110 | } 111 | 112 | /// 113 | /// Multiplies two given vectors 114 | /// 115 | public static Vector4 operator *(Vector4 a, Vector4 b) 116 | { 117 | return new Vector4(a.X * b.X, a.Y * b.Y, a.Z * b.Z, a.W * b.W); 118 | } 119 | 120 | /// 121 | /// Multiplies the vector by the given value 122 | /// 123 | public static Vector4 operator *(Vector4 a, float value) 124 | { 125 | return new Vector4(a.X * value, a.Y * value, a.Z * value, a.W * value); 126 | } 127 | 128 | /// 129 | /// Divides two given vectors 130 | /// 131 | public static Vector4 operator /(Vector4 a, Vector4 b) 132 | { 133 | return new Vector4(a.X / b.X, a.Y / b.Y, a.Z / b.Z, a.W / b.W); 134 | } 135 | 136 | /// 137 | /// Divides the vector by the given value 138 | /// 139 | public static Vector4 operator /(Vector4 a, float value) 140 | { 141 | return new Vector4(a.X / value, a.Y / value, a.Z / value, a.W / value); 142 | } 143 | 144 | /// 145 | /// Normalizes the Vector 146 | /// 147 | /// Normalized Vector 148 | public Vector4 Normalize() 149 | { 150 | float length = (float)Math.Sqrt(DotProduct(this)); 151 | return new Vector4(X / length, Y / length, Z / length, W / length); 152 | } 153 | 154 | /// 155 | /// Returns the first 3 components of the vector as a Vector3 156 | /// 157 | /// 3-D Vector 158 | public Vector3 ToVector3() 159 | { 160 | return new Vector3(X, Y, Z); 161 | } 162 | 163 | /// 164 | /// Gets a string representation of the vector 165 | /// 166 | /// String representation of the vector 167 | public override string ToString() 168 | { 169 | return string.Format(" {0}, {1}, {2}, {3}", X, Y, Z, W); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/PhilLibX/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: NativeMethods.cs 24 | // Author: Philip/Scobalula 25 | // Description: Native/Unmanaged Methods (DLLs required for certain components) 26 | using System; 27 | using System.Runtime.InteropServices; 28 | using System.Text; 29 | 30 | namespace PhilLibX 31 | { 32 | public enum ListModules : uint 33 | { 34 | Default, 35 | X86, 36 | X64, 37 | All, 38 | } 39 | 40 | /// 41 | /// Description: Native/Unmanaged Methods (DLLs required for certain components) 42 | /// 43 | public unsafe static class NativeMethods 44 | { 45 | public struct NtModuleInfo 46 | { 47 | public IntPtr BaseOfDll; 48 | public int SizeOfImage; 49 | public IntPtr EntryPoint; 50 | } 51 | 52 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "K32GetModuleInformation")] 53 | public static extern bool GetModuleInformation(IntPtr processHandle, IntPtr moduleHandle, out NtModuleInfo ntModuleInfo, int size); 54 | 55 | /// 56 | /// Oodle Library Path 57 | /// 58 | private const string OodleLibraryPath = "oo2core_5_win64"; 59 | 60 | [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] 61 | public static extern bool IsWow64Process(IntPtr processHandle, out bool wow64Process); 62 | 63 | [DllImport("psapi.dll", SetLastError = true)] 64 | public static extern bool EnumProcessModulesEx(IntPtr hProcess, IntPtr[] lphModule, int cb, out int lpcbNeeded, ListModules listFilter); 65 | 66 | [DllImport("psapi.dll")] 67 | public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In] [MarshalAs(UnmanagedType.U4)] int nSize); 68 | 69 | /// 70 | /// Reads data from an area of memory in a specified process. The entire area to be read must be accessible or the operation fails. 71 | /// 72 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 73 | /// A pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible the function fails. 74 | /// A pointer to a buffer that receives the contents from the address space of the specified process. 75 | /// The number of bytes to be read from the specified process. 76 | /// A pointer to a variable that receives the number of bytes transferred into the specified buffer. 77 | /// 78 | [DllImport("kernel32.dll", SetLastError = true)] 79 | public static extern bool ReadProcessMemory 80 | ( 81 | int hProcess, 82 | long lpBaseAddress, 83 | byte[] lpBuffer, 84 | int nSize, 85 | out int lpNumberOfBytesRead 86 | ); 87 | 88 | /// 89 | /// Reads data from an area of memory in a specified process. The entire area to be read must be accessible or the operation fails. 90 | /// 91 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 92 | /// A pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible the function fails. 93 | /// A pointer to a buffer that receives the contents from the address space of the specified process. 94 | /// The number of bytes to be read from the specified process. 95 | /// A pointer to a variable that receives the number of bytes transferred into the specified buffer. 96 | /// 97 | [DllImport("kernel32.dll", SetLastError = true)] 98 | public static extern bool ReadProcessMemory 99 | ( 100 | int hProcess, 101 | long lpBaseAddress, 102 | byte* lpBuffer, 103 | int nSize, 104 | out int lpNumberOfBytesRead 105 | ); 106 | 107 | /// 108 | /// Reads data from an area of memory in a specified process. The entire area to be read must be accessible or the operation fails. 109 | /// 110 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 111 | /// A pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible the function fails. 112 | /// A pointer to a buffer that receives the contents from the address space of the specified process. 113 | /// The number of bytes to be read from the specified process. 114 | /// A pointer to a variable that receives the number of bytes transferred into the specified buffer. 115 | /// 116 | [DllImport("kernel32.dll", SetLastError = true)] 117 | public static extern bool WriteProcessMemory 118 | ( 119 | int hProcess, 120 | long lpBaseAddress, 121 | byte[] lpBuffer, 122 | int nSize, 123 | out int lpNumberOfBytesRead 124 | ); 125 | 126 | /// 127 | /// Opens an existing local process object. 128 | /// 129 | /// The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be one or more of the process access rights. If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor. 130 | /// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle. 131 | /// The identifier of the local process to be opened. 132 | /// 133 | [DllImport("kernel32.dll")] 134 | public static extern IntPtr OpenProcess 135 | ( 136 | int dwDesiredAccess, 137 | bool bInheritHandle, 138 | int dwProcessId 139 | ); 140 | 141 | /// 142 | /// Oodle64 Decompression Method 143 | /// 144 | [DllImport(OodleLibraryPath, CallingConvention = CallingConvention.Cdecl)] 145 | public static extern long OodleLZ_Decompress(byte[] buffer, long bufferSize, byte[] result, long outputBufferSize, int a, int b, int c, long d, long e, long f, long g, long h, long i, int ThreadModule); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/PhilLibX/Oodle.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Compression/Oodle.cs 24 | // Author: Philip/Scobalula 25 | // Description: Basic Oodle64 Compression Wrapper, currently supports decompression. 26 | // Credits: 27 | // - DTZxPorter - SirenLib (for OodleLZ_Decompress parameters) 28 | // Other notes: 29 | // - Tested on Oodle V5 and V6 30 | using System.Runtime.InteropServices; 31 | 32 | namespace PhilLibX.Compression 33 | { 34 | /// 35 | /// Oodle Compression Utils 36 | /// 37 | public class Oodle 38 | { 39 | /// 40 | /// Oodle Library Path 41 | /// 42 | private const string OodleLibraryPath = "Oodle"; 43 | 44 | /// 45 | /// Oodle64 Decompression Method 46 | /// 47 | [DllImport(OodleLibraryPath, CallingConvention = CallingConvention.Cdecl)] 48 | private static extern long OodleLZ_Decompress(byte[] buffer, long bufferSize, byte[] result, long outputBufferSize, int a, int b, int c, long d, long e, long f, long g, long h, long i, int ThreadModule); 49 | 50 | /// 51 | /// Decompresses a byte array of Oodle Compressed Data (Requires Oodle DLL) 52 | /// 53 | /// Input Compressed Data 54 | /// Decompressed Size 55 | /// Resulting Array if success, otherwise null. 56 | public static byte[] Decompress(byte[] input, long decompressedLength) 57 | { 58 | // Resulting decompressed Data 59 | byte[] result = new byte[decompressedLength]; 60 | // Decode the data (other parameters such as callbacks not required) 61 | long decodedSize = OodleLZ_Decompress(input, input.Length, result, decompressedLength, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3); 62 | // Check did we fail 63 | if (decodedSize == 0) return null; 64 | // Return Result 65 | return result; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/PhilLibX/PhilLibX.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0F468D5B-2F30-42F5-9043-920040D83D9D} 8 | Library 9 | Properties 10 | PhilLibX 11 | PhilLibX 12 | v4.8 13 | 512 14 | true 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | bin\Debug\PhilLibX.xml 26 | true 27 | 7.3 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | bin\Release\PhilLibX.xml 37 | true 38 | 7.3 39 | 40 | 41 | true 42 | ..\x64\Debug\ 43 | DEBUG;TRACE 44 | full 45 | x64 46 | prompt 47 | MinimumRecommendedRules.ruleset 48 | ..\x64\Debug\PhilLibX.xml 49 | true 50 | 7.3 51 | 52 | 53 | ..\x64\Release\ 54 | TRACE 55 | true 56 | pdbonly 57 | x64 58 | prompt 59 | MinimumRecommendedRules.ruleset 60 | ..\x64\Release\PhilLibX.xml 61 | true 62 | 7.3 63 | 64 | 65 | true 66 | ..\Win32\Debug\ 67 | DEBUG;TRACE 68 | full 69 | x86 70 | prompt 71 | MinimumRecommendedRules.ruleset 72 | ..\Win32\Debug\PhilLibX.xml 73 | true 74 | 7.3 75 | 76 | 77 | ..\Win32\Release\ 78 | TRACE 79 | true 80 | pdbonly 81 | x86 82 | prompt 83 | MinimumRecommendedRules.ruleset 84 | ..\Win32\Release\PhilLibX.xml 85 | true 86 | 7.3 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /src/PhilLibX/Printer.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: Printer.cs 24 | // Author: Philip/Scobalula 25 | // Description: Class to Print stuff to the Console with more swag 🖨️ 26 | using System; 27 | using System.Diagnostics; 28 | using System.IO; 29 | 30 | namespace PhilLibX 31 | { 32 | /// 33 | /// Class to Print stuff to the Console with more swag 🖨️ 34 | /// 35 | public static class Printer 36 | { 37 | /// 38 | /// Prefix Padding 39 | /// 40 | private static int PrefixPadding = 12; 41 | 42 | /// 43 | /// Prefix Color 44 | /// 45 | private static ConsoleColor PrefixColor = ConsoleColor.DarkBlue; 46 | 47 | /// 48 | /// Sets Prefix Padding 49 | /// 50 | /// Padding Size 51 | public static void SetPrefixPadding(int padding) 52 | { 53 | PrefixPadding = padding; 54 | } 55 | 56 | /// 57 | /// Sets the Console Prefix Color 58 | /// 59 | /// Background Color for Prefix 60 | public static void SetPrefixBackgroundColor(ConsoleColor color) 61 | { 62 | PrefixColor = color; 63 | } 64 | 65 | /// 66 | /// Writes a line to the console with optional BackGround 67 | /// 68 | /// Value to print 69 | /// Value to prefix 70 | /// Background Color 71 | public static void WriteLine(object prefix = null, object value = null, ConsoleColor backgroundColor = ConsoleColor.Black) 72 | { 73 | // Check if we even have a prefix, if not just do a normal print 74 | if (prefix != null) 75 | { 76 | Console.BackgroundColor = PrefixColor; 77 | Console.Write(" {0}", prefix.ToString().PadRight(PrefixPadding)); 78 | Console.ResetColor(); 79 | Console.Write("│ "); 80 | } 81 | Console.BackgroundColor = backgroundColor; 82 | Console.WriteLine("{0}", value); 83 | Console.ResetColor(); 84 | } 85 | 86 | /// 87 | /// Writes a line to the console with optional BackGround 88 | /// 89 | /// Exception to write 90 | /// Value to print 91 | /// Value to prefix 92 | /// Background Color 93 | public static void WriteException(Exception exception, object prefix = null, object value = null, ConsoleColor backgroundColor = ConsoleColor.DarkRed) 94 | { 95 | // Write Initial Value 96 | WriteLine(prefix, value, backgroundColor); 97 | 98 | // Grab stack trace and recent frame 99 | var stackTrace = new StackTrace(exception, true); 100 | var stackFrame = stackTrace.GetFrame(0); 101 | 102 | // Write Formatted Exception 103 | WriteLine(prefix, exception.Message, backgroundColor); 104 | WriteLine(prefix, string.Format("{0}::{1}.{2}(...)::Line::{3}:{4}", 105 | Path.GetFileName(stackFrame.GetFileName()), 106 | stackFrame.GetMethod().ReflectedType.Name, 107 | stackFrame.GetMethod().Name, 108 | stackFrame.GetFileLineNumber(), 109 | stackFrame.GetFileColumnNumber()), backgroundColor); 110 | 111 | Console.ResetColor(); 112 | } 113 | 114 | /// 115 | /// Writes to the console with optional BackGround 116 | /// 117 | /// Value to print 118 | /// Value to prefix 119 | /// Background Color 120 | public static void Write(object prefix = null, object value = null, ConsoleColor backgroundColor = ConsoleColor.Black) 121 | { 122 | // Check if we even have a prefix, if not just do a normal print 123 | if (prefix != null) 124 | { 125 | Console.BackgroundColor = ConsoleColor.DarkBlue; 126 | Console.Write(" {0}", prefix.ToString().PadRight(PrefixPadding)); 127 | Console.ResetColor(); 128 | Console.Write("│ "); 129 | } 130 | Console.BackgroundColor = backgroundColor; 131 | Console.Write("{0}", value); 132 | Console.ResetColor(); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/PhilLibX/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PhilLibX Utility Library")] 9 | [assembly: AssemblyDescription("PhilLibX Utility Library")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Philip/Scobalula")] 12 | [assembly: AssemblyProduct("PhilLibX")] 13 | [assembly: AssemblyCopyright("Copyright © Philip/Scobalula 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0f468d5b-2f30-42f5-9043-920040d83d9d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.0.0.0")] 36 | [assembly: AssemblyFileVersion("2.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/SELibDotNet/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | -------------------------------------------------------------------------------- /src/SELibDotNet/README.md: -------------------------------------------------------------------------------- 1 | # SELibDotNet 2 | 3 | A .NET library for reading and writing SE Format files 4 | 5 | *.SE formats are open-sourced formats optimized for next-generation modeling and animation. They are free to be used in any project, game, software, etc with the hopes that people will adapt the standard unlike other formats available.* 6 | 7 | - Animation format documentation: [Specification](https://github.com/SE2Dev/SEAnim-Docs) 8 | - Model format documentation: [Coming soon](#) 9 | 10 | ## Usage: 11 | 12 | - Download the latest version, add it as a reference to your .NET based project and start working with SE Formats 13 | - **Note:** SEAnim format is unitless for translations, a scale of 1.0 = default scaling, and rotations are XYZW. Please be sure to encode the input properly as there is no way for the library to determine otherwise! 14 | - (Check out UnitTests for examples on using the library, everything has full documentation though.) 15 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/DebugUtil/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/DebugUtil/DebugUtil.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {ADDB9CB2-A643-49F4-AEF7-F534BACF5B8D} 8 | Exe 9 | Properties 10 | DebugUtil 11 | DebugUtil 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {e03da150-718d-4ea9-afca-d3e17a7df3e8} 53 | SELib 54 | 55 | 56 | 57 | 64 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/DebugUtil/Program.cs: -------------------------------------------------------------------------------- 1 | using SELib; 2 | using SELib.Utilities; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Program.cs (Debugger Utility) 12 | /// Author: DTZxPorter 13 | /// Written for the SE Format Project 14 | /// Follows SEAnim specification v1.1 15 | /// https://github.com/SE2Dev/SEAnim-Docs/blob/master/spec.md 16 | /// 17 | 18 | namespace DebugUtil 19 | { 20 | class Program 21 | { 22 | private static void Usage() 23 | { 24 | // Output 25 | Console.WriteLine(" DebugUtil.exe .seanim"); 26 | Console.WriteLine(" DebugUtil.exe .seanim .txt"); 27 | } 28 | 29 | static void Main(string[] args) 30 | { 31 | // Debugger start 32 | Console.Title = "SE Format Debugger Utility"; 33 | Console.WriteLine("-- SE Format Debugger Utility --\n"); 34 | // Check for input file 35 | if (args.Length <= 0) 36 | { 37 | // Usage 38 | Usage(); 39 | } 40 | else 41 | { 42 | // Make sure the file is a seanim file 43 | if (args[0].EndsWith(".seanim")) 44 | { 45 | // Load and output debug info 46 | if (args.Length > 1) 47 | { 48 | DebugLOGSEAnim(args[0], args[1]); 49 | } 50 | else 51 | { 52 | DebugSEAnim(args[0]); 53 | } 54 | } 55 | else 56 | { 57 | // Usage 58 | Usage(); 59 | } 60 | } 61 | // Pause 62 | Console.Write("\nPress any key to continue..."); 63 | Console.ReadKey(); 64 | } 65 | 66 | /// 67 | /// Print the log to the file 68 | /// 69 | /// The file to debug 70 | /// The output log file 71 | private static void DebugLOGSEAnim(string File, string FileOutput) 72 | { 73 | // Load the anim 74 | var anim = SEAnim.Read(File); 75 | // Load bones 76 | var bones = anim.Bones; 77 | // Log 78 | Console.WriteLine(" Writing log to file..."); 79 | // Prepare output 80 | using (StreamWriter writeFile = new StreamWriter(FileOutput)) 81 | { 82 | // Log 83 | writeFile.WriteLine("-- SEAnim Debugger Utility --"); 84 | writeFile.WriteLine(""); 85 | // Output initial info 86 | writeFile.WriteLine(" Header:"); 87 | // Header data 88 | { 89 | writeFile.WriteLine(" - Frame count: " + anim.FrameCount); 90 | writeFile.WriteLine(" - Frame rate: " + anim.FrameRate); 91 | writeFile.WriteLine(" - Animation type: " + anim.AnimType.ToString()); 92 | writeFile.WriteLine(" - Bone count: " + anim.BoneCount); 93 | writeFile.WriteLine(" - Notetrack count: " + anim.NotificationCount); 94 | writeFile.WriteLine(" - Modifiers count: " + anim.AnimationBoneModifiers.Count); 95 | // Check for delta 96 | if (anim.AnimType == AnimationType.Delta) 97 | { 98 | // Delta bone must be the first one 99 | writeFile.WriteLine(" - Delta tag \"" + anim.DeltaTagName + "\""); 100 | } 101 | } 102 | // Separate and prepare keys by bone 103 | writeFile.WriteLine("\n Frames:"); 104 | // Output keys 105 | foreach (string Bone in anim.Bones) 106 | { 107 | // Bone header 108 | writeFile.WriteLine(" - Bone \"" + Bone + "\" data:"); 109 | // Translation header 110 | writeFile.Write(" - Translations ["); 111 | // Check for translation keys 112 | if (anim.AnimationPositionKeys.ContainsKey(Bone)) 113 | { 114 | // Output translation keys 115 | var translationKeys = anim.AnimationPositionKeys[Bone]; 116 | // Count 117 | writeFile.WriteLine(translationKeys.Count + "]"); 118 | // Output values 119 | foreach (SEAnimFrame frame in translationKeys) 120 | { 121 | // Output the vector 122 | writeFile.WriteLine(" [" + frame.Frame + "] {0} {1} {2}", ((Vector3)frame.Data).X, ((Vector3)frame.Data).Y, ((Vector3)frame.Data).Z); 123 | } 124 | } 125 | else 126 | { 127 | // Had no keys 128 | writeFile.WriteLine("0]"); 129 | } 130 | // Rotation header 131 | writeFile.Write(" - Rotations ["); 132 | // Check for rotation keys 133 | if (anim.AnimationRotationKeys.ContainsKey(Bone)) 134 | { 135 | // Output rotation keys 136 | var rotKeys = anim.AnimationRotationKeys[Bone]; 137 | // Count 138 | writeFile.WriteLine(rotKeys.Count + "]"); 139 | // Output values 140 | foreach (SEAnimFrame frame in rotKeys) 141 | { 142 | // Output the quat 143 | writeFile.WriteLine(" [" + frame.Frame + "] {0} {1} {2} {3}", ((Quaternion)frame.Data).X, ((Quaternion)frame.Data).Y, ((Quaternion)frame.Data).Z, ((Quaternion)frame.Data).W); 144 | } 145 | } 146 | else 147 | { 148 | // Had no keys 149 | writeFile.WriteLine("0]"); 150 | } 151 | // Scales header 152 | writeFile.Write(" - Scales ["); 153 | // Check for scale keys 154 | if (anim.AnimationScaleKeys.ContainsKey(Bone)) 155 | { 156 | // Output scale keys 157 | var scaleKeys = anim.AnimationScaleKeys[Bone]; 158 | // Count 159 | writeFile.WriteLine(scaleKeys.Count + "]"); 160 | // Output values 161 | foreach (SEAnimFrame frame in scaleKeys) 162 | { 163 | // Output the vector 164 | writeFile.WriteLine(" [" + frame.Frame + "] {0} {1} {2}", ((Vector3)frame.Data).X, ((Vector3)frame.Data).Y, ((Vector3)frame.Data).Z); 165 | } 166 | } 167 | else 168 | { 169 | // Had no keys 170 | writeFile.WriteLine("0]"); 171 | } 172 | } 173 | // Separate and prepare notes 174 | writeFile.WriteLine("\n Notifications:"); 175 | // Output notetracks 176 | foreach (KeyValuePair> Notetrack in anim.AnimationNotetracks) 177 | { 178 | // Note header 179 | writeFile.WriteLine(" - Note \"" + Notetrack.Key + "\" data:"); 180 | // Loop and output keys 181 | foreach (SEAnimFrame frame in Notetrack.Value) 182 | { 183 | // Log it 184 | writeFile.WriteLine(" [" + frame.Frame + "] plays"); 185 | } 186 | } 187 | } 188 | } 189 | 190 | /// 191 | /// Print the log to the console 192 | /// 193 | /// The seanim to debug 194 | private static void DebugSEAnim(string File) 195 | { 196 | // Load the anim 197 | var anim = SEAnim.Read(File); 198 | // Load bones 199 | var bones = anim.Bones; 200 | // Output initial info 201 | Console.WriteLine(" Header:"); 202 | // Header data 203 | { 204 | Console.WriteLine(" - Frame count: " + anim.FrameCount); 205 | Console.WriteLine(" - Frame rate: " + anim.FrameRate); 206 | Console.WriteLine(" - Animation type: " + anim.AnimType.ToString()); 207 | Console.WriteLine(" - Bone count: " + anim.BoneCount); 208 | Console.WriteLine(" - Notetrack count: " + anim.NotificationCount); 209 | Console.WriteLine(" - Modifiers count: " + anim.AnimationBoneModifiers.Count); 210 | // Check for delta 211 | if (anim.AnimType == AnimationType.Delta) 212 | { 213 | // Delta bone must be the first one 214 | Console.WriteLine(" - Delta tag \"" + anim.DeltaTagName + "\""); 215 | } 216 | } 217 | // Separate and prepare keys by bone 218 | Console.WriteLine("\n Frames:"); 219 | // Output keys 220 | foreach (string Bone in anim.Bones) 221 | { 222 | // Bone header 223 | Console.WriteLine(" - Bone \"" + Bone + "\" data:"); 224 | // Translation header 225 | Console.Write(" - Translations ["); 226 | // Check for translation keys 227 | if (anim.AnimationPositionKeys.ContainsKey(Bone)) 228 | { 229 | // Output translation keys 230 | var translationKeys = anim.AnimationPositionKeys[Bone]; 231 | // Count 232 | Console.WriteLine(translationKeys.Count + "]"); 233 | // Output values 234 | foreach (SEAnimFrame frame in translationKeys) 235 | { 236 | // Output the vector 237 | Console.WriteLine(" [" + frame.Frame + "] {0} {1} {2}", ((Vector3)frame.Data).X, ((Vector3)frame.Data).Y, ((Vector3)frame.Data).Z); 238 | } 239 | } 240 | else 241 | { 242 | // Had no keys 243 | Console.WriteLine("0]"); 244 | } 245 | // Rotation header 246 | Console.Write(" - Rotations ["); 247 | // Check for rotation keys 248 | if (anim.AnimationRotationKeys.ContainsKey(Bone)) 249 | { 250 | // Output rotation keys 251 | var rotKeys = anim.AnimationRotationKeys[Bone]; 252 | // Count 253 | Console.WriteLine(rotKeys.Count + "]"); 254 | // Output values 255 | foreach (SEAnimFrame frame in rotKeys) 256 | { 257 | // Output the quat 258 | Console.WriteLine(" [" + frame.Frame + "] {0} {1} {2} {3}", ((Quaternion)frame.Data).X, ((Quaternion)frame.Data).Y, ((Quaternion)frame.Data).Z, ((Quaternion)frame.Data).W); 259 | } 260 | } 261 | else 262 | { 263 | // Had no keys 264 | Console.WriteLine("0]"); 265 | } 266 | // Scales header 267 | Console.Write(" - Scales ["); 268 | // Check for scale keys 269 | if (anim.AnimationScaleKeys.ContainsKey(Bone)) 270 | { 271 | // Output scale keys 272 | var scaleKeys = anim.AnimationScaleKeys[Bone]; 273 | // Count 274 | Console.WriteLine(scaleKeys.Count + "]"); 275 | // Output values 276 | foreach (SEAnimFrame frame in scaleKeys) 277 | { 278 | // Output the vector 279 | Console.WriteLine(" [" + frame.Frame + "] {0} {1} {2}", ((Vector3)frame.Data).X, ((Vector3)frame.Data).Y, ((Vector3)frame.Data).Z); 280 | } 281 | } 282 | else 283 | { 284 | // Had no keys 285 | Console.WriteLine("0]"); 286 | } 287 | } 288 | // Separate and prepare notes 289 | Console.WriteLine("\n Notifications:"); 290 | // Output notetracks 291 | foreach (KeyValuePair> Notetrack in anim.AnimationNotetracks) 292 | { 293 | // Note header 294 | Console.WriteLine(" - Note \"" + Notetrack.Key + "\" data:"); 295 | // Loop and output keys 296 | foreach (SEAnimFrame frame in Notetrack.Value) 297 | { 298 | // Log it 299 | Console.WriteLine(" [" + frame.Frame + "] plays"); 300 | } 301 | } 302 | } 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/DebugUtil/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DebugUtil")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DebugUtil")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("7402cb57-ef81-491f-8170-6903d6ecd030")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/SELib.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SELib", "SELib\SELib.csproj", "{E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{8448FA3E-0753-46BD-B6E3-B4F803C093B3}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugUtil", "DebugUtil\DebugUtil.csproj", "{ADDB9CB2-A643-49F4-AEF7-F534BACF5B8D}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {8448FA3E-0753-46BD-B6E3-B4F803C093B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {8448FA3E-0753-46BD-B6E3-B4F803C093B3}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {8448FA3E-0753-46BD-B6E3-B4F803C093B3}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {8448FA3E-0753-46BD-B6E3-B4F803C093B3}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {ADDB9CB2-A643-49F4-AEF7-F534BACF5B8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {ADDB9CB2-A643-49F4-AEF7-F534BACF5B8D}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {ADDB9CB2-A643-49F4-AEF7-F534BACF5B8D}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {ADDB9CB2-A643-49F4-AEF7-F534BACF5B8D}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/SELib/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SELib")] 9 | [assembly: AssemblyDescription("A library for reading and writing SE Formats")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("DTZxPorter")] 12 | [assembly: AssemblyProduct("SELib")] 13 | [assembly: AssemblyCopyright("Copyright © 2017 DTZxPorter")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("fdd4ffe1-b3dd-4999-90ad-f45725f195fc")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.0.2.0")] 36 | [assembly: AssemblyFileVersion("2.0.2.0")] 37 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/SELib/SELib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E03DA150-718D-4EA9-AFCA-D3E17A7DF3E8} 8 | Library 9 | Properties 10 | SELib 11 | SELib 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | true 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 59 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/SELib/Utilities/ExtendedBinaryReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | /// 9 | /// ExtendedBinaryReader.cs 10 | /// Author: DTZxPorter 11 | /// Written for the SE Format Project 12 | /// 13 | 14 | namespace SELib.Utilities 15 | { 16 | /// 17 | /// Supports custom methods for manipulating data between c++ streams and .net ones 18 | /// 19 | internal class ExtendedBinaryReader : BinaryReader 20 | { 21 | public ExtendedBinaryReader(Stream stream) 22 | : base(stream) 23 | { 24 | } 25 | 26 | /// 27 | /// Reads a null-terminated string from the stream 28 | /// 29 | /// The resulting string 30 | public string ReadNullTermString() 31 | { 32 | // Buffer 33 | string StringBuffer = ""; 34 | // Char buffer 35 | char CharBuffer; 36 | // Read until null-term 37 | while ((int)(CharBuffer = this.ReadChar()) != 0) 38 | { 39 | StringBuffer = StringBuffer + CharBuffer; 40 | } 41 | // Result 42 | return StringBuffer; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/SELib/Utilities/ExtendedBinaryWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | /// 9 | /// ExtendedBinaryWriter.cs 10 | /// Author: DTZxPorter 11 | /// Written for the SE Format Project 12 | /// 13 | 14 | namespace SELib.Utilities 15 | { 16 | /// 17 | /// Supports custom methods for manipulating data between c++ streams and .net ones 18 | /// 19 | internal class ExtendedBinaryWriter : BinaryWriter 20 | { 21 | public ExtendedBinaryWriter(Stream stream) 22 | : base(stream) 23 | { 24 | } 25 | 26 | /// 27 | /// Writes a null-terminated string to the stream 28 | /// 29 | /// The string to write 30 | public void WriteNullTermString(string value) 31 | { 32 | // Check value 33 | if (string.IsNullOrEmpty(value)) 34 | { 35 | value = string.Empty; 36 | } 37 | // Write to file 38 | Write(Encoding.ASCII.GetBytes(value)); 39 | // Write the null-char 40 | Write((byte)0); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/SELib/Utilities/ExtendedMath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SELib.Utilities 8 | { 9 | /// 10 | /// Generic interface for all key data 11 | /// 12 | public interface KeyData 13 | { 14 | // A generic interface for a container 15 | } 16 | 17 | /// 18 | /// A container for a vector (XY) (Normalized) 19 | /// 20 | public class Vector2 : KeyData 21 | { 22 | public double X { get; set; } 23 | public double Y { get; set; } 24 | 25 | public Vector2() { X = 0; Y = 0; } 26 | public Vector2(float XCoord, float YCoord) { X = XCoord; Y = YCoord; } 27 | 28 | public override bool Equals(object obj) 29 | { 30 | Vector2 vec = (Vector2)obj; 31 | return (vec.X == X && vec.Y == Y); 32 | } 33 | 34 | public override int GetHashCode() 35 | { 36 | return X.GetHashCode() ^ Y.GetHashCode(); 37 | } 38 | 39 | public static readonly Vector2 Zero = new Vector2() { X = 0, Y = 0 }; 40 | public static readonly Vector2 One = new Vector2() { X = 1, Y = 1 }; 41 | } 42 | 43 | /// 44 | /// A container for a vector (XYZ) (Normalized) 45 | /// 46 | public class Vector3 : Vector2 47 | { 48 | public double Z { get; set; } 49 | 50 | public Vector3() { X = 0; Y = 0; Z = 0; } 51 | public Vector3(float XCoord, float YCoord, float ZCoord) { X = XCoord; Y = YCoord; Z = ZCoord; } 52 | 53 | public override bool Equals(object obj) 54 | { 55 | Vector3 vec = (Vector3)obj; 56 | return (vec.X == X && vec.Y == Y && vec.Z == Z); 57 | } 58 | 59 | public override int GetHashCode() 60 | { 61 | return base.GetHashCode() ^ Z.GetHashCode(); 62 | } 63 | 64 | new public static readonly Vector3 Zero = new Vector3() { X = 0, Y = 0, Z = 0 }; 65 | new public static readonly Vector3 One = new Vector3() { X = 1, Y = 1, Z = 1 }; 66 | } 67 | 68 | /// 69 | /// A container for a color (RGBA) 70 | /// 71 | public class Color 72 | { 73 | public byte R { get; set; } 74 | public byte G { get; set; } 75 | public byte B { get; set; } 76 | public byte A { get; set; } 77 | 78 | public Color() { R = 255; G = 255; B = 255; A = 255; } 79 | public Color(byte Red, byte Green, byte Blue, byte Alpha) { R = Red; G = Green; B = Blue; A = Alpha; } 80 | 81 | public override bool Equals(object obj) 82 | { 83 | Color vec = (Color)obj; 84 | return (vec.R == R && vec.G == G && vec.B == B && vec.A == A); 85 | } 86 | 87 | public override int GetHashCode() 88 | { 89 | return R.GetHashCode() ^ G.GetHashCode() ^ B.GetHashCode() ^ A.GetHashCode(); 90 | } 91 | 92 | public static readonly Color White = new Color(255, 255, 255, 255); 93 | } 94 | 95 | /// 96 | /// A container for a quaternion rotation (XYZW) (Normalized) 97 | /// 98 | public class Quaternion : Vector3 99 | { 100 | public double W { get; set; } 101 | 102 | public Quaternion() { X = 0; Y = 0; Z = 0; W = 1; } 103 | public Quaternion(float XCoord, float YCoord, float ZCoord, float WCoord) { X = XCoord; Y = YCoord; Z = ZCoord; W = WCoord; } 104 | 105 | public override bool Equals(object obj) 106 | { 107 | Quaternion vec = (Quaternion)obj; 108 | return (vec.X == X && vec.Y == Y && vec.Z == Z && vec.W == W); 109 | } 110 | 111 | public override int GetHashCode() 112 | { 113 | return base.GetHashCode() ^ W.GetHashCode(); 114 | } 115 | 116 | public static readonly Quaternion Identity = new Quaternion() { X = 0, Y = 0, Z = 0, W = 1 }; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/UnitTests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/UnitTests/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using SELib; 7 | using SELib.Utilities; 8 | 9 | /// 10 | /// Program.cs (Unit tests) 11 | /// Author: DTZxPorter 12 | /// Written for the SE Format Project 13 | /// Follows SEAnim specification v1.1 14 | /// https://github.com/SE2Dev/SEAnim-Docs/blob/master/spec.md 15 | /// 16 | 17 | namespace UnitTests 18 | { 19 | class Program 20 | { 21 | static void Main(string[] args) 22 | { 23 | // SELib Unit Test 24 | Console.Title = "SELib Unit Tests"; 25 | Console.WriteLine("SELib Unit Tests\n"); 26 | 27 | Console.WriteLine("- SEAnims\n"); 28 | 29 | #region SEAnim 30 | 31 | { 32 | // Log 33 | Console.Write("-- Test 1 "); 34 | // Make it 35 | var anim = new SEAnim(); 36 | // Add some keys 37 | anim.AddTranslationKey("shoulder", 0, 0, 0, 0); 38 | anim.AddTranslationKey("shoulder", 5, 1, 1, 1); 39 | anim.AddTranslationKey("shoulder", 10, 10, 10, 10); 40 | anim.AddTranslationKey("shoulder", 30, 20, 20, 20); 41 | anim.AddTranslationKey("shoulder", 40, 30, 30, 30); 42 | 43 | // Save it 44 | anim.Write("test1.seanim"); 45 | // Done 46 | Console.WriteLine("DONE!"); 47 | } 48 | 49 | { 50 | // Log 51 | Console.Write("-- Test 2 "); 52 | // Make it 53 | var anim = new SEAnim(); 54 | // Add some keys 55 | anim.AddTranslationKey("shoulder", 0, 0, 0, 0); 56 | anim.AddTranslationKey("shoulder", 5, 1, 1, 1); 57 | anim.AddTranslationKey("shoulder", 10, 10, 10, 10); 58 | anim.AddTranslationKey("shoulder", 30, 20, 20, 20); 59 | anim.AddTranslationKey("shoulder", 40, 30, 30, 30); 60 | // Add some scale 61 | anim.AddScaleKey("shoulder", 0, 1, 1, 1); 62 | anim.AddScaleKey("shoulder", 50, 3, 3, 3); 63 | 64 | // Save it 65 | anim.Write("test2.seanim"); 66 | // Done 67 | Console.WriteLine("DONE!"); 68 | } 69 | 70 | { 71 | // Log 72 | Console.Write("-- Test 3 "); 73 | // Make it 74 | var anim = new SEAnim(); 75 | // Add some keys 76 | anim.AddTranslationKey("shoulder", 0, 0, 0, 0); 77 | anim.AddTranslationKey("shoulder", 5, 1, 1, 1); 78 | anim.AddTranslationKey("shoulder", 10, 10, 10, 10); 79 | anim.AddTranslationKey("shoulder", 30, 20, 20, 20); 80 | anim.AddTranslationKey("shoulder", 40, 30, 30, 30); 81 | // Add some scale 82 | anim.AddScaleKey("shoulder", 0, 1, 1, 1); 83 | anim.AddScaleKey("shoulder", 50, 3, 3, 3); 84 | // Add some note 85 | anim.AddNoteTrack("hello_world", 3); 86 | anim.AddNoteTrack("bye", 50); 87 | 88 | // Save it 89 | anim.Write("test3.seanim"); 90 | // Done 91 | Console.WriteLine("DONE!"); 92 | } 93 | 94 | { 95 | // Log 96 | Console.Write("-- Test 4 "); 97 | // Make it 98 | var anim = new SEAnim(); 99 | // Add some keys 100 | anim.AddTranslationKey("shoulder", 0, 0, 0, 0); 101 | anim.AddTranslationKey("shoulder", 5, 1, 1, 1); 102 | anim.AddTranslationKey("shoulder", 10, 10, 10, 10); 103 | anim.AddTranslationKey("shoulder", 30, 20, 20, 20); 104 | anim.AddTranslationKey("shoulder", 40, 30, 30, 30); 105 | // Add some scale 106 | anim.AddScaleKey("shoulder", 0, 1, 1, 1); 107 | anim.AddScaleKey("shoulder", 50, 3, 3, 3); 108 | // Add some note 109 | anim.AddNoteTrack("hello_world", 3); 110 | anim.AddNoteTrack("bye", 50); 111 | 112 | // Save it (Really, we don't need doubles!!) 113 | anim.Write("test4.seanim", true); 114 | // Done 115 | Console.WriteLine("DONE!"); 116 | } 117 | 118 | { 119 | // Log 120 | Console.Write("-- Test 5 "); 121 | // Make it 122 | var anim = new SEAnim(); 123 | // Add some keys 124 | anim.AddTranslationKey("shoulder", 0, 0, 0, 0); 125 | anim.AddTranslationKey("shoulder", 5, 1, 1, 1); 126 | anim.AddTranslationKey("shoulder", 10, 10, 10, 10); 127 | anim.AddTranslationKey("shoulder", 30, 20, 20, 20); 128 | anim.AddTranslationKey("shoulder", 40, 30, 30, 30); 129 | // Add some scale 130 | anim.AddScaleKey("shoulder", 0, 1, 1, 1); 131 | anim.AddScaleKey("shoulder", 50, 3, 3, 3); 132 | // Add some rot 133 | anim.AddRotationKey("shoulder", 0, 0, 0, 0, 1); 134 | anim.AddRotationKey("shoulder", 50, 0.3, 0.2, 0.5, 1); // Random quat for test 135 | // Add some note 136 | anim.AddNoteTrack("hello_world", 3); 137 | anim.AddNoteTrack("bye", 50); 138 | 139 | // Save it 140 | anim.Write("test5.seanim"); 141 | // Done 142 | Console.WriteLine("DONE!"); 143 | } 144 | 145 | { 146 | // Log 147 | Console.Write("-- Test 6 "); 148 | // Read from test 5 149 | var anim = SEAnim.Read("test5.seanim"); 150 | 151 | // Check data 152 | System.Diagnostics.Debug.Assert(anim.AnimationNotetracks.Count == 2); 153 | System.Diagnostics.Debug.Assert(anim.AnimationPositionKeys.Count == 1); 154 | System.Diagnostics.Debug.Assert(anim.AnimationRotationKeys.Count == 1); 155 | System.Diagnostics.Debug.Assert(anim.AnimationScaleKeys.Count == 1); 156 | System.Diagnostics.Debug.Assert(anim.BoneCount == 1); 157 | System.Diagnostics.Debug.Assert(anim.FrameCount == 51); 158 | System.Diagnostics.Debug.Assert(anim.FrameRate == 30.0); 159 | 160 | // Version 161 | System.Diagnostics.Debug.Assert(anim.APIVersion == "v1.0.1"); 162 | 163 | // Check functions 164 | System.Diagnostics.Debug.Assert(anim.RenameBone("shoulder", "shoulder") == false); 165 | System.Diagnostics.Debug.Assert(anim.RenameBone("shoulder", "new_shoulder") == true); 166 | 167 | // Done 168 | Console.WriteLine("DONE!"); 169 | } 170 | 171 | #endregion 172 | 173 | Console.WriteLine("\n- SEModels\n"); 174 | 175 | #region SEModel 176 | 177 | { 178 | // Log 179 | Console.Write("-- Test 1 "); 180 | // Make it 181 | var model = new SEModel(); 182 | // Add some bones 183 | model.AddBone("bone_0001", -1, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); 184 | model.AddBone("bone_0002", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); 185 | model.AddBone("bone_0003", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); 186 | model.AddBone("bone_0004", 2, Vector3.Zero, Quaternion.Identity, new Vector3(22, 22, 22), Quaternion.Identity, Vector3.One); 187 | 188 | // Save it 189 | model.Write("test1.semodel"); 190 | // Done 191 | Console.WriteLine("DONE!"); 192 | } 193 | 194 | { 195 | // Log 196 | Console.Write("-- Test 2 "); 197 | // Make it 198 | var model = new SEModel(); 199 | // Allow globals too 200 | model.ModelBoneSupport = ModelBoneSupportTypes.SupportsBoth; 201 | 202 | // Add some bones 203 | model.AddBone("bone_0001", -1, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); 204 | model.AddBone("bone_0002", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); 205 | model.AddBone("bone_0003", 0, Vector3.Zero, Quaternion.Identity, Vector3.Zero, Quaternion.Identity, Vector3.One); 206 | model.AddBone("bone_0004", 2, Vector3.Zero, Quaternion.Identity, new Vector3(22, 22, 22), Quaternion.Identity, Vector3.One); 207 | 208 | // Save it 209 | model.Write("test2.semodel"); 210 | // Done 211 | Console.WriteLine("DONE!"); 212 | } 213 | 214 | #endregion 215 | 216 | // Pause 217 | Console.Write("\nPress any key to continue..."); 218 | Console.ReadKey(); 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/UnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UnitTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("UnitTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5aee7554-6bb4-4830-a706-ed72e11fba94")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/SELibDotNet/src/UnitTests/UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8448FA3E-0753-46BD-B6E3-B4F803C093B3} 8 | Exe 9 | Properties 10 | UnitTests 11 | UnitTests 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {e03da150-718d-4ea9-afca-d3e17a7df3e8} 53 | SELib 54 | 55 | 56 | 57 | 64 | --------------------------------------------------------------------------------