diff --git a/public/map.json b/public/map.json index d60ef46..bc281c5 100644 --- a/public/map.json +++ b/public/map.json @@ -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": [ diff --git a/scripts/transformMap.cjs b/scripts/transformMap.cjs index c95abd0..cc119f8 100644 --- a/scripts/transformMap.cjs +++ b/scripts/transformMap.cjs @@ -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], diff --git a/src/types/three/three-addons.d.ts b/src/types/three/three-addons.d.ts index ac0eec5..ac0abe0 100644 --- a/src/types/three/three-addons.d.ts +++ b/src/types/three/three-addons.d.ts @@ -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; +} diff --git a/src/world/vegetation/InstancedVegetation.tsx b/src/world/vegetation/InstancedVegetation.tsx index 710b917..9edb773 100644 --- a/src/world/vegetation/InstancedVegetation.tsx +++ b/src/world/vegetation/InstancedVegetation.tsx @@ -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); } } diff --git a/src/world/vegetation/vegetationConfig.ts b/src/world/vegetation/vegetationConfig.ts index e904349..fb151b2 100644 --- a/src/world/vegetation/vegetationConfig.ts +++ b/src/world/vegetation/vegetationConfig.ts @@ -8,7 +8,4 @@ export const INSTANCED_MAP_EXCEPTIONS = new Set([ "Scene", "blocking", "terrain", - "ecole", - "generateur", - "lafabrik", ]);