@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.mjs
CHANGED
|
@@ -1841,8 +1841,58 @@ var HAIR_FRONT_DEPTH = 0.1;
|
|
|
1841
1841
|
var HAIR_BACK_DEPTH = -0.08;
|
|
1842
1842
|
var NOD_TRAVEL = 30;
|
|
1843
1843
|
var NOD_BEND = 0.5;
|
|
1844
|
-
var HAIR_BACK_NOD_DEPTH = -0.
|
|
1844
|
+
var HAIR_BACK_NOD_DEPTH = -0.135;
|
|
1845
|
+
function headNodParallaxUnit(gridHalfHeight) {
|
|
1846
|
+
return gridHalfHeight * HEAD_CYLINDER_RADIUS_FACTOR * Math.sin(HEAD_TURN_MAX_DEG * NOD_BEND * (Math.PI / 180));
|
|
1847
|
+
}
|
|
1848
|
+
var FEATURE_DEPTH = {
|
|
1849
|
+
eye: 0.04,
|
|
1850
|
+
iris: 0.04,
|
|
1851
|
+
pupil: 0.04,
|
|
1852
|
+
highlight: 0.04,
|
|
1853
|
+
lash: 0.04,
|
|
1854
|
+
brow: 0.04,
|
|
1855
|
+
blush: 0.04,
|
|
1856
|
+
mouth: 0.04,
|
|
1857
|
+
mouth_open: 0.04,
|
|
1858
|
+
nose: 0.08
|
|
1859
|
+
};
|
|
1860
|
+
var HAIR_FRONT_NOD_DEPTH = FEATURE_DEPTH.brow;
|
|
1861
|
+
function roleFamily(role) {
|
|
1862
|
+
return role.replace(/_[LR]$/, "");
|
|
1863
|
+
}
|
|
1864
|
+
function featureParallaxBindings(role, options) {
|
|
1865
|
+
if (!options.hasNose) return [];
|
|
1866
|
+
const depth = FEATURE_DEPTH[roleFamily(role)];
|
|
1867
|
+
if (depth === void 0) return [];
|
|
1868
|
+
const bindings = [];
|
|
1869
|
+
const shiftX = depth * (options.parallaxUnit ?? 0);
|
|
1870
|
+
if (shiftX !== 0) {
|
|
1871
|
+
bindings.push({
|
|
1872
|
+
parameter: StandardParameter.AngleX,
|
|
1873
|
+
channel: "translateX",
|
|
1874
|
+
from: -shiftX,
|
|
1875
|
+
to: shiftX
|
|
1876
|
+
});
|
|
1877
|
+
}
|
|
1878
|
+
const shiftY = depth * (options.parallaxUnitY ?? 0);
|
|
1879
|
+
if (shiftY !== 0) {
|
|
1880
|
+
bindings.push({
|
|
1881
|
+
parameter: StandardParameter.AngleY,
|
|
1882
|
+
channel: "translateY",
|
|
1883
|
+
from: -shiftY,
|
|
1884
|
+
to: shiftY
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1887
|
+
return bindings;
|
|
1888
|
+
}
|
|
1845
1889
|
function bindingsForRole(spec, role, cropW, cropH, options = {}) {
|
|
1890
|
+
return [
|
|
1891
|
+
...roleOwnBindings(spec, role, cropW, cropH, options),
|
|
1892
|
+
...featureParallaxBindings(role, options)
|
|
1893
|
+
];
|
|
1894
|
+
}
|
|
1895
|
+
function roleOwnBindings(spec, role, cropW, cropH, options) {
|
|
1846
1896
|
const isEyeStack = EYE_STACK_PREFIXES.some((p) => role.startsWith(p));
|
|
1847
1897
|
if (isEyeStack && spec.eyeSide !== void 0) {
|
|
1848
1898
|
const isGazeRole = role.startsWith("iris_") || role.startsWith("pupil_") || role.startsWith("highlight_");
|
|
@@ -1956,7 +2006,8 @@ function bindingsForRole(spec, role, cropW, cropH, options = {}) {
|
|
|
1956
2006
|
});
|
|
1957
2007
|
}
|
|
1958
2008
|
}
|
|
1959
|
-
const
|
|
2009
|
+
const frontDepth = options.hasNose ? HAIR_FRONT_NOD_DEPTH : 0;
|
|
2010
|
+
const shiftY = (isFront ? frontDepth : HAIR_BACK_NOD_DEPTH) * (options.parallaxUnitY ?? 0);
|
|
1960
2011
|
if (shiftY !== 0) {
|
|
1961
2012
|
parallax.push({
|
|
1962
2013
|
parameter: StandardParameter.AngleY,
|
|
@@ -2001,14 +2052,18 @@ function bakeHairBackTurnWarp(mesh, parameter) {
|
|
|
2001
2052
|
const radius = halfWidth * HAIR_BACK_BEND_RADIUS_FACTOR;
|
|
2002
2053
|
const bulge = HAIR_BACK_FAR_BULGE * halfWidth;
|
|
2003
2054
|
const DEG_TO_RAD = Math.PI / 180;
|
|
2004
|
-
const keyforms =
|
|
2055
|
+
const keyforms = HEAD_TURN_STOPS.map((deg) => {
|
|
2005
2056
|
const theta = deg * DEG_TO_RAD;
|
|
2006
2057
|
const s = Math.sign(deg);
|
|
2058
|
+
const turnFraction = Math.abs(deg) / HEAD_TURN_MAX_DEG;
|
|
2059
|
+
const fullTheta = s * HEAD_TURN_MAX_DEG * DEG_TO_RAD;
|
|
2060
|
+
const bulgeAtStop = bulge * deg / HEAD_TURN_MAX_DEG;
|
|
2007
2061
|
const offsets = [];
|
|
2008
2062
|
for (let i = 0; i < mesh.vertices.length; i += 2) {
|
|
2009
2063
|
const x = mesh.vertices[i];
|
|
2010
2064
|
const far = Math.max(0, -s * x / halfWidth);
|
|
2011
|
-
|
|
2065
|
+
const bend = far > 0 ? turnFraction * pinnedCylinderBend(x, radius, fullTheta) : pinnedCylinderBend(x, radius, theta);
|
|
2066
|
+
offsets.push(bend - bulgeAtStop * far, 0);
|
|
2012
2067
|
}
|
|
2013
2068
|
return { value: deg, offsets };
|
|
2014
2069
|
});
|
|
@@ -2048,6 +2103,7 @@ function generateIkiFromLayerSet(layers, canvas) {
|
|
|
2048
2103
|
validateLayerInputs(layers, canvas);
|
|
2049
2104
|
const hasHair = layers.some((l) => l.role === "hair_front");
|
|
2050
2105
|
const hasMouthOpen = layers.some((l) => l.role === "mouth_open");
|
|
2106
|
+
const hasNose = layers.some((l) => l.role === "nose");
|
|
2051
2107
|
const bodyLayer = layers.find((l) => l.role === "body");
|
|
2052
2108
|
const parameters = [
|
|
2053
2109
|
{
|
|
@@ -2226,7 +2282,7 @@ function generateIkiFromLayerSet(layers, canvas) {
|
|
|
2226
2282
|
const faceCenterY = faceTransform.y;
|
|
2227
2283
|
const halfH = Math.max(faceCenterY - unionMinY, unionMaxY - faceCenterY);
|
|
2228
2284
|
const parallaxUnit = headTurnParallaxUnit(halfW);
|
|
2229
|
-
const parallaxUnitY =
|
|
2285
|
+
const parallaxUnitY = headNodParallaxUnit(halfH);
|
|
2230
2286
|
const faceBottom = faceTransform.y - faceCropH / 2;
|
|
2231
2287
|
const neckPivot = {
|
|
2232
2288
|
x: faceCenterX,
|
|
@@ -2347,7 +2403,8 @@ function generateIkiFromLayerSet(layers, canvas) {
|
|
|
2347
2403
|
const roleBindings = bindingsForRole(spec, role, cropW, cropH, {
|
|
2348
2404
|
hasMouthOpen,
|
|
2349
2405
|
parallaxUnit,
|
|
2350
|
-
parallaxUnitY
|
|
2406
|
+
parallaxUnitY,
|
|
2407
|
+
hasNose
|
|
2351
2408
|
});
|
|
2352
2409
|
const deformerId = spec.deformer === "none" ? void 0 : spec.deformer;
|
|
2353
2410
|
if (spec.mesh) {
|