@ikijs/editor 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +63 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1900,8 +1900,58 @@ var HAIR_FRONT_DEPTH = 0.1;
|
|
|
1900
1900
|
var HAIR_BACK_DEPTH = -0.08;
|
|
1901
1901
|
var NOD_TRAVEL = 30;
|
|
1902
1902
|
var NOD_BEND = 0.5;
|
|
1903
|
-
var HAIR_BACK_NOD_DEPTH = -0.
|
|
1903
|
+
var HAIR_BACK_NOD_DEPTH = -0.135;
|
|
1904
|
+
function headNodParallaxUnit(gridHalfHeight) {
|
|
1905
|
+
return gridHalfHeight * HEAD_CYLINDER_RADIUS_FACTOR * Math.sin(HEAD_TURN_MAX_DEG * NOD_BEND * (Math.PI / 180));
|
|
1906
|
+
}
|
|
1907
|
+
var FEATURE_DEPTH = {
|
|
1908
|
+
eye: 0.04,
|
|
1909
|
+
iris: 0.04,
|
|
1910
|
+
pupil: 0.04,
|
|
1911
|
+
highlight: 0.04,
|
|
1912
|
+
lash: 0.04,
|
|
1913
|
+
brow: 0.04,
|
|
1914
|
+
blush: 0.04,
|
|
1915
|
+
mouth: 0.04,
|
|
1916
|
+
mouth_open: 0.04,
|
|
1917
|
+
nose: 0.08
|
|
1918
|
+
};
|
|
1919
|
+
var HAIR_FRONT_NOD_DEPTH = FEATURE_DEPTH.brow;
|
|
1920
|
+
function roleFamily(role) {
|
|
1921
|
+
return role.replace(/_[LR]$/, "");
|
|
1922
|
+
}
|
|
1923
|
+
function featureParallaxBindings(role, options) {
|
|
1924
|
+
if (!options.hasNose) return [];
|
|
1925
|
+
const depth = FEATURE_DEPTH[roleFamily(role)];
|
|
1926
|
+
if (depth === void 0) return [];
|
|
1927
|
+
const bindings = [];
|
|
1928
|
+
const shiftX = depth * (options.parallaxUnit ?? 0);
|
|
1929
|
+
if (shiftX !== 0) {
|
|
1930
|
+
bindings.push({
|
|
1931
|
+
parameter: import_format3.StandardParameter.AngleX,
|
|
1932
|
+
channel: "translateX",
|
|
1933
|
+
from: -shiftX,
|
|
1934
|
+
to: shiftX
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
const shiftY = depth * (options.parallaxUnitY ?? 0);
|
|
1938
|
+
if (shiftY !== 0) {
|
|
1939
|
+
bindings.push({
|
|
1940
|
+
parameter: import_format3.StandardParameter.AngleY,
|
|
1941
|
+
channel: "translateY",
|
|
1942
|
+
from: -shiftY,
|
|
1943
|
+
to: shiftY
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1946
|
+
return bindings;
|
|
1947
|
+
}
|
|
1904
1948
|
function bindingsForRole(spec, role, cropW, cropH, options = {}) {
|
|
1949
|
+
return [
|
|
1950
|
+
...roleOwnBindings(spec, role, cropW, cropH, options),
|
|
1951
|
+
...featureParallaxBindings(role, options)
|
|
1952
|
+
];
|
|
1953
|
+
}
|
|
1954
|
+
function roleOwnBindings(spec, role, cropW, cropH, options) {
|
|
1905
1955
|
const isEyeStack = EYE_STACK_PREFIXES.some((p) => role.startsWith(p));
|
|
1906
1956
|
if (isEyeStack && spec.eyeSide !== void 0) {
|
|
1907
1957
|
const isGazeRole = role.startsWith("iris_") || role.startsWith("pupil_") || role.startsWith("highlight_");
|
|
@@ -2015,7 +2065,8 @@ function bindingsForRole(spec, role, cropW, cropH, options = {}) {
|
|
|
2015
2065
|
});
|
|
2016
2066
|
}
|
|
2017
2067
|
}
|
|
2018
|
-
const
|
|
2068
|
+
const frontDepth = options.hasNose ? HAIR_FRONT_NOD_DEPTH : 0;
|
|
2069
|
+
const shiftY = (isFront ? frontDepth : HAIR_BACK_NOD_DEPTH) * (options.parallaxUnitY ?? 0);
|
|
2019
2070
|
if (shiftY !== 0) {
|
|
2020
2071
|
parallax.push({
|
|
2021
2072
|
parameter: import_format3.StandardParameter.AngleY,
|
|
@@ -2060,14 +2111,18 @@ function bakeHairBackTurnWarp(mesh, parameter) {
|
|
|
2060
2111
|
const radius = halfWidth * HAIR_BACK_BEND_RADIUS_FACTOR;
|
|
2061
2112
|
const bulge = HAIR_BACK_FAR_BULGE * halfWidth;
|
|
2062
2113
|
const DEG_TO_RAD = Math.PI / 180;
|
|
2063
|
-
const keyforms =
|
|
2114
|
+
const keyforms = HEAD_TURN_STOPS.map((deg) => {
|
|
2064
2115
|
const theta = deg * DEG_TO_RAD;
|
|
2065
2116
|
const s = Math.sign(deg);
|
|
2117
|
+
const turnFraction = Math.abs(deg) / HEAD_TURN_MAX_DEG;
|
|
2118
|
+
const fullTheta = s * HEAD_TURN_MAX_DEG * DEG_TO_RAD;
|
|
2119
|
+
const bulgeAtStop = bulge * deg / HEAD_TURN_MAX_DEG;
|
|
2066
2120
|
const offsets = [];
|
|
2067
2121
|
for (let i = 0; i < mesh.vertices.length; i += 2) {
|
|
2068
2122
|
const x = mesh.vertices[i];
|
|
2069
2123
|
const far = Math.max(0, -s * x / halfWidth);
|
|
2070
|
-
|
|
2124
|
+
const bend = far > 0 ? turnFraction * pinnedCylinderBend(x, radius, fullTheta) : pinnedCylinderBend(x, radius, theta);
|
|
2125
|
+
offsets.push(bend - bulgeAtStop * far, 0);
|
|
2071
2126
|
}
|
|
2072
2127
|
return { value: deg, offsets };
|
|
2073
2128
|
});
|
|
@@ -2107,6 +2162,7 @@ function generateIkiFromLayerSet(layers, canvas) {
|
|
|
2107
2162
|
validateLayerInputs(layers, canvas);
|
|
2108
2163
|
const hasHair = layers.some((l) => l.role === "hair_front");
|
|
2109
2164
|
const hasMouthOpen = layers.some((l) => l.role === "mouth_open");
|
|
2165
|
+
const hasNose = layers.some((l) => l.role === "nose");
|
|
2110
2166
|
const bodyLayer = layers.find((l) => l.role === "body");
|
|
2111
2167
|
const parameters = [
|
|
2112
2168
|
{
|
|
@@ -2285,7 +2341,7 @@ function generateIkiFromLayerSet(layers, canvas) {
|
|
|
2285
2341
|
const faceCenterY = faceTransform.y;
|
|
2286
2342
|
const halfH = Math.max(faceCenterY - unionMinY, unionMaxY - faceCenterY);
|
|
2287
2343
|
const parallaxUnit = headTurnParallaxUnit(halfW);
|
|
2288
|
-
const parallaxUnitY =
|
|
2344
|
+
const parallaxUnitY = headNodParallaxUnit(halfH);
|
|
2289
2345
|
const faceBottom = faceTransform.y - faceCropH / 2;
|
|
2290
2346
|
const neckPivot = {
|
|
2291
2347
|
x: faceCenterX,
|
|
@@ -2406,7 +2462,8 @@ function generateIkiFromLayerSet(layers, canvas) {
|
|
|
2406
2462
|
const roleBindings = bindingsForRole(spec, role, cropW, cropH, {
|
|
2407
2463
|
hasMouthOpen,
|
|
2408
2464
|
parallaxUnit,
|
|
2409
|
-
parallaxUnitY
|
|
2465
|
+
parallaxUnitY,
|
|
2466
|
+
hasNose
|
|
2410
2467
|
});
|
|
2411
2468
|
const deformerId = spec.deformer === "none" ? void 0 : spec.deformer;
|
|
2412
2469
|
if (spec.mesh) {
|