Merge branch '3d-brush-matrix' of https://github.com/nestorboy/blockbench into pr/Nestorboy/2529

This commit is contained in:
JannisX11 2024-11-17 13:02:57 +01:00
commit 6c05b05e0c
12 changed files with 322 additions and 398 deletions

View File

@ -158,6 +158,7 @@
padding-right: 8px;
flex-shrink: 0;
overflow-wrap: break-word;
box-sizing: content-box;
}
.dialog label.name_space_left {
min-width: 140px;

514
css/fontawesome.css vendored
View File

@ -1,27 +1,21 @@
/*!
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
* Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
* Copyright 2024 Fonticons, Inc.
*/
.fa {
font-family: var(--fa-style-family, "Font Awesome 6 Free");
font-weight: var(--fa-style, 900); }
.fa,
.fa-classic,
.fa-sharp,
.fas,
.fa-solid,
.far,
.fa-regular,
.fal,
.fa-light,
.fat,
.fa-thin,
.fad,
.fa-duotone,
.fa-brands,
.fas,
.far,
.fab,
.fa-brands {
.fa-sharp-solid,
.fa-classic,
.fa {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: var(--fa-display, inline-block);
@ -113,7 +107,7 @@
position: relative; }
.fa-li {
left: calc(var(--fa-li-width, 2em) * -1);
left: calc(-1 * var(--fa-li-width, 2em));
position: absolute;
text-align: center;
width: var(--fa-li-width, 2em);
@ -135,118 +129,71 @@
margin-left: var(--fa-pull-margin, 0.3em); }
.fa-beat {
-webkit-animation-name: fa-beat;
animation-name: fa-beat;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);
animation-timing-function: var(--fa-animation-timing, ease-in-out); }
animation-name: fa-beat;
animation-delay: var(--fa-animation-delay, 0s);
animation-direction: var(--fa-animation-direction, normal);
animation-duration: var(--fa-animation-duration, 1s);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-timing-function: var(--fa-animation-timing, ease-in-out); }
.fa-bounce {
-webkit-animation-name: fa-bounce;
animation-name: fa-bounce;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1)); }
animation-name: fa-bounce;
animation-delay: var(--fa-animation-delay, 0s);
animation-direction: var(--fa-animation-direction, normal);
animation-duration: var(--fa-animation-duration, 1s);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1)); }
.fa-fade {
-webkit-animation-name: fa-fade;
animation-name: fa-fade;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }
animation-name: fa-fade;
animation-delay: var(--fa-animation-delay, 0s);
animation-direction: var(--fa-animation-direction, normal);
animation-duration: var(--fa-animation-duration, 1s);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }
.fa-beat-fade {
-webkit-animation-name: fa-beat-fade;
animation-name: fa-beat-fade;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }
animation-name: fa-beat-fade;
animation-delay: var(--fa-animation-delay, 0s);
animation-direction: var(--fa-animation-direction, normal);
animation-duration: var(--fa-animation-duration, 1s);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }
.fa-flip {
-webkit-animation-name: fa-flip;
animation-name: fa-flip;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);
animation-timing-function: var(--fa-animation-timing, ease-in-out); }
animation-name: fa-flip;
animation-delay: var(--fa-animation-delay, 0s);
animation-direction: var(--fa-animation-direction, normal);
animation-duration: var(--fa-animation-duration, 1s);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-timing-function: var(--fa-animation-timing, ease-in-out); }
.fa-shake {
-webkit-animation-name: fa-shake;
animation-name: fa-shake;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, linear);
animation-timing-function: var(--fa-animation-timing, linear); }
animation-name: fa-shake;
animation-delay: var(--fa-animation-delay, 0s);
animation-direction: var(--fa-animation-direction, normal);
animation-duration: var(--fa-animation-duration, 1s);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-timing-function: var(--fa-animation-timing, linear); }
.fa-spin {
-webkit-animation-name: fa-spin;
animation-name: fa-spin;
-webkit-animation-delay: var(--fa-animation-delay, 0s);
animation-delay: var(--fa-animation-delay, 0s);
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 2s);
animation-duration: var(--fa-animation-duration, 2s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, linear);
animation-timing-function: var(--fa-animation-timing, linear); }
animation-name: fa-spin;
animation-delay: var(--fa-animation-delay, 0s);
animation-direction: var(--fa-animation-direction, normal);
animation-duration: var(--fa-animation-duration, 2s);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-timing-function: var(--fa-animation-timing, linear); }
.fa-spin-reverse {
--fa-animation-direction: reverse; }
.fa-pulse,
.fa-spin-pulse {
-webkit-animation-name: fa-spin;
animation-name: fa-spin;
-webkit-animation-direction: var(--fa-animation-direction, normal);
animation-direction: var(--fa-animation-direction, normal);
-webkit-animation-duration: var(--fa-animation-duration, 1s);
animation-duration: var(--fa-animation-duration, 1s);
-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
-webkit-animation-timing-function: var(--fa-animation-timing, steps(8));
animation-timing-function: var(--fa-animation-timing, steps(8)); }
animation-name: fa-spin;
animation-direction: var(--fa-animation-direction, normal);
animation-duration: var(--fa-animation-duration, 1s);
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
animation-timing-function: var(--fa-animation-timing, steps(8)); }
@media (prefers-reduced-motion: reduce) {
.fa-beat,
@ -258,219 +205,97 @@
.fa-shake,
.fa-spin,
.fa-spin-pulse {
-webkit-animation-delay: -1ms;
animation-delay: -1ms;
-webkit-animation-duration: 1ms;
animation-duration: 1ms;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
-webkit-transition-delay: 0s;
transition-delay: 0s;
-webkit-transition-duration: 0s;
transition-duration: 0s; } }
@-webkit-keyframes fa-beat {
0%, 90% {
-webkit-transform: scale(1);
transform: scale(1); }
45% {
-webkit-transform: scale(var(--fa-beat-scale, 1.25));
transform: scale(var(--fa-beat-scale, 1.25)); } }
animation-delay: -1ms;
animation-duration: 1ms;
animation-iteration-count: 1;
transition-delay: 0s;
transition-duration: 0s; } }
@keyframes fa-beat {
0%, 90% {
-webkit-transform: scale(1);
transform: scale(1); }
transform: scale(1); }
45% {
-webkit-transform: scale(var(--fa-beat-scale, 1.25));
transform: scale(var(--fa-beat-scale, 1.25)); } }
@-webkit-keyframes fa-bounce {
0% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
10% {
-webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);
transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); }
30% {
-webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));
transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); }
50% {
-webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);
transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); }
57% {
-webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));
transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); }
64% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
100% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); } }
transform: scale(var(--fa-beat-scale, 1.25)); } }
@keyframes fa-bounce {
0% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
transform: scale(1, 1) translateY(0); }
10% {
-webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);
transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); }
transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); }
30% {
-webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));
transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); }
transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); }
50% {
-webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);
transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); }
transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); }
57% {
-webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));
transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); }
transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); }
64% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); }
transform: scale(1, 1) translateY(0); }
100% {
-webkit-transform: scale(1, 1) translateY(0);
transform: scale(1, 1) translateY(0); } }
@-webkit-keyframes fa-fade {
50% {
opacity: var(--fa-fade-opacity, 0.4); } }
transform: scale(1, 1) translateY(0); } }
@keyframes fa-fade {
50% {
opacity: var(--fa-fade-opacity, 0.4); } }
@-webkit-keyframes fa-beat-fade {
0%, 100% {
opacity: var(--fa-beat-fade-opacity, 0.4);
-webkit-transform: scale(1);
transform: scale(1); }
50% {
opacity: 1;
-webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));
transform: scale(var(--fa-beat-fade-scale, 1.125)); } }
@keyframes fa-beat-fade {
0%, 100% {
opacity: var(--fa-beat-fade-opacity, 0.4);
-webkit-transform: scale(1);
transform: scale(1); }
transform: scale(1); }
50% {
opacity: 1;
-webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));
transform: scale(var(--fa-beat-fade-scale, 1.125)); } }
@-webkit-keyframes fa-flip {
50% {
-webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));
transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } }
transform: scale(var(--fa-beat-fade-scale, 1.125)); } }
@keyframes fa-flip {
50% {
-webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));
transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } }
@-webkit-keyframes fa-shake {
0% {
-webkit-transform: rotate(-15deg);
transform: rotate(-15deg); }
4% {
-webkit-transform: rotate(15deg);
transform: rotate(15deg); }
8%, 24% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg); }
12%, 28% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg); }
16% {
-webkit-transform: rotate(-22deg);
transform: rotate(-22deg); }
20% {
-webkit-transform: rotate(22deg);
transform: rotate(22deg); }
32% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg); }
36% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg); }
40%, 100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); } }
transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } }
@keyframes fa-shake {
0% {
-webkit-transform: rotate(-15deg);
transform: rotate(-15deg); }
transform: rotate(-15deg); }
4% {
-webkit-transform: rotate(15deg);
transform: rotate(15deg); }
transform: rotate(15deg); }
8%, 24% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg); }
transform: rotate(-18deg); }
12%, 28% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg); }
transform: rotate(18deg); }
16% {
-webkit-transform: rotate(-22deg);
transform: rotate(-22deg); }
transform: rotate(-22deg); }
20% {
-webkit-transform: rotate(22deg);
transform: rotate(22deg); }
transform: rotate(22deg); }
32% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg); }
transform: rotate(-12deg); }
36% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg); }
transform: rotate(12deg); }
40%, 100% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); } }
@-webkit-keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
transform: rotate(0deg); } }
@keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
transform: rotate(360deg); } }
.fa-rotate-90 {
-webkit-transform: rotate(90deg);
transform: rotate(90deg); }
transform: rotate(90deg); }
.fa-rotate-180 {
-webkit-transform: rotate(180deg);
transform: rotate(180deg); }
transform: rotate(180deg); }
.fa-rotate-270 {
-webkit-transform: rotate(270deg);
transform: rotate(270deg); }
transform: rotate(270deg); }
.fa-flip-horizontal {
-webkit-transform: scale(-1, 1);
transform: scale(-1, 1); }
transform: scale(-1, 1); }
.fa-flip-vertical {
-webkit-transform: scale(1, -1);
transform: scale(1, -1); }
transform: scale(1, -1); }
.fa-flip-both,
.fa-flip-horizontal.fa-flip-vertical {
-webkit-transform: scale(-1, -1);
transform: scale(-1, -1); }
transform: scale(-1, -1); }
.fa-rotate-by {
-webkit-transform: rotate(var(--fa-rotate-angle, none));
transform: rotate(var(--fa-rotate-angle, none)); }
transform: rotate(var(--fa-rotate-angle, 0)); }
.fa-stack {
display: inline-block;
@ -1898,6 +1723,12 @@ readers do not read off random characters that represent icons */
.fa-passport::before {
content: "\f5ab"; }
.fa-thumbtack-slash::before {
content: "\e68f"; }
.fa-thumb-tack-slash::before {
content: "\e68f"; }
.fa-heart-pulse::before {
content: "\f21e"; }
@ -2774,6 +2605,9 @@ readers do not read off random characters that represent icons */
.fa-italic::before {
content: "\f033"; }
.fa-table-cells-column-lock::before {
content: "\e678"; }
.fa-church::before {
content: "\f51d"; }
@ -4946,6 +4780,9 @@ readers do not read off random characters that represent icons */
.fa-font::before {
content: "\f031"; }
.fa-table-cells-row-lock::before {
content: "\e67a"; }
.fa-rupiah-sign::before {
content: "\e23d"; }
@ -6203,6 +6040,9 @@ readers do not read off random characters that represent icons */
.fa-bone::before {
content: "\f5d7"; }
.fa-table-cells-row-unlock::before {
content: "\e691"; }
.fa-user-injured::before {
content: "\f728"; }
@ -6340,7 +6180,7 @@ readers do not read off random characters that represent icons */
.fa-hand-holding-medical::before {
content: "\e05c"; }
fa-monero:before {
.fa-monero:before {
content: "\f3d0"; }
.fa-hooli:before {
@ -6439,6 +6279,12 @@ readers do not read off random characters that represent icons */
.fa-drupal:before {
content: "\f1a9"; }
.fa-jxl:before {
content: "\e67b"; }
.fa-dart-lang:before {
content: "\e693"; }
.fa-hire-a-helper:before {
content: "\f3b0"; }
@ -6742,6 +6588,9 @@ readers do not read off random characters that represent icons */
.fa-kickstarter:before {
content: "\f3bb"; }
.fa-square-kickstarter:before {
content: "\f3bb"; }
.fa-grav:before {
content: "\f2d6"; }
@ -7174,6 +7023,9 @@ readers do not read off random characters that represent icons */
.fa-google-plus-square:before {
content: "\f0d4"; }
.fa-web-awesome:before {
content: "\e682"; }
.fa-mandalorian:before {
content: "\f50f"; }
@ -7336,6 +7188,9 @@ readers do not read off random characters that represent icons */
.fa-xbox:before {
content: "\f412"; }
.fa-square-web-awesome-stroke:before {
content: "\e684"; }
.fa-searchengin:before {
content: "\f3eb"; }
@ -7369,6 +7224,9 @@ readers do not read off random characters that represent icons */
.fa-twitch:before {
content: "\f1e8"; }
.fa-flutter:before {
content: "\e694"; }
.fa-ravelry:before {
content: "\f2d9"; }
@ -7444,6 +7302,9 @@ readers do not read off random characters that represent icons */
.fa-whatsapp:before {
content: "\f232"; }
.fa-square-upwork:before {
content: "\e67c"; }
.fa-slideshare:before {
content: "\f1e7"; }
@ -7522,6 +7383,9 @@ readers do not read off random characters that represent icons */
.fa-sellsy:before {
content: "\f213"; }
.fa-square-web-awesome:before {
content: "\e683"; }
.fa-sass:before {
content: "\f41e"; }
@ -7558,6 +7422,9 @@ readers do not read off random characters that represent icons */
.fa-waze:before {
content: "\f83f"; }
.fa-bluesky:before {
content: "\e671"; }
.fa-cc-jcb:before {
content: "\f24b"; }
@ -7894,64 +7761,59 @@ readers do not read off random characters that represent icons */
.fa-steam-symbol:before {
content: "\f3f6"; }
@font-face {
font-family: 'Font Awesome 6 Brands';
font-style: normal;
font-weight: normal;
font-display: auto;
src: url("../font/fa-brands-400.woff2") format("woff2")}
.fa-person-circle-check::before {
content: "\e53e"; }
@font-face {
font-family: 'Font Awesome 6 Brands';
font-style: normal;
font-weight: normal;
font-display: auto;
src: url("../font/fa-brands-400.woff2") format("woff2")}
.fa {
font-family: 'Font Awesome 6 Free';
font-weight: 900; }
.fa-turn-up::before {
content: "\f3bf"; }
.fa {
font-family: 'Font Awesome 6 Free';
font-weight: 900; }
.fab {
font-family: 'Font Awesome 6 Brands'; }
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 400;
font-display: auto;
src: url("../font/fa-regular-400.woff2") format("woff2")}
.fa-level-up-alt::before {
content: "\f3bf"; }
.far {
font-family: 'Font Awesome 6 Free';
font-weight: 400; }
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 900;
font-display: auto;
src: url("../font/fa-solid-900.woff2") format("woff2")}
.sr-only,
.fa-sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0; }
.fas {
font-family: 'Font Awesome 6 Free';
font-weight: 900; }
.sr-only-focusable:not(:focus),
.fa-sr-only-focusable:not(:focus) {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0; }
.fab {
font-family: 'Font Awesome 6 Brands'; }
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 400;
font-display: auto;
src: url("../font/fa-regular-400.woff2") format("woff2")}
.far {
font-family: 'Font Awesome 6 Free';
font-weight: 400; }
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 900;
font-display: auto;
src: url("../font/fa-solid-900.woff2") format("woff2")}
.sr-only,
.fa-sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0; }
.fas {
font-family: 'Font Awesome 6 Free';
font-weight: 900; }
.sr-only-focusable:not(:focus),
.fa-sr-only-focusable:not(:focus) {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0; }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -52,16 +52,20 @@ BARS.defineActions(() => {
<i class="icon icon-blockbench_inverted" style="transform: scale(1.3);"></i>
<label>Website</label>
</a>
<a class="open-in-browser" href="https://bsky.app/profile/blockbench.net">
<i class="icon fab fa-bluesky" style="color: #208bfe;"></i>
<label>Bluesky</label>
</a>
<a class="open-in-browser" href="https://twitter.com/blockbench">
<i class="icon fab fa-twitter" style="color: #1ea6ff;"></i>
<label>Twitter</label>
</a>
<a class="open-in-browser" href="http://discord.blockbench.net">
<i class="icon fab fa-discord" style="color: #727fff;"></i>
<i class="icon fab fa-discord" style="color: #5865F2;"></i>
<label>Discord</label>
</a>
<a class="open-in-browser" href="https://youtube.com/Blockbench3D">
<i class="icon fab fa-youtube" style="color: #ff4444;"></i>
<i class="icon fab fa-youtube"></i>
<label>YouTube</label>
</a>
<a class="open-in-browser" href="https://github.com/JannisX11/blockbench">
@ -127,7 +131,7 @@ BARS.defineActions(() => {
<li><a class="open-in-browser" href="https://github.com/JannisX11/wintersky">Wintersky</a></li>
</ul>
<p style="margin-top: 20px">Published under the <a class="open-in-browser" href="https://github.com/JannisX11/blockbench/blob/master/LICENSE.MD">GPL 3.0 license</a></p>
<p style="margin-top: 20px">Released under the <a class="open-in-browser" href="https://github.com/JannisX11/blockbench/blob/master/LICENSE.MD">GPL 3.0 license</a></p>
<p><a class="open-in-browser" href="https://www.blockbench.net/privacy-policy">Privacy Policy</a></p>
</div>`

View File

@ -28,6 +28,7 @@ class InputForm extends EventSystem {
label = Interface.createElement('label', {class: 'name_space_left', for: form_id}, tl(input_config.label)+((input_config.nocolon || !input_config.label)?'':':'))
bar.append(label);
if (!input_config.full_width && input_config.condition !== false) {
console.log(getStringWidth(label.textContent), label.textContent)
this.max_label_width = Math.max(getStringWidth(label.textContent), this.max_label_width)
}
}

View File

@ -326,11 +326,17 @@ const Vertexsnap = {
element.mesh.localToWorld(vector);
return vector;
},
snap: function(data) {
Undo.initEdit({elements: Vertexsnap.elements, outliner: !!Vertexsnap.group});
snap: function(data, options = 0, amended) {
Undo.initEdit({elements: Vertexsnap.elements, outliner: !!Vertexsnap.group}, amended);
let mode = BarItems.vertex_snap_mode.get();
function ignoreVectorAxes(vector) {
if (options.ignore_x) vector.x = 0;
if (options.ignore_y) vector.y = 0;
if (options.ignore_z) vector.z = 0;
}
if (Vertexsnap.move_origin) {
if (Vertexsnap.group) {
let vec = Vertexsnap.getGlobalVertexPos(data.element, data.vertex);
@ -357,8 +363,8 @@ const Vertexsnap = {
}
} else {
var global_delta = Vertexsnap.getGlobalVertexPos(data.element, data.vertex);
global_delta.sub(Vertexsnap.vertex_pos)
let global_target_pos = Vertexsnap.getGlobalVertexPos(data.element, data.vertex);
let global_delta = new THREE.Vector3().copy(global_target_pos).sub(Vertexsnap.vertex_pos)
if (mode === 'scale' && !Format.integer_size && Vertexsnap.elements[0] instanceof Cube) {
//Scale
@ -378,13 +384,14 @@ const Vertexsnap = {
Vertexsnap.elements.forEach(function(obj) {
if (obj instanceof Cube == false) return;
var q = obj.mesh.getWorldQuaternion(new THREE.Quaternion()).invert()
var cube_pos = new THREE.Vector3().copy(global_delta).applyQuaternion(q)
var local_offset = new THREE.Vector3().copy(global_delta).applyQuaternion(q)
ignoreVectorAxes(local_offset);
for (i=0; i<3; i++) {
if (m[i] === 1) {
obj.to[i] = obj.to[i] + cube_pos.getComponent(i);
obj.to[i] = obj.to[i] + local_offset.getComponent(i);
} else {
obj.from[i] = obj.from[i] + cube_pos.getComponent(i);
obj.from[i] = obj.from[i] + local_offset.getComponent(i);
}
}
if (Format.cube_size_limiter && !settings.deactivate_size_limit.value) {
@ -396,39 +403,70 @@ const Vertexsnap = {
})
} else if (mode === 'move') {
Vertexsnap.elements.forEach(function(obj) {
var cube_pos = new THREE.Vector3().copy(global_delta)
var local_offset = new THREE.Vector3().copy(global_delta)
if (obj instanceof Mesh && Vertexsnap.selected_vertices && Vertexsnap.selected_vertices[obj.uuid]) {
let vertices = Vertexsnap.selected_vertices[obj.uuid].vertices;
var q = obj.mesh.getWorldQuaternion(Reusable.quat1).invert();
cube_pos.applyQuaternion(q);
let cube_pos_array = cube_pos.toArray();
local_offset.applyQuaternion(q);
ignoreVectorAxes(local_offset);
let local_offset_array = local_offset.toArray();
vertices.forEach(vkey => {
if (obj.vertices[vkey]) obj.vertices[vkey].V3_add(cube_pos_array);
if (obj.vertices[vkey]) obj.vertices[vkey].V3_add(local_offset_array);
})
} else {
if (Format.bone_rig && obj.parent instanceof Group) {
var q = obj.mesh.parent.getWorldQuaternion(Reusable.quat1).invert();
cube_pos.applyQuaternion(q);
local_offset.applyQuaternion(q);
}
if (obj instanceof Cube && Format.rotate_cubes) {
obj.origin.V3_add(cube_pos);
obj.origin.V3_add(local_offset);
}
var in_box = obj.moveVector(cube_pos.toArray());
ignoreVectorAxes(local_offset);
var in_box = obj.moveVector(local_offset.toArray());
if (!in_box && Format.cube_size_limiter && !settings.deactivate_size_limit.value) {
Blockbench.showMessageBox({translateKey: 'canvas_limit_error'})
}
}
})
}
} else if (mode == 'rotate') {
Vertexsnap.elements.forEach((obj) => {
let local_start = obj.mesh.worldToLocal(new THREE.Vector3().copy(Vertexsnap.vertex_pos));
let local_target = obj.mesh.worldToLocal(new THREE.Vector3().copy(global_target_pos));
ignoreVectorAxes(local_start);
ignoreVectorAxes(local_target);
if (options.align != 'direction' || !amended) {
let target_distance = local_target.length();
let longest_axis = 'x';
if ('xyz'.includes(options.align)) {
longest_axis = options.align;
} else {
if (local_start.y > local_start.x) longest_axis = 'y';
if (local_start.z > local_start.y) longest_axis = 'z';
}
let off_axes = ['x', 'y', 'z'].filter(l => l != longest_axis);
local_start[longest_axis] = Math.sqrt(target_distance**2 - local_start[off_axes[0]]**2 - local_start[off_axes[1]]**2);
}
local_start.normalize();
local_target.normalize();
let rot_diff = new THREE.Quaternion().setFromUnitVectors(local_start, local_target);
obj.mesh.quaternion.multiply(rot_diff);
let modified_rotation = obj.mesh.rotation.toArray().slice(0, 3).map(Math.radToDeg);
obj.extend({rotation: modified_rotation});
})
}
}
Vertexsnap.clearVertexGizmos()
let update_options = {
elements: Vertexsnap.elements,
element_aspects: {transform: true, geometry: true},
selection: true
};
if (Vertexsnap.group) {
update_options.elements = [...update_options.elements];
@ -440,8 +478,25 @@ const Vertexsnap = {
}
Canvas.updateView(update_options);
Undo.finishEdit('Use vertex snap');
autoFixMeshEdit()
autoFixMeshEdit();
Vertexsnap.step1 = true;
if (!amended) {
Undo.amendEdit({
align: {type: 'select', condition: mode == 'rotate', label: 'edit.vertex_snap.align', options: {
longest: 'edit.vertex_snap.align.longest',
direction: 'edit.vertex_snap.align.direction',
x: tl('edit.vertex_snap.align.align_axis', 'X'),
y: tl('edit.vertex_snap.align.align_axis', 'Y'),
z: tl('edit.vertex_snap.align.align_axis', 'Z'),
}},
ignore_x: {type: 'checkbox', label: tl('edit.vertex_snap.ignore_axis', 'X'), value: false},
ignore_y: {type: 'checkbox', label: tl('edit.vertex_snap.ignore_axis', 'Y'), value: false},
ignore_z: {type: 'checkbox', label: tl('edit.vertex_snap.ignore_axis', 'Z'), value: false},
}, form => {
Vertexsnap.snap(data, form, true);
})
}
}
}
@ -938,7 +993,8 @@ BARS.defineActions(function() {
new BarSelect('vertex_snap_mode', {
options: {
move: true,
scale: {condition: () => !Format.integer_size, name: true}
scale: {condition: () => !Format.integer_size, name: true},
rotate: true
},
category: 'edit'
})

View File

@ -52,6 +52,21 @@ class CubeFace extends Face {
case 'down': return [7, 2, 3, 6];
}
}
texelToLocalMatrix(uv, truncate_factor = [1, 1], truncated_uv) {
uv = truncated_uv == null || truncated_uv[0] == null || truncated_uv[1] == null ? [...uv] : [...truncated_uv];
let texel_pos = this.UVToLocal(uv);
let texel_x_axis = this.UVToLocal([uv[0] + truncate_factor[0], uv[1]]);
let texel_y_axis = this.UVToLocal([uv[0], uv[1] + truncate_factor[1]]);
texel_x_axis.sub(texel_pos);
texel_y_axis.sub(texel_pos);
let matrix = new THREE.Matrix4();
matrix.makeBasis(texel_x_axis, texel_y_axis, new THREE.Vector3(0, 0, 1));
matrix.setPosition(texel_pos);
return matrix;
}
UVToLocal(point) {
let from = this.cube.from.slice()
let to = this.cube.to.slice()

View File

@ -288,11 +288,12 @@ class MeshFace extends Face {
if (this.mesh.faces[fkey] == this) return fkey;
}
}
TexelToLocalMatrix(uv, vertices = this.getSortedVertices(), truncateOffset) {
texelToLocalMatrix(uv, truncate_factor = [1, 1], truncated_uv, vertices = this.getSortedVertices()) {
let vert_a = vertices[0];
let vert_b = vertices[1];
let vert_c = vertices[2];
// Use non-truncated uv coordinates to select the correct triangle of a face.
if (vertices[3]) {
let is_in_tri = pointInTriangle(uv, this.uv[vert_a], this.uv[vert_b], this.uv[vert_c]);
@ -310,49 +311,31 @@ class MeshFace extends Face {
let vertexb = this.mesh.vertices[vert_b];
let vertexc = this.mesh.vertices[vert_c];
if (typeof truncateOffset !== "undefined") {
uv[0] = Math.round(uv[0] + truncateOffset) - truncateOffset;
uv[1] = Math.round(uv[1] + truncateOffset) - truncateOffset;
uv = truncated_uv == null || truncated_uv[0] == null || truncated_uv[1] == null ? [...uv] : [...truncated_uv];
function UVToLocal(uv) {
let b0 = (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1]);
let b1 = ((p1[0] - uv[0]) * (p2[1] - uv[1]) - (p2[0] - uv[0]) * (p1[1] - uv[1])) / b0;
let b2 = ((p2[0] - uv[0]) * (p0[1] - uv[1]) - (p0[0] - uv[0]) * (p2[1] - uv[1])) / b0;
let b3 = ((p0[0] - uv[0]) * (p1[1] - uv[1]) - (p1[0] - uv[0]) * (p0[1] - uv[1])) / b0;
return new THREE.Vector3(
vertexa[0] * b1 + vertexb[0] * b2 + vertexc[0] * b3,
vertexa[1] * b1 + vertexb[1] * b2 + vertexc[1] * b3,
vertexa[2] * b1 + vertexb[2] * b2 + vertexc[2] * b3
)
}
let b0 = (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1])
let b1 = ((p1[0] - uv[0]) * (p2[1] - uv[1]) - (p2[0] - uv[0]) * (p1[1] - uv[1])) / b0
let b2 = ((p2[0] - uv[0]) * (p0[1] - uv[1]) - (p0[0] - uv[0]) * (p2[1] - uv[1])) / b0
let b3 = ((p0[0] - uv[0]) * (p1[1] - uv[1]) - (p1[0] - uv[0]) * (p0[1] - uv[1])) / b0
let texel_pos = UVToLocal(uv);
let texel_x_axis = UVToLocal([uv[0] + truncate_factor[0], uv[1]]);
let texel_y_axis = UVToLocal([uv[0], uv[1] + truncate_factor[1]]);
let texelP1 = new THREE.Vector3(
vertexa[0] * b1 + vertexb[0] * b2 + vertexc[0] * b3,
vertexa[1] * b1 + vertexb[1] * b2 + vertexc[1] * b3,
vertexa[2] * b1 + vertexb[2] * b2 + vertexc[2] * b3,
)
uv[0] += 1;
b1 = ((p1[0] - uv[0]) * (p2[1] - uv[1]) - (p2[0] - uv[0]) * (p1[1] - uv[1])) / b0
b2 = ((p2[0] - uv[0]) * (p0[1] - uv[1]) - (p0[0] - uv[0]) * (p2[1] - uv[1])) / b0
b3 = ((p0[0] - uv[0]) * (p1[1] - uv[1]) - (p1[0] - uv[0]) * (p0[1] - uv[1])) / b0
let texelRight = new THREE.Vector3(
vertexa[0] * b1 + vertexb[0] * b2 + vertexc[0] * b3,
vertexa[1] * b1 + vertexb[1] * b2 + vertexc[1] * b3,
vertexa[2] * b1 + vertexb[2] * b2 + vertexc[2] * b3,
)
uv[0] -= 1;
uv[1] += 1;
b1 = ((p1[0] - uv[0]) * (p2[1] - uv[1]) - (p2[0] - uv[0]) * (p1[1] - uv[1])) / b0
b2 = ((p2[0] - uv[0]) * (p0[1] - uv[1]) - (p0[0] - uv[0]) * (p2[1] - uv[1])) / b0
b3 = ((p0[0] - uv[0]) * (p1[1] - uv[1]) - (p1[0] - uv[0]) * (p0[1] - uv[1])) / b0
let texelUp = new THREE.Vector3(
vertexa[0] * b1 + vertexb[0] * b2 + vertexc[0] * b3,
vertexa[1] * b1 + vertexb[1] * b2 + vertexc[1] * b3,
vertexa[2] * b1 + vertexb[2] * b2 + vertexc[2] * b3,
)
texelRight.sub(texelP1);
texelUp.sub(texelP1);
texel_x_axis.sub(texel_pos);
texel_y_axis.sub(texel_pos);
let matrix = new THREE.Matrix4();
matrix.makeBasis(texelRight, texelUp, new THREE.Vector3(0, 0, 1));
matrix.setPosition(texelP1);
matrix.makeBasis(texel_x_axis, texel_y_axis, new THREE.Vector3(0, 0, 1));
matrix.setPosition(texel_pos);
return matrix;
}
UVToLocal(uv, vertices = this.getSortedVertices()) {

View File

@ -1085,18 +1085,20 @@ class Preview {
let offset = 0;
let x = intersect.uv.x * texture.width;
let y = (1-intersect.uv.y) * texture.height;
let mouse_uv_x = x * uv_factor_x;
let mouse_uv_y = y * uv_factor_y;
let truncated_x = x;
let truncated_y = y;
if (Condition(Toolbox.selected.brush.floor_coordinates)) {
offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0 : 0.5;
x = Math.round(x + offset) - offset;
y = Math.round(y + offset) - offset;
truncated_x = Math.round(x + offset) - offset;
truncated_y = Math.round(y + offset) - offset;
}
if (texture.currentFrame) {
y -= texture.display_height * texture.currentFrame;
truncated_y -= texture.display_height * texture.currentFrame;
}
// Position
let brush_matrix = face.TexelToLocalMatrix([mouse_uv_x, mouse_uv_y], face.getSortedVertices(), offset);
let brush_matrix = face.texelToLocalMatrix([x * uv_factor_x, y * uv_factor_y], [uv_factor_x, uv_factor_y], [truncated_x * uv_factor_x, truncated_y * uv_factor_y]);
let brush_coord = new THREE.Vector3().setFromMatrixPosition(brush_matrix);
intersect.object.localToWorld(brush_coord);
if (!Format.centered_grid) {
@ -1104,7 +1106,7 @@ class Preview {
brush_coord.z += 8;
}
// z fighting
// Z-fighting
let z_fight_offset = Preview.selected.calculateControlScale(brush_coord) / 8;
let camera_direction = Preview.selected.camera.getWorldDirection(Reusable.vec2);
if (camera_direction.angleTo(world_normal) < Math.PI / 2) {
@ -1115,7 +1117,7 @@ class Preview {
let matrix_offset = new THREE.Matrix4().makeTranslation(z_offset.x, z_offset.y, z_offset.z);
brush_matrix.multiplyMatrices(matrix_offset, brush_matrix);
//size
// Size
let brush_scale = new THREE.Vector3().setFromMatrixScale(brush_matrix);
let radius_x = BarItems.slider_brush_size.get() * (1+z_fight_offset) * brush_scale.x;
let radius_y = BarItems.slider_brush_size.get() * (1+z_fight_offset) * brush_scale.y;

View File

@ -858,12 +858,6 @@
"about.version": "Version:",
"about.version.up_to_date": "Up to date",
"about.version.update_available": "Version %0 is available",
"about.creator": "Creator:",
"about.website": "Website:",
"about.repository": "Repository:",
"about.vertex_snap": "Vertex Snapping is based on a plugin by SirBenet",
"about.icons": "Icon Packs:",
"about.libraries": "Libraries:",
"settings_profile.confirm_delete": "Are you sure you want to delete this settings profile?",
"settings_profile.condition": "Condition",
@ -1236,6 +1230,7 @@
"action.vertex_snap_mode.desc": "Select if Vertex Snap moves elements to the selected position or resizes them",
"action.vertex_snap_mode.move": "Move",
"action.vertex_snap_mode.scale": "Scale",
"action.vertex_snap_mode.rotate": "Rotate",
"action.move_tool": "Move",
"action.move_tool.desc": "Tool to select and move elements",
@ -2190,6 +2185,11 @@
"edit.extrude_mesh_selection.direction.average": "Average",
"edit.extrude_mesh_selection.even_extend": "Even Extend",
"edit.solidify_mesh_selection.thickness": "Thickness",
"edit.vertex_snap.align": "Align",
"edit.vertex_snap.align.longest": "Longest Axis",
"edit.vertex_snap.align.direction": "Direction from Pivot",
"edit.vertex_snap.align.align_axis": "%0 Axis",
"edit.vertex_snap.ignore_axis": "Ignore %0 Axis",
"web.download_app": "Download App",