update: merge instanced map geometry

This commit is contained in:
Tom Boullay
2026-05-15 23:29:07 +02:00
parent 9dff245aab
commit 6957b9e4f0
5 changed files with 149 additions and 100 deletions
+81 -81
View File
@@ -75,7 +75,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [121.276, 1.73, 33.8112],
"position": [121.276, 1.5021, 33.8112],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -91,7 +91,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [94.6561, 2.5066, 26.2346],
"position": [94.6561, 2.1751, 26.2346],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -123,7 +123,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-86.0245, 1.9076, -35.7442],
"position": [-86.0245, 1.6584, -35.7442],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -139,7 +139,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [37.982, 6.7216, 30.9555],
"position": [37.982, 6.565, 30.9555],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -155,7 +155,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [29.6205, 5.3697, 51.2508],
"position": [29.6205, 4.8536, 51.2508],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -171,7 +171,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [43.6785, 2.0178, 96.2199],
"position": [43.6785, 1.7013, 96.2199],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -187,7 +187,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-74.6178, 2.6552, 9.5979],
"position": [-74.6178, 2.3115, 9.5979],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -203,7 +203,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-75.4654, 2.5559, 16.9493],
"position": [-75.4654, 2.2701, 16.9493],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -219,7 +219,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-74.2835, 2.5536, 22.7387],
"position": [-74.2835, 2.2678, 22.7387],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -235,7 +235,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [86.629, 2.7422, -31.3242],
"position": [86.629, 2.4407, -31.3242],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -251,7 +251,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-63.3935, 3.1961, -18.2155],
"position": [-63.3935, 2.9078, -18.2155],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -267,7 +267,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [0.481, 4.0343, 67.7846],
"position": [0.481, 3.6547, 67.7846],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -283,7 +283,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [36.4304, 6.9609, -24.2903],
"position": [36.4304, 6.718, -24.2903],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -299,7 +299,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [116.4929, 1.8153, 13.289],
"position": [116.4929, 1.427, 13.289],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -315,7 +315,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [97.4749, 1.7989, 65.6281],
"position": [97.4749, 1.5226, 65.6281],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -363,7 +363,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [124.3065, 1.73, -13.116],
"position": [124.3065, 1.4655, -13.116],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -379,7 +379,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [78.65, 3.4716, 27.1949],
"position": [78.65, 3.0954, 27.1949],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -395,7 +395,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [76.6262, 3.5066, 31.3087],
"position": [76.6262, 3.1873, 31.3087],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -411,7 +411,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-100.0891, 1.7376, 11.5984],
"position": [-100.0891, 1.445, 11.5984],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -427,7 +427,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [40.8805, 6.8406, -21.1003],
"position": [40.8805, 6.5976, -21.1003],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -443,7 +443,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [51.1326, 4.9082, 42.1663],
"position": [51.1326, 4.3922, 42.1663],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -459,7 +459,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [107.585, 2.0754, -9.2064],
"position": [107.585, 1.7648, -9.2064],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -475,7 +475,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-94.7678, 1.8289, -16.9536],
"position": [-94.7678, 1.5849, -16.9536],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -507,7 +507,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [116.9822, 1.7625, 26.4244],
"position": [116.9822, 1.4197, 26.4244],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -523,7 +523,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [26.4407, 4.6971, 59.2547],
"position": [26.4407, 4.181, 59.2547],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -539,7 +539,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [103.8144, 2.238, -2.979],
"position": [103.8144, 1.9274, -2.979],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -555,7 +555,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [42.8316, 4.7811, -45.8639],
"position": [42.8316, 4.4314, -45.8639],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -571,7 +571,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [94.3453, 1.755, 74.5333],
"position": [94.3453, 1.416, 74.5333],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -587,7 +587,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [50.072, 2.6003, 78.7082],
"position": [50.072, 2.2583, 78.7082],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -603,7 +603,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [48.1475, 2.0144, 94.4155],
"position": [48.1475, 1.6979, 94.4155],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -619,7 +619,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [33.6819, 6.0748, 41.9355],
"position": [33.6819, 5.5588, 41.9355],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -651,7 +651,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-103.5232, 1.7593, -4.9283],
"position": [-103.5232, 1.4716, -4.9283],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -667,7 +667,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [45.7062, 4.8094, -43.4591],
"position": [45.7062, 4.4597, -43.4591],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -683,7 +683,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-39.193, 5.1507, -20.5904],
"position": [-39.193, 4.8052, -20.5904],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -699,7 +699,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [14.2481, 3.6042, 73.495],
"position": [14.2481, 3.2246, 73.495],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -715,7 +715,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-10.8931, 1.73, 122.7132],
"position": [-10.8931, 1.4202, 122.7132],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -731,7 +731,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [65.0769, 4.874, -14.5488],
"position": [65.0769, 4.5437, -14.5488],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -747,7 +747,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [14.4329, 3.9184, 69.6626],
"position": [14.4329, 3.5387, 69.6626],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -763,7 +763,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [92.08, 2.249, 47.2922],
"position": [92.08, 1.944, 47.2922],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -795,7 +795,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [15.8967, 2.1664, 97.556],
"position": [15.8967, 1.8369, 97.556],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -811,7 +811,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [87.1983, 3.1685, 4.2289],
"position": [87.1983, 2.8744, 4.2289],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -827,7 +827,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [61.4859, 4.8279, -24.328],
"position": [61.4859, 4.5221, -24.328],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -843,7 +843,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [93.3467, 2.177, 48.8426],
"position": [93.3467, 1.8721, 48.8426],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -859,7 +859,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-62.9162, 3.2697, -15.5153],
"position": [-62.9162, 2.9577, -15.5153],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -875,7 +875,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-116.2891, 1.73, 9.5757],
"position": [-116.2891, 1.4446, 9.5757],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -891,7 +891,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [59.1794, 2.5978, 73.349],
"position": [59.1794, 2.2557, 73.349],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -907,7 +907,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-114.7275, 1.73, -9.0295],
"position": [-114.7275, 1.424, -9.0295],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -923,7 +923,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [64.0578, 5.175, 10.4709],
"position": [64.0578, 4.8663, 10.4709],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -939,7 +939,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [106.4135, 2.1324, 4.2119],
"position": [106.4135, 1.8218, 4.2119],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -987,7 +987,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [61.8189, 5.3955, 11.2704],
"position": [61.8189, 5.0867, 11.2704],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1003,7 +1003,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-89.9371, 1.9245, 24.3503],
"position": [-89.9371, 1.6387, 24.3503],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1019,7 +1019,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [106.5106, 1.7455, 58.4254],
"position": [106.5106, 1.4693, 58.4254],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1035,7 +1035,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [85.5663, 1.7985, 79.0421],
"position": [85.5663, 1.4203, 79.0421],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1067,7 +1067,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-105.7379, 1.73, -55.9911],
"position": [-105.7379, 1.4476, -55.9911],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1083,7 +1083,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [98.6825, 2.0477, 45.6252],
"position": [98.6825, 1.7427, 45.6252],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1099,7 +1099,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [80.8168, 3.5714, -9.1306],
"position": [80.8168, 3.2385, -9.1306],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1115,7 +1115,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [74.0452, 2.6362, 59.2374],
"position": [74.0452, 2.309, 59.2374],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1131,7 +1131,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-54.4886, 3.0828, -41.0096],
"position": [-54.4886, 2.6773, -41.0096],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1147,7 +1147,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-124.3983, 1.73, -13.1213],
"position": [-124.3983, 1.4256, -13.1213],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1163,7 +1163,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-91.0013, 1.7467, -47.9181],
"position": [-91.0013, 1.4474, -47.9181],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1179,7 +1179,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-93.3362, 1.7383, -47.5484],
"position": [-93.3362, 1.3615, -47.5484],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1195,7 +1195,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-106.7784, 1.73, -38.7522],
"position": [-106.7784, 1.4278, -38.7522],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1211,7 +1211,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-95.473, 1.8589, 7.6623],
"position": [-95.473, 1.5663, 7.6623],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1227,7 +1227,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [63.9067, 2.7479, -61.4631],
"position": [63.9067, 2.4019, -61.4631],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1243,7 +1243,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [119.0658, 1.73, 36.3151],
"position": [119.0658, 1.5021, 36.3151],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1259,7 +1259,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [63.6675, 1.73, 105.888],
"position": [63.6675, 1.5126, 105.888],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1275,7 +1275,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-52.4236, 3.6593, -29.3635],
"position": [-52.4236, 3.3925, -29.3635],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1291,7 +1291,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-100.203, 1.7844, 4.1061],
"position": [-100.203, 1.532, 4.1061],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1323,7 +1323,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [-26.4888, 6.8456, -8.9158],
"position": [-26.4888, 6.5968, -8.9158],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1339,7 +1339,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [35.739, 1.73, 114.0022],
"position": [35.739, 1.4453, 114.0022],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -1355,7 +1355,7 @@
{
"name": "arbre",
"type": "Object3D",
"position": [78.1002, 2.121, 71.1874],
"position": [78.1002, 1.7427, 71.1874],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
@@ -37792,7 +37792,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [-44.7536, 6.5105, -33.8088],
"position": [-44.7536, 5.4185, -33.8088],
"rotation": [0, 1.3151, 0],
"scale": [1, 1, 1],
"children": [
@@ -37808,7 +37808,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [-56.3613, 6.2423, -15.6316],
"position": [-56.3613, 4.9693, -15.6316],
"rotation": [0, 0.8463, 0],
"scale": [1, 1, 1],
"children": [
@@ -37824,7 +37824,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [-84.3828, 4.1993, -61.5091],
"position": [-84.3828, 3.2803, -61.5091],
"rotation": [0, 1.1767, 0],
"scale": [1, 1, 1],
"children": [
@@ -37840,7 +37840,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [-85.2787, 4.6413, 3.4477],
"position": [-85.2787, 3.6193, 3.4477],
"rotation": [3.1416, 1.5431, -3.1416],
"scale": [1, 1, 1],
"children": [
@@ -38141,7 +38141,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [8.1016, 5.9085, 75.5432],
"position": [8.1016, 4.5891, 75.5432],
"rotation": [0, -0.116, 0],
"scale": [1, 1, 1],
"children": [
@@ -38583,7 +38583,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [107.643, 4.4872, 21.6635],
"position": [107.643, 3.0547, 21.6635],
"rotation": [3.1416, 0.7261, -3.1416],
"scale": [1, 1, 1],
"children": [
@@ -38599,7 +38599,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [48.7038, 6.157, -56.1174],
"position": [48.7038, 4.532, -56.1174],
"rotation": [0, 1.4495, 0],
"scale": [1, 1, 1],
"children": [
@@ -38615,7 +38615,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [62.838, 6.3419, -40.4284],
"position": [62.838, 4.759, -40.4284],
"rotation": [3.1416, 0.6961, -3.1416],
"scale": [1, 1, 1],
"children": [
@@ -38631,7 +38631,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [85.4777, 4.5325, -60.3785],
"position": [85.4777, 3.2953, -60.3785],
"rotation": [3.1416, 1.1427, -3.1416],
"scale": [1, 1, 1],
"children": [
@@ -38647,7 +38647,7 @@
{
"name": "maison1",
"type": "Object3D",
"position": [49.6595, 8.4233, -23.113],
"position": [49.6595, 7.1077, -23.113],
"rotation": [0, 1.5065, 0],
"scale": [1, 1, 1],
"children": [
+14 -1
View File
@@ -18,6 +18,7 @@ const IDENTITY_NODE = {
rotation: [0, 0, 0],
scale: [1, 1, 1],
};
const MAX_MESH_Y_PLACEMENT_OFFSET = 2;
function cloneNode(node) {
return {
@@ -63,9 +64,21 @@ function getOrCreateModelGroup(parent, modelName) {
function createRenderableObject(objectNode, meshNode) {
const mappedMesh = mapMeshNode(meshNode);
const renderableNode = cloneNode(objectNode ?? meshNode);
if (objectNode && meshNode) {
const yOffset = Math.abs(objectNode.position[1] - meshNode.position[1]);
if (yOffset <= MAX_MESH_Y_PLACEMENT_OFFSET) {
renderableNode.position = [
objectNode.position[0],
meshNode.position[1],
objectNode.position[2],
];
}
}
return {
...cloneNode(objectNode ?? meshNode),
...renderableNode,
name: mappedMesh.name,
type: "Object3D",
children: [mappedMesh],
+9
View File
@@ -31,3 +31,12 @@ declare module "three/addons/math/Octree.js" {
capsuleIntersect(capsule: Capsule): CapsuleIntersectResult | false;
}
}
declare module "three/addons/utils/BufferGeometryUtils.js" {
import { BufferGeometry } from "three";
export function mergeGeometries(
geometries: BufferGeometry[],
useGroups?: boolean,
): BufferGeometry | null;
}
+45 -15
View File
@@ -1,6 +1,7 @@
import { useEffect, useMemo, useRef } from "react";
import * as THREE from "three";
import { useGLTF } from "@react-three/drei";
import { mergeGeometries } from "three/addons/utils/BufferGeometryUtils.js";
import type { VegetationInstance } from "@/world/vegetation/useVegetationData";
import { disposeInstancedMesh } from "@/utils/three/dispose";
@@ -13,27 +14,59 @@ interface InstancedVegetationProps {
interface MeshData {
geometry: THREE.BufferGeometry;
material: THREE.Material | THREE.Material[];
localMatrix: THREE.Matrix4;
material: THREE.Material;
}
function extractMeshes(scene: THREE.Group): MeshData[] {
const meshes: MeshData[] = [];
const meshesByMaterial = new Map<
string,
{ geometries: THREE.BufferGeometry[]; material: THREE.Material }
>();
scene.updateMatrixWorld(true);
scene.traverse((child) => {
if (child instanceof THREE.Mesh) {
meshes.push({
geometry: child.geometry.clone(),
material: Array.isArray(child.material)
? child.material.map((m) => m.clone())
: child.material.clone(),
localMatrix: child.matrixWorld.clone(),
if (!(child instanceof THREE.Mesh)) return;
const material = Array.isArray(child.material)
? child.material[0]
: child.material;
if (!material) return;
const geometry = child.geometry.clone();
geometry.applyMatrix4(child.matrixWorld);
const existing = meshesByMaterial.get(material.uuid);
if (existing) {
existing.geometries.push(geometry);
} else {
meshesByMaterial.set(material.uuid, {
geometries: [geometry],
material: material.clone(),
});
}
});
return meshes;
return [...meshesByMaterial.values()]
.map(({ geometries, material }) => {
const mergedGeometry = mergeGeometries(geometries, false);
for (const geometry of geometries) {
if (geometry !== mergedGeometry) {
geometry.dispose();
}
}
if (!mergedGeometry) {
material.dispose();
return null;
}
return {
geometry: mergedGeometry,
material,
};
})
.filter((meshData): meshData is MeshData => meshData !== null);
}
function createInstanceMatrices(
@@ -84,10 +117,7 @@ export function InstancedVegetation({
for (let i = 0; i < matrices.length; i++) {
const matrix = matrices[i];
if (matrix) {
instancedMesh.setMatrixAt(
i,
new THREE.Matrix4().multiplyMatrices(matrix, meshData.localMatrix),
);
instancedMesh.setMatrixAt(i, matrix);
}
}
-3
View File
@@ -8,7 +8,4 @@ export const INSTANCED_MAP_EXCEPTIONS = new Set([
"Scene",
"blocking",
"terrain",
"ecole",
"generateur",
"lafabrik",
]);