Skip to content

Commit 7cbcaa0

Browse files
committed
🚧 JSON Exporter
- Added the JSON Exporter. - Added an option to toggle baked animations in the exported JSON file.
1 parent a1c9306 commit 7cbcaa0

16 files changed

+580
-106
lines changed

TODO.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@
111111

112112
- [x] Warn the user when they have custom elements in their model, but have disabled the resource pack export.
113113

114+
# Plugin Exporter
115+
116+
- [x] Add an option to export a JSON file.
117+
114118
# List of numbers to track
115119

116120
- [ ] Total exports

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"svelte-awesome-color-picker": "^3.0.0-beta.7",
9090
"svelte-preprocess": "^5.0.1",
9191
"svelte-preprocess-esbuild": "^3.0.1",
92+
"ts-json-schema-generator": "^2.3.0",
9293
"typescript": "^4.5.5"
9394
},
9495
"dependencies": {

src/blockbenchTypeMods.d.ts

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type {
44
IBlueprintBoneConfigJSON,
55
IBlueprintLocatorConfigJSON,
66
} from './blueprintFormat'
7-
import { blueprintSettingErrors } from './blueprintSettings'
7+
import { blueprintSettingErrors, defaultValues } from './blueprintSettings'
88
import { openExportProgressDialog } from './interface/exportProgressDialog'
99
import { openUnexpectedErrorDialog } from './interface/unexpectedErrorDialog'
1010
import { TextDisplay } from './outliner/textDisplay'
@@ -29,31 +29,7 @@ declare module 'three' {
2929

3030
declare global {
3131
interface ModelProject {
32-
animated_java: {
33-
export_namespace: string
34-
show_bounding_box: boolean
35-
auto_bounding_box: boolean
36-
bounding_box: [number, number]
37-
// Export Settings
38-
enable_plugin_mode: boolean
39-
enable_resource_pack: boolean
40-
enable_data_pack: boolean
41-
// Resource Pack Settings
42-
display_item: string
43-
customModelDataOffset: number
44-
enable_advanced_resource_pack_settings: boolean
45-
resource_pack: string
46-
display_item_path: string
47-
model_folder: string
48-
texture_folder: string
49-
// Data Pack Settings
50-
enable_advanced_data_pack_settings: boolean
51-
data_pack: string
52-
summon_commands: string
53-
interpolation_duration: number
54-
teleportation_duration: number
55-
use_storage_for_animation: boolean
56-
}
32+
animated_java: { [T in keyof typeof defaultValues]: (typeof defaultValues)[T] }
5733
last_used_export_namespace: string
5834
visualBoundingBox?: THREE.LineSegments
5935
pluginMode: Valuable<boolean>

src/blueprintFormat.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export const BLUEPRINT_CODEC = new Blockbench.Codec('animated_java_blueprint', {
198198
type: 'json',
199199
},
200200

201-
// ANCHOR - Codec:load
201+
// region > load
202202
load(model: IBlueprintFormatJSON, file) {
203203
console.log(`Loading Animated Java Blueprint from '${file.name}'...`)
204204
model = process(model)
@@ -211,7 +211,7 @@ export const BLUEPRINT_CODEC = new Blockbench.Codec('animated_java_blueprint', {
211211
console.log(`Successfully loaded Animated Java Blueprint`)
212212
},
213213

214-
// ANCHOR - Codec:parse
214+
// region > parse
215215
// Takes the model file and injects it's data into the global Project
216216
parse(model: IBlueprintFormatJSON, path) {
217217
console.log(`Parsing Animated Java Blueprint from '${path}'...`)
@@ -369,7 +369,7 @@ export const BLUEPRINT_CODEC = new Blockbench.Codec('animated_java_blueprint', {
369369
BLUEPRINT_CODEC.dispatchEvent('parsed', { model })
370370
},
371371

372-
// ANCHOR - Codec:compile
372+
// region > compile
373373
compile(options) {
374374
if (!options) options = {}
375375
console.log(`Compiling Animated Java Blueprint from ${Project!.name}...`)
@@ -463,7 +463,7 @@ export const BLUEPRINT_CODEC = new Blockbench.Codec('animated_java_blueprint', {
463463
return options.raw ? model : compileJSON(model)
464464
},
465465

466-
// ANCHOR - Codec:export
466+
// region > export
467467
export() {
468468
console.log(`Exporting Animated Java Blueprint for ${Project!.name}...`)
469469
if (!Project) throw new Error('No project to export.')

src/blueprintSettings.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Valuable } from './util/stores'
22

3-
export const defaultValues: ModelProject['animated_java'] = {
3+
export const defaultValues = {
44
export_namespace: 'blueprint',
55
show_bounding_box: false,
66
auto_bounding_box: true,
@@ -24,6 +24,9 @@ export const defaultValues: ModelProject['animated_java'] = {
2424
interpolation_duration: 1,
2525
teleportation_duration: 1,
2626
use_storage_for_animation: false,
27+
// Plugin Settings
28+
baked_animations: true,
29+
json_file: '',
2730
}
2831

2932
export const blueprintSettingErrors = new Valuable<Record<string, string>>({})

src/components/blueprintSettingsDialog.svelte

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
export let interpolationDuration: Valuable<number>
4444
export let teleportationDuration: Valuable<number>
4545
export let useStorageForAnimation: Valuable<boolean>
46+
// Plugin Export Settings
47+
export let bakedAnimations: Valuable<boolean>
48+
export let jsonFile: Valuable<string>
4649
4750
function exportNamespaceChecker(value: string): { type: string; message: string } {
4851
if (value === '') {
@@ -256,6 +259,25 @@
256259
}
257260
}
258261
262+
function jsonFileChecker(value: string): { type: string; message: string } {
263+
switch (true) {
264+
case value === '':
265+
return {
266+
type: 'error',
267+
message: translate(
268+
'dialog.blueprint_settings.json_file.error.no_file_selected',
269+
),
270+
}
271+
case fs.existsSync(value) && !fs.statSync(value).isFile():
272+
return {
273+
type: 'error',
274+
message: translate('dialog.blueprint_settings.json_file.error.not_a_file'),
275+
}
276+
default:
277+
return { type: 'success', message: '' }
278+
}
279+
}
280+
259281
function advancedResourcePackFolderChecker(value: string): { type: string; message: string } {
260282
switch (true) {
261283
case value === '':
@@ -351,6 +373,19 @@
351373
bind:value={displayItem}
352374
valueChecker={displayItemChecker}
353375
/>
376+
377+
<Checkbox
378+
label={translate('dialog.blueprint_settings.baked_animations.title')}
379+
tooltip={translate('dialog.blueprint_settings.baked_animations.description')}
380+
bind:checked={bakedAnimations}
381+
/>
382+
383+
<FileSelect
384+
label={translate('dialog.blueprint_settings.json_file.title')}
385+
tooltip={translate('dialog.blueprint_settings.json_file.description')}
386+
bind:value={jsonFile}
387+
valueChecker={jsonFileChecker}
388+
/>
354389
{:else}
355390
<Checkbox
356391
label={translate('dialog.blueprint_settings.enable_resource_pack.title')}

src/interface/animatedJavaBarItem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ MenuBar.addAction(
8989
category: 'animated_java',
9090
name: translate('action.export.name'),
9191
condition() {
92-
return Format === BLUEPRINT_FORMAT && !Project?.animated_java.enable_plugin_mode
92+
return Format === BLUEPRINT_FORMAT
9393
},
9494
click() {
9595
void exportProject()

src/interface/blueprintSettingsDialog.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ function getSettings() {
5555
interpolationDuration: new Valuable(Project!.animated_java.interpolation_duration),
5656
teleportationDuration: new Valuable(Project!.animated_java.teleportation_duration),
5757
useStorageForAnimation: new Valuable(Project!.animated_java.use_storage_for_animation),
58+
// Plugin Settings
59+
bakedAnimations: new Valuable(Project!.animated_java.baked_animations),
60+
jsonFile: new Valuable(Project!.animated_java.json_file),
5861
}
5962
}
6063

@@ -91,6 +94,9 @@ function setSettings(settings: ReturnType<typeof getSettings>) {
9194
Project.animated_java.interpolation_duration = settings.interpolationDuration.get()
9295
Project.animated_java.teleportation_duration = settings.teleportationDuration.get()
9396
Project.animated_java.use_storage_for_animation = settings.useStorageForAnimation.get()
97+
// Plugin Settings
98+
Project.animated_java.baked_animations = settings.bakedAnimations.get()
99+
Project.animated_java.json_file = settings.jsonFile.get()
94100
console.log('Successfully saved project settings', Project)
95101
}
96102

src/lang/en.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,18 @@ animated_java.dialog.blueprint_settings.use_storage_for_animation.description: |
143143
This will vastly reduce the number of functions in the generated Data Pack, but is 33% slower than the function method.
144144
WARNING: This animation method does not support cameras, or locators!
145145
146+
# Plugin Settings
147+
animated_java.dialog.blueprint_settings.baked_animations.title: Baked Animations
148+
animated_java.dialog.blueprint_settings.baked_animations.description: |-
149+
Whether or not to bake the exported animations.
150+
Baked animations have their frames pre-calculated and stored in the exported JSON file, reducing the complexity of rendering the model in-game.
151+
Some Plugins may require this to be enabled to function correctly.
152+
153+
animated_java.dialog.blueprint_settings.json_file.title: JSON File
154+
animated_java.dialog.blueprint_settings.json_file.description: The path to the JSON file to export the project to.
155+
animated_java.dialog.blueprint_settings.json_file.error.no_file_selected: No file selected!
156+
animated_java.dialog.blueprint_settings.json_file.error.not_a_file: The selected path is not a file!
157+
146158
## Bone Config Dialog
147159
animated_java.dialog.bone_config.title: Bone Config
148160

src/systems/exporter.ts

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { resolveEnvVariables } from '../util/misc'
77
import { translate } from '../util/translation'
88
import { hashAnimations, renderProjectAnimations } from './animationRenderer'
99
import { compileDataPack } from './datapackCompiler'
10+
import { exportJSON } from './jsonExporter'
1011
import { compileResourcePack } from './resourcepackCompiler'
1112
import { renderRig, hashRig } from './rigRenderer'
1213

@@ -25,9 +26,20 @@ async function actuallyExportProject(forceSave = true) {
2526
const resourcePackFolder = resolveEnvVariables(aj.resource_pack)
2627
const dataPackFolder = resolveEnvVariables(aj.data_pack)
2728

28-
console.log('Exporting to', resourcePackFolder, dataPackFolder)
29-
30-
if (aj.enable_advanced_resource_pack_settings) {
29+
if (aj.enable_plugin_mode) {
30+
modelExportFolder = PathModule.join(
31+
'assets/animated_java/models/item/',
32+
aj.export_namespace
33+
)
34+
textureExportFolder = PathModule.join(
35+
'assets/animated_java/textures/item/',
36+
aj.export_namespace
37+
)
38+
displayItemPath = PathModule.join(
39+
'assets/minecraft/models/item/',
40+
aj.display_item.split(':').at(-1)! + '.json'
41+
)
42+
} else if (aj.enable_advanced_resource_pack_settings) {
3143
modelExportFolder = aj.model_folder
3244
textureExportFolder = aj.texture_folder
3345
displayItemPath = aj.display_item_path
@@ -69,23 +81,34 @@ async function actuallyExportProject(forceSave = true) {
6981
const rigHash = hashRig(rig)
7082
const animationHash = hashAnimations(animations)
7183

72-
if (aj.enable_resource_pack) {
73-
compileResourcePack({
84+
if (aj.enable_plugin_mode) {
85+
exportJSON({
7486
rig,
7587
animations,
7688
displayItemPath,
77-
resourcePackFolder,
7889
textureExportFolder,
7990
modelExportFolder,
80-
dataPackFolder,
8191
})
92+
} else {
93+
if (aj.enable_resource_pack) {
94+
compileResourcePack({
95+
rig,
96+
animations,
97+
displayItemPath,
98+
resourcePackFolder,
99+
textureExportFolder,
100+
modelExportFolder,
101+
dataPackFolder,
102+
})
103+
}
104+
105+
if (aj.enable_data_pack) {
106+
await compileDataPack({ rig, animations, dataPackFolder, rigHash, animationHash })
107+
}
108+
109+
Project!.last_used_export_namespace = aj.export_namespace
82110
}
83111

84-
if (aj.enable_data_pack) {
85-
await compileDataPack({ rig, animations, dataPackFolder, rigHash, animationHash })
86-
}
87-
88-
Project!.last_used_export_namespace = aj.export_namespace
89112
console.timeEnd('Exporting project took')
90113

91114
if (forceSave) saveBlueprint()

0 commit comments

Comments
 (0)