mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-01-18 15:26:19 +08:00
v2.2.1
This commit is contained in:
parent
fdd60bd27b
commit
d4e6ad1471
@ -1381,6 +1381,7 @@
|
||||
position: absolute;
|
||||
opacity: 0.4;
|
||||
cursor: inherit;
|
||||
pointer-events: none;
|
||||
}
|
||||
#uv_dialog_toolbar {
|
||||
clear: both;
|
||||
@ -1561,7 +1562,6 @@
|
||||
width: 100%;
|
||||
min-height: 34px;
|
||||
padding-left: 6px;
|
||||
border-bottom: 2px solid var(--color-border);
|
||||
}
|
||||
#settings h3 > i {
|
||||
margin-top: 5px;
|
||||
@ -1618,7 +1618,6 @@
|
||||
}
|
||||
#settingslist > li {
|
||||
padding-left: 6px;
|
||||
border-bottom: 2px solid var(--color-border);
|
||||
}
|
||||
#settingslist li li {
|
||||
padding-top: 7px;
|
||||
|
10
index.html
10
index.html
@ -144,7 +144,7 @@
|
||||
<li v-for="item in currentBar" v-bind:title="item.name" :key="item.id||item">
|
||||
<div v-if="typeof item === 'string'" class="toolbar_separator"></div>
|
||||
<div v-else class="tool">
|
||||
<span class="icon_wrapper" v-bind:style="{opacity: BARS.condition(item.condition) ? 1 : 0.4}" v-html="Blockbench.getIconNode(item.icon).outerHTML"></span>
|
||||
<span class="icon_wrapper" v-bind:style="{opacity: BARS.condition(item.condition) ? 1 : 0.4}" v-html="Blockbench.getIconNode(item.icon, item.color).outerHTML"></span>
|
||||
<div class="tooltip">{{item.name + (BARS.condition(item.condition) ? '' : ' (' + tl('dialog.toolbar_edit.hidden') + ')' )}}</div>
|
||||
</div>
|
||||
</li>
|
||||
@ -159,7 +159,7 @@
|
||||
|
||||
<ul class="list" id="bar_item_list">
|
||||
<li v-for="item in searchedBarItems" v-on:click="addItem(item)">
|
||||
<div class="icon_wrapper normal" v-html="Blockbench.getIconNode(item.icon).outerHTML"></div>
|
||||
<div class="icon_wrapper normal" v-html="Blockbench.getIconNode(item.icon, item.color).outerHTML"></div>
|
||||
<div class="icon_wrapper add"><i class="material-icons">add</i></div>
|
||||
{{ item.name }}
|
||||
</li>
|
||||
@ -452,13 +452,13 @@
|
||||
<div class="setting_element" v-html="Blockbench.getIconNode(setting.icon).outerHTML"></div>
|
||||
</template>
|
||||
<template v-else-if="!setting.type"><!--TOGGLE-->
|
||||
<div class="setting_element"><input type="checkbox" v-model="setting.value" v-on:click="saveSettings()"></div>
|
||||
<div class="setting_element"><input type="checkbox" v-model="setting.value" v-bind:id="'setting_'+key" v-on:click="saveSettings()"></div>
|
||||
</template>
|
||||
|
||||
<div class="setting_label">
|
||||
<label class="setting_label" v-bind:for="'setting_'+key">
|
||||
<div class="setting_name">{{ tl('settings.'+key) }}</div>
|
||||
<div class="setting_description">{{ tl('settings.'+key+'.desc') }}</div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<template v-if="setting.type === 'text'">
|
||||
<input type="text" class="dark_bordered" style="width: 96%" v-model="setting.value" v-on:input="saveSettings()">
|
||||
|
218
index.php
218
index.php
@ -25,6 +25,7 @@
|
||||
<script src="lib/jquery-ui.min.js"></script>
|
||||
<script src="lib/targa.js"></script>
|
||||
<script src="lib/jimp.min.js"></script>
|
||||
<script src="lib/gif.js"></script>
|
||||
<script src="lib/spectrum.js"></script>
|
||||
<script src="lib/three.js"></script>
|
||||
<script src="js/OrbitControls.js"></script>
|
||||
@ -38,18 +39,13 @@
|
||||
<script src="js/blockbench.js"></script>
|
||||
<script src="js/undo.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (isApp === false) {
|
||||
document.write("<script type='application/x-suppress'>");
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="js/app.js"></script>
|
||||
<script type="text/javascript">
|
||||
if (isApp === true) {
|
||||
document.write("<script type='application/x-suppress'>");
|
||||
document.write("<script src='js/app.js'><\/script>");
|
||||
} else {
|
||||
document.write("<script src='js/web.js'><\/script>");
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="js/web.js"></script>
|
||||
|
||||
<script src="js/api.js"></script>
|
||||
<script src="js/actions.js"></script>
|
||||
@ -67,22 +63,22 @@
|
||||
<script src="js/plugin_loader.js"></script>
|
||||
<script>if (window.module) module = window.module;</script>
|
||||
|
||||
<div id="post_model" class="web_only post_data" hidden><?php
|
||||
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
||||
$model = $_POST['model'];
|
||||
if ($model != "text") {
|
||||
echo $model;
|
||||
}
|
||||
}
|
||||
?></div>
|
||||
<div id="post_textures" class="web_only post_data" hidden><?php
|
||||
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
||||
$textures = $_POST['textures'];
|
||||
if ($textures != "text") {
|
||||
echo $textures;
|
||||
}
|
||||
}
|
||||
?></div>
|
||||
<div id="post_model" class="web_only post_data" hidden><?php
|
||||
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
||||
$model = $_POST['model'];
|
||||
if ($model != "text") {
|
||||
echo $model;
|
||||
}
|
||||
}
|
||||
?></div>
|
||||
<div id="post_textures" class="web_only post_data" hidden><?php
|
||||
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
||||
$textures = $_POST['textures'];
|
||||
if ($textures != "text") {
|
||||
echo $textures;
|
||||
}
|
||||
}
|
||||
?></div>
|
||||
<div style="display: none;"></div>
|
||||
|
||||
|
||||
@ -160,10 +156,10 @@
|
||||
|
||||
<ul class="bar" id="bar_items_current" v-sortable="{onChoose: choose, onUpdate: sort, onEnd: drop, animation: 160 }">
|
||||
<li v-for="item in currentBar" v-bind:title="item.name" :key="item.id||item">
|
||||
<div v-if="typeof item === 'string'" class="toolbar_seperator"></div>
|
||||
<div v-if="typeof item === 'string'" class="toolbar_separator"></div>
|
||||
<div v-else class="tool">
|
||||
<span class="icon_wrapper" v-html="Blockbench.getIconNode(item.icon).outerHTML"></span>
|
||||
<div class="tooltip">{{item.name}}</div>
|
||||
<span class="icon_wrapper" v-bind:style="{opacity: BARS.condition(item.condition) ? 1 : 0.4}" v-html="Blockbench.getIconNode(item.icon, item.color).outerHTML"></span>
|
||||
<div class="tooltip">{{item.name + (BARS.condition(item.condition) ? '' : ' (' + tl('dialog.toolbar_edit.hidden') + ')' )}}</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@ -177,7 +173,7 @@
|
||||
|
||||
<ul class="list" id="bar_item_list">
|
||||
<li v-for="item in searchedBarItems" v-on:click="addItem(item)">
|
||||
<div class="icon_wrapper normal" v-html="Blockbench.getIconNode(item.icon).outerHTML"></div>
|
||||
<div class="icon_wrapper normal" v-html="Blockbench.getIconNode(item.icon, item.color).outerHTML"></div>
|
||||
<div class="icon_wrapper add"><i class="material-icons">add</i></div>
|
||||
{{ item.name }}
|
||||
</li>
|
||||
@ -234,10 +230,6 @@
|
||||
|
||||
<canvas height="256" width="256" id="extrusion_canvas"></canvas>
|
||||
|
||||
<div class="progress_bar" id="extrusion_bar">
|
||||
<div class="progress_bar_inner"></div>
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<button type="button" class="large tl confirm_btn" onclick="Extruder.startConversion()">Scan and Import</button>
|
||||
</div>
|
||||
@ -369,7 +361,7 @@
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<button type="button" class="large tl confirm_btn" onclick="createPreset()">dialog.display_preset.create</button>
|
||||
<button type="button" class="large tl confirm_btn" onclick="DisplayMode.createPreset()">dialog.display_preset.create</button>
|
||||
<button type="button" class="large tl cancel_btn" onclick="hideDialog()">dialog.cancel</button>
|
||||
</div>
|
||||
<div id="dialog_close_button" onclick="$('.dialog#'+open_dialog).find('.cancel_btn:not([disabled])').click()"><i class="material-icons">clear</i></div>
|
||||
@ -459,40 +451,40 @@
|
||||
<h2 class="tl i_b">dialog.settings.settings</h2>
|
||||
<ul id="settingslist">
|
||||
|
||||
<li v-for="category in structure">
|
||||
<h3 v-on:click="toggleCategory(category)">
|
||||
<i class="material-icons">{{ category.open ? 'expand_more' : 'navigate_next' }}</i>
|
||||
{{ category.name }}
|
||||
</h3>
|
||||
<ul v-if="category.open">
|
||||
<li v-for="category in structure">
|
||||
<h3 v-on:click="toggleCategory(category)">
|
||||
<i class="material-icons">{{ category.open ? 'expand_more' : 'navigate_next' }}</i>
|
||||
{{ category.name }}
|
||||
</h3>
|
||||
<ul v-if="category.open">
|
||||
|
||||
<li v-for="(setting, key) in category.items" v-on="setting.click ? {click: setting.click} : {}">
|
||||
<template v-if="setting.type === 'number'">
|
||||
<div class="setting_element"><input type="number" v-model="setting.value" v-on:input="saveSettings()"></div>
|
||||
</template>
|
||||
<template v-else-if="setting.type === 'click'">
|
||||
<div class="setting_element" v-html="Blockbench.getIconNode(setting.icon).outerHTML"></div>
|
||||
</template>
|
||||
<template v-else-if="!setting.type"><!--TOGGLE-->
|
||||
<div class="setting_element"><input type="checkbox" v-model="setting.value" v-on:click="saveSettings()"></div>
|
||||
</template>
|
||||
<li v-for="(setting, key) in category.items" v-on="setting.click ? {click: setting.click} : {}">
|
||||
<template v-if="setting.type === 'number'">
|
||||
<div class="setting_element"><input type="number" v-model="setting.value" v-on:input="saveSettings()"></div>
|
||||
</template>
|
||||
<template v-else-if="setting.type === 'click'">
|
||||
<div class="setting_element" v-html="Blockbench.getIconNode(setting.icon).outerHTML"></div>
|
||||
</template>
|
||||
<template v-else-if="!setting.type"><!--TOGGLE-->
|
||||
<div class="setting_element"><input type="checkbox" v-model="setting.value" v-bind:id="'setting_'+key" v-on:click="saveSettings()"></div>
|
||||
</template>
|
||||
|
||||
<div class="setting_label">
|
||||
<div class="setting_name">{{ tl('settings.'+key) }}</div>
|
||||
<div class="setting_description">{{ tl('settings.'+key+'.desc') }}</div>
|
||||
</div>
|
||||
<label class="setting_label" v-bind:for="'setting_'+key">
|
||||
<div class="setting_name">{{ tl('settings.'+key) }}</div>
|
||||
<div class="setting_description">{{ tl('settings.'+key+'.desc') }}</div>
|
||||
</label>
|
||||
|
||||
<template v-if="setting.type === 'text'">
|
||||
<input type="text" class="dark_bordered" style="width: 96%" v-model="setting.value" v-on:input="saveSettings()">
|
||||
</template>
|
||||
<template v-else-if="setting.type === 'select'">
|
||||
<select v-model="setting.value" class="dark_bordered">
|
||||
<option v-for="(text, id) in setting.options" v-bind:value="id">{{ text }}</option>
|
||||
</select>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<template v-if="setting.type === 'text'">
|
||||
<input type="text" class="dark_bordered" style="width: 96%" v-model="setting.value" v-on:input="saveSettings()">
|
||||
</template>
|
||||
<template v-else-if="setting.type === 'select'">
|
||||
<select v-model="setting.value" class="dark_bordered">
|
||||
<option v-for="(text, id) in setting.options" v-bind:value="id">{{ text }}</option>
|
||||
</select>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="keybindings" class="hidden tab_content">
|
||||
@ -605,7 +597,7 @@
|
||||
</div>
|
||||
<div class="color_field">
|
||||
<input type="color" class="color_input" id="color_text_acc" oninput="changeUIColor(event)" onclick="initUIColor(event)">
|
||||
<label for="color_text_acc" style="background-color: var(--color-text-acc)" class="color_input"></label>
|
||||
<label for="color_text_acc" style="background-color: var(--color-text_acc)" class="color_input"></label>
|
||||
<div class="desc">
|
||||
<h4 class="tl">layout.color.accent_text</h4>
|
||||
<p class="tl">layout.color.accent_text.desc</p>
|
||||
@ -652,15 +644,16 @@
|
||||
<p class="tl">about.vertex_snap</p>
|
||||
<p><b class="tl">about.icons</b> <a href="https://material.io/icons/" class="open-in-browser">material.io/icons</a> & <a href="http://fontawesome.io/icons/" class="open-in-browser">fontawesome</a></p>
|
||||
<p><b class="tl">about.libraries</b>
|
||||
<a href="https://jquery.com" class="open-in-browser">jQuery</a>,
|
||||
<a href="https://jqueryui.com" class="open-in-browser">jQuery UI</a>,
|
||||
<a href="http://touchpunch.furf.com" class="open-in-browser">jQuery UI Touch Punch</a>,
|
||||
<a href="https://vuejs.org" class="open-in-browser">VueJS</a>,
|
||||
<a href="https://github.com/weibangtuo/vue-tree" class="open-in-browser">Vue Tree</a>,
|
||||
<a href="https://github.com/sagalbot/vue-sortable" class="open-in-browser">Vue Sortable</a>,
|
||||
<a href="https://threejs.org" class="open-in-browser">ThreeJS</a>,
|
||||
<a href="https://github.com/oliver-moran/jimp" class="open-in-browser">Jimp</a>,
|
||||
<a href="https://bgrins.github.io/spectrum" class="open-in-browser">Spectrum</a>
|
||||
<a class="open-in-browser" href="https://jquery.com">jQuery</a>,
|
||||
<a class="open-in-browser" href="https://jqueryui.com">jQuery UI</a>,
|
||||
<a class="open-in-browser" href="http://touchpunch.furf.com">jQuery UI Touch Punch</a>,
|
||||
<a class="open-in-browser" href="https://vuejs.org">VueJS</a>,
|
||||
<a class="open-in-browser" href="https://github.com/weibangtuo/vue-tree">Vue Tree</a>,
|
||||
<a class="open-in-browser" href="https://github.com/sagalbot/vue-sortable">Vue Sortable</a>,
|
||||
<a class="open-in-browser" href="https://threejs.org">ThreeJS</a>,
|
||||
<a class="open-in-browser" href="https://github.com/oliver-moran/jimp">Jimp</a>,
|
||||
<a class="open-in-browser" href="https://bgrins.github.io/spectrum">Spectrum</a>,
|
||||
<a class="open-in-browser" href="https://github.com/jnordberg/gif.js">gif.js</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="dialog_bar">
|
||||
@ -750,71 +743,80 @@
|
||||
<p class="tl">display.slot</p>
|
||||
<div id="display_bar" class="bar tabs_small">
|
||||
<input class="hidden" type="radio" name="display" id="thirdperson_righthand" checked>
|
||||
<label class="tool" for="thirdperson_righthand" onclick="loadDispThirdRight()"><i class="material-icons">accessibility</i><div class="tooltip tl">display.slot.third_right</div></label>
|
||||
<label class="tool" for="thirdperson_righthand" onclick="DisplayMode.loadThirdRight()"><i class="material-icons">accessibility</i><div class="tooltip tl">display.slot.third_right</div></label>
|
||||
<input class="hidden" type="radio" name="display" id="thirdperson_lefthand">
|
||||
<label class="tool" for="thirdperson_lefthand" onclick="loadDispThirdLeft()"><i class="material-icons">accessibility</i><div class="tooltip tl">display.slot.third_left</div></label>
|
||||
<label class="tool" for="thirdperson_lefthand" onclick="DisplayMode.loadThirdLeft()"><i class="material-icons">accessibility</i><div class="tooltip tl">display.slot.third_left</div></label>
|
||||
|
||||
<input class="hidden" type="radio" name="display" id="firstperson_righthand">
|
||||
<label class="tool" for="firstperson_righthand" onclick="loadDispFirstRight()"><i class="material-icons">person</i><div class="tooltip tl">display.slot.first_right</div></label>
|
||||
<label class="tool" for="firstperson_righthand" onclick="DisplayMode.loadFirstRight()"><i class="material-icons">person</i><div class="tooltip tl">display.slot.first_right</div></label>
|
||||
<input class="hidden" type="radio" name="display" id="firstperson_lefthand">
|
||||
<label class="tool" for="firstperson_lefthand" onclick="loadDispFirstLeft()"><i class="material-icons">person</i><div class="tooltip tl">display.slot.first_left</div></label>
|
||||
<label class="tool" for="firstperson_lefthand" onclick="DisplayMode.loadFirstLeft()"><i class="material-icons">person</i><div class="tooltip tl">display.slot.first_left</div></label>
|
||||
|
||||
<input class="hidden" type="radio" name="display" id="head">
|
||||
<label class="tool" for="head" onclick="loadDispHead()"><i class="material-icons">sentiment_satisfied</i><div class="tooltip tl">display.slot.head</div></label>
|
||||
<label class="tool" for="head" onclick="DisplayMode.loadHead()"><i class="material-icons">sentiment_satisfied</i><div class="tooltip tl">display.slot.head</div></label>
|
||||
|
||||
<input class="hidden" type="radio" name="display" id="ground">
|
||||
<label class="tool" for="ground" onclick="loadDispGround()"><i class="icon-ground"></i><div class="tooltip tl">display.slot.ground</div></label>
|
||||
<label class="tool" for="ground" onclick="DisplayMode.loadGround()"><i class="icon-ground"></i><div class="tooltip tl">display.slot.ground</div></label>
|
||||
|
||||
<input class="hidden" type="radio" name="display" id="fixed">
|
||||
<label class="tool" for="fixed" onclick="loadDispFixed()"><i class="material-icons">filter_frames</i><div class="tooltip tl">display.slot.frame</div></label>
|
||||
<label class="tool" for="fixed" onclick="DisplayMode.loadFixed()"><i class="material-icons">filter_frames</i><div class="tooltip tl">display.slot.frame</div></label>
|
||||
|
||||
<input class="hidden" type="radio" name="display" id="gui">
|
||||
<label class="tool" for="gui" onclick="loadDispGUI()"><i class="material-icons">border_style</i><div class="tooltip tl">display.slot.gui</div></label>
|
||||
<label class="tool" for="gui" onclick="DisplayMode.loadGUI()"><i class="material-icons">border_style</i><div class="tooltip tl">display.slot.gui</div></label>
|
||||
</div>
|
||||
<p class="reference_model_bar tl">display.reference</p>
|
||||
<div id="display_ref_bar" class="bar tabs_small reference_model_bar">
|
||||
</div>
|
||||
|
||||
<p class="tl">display.rotation</p><div class="tool head_right" onclick="resetDisplaySettings('rotation')"><i class="material-icons">replay</i></div>
|
||||
<p class="tl">display.rotation</p><div class="tool head_right" onclick="DisplayMode.resetDisplaySettings('rotation')"><i class="material-icons">replay</i></div>
|
||||
<div class="bar">
|
||||
<input type="range" class="tool disp_range" id="rotation_x" name="" min="-180" max="180" step="1" value="0" oninput="syncDispInput(this, 'rotation', 'x')">
|
||||
<input type="number" class="tool disp_text" id="rotation_x" oninput="syncDispInput(this, 'rotation', 'x')" min="-180" max="180" step="0.5" value="0">
|
||||
<input type="range" class="tool disp_range" id="rotation_x" name="" min="-180" max="180" step="1" value="0" oninput="DisplayMode.syncDispInput(this, 'rotation', 'x')">
|
||||
<input type="number" class="tool disp_text" id="rotation_x" oninput="DisplayMode.syncDispInput(this, 'rotation', 'x')" min="-180" max="180" step="0.5" value="0">
|
||||
</div>
|
||||
<div class="bar">
|
||||
<input type="range" class="tool disp_range" id="rotation_y" name="" min="-180" max="180" step="1" value="0" oninput="syncDispInput(this, 'rotation', 'y')">
|
||||
<input type="number" class="tool disp_text" id="rotation_y" oninput="syncDispInput(this, 'rotation', 'y')" min="-180" max="180" step="0.5" value="0">
|
||||
<input type="range" class="tool disp_range" id="rotation_y" name="" min="-180" max="180" step="1" value="0" oninput="DisplayMode.syncDispInput(this, 'rotation', 'y')">
|
||||
<input type="number" class="tool disp_text" id="rotation_y" oninput="DisplayMode.syncDispInput(this, 'rotation', 'y')" min="-180" max="180" step="0.5" value="0">
|
||||
</div>
|
||||
<div class="bar">
|
||||
<input type="range" class="tool disp_range" id="rotation_z" name="" min="-180" max="180" step="1" value="0" oninput="syncDispInput(this, 'rotation', 'z')">
|
||||
<input type="number" class="tool disp_text" id="rotation_z" oninput="syncDispInput(this, 'rotation', 'z')" min="-180" max="180" step="0.5" value="0">
|
||||
<input type="range" class="tool disp_range" id="rotation_z" name="" min="-180" max="180" step="1" value="0" oninput="DisplayMode.syncDispInput(this, 'rotation', 'z')">
|
||||
<input type="number" class="tool disp_text" id="rotation_z" oninput="DisplayMode.syncDispInput(this, 'rotation', 'z')" min="-180" max="180" step="0.5" value="0">
|
||||
</div>
|
||||
|
||||
<p class="tl">display.translation</p><div class="tool head_right" onclick="resetDisplaySettings('translation')"><i class="material-icons">replay</i></div>
|
||||
<p class="tl">display.translation</p><div class="tool head_right" onclick="DisplayMode.resetDisplaySettings('translation')"><i class="material-icons">replay</i></div>
|
||||
<div class="bar">
|
||||
<input type="range" class="tool disp_range" id="translation_x" name="" min="-32" max="32" step="0.5" value="0" oninput="syncDispInput(this, 'translation', 'x')">
|
||||
<input type="number" class="tool disp_text" id="translation_x" oninput="syncDispInput(this, 'translation', 'x')" min="-80" max="80" step="0.5" value="0">
|
||||
<input type="range" class="tool disp_range" id="translation_x" name="" min="-32" max="32" step="0.5" value="0" oninput="DisplayMode.syncDispInput(this, 'translation', 'x')">
|
||||
<input type="number" class="tool disp_text" id="translation_x" oninput="DisplayMode.syncDispInput(this, 'translation', 'x')" min="-80" max="80" step="0.5" value="0">
|
||||
</div>
|
||||
<div class="bar">
|
||||
<input type="range" class="tool disp_range" id="translation_y" name="" min="-32" max="32" step="0.5" value="0" oninput="syncDispInput(this, 'translation', 'y')">
|
||||
<input type="number" class="tool disp_text" id="translation_y" oninput="syncDispInput(this, 'translation', 'y')" min="-80" max="80" step="0.5" value="0">
|
||||
<input type="range" class="tool disp_range" id="translation_y" name="" min="-32" max="32" step="0.5" value="0" oninput="DisplayMode.syncDispInput(this, 'translation', 'y')">
|
||||
<input type="number" class="tool disp_text" id="translation_y" oninput="DisplayMode.syncDispInput(this, 'translation', 'y')" min="-80" max="80" step="0.5" value="0">
|
||||
</div>
|
||||
<div class="bar">
|
||||
<input type="range" class="tool disp_range" id="translation_z" name="" min="-32" max="32" step="0.5" value="0" oninput="syncDispInput(this, 'translation', 'z')">
|
||||
<input type="number" class="tool disp_text" id="translation_z" oninput="syncDispInput(this, 'translation', 'z')" min="-80" max="80" step="0.5" value="0">
|
||||
<input type="range" class="tool disp_range" id="translation_z" name="" min="-32" max="32" step="0.5" value="0" oninput="DisplayMode.syncDispInput(this, 'translation', 'z')">
|
||||
<input type="number" class="tool disp_text" id="translation_z" oninput="DisplayMode.syncDispInput(this, 'translation', 'z')" min="-80" max="80" step="0.5" value="0">
|
||||
</div>
|
||||
|
||||
<p class="tl">display.scale</p><div class="tool head_right" onclick="resetDisplaySettings('scale')"><i class="material-icons">replay</i></div>
|
||||
<p class="tl">display.scale</p><div class="tool head_right" onclick="DisplayMode.resetDisplaySettings('scale')"><i class="material-icons">replay</i></div>
|
||||
<div class="bar">
|
||||
<input type="range" class="tool disp_range scaleRange" id="scale_x" name="" min="-4" max="4" step="0.1" value="0" oninput="syncDispInput(this, 'scaleRange', 'x', event)">
|
||||
<input type="number" class="tool disp_text scale" id="scale_x" oninput="syncDispInput(this, 'scale', 'x')" step="0.1" min="-4" max="4">
|
||||
<div class="tool display_scale_invert" id="display_scale_invert_x" onclick="DisplayMode.syncDispMirror(this, 'x')">
|
||||
<i class="material-icons">check_box_outline_blank</i><div class="tooltip tl">display.mirror</div>
|
||||
</div>
|
||||
<input type="range" class="tool disp_range scaleRange" id="scale_x" name="" min="-4" max="4" step="0.1" value="0" oninput="DisplayMode.syncDispInput(this, 'scaleRange', 'x', event)">
|
||||
<input type="number" class="tool disp_text scale" id="scale_x" oninput="DisplayMode.syncDispInput(this, 'scale', 'x')" step="0.1" min="-4" max="4">
|
||||
</div>
|
||||
<div class="bar">
|
||||
<input type="range" class="tool disp_range scaleRange" id="scale_y" name="" min="-4" max="4" step="0.1" value="0" oninput="syncDispInput(this, 'scaleRange', 'y', event)">
|
||||
<input type="number" class="tool disp_text scale" id="scale_y" oninput="syncDispInput(this, 'scale', 'y')" step="0.1" min="-4" max="4">
|
||||
<div class="tool display_scale_invert" id="display_scale_invert_y" onclick="DisplayMode.syncDispMirror(this, 'x')">
|
||||
<i class="material-icons">check_box_outline_blank</i><div class="tooltip tl">display.mirror</div>
|
||||
</div>
|
||||
<input type="range" class="tool disp_range scaleRange" id="scale_y" name="" min="-4" max="4" step="0.1" value="0" oninput="DisplayMode.syncDispInput(this, 'scaleRange', 'y', event)">
|
||||
<input type="number" class="tool disp_text scale" id="scale_y" oninput="DisplayMode.syncDispInput(this, 'scale', 'y')" step="0.1" min="-4" max="4">
|
||||
</div>
|
||||
<div class="bar">
|
||||
<input type="range" class="tool disp_range scaleRange" id="scale_z" name="" min="-4" max="4" step="0.1" value="0" oninput="syncDispInput(this, 'scaleRange', 'z', event)">
|
||||
<input type="number" class="tool disp_text scale" id="scale_z" oninput="syncDispInput(this, 'scale', 'z')" step="0.1" min="-4" max="4">
|
||||
<div class="tool display_scale_invert" id="display_scale_invert_z" onclick="DisplayMode.syncDispMirror(this, 'x')">
|
||||
<i class="material-icons">check_box_outline_blank</i><div class="tooltip tl">display.mirror</div>
|
||||
</div>
|
||||
<input type="range" class="tool disp_range scaleRange" id="scale_z" name="" min="-4" max="4" step="0.1" value="0" oninput="DisplayMode.syncDispInput(this, 'scaleRange', 'z', event)">
|
||||
<input type="number" class="tool disp_text scale" id="scale_z" oninput="DisplayMode.syncDispInput(this, 'scale', 'z')" step="0.1" min="-4" max="4">
|
||||
</div>
|
||||
</div>
|
||||
<div id="animations" class="panel">
|
||||
@ -824,7 +826,7 @@
|
||||
<li
|
||||
v-for="animation in animations"
|
||||
v-bind:class="{ selected: animation.selected }"
|
||||
v-bind:texid="animation.uuid"
|
||||
v-bind:anim_id="animation.uuid"
|
||||
class="animation"
|
||||
v-on:click.stop="animation.select()"
|
||||
@contextmenu.prevent.stop="animation.showContextMenu($event)"
|
||||
@ -839,19 +841,19 @@
|
||||
<p class="tl" id="keyframe_type_label"></p>
|
||||
<div class="bar" id="keyframe_bar_x">
|
||||
<label>X</label>
|
||||
<input type="text" id="keyframe_x" class="dark_bordered code" axis="x" oninput="updateKeyframeValue(this)">
|
||||
<input type="text" id="keyframe_x" class="dark_bordered code keyframe_input" axis="x" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar" id="keyframe_bar_y">
|
||||
<label>Y</label>
|
||||
<input type="text" id="keyframe_y" class="dark_bordered code" axis="y" oninput="updateKeyframeValue(this)">
|
||||
<input type="text" id="keyframe_y" class="dark_bordered code keyframe_input" axis="y" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar" id="keyframe_bar_z">
|
||||
<label>Z</label>
|
||||
<input type="text" id="keyframe_z" class="dark_bordered code" axis="z" oninput="updateKeyframeValue(this)">
|
||||
<input type="text" id="keyframe_z" class="dark_bordered code keyframe_input" axis="z" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar" id="keyframe_bar_w">
|
||||
<label>W</label>
|
||||
<input type="text" id="keyframe_w" class="dark_bordered code" axis="w" oninput="updateKeyframeValue(this)">
|
||||
<input type="text" id="keyframe_w" class="dark_bordered code keyframe_input" axis="w" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
</div>
|
||||
<div id="variable_placeholders" class="panel grow">
|
||||
|
@ -535,14 +535,14 @@ class BarSelect extends Widget {
|
||||
})
|
||||
}
|
||||
change(event) {
|
||||
this.set( $(event.target).find('option:selected').attr('id') )
|
||||
this.set( $(event.target).find('option:selected').prop('id') )
|
||||
if (this.onChange) {
|
||||
this.onChange(this, event)
|
||||
}
|
||||
}
|
||||
set(id) {
|
||||
this.value = id
|
||||
$(this.nodes).find('option#'+id).attr('selected', true).siblings().attr('selected', false)
|
||||
$(this.nodes).find('option#'+id).prop('selected', true).siblings().prop('selected', false)
|
||||
}
|
||||
get() {
|
||||
return this.value
|
||||
|
@ -407,11 +407,12 @@ class Keyframe {
|
||||
}
|
||||
}
|
||||
get(axis) {
|
||||
let num = parseFloat(this[axis])
|
||||
if (isNaN(num)) {
|
||||
return this[axis]
|
||||
if (!this[axis]) {
|
||||
return 0;
|
||||
} else if (!isNaN(this[axis])) {
|
||||
return parseFloat(this[axis])
|
||||
} else {
|
||||
return num
|
||||
return this[axis]
|
||||
}
|
||||
}
|
||||
calc(axis) {
|
||||
@ -423,6 +424,9 @@ class Keyframe {
|
||||
}
|
||||
}
|
||||
getArray() {
|
||||
if (this.channel === 'scale') {
|
||||
return this.get('x')
|
||||
}
|
||||
var arr = [
|
||||
this.get('x'),
|
||||
this.get('y'),
|
||||
@ -636,7 +640,7 @@ function selectAllKeyframes() {
|
||||
updateKeyframeSelection()
|
||||
}
|
||||
function removeSelectedKeyframes() {
|
||||
Undo.initEdit({keyframes: Timeline.selected})
|
||||
Undo.initEdit({keyframes: Timeline.selected, keep_saved: true})
|
||||
var i = Timeline.keyframes.length;
|
||||
while (i > 0) {
|
||||
i--;
|
||||
@ -645,6 +649,7 @@ function removeSelectedKeyframes() {
|
||||
kf.remove()
|
||||
}
|
||||
}
|
||||
updateKeyframeSelection()
|
||||
Undo.finishEdit('remove keyframes')
|
||||
}
|
||||
|
||||
@ -689,6 +694,10 @@ const Animator = {
|
||||
if (Animator.selected) {
|
||||
Animator.selected.select()
|
||||
}
|
||||
if (isApp && !Prop.animation_path && !Animator.animations.length && Prop.file_path) {
|
||||
//Load
|
||||
findBedrockAnimation()
|
||||
}
|
||||
},
|
||||
leave: function (argument) {
|
||||
Timeline.pause()
|
||||
@ -745,6 +754,9 @@ const Animator = {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isApp && file.path) {
|
||||
Prop.animation_path = file.path
|
||||
}
|
||||
}
|
||||
},
|
||||
buildFile: function(options) {
|
||||
@ -866,7 +878,7 @@ const Timeline = {
|
||||
}
|
||||
})
|
||||
$('.keyframe_input').click(e => {
|
||||
Undo.initEdit({keyframes: Timeline.selected})
|
||||
Undo.initEdit({keyframes: Timeline.selected, keep_saved: true})
|
||||
}).focusout(e => {
|
||||
Undo.finishEdit('edit keyframe')
|
||||
})
|
||||
@ -878,7 +890,7 @@ const Timeline = {
|
||||
axis: 'x',
|
||||
distance: 10,
|
||||
start: function(event, ui) {
|
||||
Undo.initEdit({keyframes: Timeline.keyframes})
|
||||
Undo.initEdit({keyframes: Timeline.keyframes, keep_saved: true})
|
||||
var id = $(ui.helper).attr('id')
|
||||
var i = 0;
|
||||
while (i < Timeline.vue._data.keyframes.length) {
|
||||
@ -1020,7 +1032,7 @@ const Timeline = {
|
||||
Blockbench.showQuickMessage('message.no_bone_selected')
|
||||
return
|
||||
}
|
||||
Undo.initEdit({keyframes: bone.keyframes})
|
||||
Undo.initEdit({keyframes: bone.keyframes, keep_saved: true})
|
||||
var kf = bone.addKeyframe(false, Timeline.second, channel?channel:'rotation')
|
||||
kf.select()
|
||||
Undo.finishEdit('add_keyframe')
|
||||
@ -1041,7 +1053,7 @@ const Timeline = {
|
||||
}
|
||||
var bone = Animator.selected.getBoneAnimator()
|
||||
if (bone) {
|
||||
Undo.initEdit({keyframes: bone.keyframes})
|
||||
Undo.initEdit({keyframes: bone.keyframes, keep_saved: true})
|
||||
var kf = bone.addKeyframe(false, Math.round(time*30)/30, row === 2 ? 'scale' : (row === 1 ? 'position' : 'rotation'))
|
||||
kf.select().callMarker()
|
||||
Vue.nextTick(Timeline.update)
|
||||
@ -1096,8 +1108,10 @@ BARS.defineActions(function() {
|
||||
condition: () => Animator.open,
|
||||
click: function () {
|
||||
var content = autoStringify(Animator.buildFile())
|
||||
var path = Prop.file_path
|
||||
if (isApp) {
|
||||
var path = Prop.animation_path
|
||||
|
||||
if (isApp && !path) {
|
||||
path = Prop.file_path
|
||||
var exp = new RegExp(osfs.replace('\\', '\\\\')+'models'+osfs.replace('\\', '\\\\'))
|
||||
var m_index = path.search(exp)
|
||||
if (m_index > 3) {
|
||||
@ -1160,7 +1174,7 @@ BARS.defineActions(function() {
|
||||
Animator.preview()
|
||||
},
|
||||
onBefore: function() {
|
||||
Undo.initEdit({keyframes: Timeline.selected})
|
||||
Undo.initEdit({keyframes: Timeline.selected, keep_saved: true})
|
||||
},
|
||||
onAfter: function() {
|
||||
Undo.finishEdit('edit keyframe')
|
||||
|
150
js/api.js
150
js/api.js
@ -42,16 +42,22 @@ class API {
|
||||
icon = icon()
|
||||
}
|
||||
if (icon === undefined) {
|
||||
//Missing
|
||||
jq = $('<i class="material-icons icon">help_outline</i>')
|
||||
} else if (icon instanceof HTMLElement) {
|
||||
//Node
|
||||
jq = $(icon)
|
||||
} else if (icon.substr(0, 2) === 'fa') {
|
||||
//Font Awesome
|
||||
jq = $('<i class="icon fa fa_big ' + icon + '"></i>')
|
||||
} else if (icon.substr(0, 5) === 'icon-') {
|
||||
//Icomoon
|
||||
jq = $('<i class="' + icon + '"></i>')
|
||||
} else if (icon.substr(0, 14) === 'data:image/png') {
|
||||
//Data URL
|
||||
jq = $('<img class="icon" src="'+icon+'">')
|
||||
} else {
|
||||
//Material Icon
|
||||
jq = $('<i class="material-icons icon">' + icon + '</i>')
|
||||
}
|
||||
if (color) {
|
||||
@ -228,77 +234,7 @@ class API {
|
||||
defaultPath: options.startpath
|
||||
},
|
||||
function (fileNames) {
|
||||
if (fileNames == undefined) return;
|
||||
|
||||
var results = [];
|
||||
var result_count = 0;
|
||||
var i = 0;
|
||||
var errant;
|
||||
while (i < fileNames.length) {
|
||||
(function() {
|
||||
var this_i = i;
|
||||
var file = fileNames[i]
|
||||
|
||||
if (options.readtype === 'image') {
|
||||
//
|
||||
var extension = pathToExtension(file)
|
||||
if (extension === 'tga') {
|
||||
var targa_loader = new Targa()
|
||||
targa_loader.open(file, () => {
|
||||
|
||||
results[this_i] = {
|
||||
name: pathToName(file, true),
|
||||
path: file,
|
||||
content: targa_loader.getDataURL()
|
||||
}
|
||||
|
||||
result_count++;
|
||||
if (result_count === fileNames.length) {
|
||||
cb(results)
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
results[this_i] = {
|
||||
name: pathToName(file, true),
|
||||
path: file
|
||||
}
|
||||
result_count++;
|
||||
if (result_count === fileNames.length) {
|
||||
cb(results)
|
||||
}
|
||||
}
|
||||
} else /*text*/ {
|
||||
fs.readFile(file, 'utf-8', function (err, data) {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
if (!errant && options.errorbox !== false) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'file_not_found',
|
||||
icon: 'error_outline'
|
||||
})
|
||||
}
|
||||
errant = true
|
||||
return;
|
||||
}
|
||||
if (data.charCodeAt(0) === 0xFEFF) {
|
||||
data = data.substr(1)
|
||||
}
|
||||
results[this_i] = {
|
||||
name: pathToName(file, true),
|
||||
path: file,
|
||||
content: data
|
||||
}
|
||||
result_count++;
|
||||
if (result_count === fileNames.length) {
|
||||
cb(results)
|
||||
}
|
||||
})
|
||||
}
|
||||
})()
|
||||
i++;
|
||||
}
|
||||
|
||||
Blockbench.read(fileNames, options, cb)
|
||||
})
|
||||
} else {
|
||||
$('<input '+
|
||||
@ -350,6 +286,78 @@ class API {
|
||||
}).click()
|
||||
}
|
||||
}
|
||||
read(paths, options, cb) {
|
||||
if (!isApp || paths == undefined) return false;
|
||||
|
||||
var results = [];
|
||||
var result_count = 0;
|
||||
var i = 0;
|
||||
var errant;
|
||||
while (i < paths.length) {
|
||||
(function() {
|
||||
var this_i = i;
|
||||
var file = paths[i]
|
||||
|
||||
if (options.readtype === 'image') {
|
||||
//
|
||||
var extension = pathToExtension(file)
|
||||
if (extension === 'tga') {
|
||||
var targa_loader = new Targa()
|
||||
targa_loader.open(file, () => {
|
||||
|
||||
results[this_i] = {
|
||||
name: pathToName(file, true),
|
||||
path: file,
|
||||
content: targa_loader.getDataURL()
|
||||
}
|
||||
|
||||
result_count++;
|
||||
if (result_count === paths.length) {
|
||||
cb(results)
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
results[this_i] = {
|
||||
name: pathToName(file, true),
|
||||
path: file
|
||||
}
|
||||
result_count++;
|
||||
if (result_count === paths.length) {
|
||||
cb(results)
|
||||
}
|
||||
}
|
||||
} else /*text*/ {
|
||||
fs.readFile(file, 'utf-8', function (err, data) {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
if (!errant && options.errorbox !== false) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'file_not_found',
|
||||
icon: 'error_outline'
|
||||
})
|
||||
}
|
||||
errant = true
|
||||
return;
|
||||
}
|
||||
if (data.charCodeAt(0) === 0xFEFF) {
|
||||
data = data.substr(1)
|
||||
}
|
||||
results[this_i] = {
|
||||
name: pathToName(file, true),
|
||||
path: file,
|
||||
content: data
|
||||
}
|
||||
result_count++;
|
||||
if (result_count === paths.length) {
|
||||
cb(results)
|
||||
}
|
||||
})
|
||||
}
|
||||
})()
|
||||
i++;
|
||||
}
|
||||
}
|
||||
export(options, cb) {
|
||||
if (!options) return;
|
||||
/*
|
||||
|
12
js/app.js
12
js/app.js
@ -356,6 +356,18 @@ function findEntityTexture(mob, return_path) {
|
||||
}
|
||||
}
|
||||
}
|
||||
function findBedrockAnimation() {
|
||||
|
||||
var animation_path = Prop.file_path.split(osfs)
|
||||
var index = animation_path.lastIndexOf('models')
|
||||
animation_path.splice(index)
|
||||
animation_path = [...animation_path, 'animations', pathToName(Prop.file_path)+'.json'].join(osfs)
|
||||
if (fs.existsSync(animation_path)) {
|
||||
Blockbench.read([animation_path], {}, (files) => {
|
||||
Animator.loadFile(files[0])
|
||||
})
|
||||
}
|
||||
}
|
||||
//Writers
|
||||
function saveFile(props) {
|
||||
if (Prop.file_path) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
const appVersion = '2.2.0'
|
||||
const appVersion = '2.2.1'
|
||||
var osfs = '/'
|
||||
var File, i;
|
||||
const elements = [];
|
||||
@ -535,7 +535,7 @@ var Clipbench = {
|
||||
if (open_dialog == 'uv_dialog') {
|
||||
uv_dialog.copy(event)
|
||||
} else if (display_mode) {
|
||||
copyDisplaySlot()
|
||||
DisplayMode.copy()
|
||||
} else if (Animator.open) {
|
||||
if (Timeline.selected.length) {
|
||||
Clipbench.setKeyframes(Timeline.selected)
|
||||
@ -564,7 +564,7 @@ var Clipbench = {
|
||||
if (open_dialog == 'uv_dialog') {
|
||||
uv_dialog.paste(event)
|
||||
} else if (display_mode) {
|
||||
pasteDisplaySlot()
|
||||
DisplayMode.paste()
|
||||
} else if (Animator.open) {
|
||||
//
|
||||
if (isApp) {
|
||||
|
@ -36,7 +36,7 @@ class refModel {
|
||||
} else if (display_slot === 'thirdperson_lefthand') {
|
||||
setDisplayArea(-x, y, -z, -67.5,0,0, 1, 1, 1)
|
||||
} else if (display_slot === 'head') {
|
||||
setDisplayArea(0, 22, 0, 0, 0, 0, 0.625, 0.625, 0.625)
|
||||
setDisplayArea(0, 28, 0, 0, 0, 0, 0.625, 0.625, 0.625)
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1245,28 +1245,24 @@ enterDisplaySettings = function() { //Enterung Display Setting Mode, changes th
|
||||
exitDisplaySettings = function() { //Enterung Display Setting Mode, changes the scene etc
|
||||
resetDisplayBase()
|
||||
setDisplayArea(0,0,0, 0,0,0, 1,1,1)
|
||||
display_area.updateMatrixWorld()
|
||||
display_base.updateMatrixWorld()
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
display_mode = false;
|
||||
|
||||
main_preview.fullscreen()
|
||||
|
||||
$('.m_disp').hide()
|
||||
$('.m_edit').show()
|
||||
$('.selection_only').css('visibility', 'hidden')
|
||||
$('body').removeClass('display_mode')
|
||||
resizeWindow()
|
||||
updateInterface()
|
||||
if (quad_previews.enabled_before) {
|
||||
openQuadView()
|
||||
}
|
||||
|
||||
buildGrid()
|
||||
setShading()
|
||||
Canvas.updateRenderSides()
|
||||
}, 60)
|
||||
display_mode = false;
|
||||
main_preview.fullscreen()
|
||||
|
||||
$('.m_disp').hide()
|
||||
$('.m_edit').show()
|
||||
$('.selection_only').css('visibility', 'hidden')
|
||||
$('body').removeClass('display_mode')
|
||||
resizeWindow()
|
||||
updateInterface()
|
||||
if (quad_previews.enabled_before) {
|
||||
openQuadView()
|
||||
}
|
||||
buildGrid()
|
||||
setShading()
|
||||
Canvas.updateRenderSides()
|
||||
}
|
||||
function axisIndex(index) {
|
||||
if (typeof index === 'number') {
|
||||
@ -1352,7 +1348,7 @@ DisplayMode.syncDispMirror = function(node, axis) {
|
||||
}
|
||||
var axis = (node.id||'x').substr(-1)
|
||||
display_base.scale[axis] = display[display_slot].scale[axisIndex(axis)] *= -1
|
||||
loadDisp(display_slot)
|
||||
DisplayMode.load(display_slot)
|
||||
}
|
||||
function dispRotate(val, axis) { //Change the actual thing
|
||||
if (display[display_slot].rotation == undefined) {
|
||||
@ -1447,7 +1443,7 @@ DisplayMode.createPreset = function() {
|
||||
}
|
||||
|
||||
|
||||
function setDisplayArea(x, y, z, rx, ry, rz, sx, sy, sz) {//Sets the Work Area to the given Space
|
||||
var setDisplayArea = DisplayMode.setBase = function(x, y, z, rx, ry, rz, sx, sy, sz) {//Sets the Work Area to the given Space
|
||||
display_area.rotation['x'] = Math.PI / (180 / rx);
|
||||
display_area.rotation['y'] = Math.PI / (180 / ry);
|
||||
display_area.rotation['z'] = Math.PI / (180 / rz);
|
||||
@ -1624,12 +1620,12 @@ DisplayMode.load = function(slot) {
|
||||
}
|
||||
}
|
||||
|
||||
function copyDisplaySlot() {
|
||||
DisplayMode.copy = function() {
|
||||
var base_setting = {rotation: [0, 0, 0], translation: [0, 0, 0], scale: [1, 1, 1]}
|
||||
$.extend(true, base_setting, display[display_slot])
|
||||
display_clipboard = base_setting
|
||||
}
|
||||
function pasteDisplaySlot() {
|
||||
DisplayMode.paste = function() {
|
||||
if (display_clipboard == undefined) return;
|
||||
|
||||
if (typeof display_clipboard.rotation === 'object' && display_clipboard.rotation.join('_') === '0_0_0') {
|
||||
|
@ -264,6 +264,19 @@ class OutlinerElement {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
isChildOf(group, max_levels) {
|
||||
function iterate(obj, level) {
|
||||
if (!obj || obj === 'root') {
|
||||
return false;
|
||||
} else if (obj === group) {
|
||||
return true;
|
||||
} else if (!max_levels || level < max_levels-1) {
|
||||
return iterate(obj.parent, level+1)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return iterate(this.parent, 0)
|
||||
}
|
||||
}
|
||||
class Cube extends OutlinerElement {
|
||||
constructor(data, uuid) {
|
||||
@ -333,15 +346,11 @@ class Cube extends OutlinerElement {
|
||||
}
|
||||
}
|
||||
rotationAxis() {
|
||||
if (this.rotation_axis) {
|
||||
return this.rotation_axis
|
||||
}
|
||||
var axis_i = 0;
|
||||
while (axis_i < 3) {
|
||||
for (var axis = 0; axis < 3; axis++) {
|
||||
if (this.rotation[axis_i] !== 0) {
|
||||
return getAxisLetter(axis_i)
|
||||
this.rotation_axis = getAxisLetter(axis_i);
|
||||
return this.rotation_axis;
|
||||
}
|
||||
axis_i++;
|
||||
}
|
||||
}
|
||||
getMesh() {
|
||||
@ -688,7 +697,9 @@ class Cube extends OutlinerElement {
|
||||
}
|
||||
setColor(index) {
|
||||
this.color = index;
|
||||
Canvas.updateSelectedFaces()
|
||||
if (this.visibility) {
|
||||
Canvas.adaptObjectFaces(obj)
|
||||
}
|
||||
}
|
||||
showContextMenu(event) {
|
||||
if (!this.selected) {
|
||||
@ -1014,7 +1025,8 @@ class Group extends OutlinerElement {
|
||||
var scope = this;
|
||||
if (Blockbench.hasFlag('renaming')) return;
|
||||
if (!event) event = {shiftKey: false}
|
||||
var allSelected = (selected_group === this && selected.length === this.children.length)
|
||||
var allSelected = selected_group === this && selected.length && this.matchesSelection()
|
||||
//(selected_group === this && selected.length >= this.children.length)
|
||||
|
||||
//Clear Old Group
|
||||
if (selected_group) selected_group.unselect()
|
||||
@ -1077,6 +1089,21 @@ class Group extends OutlinerElement {
|
||||
this.selected = false
|
||||
return this;
|
||||
}
|
||||
matchesSelection() {
|
||||
var scope = this;
|
||||
var match = true;
|
||||
for (var i = 0; i < selected.length; i++) {
|
||||
if (!selected[i].isChildOf(scope, 20)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
this.forEachChild(obj => {
|
||||
if (!obj.selected) {
|
||||
match = false
|
||||
}
|
||||
})
|
||||
return match;
|
||||
}
|
||||
extend(object) {
|
||||
Merge.string(this, object, 'name')
|
||||
Merge.boolean(this, object, 'shade')
|
||||
@ -1207,6 +1234,7 @@ class Group extends OutlinerElement {
|
||||
} else if (destination !== 'cache') {
|
||||
base_group.addTo(destination, false)
|
||||
}
|
||||
Canvas.updatePositions()
|
||||
loadOutlinerDraggable()
|
||||
return base_group;
|
||||
}
|
||||
|
@ -463,6 +463,7 @@ function updateInterfacePanels() {
|
||||
var panel = Interface.Panels[key]
|
||||
panel.update()
|
||||
}
|
||||
return;
|
||||
var left_width = $('.sidebar#left_bar > .panel:visible').length ? Interface.data.left_bar_width : 0
|
||||
var right_width = $('.sidebar#right_bar > .panel:visible').length ? Interface.data.right_bar_width : 0
|
||||
$('body').css(
|
||||
|
26
js/io.js
26
js/io.js
@ -15,6 +15,7 @@ function newProject(entity_mode) {
|
||||
Project.ambientocclusion = true;
|
||||
Prop.file_path = Prop.file_name = Prop.file_name_alt = '';
|
||||
Prop.project_saved = true;
|
||||
Prop.animation_path = '';
|
||||
Prop.added_models = 0;
|
||||
setProjectTitle();
|
||||
Canvas.updateAll();
|
||||
@ -1313,9 +1314,26 @@ function buildClassModel(options) {
|
||||
|
||||
var bones = []
|
||||
var bone_nr = 1
|
||||
var model_id = Project.parent.replace('geometry.', '')
|
||||
var model_id = Project.parent.replace('geometry.', '') || 'unknown';
|
||||
var all_groups = getAllOutlinerGroups()
|
||||
|
||||
var loose_cubes = []
|
||||
TreeElements.forEach(obj => {
|
||||
if (obj.type === 'cube') {
|
||||
loose_cubes.push(obj)
|
||||
}
|
||||
})
|
||||
if (loose_cubes.length) {
|
||||
var group = {
|
||||
name: 'bb_main',
|
||||
rotation: [0, 0, 0],
|
||||
origin: [0, 0, 0],
|
||||
parent: 'root',
|
||||
children: loose_cubes
|
||||
}
|
||||
all_groups.splice(0, 0, group)
|
||||
}
|
||||
|
||||
all_groups.forEach((g) => {
|
||||
//model += `\nthis.bone${bone_nr} = new ModelRenderer`
|
||||
var id = g.name
|
||||
@ -1377,7 +1395,7 @@ function buildClassModel(options) {
|
||||
var model = (settings.credit.value
|
||||
? '//'+settings.credit.value+'\n'
|
||||
: '')+
|
||||
'//Paste this code into your mod. Don\'t forget to add your imports\n' +
|
||||
'//Paste this code into your mod.\n' +
|
||||
'\nimport org.lwjgl.opengl.GL11;'+
|
||||
'\nimport net.minecraft.client.model.ModelBase;'+
|
||||
'\nimport net.minecraft.client.model.ModelBox;'+
|
||||
@ -1387,7 +1405,7 @@ function buildClassModel(options) {
|
||||
'\npublic class '+model_id+' extends ModelBase {'
|
||||
|
||||
bones.forEach((bone) => {
|
||||
model += `\n public ModelRenderer ${bone.id};`;
|
||||
model += `\n private final ModelRenderer ${bone.id};`;
|
||||
})
|
||||
|
||||
model += '\n'+
|
||||
@ -1402,7 +1420,7 @@ function buildClassModel(options) {
|
||||
model +=
|
||||
' }\n'+
|
||||
'\n @Override'+
|
||||
'\n public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { '
|
||||
'\n public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) {'
|
||||
|
||||
bones.forEach((bone) => {
|
||||
if (bone.rootBone) {
|
||||
|
@ -33,7 +33,7 @@ const Language = {
|
||||
nl: 'Nederlands (Dutch)',
|
||||
pl: 'Polski (Polish)',
|
||||
ru: '\u0440\u0443\u0441\u0441\u043A\u0438\u0439 (Russian)',
|
||||
//sv: 'Svenska (Swedish)',
|
||||
sv: 'Svenska (Swedish)',
|
||||
zh: '\u4e2d\u6587 (Chinese)',//中文
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class BBPainter {
|
||||
})
|
||||
}
|
||||
edit(texture, cb, options) {
|
||||
if (!options.noUndo) {
|
||||
if (!options.no_undo) {
|
||||
Undo.initEdit({textures: [texture], bitmap: true})
|
||||
}
|
||||
if (options.use_cache &&
|
||||
@ -19,9 +19,12 @@ class BBPainter {
|
||||
typeof Painter.current.image === 'object'
|
||||
) {
|
||||
Painter.current.image = cb(Painter.current.image) || Painter.current.image
|
||||
if (options.no_update === true) {
|
||||
return;
|
||||
}
|
||||
Painter.current.image.getBase64(Jimp.MIME_PNG, function(a, dataUrl){
|
||||
texture.updateSource(dataUrl)
|
||||
if (!options.noUndo) {
|
||||
if (!options.no_undo) {
|
||||
Undo.finishEdit('edit_texture')
|
||||
}
|
||||
})
|
||||
@ -32,7 +35,7 @@ class BBPainter {
|
||||
Painter.current.image = image
|
||||
image.getBase64(Jimp.MIME_PNG, function(a, dataUrl){
|
||||
texture.updateSource(dataUrl)
|
||||
if (!options.noUndo) {
|
||||
if (!options.no_undo) {
|
||||
Undo.finishEdit('edit_texture')
|
||||
}
|
||||
})
|
||||
@ -85,7 +88,7 @@ class BBPainter {
|
||||
while (i < length) {
|
||||
x = end_x - diff.x / length * i
|
||||
y = end_y - diff.y / length * i
|
||||
Painter.useBrush(texture, x, y, data.cube.faces[data.face].uv)
|
||||
Painter.useBrush(texture, x, y, data.cube.faces[data.face].uv, i < length-1)
|
||||
i++;
|
||||
}
|
||||
Painter.current.x = end_x
|
||||
@ -121,7 +124,7 @@ class BBPainter {
|
||||
Jimp.read(texture.source).then(getPxColor)
|
||||
}
|
||||
}
|
||||
useBrush(texture, x, y, uvTag) {
|
||||
useBrush(texture, x, y, uvTag, no_update) {
|
||||
if ((Painter.currentPixel[0] !== x || Painter.currentPixel[1] !== y)) {
|
||||
Painter.currentPixel = [x, y]
|
||||
Painter.brushChanges = true
|
||||
@ -175,7 +178,7 @@ class BBPainter {
|
||||
})
|
||||
}
|
||||
Painter.editing_area = undefined
|
||||
}, {noUndo: true, use_cache: true})
|
||||
}, {no_undo: true, use_cache: true, no_update: no_update})
|
||||
}
|
||||
}
|
||||
stopBrush() {
|
||||
@ -569,18 +572,30 @@ class BBPainter {
|
||||
})
|
||||
}
|
||||
|
||||
var face_data = {
|
||||
up: {c1: 0xb4d4e1ff, c2: 0xecf8fdff, place: t => {return {x: t.posx+t.z, y: t.posy, w: t.x, h: t.z}}},
|
||||
down: {c1: 0x536174ff, c2: 0x6e788cff, place: t => {return {x: t.posx+t.z+t.x, y: t.posy, w: t.x, h: t.z}}},
|
||||
east: {c1: 0x43e88dff, c2: 0x7BFFA3ff, place: t => {return {x: t.posx, y: t.posy+t.z, w: t.z, h: t.y}}},
|
||||
north: {c1: 0x5bbcf4ff, c2: 0x7BD4FFff, place: t => {return {x: t.posx+t.z, y: t.posy+t.z, w: t.x, h: t.y}}},
|
||||
west: {c1: 0xf48686ff, c2: 0xFFA7A4ff, place: t => {return {x: t.posx+t.z+t.x, y: t.posy+t.z, w: t.z, h: t.y}}},
|
||||
south: {c1: 0xf8dd72ff, c2: 0xFFF899ff, place: t => {return {x: t.posx+t.z+t.x+t.z,y: t.posy+t.z, w: t.x, h: t.y}}},
|
||||
}
|
||||
|
||||
//Drawing
|
||||
new Jimp(max_size*res_multiple, max_size*res_multiple, 0, function(err, image) {
|
||||
|
||||
bone_temps.forEach(function(bt) {
|
||||
bt.forEach(function(t) {
|
||||
|
||||
drawTemplateRectangle(image, 0xb4d4e1ff, 0xecf8fdff, {x: t.posx+t.z, y: t.posy, w: t.x, h: t.z})// up
|
||||
drawTemplateRectangle(image, 0x536174ff, 0x6e788cff, {x: t.posx+t.z+t.x, y: t.posy, w: t.x, h: t.z})// down
|
||||
drawTemplateRectangle(image, 0x43e88dff, 0x7BFFA3ff, {x: t.posx, y: t.posy+t.z, w: t.z, h: t.y})// east
|
||||
drawTemplateRectangle(image, 0x5bbcf4ff, 0x7BD4FFff, {x: t.posx+t.z, y: t.posy+t.z, w: t.x, h: t.y})// north
|
||||
drawTemplateRectangle(image, 0xf48686ff, 0xFFA7A4ff, {x: t.posx+t.z+t.x, y: t.posy+t.z, w: t.z, h: t.y})// west
|
||||
drawTemplateRectangle(image, 0xf8dd72ff, 0xFFF899ff, {x: t.posx+t.z+t.x+t.z,y: t.posy+t.z, w: t.x, h: t.y})// south
|
||||
for (var face in face_data) {
|
||||
let d = face_data[face]
|
||||
if (!options.use_texture || (t.obj.faces[face].texture)) {
|
||||
//Colored
|
||||
drawTemplateRectangle(image, d.c1, d.c2, d.place(t))
|
||||
} else {
|
||||
//Texture
|
||||
}
|
||||
}
|
||||
|
||||
let obj = t.obj
|
||||
obj.uv_offset[0] = t.posx
|
||||
|
@ -172,19 +172,14 @@ class Preview {
|
||||
render() {
|
||||
if (this.canvas.isConnected === false) return;
|
||||
this.controls.update()
|
||||
if (display_mode === false) {
|
||||
if (this.isOrtho === true) {
|
||||
this.renderer.render(scene, this.camOrtho)
|
||||
} else {
|
||||
this.renderer.render(scene, this.camPers)
|
||||
}
|
||||
} else {
|
||||
if (this.isOrtho === true) {
|
||||
this.renderer.render(display_scene, this.camOrtho)
|
||||
} else {
|
||||
this.renderer.render(display_scene, this.camPers)
|
||||
}
|
||||
}
|
||||
this.renderer.render(
|
||||
display_mode
|
||||
? display_scene
|
||||
: scene,
|
||||
this.isOrtho
|
||||
? this.camOrtho
|
||||
: this.camPers
|
||||
)
|
||||
}
|
||||
//Camera
|
||||
setNormalCamera() {
|
||||
@ -589,6 +584,7 @@ class Preview {
|
||||
edit(Transformer)
|
||||
edit(outlines)
|
||||
edit(rot_origin)
|
||||
edit(Vertexsnap.vertexes)
|
||||
selected.forEach(function(obj) {
|
||||
var m = obj.getMesh()
|
||||
if (m && m.outline) {
|
||||
@ -597,7 +593,7 @@ class Preview {
|
||||
})
|
||||
}
|
||||
|
||||
editVis(function(obj) {
|
||||
editVis(obj => {
|
||||
obj.was_visible = obj.visible
|
||||
obj.visible = false
|
||||
})
|
||||
@ -619,7 +615,7 @@ class Preview {
|
||||
})
|
||||
});
|
||||
|
||||
editVis(function(obj) {
|
||||
editVis(obj => {
|
||||
obj.visible = obj.was_visible
|
||||
delete obj.was_visible
|
||||
})
|
||||
@ -890,7 +886,12 @@ function initCanvas() {
|
||||
img.onload = function() {
|
||||
this.tex.needsUpdate = true;
|
||||
}
|
||||
northMarkMaterial = new THREE.MeshBasicMaterial({map: tex, transparent: true, side: THREE.DoubleSide})
|
||||
northMarkMaterial = new THREE.MeshBasicMaterial({
|
||||
map: tex,
|
||||
transparent: true,
|
||||
side: THREE.DoubleSide,
|
||||
alphaTest: 0.2
|
||||
})
|
||||
|
||||
//Rotation Pivot
|
||||
var helper1 = new THREE.AxesHelper(2)
|
||||
@ -1754,20 +1755,21 @@ class CanvasController {
|
||||
}
|
||||
buildOutline(obj) {
|
||||
if (obj.visibility == false) return;
|
||||
var mesh = obj.getMesh()
|
||||
var mesh = obj.getMesh();
|
||||
if (mesh === undefined) return;
|
||||
|
||||
if (mesh.outline) {
|
||||
mesh.outline.geometry.verticesNeedUpdate = true;
|
||||
return;
|
||||
}
|
||||
mesh.remove(mesh.outline)
|
||||
mesh.remove(mesh.outline);
|
||||
|
||||
var line = Canvas.getOutlineMesh(mesh)
|
||||
line.name = obj.uuid+'_outline'
|
||||
line.visible = obj.selected
|
||||
mesh.outline = line
|
||||
mesh.add(line)
|
||||
var line = Canvas.getOutlineMesh(mesh);
|
||||
line.name = obj.uuid+'_outline';
|
||||
line.visible = obj.selected;
|
||||
line.renderOrder = 2;
|
||||
mesh.outline = line;
|
||||
mesh.add(line);
|
||||
}
|
||||
}
|
||||
var Canvas = new CanvasController()
|
||||
|
@ -11,12 +11,13 @@ function settingSetup() {
|
||||
show_actions: {value: false},
|
||||
backup_interval: {value: 10, type: 'number'},
|
||||
//Preview
|
||||
origin_size: {category: 'preview', value: 10, type: 'number'},
|
||||
control_size: {category: 'preview', value: 10, type: 'number'},
|
||||
display_skin: {category: 'preview', value: false, type: 'click', condition: isApp, icon: 'icon-player', click: function() { changeDisplaySkin() }},
|
||||
shading: {category: 'preview', value: true},
|
||||
transparency: {category: 'preview', value: true},
|
||||
texture_fps: {category: 'preview', value: 2, type: 'number'},
|
||||
origin_size: {category: 'preview', value: 10, type: 'number'},
|
||||
control_size: {category: 'preview', value: 10, type: 'number'},
|
||||
display_skin: {category: 'preview', value: false, type: 'click', condition: isApp, icon: 'icon-player', click: function() { changeDisplaySkin() }},
|
||||
seethrough_outline: {category: 'preview', value: false},
|
||||
shading: {category: 'preview', value: true},
|
||||
transparency: {category: 'preview', value: true},
|
||||
texture_fps: {category: 'preview', value: 2, type: 'number'},
|
||||
//Grid
|
||||
base_grid: {category: 'grid', value: true,},
|
||||
large_grid: {category: 'grid', value: false},
|
||||
@ -228,7 +229,8 @@ function saveSettings(force_update) {
|
||||
action.toggleLinkedSetting(false)
|
||||
}
|
||||
}
|
||||
if (hasSettingChanged('base_grid') || hasSettingChanged('large_grid') || hasSettingChanged('full_grid') ||hasSettingChanged('large_box') || hasSettingChanged('display_grid')) {
|
||||
if (hasSettingChanged('base_grid') || hasSettingChanged('large_grid') || hasSettingChanged('full_grid')
|
||||
||hasSettingChanged('large_box') || hasSettingChanged('display_grid') || hasSettingChanged('edit_size')) {
|
||||
buildGrid()
|
||||
}
|
||||
if (hasSettingChanged('transparency')) {
|
||||
@ -238,6 +240,7 @@ function saveSettings(force_update) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Canvas.outlineMaterial.depthTest = !settings.seethrough_outline.value
|
||||
if (hasSettingChanged('shading')) {
|
||||
setShading()
|
||||
}
|
||||
|
@ -54,7 +54,9 @@ class Texture {
|
||||
selected: this.selected,
|
||||
mode: this.mode,
|
||||
saved: this.saved,
|
||||
uuid: this.uuid
|
||||
uuid: this.uuid,
|
||||
old_width: this.old_width,
|
||||
old_height: this.old_height
|
||||
}
|
||||
if (bitmap || this.mode === 'link') {
|
||||
copy.source = this.source
|
||||
@ -135,33 +137,37 @@ class Texture {
|
||||
Blockbench.showQuickMessage('message.square_textures')
|
||||
}
|
||||
}
|
||||
if (Blockbench.entity_mode && textures.indexOf(scope) === 0 && !scope.keep_size) {
|
||||
var size = {
|
||||
ow: Project.texture_width,
|
||||
oh: Project.texture_height,
|
||||
nw: img.naturalWidth,
|
||||
nh: img.naturalHeight
|
||||
}
|
||||
if (size.ow != size.nw || size.oh != size.nh) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'update_res',
|
||||
icon: 'photo_size_select_small',
|
||||
buttons: [tl('message.update_res.update'), tl('dialog.cancel')],
|
||||
confirm: 0,
|
||||
cancel: 1
|
||||
}, function(result) {
|
||||
if (result === 0) {
|
||||
var lockUV = ( // EG. Texture Optimierung > Modulo geht nicht in allen Bereichen auf
|
||||
(size.ow%size.nw || size.oh%size.nh) &&
|
||||
(size.nw%size.ow || size.nh%size.oh)
|
||||
)
|
||||
entityMode.setResolution(img.naturalWidth, img.naturalHeight, lockUV)
|
||||
if (selected.length) {
|
||||
main_uv.loadData()
|
||||
main_uv.setGrid()
|
||||
if (Blockbench.entity_mode && textures.indexOf(scope) === 0) {
|
||||
if (!scope.keep_size) {
|
||||
var size = {
|
||||
pw: Project.texture_width,
|
||||
ph: Project.texture_height,
|
||||
nw: img.naturalWidth,
|
||||
nh: img.naturalHeight
|
||||
}
|
||||
if ((scope.old_width != size.nw || scope.old_height != size.nh) && (size.pw != size.nw || size.ph != size.nh)) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'update_res',
|
||||
icon: 'photo_size_select_small',
|
||||
buttons: [tl('message.update_res.update'), tl('dialog.cancel')],
|
||||
confirm: 0,
|
||||
cancel: 1
|
||||
}, function(result) {
|
||||
if (result === 0) {
|
||||
var lockUV = ( // EG. Texture Optimierung > Modulo geht nicht in allen Bereichen auf
|
||||
(size.pw%size.nw || size.ph%size.nh) &&
|
||||
(size.nw%size.pw || size.nh%size.ph)
|
||||
)
|
||||
entityMode.setResolution(img.naturalWidth, img.naturalHeight, lockUV)
|
||||
if (selected.length) {
|
||||
main_uv.loadData()
|
||||
main_uv.setGrid()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
scope.old_width = img.naturalWidth
|
||||
scope.old_height = img.naturalHeight
|
||||
}
|
||||
}
|
||||
if ($('.dialog#texture_edit:visible').length >= 1 && scope.selected === true) {
|
||||
|
@ -265,10 +265,23 @@ function mirrorSelected(axis) {
|
||||
if (!selected.length) return;
|
||||
Undo.initEdit({cubes: selected})
|
||||
var center = 8
|
||||
if (selected_group && Blockbench.entity_mode) {
|
||||
center = selected_group.origin[axis]
|
||||
} else if (Blockbench.entity_mode) {
|
||||
if (Blockbench.entity_mode) {
|
||||
center = 0
|
||||
if (selected_group && selected_group.matchesSelection()) {
|
||||
function flipGroup(group) {
|
||||
if (group.type === 'group') {
|
||||
for (var i = 0; i < 3; i++) {
|
||||
if (i === axis) {
|
||||
group.origin[i] *= -1
|
||||
} else {
|
||||
group.rotation[i] *= -1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
flipGroup(selected_group)
|
||||
selected_group.forEachChild(flipGroup)
|
||||
}
|
||||
}
|
||||
selected.forEach(function(obj) {
|
||||
obj.flip(axis, center, false)
|
||||
@ -279,6 +292,12 @@ function mirrorSelected(axis) {
|
||||
})
|
||||
updateSelection()
|
||||
Undo.finishEdit('mirror')
|
||||
/*
|
||||
Conditions:
|
||||
Selection equals group cubes:
|
||||
all selected cubes have group as parent
|
||||
|
||||
*/
|
||||
}
|
||||
//Scale
|
||||
function scaleAll(save, size) {
|
||||
|
@ -12,10 +12,11 @@ var Undo = {
|
||||
Undo.current_save = new Undo.save(aspects)
|
||||
},
|
||||
finishEdit: function(action, aspects) {
|
||||
aspects = aspects || Undo.current_save.aspects
|
||||
//After
|
||||
var entry = {
|
||||
before: Undo.current_save,
|
||||
post: new Undo.save(aspects || Undo.current_save.aspects),
|
||||
post: new Undo.save(aspects),
|
||||
action: action
|
||||
}
|
||||
Undo.current_save = entry.post
|
||||
@ -30,7 +31,9 @@ var Undo = {
|
||||
Undo.history.shift()
|
||||
}
|
||||
Undo.index = Undo.history.length
|
||||
Prop.project_saved = false;
|
||||
if (!aspects || !aspects.keep_saved) {
|
||||
Prop.project_saved = false;
|
||||
}
|
||||
},
|
||||
undo: function() {
|
||||
if (Undo.history.length <= 0 || Undo.index < 1) return;
|
||||
|
15
js/uv.js
15
js/uv.js
@ -718,10 +718,15 @@ class UVEditor {
|
||||
if (!Blockbench.entity_mode) return this;
|
||||
var scope = this;
|
||||
var pixels = scope.getPixelSize()
|
||||
function addElement(x,y,width, height, n, color) {
|
||||
function addElement(x, y, width, height, n, color) {
|
||||
x *= pixels;
|
||||
y *= pixels;
|
||||
width = limitNumber(width *pixels + x, 0, scope.size) - x;
|
||||
height = limitNumber(height*pixels + y, 0, scope.height)- y;
|
||||
|
||||
scope.jquery.size.append('<div class="uv_mapping_overlay" '+
|
||||
'style="left: '+x*pixels+'px; top: '+y*pixels+'px;'+
|
||||
'height: '+height*pixels+'px; width: '+width*pixels+'px;'+
|
||||
'style="left: '+x+'px; top: '+y+'px;'+
|
||||
'height: '+height+'px; width: '+width+'px;'+
|
||||
'background: '+color+';"></div>')
|
||||
}
|
||||
var size = selected[0].size(undefined, true)
|
||||
@ -1759,8 +1764,8 @@ BARS.defineActions(function() {
|
||||
south: tl('face.south'),
|
||||
west: tl('face.west'),
|
||||
east: tl('face.east'),
|
||||
top: tl('face.up'),
|
||||
bottom: tl('face.down'),
|
||||
up: tl('face.up'),
|
||||
down: tl('face.down'),
|
||||
},
|
||||
onChange: function(sel, event) {
|
||||
Undo.initEdit({cubes: selected, uv_only: true})
|
||||
|
@ -809,5 +809,7 @@
|
||||
"menu.preview.background.set_position": "Position festlegen",
|
||||
"dialog.toolbar_edit.hidden": "Ausgeblendet",
|
||||
"action.export_class_entity": "Java Entity exportieren",
|
||||
"action.export_class_entity.desc": "Exportiert das Modell als Java Class."
|
||||
"action.export_class_entity.desc": "Exportiert das Modell als Java Class.",
|
||||
"settings.seethrough_outline": "Durchscheinende Auswahl",
|
||||
"settings.seethrough_outline.desc": "Zeige Auswahl durch Objekte hindurch an"
|
||||
}
|
@ -312,6 +312,8 @@
|
||||
"settings.control_size.desc": "Size of the 3 axis control tool",
|
||||
"settings.display_skin": "Display Skin",
|
||||
"settings.display_skin.desc": "Skin used for the display reference player model",
|
||||
"settings.seethrough_outline": "X-Ray Outlines",
|
||||
"settings.seethrough_outline.desc": "Show outlines through objects",
|
||||
"settings.shading": "Shading",
|
||||
"settings.shading.desc": "Enable shading",
|
||||
"settings.transparency": "Transparency",
|
||||
|
12
lang/es.json
12
lang/es.json
@ -805,9 +805,11 @@
|
||||
"action.record_model_gif.desc": "Graba un GIF animado de este modelo desde este ángulo",
|
||||
"display.mirror": "Invertir",
|
||||
"data.separator": "Separador",
|
||||
"message.set_background_position.title": "Background Position",
|
||||
"menu.preview.background.set_position": "Set Position",
|
||||
"dialog.toolbar_edit.hidden": "Hidden",
|
||||
"action.export_class_entity": "Export Java Entity",
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class"
|
||||
"message.set_background_position.title": "Posición del Fondo",
|
||||
"menu.preview.background.set_position": "Ajustar Posición",
|
||||
"dialog.toolbar_edit.hidden": "Oculto",
|
||||
"action.export_class_entity": "Exportar Entidad de Java",
|
||||
"action.export_class_entity.desc": "Exporta el modelo de entidad como una clase de Java",
|
||||
"settings.seethrough_outline": "X-Ray Outlines",
|
||||
"settings.seethrough_outline.desc": "Show outlines through objects"
|
||||
}
|
@ -809,5 +809,7 @@
|
||||
"menu.preview.background.set_position": "Définir la position",
|
||||
"dialog.toolbar_edit.hidden": "Hidden",
|
||||
"action.export_class_entity": "Export Java Entity",
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class"
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class",
|
||||
"settings.seethrough_outline": "X-Ray Outlines",
|
||||
"settings.seethrough_outline.desc": "Show outlines through objects"
|
||||
}
|
12
lang/ja.json
12
lang/ja.json
@ -805,9 +805,11 @@
|
||||
"action.record_model_gif.desc": "現在の角度からモデルのアニメーションGIFを記録する",
|
||||
"display.mirror": "ミラー",
|
||||
"data.separator": "セパレータ",
|
||||
"message.set_background_position.title": "Background Position",
|
||||
"menu.preview.background.set_position": "Set Position",
|
||||
"dialog.toolbar_edit.hidden": "Hidden",
|
||||
"action.export_class_entity": "Export Java Entity",
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class"
|
||||
"message.set_background_position.title": "背景の位置",
|
||||
"menu.preview.background.set_position": "位置をセット",
|
||||
"dialog.toolbar_edit.hidden": "隠す",
|
||||
"action.export_class_entity": "Java Entityをエクスポート",
|
||||
"action.export_class_entity.desc": "エンティティモデルをjava としてエクスポートする",
|
||||
"settings.seethrough_outline": "X-Ray Outlines",
|
||||
"settings.seethrough_outline.desc": "Show outlines through objects"
|
||||
}
|
@ -809,5 +809,7 @@
|
||||
"menu.preview.background.set_position": "Set Position",
|
||||
"dialog.toolbar_edit.hidden": "Hidden",
|
||||
"action.export_class_entity": "Export Java Entity",
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class"
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class",
|
||||
"settings.seethrough_outline": "X-Ray Outlines",
|
||||
"settings.seethrough_outline.desc": "Show outlines through objects"
|
||||
}
|
@ -809,5 +809,7 @@
|
||||
"menu.preview.background.set_position": "Set Position",
|
||||
"dialog.toolbar_edit.hidden": "Hidden",
|
||||
"action.export_class_entity": "Export Java Entity",
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class"
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class",
|
||||
"settings.seethrough_outline": "X-Ray Outlines",
|
||||
"settings.seethrough_outline.desc": "Show outlines through objects"
|
||||
}
|
52
lang/ru.json
52
lang/ru.json
@ -557,12 +557,12 @@
|
||||
"menu.preview.background.position": "Позиция",
|
||||
"menu.preview.background.lock": "Привязать к камере",
|
||||
"menu.preview.background.remove": "Удалить",
|
||||
"menu.preview.screenshot": "Снимок экрана",
|
||||
"menu.preview.screenshot": "Скриншот",
|
||||
"menu.preview.perspective": "Перспектива",
|
||||
"menu.preview.perspective.normal": "Обычная",
|
||||
"menu.preview.quadview": "Четыре вида",
|
||||
"menu.preview.fullview": "Полный вид",
|
||||
"menu.preview.stop_drag": "Закончить изменение расположения",
|
||||
"menu.preview.stop_drag": "Закончить изменение позиции",
|
||||
"menu.uv.copy": "Копировать",
|
||||
"menu.uv.paste": "Вставить",
|
||||
"menu.uv.mapping": "UV-преобразование",
|
||||
@ -588,7 +588,7 @@
|
||||
"switches.shading": "Тень",
|
||||
"switches.autouv": "Авто UV",
|
||||
"panel.uv": "UV",
|
||||
"panel.display": "Дисплей",
|
||||
"panel.display": "Отображение",
|
||||
"panel.textures": "Текстуры",
|
||||
"panel.outliner": "Элементы",
|
||||
"panel.options": "Поворот",
|
||||
@ -609,37 +609,37 @@
|
||||
"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": "Рамка",
|
||||
"display.slot.gui": "ГПИ",
|
||||
"display.slot.gui": "Интерфейс",
|
||||
"display.rotation": "Поворот",
|
||||
"display.translation": "Смещение",
|
||||
"display.scale": "Масштаб",
|
||||
"display.slot": "Слот",
|
||||
"display.reference": "Эталонная модель",
|
||||
"display.presetname": "Имя",
|
||||
"display.presetname": "Название",
|
||||
"display.reference.player": "Игрок",
|
||||
"display.reference.zombie": "Зомби",
|
||||
"display.reference.armor_stand": "Стойка для брони",
|
||||
"display.reference.baby_zombie": "Маленький зомби",
|
||||
"display.reference.armor_stand_small": "Маленькая стойка для брони",
|
||||
"display.reference.monitor": "Обычный",
|
||||
"display.reference.monitor": "Обычный вид",
|
||||
"display.reference.bow": "Лук",
|
||||
"display.reference.block": "Блок",
|
||||
"display.reference.frame": "Рамка",
|
||||
"display.reference.inventory_nine": "3x3",
|
||||
"display.reference.inventory_full": "Инвентарь",
|
||||
"display.reference.hud": "HUD",
|
||||
"display.preset.blank_name": "Пожалуйста, введите имя",
|
||||
"display.preset.item": "Предмет по умолчанию",
|
||||
"display.preset.block": "Блок по умолчанию",
|
||||
"display.preset.handheld": "Оружие по умолчанию",
|
||||
"display.preset.rod": "Стержень по умолчанию",
|
||||
"display.preset.blank_name": "Введите название",
|
||||
"display.preset.item": "Предмет",
|
||||
"display.preset.block": "Блок",
|
||||
"display.preset.handheld": "Оружие",
|
||||
"display.preset.rod": "Стержень",
|
||||
"dialog.continue": "Продолжить",
|
||||
"message.square_textures": "Текстуры должны быть квадратными",
|
||||
"message.unsaved_texture.title": "Несохранённая текстура",
|
||||
@ -651,22 +651,22 @@
|
||||
"action.brush_mode.brush": "Кисть",
|
||||
"action.brush_mode.noise": "Шум",
|
||||
"action.brush_mode.eraser": "Ластик",
|
||||
"action.brush_mode.fill": "Заполнить",
|
||||
"action.vertex_snap_mode.move": "Двигать",
|
||||
"action.vertex_snap_mode.scale": "Масштабировать",
|
||||
"action.open_model_folder": "Открыть папку модели",
|
||||
"action.open_model_folder.desc": "Открывает модель в которой находится текстура",
|
||||
"action.change_textures_folder": "Изменить папку текстур",
|
||||
"action.change_textures_folder.desc": "Изменить папку в которой сохранены все текстуры",
|
||||
"action.brush_mode.fill": "Заливка",
|
||||
"action.vertex_snap_mode.move": "Перемещение",
|
||||
"action.vertex_snap_mode.scale": "Масштабирование",
|
||||
"action.open_model_folder": "Открыть расположение модели",
|
||||
"action.open_model_folder.desc": "Открывает папку, в которой находится модель",
|
||||
"action.change_textures_folder": "Изменить расположение текстур",
|
||||
"action.change_textures_folder.desc": "Изменить папку, в которой сохранены текстуры",
|
||||
"menu.texture.particle": "Использовать для частиц",
|
||||
"message.update_notification.title": "Доступно обновление",
|
||||
"message.update_notification.message": "Доступно обновление Blockbench \"%0\". Вы хотите установить его?",
|
||||
"message.update_notification.message": "Доступно обновление Blockbench «%0». Хотите установить его?",
|
||||
"message.update_notification.install": "Установить",
|
||||
"message.update_notification.later": "Позже",
|
||||
"message.untextured": "Эта поверхность не имеет текстур",
|
||||
"dialog.toolbar_edit.title": "Настроить панель инструментов",
|
||||
"dialog.shift_uv.title": "Сместить UV",
|
||||
"dialog.shift_uv.message": "Введите число по которому Вы хотите умножить смещение UV. Математические выражения разрешены. Добавьте \"+\" перед числом если Вы хотите добавить его.",
|
||||
"dialog.shift_uv.message": "Введите число по которому нужно умножить смещение UV. Математические выражения разрешены. Добавьте «+» перед числом, если нужно его добавить.",
|
||||
"dialog.shift_uv.horizontal": "Горизонтально",
|
||||
"dialog.shift_uv.vertical": "Вертикально",
|
||||
"keybindings.reset": "Сбросить",
|
||||
@ -809,5 +809,7 @@
|
||||
"menu.preview.background.set_position": "Установить позицию",
|
||||
"dialog.toolbar_edit.hidden": "Спрятано",
|
||||
"action.export_class_entity": "Экспортировать сущность Java",
|
||||
"action.export_class_entity.desc": "Экспортировать модель сущности как класс Java"
|
||||
"action.export_class_entity.desc": "Экспортировать модель сущности как класс Java",
|
||||
"settings.seethrough_outline": "X-Ray Outlines",
|
||||
"settings.seethrough_outline.desc": "Show outlines through objects"
|
||||
}
|
@ -809,5 +809,7 @@
|
||||
"menu.preview.background.set_position": "Set Position",
|
||||
"dialog.toolbar_edit.hidden": "Hidden",
|
||||
"action.export_class_entity": "Export Java Entity",
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class"
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class",
|
||||
"settings.seethrough_outline": "X-Ray Outlines",
|
||||
"settings.seethrough_outline.desc": "Show outlines through objects"
|
||||
}
|
60
lang/zh.json
60
lang/zh.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"dialog.ok": "好的",
|
||||
"dialog.ok": "确认",
|
||||
"dialog.cancel": "取消",
|
||||
"dialog.confirm": "确认",
|
||||
"dialog.close": "关闭",
|
||||
@ -19,7 +19,7 @@
|
||||
"keys.shift": "Shift",
|
||||
"keys.alt": "Alt",
|
||||
"keys.meta": "Cmd",
|
||||
"keys.delete": "删除",
|
||||
"keys.delete": "Delete",
|
||||
"keys.space": "空格",
|
||||
"keys.leftclick": "左键点击",
|
||||
"keys.middleclick": "中键点击",
|
||||
@ -402,9 +402,9 @@
|
||||
"action.load_plugin.desc": "通过导入源文件加载插件。",
|
||||
"action.reload_plugins": "重新加载插件",
|
||||
"action.reload_plugins.desc": "重载所有开发插件。",
|
||||
"action.uv_dialog": "UV 窗口",
|
||||
"action.uv_dialog": "打开全部 UV 窗口",
|
||||
"action.uv_dialog.desc": "打开 UV 对话框以查看彼此相邻的所有面",
|
||||
"action.uv_dialog_full": "全视图",
|
||||
"action.uv_dialog_full": "大视图",
|
||||
"action.uv_dialog_full.desc": "打开UV对话框以全屏编辑一个面",
|
||||
"action.undo": "撤消",
|
||||
"action.undo.desc": "撤消上次更改",
|
||||
@ -561,7 +561,7 @@
|
||||
"menu.preview.perspective": "透视",
|
||||
"menu.preview.perspective.normal": "正常",
|
||||
"menu.preview.quadview": "四视图",
|
||||
"menu.preview.fullview": "全视图",
|
||||
"menu.preview.fullview": "大视图",
|
||||
"menu.preview.stop_drag": "停止背景定位",
|
||||
"menu.uv.copy": "复制",
|
||||
"menu.uv.paste": "粘贴",
|
||||
@ -583,7 +583,7 @@
|
||||
"cube.color.blue": "蓝色",
|
||||
"cube.color.green": "绿色",
|
||||
"cube.color.lime": "黄绿色",
|
||||
"switches.visibility": "可见度",
|
||||
"switches.visibility": "切换可见",
|
||||
"switches.export": "导出",
|
||||
"switches.shading": "阴影",
|
||||
"switches.autouv": "自动UV",
|
||||
@ -593,16 +593,16 @@
|
||||
"panel.outliner": "大纲",
|
||||
"panel.options": "旋转",
|
||||
"panel.options.angle": "角度",
|
||||
"panel.options.origin": "原点",
|
||||
"panel.options.origin": "旋转原点",
|
||||
"uv_editor.title": "UV 编辑器",
|
||||
"uv_editor.all_faces": "全部",
|
||||
"uv_editor.no_faces": "无",
|
||||
"face.north": "北",
|
||||
"face.south": "南",
|
||||
"face.west": "西",
|
||||
"face.east": "东",
|
||||
"face.up": "上",
|
||||
"face.down": "下",
|
||||
"face.north": "北/-X面",
|
||||
"face.south": "南/X面",
|
||||
"face.west": "西/-Y面",
|
||||
"face.east": "东/Y面",
|
||||
"face.up": "上/Z面",
|
||||
"face.down": "下/-Z面",
|
||||
"direction.north": "北",
|
||||
"direction.south": "南",
|
||||
"direction.west": "西",
|
||||
@ -649,7 +649,7 @@
|
||||
"dialog.update.installed": "已安装的版本",
|
||||
"dialog.update.update": "更新",
|
||||
"action.brush_mode.brush": "笔刷",
|
||||
"action.brush_mode.noise": "点",
|
||||
"action.brush_mode.noise": "像素点",
|
||||
"action.brush_mode.eraser": "橡皮擦",
|
||||
"action.brush_mode.fill": "油漆桶",
|
||||
"action.vertex_snap_mode.move": "移动",
|
||||
@ -711,13 +711,13 @@
|
||||
"uv_editor.maximized": "最大化",
|
||||
"uv_editor.autouv": "尺寸自动",
|
||||
"uv_editor.mirrored": "镜像",
|
||||
"uv_editor.to_all": "适用于所有人",
|
||||
"uv_editor.to_all": "适用于所有的面",
|
||||
"uv_editor.transparent": "设置透明度",
|
||||
"uv_editor.cullface_on": "开启面剔除",
|
||||
"uv_editor.cullface_off": "关闭面剔除",
|
||||
"uv_editor.tint_on": "开启着色",
|
||||
"uv_editor.tint_off": "关闭着色",
|
||||
"action.uv_apply_all": "适用于所有人",
|
||||
"action.uv_apply_all": "适用于所有的面",
|
||||
"action.uv_apply_all.desc": "将当前面的设置应用于所有面",
|
||||
"message.convert_mode.title": "模型转换",
|
||||
"message.convert_mode.message": "您确定要将此类型转换为 %0 吗?您无法撤消此步骤",
|
||||
@ -795,19 +795,21 @@
|
||||
"panel.variable_placeholders": "变量占位符",
|
||||
"panel.variable_placeholders.info": "列出要通过 name=value 预览的变量",
|
||||
"status_bar.vertex_distance": "距离: %0",
|
||||
"dialog.create_gif.title": "Record GIF",
|
||||
"dialog.create_gif.length": "Length (Seconds)",
|
||||
"dialog.create_gif.title": "录制GIF",
|
||||
"dialog.create_gif.length": "长度(秒)",
|
||||
"dialog.create_gif.fps": "FPS",
|
||||
"dialog.create_gif.compression": "Compression Amount",
|
||||
"dialog.create_gif.play": "Start Animation",
|
||||
"category.animation": "Animation",
|
||||
"action.record_model_gif": "Record GIF",
|
||||
"action.record_model_gif.desc": "Record an animated GIF of the model from the current angle",
|
||||
"display.mirror": "Mirror",
|
||||
"dialog.create_gif.compression": "压缩量",
|
||||
"dialog.create_gif.play": "播放动画",
|
||||
"category.animation": "动画",
|
||||
"action.record_model_gif": "录制GIF",
|
||||
"action.record_model_gif.desc": "从当前角度记录模型的GIF动画",
|
||||
"display.mirror": "镜像",
|
||||
"data.separator": "分隔符",
|
||||
"message.set_background_position.title": "Background Position",
|
||||
"menu.preview.background.set_position": "Set Position",
|
||||
"dialog.toolbar_edit.hidden": "Hidden",
|
||||
"action.export_class_entity": "Export Java Entity",
|
||||
"action.export_class_entity.desc": "Export the entity model as a Java class"
|
||||
"message.set_background_position.title": "背景位置",
|
||||
"menu.preview.background.set_position": "设置位置",
|
||||
"dialog.toolbar_edit.hidden": "隐藏",
|
||||
"action.export_class_entity": "导出java实体(?",
|
||||
"action.export_class_entity.desc": "作为java class导出模型",
|
||||
"settings.seethrough_outline": "X-Ray Outlines",
|
||||
"settings.seethrough_outline.desc": "Show outlines through objects"
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Blockbench",
|
||||
"description": "Minecraft Block Model Editor",
|
||||
"version": "2.2.0",
|
||||
"version": "2.2.1",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "JannisX11",
|
||||
|
Loading…
Reference in New Issue
Block a user