Merge branch 'master' into next

This commit is contained in:
JannisX11 2023-05-28 12:14:50 +02:00
commit 4260d6bb58
55 changed files with 945 additions and 785 deletions

View File

@ -1,21 +1,28 @@
name: Bug / Issue
description: Use this form to report an issue that occurs when using Blockbench
title: "[Issue] Issue summary"
title: "Issue Summary"
body:
- type: markdown
attributes:
value: |
- Before you report an issue, check if if has already been reported.
- Also check if you are using the latest version of Blockbench.
- Please only report one issue per issue.
- If applicable, go to Help > Developer > Open Dev Tools. Switch to the Console tab. If there are any (red) error messages, please attach a screenshot of them.
- type: markdown
attributes:
value: |
Please make sure to provide the following information:
- type: textarea
id: details
id: description
attributes:
label: Detailed description of your issue
label: What are you trying to do, and what do you expect to happen?
validations:
required: true
- type: textarea
id: error
attributes:
label: What happens instead?
validations:
required: true
- type: input
@ -40,4 +47,8 @@ body:
attributes:
label: Operating System
validations:
required: true
required: true
- type: input
id: plugins
attributes:
label: Installed Blockbench plugins

View File

@ -1,6 +1,6 @@
name: Suggestion
description: Use this form to suggest features or improvements for Blockbench
title: "[Suggestion] Suggestion summary"
title: "Suggestion Summary"
body:
- type: markdown
attributes:

View File

@ -578,6 +578,10 @@
display: none;
margin-top: -4px;
}
.contextMenu.scrollable {
max-height: min(500px, 100vh);
overflow: auto;
}
.contextMenu li {
display: flex;
height: 30px;

View File

@ -1386,7 +1386,7 @@
background-color: var(--color-ui);
right: 12px;
margin-top: 29px;
z-index: 2;
z-index: 5;
}
#timeline_graph_editor_amplifier > div {
position: absolute;

View File

@ -477,7 +477,13 @@ class Animation extends AnimationItem {
}
}
get time() {
return (this.length && this.loop === 'loop') ? ((Timeline.time - 0.001) % this.length) + 0.001 : Timeline.time;
if (!this.length || this.loop == 'once') {
return Timeline.time;
} else if (this.loop === 'loop') {
return ((Timeline.time - 0.001) % this.length) + 0.001;
} else if (this.loop === 'hold') {
return Math.min(Timeline.time, this.length);
}
}
createUniqueName(arr) {
var scope = this;
@ -953,8 +959,8 @@ const Animator = {
Canvas.outlines.children.empty()
Canvas.updateAllPositions()
}
if (Animation.all.length && !Animation.all.includes(Animation.selected)) {
Animation.all[0].select();
if (AnimationItem.all.length && !AnimationItem.all.includes(Animation.selected)) {
AnimationItem.all[0].select();
} else if (!Animation.all.length) {
Timeline.selected.empty();
}
@ -1116,6 +1122,9 @@ const Animator = {
if (!node.constructor.animator) return;
Animator.resetLastValues();
animations.forEach(animation => {
if (animation.loop == 'once' && Timeline.time > animation.length && animation.length) {
return;
}
let multiplier = animation.blend_weight ? Math.clamp(Animator.MolangParser.parse(animation.blend_weight), 0, Infinity) : 1;
if (typeof controller_blend_values[animation.uuid] == 'number') multiplier *= controller_blend_values[animation.uuid];
animation.getBoneAnimator(node).displayFrame(multiplier);
@ -1143,7 +1152,7 @@ const Animator = {
let controller = AnimationController.selected;
let {selected_state, last_state} = controller;
let state_time = selected_state.getStateTime();
let blend_progress = (selected_state.blend_transition && last_state) ? Math.clamp(state_time / selected_state.blend_transition, 0, 1) : 1;
let blend_progress = (last_state && last_state.blend_transition) ? Math.clamp(state_time / last_state.blend_transition, 0, 1) : 1;
// Active State
Timeline.time = state_time;

View File

@ -104,7 +104,7 @@ class AnimationControllerState {
// From Bedrock
if (data.particle_effects instanceof Array) {
this.particles.empty();
data.particles.forEach(effect => {
data.particle_effects.forEach(effect => {
let particle = {
uuid: guid(),
effect: effect.effect || '',
@ -118,7 +118,7 @@ class AnimationControllerState {
}
if (data.sound_effects instanceof Array) {
this.sounds.empty();
data.sounds.forEach(effect => {
data.sound_effects.forEach(effect => {
let sound = {
uuid: guid(),
effect: effect.effect || '',
@ -1064,7 +1064,8 @@ Interface.definePanels(() => {
let menu = new Menu('controller_state_transitions', list, {searchable: list.length > 9});
menu.open(event.target);
},
openParticleMenu(state, particle) {
openParticleMenu(state, particle, event) {
if (getFocusedTextInput()) return;
new Menu('controller_state_particle', [
{
name: 'generic.remove',
@ -1075,9 +1076,11 @@ Interface.definePanels(() => {
Undo.finishEdit('Remove particle from controller state');
}
}
])
]).open(event);
event.stopPropagation();
},
openSoundMenu(state, sound) {
openSoundMenu(state, sound, event) {
if (getFocusedTextInput()) return;
new Menu('controller_state_sound', [
{
name: 'generic.remove',
@ -1088,7 +1091,8 @@ Interface.definePanels(() => {
Undo.finishEdit('Remove sound from controller state');
}
}
])
]).open(event);
event.stopPropagation();
},
addAnimationButton(state, event) {
state.select();
@ -1568,7 +1572,7 @@ Interface.definePanels(() => {
</div>
</div>
<ul v-if="!state.fold.particles">
<li v-for="particle in state.particles" :key="particle.uuid" class="controller_particle" @contextmenu="openParticleMenu(state, particle)">
<li v-for="particle in state.particles" :key="particle.uuid" class="controller_particle" @contextmenu="openParticleMenu(state, particle, $event)">
<div class="bar flex">
<label>${tl('data.effect')}</label>
<input type="text" class="dark_bordered tab_target animation_controller_text_input" v-model="particle.effect">
@ -1612,7 +1616,7 @@ Interface.definePanels(() => {
</div>
</div>
<ul v-if="!state.fold.sounds">
<li v-for="sound in state.sounds" :key="sound.uuid" class="controller_sound" @contextmenu="openSoundMenu(state, sound)">
<li v-for="sound in state.sounds" :key="sound.uuid" class="controller_sound" @contextmenu="openSoundMenu(state, sound, $event)">
<div class="bar flex">
<label>${tl('data.effect')}</label>
<input type="text" class="dark_bordered tab_target animation_controller_text_input" v-model="sound.effect">

View File

@ -1,14 +1,14 @@
Animator.MolangParser.context = {};
Animator.MolangParser.global_variables = {
'true': 1,
'false': 0,
get 'query.delta_time'() {
let time = (Date.now() - Timeline.last_frame_timecode + 1) / 1000;
let time = (Date.now() - Timeline.last_frame_timecode) / 1000;
if (time < 0) time += 1;
return Math.clamp(time, 0, 0.1);
},
get 'query.anim_time'() {
return Animation.selected ? Animation.selected.time : Timeline.time;
return Animator.MolangParser.context.animation ? Animator.MolangParser.context.animation.time : Timeline.time;
},
get 'query.life_time'() {
return Timeline.time;
@ -69,6 +69,9 @@ Animator.MolangParser.global_variables = {
get 'query.is_first_person'() {
return Project.bedrock_animation_mode == 'attachable_first' ? 1 : 0;
},
get 'context.is_first_person'() {
return Project.bedrock_animation_mode == 'attachable_first' ? 1 : 0;
},
get 'time'() {
return Timeline.time;
}

View File

@ -213,12 +213,13 @@ const Timeline = {
Timeline.revealTime(seconds)
},
revealTime(time) {
var scroll = $('#timeline_body').scrollLeft();
let body = document.getElementById('timeline_body');
var scroll = body.scrollLeft;
var playhead = time * Timeline.vue._data.size + 8;
if (playhead < scroll || playhead > scroll + $('#timeline_vue').width() - Timeline.vue._data.head_width) {
$('#timeline_body').scrollLeft(playhead-16);
if (playhead < scroll || playhead > scroll + document.getElementById('timeline_vue').clientWidth - Timeline.vue._data.head_width) {
body.scrollLeft = playhead-16;
} else if (time == 0) {
$('#timeline_body').scrollLeft(0);
body.scrollLeft = 0;
}
},
setTimecode(time) {
@ -228,7 +229,7 @@ const Timeline = {
let f = Math.floor((time%1) * second_fractions)
if ((s+'').length === 1) {s = '0'+s}
if ((f+'').length === 1) {f = '0'+f}
$('#timeline_timestamp').text(m + ':' + s + ':' + f)
Timeline.vue.timestamp = `${m}:${s}:${f}`;
},
snapTime(time, animation) {
//return time;
@ -501,8 +502,8 @@ const Timeline = {
if (Animation.selected.loop == 'hold') {
time = Math.clamp(time, 0, Animation.selected.length);
}
Timeline.setTime(time);
Timeline.last_frame_timecode = Date.now();
Timeline.setTime(time);
} else {
if (Animation.selected.loop == 'loop' || BarItems.looped_animation_playback.value) {
@ -653,6 +654,7 @@ Interface.definePanels(() => {
waveforms: Timeline.waveforms,
focus_channel: null,
playhead: Timeline.time,
timestamp: '0',
graph_editor_open: false,
graph_editor_channel: 'rotation',
@ -1214,7 +1216,11 @@ Interface.definePanels(() => {
value = Math.round(value*100)/100;
for (let kf of keyframes) {
let target_value = (original_values[kf.uuid] - original_range[anchor_side]) * value + original_range[anchor_side];
let origin = original_range[anchor_side];
if (e2.altKey) {
origin = Math.lerp(original_range[0], original_range[1], 0.5);
}
target_value = (original_values[kf.uuid] - origin) * value + origin;
kf.offset(axis, -kf.get(axis) + target_value);
values_changed = true;
}
@ -1282,7 +1288,7 @@ Interface.definePanels(() => {
<div id="timeline_vue" :class="{graph_editor: graph_editor_open}">
<div id="timeline_header">
<div id="timeline_corner" v-bind:style="{width: head_width+'px'}">
<div id="timeline_timestamp"></div>
<div id="timeline_timestamp">{{ timestamp }}</div>
<div class="channel_axis_selector" v-if="graph_editor_open">
<div @click="graph_editor_axis = 'x';" :class="{selected: graph_editor_axis == 'x'}" style="color: var(--color-axis-x);">X</div>
<div @click="graph_editor_axis = 'y';" :class="{selected: graph_editor_axis == 'y'}" style="color: var(--color-axis-y);">Y</div>

View File

@ -444,6 +444,7 @@ class BoneAnimator extends GeneralAnimator {
displayFrame(multiplier = 1) {
if (!this.doRender()) return;
this.getGroup()
Animator.MolangParser.context.animation = this.animation;
if (!this.muted.rotation) this.displayRotation(this.interpolate('rotation'), multiplier)
if (!this.muted.position) this.displayPosition(this.interpolate('position'), multiplier)

View File

@ -202,7 +202,7 @@ const Blockbench = {
text: {full_width: true, placeholder, value}
},
onConfirm({text}) {
callback(text);
if (callback) callback(text);
resolve(text);
},
onOpen() {

View File

@ -447,7 +447,7 @@ class Tool extends Action {
}
if (this.allowed_view_modes && !this.allowed_view_modes.includes(Project.view_mode)) {
Project.view_mode = 'textured';
Canvas.updateAllFaces()
BarItems.view_mode.change('textured');
}
if (this.toolbar && Toolbars[this.toolbar]) {
Toolbars[this.toolbar].toPlace('tool_options')
@ -1502,7 +1502,7 @@ class Toolbar {
if (item === action || item.id === action) {
item.toolbars.remove(this)
this.children.splice(i, 1)
this.update().save();
this.update(true).save();
return this;
}
i--;
@ -1520,7 +1520,7 @@ class Toolbar {
}
this.previously_enabled = enabled;
}
if (!enabled) return this;
if (!enabled && !force) return this;
// check if some unkown actions are now known
if (this.postload) {

View File

@ -751,14 +751,14 @@ window.Dialog = class Dialog {
let buttons = []
this.buttons.forEach((b, i) => {
let btn = $('<button type="button">'+tl(b)+'</button> ')
buttons.push(btn)
btn.on('click', (event) => {
let btn = Interface.createElement('button', {type: 'button'}, tl(b));
buttons.push(btn);
btn.addEventListener('click', (event) => {
this.close(i, event);
})
})
buttons[this.confirmIndex] && buttons[this.confirmIndex].addClass('confirm_btn')
buttons[this.cancelIndex] && buttons[this.cancelIndex].addClass('cancel_btn')
buttons[this.confirmIndex] && buttons[this.confirmIndex].classList.add('confirm_btn')
buttons[this.cancelIndex] && buttons[this.cancelIndex].classList.add('cancel_btn')
let button_bar = $('<div class="dialog_bar button_bar"></div>');
buttons.forEach((button, i) => {
@ -968,7 +968,7 @@ window.MessageBox = class MessageBox extends Dialog {
let text = tl(typeof command == 'string' ? command : command.text);
let entry = Interface.createElement('li', {class: 'dialog_message_box_command'}, text)
entry.addEventListener('click', e => {
this.close(id, results);
this.close(id, results, e);
})
list.append(entry);
}
@ -1001,14 +1001,14 @@ window.MessageBox = class MessageBox extends Dialog {
let buttons = []
this.buttons.forEach((b, i) => {
let btn = $('<button type="button">'+tl(b)+'</button> ')
buttons.push(btn)
btn.on('click', (event) => {
let btn = Interface.createElement('button', {type: 'button'}, tl(b));
buttons.push(btn);
btn.addEventListener('click', (event) => {
this.close(i, results, event);
})
})
buttons[this.confirmIndex] && buttons[this.confirmIndex].addClass('confirm_btn')
buttons[this.cancelIndex] && buttons[this.cancelIndex].addClass('cancel_btn')
buttons[this.confirmIndex] && buttons[this.confirmIndex].classList.add('confirm_btn')
buttons[this.cancelIndex] && buttons[this.cancelIndex].classList.add('cancel_btn')
let button_bar = $('<div class="dialog_bar button_bar"></div>');
buttons.forEach((button, i) => {

View File

@ -949,18 +949,7 @@ BARS.defineActions(function() {
for (let id in Panels) {
let panel = Panels[id];
if (!Interface.data.panels[id]) Interface.data.panels[id] = {};
panel.position_data = Interface.data.panels[id];
let defaultp = panel.default_position || 0;
if (!panel.position_data.slot) panel.position_data.slot = defaultp.slot || 'left_bar';
if (!panel.position_data.float_position)panel.position_data.float_position = defaultp.float_position || [0, 0];
if (!panel.position_data.float_size) panel.position_data.float_size = defaultp.float_size || [300, 300];
if (!panel.position_data.height) panel.position_data.height = defaultp.height || 300;
if (panel.position_data.folded == undefined) panel.position_data.folded = defaultp.folded || false;
panel.moveTo(panel.slot);
panel.resetCustomLayout();
}
Blockbench.dispatchEvent('reset_layout', {});

View File

@ -186,9 +186,14 @@ class Menu {
node.addClass('hybrid_parent');
let more_button = Interface.createElement('div', {class: 'menu_more_button'}, Blockbench.getIconNode('more_horiz'));
node.append(more_button);
$(more_button).mouseenter(e => {
more_button.addEventListener('mouseenter', e => {
scope.hover(node.get(0), e, true);
})
more_button.addEventListener('mouseleave', e => {
if (node.is(':hover') && !childlist.is(':hover')) {
scope.hover(node, e);
}
})
}
} else {
node.addClass('parent');
@ -251,9 +256,13 @@ class Menu {
getEntry(object, menu_node);
})
}
var last = menu_node.children().last();
if (last.length && last.hasClass('menu_separator')) {
last.remove()
let nodes = menu_node.children();
if (nodes.length && nodes.last().hasClass('menu_separator')) {
nodes.last().remove();
}
if (!nodes.toArray().find(node => node.classList.contains('parent') || node.classList.contains('hybrid_parent'))) {
menu_node.addClass('scrollable');
}
}
@ -472,12 +481,16 @@ class Menu {
if (position && position.clientWidth) offset_left += position.clientWidth;
if (offset_left < 0) offset_left = 0;
}
if (!this.options.searchable) {
if (offset_top > window_height - el_height ) {
if (offset_top > window_height - el_height ) {
if (el_height < offset_top - 50) {
// Snap to element top
offset_top -= el_height;
if (position instanceof HTMLElement) {
offset_top -= position.clientHeight;
}
} else {
// Move up
offset_top = window_height - el_height;
}
}
offset_top = Math.max(offset_top, 26);

View File

@ -468,6 +468,7 @@ const MenuBar = {
singleButton: true
}).show();
}},
'reset_layout',
{name: 'menu.help.developer.reset_storage', icon: 'fas.fa-hdd', click: () => {
if (confirm(tl('menu.help.developer.reset_storage.confirm'))) {
localStorage.clear()

View File

@ -334,7 +334,19 @@ class Panel extends EventSystem {
this.position_data.folded = !!state;
}
resetCustomLayout() {
if (!Interface.data.panels[this.id]) Interface.data.panels[this.id] = {};
this.position_data = Interface.data.panels[this.id];
let defaultp = this.default_position || 0;
if (!this.position_data.slot) this.position_data.slot = defaultp.slot || 'left_bar';
if (!this.position_data.float_position) this.position_data.float_position = defaultp.float_position || [0, 0];
if (!this.position_data.float_size) this.position_data.float_size = defaultp.float_size || [300, 300];
if (!this.position_data.height) this.position_data.height = defaultp.height || 300;
if (this.position_data.folded == undefined) this.position_data.folded = defaultp.folded || false;
this.moveTo(this.slot);
this.fold(this.folded);
return this;
}
addToolbar(toolbar, position = this.toolbars.length) {
let nodes = [];

View File

@ -155,7 +155,7 @@ onVueSetup(function() {
},
{
source: "./assets/splash_art/2.png",
description: "Splash Art 2nd Place by [MorganFreeguy](https://morganfreeguy.artstation.com/) & [WOLLAND](https://wolland-services.com/)",
description: "Splash Art 2nd Place by [MorganFreeguy](https://www.artstation.com/morganfreeguy) & [WOLLAND](https://wolland-services.com/)",
},
{
source: "./assets/splash_art/3.png",

View File

@ -217,6 +217,7 @@ window.BedrockEntityManager = class BedrockEntityManager {
}
}
initAnimations() {
this.initialized_animations = true;
let anim_list = this.client_entity && this.client_entity.description && this.client_entity.description.animations;
if (anim_list instanceof Object) {
let animation_names = [];
@ -256,7 +257,6 @@ window.BedrockEntityManager = class BedrockEntityManager {
} catch (err) {}
})
}
this.initialized_animations = true;
}
findEntityTexture(mob, return_path) {
if (!mob) return;

View File

@ -667,9 +667,6 @@ var codec = new Codec('fbx', {
let curve_name = `AnimCurve::${unique_name}.${track.channel[0].toUpperCase()}${axis_letter}`;
let values = track.values.filter((val, i) => (i % 3) == axis_number);
if (track.channel == 'position') {
values.forEach((v, i) => values[i] = v * 100);
}
if (track.channel == 'rotation') {
values.forEach((v, i) => values[i] = Math.radToDeg(v));
}

View File

@ -121,6 +121,9 @@ const codec = new Codec('skin_model', {
group.addTo(parent_group)
})
}
if (!Cube.all.find(cube => cube.box_uv)) {
Project.box_uv = false;
}
if (texture_path) {
var texture = new Texture().fromPath(texture_path).add(false);
} else if (resolution) {

View File

@ -7,6 +7,19 @@ function setupDragHandlers() {
loadImages(files, event)
}
)
Blockbench.addDragHandler(
'reference_image',
{extensions: ['jpg', 'jpeg', 'bmp', 'tiff', 'tif', 'gif'], propagate: true, readtype: 'image', condition: () => !Dialog.open},
function(files, event) {
files.map(file => {
return new ReferenceImage({
source: file.content,
name: file.name || 'Reference'
}).addAsReference(true);
}).last().select();
ReferenceImageMode.activate();
}
)
Blockbench.addDragHandler(
'model',
{extensions: Codec.getAllExtensions},
@ -125,7 +138,7 @@ async function loadImages(files, event) {
} else if (method == 'reference_image') {
files.map(file => {
new ReferenceImage({
return new ReferenceImage({
source: file.content,
name: file.name || 'Reference'
}).addAsReference(true);
@ -658,7 +671,7 @@ BARS.defineActions(function() {
}
}
}
if (Format.animation_mode && Format.animation_files && Animation.all.length) {
if (Format.animation_mode && Format.animation_files && AnimationItem.all.length) {
BarItems.save_all_animations.trigger();
}
} else {
@ -695,7 +708,7 @@ BARS.defineActions(function() {
Project.saved = false;
}*/
}
Blockbench.dispatchEvent('save_model_action', {event});
Blockbench.dispatchEvent('quick_save_model', {});
}
})
if (!isApp) {

View File

@ -301,6 +301,7 @@ class ModelProject {
if (TextureAnimator.isPlaying) TextureAnimator.stop();
this.selected = false;
Painter.current = {};
Animator.MolangParser.context = {};
scene.remove(this.model_3d);
OutlinerNode.uuids = {};
Format = 0;

View File

@ -104,7 +104,7 @@ BARS.defineActions(function() {
title: 'action.add_mesh',
form: {
shape: {label: 'dialog.add_primitive.shape', type: 'select', options: {
cube: 'dialog.add_primitive.shape.cube',
cuboid: 'dialog.add_primitive.shape.cube',
pyramid: 'dialog.add_primitive.shape.pyramid',
plane: 'dialog.add_primitive.shape.plane',
circle: 'dialog.add_primitive.shape.circle',
@ -115,8 +115,8 @@ BARS.defineActions(function() {
torus: 'dialog.add_primitive.shape.torus',
}},
diameter: {label: 'dialog.add_primitive.diameter', type: 'number', value: 16},
align_edges: {label: 'dialog.add_primitive.align_edges', type: 'checkbox', value: true, condition: ({shape}) => !['cube', 'pyramid', 'plane'].includes(shape)},
height: {label: 'dialog.add_primitive.height', type: 'number', value: 8, condition: ({shape}) => ['cylinder', 'cone', 'cube', 'pyramid', 'tube'].includes(shape)},
align_edges: {label: 'dialog.add_primitive.align_edges', type: 'checkbox', value: true, condition: ({shape}) => !['cuboid', 'pyramid', 'plane'].includes(shape)},
height: {label: 'dialog.add_primitive.height', type: 'number', value: 8, condition: ({shape}) => ['cylinder', 'cone', 'cuboid', 'pyramid', 'tube'].includes(shape)},
sides: {label: 'dialog.add_primitive.sides', type: 'number', value: 12, min: 3, max: 48, condition: ({shape}) => ['cylinder', 'cone', 'circle', 'torus', 'sphere', 'tube'].includes(shape)},
minor_diameter: {label: 'dialog.add_primitive.minor_diameter', type: 'number', value: 4, condition: ({shape}) => ['torus', 'tube'].includes(shape)},
minor_sides: {label: 'dialog.add_primitive.minor_sides', type: 'number', value: 8, min: 2, max: 32, condition: ({shape}) => ['torus'].includes(shape)},
@ -321,7 +321,7 @@ BARS.defineActions(function() {
}
}
}
if (result.shape == 'cube') {
if (result.shape == 'cuboid') {
let r = result.diameter/2;
let h = result.height;
mesh.addVertices([r, h, r], [r, h, -r], [r, 0, r], [r, 0, -r], [-r, h, r], [-r, h, -r], [-r, 0, r], [-r, 0, -r]);
@ -391,7 +391,7 @@ BARS.defineActions(function() {
Undo.amendEdit({
diameter: {label: 'dialog.add_primitive.diameter', type: 'number', value: result.diameter, interval_type: 'position'},
height: {label: 'dialog.add_primitive.height', type: 'number', value: result.height, condition: ['cylinder', 'cone', 'cube', 'pyramid', 'tube'].includes(result.shape), interval_type: 'position'},
height: {label: 'dialog.add_primitive.height', type: 'number', value: result.height, condition: ['cylinder', 'cone', 'cuboid', 'pyramid', 'tube'].includes(result.shape), interval_type: 'position'},
sides: {label: 'dialog.add_primitive.sides', type: 'number', value: result.sides, min: 3, max: 48, condition: ['cylinder', 'cone', 'circle', 'torus', 'sphere', 'tube'].includes(result.shape)},
minor_diameter: {label: 'dialog.add_primitive.minor_diameter', type: 'number', value: result.minor_diameter, condition: ['torus', 'tube'].includes(result.shape), interval_type: 'position'},
minor_sides: {label: 'dialog.add_primitive.minor_sides', type: 'number', value: result.minor_sides, min: 2, max: 32, condition: ['torus'].includes(result.shape)},
@ -420,7 +420,7 @@ BARS.defineActions(function() {
vertex: {name: true, icon: 'fiber_manual_record'},
},
icon_mode: true,
condition: () => Modes.edit && Mesh.all.length,
condition: () => Modes.edit && Mesh.hasAny(),
onChange({value}) {
if (value === previous_selection_mode) return;
if (value === 'object') {
@ -516,7 +516,7 @@ BARS.defineActions(function() {
category: 'tools',
selectElements: true,
modes: ['edit'],
condition: () => Modes.edit && Mesh.all.length,
condition: () => Modes.edit && Mesh.hasAny(),
onCanvasClick(data) {
if (!seam_timeout) {
seam_timeout = setTimeout(() => {
@ -545,21 +545,15 @@ BARS.defineActions(function() {
divide: true,
join: true,
},
condition: () => Modes.edit && Mesh.all.length,
condition: () => Modes.edit && Mesh.hasAny(),
onChange({value}) {
if (value == 'auto') value = null;
Undo.initEdit({elements: Mesh.selected});
Mesh.selected.forEach(mesh => {
let selected_vertices = mesh.getSelectedVertices();
mesh.forAllFaces((face) => {
let vertices = face.getSortedVertices();
vertices.forEach((vkey_a, i) => {
let vkey_b = vertices[i+1] || vertices[0];
if (selected_vertices.includes(vkey_a) && selected_vertices.includes(vkey_b)) {
mesh.setSeam([vkey_a, vkey_b], value);
}
})
});
let selected_edges = mesh.getSelectedEdges();
selected_edges.forEach(edge => {
mesh.setSeam(edge, value);
})
Mesh.preview_controller.updateSelection(mesh);
})
Undo.finishEdit('Set mesh seam');
@ -1072,15 +1066,9 @@ BARS.defineActions(function() {
if (original_vertices.length < 3) return;
original_vertices = original_vertices.slice();
let new_vertices;
let selected_faces = [];
let selected_face_keys = [];
for (let key in mesh.faces) {
let face = mesh.faces[key];
if (face.isSelected()) {
selected_faces.push(face);
selected_face_keys.push(key);
}
}
let selected_face_keys = mesh.getSelectedFaces();
let selected_faces = selected_face_keys.map(fkey => mesh.faces[fkey]);
let modified_face_keys = selected_face_keys.slice();
new_vertices = mesh.addVertices(...original_vertices.map(vkey => {
let vector = mesh.vertices[vkey].slice();
@ -1137,15 +1125,24 @@ BARS.defineActions(function() {
if (vertices.length == 2 && i) return; // Only create one quad when extruding line
if (selected_faces.find(f => f != face && f.vertices.includes(a) && f.vertices.includes(b))) return;
let new_face_vertices = [
b,
a,
original_vertices[new_vertices.indexOf(a)],
original_vertices[new_vertices.indexOf(b)],
];
let new_face_uv = {
[a]: face.uv[a],
[b]: face.uv[b],
[new_face_vertices[2]]: face.uv[a],
[new_face_vertices[3]]: face.uv[b],
};
let new_face = new MeshFace(mesh, mesh.faces[selected_face_keys[face_index]]).extend({
vertices: [
b,
a,
original_vertices[new_vertices.indexOf(a)],
original_vertices[new_vertices.indexOf(b)],
]
vertices: new_face_vertices,
uv: new_face_uv
});
mesh.addFaces(new_face);
let [fkey] = mesh.addFaces(new_face);
modified_face_keys.push(fkey);
remaining_vertices.remove(a);
remaining_vertices.remove(b);
})
@ -1165,6 +1162,7 @@ BARS.defineActions(function() {
}
delete mesh.vertices[b];
})
UVEditor.setAutoSize(null, true, modified_face_keys);
})
Undo.finishEdit('Extrude mesh selection')
@ -1315,85 +1313,117 @@ BARS.defineActions(function() {
}
}
} else if (direction > 2) {
// Split tri from edge to edge
} else if (face.vertices.length == 3) {
if (direction > 2) {
// Split tri from edge to edge
let opposed_vertex = sorted_vertices.find(vkey => !side_vertices.includes(vkey));
let opposite_vertices = [opposed_vertex, side_vertices[direction % side_vertices.length]];
let opposed_vertex = sorted_vertices.find(vkey => !side_vertices.includes(vkey));
let opposite_vertices = [opposed_vertex, side_vertices[direction % side_vertices.length]];
let opposite_index_diff = sorted_vertices.indexOf(opposite_vertices[0]) - sorted_vertices.indexOf(opposite_vertices[1]);
if (opposite_index_diff == 1 || opposite_index_diff < -2) opposite_vertices.reverse();
let opposite_index_diff = sorted_vertices.indexOf(opposite_vertices[0]) - sorted_vertices.indexOf(opposite_vertices[1]);
if (opposite_index_diff == 1 || opposite_index_diff < -2) opposite_vertices.reverse();
let center_vertices = [
getCenterVertex(side_vertices),
getCenterVertex(opposite_vertices)
]
let center_vertices = [
getCenterVertex(side_vertices),
getCenterVertex(opposite_vertices)
]
let c1_uv_coords = [
Math.lerp(face.uv[side_vertices[0]][0], face.uv[side_vertices[1]][0], offset/length),
Math.lerp(face.uv[side_vertices[0]][1], face.uv[side_vertices[1]][1], offset/length),
];
let c2_uv_coords = [
Math.lerp(face.uv[opposite_vertices[0]][0], face.uv[opposite_vertices[1]][0], offset/length),
Math.lerp(face.uv[opposite_vertices[0]][1], face.uv[opposite_vertices[1]][1], offset/length),
];
let c1_uv_coords = [
Math.lerp(face.uv[side_vertices[0]][0], face.uv[side_vertices[1]][0], offset/length),
Math.lerp(face.uv[side_vertices[0]][1], face.uv[side_vertices[1]][1], offset/length),
];
let c2_uv_coords = [
Math.lerp(face.uv[opposite_vertices[0]][0], face.uv[opposite_vertices[1]][0], offset/length),
Math.lerp(face.uv[opposite_vertices[0]][1], face.uv[opposite_vertices[1]][1], offset/length),
];
let other_quad_vertex = side_vertices.find(vkey => !opposite_vertices.includes(vkey));
let other_tri_vertex = side_vertices.find(vkey => opposite_vertices.includes(vkey));
let new_face = new MeshFace(mesh, face).extend({
vertices: [other_tri_vertex, center_vertices[0], center_vertices[1]],
uv: {
[other_tri_vertex]: face.uv[other_tri_vertex],
[center_vertices[0]]: c1_uv_coords,
[center_vertices[1]]: c2_uv_coords,
let other_quad_vertex = side_vertices.find(vkey => !opposite_vertices.includes(vkey));
let other_tri_vertex = side_vertices.find(vkey => opposite_vertices.includes(vkey));
let new_face = new MeshFace(mesh, face).extend({
vertices: [other_tri_vertex, center_vertices[0], center_vertices[1]],
uv: {
[other_tri_vertex]: face.uv[other_tri_vertex],
[center_vertices[0]]: c1_uv_coords,
[center_vertices[1]]: c2_uv_coords,
}
})
if (new_face.getAngleTo(face) > 90) {
new_face.invert();
}
})
if (new_face.getAngleTo(face) > 90) {
new_face.invert();
}
face.extend({
vertices: [opposed_vertex, center_vertices[0], center_vertices[1], other_quad_vertex],
uv: {
[opposed_vertex]: face.uv[opposed_vertex],
[center_vertices[0]]: c1_uv_coords,
[center_vertices[1]]: c2_uv_coords,
[other_quad_vertex]: face.uv[other_quad_vertex],
face.extend({
vertices: [opposed_vertex, center_vertices[0], center_vertices[1], other_quad_vertex],
uv: {
[opposed_vertex]: face.uv[opposed_vertex],
[center_vertices[0]]: c1_uv_coords,
[center_vertices[1]]: c2_uv_coords,
[other_quad_vertex]: face.uv[other_quad_vertex],
}
})
if (face.getAngleTo(new_face) > 90) {
face.invert();
}
})
if (face.getAngleTo(new_face) > 90) {
face.invert();
}
mesh.addFaces(new_face);
mesh.addFaces(new_face);
// Find next (and previous) face
for (let fkey in mesh.faces) {
let ref_face = mesh.faces[fkey];
if (ref_face.vertices.length < 3 || processed_faces.includes(ref_face)) continue;
let vertices = ref_face.vertices.filter(vkey => opposite_vertices.includes(vkey))
if (vertices.length >= 2) {
splitFace(ref_face, opposite_vertices, ref_face.vertices.length == 4);
break;
}
}
if (double_side) {
// Find next (and previous) face
for (let fkey in mesh.faces) {
let ref_face = mesh.faces[fkey];
if (ref_face.vertices.length < 3 || processed_faces.includes(ref_face)) continue;
let vertices = ref_face.vertices.filter(vkey => side_vertices.includes(vkey))
let vertices = ref_face.vertices.filter(vkey => opposite_vertices.includes(vkey))
if (vertices.length >= 2) {
let ref_sorted_vertices = ref_face.getSortedVertices();
let ref_opposite_vertices = ref_sorted_vertices.filter(vkey => !side_vertices.includes(vkey));
if (ref_opposite_vertices.length == 2) {
splitFace(ref_face, ref_opposite_vertices, ref_face.vertices.length == 4);
break;
splitFace(ref_face, opposite_vertices, ref_face.vertices.length == 4);
break;
}
}
if (double_side) {
for (let fkey in mesh.faces) {
let ref_face = mesh.faces[fkey];
if (ref_face.vertices.length < 3 || processed_faces.includes(ref_face)) continue;
let vertices = ref_face.vertices.filter(vkey => side_vertices.includes(vkey))
if (vertices.length >= 2) {
let ref_sorted_vertices = ref_face.getSortedVertices();
let ref_opposite_vertices = ref_sorted_vertices.filter(vkey => !side_vertices.includes(vkey));
if (ref_opposite_vertices.length == 2) {
splitFace(ref_face, ref_opposite_vertices, ref_face.vertices.length == 4);
break;
}
}
}
}
} else {
let opposite_vertex = sorted_vertices.find(vkey => !side_vertices.includes(vkey));
let center_vertex = getCenterVertex(side_vertices);
let c1_uv_coords = [
Math.lerp(face.uv[side_vertices[0]][0], face.uv[side_vertices[1]][0], offset/length),
Math.lerp(face.uv[side_vertices[0]][1], face.uv[side_vertices[1]][1], offset/length),
];
let new_face = new MeshFace(mesh, face).extend({
vertices: [side_vertices[1], center_vertex, opposite_vertex],
uv: {
[side_vertices[1]]: face.uv[side_vertices[1]],
[center_vertex]: c1_uv_coords,
[opposite_vertex]: face.uv[opposite_vertex],
}
})
face.extend({
vertices: [opposite_vertex, center_vertex, side_vertices[0]],
uv: {
[opposite_vertex]: face.uv[opposite_vertex],
[center_vertex]: c1_uv_coords,
[side_vertices[0]]: face.uv[side_vertices[0]],
}
})
if (direction % 3 == 2) {
new_face.invert();
face.invert();
}
mesh.addFaces(new_face);
}
} else {
let opposite_vertex = sorted_vertices.find(vkey => !side_vertices.includes(vkey));
} else if (face.vertices.length == 2) {
let center_vertex = getCenterVertex(side_vertices);
@ -1403,25 +1433,19 @@ BARS.defineActions(function() {
];
let new_face = new MeshFace(mesh, face).extend({
vertices: [side_vertices[1], center_vertex, opposite_vertex],
vertices: [side_vertices[1], center_vertex],
uv: {
[side_vertices[1]]: face.uv[side_vertices[1]],
[center_vertex]: c1_uv_coords,
[opposite_vertex]: face.uv[opposite_vertex],
}
})
face.extend({
vertices: [opposite_vertex, center_vertex, side_vertices[0]],
vertices: [center_vertex, side_vertices[0]],
uv: {
[opposite_vertex]: face.uv[opposite_vertex],
[center_vertex]: c1_uv_coords,
[side_vertices[0]]: face.uv[side_vertices[0]],
}
})
if (direction % 3 == 2) {
new_face.invert();
face.invert();
}
mesh.addFaces(new_face);
}
}

View File

@ -578,6 +578,12 @@ function moveElementsInSpace(difference, axis) {
m.applyEuler(selection_rotation);
difference_vec.V3_set(m.x, m.y, m.z);
} else if (space instanceof Group) {
let m = vector.set(0, 0, 0);
m[getAxisLetter(axis)] = difference;
m.applyQuaternion(new THREE.Quaternion().copy(el.mesh.quaternion).invert());
difference_vec.V3_set(m.x, m.y, m.z);
} else {
let m = vector.set(0, 0, 0);
m[getAxisLetter(axis)] = difference;

View File

@ -58,9 +58,6 @@ class Group extends OutlinerNode {
init() {
super.init();
Project.groups.push(this);
if (typeof this.parent !== 'object') {
this.addTo();
}
if (!this.mesh || !this.mesh.parent) {
this.constructor.preview_controller.setup(this);
}

View File

@ -895,7 +895,7 @@ new NodePreviewController(Mesh, {
mesh.vertex_points.geometry.computeBoundingSphere();
mesh.outline.geometry.computeBoundingSphere();
updateCubeHighlights()
Mesh.preview_controller.updateHighlight(element);
if (Modes.paint) {
Mesh.preview_controller.updatePaintingGrid(element);

View File

@ -115,9 +115,8 @@ class OutlinerNode {
return this.constructor.preview_controller;
}
//Sorting
sortInBefore(element, index_mod) {
sortInBefore(element, index_mod = 0) {
var index = -1;
index_mod = index_mod || 0;
if (element.parent === 'root') {
index = Outliner.root.indexOf(element)
@ -520,6 +519,12 @@ class OutlinerElement extends OutlinerNode {
console.warn('You cannot modify this')
}
})
OutlinerElement.hasAny = function() {
return Outliner.elements.length > 0 && Outliner.elements.findIndex(element => element instanceof this) !== -1;
}
OutlinerElement.hasSelected = function() {
return Outliner.selected.length > 0 && Outliner.selected.findIndex(element => element instanceof this) !== -1;
}
OutlinerElement.types = {};

View File

@ -483,7 +483,7 @@ async function loadInstalledPlugins() {
load_counter++;
console.log(`🧩📁 Loaded plugin "${plugin.id || plugin.path}" from file`);
} else {
Plugins.installed.remove(plugin)
Plugins.installed.remove(plugin);
}
} else if (plugin.source == 'url') {
@ -493,8 +493,12 @@ async function loadInstalledPlugins() {
console.log(`🧩🌐 Loaded plugin "${plugin.id || plugin.path}" from URL`);
} else {
load_counter++;
console.log(`🧩🛒 Loaded plugin "${plugin.id}" from store`)
if (Plugins.all.find(p => p.id == plugin.id)) {
load_counter++;
console.log(`🧩🛒 Loaded plugin "${plugin.id}" from store`);
} else {
Plugins.installed.remove(plugin);
}
}
})
console.log(`Loaded ${load_counter} plugin${pluralS(load_counter)}`)

View File

@ -737,6 +737,9 @@ class Preview {
}
let select_mode = BarItems.selection_mode.value
if (!Condition(BarItems.selection_mode.condition)) {
select_mode = 'object';
}
if (Toolbox.selected.selectElements && Modes.selected.selectElements && data.type === 'element') {
if (Toolbox.selected.selectFace && data.face) {
@ -1349,6 +1352,7 @@ class Preview {
}
delete() {
this.renderer.dispose();
this.renderer.forceContextLoss()
this.canvas.remove();
this.node.remove();
Blockbench.removeDragHandler('preview_'+this.id)

View File

@ -104,6 +104,7 @@ class ReferenceImage {
}
addAsReference(save) {
Project.reference_images.push(this);
if (Preview.selected && Preview.selected.isOrtho) this.changeLayer('blueprint');
this.scope = 'project';
this.update();
if (save) this.save();
@ -111,6 +112,7 @@ class ReferenceImage {
}
addAsGlobalReference(save) {
ReferenceImage.global.push(this);
if (Preview.selected && Preview.selected.isOrtho) this.changeLayer('blueprint');
this.scope = 'global';
this.update();
if (save) this.save();
@ -257,6 +259,11 @@ class ReferenceImage {
pos_y *= preview.camOrtho.backgroundHandle[1].n === true ? 1 : -1;
pos_x += preview.width/2;
pos_y += preview.height/2;
if (quad_previews.enabled) {
pos_x += preview.node.parentElement.offsetLeft;
pos_y += preview.node.parentElement.offsetTop;
}
pos_x += (this.position[0] * zoom) - (this.size[0] * zoom) / 2;
pos_y += (this.position[1] * zoom) - (this.size[1] * zoom) / 2;
@ -292,6 +299,7 @@ class ReferenceImage {
let corner = Interface.createElement('div', {class: 'reference_image_resize_corner '+direction});
let sign_x = direction[1] == 'e' ? 1 : -1;
let sign_y = direction[0] == 's' ? 1 : -1;
let multiplier = 1 / this.getZoomLevel();
addEventListeners(corner, 'mousedown touchstart', e1 => {
convertTouchEvent(e1);
@ -301,8 +309,8 @@ class ReferenceImage {
let move = (e2) => {
convertTouchEvent(e2);
let offset = [
(e2.clientX - e1.clientX),
(e2.clientY - e1.clientY),
(e2.clientX - e1.clientX) * multiplier,
(e2.clientY - e1.clientY) * multiplier,
];
this.size[0] = Math.max(original_size[0] + offset[0] * sign_x, 48);
this.position[0] = original_position[0] + offset[0] / 2, 0;
@ -520,9 +528,12 @@ class ReferenceImage {
}
async delete(force) {
if (!force) {
let img = new Image();
img.src = this.source;
let result = await new Promise(resolve => Blockbench.showMessageBox({
title: 'data.reference_image',
message: 'message.delete_reference_image',
icon: img,
buttons: ['dialog.confirm', 'dialog.cancel']
}, resolve));
if (result == 1) return;
@ -534,8 +545,8 @@ class ReferenceImage {
case 'global': ReferenceImage.global.remove(this); break;
case 'built_in': ReferenceImage.built_in.remove(this); break;
}
this.removed = true;
this.save();
this.removed = true;
this.node.remove();
}
changeLayer(layer) {
@ -774,6 +785,7 @@ const ReferenceImageMode = {
Interface.work_screen.classList.add('reference_image_mode');
Interface.work_screen.append(ReferenceImageMode.toolbar.node);
ReferenceImage.updateAll();
BARS.updateConditions();
setTimeout(_ => {
if (!ReferenceImage.selected && ReferenceImage.active[0]) {
ReferenceImage.active[0].select();
@ -786,6 +798,7 @@ const ReferenceImageMode = {
Interface.work_screen.classList.remove('reference_image_mode');
ReferenceImageMode.toolbar.node.remove();
ReferenceImage.updateAll();
BARS.updateConditions();
},
async importReferences(files) {
let save_mode = await new Promise(resolve => {

View File

@ -460,16 +460,19 @@ const Painter = {
let softness = BarItems.slider_brush_softness.get()/100;
let b_opacity = BarItems.slider_brush_opacity.get()/255;
let tool = Toolbox.selected;
let matrix_id = Painter.current.element
? (Painter.current.element.uuid + Painter.current.face)
: Painter.current.face;
ctx.clip()
if (Painter.current.element instanceof Mesh) {
let face = Painter.current.element.faces[Painter.current.face];
if (face && face.vertices.length > 2 && !Painter.current.face_matrices[Painter.current.face]) {
Painter.current.face_matrices[Painter.current.face] = face.getOccupationMatrix(true, [0, 0]);
if (face && face.vertices.length > 2 && !Painter.current.face_matrices[matrix_id]) {
Painter.current.face_matrices[matrix_id] = face.getOccupationMatrix(true, [0, 0]);
let island = face.getUVIsland();
for (let fkey of island) {
let face = Painter.current.element.faces[fkey];
face.getOccupationMatrix(true, [0, 0], Painter.current.face_matrices[Painter.current.face]);
face.getOccupationMatrix(true, [0, 0], Painter.current.face_matrices[matrix_id]);
}
}
}
@ -497,27 +500,20 @@ const Painter = {
tool.brush.draw({ctx, x, y, size, softness, texture, event});
} else {
let run_per_pixel = (pxcolor, local_opacity, px, py) => {
if (Painter.current.face_matrices[matrix_id] && settings.paint_side_restrict.value) {
let matrix = Painter.current.face_matrices[matrix_id];
if (!matrix[px] || !matrix[px][py % texture.display_height]) {
return pxcolor;
}
}
return tool.brush.changePixel(px, py, pxcolor, local_opacity, {color, opacity: b_opacity, ctx, x, y, size, softness, texture, event});
}
let shape = BarItems.brush_shape.value;
if (shape == 'square') {
Painter.editSquare(ctx, x, y, size, softness, function(pxcolor, local_opacity, px, py) {
if (Painter.current.face_matrices[Painter.current.face] && settings.paint_side_restrict.value) {
let matrix = Painter.current.face_matrices[Painter.current.face];
if (!matrix[px] || !matrix[px][py % texture.display_height]) {
return pxcolor;
}
}
return tool.brush.changePixel(px, py, pxcolor, local_opacity, {color, opacity: b_opacity, ctx, x, y, size, softness, texture, event});
})
Painter.editSquare(ctx, x, y, size, softness, run_per_pixel);
} else if (shape == 'circle') {
Painter.editCircle(ctx, x, y, size, softness, function(pxcolor, local_opacity, px, py) {
if (Painter.current.face_matrices[Painter.current.face] && settings.paint_side_restrict.value) {
let matrix = Painter.current.face_matrices[Painter.current.face];
if (!matrix[px] || !matrix[px][py % texture.display_height]) {
return pxcolor;
}
}
return tool.brush.changePixel(px, py, pxcolor, local_opacity, {color, opacity: b_opacity, ctx, x, y, size, softness, texture, event});
})
Painter.editCircle(ctx, x, y, size, softness, run_per_pixel);
}
}
@ -572,8 +568,8 @@ const Painter = {
if (fill_mode === 'face' && fkey !== Painter.current.face) continue;
if (face.vertices.length <= 2 || face.getTexture() !== texture) continue;
let matrix = Painter.current.face_matrices[fkey] || face.getOccupationMatrix(true, [0, 0]);
Painter.current.face_matrices[fkey] = matrix;
let matrix = Painter.current.face_matrices[element.uuid + fkey] || face.getOccupationMatrix(true, [0, 0]);
Painter.current.face_matrices[element.uuid + fkey] = matrix;
for (let x in matrix) {
for (let y in matrix[x]) {
if (!matrix[x][y]) continue;

View File

@ -783,6 +783,8 @@ class Texture {
if ((Texture.all.length > 1 || !Format.edit_mode) && Modes.paint && !UVEditor.getReferenceFace()) {
UVEditor.vue.updateTexture();
}
Blockbench.dispatchEvent('select_texture', {texture: this});
Blockbench.dispatchEvent('update_texture_selection');
return this;
}
add(undo) {
@ -827,6 +829,7 @@ class Texture {
}
Project.textures.splice(Texture.all.indexOf(this), 1)
delete Project.materials[this.uuid];
Blockbench.dispatchEvent('update_texture_selection');
if (!no_update) {
Canvas.updateAllFaces()
TextureAnimator.updateButton()
@ -1736,31 +1739,29 @@ function loadTextureDraggable() {
Undo.finishEdit('Reorder textures')
} else if ($('#cubes_list:hover').length) {
var target_node = $('#cubes_list li.outliner_node.drag_hover').last().get(0);
let target_node = $('#cubes_list li.outliner_node.drag_hover').last().get(0);
$('.drag_hover').removeClass('drag_hover');
if (!target_node) return;
let uuid = target_node.id;
var target = OutlinerNode.uuids[uuid];
var array = [];
let target = OutlinerNode.uuids[uuid];
let array = [];
if (target.type === 'group') {
target.forEachChild(function(cube) {
array.push(cube)
}, [Cube, Mesh])
target.forEachChild((element) => {
array.push(element);
})
} else {
array = selected.includes(target) ? selected : [target];
}
array = array.filter(element => element.applyTexture);
Undo.initEdit({elements: array, uv_only: true})
array.forEach(function(cube) {
for (var face in cube.faces) {
cube.faces[face].texture = tex.uuid;
}
})
Undo.finishEdit('Drop texture')
array.forEach(element => {
element.applyTexture(tex, true);
});
Undo.finishEdit('Apply texture')
UVEditor.loadData()
Canvas.updateAllFaces()
} else if ($('#uv_viewport:hover').length) {
UVEditor.applyTexture(tex);
}
@ -1775,7 +1776,8 @@ function unselectTextures() {
s.selected = false;
})
Texture.selected = undefined;
Canvas.updateLayeredTextures()
Canvas.updateLayeredTextures();
Blockbench.dispatchEvent('update_texture_selection');
}
function getTexturesById(id) {
if (id === undefined) return;

View File

@ -777,7 +777,7 @@ const UVEditor = {
plane = new THREE.Plane();
this.getMappableElements().forEach(obj => {
var top2, left2;
let height, width;
let faces = face_keys || this.getFaces(obj, event);
if (obj instanceof Cube) {
faces.forEach(function(side) {
@ -787,21 +787,25 @@ const UVEditor = {
face.uv[0] = Math.min(face.uv[0], face.uv[2]);
face.uv[1] = Math.min(face.uv[1], face.uv[3]);
if (side == 'north' || side == 'south') {
left2 = limitNumber(obj.size('0'), 0, Project.texture_width)
top2 = limitNumber(obj.size('1'), 0, Project.texture_height)
width = obj.size(0);
height = obj.size(1);
} else if (side == 'east' || side == 'west') {
left2 = limitNumber(obj.size('2'), 0, Project.texture_width)
top2 = limitNumber(obj.size('1'), 0, Project.texture_height)
width = obj.size(2);
height = obj.size(1);
} else if (side == 'up' || side == 'down') {
left2 = limitNumber(obj.size('0'), 0, Project.texture_width)
top2 = limitNumber(obj.size('2'), 0, Project.texture_height)
width = obj.size(0);
height = obj.size(2);
}
if (face.rotation % 180) {
[left2, top2] = [top2, left2];
[width, height] = [height, width];
}
left2 *= UVEditor.getResolution(0, face) / Project.texture_width;
top2 *= UVEditor.getResolution(1, face) / Project.texture_height;
face.uv_size = [left2, top2];
width *= UVEditor.getResolution(0, face) / Project.texture_width;
height *= UVEditor.getResolution(1, face) / Project.texture_height;
width = Math.clamp(width, 0, Project.texture_width);
height = Math.clamp(height, 0, Project.texture_height);
face.uv[0] = Math.min(face.uv[0], Project.texture_width - width);
face.uv[1] = Math.min(face.uv[1], Project.texture_height - height);
face.uv_size = [width, height];
if (mirror_x) [face.uv[0], face.uv[2]] = [face.uv[2], face.uv[0]];
if (mirror_y) [face.uv[1], face.uv[3]] = [face.uv[3], face.uv[1]];
})
@ -2129,6 +2133,9 @@ Interface.definePanels(function() {
this.texture.canvas.style.objectPosition = `0 ${-this.texture.currentFrame * this.inner_height}px`;
this.texture.canvas.style.objectFit = this.texture.frameCount > 1 ? 'cover' : 'fill';
this.texture.canvas.style.imageRendering = this.texture.width < this.inner_width ? 'inherit' : 'auto';
if (wrapper.firstChild) {
wrapper.firstChild.remove();
}
wrapper.append(this.texture.canvas);
})
}
@ -2634,7 +2641,7 @@ Interface.definePanels(function() {
} else {
this.selected_faces.forEach(key => {
if (element.faces[key] && element instanceof Cube) {
if (element.faces[key] && element instanceof Cube && element.faces[key].texture !== null) {
diff_x = Math.clamp(diff_x, -element.faces[key].uv[0], Project.texture_width - element.faces[key].uv[0]);
diff_y = Math.clamp(diff_y, -element.faces[key].uv[1], Project.texture_height - element.faces[key].uv[1]);
diff_x = Math.clamp(diff_x, -element.faces[key].uv[2], Project.texture_width - element.faces[key].uv[2]);
@ -2658,7 +2665,7 @@ Interface.definePanels(function() {
element.uv_offset[1] = Math.floor(element.uv_offset[1] + diff_y);
} else {
this.selected_faces.forEach(key => {
if (element.faces[key] && element instanceof Cube) {
if (element.faces[key] && element instanceof Cube && element.faces[key].texture !== null) {
element.faces[key].uv[0] += diff_x;
element.faces[key].uv[1] += diff_y;
element.faces[key].uv[2] += diff_x;

View File

@ -342,6 +342,7 @@ class UndoSystem {
}
if (Texture.selected == tex) {
Texture.selected = undefined;
Blockbench.dispatchEvent('update_texture_selection');
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Auslösung übersteigt das Maximum von %0",
"dialog.copy_to_clipboard": "In Zwischenablage kopieren",
"dialog.open_url": "Link öffnen",
"reference_image.image": "Bild"
"reference_image.image": "Bild",
"uv_editor.rotate_uv": "UV drehen",
"projects.start_screen": "Start Screen"
}

View File

@ -106,6 +106,7 @@
"mode.start.quick_setup.more_themes": "More...",
"projects.new_tab": "New Tab",
"projects.start_screen": "Start Screen",
"projects.close_tab": "Close Tab",
"format.free": "Generic Model",
@ -1963,6 +1964,7 @@
"uv_editor.all_faces": "All",
"uv_editor.no_faces": "None",
"uv_editor.rotated": "Rotated",
"uv_editor.rotate_uv": "Rotate UV",
"uv_editor.scale_uv": "Scale UV",
"uv_editor.auto_cull": "Cullface To Self",
"uv_editor.copied": "Copied Face",

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1790,7 +1790,7 @@
"message.save_codec_selector.message": "Select a format to save the model in.",
"message.save_codec_selector.project_file": "Blockbench Project (.bbmodel)",
"message.save_codec_selector.both": "Both",
"message.display_skin.username": "Username (Java)",
"message.display_skin.username": "Nom d'utilisateur (Java)",
"message.palette_locked": "La palette est verrouillée",
"dialog.project.default_uv_mode": "Default UV Mode",
"dialog.project.default_uv_mode.description": "Default UV Mode of the project. The UV mode can also be changed per cube.",
@ -1807,20 +1807,20 @@
"dialog.mirror_painting_texture_center.middle": "Middle",
"dialog.mirror_painting_texture_center.custom": "Custom",
"dialog.settings.reset_to_default": "Reset to Default",
"keybindings.item.num_slider.increase": "Increase",
"keybindings.item.num_slider.decrease": "Decrease",
"keybindings.item.num_slider.increase": "Augmenter",
"keybindings.item.num_slider.decrease": "Diminuer",
"settings.always_show_splash_art": "Always Show Splash Art",
"settings.always_show_splash_art.desc": "Always display the splash art on the start screen",
"action.slider_palette_color": "Switch Palette Color",
"action.slider_palette_color.desc": "Cycle between the colors in the palette",
"action.proportional_editing": "Édition proportionnelle",
"action.proportional_editing.desc": "Proportionally affect surrounding vertices when editing parts of a mesh",
"action.limit_to_palette": "Limit to Palette",
"action.limit_to_palette": "Limiter à la palette",
"action.limit_to_palette.desc": "Limits the colors of the texture to those in the currently loaded palette",
"action.edit_reference_images": "Modifier les images de référence",
"action.edit_reference_images.desc": "Turn on reference image mode to add or edit reference images and blueprints",
"action.add_reference_image": "Ajouter une image de référence",
"action.reference_image_from_clipboard": "Reference Image from Clipboard",
"action.reference_image_from_clipboard": "Image de référence du presse-papier",
"action.reference_image_list": "Images de référence",
"action.connect_uv_faces": "Connect UV Faces",
"action.connect_uv_faces.desc": "Connect the selected UV faces to the last selected UV face",
@ -1871,5 +1871,7 @@
"texture.error.too_large": "La résolution dépasse le maximum de %0",
"dialog.copy_to_clipboard": "Copier dans le presse-papier",
"dialog.open_url": "Ouvrir l'URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -504,7 +504,7 @@
"action.uv_grid.desc": "UV 선택기가 스냅하는 격자의 해상도",
"action.uv_grid.auto": "자동",
"action.uv_maximize": "UV 최대화",
"action.uv_maximize.desc": "이 표면의 UV를 전체 텍스로 설정",
"action.uv_maximize.desc": "이 표면의 UV를 전체 텍스로 설정",
"action.uv_auto": "자동 UV",
"action.uv_auto.desc": "이 표면의 UV 크기를 표면의 실제 크기로 설정",
"action.uv_rel_auto": "상대적 자동 UV",
@ -663,7 +663,7 @@
"message.outdated_client.title": "업데이트 되지 않은 클라이언트",
"message.outdated_client.message": "이 작업을 하려면 Blockbench를 최신 버전으로 업데이트해야 합니다.",
"action.export_asset_archive": "압축파일 다운로드",
"action.export_asset_archive.desc": "모델과 모든 텍스가 포함된 압축 파일을 다운로드",
"action.export_asset_archive.desc": "모델과 모든 텍스가 포함된 압축 파일을 다운로드",
"action.upload_sketchfab": "Sketchfab 업로드",
"message.sketchfab.name_or_token": "Sketchfab 토큰과 이름 입력",
"dialog.sketchfab_uploader.title": "Sketchfab 모델 업로드",
@ -744,12 +744,12 @@
"message.wireframe.disabled": "와이어프레임 뷰 비활성화",
"dialog.convert_project.title": "프로젝트 변환",
"dialog.convert_project.text": "이 프로젝트를 전환하시겠습니까? 이것은 되돌릴 수 없습니다.",
"dialog.create_texture.double_use": "다중 텍스 점유 유지",
"dialog.create_texture.double_use": "다중 텍스 점유 유지",
"dialog.model_stats.title": "모델 상태",
"dialog.model_stats.cubes": "큐브들",
"dialog.model_stats.locators": "로케이터",
"dialog.model_stats.groups": "그룹들",
"dialog.model_stats.vertices": "수직",
"dialog.model_stats.vertices": "정점",
"dialog.model_stats.faces": "표면들",
"settings.username": "닉네임",
"settings.username.desc": "수정된 세션을 위한 닉네임",
@ -766,7 +766,7 @@
"action.save_project_as": "다른 이름으로 프로젝트 저장",
"action.save_project_as.desc": "새로운 곳에 현재 프로젝트를 저장",
"action.export_over": "모델 저장",
"action.export_over.desc": "파일을 덮어쓰고 모델, 텍스 및 애니메이션 저장",
"action.export_over.desc": "파일을 덮어쓰고 모델, 텍스 및 애니메이션 저장",
"action.add_locator": "로케이터 추가",
"action.add_locator.desc": "입자, 리쉬 등을 제어하기 위한 새 로케이터 추가",
"action.uv_turn_mapping": "매핑 전환",
@ -1163,8 +1163,8 @@
"message.keymap_loaded": "키맵핑 로드됨",
"dialog.convert_project.current_format": "현재 포맷",
"dialog.create_texture.rearrange_uv.desc": "새로운 UV 배열을 만들어 모든 표면에 질감에 대한 자체 지점을 생성",
"dialog.create_texture.compress.desc": "UV 맵을 조밀한 레이아웃으로 배열하여 텍스 크기를 최소화",
"dialog.create_texture.power.desc": "자동 텍스 크기를 64 또는 128과 같은 2의 거듭제곱으로 잠금. 일부 렌더러가 요구됨",
"dialog.create_texture.compress.desc": "UV 맵을 조밀한 레이아웃으로 배열하여 텍스 크기를 최소화",
"dialog.create_texture.power.desc": "자동 텍스 크기를 64 또는 128과 같은 2의 거듭제곱으로 잠금. 일부 렌더러가 요구됨",
"dialog.create_texture.double_use.desc": "두 요소가 이미 동일한 UV 공간을 할당한 경우 새 맵에 그대로 유지",
"dialog.create_texture.padding.desc": "템플릿의 개별 부위 사이에 작은 여백을 추가",
"dialog.create_texture.resolution.desc": "텍스쳐의 높이 및 폭",
@ -1504,9 +1504,9 @@
"action.resize_texture": "텍스쳐 크기 조정...",
"action.view_mode.uv": "UV 미리보기",
"action.append_to_template": "요소를 템플릿에 추가...",
"action.append_to_template.desc": "현재 선택한 요소를 텍스 템플릿에 추가함",
"action.append_to_template.desc": "현재 선택한 요소를 텍스 템플릿에 추가함",
"action.move_texture_with_uv": "UV와 텍스쳐 이동",
"action.move_texture_with_uv.desc": "UV 표면을 드래그할 때 표면의 텍스처를 이동합니다.",
"action.move_texture_with_uv.desc": "UV 표면을 드래그할 때 표면의 텍스쳐를 이동합니다",
"action.timeline_setups": "타임라인 설정",
"action.save_timeline_setup": "타임라인 설정 저장...",
"action.save_timeline_setup.desc": "현재 선택한 애니메이터 및 채널의 프리셋 저장",
@ -1609,7 +1609,7 @@
"action.blend_mode.hard_light": "하드 라이트",
"action.blend_mode.difference": "차이",
"action.copy_brush": "브러시 복사",
"action.copy_brush.desc": "브러시로 텍스의 일부를 복제하거나 패턴을 그립니다. Ctrl 키를 누른 상태에서 클릭하여 복사 할 곳을 선택합니다.",
"action.copy_brush.desc": "브러시로 텍스의 일부를 복제하거나 패턴을 그립니다. Ctrl 키를 누른 상태에서 클릭하여 복사 할 곳을 선택합니다.",
"action.validator_window": "모델 문제 보기...",
"action.validator_window.desc": "현재 모델의 문제를 나열하는 유효성 검사기를 엽니다.",
"action.cancel_gif": "GIF 취소",
@ -1624,14 +1624,14 @@
"menu.mirror_painting.global.desc": "전역 공간에서 모델에 반전 칠하기 사용",
"menu.mirror_painting.local": "지역 대칭",
"menu.mirror_painting.local.desc": "각 요소에 대해 로컬 공간에서 반전 칠하기 사용",
"menu.mirror_painting.texture_frames": "애니메이션 텍스 프레임에서 반복",
"menu.mirror_painting.texture_frames.desc": "애니메이션 텍스의 모든 프레임에 대한 반전 페인트 스트로크",
"menu.mirror_painting.texture_frames": "애니메이션 텍스 프레임에서 반복",
"menu.mirror_painting.texture_frames.desc": "애니메이션 텍스의 모든 프레임에 대한 반전 페인트 스트로크",
"format.bedrock_block.info.size_limit": "크기 블록의 전체 크기는 모든 곳에서 30픽셀로 제한됩니다. 제한은 블록 중심에서 7픽셀만큼 모든 방향으로 중심을 벗어날 수 있습니다.",
"format.bedrock_block.info.textures": "Blockbench에서는 여러 큐브에 여러 텍스를 적용할 수 있지만 게임 내에서 올바르게 작동하려면 행동 팩에서 추가 설정이 필요합니다.",
"format.bedrock_block.info.textures": "Blockbench에서는 여러 큐브에 여러 텍스를 적용할 수 있지만 게임 내에서 올바르게 작동하려면 행동 팩에서 추가 설정이 필요합니다.",
"format.image.desc": "2D 이미지 편집기에서 이미지 편집",
"generic.delete_all": "모두 삭제",
"message.child_model_only.open": "부모 열기",
"message.child_model_only.open_with_textures": "부모 열기 & 텍스 선택",
"message.child_model_only.open_with_textures": "부모 열기 & 텍스 선택",
"dialog.project.credit": "크레딧",
"dialog.convert_project.create_copy": "사본 생성",
"dialog.texture.frame_time": "프레임 시간",
@ -1686,16 +1686,16 @@
"action.center_lateral": "중앙 측면",
"action.center_lateral.desc": "선택한 요소를 X 및 Z축 중앙에 배치",
"action.adjust_opacity": "불투명도 조정...",
"action.adjust_opacity.desc": "선택한 텍스의 불투명도를 조정",
"action.rotate_texture_cw": "텍스를 시계 방향으로 회전",
"action.rotate_texture_ccw": "텍스를 시계 반대 방향으로 회전",
"action.adjust_opacity.desc": "선택한 텍스의 불투명도를 조정",
"action.rotate_texture_cw": "텍스를 시계 방향으로 회전",
"action.rotate_texture_ccw": "텍스를 시계 반대 방향으로 회전",
"action.predicate_overrides": "조건자 재정의 편집...",
"action.predicate_overrides.desc": "선택한 조건에 따라 이 모델을 재정의하려면 모델을 선택하세요.",
"action.auto_set_cullfaces": "후면 제거를 자동으로 설정",
"action.auto_set_cullfaces.desc": "인접한 블록에 의해 가려질 때 면을 숨기기 위해 후면 제거를 자동으로 생성합니다.",
"menu.texture.edit_externally": "외부에서 편집",
"menu.mirror_painting.texture": "2D 편집기 대칭",
"menu.mirror_painting.texture.desc": "이미지 또는 텍스의 2D 공간에서 반전 칠하기 활성화",
"menu.mirror_painting.texture.desc": "이미지 또는 텍스의 2D 공간에서 반전 칠하기 활성화",
"menu.animator.rotation_global": "전역 공간에서 회전",
"uv_editor.face_properties": "표면 속성",
"uv_editor.face_properties.material_instance": "머티리얼 인스턴스",
@ -1776,100 +1776,102 @@
"settings.only_selected_bezier_handles": "선택한 베지어 핸들만 표시하기",
"settings.only_selected_bezier_handles.desc": "현재 선택되지 않은 베지어 키프레임의 핸들 숨기기",
"settings.embed_textures": "텍스쳐 임베드",
"settings.embed_textures.desc": "텍스 파일 콘텐츠를 .bbmodel 파일에 임베드",
"settings.embed_textures.desc": "텍스 파일 콘텐츠를 .bbmodel 파일에 임베드",
"action.selection_mode.cluster": "클러스터",
"dialog.copied_to_clipboard": "Copied to clipboard",
"data.reference_image": "Reference Image",
"message.delete_reference_image": "Are you sure you want to delete this reference image? This cannot be undone.",
"message.add_reference_image.message": "Select where to load the reference image",
"message.add_reference_image.project": "Add to this project",
"message.add_reference_image.app": "Add to all projects",
"message.import_particle_texture.import": "Import Particle Texture",
"message.import_particle_texture.message": "Would you like to import a texture file to be used for your particle?",
"message.save_codec_selector.title": "Save Model Format",
"message.save_codec_selector.message": "Select a format to save the model in.",
"message.save_codec_selector.project_file": "Blockbench Project (.bbmodel)",
"message.save_codec_selector.both": "Both",
"message.display_skin.username": "Username (Java)",
"message.palette_locked": "The palette is locked",
"dialog.project.default_uv_mode": "Default UV Mode",
"dialog.project.default_uv_mode.description": "Default UV Mode of the project. The UV mode can also be changed per cube.",
"dialog.export_options.title": "Export Options",
"dialog.edit_texture.preview": "Preview",
"dialog.proportional_editing.range": "Range",
"dialog.proportional_editing.falloff": "Falloff",
"dialog.proportional_editing.falloff.linear": "Linear",
"dialog.proportional_editing.falloff.hermite_spline": "Smooth",
"dialog.proportional_editing.falloff.constant": "Constant",
"dialog.proportional_editing.selection": "Selection",
"dialog.proportional_editing.selection.linear": "Linear Distance",
"dialog.proportional_editing.selection.connections": "Connections",
"dialog.mirror_painting_texture_center.middle": "Middle",
"dialog.mirror_painting_texture_center.custom": "Custom",
"dialog.settings.reset_to_default": "Reset to Default",
"keybindings.item.num_slider.increase": "Increase",
"keybindings.item.num_slider.decrease": "Decrease",
"settings.always_show_splash_art": "Always Show Splash Art",
"settings.always_show_splash_art.desc": "Always display the splash art on the start screen",
"action.slider_palette_color": "Switch Palette Color",
"action.slider_palette_color.desc": "Cycle between the colors in the palette",
"action.proportional_editing": "Proportional Editing",
"action.proportional_editing.desc": "Proportionally affect surrounding vertices when editing parts of a mesh",
"action.limit_to_palette": "Limit to Palette",
"action.limit_to_palette.desc": "Limits the colors of the texture to those in the currently loaded palette",
"action.edit_reference_images": "Edit Reference Images",
"action.edit_reference_images.desc": "Turn on reference image mode to add or edit reference images and blueprints",
"action.add_reference_image": "Add Reference Image",
"action.reference_image_from_clipboard": "Reference Image from Clipboard",
"action.reference_image_list": "Reference Images",
"action.connect_uv_faces": "Connect UV Faces",
"action.connect_uv_faces.desc": "Connect the selected UV faces to the last selected UV face",
"action.merge_uv_vertices": "Merge UV Vertices",
"action.merge_uv_vertices.desc": "Snap the first selected UV vertices to the last selected UV vertices",
"action.bedrock_animation_mode": "Bedrock Animation Mode",
"dialog.copied_to_clipboard": "클립보드에 복사됨",
"data.reference_image": "참조용 이미지",
"message.delete_reference_image": "이 참조용 이미지를 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.",
"message.add_reference_image.message": "참조용 이미지를 로드할 위치 선택",
"message.add_reference_image.project": "이 프로젝트에 추가하기",
"message.add_reference_image.app": "모든 프로젝트에 추가하기",
"message.import_particle_texture.import": "파티클 이미지 가져오기",
"message.import_particle_texture.message": "파티클에 사용할 텍스쳐 파일을 가져오시겠습니까?",
"message.save_codec_selector.title": "모델 형식 저장",
"message.save_codec_selector.message": "모델을 저장할 형식을 선택합니다.",
"message.save_codec_selector.project_file": "Blockbench 프로젝트 (.bbmodel)",
"message.save_codec_selector.both": "둘 다",
"message.display_skin.username": "닉네임 (Java)",
"message.palette_locked": "팔레트가 잠겨 있습니다",
"dialog.project.default_uv_mode": "기본 UV 모드",
"dialog.project.default_uv_mode.description": "프로젝트의 기본 UV 모드입니다. UV 모드는 큐브별로 변경할 수도 있습니다.",
"dialog.export_options.title": "내보내기 옵션",
"dialog.edit_texture.preview": "미리보기",
"dialog.proportional_editing.range": "범위",
"dialog.proportional_editing.falloff": "폴오프",
"dialog.proportional_editing.falloff.linear": "선형",
"dialog.proportional_editing.falloff.hermite_spline": "스무스",
"dialog.proportional_editing.falloff.constant": "컨스턴트",
"dialog.proportional_editing.selection": "선택",
"dialog.proportional_editing.selection.linear": "선형 거리",
"dialog.proportional_editing.selection.connections": "연결",
"dialog.mirror_painting_texture_center.middle": "중간",
"dialog.mirror_painting_texture_center.custom": "사용자 지정",
"dialog.settings.reset_to_default": "기본값으로 재설정",
"keybindings.item.num_slider.increase": "증가",
"keybindings.item.num_slider.decrease": "감소",
"settings.always_show_splash_art": "항상 스플래시 아트 표시",
"settings.always_show_splash_art.desc": "시작 화면에 항상 스플래시 아트를 표시합니다",
"action.slider_palette_color": "팔레트 색상 전환",
"action.slider_palette_color.desc": "팔레트의 색상 순환",
"action.proportional_editing": "비율 편집",
"action.proportional_editing.desc": "메쉬의 일부를 편집할 때 주변 정점에 비례적으로 영향을 줍니다",
"action.limit_to_palette": "팔레트 제한",
"action.limit_to_palette.desc": "텍스쳐의 색상을 현재 로드된 팔레트에 있는 색상으로 제한합니다",
"action.edit_reference_images": "참조용 이미지 편집",
"action.edit_reference_images.desc": "참조용 이미지 모드를 켜서 참조용 이미지와 청사진을 추가하거나 편집함",
"action.add_reference_image": "참조용 이미지 추가",
"action.reference_image_from_clipboard": "클립보드의 참조용 이미지",
"action.reference_image_list": "참조용 이미지",
"action.connect_uv_faces": "UV 표면 연결",
"action.connect_uv_faces.desc": "선택한 UV 표면을 마지막으로 선택한 UV 표면에 연결",
"action.merge_uv_vertices": "UV 정점 병합",
"action.merge_uv_vertices.desc": "처음 선택한 UV 정점을 마지막으로 선택한 UV 정점에 맞춥니다",
"action.bedrock_animation_mode": "Bedrock 애니메이션 모드",
"action.bedrock_animation_mode.desc": "마인크래프트 베드락에디션의 에니매이션을 편집할 모드를 선택",
"action.bedrock_animation_mode.entity": "엔티티",
"action.bedrock_animation_mode.attachable_first": "아이템 1인칭",
"action.bedrock_animation_mode.attachable_third": "아이템 3인칭",
"timeline.amplify": "Amplify",
"menu.options": "Options...",
"menu.palette.lock_palette": "Lock Palette",
"menu.uv.export": "Export UV Mapping",
"timeline.amplify": "증폭",
"menu.options": "옵션...",
"menu.palette.lock_palette": "팔레트 잠금",
"menu.uv.export": "UV 매핑 내보내기",
"menu.uv.flip_x": "X 반전",
"menu.uv.flip_y": "Y 반전",
"menu.mirror_painting.enabled": "켜짐",
"menu.mirror_painting.configure_texture_center": "Configure Texture Center...",
"reference_image.position": "Position",
"menu.mirror_painting.configure_texture_center": "텍스쳐 센터 구성...",
"reference_image.position": "위치",
"reference_image.size": "크기",
"reference_image.rotation": "회전",
"reference_image.opacity": "투명도",
"reference_image.visibility": "Visibility",
"reference_image.clear_mode": "Clear Mode",
"reference_image.visibility": "가시성",
"reference_image.clear_mode": "지우기 모드",
"reference_image.layer": "레이어",
"reference_image.layer.background": "Behind Model",
"reference_image.layer.viewport": "Above Model",
"reference_image.layer.float": "Above Interface",
"reference_image.layer.blueprint": "Locked Blueprint",
"reference_image.scope": "Scope",
"reference_image.scope.project": "Just this project",
"reference_image.layer.background": "모델 아래",
"reference_image.layer.viewport": "모델 위",
"reference_image.layer.float": "인터페이스 위",
"reference_image.layer.blueprint": "잠긴 청사진",
"reference_image.scope": "범위",
"reference_image.scope.project": "이 프로젝트만",
"reference_image.scope.global": "모든 프로젝트",
"reference_image.enabled_modes": "Enabled in Modes",
"codec.common.encoding": "Encoding",
"codec.common.armature": "Export Groups as Armature",
"reference_image.enabled_modes": "모드에서 활성화됨",
"codec.common.encoding": "인코딩",
"codec.common.armature": "그룹을 뼈대로 내보내기",
"codec.common.export_animations": "에니메이션 추출",
"codec.common.embed_textures": "Embed Textures",
"codec.common.embed_textures": "텍스쳐 임베드",
"preview.center_camera": "중앙 카메라",
"display.reference.frame_top": "아이템 액자 위",
"display.reference.frame_top_invisible": "아이템 액자 위 (투명)",
"action.proportional_editing_range": "Proportional Editing Range",
"action.proportional_editing_range.desc": "Adjust the range for proportional editing",
"action.toggle_all_reference_images": "Hide/Show All Reference Images",
"action.toggle_all_reference_images.desc": "Toggle the visibility of all reference images at once",
"action.add_animation_controller_state": "Add Animation Controller State",
"action.add_animation_controller_state.desc": "Add a new state to the animation controller",
"menu.slider.round_value": "Round Value",
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"action.proportional_editing_range": "비율 편집 범위",
"action.proportional_editing_range.desc": "비율 편집 범위 조정",
"action.toggle_all_reference_images": "모든 참조용 이미지 숨기기/보기",
"action.toggle_all_reference_images.desc": "모든 참조용 이미지의 표시 여부를 한 번에 전환",
"action.add_animation_controller_state": "애니메이션 컨트롤러 상태 추가",
"action.add_animation_controller_state.desc": "애니메이션 컨트롤러에 새로운 상태 추가",
"menu.slider.round_value": "라운드 값",
"texture.error.too_large": "해상도가 최대 %0을 초과함",
"dialog.copy_to_clipboard": "클립보드에 복사",
"dialog.open_url": "URL 열기",
"reference_image.image": "이미지",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolutie overschrijdt het maximum van %0",
"dialog.copy_to_clipboard": "Kopieer naar klembord",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1,12 +1,12 @@
{
"dialog.ok": "Ок",
"dialog.ok": "ОК",
"dialog.cancel": "Отменить",
"dialog.confirm": "Подтвердить",
"dialog.close": "Закрыть",
"dialog.import": "Импортировать",
"dialog.save": "Сохранить",
"dialog.discard": "Сбросить",
"dialog.dontshowagain": "Не показывать снова",
"dialog.dontshowagain": "Не Показывать Снова",
"data.cube": "Куб",
"data.group": "Группа",
"data.texture": "Текстура",
@ -14,100 +14,100 @@
"data.preview": "Предпросмотр",
"data.toolbar": "Инструменты",
"data.image": "Изображение",
"keys.ctrl": "Контрол",
"keys.shift": "Шифт",
"keys.alt": "Альт",
"keys.meta": "Коммандная Строка",
"keys.ctrl": "Ctrl",
"keys.shift": "Shift",
"keys.alt": "Alt",
"keys.meta": "Командная строка",
"keys.delete": "Удалить",
"keys.space": "Пробел",
"keys.space": "Space",
"keys.leftclick": "ЛКМ",
"keys.middleclick": "СКМ",
"keys.rightclick": "ПКМ",
"keys.tab": "Таб",
"keys.backspace": "Отмена",
"keys.enter": "Ввод",
"keys.escape": "Выход",
"keys.tab": "Tab",
"keys.backspace": "Backspace",
"keys.enter": "Enter",
"keys.escape": "Escape",
"keys.function": "F%0",
"keys.numpad": "%0 (цифр. кл.)",
"keys.caps": "Капс",
"keys.numpad": "Цифровая клавиатура %0",
"keys.caps": "Caps",
"keys.menu": "Меню",
"keys.left": "Стрелка влево",
"keys.up": "Стрелка вверх",
"keys.right": "Стрелка вправо",
"keys.down": "Стрелка вниз",
"keys.pageup": "Странница вверх",
"keys.pagedown": "Странница вверх",
"keys.pageup": "PgUp",
"keys.pagedown": "PgDn",
"keys.plus": "Плюс",
"keys.comma": "Запятая",
"keys.point": "Точка",
"keys.minus": "Минус",
"keys.cross": "Крестик",
"keys.end": "Конец",
"keys.end": "End",
"keys.pos1": "Поз 1",
"keys.printscreen": "Снимок Экрана",
"keys.printscreen": "PrtSc",
"keys.pause": "Пауза",
"message.rotation_limit.title": "Ограничение поворота",
"message.rotation_limit.message": "Поворот ограничен Minecraft до одной оси и 22,5 градусов. Поворот на разных осях сбросит все повороты на других осях. Конвертируйте модель в \"свободную\", если вы создаете модель для других целей, где нужен свободный поворот.",
"message.file_not_found.title": "Файл не найден",
"message.rotation_limit.title": "Ограничение Поворота",
"message.rotation_limit.message": "Вращения ограничены Minecraft одной осью и шагом 22,5 градуса. Вращение по другой оси очистит все вращения по другим осям. Преобразуйте модель в \"Общую модель\", если вы моделируете для других целей и вам нужны свободные вращения.",
"message.file_not_found.title": "Файл Не Найден",
"message.file_not_found.message": "Blockbench не может найти запрашиваемый файл. Убедитесь, что он сохранен по указанному пути, не в облаке.",
"message.screenshot.title": "Скриншот",
"message.screenshot.clipboard": "Скопировать",
"message.screenshot.right_click": "Скриншот: ПКМ — скопировать",
"message.invalid_file.title": "Недопустимый файл",
"message.screenshot.right_click": "Щелкните правой кнопкой мыши или нажмите и удерживайте скриншот, чтобы скопировать",
"message.invalid_file.title": "Недопустимый Файл",
"message.invalid_file.message": "Не удалось открыть файл типа json: %0",
"message.invalid_model.title": "Недопустимый файл модели",
"message.invalid_model.title": "Недопустимый Файл Модели",
"message.invalid_model.message": "Этот файл содержит недопустимые данные модели.",
"message.child_model_only.title": "Пустая дочерняя модель",
"message.child_model_only.title": "Пустая Дочерняя Модель",
"message.child_model_only.message": "Это дочерняя модель %0, которая не содержит модели.",
"message.unsaved_textures.title": "Несохранённые текстуры",
"message.unsaved_textures.title": "Несохранённые Текстуры",
"message.unsaved_textures.message": "Ваша модель содержит несохранённые текстуры. Убедитесь, что они сохранены и помещены в ваш набор ресурсов в правильной папке.",
"message.model_clipping.title": "Модель слишком большая",
"message.model_clipping.title": "Модель Слишком Большая",
"message.model_clipping.message": "Ваша модель содержит %0 кубов, которые больше чем ограничение 3x3x3. Эта модель не будет работать в Minecraft.",
"message.loose_texture.title": "Импортирование текстуры",
"message.loose_texture.title": "Импортирование Текстуры",
"message.loose_texture.message": "Импортированная текстура не находится в наборе ресурсов. Minecraft может загружать только текстуры, находящиеся в папке текстур загруженного набора ресурсов.",
"message.loose_texture.change": "Изменить путь",
"message.update_res.title": "Разрешение текстуры",
"message.loose_texture.change": "Изменить Путь",
"message.update_res.title": "Разрешение Текстуры",
"message.update_res.message": "Хотите ли вы обновить разрешение проекта на разрешение этой текстуры? Нажмите «Отмена», если ваша текстура имеет разрешение больше нормального.",
"message.update_res.update": "Обновить",
"message.bedrock_overwrite_error.message": "Blockbench не может совместить эту модель со старым файлом.",
"message.bedrock_overwrite_error.backup_overwrite": "Сделать бэкап и заменить",
"message.bedrock_overwrite_error.message": "Blockbench не может объединить эту модель со старым файлом",
"message.bedrock_overwrite_error.backup_overwrite": "Сделать Бэкап и Заменить",
"message.bedrock_overwrite_error.overwrite": "Заменить",
"message.close_warning.message": "Вы хотите сохранить вашу модель?",
"message.close_warning.web": "Ваша работа будет утеряна. Вы уверены, что хотите выйти?",
"message.default_textures.title": "Стандартные текстуры",
"message.default_textures.message": "Выберите папку «textures» стандартного набора ресурсов.",
"message.default_textures.detail": "Извлеките стандартный набор ресурсов из Minecraft jar или поищите его в интернете. Затем найдите папку «textures» и откройте ее. Blockbench запомнит её расположение и будет загружать текстуры из неё, если не сможет найти их в текущем наборе ресурсов.",
"message.default_textures.select": "Выбрать папку «textures»",
"message.default_textures.title": "Стандартные Текстуры",
"message.default_textures.message": "Выберите папку \"текстуры\" пакета ресурсов по умолчанию.",
"message.default_textures.detail": "Извлеките пакет ресурсов по умолчанию из банки Minecraft или Google и загрузите его. Затем найдите папку \"текстуры\" и откройте ее. Blockbench запомнит это местоположение и попытается извлечь оттуда текстуры, если не сможет найти их в текущем пакете ресурсов.",
"message.default_textures.select": "Выберите папку по умолчанию \"текстуры\"",
"message.image_editor.title": "Выбор редактора изображений",
"message.image_editor.file": "Выбрать файл...",
"message.image_editor.file": "Выбрать Файл...",
"message.image_editor.exe": "Выберите исполняемый файл редактора изображений",
"message.display_skin.title": "Отображаемый скин",
"message.display_skin.title": "Отображаемый Скин",
"message.display_skin.message": "Выберите скин на вашем компьютере или введите имя игрока",
"message.display_skin.upload": "Загрузить скин",
"message.display_skin.reset": "Сброс",
"message.invalid_plugin": "Неверный файл плагина, посмотрите в консоль",
"message.invalid_plugin": "Неверный Файл Плагина, Посмотрите В Консоль",
"message.load_plugin_app": "Хотите ли вы разрешить этому плагину изменять файлы на вашем компьютере? Загружайте только те плагины, которым вы доверяете.",
"message.load_plugin_web": "Вы хотите загрузить этот плагин? Загружайте плагины только от людей, которым вы доверяете.",
"message.preset_no_info": "Шаблон не содержит информации для этого слота.",
"message.preset_no_info": "Пресет не содержит информации для этого слота",
"message.restart_to_update": "Перезапустите Blockbench, чтобы применить изменения",
"message.save_file": "Сохранено как %0",
"message.save_obj": "Сохранено как .obj модель",
"dialog.project.title": "Проект",
"dialog.project.name": "Имя файла",
"dialog.project.parent": "Родительская модель",
"dialog.project.name": "Имя Файла",
"dialog.project.parent": "Родительская Модель",
"dialog.project.geoname": "Идентификатор Модели",
"dialog.project.ao": "Мягкое освещение",
"dialog.project.ao": "Мягкое Освещение",
"dialog.texture.title": "Текстура",
"dialog.texture.variable": "Переменная",
"dialog.texture.namespace": "Пространство имён",
"dialog.texture.folder": "Папка",
"dialog.extrude.title": "Сканирование изображения",
"dialog.extrude.mode": "Способ создания модели",
"dialog.extrude.mode.areas": "по областям",
"dialog.extrude.mode.lines": "по линиям",
"dialog.extrude.title": "Сканирование Изображения",
"dialog.extrude.mode": "Способ Создания Модели",
"dialog.extrude.mode.areas": "По Областям",
"dialog.extrude.mode.lines": "По Линиям",
"dialog.extrude.mode.columns": "по столбцам",
"dialog.extrude.mode.pixels": "по пикселям",
"dialog.extrude.opacity": "Мин. непрозрачность",
"dialog.extrude.opacity": "Минимальная непрозрачность",
"dialog.extrude.scan": "Сканировать и импортировать",
"dialog.display_preset.title": "Создание шаблона",
"dialog.display_preset.message": "Выберите слоты, которые нужно сохранить",
@ -115,7 +115,7 @@
"dialog.select.title": "Выделение",
"dialog.select.group": "В выделенной группе",
"dialog.select.name": "Имя содержит",
"dialog.select.random": "Случайность",
"dialog.select.random": "Случайный шанс (%)",
"dialog.select.select": "Выделить",
"dialog.scale.title": "Масштабирование модели",
"dialog.scale.axis": "Оси",
@ -180,7 +180,7 @@
"settings.category.dialogs": "Диалоговые окна",
"settings.category.export": "Экспорт",
"settings.language": "Язык",
"settings.language.desc": "Язык интерфейса. Перезапустите Blockbench, чтобы применить изменения.",
"settings.language.desc": "Язык интерфейса. Перезапустите Blockbench, чтобы применить изменения",
"settings.backup_interval": "Интервал автосохранения",
"settings.backup_interval.desc": "Интервал автосохранения в минутах",
"settings.origin_size": "Центр поворота",
@ -265,7 +265,7 @@
"action.uv_slider_size_y": "Вертикальный масштаб",
"action.uv_slider_size_y.desc": "Масштабировать UV выбранных кубов вертикально",
"action.vertex_snap_mode": "Режим привязки",
"action.vertex_snap_mode.desc": "Выбор режима привязки: перемещение элементов или изменение их размера",
"action.vertex_snap_mode.desc": "Выберите, перемещает ли Vertex Snap элементы в выбранное положение или изменяет их размер",
"action.move_tool": "Перемещение",
"action.move_tool.desc": "Инструмент для выделения и перемещения элементов",
"action.resize_tool": "Изменение размера",
@ -291,7 +291,7 @@
"action.export_obj": "Экспортировать в OBJ",
"action.export_obj.desc": "Экспортировать obj модель для рендеринга",
"action.settings_window": "Настройки...",
"action.settings_window.desc": "Открыть окно настроек Blockbench",
"action.settings_window.desc": "Откройте диалоговое окно настроек Blockbench.",
"action.plugins_window": "Плагины...",
"action.plugins_window.desc": "Открыть окно хранилища плагинов",
"action.reset_layout": "Сбросить внешний вид",
@ -299,7 +299,7 @@
"action.load_plugin": "Загрузить плагин из файла",
"action.load_plugin.desc": "Загрузить плагин, импортировав файл",
"action.reload_plugins": "Перезагрузить плагины",
"action.reload_plugins.desc": "Перезагрузить все плагины в разработке.",
"action.reload_plugins.desc": "Перезагрузить все плагины разработки",
"action.undo": "Отмена",
"action.undo.desc": "Отмена последнего действия",
"action.redo": "Возврат",
@ -345,7 +345,7 @@
"action.add_display_preset": "Новый Шаблон",
"action.add_display_preset.desc": "Создать шаблон настроек отображения",
"action.fullscreen": "Полный экран",
"action.fullscreen.desc": "Включает/Выключает полноэкранный режим.",
"action.fullscreen.desc": "Переключает полноэкранный режим",
"action.zoom_in": "Увеличить",
"action.zoom_in.desc": "Увеличить масштаб интерфейса",
"action.zoom_out": "Уменьшить",
@ -450,10 +450,10 @@
"direction.east": "Восток",
"direction.top": "Верх",
"direction.bottom": "Низ",
"display.slot.third_right": "Третье лицо: правая рука",
"display.slot.third_left": "Третье лицо: левая рука",
"display.slot.first_right": ервое лицо: правая рука",
"display.slot.first_left": "Первое лицо: левая рука",
"display.slot.third_right": "Право третьего лица",
"display.slot.third_left": "От третьего лица слева",
"display.slot.first_right": раво первого лица",
"display.slot.first_left": "Слева от первого лица",
"display.slot.head": "Голова",
"display.slot.ground": "Земля",
"display.slot.frame": "Рамка",
@ -492,7 +492,7 @@
"action.change_textures_folder.desc": "Изменить папку, в которой сохранены текстуры",
"menu.texture.particle": "Использовать для частиц",
"message.update_notification.title": "Доступно обновление",
"message.update_notification.message": "Доступно обновление Blockbench «%0». Хотите установить его?",
"message.update_notification.message": "Доступна новая версия Blockbench. Пожалуйста, включите автоматическое обновление в настройках, чтобы обновиться!",
"message.untextured": "Эта поверхность не имеет текстур",
"dialog.toolbar_edit.title": "Настроить панель инструментов",
"keybindings.reset": "Сбросить",
@ -731,7 +731,7 @@
"format.java_block.desc": "Модель для Java Edition. Размер и повороты ограничены.",
"format.bedrock": "Модель Bedrock",
"format.bedrock.desc": "Модель для Bedrock Edition",
"format.bedrock_old": "Модель Bedrock (старая)",
"format.bedrock_old": "Устаревшая модель Bedrock",
"format.bedrock_old.desc": "Модель Bedrock Edition для версий старее 1.12",
"format.modded_entity": "Сущность для модов",
"format.modded_entity.desc": "Модель сущности для Minecraft модов. Может быть экспортирована как файл класса .java",
@ -898,7 +898,7 @@
"timeline.pre_effect_script": "Скрипт",
"format.skin": "Скин",
"format.skin.desc": "Редактирование скинов игроков и сущностей",
"message.sketchfab.setup_guide": "Узнать, как настроить модели в Sketchfab: %0",
"message.sketchfab.setup_guide": "Хотите узнать, как настраивать модели в Sketchfab? Читать %0",
"dialog.skin.title": "Создать скин",
"dialog.skin.model": "Модель",
"dialog.skin.texture": "Текстура (необязательно)",
@ -948,9 +948,9 @@
"action.fill_mode.color_connected": "Соединённые цвета",
"action.draw_shape_type": "Тип фигуры",
"action.draw_shape_type.rectangle": "Четырёхугольник",
"action.draw_shape_type.rectangle_h": устой четырёхугольник",
"action.draw_shape_type.rectangle_h": рямоугольник (полый)",
"action.draw_shape_type.ellipse": "Эллипс",
"action.draw_shape_type.ellipse_h": "Пустой эллипс",
"action.draw_shape_type.ellipse_h": "Эллипс (полый)",
"action.draw_shape_type.line": "Линия",
"action.mirror_painting": "Зеркальное рисование",
"action.mirror_painting.description": "Зеркально отразите свои мазки текстуры на другой стороне модели",
@ -977,7 +977,7 @@
"menu.help.developer": "Фунции разработчика",
"menu.help.developer.dev_tools": "Открыть инструменты разработчика",
"menu.help.developer.reset_storage": "Перезагрузка фабрики",
"menu.help.developer.reset_storage.confirm": "Вы уверены, что хотите снести Блокбенч до настроек фабрики. Это удалит все ваши настройки, горячтие клавиши и загруженные плагины.",
"menu.help.developer.reset_storage.confirm": "Вы уверены, что хотите сбросить настройки Blockbench до заводских? Это удалит все пользовательские настройки, сочетания клавиш и установленные плагины.",
"menu.help.developer.cache_reload": "Перезагрузить кэш",
"menu.preview.orthographic": "Ортография",
"menu.preview.save_angle": "Сохранить угол...",
@ -1140,10 +1140,10 @@
"dates.hours": "%0 часов",
"dates.day": "%0 дней",
"dates.days": "%0 дней",
"dates.week": "%0 нед.",
"dates.weeks": "%0 нед.",
"dates.week": "%0 неделя",
"dates.weeks": "%0 недель",
"dates.year": "%0 лет",
"dates.years": "%0 год(а-ов)",
"dates.years": "%0 лет",
"message.installed_plugin": "Плагин %0 успешно загружен",
"message.installed_plugin_fail": "Не удалось загрузить плагин %0",
"dialog.share_model.title": "Поделиться моделью",
@ -1157,7 +1157,7 @@
"action.import_project.desc": "Импортировать другой проект из файла .bbmodel в текущий проект",
"dialog.toolbar_edit.hidden_tools": "Некоторые инструменты могут быть скрыты из-за невозможности использования в текущем режиме, формате или ситуации.",
"settings.camera_near_plane": "Камера рядом с плоскостью",
"settings.camera_near_plane.desc": "Мин. дистанция от камеры на которой рендерятся объекты. Большие значения уменьшают Z-файт. По умолчанию 1.\n",
"settings.camera_near_plane.desc": "Мин. дистанция от камеры на которой рендерятся объекты. Большие значения уменьшают Z-файт. По умолчанию 1.",
"mode.start.keymap_preference.desc": "Если вы новичок в Blockbench и пришли из другой программы для 3D вы можете выбрать схему управления, чтобы переход дался вам легче. Позже вы сможете изменить схему или индивидуальные привязки в настройках",
"message.load_keymap": "Вы уверены, что хотите загрузить эту схему? Она перезапишет ваши текущие привязки клавиш.",
"message.keymap_loaded": "Схема загружена",
@ -1171,7 +1171,7 @@
"dialog.create_gif.color": "Цвет фона",
"dialog.save_angle.zoom": "Приближение",
"dialog.skin.variant": "Вариант",
"dialog.flip_animation.info": "Противоположные кости идентифицируются ключевыми словами \"left\" и \"right\" в их названии.",
"dialog.flip_animation.info": "Противоположные кости идентифицируются ключевыми словами 'left' и 'right' в их названии.",
"dialog.flip_animation.offset": "Смещение половиной длинны анимации",
"dialog.export_private_settings.title": "Приватные настройки",
"dialog.export_private_settings.message": "Ваш файл содержит следующую личную информацию: **%0**. Удалите эти значения, если вы планируете с кем-то делиться этим файлом.",
@ -1490,238 +1490,238 @@
"action.select_seam.desc": "Выберите режим шва UV для выбранных краев.",
"action.select_seam.auto": "Авто",
"action.select_seam.join": "Присоединиться",
"action.select_seam.divide": "Divide",
"action.select_seam.divide": "Разделять",
"action.adjust_brightness_contrast": "Настройка яркости и контрастности...",
"action.adjust_brightness_contrast.desc": "Отрегулируйте яркость и контрастность выбранной текстуры",
"action.adjust_saturation_hue": "Отрегулируйте насыщенность и оттенок...",
"action.adjust_saturation_hue.desc": "Отрегулируйте насыщенность и оттенок выбранной текстуры",
"action.invert_colors": "Инвертировать цвета",
"action.invert_colors.desc": "Invert all colors of the selected texture",
"action.invert_colors.desc": "Инвертировать все цвета выбранной текстуры",
"action.adjust_curves": "Настроить кривые...",
"action.adjust_curves.desc": "Отрегулируйте кривые яркости выбранной текстуры",
"action.flip_texture_x": "Отразить по горизонтали",
"action.flip_texture_y": "Отразить по вертикали",
"action.resize_texture": "Resize Texture...",
"action.view_mode.uv": "UV Preview",
"action.resize_texture": "Изменить размер текстуры...",
"action.view_mode.uv": "UV-предварительный просмотр",
"action.append_to_template": "Добавить элементы в шаблон...",
"action.append_to_template.desc": "Добавить выбранные в данный момент элементы в шаблон текстуры",
"action.move_texture_with_uv": "Move Texture with UV",
"action.move_texture_with_uv.desc": "Move the texture of the face along when dragging UV faces",
"action.timeline_setups": "Timeline Setups",
"action.save_timeline_setup": "Save Timeline Setup...",
"action.save_timeline_setup.desc": "Save a preset for the currently selected animators and channels",
"action.move_texture_with_uv": "Переместить текстуру с помощью UV",
"action.move_texture_with_uv.desc": "Перемещайте текстуру лица при перетаскивании UV-граней",
"action.timeline_setups": "Настройки временной шкалы",
"action.save_timeline_setup": "Сохранить настройку временной шкалы...",
"action.save_timeline_setup.desc": "Сохранить пресет для выбранных в данный момент аниматоров и каналов",
"menu.texture": "Текстура",
"menu.texture.render_mode.default": "Default",
"menu.texture.merge_onto_texture": "Merge Onto Texture Above",
"menu.animation.unload": "Unload",
"menu.texture.render_mode.default": "По Умолчанию",
"menu.texture.merge_onto_texture": "Слияние С Текстурой Выше",
"menu.animation.unload": "Разгрузить",
"panel.timeline": "Таймлайн",
"action.pan_tool": "Pan Tool",
"action.pan_tool.desc": "Tool to navigate in the viewport and the texture editor",
"action.pan_tool": "Инструмент панорамирования",
"action.pan_tool.desc": "Инструмент для навигации в окне просмотра и редакторе текстур",
"mode.start.recent.favorite": "Пометить как избранное",
"mode.start.info": "Info",
"mode.start.target": "Target",
"mode.start.start": "Start",
"mode.start.info": "Информация",
"mode.start.target": "Цель",
"mode.start.start": "Начинать",
"mode.start.create_new": "Создать новую модель",
"mode.start.format.informations": "Лучше знать:",
"mode.start.format.resources": "Resources:",
"format.free.info.meshes": "In this format, you can create low poly models using cubes and custom shaped meshes.",
"format.free.info.limitation": "Models cannot be loaded into games that need specialized formats, such as Minecraft.",
"format.skin.info.skin": "This format is designed to create Minecraft skins and entity textures.",
"format.skin.info.model": "The model cannot be changed. In order to make changes to the model, first convert to a different format via **File** > **Convert Project**.",
"format.java_block.info.rotation": "Rotations are limited to 22.5 degree steps and one axis per element",
"format.java_block.info.size": "The model is limited to a size of 3 by 3 by 3 blocks. Display settings can make item models larger though",
"format.java_block.info.animation": "This format does not support animations in vanilla Minecraft. If you are creating a mod, you can use GeckoLib to animate models. If not, the only way to animate is to switch out the model using commands or animated textures.",
"format.bedrock.info.textures": "Each model can only have one texture",
"format.bedrock_block": "Bedrock Block",
"format.bedrock_block.desc": "Block model for Minecraft Bedrock Edition",
"format.modded_entity.info.integer_size": "The size of individual cubes is limited to integers.",
"format.modded_entity.info.format": "Models are written in Java code instead of dedicated data structures like all other Blockbench export formats.",
"format.optifine_entity.info.optifine_required": "Users without OptiFine installed won't see the model.",
"format.optifine_entity.info.pivots": "Bone pivots are locked, so it is a good idea to leave them untouched.",
"format_category.low_poly": "Low-Poly",
"mode.start.format.resources": "Ресурсы:",
"format.free.info.meshes": "В этом формате вы можете создавать низкополигональные модели, используя кубы и сетки нестандартной формы.",
"format.free.info.limitation": "Модели нельзя загружать в игры, которым нужны специализированные форматы, такие как Minecraft.",
"format.skin.info.skin": "Этот формат предназначен для создания скинов Minecraft и текстур сущностей.",
"format.skin.info.model": "Модель не может быть изменена. Чтобы внести изменения в модель, сначала преобразуйте ее в другой формат с помощью **Файл** > **Преобразовать проект**.",
"format.java_block.info.rotation": "Вращения ограничены шагами в 22,5 градуса и одной осью на элемент.",
"format.java_block.info.size": "Модель ограничена размером 3 на 3 на 3 блока. Однако настройки отображения могут сделать модели предметов больше.",
"format.java_block.info.animation": "Этот формат не поддерживает анимацию в ванильном Minecraft. Если вы создаете мод, вы можете использовать GeckoLib для анимации моделей. Если нет, единственный способ анимировать — отключить модель с помощью команд или анимированных текстур.",
"format.bedrock.info.textures": "Каждая модель может иметь только одну текстуру",
"format.bedrock_block": "Бедрок Блок",
"format.bedrock_block.desc": "Блочная модель для Minecraft Bedrock Edition",
"format.modded_entity.info.integer_size": "Размер отдельных кубов ограничен целыми числами.",
"format.modded_entity.info.format": "Модели записываются в коде Java, а не в специальных структурах данных, как во всех других форматах экспорта Blockbench.",
"format.optifine_entity.info.optifine_required": "Пользователи без установленного OptiFine не увидят модель.",
"format.optifine_entity.info.pivots": "Костные шарниры заблокированы, поэтому рекомендуется оставить их нетронутыми.",
"format_category.low_poly": "Низкополигональная",
"format_category.minecraft": "Майнкрафт",
"format_category.other": "Другое",
"format_category.loaders": "Loaders",
"format_category.loaders": "Погрузчики",
"message.recover_backup.recover": "Восстановить",
"message.invalid_characters.title": "Invalid Path",
"message.invalid_characters.message": "The path of the imported file contains invalid characters, uppercase letters, or white spaces. The supported characters are: %0",
"dialog.share_model.thumbnail": "Thumbnail",
"dialog.skin.high_res_texture": "Please note that skins with the selected resolution will not work as regular Minecraft skins. Select a lower resolution.",
"settings.allow_display_slot_mirror": "Allow Display Slot Mirroring",
"settings.allow_display_slot_mirror.desc": "Allow Display slots for Java item models to be mirrored. WARNING: This only works in Minecraft 1.14 or earlier or in special cases.",
"action.switch_tabs": "Switch Tabs",
"action.switch_tabs.desc": "Cycle between opened tabs. Hold shift to cycle in the opposite direction.",
"action.unselect_all": "Unselect All",
"action.unselect_all.desc": "Unselect all elements, faces, vertices, or keyframes",
"message.invalid_characters.title": "Неверный путь",
"message.invalid_characters.message": "Путь к импортируемому файлу содержит недопустимые символы, буквы верхнего регистра или пробелы. Поддерживаемые символы: %0",
"dialog.share_model.thumbnail": "Миниатюра",
"dialog.skin.high_res_texture": "Обратите внимание, что скины с выбранным разрешением не будут работать как обычные скины Minecraft. Выберите меньшее разрешение.",
"settings.allow_display_slot_mirror": "Разрешить зеркалирование слота дисплея",
"settings.allow_display_slot_mirror.desc": "Разрешить зеркальное отображение слотов отображения для моделей элементов Java. ВНИМАНИЕ: Это работает только в Minecraft 1.14 или более ранней версии или в особых случаях.",
"action.switch_tabs": "Переключить вкладки",
"action.switch_tabs.desc": "Цикл между открытыми вкладками. Удерживайте Shift для переключения в обратном направлении.",
"action.unselect_all": "Снять все",
"action.unselect_all.desc": "Отменить выбор всех элементов, граней, вершин или ключевых кадров",
"action.save_palette": "Сохранить палитру...",
"action.save_palette.desc": "Save the current color palette inside Blockbench for later use",
"action.keyframe_column_create": "Create Keyframe Column",
"action.keyframe_column_create.desc": "Key all channels in the timeline at the current timecode, if they already have keyframes",
"action.keyframe_column_select": "Select Keyframe Column",
"action.keyframe_column_select.desc": "Select all keyframes in the timeline along a column below the playhead",
"action.save_palette.desc": "Сохраните текущую цветовую палитру в Blockbench для последующего использования.",
"action.keyframe_column_create": "Создать столбец ключевого кадра",
"action.keyframe_column_create.desc": "Включите все каналы на временной шкале с текущим временным кодом, если у них уже есть ключевые кадры.",
"action.keyframe_column_select": "Выберите столбец ключевого кадра",
"action.keyframe_column_select.desc": "Выберите все ключевые кадры на временной шкале в столбце под указателем воспроизведения.",
"menu.uv": "UV",
"menu.keyframe": "Keyframe",
"menu.keyframe": "Ключевой кадр",
"menu.palette.load.update": "Обновить палитру",
"menu.palette.load.update.desc": "Updates this palette with the colors of the current Blockbench palette",
"menu.timeline_marker.set_time": "Set Time...",
"uv_editor.scale_uv": "Scale UV",
"action.preview_scene": "Preview Scene",
"action.preview_scene.desc": "Change the model preview scene",
"menu.palette.load.update.desc": "Обновляет эту палитру цветами текущей палитры Blockbench.",
"menu.timeline_marker.set_time": "Установить время...",
"uv_editor.scale_uv": "Шкала UV",
"action.preview_scene": "Предварительный просмотр сцены",
"action.preview_scene.desc": "Изменить сцену предварительного просмотра модели",
"preview_scene.minecraft_overworld": "Верхний мир Майнкрафта",
"preview_scene.minecraft_nether": "Незер Майнкрафта",
"preview_scene.minecraft_end": "Край Майнкрафта",
"dialog.project.modded_entity_flip_y": "Flip Y Axis",
"preview_scene.studio": "Studio",
"format.image": "Image",
"modifier_actions.set_copy_source": "Set Copy Source",
"message.load_images.title": "Load Images",
"message.load_images.edit_image": "Edit Image",
"dialog.add_primitive.align_edges": "Align Edges",
"dialog.flip_animation.show_in_timeline": "Show modified bones in timeline",
"settings.default_cube_size": "Cube Size",
"settings.default_cube_size.desc": "Set the default cube size when creating a new cube",
"settings.uniform_keyframe": "Uniform Scale Keyframes",
"settings.uniform_keyframe.desc": "Set scale keyframes to uniform scaling by default",
"settings.nearest_rectangle_select": "Rectangle Selection: Nearest Edge",
"settings.nearest_rectangle_select.desc": "Snap rectangle selections to the nearest pixel edge, like in GIMP, instead of entire pixels.",
"settings.pick_color_opacity": "Pick Color Opacity",
"settings.pick_color_opacity.desc": "Pick the color opacity with the Color Picker and set it as brush opacity",
"dialog.project.modded_entity_flip_y": "Отразить ось Y",
"preview_scene.studio": "Студия",
"format.image": "Изображение",
"modifier_actions.set_copy_source": "Установить источник копирования",
"message.load_images.title": "Загрузить изображения",
"message.load_images.edit_image": "Редактировать изображение",
"dialog.add_primitive.align_edges": "Выровнять края",
"dialog.flip_animation.show_in_timeline": "Показать измененные кости на временной шкале",
"settings.default_cube_size": "Размер куба",
"settings.default_cube_size.desc": "Установите размер куба по умолчанию при создании нового куба",
"settings.uniform_keyframe": "Ключевые кадры единого масштаба",
"settings.uniform_keyframe.desc": "Установите масштабирование ключевых кадров на равномерное масштабирование по умолчанию.",
"settings.nearest_rectangle_select": "Выбор прямоугольника: ближайший край",
"settings.nearest_rectangle_select.desc": "Привязывайте выделенные прямоугольники к ближайшему краю пикселя, как в GIMP, а не к целым пикселям.",
"settings.pick_color_opacity": "Выберите непрозрачность цвета",
"settings.pick_color_opacity.desc": "Выберите непрозрачность цвета с помощью палитры цветов и установите ее как непрозрачность кисти.",
"settings.paint_with_stylus_only": "Рисовать только со стилусом",
"settings.paint_with_stylus_only.desc": "Only use the stylus for painting, reserve mouse or touch input for navigation.",
"settings.paint_with_stylus_only.desc": "Используйте только стилус для рисования, резервную мышь или сенсорный ввод для навигации.",
"action.copy_brush_mode": "Копировать режим кисти",
"action.copy_brush_mode.copy": "Копировать",
"action.copy_brush_mode.pattern": "Pattern",
"action.copy_brush_mode.sample": "Sample",
"action.copy_brush_mode.pattern": "Шаблон",
"action.copy_brush_mode.sample": "Образец",
"action.brush_shape": "Форма кисти",
"action.brush_shape.square": "Квадрат",
"action.brush_shape.circle": "Круг",
"action.blend_mode": "Blend Mode",
"action.blend_mode.default": "Default",
"action.blend_mode.set_opacity": "Set Opacity",
"action.blend_mode": "Режим смешивания",
"action.blend_mode.default": "По умолчанию",
"action.blend_mode.set_opacity": "Установить непрозрачность",
"action.blend_mode.color": "Цвет",
"action.blend_mode.behind": "Behind",
"action.blend_mode.multiply": "Multiply",
"action.blend_mode.divide": "Divide",
"action.blend_mode.add": "Add",
"action.blend_mode.subtract": "Subtract",
"action.blend_mode.screen": "Screen",
"action.blend_mode.overlay": "Overlay",
"action.blend_mode.hard_light": "Hard Light",
"action.blend_mode.difference": "Difference",
"action.blend_mode.behind": "Позади",
"action.blend_mode.multiply": "Умножить",
"action.blend_mode.divide": "Разделять",
"action.blend_mode.add": "Добавлять",
"action.blend_mode.subtract": "Вычесть",
"action.blend_mode.screen": "Экран",
"action.blend_mode.overlay": "Наложение",
"action.blend_mode.hard_light": "Жесткий свет",
"action.blend_mode.difference": "Разница",
"action.copy_brush": "Скопировать кисть",
"action.copy_brush.desc": "Brush to clone parts of your texture or draw patterns. Hold Ctrl and click to select a copy source.",
"action.validator_window": "View Model Issues...",
"action.validator_window.desc": "Opens the validator, which lists issues with the current model.",
"action.copy_brush.desc": "Кисть, чтобы клонировать части вашей текстуры или рисовать узоры. Удерживая нажатой клавишу Ctrl, щелкните, чтобы выбрать источник копирования.",
"action.validator_window": "Просмотр проблем с моделью...",
"action.validator_window.desc": "Открывает средство проверки, в котором перечислены проблемы с текущей моделью.",
"action.cancel_gif": "Отменить GIF",
"menu.text_edit.copy_vector": "Copy Vector",
"menu.brush_presets.dialog": "Brush Presets...",
"menu.text_edit.copy_vector": "Копировать вектор",
"menu.brush_presets.dialog": "Предустановки кистей...",
"menu.brush_presets.pixel_brush": "Пиксельная кисть",
"menu.brush_presets.smooth_brush": "Smooth Brush",
"menu.texture.edit_in_blockbench": "Edit in Blockbench",
"menu.brush_presets.smooth_brush": "Гладкая кисть",
"menu.texture.edit_in_blockbench": "Редактировать в Blockbench",
"menu.mirror_painting.axis": "Ось",
"menu.mirror_painting.axis.desc": "Select on which axis paint strokes will get mirrored",
"menu.mirror_painting.global": "Global Symmetry",
"menu.mirror_painting.global.desc": "Enabled mirror painting on the model in global space",
"menu.mirror_painting.local": "Local Symmetry",
"menu.mirror_painting.local.desc": "Enable mirror painting in local space for each element",
"menu.mirror_painting.texture_frames": "Repeat on Animated Texture Frames",
"menu.mirror_painting.texture_frames.desc": "Mirror paint strokes to every frame of animated textures",
"format.bedrock_block.info.size_limit": "Size total size of a block is limited to 30 pixels in all dimensions. The limit can be off-centered in all directions by 7 pixels from the block center.",
"format.bedrock_block.info.textures": "Multiple textures can be applied to different cubes in Blockbench, but require additional setup in the behavior pack to work correctly in-game.",
"format.image.desc": "Edit images in the 2D image editor",
"menu.mirror_painting.axis.desc": "Выберите, на какой оси штрихи краски будут отражаться",
"menu.mirror_painting.global": "Глобальная симметрия",
"menu.mirror_painting.global.desc": "Включена зеркальная отрисовка модели в глобальном пространстве.",
"menu.mirror_painting.local": "Локальная симметрия",
"menu.mirror_painting.local.desc": "Включить зеркальное рисование в локальном пространстве для каждого элемента",
"menu.mirror_painting.texture_frames": "Повтор на кадрах анимированных текстур",
"menu.mirror_painting.texture_frames.desc": "Отражайте мазки краской в ​​каждом кадре анимированных текстур.",
"format.bedrock_block.info.size_limit": "Размер Общий размер блока ограничен 30 пикселями во всех измерениях. Предел может быть смещен во всех направлениях на 7 пикселей от центра блока.",
"format.bedrock_block.info.textures": "Несколько текстур можно применять к разным кубам в Blockbench, но для правильной работы в игре требуется дополнительная настройка в пакете поведения.",
"format.image.desc": "Редактировать изображения в редакторе 2D-изображений",
"generic.delete_all": "Удалить всё",
"message.child_model_only.open": "Open Parent",
"message.child_model_only.open_with_textures": "Open Parent & Adopt Textures",
"dialog.project.credit": "Credit",
"dialog.convert_project.create_copy": "Create Copy",
"dialog.texture.frame_time": "Frame Time",
"dialog.texture.frame_time.desc": "Set for how long each frame will be visible, in ticks. Each tick is 1/20th of a second.",
"dialog.texture.frame_interpolate": "Interpolate",
"dialog.texture.frame_interpolate.desc": "Interpolate between animation frames by cross-fading to the next frame",
"message.child_model_only.open": "Открытый родитель",
"message.child_model_only.open_with_textures": "Открыть родительские и принять текстуры",
"dialog.project.credit": "Кредит",
"dialog.convert_project.create_copy": "Создать копию",
"dialog.texture.frame_time": "Время кадра",
"dialog.texture.frame_time.desc": "Установите, как долго каждый кадр будет виден в тиках. Каждый тик равен 1/20 секунды.",
"dialog.texture.frame_interpolate": "Интерполировать",
"dialog.texture.frame_interpolate.desc": "Интерполяция между кадрами анимации путем плавного перехода к следующему кадру",
"dialog.texture.frame_order_type": "Режим цикла",
"dialog.texture.frame_order_type.loop": "Цикл",
"dialog.texture.frame_order_type.backwards": "Обратный цикл",
"dialog.texture.frame_order_type.back_and_forth": "Туда-сюда",
"dialog.texture.frame_order_type.custom": "Своя последовательность",
"dialog.texture.frame_order": "Frame Order",
"dialog.texture.frame_order.desc": "Set a custom frame order by listing frame indices in a new order. Frame indices start at 0 with the first frame.",
"dialog.texture.frame_order": "Порядок кадров",
"dialog.texture.frame_order.desc": "Установите пользовательский порядок кадров, перечислив индексы кадров в новом порядке. Индексы кадров начинаются с 0 с первого кадра.",
"dialog.select.mode": "Режим",
"dialog.select.mode.new": "New Selection",
"dialog.select.mode.add": "Add to Selected",
"dialog.select.mode.remove": "Remove from Selected",
"dialog.select.mode.in_selection": "Select only from Selected",
"dialog.select.mode.new": "Новый выбор",
"dialog.select.mode.add": "Добавить в избранное",
"dialog.select.mode.remove": "Удалить из выбранных",
"dialog.select.mode.in_selection": "Выбрать только из выбранных",
"dialog.predicate_overrides.model": "Модель",
"dialog.predicate_overrides.predicates": "Predicates",
"dialog.predicate_overrides.variants": "Variants",
"dialog.predicate_overrides.start_value": "Start",
"dialog.predicate_overrides.add_override": "Add Override",
"dialog.predicate_overrides.add_predicate": "Add Predicate",
"dialog.predicate_overrides.generate_overrides": "Generate Overrides",
"dialog.predicate_overrides.confirm_delete": "Are you sure you want to delete all overrides?",
"dialog.predicate_overrides.predicate.angle": "Compass Angle",
"dialog.predicate_overrides.predicate.blocking": "Is Blocking",
"dialog.predicate_overrides.predicate.broken": "Is Broken",
"dialog.predicate_overrides.predicate.cast": "Is Cast",
"dialog.predicate_overrides.predicate.cooldown": "Cooldown",
"dialog.predicate_overrides.predicate.damage": "Damage",
"dialog.predicate_overrides.predicate.damaged": "Is Damaged",
"dialog.predicate_overrides.predicate.lefthanded": "Is Left-Handed",
"dialog.predicate_overrides.predicate.pull": "Pull Amount",
"dialog.predicate_overrides.predicate.pulling": "Is Pulling",
"dialog.predicate_overrides.predicate.charged": "Is Charged",
"dialog.predicate_overrides.predicate.firework": "Has Firework",
"dialog.predicate_overrides.predicate.throwing": "Ready to Throw",
"dialog.predicate_overrides.predicate.time": "Time of Day",
"dialog.predicate_overrides.predicate.custom_model_data": "Custom Model Data",
"dialog.predicate_overrides.predicate.level": "Light Level",
"dialog.predicate_overrides.predicate.filled": "Bundle Fill Level",
"dialog.predicate_overrides.predicate.tooting": "Tooting",
"settings.model_export_scale": "Model Export Scale",
"settings.model_export_scale.desc": "Factor by which the scale of exported glTF, DAE, and FBX models gets reduced. The default is 16, which converts 16 Blockbench units into 1 meter in the export.",
"action.copy_paste_tool_mode": "Copy Paste Mode",
"dialog.predicate_overrides.predicates": "Предикаты",
"dialog.predicate_overrides.variants": "Варианты",
"dialog.predicate_overrides.start_value": "Начинать",
"dialog.predicate_overrides.add_override": "Добавить переопределение",
"dialog.predicate_overrides.add_predicate": "Добавить предикат",
"dialog.predicate_overrides.generate_overrides": "Генерировать переопределения",
"dialog.predicate_overrides.confirm_delete": "Вы уверены, что хотите удалить все переопределения?",
"dialog.predicate_overrides.predicate.angle": "Угол компаса",
"dialog.predicate_overrides.predicate.blocking": "Блокирует",
"dialog.predicate_overrides.predicate.broken": "Сломан",
"dialog.predicate_overrides.predicate.cast": "литой",
"dialog.predicate_overrides.predicate.cooldown": "Остывать",
"dialog.predicate_overrides.predicate.damage": "Повреждать",
"dialog.predicate_overrides.predicate.damaged": "Поврежден",
"dialog.predicate_overrides.predicate.lefthanded": "Левша",
"dialog.predicate_overrides.predicate.pull": "Сумма вытягивания",
"dialog.predicate_overrides.predicate.pulling": "Тянет",
"dialog.predicate_overrides.predicate.charged": "Взимается",
"dialog.predicate_overrides.predicate.firework": "Имеет фейерверк",
"dialog.predicate_overrides.predicate.throwing": "Готов бросить",
"dialog.predicate_overrides.predicate.time": "Время суток",
"dialog.predicate_overrides.predicate.custom_model_data": "Пользовательские данные модели",
"dialog.predicate_overrides.predicate.level": "Уровень освещенности",
"dialog.predicate_overrides.predicate.filled": "Уровень заполнения пакета",
"dialog.predicate_overrides.predicate.tooting": "Верно подмечено",
"settings.model_export_scale": "Масштаб экспорта модели",
"settings.model_export_scale.desc": "Коэффициент, на который уменьшается масштаб экспортируемых моделей glTF, DAE и FBX. Значение по умолчанию — 16, что преобразует 16 единиц Blockbench в 1 метр при экспорте.",
"action.copy_paste_tool_mode": "Режим копирования и вставки",
"action.copy_paste_tool_mode.copy": "Копировать",
"action.copy_paste_tool_mode.move": "Move",
"action.copy_paste_tool_mode.move": "Двигаться",
"action.export_fbx": "Экспортировать FBX Модель",
"action.export_fbx.desc": "Export model and animations as fbx file to use it in other 3D applications and game engines",
"action.center_lateral": "Center Lateral",
"action.center_lateral.desc": "Center the selected elements on the X and Z axis",
"action.export_fbx.desc": "Экспортируйте модель и анимацию в виде файла fbx для использования в других 3D-приложениях и игровых движках.",
"action.center_lateral": "Центр Боковой",
"action.center_lateral.desc": "Центрировать выбранные элементы по осям X и Z",
"action.adjust_opacity": "Отрегулировать непрозрачность...",
"action.adjust_opacity.desc": "Отрегулируйте непрозрачность выбранной текстуры",
"action.rotate_texture_cw": "Повернуть текстуру по часовой стрелке",
"action.rotate_texture_ccw": "Повернуть текстуру против часовой стрелки",
"action.predicate_overrides": "Edit Predicate Overrides...",
"action.predicate_overrides.desc": "Select models to override this model based on selected conditions",
"action.predicate_overrides": "Редактировать переопределения предикатов...",
"action.predicate_overrides.desc": "Выберите модели для переопределения этой модели на основе выбранных условий",
"action.auto_set_cullfaces": "Автоматически устанавливать Cullfaces",
"action.auto_set_cullfaces.desc": "Автоматически генерировать cullfaces, чтобы скрыть грани, когда они перекрыты соседним блоком.",
"menu.texture.edit_externally": "Edit Externally",
"menu.texture.edit_externally": "Внешнее редактирование",
"menu.mirror_painting.texture": "Симметрия 2D редактора",
"menu.mirror_painting.texture.desc": "Enable mirror painting in 2D space on the image or texture",
"menu.animator.rotation_global": "Rotate in Global Space",
"uv_editor.face_properties": "Face Properties",
"uv_editor.face_properties.material_instance": "Material Instance",
"uv_editor.tint.info": "Tint can be enabled on a face to tell the Minecraft to tint it. In vanilla, tint can only be used by specific blocks such as leaves and redstone dust, and can only have a value of 0.",
"uv_editor.cullface.info": "Enabling cullface tells a face on a block to unrender if another full block is placed next to it in the specified direction in your Minecraft world. This can be used to optimize performance.",
"uv_editor.material_instance.info": "Material instances can be set to a user-defined name. That name can be used in the block JSON file in the behavior pack to assign a particular texture and material that the face.",
"menu.mirror_painting.texture.desc": "Включить зеркальное рисование в 2D-пространстве на изображении или текстуре",
"menu.animator.rotation_global": "Вращение в глобальном пространстве",
"uv_editor.face_properties": "Свойства грани",
"uv_editor.face_properties.material_instance": "Экземпляр материала",
"uv_editor.tint.info": "Оттенок можно включить на лице, чтобы сообщить Minecraft, чтобы он подкрашивал его. В ванили оттенок может использоваться только определенными блоками, такими как листья и пыль красного камня, и может иметь значение только 0.",
"uv_editor.cullface.info": "Включение cullface указывает лицу на блоке отменить рендеринг, если рядом с ним в указанном направлении в вашем мире Minecraft будет размещен другой полный блок. Это можно использовать для оптимизации производительности.",
"uv_editor.material_instance.info": "Экземплярам материала можно присвоить определяемое пользователем имя. Это имя можно использовать в файле блока JSON в пакете поведения, чтобы назначить конкретную текстуру и материал для лица.",
"display.reference.frame_invisible": "Рамка (Невидимая)",
"data.settings_profile": "Профиль",
"message.display_skin.invalid_name": "Cannot find Minecraft account with the name \"%0\".",
"dialog.load_plugins_from_query.title": "Load Plugins",
"dialog.load_plugins_from_query.text": "You used a link that requires plugins to be installed. Would you like to install them?",
"message.display_skin.invalid_name": "Не удается найти учетную запись Minecraft с именем \"%0\".",
"dialog.load_plugins_from_query.title": "Загрузить плагины",
"dialog.load_plugins_from_query.text": "Вы использовали ссылку, которая требует установки плагинов. Хотите их установить?",
"dialog.select_model.title": "Выбрать модель",
"dialog.select_model.bones": "Bones",
"dialog.select_model.cubes": "Cubes",
"dialog.select_model.bones": "Кости",
"dialog.select_model.cubes": "Кубики",
"dialog.settings.create_profile": "Создать профиль...",
"settings_profile.confirm_delete": "Are you sure you want to delete this settings profile?",
"settings_profile.condition.type.selectable": "Manually Selectable",
"settings.interface_mode": "UI Mode",
"settings.interface_mode.desc": "Interface mode. Restart Blockbench to apply changes",
"settings.interface_mode.auto": "Automatic",
"settings.interface_mode.desktop": "Desktop",
"settings.interface_mode.mobile": "Mobile",
"settings.paint_through_transparency": "Paint Through Transparency",
"settings.paint_through_transparency.desc": "Paint through transparent pixels when Lock Alpha Channel is enabled",
"action.tab_overview": "Tab Overview",
"action.tab_overview.desc": "View all open tabs in a grid and jump to one",
"settings_profile.confirm_delete": "Вы уверены, что хотите удалить этот профиль настроек?",
"settings_profile.condition.type.selectable": "Выбирается вручную",
"settings.interface_mode": "Режим пользовательского интерфейса",
"settings.interface_mode.desc": "Режим интерфейса. Перезапустите Blockbench, чтобы применить изменения",
"settings.interface_mode.auto": "автоматический",
"settings.interface_mode.desktop": "Рабочий стол",
"settings.interface_mode.mobile": "Мобильный",
"settings.paint_through_transparency": "Рисовать через прозрачность",
"settings.paint_through_transparency.desc": "Рисуйте через прозрачные пиксели, когда включена блокировка альфа-канала",
"action.tab_overview": "Обзор вкладки",
"action.tab_overview.desc": "Просмотр всех открытых вкладок в сетке и переход к одной из них",
"action.slider_color_red": "Красный цвет",
"action.slider_color_green": "Зелёный цвет",
"action.slider_color_blue": "Синий цвет",
@ -1732,144 +1732,146 @@
"action.animation_controller_preview_mode.manual": "Предварительный просмотр вручную",
"action.animation_controller_preview_mode.play": "Авто-проигрывание",
"action.keyframe_interpolation.bezier": "Кривая",
"action.keyframe_bezier_linked": "Link Bézier Handles",
"action.keyframe_bezier_linked.desc": "Connect the right and left keyframe bézier handle",
"action.reset_keyframe_handles": "Reset Keyframe Handles",
"action.reset_keyframe_handles.desc": "Reset the bézier handles of the selected keyframes",
"action.looped_animation_playback": "Looped Playback",
"action.looped_animation_playback.desc": "Preview animations in an infinite loop",
"timeline.bind_to_actor": "Bind to Actor",
"animation_controllers.select_preset": "Select a controller preset...",
"action.keyframe_bezier_linked": "Link Ручки Безье",
"action.keyframe_bezier_linked.desc": "Соедините правый и левый маркер Безье ключевого кадра",
"action.reset_keyframe_handles": "Сбросить маркеры ключевого кадра",
"action.reset_keyframe_handles.desc": "Сбросить маркеры Безье выбранных ключевых кадров",
"action.looped_animation_playback": "Зацикленное воспроизведение",
"action.looped_animation_playback.desc": "Предварительный просмотр анимации в бесконечном цикле",
"timeline.bind_to_actor": "Привязать к актеру",
"animation_controllers.select_preset": "Выберите предустановку контроллера...",
"animation_controllers.state.animations": "Анимации",
"animation_controllers.state.particles": "Частицы",
"animation_controllers.state.sounds": "Звуки",
"animation_controllers.state.on_entry": "On Entry",
"animation_controllers.state.on_exit": "On Exit",
"animation_controllers.state.on_entry": "При въезде",
"animation_controllers.state.on_exit": "На выходе",
"animation_controllers.state.transitions": "Переходы",
"animation_controllers.state.condition": "Condition",
"animation_controllers.state.blend_transition": "Blend Time",
"animation_controllers.state.shortest_path": "Blend by Shortest Path",
"animation_controllers.state.edit_transition": "Edit Transition",
"menu.color_picker.picker_type": "Picker Type",
"animation_controllers.state.condition": "Состояние",
"animation_controllers.state.blend_transition": "Время смешивания",
"animation_controllers.state.shortest_path": "Смешать по кратчайшему пути",
"animation_controllers.state.edit_transition": "Изменить переход",
"menu.color_picker.picker_type": "Тип подборщика",
"menu.color_picker.picker_type.square": "Квадрат",
"menu.color_picker.picker_type.wheel": "Колесо",
"menu.color_picker.slider_mode": "Slider Mode",
"menu.color_picker.slider_mode": "Режим слайдера",
"menu.color_picker.slider_mode.hsv": "HSV",
"menu.color_picker.slider_mode.rgb": "Красный, Зелёный, Синий",
"menu.texture.render_mode.additive": "Additive",
"panel.color.picker_options": "Color Picker Options",
"panel.animation_controllers": "Animation Controller",
"display.preset.armor_stand": "Ground (Armor Stand)",
"menu.texture.render_mode.additive": "добавка",
"panel.color.picker_options": "Параметры палитры цветов",
"panel.animation_controllers": "Контроллер анимации",
"display.preset.armor_stand": "Земля (подставка для брони)",
"data.file_path": "Путь до файлы",
"dialog.extrude.orientation": "Ориентация",
"dialog.extrude.orientation.upright": "Upright",
"dialog.extrude.orientation.flat": "Flat",
"dialog.scale.box_uv_warning": "Scaling a Box UV model may break the UV of your model. Instead, try to scale your model externally, or switch to Per-face UV Mode in File > Project.",
"dialog.create_gif.format": "Format",
"dialog.extrude.orientation.upright": "Вертикальный",
"dialog.extrude.orientation.flat": "Плоский",
"dialog.scale.box_uv_warning": "Масштабирование модели Box UV может сломать UV вашей модели. Вместо этого попробуйте масштабировать модель снаружи или переключитесь в режим Per-face UV Mode в меню «Файл» > «Проект».",
"dialog.create_gif.format": "Формат",
"dialog.create_gif.format.gif": "GIF",
"dialog.create_gif.format.png_sequence": "Последовательность PNG",
"dialog.create_gif.pixelate": "Pixelate",
"dialog.create_gif.pixelate": "Пикселизация",
"dialog.create_gif.bg_image": "Фоновое изображение",
"dialog.create_gif.turn.desc": "Rotate the model while recording. Use negative values to turn the model clockwise. A value of 60 corresponds to one rotation every second.",
"settings_profile.condition": "Condition",
"settings_profile.condition.type.file_path.desc": "Use Regular Expression syntax to match the file path of the current project. Use forward slashes for directories",
"settings.only_selected_bezier_handles": "Show Only Selected Bézier Handles",
"settings.only_selected_bezier_handles.desc": "Hide handles of bézier keyframes that are not currently selected",
"settings.embed_textures": "Embed Textures",
"settings.embed_textures.desc": "Embed texture file content in .bbmodel files",
"action.selection_mode.cluster": "Cluster",
"dialog.copied_to_clipboard": "Copied to clipboard",
"data.reference_image": "Reference Image",
"message.delete_reference_image": "Are you sure you want to delete this reference image? This cannot be undone.",
"message.add_reference_image.message": "Select where to load the reference image",
"message.add_reference_image.project": "Add to this project",
"message.add_reference_image.app": "Add to all projects",
"message.import_particle_texture.import": "Import Particle Texture",
"message.import_particle_texture.message": "Would you like to import a texture file to be used for your particle?",
"message.save_codec_selector.title": "Save Model Format",
"message.save_codec_selector.message": "Select a format to save the model in.",
"message.save_codec_selector.project_file": "Blockbench Project (.bbmodel)",
"message.save_codec_selector.both": "Both",
"message.display_skin.username": "Username (Java)",
"message.palette_locked": "The palette is locked",
"dialog.project.default_uv_mode": "Default UV Mode",
"dialog.project.default_uv_mode.description": "Default UV Mode of the project. The UV mode can also be changed per cube.",
"dialog.export_options.title": "Export Options",
"dialog.edit_texture.preview": "Preview",
"dialog.proportional_editing.range": "Range",
"dialog.proportional_editing.falloff": "Falloff",
"dialog.proportional_editing.falloff.linear": "Linear",
"dialog.proportional_editing.falloff.hermite_spline": "Smooth",
"dialog.proportional_editing.falloff.constant": "Constant",
"dialog.proportional_editing.selection": "Selection",
"dialog.proportional_editing.selection.linear": "Linear Distance",
"dialog.proportional_editing.selection.connections": "Connections",
"dialog.mirror_painting_texture_center.middle": "Middle",
"dialog.mirror_painting_texture_center.custom": "Custom",
"dialog.settings.reset_to_default": "Reset to Default",
"keybindings.item.num_slider.increase": "Increase",
"keybindings.item.num_slider.decrease": "Decrease",
"settings.always_show_splash_art": "Always Show Splash Art",
"settings.always_show_splash_art.desc": "Always display the splash art on the start screen",
"action.slider_palette_color": "Switch Palette Color",
"action.slider_palette_color.desc": "Cycle between the colors in the palette",
"action.proportional_editing": "Proportional Editing",
"action.proportional_editing.desc": "Proportionally affect surrounding vertices when editing parts of a mesh",
"action.limit_to_palette": "Limit to Palette",
"action.limit_to_palette.desc": "Limits the colors of the texture to those in the currently loaded palette",
"action.edit_reference_images": "Edit Reference Images",
"action.edit_reference_images.desc": "Turn on reference image mode to add or edit reference images and blueprints",
"dialog.create_gif.turn.desc": "Поворачивайте модель во время записи. Используйте отрицательные значения, чтобы повернуть модель по часовой стрелке. Значение 60 соответствует одному обороту в секунду.",
"settings_profile.condition": "Состояние",
"settings_profile.condition.type.file_path.desc": "Используйте синтаксис регулярного выражения для соответствия пути к файлу текущего проекта. Используйте косую черту для каталогов",
"settings.only_selected_bezier_handles": "Показать только выбранные ручки Безье",
"settings.only_selected_bezier_handles.desc": "Скрыть маркеры ключевых кадров Безье, которые в данный момент не выбраны",
"settings.embed_textures": "Встроить текстуры",
"settings.embed_textures.desc": "Встроить содержимое файла текстуры в файлы .bbmodel",
"action.selection_mode.cluster": "Кластер",
"dialog.copied_to_clipboard": "Скопировано в буфер обмена",
"data.reference_image": "Эталонное изображение",
"message.delete_reference_image": "Вы уверены, что хотите удалить это эталонное изображение? Это не может быть отменено.",
"message.add_reference_image.message": "Выберите, куда загрузить эталонное изображение",
"message.add_reference_image.project": "Добавить в этот проект",
"message.add_reference_image.app": "Добавить во все проекты",
"message.import_particle_texture.import": "Импорт текстуры частиц",
"message.import_particle_texture.message": "Вы хотите импортировать файл текстуры, который будет использоваться для вашей частицы?",
"message.save_codec_selector.title": "Сохранить формат модели",
"message.save_codec_selector.message": "Выберите формат для сохранения модели.",
"message.save_codec_selector.project_file": "Проект Blockbench (.bbmodel)",
"message.save_codec_selector.both": "Оба",
"message.display_skin.username": "Имя пользователя (Ява)",
"message.palette_locked": "Палитра заблокирована",
"dialog.project.default_uv_mode": "UV-режим по умолчанию",
"dialog.project.default_uv_mode.description": "UV-режим проекта по умолчанию. Режим UV также можно изменить для каждого куба.",
"dialog.export_options.title": "Параметры экспорта",
"dialog.edit_texture.preview": "Предварительный просмотр",
"dialog.proportional_editing.range": "Диапазон",
"dialog.proportional_editing.falloff": "Спад",
"dialog.proportional_editing.falloff.linear": "Линейный",
"dialog.proportional_editing.falloff.hermite_spline": "Гладкий",
"dialog.proportional_editing.falloff.constant": "Постоянный",
"dialog.proportional_editing.selection": "Выбор",
"dialog.proportional_editing.selection.linear": "Линейное расстояние",
"dialog.proportional_editing.selection.connections": "Соединения",
"dialog.mirror_painting_texture_center.middle": "Середина",
"dialog.mirror_painting_texture_center.custom": "Обычай",
"dialog.settings.reset_to_default": "Восстановление значений по умолчанию",
"keybindings.item.num_slider.increase": "Увеличивать",
"keybindings.item.num_slider.decrease": "Снижаться",
"settings.always_show_splash_art": "Всегда показывать заставки",
"settings.always_show_splash_art.desc": "Всегда отображать заставку на стартовом экране",
"action.slider_palette_color": "Переключить цвет палитры",
"action.slider_palette_color.desc": "Цикл между цветами в палитре",
"action.proportional_editing": "Пропорциональное редактирование",
"action.proportional_editing.desc": "Пропорционально влияет на окружающие вершины при редактировании частей сетки.",
"action.limit_to_palette": "Ограничить палитрой",
"action.limit_to_palette.desc": "Ограничивает цвета текстуры цветами из текущей загруженной палитры.",
"action.edit_reference_images": "Редактировать эталонные изображения",
"action.edit_reference_images.desc": "Включите режим эталонного изображения, чтобы добавлять или редактировать эталонные изображения и чертежи.",
"action.add_reference_image": "Добавить Эталонное Изображение",
"action.reference_image_from_clipboard": "Reference Image from Clipboard",
"action.reference_image_list": "Reference Images",
"action.connect_uv_faces": "Connect UV Faces",
"action.connect_uv_faces.desc": "Connect the selected UV faces to the last selected UV face",
"action.merge_uv_vertices": "Merge UV Vertices",
"action.merge_uv_vertices.desc": "Snap the first selected UV vertices to the last selected UV vertices",
"action.reference_image_from_clipboard": "Эталонное изображение из буфера обмена",
"action.reference_image_list": "Эталонные изображения",
"action.connect_uv_faces": "Соедините UV-грани",
"action.connect_uv_faces.desc": "Соедините выбранные UV-грани с последней выбранной UV-гранью",
"action.merge_uv_vertices": "Объединить UV-вершины",
"action.merge_uv_vertices.desc": "Привязать первые выбранные вершины UV к последним выбранным вершинам UV",
"action.bedrock_animation_mode": "Режим анимации бедрока",
"action.bedrock_animation_mode.desc": "Select the mode to edit animations for Minecraft: Bedrock Edition in",
"action.bedrock_animation_mode.entity": "Entity",
"action.bedrock_animation_mode.attachable_first": "Item 1st Person",
"action.bedrock_animation_mode.attachable_third": "Item 3rd Person",
"timeline.amplify": "Amplify",
"menu.options": "Options...",
"menu.palette.lock_palette": "Lock Palette",
"menu.uv.export": "Export UV Mapping",
"menu.uv.flip_x": "Mirror X",
"menu.uv.flip_y": "Mirror Y",
"menu.mirror_painting.enabled": "Enabled",
"menu.mirror_painting.configure_texture_center": "Configure Texture Center...",
"reference_image.position": "Position",
"reference_image.size": "Size",
"reference_image.rotation": "Rotation",
"reference_image.opacity": "Opacity",
"reference_image.visibility": "Visibility",
"reference_image.clear_mode": "Clear Mode",
"reference_image.layer": "Layer",
"reference_image.layer.background": "Behind Model",
"reference_image.layer.viewport": "Above Model",
"reference_image.layer.float": "Above Interface",
"reference_image.layer.blueprint": "Locked Blueprint",
"reference_image.scope": "Scope",
"reference_image.scope.project": "Just this project",
"reference_image.scope.global": "All projects",
"reference_image.enabled_modes": "Enabled in Modes",
"codec.common.encoding": "Encoding",
"codec.common.armature": "Export Groups as Armature",
"codec.common.export_animations": "Export Animations",
"codec.common.embed_textures": "Embed Textures",
"preview.center_camera": "Center Camera",
"display.reference.frame_top": "Item Frame Top",
"display.reference.frame_top_invisible": "Item Frame Top (Invisible)",
"action.proportional_editing_range": "Proportional Editing Range",
"action.proportional_editing_range.desc": "Adjust the range for proportional editing",
"action.toggle_all_reference_images": "Hide/Show All Reference Images",
"action.toggle_all_reference_images.desc": "Toggle the visibility of all reference images at once",
"action.bedrock_animation_mode.desc": "Выберите режим редактирования анимации для Minecraft: Bedrock Edition в",
"action.bedrock_animation_mode.entity": "Сущность",
"action.bedrock_animation_mode.attachable_first": "Пункт 1-е лицо",
"action.bedrock_animation_mode.attachable_third": "Пункт 3-е лицо",
"timeline.amplify": "Усиление",
"menu.options": "Параметры...",
"menu.palette.lock_palette": "Заблокировать палитру",
"menu.uv.export": "Экспорт UV-карты",
"menu.uv.flip_x": "Зеркало Х",
"menu.uv.flip_y": "Зеркало Y",
"menu.mirror_painting.enabled": "Включено",
"menu.mirror_painting.configure_texture_center": "Настроить центр текстур...",
"reference_image.position": "Позиция",
"reference_image.size": "Размер",
"reference_image.rotation": "Вращение",
"reference_image.opacity": "Непрозрачность",
"reference_image.visibility": "Видимость",
"reference_image.clear_mode": "Очистить режим",
"reference_image.layer": "Слой",
"reference_image.layer.background": "За моделью",
"reference_image.layer.viewport": "Модель выше",
"reference_image.layer.float": "Над интерфейсом",
"reference_image.layer.blueprint": "Закрытый чертёж",
"reference_image.scope": "Объём",
"reference_image.scope.project": "Только этот проект",
"reference_image.scope.global": "Все проекты",
"reference_image.enabled_modes": "Включено в режимах",
"codec.common.encoding": "Кодирование",
"codec.common.armature": "Экспортировать группы как арматуру",
"codec.common.export_animations": "Экспорт анимации",
"codec.common.embed_textures": "Встроить текстуры",
"preview.center_camera": "Центральная камера",
"display.reference.frame_top": "Верх рамки элемента",
"display.reference.frame_top_invisible": "Верхняя часть рамки предмета (невидимая)",
"action.proportional_editing_range": "Пропорциональный диапазон редактирования",
"action.proportional_editing_range.desc": "Отрегулируйте диапазон для пропорционального редактирования",
"action.toggle_all_reference_images": "Скрыть/показать все эталонные изображения",
"action.toggle_all_reference_images.desc": "Переключить видимость всех эталонных изображений одновременно",
"action.add_animation_controller_state": "Добавить Состояние Контроллера Анимации",
"action.add_animation_controller_state.desc": "Добавьте новое состояние в контроллер анимации",
"menu.slider.round_value": "Round Value",
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"menu.slider.round_value": "Круглое значение",
"texture.error.too_large": "Разрешение превышает максимум %0",
"dialog.copy_to_clipboard": "Скопировать в буфер обмена",
"dialog.open_url": "Открыть URL",
"reference_image.image": "Изображение",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -51,7 +51,7 @@
"message.file_not_found.title": "Không tìm thấy Tệp",
"message.file_not_found.message": "Blockbench không thể tìm được tệp được yêu cầu. Hãy đảm bảo rằng nó được lưu trên máy và không phải trong hệ thống cloud.",
"message.screenshot.title": "Chụp ảnh màn hình",
"message.screenshot.clipboard": "Bảng ghi tạm",
"message.screenshot.clipboard": "Bảng tạm",
"message.screenshot.right_click": "Chụp hình - Nháy Phải để sao chép",
"message.invalid_file.title": "Tệp không hợp lệ",
"message.invalid_file.message": "Không thể mở tệp json: %0",
@ -438,12 +438,12 @@
"uv_editor.title": "Chỉnh sửa UV",
"uv_editor.all_faces": "Mọi mặt",
"uv_editor.no_faces": "không có mặt",
"face.north": "Mặt Bắc",
"face.south": "Mặt Nam",
"face.west": "Mặt Tây",
"face.east": "Mặt Đông",
"face.up": "Mặt Trên",
"face.down": "Mặt Dưới",
"face.north": "Bắc",
"face.south": "Nam",
"face.west": "Tây",
"face.east": "Đông",
"face.up": "Trên",
"face.down": "Dưới",
"direction.north": "Bắc",
"direction.south": "Nam",
"direction.west": "Tây",
@ -917,7 +917,7 @@
"menu.help.search_action": "Tìm kiếm và chạy hành động",
"menu.help.donate": "Donate",
"menu.help.about": "Giới thiệu...",
"menu.preview.background.clipboard": "Tải từ clipboard",
"menu.preview.background.clipboard": "Tải từ bảng tạm",
"dialog.ignore": "Phớt lờ",
"generic.unset": "Bỏ đặt",
"message.invalid_builtin_parent.title": "Mô hình gốc không hợp lệ",
@ -1266,7 +1266,7 @@
"dialog.add_primitive.shape.tube": "Hình ống",
"dialog.add_primitive.shape.cone": "Hình nón",
"dialog.add_primitive.shape.cylinder": "Hình trụ",
"dialog.add_primitive.shape.sphere": "Quả cầu",
"dialog.add_primitive.shape.sphere": "Hình cầu",
"dialog.add_primitive.shape.torus": "Hình xuyến",
"dialog.add_primitive.shape.cube": "Hình khối",
"dialog.add_primitive.shape.pyramid": "Hình kim tự tháp",
@ -1404,7 +1404,7 @@
"modifier_actions.uniform_scaling": "Tỷ lệ thống nhất",
"modifier_actions.snap_direction": "Định hướng",
"message.no_valid_elements": "Không có yếu tố hợp lệ được chọn...",
"dialog.add_primitive.shape.plane": "Sàn",
"dialog.add_primitive.shape.plane": "Mặt phẳng",
"dialog.save_angle.rotation_mode": "Chế độ quay",
"dialog.save_angle.rotation": "Quay",
"dialog.save_angle.fov": "FOV",
@ -1524,7 +1524,7 @@
"mode.start.create_new": "Tạo mô hình mới",
"mode.start.format.informations": "Tốt để biết:",
"mode.start.format.resources": "Tài nguyên:",
"format.free.info.meshes": "Định dạng này cho phép xây dựng các mô hình low-poly bằng cách sử dụng các hình khối và khung lưới có hình dạng tùy chỉnh.",
"format.free.info.meshes": "Định dạng này cho phép xây dựng các mô hình đa giác thấp bằng cách sử dụng các hình khối và khung lưới có hình dạng tùy chỉnh.",
"format.free.info.limitation": "Không thể tải mô hình vào các trò chơi cần định dạng chuyên biệt, chẳng hạn như Minecraft.",
"format.skin.info.skin": "Định dạng này được thiết kế để tạo giao diện và kết cấu thực thể cho Minecraft.",
"format.skin.info.model": "Không thể thay đổi mô hình. Để thay đổi mô hình, trước tiên hãy chuyển đổi sang định dạng khác thông qua **Tệp** > **Chuyển đổi dự án**.",
@ -1538,7 +1538,7 @@
"format.modded_entity.info.format": "Các mô hình được viết bằng mã Java thay vì cấu trúc dữ liệu chuyên dụng như tất cả các định dạng xuất Blockbench khác.",
"format.optifine_entity.info.optifine_required": "Người dùng không cài đặt OptiFine sẽ không thấy mô hình.",
"format.optifine_entity.info.pivots": "Tâm quay của phần xương bị khóa, tốt nhất bạn không nên chạm vào nó.",
"format_category.low_poly": "Low-Poly",
"format_category.low_poly": "Đa giác thấp",
"format_category.minecraft": "Minecraft",
"format_category.other": "Khác",
"format_category.loaders": "Trình tải",
@ -1778,49 +1778,49 @@
"settings.embed_textures": "Nhúng kết cấu",
"settings.embed_textures.desc": "Nhúng nội dung tệp kết cấu vào tệp .bbmodel",
"action.selection_mode.cluster": "Cụm",
"dialog.copied_to_clipboard": "Copied to clipboard",
"data.reference_image": "Reference Image",
"message.delete_reference_image": "Are you sure you want to delete this reference image? This cannot be undone.",
"message.add_reference_image.message": "Select where to load the reference image",
"message.add_reference_image.project": "Add to this project",
"message.add_reference_image.app": "Add to all projects",
"message.import_particle_texture.import": "Import Particle Texture",
"message.import_particle_texture.message": "Would you like to import a texture file to be used for your particle?",
"message.save_codec_selector.title": "Save Model Format",
"message.save_codec_selector.message": "Select a format to save the model in.",
"message.save_codec_selector.project_file": "Blockbench Project (.bbmodel)",
"message.save_codec_selector.both": "Both",
"message.display_skin.username": "Username (Java)",
"message.palette_locked": "The palette is locked",
"dialog.project.default_uv_mode": "Default UV Mode",
"dialog.project.default_uv_mode.description": "Default UV Mode of the project. The UV mode can also be changed per cube.",
"dialog.export_options.title": "Export Options",
"dialog.edit_texture.preview": "Preview",
"dialog.proportional_editing.range": "Range",
"dialog.proportional_editing.falloff": "Falloff",
"dialog.proportional_editing.falloff.linear": "Linear",
"dialog.proportional_editing.falloff.hermite_spline": "Smooth",
"dialog.proportional_editing.falloff.constant": "Constant",
"dialog.proportional_editing.selection": "Selection",
"dialog.proportional_editing.selection.linear": "Linear Distance",
"dialog.proportional_editing.selection.connections": "Connections",
"dialog.mirror_painting_texture_center.middle": "Middle",
"dialog.mirror_painting_texture_center.custom": "Custom",
"dialog.settings.reset_to_default": "Reset to Default",
"keybindings.item.num_slider.increase": "Increase",
"keybindings.item.num_slider.decrease": "Decrease",
"settings.always_show_splash_art": "Always Show Splash Art",
"settings.always_show_splash_art.desc": "Always display the splash art on the start screen",
"action.slider_palette_color": "Switch Palette Color",
"action.slider_palette_color.desc": "Cycle between the colors in the palette",
"action.proportional_editing": "Proportional Editing",
"action.proportional_editing.desc": "Proportionally affect surrounding vertices when editing parts of a mesh",
"action.limit_to_palette": "Limit to Palette",
"action.limit_to_palette.desc": "Limits the colors of the texture to those in the currently loaded palette",
"action.edit_reference_images": "Edit Reference Images",
"action.edit_reference_images.desc": "Turn on reference image mode to add or edit reference images and blueprints",
"dialog.copied_to_clipboard": "Đã sao chép vào bảng tạm",
"data.reference_image": "Ảnh tham chiếu",
"message.delete_reference_image": "Bạn có chắc chắn muốn xóa ảnh tham chiếu này không? Điều này không thể được hoàn tác.",
"message.add_reference_image.message": "Chọn nơi tải ảnh tham chiếu",
"message.add_reference_image.project": "Thêm vào dự án này",
"message.add_reference_image.app": "Thêm vào tất cả các dự án",
"message.import_particle_texture.import": "Nhập kết cấu hạt",
"message.import_particle_texture.message": "Bạn có muốn nhập tệp kết cấu để sử dụng cho hạt của mình không?",
"message.save_codec_selector.title": "Lưu định dạng mô hình",
"message.save_codec_selector.message": "Chọn một định dạng để lưu mô hình.",
"message.save_codec_selector.project_file": "Dự án Blockbench (.bbmodel)",
"message.save_codec_selector.both": "Cả hai",
"message.display_skin.username": "Tên người dùng (Java)",
"message.palette_locked": "Bảng màu bị khóa",
"dialog.project.default_uv_mode": "Chế độ UV mặc định",
"dialog.project.default_uv_mode.description": "Chế độ UV mặc định của dự án. Chế độ UV cũng có thể được thay đổi trên mỗi khối.",
"dialog.export_options.title": "Tùy chọn xuất",
"dialog.edit_texture.preview": "Xem trước",
"dialog.proportional_editing.range": "Phạm vi",
"dialog.proportional_editing.falloff": "Suy thoái",
"dialog.proportional_editing.falloff.linear": "Tuyến tính",
"dialog.proportional_editing.falloff.hermite_spline": "Mịn màng",
"dialog.proportional_editing.falloff.constant": "Hằng số",
"dialog.proportional_editing.selection": "Lựa chọn",
"dialog.proportional_editing.selection.linear": "Khoảng cách tuyến tính",
"dialog.proportional_editing.selection.connections": "Các kết nối",
"dialog.mirror_painting_texture_center.middle": "Ở giữa",
"dialog.mirror_painting_texture_center.custom": "Tuỳ biến",
"dialog.settings.reset_to_default": "Đặt lại về mặc định",
"keybindings.item.num_slider.increase": "Tăng",
"keybindings.item.num_slider.decrease": "Giảm bớt",
"settings.always_show_splash_art": "Luôn hiển thị màn hình giật gân",
"settings.always_show_splash_art.desc": "Luôn hiển thị màn hình giật gân trên màn hình bắt đầu",
"action.slider_palette_color": "Chuyển đổi bảng màu",
"action.slider_palette_color.desc": "Luân chuyển giữa các màu trong bảng màu",
"action.proportional_editing": "Chỉnh sửa theo tỷ lệ",
"action.proportional_editing.desc": "Ảnh hưởng đến các đỉnh xung quanh theo tỷ lệ khi chỉnh sửa các phần của lưới.",
"action.limit_to_palette": "Giới hạn bảng màu",
"action.limit_to_palette.desc": "Giới hạn màu kết cấu thành màu từ bảng màu được tải",
"action.edit_reference_images": "Chỉnh sửa hình ảnh tham khảo",
"action.edit_reference_images.desc": "Bật chế độ hình ảnh tham chiếu để thêm hoặc chỉnh sửa hình ảnh tham khảo và bản thiết kế",
"action.add_reference_image": "Add Reference Image",
"action.reference_image_from_clipboard": "Reference Image from Clipboard",
"action.reference_image_from_clipboard": "Ảnh tham chiếu từ bảng tạm",
"action.reference_image_list": "Reference Images",
"action.connect_uv_faces": "Connect UV Faces",
"action.connect_uv_faces.desc": "Connect the selected UV faces to the last selected UV face",
@ -1861,15 +1861,17 @@
"preview.center_camera": "Center Camera",
"display.reference.frame_top": "Item Frame Top",
"display.reference.frame_top_invisible": "Item Frame Top (Invisible)",
"action.proportional_editing_range": "Proportional Editing Range",
"action.proportional_editing_range.desc": "Adjust the range for proportional editing",
"action.proportional_editing_range": "Phạm vi chỉnh sửa theo tỷ lệ",
"action.proportional_editing_range.desc": "Điều chỉnh phạm vi để chỉnh sửa theo tỷ lệ",
"action.toggle_all_reference_images": "Hide/Show All Reference Images",
"action.toggle_all_reference_images.desc": "Toggle the visibility of all reference images at once",
"action.add_animation_controller_state": "Add Animation Controller State",
"action.add_animation_controller_state.desc": "Add a new state to the animation controller",
"menu.slider.round_value": "Round Value",
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.copy_to_clipboard": "Sao chép vào bảng tạm",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -1871,5 +1871,7 @@
"texture.error.too_large": "Resolution exceeds the maximum of %0",
"dialog.copy_to_clipboard": "Copy to clipboard",
"dialog.open_url": "Open URL",
"reference_image.image": "Image"
"reference_image.image": "Image",
"uv_editor.rotate_uv": "Rotate UV",
"projects.start_screen": "Start Screen"
}

View File

@ -276,19 +276,19 @@ app.on('ready', () => {
ipcMain.on('allow-auto-update', () => {
autoUpdater.downloadUpdate()
})
orig_win.webContents.send('update-available', a);
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-available', a);
})
autoUpdater.on('update-downloaded', (a) => {
console.log('update-downloaded', a)
orig_win.webContents.send('update-downloaded', a)
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-downloaded', a)
})
autoUpdater.on('error', (a) => {
console.log('update-error', a)
orig_win.webContents.send('update-error', a)
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-error', a)
})
autoUpdater.on('download-progress', (a) => {
console.log('update-progress', a)
orig_win.webContents.send('update-progress', a)
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-progress', a)
})
autoUpdater.checkForUpdates().catch(err => {})
}

View File

@ -1,7 +1,7 @@
{
"name": "Blockbench",
"description": "Low-poly modeling and animation software",
"version": "4.7.1",
"version": "4.7.4",
"license": "GPL-3.0-or-later",
"author": {
"name": "JannisX11",

File diff suppressed because one or more lines are too long