@mml-io/3d-web-client-core 0.23.2 → 0.23.3
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.
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Color,
|
1
|
+
import { Color, Object3D } from "three";
|
2
2
|
import { ColorPartName } from "../CharacterModel";
|
3
3
|
import { InstancedMesh2 } from "./vendor/";
|
4
4
|
export type ColorSamplingOptions = {
|
@@ -9,6 +9,6 @@ export type ColorSamplingOptions = {
|
|
9
9
|
};
|
10
10
|
debug?: boolean;
|
11
11
|
};
|
12
|
-
export declare function captureCharacterColors(characterMesh:
|
12
|
+
export declare function captureCharacterColors(characterMesh: Object3D, options: ColorSamplingOptions): Map<ColorPartName, Color>;
|
13
13
|
export declare function captureCharacterColorsFromObject3D(object3D: Object3D, options: ColorSamplingOptions): Map<ColorPartName, Color>;
|
14
14
|
export declare function updateDebugTextureCanvas(instancedMesh: InstancedMesh2): void;
|
package/build/index.js
CHANGED
@@ -1407,7 +1407,7 @@ import {
|
|
1407
1407
|
Group,
|
1408
1408
|
LoopRepeat,
|
1409
1409
|
Mesh,
|
1410
|
-
SkinnedMesh as
|
1410
|
+
SkinnedMesh as SkinnedMesh2,
|
1411
1411
|
Vector3 as Vector33
|
1412
1412
|
} from "three";
|
1413
1413
|
|
@@ -1506,6 +1506,7 @@ ${before}
|
|
1506
1506
|
|
1507
1507
|
// src/tweakpane/blades/characterFolder.ts
|
1508
1508
|
var characterValues = {
|
1509
|
+
overrideMaterialParams: false,
|
1509
1510
|
metalness: 0.2,
|
1510
1511
|
roughness: 0.8,
|
1511
1512
|
emissive: { r: 1, g: 1, b: 1 },
|
@@ -1520,25 +1521,45 @@ var characterOptions = {
|
|
1520
1521
|
};
|
1521
1522
|
var CharacterFolder = class {
|
1522
1523
|
folder;
|
1524
|
+
materialParamsFolder;
|
1523
1525
|
constructor(parentFolder, expand = false) {
|
1524
1526
|
this.folder = parentFolder.addFolder({ title: "characterMaterial", expanded: expand });
|
1525
|
-
this.folder.addBinding(characterValues, "
|
1526
|
-
|
1527
|
-
|
1527
|
+
this.folder.addBinding(characterValues, "overrideMaterialParams", {
|
1528
|
+
label: "override material params"
|
1529
|
+
});
|
1530
|
+
this.materialParamsFolder = this.folder.addFolder({
|
1531
|
+
title: "Material Parameters",
|
1532
|
+
expanded: true
|
1533
|
+
});
|
1534
|
+
this.materialParamsFolder.addBinding(characterValues, "metalness", characterOptions.metalness);
|
1535
|
+
this.materialParamsFolder.addBinding(characterValues, "roughness", characterOptions.roughness);
|
1536
|
+
this.materialParamsFolder.addBinding(characterValues, "emissive", {
|
1528
1537
|
color: { type: "float" }
|
1529
1538
|
});
|
1530
|
-
this.
|
1539
|
+
this.materialParamsFolder.addBinding(
|
1531
1540
|
characterValues,
|
1532
1541
|
"emissiveIntensity",
|
1533
1542
|
characterOptions.emissiveIntensity
|
1534
1543
|
);
|
1535
|
-
this.
|
1544
|
+
this.materialParamsFolder.addBinding(
|
1545
|
+
characterValues,
|
1546
|
+
"envMapIntensity",
|
1547
|
+
characterOptions.envMapIntensity
|
1548
|
+
);
|
1549
|
+
this.updateMaterialParamsVisibility();
|
1550
|
+
}
|
1551
|
+
updateMaterialParamsVisibility() {
|
1552
|
+
this.materialParamsFolder.hidden = !characterValues.overrideMaterialParams;
|
1536
1553
|
}
|
1537
1554
|
setupChangeEvent() {
|
1538
1555
|
this.folder.on("change", (e) => {
|
1539
1556
|
const target = e.target.key;
|
1540
1557
|
if (!target) return;
|
1541
1558
|
switch (target) {
|
1559
|
+
case "overrideMaterialParams": {
|
1560
|
+
this.updateMaterialParamsVisibility();
|
1561
|
+
break;
|
1562
|
+
}
|
1542
1563
|
case "emissive": {
|
1543
1564
|
const value = e.value;
|
1544
1565
|
characterValues.emissive = {
|
@@ -1666,15 +1687,17 @@ var CharacterMaterial = class extends MeshStandardMaterial {
|
|
1666
1687
|
this.opacity = this.currentAlpha;
|
1667
1688
|
}
|
1668
1689
|
}
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1690
|
+
if (characterValues.overrideMaterialParams) {
|
1691
|
+
this.metalness = characterValues.metalness;
|
1692
|
+
this.roughness = characterValues.roughness;
|
1693
|
+
this.emissive = new Color().setRGB(
|
1694
|
+
characterValues.emissive.r,
|
1695
|
+
characterValues.emissive.g,
|
1696
|
+
characterValues.emissive.b
|
1697
|
+
);
|
1698
|
+
this.emissiveIntensity = characterValues.emissiveIntensity;
|
1699
|
+
this.envMapIntensity = characterValues.envMapIntensity;
|
1700
|
+
}
|
1678
1701
|
}
|
1679
1702
|
};
|
1680
1703
|
|
@@ -1698,155 +1721,13 @@ import {
|
|
1698
1721
|
Color as Color2,
|
1699
1722
|
OrthographicCamera,
|
1700
1723
|
Scene,
|
1701
|
-
SkinnedMesh
|
1724
|
+
SkinnedMesh,
|
1702
1725
|
Vector2,
|
1703
1726
|
Vector3 as Vector32,
|
1704
1727
|
WebGLRenderer,
|
1705
1728
|
WebGLRenderTarget
|
1706
1729
|
} from "three";
|
1707
1730
|
import * as SkeletonUtils from "three/examples/jsm/utils/SkeletonUtils.js";
|
1708
|
-
|
1709
|
-
// src/character/instancing/CharacterInstancingUtils.ts
|
1710
|
-
import { BufferAttribute, SkinnedMesh } from "three";
|
1711
|
-
import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
|
1712
|
-
function mergeSkinnedMeshes(skinnedMeshes, debug) {
|
1713
|
-
const geometries = [];
|
1714
|
-
const materials = [];
|
1715
|
-
const skeleton = skinnedMeshes[0].skeleton;
|
1716
|
-
for (const skinnedMesh of skinnedMeshes) {
|
1717
|
-
const geometry = skinnedMesh.geometry.clone();
|
1718
|
-
const materialIndex = materials.length;
|
1719
|
-
if (Array.isArray(skinnedMesh.material)) {
|
1720
|
-
materials.push(...skinnedMesh.material);
|
1721
|
-
for (let i = 0; i < skinnedMesh.material.length; i++) {
|
1722
|
-
geometry.addGroup(
|
1723
|
-
0,
|
1724
|
-
geometry.index ? geometry.index.count : geometry.attributes.position.count,
|
1725
|
-
materialIndex + i
|
1726
|
-
);
|
1727
|
-
}
|
1728
|
-
} else {
|
1729
|
-
materials.push(skinnedMesh.material);
|
1730
|
-
geometry.addGroup(
|
1731
|
-
0,
|
1732
|
-
geometry.index ? geometry.index.count : geometry.attributes.position.count,
|
1733
|
-
materialIndex
|
1734
|
-
);
|
1735
|
-
}
|
1736
|
-
geometries.push(geometry);
|
1737
|
-
}
|
1738
|
-
const mergedGeometry = BufferGeometryUtils.mergeGeometries(geometries, true);
|
1739
|
-
if (!mergedGeometry) {
|
1740
|
-
throw new Error("Failed to merge geometries");
|
1741
|
-
}
|
1742
|
-
const mergedMesh = new SkinnedMesh(mergedGeometry, materials);
|
1743
|
-
mergedMesh.skeleton = skeleton;
|
1744
|
-
mergedMesh.bindMatrix.copy(skinnedMeshes[0].bindMatrix);
|
1745
|
-
mergedMesh.bindMatrixInverse.copy(skinnedMeshes[0].bindMatrixInverse);
|
1746
|
-
mergedMesh.bind(skeleton, mergedMesh.bindMatrix);
|
1747
|
-
if (debug) {
|
1748
|
-
console.log(`Merged into single mesh with ${materials.length} materials`);
|
1749
|
-
}
|
1750
|
-
addVertexColorsToGeometry(mergedGeometry, materials, debug);
|
1751
|
-
return mergedMesh;
|
1752
|
-
}
|
1753
|
-
function validateAndCleanSkeleton(skinnedMesh) {
|
1754
|
-
const skeleton = skinnedMesh.skeleton;
|
1755
|
-
const nullBoneIndices = [];
|
1756
|
-
for (let i = 0; i < skeleton.bones.length; i++) {
|
1757
|
-
if (!skeleton.bones[i]) {
|
1758
|
-
nullBoneIndices.push(i);
|
1759
|
-
}
|
1760
|
-
}
|
1761
|
-
if (nullBoneIndices.length > 0) {
|
1762
|
-
skeleton.bones = skeleton.bones.filter((bone) => bone !== null && bone !== void 0);
|
1763
|
-
skeleton.update();
|
1764
|
-
}
|
1765
|
-
}
|
1766
|
-
function addVertexColorsToGeometry(geometry, materials, debug) {
|
1767
|
-
const positionAttribute = geometry.getAttribute("position");
|
1768
|
-
if (!positionAttribute) {
|
1769
|
-
console.error("No position attribute found in geometry");
|
1770
|
-
return;
|
1771
|
-
}
|
1772
|
-
const vertexCount = positionAttribute.count;
|
1773
|
-
if (debug) {
|
1774
|
-
console.log(`Geometry has ${vertexCount} vertices`);
|
1775
|
-
}
|
1776
|
-
const colors = new Float32Array(vertexCount * 3);
|
1777
|
-
for (let i = 0; i < vertexCount; i++) {
|
1778
|
-
colors[i * 3] = 1;
|
1779
|
-
colors[i * 3 + 1] = 1;
|
1780
|
-
colors[i * 3 + 2] = 1;
|
1781
|
-
}
|
1782
|
-
const materialColorCodes = {
|
1783
|
-
// bin material IDs to be replaced by the final colors on the GPU
|
1784
|
-
hair: [0, 0, 0],
|
1785
|
-
shirt_short: [0, 0, 1],
|
1786
|
-
shirt_long: [0, 1, 0],
|
1787
|
-
pants_short: [0, 1, 1],
|
1788
|
-
pants_long: [1, 0, 0],
|
1789
|
-
shoes: [1, 0, 1],
|
1790
|
-
skin: [1, 1, 0],
|
1791
|
-
lips: [1, 1, 1],
|
1792
|
-
eyes_black: [0.5, 0, 0],
|
1793
|
-
eyes_white: [0, 0.5, 0]
|
1794
|
-
};
|
1795
|
-
if (debug) {
|
1796
|
-
console.log("Geometry groups:", geometry.groups);
|
1797
|
-
console.log(
|
1798
|
-
"Materials:",
|
1799
|
-
materials.map((m) => m.name)
|
1800
|
-
);
|
1801
|
-
}
|
1802
|
-
if (geometry.groups && geometry.groups.length > 0) {
|
1803
|
-
geometry.groups.forEach((group, groupIndex) => {
|
1804
|
-
const material = materials[group.materialIndex || groupIndex];
|
1805
|
-
const materialName = (material == null ? void 0 : material.name) || `material_${groupIndex}`;
|
1806
|
-
if (debug) {
|
1807
|
-
console.log(
|
1808
|
-
`Processing group ${groupIndex}: material "${materialName}", start: ${group.start}, count: ${group.count}`
|
1809
|
-
);
|
1810
|
-
}
|
1811
|
-
const materialColor = materialColorCodes[materialName] || [
|
1812
|
-
1,
|
1813
|
-
1,
|
1814
|
-
1
|
1815
|
-
];
|
1816
|
-
if (debug) {
|
1817
|
-
console.log(
|
1818
|
-
`Using ID color [${materialColor.join(", ")}] for material "${materialName}" (${materialColor[0] === 1 && materialColor[1] === 1 && materialColor[2] === 0 ? "YELLOW=SKIN" : materialColor[0] === 0 && materialColor[1] === 0 && materialColor[2] === 1 ? "BLUE=SHIRT" : "OTHER"})`
|
1819
|
-
);
|
1820
|
-
}
|
1821
|
-
const indexAttribute = geometry.getIndex();
|
1822
|
-
if (indexAttribute) {
|
1823
|
-
for (let i = group.start; i < group.start + group.count; i++) {
|
1824
|
-
const vertexIndex = indexAttribute.getX(i);
|
1825
|
-
colors[vertexIndex * 3] = materialColor[0];
|
1826
|
-
colors[vertexIndex * 3 + 1] = materialColor[1];
|
1827
|
-
colors[vertexIndex * 3 + 2] = materialColor[2];
|
1828
|
-
}
|
1829
|
-
} else {
|
1830
|
-
const startVertex = group.start / 3;
|
1831
|
-
const vertexCount2 = group.count / 3;
|
1832
|
-
for (let i = 0; i < vertexCount2; i++) {
|
1833
|
-
const vertexIndex = startVertex + i;
|
1834
|
-
colors[vertexIndex * 3] = materialColor[0];
|
1835
|
-
colors[vertexIndex * 3 + 1] = materialColor[1];
|
1836
|
-
colors[vertexIndex * 3 + 2] = materialColor[2];
|
1837
|
-
}
|
1838
|
-
}
|
1839
|
-
});
|
1840
|
-
} else {
|
1841
|
-
console.warn("No geometry groups found, using single material coloring");
|
1842
|
-
}
|
1843
|
-
geometry.setAttribute("color", new BufferAttribute(colors, 3));
|
1844
|
-
if (debug) {
|
1845
|
-
console.log(`Added per-material vertex colors to ${vertexCount} vertices`);
|
1846
|
-
}
|
1847
|
-
}
|
1848
|
-
|
1849
|
-
// src/character/instancing/CharacterColourSamplingUtils.ts
|
1850
1731
|
function listAllBoneNames(obj) {
|
1851
1732
|
const boneNames = [];
|
1852
1733
|
if (!obj) {
|
@@ -1997,26 +1878,14 @@ function captureCharacterColorsFromObject3D(object3D, options) {
|
|
1997
1878
|
clone3.scale.set(1, 1, 1);
|
1998
1879
|
const skinnedMeshes = [];
|
1999
1880
|
clone3.traverse((child) => {
|
2000
|
-
if (child instanceof
|
2001
|
-
|
1881
|
+
if (child instanceof SkinnedMesh || child.isSkinnedMesh) {
|
1882
|
+
const skinnedMesh = child;
|
1883
|
+
skinnedMesh.skeleton.pose();
|
1884
|
+
skinnedMesh.skeleton.update();
|
1885
|
+
skinnedMesh.updateMatrixWorld(true);
|
2002
1886
|
}
|
2003
1887
|
});
|
2004
|
-
|
2005
|
-
console.warn("No SkinnedMesh objects found in Object3D hierarchy");
|
2006
|
-
return /* @__PURE__ */ new Map();
|
2007
|
-
}
|
2008
|
-
let skinnedMesh;
|
2009
|
-
if (skinnedMeshes.length === 1) {
|
2010
|
-
skinnedMesh = skinnedMeshes[0];
|
2011
|
-
} else {
|
2012
|
-
skinnedMesh = mergeSkinnedMeshes(skinnedMeshes);
|
2013
|
-
}
|
2014
|
-
const skeleton = skinnedMesh.skeleton;
|
2015
|
-
skeleton.pose();
|
2016
|
-
skeleton.update();
|
2017
|
-
skinnedMesh.updateMatrixWorld(true);
|
2018
|
-
validateAndCleanSkeleton(skinnedMesh);
|
2019
|
-
return captureCharacterColors(skinnedMesh, options);
|
1888
|
+
return captureCharacterColors(object3D, options);
|
2020
1889
|
}
|
2021
1890
|
function findBoneCenter(bone) {
|
2022
1891
|
const boneStart = new Vector32();
|
@@ -2031,9 +1900,20 @@ function findBoneCenter(bone) {
|
|
2031
1900
|
}
|
2032
1901
|
function getBoneRegionsForColorSampling(characterMesh, camera, renderSize, circularSamplingRadius, topDownSamplingSize, debug) {
|
2033
1902
|
const regions = [];
|
1903
|
+
let firstSkinnedMesh = null;
|
1904
|
+
characterMesh.traverse((child) => {
|
1905
|
+
if (!firstSkinnedMesh && (child instanceof SkinnedMesh || child.isSkinnedMesh)) {
|
1906
|
+
firstSkinnedMesh = child;
|
1907
|
+
}
|
1908
|
+
});
|
1909
|
+
if (!firstSkinnedMesh) {
|
1910
|
+
console.warn("No SkinnedMesh objects found in Object3D hierarchy");
|
1911
|
+
return regions;
|
1912
|
+
}
|
1913
|
+
const skinnedMesh = firstSkinnedMesh;
|
2034
1914
|
if (debug) {
|
2035
1915
|
console.log("Available bones:");
|
2036
|
-
console.table(listAllBoneNames(
|
1916
|
+
console.table(listAllBoneNames(skinnedMesh));
|
2037
1917
|
}
|
2038
1918
|
const boneTargets = [
|
2039
1919
|
{ name: "Face/Chin", boneName: "neck_02" },
|
@@ -2052,7 +1932,7 @@ function getBoneRegionsForColorSampling(characterMesh, camera, renderSize, circu
|
|
2052
1932
|
];
|
2053
1933
|
const screenPos = new Vector32();
|
2054
1934
|
for (const target of boneTargets) {
|
2055
|
-
const bone =
|
1935
|
+
const bone = skinnedMesh.skeleton.bones.find(
|
2056
1936
|
(child) => child.name === target.boneName
|
2057
1937
|
);
|
2058
1938
|
if (bone) {
|
@@ -2646,7 +2526,7 @@ var CharacterModel = class {
|
|
2646
2526
|
this.animationMixer = null;
|
2647
2527
|
}
|
2648
2528
|
(_a = this.mesh) == null ? void 0 : _a.traverse((child) => {
|
2649
|
-
if (child instanceof
|
2529
|
+
if (child instanceof SkinnedMesh2 || child.isSkinnedMesh) {
|
2650
2530
|
const asSkinnedMesh = child;
|
2651
2531
|
if (asSkinnedMesh.geometry) {
|
2652
2532
|
asSkinnedMesh.geometry.dispose();
|
@@ -3368,6 +3248,146 @@ function getTrackTypeFromName(trackName) {
|
|
3368
3248
|
return NumberKeyframeTrack;
|
3369
3249
|
}
|
3370
3250
|
|
3251
|
+
// src/character/instancing/CharacterInstancingUtils.ts
|
3252
|
+
import { BufferAttribute, SkinnedMesh as SkinnedMesh3 } from "three";
|
3253
|
+
import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
|
3254
|
+
function mergeSkinnedMeshes(skinnedMeshes, debug) {
|
3255
|
+
const geometries = [];
|
3256
|
+
const materials = [];
|
3257
|
+
const skeleton = skinnedMeshes[0].skeleton;
|
3258
|
+
for (const skinnedMesh of skinnedMeshes) {
|
3259
|
+
const geometry = skinnedMesh.geometry.clone();
|
3260
|
+
const materialIndex = materials.length;
|
3261
|
+
if (Array.isArray(skinnedMesh.material)) {
|
3262
|
+
materials.push(...skinnedMesh.material);
|
3263
|
+
for (let i = 0; i < skinnedMesh.material.length; i++) {
|
3264
|
+
geometry.addGroup(
|
3265
|
+
0,
|
3266
|
+
geometry.index ? geometry.index.count : geometry.attributes.position.count,
|
3267
|
+
materialIndex + i
|
3268
|
+
);
|
3269
|
+
}
|
3270
|
+
} else {
|
3271
|
+
materials.push(skinnedMesh.material);
|
3272
|
+
geometry.addGroup(
|
3273
|
+
0,
|
3274
|
+
geometry.index ? geometry.index.count : geometry.attributes.position.count,
|
3275
|
+
materialIndex
|
3276
|
+
);
|
3277
|
+
}
|
3278
|
+
geometries.push(geometry);
|
3279
|
+
}
|
3280
|
+
const mergedGeometry = BufferGeometryUtils.mergeGeometries(geometries, true);
|
3281
|
+
if (!mergedGeometry) {
|
3282
|
+
throw new Error("Failed to merge geometries");
|
3283
|
+
}
|
3284
|
+
const mergedMesh = new SkinnedMesh3(mergedGeometry, materials);
|
3285
|
+
mergedMesh.skeleton = skeleton;
|
3286
|
+
mergedMesh.bindMatrix.copy(skinnedMeshes[0].bindMatrix);
|
3287
|
+
mergedMesh.bindMatrixInverse.copy(skinnedMeshes[0].bindMatrixInverse);
|
3288
|
+
mergedMesh.bind(skeleton, mergedMesh.bindMatrix);
|
3289
|
+
if (debug) {
|
3290
|
+
console.log(`Merged into single mesh with ${materials.length} materials`);
|
3291
|
+
}
|
3292
|
+
addVertexColorsToGeometry(mergedGeometry, materials, debug);
|
3293
|
+
return mergedMesh;
|
3294
|
+
}
|
3295
|
+
function validateAndCleanSkeleton(skinnedMesh) {
|
3296
|
+
const skeleton = skinnedMesh.skeleton;
|
3297
|
+
const nullBoneIndices = [];
|
3298
|
+
for (let i = 0; i < skeleton.bones.length; i++) {
|
3299
|
+
if (!skeleton.bones[i]) {
|
3300
|
+
nullBoneIndices.push(i);
|
3301
|
+
}
|
3302
|
+
}
|
3303
|
+
if (nullBoneIndices.length > 0) {
|
3304
|
+
skeleton.bones = skeleton.bones.filter((bone) => bone !== null && bone !== void 0);
|
3305
|
+
skeleton.update();
|
3306
|
+
}
|
3307
|
+
}
|
3308
|
+
function addVertexColorsToGeometry(geometry, materials, debug) {
|
3309
|
+
const positionAttribute = geometry.getAttribute("position");
|
3310
|
+
if (!positionAttribute) {
|
3311
|
+
console.error("No position attribute found in geometry");
|
3312
|
+
return;
|
3313
|
+
}
|
3314
|
+
const vertexCount = positionAttribute.count;
|
3315
|
+
if (debug) {
|
3316
|
+
console.log(`Geometry has ${vertexCount} vertices`);
|
3317
|
+
}
|
3318
|
+
const colors = new Float32Array(vertexCount * 3);
|
3319
|
+
for (let i = 0; i < vertexCount; i++) {
|
3320
|
+
colors[i * 3] = 1;
|
3321
|
+
colors[i * 3 + 1] = 1;
|
3322
|
+
colors[i * 3 + 2] = 1;
|
3323
|
+
}
|
3324
|
+
const materialColorCodes = {
|
3325
|
+
// bin material IDs to be replaced by the final colors on the GPU
|
3326
|
+
hair: [0, 0, 0],
|
3327
|
+
shirt_short: [0, 0, 1],
|
3328
|
+
shirt_long: [0, 1, 0],
|
3329
|
+
pants_short: [0, 1, 1],
|
3330
|
+
pants_long: [1, 0, 0],
|
3331
|
+
shoes: [1, 0, 1],
|
3332
|
+
skin: [1, 1, 0],
|
3333
|
+
lips: [1, 1, 1],
|
3334
|
+
eyes_black: [0.5, 0, 0],
|
3335
|
+
eyes_white: [0, 0.5, 0]
|
3336
|
+
};
|
3337
|
+
if (debug) {
|
3338
|
+
console.log("Geometry groups:", geometry.groups);
|
3339
|
+
console.log(
|
3340
|
+
"Materials:",
|
3341
|
+
materials.map((m) => m.name)
|
3342
|
+
);
|
3343
|
+
}
|
3344
|
+
if (geometry.groups && geometry.groups.length > 0) {
|
3345
|
+
geometry.groups.forEach((group, groupIndex) => {
|
3346
|
+
const material = materials[group.materialIndex || groupIndex];
|
3347
|
+
const materialName = (material == null ? void 0 : material.name) || `material_${groupIndex}`;
|
3348
|
+
if (debug) {
|
3349
|
+
console.log(
|
3350
|
+
`Processing group ${groupIndex}: material "${materialName}", start: ${group.start}, count: ${group.count}`
|
3351
|
+
);
|
3352
|
+
}
|
3353
|
+
const materialColor = materialColorCodes[materialName] || [
|
3354
|
+
1,
|
3355
|
+
1,
|
3356
|
+
1
|
3357
|
+
];
|
3358
|
+
if (debug) {
|
3359
|
+
console.log(
|
3360
|
+
`Using ID color [${materialColor.join(", ")}] for material "${materialName}" (${materialColor[0] === 1 && materialColor[1] === 1 && materialColor[2] === 0 ? "YELLOW=SKIN" : materialColor[0] === 0 && materialColor[1] === 0 && materialColor[2] === 1 ? "BLUE=SHIRT" : "OTHER"})`
|
3361
|
+
);
|
3362
|
+
}
|
3363
|
+
const indexAttribute = geometry.getIndex();
|
3364
|
+
if (indexAttribute) {
|
3365
|
+
for (let i = group.start; i < group.start + group.count; i++) {
|
3366
|
+
const vertexIndex = indexAttribute.getX(i);
|
3367
|
+
colors[vertexIndex * 3] = materialColor[0];
|
3368
|
+
colors[vertexIndex * 3 + 1] = materialColor[1];
|
3369
|
+
colors[vertexIndex * 3 + 2] = materialColor[2];
|
3370
|
+
}
|
3371
|
+
} else {
|
3372
|
+
const startVertex = group.start / 3;
|
3373
|
+
const vertexCount2 = group.count / 3;
|
3374
|
+
for (let i = 0; i < vertexCount2; i++) {
|
3375
|
+
const vertexIndex = startVertex + i;
|
3376
|
+
colors[vertexIndex * 3] = materialColor[0];
|
3377
|
+
colors[vertexIndex * 3 + 1] = materialColor[1];
|
3378
|
+
colors[vertexIndex * 3 + 2] = materialColor[2];
|
3379
|
+
}
|
3380
|
+
}
|
3381
|
+
});
|
3382
|
+
} else {
|
3383
|
+
console.warn("No geometry groups found, using single material coloring");
|
3384
|
+
}
|
3385
|
+
geometry.setAttribute("color", new BufferAttribute(colors, 3));
|
3386
|
+
if (debug) {
|
3387
|
+
console.log(`Added per-material vertex colors to ${vertexCount} vertices`);
|
3388
|
+
}
|
3389
|
+
}
|
3390
|
+
|
3371
3391
|
// src/character/instancing/vendor/core/InstancedEntity.ts
|
3372
3392
|
import {
|
3373
3393
|
Euler,
|
@@ -9214,7 +9234,7 @@ var sunValues = {
|
|
9214
9234
|
var sunOptions = {
|
9215
9235
|
sunPosition: {
|
9216
9236
|
sunAzimuthalAngle: { min: 0, max: 360, step: 1 },
|
9217
|
-
sunPolarAngle: { min: -
|
9237
|
+
sunPolarAngle: { min: -95, max: 95, step: 1 }
|
9218
9238
|
},
|
9219
9239
|
sunIntensity: { min: 0, max: 10, step: 0.1 },
|
9220
9240
|
skyTurbidity: { min: 1, max: 30, step: 0.1 },
|
@@ -9225,7 +9245,7 @@ var sunOptions = {
|
|
9225
9245
|
var envValues = {
|
9226
9246
|
skyboxAzimuthalAngle: 0,
|
9227
9247
|
skyboxPolarAngle: 0,
|
9228
|
-
envMapIntensity: 0.
|
9248
|
+
envMapIntensity: 0.6,
|
9229
9249
|
skyboxIntensity: 0.9,
|
9230
9250
|
skyboxBlurriness: 0,
|
9231
9251
|
ambientLight: {
|
@@ -11494,10 +11514,11 @@ var PostProcessingFolder = class {
|
|
11494
11514
|
};
|
11495
11515
|
|
11496
11516
|
// src/tweakpane/blades/rendererFolder.ts
|
11517
|
+
import { NoToneMapping } from "three";
|
11497
11518
|
var rendererValues = {
|
11498
11519
|
shadowMap: 2,
|
11499
|
-
toneMapping:
|
11500
|
-
exposure:
|
11520
|
+
toneMapping: 4,
|
11521
|
+
exposure: 0.75
|
11501
11522
|
};
|
11502
11523
|
var rendererOptions = {
|
11503
11524
|
shadowMap: { min: 0, max: 2, step: 1 },
|
@@ -11556,6 +11577,7 @@ var RendererFolder = class {
|
|
11556
11577
|
const value = e.value;
|
11557
11578
|
toneMappingFolder.hidden = e.value !== 5;
|
11558
11579
|
toneMappingPass.enabled = e.value === 5 ? true : false;
|
11580
|
+
renderer.toneMapping = e.value === 5 ? NoToneMapping : e.value;
|
11559
11581
|
setToneMappingType(e.value);
|
11560
11582
|
break;
|
11561
11583
|
case "exposure":
|
@@ -11838,6 +11860,7 @@ var TweakPane = class {
|
|
11838
11860
|
}
|
11839
11861
|
setupCharacterController(localController) {
|
11840
11862
|
this.characterControls.setupChangeEvent(localController);
|
11863
|
+
this.character.setupChangeEvent();
|
11841
11864
|
}
|
11842
11865
|
setupPostProcessingPane(postProcessingManager) {
|
11843
11866
|
this.postProcessingFolder.setupChangeEvent(postProcessingManager);
|
@@ -11934,7 +11957,7 @@ import {
|
|
11934
11957
|
SRGBColorSpace,
|
11935
11958
|
Vector3 as Vector316,
|
11936
11959
|
WebGLCubeRenderTarget,
|
11937
|
-
WebGLRenderer as
|
11960
|
+
WebGLRenderer as WebGLRenderer10
|
11938
11961
|
} from "three";
|
11939
11962
|
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
|
11940
11963
|
import { Sky } from "three/examples/jsm/objects/Sky.js";
|
@@ -12066,7 +12089,7 @@ var Composer = class {
|
|
12066
12089
|
this.postPostScene = new Scene6();
|
12067
12090
|
this.spawnSun = spawnSun;
|
12068
12091
|
this.postProcessingEnabled = postProcessingEnabled;
|
12069
|
-
this.renderer = new
|
12092
|
+
this.renderer = new WebGLRenderer10({
|
12070
12093
|
powerPreference: "high-performance",
|
12071
12094
|
antialias: true
|
12072
12095
|
});
|