Skip to content

Commit 83a2030

Browse files
committed
🚧 JSON Compiler improvements
- Implemented #227. - Fixed #228. - Added new node type: `struct`. Can be used to re-create the rig's bone structure for dynamic animations. - Added `is_default` to exported variant JSON.
1 parent 2e4f4b5 commit 83a2030

File tree

8 files changed

+85
-43
lines changed

8 files changed

+85
-43
lines changed

schemas/pluginJson.schema.json

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -144,24 +144,15 @@
144144
"type": "object",
145145
"additionalProperties": false,
146146
"patternProperties": {
147-
"animated_java:transparent_texture": {
148-
"type": "object",
149-
"description": "The internal transparent texture used to hide parts of the Rig.",
150-
"properties": {
151-
"name": { "const": "Transparent" },
152-
"expectedPath": {
153-
"const": "assets\\animated_java\\textures\\item\\armor_stand\\Transparent.png"
154-
},
155-
"src": {
156-
"const": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABgWlDQ1BJQ0MgcHJvZmlsZQAAKJF9kTtIA0EURY+JokjEwhQiFltEK21UxFKiKIKBkETwV7i7MVHIrmE3YmMp2AYs/DRGLWystbWwFQTBD4i1hZWijcj6ZhNIEOPAMIc7cy9v3oNAKWdabuMoWHbBSUxGtdm5ea35hSaCQIAR3XTzseREirrr844Gdd72q6z67/5cbell14QGTXjUzDsF4SXh4Y1CXvGecNhc0dPCZ8J9jhQo/KB0o8yvirM+B1Rm2EklxoTDwlq2ho0aNlccS3hIOJK2bMkPzJY5rXhTsZVbNyt1qh+Glu2ZpNJldzPJFDHiaBiss0qOAv1y2qK4JOQ+Wsff5fvj4jLEtYopjnHWsNB9P2oGv3vrZgYHykmhKDQ9e957DzTvwHfR876OPO/7GIJPcGlX/WslGPkQvVjVIofQvgXnV1XN2IWLbeh8zOuO7kv+/DMZeDuVMc1Bxw20LpT7Vrnn5B5S0qvpa9g/gN6sZC/W+XdLbd/+fVPp3w9iNHKgdXImZAAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gFAwAFKkpaLkIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAEklEQVQ4y2NgGAWjYBSMAggAAAQQAAGFP6pyAAAAAElFTkSuQmCC"
157-
}
158-
}
159-
},
160-
".+": {
147+
"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$": {
161148
"type": "object",
162149
"required": ["name", "expectedPath", "src"],
163150
"properties": {
164151
"name": { "type": "string" },
152+
"id": {
153+
"type": "string",
154+
"description": "The ID of the texture used when making vanilla models."
155+
},
165156
"expectedPath": {
166157
"type": "string",
167158
"description": "The path in the resource pack that the models that reference this texture expect the texture to be at."
@@ -330,6 +321,7 @@
330321
"type": "string",
331322
"enum": [
332323
"bone",
324+
"struct",
333325
"camera",
334326
"locator",
335327
"text_display",
@@ -395,6 +387,7 @@
395387
"type": "string",
396388
"enum": [
397389
"bone",
390+
"struct",
398391
"camera",
399392
"locator",
400393
"text_display",
@@ -403,7 +396,8 @@
403396
]
404397
},
405398
"name": { "type": "string" },
406-
"uuid": { "type": "string" }
399+
"uuid": { "type": "string" },
400+
"parent": { "type": "string" }
407401
},
408402
"allOf": [
409403
{
@@ -436,23 +430,23 @@
436430
"scale": { "type": "number" },
437431
"configs": {
438432
"type": "object",
439-
"properties": {
440-
"default": {
433+
"patternProperties": {
434+
"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$": {
441435
"$ref": "#/definitions/boneConfig"
442-
},
443-
"variants": {
444-
"type": "object",
445-
"patternProperties": {
446-
".+": {
447-
"$ref": "#/definitions/boneConfig"
448-
}
449-
}
450436
}
451437
}
452438
}
453439
}
454440
}
455441
},
442+
{
443+
"if": {
444+
"properties": {
445+
"type": { "const": "struct" }
446+
}
447+
},
448+
"then": {}
449+
},
456450
{
457451
"if": {
458452
"properties": {
@@ -775,6 +769,10 @@
775769
"type": "array",
776770
"description": "A list of node UUIDs that should be excluded / ignored when this variant is applied.",
777771
"items": { "type": "string" }
772+
},
773+
"is_default": {
774+
"type": "boolean",
775+
"description": "Whether or not this variant is the default variant."
778776
}
779777
}
780778
}

src/blueprintFormat.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ export interface IBlueprintVariantJSON {
9797
* The list of bones that should be ignored when applying the Variant
9898
*/
9999
excluded_nodes: string[]
100+
/**
101+
* Whether or not this is the default Variant
102+
*/
103+
is_default?: true
100104
}
101105

102106
/**

src/systems/animationRenderer.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,14 @@ function threeAxisRotationToTwoAxisRotation(rot: THREE.Quaternion): ArrayVector2
5454
}
5555

5656
export interface INodeTransform {
57-
type: 'bone' | 'camera' | 'locator' | 'text_display' | 'item_display' | 'block_display'
57+
type:
58+
| 'bone'
59+
| 'struct'
60+
| 'camera'
61+
| 'locator'
62+
| 'text_display'
63+
| 'item_display'
64+
| 'block_display'
5865
name: string
5966
uuid: string
6067
node?: Group | NullObject | Locator | OutlinerElement | TextDisplay
@@ -204,6 +211,10 @@ export function getNodeTransforms(
204211
matrix = getNodeMatrix(node.node, 1)
205212
break
206213
}
214+
case 'struct': {
215+
matrix = getNodeMatrix(node.node, 1)
216+
break
217+
}
207218
}
208219

209220
const pos = new THREE.Vector3()

src/systems/jsonCompiler.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/// <reference path="D:/github-repos/snavesutit/blockbench-types/types/index.d.ts"/>
33
/// <reference path="../global.d.ts"/>
44

5-
import { IBlueprintVariantJSON } from '../blueprintFormat'
5+
import type { IBlueprintBoneConfigJSON, IBlueprintVariantJSON } from '../blueprintFormat'
66
import { type defaultValues } from '../blueprintSettings'
77
import { EasingKey } from '../util/easing'
88
import { detectCircularReferences, scrubUndefined } from '../util/misc'
@@ -29,9 +29,10 @@ type ExportedNodetransform = Omit<INodeTransform, 'node' | 'matrix' | 'transform
2929
}
3030
type ExportedRenderedNode = Omit<
3131
AnyRenderedNode,
32-
'node' | 'parentNode' | 'model' | 'boundingBox'
32+
'node' | 'parentNode' | 'model' | 'boundingBox' | 'configs'
3333
> & {
3434
boundingBox?: { min: ArrayVector3; max: ArrayVector3 }
35+
configs?: Record<string, IBlueprintBoneConfigJSON>
3536
}
3637
type ExportedAnimationFrame = Omit<IRenderedFrame, 'nodes' | 'node_transforms'> & {
3738
node_transforms: ExportedNodetransform[]
@@ -68,6 +69,7 @@ type ExportedDynamicAnimation = {
6869
}
6970
interface ISerializedTexture {
7071
name: string
72+
id: string
7173
expectedPath: string
7274
src: string
7375
}
@@ -124,9 +126,10 @@ export function exportJSON(options: {
124126

125127
console.log('Exporting JSON...', options)
126128

127-
function serializeTexture(texture: Texture): ISerializedTexture {
129+
function serializeTexture(id: string, texture: Texture): ISerializedTexture {
128130
return {
129131
name: texture.name,
132+
id,
130133
expectedPath: PathModule.join(
131134
textureExportFolder,
132135
texture.name.endsWith('.png') ? texture.name : texture.name + '.png'
@@ -154,9 +157,9 @@ export function exportJSON(options: {
154157
models: rig.models,
155158
variant_models: rig.variantModels,
156159
textures: Object.fromEntries(
157-
Object.entries(rig.textures).map(([key, texture]) => [
158-
key,
159-
serializeTexture(texture),
160+
Object.entries(rig.textures).map(([id, texture]) => [
161+
texture.uuid,
162+
serializeTexture(id, texture),
160163
])
161164
),
162165
},
@@ -222,6 +225,12 @@ function serailizeRenderedNode(node: AnyRenderedNode): ExportedRenderedNode {
222225
min: node.boundingBox.min.toArray(),
223226
max: node.boundingBox.max.toArray(),
224227
}
228+
delete json.configs
229+
json.configs = { ...node.configs.variants }
230+
const defaultVariant = Variant.getDefault()
231+
if (node.configs.default && defaultVariant) {
232+
json.configs[defaultVariant.uuid] = node.configs.default
233+
}
225234
}
226235
return json as ExportedRenderedNode
227236
}

src/systems/rigRenderer.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ export interface IRenderedNodes {
9696
variants: Record<string, IBlueprintBoneConfigJSON>
9797
}
9898
}
99+
Struct: IRenderedNode & {
100+
type: 'struct'
101+
node: Group
102+
}
99103
Camera: IRenderedNode & {
100104
type: 'camera'
101105
name: string
@@ -166,7 +170,7 @@ export interface IRenderedRig {
166170
*/
167171
nodeStructure: INodeStructure
168172
/**
169-
* A map of texture UUIDs to textures
173+
* A map of texture IDs to textures
170174
*/
171175
textures: Record<string, Texture>
172176
/**
@@ -390,8 +394,19 @@ function renderGroup(group: Group, rig: IRenderedRig): INodeStructure | undefine
390394
}
391395
}
392396

393-
// Don't export groups without a model.
394-
if (group.children.filter(c => c instanceof Cube).length === 0) return structure
397+
// Export a struct instead of a bone if no cubes are present
398+
if (group.children.filter(c => c instanceof Cube).length === 0) {
399+
const struct: IRenderedNodes['Struct'] = {
400+
type: 'struct',
401+
parent: parentId,
402+
parentNode: group.parent instanceof Group ? group.parent : null,
403+
node: group,
404+
name: group.name,
405+
uuid: group.uuid,
406+
}
407+
rig.nodeMap[group.uuid] = struct
408+
return structure
409+
}
395410

396411
const diff = new THREE.Vector3().subVectors(
397412
renderedBone.boundingBox.max,

src/variants.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,18 @@ export class Variant {
134134
events.DELETE_VARIANT.dispatch(this)
135135
}
136136

137-
public toJSON(): IBlueprintVariantJSON {
138-
return {
137+
public toJSON() {
138+
const json: IBlueprintVariantJSON = {
139139
name: this.name,
140140
display_name: this.displayName,
141141
uuid: this.uuid,
142142
texture_map: Object.fromEntries(this.textureMap.map),
143143
excluded_nodes: this.excludedNodes.map(item => item.value),
144144
}
145+
if (this.isDefault) {
146+
json.is_default = true
147+
}
148+
return json
145149
}
146150

147151
public duplicate() {

test_blueprints/armor_stand.ajblueprint

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"meta": {
33
"format": "animated_java_blueprint",
4-
"format_version": "1.0.0",
4+
"format_version": "1.1.0",
55
"uuid": "167b27cd-b559-3f13-a97c-0841fe21f1d1",
66
"save_location": "D:\\github-repos\\animated-java\\animated-java\\test_blueprints\\armor_stand.ajblueprint",
77
"last_used_export_namespace": "armor_stand"
@@ -1445,7 +1445,8 @@
14451445
"display_name": "Default",
14461446
"uuid": "99583e4c-1e3a-b03f-a802-1b5212a6eedb",
14471447
"texture_map": {},
1448-
"excluded_nodes": []
1448+
"excluded_nodes": [],
1449+
"is_default": true
14491450
},
14501451
"list": [
14511452
{

test_blueprints/blockstates.ajblueprint

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"meta": {
33
"format": "animated_java_blueprint",
4-
"format_version": "1.0.0",
4+
"format_version": "1.1.0",
55
"uuid": "0184ff74-4557-e0db-2ecc-efe8a7011a46",
66
"save_location": "D:\\github-repos\\animated-java\\animated-java\\test_blueprints\\blockstates.ajblueprint",
77
"last_used_export_namespace": "blueprint"
@@ -37,7 +37,7 @@
3737
"elements": [
3838
{
3939
"name": "vanilla_block_display",
40-
"position": [3.5, 0, -8],
40+
"position": [12.5, 0, -8],
4141
"rotation": [0, -90, 0],
4242
"scale": [1, 1, 1],
4343
"visibility": true,
@@ -54,7 +54,7 @@
5454
},
5555
{
5656
"name": "vanilla_block_display2",
57-
"position": [-3.5, 0.05, 8.075],
57+
"position": [-12.5, 0.05, 8.075],
5858
"rotation": [0, 90, 0],
5959
"scale": [1, 1, 1],
6060
"visibility": true,
@@ -207,7 +207,7 @@
207207
},
208208
{
209209
"name": "vanilla_block_display",
210-
"position": [1, 6, -4.75],
210+
"position": [1, 6, -7.75],
211211
"rotation": [0, 0, 0],
212212
"scale": [0.25, 0.25, 0.25],
213213
"visibility": true,

0 commit comments

Comments
 (0)