Compare commits
82 Commits
v0.13.0
...
v0.14.38-m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eab789939d | ||
|
|
04266251aa | ||
|
|
c5f7ef6e91 | ||
|
|
4a81c461e8 | ||
|
|
b10d03d50d | ||
|
|
da98a0c5b8 | ||
|
|
76d17bacf5 | ||
|
|
6678ce082b | ||
|
|
07074b3deb | ||
|
|
df5d9f90d4 | ||
|
|
4f2d30552a | ||
|
|
d259c7a5cd | ||
|
|
c71ceb7ea6 | ||
|
|
85cf134a49 | ||
|
|
687b1d3a0d | ||
|
|
a30a0d0bc5 | ||
|
|
e1dc54d6d7 | ||
|
|
c4270e186d | ||
|
|
182a42ace2 | ||
|
|
06fbe69a97 | ||
|
|
a0bf4f9acd | ||
|
|
12568ba044 | ||
|
|
de95b02285 | ||
|
|
286edfe72c | ||
|
|
d717b223b7 | ||
|
|
9e195832ef | ||
|
|
c8d08b2793 | ||
|
|
2bcd9662be | ||
|
|
ea461ee3d2 | ||
|
|
fda821b441 | ||
|
|
5c193c761a | ||
|
|
14f47c6d30 | ||
|
|
e53eacef78 | ||
|
|
ada26db659 | ||
|
|
48ca96807f | ||
|
|
2018028853 | ||
|
|
6f138dcc05 | ||
|
|
69bcd2be67 | ||
|
|
45ad53b19a | ||
|
|
6230240ee3 | ||
|
|
73ec9f4bee | ||
|
|
f3a0bf505e | ||
|
|
290708876d | ||
|
|
5b96a29cca | ||
|
|
948e2c4d92 | ||
|
|
76da1c33ae | ||
|
|
72b84ee24d | ||
|
|
7b33d41172 | ||
|
|
c7043c1a83 | ||
|
|
d0baf26c61 | ||
|
|
60ac10b043 | ||
|
|
80dc24b487 | ||
|
|
9d32a9dd6a | ||
|
|
d96cc3c762 | ||
|
|
509df42730 | ||
|
|
4efa5b0507 | ||
|
|
cffe96b409 | ||
|
|
16dddc01e3 | ||
|
|
b5d2c2cadb | ||
|
|
1d2c0ab6cb | ||
|
|
c6b7e04c47 | ||
|
|
5704813b28 | ||
|
|
465c989e75 | ||
|
|
d335aaef9e | ||
|
|
495b48c783 | ||
|
|
05b55722fb | ||
|
|
de54257eef | ||
|
|
e62b6c3d77 | ||
|
|
dc05e5b5eb | ||
|
|
f377381e26 | ||
|
|
20f9fe493f | ||
|
|
0b462754a5 | ||
|
|
b1ea8dd346 | ||
|
|
4a46f897bd | ||
|
|
6a5ec80de7 | ||
|
|
4f2046d412 | ||
|
|
1cf59e8d67 | ||
|
|
e9e8390bbc | ||
|
|
738b084440 | ||
|
|
32cce894ac | ||
|
|
a6264b39d1 | ||
|
|
eb4981808b |
172
.gitignore
vendored
172
.gitignore
vendored
@@ -1,7 +1,10 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
@@ -15,13 +18,22 @@
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
build/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
@@ -36,18 +48,28 @@ TestResult.xml
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
@@ -57,6 +79,7 @@ artifacts/
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
@@ -72,14 +95,21 @@ _Chutzpah*
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
@@ -101,9 +131,18 @@ _TeamCity*
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
@@ -131,47 +170,68 @@ publish/
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
## TODO: Comment the next line if you want to checkin your
|
||||
## web deploy settings but do note that will include unencrypted
|
||||
## passwords
|
||||
#*.pubxml
|
||||
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Windows Azure Build Output
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
@@ -182,21 +242,30 @@ _UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- Backup*.rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
@@ -204,7 +273,68 @@ FakesAssemblies/
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# LightSwitch generated files
|
||||
GeneratedArtifacts/
|
||||
_Pvt_Extensions/
|
||||
ModelManifest.xml
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
@@ -1,15 +1,17 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2024
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29920.165
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBX", "AssetStudioFBX\AssetStudioFBX.vcxproj", "{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBX", "AssetStudioFBX\AssetStudioFBX.vcxproj", "{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Texture2DDecoder", "Texture2DDecoder\Texture2DDecoder.vcxproj", "{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{AF56B63C-1764-41B7-9E60-8D485422AC3B}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{80AEC261-21EE-4E4F-A93B-7A744DC84888}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -19,43 +21,51 @@ Global
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Debug|x64.Build.0 = Debug|x64
|
||||
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Debug|x86.Build.0 = Debug|x86
|
||||
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Release|x64.ActiveCfg = Release|x64
|
||||
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Release|x64.Build.0 = Release|x64
|
||||
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Release|x86.ActiveCfg = Release|x86
|
||||
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Release|x86.Build.0 = Release|x86
|
||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Debug|x64.Build.0 = Debug|x64
|
||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Debug|x86.Build.0 = Debug|Win32
|
||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x64.ActiveCfg = Release|x64
|
||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x64.Build.0 = Release|x64
|
||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x86.ActiveCfg = Release|Win32
|
||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x86.Build.0 = Release|Win32
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.Build.0 = Debug|x64
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.Build.0 = Debug|x86
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.ActiveCfg = Release|x64
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.Build.0 = Release|x64
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.ActiveCfg = Release|x86
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.Build.0 = Release|x86
|
||||
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x64.Build.0 = Debug|x64
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x64.ActiveCfg = Release|x64
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x64.Build.0 = Release|x64
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x86.Build.0 = Release|Win32
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x64.Build.0 = Debug|x64
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x86.Build.0 = Debug|Win32
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x64.ActiveCfg = Release|x64
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x64.Build.0 = Release|x64
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x86.ActiveCfg = Release|Win32
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x86.Build.0 = Release|Win32
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.Build.0 = Debug|x64
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.Build.0 = Debug|x86
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.ActiveCfg = Release|x64
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.Build.0 = Release|x64
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.ActiveCfg = Release|x86
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.Build.0 = Release|x86
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.Build.0 = Debug|x64
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.Build.0 = Debug|x86
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.ActiveCfg = Release|x64
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.Build.0 = Release|x64
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.ActiveCfg = Release|x86
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F5C476A6-2B3B-416F-8BD5-6FE454FF3972}
|
||||
SolutionGuid = {F8734F96-97B6-40CA-B791-6D5467F2F713}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{AF56B63C-1764-41B7-9E60-8D485422AC3B}</ProjectGuid>
|
||||
<ProjectGuid>{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AssetStudio</RootNamespace>
|
||||
<AssemblyName>AssetStudio</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
@@ -23,7 +23,7 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
@@ -38,6 +38,7 @@
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -56,22 +57,7 @@
|
||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBit.cs" />
|
||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBitTree.cs" />
|
||||
<Compile Include="7zip\ICoder.cs" />
|
||||
<Compile Include="Classes\RuntimeAnimatorController.cs" />
|
||||
<Compile Include="Math\Color.cs" />
|
||||
<Compile Include="Math\Half.cs" />
|
||||
<Compile Include="Math\HalfHelper.cs" />
|
||||
<Compile Include="Math\Matrix4x4.cs" />
|
||||
<Compile Include="Math\Quaternion.cs" />
|
||||
<Compile Include="Math\Vector2.cs" />
|
||||
<Compile Include="Math\Vector3.cs" />
|
||||
<Compile Include="Math\Vector4.cs" />
|
||||
<Compile Include="UType.cs" />
|
||||
<Compile Include="ResourceReader.cs" />
|
||||
<Compile Include="IImported.cs" />
|
||||
<Compile Include="SerializedFile.cs" />
|
||||
<Compile Include="AssetsManager.cs" />
|
||||
<Compile Include="Extensions\BinaryReaderExtensions.cs" />
|
||||
<Compile Include="Extensions\BinaryWriterExtensions.cs" />
|
||||
<Compile Include="Brotli\BitReader.cs" />
|
||||
<Compile Include="Brotli\BrotliInputStream.cs" />
|
||||
<Compile Include="Brotli\BrotliRuntimeException.cs" />
|
||||
@@ -114,8 +100,10 @@
|
||||
<Compile Include="Classes\NamedObject.cs" />
|
||||
<Compile Include="Classes\Object.cs" />
|
||||
<Compile Include="Classes\PlayerSettings.cs" />
|
||||
<Compile Include="Classes\PPtr.cs" />
|
||||
<Compile Include="Classes\RectTransform.cs" />
|
||||
<Compile Include="Classes\Renderer.cs" />
|
||||
<Compile Include="Classes\RuntimeAnimatorController.cs" />
|
||||
<Compile Include="Classes\Shader.cs" />
|
||||
<Compile Include="Classes\SkinnedMeshRenderer.cs" />
|
||||
<Compile Include="Classes\Sprite.cs" />
|
||||
@@ -128,26 +116,39 @@
|
||||
<Compile Include="ClassIDType.cs" />
|
||||
<Compile Include="CommonString.cs" />
|
||||
<Compile Include="EndianBinaryReader.cs" />
|
||||
<Compile Include="Extensions\BinaryReaderExtensions.cs" />
|
||||
<Compile Include="Extensions\BinaryWriterExtensions.cs" />
|
||||
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||
<Compile Include="FileIdentifier.cs" />
|
||||
<Compile Include="IImported.cs" />
|
||||
<Compile Include="ILogger.cs" />
|
||||
<Compile Include="ImportHelper.cs" />
|
||||
<Compile Include="IProgress.cs" />
|
||||
<Compile Include="LocalSerializedObjectIdentifier.cs" />
|
||||
<Compile Include="Logger.cs" />
|
||||
<Compile Include="Lz4DecoderStream.cs" />
|
||||
<Compile Include="Math\Color.cs" />
|
||||
<Compile Include="Math\Half.cs" />
|
||||
<Compile Include="Math\HalfHelper.cs" />
|
||||
<Compile Include="Math\Matrix4x4.cs" />
|
||||
<Compile Include="Math\Quaternion.cs" />
|
||||
<Compile Include="Math\Vector2.cs" />
|
||||
<Compile Include="Math\Vector3.cs" />
|
||||
<Compile Include="Math\Vector4.cs" />
|
||||
<Compile Include="ObjectInfo.cs" />
|
||||
<Compile Include="ObjectReader.cs" />
|
||||
<Compile Include="Classes\PPtr.cs" />
|
||||
<Compile Include="Progress.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ResourceReader.cs" />
|
||||
<Compile Include="SerializedFile.cs" />
|
||||
<Compile Include="SerializedFileHeader.cs" />
|
||||
<Compile Include="SerializedType.cs" />
|
||||
<Compile Include="SevenZipHelper.cs" />
|
||||
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||
<Compile Include="StreamFile.cs" />
|
||||
<Compile Include="TypeTreeHelper.cs" />
|
||||
<Compile Include="TypeTreeNode.cs" />
|
||||
<Compile Include="UType.cs" />
|
||||
<Compile Include="WebFile.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using static AssetStudio.ImportHelper;
|
||||
@@ -8,12 +9,12 @@ namespace AssetStudio
|
||||
public class AssetsManager
|
||||
{
|
||||
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
|
||||
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>();
|
||||
internal Dictionary<string, EndianBinaryReader> resourceFileReaders = new Dictionary<string, EndianBinaryReader>();
|
||||
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
||||
internal Dictionary<string, BinaryReader> resourceFileReaders = new Dictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private List<string> importFiles = new List<string>();
|
||||
private HashSet<string> importFilesHash = new HashSet<string>();
|
||||
private HashSet<string> assetsFileListHash = new HashSet<string>();
|
||||
private HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public void LoadFiles(params string[] files)
|
||||
{
|
||||
@@ -36,7 +37,7 @@ namespace AssetStudio
|
||||
foreach (var file in files)
|
||||
{
|
||||
importFiles.Add(file);
|
||||
importFilesHash.Add(Path.GetFileName(file).ToUpper());
|
||||
importFilesHash.Add(Path.GetFileName(file));
|
||||
}
|
||||
|
||||
Progress.Reset();
|
||||
@@ -52,7 +53,7 @@ namespace AssetStudio
|
||||
assetsFileListHash.Clear();
|
||||
|
||||
ReadAssets();
|
||||
ProcessGameObject();
|
||||
ProcessAssets();
|
||||
}
|
||||
|
||||
private void LoadFile(string fullName)
|
||||
@@ -74,21 +75,21 @@ namespace AssetStudio
|
||||
private void LoadAssetsFile(string fullName, EndianBinaryReader reader)
|
||||
{
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
if (!assetsFileListHash.Contains(fileName.ToUpper()))
|
||||
if (!assetsFileListHash.Contains(fileName))
|
||||
{
|
||||
Logger.Info($"Loading {fileName}");
|
||||
try
|
||||
{
|
||||
var assetsFile = new SerializedFile(this, fullName, reader);
|
||||
assetsFileList.Add(assetsFile);
|
||||
assetsFileListHash.Add(assetsFile.upperFileName);
|
||||
assetsFileListHash.Add(assetsFile.fileName);
|
||||
|
||||
foreach (var sharedFile in assetsFile.m_Externals)
|
||||
{
|
||||
var sharedFilePath = Path.GetDirectoryName(fullName) + "\\" + sharedFile.fileName;
|
||||
var sharedFileName = sharedFile.fileName;
|
||||
|
||||
if (!importFilesHash.Contains(sharedFileName.ToUpper()))
|
||||
if (!importFilesHash.Contains(sharedFileName))
|
||||
{
|
||||
if (!File.Exists(sharedFilePath))
|
||||
{
|
||||
@@ -102,7 +103,7 @@ namespace AssetStudio
|
||||
if (File.Exists(sharedFilePath))
|
||||
{
|
||||
importFiles.Add(sharedFilePath);
|
||||
importFilesHash.Add(sharedFileName.ToUpper());
|
||||
importFilesHash.Add(sharedFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +111,7 @@ namespace AssetStudio
|
||||
catch
|
||||
{
|
||||
reader.Dispose();
|
||||
//Logger.Error($"Unable to load assets file {fileName}");
|
||||
//Logger.Warning($"Unable to load assets file {fileName}");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -121,8 +122,8 @@ namespace AssetStudio
|
||||
|
||||
private void LoadAssetsFromMemory(string fullName, EndianBinaryReader reader, string originalPath, string unityVersion = null)
|
||||
{
|
||||
var upperFileName = Path.GetFileName(fullName).ToUpper();
|
||||
if (!assetsFileListHash.Contains(upperFileName))
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
if (!assetsFileListHash.Contains(fileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -133,15 +134,12 @@ namespace AssetStudio
|
||||
assetsFile.SetVersion(unityVersion);
|
||||
}
|
||||
assetsFileList.Add(assetsFile);
|
||||
assetsFileListHash.Add(assetsFile.upperFileName);
|
||||
assetsFileListHash.Add(assetsFile.fileName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Logger.Error($"Unable to load assets file {fileName} from {Path.GetFileName(originalPath)}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
resourceFileReaders.Add(upperFileName, reader);
|
||||
resourceFileReaders.Add(fileName, reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,8 +153,16 @@ namespace AssetStudio
|
||||
var bundleFile = new BundleFile(reader, fullName);
|
||||
foreach (var file in bundleFile.fileList)
|
||||
{
|
||||
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
|
||||
LoadAssetsFromMemory(dummyPath, new EndianBinaryReader(file.stream), parentPath ?? fullName, bundleFile.versionEngine);
|
||||
var subReader = new EndianBinaryReader(file.stream);
|
||||
if (SerializedFile.IsSerializedFile(subReader))
|
||||
{
|
||||
var dummyPath = Path.GetDirectoryName(fullName) + Path.DirectorySeparatorChar + file.fileName;
|
||||
LoadAssetsFromMemory(dummyPath, subReader, parentPath ?? fullName, bundleFile.m_Header.unityRevision);
|
||||
}
|
||||
else
|
||||
{
|
||||
resourceFileReaders.Add(file.fileName, subReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -195,6 +201,9 @@ namespace AssetStudio
|
||||
case FileType.WebFile:
|
||||
LoadWebFile(dummyPath, fileReader);
|
||||
break;
|
||||
case FileType.ResourceFile:
|
||||
resourceFileReaders.Add(file.fileName, fileReader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,96 +244,110 @@ namespace AssetStudio
|
||||
Progress.Reset();
|
||||
foreach (var assetsFile in assetsFileList)
|
||||
{
|
||||
assetsFile.Objects = new Dictionary<long, Object>(assetsFile.m_Objects.Count);
|
||||
foreach (var objectInfo in assetsFile.m_Objects)
|
||||
{
|
||||
var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objectInfo);
|
||||
switch (objectReader.type)
|
||||
try
|
||||
{
|
||||
case ClassIDType.Animation:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Animation(objectReader));
|
||||
break;
|
||||
case ClassIDType.AnimationClip:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new AnimationClip(objectReader));
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Animator(objectReader));
|
||||
break;
|
||||
case ClassIDType.AnimatorController:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new AnimatorController(objectReader));
|
||||
break;
|
||||
case ClassIDType.AnimatorOverrideController:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new AnimatorOverrideController(objectReader));
|
||||
break;
|
||||
case ClassIDType.AssetBundle:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new AssetBundle(objectReader));
|
||||
break;
|
||||
case ClassIDType.AudioClip:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new AudioClip(objectReader));
|
||||
break;
|
||||
case ClassIDType.Avatar:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Avatar(objectReader));
|
||||
break;
|
||||
case ClassIDType.Font:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Font(objectReader));
|
||||
break;
|
||||
case ClassIDType.GameObject:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new GameObject(objectReader));
|
||||
break;
|
||||
case ClassIDType.Material:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Material(objectReader));
|
||||
break;
|
||||
case ClassIDType.Mesh:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Mesh(objectReader));
|
||||
break;
|
||||
case ClassIDType.MeshFilter:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new MeshFilter(objectReader));
|
||||
break;
|
||||
case ClassIDType.MeshRenderer:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new MeshRenderer(objectReader));
|
||||
break;
|
||||
case ClassIDType.MonoBehaviour:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new MonoBehaviour(objectReader));
|
||||
break;
|
||||
case ClassIDType.MonoScript:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new MonoScript(objectReader));
|
||||
break;
|
||||
case ClassIDType.MovieTexture:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new MovieTexture(objectReader));
|
||||
break;
|
||||
case ClassIDType.PlayerSettings:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new PlayerSettings(objectReader));
|
||||
break;
|
||||
case ClassIDType.RectTransform:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new RectTransform(objectReader));
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Shader(objectReader));
|
||||
break;
|
||||
case ClassIDType.SkinnedMeshRenderer:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new SkinnedMeshRenderer(objectReader));
|
||||
break;
|
||||
case ClassIDType.Sprite:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Sprite(objectReader));
|
||||
break;
|
||||
case ClassIDType.SpriteAtlas:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new SpriteAtlas(objectReader));
|
||||
break;
|
||||
case ClassIDType.TextAsset:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new TextAsset(objectReader));
|
||||
break;
|
||||
case ClassIDType.Texture2D:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Texture2D(objectReader));
|
||||
break;
|
||||
case ClassIDType.Transform:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Transform(objectReader));
|
||||
break;
|
||||
case ClassIDType.VideoClip:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new VideoClip(objectReader));
|
||||
break;
|
||||
default:
|
||||
assetsFile.Objects.Add(objectInfo.m_PathID, new Object(objectReader));
|
||||
break;
|
||||
Object obj;
|
||||
switch (objectReader.type)
|
||||
{
|
||||
case ClassIDType.Animation:
|
||||
obj = new Animation(objectReader);
|
||||
break;
|
||||
case ClassIDType.AnimationClip:
|
||||
obj = new AnimationClip(objectReader);
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
obj = new Animator(objectReader);
|
||||
break;
|
||||
case ClassIDType.AnimatorController:
|
||||
obj = new AnimatorController(objectReader);
|
||||
break;
|
||||
case ClassIDType.AnimatorOverrideController:
|
||||
obj = new AnimatorOverrideController(objectReader);
|
||||
break;
|
||||
case ClassIDType.AssetBundle:
|
||||
obj = new AssetBundle(objectReader);
|
||||
break;
|
||||
case ClassIDType.AudioClip:
|
||||
obj = new AudioClip(objectReader);
|
||||
break;
|
||||
case ClassIDType.Avatar:
|
||||
obj = new Avatar(objectReader);
|
||||
break;
|
||||
case ClassIDType.Font:
|
||||
obj = new Font(objectReader);
|
||||
break;
|
||||
case ClassIDType.GameObject:
|
||||
obj = new GameObject(objectReader);
|
||||
break;
|
||||
case ClassIDType.Material:
|
||||
obj = new Material(objectReader);
|
||||
break;
|
||||
case ClassIDType.Mesh:
|
||||
obj = new Mesh(objectReader);
|
||||
break;
|
||||
case ClassIDType.MeshFilter:
|
||||
obj = new MeshFilter(objectReader);
|
||||
break;
|
||||
case ClassIDType.MeshRenderer:
|
||||
obj = new MeshRenderer(objectReader);
|
||||
break;
|
||||
case ClassIDType.MonoBehaviour:
|
||||
obj = new MonoBehaviour(objectReader);
|
||||
break;
|
||||
case ClassIDType.MonoScript:
|
||||
obj = new MonoScript(objectReader);
|
||||
break;
|
||||
case ClassIDType.MovieTexture:
|
||||
obj = new MovieTexture(objectReader);
|
||||
break;
|
||||
case ClassIDType.PlayerSettings:
|
||||
obj = new PlayerSettings(objectReader);
|
||||
break;
|
||||
case ClassIDType.RectTransform:
|
||||
obj = new RectTransform(objectReader);
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
obj = new Shader(objectReader);
|
||||
break;
|
||||
case ClassIDType.SkinnedMeshRenderer:
|
||||
obj = new SkinnedMeshRenderer(objectReader);
|
||||
break;
|
||||
case ClassIDType.Sprite:
|
||||
obj = new Sprite(objectReader);
|
||||
break;
|
||||
case ClassIDType.SpriteAtlas:
|
||||
obj = new SpriteAtlas(objectReader);
|
||||
break;
|
||||
case ClassIDType.TextAsset:
|
||||
obj = new TextAsset(objectReader);
|
||||
break;
|
||||
case ClassIDType.Texture2D:
|
||||
obj = new Texture2D(objectReader);
|
||||
break;
|
||||
case ClassIDType.Transform:
|
||||
obj = new Transform(objectReader);
|
||||
break;
|
||||
case ClassIDType.VideoClip:
|
||||
obj = new VideoClip(objectReader);
|
||||
break;
|
||||
default:
|
||||
obj = new Object(objectReader);
|
||||
break;
|
||||
}
|
||||
assetsFile.AddObject(obj);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
/*var sb = new StringBuilder();
|
||||
sb.AppendLine("Unable to load object")
|
||||
.AppendLine($"Assets {assetsFile.fileName}")
|
||||
.AppendLine($"Type {objectReader.type}")
|
||||
.AppendLine($"PathID {objectInfo.m_PathID}")
|
||||
.Append(e);
|
||||
Logger.Error(sb.ToString());*/
|
||||
}
|
||||
|
||||
Progress.Report(++i, progressCount);
|
||||
@@ -332,13 +355,13 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessGameObject()
|
||||
private void ProcessAssets()
|
||||
{
|
||||
Logger.Info("Process GameObject...");
|
||||
Logger.Info("Process Assets...");
|
||||
|
||||
foreach (var assetsFile in assetsFileList)
|
||||
{
|
||||
foreach (var obj in assetsFile.Objects.Values)
|
||||
foreach (var obj in assetsFile.Objects)
|
||||
{
|
||||
if (obj is GameObject m_GameObject)
|
||||
{
|
||||
@@ -370,6 +393,19 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (obj is SpriteAtlas m_SpriteAtlas)
|
||||
{
|
||||
foreach (var m_PackedSprite in m_SpriteAtlas.m_PackedSprites)
|
||||
{
|
||||
if (m_PackedSprite.TryGet(out var m_Sprite))
|
||||
{
|
||||
if (m_Sprite.m_SpriteAtlas.IsNull)
|
||||
{
|
||||
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,246 +1,306 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Lz4;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class StreamFile
|
||||
{
|
||||
public string fileName;
|
||||
public Stream stream;
|
||||
}
|
||||
|
||||
public class BlockInfo
|
||||
{
|
||||
public uint compressedSize;
|
||||
public uint uncompressedSize;
|
||||
public short flag;
|
||||
}
|
||||
|
||||
public class BundleFile
|
||||
{
|
||||
private string path;
|
||||
public string versionPlayer;
|
||||
public string versionEngine;
|
||||
public List<StreamFile> fileList = new List<StreamFile>();
|
||||
|
||||
public BundleFile(EndianBinaryReader bundleReader, string path)
|
||||
public class Header
|
||||
{
|
||||
this.path = path;
|
||||
var signature = bundleReader.ReadStringToNull();
|
||||
switch (signature)
|
||||
public string signature;
|
||||
public uint version;
|
||||
public string unityVersion;
|
||||
public string unityRevision;
|
||||
public long size;
|
||||
public uint compressedBlocksInfoSize;
|
||||
public uint uncompressedBlocksInfoSize;
|
||||
public uint flags;
|
||||
}
|
||||
|
||||
public class StorageBlock
|
||||
{
|
||||
public uint compressedSize;
|
||||
public uint uncompressedSize;
|
||||
public ushort flags;
|
||||
}
|
||||
|
||||
public class Node
|
||||
{
|
||||
public long offset;
|
||||
public long size;
|
||||
public uint flags;
|
||||
public string path;
|
||||
}
|
||||
|
||||
public Header m_Header;
|
||||
private StorageBlock[] m_BlocksInfo;
|
||||
private Node[] m_DirectoryInfo;
|
||||
|
||||
public StreamFile[] fileList;
|
||||
|
||||
public BundleFile(EndianBinaryReader reader, string path)
|
||||
{
|
||||
m_Header = new Header();
|
||||
m_Header.signature = reader.ReadStringToNull();
|
||||
switch (m_Header.signature)
|
||||
{
|
||||
case "UnityArchive":
|
||||
break; //TODO
|
||||
case "UnityWeb":
|
||||
case "UnityRaw":
|
||||
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":
|
||||
ReadHeaderAndBlocksInfo(reader);
|
||||
using (var blocksStream = CreateBlocksStream(path))
|
||||
{
|
||||
var format = bundleReader.ReadInt32();
|
||||
versionPlayer = bundleReader.ReadStringToNull();
|
||||
versionEngine = bundleReader.ReadStringToNull();
|
||||
if (format < 6)
|
||||
{
|
||||
int bundleSize = bundleReader.ReadInt32();
|
||||
}
|
||||
else if (format == 6)
|
||||
{
|
||||
ReadFormat6(bundleReader, true);
|
||||
return;
|
||||
}
|
||||
short dummy2 = bundleReader.ReadInt16();
|
||||
int offset = bundleReader.ReadInt16();
|
||||
int dummy3 = bundleReader.ReadInt32();
|
||||
int lzmaChunks = bundleReader.ReadInt32();
|
||||
|
||||
int lzmaSize = 0;
|
||||
long streamSize = 0;
|
||||
|
||||
for (int i = 0; i < lzmaChunks; i++)
|
||||
{
|
||||
lzmaSize = bundleReader.ReadInt32();
|
||||
streamSize = bundleReader.ReadInt32();
|
||||
}
|
||||
|
||||
bundleReader.Position = offset;
|
||||
switch (signature)
|
||||
{
|
||||
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA": //.bytes
|
||||
case "UnityWeb":
|
||||
{
|
||||
var lzmaBuffer = bundleReader.ReadBytes(lzmaSize);
|
||||
using (var lzmaStream = new EndianBinaryReader(SevenZipHelper.StreamDecompress(new MemoryStream(lzmaBuffer))))
|
||||
{
|
||||
GetAssetsFiles(lzmaStream, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "UnityRaw":
|
||||
{
|
||||
GetAssetsFiles(bundleReader, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
ReadBlocksAndDirectory(reader, blocksStream);
|
||||
ReadFiles(blocksStream, path);
|
||||
}
|
||||
break;
|
||||
case "UnityFS":
|
||||
ReadHeader(reader);
|
||||
ReadBlocksInfoAndDirectory(reader);
|
||||
using (var blocksStream = CreateBlocksStream(path))
|
||||
{
|
||||
var format = bundleReader.ReadInt32();
|
||||
versionPlayer = bundleReader.ReadStringToNull();
|
||||
versionEngine = bundleReader.ReadStringToNull();
|
||||
if (format == 6)
|
||||
{
|
||||
ReadFormat6(bundleReader);
|
||||
}
|
||||
break;
|
||||
ReadBlocks(reader, blocksStream);
|
||||
ReadFiles(blocksStream, path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetAssetsFiles(EndianBinaryReader reader, int offset)
|
||||
private void ReadHeaderAndBlocksInfo(EndianBinaryReader reader)
|
||||
{
|
||||
int fileCount = reader.ReadInt32();
|
||||
for (int i = 0; i < fileCount; i++)
|
||||
var isCompressed = m_Header.signature == "UnityWeb";
|
||||
m_Header.version = reader.ReadUInt32();
|
||||
m_Header.unityVersion = reader.ReadStringToNull();
|
||||
m_Header.unityRevision = reader.ReadStringToNull();
|
||||
if (m_Header.version >= 4)
|
||||
{
|
||||
var file = new StreamFile();
|
||||
file.fileName = Path.GetFileName(reader.ReadStringToNull());
|
||||
int fileOffset = reader.ReadInt32();
|
||||
fileOffset += offset;
|
||||
int fileSize = reader.ReadInt32();
|
||||
long nextFile = reader.Position;
|
||||
reader.Position = fileOffset;
|
||||
var buffer = reader.ReadBytes(fileSize);
|
||||
file.stream = new MemoryStream(buffer);
|
||||
fileList.Add(file);
|
||||
reader.Position = nextFile;
|
||||
var hash = reader.ReadBytes(16);
|
||||
var crc = reader.ReadUInt32();
|
||||
}
|
||||
var minimumStreamedBytes = reader.ReadUInt32();
|
||||
var headerSize = reader.ReadUInt32();
|
||||
var numberOfLevelsToDownloadBeforeStreaming = reader.ReadUInt32();
|
||||
var levelCount = reader.ReadInt32();
|
||||
m_BlocksInfo = new StorageBlock[1];
|
||||
for (int i = 0; i < levelCount; i++)
|
||||
{
|
||||
var storageBlock = new StorageBlock()
|
||||
{
|
||||
compressedSize = reader.ReadUInt32(),
|
||||
uncompressedSize = reader.ReadUInt32(),
|
||||
flags = (ushort)(isCompressed ? 1 : 0)
|
||||
};
|
||||
if (i == levelCount - 1)
|
||||
{
|
||||
m_BlocksInfo[0] = storageBlock;
|
||||
}
|
||||
}
|
||||
if (m_Header.version >= 2)
|
||||
{
|
||||
var completeFileSize = reader.ReadUInt32();
|
||||
}
|
||||
if (m_Header.version >= 3)
|
||||
{
|
||||
var fileInfoHeaderSize = reader.ReadUInt32();
|
||||
}
|
||||
reader.Position = headerSize;
|
||||
}
|
||||
|
||||
private void ReadFormat6(EndianBinaryReader bundleReader, bool padding = false)
|
||||
private Stream CreateBlocksStream(string path)
|
||||
{
|
||||
var bundleSize = bundleReader.ReadInt64();
|
||||
int compressedSize = bundleReader.ReadInt32();
|
||||
int uncompressedSize = bundleReader.ReadInt32();
|
||||
int flag = bundleReader.ReadInt32();
|
||||
if (padding)
|
||||
bundleReader.ReadByte();
|
||||
byte[] blocksInfoBytes;
|
||||
if ((flag & 0x80) != 0)//at end of file
|
||||
Stream blocksStream;
|
||||
var uncompressedSizeSum = m_BlocksInfo.Sum(x => x.uncompressedSize);
|
||||
if (uncompressedSizeSum >= int.MaxValue)
|
||||
{
|
||||
var position = bundleReader.Position;
|
||||
bundleReader.Position = bundleReader.BaseStream.Length - compressedSize;
|
||||
blocksInfoBytes = bundleReader.ReadBytes(compressedSize);
|
||||
bundleReader.Position = position;
|
||||
/*var memoryMappedFile = MemoryMappedFile.CreateNew(Path.GetFileName(path), uncompressedSizeSum);
|
||||
assetsDataStream = memoryMappedFile.CreateViewStream();*/
|
||||
blocksStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
|
||||
}
|
||||
else
|
||||
{
|
||||
blocksInfoBytes = bundleReader.ReadBytes(compressedSize);
|
||||
blocksStream = new MemoryStream((int)uncompressedSizeSum);
|
||||
}
|
||||
MemoryStream blocksInfoStream;
|
||||
switch (flag & 0x3F)
|
||||
return blocksStream;
|
||||
}
|
||||
|
||||
private void ReadBlocksAndDirectory(EndianBinaryReader reader, Stream blocksStream)
|
||||
{
|
||||
foreach (var blockInfo in m_BlocksInfo)
|
||||
{
|
||||
default://None
|
||||
var uncompressedBytes = reader.ReadBytes((int)blockInfo.compressedSize);
|
||||
if (blockInfo.flags == 1)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream(uncompressedBytes))
|
||||
{
|
||||
blocksInfoStream = new MemoryStream(blocksInfoBytes);
|
||||
break;
|
||||
}
|
||||
case 1://LZMA
|
||||
{
|
||||
blocksInfoStream = SevenZipHelper.StreamDecompress(new MemoryStream(blocksInfoBytes));
|
||||
break;
|
||||
}
|
||||
case 2://LZ4
|
||||
case 3://LZ4HC
|
||||
{
|
||||
byte[] uncompressedBytes = new byte[uncompressedSize];
|
||||
using (var decoder = new Lz4DecoderStream(new MemoryStream(blocksInfoBytes)))
|
||||
using (var decompressStream = SevenZipHelper.StreamDecompress(memoryStream))
|
||||
{
|
||||
decoder.Read(uncompressedBytes, 0, uncompressedSize);
|
||||
uncompressedBytes = decompressStream.ToArray();
|
||||
}
|
||||
blocksInfoStream = new MemoryStream(uncompressedBytes);
|
||||
break;
|
||||
}
|
||||
//case 4:LZHAM?
|
||||
}
|
||||
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoStream))
|
||||
{
|
||||
blocksInfoReader.Position = 0x10;
|
||||
int blockcount = blocksInfoReader.ReadInt32();
|
||||
var blockInfos = new BlockInfo[blockcount];
|
||||
for (int i = 0; i < blockcount; i++)
|
||||
{
|
||||
blockInfos[i] = new BlockInfo
|
||||
{
|
||||
uncompressedSize = blocksInfoReader.ReadUInt32(),
|
||||
compressedSize = blocksInfoReader.ReadUInt32(),
|
||||
flag = blocksInfoReader.ReadInt16()
|
||||
};
|
||||
}
|
||||
Stream dataStream;
|
||||
var uncompressedSizeSum = blockInfos.Sum(x => x.uncompressedSize);
|
||||
if (uncompressedSizeSum > int.MaxValue)
|
||||
blocksStream.Write(uncompressedBytes, 0, uncompressedBytes.Length);
|
||||
}
|
||||
blocksStream.Position = 0;
|
||||
var blocksReader = new EndianBinaryReader(blocksStream);
|
||||
var nodesCount = blocksReader.ReadInt32();
|
||||
m_DirectoryInfo = new Node[nodesCount];
|
||||
for (int i = 0; i < nodesCount; i++)
|
||||
{
|
||||
m_DirectoryInfo[i] = new Node
|
||||
{
|
||||
/*var memoryMappedFile = MemoryMappedFile.CreateNew(Path.GetFileName(path), uncompressedSizeSum);
|
||||
assetsDataStream = memoryMappedFile.CreateViewStream();*/
|
||||
dataStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
|
||||
path = blocksReader.ReadStringToNull(),
|
||||
offset = blocksReader.ReadUInt32(),
|
||||
size = blocksReader.ReadUInt32()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void ReadFiles(Stream blocksStream, string path)
|
||||
{
|
||||
fileList = new StreamFile[m_DirectoryInfo.Length];
|
||||
for (int i = 0; i < m_DirectoryInfo.Length; i++)
|
||||
{
|
||||
var node = m_DirectoryInfo[i];
|
||||
var file = new StreamFile();
|
||||
fileList[i] = file;
|
||||
file.fileName = Path.GetFileName(node.path);
|
||||
if (node.size >= int.MaxValue)
|
||||
{
|
||||
/*var memoryMappedFile = MemoryMappedFile.CreateNew(file.fileName, entryinfo_size);
|
||||
file.stream = memoryMappedFile.CreateViewStream();*/
|
||||
var extractPath = path + "_unpacked" + Path.DirectorySeparatorChar;
|
||||
Directory.CreateDirectory(extractPath);
|
||||
file.stream = File.Create(extractPath + file.fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataStream = new MemoryStream();
|
||||
file.stream = new MemoryStream((int)node.size);
|
||||
}
|
||||
foreach (var blockInfo in blockInfos)
|
||||
blocksStream.Position = node.offset;
|
||||
blocksStream.CopyTo(file.stream, node.size);
|
||||
file.stream.Position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadHeader(EndianBinaryReader reader)
|
||||
{
|
||||
m_Header.version = reader.ReadUInt32();
|
||||
m_Header.unityVersion = reader.ReadStringToNull();
|
||||
m_Header.unityRevision = reader.ReadStringToNull();
|
||||
m_Header.size = reader.ReadInt64();
|
||||
m_Header.compressedBlocksInfoSize = reader.ReadUInt32();
|
||||
m_Header.uncompressedBlocksInfoSize = reader.ReadUInt32();
|
||||
m_Header.flags = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader)
|
||||
{
|
||||
byte[] blocksInfoBytes;
|
||||
if ((m_Header.flags & 0x80) != 0) //kArchiveBlocksInfoAtTheEnd
|
||||
{
|
||||
var position = reader.Position;
|
||||
reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
|
||||
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
||||
reader.Position = position;
|
||||
}
|
||||
else //0x40 kArchiveBlocksAndDirectoryInfoCombined
|
||||
{
|
||||
if (m_Header.version >= 7)
|
||||
{
|
||||
switch (blockInfo.flag & 0x3F)
|
||||
{
|
||||
default://None
|
||||
{
|
||||
bundleReader.BaseStream.CopyTo(dataStream, blockInfo.compressedSize);
|
||||
break;
|
||||
}
|
||||
case 1://LZMA
|
||||
{
|
||||
SevenZipHelper.StreamDecompress(bundleReader.BaseStream, dataStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
|
||||
break;
|
||||
}
|
||||
case 2://LZ4
|
||||
case 3://LZ4HC
|
||||
{
|
||||
var lz4Stream = new Lz4DecoderStream(bundleReader.BaseStream, blockInfo.compressedSize);
|
||||
lz4Stream.CopyTo(dataStream, blockInfo.uncompressedSize);
|
||||
break;
|
||||
}
|
||||
//case 4:LZHAM?
|
||||
}
|
||||
reader.AlignStream(16);
|
||||
}
|
||||
dataStream.Position = 0;
|
||||
using (dataStream)
|
||||
{
|
||||
var entryinfo_count = blocksInfoReader.ReadInt32();
|
||||
for (int i = 0; i < entryinfo_count; i++)
|
||||
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
||||
}
|
||||
var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
|
||||
MemoryStream blocksInfoUncompresseddStream;
|
||||
switch (m_Header.flags & 0x3F) //kArchiveCompressionTypeMask
|
||||
{
|
||||
default: //None
|
||||
{
|
||||
var file = new StreamFile();
|
||||
var entryinfo_offset = blocksInfoReader.ReadInt64();
|
||||
var entryinfo_size = blocksInfoReader.ReadInt64();
|
||||
flag = blocksInfoReader.ReadInt32();
|
||||
file.fileName = Path.GetFileName(blocksInfoReader.ReadStringToNull());
|
||||
if (entryinfo_size > int.MaxValue)
|
||||
{
|
||||
/*var memoryMappedFile = MemoryMappedFile.CreateNew(file.fileName, entryinfo_size);
|
||||
file.stream = memoryMappedFile.CreateViewStream();*/
|
||||
var extractPath = path + "_unpacked\\";
|
||||
Directory.CreateDirectory(extractPath);
|
||||
file.stream = File.Create(extractPath + file.fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
file.stream = new MemoryStream();
|
||||
}
|
||||
dataStream.Position = entryinfo_offset;
|
||||
dataStream.CopyTo(file.stream, entryinfo_size);
|
||||
file.stream.Position = 0;
|
||||
fileList.Add(file);
|
||||
blocksInfoUncompresseddStream = blocksInfoCompressedStream;
|
||||
break;
|
||||
}
|
||||
case 1: //LZMA
|
||||
{
|
||||
blocksInfoUncompresseddStream = SevenZipHelper.StreamDecompress(blocksInfoCompressedStream);
|
||||
blocksInfoCompressedStream.Close();
|
||||
break;
|
||||
}
|
||||
case 2: //LZ4
|
||||
case 3: //LZ4HC
|
||||
{
|
||||
var uncompressedBytes = new byte[m_Header.uncompressedBlocksInfoSize];
|
||||
using (var decoder = new Lz4DecoderStream(blocksInfoCompressedStream))
|
||||
{
|
||||
decoder.Read(uncompressedBytes, 0, uncompressedBytes.Length);
|
||||
}
|
||||
blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
|
||||
{
|
||||
var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
|
||||
var blocksInfoCount = blocksInfoReader.ReadInt32();
|
||||
m_BlocksInfo = new StorageBlock[blocksInfoCount];
|
||||
for (int i = 0; i < blocksInfoCount; i++)
|
||||
{
|
||||
m_BlocksInfo[i] = new StorageBlock
|
||||
{
|
||||
uncompressedSize = blocksInfoReader.ReadUInt32(),
|
||||
compressedSize = blocksInfoReader.ReadUInt32(),
|
||||
flags = blocksInfoReader.ReadUInt16()
|
||||
};
|
||||
}
|
||||
|
||||
var nodesCount = blocksInfoReader.ReadInt32();
|
||||
m_DirectoryInfo = new Node[nodesCount];
|
||||
for (int i = 0; i < nodesCount; i++)
|
||||
{
|
||||
m_DirectoryInfo[i] = new Node
|
||||
{
|
||||
offset = blocksInfoReader.ReadInt64(),
|
||||
size = blocksInfoReader.ReadInt64(),
|
||||
flags = blocksInfoReader.ReadUInt32(),
|
||||
path = blocksInfoReader.ReadStringToNull(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
|
||||
{
|
||||
foreach (var blockInfo in m_BlocksInfo)
|
||||
{
|
||||
switch (blockInfo.flags & 0x3F) //kStorageBlockCompressionTypeMask
|
||||
{
|
||||
default: //None
|
||||
{
|
||||
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
|
||||
break;
|
||||
}
|
||||
case 1: //LZMA
|
||||
{
|
||||
SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
|
||||
break;
|
||||
}
|
||||
case 2: //LZ4
|
||||
case 3: //LZ4HC
|
||||
{
|
||||
var compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize));
|
||||
using (var lz4Stream = new Lz4DecoderStream(compressedStream))
|
||||
{
|
||||
lz4Stream.CopyTo(blocksStream, blockInfo.uncompressedSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
blocksStream.Position = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace AssetStudio
|
||||
public AnimationCurve<float> curve;
|
||||
public string attribute;
|
||||
public string path;
|
||||
public int classID;
|
||||
public ClassIDType classID;
|
||||
public PPtr<MonoScript> script;
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace AssetStudio
|
||||
curve = new AnimationCurve<float>(reader, reader.ReadSingle);
|
||||
attribute = reader.ReadAlignedString();
|
||||
path = reader.ReadAlignedString();
|
||||
classID = reader.ReadInt32();
|
||||
classID = (ClassIDType)reader.ReadInt32();
|
||||
script = new PPtr<MonoScript>(reader);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace AssetStudio
|
||||
public string m_Source;
|
||||
public long m_Offset;
|
||||
public long m_Size;
|
||||
public Lazy<byte[]> m_AudioData;
|
||||
public ResourceReader m_AudioData;
|
||||
|
||||
public AudioClip(ObjectReader reader) : base(reader)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ namespace AssetStudio
|
||||
{
|
||||
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size);
|
||||
}
|
||||
m_AudioData = new Lazy<byte[]>(resourceReader.GetData);
|
||||
m_AudioData = resourceReader;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -166,19 +166,19 @@ namespace AssetStudio
|
||||
|
||||
if (version[0] < 4) //4.0 down
|
||||
{
|
||||
GetChannels();
|
||||
GetChannels(version);
|
||||
}
|
||||
}
|
||||
else //5.0 and up
|
||||
{
|
||||
GetStreams();
|
||||
GetStreams(version);
|
||||
}
|
||||
|
||||
m_DataSize = reader.ReadBytes(reader.ReadInt32());
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
private void GetStreams()
|
||||
private void GetStreams(int[] version)
|
||||
{
|
||||
var streamCount = m_Channels.Max(x => x.stream) + 1;
|
||||
m_Streams = new StreamInfo[streamCount];
|
||||
@@ -195,7 +195,7 @@ namespace AssetStudio
|
||||
if (m_Channel.dimension > 0)
|
||||
{
|
||||
chnMask |= 1u << chn;
|
||||
stride += m_Channel.dimension * MeshHelper.GetChannelFormatSize(m_Channel.format);
|
||||
stride += m_Channel.dimension * MeshHelper.GetFormatSize(version, m_Channel.format);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +213,7 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
private void GetChannels()
|
||||
private void GetChannels(int[] version)
|
||||
{
|
||||
m_Channels = new ChannelInfo[6];
|
||||
for (int i = 0; i < 6; i++)
|
||||
@@ -253,7 +253,7 @@ namespace AssetStudio
|
||||
m_Channel.dimension = 4;
|
||||
break;
|
||||
}
|
||||
offset += (byte)(m_Channel.dimension * MeshHelper.GetChannelFormatSize(m_Channel.format));
|
||||
offset += (byte)(m_Channel.dimension * MeshHelper.GetFormatSize(version, m_Channel.format));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,11 +396,21 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
public enum GfxPrimitiveType : int
|
||||
{
|
||||
kPrimitiveTriangles = 0,
|
||||
kPrimitiveTriangleStrip = 1,
|
||||
kPrimitiveQuads = 2,
|
||||
kPrimitiveLines = 3,
|
||||
kPrimitiveLineStrip = 4,
|
||||
kPrimitivePoints = 5,
|
||||
};
|
||||
|
||||
public class SubMesh
|
||||
{
|
||||
public uint firstByte;
|
||||
public uint indexCount;
|
||||
public int topology;
|
||||
public GfxPrimitiveType topology;
|
||||
public uint triangleCount;
|
||||
public uint baseVertex;
|
||||
public uint firstVertex;
|
||||
@@ -413,7 +423,7 @@ namespace AssetStudio
|
||||
|
||||
firstByte = reader.ReadUInt32();
|
||||
indexCount = reader.ReadUInt32();
|
||||
topology = reader.ReadInt32();
|
||||
topology = (GfxPrimitiveType)reader.ReadInt32();
|
||||
|
||||
if (version[0] < 4) //4.0 down
|
||||
{
|
||||
@@ -451,12 +461,16 @@ namespace AssetStudio
|
||||
public float[] m_UV1;
|
||||
public float[] m_UV2;
|
||||
public float[] m_UV3;
|
||||
public float[] m_UV4;
|
||||
public float[] m_UV5;
|
||||
public float[] m_UV6;
|
||||
public float[] m_UV7;
|
||||
public float[] m_Tangents;
|
||||
private VertexData m_VertexData;
|
||||
private CompressedMesh m_CompressedMesh;
|
||||
private StreamingInfo m_StreamData;
|
||||
|
||||
public List<uint> m_Indices = new List<uint>(); //use a list because I don't always know the facecount for triangle strips
|
||||
public List<uint> m_Indices = new List<uint>();
|
||||
|
||||
public Mesh(ObjectReader reader) : base(reader)
|
||||
{
|
||||
@@ -680,7 +694,7 @@ namespace AssetStudio
|
||||
DecompressCompressedMesh();
|
||||
}
|
||||
|
||||
BuildFaces();
|
||||
GetTriangles();
|
||||
}
|
||||
|
||||
private void ReadVertexData()
|
||||
@@ -701,7 +715,7 @@ namespace AssetStudio
|
||||
m_Channel.dimension = 4;
|
||||
}
|
||||
|
||||
var componentByteSize = (int)MeshHelper.GetChannelFormatSize(m_Channel.format);
|
||||
var componentByteSize = (int)MeshHelper.GetFormatSize(version, m_Channel.format);
|
||||
var componentBytes = new byte[m_VertexCount * m_Channel.dimension * componentByteSize];
|
||||
for (int v = 0; v < m_VertexCount; v++)
|
||||
{
|
||||
@@ -726,8 +740,8 @@ namespace AssetStudio
|
||||
|
||||
int[] componentsIntArray = null;
|
||||
float[] componentsFloatArray = null;
|
||||
if (m_Channel.format == 10 || m_Channel.format == 11)
|
||||
componentsIntArray = MeshHelper.BytesToIntArray(componentBytes);
|
||||
if (MeshHelper.IsIntFormat(version, m_Channel.format))
|
||||
componentsIntArray = MeshHelper.BytesToIntArray(componentBytes, componentByteSize);
|
||||
else
|
||||
componentsFloatArray = MeshHelper.BytesToFloatArray(componentBytes, componentByteSize);
|
||||
|
||||
@@ -759,10 +773,18 @@ namespace AssetStudio
|
||||
case 7: //kShaderChannelTexCoord3
|
||||
m_UV3 = componentsFloatArray;
|
||||
break;
|
||||
//kShaderChannelTexCoord4 8
|
||||
//kShaderChannelTexCoord5 9
|
||||
//kShaderChannelTexCoord6 10
|
||||
//kShaderChannelTexCoord7 11
|
||||
case 8: //kShaderChannelTexCoord4
|
||||
m_UV4 = componentsFloatArray;
|
||||
break;
|
||||
case 9: //kShaderChannelTexCoord5
|
||||
m_UV5 = componentsFloatArray;
|
||||
break;
|
||||
case 10: //kShaderChannelTexCoord6
|
||||
m_UV6 = componentsFloatArray;
|
||||
break;
|
||||
case 11: //kShaderChannelTexCoord7
|
||||
m_UV7 = componentsFloatArray;
|
||||
break;
|
||||
//2018.2 and up
|
||||
case 12: //kShaderChannelBlendWeight
|
||||
if (m_Skin == null)
|
||||
@@ -840,23 +862,40 @@ namespace AssetStudio
|
||||
if (m_CompressedMesh.m_Vertices.m_NumItems > 0)
|
||||
{
|
||||
m_VertexCount = (int)m_CompressedMesh.m_Vertices.m_NumItems / 3;
|
||||
m_Vertices = m_CompressedMesh.m_Vertices.UnpackFloats(3, 4);
|
||||
m_Vertices = m_CompressedMesh.m_Vertices.UnpackFloats(3, 3 * 4);
|
||||
}
|
||||
//UV
|
||||
if (m_CompressedMesh.m_UV.m_NumItems > 0)
|
||||
{
|
||||
m_UV0 = m_CompressedMesh.m_UV.UnpackFloats(2, 4, 0, m_VertexCount);
|
||||
if (m_CompressedMesh.m_UV.m_NumItems >= m_VertexCount * 4)
|
||||
var m_UVInfo = m_CompressedMesh.m_UVInfo;
|
||||
if (m_UVInfo != 0)
|
||||
{
|
||||
m_UV1 = m_CompressedMesh.m_UV.UnpackFloats(2, 4, m_VertexCount * 2, m_VertexCount);
|
||||
const int kInfoBitsPerUV = 4;
|
||||
const int kUVDimensionMask = 3;
|
||||
const int kUVChannelExists = 4;
|
||||
const int kMaxTexCoordShaderChannels = 8;
|
||||
|
||||
int uvSrcOffset = 0;
|
||||
for (int uv = 0; uv < kMaxTexCoordShaderChannels; uv++)
|
||||
{
|
||||
var texCoordBits = m_UVInfo >> (uv * kInfoBitsPerUV);
|
||||
texCoordBits &= (1u << kInfoBitsPerUV) - 1u;
|
||||
if ((texCoordBits & kUVChannelExists) != 0)
|
||||
{
|
||||
var uvDim = 1 + (int)(texCoordBits & kUVDimensionMask);
|
||||
var m_UV = m_CompressedMesh.m_UV.UnpackFloats(uvDim, uvDim * 4, uvSrcOffset, m_VertexCount);
|
||||
SetUV(uv, m_UV);
|
||||
uvSrcOffset += uvDim * m_VertexCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_CompressedMesh.m_UV.m_NumItems >= m_VertexCount * 6)
|
||||
else
|
||||
{
|
||||
m_UV2 = m_CompressedMesh.m_UV.UnpackFloats(2, 4, m_VertexCount * 4, m_VertexCount);
|
||||
}
|
||||
if (m_CompressedMesh.m_UV.m_NumItems >= m_VertexCount * 8)
|
||||
{
|
||||
m_UV3 = m_CompressedMesh.m_UV.UnpackFloats(2, 4, m_VertexCount * 6, m_VertexCount);
|
||||
m_UV0 = m_CompressedMesh.m_UV.UnpackFloats(2, 2 * 4, 0, m_VertexCount);
|
||||
if (m_CompressedMesh.m_UV.m_NumItems >= m_VertexCount * 4)
|
||||
{
|
||||
m_UV1 = m_CompressedMesh.m_UV.UnpackFloats(2, 2 * 4, m_VertexCount * 2, m_VertexCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
//BindPose
|
||||
@@ -1008,7 +1047,7 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildFaces()
|
||||
private void GetTriangles()
|
||||
{
|
||||
foreach (var m_SubMesh in m_SubMeshes)
|
||||
{
|
||||
@@ -1017,43 +1056,65 @@ namespace AssetStudio
|
||||
{
|
||||
firstIndex /= 2;
|
||||
}
|
||||
|
||||
if (m_SubMesh.topology == 0)
|
||||
var indexCount = m_SubMesh.indexCount;
|
||||
var topology = m_SubMesh.topology;
|
||||
if (topology == GfxPrimitiveType.kPrimitiveTriangles)
|
||||
{
|
||||
for (int i = 0; i < m_SubMesh.indexCount / 3; i++)
|
||||
for (int i = 0; i < indexCount; i += 3)
|
||||
{
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + i * 3]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + i * 3 + 1]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + i * 3 + 2]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + i]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + i + 1]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + i + 2]);
|
||||
}
|
||||
}
|
||||
else if (version[0] < 4 || topology == GfxPrimitiveType.kPrimitiveTriangleStrip)
|
||||
{
|
||||
// de-stripify :
|
||||
uint triIndex = 0;
|
||||
for (int i = 0; i < indexCount - 2; i++)
|
||||
{
|
||||
var a = m_IndexBuffer[firstIndex + i];
|
||||
var b = m_IndexBuffer[firstIndex + i + 1];
|
||||
var c = m_IndexBuffer[firstIndex + i + 2];
|
||||
|
||||
// skip degenerates
|
||||
if (a == b || a == c || b == c)
|
||||
continue;
|
||||
|
||||
// do the winding flip-flop of strips :
|
||||
if ((i & 1) == 1)
|
||||
{
|
||||
m_Indices.Add(b);
|
||||
m_Indices.Add(a);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Indices.Add(a);
|
||||
m_Indices.Add(b);
|
||||
}
|
||||
m_Indices.Add(c);
|
||||
triIndex += 3;
|
||||
}
|
||||
//fix indexCount
|
||||
m_SubMesh.indexCount = triIndex;
|
||||
}
|
||||
else if (topology == GfxPrimitiveType.kPrimitiveQuads)
|
||||
{
|
||||
for (int q = 0; q < indexCount; q += 4)
|
||||
{
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + q]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + q + 1]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + q + 2]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + q]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + q + 2]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + q + 3]);
|
||||
}
|
||||
//fix indexCount
|
||||
m_SubMesh.indexCount = indexCount / 2 * 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint j = 0;
|
||||
for (int i = 0; i < m_SubMesh.indexCount - 2; i++)
|
||||
{
|
||||
uint fa = m_IndexBuffer[firstIndex + i];
|
||||
uint fb = m_IndexBuffer[firstIndex + i + 1];
|
||||
uint fc = m_IndexBuffer[firstIndex + i + 2];
|
||||
|
||||
if ((fa != fb) && (fa != fc) && (fc != fb))
|
||||
{
|
||||
m_Indices.Add(fa);
|
||||
if ((i % 2) == 0)
|
||||
{
|
||||
m_Indices.Add(fb);
|
||||
m_Indices.Add(fc);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Indices.Add(fc);
|
||||
m_Indices.Add(fb);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
//fix indexCount
|
||||
m_SubMesh.indexCount = j * 3;
|
||||
throw new NotSupportedException("Failed getting triangles. Submesh topology is lines or points.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1066,30 +1127,211 @@ namespace AssetStudio
|
||||
m_Skin[i] = new BoneWeights4();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetUV(int uv, float[] m_UV)
|
||||
{
|
||||
switch (uv)
|
||||
{
|
||||
case 0:
|
||||
m_UV0 = m_UV;
|
||||
break;
|
||||
case 1:
|
||||
m_UV1 = m_UV;
|
||||
break;
|
||||
case 2:
|
||||
m_UV2 = m_UV;
|
||||
break;
|
||||
case 3:
|
||||
m_UV3 = m_UV;
|
||||
break;
|
||||
case 4:
|
||||
m_UV4 = m_UV;
|
||||
break;
|
||||
case 5:
|
||||
m_UV5 = m_UV;
|
||||
break;
|
||||
case 6:
|
||||
m_UV6 = m_UV;
|
||||
break;
|
||||
case 7:
|
||||
m_UV7 = m_UV;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public float[] GetUV(int uv)
|
||||
{
|
||||
switch (uv)
|
||||
{
|
||||
case 0:
|
||||
return m_UV0;
|
||||
case 1:
|
||||
return m_UV1;
|
||||
case 2:
|
||||
return m_UV2;
|
||||
case 3:
|
||||
return m_UV3;
|
||||
case 4:
|
||||
return m_UV4;
|
||||
case 5:
|
||||
return m_UV5;
|
||||
case 6:
|
||||
return m_UV6;
|
||||
case 7:
|
||||
return m_UV7;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MeshHelper
|
||||
{
|
||||
public static uint GetChannelFormatSize(int format)
|
||||
private enum VertexChannelFormat
|
||||
{
|
||||
switch (format)
|
||||
kChannelFormatFloat,
|
||||
kChannelFormatFloat16,
|
||||
kChannelFormatColor,
|
||||
kChannelFormatByte,
|
||||
kChannelFormatUInt32
|
||||
}
|
||||
|
||||
private enum VertexFormat
|
||||
{
|
||||
kVertexFormatFloat,
|
||||
kVertexFormatFloat16,
|
||||
kVertexFormatColor,
|
||||
kVertexFormatUNorm8,
|
||||
kVertexFormatSNorm8,
|
||||
kVertexFormatUNorm16,
|
||||
kVertexFormatSNorm16,
|
||||
kVertexFormatUInt8,
|
||||
kVertexFormatSInt8,
|
||||
kVertexFormatUInt16,
|
||||
kVertexFormatSInt16,
|
||||
kVertexFormatUInt32,
|
||||
kVertexFormatSInt32
|
||||
}
|
||||
|
||||
private enum VertexFormatV2019
|
||||
{
|
||||
kVertexFormatFloat,
|
||||
kVertexFormatFloat16,
|
||||
kVertexFormatUNorm8,
|
||||
kVertexFormatSNorm8,
|
||||
kVertexFormatUNorm16,
|
||||
kVertexFormatSNorm16,
|
||||
kVertexFormatUInt8,
|
||||
kVertexFormatSInt8,
|
||||
kVertexFormatUInt16,
|
||||
kVertexFormatSInt16,
|
||||
kVertexFormatUInt32,
|
||||
kVertexFormatSInt32
|
||||
}
|
||||
|
||||
public static uint GetFormatSize(int[] version, int format)
|
||||
{
|
||||
if (version[0] < 2017)
|
||||
{
|
||||
case 0: //kChannelFormatFloat
|
||||
return 4u;
|
||||
case 1: //kChannelFormatFloat16
|
||||
return 2u;
|
||||
case 2: //kChannelFormatColor
|
||||
return 1u;
|
||||
case 3: //kChannelFormatByte
|
||||
return 1u;
|
||||
case 4: //kChannelFormatUInt32
|
||||
return 4u;
|
||||
case 10: //kChannelFormatInt32
|
||||
return 4u;
|
||||
case 11: //kChannelFormatInt32
|
||||
return 4u;
|
||||
default:
|
||||
return 0;
|
||||
switch ((VertexChannelFormat)format)
|
||||
{
|
||||
case VertexChannelFormat.kChannelFormatFloat:
|
||||
return 4u;
|
||||
case VertexChannelFormat.kChannelFormatFloat16:
|
||||
return 2u;
|
||||
case VertexChannelFormat.kChannelFormatColor: //in 4.x is size 4
|
||||
return 1u;
|
||||
case VertexChannelFormat.kChannelFormatByte:
|
||||
return 1u;
|
||||
case VertexChannelFormat.kChannelFormatUInt32: //in 5.x
|
||||
return 4u;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(format), format, null);
|
||||
}
|
||||
}
|
||||
else if (version[0] < 2019)
|
||||
{
|
||||
switch ((VertexFormat)format)
|
||||
{
|
||||
case VertexFormat.kVertexFormatFloat:
|
||||
return 4u;
|
||||
case VertexFormat.kVertexFormatFloat16:
|
||||
return 2u;
|
||||
case VertexFormat.kVertexFormatColor:
|
||||
return 1u;
|
||||
case VertexFormat.kVertexFormatUNorm8:
|
||||
return 1u;
|
||||
case VertexFormat.kVertexFormatSNorm8:
|
||||
return 1u;
|
||||
case VertexFormat.kVertexFormatUNorm16:
|
||||
return 2u;
|
||||
case VertexFormat.kVertexFormatSNorm16:
|
||||
return 2u;
|
||||
case VertexFormat.kVertexFormatUInt8:
|
||||
return 1u;
|
||||
case VertexFormat.kVertexFormatSInt8:
|
||||
return 1u;
|
||||
case VertexFormat.kVertexFormatUInt16:
|
||||
return 2u;
|
||||
case VertexFormat.kVertexFormatSInt16:
|
||||
return 2u;
|
||||
case VertexFormat.kVertexFormatUInt32:
|
||||
return 4u;
|
||||
case VertexFormat.kVertexFormatSInt32:
|
||||
return 4u;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(format), format, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ((VertexFormatV2019)format)
|
||||
{
|
||||
case VertexFormatV2019.kVertexFormatFloat:
|
||||
return 4u;
|
||||
case VertexFormatV2019.kVertexFormatFloat16:
|
||||
return 2u;
|
||||
case VertexFormatV2019.kVertexFormatUNorm8:
|
||||
return 1u;
|
||||
case VertexFormatV2019.kVertexFormatSNorm8:
|
||||
return 1u;
|
||||
case VertexFormatV2019.kVertexFormatUNorm16:
|
||||
return 2u;
|
||||
case VertexFormatV2019.kVertexFormatSNorm16:
|
||||
return 2u;
|
||||
case VertexFormatV2019.kVertexFormatUInt8:
|
||||
return 1u;
|
||||
case VertexFormatV2019.kVertexFormatSInt8:
|
||||
return 1u;
|
||||
case VertexFormatV2019.kVertexFormatUInt16:
|
||||
return 2u;
|
||||
case VertexFormatV2019.kVertexFormatSInt16:
|
||||
return 2u;
|
||||
case VertexFormatV2019.kVertexFormatUInt32:
|
||||
return 4u;
|
||||
case VertexFormatV2019.kVertexFormatSInt32:
|
||||
return 4u;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(format), format, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsIntFormat(int[] version, int format)
|
||||
{
|
||||
if (version[0] < 2017)
|
||||
{
|
||||
return format == 4;
|
||||
}
|
||||
else if (version[0] < 2019)
|
||||
{
|
||||
return format >= 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
return format >= 6;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1116,12 +1358,23 @@ namespace AssetStudio
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int[] BytesToIntArray(byte[] inputBytes)
|
||||
public static int[] BytesToIntArray(byte[] inputBytes, int size)
|
||||
{
|
||||
var result = new int[inputBytes.Length / 4];
|
||||
for (int i = 0; i < inputBytes.Length / 4; i++)
|
||||
var result = new int[inputBytes.Length / size];
|
||||
for (int i = 0; i < inputBytes.Length / size; i++)
|
||||
{
|
||||
result[i] = BitConverter.ToInt32(inputBytes, i * 4);
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
result[i] = inputBytes[i];
|
||||
break;
|
||||
case 2:
|
||||
result[i] = BitConverter.ToInt16(inputBytes, i * 2);
|
||||
break;
|
||||
case 4:
|
||||
result[i] = BitConverter.ToInt32(inputBytes, i * 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ namespace AssetStudio
|
||||
if (index == -2)
|
||||
{
|
||||
var m_External = assetsFile.m_Externals[m_FileID - 1];
|
||||
var name = m_External.fileName.ToUpper();
|
||||
var name = m_External.fileName;
|
||||
if (!assetsFileIndexCache.TryGetValue(name, out index))
|
||||
{
|
||||
index = assetsFileList.FindIndex(x => x.upperFileName == name);
|
||||
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
assetsFileIndexCache.Add(name, index);
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ namespace AssetStudio
|
||||
{
|
||||
if (TryGetAssetsFile(out var sourceFile))
|
||||
{
|
||||
if (sourceFile.Objects.TryGetValue(m_PathID, out var obj))
|
||||
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
||||
{
|
||||
if (obj is T variable)
|
||||
{
|
||||
@@ -75,7 +75,7 @@ namespace AssetStudio
|
||||
{
|
||||
if (TryGetAssetsFile(out var sourceFile))
|
||||
{
|
||||
if (sourceFile.Objects.TryGetValue(m_PathID, out var obj))
|
||||
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
||||
{
|
||||
if (obj is T2 variable)
|
||||
{
|
||||
@@ -91,8 +91,8 @@ namespace AssetStudio
|
||||
|
||||
public void Set(T m_Object)
|
||||
{
|
||||
var name = m_Object.assetsFile.upperFileName;
|
||||
if (string.Equals(assetsFile.upperFileName, name, StringComparison.Ordinal))
|
||||
var name = m_Object.assetsFile.fileName;
|
||||
if (string.Equals(assetsFile.fileName, name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
m_FileID = 0;
|
||||
}
|
||||
@@ -119,13 +119,13 @@ namespace AssetStudio
|
||||
|
||||
if (!assetsFileIndexCache.TryGetValue(name, out index))
|
||||
{
|
||||
index = assetsFileList.FindIndex(x => x.upperFileName == name);
|
||||
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
assetsFileIndexCache.Add(name, index);
|
||||
}
|
||||
|
||||
m_PathID = m_Object.m_PathID;
|
||||
}
|
||||
|
||||
public bool IsNull() => m_PathID == 0 || m_FileID < 0;
|
||||
public bool IsNull => m_PathID == 0 || m_FileID < 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,13 +39,17 @@ namespace AssetStudio
|
||||
var m_Enabled = reader.ReadBoolean();
|
||||
var m_CastShadows = reader.ReadByte();
|
||||
var m_ReceiveShadows = reader.ReadByte();
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[0] >= 2)) //2017.2 and up
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||
{
|
||||
var m_DynamicOccludee = reader.ReadByte();
|
||||
}
|
||||
var m_MotionVectors = reader.ReadByte();
|
||||
var m_LightProbeUsage = reader.ReadByte();
|
||||
var m_ReflectionProbeUsage = reader.ReadByte();
|
||||
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||
{
|
||||
var m_RayTracingMode = reader.ReadByte();
|
||||
}
|
||||
reader.AlignStream();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -591,6 +591,7 @@ namespace AssetStudio
|
||||
public SerializedProgram progGeometry;
|
||||
public SerializedProgram progHull;
|
||||
public SerializedProgram progDomain;
|
||||
public SerializedProgram progRayTracing;
|
||||
public bool m_HasInstancingVariant;
|
||||
public string m_UseName;
|
||||
public string m_Name;
|
||||
@@ -616,6 +617,10 @@ namespace AssetStudio
|
||||
progGeometry = new SerializedProgram(reader);
|
||||
progHull = new SerializedProgram(reader);
|
||||
progDomain = new SerializedProgram(reader);
|
||||
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||
{
|
||||
progRayTracing = new SerializedProgram(reader);
|
||||
}
|
||||
m_HasInstancingVariant = reader.ReadBoolean();
|
||||
if (version[0] >= 2018) //2018 and up
|
||||
{
|
||||
@@ -759,9 +764,18 @@ namespace AssetStudio
|
||||
{
|
||||
m_ParsedForm = new SerializedShader(reader);
|
||||
platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
|
||||
offsets = reader.ReadUInt32Array();
|
||||
compressedLengths = reader.ReadUInt32Array();
|
||||
decompressedLengths = reader.ReadUInt32Array();
|
||||
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||
{
|
||||
offsets = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
|
||||
compressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
|
||||
decompressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
offsets = reader.ReadUInt32Array();
|
||||
compressedLengths = reader.ReadUInt32Array();
|
||||
decompressedLengths = reader.ReadUInt32Array();
|
||||
}
|
||||
compressedBlob = reader.ReadBytes(reader.ReadInt32());
|
||||
}
|
||||
else
|
||||
|
||||
@@ -32,6 +32,12 @@ namespace AssetStudio
|
||||
kSPMRectangle
|
||||
};
|
||||
|
||||
public enum SpriteMeshType
|
||||
{
|
||||
kSpriteMeshTypeFullRect,
|
||||
kSpriteMeshTypeTight
|
||||
};
|
||||
|
||||
public class SpriteSettings
|
||||
{
|
||||
public uint settingsRaw;
|
||||
@@ -39,6 +45,7 @@ namespace AssetStudio
|
||||
public uint packed;
|
||||
public SpritePackingMode packingMode;
|
||||
public SpritePackingRotation packingRotation;
|
||||
public SpriteMeshType meshType;
|
||||
|
||||
public SpriteSettings(BinaryReader reader)
|
||||
{
|
||||
@@ -47,8 +54,7 @@ namespace AssetStudio
|
||||
packed = settingsRaw & 1; //1
|
||||
packingMode = (SpritePackingMode)((settingsRaw >> 1) & 1); //1
|
||||
packingRotation = (SpritePackingRotation)((settingsRaw >> 2) & 0xf); //4
|
||||
|
||||
//meshType = (settingsRaw >> 6) & 1; //1
|
||||
meshType = (SpriteMeshType)((settingsRaw >> 6) & 1); //1
|
||||
//reserved
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -56,7 +51,7 @@ namespace AssetStudio
|
||||
public bool m_MipMap;
|
||||
public int m_MipCount;
|
||||
public GLTextureSettings m_TextureSettings;
|
||||
public Lazy<byte[]> image_data;
|
||||
public ResourceReader image_data;
|
||||
public StreamingInfo m_StreamData;
|
||||
|
||||
public Texture2D(ObjectReader reader) : base(reader)
|
||||
@@ -107,7 +102,7 @@ namespace AssetStudio
|
||||
{
|
||||
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
|
||||
}
|
||||
image_data = new Lazy<byte[]>(resourceReader.GetData);
|
||||
image_data = resourceReader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,5 +165,11 @@ namespace AssetStudio
|
||||
R8,
|
||||
ETC_RGB4Crunched,
|
||||
ETC2_RGBA8Crunched,
|
||||
ASTC_HDR_4x4,
|
||||
ASTC_HDR_5x5,
|
||||
ASTC_HDR_6x6,
|
||||
ASTC_HDR_8x8,
|
||||
ASTC_HDR_10x10,
|
||||
ASTC_HDR_12x12,
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace AssetStudio
|
||||
{
|
||||
public sealed class VideoClip : NamedObject
|
||||
{
|
||||
public Lazy<byte[]> m_VideoData;
|
||||
public ResourceReader m_VideoData;
|
||||
public string m_OriginalPath;
|
||||
public string m_Source;
|
||||
public ulong m_Size;
|
||||
@@ -47,7 +47,7 @@ namespace AssetStudio
|
||||
{
|
||||
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size);
|
||||
}
|
||||
m_VideoData = new Lazy<byte[]>(resourceReader.GetData);
|
||||
m_VideoData = resourceReader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,8 @@ namespace AssetStudio
|
||||
{1083, "BoundsInt"},
|
||||
{1093, "m_CorrespondingSourceObject"},
|
||||
{1121, "m_PrefabInstance"},
|
||||
{1138, "m_PrefabAsset"}
|
||||
{1138, "m_PrefabAsset"},
|
||||
{1152, "FileSize"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,11 @@ namespace AssetStudio
|
||||
return ReadArray(reader.ReadUInt32, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static uint[][] ReadUInt32ArrayArray(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadUInt32Array, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static uint[] ReadUInt32Array(this BinaryReader reader, int length)
|
||||
{
|
||||
return ReadArray(reader.ReadUInt32, length);
|
||||
|
||||
@@ -134,6 +134,10 @@ namespace AssetStudio
|
||||
public string Path { get; set; }
|
||||
public List<ImportedSubmesh> SubmeshList { get; set; }
|
||||
public List<ImportedBone> BoneList { get; set; }
|
||||
public bool hasNormal { get; set; }
|
||||
public bool[] hasUV { get; set; }
|
||||
public bool hasTangent { get; set; }
|
||||
public bool hasColor { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedSubmesh
|
||||
@@ -145,17 +149,13 @@ namespace AssetStudio
|
||||
|
||||
public class ImportedVertex
|
||||
{
|
||||
public Vector3 Position { get; set; }
|
||||
public Vector3 Vertex { get; set; }
|
||||
public Vector3 Normal { get; set; }
|
||||
public float[][] UV { get; set; }
|
||||
public Vector4 Tangent { get; set; }
|
||||
public Color Color { get; set; }
|
||||
public float[] Weights { get; set; }
|
||||
public int[] BoneIndices { get; set; }
|
||||
public Vector3 Normal { get; set; }
|
||||
public float[] UV { get; set; }
|
||||
public Vector4 Tangent { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedVertexWithColour : ImportedVertex
|
||||
{
|
||||
public Color Colour { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedFace
|
||||
@@ -205,7 +205,7 @@ namespace AssetStudio
|
||||
public class ImportedKeyframedAnimation
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public float SampleRate { get; set; }
|
||||
public List<ImportedAnimationKeyframedTrack> TrackList { get; set; }
|
||||
|
||||
public ImportedAnimationKeyframedTrack FindTrack(string path)
|
||||
@@ -227,14 +227,13 @@ namespace AssetStudio
|
||||
public List<ImportedKeyframe<Vector3>> Scalings = new List<ImportedKeyframe<Vector3>>();
|
||||
public List<ImportedKeyframe<Vector3>> Rotations = new List<ImportedKeyframe<Vector3>>();
|
||||
public List<ImportedKeyframe<Vector3>> Translations = new List<ImportedKeyframe<Vector3>>();
|
||||
public ImportedBlendShape BlendShape;
|
||||
}
|
||||
|
||||
public class ImportedKeyframe<T>
|
||||
{
|
||||
public float time { get; set; }
|
||||
public T value { get; set; }
|
||||
public T inSlope { get; set; }
|
||||
public T outSlope { get; set; }
|
||||
|
||||
public ImportedKeyframe(float time, T value)
|
||||
{
|
||||
@@ -243,21 +242,36 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
public class ImportedBlendShape
|
||||
{
|
||||
public string ChannelName;
|
||||
public List<ImportedKeyframe<float>> Keyframes = new List<ImportedKeyframe<float>>();
|
||||
}
|
||||
|
||||
public class ImportedMorph
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public string ClipName { get; set; }
|
||||
public List<Tuple<float, int, int>> Channels { get; set; }
|
||||
public List<ImportedMorphChannel> Channels { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedMorphChannel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<ImportedMorphKeyframe> KeyframeList { get; set; }
|
||||
public List<ushort> MorphedVertexIndices { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedMorphKeyframe
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<ImportedVertex> VertexList { get; set; }
|
||||
public List<ushort> MorphedVertexIndices { get; set; }
|
||||
public bool hasNormals { get; set; }
|
||||
public bool hasTangents { get; set; }
|
||||
public float Weight { get; set; }
|
||||
public List<ImportedMorphVertex> VertexList { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedMorphVertex
|
||||
{
|
||||
public uint Index { get; set; }
|
||||
public ImportedVertex Vertex { get; set; }
|
||||
}
|
||||
|
||||
public static class ImportedHelpers
|
||||
|
||||
@@ -8,7 +8,8 @@ namespace AssetStudio
|
||||
{
|
||||
AssetsFile,
|
||||
BundleFile,
|
||||
WebFile
|
||||
WebFile,
|
||||
ResourceFile
|
||||
}
|
||||
|
||||
public static class ImportHelper
|
||||
@@ -76,7 +77,7 @@ namespace AssetStudio
|
||||
{
|
||||
case "UnityWeb":
|
||||
case "UnityRaw":
|
||||
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":
|
||||
case "UnityArchive":
|
||||
case "UnityFS":
|
||||
return FileType.BundleFile;
|
||||
case "UnityWebData1.0":
|
||||
@@ -96,7 +97,14 @@ namespace AssetStudio
|
||||
{
|
||||
return FileType.WebFile;
|
||||
}
|
||||
return FileType.AssetsFile;
|
||||
if (SerializedFile.IsSerializedFile(reader))
|
||||
{
|
||||
return FileType.AssetsFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FileType.ResourceFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,8 @@ namespace AssetStudio
|
||||
|
||||
public static Vector3 Zero => new Vector3();
|
||||
|
||||
public static Vector3 One => new Vector3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
public static Vector3 operator +(Vector3 a, Vector3 b)
|
||||
{
|
||||
return new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace AssetStudio
|
||||
{
|
||||
public class ObjectInfo
|
||||
{
|
||||
public uint byteStart;
|
||||
public long byteStart;
|
||||
public uint byteSize;
|
||||
public int typeID;
|
||||
public int classID;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace AssetStudio
|
||||
{
|
||||
public SerializedFile assetsFile;
|
||||
public long m_PathID;
|
||||
public uint byteStart;
|
||||
public long byteStart;
|
||||
public uint byteSize;
|
||||
public ClassIDType type;
|
||||
public SerializedType serializedType;
|
||||
|
||||
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AssetStudio")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyCopyright("Copyright © Perfare 2018-2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("af56b63c-1764-41b7-9e60-8d485422ac3b")]
|
||||
[assembly: Guid("7662f8c2-7bfd-442e-a948-a43b4f7eb06e")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
@@ -29,8 +29,8 @@ using System.Runtime.InteropServices;
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyVersion("0.14.38.5")]
|
||||
[assembly: AssemblyFileVersion("0.14.38.5")]
|
||||
|
||||
@@ -34,17 +34,18 @@ namespace AssetStudio
|
||||
{
|
||||
var resourceFileName = Path.GetFileName(path);
|
||||
|
||||
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader))
|
||||
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader))
|
||||
{
|
||||
reader.Position = offset;
|
||||
needSearch = false;
|
||||
reader.BaseStream.Position = offset;
|
||||
return reader.ReadBytes(size);
|
||||
}
|
||||
|
||||
var currentDirectory = Path.GetDirectoryName(assetsFile.fullName);
|
||||
var resourceFilePath = currentDirectory + "\\" + resourceFileName;
|
||||
var assetsFileDirectory = Path.GetDirectoryName(assetsFile.fullName);
|
||||
var resourceFilePath = assetsFileDirectory + Path.DirectorySeparatorChar + resourceFileName;
|
||||
if (!File.Exists(resourceFilePath))
|
||||
{
|
||||
var findFiles = Directory.GetFiles(currentDirectory, resourceFileName, SearchOption.AllDirectories);
|
||||
var findFiles = Directory.GetFiles(assetsFileDirectory, resourceFileName, SearchOption.AllDirectories);
|
||||
if (findFiles.Length > 0)
|
||||
{
|
||||
resourceFilePath = findFiles[0];
|
||||
@@ -52,11 +53,11 @@ namespace AssetStudio
|
||||
}
|
||||
if (File.Exists(resourceFilePath))
|
||||
{
|
||||
using (var resourceReader = new BinaryReader(File.OpenRead(resourceFilePath)))
|
||||
{
|
||||
resourceReader.BaseStream.Position = offset;
|
||||
return resourceReader.ReadBytes(size);
|
||||
}
|
||||
reader = new BinaryReader(File.OpenRead(resourceFilePath));
|
||||
needSearch = false;
|
||||
assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader);
|
||||
reader.BaseStream.Position = offset;
|
||||
return reader.ReadBytes(size);
|
||||
}
|
||||
|
||||
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
|
||||
|
||||
@@ -13,10 +13,10 @@ namespace AssetStudio
|
||||
public string fullName;
|
||||
public string originalPath;
|
||||
public string fileName;
|
||||
public string upperFileName;
|
||||
public int[] version = { 0, 0, 0, 0 };
|
||||
public BuildType buildType;
|
||||
public Dictionary<long, Object> Objects;
|
||||
public List<Object> Objects;
|
||||
public Dictionary<long, Object> ObjectsDic;
|
||||
|
||||
public SerializedFileHeader header;
|
||||
private EndianType m_FileEndianess;
|
||||
@@ -24,6 +24,7 @@ namespace AssetStudio
|
||||
public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform;
|
||||
private bool m_EnableTypeTree = true;
|
||||
public List<SerializedType> m_Types;
|
||||
public List<SerializedType> m_RefTypes;
|
||||
public List<ObjectInfo> m_Objects;
|
||||
private List<LocalSerializedObjectIdentifier> m_ScriptTypes;
|
||||
public List<FileIdentifier> m_Externals;
|
||||
@@ -34,7 +35,6 @@ namespace AssetStudio
|
||||
this.reader = reader;
|
||||
this.fullName = fullName;
|
||||
fileName = Path.GetFileName(fullName);
|
||||
upperFileName = fileName.ToUpper();
|
||||
|
||||
//ReadHeader
|
||||
header = new SerializedFileHeader();
|
||||
@@ -55,6 +55,14 @@ namespace AssetStudio
|
||||
m_FileEndianess = (EndianType)reader.ReadByte();
|
||||
}
|
||||
|
||||
if (header.m_Version >= 22)
|
||||
{
|
||||
header.m_MetadataSize = reader.ReadUInt32();
|
||||
header.m_FileSize = reader.ReadInt64();
|
||||
header.m_DataOffset = reader.ReadInt64();
|
||||
reader.ReadInt64(); // unknown
|
||||
}
|
||||
|
||||
//ReadMetadata
|
||||
if (m_FileEndianess == EndianType.LittleEndian)
|
||||
{
|
||||
@@ -86,18 +94,25 @@ namespace AssetStudio
|
||||
m_Types.Add(ReadSerializedType());
|
||||
}
|
||||
|
||||
var bigIDEnabled = 0;
|
||||
if (header.m_Version >= 7 && header.m_Version < 14)
|
||||
{
|
||||
var bigIDEnabled = reader.ReadInt32();
|
||||
bigIDEnabled = reader.ReadInt32();
|
||||
}
|
||||
|
||||
//ReadObjects
|
||||
int objectCount = reader.ReadInt32();
|
||||
m_Objects = new List<ObjectInfo>(objectCount);
|
||||
Objects = new List<Object>(objectCount);
|
||||
ObjectsDic = new Dictionary<long, Object>(objectCount);
|
||||
for (int i = 0; i < objectCount; i++)
|
||||
{
|
||||
var objectInfo = new ObjectInfo();
|
||||
if (header.m_Version < 14)
|
||||
if (bigIDEnabled != 0)
|
||||
{
|
||||
objectInfo.m_PathID = reader.ReadInt64();
|
||||
}
|
||||
else if (header.m_Version < 14)
|
||||
{
|
||||
objectInfo.m_PathID = reader.ReadInt32();
|
||||
}
|
||||
@@ -106,7 +121,12 @@ namespace AssetStudio
|
||||
reader.AlignStream();
|
||||
objectInfo.m_PathID = reader.ReadInt64();
|
||||
}
|
||||
objectInfo.byteStart = reader.ReadUInt32();
|
||||
|
||||
if (header.m_Version >= 22)
|
||||
objectInfo.byteStart = reader.ReadInt64();
|
||||
else
|
||||
objectInfo.byteStart = reader.ReadUInt32();
|
||||
|
||||
objectInfo.byteStart += header.m_DataOffset;
|
||||
objectInfo.byteSize = reader.ReadUInt32();
|
||||
objectInfo.typeID = reader.ReadInt32();
|
||||
@@ -114,7 +134,6 @@ namespace AssetStudio
|
||||
{
|
||||
objectInfo.classID = reader.ReadUInt16();
|
||||
objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
|
||||
var isDestroyed = reader.ReadUInt16();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -122,6 +141,16 @@ namespace AssetStudio
|
||||
objectInfo.serializedType = type;
|
||||
objectInfo.classID = type.classID;
|
||||
}
|
||||
if (header.m_Version < 11)
|
||||
{
|
||||
var isDestroyed = reader.ReadUInt16();
|
||||
}
|
||||
if (header.m_Version >= 11 && header.m_Version < 17)
|
||||
{
|
||||
var m_ScriptTypeIndex = reader.ReadInt16();
|
||||
if (objectInfo.serializedType != null)
|
||||
objectInfo.serializedType.m_ScriptTypeIndex = m_ScriptTypeIndex;
|
||||
}
|
||||
if (header.m_Version == 15 || header.m_Version == 16)
|
||||
{
|
||||
var stripped = reader.ReadByte();
|
||||
@@ -169,10 +198,22 @@ namespace AssetStudio
|
||||
m_Externals.Add(m_External);
|
||||
}
|
||||
|
||||
if (header.m_Version >= 20)
|
||||
{
|
||||
int refTypesCount = reader.ReadInt32();
|
||||
m_RefTypes = new List<SerializedType>(refTypesCount);
|
||||
for (int i = 0; i < refTypesCount; i++)
|
||||
{
|
||||
m_RefTypes.Add(ReadSerializedType());
|
||||
}
|
||||
}
|
||||
|
||||
if (header.m_Version >= 5)
|
||||
{
|
||||
//var userInformation = reader.ReadStringToNull();
|
||||
var userInformation = reader.ReadStringToNull();
|
||||
}
|
||||
|
||||
//reader.AlignStream(16);
|
||||
}
|
||||
|
||||
public void SetVersion(string stringVersion)
|
||||
@@ -214,13 +255,18 @@ namespace AssetStudio
|
||||
var typeTree = new List<TypeTreeNode>();
|
||||
if (header.m_Version >= 12 || header.m_Version == 10)
|
||||
{
|
||||
ReadTypeTree5(typeTree);
|
||||
TypeTreeBlobRead(typeTree);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadTypeTree(typeTree);
|
||||
}
|
||||
|
||||
if (header.m_Version >= 21)
|
||||
{
|
||||
type.m_TypeDependencies = reader.ReadInt32Array();
|
||||
}
|
||||
|
||||
type.m_Nodes = typeTree;
|
||||
}
|
||||
|
||||
@@ -257,42 +303,37 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadTypeTree5(List<TypeTreeNode> typeTree)
|
||||
private void TypeTreeBlobRead(List<TypeTreeNode> typeTree)
|
||||
{
|
||||
int numberOfNodes = reader.ReadInt32();
|
||||
int stringBufferSize = reader.ReadInt32();
|
||||
|
||||
var nodeSize = 24;
|
||||
if (header.m_Version > 17)
|
||||
for (int i = 0; i < numberOfNodes; i++)
|
||||
{
|
||||
nodeSize = 32;
|
||||
var typeTreeNode = new TypeTreeNode();
|
||||
typeTree.Add(typeTreeNode);
|
||||
typeTreeNode.m_Version = reader.ReadUInt16();
|
||||
typeTreeNode.m_Level = reader.ReadByte();
|
||||
typeTreeNode.m_IsArray = reader.ReadBoolean() ? 1 : 0;
|
||||
typeTreeNode.m_TypeStrOffset = reader.ReadUInt32();
|
||||
typeTreeNode.m_NameStrOffset = reader.ReadUInt32();
|
||||
typeTreeNode.m_ByteSize = reader.ReadInt32();
|
||||
typeTreeNode.m_Index = reader.ReadInt32();
|
||||
typeTreeNode.m_MetaFlag = reader.ReadInt32();
|
||||
if (header.m_Version >= 19)
|
||||
{
|
||||
typeTreeNode.m_RefTypeHash = reader.ReadUInt64();
|
||||
}
|
||||
}
|
||||
reader.Position += numberOfNodes * nodeSize;
|
||||
using (var stringBufferReader = new BinaryReader(new MemoryStream(reader.ReadBytes(stringBufferSize))))
|
||||
var m_StringBuffer = reader.ReadBytes(stringBufferSize);
|
||||
|
||||
using (var stringBufferReader = new BinaryReader(new MemoryStream(m_StringBuffer)))
|
||||
{
|
||||
reader.Position -= numberOfNodes * nodeSize + stringBufferSize;
|
||||
for (int i = 0; i < numberOfNodes; i++)
|
||||
{
|
||||
var typeTreeNode = new TypeTreeNode();
|
||||
typeTree.Add(typeTreeNode);
|
||||
typeTreeNode.m_Version = reader.ReadUInt16();
|
||||
typeTreeNode.m_Level = reader.ReadByte();
|
||||
typeTreeNode.m_IsArray = reader.ReadBoolean() ? 1 : 0;
|
||||
typeTreeNode.m_TypeStrOffset = reader.ReadUInt32();
|
||||
typeTreeNode.m_NameStrOffset = reader.ReadUInt32();
|
||||
typeTreeNode.m_ByteSize = reader.ReadInt32();
|
||||
typeTreeNode.m_Index = reader.ReadInt32();
|
||||
typeTreeNode.m_MetaFlag = reader.ReadInt32();
|
||||
|
||||
if (header.m_Version > 17)
|
||||
{
|
||||
reader.Position += 8;
|
||||
}
|
||||
|
||||
var typeTreeNode = typeTree[i];
|
||||
typeTreeNode.m_Type = ReadString(stringBufferReader, typeTreeNode.m_TypeStrOffset);
|
||||
typeTreeNode.m_Name = ReadString(stringBufferReader, typeTreeNode.m_NameStrOffset);
|
||||
}
|
||||
reader.Position += stringBufferSize;
|
||||
}
|
||||
|
||||
string ReadString(BinaryReader stringBufferReader, uint value)
|
||||
@@ -311,5 +352,48 @@ namespace AssetStudio
|
||||
return offset.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddObject(Object obj)
|
||||
{
|
||||
Objects.Add(obj);
|
||||
ObjectsDic.Add(obj.m_PathID, obj);
|
||||
}
|
||||
|
||||
public static bool IsSerializedFile(EndianBinaryReader reader)
|
||||
{
|
||||
var fileSize = reader.BaseStream.Length;
|
||||
if (fileSize < 20)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var m_MetadataSize = reader.ReadUInt32();
|
||||
long m_FileSize = reader.ReadUInt32();
|
||||
var m_Version = reader.ReadUInt32();
|
||||
long m_DataOffset = reader.ReadUInt32();
|
||||
var m_Endianess = reader.ReadByte();
|
||||
var m_Reserved = reader.ReadBytes(3);
|
||||
if (m_Version >= 22)
|
||||
{
|
||||
if (fileSize < 48)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_MetadataSize = reader.ReadUInt32();
|
||||
m_FileSize = reader.ReadInt64();
|
||||
m_DataOffset = reader.ReadInt64();
|
||||
}
|
||||
if (m_FileSize != fileSize)
|
||||
{
|
||||
reader.Position = 0;
|
||||
return false;
|
||||
}
|
||||
if (m_DataOffset > fileSize)
|
||||
{
|
||||
reader.Position = 0;
|
||||
return false;
|
||||
}
|
||||
reader.Position = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ namespace AssetStudio
|
||||
public class SerializedFileHeader
|
||||
{
|
||||
public uint m_MetadataSize;
|
||||
public uint m_FileSize;
|
||||
public long m_FileSize;
|
||||
public uint m_Version;
|
||||
public uint m_DataOffset;
|
||||
public long m_DataOffset;
|
||||
public byte m_Endianess;
|
||||
public byte[] m_Reserved;
|
||||
}
|
||||
|
||||
@@ -13,5 +13,6 @@ namespace AssetStudio
|
||||
public List<TypeTreeNode> m_Nodes;
|
||||
public byte[] m_ScriptID; //Hash128
|
||||
public byte[] m_OldTypeHash; //Hash128
|
||||
public int[] m_TypeDependencies;
|
||||
}
|
||||
}
|
||||
|
||||
10
AssetStudio/StreamFile.cs
Normal file
10
AssetStudio/StreamFile.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.IO;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class StreamFile
|
||||
{
|
||||
public string fileName;
|
||||
public Stream stream;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ namespace AssetStudio
|
||||
value = reader.ReadSByte();
|
||||
break;
|
||||
case "UInt8":
|
||||
case "char":
|
||||
value = reader.ReadByte();
|
||||
break;
|
||||
case "short":
|
||||
@@ -56,6 +57,7 @@ namespace AssetStudio
|
||||
break;
|
||||
case "UInt64":
|
||||
case "unsigned long long":
|
||||
case "FileSize":
|
||||
value = reader.ReadUInt64();
|
||||
break;
|
||||
case "float":
|
||||
@@ -73,26 +75,6 @@ namespace AssetStudio
|
||||
sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str);
|
||||
i += 3;
|
||||
break;
|
||||
case "vector":
|
||||
{
|
||||
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
|
||||
align = true;
|
||||
append = false;
|
||||
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
|
||||
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array");
|
||||
var size = reader.ReadInt32();
|
||||
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size);
|
||||
var vector = GetMembers(members, level, i);
|
||||
i += vector.Count - 1;
|
||||
vector.RemoveRange(0, 3);
|
||||
for (int j = 0; j < size; j++)
|
||||
{
|
||||
sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j);
|
||||
int tmp = 0;
|
||||
ReadStringValue(sb, vector, reader, ref tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "map":
|
||||
{
|
||||
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
|
||||
@@ -102,12 +84,11 @@ namespace AssetStudio
|
||||
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array");
|
||||
var size = reader.ReadInt32();
|
||||
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size);
|
||||
var map = GetMembers(members, level, i);
|
||||
var map = GetMembers(members, i);
|
||||
i += map.Count - 1;
|
||||
map.RemoveRange(0, 4);
|
||||
var first = GetMembers(map, map[0].m_Level, 0);
|
||||
map.RemoveRange(0, first.Count);
|
||||
var second = map;
|
||||
var first = GetMembers(map, 4);
|
||||
var next = 4 + first.Count;
|
||||
var second = GetMembers(map, next);
|
||||
for (int j = 0; j < size; j++)
|
||||
{
|
||||
sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j);
|
||||
@@ -131,20 +112,37 @@ namespace AssetStudio
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (i != members.Count && members[i + 1].m_Type == "Array")
|
||||
if (i < members.Count - 1 && members[i + 1].m_Type == "Array") //Array
|
||||
{
|
||||
goto case "vector";
|
||||
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
|
||||
align = true;
|
||||
append = false;
|
||||
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
|
||||
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array");
|
||||
var size = reader.ReadInt32();
|
||||
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size);
|
||||
var vector = GetMembers(members, i);
|
||||
i += vector.Count - 1;
|
||||
for (int j = 0; j < size; j++)
|
||||
{
|
||||
sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j);
|
||||
int tmp = 3;
|
||||
ReadStringValue(sb, vector, reader, ref tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
append = false;
|
||||
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
|
||||
var @class = GetMembers(members, level, i);
|
||||
@class.RemoveAt(0);
|
||||
i += @class.Count;
|
||||
for (int j = 0; j < @class.Count; j++)
|
||||
else //Class
|
||||
{
|
||||
ReadStringValue(sb, @class, reader, ref j);
|
||||
append = false;
|
||||
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
|
||||
var @class = GetMembers(members, i);
|
||||
i += @class.Count - 1;
|
||||
for (int j = 1; j < @class.Count; j++)
|
||||
{
|
||||
ReadStringValue(sb, @class, reader, ref j);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (append)
|
||||
@@ -168,7 +166,6 @@ namespace AssetStudio
|
||||
private static object ReadValue(List<TypeTreeNode> members, BinaryReader reader, ref int i)
|
||||
{
|
||||
var member = members[i];
|
||||
var level = member.m_Level;
|
||||
var varTypeStr = member.m_Type;
|
||||
object value;
|
||||
var align = (member.m_MetaFlag & 0x4000) != 0;
|
||||
@@ -178,6 +175,7 @@ namespace AssetStudio
|
||||
value = reader.ReadSByte();
|
||||
break;
|
||||
case "UInt8":
|
||||
case "char":
|
||||
value = reader.ReadByte();
|
||||
break;
|
||||
case "short":
|
||||
@@ -203,6 +201,7 @@ namespace AssetStudio
|
||||
break;
|
||||
case "UInt64":
|
||||
case "unsigned long long":
|
||||
case "FileSize":
|
||||
value = reader.ReadUInt64();
|
||||
break;
|
||||
case "float":
|
||||
@@ -222,14 +221,13 @@ namespace AssetStudio
|
||||
{
|
||||
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
|
||||
align = true;
|
||||
var map = GetMembers(members, i);
|
||||
i += map.Count - 1;
|
||||
var first = GetMembers(map, 4);
|
||||
var next = 4 + first.Count;
|
||||
var second = GetMembers(map, next);
|
||||
var size = reader.ReadInt32();
|
||||
var dic = new List<KeyValuePair<object, object>>(size);
|
||||
var map = GetMembers(members, level, i);
|
||||
i += map.Count - 1;
|
||||
map.RemoveRange(0, 4);
|
||||
var first = GetMembers(map, map[0].m_Level, 0);
|
||||
map.RemoveRange(0, first.Count);
|
||||
var second = map;
|
||||
for (int j = 0; j < size; j++)
|
||||
{
|
||||
int tmp1 = 0;
|
||||
@@ -248,18 +246,17 @@ namespace AssetStudio
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (i != members.Count && members[i + 1].m_Type == "Array") //Array
|
||||
if (i < members.Count - 1 && members[i + 1].m_Type == "Array") //Array
|
||||
{
|
||||
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
|
||||
align = true;
|
||||
var vector = GetMembers(members, i);
|
||||
i += vector.Count - 1;
|
||||
var size = reader.ReadInt32();
|
||||
var list = new List<object>(size);
|
||||
var vector = GetMembers(members, level, i);
|
||||
i += vector.Count - 1;
|
||||
vector.RemoveRange(0, 3);
|
||||
for (int j = 0; j < size; j++)
|
||||
{
|
||||
int tmp = 0;
|
||||
int tmp = 3;
|
||||
list.Add(ReadValue(vector, reader, ref tmp));
|
||||
}
|
||||
value = list;
|
||||
@@ -267,11 +264,10 @@ namespace AssetStudio
|
||||
}
|
||||
else //Class
|
||||
{
|
||||
var @class = GetMembers(members, level, i);
|
||||
@class.RemoveAt(0);
|
||||
i += @class.Count;
|
||||
var @class = GetMembers(members, i);
|
||||
i += @class.Count - 1;
|
||||
var obj = new UType();
|
||||
for (int j = 0; j < @class.Count; j++)
|
||||
for (int j = 1; j < @class.Count; j++)
|
||||
{
|
||||
var classmember = @class[j];
|
||||
var name = classmember.m_Name;
|
||||
@@ -287,10 +283,11 @@ namespace AssetStudio
|
||||
return value;
|
||||
}
|
||||
|
||||
private static List<TypeTreeNode> GetMembers(List<TypeTreeNode> members, int level, int index)
|
||||
private static List<TypeTreeNode> GetMembers(List<TypeTreeNode> members, int index)
|
||||
{
|
||||
var member2 = new List<TypeTreeNode>();
|
||||
member2.Add(members[0]);
|
||||
member2.Add(members[index]);
|
||||
var level = members[index].m_Level;
|
||||
for (int i = index + 1; i < members.Count; i++)
|
||||
{
|
||||
var member = members[i];
|
||||
@@ -303,140 +300,5 @@ namespace AssetStudio
|
||||
}
|
||||
return member2;
|
||||
}
|
||||
|
||||
public static byte[] WriteUType(UType obj, List<TypeTreeNode> members)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var write = new BinaryWriter(stream);
|
||||
for (int i = 0; i < members.Count; i++)
|
||||
{
|
||||
var member = members[i];
|
||||
var varNameStr = member.m_Name;
|
||||
WriteValue(obj[varNameStr], members, write, ref i);
|
||||
}
|
||||
return stream.ToArray();
|
||||
}
|
||||
|
||||
private static void WriteValue(object value, List<TypeTreeNode> members, BinaryWriter write, ref int i)
|
||||
{
|
||||
var member = members[i];
|
||||
var level = member.m_Level;
|
||||
var varTypeStr = member.m_Type;
|
||||
var align = (member.m_MetaFlag & 0x4000) != 0;
|
||||
switch (varTypeStr)
|
||||
{
|
||||
case "SInt8":
|
||||
write.Write((sbyte)value);
|
||||
break;
|
||||
case "UInt8":
|
||||
write.Write((byte)value);
|
||||
break;
|
||||
case "short":
|
||||
case "SInt16":
|
||||
write.Write((short)value);
|
||||
break;
|
||||
case "UInt16":
|
||||
case "unsigned short":
|
||||
write.Write((ushort)value);
|
||||
break;
|
||||
case "int":
|
||||
case "SInt32":
|
||||
write.Write((int)value);
|
||||
break;
|
||||
case "UInt32":
|
||||
case "unsigned int":
|
||||
case "Type*":
|
||||
write.Write((uint)value);
|
||||
break;
|
||||
case "long long":
|
||||
case "SInt64":
|
||||
write.Write((long)value);
|
||||
break;
|
||||
case "UInt64":
|
||||
case "unsigned long long":
|
||||
write.Write((ulong)value);
|
||||
break;
|
||||
case "float":
|
||||
write.Write((float)value);
|
||||
break;
|
||||
case "double":
|
||||
write.Write((double)value);
|
||||
break;
|
||||
case "bool":
|
||||
write.Write((bool)value);
|
||||
break;
|
||||
case "string":
|
||||
write.WriteAlignedString((string)value);
|
||||
i += 3;
|
||||
break;
|
||||
case "map":
|
||||
{
|
||||
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
|
||||
align = true;
|
||||
var dic = (List<KeyValuePair<object, object>>)value;
|
||||
var size = dic.Count;
|
||||
write.Write(size);
|
||||
var map = GetMembers(members, level, i);
|
||||
i += map.Count - 1;
|
||||
map.RemoveRange(0, 4);
|
||||
var first = GetMembers(map, map[0].m_Level, 0);
|
||||
map.RemoveRange(0, first.Count);
|
||||
var second = map;
|
||||
for (int j = 0; j < size; j++)
|
||||
{
|
||||
int tmp1 = 0;
|
||||
int tmp2 = 0;
|
||||
WriteValue(dic[j].Key, first, write, ref tmp1);
|
||||
WriteValue(dic[j].Value, second, write, ref tmp2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TypelessData":
|
||||
{
|
||||
var bytes = ((object[])value).Cast<byte>().ToArray();
|
||||
var size = bytes.Length;
|
||||
write.Write(size);
|
||||
write.Write(bytes);
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (i != members.Count && members[i + 1].m_Type == "Array") //Array
|
||||
{
|
||||
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
|
||||
align = true;
|
||||
var list = (List<object>)value;
|
||||
var size = list.Count;
|
||||
write.Write(size);
|
||||
var vector = GetMembers(members, level, i);
|
||||
i += vector.Count - 1;
|
||||
vector.RemoveRange(0, 3);
|
||||
for (int j = 0; j < size; j++)
|
||||
{
|
||||
int tmp = 0;
|
||||
WriteValue(list[j], vector, write, ref tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else //Class
|
||||
{
|
||||
var @class = GetMembers(members, level, i);
|
||||
@class.RemoveAt(0);
|
||||
i += @class.Count;
|
||||
var obj = (UType)value;
|
||||
for (int j = 0; j < @class.Count; j++)
|
||||
{
|
||||
var classmember = @class[j];
|
||||
var name = classmember.m_Name;
|
||||
WriteValue(obj[name], @class, write, ref j);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (align)
|
||||
write.AlignStream(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,12 @@ namespace AssetStudio
|
||||
public string m_Name;
|
||||
public int m_ByteSize;
|
||||
public int m_Index;
|
||||
public int m_IsArray;
|
||||
public int m_IsArray; //m_TypeFlags
|
||||
public int m_Version;
|
||||
public int m_MetaFlag;
|
||||
public int m_Level;
|
||||
public uint m_TypeStrOffset;
|
||||
public uint m_NameStrOffset;
|
||||
public ulong m_RefTypeHash;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,73 +9,37 @@ namespace AssetStudio
|
||||
public class UType : IDictionary<string, object>
|
||||
{
|
||||
private List<string> keys;
|
||||
private List<object> values;
|
||||
private IDictionary<string, object> values;
|
||||
|
||||
public UType()
|
||||
{
|
||||
keys = new List<string>();
|
||||
values = new List<object>();
|
||||
}
|
||||
|
||||
private int GetValueIndex(string name)
|
||||
{
|
||||
for (int i = 0, n = keys.Count; i < n; i++)
|
||||
{
|
||||
if (string.Equals(keys[i], name, StringComparison.Ordinal))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public bool TryGetValue<T>(string key, out T value)
|
||||
{
|
||||
var index = GetValueIndex(key);
|
||||
if (index != -1)
|
||||
{
|
||||
value = (T)values[index];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
values = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public object this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
var index = GetValueIndex(key);
|
||||
if (index != -1)
|
||||
{
|
||||
return values[index];
|
||||
}
|
||||
else
|
||||
if (!values.ContainsKey(key))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return values[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
var index = GetValueIndex(key);
|
||||
if (index == -1)
|
||||
if (!values.ContainsKey(key))
|
||||
{
|
||||
keys.Add(key);
|
||||
values.Add(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
values[index] = value;
|
||||
}
|
||||
values[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<string> Keys => keys;
|
||||
|
||||
public ICollection<object> Values => values;
|
||||
public ICollection<object> Values => values.Values;
|
||||
|
||||
public int Count => keys.Count;
|
||||
|
||||
@@ -84,13 +48,13 @@ namespace AssetStudio
|
||||
public void Add(string key, object value)
|
||||
{
|
||||
keys.Add(key);
|
||||
values.Add(value);
|
||||
values.Add(key, value);
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<string, object> item)
|
||||
{
|
||||
keys.Add(item.Key);
|
||||
values.Add(item.Value);
|
||||
values.Add(item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
@@ -101,55 +65,44 @@ namespace AssetStudio
|
||||
|
||||
public bool Contains(KeyValuePair<string, object> item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return values.Contains(item);
|
||||
}
|
||||
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return GetValueIndex(key) != -1;
|
||||
return values.ContainsKey(key);
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
values.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
for (int i = 0, n = keys.Count; i < n; i++)
|
||||
{
|
||||
yield return new KeyValuePair<string, object>(keys[i], values[i]);
|
||||
}
|
||||
return values.GetEnumerator();
|
||||
}
|
||||
|
||||
public bool Remove(string key)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
keys.Remove(key);
|
||||
return values.Remove(key);
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<string, object> item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
keys.Remove(item.Key);
|
||||
return values.Remove(item);
|
||||
}
|
||||
|
||||
public bool TryGetValue(string key, out object value)
|
||||
{
|
||||
var index = GetValueIndex(key);
|
||||
if (index != -1)
|
||||
{
|
||||
value = values[index];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
return values.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
return values.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace AssetStudio
|
||||
{
|
||||
public static byte[] gzipMagic = { 0x1f, 0x8b };
|
||||
public static byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
|
||||
public List<StreamFile> fileList = new List<StreamFile>();
|
||||
public StreamFile[] fileList;
|
||||
|
||||
private class WebData
|
||||
{
|
||||
@@ -78,14 +78,15 @@ namespace AssetStudio
|
||||
data.path = Encoding.UTF8.GetString(reader.ReadBytes(pathLength));
|
||||
dataList.Add(data);
|
||||
}
|
||||
|
||||
foreach (var data in dataList)
|
||||
fileList = new StreamFile[dataList.Count];
|
||||
for (int i = 0; i < dataList.Count; i++)
|
||||
{
|
||||
var data = dataList[i];
|
||||
var file = new StreamFile();
|
||||
file.fileName = Path.GetFileName(data.path);
|
||||
reader.BaseStream.Position = data.dataOffset;
|
||||
file.stream = new MemoryStream(reader.ReadBytes(data.dataLength));
|
||||
fileList.Add(file);
|
||||
fileList[i] = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ using namespace System::Security::Permissions;
|
||||
[assembly:AssemblyConfigurationAttribute(L"")];
|
||||
[assembly:AssemblyCompanyAttribute(L"")];
|
||||
[assembly:AssemblyProductAttribute(L"AssetStudioFBX")];
|
||||
[assembly:AssemblyCopyrightAttribute(L"Copyright © Perfare 2018")];
|
||||
[assembly:AssemblyCopyrightAttribute(L"Copyright © Perfare 2018-2020")];
|
||||
[assembly:AssemblyTrademarkAttribute(L"")];
|
||||
[assembly:AssemblyCultureAttribute(L"")];
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
char* Fbx::StringToCharArray(String^ s)
|
||||
char* Fbx::StringToUTF8(String^ s)
|
||||
{
|
||||
return (char*)(void*)Marshal::StringToHGlobalAnsi(s);
|
||||
auto bytes = Text::Encoding::UTF8->GetBytes(s);
|
||||
auto chars = new char[bytes->Length + 1];
|
||||
pin_ptr<unsigned char> ptr = &bytes[0];
|
||||
memcpy(chars, ptr, bytes->Length);
|
||||
chars[bytes->Length] = '\0';
|
||||
return chars;
|
||||
}
|
||||
|
||||
void Fbx::Init(FbxManager** pSdkManager, FbxScene** pScene)
|
||||
|
||||
@@ -10,19 +10,18 @@
|
||||
using namespace System;
|
||||
using namespace System::Collections::Generic;
|
||||
using namespace System::IO;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
|
||||
#define WITH_MARSHALLED_STRING(name,str,block)\
|
||||
{ \
|
||||
char* name; \
|
||||
try \
|
||||
{ \
|
||||
name = StringToCharArray(str); \
|
||||
name = StringToUTF8(str); \
|
||||
block \
|
||||
} \
|
||||
finally \
|
||||
{ \
|
||||
Marshal::FreeHGlobal((IntPtr)name); \
|
||||
delete name; \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -43,13 +42,14 @@ namespace AssetStudio {
|
||||
public:
|
||||
static Vector3 QuaternionToEuler(Quaternion q);
|
||||
static Quaternion EulerToQuaternion(Vector3 v);
|
||||
static char* StringToCharArray(String^ s);
|
||||
static char* StringToUTF8(String^ s);
|
||||
static void Init(FbxManager** pSdkManager, FbxScene** pScene);
|
||||
|
||||
ref class Exporter
|
||||
{
|
||||
public:
|
||||
static void Export(String^ path, IImported^ imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, bool flatInbetween, int versionIndex, bool isAscii);
|
||||
static void Export(String^ path, IImported^ imported, bool eulerFilter, float filterPrecision,
|
||||
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii);
|
||||
|
||||
private:
|
||||
bool exportSkins;
|
||||
@@ -67,7 +67,7 @@ namespace AssetStudio {
|
||||
FbxArray<FbxFileTexture*>* pTextures;
|
||||
FbxPose* pBindPose;
|
||||
|
||||
Exporter(String^ path, IImported^ imported, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, int versionIndex, bool isAscii);
|
||||
Exporter(String^ name, IImported^ imported, bool allNodes, bool skins, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii);
|
||||
~Exporter();
|
||||
|
||||
void Exporter::LinkTexture(ImportedMaterialTexture^ texture, FbxFileTexture* pTexture, FbxProperty& prop);
|
||||
@@ -76,11 +76,11 @@ namespace AssetStudio {
|
||||
void SearchHierarchy(ImportedFrame^ frame, HashSet<String^>^ exportFrames);
|
||||
void SetJointsFromImportedMeshes(bool allBones);
|
||||
void ExportFrame(FbxNode* pParentNode, ImportedFrame^ frame);
|
||||
void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ meshList);
|
||||
void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ iMesh);
|
||||
FbxFileTexture* ExportTexture(ImportedTexture^ matTex);
|
||||
void ExportAnimations(bool eulerFilter, float filterValue, bool flatInbetween);
|
||||
void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision, bool flatInbetween);
|
||||
void ExportMorphs(bool morphMask, bool flatInbetween);
|
||||
void ExportAnimations(bool eulerFilter, float filterValue);
|
||||
void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision);
|
||||
void ExportMorphs();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,57 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}</ProjectGuid>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}</ProjectGuid>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<Keyword>ManagedCProj</Keyword>
|
||||
<RootNamespace>AssetStudioFBX</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -60,92 +60,79 @@
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>FBXSDK_SHARED;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2019.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2019.0\lib\vs2015\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>FBXSDK_SHARED;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2019.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>FBXSDK_SHARED;WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2019.0\lib\vs2015\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>FBXSDK_SHARED;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>FBXSDK_SHARED;WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>FBXSDK_SHARED;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2019.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2019.0\lib\vs2015\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>FBXSDK_SHARED;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2019.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2019.0\lib\vs2015\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AssetStudioFBX.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AssemblyInfo.cpp" />
|
||||
<ClCompile Include="AssetStudioFBX.cpp" />
|
||||
<ClCompile Include="AssetStudioFBXExporter.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AssetStudioFBX.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
|
||||
<Project>{af56b63c-1764-41b7-9e60-8d485422ac3b}</Project>
|
||||
<Project>{7662f8c2-7bfd-442e-a948-a43b4f7eb06e}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -3,12 +3,21 @@
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AssetStudioFBX.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AssemblyInfo.cpp">
|
||||
@@ -21,9 +30,4 @@
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AssetStudioFBX.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
void Fbx::Exporter::Export(String^ path, IImported^ imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, bool flatInbetween, int versionIndex, bool isAscii)
|
||||
void Fbx::Exporter::Export(String^ path, IImported^ imported, bool eulerFilter, float filterPrecision,
|
||||
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii)
|
||||
{
|
||||
FileInfo^ file = gcnew FileInfo(path);
|
||||
DirectoryInfo^ dir = file->Directory;
|
||||
@@ -12,18 +13,23 @@ namespace AssetStudio
|
||||
}
|
||||
String^ currentDir = Directory::GetCurrentDirectory();
|
||||
Directory::SetCurrentDirectory(dir->FullName);
|
||||
path = Path::GetFileName(path);
|
||||
|
||||
Exporter^ exporter = gcnew Exporter(path, imported, allFrames, allBones, skins, boneSize, scaleFactor, versionIndex, isAscii);
|
||||
//TODO exporter->ExportMorphs(false, flatInbetween);
|
||||
exporter->ExportAnimations(eulerFilter, filterPrecision, flatInbetween);
|
||||
auto name = Path::GetFileName(path);
|
||||
Exporter^ exporter = gcnew Exporter(name, imported, allNodes, skins, castToBone, boneSize, scaleFactor, versionIndex, isAscii);
|
||||
if (blendShape)
|
||||
{
|
||||
exporter->ExportMorphs();
|
||||
}
|
||||
if (animation)
|
||||
{
|
||||
exporter->ExportAnimations(eulerFilter, filterPrecision);
|
||||
}
|
||||
exporter->pExporter->Export(exporter->pScene);
|
||||
delete exporter;
|
||||
|
||||
Directory::SetCurrentDirectory(currentDir);
|
||||
}
|
||||
|
||||
Fbx::Exporter::Exporter(String^ path, IImported^ imported, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, int versionIndex, bool isAscii)
|
||||
Fbx::Exporter::Exporter(String^ name, IImported^ imported, bool allNodes, bool skins, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii)
|
||||
{
|
||||
this->imported = imported;
|
||||
exportSkins = skins;
|
||||
@@ -51,7 +57,16 @@ namespace AssetStudio
|
||||
FbxGlobalSettings& globalSettings = pScene->GetGlobalSettings();
|
||||
globalSettings.SetSystemUnit(FbxSystemUnit(scaleFactor));
|
||||
|
||||
cDest = StringToCharArray(path);
|
||||
if (imported->AnimationList->Count > 0)
|
||||
{
|
||||
auto ani = imported->AnimationList[0];
|
||||
if (ani->SampleRate == 60.0f)
|
||||
{
|
||||
globalSettings.SetTimeMode(FbxTime::eFrames60);
|
||||
}
|
||||
}
|
||||
|
||||
cDest = StringToUTF8(name);
|
||||
pExporter = FbxExporter::Create(pScene, "");
|
||||
|
||||
int pFileFormat = 0;
|
||||
@@ -78,7 +93,7 @@ namespace AssetStudio
|
||||
}
|
||||
|
||||
framePaths = nullptr;
|
||||
if (!allFrames)
|
||||
if (!allNodes)
|
||||
{
|
||||
framePaths = SearchHierarchy();
|
||||
if (!framePaths)
|
||||
@@ -88,7 +103,7 @@ namespace AssetStudio
|
||||
}
|
||||
|
||||
pBindPose = FbxPose::Create(pScene, "BindPose");
|
||||
pBindPose->SetIsBindPose(true);
|
||||
pScene->AddPose(pBindPose);
|
||||
|
||||
frameToNode = gcnew Dictionary<ImportedFrame^, size_t>();
|
||||
meshFrames = imported->MeshList != nullptr ? gcnew List<ImportedFrame^>() : nullptr;
|
||||
@@ -96,7 +111,7 @@ namespace AssetStudio
|
||||
|
||||
if (imported->MeshList != nullptr)
|
||||
{
|
||||
SetJointsFromImportedMeshes(allBones);
|
||||
SetJointsFromImportedMeshes(castToBone);
|
||||
|
||||
pMaterials = new FbxArray<FbxSurfacePhong*>();
|
||||
pTextures = new FbxArray<FbxFileTexture*>();
|
||||
@@ -155,23 +170,35 @@ namespace AssetStudio
|
||||
}
|
||||
if (cDest != NULL)
|
||||
{
|
||||
Marshal::FreeHGlobal((IntPtr)cDest);
|
||||
delete cDest;
|
||||
}
|
||||
}
|
||||
|
||||
void Fbx::Exporter::SetJointsNode(ImportedFrame^ frame, HashSet<String^>^ bonePaths, bool allBones)
|
||||
void Fbx::Exporter::SetJointsNode(ImportedFrame^ frame, HashSet<String^>^ bonePaths, bool castToBone)
|
||||
{
|
||||
size_t pointer;
|
||||
if (frameToNode->TryGetValue(frame, pointer))
|
||||
{
|
||||
auto pNode = (FbxNode*)pointer;
|
||||
if (allBones || bonePaths->Contains(frame->Path))
|
||||
if (castToBone)
|
||||
{
|
||||
FbxSkeleton* pJoint = FbxSkeleton::Create(pScene, "");
|
||||
pJoint->Size.Set(FbxDouble(boneSize));
|
||||
pJoint->SetSkeletonType(FbxSkeleton::eLimbNode);
|
||||
pNode->SetNodeAttribute(pJoint);
|
||||
}
|
||||
else if (bonePaths->Contains(frame->Path))
|
||||
{
|
||||
FbxSkeleton* pJoint = FbxSkeleton::Create(pScene, "");
|
||||
pJoint->Size.Set(FbxDouble(boneSize));
|
||||
pJoint->SetSkeletonType(FbxSkeleton::eLimbNode);
|
||||
pNode->SetNodeAttribute(pJoint);
|
||||
|
||||
pJoint = FbxSkeleton::Create(pScene, "");
|
||||
pJoint->Size.Set(FbxDouble(boneSize));
|
||||
pJoint->SetSkeletonType(FbxSkeleton::eLimbNode);
|
||||
pNode->GetParent()->SetNodeAttribute(pJoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
FbxNull* pNull = FbxNull::Create(pScene, "");
|
||||
@@ -185,7 +212,7 @@ namespace AssetStudio
|
||||
}
|
||||
for (int i = 0; i < frame->Count; i++)
|
||||
{
|
||||
SetJointsNode(frame[i], bonePaths, allBones);
|
||||
SetJointsNode(frame[i], bonePaths, castToBone);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +263,7 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
void Fbx::Exporter::SetJointsFromImportedMeshes(bool allBones)
|
||||
void Fbx::Exporter::SetJointsFromImportedMeshes(bool castToBone)
|
||||
{
|
||||
if (!exportSkins)
|
||||
{
|
||||
@@ -257,7 +284,7 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
SetJointsNode(imported->RootFrame, bonePaths, allBones);
|
||||
SetJointsNode(imported->RootFrame, bonePaths, castToBone);
|
||||
}
|
||||
|
||||
void Fbx::Exporter::ExportFrame(FbxNode* pParentNode, ImportedFrame^ frame)
|
||||
@@ -293,9 +320,9 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
void Fbx::Exporter::ExportMesh(FbxNode* pFrameNode, ImportedMesh^ meshList)
|
||||
void Fbx::Exporter::ExportMesh(FbxNode* pFrameNode, ImportedMesh^ iMesh)
|
||||
{
|
||||
List<ImportedBone^>^ boneList = meshList->BoneList;
|
||||
List<ImportedBone^>^ boneList = iMesh->BoneList;
|
||||
bool hasBones;
|
||||
if (exportSkins && boneList != nullptr)
|
||||
{
|
||||
@@ -306,63 +333,88 @@ namespace AssetStudio
|
||||
hasBones = false;
|
||||
}
|
||||
|
||||
FbxArray<FbxNode*>* pBoneNodeList = nullptr;
|
||||
FbxArray<FbxCluster*>* pClusterArray = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
if (hasBones)
|
||||
{
|
||||
pBoneNodeList = new FbxArray<FbxNode*>();
|
||||
pBoneNodeList->Reserve(boneList->Count);
|
||||
pClusterArray = new FbxArray<FbxCluster*>(boneList->Count);
|
||||
|
||||
for (int i = 0; i < boneList->Count; i++)
|
||||
{
|
||||
auto bone = boneList[i];
|
||||
auto frame = imported->RootFrame->FindFrameByPath(bone->Path);
|
||||
auto frameNode = (FbxNode*)frameToNode[frame];
|
||||
pBoneNodeList->Add(frameNode);
|
||||
}
|
||||
|
||||
pClusterArray = new FbxArray<FbxCluster*>();
|
||||
pClusterArray->Reserve(boneList->Count);
|
||||
for (int i = 0; i < boneList->Count; i++)
|
||||
{
|
||||
FbxNode* pNode = pBoneNodeList->GetAt(i);
|
||||
FbxString lClusterName = pNode->GetNameOnly() + FbxString("Cluster");
|
||||
FbxCluster* pCluster = FbxCluster::Create(pScene, lClusterName.Buffer());
|
||||
pCluster->SetLink(pNode);
|
||||
pCluster->SetLinkMode(FbxCluster::eTotalOne);
|
||||
pClusterArray->Add(pCluster);
|
||||
if (bone->Path != nullptr)
|
||||
{
|
||||
auto frame = imported->RootFrame->FindFrameByPath(bone->Path);
|
||||
auto boneNode = (FbxNode*)frameToNode[frame];
|
||||
FbxString lClusterName = boneNode->GetNameOnly() + FbxString("Cluster");
|
||||
FbxCluster* pCluster = FbxCluster::Create(pScene, lClusterName.Buffer());
|
||||
pCluster->SetLink(boneNode);
|
||||
pCluster->SetLinkMode(FbxCluster::eTotalOne);
|
||||
pClusterArray->Add(pCluster);
|
||||
}
|
||||
else
|
||||
{
|
||||
pClusterArray->Add(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FbxMesh* pMesh = FbxMesh::Create(pScene, "");
|
||||
FbxMesh* pMesh = FbxMesh::Create(pScene, pFrameNode->GetName());
|
||||
pFrameNode->SetNodeAttribute(pMesh);
|
||||
|
||||
int vertexCount = 0;
|
||||
for (int i = 0; i < meshList->SubmeshList->Count; i++)
|
||||
for (int i = 0; i < iMesh->SubmeshList->Count; i++)
|
||||
{
|
||||
vertexCount += meshList->SubmeshList[i]->VertexList->Count;
|
||||
vertexCount += iMesh->SubmeshList[i]->VertexList->Count;
|
||||
}
|
||||
|
||||
pMesh->InitControlPoints(vertexCount);
|
||||
FbxVector4* pControlPoints = pMesh->GetControlPoints();
|
||||
|
||||
FbxGeometryElementNormal* lGeometryElementNormal = pMesh->CreateElementNormal();
|
||||
lGeometryElementNormal->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
lGeometryElementNormal->SetReferenceMode(FbxGeometryElement::eDirect);
|
||||
FbxGeometryElementNormal* lGeometryElementNormal = NULL;
|
||||
if (iMesh->hasNormal)
|
||||
{
|
||||
lGeometryElementNormal = pMesh->CreateElementNormal();
|
||||
lGeometryElementNormal->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
lGeometryElementNormal->SetReferenceMode(FbxGeometryElement::eDirect);
|
||||
}
|
||||
|
||||
FbxGeometryElementUV* lGeometryElementUV = pMesh->CreateElementUV("UV0");
|
||||
lGeometryElementUV->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
lGeometryElementUV->SetReferenceMode(FbxGeometryElement::eDirect);
|
||||
if (iMesh->hasUV[0])
|
||||
{
|
||||
auto lGeometryElementUV = pMesh->CreateElementUV("UV0", FbxLayerElement::eTextureDiffuse);
|
||||
lGeometryElementUV->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
lGeometryElementUV->SetReferenceMode(FbxGeometryElement::eDirect);
|
||||
}
|
||||
|
||||
FbxGeometryElementTangent* lGeometryElementTangent = pMesh->CreateElementTangent();
|
||||
lGeometryElementTangent->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
lGeometryElementTangent->SetReferenceMode(FbxGeometryElement::eDirect);
|
||||
if (iMesh->hasUV[1])
|
||||
{
|
||||
auto lGeometryElementUV = pMesh->CreateElementUV("UV1", FbxLayerElement::eTextureNormalMap);
|
||||
lGeometryElementUV->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
lGeometryElementUV->SetReferenceMode(FbxGeometryElement::eDirect);
|
||||
}
|
||||
|
||||
FbxGeometryElementVertexColor* lGeometryElementVertexColor = nullptr;
|
||||
bool vertexColours = vertexCount > 0 && dynamic_cast<ImportedVertexWithColour^>(meshList->SubmeshList[0]->VertexList[0]) != nullptr;
|
||||
if (vertexColours)
|
||||
/*for (int uv = 0; uv < 8; uv++)
|
||||
{
|
||||
if (iMesh->hasUV[uv])
|
||||
{
|
||||
auto lGeometryElementUV = pMesh->CreateElementUV(FbxString("UV") + FbxString(uv));
|
||||
lGeometryElementUV->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
lGeometryElementUV->SetReferenceMode(FbxGeometryElement::eDirect);
|
||||
}
|
||||
}*/
|
||||
|
||||
FbxGeometryElementTangent* lGeometryElementTangent = NULL;
|
||||
if (iMesh->hasTangent)
|
||||
{
|
||||
lGeometryElementTangent = pMesh->CreateElementTangent();
|
||||
lGeometryElementTangent->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
lGeometryElementTangent->SetReferenceMode(FbxGeometryElement::eDirect);
|
||||
}
|
||||
|
||||
FbxGeometryElementVertexColor* lGeometryElementVertexColor = NULL;
|
||||
if (iMesh->hasColor)
|
||||
{
|
||||
lGeometryElementVertexColor = pMesh->CreateElementVertexColor();
|
||||
lGeometryElementVertexColor->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
@@ -374,9 +426,9 @@ namespace AssetStudio
|
||||
lGeometryElementMaterial->SetReferenceMode(FbxGeometryElement::eIndexToDirect);
|
||||
|
||||
int firstVertex = 0;
|
||||
for (int i = 0; i < meshList->SubmeshList->Count; i++)
|
||||
for (int i = 0; i < iMesh->SubmeshList->Count; i++)
|
||||
{
|
||||
ImportedSubmesh^ meshObj = meshList->SubmeshList[i];
|
||||
ImportedSubmesh^ meshObj = iMesh->SubmeshList[i];
|
||||
List<ImportedVertex^>^ vertexList = meshObj->VertexList;
|
||||
List<ImportedFace^>^ faceList = meshObj->FaceList;
|
||||
|
||||
@@ -387,7 +439,7 @@ namespace AssetStudio
|
||||
char* pMatName = NULL;
|
||||
try
|
||||
{
|
||||
pMatName = StringToCharArray(mat->Name);
|
||||
pMatName = StringToUTF8(mat->Name);
|
||||
int foundMat = -1;
|
||||
for (int j = 0; j < pMaterials->GetCount(); j++)
|
||||
{
|
||||
@@ -414,15 +466,15 @@ namespace AssetStudio
|
||||
Color reflection = mat->Reflection;
|
||||
pMat = FbxSurfacePhong::Create(pScene, pMatName);
|
||||
pMat->Diffuse.Set(FbxDouble3(diffuse.R, diffuse.G, diffuse.B));
|
||||
pMat->DiffuseFactor.Set(FbxDouble(diffuse.A));
|
||||
//pMat->DiffuseFactor.Set(FbxDouble(diffuse.A));
|
||||
pMat->Ambient.Set(FbxDouble3(ambient.R, ambient.G, ambient.B));
|
||||
pMat->AmbientFactor.Set(FbxDouble(ambient.A));
|
||||
//pMat->AmbientFactor.Set(FbxDouble(ambient.A));
|
||||
pMat->Emissive.Set(FbxDouble3(emissive.R, emissive.G, emissive.B));
|
||||
pMat->EmissiveFactor.Set(FbxDouble(emissive.A));
|
||||
//pMat->EmissiveFactor.Set(FbxDouble(emissive.A));
|
||||
pMat->Specular.Set(FbxDouble3(specular.R, specular.G, specular.B));
|
||||
pMat->SpecularFactor.Set(FbxDouble(specular.A));
|
||||
//pMat->SpecularFactor.Set(FbxDouble(specular.A));
|
||||
pMat->Reflection.Set(FbxDouble3(reflection.R, reflection.G, reflection.B));
|
||||
pMat->ReflectionFactor.Set(FbxDouble(reflection.A));
|
||||
//pMat->ReflectionFactor.Set(FbxDouble(reflection.A));
|
||||
pMat->Shininess.Set(FbxDouble(mat->Shininess));
|
||||
pMat->TransparencyFactor.Set(FbxDouble(mat->Transparency));
|
||||
pMat->ShadingModel.Set(lShadingName);
|
||||
@@ -432,7 +484,7 @@ namespace AssetStudio
|
||||
|
||||
bool hasTexture = false;
|
||||
|
||||
for each (ImportedMaterialTexture^ texture in mat->Textures)
|
||||
for each (ImportedMaterialTexture ^ texture in mat->Textures)
|
||||
{
|
||||
auto pTexture = ExportTexture(ImportedHelpers::FindTexture(texture->Name, imported->TextureList));
|
||||
if (pTexture != NULL)
|
||||
@@ -467,45 +519,59 @@ namespace AssetStudio
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal::FreeHGlobal((IntPtr)pMatName);
|
||||
delete pMatName;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < vertexList->Count; j++)
|
||||
{
|
||||
ImportedVertex^ vertex = vertexList[j];
|
||||
ImportedVertex^ iVertex = vertexList[j];
|
||||
|
||||
Vector3 coords = vertex->Position;
|
||||
pControlPoints[j + firstVertex] = FbxVector4(coords.X, coords.Y, coords.Z, 0);
|
||||
Vector3 vertex = iVertex->Vertex;
|
||||
pControlPoints[j + firstVertex] = FbxVector4(vertex.X, vertex.Y, vertex.Z, 0);
|
||||
|
||||
Vector3 normal = vertex->Normal;
|
||||
lGeometryElementNormal->GetDirectArray().Add(FbxVector4(normal.X, normal.Y, normal.Z, 0));
|
||||
|
||||
array<float>^ uv = vertex->UV;
|
||||
if (uv != nullptr)
|
||||
if (iMesh->hasNormal)
|
||||
{
|
||||
lGeometryElementUV->GetDirectArray().Add(FbxVector2(uv[0], uv[1]));
|
||||
Vector3 normal = iVertex->Normal;
|
||||
lGeometryElementNormal->GetDirectArray().Add(FbxVector4(normal.X, normal.Y, normal.Z, 0));
|
||||
}
|
||||
|
||||
Vector4 tangent = vertex->Tangent;
|
||||
lGeometryElementTangent->GetDirectArray().Add(FbxVector4(tangent.X, tangent.Y, tangent.Z, tangent.W));
|
||||
|
||||
if (vertexColours)
|
||||
//for (int uv = 0; uv < 8; uv++)
|
||||
for (int uv = 0; uv < 2; uv++)
|
||||
{
|
||||
ImportedVertexWithColour^ vert = (ImportedVertexWithColour^)vertexList[j];
|
||||
lGeometryElementVertexColor->GetDirectArray().Add(FbxColor(vert->Colour.R, vert->Colour.G, vert->Colour.B, vert->Colour.A));
|
||||
if (iMesh->hasUV[uv])
|
||||
{
|
||||
auto m_UV = iVertex->UV[uv];
|
||||
auto lGeometryElementUV = pMesh->GetElementUV(uv);
|
||||
lGeometryElementUV->GetDirectArray().Add(FbxVector2(m_UV[0], m_UV[1]));
|
||||
}
|
||||
}
|
||||
|
||||
if (hasBones && vertex->BoneIndices != nullptr)
|
||||
if (iMesh->hasTangent)
|
||||
{
|
||||
auto boneIndices = vertex->BoneIndices;
|
||||
auto weights4 = vertex->Weights;
|
||||
Vector4 tangent = iVertex->Tangent;
|
||||
lGeometryElementTangent->GetDirectArray().Add(FbxVector4(tangent.X, tangent.Y, tangent.Z, tangent.W));
|
||||
}
|
||||
|
||||
if (iMesh->hasColor)
|
||||
{
|
||||
auto color = iVertex->Color;
|
||||
lGeometryElementVertexColor->GetDirectArray().Add(FbxColor(color.R, color.G, color.B, color.A));
|
||||
}
|
||||
|
||||
if (hasBones && iVertex->BoneIndices != nullptr)
|
||||
{
|
||||
auto boneIndices = iVertex->BoneIndices;
|
||||
auto weights4 = iVertex->Weights;
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
if (boneIndices[k] < boneList->Count && weights4[k] > 0)
|
||||
{
|
||||
FbxCluster* pCluster = pClusterArray->GetAt(boneIndices[k]);
|
||||
pCluster->AddControlPointIndex(j + firstVertex, weights4[k]);
|
||||
if (pCluster)
|
||||
{
|
||||
pCluster->AddControlPointIndex(j + firstVertex, weights4[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -531,7 +597,7 @@ namespace AssetStudio
|
||||
for (int j = 0; j < boneList->Count; j++)
|
||||
{
|
||||
FbxCluster* pCluster = pClusterArray->GetAt(j);
|
||||
if (pCluster->GetControlPointIndicesCount() > 0)
|
||||
if (pCluster)
|
||||
{
|
||||
auto boneMatrix = boneList[j]->Matrix;
|
||||
FbxAMatrix lBoneMatrix;
|
||||
@@ -558,10 +624,6 @@ namespace AssetStudio
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pBoneNodeList != NULL)
|
||||
{
|
||||
delete pBoneNodeList;
|
||||
}
|
||||
if (pClusterArray != NULL)
|
||||
{
|
||||
delete pClusterArray;
|
||||
@@ -579,7 +641,7 @@ namespace AssetStudio
|
||||
char* pTexName = NULL;
|
||||
try
|
||||
{
|
||||
pTexName = StringToCharArray(matTexName);
|
||||
pTexName = StringToUTF8(matTexName);
|
||||
int foundTex = -1;
|
||||
for (int i = 0; i < pTextures->GetCount(); i++)
|
||||
{
|
||||
@@ -608,17 +670,7 @@ namespace AssetStudio
|
||||
pTex->SetRotation(0.0, 0.0);
|
||||
pTextures->Add(pTex);
|
||||
|
||||
String^ path = Path::GetDirectoryName(gcnew String(pExporter->GetFileName().Buffer()));
|
||||
if (path == String::Empty)
|
||||
{
|
||||
path = ".";
|
||||
}
|
||||
FileInfo^ file = gcnew FileInfo(path + Path::DirectorySeparatorChar + Path::GetFileName(matTex->Name));
|
||||
DirectoryInfo^ dir = file->Directory;
|
||||
if (!dir->Exists)
|
||||
{
|
||||
dir->Create();
|
||||
}
|
||||
FileInfo^ file = gcnew FileInfo(matTex->Name);
|
||||
BinaryWriter^ writer = gcnew BinaryWriter(file->Create());
|
||||
writer->Write(matTex->Data);
|
||||
writer->Close();
|
||||
@@ -626,7 +678,7 @@ namespace AssetStudio
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal::FreeHGlobal((IntPtr)pTexName);
|
||||
delete pTexName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,7 +692,7 @@ namespace AssetStudio
|
||||
prop.ConnectSrcObject(pTexture);
|
||||
}
|
||||
|
||||
void Fbx::Exporter::ExportAnimations(bool eulerFilter, float filterPrecision, bool flatInbetween)
|
||||
void Fbx::Exporter::ExportAnimations(bool eulerFilter, float filterPrecision)
|
||||
{
|
||||
auto importedAnimationList = imported->AnimationList;
|
||||
if (importedAnimationList == nullptr)
|
||||
@@ -667,11 +719,11 @@ namespace AssetStudio
|
||||
{
|
||||
kTakeName = FbxString("Take") + FbxString(i);
|
||||
}
|
||||
ExportKeyframedAnimation(importedAnimation, kTakeName, lFilter, filterPrecision, flatInbetween);
|
||||
ExportKeyframedAnimation(importedAnimation, kTakeName, lFilter, filterPrecision);
|
||||
}
|
||||
}
|
||||
|
||||
void Fbx::Exporter::ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision, bool flatInbetween)
|
||||
void Fbx::Exporter::ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision)
|
||||
{
|
||||
List<ImportedAnimationKeyframedTrack^>^ pAnimationList = parser->TrackList;
|
||||
|
||||
@@ -760,210 +812,104 @@ namespace AssetStudio
|
||||
eulerFilter->SetQualityTolerance(filterPrecision);
|
||||
eulerFilter->Apply(lCurve, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Fbx::Exporter::ExportMorphs(bool morphMask, bool flatInbetween)
|
||||
{
|
||||
/*if (imported->MeshList == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int meshIdx = 0; meshIdx < imported->MeshList->Count; meshIdx++)
|
||||
{
|
||||
ImportedMesh^ meshList = imported->MeshList[meshIdx];
|
||||
FbxNode* pBaseNode = NULL;
|
||||
for (int nodeIdx = 0; nodeIdx < pMeshNodes->GetCount(); nodeIdx++)
|
||||
{
|
||||
FbxNode* pMeshNode = pMeshNodes->GetAt(nodeIdx);
|
||||
String^ framePath = gcnew String(pMeshNode->GetName());
|
||||
FbxNode* rootNode = pMeshNode;
|
||||
while ((rootNode = rootNode->GetParent()) != pScene->GetRootNode())
|
||||
//BlendShape
|
||||
if (keyframeList->BlendShape != nullptr)
|
||||
{
|
||||
framePath = gcnew String(rootNode->GetName()) + "/" + framePath;
|
||||
}
|
||||
if (framePath == meshList->Path)
|
||||
{
|
||||
pBaseNode = pMeshNode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pBaseNode == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for each (ImportedMorph^ morph in imported->MorphList)
|
||||
{
|
||||
if (morph->Path != meshList->Path)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int meshVertexIndex = 0;
|
||||
for (int meshObjIdx = pBaseNode->GetChildCount() - meshList->SubmeshList->Count; meshObjIdx < meshList->SubmeshList->Count; meshObjIdx++)
|
||||
{
|
||||
List<ImportedVertex^>^ vertList = meshList->SubmeshList[meshObjIdx]->VertexList;
|
||||
FbxNode* pBaseMeshNode = pBaseNode->GetChild(meshObjIdx);
|
||||
FbxMesh* pBaseMesh = pBaseMeshNode->GetMesh();
|
||||
int numColourSets = pBaseMesh->GetElementVertexColorCount();
|
||||
|
||||
FbxBlendShape* lBlendShape;
|
||||
FbxString channelName;
|
||||
WITH_MARSHALLED_STRING
|
||||
(
|
||||
pShapeName,
|
||||
morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty),
|
||||
lBlendShape = FbxBlendShape::Create(pScene, pShapeName);
|
||||
pClipName,
|
||||
keyframeList->BlendShape->ChannelName,
|
||||
channelName = FbxString(pClipName);
|
||||
);
|
||||
FbxProperty rootGroupProp = FbxProperty::Create(lBlendShape, FbxStringDT, "RootGroup");
|
||||
pBaseMesh->AddDeformer(lBlendShape);
|
||||
List<ImportedMorphKeyframe^>^ keyframes = morph->KeyframeList;
|
||||
for (int i = 0; i < morph->Channels->Count; i++)
|
||||
|
||||
auto lGeometry = (FbxGeometry*)pNode->GetNodeAttribute();
|
||||
int lBlendShapeDeformerCount = lGeometry->GetDeformerCount(FbxDeformer::eBlendShape);
|
||||
if (lBlendShapeDeformerCount > 0)
|
||||
{
|
||||
FbxBlendShapeChannel* lBlendShapeChannel;
|
||||
if (!flatInbetween)
|
||||
FbxBlendShape* lBlendShape = (FbxBlendShape*)lGeometry->GetDeformer(0, FbxDeformer::eBlendShape);
|
||||
int lBlendShapeChannelCount = lBlendShape->GetBlendShapeChannelCount();
|
||||
for (int lChannelIndex = 0; lChannelIndex < lBlendShapeChannelCount; ++lChannelIndex)
|
||||
{
|
||||
WITH_MARSHALLED_STRING
|
||||
(
|
||||
pChannelName,
|
||||
gcnew String(lBlendShape->GetName()) + "." + keyframes[morph->Channels[i]->Item2]->Name->Substring(0, keyframes[morph->Channels[i]->Item2]->Name->LastIndexOf("_")),
|
||||
lBlendShapeChannel = FbxBlendShapeChannel::Create(pScene, pChannelName);
|
||||
);
|
||||
lBlendShapeChannel->DeformPercent = morph->Channels[i]->Item1;
|
||||
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel);
|
||||
}
|
||||
|
||||
for (int frameIdx = 0; frameIdx < morph->Channels[i]->Item3; frameIdx++)
|
||||
{
|
||||
int shapeIdx = morph->Channels[i]->Item2 + frameIdx;
|
||||
ImportedMorphKeyframe^ keyframe = keyframes[shapeIdx];
|
||||
|
||||
FbxShape* pShape;
|
||||
if (!flatInbetween)
|
||||
FbxBlendShapeChannel* lChannel = lBlendShape->GetBlendShapeChannel(lChannelIndex);
|
||||
FbxString lChannelName = lChannel->GetNameOnly();
|
||||
if (lChannelName == channelName)
|
||||
{
|
||||
char* pMorphShapeName;
|
||||
try
|
||||
{
|
||||
pMorphShapeName = StringToCharArray(keyframe->Name);
|
||||
if (pScene->FindMember<FbxShape>(pMorphShapeName))
|
||||
{
|
||||
Marshal::FreeHGlobal((IntPtr)pMorphShapeName);
|
||||
pMorphShapeName = StringToCharArray(morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty) + "__" + keyframe->Name);
|
||||
}
|
||||
pShape = FbxShape::Create(pScene, pMorphShapeName);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal::FreeHGlobal((IntPtr)pMorphShapeName);
|
||||
}
|
||||
if (frameIdx == morph->Channels[i]->Item3 - 1)
|
||||
{
|
||||
FbxProperty::Create(lBlendShape, FbxStringDT, rootGroupProp.GetName() + "|" + pShape->GetName());
|
||||
}
|
||||
lBlendShapeChannel->AddTargetShape(pShape, keyframe->Weight);
|
||||
}
|
||||
else
|
||||
{
|
||||
lBlendShapeChannel = FbxBlendShapeChannel::Create(pScene, "");
|
||||
lBlendShapeChannel->DeformPercent = morph->Channels[i]->Item1;
|
||||
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel);
|
||||
FbxAnimCurve* lAnimCurve = lGeometry->GetShapeChannel(0, lChannelIndex, lAnimLayer, true);
|
||||
lAnimCurve->KeyModifyBegin();
|
||||
|
||||
WITH_MARSHALLED_STRING
|
||||
(
|
||||
pMorphShapeName,
|
||||
morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty) + "." + keyframe->Name,
|
||||
pShape = FbxShape::Create(pScene, pMorphShapeName);
|
||||
);
|
||||
lBlendShapeChannel->AddTargetShape(pShape, 100);
|
||||
|
||||
FbxProperty weightProp;
|
||||
WITH_MARSHALLED_STRING
|
||||
(
|
||||
pWeightName,
|
||||
gcnew String(pShape->GetName()) + ".Weight",
|
||||
weightProp = FbxProperty::Create(pBaseMesh, FbxDoubleDT, pWeightName);
|
||||
);
|
||||
weightProp.ModifyFlag(FbxPropertyFlags::eUserDefined, true);
|
||||
weightProp.Set<double>(keyframe->Weight);
|
||||
}
|
||||
|
||||
pShape->InitControlPoints(vertList->Count);
|
||||
FbxVector4* pControlPoints = pShape->GetControlPoints();
|
||||
|
||||
for (int j = 0; j < vertList->Count; j++)
|
||||
{
|
||||
ImportedVertex^ vertex = vertList[j];
|
||||
Vector3 coords = vertex->Position;
|
||||
pControlPoints[j] = FbxVector4(coords.X, coords.Y, coords.Z, 0);
|
||||
}
|
||||
List<unsigned short>^ meshIndices = keyframe->MorphedVertexIndices;
|
||||
for (int j = 0; j < meshIndices->Count; j++)
|
||||
{
|
||||
int controlPointIndex = meshIndices[j] - meshVertexIndex;
|
||||
if (controlPointIndex >= 0 && controlPointIndex < vertList->Count)
|
||||
for each (auto keyframe in keyframeList->BlendShape->Keyframes)
|
||||
{
|
||||
Vector3 coords = keyframe->VertexList[j]->Position;
|
||||
pControlPoints[controlPointIndex] = FbxVector4(coords.X, coords.Y, coords.Z, 0);
|
||||
lTime.SetSecondDouble(keyframe->time);
|
||||
int lKeyIndex = lAnimCurve->KeyAdd(lTime);
|
||||
lAnimCurve->KeySetValue(lKeyIndex, keyframe->value);
|
||||
lAnimCurve->KeySetInterpolation(lKeyIndex, FbxAnimCurveDef::eInterpolationCubic);
|
||||
}
|
||||
}
|
||||
if (flatInbetween && meshIndices->Count == 0)
|
||||
{
|
||||
Vector3 coords = vertList[0]->Position;
|
||||
pControlPoints[0] = FbxVector4(coords.X - 1.0e-6, coords.Y, coords.Z, 0);
|
||||
}
|
||||
|
||||
if (flatInbetween && frameIdx > 0)
|
||||
{
|
||||
int shapeIdx = morph->Channels[i]->Item2 + frameIdx - 1;
|
||||
ImportedMorphKeyframe^ keyframe = keyframes[shapeIdx];
|
||||
|
||||
List<unsigned short>^ meshIndices = keyframe->MorphedVertexIndices;
|
||||
for (int j = 0; j < meshIndices->Count; j++)
|
||||
{
|
||||
int controlPointIndex = meshIndices[j] - meshVertexIndex;
|
||||
if (controlPointIndex >= 0 && controlPointIndex < vertList->Count)
|
||||
{
|
||||
Vector3 coords = keyframe->VertexList[j]->Position - vertList[controlPointIndex]->Position;
|
||||
pControlPoints[controlPointIndex] -= FbxVector4(coords.X, coords.Y, coords.Z, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (morphMask && frameIdx == 0)
|
||||
{
|
||||
int colourSetIdx = numColourSets + shapeIdx;
|
||||
FbxGeometryElementVertexColor* lGeometryElementVertexColor = pBaseMesh->GetElementVertexColor(colourSetIdx);
|
||||
if (lGeometryElementVertexColor == NULL)
|
||||
{
|
||||
lGeometryElementVertexColor = pBaseMesh->CreateElementVertexColor();
|
||||
}
|
||||
lGeometryElementVertexColor->SetMappingMode(FbxGeometryElement::eByControlPoint);
|
||||
lGeometryElementVertexColor->SetReferenceMode(FbxGeometryElement::eDirect);
|
||||
WITH_MARSHALLED_STRING
|
||||
(
|
||||
pColourLayerName, morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty) + "." + keyframe->Name,
|
||||
lGeometryElementVertexColor->SetName(pColourLayerName);
|
||||
);
|
||||
for (int j = 0; j < vertList->Count; j++)
|
||||
{
|
||||
lGeometryElementVertexColor->GetDirectArray().Add(FbxColor(1, 1, 1));
|
||||
}
|
||||
for (int j = 0; j < meshIndices->Count; j++)
|
||||
{
|
||||
int controlPointIndex = meshIndices[j] - meshVertexIndex;
|
||||
if (controlPointIndex >= 0 && controlPointIndex < vertList->Count)
|
||||
{
|
||||
lGeometryElementVertexColor->GetDirectArray().SetAt(controlPointIndex, FbxColor(0, 0, 1));
|
||||
}
|
||||
}
|
||||
lAnimCurve->KeyModifyEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
meshVertexIndex += meshList->SubmeshList[meshObjIdx]->VertexList->Count;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void Fbx::Exporter::ExportMorphs()
|
||||
{
|
||||
if (imported->MeshList == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for each (ImportedMorph ^ morph in imported->MorphList)
|
||||
{
|
||||
auto frame = imported->RootFrame->FindFrameByPath(morph->Path);
|
||||
if (frame != nullptr)
|
||||
{
|
||||
FbxNode* pNode = (FbxNode*)frameToNode[frame];
|
||||
FbxMesh* pMesh = pNode->GetMesh();
|
||||
|
||||
FbxBlendShape* lBlendShape = FbxBlendShape::Create(pScene, pMesh->GetNameOnly() + FbxString("BlendShape"));
|
||||
pMesh->AddDeformer(lBlendShape);
|
||||
|
||||
for (int i = 0; i < morph->Channels->Count; i++)
|
||||
{
|
||||
auto channel = morph->Channels[i];
|
||||
|
||||
FbxBlendShapeChannel* lBlendShapeChannel;
|
||||
WITH_MARSHALLED_STRING
|
||||
(
|
||||
pChannelName,
|
||||
channel->Name,
|
||||
lBlendShapeChannel = FbxBlendShapeChannel::Create(pScene, pChannelName);
|
||||
);
|
||||
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel);
|
||||
|
||||
for each (ImportedMorphKeyframe ^ keyframe in channel->KeyframeList)
|
||||
{
|
||||
FbxShape* lShape = FbxShape::Create(pScene, FbxString(keyframe->Weight));
|
||||
lBlendShapeChannel->AddTargetShape(lShape, keyframe->Weight);
|
||||
|
||||
auto vectorCount = pMesh->GetControlPointsCount();
|
||||
FbxVector4* orilVector4 = pMesh->GetControlPoints();
|
||||
lShape->InitControlPoints(vectorCount);
|
||||
FbxVector4* lVector4 = lShape->GetControlPoints();
|
||||
|
||||
for (int j = 0; j < vectorCount; j++)
|
||||
{
|
||||
auto vertex = orilVector4[j];
|
||||
lVector4[j] = FbxVector4(vertex);
|
||||
}
|
||||
for (int j = 0; j < keyframe->VertexList->Count; j++)
|
||||
{
|
||||
auto index = keyframe->VertexList[j]->Index;
|
||||
auto vertex = keyframe->VertexList[j]->Vertex->Vertex;
|
||||
lVector4[index] = FbxVector4(vertex.X, vertex.Y, vertex.Z, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}</ProjectGuid>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AssetStudioGUI</RootNamespace>
|
||||
<AssemblyName>AssetStudioGUI</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -39,20 +20,21 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugType>none</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -60,24 +42,31 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugType>none</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="OpenTK">
|
||||
<HintPath>Libraries\OpenTK.dll</HintPath>
|
||||
<Reference Include="OpenTK, Version=3.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\OpenTK.3.1.0\lib\net20\OpenTK.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OpenTK.GLControl">
|
||||
<HintPath>Libraries\OpenTK.GLControl.dll</HintPath>
|
||||
<Reference Include="OpenTK.GLControl, Version=3.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\OpenTK.GLControl.3.1.0\lib\net20\OpenTK.GLControl.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -85,37 +74,43 @@
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="GUILogger.cs" />
|
||||
<Compile Include="GUIProgress.cs" />
|
||||
<Compile Include="Components\GameObjectTreeNode.cs" />
|
||||
<Compile Include="Components\OpenFolderDialog.cs" />
|
||||
<Compile Include="Components\AssetItem.cs" />
|
||||
<Compile Include="Exporter.cs" />
|
||||
<Compile Include="Studio.cs" />
|
||||
<Compile Include="ExportOptions.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ExportOptions.Designer.cs">
|
||||
<DependentUpon>ExportOptions.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Components\GOHierarchy.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="AssetStudioGUIForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AssetStudioGUIForm.Designer.cs">
|
||||
<Compile Include="AssetStudioGUIForm.designer.cs">
|
||||
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Components\TypeTreeItem.cs" />
|
||||
<Compile Include="Components\AssetItem.cs" />
|
||||
<Compile Include="Components\GameObjectTreeNode.cs" />
|
||||
<Compile Include="Components\GOHierarchy.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Components\OpenFolderDialog.cs" />
|
||||
<Compile Include="Components\TreeViewExtensions.cs" />
|
||||
<Compile Include="Components\TypeTreeItem.cs" />
|
||||
<Compile Include="Exporter.cs" />
|
||||
<Compile Include="ExportOptions.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ExportOptions.designer.cs">
|
||||
<DependentUpon>ExportOptions.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="GUILogger.cs" />
|
||||
<Compile Include="GUIProgress.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Studio.cs" />
|
||||
<Compile Include="TGASharpLib.cs" />
|
||||
<EmbeddedResource Include="AssetStudioGUIForm.resx">
|
||||
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="ExportOptions.resx">
|
||||
<DependentUpon>ExportOptions.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
@@ -129,11 +124,8 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="AssetStudioGUIForm.resx">
|
||||
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<None Include="app.config" />
|
||||
<None Include="OpenTK.dll.config" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
@@ -145,21 +137,7 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4 Client Profile %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 4.5</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\preview.png" />
|
||||
@@ -167,26 +145,35 @@
|
||||
<ItemGroup>
|
||||
<None Include="Resources\as.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Platform)' == 'x86'">
|
||||
<ContentWithTargetPath Include="Libraries\x86\fmod.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>fmod.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="Libraries\x86\libfbxsdk.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>libfbxsdk.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Platform)' == 'x64'">
|
||||
<ContentWithTargetPath Include="Libraries\x64\fmod.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>fmod.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="Libraries\x64\libfbxsdk.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>libfbxsdk.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj">
|
||||
<Project>{9131c403-7fe8-444d-9af5-5fe5df76ff24}</Project>
|
||||
<Project>{80aec261-21ee-4e4f-a93b-7a744dc84888}</Project>
|
||||
<Name>AssetStudioUtility</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
|
||||
<Project>{af56b63c-1764-41b7-9e60-8d485422ac3b}</Project>
|
||||
<Project>{7662f8c2-7bfd-442e-a948-a43b4f7eb06e}</Project>
|
||||
<Name>AssetStudio</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>xcopy /y "$(ProjectDir)Libraries" "$(TargetDir)"
|
||||
xcopy /y "$(ProjectDir)Libraries\$(PlatformName)" "$(TargetDir)"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
538
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
538
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -7,11 +7,11 @@ namespace AssetStudioGUI
|
||||
{
|
||||
public Object Asset;
|
||||
public SerializedFile SourceFile;
|
||||
public string Container = string.Empty;
|
||||
public string TypeString;
|
||||
public long m_PathID;
|
||||
public long FullSize;
|
||||
public ClassIDType Type;
|
||||
public string TypeString;
|
||||
|
||||
public string Extension;
|
||||
public string InfoText;
|
||||
public string UniqueID;
|
||||
public GameObjectTreeNode TreeNode;
|
||||
@@ -20,9 +20,21 @@ namespace AssetStudioGUI
|
||||
{
|
||||
Asset = asset;
|
||||
SourceFile = asset.assetsFile;
|
||||
FullSize = asset.byteSize;
|
||||
Type = asset.type;
|
||||
TypeString = Type.ToString();
|
||||
m_PathID = asset.m_PathID;
|
||||
FullSize = asset.byteSize;
|
||||
}
|
||||
|
||||
public void SetSubItems()
|
||||
{
|
||||
SubItems.AddRange(new[]
|
||||
{
|
||||
Container, //Container
|
||||
TypeString, //Type
|
||||
m_PathID.ToString(), //PathID
|
||||
FullSize.ToString(), //Size
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace AssetStudioGUI
|
||||
hItem = node.Handle,
|
||||
mask = TVIF_STATE,
|
||||
stateMask = TVIS_STATEIMAGEMASK,
|
||||
state = 0
|
||||
state = node.StateImageIndex //freeze bugfix (no)
|
||||
};
|
||||
SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi);
|
||||
}
|
||||
|
||||
311
AssetStudioGUI/ExportOptions.Designer.cs
generated
311
AssetStudioGUI/ExportOptions.Designer.cs
generated
@@ -31,27 +31,35 @@
|
||||
this.OKbutton = new System.Windows.Forms.Button();
|
||||
this.Cancel = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.pathIDAsDumpName = new System.Windows.Forms.CheckBox();
|
||||
this.pathIDAsImageName = new System.Windows.Forms.CheckBox();
|
||||
this.openAfterExport = new System.Windows.Forms.CheckBox();
|
||||
this.restoreExtensionName = new System.Windows.Forms.CheckBox();
|
||||
this.assetGroupOptions = new System.Windows.Forms.ComboBox();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.convertAudio = new System.Windows.Forms.CheckBox();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.totga = new System.Windows.Forms.RadioButton();
|
||||
this.tojpg = new System.Windows.Forms.RadioButton();
|
||||
this.topng = new System.Windows.Forms.RadioButton();
|
||||
this.tobmp = new System.Windows.Forms.RadioButton();
|
||||
this.converttexture = new System.Windows.Forms.CheckBox();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.exportBlendShape = new System.Windows.Forms.CheckBox();
|
||||
this.exportAnimations = new System.Windows.Forms.CheckBox();
|
||||
this.scaleFactor = new System.Windows.Forms.NumericUpDown();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.fbxFormat = new System.Windows.Forms.ComboBox();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.fbxVersion = new System.Windows.Forms.ComboBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.flatInbetween = new System.Windows.Forms.CheckBox();
|
||||
this.boneSize = new System.Windows.Forms.NumericUpDown();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.skins = new System.Windows.Forms.CheckBox();
|
||||
this.exportSkins = new System.Windows.Forms.CheckBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.filterPrecision = new System.Windows.Forms.NumericUpDown();
|
||||
this.allBones = new System.Windows.Forms.CheckBox();
|
||||
this.allFrames = new System.Windows.Forms.CheckBox();
|
||||
this.castToBone = new System.Windows.Forms.CheckBox();
|
||||
this.exportAllNodes = new System.Windows.Forms.CheckBox();
|
||||
this.eulerFilter = new System.Windows.Forms.CheckBox();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
@@ -63,20 +71,20 @@
|
||||
//
|
||||
// OKbutton
|
||||
//
|
||||
this.OKbutton.Location = new System.Drawing.Point(321, 267);
|
||||
this.OKbutton.Location = new System.Drawing.Point(308, 347);
|
||||
this.OKbutton.Name = "OKbutton";
|
||||
this.OKbutton.Size = new System.Drawing.Size(75, 21);
|
||||
this.OKbutton.Size = new System.Drawing.Size(75, 23);
|
||||
this.OKbutton.TabIndex = 6;
|
||||
this.OKbutton.Text = "OK";
|
||||
this.OKbutton.UseVisualStyleBackColor = true;
|
||||
this.OKbutton.Click += new System.EventHandler(this.fbxOKbutton_Click);
|
||||
this.OKbutton.Click += new System.EventHandler(this.OKbutton_Click);
|
||||
//
|
||||
// Cancel
|
||||
//
|
||||
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.Cancel.Location = new System.Drawing.Point(402, 267);
|
||||
this.Cancel.Location = new System.Drawing.Point(389, 347);
|
||||
this.Cancel.Name = "Cancel";
|
||||
this.Cancel.Size = new System.Drawing.Size(75, 21);
|
||||
this.Cancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.Cancel.TabIndex = 7;
|
||||
this.Cancel.Text = "Cancel";
|
||||
this.Cancel.UseVisualStyleBackColor = true;
|
||||
@@ -85,44 +93,132 @@
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.AutoSize = true;
|
||||
this.groupBox1.Controls.Add(this.pathIDAsDumpName);
|
||||
this.groupBox1.Controls.Add(this.pathIDAsImageName);
|
||||
this.groupBox1.Controls.Add(this.openAfterExport);
|
||||
this.groupBox1.Controls.Add(this.restoreExtensionName);
|
||||
this.groupBox1.Controls.Add(this.assetGroupOptions);
|
||||
this.groupBox1.Controls.Add(this.label6);
|
||||
this.groupBox1.Controls.Add(this.convertAudio);
|
||||
this.groupBox1.Controls.Add(this.panel1);
|
||||
this.groupBox1.Controls.Add(this.converttexture);
|
||||
this.groupBox1.Location = new System.Drawing.Point(232, 12);
|
||||
this.groupBox1.Location = new System.Drawing.Point(12, 13);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(245, 114);
|
||||
this.groupBox1.Size = new System.Drawing.Size(246, 327);
|
||||
this.groupBox1.TabIndex = 9;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Convert";
|
||||
this.groupBox1.Text = "Export";
|
||||
//
|
||||
// pathIDAsDumpName
|
||||
//
|
||||
this.pathIDAsDumpName.AutoSize = true;
|
||||
this.pathIDAsDumpName.Checked = true;
|
||||
this.pathIDAsDumpName.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.pathIDAsDumpName.Location = new System.Drawing.Point(6, 217);
|
||||
this.pathIDAsDumpName.Name = "pathIDAsDumpName";
|
||||
this.pathIDAsDumpName.Size = new System.Drawing.Size(201, 17);
|
||||
this.pathIDAsDumpName.TabIndex = 12;
|
||||
this.pathIDAsDumpName.Text = "Dump assets with PathID as filename";
|
||||
this.pathIDAsDumpName.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// pathIDAsImageName
|
||||
//
|
||||
this.pathIDAsImageName.AutoSize = true;
|
||||
this.pathIDAsImageName.Checked = true;
|
||||
this.pathIDAsImageName.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.pathIDAsImageName.Location = new System.Drawing.Point(6, 196);
|
||||
this.pathIDAsImageName.Name = "pathIDAsImageName";
|
||||
this.pathIDAsImageName.Size = new System.Drawing.Size(234, 17);
|
||||
this.pathIDAsImageName.TabIndex = 11;
|
||||
this.pathIDAsImageName.Text = "Export image assets with PathID as filename";
|
||||
this.pathIDAsImageName.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// openAfterExport
|
||||
//
|
||||
this.openAfterExport.AutoSize = true;
|
||||
this.openAfterExport.Checked = true;
|
||||
this.openAfterExport.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.openAfterExport.Location = new System.Drawing.Point(6, 173);
|
||||
this.openAfterExport.Name = "openAfterExport";
|
||||
this.openAfterExport.Size = new System.Drawing.Size(137, 17);
|
||||
this.openAfterExport.TabIndex = 10;
|
||||
this.openAfterExport.Text = "Open folder after export";
|
||||
this.openAfterExport.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// restoreExtensionName
|
||||
//
|
||||
this.restoreExtensionName.AutoSize = true;
|
||||
this.restoreExtensionName.Checked = true;
|
||||
this.restoreExtensionName.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.restoreExtensionName.Location = new System.Drawing.Point(6, 63);
|
||||
this.restoreExtensionName.Name = "restoreExtensionName";
|
||||
this.restoreExtensionName.Size = new System.Drawing.Size(190, 17);
|
||||
this.restoreExtensionName.TabIndex = 9;
|
||||
this.restoreExtensionName.Text = "Restore TextAsset extension name";
|
||||
this.restoreExtensionName.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// assetGroupOptions
|
||||
//
|
||||
this.assetGroupOptions.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.assetGroupOptions.FormattingEnabled = true;
|
||||
this.assetGroupOptions.Items.AddRange(new object[] {
|
||||
"type name",
|
||||
"container path",
|
||||
"source file name",
|
||||
"do not group"});
|
||||
this.assetGroupOptions.Location = new System.Drawing.Point(6, 35);
|
||||
this.assetGroupOptions.Name = "assetGroupOptions";
|
||||
this.assetGroupOptions.Size = new System.Drawing.Size(149, 21);
|
||||
this.assetGroupOptions.TabIndex = 8;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(6, 18);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(127, 13);
|
||||
this.label6.TabIndex = 7;
|
||||
this.label6.Text = "Group exported assets by";
|
||||
//
|
||||
// convertAudio
|
||||
//
|
||||
this.convertAudio.AutoSize = true;
|
||||
this.convertAudio.Checked = true;
|
||||
this.convertAudio.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.convertAudio.Location = new System.Drawing.Point(6, 78);
|
||||
this.convertAudio.Location = new System.Drawing.Point(6, 150);
|
||||
this.convertAudio.Name = "convertAudio";
|
||||
this.convertAudio.Size = new System.Drawing.Size(198, 16);
|
||||
this.convertAudio.Size = new System.Drawing.Size(179, 17);
|
||||
this.convertAudio.TabIndex = 6;
|
||||
this.convertAudio.Text = "Convert AudioClip to WAV(PCM)";
|
||||
this.convertAudio.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.totga);
|
||||
this.panel1.Controls.Add(this.tojpg);
|
||||
this.panel1.Controls.Add(this.topng);
|
||||
this.panel1.Controls.Add(this.tobmp);
|
||||
this.panel1.Location = new System.Drawing.Point(30, 42);
|
||||
this.panel1.Location = new System.Drawing.Point(20, 111);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(146, 30);
|
||||
this.panel1.Size = new System.Drawing.Size(202, 33);
|
||||
this.panel1.TabIndex = 5;
|
||||
//
|
||||
// totga
|
||||
//
|
||||
this.totga.AutoSize = true;
|
||||
this.totga.Location = new System.Drawing.Point(150, 7);
|
||||
this.totga.Name = "totga";
|
||||
this.totga.Size = new System.Drawing.Size(47, 17);
|
||||
this.totga.TabIndex = 2;
|
||||
this.totga.Text = "TGA";
|
||||
this.totga.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tojpg
|
||||
//
|
||||
this.tojpg.AutoSize = true;
|
||||
this.tojpg.Location = new System.Drawing.Point(97, 6);
|
||||
this.tojpg.Location = new System.Drawing.Point(97, 7);
|
||||
this.tojpg.Name = "tojpg";
|
||||
this.tojpg.Size = new System.Drawing.Size(47, 16);
|
||||
this.tojpg.Size = new System.Drawing.Size(52, 17);
|
||||
this.tojpg.TabIndex = 4;
|
||||
this.tojpg.Text = "JPEG";
|
||||
this.tojpg.UseVisualStyleBackColor = true;
|
||||
@@ -131,9 +227,9 @@
|
||||
//
|
||||
this.topng.AutoSize = true;
|
||||
this.topng.Checked = true;
|
||||
this.topng.Location = new System.Drawing.Point(50, 6);
|
||||
this.topng.Location = new System.Drawing.Point(50, 7);
|
||||
this.topng.Name = "topng";
|
||||
this.topng.Size = new System.Drawing.Size(41, 16);
|
||||
this.topng.Size = new System.Drawing.Size(48, 17);
|
||||
this.topng.TabIndex = 3;
|
||||
this.topng.TabStop = true;
|
||||
this.topng.Text = "PNG";
|
||||
@@ -142,9 +238,9 @@
|
||||
// tobmp
|
||||
//
|
||||
this.tobmp.AutoSize = true;
|
||||
this.tobmp.Location = new System.Drawing.Point(3, 6);
|
||||
this.tobmp.Location = new System.Drawing.Point(3, 7);
|
||||
this.tobmp.Name = "tobmp";
|
||||
this.tobmp.Size = new System.Drawing.Size(41, 16);
|
||||
this.tobmp.Size = new System.Drawing.Size(48, 17);
|
||||
this.tobmp.TabIndex = 2;
|
||||
this.tobmp.Text = "BMP";
|
||||
this.tobmp.UseVisualStyleBackColor = true;
|
||||
@@ -154,9 +250,9 @@
|
||||
this.converttexture.AutoSize = true;
|
||||
this.converttexture.Checked = true;
|
||||
this.converttexture.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.converttexture.Location = new System.Drawing.Point(6, 20);
|
||||
this.converttexture.Location = new System.Drawing.Point(6, 87);
|
||||
this.converttexture.Name = "converttexture";
|
||||
this.converttexture.Size = new System.Drawing.Size(126, 16);
|
||||
this.converttexture.Size = new System.Drawing.Size(116, 17);
|
||||
this.converttexture.TabIndex = 1;
|
||||
this.converttexture.Text = "Convert Texture2D";
|
||||
this.converttexture.UseVisualStyleBackColor = true;
|
||||
@@ -164,28 +260,53 @@
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.AutoSize = true;
|
||||
this.groupBox2.Controls.Add(this.exportBlendShape);
|
||||
this.groupBox2.Controls.Add(this.exportAnimations);
|
||||
this.groupBox2.Controls.Add(this.scaleFactor);
|
||||
this.groupBox2.Controls.Add(this.label5);
|
||||
this.groupBox2.Controls.Add(this.fbxFormat);
|
||||
this.groupBox2.Controls.Add(this.label4);
|
||||
this.groupBox2.Controls.Add(this.fbxVersion);
|
||||
this.groupBox2.Controls.Add(this.label3);
|
||||
this.groupBox2.Controls.Add(this.flatInbetween);
|
||||
this.groupBox2.Controls.Add(this.boneSize);
|
||||
this.groupBox2.Controls.Add(this.label2);
|
||||
this.groupBox2.Controls.Add(this.skins);
|
||||
this.groupBox2.Controls.Add(this.exportSkins);
|
||||
this.groupBox2.Controls.Add(this.label1);
|
||||
this.groupBox2.Controls.Add(this.filterPrecision);
|
||||
this.groupBox2.Controls.Add(this.allBones);
|
||||
this.groupBox2.Controls.Add(this.allFrames);
|
||||
this.groupBox2.Controls.Add(this.castToBone);
|
||||
this.groupBox2.Controls.Add(this.exportAllNodes);
|
||||
this.groupBox2.Controls.Add(this.eulerFilter);
|
||||
this.groupBox2.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox2.Location = new System.Drawing.Point(258, 13);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(214, 276);
|
||||
this.groupBox2.Size = new System.Drawing.Size(206, 327);
|
||||
this.groupBox2.TabIndex = 11;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Fbx";
|
||||
//
|
||||
// exportBlendShape
|
||||
//
|
||||
this.exportBlendShape.AutoSize = true;
|
||||
this.exportBlendShape.Checked = true;
|
||||
this.exportBlendShape.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportBlendShape.Location = new System.Drawing.Point(6, 138);
|
||||
this.exportBlendShape.Name = "exportBlendShape";
|
||||
this.exportBlendShape.Size = new System.Drawing.Size(114, 17);
|
||||
this.exportBlendShape.TabIndex = 22;
|
||||
this.exportBlendShape.Text = "Export blendshape";
|
||||
this.exportBlendShape.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// exportAnimations
|
||||
//
|
||||
this.exportAnimations.AutoSize = true;
|
||||
this.exportAnimations.Checked = true;
|
||||
this.exportAnimations.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportAnimations.Location = new System.Drawing.Point(6, 114);
|
||||
this.exportAnimations.Name = "exportAnimations";
|
||||
this.exportAnimations.Size = new System.Drawing.Size(109, 17);
|
||||
this.exportAnimations.TabIndex = 21;
|
||||
this.exportAnimations.Text = "Export animations";
|
||||
this.exportAnimations.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// scaleFactor
|
||||
//
|
||||
this.scaleFactor.DecimalPlaces = 2;
|
||||
@@ -194,9 +315,9 @@
|
||||
0,
|
||||
0,
|
||||
131072});
|
||||
this.scaleFactor.Location = new System.Drawing.Point(83, 155);
|
||||
this.scaleFactor.Location = new System.Drawing.Point(83, 219);
|
||||
this.scaleFactor.Name = "scaleFactor";
|
||||
this.scaleFactor.Size = new System.Drawing.Size(60, 21);
|
||||
this.scaleFactor.Size = new System.Drawing.Size(60, 20);
|
||||
this.scaleFactor.TabIndex = 20;
|
||||
this.scaleFactor.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.scaleFactor.Value = new decimal(new int[] {
|
||||
@@ -208,9 +329,9 @@
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(6, 157);
|
||||
this.label5.Location = new System.Drawing.Point(6, 221);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(71, 12);
|
||||
this.label5.Size = new System.Drawing.Size(64, 13);
|
||||
this.label5.TabIndex = 19;
|
||||
this.label5.Text = "ScaleFactor";
|
||||
//
|
||||
@@ -221,17 +342,17 @@
|
||||
this.fbxFormat.Items.AddRange(new object[] {
|
||||
"Binary",
|
||||
"Ascii"});
|
||||
this.fbxFormat.Location = new System.Drawing.Point(75, 207);
|
||||
this.fbxFormat.Location = new System.Drawing.Point(77, 252);
|
||||
this.fbxFormat.Name = "fbxFormat";
|
||||
this.fbxFormat.Size = new System.Drawing.Size(61, 20);
|
||||
this.fbxFormat.Size = new System.Drawing.Size(61, 21);
|
||||
this.fbxFormat.TabIndex = 18;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(4, 210);
|
||||
this.label4.Location = new System.Drawing.Point(6, 256);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(59, 12);
|
||||
this.label4.Size = new System.Drawing.Size(59, 13);
|
||||
this.label4.TabIndex = 17;
|
||||
this.label4.Text = "FBXFormat";
|
||||
//
|
||||
@@ -246,35 +367,25 @@
|
||||
"7.3",
|
||||
"7.4",
|
||||
"7.5"});
|
||||
this.fbxVersion.Location = new System.Drawing.Point(75, 236);
|
||||
this.fbxVersion.Location = new System.Drawing.Point(77, 284);
|
||||
this.fbxVersion.Name = "fbxVersion";
|
||||
this.fbxVersion.Size = new System.Drawing.Size(47, 20);
|
||||
this.fbxVersion.Size = new System.Drawing.Size(47, 21);
|
||||
this.fbxVersion.TabIndex = 16;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(4, 239);
|
||||
this.label3.Location = new System.Drawing.Point(6, 287);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(65, 12);
|
||||
this.label3.Size = new System.Drawing.Size(62, 13);
|
||||
this.label3.TabIndex = 15;
|
||||
this.label3.Text = "FBXVersion";
|
||||
//
|
||||
// flatInbetween
|
||||
//
|
||||
this.flatInbetween.AutoSize = true;
|
||||
this.flatInbetween.Location = new System.Drawing.Point(6, 182);
|
||||
this.flatInbetween.Name = "flatInbetween";
|
||||
this.flatInbetween.Size = new System.Drawing.Size(102, 16);
|
||||
this.flatInbetween.TabIndex = 12;
|
||||
this.flatInbetween.Text = "FlatInbetween";
|
||||
this.flatInbetween.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// boneSize
|
||||
//
|
||||
this.boneSize.Location = new System.Drawing.Point(65, 128);
|
||||
this.boneSize.Location = new System.Drawing.Point(65, 190);
|
||||
this.boneSize.Name = "boneSize";
|
||||
this.boneSize.Size = new System.Drawing.Size(46, 21);
|
||||
this.boneSize.Size = new System.Drawing.Size(46, 20);
|
||||
this.boneSize.TabIndex = 11;
|
||||
this.boneSize.Value = new decimal(new int[] {
|
||||
10,
|
||||
@@ -285,30 +396,30 @@
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(6, 130);
|
||||
this.label2.Location = new System.Drawing.Point(6, 192);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(53, 12);
|
||||
this.label2.Size = new System.Drawing.Size(52, 13);
|
||||
this.label2.TabIndex = 10;
|
||||
this.label2.Text = "BoneSize";
|
||||
//
|
||||
// skins
|
||||
// exportSkins
|
||||
//
|
||||
this.skins.AutoSize = true;
|
||||
this.skins.Checked = true;
|
||||
this.skins.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.skins.Location = new System.Drawing.Point(6, 105);
|
||||
this.skins.Name = "skins";
|
||||
this.skins.Size = new System.Drawing.Size(54, 16);
|
||||
this.skins.TabIndex = 8;
|
||||
this.skins.Text = "Skins";
|
||||
this.skins.UseVisualStyleBackColor = true;
|
||||
this.exportSkins.AutoSize = true;
|
||||
this.exportSkins.Checked = true;
|
||||
this.exportSkins.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportSkins.Location = new System.Drawing.Point(6, 90);
|
||||
this.exportSkins.Name = "exportSkins";
|
||||
this.exportSkins.Size = new System.Drawing.Size(83, 17);
|
||||
this.exportSkins.TabIndex = 8;
|
||||
this.exportSkins.Text = "Export skins";
|
||||
this.exportSkins.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(26, 39);
|
||||
this.label1.Location = new System.Drawing.Point(26, 42);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(95, 12);
|
||||
this.label1.Size = new System.Drawing.Size(72, 13);
|
||||
this.label1.TabIndex = 7;
|
||||
this.label1.Text = "FilterPrecision";
|
||||
//
|
||||
@@ -320,9 +431,9 @@
|
||||
0,
|
||||
0,
|
||||
131072});
|
||||
this.filterPrecision.Location = new System.Drawing.Point(127, 37);
|
||||
this.filterPrecision.Location = new System.Drawing.Point(127, 40);
|
||||
this.filterPrecision.Name = "filterPrecision";
|
||||
this.filterPrecision.Size = new System.Drawing.Size(51, 21);
|
||||
this.filterPrecision.Size = new System.Drawing.Size(51, 20);
|
||||
this.filterPrecision.TabIndex = 6;
|
||||
this.filterPrecision.Value = new decimal(new int[] {
|
||||
25,
|
||||
@@ -330,36 +441,36 @@
|
||||
0,
|
||||
131072});
|
||||
//
|
||||
// allBones
|
||||
// castToBone
|
||||
//
|
||||
this.allBones.AutoSize = true;
|
||||
this.allBones.Checked = true;
|
||||
this.allBones.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.allBones.Location = new System.Drawing.Point(6, 83);
|
||||
this.allBones.Name = "allBones";
|
||||
this.allBones.Size = new System.Drawing.Size(72, 16);
|
||||
this.allBones.TabIndex = 5;
|
||||
this.allBones.Text = "AllBones";
|
||||
this.allBones.UseVisualStyleBackColor = true;
|
||||
this.castToBone.AutoSize = true;
|
||||
this.castToBone.Location = new System.Drawing.Point(6, 161);
|
||||
this.castToBone.Name = "castToBone";
|
||||
this.castToBone.Size = new System.Drawing.Size(131, 17);
|
||||
this.castToBone.TabIndex = 5;
|
||||
this.castToBone.Text = "All nodes cast to bone";
|
||||
this.castToBone.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// allFrames
|
||||
// exportAllNodes
|
||||
//
|
||||
this.allFrames.AutoSize = true;
|
||||
this.allFrames.Location = new System.Drawing.Point(6, 61);
|
||||
this.allFrames.Name = "allFrames";
|
||||
this.allFrames.Size = new System.Drawing.Size(78, 16);
|
||||
this.allFrames.TabIndex = 4;
|
||||
this.allFrames.Text = "AllFrames";
|
||||
this.allFrames.UseVisualStyleBackColor = true;
|
||||
this.exportAllNodes.AutoSize = true;
|
||||
this.exportAllNodes.Checked = true;
|
||||
this.exportAllNodes.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportAllNodes.Location = new System.Drawing.Point(6, 66);
|
||||
this.exportAllNodes.Name = "exportAllNodes";
|
||||
this.exportAllNodes.Size = new System.Drawing.Size(101, 17);
|
||||
this.exportAllNodes.TabIndex = 4;
|
||||
this.exportAllNodes.Text = "Export all nodes";
|
||||
this.exportAllNodes.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// eulerFilter
|
||||
//
|
||||
this.eulerFilter.AutoSize = true;
|
||||
this.eulerFilter.Checked = true;
|
||||
this.eulerFilter.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.eulerFilter.Location = new System.Drawing.Point(6, 20);
|
||||
this.eulerFilter.Location = new System.Drawing.Point(6, 22);
|
||||
this.eulerFilter.Name = "eulerFilter";
|
||||
this.eulerFilter.Size = new System.Drawing.Size(90, 16);
|
||||
this.eulerFilter.Size = new System.Drawing.Size(72, 17);
|
||||
this.eulerFilter.TabIndex = 3;
|
||||
this.eulerFilter.Text = "EulerFilter";
|
||||
this.eulerFilter.UseVisualStyleBackColor = true;
|
||||
@@ -367,10 +478,10 @@
|
||||
// ExportOptions
|
||||
//
|
||||
this.AcceptButton = this.OKbutton;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.Cancel;
|
||||
this.ClientSize = new System.Drawing.Size(490, 301);
|
||||
this.ClientSize = new System.Drawing.Size(477, 380);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.Cancel);
|
||||
@@ -405,17 +516,17 @@
|
||||
private System.Windows.Forms.RadioButton tojpg;
|
||||
private System.Windows.Forms.RadioButton topng;
|
||||
private System.Windows.Forms.RadioButton tobmp;
|
||||
private System.Windows.Forms.RadioButton totga;
|
||||
private System.Windows.Forms.CheckBox convertAudio;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.GroupBox groupBox2;
|
||||
private System.Windows.Forms.CheckBox flatInbetween;
|
||||
private System.Windows.Forms.NumericUpDown boneSize;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.CheckBox skins;
|
||||
private System.Windows.Forms.CheckBox exportSkins;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.NumericUpDown filterPrecision;
|
||||
private System.Windows.Forms.CheckBox allBones;
|
||||
private System.Windows.Forms.CheckBox allFrames;
|
||||
private System.Windows.Forms.CheckBox castToBone;
|
||||
private System.Windows.Forms.CheckBox exportAllNodes;
|
||||
private System.Windows.Forms.CheckBox eulerFilter;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.ComboBox fbxVersion;
|
||||
@@ -423,5 +534,13 @@
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.NumericUpDown scaleFactor;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.CheckBox exportBlendShape;
|
||||
private System.Windows.Forms.CheckBox exportAnimations;
|
||||
private System.Windows.Forms.ComboBox assetGroupOptions;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.CheckBox restoreExtensionName;
|
||||
private System.Windows.Forms.CheckBox openAfterExport;
|
||||
private System.Windows.Forms.CheckBox pathIDAsImageName;
|
||||
private System.Windows.Forms.CheckBox pathIDAsDumpName;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
@@ -15,9 +8,11 @@ namespace AssetStudioGUI
|
||||
public ExportOptions()
|
||||
{
|
||||
InitializeComponent();
|
||||
converttexture.Checked = (bool)Properties.Settings.Default["convertTexture"];
|
||||
convertAudio.Checked = (bool)Properties.Settings.Default["convertAudio"];
|
||||
var str = (string)Properties.Settings.Default["convertType"];
|
||||
assetGroupOptions.SelectedIndex = Properties.Settings.Default.assetGroupOption;
|
||||
restoreExtensionName.Checked = Properties.Settings.Default.restoreExtensionName;
|
||||
converttexture.Checked = Properties.Settings.Default.convertTexture;
|
||||
convertAudio.Checked = Properties.Settings.Default.convertAudio;
|
||||
var str = Properties.Settings.Default.convertType;
|
||||
foreach (Control c in panel1.Controls)
|
||||
{
|
||||
if (c.Text == str)
|
||||
@@ -26,46 +21,50 @@ namespace AssetStudioGUI
|
||||
break;
|
||||
}
|
||||
}
|
||||
eulerFilter.Checked = (bool)Properties.Settings.Default["eulerFilter"];
|
||||
filterPrecision.Value = (decimal)Properties.Settings.Default["filterPrecision"];
|
||||
allFrames.Checked = (bool)Properties.Settings.Default["allFrames"];
|
||||
allBones.Checked = (bool)Properties.Settings.Default["allBones"];
|
||||
skins.Checked = (bool)Properties.Settings.Default["skins"];
|
||||
boneSize.Value = (decimal)Properties.Settings.Default["boneSize"];
|
||||
scaleFactor.Value = (decimal)Properties.Settings.Default["scaleFactor"];
|
||||
flatInbetween.Checked = (bool)Properties.Settings.Default["flatInbetween"];
|
||||
fbxVersion.SelectedIndex = (int)Properties.Settings.Default["fbxVersion"];
|
||||
fbxFormat.SelectedIndex = (int)Properties.Settings.Default["fbxFormat"];
|
||||
openAfterExport.Checked = Properties.Settings.Default.openAfterExport;
|
||||
eulerFilter.Checked = Properties.Settings.Default.eulerFilter;
|
||||
filterPrecision.Value = Properties.Settings.Default.filterPrecision;
|
||||
exportAllNodes.Checked = Properties.Settings.Default.exportAllNodes;
|
||||
exportSkins.Checked = Properties.Settings.Default.exportSkins;
|
||||
exportAnimations.Checked = Properties.Settings.Default.exportAnimations;
|
||||
exportBlendShape.Checked = Properties.Settings.Default.exportBlendShape;
|
||||
castToBone.Checked = Properties.Settings.Default.castToBone;
|
||||
boneSize.Value = Properties.Settings.Default.boneSize;
|
||||
scaleFactor.Value = Properties.Settings.Default.scaleFactor;
|
||||
fbxVersion.SelectedIndex = Properties.Settings.Default.fbxVersion;
|
||||
fbxFormat.SelectedIndex = Properties.Settings.Default.fbxFormat;
|
||||
pathIDAsImageName.Checked = Properties.Settings.Default.pathIDAsImageName;
|
||||
pathIDAsDumpName.Checked = Properties.Settings.Default.pathIDAsDumpName;
|
||||
}
|
||||
|
||||
private void exportOpnions_CheckedChanged(object sender, EventArgs e)
|
||||
private void OKbutton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default[((CheckBox)sender).Name] = ((CheckBox)sender).Checked;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
private void fbxOKbutton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default["convertTexture"] = converttexture.Checked;
|
||||
Properties.Settings.Default["convertAudio"] = convertAudio.Checked;
|
||||
Properties.Settings.Default.assetGroupOption = assetGroupOptions.SelectedIndex;
|
||||
Properties.Settings.Default.restoreExtensionName = restoreExtensionName.Checked;
|
||||
Properties.Settings.Default.convertTexture = converttexture.Checked;
|
||||
Properties.Settings.Default.convertAudio = convertAudio.Checked;
|
||||
foreach (Control c in panel1.Controls)
|
||||
{
|
||||
if (((RadioButton)c).Checked)
|
||||
{
|
||||
Properties.Settings.Default["convertType"] = c.Text;
|
||||
Properties.Settings.Default.convertType = c.Text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Properties.Settings.Default["eulerFilter"] = eulerFilter.Checked;
|
||||
Properties.Settings.Default["filterPrecision"] = filterPrecision.Value;
|
||||
Properties.Settings.Default["allFrames"] = allFrames.Checked;
|
||||
Properties.Settings.Default["allBones"] = allBones.Checked;
|
||||
Properties.Settings.Default["skins"] = skins.Checked;
|
||||
Properties.Settings.Default["boneSize"] = boneSize.Value;
|
||||
Properties.Settings.Default["scaleFactor"] = scaleFactor.Value;
|
||||
Properties.Settings.Default["flatInbetween"] = flatInbetween.Checked;
|
||||
Properties.Settings.Default["fbxVersion"] = fbxVersion.SelectedIndex;
|
||||
Properties.Settings.Default["fbxFormat"] = fbxFormat.SelectedIndex;
|
||||
Properties.Settings.Default.openAfterExport = openAfterExport.Checked;
|
||||
Properties.Settings.Default.eulerFilter = eulerFilter.Checked;
|
||||
Properties.Settings.Default.filterPrecision = filterPrecision.Value;
|
||||
Properties.Settings.Default.exportAllNodes = exportAllNodes.Checked;
|
||||
Properties.Settings.Default.exportSkins = exportSkins.Checked;
|
||||
Properties.Settings.Default.exportAnimations = exportAnimations.Checked;
|
||||
Properties.Settings.Default.exportBlendShape = exportBlendShape.Checked;
|
||||
Properties.Settings.Default.castToBone = castToBone.Checked;
|
||||
Properties.Settings.Default.boneSize = boneSize.Value;
|
||||
Properties.Settings.Default.scaleFactor = scaleFactor.Value;
|
||||
Properties.Settings.Default.fbxVersion = fbxVersion.SelectedIndex;
|
||||
Properties.Settings.Default.fbxFormat = fbxFormat.SelectedIndex;
|
||||
Properties.Settings.Default.pathIDAsImageName = pathIDAsImageName.Checked;
|
||||
Properties.Settings.Default.pathIDAsDumpName = pathIDAsDumpName.Checked;
|
||||
Properties.Settings.Default.Save();
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using AssetStudio;
|
||||
using TGASharpLib;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
@@ -11,15 +12,16 @@ namespace AssetStudioGUI
|
||||
{
|
||||
public static bool ExportTexture2D(AssetItem item, string exportPathName)
|
||||
{
|
||||
var converter = new Texture2DConverter((Texture2D)item.Asset);
|
||||
var convertTexture = (bool)Properties.Settings.Default["convertTexture"];
|
||||
if (convertTexture)
|
||||
string exportFullName;
|
||||
var m_Texture2D = (Texture2D)item.Asset;
|
||||
if (Properties.Settings.Default.convertTexture)
|
||||
{
|
||||
var bitmap = converter.ConvertToBitmap(true);
|
||||
var bitmap = m_Texture2D.ConvertToBitmap(true);
|
||||
if (bitmap == null)
|
||||
return false;
|
||||
ImageFormat format = null;
|
||||
var ext = (string)Properties.Settings.Default["convertType"];
|
||||
var ext = Properties.Settings.Default.convertType;
|
||||
bool tga = false;
|
||||
switch (ext)
|
||||
{
|
||||
case "BMP":
|
||||
@@ -31,20 +33,35 @@ namespace AssetStudioGUI
|
||||
case "JPEG":
|
||||
format = ImageFormat.Jpeg;
|
||||
break;
|
||||
case "TGA":
|
||||
tga = true;
|
||||
break;
|
||||
}
|
||||
var exportFullName = exportPathName + item.Text + "." + ext.ToLower();
|
||||
if (Properties.Settings.Default.pathIDAsImageName)
|
||||
exportFullName = exportPathName + item.m_PathID.ToString() + "." + ext.ToLower();
|
||||
else
|
||||
exportFullName = exportPathName + item.Text + "." + ext.ToLower();
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
bitmap.Save(exportFullName, format);
|
||||
if (tga)
|
||||
{
|
||||
var file = new TGA(bitmap);
|
||||
file.Save(exportFullName);
|
||||
}
|
||||
else
|
||||
bitmap.Save(exportFullName, format);
|
||||
bitmap.Dispose();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var exportFullName = exportPathName + item.Text + converter.GetExtensionName();
|
||||
if (Properties.Settings.Default.pathIDAsImageName)
|
||||
exportFullName = exportPathName + item.m_PathID.ToString() + ".tex";
|
||||
else
|
||||
exportFullName = exportPathName + item.Text + ".tex";
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullName, converter.ConvertToContainer());
|
||||
File.WriteAllBytes(exportFullName, m_Texture2D.image_data.GetData());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -52,12 +69,11 @@ namespace AssetStudioGUI
|
||||
public static bool ExportAudioClip(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_AudioClip = (AudioClip)item.Asset;
|
||||
var m_AudioData = m_AudioClip.m_AudioData.Value;
|
||||
var m_AudioData = m_AudioClip.m_AudioData.GetData();
|
||||
if (m_AudioData == null || m_AudioData.Length == 0)
|
||||
return false;
|
||||
var convertAudio = (bool)Properties.Settings.Default["convertAudio"];
|
||||
var converter = new AudioClipConverter(m_AudioClip);
|
||||
if (convertAudio && converter.IsFMODSupport)
|
||||
if (Properties.Settings.Default.convertAudio && converter.IsSupport)
|
||||
{
|
||||
var exportFullName = exportPath + item.Text + ".wav";
|
||||
if (ExportFileExists(exportFullName))
|
||||
@@ -82,7 +98,7 @@ namespace AssetStudioGUI
|
||||
var exportFullName = exportPath + item.Text + ".shader";
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
var m_Shader = (Shader) item.Asset;
|
||||
var m_Shader = (Shader)item.Asset;
|
||||
if (m_Shader.compressedBlob != null) //5.5 and up
|
||||
{
|
||||
var strs = ShaderConverter.ConvertMultiple(m_Shader);
|
||||
@@ -103,7 +119,15 @@ namespace AssetStudioGUI
|
||||
public static bool ExportTextAsset(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_TextAsset = (TextAsset)(item.Asset);
|
||||
var exportFullName = exportPath + item.Text + (item.Extension ?? ".txt");
|
||||
var extension = ".txt";
|
||||
if (Properties.Settings.Default.restoreExtensionName)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.Container))
|
||||
{
|
||||
extension = Path.GetExtension(item.Container);
|
||||
}
|
||||
}
|
||||
var exportFullName = exportPath + item.Text + extension;
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullName, m_TextAsset.m_Script);
|
||||
@@ -167,24 +191,25 @@ namespace AssetStudioGUI
|
||||
#endregion
|
||||
|
||||
#region UV
|
||||
if (m_Mesh.m_UV0 != null && m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 2)
|
||||
if (m_Mesh.m_UV0?.Length > 0)
|
||||
{
|
||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||
if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 2)
|
||||
{
|
||||
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV0[v * 2], m_Mesh.m_UV0[v * 2 + 1]);
|
||||
c = 2;
|
||||
}
|
||||
else if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 3)
|
||||
{
|
||||
c = 3;
|
||||
}
|
||||
}
|
||||
else if (m_Mesh.m_UV1 != null && m_Mesh.m_UV1.Length == m_Mesh.m_VertexCount * 2)
|
||||
{
|
||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||
{
|
||||
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV1[v * 2], m_Mesh.m_UV1[v * 2 + 1]);
|
||||
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV0[v * c], m_Mesh.m_UV0[v * c + 1]);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Normals
|
||||
if (m_Mesh.m_Normals != null && m_Mesh.m_Normals.Length > 0)
|
||||
if (m_Mesh.m_Normals?.Length > 0)
|
||||
{
|
||||
if (m_Mesh.m_Normals.Length == m_Mesh.m_VertexCount * 3)
|
||||
{
|
||||
@@ -224,7 +249,7 @@ namespace AssetStudioGUI
|
||||
public static bool ExportVideoClip(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_VideoClip = (VideoClip)item.Asset;
|
||||
var m_VideoData = m_VideoClip.m_VideoData.Value;
|
||||
var m_VideoData = m_VideoClip.m_VideoData.GetData();
|
||||
if (m_VideoData != null && m_VideoData.Length != 0)
|
||||
{
|
||||
var exportFullName = exportPath + item.Text + Path.GetExtension(m_VideoClip.m_OriginalPath);
|
||||
@@ -249,7 +274,9 @@ namespace AssetStudioGUI
|
||||
public static bool ExportSprite(AssetItem item, string exportPath)
|
||||
{
|
||||
ImageFormat format = null;
|
||||
var type = (string)Properties.Settings.Default["convertType"];
|
||||
string exportFullName;
|
||||
var type = Properties.Settings.Default.convertType;
|
||||
bool tga = false;
|
||||
switch (type)
|
||||
{
|
||||
case "BMP":
|
||||
@@ -261,14 +288,26 @@ namespace AssetStudioGUI
|
||||
case "JPEG":
|
||||
format = ImageFormat.Jpeg;
|
||||
break;
|
||||
case "TGA":
|
||||
tga = true;
|
||||
break;
|
||||
}
|
||||
var exportFullName = exportPath + item.Text + "." + type.ToLower();
|
||||
if (Properties.Settings.Default.pathIDAsImageName)
|
||||
exportFullName = exportPath + item.m_PathID.ToString() + "." + type.ToLower();
|
||||
else
|
||||
exportFullName = exportPath + item.Text + "." + type.ToLower();
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
var bitmap = SpriteHelper.GetImageFromSprite((Sprite)item.Asset);
|
||||
var bitmap = ((Sprite)item.Asset).GetImage();
|
||||
if (bitmap != null)
|
||||
{
|
||||
bitmap.Save(exportFullName, format);
|
||||
if (tga)
|
||||
{
|
||||
var file = new TGA(bitmap);
|
||||
file.Save(exportFullName);
|
||||
}
|
||||
else
|
||||
bitmap.Save(exportFullName, format);
|
||||
bitmap.Dispose();
|
||||
return true;
|
||||
}
|
||||
@@ -299,30 +338,94 @@ namespace AssetStudioGUI
|
||||
var m_Animator = (Animator)item.Asset;
|
||||
var convert = animationList != null ? new ModelConverter(m_Animator, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(m_Animator);
|
||||
exportPath = $"{exportPath}{item.Text}\\{item.Text}.fbx";
|
||||
return ExportFbx(convert, exportPath);
|
||||
ExportFbx(convert, exportPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
|
||||
public static void ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
|
||||
{
|
||||
var convert = animationList != null ? new ModelConverter(gameObject, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(gameObject);
|
||||
exportPath = exportPath + Studio.FixFileName(gameObject.m_Name) + ".fbx";
|
||||
return ExportFbx(convert, exportPath);
|
||||
ExportFbx(convert, exportPath);
|
||||
}
|
||||
|
||||
private static bool ExportFbx(IImported convert, string exportPath)
|
||||
public static void ExportGameObjectMerge(List<GameObject> gameObject, string exportPath, List<AssetItem> animationList = null)
|
||||
{
|
||||
var eulerFilter = (bool)Properties.Settings.Default["eulerFilter"];
|
||||
var filterPrecision = (float)(decimal)Properties.Settings.Default["filterPrecision"];
|
||||
var allFrames = (bool)Properties.Settings.Default["allFrames"];
|
||||
var allBones = (bool)Properties.Settings.Default["allBones"];
|
||||
var skins = (bool)Properties.Settings.Default["skins"];
|
||||
var boneSize = (int)(decimal)Properties.Settings.Default["boneSize"];
|
||||
var scaleFactor = (float)(decimal)Properties.Settings.Default["scaleFactor"];
|
||||
var flatInbetween = (bool)Properties.Settings.Default["flatInbetween"];
|
||||
var fbxVersion = (int)Properties.Settings.Default["fbxVersion"];
|
||||
var fbxFormat = (int)Properties.Settings.Default["fbxFormat"];
|
||||
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, flatInbetween, fbxVersion, fbxFormat == 1);
|
||||
return true;
|
||||
var rootName = Path.GetFileNameWithoutExtension(exportPath);
|
||||
var convert = animationList != null ? new ModelConverter(rootName, gameObject, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(rootName, gameObject);
|
||||
ExportFbx(convert, exportPath);
|
||||
}
|
||||
|
||||
private static void ExportFbx(IImported convert, string exportPath)
|
||||
{
|
||||
var eulerFilter = Properties.Settings.Default.eulerFilter;
|
||||
var filterPrecision = (float)Properties.Settings.Default.filterPrecision;
|
||||
var exportAllNodes = Properties.Settings.Default.exportAllNodes;
|
||||
var exportSkins = Properties.Settings.Default.exportSkins;
|
||||
var exportAnimations = Properties.Settings.Default.exportAnimations;
|
||||
var exportBlendShape = Properties.Settings.Default.exportBlendShape;
|
||||
var castToBone = Properties.Settings.Default.castToBone;
|
||||
var boneSize = (int)Properties.Settings.Default.boneSize;
|
||||
var scaleFactor = (float)Properties.Settings.Default.scaleFactor;
|
||||
var fbxVersion = Properties.Settings.Default.fbxVersion;
|
||||
var fbxFormat = Properties.Settings.Default.fbxFormat;
|
||||
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision,
|
||||
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, scaleFactor, fbxVersion, fbxFormat == 1);
|
||||
}
|
||||
|
||||
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
||||
{
|
||||
string exportFullName;
|
||||
if (Properties.Settings.Default.pathIDAsDumpName)
|
||||
{
|
||||
exportFullName = exportPath + item.m_PathID.ToString() + ".txt";
|
||||
}
|
||||
else
|
||||
{
|
||||
exportFullName = exportPath + item.Text + ".txt";
|
||||
}
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
var str = item.Asset.Dump();
|
||||
if (str != null)
|
||||
{
|
||||
File.WriteAllText(exportFullName, str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportConvertFile(AssetItem item, string exportPath)
|
||||
{
|
||||
switch (item.Type)
|
||||
{
|
||||
case ClassIDType.Texture2D:
|
||||
return ExportTexture2D(item, exportPath);
|
||||
case ClassIDType.AudioClip:
|
||||
return ExportAudioClip(item, exportPath);
|
||||
case ClassIDType.Shader:
|
||||
return ExportShader(item, exportPath);
|
||||
case ClassIDType.TextAsset:
|
||||
return ExportTextAsset(item, exportPath);
|
||||
case ClassIDType.MonoBehaviour:
|
||||
return ExportMonoBehaviour(item, exportPath);
|
||||
case ClassIDType.Font:
|
||||
return ExportFont(item, exportPath);
|
||||
case ClassIDType.Mesh:
|
||||
return ExportMesh(item, exportPath);
|
||||
case ClassIDType.VideoClip:
|
||||
return ExportVideoClip(item, exportPath);
|
||||
case ClassIDType.MovieTexture:
|
||||
return ExportMovieTexture(item, exportPath);
|
||||
case ClassIDType.Sprite:
|
||||
return ExportSprite(item, exportPath);
|
||||
case ClassIDType.Animator:
|
||||
return ExportAnimator(item, exportPath);
|
||||
case ClassIDType.AnimationClip:
|
||||
return false;
|
||||
default:
|
||||
return ExportRawFile(item, exportPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
FMOD, FMOD Ex, FMOD Designer and FMOD Studio are
|
||||
Copyright <20> 2005-2016 Firelight Technologies Pty, Ltd.
|
||||
|
||||
GRANT OF LICENSE
|
||||
----------------
|
||||
THIS END USER LICENSE AGREEMENT GRANTS THE USER, THE RIGHT TO USE FMOD,
|
||||
IN ITS LIBRARY AND TOOL FORM, IN THEIR OWN PRODUCTS, BE THEY FOR PERSONAL,
|
||||
EDUCATIONAL OR COMMERCIAL USE.
|
||||
THE USER MUST ADHERE TO THE LICENSING MODEL PROVIDED BY FIRELIGHT
|
||||
TECHNOLOGIES, AND MUST APPLY FOR A LICENSE IF NECESSARY. THE FOLLOWING
|
||||
LICENSES ARE AVAILABLE.
|
||||
|
||||
FMOD NON-COMMERCIAL LICENSE
|
||||
------------------------------------
|
||||
IF YOUR PRODUCT IS NOT INTENDED FOR COMMERCIAL GAIN AND DOES NOT
|
||||
INCLUDE THE FMOD LIBRARY FOR RESALE, LICENSE OR OTHER COMMERCIAL
|
||||
DISTRIBUTION, THEN USE OF FMOD IS FREE OF CHARGE. THERE ARE NO
|
||||
LICENSE FEES FOR NON-COMMERCIAL APPLICATIONS.
|
||||
THE USER MAY USE THIS EULA AS EVIDENCE OF THEIR LICENSE WITHOUT
|
||||
CONTACTING FIRELIGHT TECHNOLOGIES.
|
||||
|
||||
CONDITIONS/LIMITATIONS:
|
||||
- WHEN USING THIS LICENSE, THE FMOD LIBRARY CANNOT BE USED FOR
|
||||
RESALE OR OTHER COMMERCIAL DISTRIBUTION
|
||||
- THIS LICENSE CANNOT BE USED FOR PRODUCTS WHICH DO NOT MAKE
|
||||
PROFIT BUT ARE STILL COMMERCIALLY RELEASED
|
||||
- THIS LICENSE CANNOT BE USED FOR COMMERCIAL SERVICES, WHERE THE
|
||||
EXECUTABLE CONTAINING FMOD IS NOT SOLD, BUT THE DATA IS.
|
||||
- WHEN USING FMOD, A CREDIT LINE IS REQUIRED IN EITHER DOCUMENTATION,
|
||||
OR 'ON SCREEN' FORMAT (IF POSSIBLE). IT SHOULD CONTAIN AT LEAST
|
||||
THE WORDS "FMOD" (OR "FMOD STUDIO" IF APPLICABLE) AND
|
||||
"FIRELIGHT TECHNOLOGIES."
|
||||
LOGOS ARE AVAILABLE FOR BOX OR MANUAL ART, BUT ARE NOT MANDATORY.
|
||||
AN EXAMPLE CREDIT COULD BE:
|
||||
|
||||
FMOD Sound System, copyright <20> Firelight Technologies Pty, Ltd., 1994-2016.
|
||||
OR
|
||||
FMOD Studio, copyright <20> Firelight Technologies Pty, Ltd., 1994-2016.
|
||||
OR
|
||||
Audio Engine supplied by FMOD by Firelight Technologies.
|
||||
|
||||
NOTE THIS IN ADVANCE, AS IT MUST BE DONE BEFORE SHIPPING YOUR
|
||||
PRODUCT WITH FMOD.
|
||||
|
||||
FMOD FREE FOR INDIES LICENSE (FMOD STUDIO ONLY)
|
||||
------------------------------------------------
|
||||
INDIE DEVELOPERS ARE CONSIDERED BY OUR LICENSING MODEL, DEVELOPERS THAT DEVELOP
|
||||
A TITLE FOR UNDER $100K USD (TYPICALLY CONSIDERED AN 'INDIE' TITLE) TOTAL
|
||||
BUDGET, MEANING YOUR TOTAL COSTS ARE LESS THAN $100K USD AT TIME OF SHIPPING,
|
||||
YOU CAN USE FMOD FOR FREE.
|
||||
|
||||
CONDITIONS/LIMITATIONS
|
||||
- PLEASE WRITE TO SALES@FMOD.COM WITH THE NAME OF YOUR TITLE, RELEASE DATE
|
||||
AND PLATFORMS SO WE CAN REGISTER YOU IN OUR SYSTEM.
|
||||
- THERE IS NO RESTRICTION ON PLATFORM, ANY PLATFORM COMBINATION MAY BE USED.
|
||||
- INCOME IS NOT RELEVANT TO THE BUDGET LEVEL, IT MUST BE EXPENSE RELATED.
|
||||
- WHEN USING FMOD, A CREDIT LINE IS REQUIRED IN EITHER DOCUMENTATION,
|
||||
OR 'ON SCREEN' FORMAT (IF POSSIBLE). IT SHOULD CONTAIN AT LEAST
|
||||
THE WORDS FMOD STUDIO AND FIRELIGHT TECHNOLOGIES.
|
||||
LOGOS ARE AVAILABLE FOR BOX OR MANUAL ART, BUT ARE NOT MANDATORY.
|
||||
AN EXAMPLE CREDIT COULD BE:
|
||||
|
||||
FMOD STUDIO, COPYRIGHT <20> FIRELIGHT TECHNOLOGIES PTY, LTD., 1994-2016.
|
||||
|
||||
COMMERCIAL USAGE (FMOD EX AND FMOD STUDIO)
|
||||
------------------------------------------
|
||||
IF THE PRODUCT THAT USES FMOD IS INTENDED TO GENERATE INCOME, VIA DIRECT SALES
|
||||
OR INDIRECT REVENUE (SUCH AS ADVERTISING, DONATIONS, CONTRACT FEE) THEN THE
|
||||
DEVELOPER MUST APPLY TO FIRELIGHT TECHNOLOGIES FOR A COMMERCIAL LICENSE (UNLESS
|
||||
THE USER QUALIFIES FOR AN FMOD STUDIO 'INDIE LICENSE').
|
||||
TO APPLY FOR THIS LICENSE WRITE TO SALES@FMOD.COM WITH THE RELEVANT DETAILS.
|
||||
|
||||
REDISTRIBUTION LICENSE (FMOD EX AND FMOD STUDIO)
|
||||
------------------------------------------------
|
||||
IF THE USER WISHES TO REDISTRIBUTE FMOD AS PART OF AN ENGINE OR TOOL SOLUTION,
|
||||
THE USER MUST APPLY TO FIRELIGHT TECHNOLOGIES TO BE GRANTED A 'REDISTRIBUTION
|
||||
LICENSE'.
|
||||
TO APPLY FOR THIS LICENSE WRITE TO SALES@FMOD.COM WITH THE RELEVANT DETAILS.
|
||||
|
||||
WARRANTY AND LIMITATION OF LIABILITY
|
||||
------------------------------------
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
FMOD Uses Ogg Vorbis codec. BSD license.
|
||||
-----------------------------------------
|
||||
Copyright (c) 2002, Xiph.org Foundation
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
For Android platform code.
|
||||
--------------------------
|
||||
Copyright (C) 2010 The Android Open Source Project
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,22 +0,0 @@
|
||||
crunch/crnlib uses the ZLIB license:
|
||||
http://opensource.org/licenses/Zlib
|
||||
|
||||
Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial LLC
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
@@ -1,13 +0,0 @@
|
||||
Copyright (c) 2015 Harm Hanemaaijer <fgenfb@yahoo.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
25
AssetStudioGUI/OpenTK.dll.config
Normal file
25
AssetStudioGUI/OpenTK.dll.config
Normal file
@@ -0,0 +1,25 @@
|
||||
<configuration>
|
||||
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
|
||||
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
|
||||
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
|
||||
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
|
||||
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
|
||||
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
|
||||
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
|
||||
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
|
||||
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
|
||||
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
||||
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
||||
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
||||
<dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
||||
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
||||
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
|
||||
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
|
||||
<!-- XQuartz compatibility (X11 on Mac) -->
|
||||
<dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
|
||||
<dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
|
||||
<dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
|
||||
<dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
|
||||
<dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
|
||||
<dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
|
||||
</configuration>
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
@@ -8,7 +9,7 @@ namespace AssetStudioGUI
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// 应用程序的主入口点。
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
|
||||
@@ -2,35 +2,35 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AssetStudioGUI")]
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("AssetStudioGUI Mod by VaDiM")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AssetStudioGUI")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyCopyright("Copyright © Perfare 2018-2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("05c04c20-dd89-4895-9f06-33d5cfbfe925")]
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("52b196fb-4c8a-499b-b877-1a0eb4f33ec0")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyVersion("0.14.38.5")]
|
||||
[assembly: AssemblyFileVersion("0.14.38.5")]
|
||||
|
||||
3
AssetStudioGUI/Properties/Resources.Designer.cs
generated
3
AssetStudioGUI/Properties/Resources.Designer.cs
generated
@@ -19,7 +19,7 @@ namespace AssetStudioGUI.Properties {
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
@@ -48,6 +48,7 @@ namespace AssetStudioGUI.Properties {
|
||||
|
||||
/// <summary>
|
||||
/// 重写当前线程的 CurrentUICulture 属性
|
||||
/// 重写当前线程的 CurrentUICulture 属性。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
|
||||
112
AssetStudioGUI/Properties/Settings.Designer.cs
generated
112
AssetStudioGUI/Properties/Settings.Designer.cs
generated
@@ -1,10 +1,10 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
// Этот код создан программой.
|
||||
// Исполняемая версия:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
|
||||
// повторной генерации кода.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace AssetStudioGUI.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.6.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
@@ -119,18 +119,6 @@ namespace AssetStudioGUI.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool displayOriginalName {
|
||||
get {
|
||||
return ((bool)(this["displayOriginalName"]));
|
||||
}
|
||||
set {
|
||||
this["displayOriginalName"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
@@ -158,36 +146,36 @@ namespace AssetStudioGUI.Properties {
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool allFrames {
|
||||
public bool exportAllNodes {
|
||||
get {
|
||||
return ((bool)(this["allFrames"]));
|
||||
return ((bool)(this["exportAllNodes"]));
|
||||
}
|
||||
set {
|
||||
this["allFrames"] = value;
|
||||
this["exportAllNodes"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool allBones {
|
||||
public bool exportSkins {
|
||||
get {
|
||||
return ((bool)(this["allBones"]));
|
||||
return ((bool)(this["exportSkins"]));
|
||||
}
|
||||
set {
|
||||
this["allBones"] = value;
|
||||
this["exportSkins"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool skins {
|
||||
public bool exportAnimations {
|
||||
get {
|
||||
return ((bool)(this["skins"]));
|
||||
return ((bool)(this["exportAnimations"]));
|
||||
}
|
||||
set {
|
||||
this["skins"] = value;
|
||||
this["exportAnimations"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,18 +191,6 @@ namespace AssetStudioGUI.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool flatInbetween {
|
||||
get {
|
||||
return ((bool)(this["flatInbetween"]));
|
||||
}
|
||||
set {
|
||||
this["flatInbetween"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("3")]
|
||||
@@ -250,5 +226,65 @@ namespace AssetStudioGUI.Properties {
|
||||
this["scaleFactor"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool exportBlendShape {
|
||||
get {
|
||||
return ((bool)(this["exportBlendShape"]));
|
||||
}
|
||||
set {
|
||||
this["exportBlendShape"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool castToBone {
|
||||
get {
|
||||
return ((bool)(this["castToBone"]));
|
||||
}
|
||||
set {
|
||||
this["castToBone"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool restoreExtensionName {
|
||||
get {
|
||||
return ((bool)(this["restoreExtensionName"]));
|
||||
}
|
||||
set {
|
||||
this["restoreExtensionName"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool pathIDAsImageName {
|
||||
get {
|
||||
return ((bool)(this["pathIDAsImageName"]));
|
||||
}
|
||||
set {
|
||||
this["pathIDAsImageName"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool pathIDAsDumpName {
|
||||
get {
|
||||
return ((bool)(this["pathIDAsDumpName"]));
|
||||
}
|
||||
set {
|
||||
this["pathIDAsDumpName"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,30 +26,24 @@
|
||||
<Setting Name="convertType" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">PNG</Value>
|
||||
</Setting>
|
||||
<Setting Name="displayOriginalName" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="eulerFilter" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="filterPrecision" Type="System.Decimal" Scope="User">
|
||||
<Value Profile="(Default)">0.25</Value>
|
||||
</Setting>
|
||||
<Setting Name="allFrames" Type="System.Boolean" Scope="User">
|
||||
<Setting Name="exportAllNodes" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="allBones" Type="System.Boolean" Scope="User">
|
||||
<Setting Name="exportSkins" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="skins" Type="System.Boolean" Scope="User">
|
||||
<Setting Name="exportAnimations" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="boneSize" Type="System.Decimal" Scope="User">
|
||||
<Value Profile="(Default)">10</Value>
|
||||
</Setting>
|
||||
<Setting Name="flatInbetween" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="fbxVersion" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">3</Value>
|
||||
</Setting>
|
||||
@@ -59,5 +53,20 @@
|
||||
<Setting Name="scaleFactor" Type="System.Decimal" Scope="User">
|
||||
<Value Profile="(Default)">1</Value>
|
||||
</Setting>
|
||||
<Setting Name="exportBlendShape" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="castToBone" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="restoreExtensionName" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="pathIDAsImageName" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="pathIDAsDumpName" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 3.9 KiB |
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using AssetStudio;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
@@ -6,18 +7,25 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using AssetStudio;
|
||||
using static AssetStudioGUI.Exporter;
|
||||
using Object = AssetStudio.Object;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal enum ExportType
|
||||
{
|
||||
Convert,
|
||||
Raw,
|
||||
Dump
|
||||
}
|
||||
|
||||
internal static class Studio
|
||||
{
|
||||
public static AssetsManager assetsManager = new AssetsManager();
|
||||
public static ScriptDumper scriptDumper = new ScriptDumper();
|
||||
public static List<AssetItem> exportableAssets = new List<AssetItem>();
|
||||
public static List<AssetItem> visibleAssets = new List<AssetItem>();
|
||||
internal static Action<string> StatusStripUpdate = x => { };
|
||||
|
||||
public static void ExtractFile(string[] fileNames)
|
||||
{
|
||||
@@ -38,16 +46,16 @@ namespace AssetStudioGUI
|
||||
Progress.Report(i + 1, fileNames.Length);
|
||||
}
|
||||
|
||||
Logger.Info($"Finished extracting {extractedCount} files.");
|
||||
StatusStripUpdate($"Finished extracting {extractedCount} files.");
|
||||
});
|
||||
}
|
||||
|
||||
private static int ExtractBundleFile(string bundleFileName, EndianBinaryReader reader)
|
||||
{
|
||||
Logger.Info($"Decompressing {Path.GetFileName(bundleFileName)} ...");
|
||||
StatusStripUpdate($"Decompressing {Path.GetFileName(bundleFileName)} ...");
|
||||
var bundleFile = new BundleFile(reader, bundleFileName);
|
||||
reader.Dispose();
|
||||
if (bundleFile.fileList.Count > 0)
|
||||
if (bundleFile.fileList.Length > 0)
|
||||
{
|
||||
var extractPath = bundleFileName + "_unpacked\\";
|
||||
return ExtractStreamFile(extractPath, bundleFile.fileList);
|
||||
@@ -57,10 +65,10 @@ namespace AssetStudioGUI
|
||||
|
||||
private static int ExtractWebDataFile(string webFileName, EndianBinaryReader reader)
|
||||
{
|
||||
Logger.Info($"Decompressing {Path.GetFileName(webFileName)} ...");
|
||||
StatusStripUpdate($"Decompressing {Path.GetFileName(webFileName)} ...");
|
||||
var webFile = new WebFile(reader);
|
||||
reader.Dispose();
|
||||
if (webFile.fileList.Count > 0)
|
||||
if (webFile.fileList.Length > 0)
|
||||
{
|
||||
var extractPath = webFileName + "_unpacked\\";
|
||||
return ExtractStreamFile(extractPath, webFile.fileList);
|
||||
@@ -68,7 +76,7 @@ namespace AssetStudioGUI
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int ExtractStreamFile(string extractPath, List<StreamFile> fileList)
|
||||
private static int ExtractStreamFile(string extractPath,StreamFile[] fileList)
|
||||
{
|
||||
int extractedCount = 0;
|
||||
foreach (var file in fileList)
|
||||
@@ -88,24 +96,25 @@ namespace AssetStudioGUI
|
||||
return extractedCount;
|
||||
}
|
||||
|
||||
public static void BuildAssetList(Dictionary<Object, AssetItem> tempDic, bool displayAll, bool displayOriginalName, out string productName)
|
||||
public static (string, List<TreeNode>) BuildAssetData()
|
||||
{
|
||||
Logger.Info("Building asset list...");
|
||||
StatusStripUpdate("Building asset list...");
|
||||
|
||||
productName = string.Empty;
|
||||
var assetsNameHash = new HashSet<string>();
|
||||
var progressCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
||||
int j = 0;
|
||||
string productName = null;
|
||||
var assetsNameHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
||||
var objectAssetItemDic = new Dictionary<Object, AssetItem>(objectCount);
|
||||
int i = 0;
|
||||
Progress.Reset();
|
||||
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||
{
|
||||
var tempExportableAssets = new List<AssetItem>();
|
||||
AssetBundle ab = null;
|
||||
foreach (var asset in assetsFile.Objects.Values)
|
||||
Dictionary<long, string> containers = null;
|
||||
foreach (var asset in assetsFile.Objects)
|
||||
{
|
||||
var assetItem = new AssetItem(asset);
|
||||
tempDic.Add(asset, assetItem);
|
||||
assetItem.UniqueID = " #" + j;
|
||||
objectAssetItemDic.Add(asset, assetItem);
|
||||
assetItem.UniqueID = " #" + i;
|
||||
var exportable = false;
|
||||
switch (asset)
|
||||
{
|
||||
@@ -165,20 +174,12 @@ namespace AssetStudioGUI
|
||||
productName = m_PlayerSettings.productName;
|
||||
break;
|
||||
case AssetBundle m_AssetBundle:
|
||||
ab = m_AssetBundle;
|
||||
assetItem.Text = ab.m_Name;
|
||||
break;
|
||||
case SpriteAtlas m_SpriteAtlas:
|
||||
foreach (var m_PackedSprite in m_SpriteAtlas.m_PackedSprites)
|
||||
containers = new Dictionary<long, string>();
|
||||
foreach (var m_Container in m_AssetBundle.m_Container)
|
||||
{
|
||||
if (m_PackedSprite.TryGet(out var m_Sprite))
|
||||
{
|
||||
if (m_Sprite.m_SpriteAtlas.IsNull())
|
||||
{
|
||||
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
||||
}
|
||||
}
|
||||
containers[m_Container.Value.asset.m_PathID] = m_Container.Key;
|
||||
}
|
||||
assetItem.Text = m_AssetBundle.m_Name;
|
||||
break;
|
||||
case NamedObject m_NamedObject:
|
||||
assetItem.Text = m_NamedObject.m_Name;
|
||||
@@ -188,68 +189,52 @@ namespace AssetStudioGUI
|
||||
{
|
||||
assetItem.Text = assetItem.TypeString + assetItem.UniqueID;
|
||||
}
|
||||
assetItem.SubItems.AddRange(new[] { assetItem.TypeString, assetItem.FullSize.ToString() });
|
||||
//处理同名文件
|
||||
if (!assetsNameHash.Add((assetItem.TypeString + assetItem.Text).ToUpper()))
|
||||
if (!assetsNameHash.Add(assetItem.TypeString + assetItem.Text))
|
||||
{
|
||||
assetItem.Text += assetItem.UniqueID;
|
||||
}
|
||||
//处理非法文件名
|
||||
assetItem.Text = FixFileName(assetItem.Text);
|
||||
if (displayAll)
|
||||
{
|
||||
exportable = true;
|
||||
}
|
||||
if (exportable)
|
||||
if (Properties.Settings.Default.displayAll || exportable)
|
||||
{
|
||||
tempExportableAssets.Add(assetItem);
|
||||
}
|
||||
|
||||
Progress.Report(++j, progressCount);
|
||||
Progress.Report(++i, objectCount);
|
||||
}
|
||||
if (displayOriginalName && ab != null)
|
||||
foreach (var item in tempExportableAssets)
|
||||
{
|
||||
foreach (var item in tempExportableAssets)
|
||||
if (containers != null)
|
||||
{
|
||||
var originalPath = ab.m_Container.FirstOrDefault(y => y.Value.asset.m_PathID == item.Asset.m_PathID).Key;
|
||||
if (!string.IsNullOrEmpty(originalPath))
|
||||
if (containers.TryGetValue(item.Asset.m_PathID, out var container))
|
||||
{
|
||||
var extension = Path.GetExtension(originalPath);
|
||||
if (!string.IsNullOrEmpty(extension) && item.Type == ClassIDType.TextAsset)
|
||||
if (!string.IsNullOrEmpty(container))
|
||||
{
|
||||
item.Extension = extension;
|
||||
}
|
||||
|
||||
item.Text = Path.GetDirectoryName(originalPath) + "\\" + Path.GetFileNameWithoutExtension(originalPath);
|
||||
if (!assetsNameHash.Add((item.TypeString + item.Text).ToUpper()))
|
||||
{
|
||||
item.Text += item.UniqueID;
|
||||
item.Container = container;
|
||||
}
|
||||
}
|
||||
}
|
||||
item.SetSubItems();
|
||||
}
|
||||
exportableAssets.AddRange(tempExportableAssets);
|
||||
tempExportableAssets.Clear();
|
||||
containers?.Clear();
|
||||
}
|
||||
|
||||
visibleAssets = exportableAssets;
|
||||
assetsNameHash.Clear();
|
||||
}
|
||||
|
||||
public static List<TreeNode> BuildTreeStructure(Dictionary<Object, AssetItem> tempDic)
|
||||
{
|
||||
Logger.Info("Building tree structure...");
|
||||
StatusStripUpdate("Building tree structure...");
|
||||
|
||||
var treeNodeCollection = new List<TreeNode>();
|
||||
var treeNodeDictionary = new Dictionary<GameObject, GameObjectTreeNode>();
|
||||
var progressCount = assetsManager.assetsFileList.Count;
|
||||
int i = 0;
|
||||
var assetsFileCount = assetsManager.assetsFileList.Count;
|
||||
int j = 0;
|
||||
Progress.Reset();
|
||||
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||
{
|
||||
var fileNode = new GameObjectTreeNode(assetsFile.fileName); //RootNode
|
||||
|
||||
foreach (var obj in assetsFile.Objects.Values)
|
||||
foreach (var obj in assetsFile.Objects)
|
||||
{
|
||||
if (obj is GameObject m_GameObject)
|
||||
{
|
||||
@@ -259,24 +244,26 @@ namespace AssetStudioGUI
|
||||
treeNodeDictionary.Add(m_GameObject, currentNode);
|
||||
}
|
||||
|
||||
if (m_GameObject.m_MeshFilter != null)
|
||||
foreach (var pptr in m_GameObject.m_Components)
|
||||
{
|
||||
if (m_GameObject.m_MeshFilter.m_Mesh.TryGet(out var m_Mesh))
|
||||
if (pptr.TryGet(out var m_Component))
|
||||
{
|
||||
var item = tempDic[m_Mesh];
|
||||
item.TreeNode = currentNode;
|
||||
objectAssetItemDic[m_Component].TreeNode = currentNode;
|
||||
if (m_Component is MeshFilter m_MeshFilter)
|
||||
{
|
||||
if (m_MeshFilter.m_Mesh.TryGet(out var m_Mesh))
|
||||
{
|
||||
objectAssetItemDic[m_Mesh].TreeNode = currentNode;
|
||||
}
|
||||
}
|
||||
else if (m_Component is SkinnedMeshRenderer m_SkinnedMeshRenderer)
|
||||
{
|
||||
if (m_SkinnedMeshRenderer.m_Mesh.TryGet(out var m_Mesh))
|
||||
{
|
||||
objectAssetItemDic[m_Mesh].TreeNode = currentNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
tempDic[m_GameObject.m_MeshFilter].TreeNode = currentNode;
|
||||
}
|
||||
|
||||
if (m_GameObject.m_SkinnedMeshRenderer != null)
|
||||
{
|
||||
if (m_GameObject.m_SkinnedMeshRenderer.m_Mesh.TryGet(out var m_Mesh))
|
||||
{
|
||||
var item = tempDic[m_Mesh];
|
||||
item.TreeNode = currentNode;
|
||||
}
|
||||
tempDic[m_GameObject.m_SkinnedMeshRenderer].TreeNode = currentNode;
|
||||
}
|
||||
|
||||
var parentNode = fileNode;
|
||||
@@ -305,12 +292,13 @@ namespace AssetStudioGUI
|
||||
treeNodeCollection.Add(fileNode);
|
||||
}
|
||||
|
||||
Progress.Report(++i, progressCount);
|
||||
Progress.Report(++j, assetsFileCount);
|
||||
}
|
||||
|
||||
treeNodeDictionary.Clear();
|
||||
|
||||
return treeNodeCollection;
|
||||
objectAssetItemDic.Clear();
|
||||
|
||||
return (productName, treeNodeCollection);
|
||||
}
|
||||
|
||||
public static Dictionary<string, SortedDictionary<int, TypeTreeItem>> BuildClassStructure()
|
||||
@@ -355,7 +343,7 @@ namespace AssetStudioGUI
|
||||
return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
||||
}
|
||||
|
||||
public static void ExportAssets(string savePath, List<AssetItem> toExportAssets, int assetGroupSelectedIndex, bool openAfterExport)
|
||||
public static void ExportAssets(string savePath, List<AssetItem> toExportAssets, ExportType exportType)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
@@ -367,95 +355,53 @@ namespace AssetStudioGUI
|
||||
Progress.Reset();
|
||||
foreach (var asset in toExportAssets)
|
||||
{
|
||||
var exportpath = savePath + "\\";
|
||||
if (assetGroupSelectedIndex == 1)
|
||||
string exportPath;
|
||||
switch (Properties.Settings.Default.assetGroupOption)
|
||||
{
|
||||
exportpath += Path.GetFileNameWithoutExtension(asset.SourceFile.fullName) + "_export\\";
|
||||
case 0: //type name
|
||||
exportPath = Path.Combine(savePath, asset.TypeString);
|
||||
break;
|
||||
case 1: //container path
|
||||
if (!string.IsNullOrEmpty(asset.Container))
|
||||
{
|
||||
exportPath = Path.Combine(savePath, Path.GetDirectoryName(asset.Container));
|
||||
}
|
||||
else
|
||||
{
|
||||
exportPath = savePath;
|
||||
}
|
||||
break;
|
||||
case 2: //source file
|
||||
exportPath = Path.Combine(savePath, asset.SourceFile.fullName + "_export");
|
||||
break;
|
||||
default:
|
||||
exportPath = savePath;
|
||||
break;
|
||||
}
|
||||
else if (assetGroupSelectedIndex == 0)
|
||||
{
|
||||
exportpath = savePath + "\\" + asset.TypeString + "\\";
|
||||
}
|
||||
Logger.Info($"Exporting {asset.TypeString}: {asset.Text}");
|
||||
exportPath += Path.DirectorySeparatorChar;
|
||||
StatusStripUpdate($"Exporting {asset.TypeString}: {asset.Text}");
|
||||
try
|
||||
{
|
||||
switch (asset.Type)
|
||||
switch (exportType)
|
||||
{
|
||||
case ClassIDType.Texture2D:
|
||||
if (ExportTexture2D(asset, exportpath))
|
||||
case ExportType.Raw:
|
||||
if (ExportRawFile(asset, exportPath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.AudioClip:
|
||||
if (ExportAudioClip(asset, exportpath))
|
||||
case ExportType.Dump:
|
||||
if (ExportDumpFile(asset, exportPath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
if (ExportShader(asset, exportpath))
|
||||
case ExportType.Convert:
|
||||
if (ExportConvertFile(asset, exportPath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.TextAsset:
|
||||
if (ExportTextAsset(asset, exportpath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.MonoBehaviour:
|
||||
if (ExportMonoBehaviour(asset, exportpath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Font:
|
||||
if (ExportFont(asset, exportpath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Mesh:
|
||||
if (ExportMesh(asset, exportpath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.VideoClip:
|
||||
if (ExportVideoClip(asset, exportpath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.MovieTexture:
|
||||
if (ExportMovieTexture(asset, exportpath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Sprite:
|
||||
if (ExportSprite(asset, exportpath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
if (ExportAnimator(asset, exportpath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.AnimationClip:
|
||||
break;
|
||||
default:
|
||||
if (ExportRawFile(asset, exportpath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -473,16 +419,16 @@ namespace AssetStudioGUI
|
||||
statusText += $" {toExportCount - exportedCount} assets skipped (not extractable or files already exist)";
|
||||
}
|
||||
|
||||
Logger.Info(statusText);
|
||||
StatusStripUpdate(statusText);
|
||||
|
||||
if (openAfterExport && exportedCount > 0)
|
||||
if (Properties.Settings.Default.openAfterExport && exportedCount > 0)
|
||||
{
|
||||
Process.Start(savePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void ExportSplitObjects(string savePath, TreeNodeCollection nodes, bool openAfterExport)
|
||||
public static void ExportSplitObjects(string savePath, TreeNodeCollection nodes)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
@@ -521,7 +467,7 @@ namespace AssetStudioGUI
|
||||
}
|
||||
Directory.CreateDirectory(targetPath);
|
||||
//导出FBX
|
||||
Logger.Info($"Exporting {filename}.fbx");
|
||||
StatusStripUpdate($"Exporting {filename}.fbx");
|
||||
try
|
||||
{
|
||||
ExportGameObject(j.gameObject, targetPath);
|
||||
@@ -532,14 +478,14 @@ namespace AssetStudioGUI
|
||||
}
|
||||
|
||||
Progress.Report(++k, count);
|
||||
Logger.Info($"Finished exporting {filename}.fbx");
|
||||
StatusStripUpdate($"Finished exporting {filename}.fbx");
|
||||
}
|
||||
}
|
||||
if (openAfterExport)
|
||||
if (Properties.Settings.Default.openAfterExport)
|
||||
{
|
||||
Process.Start(savePath);
|
||||
}
|
||||
Logger.Info("Finished");
|
||||
StatusStripUpdate("Finished");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -552,31 +498,31 @@ namespace AssetStudioGUI
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExportAnimatorWithAnimationClip(AssetItem animator, List<AssetItem> animationList, string exportPath, bool openAfterExport)
|
||||
public static void ExportAnimatorWithAnimationClip(AssetItem animator, List<AssetItem> animationList, string exportPath)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
Progress.Reset();
|
||||
Logger.Info($"Exporting {animator.Text}");
|
||||
StatusStripUpdate($"Exporting {animator.Text}");
|
||||
try
|
||||
{
|
||||
ExportAnimator(animator, exportPath, animationList);
|
||||
if (openAfterExport)
|
||||
if (Properties.Settings.Default.openAfterExport)
|
||||
{
|
||||
Process.Start(exportPath);
|
||||
}
|
||||
Progress.Report(1, 1);
|
||||
Logger.Info($"Finished exporting {animator.Text}");
|
||||
StatusStripUpdate($"Finished exporting {animator.Text}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Export Animator:{animator.Text} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||
Logger.Info("Error in export");
|
||||
StatusStripUpdate("Error in export");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void ExportObjectsWithAnimationClip(string exportPath, TreeNodeCollection nodes, bool openAfterExport, List<AssetItem> animationList = null)
|
||||
public static void ExportObjectsWithAnimationClip(string exportPath, TreeNodeCollection nodes, List<AssetItem> animationList = null)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
@@ -589,33 +535,58 @@ namespace AssetStudioGUI
|
||||
Progress.Reset();
|
||||
foreach (var gameObject in gameObjects)
|
||||
{
|
||||
Logger.Info($"Exporting {gameObject.m_Name}");
|
||||
StatusStripUpdate($"Exporting {gameObject.m_Name}");
|
||||
try
|
||||
{
|
||||
ExportGameObject(gameObject, exportPath, animationList);
|
||||
Logger.Info($"Finished exporting {gameObject.m_Name}");
|
||||
StatusStripUpdate($"Finished exporting {gameObject.m_Name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Export GameObject:{gameObject.m_Name} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||
Logger.Info("Error in export");
|
||||
StatusStripUpdate("Error in export");
|
||||
}
|
||||
|
||||
Progress.Report(++i, count);
|
||||
}
|
||||
if (openAfterExport)
|
||||
if (Properties.Settings.Default.openAfterExport)
|
||||
{
|
||||
Process.Start(exportPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info("No Object can be exported.");
|
||||
StatusStripUpdate("No Object can be exported.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void GetSelectedParentNode(TreeNodeCollection nodes, List<GameObject> gameObjects)
|
||||
public static void ExportObjectsMergeWithAnimationClip(string exportPath, List<GameObject> gameObjects, List<AssetItem> animationList = null)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
var name = Path.GetFileName(exportPath);
|
||||
Progress.Reset();
|
||||
StatusStripUpdate($"Exporting {name}");
|
||||
try
|
||||
{
|
||||
ExportGameObjectMerge(gameObjects, exportPath, animationList);
|
||||
Progress.Report(1, 1);
|
||||
StatusStripUpdate($"Finished exporting {name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Export Model:{name} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||
StatusStripUpdate("Error in export");
|
||||
}
|
||||
if (Properties.Settings.Default.openAfterExport)
|
||||
{
|
||||
Process.Start(Path.GetDirectoryName(exportPath));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void GetSelectedParentNode(TreeNodeCollection nodes, List<GameObject> gameObjects)
|
||||
{
|
||||
foreach (GameObjectTreeNode i in nodes)
|
||||
{
|
||||
|
||||
5963
AssetStudioGUI/TGASharpLib.cs
Normal file
5963
AssetStudioGUI/TGASharpLib.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,69 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||
<section name="AssetStudioGUI.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<userSettings>
|
||||
<AssetStudioGUI.Properties.Settings>
|
||||
<setting name="displayAll" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="enablePreview" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="displayInfo" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="openAfterExport" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="assetGroupOption" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="convertTexture" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="convertAudio" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="convertType" serializeAs="String">
|
||||
<value>PNG</value>
|
||||
</setting>
|
||||
<setting name="displayOriginalName" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="eulerFilter" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="filterPrecision" serializeAs="String">
|
||||
<value>0.25</value>
|
||||
</setting>
|
||||
<setting name="allFrames" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="allBones" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="skins" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="boneSize" serializeAs="String">
|
||||
<value>10</value>
|
||||
</setting>
|
||||
<setting name="flatInbetween" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="fbxVersion" serializeAs="String">
|
||||
<value>3</value>
|
||||
</setting>
|
||||
<setting name="fbxFormat" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="scaleFactor" serializeAs="String">
|
||||
<value>1</value>
|
||||
</setting>
|
||||
</AssetStudioGUI.Properties.Settings>
|
||||
</userSettings>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||
<section name="AssetStudioGUI.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
<userSettings>
|
||||
<AssetStudioGUI.Properties.Settings>
|
||||
<setting name="displayAll" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="enablePreview" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="displayInfo" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="openAfterExport" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="assetGroupOption" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="convertTexture" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="convertAudio" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="convertType" serializeAs="String">
|
||||
<value>PNG</value>
|
||||
</setting>
|
||||
<setting name="eulerFilter" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="filterPrecision" serializeAs="String">
|
||||
<value>0.25</value>
|
||||
</setting>
|
||||
<setting name="exportAllNodes" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="exportSkins" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="exportAnimations" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="boneSize" serializeAs="String">
|
||||
<value>10</value>
|
||||
</setting>
|
||||
<setting name="fbxVersion" serializeAs="String">
|
||||
<value>3</value>
|
||||
</setting>
|
||||
<setting name="fbxFormat" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="scaleFactor" serializeAs="String">
|
||||
<value>1</value>
|
||||
</setting>
|
||||
<setting name="exportBlendShape" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="castToBone" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="restoreExtensionName" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="pathIDAsImageName" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="pathIDAsDumpName" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
</AssetStudioGUI.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
||||
5
AssetStudioGUI/packages.config
Normal file
5
AssetStudioGUI/packages.config
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="OpenTK" version="3.1.0" targetFramework="net472" />
|
||||
<package id="OpenTK.GLControl" version="3.1.0" targetFramework="net472" />
|
||||
</packages>
|
||||
@@ -4,13 +4,14 @@
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}</ProjectGuid>
|
||||
<ProjectGuid>{80AEC261-21EE-4E4F-A93B-7A744DC84888}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AssetStudio</RootNamespace>
|
||||
<RootNamespace>AssetStudioUtility</RootNamespace>
|
||||
<AssemblyName>AssetStudioUtility</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -18,6 +19,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
@@ -25,8 +27,9 @@
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugType>none</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
@@ -36,6 +39,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
@@ -45,6 +49,7 @@
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
@@ -59,6 +64,7 @@
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -73,16 +79,21 @@
|
||||
<Compile Include="ShaderConverter.cs" />
|
||||
<Compile Include="SpriteHelper.cs" />
|
||||
<Compile Include="Texture2DConverter.cs" />
|
||||
<Compile Include="Texture2DExtensions.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AssetStudioFBX\AssetStudioFBX.vcxproj">
|
||||
<Project>{4f8ef5ef-732b-49cf-9eb3-b23e19ae6267}</Project>
|
||||
<Project>{b82dd1ba-4eec-4f29-a686-03d7f0df39b8}</Project>
|
||||
<Name>AssetStudioFBX</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
|
||||
<Project>{af56b63c-1764-41b7-9e60-8d485422ac3b}</Project>
|
||||
<Project>{7662f8c2-7bfd-442e-a948-a43b4f7eb06e}</Project>
|
||||
<Name>AssetStudio</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Texture2DDecoder\Texture2DDecoder.vcxproj">
|
||||
<Project>{bec7b5e6-0a7b-4824-97a7-eea04d9eba29}</Project>
|
||||
<Name>Texture2DDecoder</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -15,7 +15,7 @@ namespace AssetStudio
|
||||
|
||||
public byte[] ConvertToWav()
|
||||
{
|
||||
var m_AudioData = m_AudioClip.m_AudioData.Value;
|
||||
var m_AudioData = m_AudioClip.m_AudioData.GetData();
|
||||
if (m_AudioData == null || m_AudioData.Length == 0)
|
||||
return null;
|
||||
var exinfo = new FMOD.CREATESOUNDEXINFO();
|
||||
@@ -116,24 +116,24 @@ namespace AssetStudio
|
||||
case AudioCompressionFormat.MP3:
|
||||
return ".fsb";
|
||||
case AudioCompressionFormat.VAG:
|
||||
return ".vag";
|
||||
return ".fsb";
|
||||
case AudioCompressionFormat.HEVAG:
|
||||
return ".vag";
|
||||
return ".fsb";
|
||||
case AudioCompressionFormat.XMA:
|
||||
return ".wav";
|
||||
return ".fsb";
|
||||
case AudioCompressionFormat.AAC:
|
||||
return ".m4a";
|
||||
case AudioCompressionFormat.GCADPCM:
|
||||
return ".fsb";
|
||||
case AudioCompressionFormat.ATRAC9:
|
||||
return ".at9";
|
||||
return ".fsb";
|
||||
}
|
||||
}
|
||||
|
||||
return ".AudioClip";
|
||||
}
|
||||
|
||||
public bool IsFMODSupport
|
||||
public bool IsSupport
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -147,7 +147,6 @@ namespace AssetStudio
|
||||
case AudioType.S3M:
|
||||
case AudioType.XM:
|
||||
case AudioType.XMA:
|
||||
case AudioType.VAG:
|
||||
case AudioType.AUDIOQUEUE:
|
||||
return true;
|
||||
default:
|
||||
@@ -162,11 +161,7 @@ namespace AssetStudio
|
||||
case AudioCompressionFormat.Vorbis:
|
||||
case AudioCompressionFormat.ADPCM:
|
||||
case AudioCompressionFormat.MP3:
|
||||
case AudioCompressionFormat.VAG:
|
||||
case AudioCompressionFormat.HEVAG:
|
||||
case AudioCompressionFormat.XMA:
|
||||
case AudioCompressionFormat.GCADPCM:
|
||||
case AudioCompressionFormat.ATRAC9:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -21,47 +21,74 @@ namespace AssetStudio
|
||||
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
|
||||
private Dictionary<Texture2D, string> textureNameDictionary = new Dictionary<Texture2D, string>();
|
||||
private Dictionary<Transform, ImportedFrame> transformDictionary = new Dictionary<Transform, ImportedFrame>();
|
||||
Dictionary<uint, string> morphChannelNames = new Dictionary<uint, string>();
|
||||
|
||||
public ModelConverter(GameObject m_GameObject)
|
||||
public ModelConverter(GameObject m_GameObject, AnimationClip[] animationList = null)
|
||||
{
|
||||
if (m_GameObject.m_Animator != null)
|
||||
{
|
||||
InitWithAnimator(m_GameObject.m_Animator);
|
||||
CollectAnimationClip(m_GameObject.m_Animator);
|
||||
if (animationList == null)
|
||||
{
|
||||
CollectAnimationClip(m_GameObject.m_Animator);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InitWithGameObject(m_GameObject);
|
||||
}
|
||||
if (animationList != null)
|
||||
{
|
||||
foreach (var animationClip in animationList)
|
||||
{
|
||||
animationClipHashSet.Add(animationClip);
|
||||
}
|
||||
}
|
||||
ConvertAnimations();
|
||||
}
|
||||
|
||||
public ModelConverter(GameObject m_GameObject, AnimationClip[] animationList)
|
||||
public ModelConverter(string rootName, List<GameObject> m_GameObjects, AnimationClip[] animationList = null)
|
||||
{
|
||||
if (m_GameObject.m_Animator != null)
|
||||
RootFrame = CreateFrame(rootName, Vector3.Zero, new Quaternion(0, 0, 0, 0), Vector3.One);
|
||||
foreach (var m_GameObject in m_GameObjects)
|
||||
{
|
||||
InitWithAnimator(m_GameObject.m_Animator);
|
||||
if (m_GameObject.m_Animator != null && animationList == null)
|
||||
{
|
||||
CollectAnimationClip(m_GameObject.m_Animator);
|
||||
}
|
||||
|
||||
var m_Transform = m_GameObject.m_Transform;
|
||||
ConvertTransforms(m_Transform, RootFrame);
|
||||
CreateBonePathHash(m_Transform);
|
||||
}
|
||||
foreach (var m_GameObject in m_GameObjects)
|
||||
{
|
||||
var m_Transform = m_GameObject.m_Transform;
|
||||
ConvertMeshRenderer(m_Transform);
|
||||
}
|
||||
if (animationList != null)
|
||||
{
|
||||
foreach (var animationClip in animationList)
|
||||
{
|
||||
animationClipHashSet.Add(animationClip);
|
||||
}
|
||||
}
|
||||
ConvertAnimations();
|
||||
}
|
||||
|
||||
public ModelConverter(Animator m_Animator, AnimationClip[] animationList = null)
|
||||
{
|
||||
InitWithAnimator(m_Animator);
|
||||
if (animationList == null)
|
||||
{
|
||||
CollectAnimationClip(m_Animator);
|
||||
}
|
||||
else
|
||||
InitWithGameObject(m_GameObject);
|
||||
foreach (var animationClip in animationList)
|
||||
{
|
||||
animationClipHashSet.Add(animationClip);
|
||||
}
|
||||
ConvertAnimations();
|
||||
}
|
||||
|
||||
public ModelConverter(Animator m_Animator)
|
||||
{
|
||||
InitWithAnimator(m_Animator);
|
||||
CollectAnimationClip(m_Animator);
|
||||
ConvertAnimations();
|
||||
}
|
||||
|
||||
public ModelConverter(Animator m_Animator, AnimationClip[] animationList)
|
||||
{
|
||||
InitWithAnimator(m_Animator);
|
||||
foreach (var animationClip in animationList)
|
||||
{
|
||||
animationClipHashSet.Add(animationClip);
|
||||
foreach (var animationClip in animationList)
|
||||
{
|
||||
animationClipHashSet.Add(animationClip);
|
||||
}
|
||||
}
|
||||
ConvertAnimations();
|
||||
}
|
||||
@@ -256,6 +283,16 @@ namespace AssetStudio
|
||||
}
|
||||
combine = true;
|
||||
}
|
||||
|
||||
iMesh.hasNormal = mesh.m_Normals?.Length > 0;
|
||||
iMesh.hasUV = new bool[8];
|
||||
for (int uv = 0; uv < 8; uv++)
|
||||
{
|
||||
iMesh.hasUV[uv] = mesh.GetUV(uv)?.Length > 0;
|
||||
}
|
||||
iMesh.hasTangent = mesh.m_Tangents != null && mesh.m_Tangents.Length == mesh.m_VertexCount * 4;
|
||||
iMesh.hasColor = mesh.m_Colors?.Length > 0;
|
||||
|
||||
int firstFace = 0;
|
||||
for (int i = 0; i < mesh.m_SubMeshes.Length; i++)
|
||||
{
|
||||
@@ -278,19 +315,18 @@ namespace AssetStudio
|
||||
ImportedMaterial iMat = ConvertMaterial(mat);
|
||||
iSubmesh.Material = iMat.Name;
|
||||
iSubmesh.VertexList = new List<ImportedVertex>((int)submesh.vertexCount);
|
||||
var vertexColours = mesh.m_Colors != null && (mesh.m_Colors.Length == mesh.m_VertexCount * 3 || mesh.m_Colors.Length == mesh.m_VertexCount * 4);
|
||||
for (var j = mesh.m_SubMeshes[i].firstVertex; j < mesh.m_SubMeshes[i].firstVertex + mesh.m_SubMeshes[i].vertexCount; j++)
|
||||
{
|
||||
var iVertex = vertexColours ? new ImportedVertexWithColour() : new ImportedVertex();
|
||||
var iVertex = new ImportedVertex();
|
||||
//Vertices
|
||||
int c = 3;
|
||||
if (mesh.m_Vertices.Length == mesh.m_VertexCount * 4)
|
||||
{
|
||||
c = 4;
|
||||
}
|
||||
iVertex.Position = new Vector3(-mesh.m_Vertices[j * c], mesh.m_Vertices[j * c + 1], mesh.m_Vertices[j * c + 2]);
|
||||
iVertex.Vertex = new Vector3(-mesh.m_Vertices[j * c], mesh.m_Vertices[j * c + 1], mesh.m_Vertices[j * c + 2]);
|
||||
//Normals
|
||||
if (mesh.m_Normals?.Length > 0)
|
||||
if (iMesh.hasNormal)
|
||||
{
|
||||
if (mesh.m_Normals.Length == mesh.m_VertexCount * 3)
|
||||
{
|
||||
@@ -302,32 +338,41 @@ namespace AssetStudio
|
||||
}
|
||||
iVertex.Normal = new Vector3(-mesh.m_Normals[j * c], mesh.m_Normals[j * c + 1], mesh.m_Normals[j * c + 2]);
|
||||
}
|
||||
//UV
|
||||
iVertex.UV = new float[8][];
|
||||
for (int uv = 0; uv < 8; uv++)
|
||||
{
|
||||
if (iMesh.hasUV[uv])
|
||||
{
|
||||
var m_UV = mesh.GetUV(uv);
|
||||
if (m_UV.Length == mesh.m_VertexCount * 2)
|
||||
{
|
||||
c = 2;
|
||||
}
|
||||
else if (m_UV.Length == mesh.m_VertexCount * 3)
|
||||
{
|
||||
c = 3;
|
||||
}
|
||||
iVertex.UV[uv] = new[] { m_UV[j * c], m_UV[j * c + 1] };
|
||||
}
|
||||
}
|
||||
//Tangent
|
||||
if (iMesh.hasTangent)
|
||||
{
|
||||
iVertex.Tangent = new Vector4(-mesh.m_Tangents[j * 4], mesh.m_Tangents[j * 4 + 1], mesh.m_Tangents[j * 4 + 2], mesh.m_Tangents[j * 4 + 3]);
|
||||
}
|
||||
//Colors
|
||||
if (vertexColours)
|
||||
if (iMesh.hasColor)
|
||||
{
|
||||
if (mesh.m_Colors.Length == mesh.m_VertexCount * 3)
|
||||
{
|
||||
((ImportedVertexWithColour)iVertex).Colour = new Color(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f);
|
||||
iVertex.Color = new Color(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
((ImportedVertexWithColour)iVertex).Colour = new Color(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]);
|
||||
iVertex.Color = new Color(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]);
|
||||
}
|
||||
}
|
||||
//UV
|
||||
if (mesh.m_UV0 != null && mesh.m_UV0.Length == mesh.m_VertexCount * 2)
|
||||
{
|
||||
iVertex.UV = new[] { mesh.m_UV0[j * 2], mesh.m_UV0[j * 2 + 1] };
|
||||
}
|
||||
else if (mesh.m_UV1 != null && mesh.m_UV1.Length == mesh.m_VertexCount * 2)
|
||||
{
|
||||
iVertex.UV = new[] { mesh.m_UV1[j * 2], mesh.m_UV1[j * 2 + 1] };
|
||||
}
|
||||
//Tangent
|
||||
if (mesh.m_Tangents != null && mesh.m_Tangents.Length == mesh.m_VertexCount * 4)
|
||||
{
|
||||
iVertex.Tangent = new Vector4(-mesh.m_Tangents[j * 4], mesh.m_Tangents[j * 4 + 1], mesh.m_Tangents[j * 4 + 2], -mesh.m_Tangents[j * 4 + 3]);
|
||||
}
|
||||
//BoneInfluence
|
||||
if (mesh.m_Skin?.Length > 0)
|
||||
{
|
||||
@@ -361,97 +406,133 @@ namespace AssetStudio
|
||||
if (meshR is SkinnedMeshRenderer sMesh)
|
||||
{
|
||||
//Bone
|
||||
/*
|
||||
* 0 - None
|
||||
* 1 - m_Bones
|
||||
* 2 - m_BoneNameHashes
|
||||
*/
|
||||
var boneType = 0;
|
||||
if (sMesh.m_Bones.Length > 0)
|
||||
{
|
||||
var boneMax = Math.Min(sMesh.m_Bones.Length, mesh.m_BindPose.Length);
|
||||
iMesh.BoneList = new List<ImportedBone>(boneMax);
|
||||
for (int i = 0; i < boneMax; i++)
|
||||
if (sMesh.m_Bones.Length == mesh.m_BindPose.Length)
|
||||
{
|
||||
var verifiedBoneCount = sMesh.m_Bones.Count(x => x.TryGet(out _));
|
||||
if (verifiedBoneCount > 0)
|
||||
{
|
||||
boneType = 1;
|
||||
}
|
||||
if (verifiedBoneCount != sMesh.m_Bones.Length)
|
||||
{
|
||||
//尝试使用m_BoneNameHashes 4.3 and up
|
||||
if (mesh.m_BindPose.Length > 0 && (mesh.m_BindPose.Length == mesh.m_BoneNameHashes?.Length))
|
||||
{
|
||||
//有效bone数量是否大于SkinnedMeshRenderer
|
||||
var verifiedBoneCount2 = mesh.m_BoneNameHashes.Count(x => FixBonePath(GetPathFromHash(x)) != null);
|
||||
if (verifiedBoneCount2 > verifiedBoneCount)
|
||||
{
|
||||
boneType = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Logger.Error("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//尝试使用m_BoneNameHashes 4.3 and up
|
||||
if (mesh.m_BindPose.Length > 0 && (mesh.m_BindPose.Length == mesh.m_BoneNameHashes?.Length))
|
||||
{
|
||||
boneType = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (boneType == 1)
|
||||
{
|
||||
var boneCount = sMesh.m_Bones.Length;
|
||||
iMesh.BoneList = new List<ImportedBone>(boneCount);
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
{
|
||||
var bone = new ImportedBone();
|
||||
if (sMesh.m_Bones[i].TryGet(out var m_Transform))
|
||||
{
|
||||
bone.Path = GetTransformPath(m_Transform);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(bone.Path))
|
||||
{
|
||||
var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1));
|
||||
bone.Matrix = convert * mesh.m_BindPose[i] * convert;
|
||||
iMesh.BoneList.Add(bone);
|
||||
}
|
||||
var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1));
|
||||
bone.Matrix = convert * mesh.m_BindPose[i] * convert;
|
||||
iMesh.BoneList.Add(bone);
|
||||
}
|
||||
}
|
||||
if (iMesh.BoneList == null || iMesh.BoneList.Count == 0)
|
||||
else if (boneType == 2)
|
||||
{
|
||||
if (mesh.m_BindPose.Length > 0 && mesh.m_BoneNameHashes?.Length > 0)
|
||||
var boneCount = mesh.m_BindPose.Length;
|
||||
iMesh.BoneList = new List<ImportedBone>(boneCount);
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
{
|
||||
var boneMax = Math.Min(mesh.m_BindPose.Length, mesh.m_BoneNameHashes.Length);
|
||||
iMesh.BoneList = new List<ImportedBone>(boneMax);
|
||||
for (int i = 0; i < boneMax; i++)
|
||||
{
|
||||
var bone = new ImportedBone();
|
||||
var boneHash = mesh.m_BoneNameHashes[i];
|
||||
var path = GetPathFromHash(boneHash);
|
||||
bone.Path = FixBonePath(path);
|
||||
if (!string.IsNullOrEmpty(bone.Path))
|
||||
{
|
||||
var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1));
|
||||
bone.Matrix = convert * mesh.m_BindPose[i] * convert;
|
||||
iMesh.BoneList.Add(bone);
|
||||
}
|
||||
}
|
||||
var bone = new ImportedBone();
|
||||
var boneHash = mesh.m_BoneNameHashes[i];
|
||||
var path = GetPathFromHash(boneHash);
|
||||
bone.Path = FixBonePath(path);
|
||||
var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1));
|
||||
bone.Matrix = convert * mesh.m_BindPose[i] * convert;
|
||||
iMesh.BoneList.Add(bone);
|
||||
}
|
||||
}
|
||||
|
||||
//Morphs
|
||||
if (mesh.m_Shapes?.shapes != null)
|
||||
if (mesh.m_Shapes?.channels?.Length > 0)
|
||||
{
|
||||
if (mesh.m_Shapes.shapes.Length > 0)
|
||||
var morph = new ImportedMorph();
|
||||
MorphList.Add(morph);
|
||||
morph.Path = iMesh.Path;
|
||||
morph.Channels = new List<ImportedMorphChannel>(mesh.m_Shapes.channels.Length);
|
||||
for (int i = 0; i < mesh.m_Shapes.channels.Length; i++)
|
||||
{
|
||||
ImportedMorph morph = null;
|
||||
string lastGroup = "";
|
||||
for (int i = 0; i < mesh.m_Shapes.channels.Length; i++)
|
||||
var channel = new ImportedMorphChannel();
|
||||
morph.Channels.Add(channel);
|
||||
var shapeChannel = mesh.m_Shapes.channels[i];
|
||||
|
||||
var blendShapeName = "blendShape." + shapeChannel.name;
|
||||
var crc = new SevenZip.CRC();
|
||||
var bytes = Encoding.UTF8.GetBytes(blendShapeName);
|
||||
crc.Update(bytes, 0, (uint)bytes.Length);
|
||||
morphChannelNames[crc.GetDigest()] = blendShapeName;
|
||||
|
||||
channel.Name = shapeChannel.name;
|
||||
channel.KeyframeList = new List<ImportedMorphKeyframe>(shapeChannel.frameCount);
|
||||
var frameEnd = shapeChannel.frameIndex + shapeChannel.frameCount;
|
||||
for (int frameIdx = shapeChannel.frameIndex; frameIdx < frameEnd; frameIdx++)
|
||||
{
|
||||
string group = BlendShapeNameGroup(mesh, i);
|
||||
if (group != lastGroup)
|
||||
var keyframe = new ImportedMorphKeyframe();
|
||||
channel.KeyframeList.Add(keyframe);
|
||||
keyframe.Weight = mesh.m_Shapes.fullWeights[frameIdx];
|
||||
var shape = mesh.m_Shapes.shapes[frameIdx];
|
||||
keyframe.hasNormals = shape.hasNormals;
|
||||
keyframe.hasTangents = shape.hasTangents;
|
||||
keyframe.VertexList = new List<ImportedMorphVertex>((int)shape.vertexCount);
|
||||
var vertexEnd = shape.firstVertex + shape.vertexCount;
|
||||
for (uint j = shape.firstVertex; j < vertexEnd; j++)
|
||||
{
|
||||
morph = new ImportedMorph();
|
||||
MorphList.Add(morph);
|
||||
morph.Path = iMesh.Path;
|
||||
morph.ClipName = group;
|
||||
morph.Channels = new List<Tuple<float, int, int>>(mesh.m_Shapes.channels.Length);
|
||||
morph.KeyframeList = new List<ImportedMorphKeyframe>(mesh.m_Shapes.shapes.Length);
|
||||
lastGroup = group;
|
||||
}
|
||||
|
||||
morph.Channels.Add(new Tuple<float, int, int>(i < sMesh.m_BlendShapeWeights.Length ? sMesh.m_BlendShapeWeights[i] : 0f, morph.KeyframeList.Count, mesh.m_Shapes.channels[i].frameCount));
|
||||
for (int frameIdx = 0; frameIdx < mesh.m_Shapes.channels[i].frameCount; frameIdx++)
|
||||
{
|
||||
ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe();
|
||||
keyframe.Name = BlendShapeNameExtension(mesh, i) + "_" + frameIdx;
|
||||
int shapeIdx = mesh.m_Shapes.channels[i].frameIndex + frameIdx;
|
||||
keyframe.VertexList = new List<ImportedVertex>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount);
|
||||
keyframe.MorphedVertexIndices = new List<ushort>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount);
|
||||
keyframe.Weight = shapeIdx < mesh.m_Shapes.fullWeights.Length ? mesh.m_Shapes.fullWeights[shapeIdx] : 100f;
|
||||
int lastVertIndex = (int)(mesh.m_Shapes.shapes[shapeIdx].firstVertex + mesh.m_Shapes.shapes[shapeIdx].vertexCount);
|
||||
for (int j = (int)mesh.m_Shapes.shapes[shapeIdx].firstVertex; j < lastVertIndex; j++)
|
||||
var destVertex = new ImportedMorphVertex();
|
||||
keyframe.VertexList.Add(destVertex);
|
||||
var morphVertex = mesh.m_Shapes.vertices[j];
|
||||
destVertex.Index = morphVertex.index;
|
||||
var sourceVertex = GetSourceVertex(iMesh.SubmeshList, (int)morphVertex.index);
|
||||
destVertex.Vertex = new ImportedVertex();
|
||||
var morphPos = morphVertex.vertex;
|
||||
destVertex.Vertex.Vertex = sourceVertex.Vertex + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z);
|
||||
if (shape.hasNormals)
|
||||
{
|
||||
var morphVert = mesh.m_Shapes.vertices[j];
|
||||
ImportedVertex vert = GetSourceVertex(iMesh.SubmeshList, (int)morphVert.index);
|
||||
ImportedVertex destVert = new ImportedVertex();
|
||||
Vector3 morphPos = morphVert.vertex;
|
||||
morphPos.X *= -1;
|
||||
destVert.Position = vert.Position + morphPos;
|
||||
Vector3 morphNormal = morphVert.normal;
|
||||
morphNormal.X *= -1;
|
||||
destVert.Normal = morphNormal;
|
||||
Vector4 morphTangent = new Vector4(morphVert.tangent, 0);
|
||||
morphTangent.X *= -1;
|
||||
destVert.Tangent = morphTangent;
|
||||
keyframe.VertexList.Add(destVert);
|
||||
keyframe.MorphedVertexIndices.Add((ushort)morphVert.index);
|
||||
var morphNormal = morphVertex.normal;
|
||||
destVertex.Vertex.Normal = new Vector3(-morphNormal.X, morphNormal.Y, morphNormal.Z);
|
||||
}
|
||||
if (shape.hasTangents)
|
||||
{
|
||||
var morphTangent = morphVertex.tangent;
|
||||
destVertex.Vertex.Tangent = new Vector4(-morphTangent.X, morphTangent.Y, morphTangent.Z, 0);
|
||||
}
|
||||
|
||||
morph.KeyframeList.Add(keyframe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -541,6 +622,14 @@ namespace AssetStudio
|
||||
}
|
||||
iMat = new ImportedMaterial();
|
||||
iMat.Name = mat.m_Name;
|
||||
//default values
|
||||
iMat.Diffuse = new Color(0.8f, 0.8f, 0.8f, 1);
|
||||
iMat.Ambient = new Color(0.2f, 0.2f, 0.2f, 1);
|
||||
iMat.Emissive = new Color(0, 0, 0, 1);
|
||||
iMat.Specular = new Color(0.2f, 0.2f, 0.2f, 1);
|
||||
iMat.Reflection = new Color(0, 0, 0, 1);
|
||||
iMat.Shininess = 20f;
|
||||
iMat.Transparency = 0f;
|
||||
foreach (var col in mat.m_SavedProperties.m_Colors)
|
||||
{
|
||||
switch (col.Key)
|
||||
@@ -555,7 +644,6 @@ namespace AssetStudio
|
||||
iMat.Emissive = col.Value;
|
||||
break;
|
||||
case "_SpecularColor":
|
||||
case "_SpecColor":
|
||||
iMat.Specular = col.Value;
|
||||
break;
|
||||
case "_ReflectColor":
|
||||
@@ -638,7 +726,7 @@ namespace AssetStudio
|
||||
return iMat;
|
||||
}
|
||||
|
||||
private void ConvertTexture2D(Texture2D tex2D, string name)
|
||||
private void ConvertTexture2D(Texture2D m_Texture2D, string name)
|
||||
{
|
||||
var iTex = ImportedHelpers.FindTexture(name, TextureList);
|
||||
if (iTex != null)
|
||||
@@ -646,7 +734,7 @@ namespace AssetStudio
|
||||
return;
|
||||
}
|
||||
|
||||
var bitmap = new Texture2DConverter(tex2D).ConvertToBitmap(true);
|
||||
var bitmap = m_Texture2D.ConvertToBitmap(true);
|
||||
if (bitmap != null)
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
@@ -678,6 +766,7 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
iAnim.Name = name;
|
||||
iAnim.SampleRate = animationClip.m_SampleRate;
|
||||
iAnim.TrackList = new List<ImportedAnimationKeyframedTrack>();
|
||||
AnimationList.Add(iAnim);
|
||||
if (animationClip.m_Legacy)
|
||||
@@ -740,6 +829,31 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var m_FloatCurve in animationClip.m_FloatCurves)
|
||||
{
|
||||
if (m_FloatCurve.classID == ClassIDType.SkinnedMeshRenderer) //BlendShape
|
||||
{
|
||||
var channelName = m_FloatCurve.attribute;
|
||||
int dotPos = channelName.IndexOf('.');
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
channelName = channelName.Substring(dotPos + 1);
|
||||
}
|
||||
|
||||
var path = FixBonePath(m_FloatCurve.path);
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
path = GetPathByChannelName(channelName);
|
||||
}
|
||||
var track = iAnim.FindTrack(path);
|
||||
track.BlendShape = new ImportedBlendShape();
|
||||
track.BlendShape.ChannelName = channelName;
|
||||
foreach (var m_Curve in m_FloatCurve.curve.m_Curve)
|
||||
{
|
||||
track.BlendShape.Keyframes.Add(new ImportedKeyframe<float>(m_Curve.time, m_Curve.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -789,55 +903,79 @@ namespace AssetStudio
|
||||
private void ReadCurveData(ImportedKeyframedAnimation iAnim, AnimationClipBindingConstant m_ClipBindingConstant, int index, float time, float[] data, int offset, ref int curveIndex)
|
||||
{
|
||||
var binding = m_ClipBindingConstant.FindBinding(index);
|
||||
if (binding.path == 0)
|
||||
if (binding.typeID == ClassIDType.SkinnedMeshRenderer) //BlendShape
|
||||
{
|
||||
var channelName = GetChannelNameFromHash(binding.attribute);
|
||||
if (string.IsNullOrEmpty(channelName))
|
||||
{
|
||||
curveIndex++;
|
||||
return;
|
||||
}
|
||||
int dotPos = channelName.IndexOf('.');
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
channelName = channelName.Substring(dotPos + 1);
|
||||
}
|
||||
|
||||
var bPath = FixBonePath(GetPathFromHash(binding.path));
|
||||
if (string.IsNullOrEmpty(bPath))
|
||||
{
|
||||
bPath = GetPathByChannelName(channelName);
|
||||
}
|
||||
var bTrack = iAnim.FindTrack(bPath);
|
||||
bTrack.BlendShape = new ImportedBlendShape();
|
||||
bTrack.BlendShape.ChannelName = channelName;
|
||||
bTrack.BlendShape.Keyframes.Add(new ImportedKeyframe<float>(time, data[curveIndex++ + offset]));
|
||||
}
|
||||
else if (binding.typeID == ClassIDType.Transform)
|
||||
{
|
||||
var path = FixBonePath(GetPathFromHash(binding.path));
|
||||
var track = iAnim.FindTrack(path);
|
||||
|
||||
switch (binding.attribute)
|
||||
{
|
||||
case 1:
|
||||
track.Translations.Add(new ImportedKeyframe<Vector3>(time, new Vector3
|
||||
(
|
||||
-data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset]
|
||||
)));
|
||||
break;
|
||||
case 2:
|
||||
var value = Fbx.QuaternionToEuler(new Quaternion
|
||||
(
|
||||
data[curveIndex++ + offset],
|
||||
-data[curveIndex++ + offset],
|
||||
-data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset]
|
||||
));
|
||||
track.Rotations.Add(new ImportedKeyframe<Vector3>(time, value));
|
||||
break;
|
||||
case 3:
|
||||
track.Scalings.Add(new ImportedKeyframe<Vector3>(time, new Vector3
|
||||
(
|
||||
data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset]
|
||||
)));
|
||||
break;
|
||||
case 4:
|
||||
track.Rotations.Add(new ImportedKeyframe<Vector3>(time, new Vector3
|
||||
(
|
||||
data[curveIndex++ + offset],
|
||||
-data[curveIndex++ + offset],
|
||||
-data[curveIndex++ + offset]
|
||||
)));
|
||||
break;
|
||||
default:
|
||||
curveIndex++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
curveIndex++;
|
||||
return;
|
||||
}
|
||||
|
||||
var path = FixBonePath(GetPathFromHash(binding.path));
|
||||
var track = iAnim.FindTrack(path);
|
||||
|
||||
switch (binding.attribute)
|
||||
{
|
||||
case 1:
|
||||
track.Translations.Add(new ImportedKeyframe<Vector3>(time, new Vector3
|
||||
(
|
||||
-data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset]
|
||||
)));
|
||||
break;
|
||||
case 2:
|
||||
var value = Fbx.QuaternionToEuler(new Quaternion
|
||||
(
|
||||
data[curveIndex++ + offset],
|
||||
-data[curveIndex++ + offset],
|
||||
-data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset]
|
||||
));
|
||||
track.Rotations.Add(new ImportedKeyframe<Vector3>(time, value));
|
||||
break;
|
||||
case 3:
|
||||
track.Scalings.Add(new ImportedKeyframe<Vector3>(time, new Vector3
|
||||
(
|
||||
data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset],
|
||||
data[curveIndex++ + offset]
|
||||
)));
|
||||
break;
|
||||
case 4:
|
||||
track.Rotations.Add(new ImportedKeyframe<Vector3>(time, new Vector3
|
||||
(
|
||||
data[curveIndex++ + offset],
|
||||
-data[curveIndex++ + offset],
|
||||
-data[curveIndex++ + offset]
|
||||
)));
|
||||
break;
|
||||
default:
|
||||
//track.Curve.Add(new ImportedKeyframe<float>(time, data[curveIndex++]));
|
||||
curveIndex++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -855,28 +993,6 @@ namespace AssetStudio
|
||||
return boneName;
|
||||
}
|
||||
|
||||
private static string BlendShapeNameGroup(Mesh mesh, int index)
|
||||
{
|
||||
string name = mesh.m_Shapes.channels[index].name;
|
||||
int dotPos = name.IndexOf('.');
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
return name.Substring(0, dotPos);
|
||||
}
|
||||
return "Ungrouped";
|
||||
}
|
||||
|
||||
private static string BlendShapeNameExtension(Mesh mesh, int index)
|
||||
{
|
||||
string name = mesh.m_Shapes.channels[index].name;
|
||||
int dotPos = name.IndexOf('.');
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
return name.Substring(dotPos + 1);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private static ImportedVertex GetSourceVertex(List<ImportedSubmesh> submeshList, int morphVertIndex)
|
||||
{
|
||||
foreach (var submesh in submeshList)
|
||||
@@ -963,5 +1079,32 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetPathByChannelName(string channelName)
|
||||
{
|
||||
foreach (var morph in MorphList)
|
||||
{
|
||||
foreach (var channel in morph.Channels)
|
||||
{
|
||||
if (channel.Name == channelName)
|
||||
{
|
||||
return morph.Path;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetChannelNameFromHash(uint attribute)
|
||||
{
|
||||
if (morphChannelNames.TryGetValue(attribute, out var name))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
{
|
||||
public static class ModelExporter
|
||||
{
|
||||
public static void ExportFbx(string path, IImported imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, bool flatInbetween, int versionIndex, bool isAscii)
|
||||
public static void ExportFbx(string path, IImported imported, bool eulerFilter, float filterPrecision,
|
||||
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii)
|
||||
{
|
||||
Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, flatInbetween, versionIndex, isAscii);
|
||||
Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allNodes, skins, animation, blendShape, castToBone, boneSize, scaleFactor, versionIndex, isAscii);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("AssetStudioTools")]
|
||||
[assembly: AssemblyTitle("AssetStudioUtility")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AssetStudioTools")]
|
||||
[assembly: AssemblyCopyright("Copyright © Perfare 2018")]
|
||||
[assembly: AssemblyProduct("AssetStudioUtility")]
|
||||
[assembly: AssemblyCopyright("Copyright © Perfare 2018-2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("9131c403-7fe8-444d-9af5-5fe5df76ff24")]
|
||||
[assembly: Guid("80aec261-21ee-4e4f-a93b-7a744dc84888")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
@@ -29,8 +29,8 @@ using System.Runtime.InteropServices;
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyVersion("0.14.38.5")]
|
||||
[assembly: AssemblyFileVersion("0.14.38.5")]
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace AssetStudio
|
||||
}
|
||||
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
|
||||
{
|
||||
var program = new ShaderProgram(blobReader);
|
||||
var program = new ShaderProgram(blobReader, shader.version);
|
||||
return program.Export(Encoding.UTF8.GetString(shader.m_Script));
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ namespace AssetStudio
|
||||
}
|
||||
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
|
||||
{
|
||||
var program = new ShaderProgram(blobReader);
|
||||
var program = new ShaderProgram(blobReader, shader.version);
|
||||
var m_Script = ConvertSerializedShader(shader.m_ParsedForm, shader.platforms[i]);
|
||||
strs[i] = header + program.Export(m_Script);
|
||||
}
|
||||
@@ -556,13 +556,22 @@ namespace AssetStudio
|
||||
{
|
||||
private ShaderSubProgram[] m_SubPrograms;
|
||||
|
||||
public ShaderProgram(BinaryReader reader)
|
||||
public ShaderProgram(BinaryReader reader, int[] version)
|
||||
{
|
||||
var subProgramsCapacity = reader.ReadInt32();
|
||||
m_SubPrograms = new ShaderSubProgram[subProgramsCapacity];
|
||||
int entrySize;
|
||||
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||
{
|
||||
entrySize = 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
entrySize = 8;
|
||||
}
|
||||
for (int i = 0; i < subProgramsCapacity; i++)
|
||||
{
|
||||
reader.BaseStream.Position = 4 + i * 8;
|
||||
reader.BaseStream.Position = 4 + i * entrySize;
|
||||
var offset = reader.ReadInt32();
|
||||
reader.BaseStream.Position = offset;
|
||||
m_SubPrograms[i] = new ShaderSubProgram(reader);
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace AssetStudio
|
||||
{
|
||||
public static class SpriteHelper
|
||||
{
|
||||
public static Bitmap GetImageFromSprite(Sprite m_Sprite)
|
||||
public static Bitmap GetImage(this Sprite m_Sprite)
|
||||
{
|
||||
if (m_Sprite.m_SpriteAtlas != null && m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlas))
|
||||
{
|
||||
@@ -30,18 +30,18 @@ namespace AssetStudio
|
||||
|
||||
private static Bitmap CutImage(Texture2D m_Texture2D, Sprite m_Sprite, RectangleF textureRect, Vector2 textureRectOffset, SpriteSettings settingsRaw)
|
||||
{
|
||||
var texture2D = new Texture2DConverter(m_Texture2D);
|
||||
var originalImage = texture2D.ConvertToBitmap(false);
|
||||
var originalImage = m_Texture2D.ConvertToBitmap(false);
|
||||
if (originalImage != null)
|
||||
{
|
||||
using (originalImage)
|
||||
{
|
||||
//var spriteImage = originalImage.Clone(textureRect, PixelFormat.Format32bppArgb);
|
||||
var spriteImage = new Bitmap((int)textureRect.Width, (int)textureRect.Height, PixelFormat.Format32bppArgb);
|
||||
var destRect = new Rectangle(0, 0, (int)textureRect.Width, (int)textureRect.Height);
|
||||
var textureRectI = Rectangle.Round(textureRect);
|
||||
var spriteImage = new Bitmap(textureRectI.Width, textureRectI.Height, PixelFormat.Format32bppArgb);
|
||||
var destRect = new Rectangle(0, 0, textureRectI.Width, textureRectI.Height);
|
||||
using (var graphic = Graphics.FromImage(spriteImage))
|
||||
{
|
||||
graphic.DrawImage(originalImage, destRect, textureRect, GraphicsUnit.Pixel);
|
||||
graphic.DrawImage(originalImage, destRect, textureRectI, GraphicsUnit.Pixel);
|
||||
}
|
||||
if (settingsRaw.packed == 1)
|
||||
{
|
||||
@@ -61,49 +61,52 @@ namespace AssetStudio
|
||||
spriteImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Tight
|
||||
if (settingsRaw.packingMode == SpritePackingMode.kSPMTight)
|
||||
//Tight
|
||||
if (settingsRaw.packingMode == SpritePackingMode.kSPMTight)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
var triangles = GetTriangles(m_Sprite.m_RD);
|
||||
var points = triangles.Select(x => x.Select(y => new PointF(y.X, y.Y)).ToArray());
|
||||
using (var path = new GraphicsPath())
|
||||
{
|
||||
var triangles = GetTriangles(m_Sprite.m_RD);
|
||||
var points = triangles.Select(x => x.Select(y => new PointF(y.X, y.Y)).ToArray());
|
||||
using (var path = new GraphicsPath())
|
||||
foreach (var p in points)
|
||||
{
|
||||
foreach (var p in points)
|
||||
path.AddPolygon(p);
|
||||
}
|
||||
using (var matr = new Matrix())
|
||||
{
|
||||
var version = m_Sprite.version;
|
||||
if (version[0] < 5
|
||||
|| (version[0] == 5 && version[1] < 4)
|
||||
|| (version[0] == 5 && version[1] == 4 && version[2] <= 1)) //5.4.1p3 down
|
||||
{
|
||||
path.AddPolygon(p);
|
||||
matr.Translate(m_Sprite.m_Rect.Width * 0.5f - textureRectOffset.X, m_Sprite.m_Rect.Height * 0.5f - textureRectOffset.Y);
|
||||
}
|
||||
using (var matr = new Matrix())
|
||||
else
|
||||
{
|
||||
if (m_Sprite.m_Pivot == Vector2.Zero) //5.4.2 down
|
||||
matr.Translate(m_Sprite.m_Rect.Width * m_Sprite.m_Pivot.X - textureRectOffset.X, m_Sprite.m_Rect.Height * m_Sprite.m_Pivot.Y - textureRectOffset.Y);
|
||||
}
|
||||
matr.Scale(m_Sprite.m_PixelsToUnits, m_Sprite.m_PixelsToUnits);
|
||||
path.Transform(matr);
|
||||
var bitmap = new Bitmap(textureRectI.Width, textureRectI.Height);
|
||||
using (var graphic = Graphics.FromImage(bitmap))
|
||||
{
|
||||
using (var brush = new TextureBrush(spriteImage))
|
||||
{
|
||||
matr.Translate(m_Sprite.m_Rect.Width * 0.5f - textureRectOffset.X, m_Sprite.m_Rect.Height * 0.5f - textureRectOffset.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
matr.Translate(m_Sprite.m_Rect.Width * m_Sprite.m_Pivot.X - textureRectOffset.X, m_Sprite.m_Rect.Height * m_Sprite.m_Pivot.Y - textureRectOffset.Y);
|
||||
}
|
||||
matr.Scale(m_Sprite.m_PixelsToUnits, m_Sprite.m_PixelsToUnits);
|
||||
path.Transform(matr);
|
||||
var bitmap = new Bitmap((int)textureRect.Width, (int)textureRect.Height);
|
||||
using (var graphic = Graphics.FromImage(bitmap))
|
||||
{
|
||||
using (var brush = new TextureBrush(spriteImage))
|
||||
{
|
||||
graphic.FillPath(brush, path);
|
||||
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
||||
return bitmap;
|
||||
}
|
||||
graphic.FillPath(brush, path);
|
||||
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
13
AssetStudioUtility/Texture2DExtensions.cs
Normal file
13
AssetStudioUtility/Texture2DExtensions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static class Texture2DExtensions
|
||||
{
|
||||
public static Bitmap ConvertToBitmap(this Texture2D m_Texture2D, bool flip)
|
||||
{
|
||||
var converter = new Texture2DConverter(m_Texture2D);
|
||||
return converter.ConvertToBitmap(flip);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Radu
|
||||
Copyright (c) 2016-2018 Perfare
|
||||
Copyright (c) 2016 Radu
|
||||
Copyright (c) 2016-2020 Perfare
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
26
README.md
26
README.md
@@ -7,12 +7,12 @@ AssetStudio is a tool for exploring, extracting and exporting assets and assetbu
|
||||
|
||||
## Features
|
||||
* Support version:
|
||||
* 2.5 - 2019.1
|
||||
* 2.5 - 2019.3
|
||||
* Support asset types:
|
||||
* **Texture2D** : support convert to bmp, png or jpeg. export to containers: DDS, PVR and KTX
|
||||
* **Sprite** : bmp, png or jpeg
|
||||
* **Texture2D** : convert to png, tga, jpeg, bmp
|
||||
* **Sprite** : crop Texture2D to png, tga, jpeg, bmp
|
||||
* **AudioClip** : mp3, ogg, wav, m4a, fsb. support convert FSB file to WAV(PCM)
|
||||
* **Font**
|
||||
* **Font** : ttf, otf
|
||||
* **Mesh** : obj
|
||||
* **TextAsset**
|
||||
* **Shader**
|
||||
@@ -24,9 +24,8 @@ AssetStudio is a tool for exploring, extracting and exporting assets and assetbu
|
||||
## Usage
|
||||
### Requirements
|
||||
|
||||
- [.NET Framework 4.0](https://www.microsoft.com/en-us/download/details.aspx?id=17718)
|
||||
- [Microsoft Visual C++ 2013 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=40784)
|
||||
- [Microsoft Visual C++ 2015 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=53840)
|
||||
- [.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472)
|
||||
- [Microsoft Visual C++ 2017 Redistributable](https://support.microsoft.com/help/2977003/the-latest-supported-visual-c-downloads)
|
||||
|
||||
### How to use
|
||||
|
||||
@@ -42,6 +41,13 @@ AssetStudio is a tool for exploring, extracting and exporting assets and assetbu
|
||||
|
||||
## Build
|
||||
|
||||
* The project uses some C# 7 syntax, need Visual Studio 2017 or newer
|
||||
* **AssetStudioFBX** uses FBX SDK 2019.0 VS2015, before building, you need to install the FBX SDK and modify the project file, change include directory and library directory to point to the FBX SDK directory
|
||||
* If you want to change the FBX SDK version, you need to replace `libfbxsdk.dll` which in `AssetStudioGUI/Libraries/x86/` and `AssetStudioGUI/Libraries/x64` directory to the new version
|
||||
* Visual Studio 2019 or newer
|
||||
* **AssetStudioFBX** uses FBX SDK 2020.0.1 VS2017, before building, you need to install the FBX SDK and modify the project file, change include directory and library directory to point to the FBX SDK directory
|
||||
* If you want to change the FBX SDK version, you need to replace `libfbxsdk.dll` which in `AssetStudioGUI/Libraries/x86/` and `AssetStudioGUI/Libraries/x64/` directory to the new version
|
||||
|
||||
## Open source libraries used
|
||||
|
||||
### Texture2DDecoder
|
||||
* [Ishotihadus/mikunyan](https://github.com/Ishotihadus/mikunyan)
|
||||
* [BinomialLLC/crunch](https://github.com/BinomialLLC/crunch)
|
||||
* [Unity-Technologies/crunch](https://github.com/Unity-Technologies/crunch/tree/unity)
|
||||
|
||||
20
Texture2DDecoder/AssemblyInfo.cpp
Normal file
20
Texture2DDecoder/AssemblyInfo.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
using namespace System;
|
||||
using namespace System::Reflection;
|
||||
using namespace System::Runtime::CompilerServices;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
using namespace System::Security::Permissions;
|
||||
|
||||
[assembly:AssemblyTitleAttribute(L"Texture2DDecoder")];
|
||||
[assembly:AssemblyDescriptionAttribute(L"")];
|
||||
[assembly:AssemblyConfigurationAttribute(L"")];
|
||||
[assembly:AssemblyCompanyAttribute(L"")];
|
||||
[assembly:AssemblyProductAttribute(L"Texture2DDecoder")];
|
||||
[assembly:AssemblyCopyrightAttribute(L"Copyright © Perfare 2020")];
|
||||
[assembly:AssemblyTrademarkAttribute(L"")];
|
||||
[assembly:AssemblyCultureAttribute(L"")];
|
||||
|
||||
[assembly:AssemblyVersionAttribute("1.0.*")];
|
||||
|
||||
[assembly:ComVisible(false)];
|
||||
|
||||
[assembly:CLSCompliantAttribute(true)];
|
||||
148
Texture2DDecoder/Texture2DDecoder.cpp
Normal file
148
Texture2DDecoder/Texture2DDecoder.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#include <string.h>
|
||||
#include "Texture2DDecoder.h"
|
||||
#include "bcn.h"
|
||||
#include "pvrtc.h"
|
||||
#include "etc.h"
|
||||
#include "atc.h"
|
||||
#include "astc.h"
|
||||
#include "crunch.h"
|
||||
#include "unitycrunch.h"
|
||||
|
||||
namespace Texture2DDecoder {
|
||||
bool TextureDecoder::DecodeDXT1(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_bc1(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeDXT5(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_bc3(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodePVRTC(array<Byte>^ data, long w, long h, array<Byte>^ image, bool is2bpp) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_pvrtc(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin), is2bpp ? 1 : 0);
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeETC1(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_etc1(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeETC2(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_etc2(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeETC2A1(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_etc2a1(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeETC2A8(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_etc2a8(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeEACR(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_eacr(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeEACRSigned(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_eacr_signed(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeEACRG(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_eacrg(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeEACRGSigned(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_eacrg_signed(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeBC4(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_bc4(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeBC5(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_bc5(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeBC6(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_bc6(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeBC7(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_bc7(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeATCRGB4(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_atc_rgb4(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeATCRGBA8(array<Byte>^ data, long w, long h, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_atc_rgba8(dataPin, w, h, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
bool TextureDecoder::DecodeASTC(array<Byte>^ data, long w, long h, int bw, int bh, array<Byte>^ image) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
pin_ptr<unsigned char> imagePin = &image[0];
|
||||
return decode_astc(dataPin, w, h, bw, bh, reinterpret_cast<uint32_t*>(imagePin));
|
||||
}
|
||||
|
||||
array<Byte>^ TextureDecoder::UnpackCrunch(array<Byte>^ data) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
void* ret;
|
||||
uint32_t retSize;
|
||||
if (!crunch_unpack_level(dataPin, data->Length, 0, &ret, &retSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto buff = gcnew array<Byte>(retSize);
|
||||
pin_ptr<unsigned char> buffPin = &buff[0];
|
||||
memcpy(buffPin, ret, retSize);
|
||||
delete ret;
|
||||
return buff;
|
||||
}
|
||||
|
||||
array<Byte>^ TextureDecoder::UnpackUnityCrunch(array<Byte>^ data) {
|
||||
pin_ptr<unsigned char> dataPin = &data[0];
|
||||
void* ret;
|
||||
uint32_t retSize;
|
||||
if (!unity_crunch_unpack_level(dataPin, data->Length, 0, &ret, &retSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto buff = gcnew array<Byte>(retSize);
|
||||
pin_ptr<unsigned char> buffPin = &buff[0];
|
||||
memcpy(buffPin, ret, retSize);
|
||||
delete ret;
|
||||
return buff;
|
||||
}
|
||||
}
|
||||
|
||||
30
Texture2DDecoder/Texture2DDecoder.h
Normal file
30
Texture2DDecoder/Texture2DDecoder.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
using namespace System;
|
||||
|
||||
namespace Texture2DDecoder {
|
||||
public ref class TextureDecoder
|
||||
{
|
||||
public:
|
||||
static bool DecodeDXT1(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeDXT5(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodePVRTC(array<Byte>^ data, long w, long h, array<Byte>^ image, bool is2bpp);
|
||||
static bool DecodeETC1(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeETC2(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeETC2A1(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeETC2A8(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeEACR(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeEACRSigned(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeEACRG(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeEACRGSigned(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeBC4(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeBC5(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeBC6(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeBC7(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeATCRGB4(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeATCRGBA8(array<Byte>^ data, long w, long h, array<Byte>^ image);
|
||||
static bool DecodeASTC(array<Byte>^ data, long w, long h, int bw, int bh, array<Byte>^ image);
|
||||
static array<Byte>^ UnpackCrunch(array<Byte>^ data);
|
||||
static array<Byte>^ UnpackUnityCrunch(array<Byte>^ data);
|
||||
};
|
||||
}
|
||||
147
Texture2DDecoder/Texture2DDecoder.vcxproj
Normal file
147
Texture2DDecoder/Texture2DDecoder.vcxproj
Normal file
@@ -0,0 +1,147 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}</ProjectGuid>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<Keyword>ManagedCProj</Keyword>
|
||||
<RootNamespace>Texture2DDecoder</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies />
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies />
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies />
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies />
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="astc.h" />
|
||||
<ClInclude Include="atc.h" />
|
||||
<ClInclude Include="bcn.h" />
|
||||
<ClInclude Include="color.h" />
|
||||
<ClInclude Include="crunch.h" />
|
||||
<ClInclude Include="crunch\crnlib.h" />
|
||||
<ClInclude Include="crunch\crn_decomp.h" />
|
||||
<ClInclude Include="endianness.h" />
|
||||
<ClInclude Include="etc.h" />
|
||||
<ClInclude Include="fp16.h" />
|
||||
<ClInclude Include="fp16\bitcasts.h" />
|
||||
<ClInclude Include="fp16\fp16.h" />
|
||||
<ClInclude Include="pvrtc.h" />
|
||||
<ClInclude Include="Texture2DDecoder.h" />
|
||||
<ClInclude Include="unitycrunch.h" />
|
||||
<ClInclude Include="unitycrunch\crnlib.h" />
|
||||
<ClInclude Include="unitycrunch\crn_decomp.h" />
|
||||
<ClInclude Include="unitycrunch\crn_defs.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AssemblyInfo.cpp" />
|
||||
<ClCompile Include="astc.cpp" />
|
||||
<ClCompile Include="atc.cpp" />
|
||||
<ClCompile Include="bcn.cpp" />
|
||||
<ClCompile Include="crunch.cpp" />
|
||||
<ClCompile Include="etc.cpp" />
|
||||
<ClCompile Include="pvrtc.cpp" />
|
||||
<ClCompile Include="Texture2DDecoder.cpp" />
|
||||
<ClCompile Include="unitycrunch.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
102
Texture2DDecoder/Texture2DDecoder.vcxproj.filters
Normal file
102
Texture2DDecoder/Texture2DDecoder.vcxproj.filters
Normal file
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="astc.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="atc.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="bcn.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="color.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="crunch.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="endianness.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="etc.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fp16.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pvrtc.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Texture2DDecoder.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="unitycrunch.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="crunch\crn_decomp.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="crunch\crnlib.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fp16\bitcasts.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fp16\fp16.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="unitycrunch\crn_decomp.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="unitycrunch\crn_defs.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="unitycrunch\crnlib.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AssemblyInfo.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="astc.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="atc.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="bcn.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="crunch.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="etc.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pvrtc.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Texture2DDecoder.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="unitycrunch.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
1148
Texture2DDecoder/astc.cpp
Normal file
1148
Texture2DDecoder/astc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
8
Texture2DDecoder/astc.h
Normal file
8
Texture2DDecoder/astc.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef ASTC_H
|
||||
#define ASTC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int decode_astc(const uint8_t *, const long, const long, const int, const int, uint32_t *);
|
||||
|
||||
#endif /* end of include guard: ASTC_H */
|
||||
91
Texture2DDecoder/atc.cpp
Normal file
91
Texture2DDecoder/atc.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include "bcn.h"
|
||||
#include "atc.h"
|
||||
#include "color.h"
|
||||
#include <algorithm>
|
||||
|
||||
static uint8_t expand_quantized(uint8_t v, int bits) {
|
||||
v = v << (8 - bits);
|
||||
return v | (v >> bits);
|
||||
}
|
||||
|
||||
void decode_atc_block(const uint8_t* _src, uint32_t* _dst)
|
||||
{
|
||||
uint8_t colors[4 * 4];
|
||||
|
||||
uint32_t c0 = _src[0] | (_src[1] << 8);
|
||||
uint32_t c1 = _src[2] | (_src[3] << 8);
|
||||
|
||||
if (0 == (c0 & 0x8000))
|
||||
{
|
||||
colors[0] = expand_quantized((c0 >> 0) & 0x1f, 5);
|
||||
colors[1] = expand_quantized((c0 >> 5) & 0x1f, 5);
|
||||
colors[2] = expand_quantized((c0 >> 10) & 0x1f, 5);
|
||||
|
||||
colors[12] = expand_quantized((c1 >> 0) & 0x1f, 5);
|
||||
colors[13] = expand_quantized((c1 >> 5) & 0x3f, 6);
|
||||
colors[14] = expand_quantized((c1 >> 11) & 0x1f, 5);
|
||||
|
||||
colors[4] = (5 * colors[0] + 3 * colors[12]) / 8;
|
||||
colors[5] = (5 * colors[1] + 3 * colors[13]) / 8;
|
||||
colors[6] = (5 * colors[2] + 3 * colors[14]) / 8;
|
||||
|
||||
colors[8] = (3 * colors[0] + 5 * colors[12]) / 8;
|
||||
colors[9] = (3 * colors[1] + 5 * colors[13]) / 8;
|
||||
colors[10] = (3 * colors[2] + 5 * colors[14]) / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
colors[0] = 0;
|
||||
colors[1] = 0;
|
||||
colors[2] = 0;
|
||||
|
||||
colors[8] = expand_quantized((c0 >> 0) & 0x1f, 5);
|
||||
colors[9] = expand_quantized((c0 >> 5) & 0x1f, 5);
|
||||
colors[10] = expand_quantized((c0 >> 10) & 0x1f, 5);
|
||||
|
||||
colors[12] = expand_quantized((c1 >> 0) & 0x1f, 5);
|
||||
colors[13] = expand_quantized((c1 >> 5) & 0x3f, 6);
|
||||
colors[14] = expand_quantized((c1 >> 11) & 0x1f, 5);
|
||||
|
||||
colors[4] = std::max(0, colors[8] - colors[12] / 4);
|
||||
colors[5] = std::max(0, colors[9] - colors[13] / 4);
|
||||
colors[6] = std::max(0, colors[10] - colors[14] / 4);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0, next = 8 * 4; i < 16; i += 1, next += 2)
|
||||
{
|
||||
int32_t idx = ((_src[next >> 3] >> (next & 7)) & 3) * 4;
|
||||
_dst[i] = color(colors[idx + 2], colors[idx + 1], colors[idx + 0], 255);
|
||||
}
|
||||
}
|
||||
|
||||
int decode_atc_rgb4(const uint8_t* data, uint32_t m_width, uint32_t m_height, uint32_t* image) {
|
||||
uint32_t m_block_width = 4;
|
||||
uint32_t m_block_height = 4;
|
||||
uint32_t m_blocks_x = (m_width + m_block_width - 1) / m_block_width;
|
||||
uint32_t m_blocks_y = (m_height + m_block_height - 1) / m_block_height;
|
||||
uint32_t buffer[16];
|
||||
for (uint32_t by = 0; by < m_blocks_y; by++) {
|
||||
for (uint32_t bx = 0; bx < m_blocks_x; bx++, data += 8) {
|
||||
decode_atc_block(data, buffer);
|
||||
copy_block_buffer(bx, by, m_width, m_height, m_block_width, m_block_height, buffer, image);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int decode_atc_rgba8(const uint8_t* data, uint32_t m_width, uint32_t m_height, uint32_t* image) {
|
||||
uint32_t m_block_width = 4;
|
||||
uint32_t m_block_height = 4;
|
||||
uint32_t m_blocks_x = (m_width + m_block_width - 1) / m_block_width;
|
||||
uint32_t m_blocks_y = (m_height + m_block_height - 1) / m_block_height;
|
||||
uint32_t buffer[16];
|
||||
for (uint32_t by = 0; by < m_blocks_y; by++) {
|
||||
for (uint32_t bx = 0; bx < m_blocks_x; bx++, data += 16) {
|
||||
decode_atc_block(data + 8, buffer);
|
||||
decode_bc3_alpha(data, buffer, 3);
|
||||
copy_block_buffer(bx, by, m_width, m_height, m_block_width, m_block_height, buffer, image);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
5
Texture2DDecoder/atc.h
Normal file
5
Texture2DDecoder/atc.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
int decode_atc_rgb4(const uint8_t* data, uint32_t m_width, uint32_t m_height, uint32_t* image);
|
||||
int decode_atc_rgba8(const uint8_t* data, uint32_t m_width, uint32_t m_height, uint32_t* image);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user