Feat/map-environment #6

Merged
math-pixel merged 116 commits from feat/map-environment into develop 2026-05-29 00:00:51 +00:00
7 changed files with 430 additions and 670 deletions
Showing only changes of commit 9dff245aab - Show all commits
+320 -539
View File
@@ -37610,6 +37610,177 @@
"rotation": [-3.1416, -1.1003, -3.1416], "rotation": [-3.1416, -1.1003, -3.1416],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble1",
"type": "Object3D",
"role": "group",
"position": [0, 0, 0],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Object3D",
"position": [-33.4517, 8.4233, -14.3777],
"rotation": [0, 1.0967, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-35.0952, 7.4391, -11.2481],
"rotation": [0, 1.0967, 0],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [-31.8081, 9.4074, -17.5073],
"rotation": [0, 1.0967, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-61.1478, 6.0441, 5.1504],
"rotation": [0, 0.8515, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-63.5018, 5.0599, 7.7876],
"rotation": [0, 0.8515, 0],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [-58.7939, 7.0283, 2.5133],
"rotation": [0, 0.8515, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-36.6903, 8.3502, 9.731],
"rotation": [0, 1.1991, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-38.0051, 7.366, 13.0123],
"rotation": [0, 1.1992, 0],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [-35.3756, 9.3343, 6.4496],
"rotation": [0, 1.1991, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-68.7111, 4.651, -50.5238],
"rotation": [0, 1.3104, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-69.6533, 3.6669, -47.1168],
"rotation": [0, 1.3105, 0],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [-67.7689, 5.6352, -53.9309],
"rotation": [0, 1.3104, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-100.9035, 4.19, -31.7676],
"rotation": [0, 0.9317, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-103.0387, 3.2058, -28.9504],
"rotation": [0, 0.9317, 0],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [-98.7682, 5.1742, -34.5848],
"rotation": [0, 0.9317, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-79.1874, 4.7345, -23.9129],
"rotation": [0, 1.0321, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-81.0293, 3.7503, -20.8958],
"rotation": [0, 1.0322, 0],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [-77.3455, 5.7187, -26.9301],
"rotation": [0, 1.0321, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-107.9151, 4.19, 1.755],
"rotation": [3.1416, 1.5267, -3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-107.7927, 3.2058, 5.2878],
"rotation": [3.1416, 1.5267, 3.1416],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [-108.0375, 5.1742, -1.7778],
"rotation": [3.1416, 1.5267, -3.1416],
"scale": [1, 1, 1]
}
]
}
]
},
{ {
"name": "maison1", "name": "maison1",
"type": "Object3D", "type": "Object3D",
@@ -37684,250 +37855,6 @@
} }
] ]
}, },
{
"name": "immeuble_2",
"type": "Object3D",
"role": "group",
"position": [0, 0, 0],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Object3D",
"position": [-35.0952, 7.4391, -11.2481],
"rotation": [0, 1.0967, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-35.0952, 7.4391, -11.2481],
"rotation": [0, 1.0967, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [-63.5018, 5.0599, 7.7876],
"rotation": [0, 0.8515, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-63.5018, 5.0599, 7.7876],
"rotation": [0, 0.8515, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [-38.0051, 7.366, 13.0123],
"rotation": [0, 1.1992, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-38.0051, 7.366, 13.0123],
"rotation": [0, 1.1992, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [-69.6533, 3.6669, -47.1168],
"rotation": [0, 1.3105, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-69.6533, 3.6669, -47.1168],
"rotation": [0, 1.3105, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [-103.0387, 3.2058, -28.9504],
"rotation": [0, 0.9317, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-103.0387, 3.2058, -28.9504],
"rotation": [0, 0.9317, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [-81.0293, 3.7503, -20.8958],
"rotation": [0, 1.0322, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-81.0293, 3.7503, -20.8958],
"rotation": [0, 1.0322, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [-107.7927, 3.2058, 5.2878],
"rotation": [3.1416, 1.5267, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [-107.7927, 3.2058, 5.2878],
"rotation": [3.1416, 1.5267, 3.1416],
"scale": [1, 1, 1]
}
]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"role": "group",
"position": [0, 0, 0],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Object3D",
"position": [-31.8081, 9.4074, -17.5073],
"rotation": [0, 1.0967, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [-31.8081, 9.4074, -17.5073],
"rotation": [0, 1.0967, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-58.7939, 7.0283, 2.5133],
"rotation": [0, 0.8515, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [-58.7939, 7.0283, 2.5133],
"rotation": [0, 0.8515, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-35.3756, 9.3343, 6.4496],
"rotation": [0, 1.1991, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [-35.3756, 9.3343, 6.4496],
"rotation": [0, 1.1991, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-67.7689, 5.6352, -53.9309],
"rotation": [0, 1.3104, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [-67.7689, 5.6352, -53.9309],
"rotation": [0, 1.3104, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-98.7682, 5.1742, -34.5848],
"rotation": [0, 0.9317, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [-98.7682, 5.1742, -34.5848],
"rotation": [0, 0.9317, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-77.3455, 5.7187, -26.9301],
"rotation": [0, 1.0321, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [-77.3455, 5.7187, -26.9301],
"rotation": [0, 1.0321, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [-108.0375, 5.1742, -1.7778],
"rotation": [3.1416, 1.5267, -3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [-108.0375, 5.1742, -1.7778],
"rotation": [3.1416, 1.5267, -3.1416],
"scale": [1, 1, 1]
}
]
}
]
},
{ {
"name": "boiteauxlettres", "name": "boiteauxlettres",
"type": "Object3D", "type": "Object3D",
@@ -38135,7 +38062,7 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [4.3643, 3.2151, 114.4985], "position": [7.8967, 4.1992, 114.363],
"rotation": [0, 0.0478, 0], "rotation": [0, 0.0478, 0],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
@@ -38145,16 +38072,7 @@
"position": [4.3643, 3.2151, 114.4985], "position": [4.3643, 3.2151, 114.4985],
"rotation": [0, 0.0478, 0], "rotation": [0, 0.0478, 0],
"scale": [1, 1, 1] "scale": [1, 1, 1]
} },
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [11.429, 5.1834, 114.2275],
"rotation": [0, 0.0478, 0],
"scale": [1, 1, 1],
"children": [
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38167,7 +38085,7 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [4.8661, 3.8156, 93.9483], "position": [8.3955, 4.7997, 93.7519],
"rotation": [0, 0.065, 0], "rotation": [0, 0.065, 0],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
@@ -38177,16 +38095,7 @@
"position": [4.8661, 3.8156, 93.9483], "position": [4.8661, 3.8156, 93.9483],
"rotation": [0, 0.065, 0], "rotation": [0, 0.065, 0],
"scale": [1, 1, 1] "scale": [1, 1, 1]
} },
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [11.925, 5.7839, 93.5555],
"rotation": [0, 0.065, 0],
"scale": [1, 1, 1],
"children": [
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38199,7 +38108,7 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [4.328, 6.8554, 54.6231], "position": [7.8601, 7.8395, 54.7639],
"rotation": [0, -0.0304, 0], "rotation": [0, -0.0304, 0],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
@@ -38209,16 +38118,7 @@
"position": [4.328, 6.8554, 54.6231], "position": [4.328, 6.8554, 54.6231],
"rotation": [0, -0.0304, 0], "rotation": [0, -0.0304, 0],
"scale": [1, 1, 1] "scale": [1, 1, 1]
} },
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [11.3922, 8.8237, 54.9046],
"rotation": [0, -0.0304, 0],
"scale": [1, 1, 1],
"children": [
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38478,144 +38378,6 @@
"rotation": [3.1416, 1.1456, -3.1416], "rotation": [3.1416, 1.1456, -3.1416],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble_2",
"type": "Object3D",
"role": "group",
"position": [0, 0, 0],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Object3D",
"position": [58.5315, 7.4391, 16.5809],
"rotation": [3.1416, 0.5971, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [58.5315, 7.4391, 16.5809],
"rotation": [3.1416, 0.5971, 3.1416],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [80.4667, 5.2224, 21.2652],
"rotation": [3.1416, 0.6567, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [80.4667, 5.2224, 21.2652],
"rotation": [3.1416, 0.6567, 3.1416],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [38.4102, 7.4391, -34.443],
"rotation": [3.1416, 0.7598, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [38.4102, 7.4391, -34.443],
"rotation": [3.1416, 0.7598, 3.1416],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [81.4108, 5.2437, 0.7526],
"rotation": [3.1416, 0.9283, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [81.4108, 5.2437, 0.7526],
"rotation": [3.1416, 0.9283, 3.1416],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [96.2087, 3.5829, -38.0843],
"rotation": [0, 1.4947, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [96.2087, 3.5829, -38.0843],
"rotation": [0, 1.4947, 0],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [73.8823, 5.435, -18.1955],
"rotation": [3.1416, 1.2395, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [73.8823, 5.435, -18.1955],
"rotation": [3.1416, 1.2395, 3.1416],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [57.2363, 7.4391, -1.4223],
"rotation": [3.1416, 1.3941, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [57.2363, 7.4391, -1.4223],
"rotation": [3.1416, 1.3941, 3.1416],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [112.0712, 3.4242, -13.0076],
"rotation": [3.1416, 1.0875, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [112.0712, 3.4242, -13.0076],
"rotation": [3.1416, 1.0875, 3.1416],
"scale": [1, 1, 1]
}
]
}
]
},
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
@@ -38627,10 +38389,17 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [52.7229, 9.4074, 12.5507], "position": [55.6272, 8.4233, 14.5658],
"rotation": [3.1416, 0.5972, -3.1416], "rotation": [3.1416, 0.5972, -3.1416],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [58.5315, 7.4391, 16.5809],
"rotation": [3.1416, 0.5971, 3.1416],
"scale": [1, 1, 1]
},
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38643,10 +38412,17 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [74.9084, 7.1908, 16.8962], "position": [77.6876, 6.2066, 19.0807],
"rotation": [3.1416, 0.6567, -3.1416], "rotation": [3.1416, 0.6567, -3.1416],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [80.4667, 5.2224, 21.2652],
"rotation": [3.1416, 0.6567, 3.1416],
"scale": [1, 1, 1]
},
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38659,10 +38435,17 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [33.331, 9.4074, -39.3608], "position": [35.8706, 8.4233, -36.9019],
"rotation": [3.1416, 0.7598, -3.1416], "rotation": [3.1416, 0.7598, -3.1416],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [38.4102, 7.4391, -34.443],
"rotation": [3.1416, 0.7598, 3.1416],
"scale": [1, 1, 1]
},
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38675,10 +38458,17 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [77.2281, 7.212, -4.9471], "position": [79.3194, 6.2278, -2.0972],
"rotation": [3.1416, 0.9283, -3.1416], "rotation": [3.1416, 0.9283, -3.1416],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [81.4108, 5.2437, 0.7526],
"rotation": [3.1416, 0.9283, 3.1416],
"scale": [1, 1, 1]
},
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38691,10 +38481,17 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [96.8126, 5.5512, -45.1283], "position": [96.5106, 4.567, -41.6063],
"rotation": [0, 1.4947, 0], "rotation": [0, 1.4947, 0],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [96.2087, 3.5829, -38.0843],
"rotation": [0, 1.4947, 0],
"scale": [1, 1, 1]
},
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38707,10 +38504,17 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [71.646, 7.4033, -24.9023], "position": [72.7641, 6.4192, -21.5489],
"rotation": [3.1416, 1.2395, -3.1416], "rotation": [3.1416, 1.2395, -3.1416],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [73.8823, 5.435, -18.1955],
"rotation": [3.1416, 1.2395, 3.1416],
"scale": [1, 1, 1]
},
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38723,10 +38527,17 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [56.0593, 9.4074, -8.3934], "position": [56.6478, 8.4233, -4.9078],
"rotation": [3.1416, 1.3941, -3.1416], "rotation": [3.1416, 1.3941, -3.1416],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [57.2363, 7.4391, -1.4223],
"rotation": [3.1416, 1.3941, 3.1416],
"scale": [1, 1, 1]
},
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -38739,10 +38550,17 @@
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Object3D", "type": "Object3D",
"position": [108.8451, 5.3925, -19.2984], "position": [110.4581, 4.4084, -16.153],
"rotation": [3.1416, 1.0875, -3.1416], "rotation": [3.1416, 1.0875, -3.1416],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [112.0712, 3.4242, -13.0076],
"rotation": [3.1416, 1.0875, 3.1416],
"scale": [1, 1, 1]
},
{ {
"name": "immeuble1", "name": "immeuble1",
"type": "Mesh", "type": "Mesh",
@@ -40600,6 +40418,85 @@
"rotation": [0, -1.5519, 0], "rotation": [0, -1.5519, 0],
"scale": [1, 1, 1], "scale": [1, 1, 1],
"children": [ "children": [
{
"name": "immeuble1",
"type": "Object3D",
"role": "group",
"position": [0, 0, 0],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Object3D",
"position": [41.2436, 4.9268, 85.9236],
"rotation": [-3.1416, -0.7879, -3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [43.9828, 3.8964, 80.0347],
"rotation": [3.0968, -0.7874, 3.1104],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [38.9058, 5.8659, 84.9543],
"rotation": [3.0968, -0.7874, 3.1104],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [68.0365, 12.8264, 90.8185],
"rotation": [-3.1416, -0.5678, -3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [72.189, 3.1922, 85.8558],
"rotation": [-3.1416, -0.5678, 3.1416],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [66.1929, 5.1605, 89.6013],
"rotation": [-3.1416, -0.5678, -3.1416],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [61.7855, 15.3193, 38.8586],
"rotation": [-3.1416, -0.5678, -3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [65.9379, 5.6851, 33.8958],
"rotation": [-3.1416, -0.5678, 3.1416],
"scale": [1, 1, 1]
},
{
"name": "immeuble1",
"type": "Mesh",
"position": [59.9418, 7.6534, 37.6414],
"rotation": [-3.1416, -0.5678, -3.1416],
"scale": [1, 1, 1]
}
]
}
]
},
{ {
"name": "lafabrik", "name": "lafabrik",
"type": "Object3D", "type": "Object3D",
@@ -40626,122 +40523,6 @@
} }
] ]
}, },
{
"name": "immeuble_2",
"type": "Object3D",
"role": "group",
"position": [0, 0, 0],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Object3D",
"position": [43.9828, 3.8964, 80.0347],
"rotation": [3.0968, -0.7874, 3.1104],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [43.9828, 3.8964, 80.0347],
"rotation": [3.0968, -0.7874, 3.1104],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [72.189, 3.1922, 85.8558],
"rotation": [-3.1416, -0.5678, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [72.189, 3.1922, 85.8558],
"rotation": [-3.1416, -0.5678, 3.1416],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble_2",
"type": "Object3D",
"position": [65.9379, 5.6851, 33.8958],
"rotation": [-3.1416, -0.5678, 3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble_2",
"type": "Mesh",
"position": [65.9379, 5.6851, 33.8958],
"rotation": [-3.1416, -0.5678, 3.1416],
"scale": [1, 1, 1]
}
]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"role": "group",
"position": [0, 0, 0],
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Object3D",
"position": [38.9058, 5.8659, 84.9543],
"rotation": [3.0968, -0.7874, 3.1104],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [38.9058, 5.8659, 84.9543],
"rotation": [3.0968, -0.7874, 3.1104],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [66.1929, 5.1605, 89.6013],
"rotation": [-3.1416, -0.5678, -3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [66.1929, 5.1605, 89.6013],
"rotation": [-3.1416, -0.5678, -3.1416],
"scale": [1, 1, 1]
}
]
},
{
"name": "immeuble1",
"type": "Object3D",
"position": [59.9418, 7.6534, 37.6414],
"rotation": [-3.1416, -0.5678, -3.1416],
"scale": [1, 1, 1],
"children": [
{
"name": "immeuble1",
"type": "Mesh",
"position": [59.9418, 7.6534, 37.6414],
"rotation": [-3.1416, -0.5678, -3.1416],
"scale": [1, 1, 1]
}
]
}
]
},
{ {
"name": "maison1", "name": "maison1",
"type": "Object3D", "type": "Object3D",
+50 -7
View File
@@ -72,6 +72,14 @@ function createRenderableObject(objectNode, meshNode) {
}; };
} }
function createRenderableContainer(objectNode, meshNodes) {
return {
...cloneNode(objectNode),
type: "Object3D",
children: meshNodes.map(mapMeshNode),
};
}
function addRenderable(parent, objectNode, meshNode) { function addRenderable(parent, objectNode, meshNode) {
const renderable = createRenderableObject(objectNode, meshNode); const renderable = createRenderableObject(objectNode, meshNode);
getOrCreateModelGroup(parent, renderable.name).children.push(renderable); getOrCreateModelGroup(parent, renderable.name).children.push(renderable);
@@ -95,6 +103,36 @@ function addObjectsByRange(rawData, parent, start, end, allowedNames) {
} }
} }
function addBuildingsByRange(rawData, parent, start, end) {
for (let i = start; i <= end; i++) {
const node = rawData[i];
if (node?.type !== "Object3D" || node.name !== "immeuble1") continue;
const meshNodes = [];
for (let childIndex = i + 1; childIndex <= end; childIndex++) {
const childNode = rawData[childIndex];
if (childNode?.type === "Object3D") {
if (BUILDING_CHILD_OBJECT_NAMES.has(childNode.name)) continue;
break;
}
if (
childNode?.type === "Mesh" &&
BUILDING_MESH_NAMES.has(childNode.name)
) {
meshNodes.push(childNode);
}
}
if (meshNodes.length > 0) {
getOrCreateModelGroup(parent, node.name).children.push(
createRenderableContainer(node, meshNodes),
);
}
}
}
function getNearestGroup(groups, node) { function getNearestGroup(groups, node) {
const [x, , z] = node.position; const [x, , z] = node.position;
@@ -116,6 +154,9 @@ function createResidenceZones(rawData, residence) {
return zone; return zone;
}); });
addBuildingsByRange(rawData, zones[0], 831, 873);
addBuildingsByRange(rawData, zones[1], 875, 891);
addBuildingsByRange(rawData, zones[2], 893, 942);
addObjectsByRange(rawData, zones[0], 831, 873, RESIDENCE_MESH_NAMES); addObjectsByRange(rawData, zones[0], 831, 873, RESIDENCE_MESH_NAMES);
addObjectsByRange(rawData, zones[1], 875, 891, RESIDENCE_MESH_NAMES); addObjectsByRange(rawData, zones[1], 875, 891, RESIDENCE_MESH_NAMES);
addObjectsByRange(rawData, zones[2], 893, 942, RESIDENCE_MESH_NAMES); addObjectsByRange(rawData, zones[2], 893, 942, RESIDENCE_MESH_NAMES);
@@ -144,7 +185,13 @@ const CHAMP_MESH_NAMES = new Set([
"champsdetournesol", "champsdetournesol",
]); ]);
const FERME_MESH_NAMES = new Set(["buissons", "buisson", "fermeverticale"]); const FERME_MESH_NAMES = new Set(["buissons", "buisson", "fermeverticale"]);
const RESIDENCE_MESH_NAMES = new Set(["immeuble_1", "immeuble_2", "maison1"]); const RESIDENCE_MESH_NAMES = new Set(["maison1"]);
const BUILDING_CHILD_OBJECT_NAMES = new Set([
"immeuble",
"immeuble_1",
"immeuble_2",
]);
const BUILDING_MESH_NAMES = new Set(["immeuble_1", "immeuble_2"]);
const ENERGIE_MESH_NAMES = new Set([ const ENERGIE_MESH_NAMES = new Set([
"pyloneelectrique", "pyloneelectrique",
"eoliennes", "eoliennes",
@@ -161,12 +208,7 @@ const DIRECTION_MESH_NAMES = new Set([
"panneaudirresidences2", "panneaudirresidences2",
"panneauxquartier", "panneauxquartier",
]); ]);
const LAFABRIK_MESH_NAMES = new Set([ const LAFABRIK_MESH_NAMES = new Set(["lafabrik", "maison1"]);
"lafabrik",
"immeuble_1",
"immeuble_2",
"maison1",
]);
function transformMap() { function transformMap() {
console.log("Reading map_raw.json..."); console.log("Reading map_raw.json...");
const rawData = JSON.parse(fs.readFileSync(INPUT_PATH, "utf-8")); const rawData = JSON.parse(fs.readFileSync(INPUT_PATH, "utf-8"));
@@ -225,6 +267,7 @@ function transformMap() {
addObjectsByRange(rawData, ferme, 4595, 4799, FERME_MESH_NAMES); addObjectsByRange(rawData, ferme, 4595, 4799, FERME_MESH_NAMES);
addObjectsByRange(rawData, vegetation, 4750, 4797, VEGETATION_MESH_NAMES); addObjectsByRange(rawData, vegetation, 4750, 4797, VEGETATION_MESH_NAMES);
addObjectsByRange(rawData, energie, 4801, 4872, ENERGIE_MESH_NAMES); addObjectsByRange(rawData, energie, 4801, 4872, ENERGIE_MESH_NAMES);
addBuildingsByRange(rawData, lafabrik, 4874, 4894);
addObjectsByRange(rawData, lafabrik, 4874, 4894, LAFABRIK_MESH_NAMES); addObjectsByRange(rawData, lafabrik, 4874, 4894, LAFABRIK_MESH_NAMES);
addObjectsByRange(rawData, direction, 4896, 4897, DIRECTION_MESH_NAMES); addObjectsByRange(rawData, direction, 4896, 4897, DIRECTION_MESH_NAMES);
addObjectsByRange(rawData, vegetation, 4898, 4997, VEGETATION_MESH_NAMES); addObjectsByRange(rawData, vegetation, 4898, 4997, VEGETATION_MESH_NAMES);
+7 -13
View File
@@ -17,24 +17,18 @@ import type { SceneLoadingChangeHandler } from "@/types/world/sceneLoading";
import { logger } from "@/utils/core/Logger"; import { logger } from "@/utils/core/Logger";
import { loadMapSceneData } from "@/utils/map/loadMapSceneData"; import { loadMapSceneData } from "@/utils/map/loadMapSceneData";
import { logModelLoadError } from "@/utils/three/modelLoadLogger"; import { logModelLoadError } from "@/utils/three/modelLoadLogger";
import { INSTANCED_MAP_EXCEPTIONS } from "@/world/vegetation/vegetationConfig";
import type { MapNode } from "@/types/editor/editor"; import type { MapNode } from "@/types/editor/editor";
import type { OctreeReadyHandler } from "@/types/three/three"; import type { OctreeReadyHandler } from "@/types/three/three";
const MODEL_RENDER_SCALE: [number, number, number] = [1, 1, 1];
interface LoadedMapNode { interface LoadedMapNode {
node: MapNode; node: MapNode;
modelUrl: string | null; modelUrl: string | null;
} }
const MAP_STRUCTURE_NODE_NAMES = new Set(["Scene", "blocking"]); const MAP_STRUCTURE_NODE_NAMES = new Set(["Scene", "blocking"]);
const LITE_MAP_SKIPPED_NODE_NAMES = new Set([
"arbre",
"buisson",
"champdeble",
"champdesoja",
"champsdetournesol",
"sapin",
]);
interface ErrorBoundaryProps { interface ErrorBoundaryProps {
children: ReactNode; children: ReactNode;
fallback: ReactNode; fallback: ReactNode;
@@ -256,7 +250,7 @@ function liteMap(node: MapNode): boolean {
return false; return false;
} }
return !LITE_MAP_SKIPPED_NODE_NAMES.has(node.name); return INSTANCED_MAP_EXCEPTIONS.has(node.name);
} }
function MapNodeInstance({ function MapNodeInstance({
@@ -294,12 +288,12 @@ function ModelInstance({
modelUrl: string; modelUrl: string;
onLoaded: () => void; onLoaded: () => void;
}): React.JSX.Element { }): React.JSX.Element {
const { position, rotation, scale } = node; const { position, rotation } = node;
const { scene } = useLoggedGLTF(modelUrl, { const { scene } = useLoggedGLTF(modelUrl, {
scope: "GameMap.ModelInstance", scope: "GameMap.ModelInstance",
position, position,
rotation, rotation,
scale, scale: MODEL_RENDER_SCALE,
}); });
const sceneInstance = useClonedObject(scene); const sceneInstance = useClonedObject(scene);
@@ -318,7 +312,7 @@ function ModelInstance({
object={sceneInstance} object={sceneInstance}
position={position} position={position}
rotation={rotation} rotation={rotation}
scale={scale} scale={MODEL_RENDER_SCALE}
/> />
); );
} }
+8 -4
View File
@@ -14,10 +14,12 @@ interface InstancedVegetationProps {
interface MeshData { interface MeshData {
geometry: THREE.BufferGeometry; geometry: THREE.BufferGeometry;
material: THREE.Material | THREE.Material[]; material: THREE.Material | THREE.Material[];
localMatrix: THREE.Matrix4;
} }
function extractMeshes(scene: THREE.Group): MeshData[] { function extractMeshes(scene: THREE.Group): MeshData[] {
const meshes: MeshData[] = []; const meshes: MeshData[] = [];
scene.updateMatrixWorld(true);
scene.traverse((child) => { scene.traverse((child) => {
if (child instanceof THREE.Mesh) { if (child instanceof THREE.Mesh) {
@@ -26,6 +28,7 @@ function extractMeshes(scene: THREE.Group): MeshData[] {
material: Array.isArray(child.material) material: Array.isArray(child.material)
? child.material.map((m) => m.clone()) ? child.material.map((m) => m.clone())
: child.material.clone(), : child.material.clone(),
localMatrix: child.matrixWorld.clone(),
}); });
} }
}); });
@@ -40,7 +43,7 @@ function createInstanceMatrices(
const position = new THREE.Vector3(); const position = new THREE.Vector3();
const rotation = new THREE.Euler(); const rotation = new THREE.Euler();
const quaternion = new THREE.Quaternion(); const quaternion = new THREE.Quaternion();
const scale = new THREE.Vector3(); const scale = new THREE.Vector3(1, 1, 1);
for (const instance of instances) { for (const instance of instances) {
const matrix = new THREE.Matrix4(); const matrix = new THREE.Matrix4();
@@ -48,8 +51,6 @@ function createInstanceMatrices(
position.set(...instance.position); position.set(...instance.position);
rotation.set(...instance.rotation); rotation.set(...instance.rotation);
quaternion.setFromEuler(rotation); quaternion.setFromEuler(rotation);
scale.set(...instance.scale);
matrix.compose(position, quaternion, scale); matrix.compose(position, quaternion, scale);
matrices.push(matrix); matrices.push(matrix);
} }
@@ -83,7 +84,10 @@ export function InstancedVegetation({
for (let i = 0; i < matrices.length; i++) { for (let i = 0; i < matrices.length; i++) {
const matrix = matrices[i]; const matrix = matrices[i];
if (matrix) { if (matrix) {
instancedMesh.setMatrixAt(i, matrix); instancedMesh.setMatrixAt(
i,
new THREE.Matrix4().multiplyMatrices(matrix, meshData.localMatrix),
);
} }
} }
+8 -18
View File
@@ -1,10 +1,6 @@
import { Suspense } from "react"; import { Suspense } from "react";
import { InstancedVegetation } from "@/world/vegetation/InstancedVegetation"; import { InstancedVegetation } from "@/world/vegetation/InstancedVegetation";
import { useVegetationData } from "@/world/vegetation/useVegetationData"; import { useVegetationData } from "@/world/vegetation/useVegetationData";
import {
VEGETATION_TYPES,
type VegetationType,
} from "@/world/vegetation/vegetationConfig";
export function VegetationSystem(): React.JSX.Element | null { export function VegetationSystem(): React.JSX.Element | null {
const { data, isLoading } = useVegetationData(); const { data, isLoading } = useVegetationData();
@@ -13,26 +9,20 @@ export function VegetationSystem(): React.JSX.Element | null {
return null; return null;
} }
const enabledTypes = Object.entries(VEGETATION_TYPES).filter(
([, config]) => config.enabled,
);
return ( return (
<group name="vegetation-system"> <group name="instanced-map-system">
{enabledTypes.map(([type, config]) => { {[...data.entries()].map(([modelName, entry]) => {
const instances = data.get(type as VegetationType); if (entry.instances.length === 0) {
if (!instances || instances.length === 0) {
return null; return null;
} }
return ( return (
<Suspense key={type} fallback={null}> <Suspense key={modelName} fallback={null}>
<InstancedVegetation <InstancedVegetation
modelPath={config.modelPath} modelPath={entry.modelPath}
instances={instances} instances={entry.instances}
castShadow={config.castShadow} castShadow={true}
receiveShadow={config.receiveShadow} receiveShadow={true}
/> />
</Suspense> </Suspense>
); );
+29 -30
View File
@@ -1,11 +1,8 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import type { MapNode } from "@/types/editor/editor"; import type { MapNode } from "@/types/editor/editor";
import type { Vector3Tuple } from "@/types/three/three"; import type { Vector3Tuple } from "@/types/three/three";
import { getMapNodes, loadMapSceneData } from "@/utils/map/loadMapSceneData"; import { loadMapSceneData } from "@/utils/map/loadMapSceneData";
import { import { INSTANCED_MAP_EXCEPTIONS } from "@/world/vegetation/vegetationConfig";
VEGETATION_TYPES,
type VegetationType,
} from "@/world/vegetation/vegetationConfig";
export interface VegetationInstance { export interface VegetationInstance {
position: Vector3Tuple; position: Vector3Tuple;
@@ -13,7 +10,12 @@ export interface VegetationInstance {
scale: Vector3Tuple; scale: Vector3Tuple;
} }
export type VegetationData = Map<VegetationType, VegetationInstance[]>; export interface InstancedMapEntry {
modelPath: string;
instances: VegetationInstance[];
}
export type VegetationData = Map<string, InstancedMapEntry>;
function mapNodeToInstance(node: MapNode): VegetationInstance { function mapNodeToInstance(node: MapNode): VegetationInstance {
return { return {
@@ -23,20 +25,28 @@ function mapNodeToInstance(node: MapNode): VegetationInstance {
}; };
} }
function extractVegetationData(mapNodes: MapNode[]): VegetationData { function extractVegetationData(
mapNodes: MapNode[],
models: Map<string, string>,
): VegetationData {
const data: VegetationData = new Map(); const data: VegetationData = new Map();
for (const [type, config] of Object.entries(VEGETATION_TYPES)) { for (const node of mapNodes) {
if (!config.enabled) continue; if (node.type !== "Object3D") continue;
if (INSTANCED_MAP_EXCEPTIONS.has(node.name)) continue;
const instances = mapNodes const modelPath = models.get(node.name);
.filter( if (!modelPath) continue;
(node) => node.name === config.mapName && node.type === "Object3D",
)
.map(mapNodeToInstance);
if (instances.length > 0) { const entry = data.get(node.name);
data.set(type as VegetationType, instances);
if (entry) {
entry.instances.push(mapNodeToInstance(node));
} else {
data.set(node.name, {
modelPath,
instances: [mapNodeToInstance(node)],
});
} }
} }
@@ -54,21 +64,10 @@ export function useVegetationData(): {
let cancelled = false; let cancelled = false;
async function load() { async function load() {
const cachedNodes = getMapNodes(); const sceneData = await loadMapSceneData();
if (cachedNodes) { if (!cancelled && sceneData) {
if (!cancelled) { setData(extractVegetationData(sceneData.mapNodes, sceneData.models));
setData(extractVegetationData(cachedNodes));
setIsLoading(false);
}
return;
}
await loadMapSceneData();
const nodes = getMapNodes();
if (!cancelled && nodes) {
setData(extractVegetationData(nodes));
setIsLoading(false); setIsLoading(false);
} }
} }
+8 -59
View File
@@ -4,62 +4,11 @@ export const VEGETATION_LOD = {
windFadeEnd: 70, windFadeEnd: 70,
}; };
export const VEGETATION_TYPES = { export const INSTANCED_MAP_EXCEPTIONS = new Set([
buissons: { "Scene",
mapName: "buisson", "blocking",
modelPath: "/models/buisson/model.gltf", "terrain",
castShadow: true, "ecole",
receiveShadow: true, "generateur",
enabled: true, "lafabrik",
windEnabled: false, ]);
windIntensity: 1.2,
},
sapin: {
mapName: "sapin",
modelPath: "/models/sapin/model.gltf",
castShadow: true,
receiveShadow: true,
enabled: true,
windEnabled: false,
windIntensity: 0.6,
},
arbre: {
mapName: "arbre",
modelPath: "/models/arbre/model.gltf",
castShadow: true,
receiveShadow: true,
enabled: true,
windEnabled: false,
windIntensity: 0.8,
},
champdeble: {
mapName: "champdeble",
modelPath: "/models/champdeble/model.gltf",
castShadow: true,
receiveShadow: true,
enabled: true,
windEnabled: false,
windIntensity: 1.0,
},
champdesoja: {
mapName: "champdesoja",
modelPath: "/models/champdesoja/model.gltf",
castShadow: true,
receiveShadow: true,
enabled: true,
windEnabled: false,
windIntensity: 1.0,
},
champsdetournesol: {
mapName: "champsdetournesol",
modelPath: "/models/champsdetournesol/model.gltf",
castShadow: true,
receiveShadow: true,
enabled: true,
windEnabled: false,
windIntensity: 0.9,
},
} as const;
export type VegetationType = keyof typeof VEGETATION_TYPES;
export type VegetationConfig = (typeof VEGETATION_TYPES)[VegetationType];