diff --git a/TODO.md b/TODO.md index 81eeaa30..2ea618d5 100644 --- a/TODO.md +++ b/TODO.md @@ -43,12 +43,25 @@ - [ ] Add an option to change the alignment of the text. - [x] Respect inheritance in the bone config. - [x] Change font rendering to use a geometry for each character instead of a single plane for the entire text display. This will open the possibility of loading custom fonts and spacing. +- [x] Add vanilla block displays + - [x] Create a custom element type for block displays. + - [x] Add rendering for vanilla block models. + - [x] Use Blockstates to select models. + - [x] Parent model inheritance + - [x] block/block + - [x] Add overrides for entity-based block models. + - [x] chest + - [x] ender_chest + - [x] mob heads + - [x] shulker boxes + - [x] beds + - [x] multi-parts like walls throw an intneral error if they don't have any elements. +- [x] Add an option to Locators to use the old entity-based functionality. +- [x] Add an about page. - [ ] Camera Plugin Support - [ ] Camera config. - [ ] Data Pack Compiler support. - [ ] Change the Collection setting type to allow single-click swapping of items between lists. -- [ ] Add an about page. -- [ ] Add Variants to the UndoSystem (Blocked by vanilla Blockbench not supporting custom undo actions) - [ ] Add vanilla item displays - [x] Create a custom element type for item displays. - [ ] Add rendering for vanilla item models. @@ -67,20 +80,7 @@ - [x] template_skull - [ ] trident - [x] banners -- [ ] Add vanilla block displays - - [x] Create a custom element type for block displays. - - [x] Add rendering for vanilla block models. - - [x] Use Blockstates to select models. - - [x] Parent model inheritance - - [x] block/block - - [x] Add overrides for entity-based block models. - - [x] chest - - [x] ender_chest - - [x] mob heads - - [x] shulker boxes - - [x] beds - - [x] multi-parts like walls throw an intneral error if they don't have any elements. -- [x] Add an option to Locators to use the old entity-based functionality. +- [ ] Add Variants to the UndoSystem (Blocked by vanilla Blockbench not supporting custom undo actions) # Data Pack Compiler @@ -137,4 +137,5 @@ # Post 1.0.0 - [ ] Add support for [block-display.com's API](https://wiki.block-display.com/api/get-api) +- [ ] Add support for custom fonts in TextDisplays. - [ ] Add support and previewing for interaction entities. diff --git a/package.json b/package.json index ff528611..73cc3d80 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "name": "animated_java", "title": "Animated Java", "version": "0.5.0", + "display_version": "1.0.0-pre1", "min_blockbench_version": "4.10.0", "author": { "name": "Titus Evans (SnaveSutit)", diff --git a/src/blueprintFormat.ts b/src/blueprintFormat.ts index cc33b80e..85e9f9ef 100644 --- a/src/blueprintFormat.ts +++ b/src/blueprintFormat.ts @@ -38,7 +38,7 @@ export interface IBlueprintBoneConfigJSON { export interface IBlueprintLocatorConfigJSON { use_entity?: LocatorConfig['useEntity'] entity_type?: LocatorConfig['entityType'] - summon_commands?: LocatorConfig['entityNBT'] + summon_commands?: LocatorConfig['_summonCommands'] ticking_commands?: LocatorConfig['tickingCommands'] } @@ -613,7 +613,8 @@ export function updateRotationLock() { Group.selected || !!AnimatedJava.API.TextDisplay.selected.length || !!AnimatedJava.API.VanillaItemDisplay.selected.length || - !!AnimatedJava.API.VanillaBlockDisplay.selected.length + !!AnimatedJava.API.VanillaBlockDisplay.selected.length || + !!OutlinerElement.types.camera?.all.length ) BLUEPRINT_FORMAT.rotation_snap = BLUEPRINT_FORMAT.rotation_limit } diff --git a/src/components/about.svelte b/src/components/about.svelte index 0f39467a..b6656147 100644 --- a/src/components/about.svelte +++ b/src/components/about.svelte @@ -10,7 +10,7 @@

Animated Java

-

v{PACKAGE.version}

+

v{PACKAGE.display_version}

diff --git a/src/systems/animated_java.mcb b/src/systems/animated_java.mcb index 6b388840..af6fec0e 100644 --- a/src/systems/animated_java.mcb +++ b/src/systems/animated_java.mcb @@ -163,22 +163,25 @@ dir <%export_namespace%> { } REPEAT (Object.values(rig.nodeMap).filter(v => v.type === 'locator')) as node { IF (node.config.use_entity) { - execute on passengers if entity @s[tag=<%TAGS.PROJECT_DATA(export_namespace)%>] run { with entity @s data.locators.<%node.name%> + execute on passengers if entity @s[tag=<%TAGS.PROJECT_DATA(export_namespace)%>] run { with entity @s data.positions.locators.<%node.name%> $execute as $(uuid) positioned ^$(posx) ^$(posy) ^$(posz) rotated ~$(roty) ~$(rotx) run { tp @s ~ ~ ~ ~ ~ - IF (node.config?.ticking_commands) { - <%node.config.ticking_commands%> - } + <%node.config?.ticking_commands || ''%> } } } ELSE IF (node.config?.ticking_commands) { - execute on passengers if entity @s[tag=<%TAGS.PROJECT_DATA(export_namespace)%>] run { with entity @s data.locators.<%node.name%> + execute on passengers if entity @s[tag=<%TAGS.PROJECT_DATA(export_namespace)%>] run { with entity @s data.positions.locators.<%node.name%> $execute positioned ^$(posx) ^$(posy) ^$(posz) rotated ~$(roty) ~$(rotx) run { <%node.config.ticking_commands%> } } } } + REPEAT (Object.values(rig.nodeMap).filter(v => v.type === 'camera')) as node { + execute on passengers if entity @s[tag=<%TAGS.PROJECT_DATA(export_namespace)%>] run { with entity @s data.positions.cameras.<%node.name%> + $execute as $(uuid) positioned ^$(posx) ^$(posy) ^$(posz) rotated ~$(roty) ~$(rotx) run tp @s ~ ~ ~ ~ ~ + } + } # Rotation Logic execute at @s on passengers run tp @s ~ ~ ~ ~ ~ # Post tick @@ -377,10 +380,13 @@ dir <%export_namespace%> { } } ELSE IF (node.type === 'locator') { IF (rig.nodeMap[node.uuid]?.config?.use_entity || rig.nodeMap[node.uuid]?.config?.ticking_commands) { + <%% + global.rot = getRotationFromQuaternion(node.rot) + %%> execute on passengers if entity @s[tag=<%TAGS.PROJECT_DATA(export_namespace)%>] run \ - data modify entity @s data.locators.<%node.name%> merge value { \ + data modify entity @s data.positions.locators.<%node.name%> merge value { \ posx: <%node.pos.x%>, posy: <%node.pos.y%>, posz: <%node.pos.z%>, \ - rotx: <%node.rot.x%>, roty: <%node.rot.y%>, \ + rotx: <%global.rot.x%>, roty: <%global.rot.y%>, \ } } IF (node.commands) { @@ -395,6 +401,17 @@ dir <%export_namespace%> { <%node.commands%> } } + } ELSE IF (node.type === 'camera') { + IF (rig.nodeMap[node.uuid]) { + <%% + global.rot = getRotationFromQuaternion(node.rot) + %%> + execute on passengers if entity @s[tag=<%TAGS.PROJECT_DATA(export_namespace)%>] run \ + data modify entity @s data.positions.cameras.<%node.name%> merge value { \ + posx: <%node.pos.x%>, posy: <%node.pos.y%>, posz: <%node.pos.z%>, \ + rotx: <%global.rot.x%>, roty: <%global.rot.y%>, \ + } + } } } } @@ -439,14 +456,25 @@ dir <%export_namespace%> { function animated_java:global/internal/gu/convert_uuid_array_to_string with entity @s execute as @e[type=item_display,tag=<%TAGS.NEW()%>,limit=1,distance=..0.01] on passengers if entity @s[tag=<%TAGS.GLOBAL_DATA()%>] run { - data modify entity @s data.locators.<%locator.name%>.uuid set from storage aj:uuid main.out + data modify entity @s data.positions.locators.<%locator.name%>.uuid set from storage aj:uuid main.out } - <%locator.config.summon_commands%> } } } + REPEAT (Object.values(rig.nodeMap).filter(v => v.type === 'camera')) as camera { + summon item_display ~ ~ ~ {Tags:['<%TAGS.NEW()%>', '<%TAGS.GLOBAL_CAMERA()%>', '<%TAGS.PROJECT_CAMERA(export_namespace)%>', '<%TAGS.LOCAL_CAMERA(export_namespace, camera.name)%>'], interpolation_duration: 2} + execute as @e[type=item_display,tag=<%TAGS.NEW()%>,tag=<%TAGS.GLOBAL_CAMERA()%>,limit=1,distance=..0.01] run { + tag @s remove <%TAGS.NEW()%> + + function animated_java:global/internal/gu/convert_uuid_array_to_string with entity @s + execute as @e[type=item_display,tag=<%TAGS.NEW()%>,limit=1,distance=..0.01] on passengers if entity @s[tag=<%TAGS.GLOBAL_DATA()%>] run { + data modify entity @s data.positions.camerass.<%camera.name%>.uuid set from storage aj:uuid main.out + } + } + } + tag @s remove <%TAGS.NEW()%> # Variant Arguement diff --git a/src/systems/datapackCompiler.ts b/src/systems/datapackCompiler.ts index f08d6974..cd15f05f 100644 --- a/src/systems/datapackCompiler.ts +++ b/src/systems/datapackCompiler.ts @@ -220,7 +220,7 @@ async function generateRootEntityPassengers(rig: IRenderedRig, rigHash: string) 'data', new NbtCompound() .set('rigHash', new NbtString(rigHash)) - .set('locators', createLocatorPositionStorage(rig)) + .set('positions', createPositionStorage(rig)) ) ) @@ -274,13 +274,6 @@ async function generateRootEntityPassengers(rig: IRenderedRig, rigHash: string) passenger.set('width', new NbtFloat(aj.bounding_box[0])) break } - case 'camera': { - passenger.set('id', new NbtString('minecraft:item_display')) - tags.add(new NbtString(TAGS.GLOBAL_CAMERA())) - tags.add(new NbtString(TAGS.PROJECT_CAMERA(aj.export_namespace))) - tags.add(new NbtString(TAGS.LOCAL_CAMERA(aj.export_namespace, node.name))) - break - } case 'text_display': { passenger.set('id', new NbtString('minecraft:text_display')) tags.add(new NbtString(TAGS.GLOBAL_BONE())) @@ -434,19 +427,32 @@ function createAnimationStorage(animations: IRenderedAnimation[]) { return storage } -function createLocatorPositionStorage(rig: IRenderedRig) { +function getRotationFromQuaternion(q: THREE.Quaternion) { + const euler = new THREE.Euler().setFromQuaternion(q, 'YXZ') + const rot = new THREE.Vector3(euler.x, euler.y, euler.z).multiplyScalar(180 / Math.PI) + rot.x *= -1 + rot.y = rot.y * -1 + 180 + return rot +} + +function createPositionStorage(rig: IRenderedRig) { const storage = new NbtCompound() + const locators = new NbtCompound() + const cameras = new NbtCompound() + storage.set('locators', locators) + storage.set('cameras', cameras) for (const node of Object.values(rig.defaultPose)) { - if (node.type !== 'locator') continue - storage.set( + if (node.type !== 'locator' && node.type !== 'camera') continue + const rot = getRotationFromQuaternion(node.rot) + ;(node.type === 'locator' ? locators : cameras).set( node.name, new NbtCompound() .set('uuid', new NbtString('')) .set('posx', new NbtFloat(node.pos.x)) .set('posy', new NbtFloat(node.pos.y)) .set('posz', new NbtFloat(node.pos.z)) - .set('rotx', new NbtFloat(node.rot.x)) - .set('roty', new NbtFloat(node.rot.y)) + .set('rotx', new NbtFloat(Math.radToDeg(rot.x))) + .set('roty', new NbtFloat(Math.radToDeg(rot.y))) ) } return storage @@ -568,6 +574,7 @@ export async function compileDataPack(options: { BoneConfig, roundTo, nodeSorter, + getRotationFromQuaternion, } console.log('Compiler Variables:', variables) diff --git a/test_blueprints/armor_stand.ajblueprint b/test_blueprints/armor_stand.ajblueprint index df7102ad..396f12cd 100644 --- a/test_blueprints/armor_stand.ajblueprint +++ b/test_blueprints/armor_stand.ajblueprint @@ -1,7 +1,7 @@ { "meta": { "format": "animated_java_blueprint", - "format_version": "1.0.0", + "format_version": "0.5.0", "uuid": "167b27cd-b559-3f13-a97c-0841fe21f1d1", "save_location": "D:\\github-repos\\animated-java\\animated-java\\test_blueprints\\armor_stand.ajblueprint", "last_used_export_namespace": "armor_stand" @@ -958,6 +958,17 @@ }, "uuid": "a2ebcf74-9f58-df75-9b42-f565d9d6e42c", "type": "locator" + }, + { + "name": "camera", + "path": "", + "position": [0, 40, 31], + "rotation": [-22.5, -22.5, 0], + "linked_preview": "", + "camera_linked": false, + "visibility": true, + "type": "camera", + "uuid": "d0076177-a6cf-561c-08d8-efd07677b337" } ], "outliner": [ @@ -1471,7 +1482,8 @@ "visibility": true, "autouv": 0, "children": ["a2ebcf74-9f58-df75-9b42-f565d9d6e42c"] - } + }, + "d0076177-a6cf-561c-08d8-efd07677b337" ], "textures": [ {