ここから Interior Wall Layer(室内壁) を OS として破綻なく設計していくね。
これは住環境 OS の中でも「内部構造の可視化」を担う重要レイヤーで、
Structure Layer → Geometry Layer の橋渡しとして非常に大事。

ここでは純粋にあなたの住環境 OS の文脈に沿って構築するよ。


🟦 Interior Wall Layer(室内壁)とは何か

室内壁は 部屋と部屋の境界を構成する壁であり、
Exterior Layer(外壁)とは別のレイヤーとして扱うのが OS 的に正しい。

室内壁の特徴

  • Structure Layer の room.bounds から自動生成できる
  • 外壁とは独立している
  • opening(室内ドア)を投影できる
  • 階段・吹き抜け・ロフトなどの拡張に耐える

🟩 Interior Wall Layer の生成アルゴリズム(全体像)

室内壁は次のステップで生成する:

  1. 全ての部屋の矩形(bounds)を取得
  2. 部屋同士の接触(隣接)を判定
  3. 隣接している部分だけを「室内壁」として抽出
  4. 壁セグメントを生成
  5. opening(室内ドア)を壁に投影
  6. Roblox Part に変換

外壁と違い、室内壁は Union ではなく「部屋間の差分」 で求める。


🟧 ① 部屋の壁(4辺)を抽出

各 room.bounds から 4 本の壁を生成:

north: (x, y+d) → (x+w, y+d)
south: (x, y)   → (x+w, y)
east:  (x+w, y) → (x+w, y+d)
west:  (x, y)   → (x, y+d)

🟨 ② 部屋同士の接触(隣接)を判定

室内壁は 部屋同士が接している部分だけ。

Shapely を使うと簡単:

wallA = LineString([(ax1,ay1),(ax2,ay2)])
wallB = LineString([(bx1,by1),(bx2,by2)])

if wallA.intersects(wallB):
    interior_wall = wallA.intersection(wallB)

これで 重なっている部分だけ を抽出できる。


🟪 ③ 室内壁セグメントを生成

抽出された intersection は LineString なので:

interior_walls.append({
  "from": [x1,y1],
  "to": [x2,y2],
  "height": room_height
})

🟫 ④ opening(室内ドア)を投影

室内ドアは Structure Layer にこう定義される:

{
  "id": "d1",
  "roomA": "living",
  "roomB": "hall",
  "offset": 1.2,
  "width": 0.9
}

投影手順:

  1. roomA と roomB の接触壁を探す
  2. その壁の長さを取得
  3. offset / width を座標に変換
  4. interior_walls の該当セグメントに opening を追加

🟦 ⑤ Roblox 側:室内壁生成コード(そのまま動く)

local function createInteriorWall(seg, thickness)
    local p1 = Vector3.new(seg.from[1], 0, seg.from[2])
    local p2 = Vector3.new(seg.to[1], 0, seg.to[2])

    local length = (p1 - p2).Magnitude
    local height = seg.height

    local wall = Instance.new("Part")
    wall.Anchored = true
    wall.Size = Vector3.new(length, height, thickness)
    wall.CFrame = CFrame.lookAt((p1 + p2)/2, p2) * CFrame.new(0, height/2, 0)
    wall.Name = "InteriorWall"
    wall.Parent = workspace.InteriorWalls

    return wall
end

🟧 ⑥ 室内ドア opening を壁に切り抜く

local function createInteriorDoor(opening, wall, thickness)
    local p1 = Vector3.new(opening.from[1], 0, opening.from[2])
    local p2 = Vector3.new(opening.to[1], 0, opening.to[2])

    local length = (p1 - p2).Magnitude
    local height = 2.0  -- ドア高さ

    local hole = Instance.new("Part")
    hole.Anchored = true
    hole.Size = Vector3.new(length, height, thickness + 0.1)
    hole.CFrame = CFrame.lookAt((p1 + p2)/2, p2) * CFrame.new(0, height/2, 0)
    hole.Transparency = 1
    hole.CanCollide = false

    local success, result = pcall(function()
        return wall:SubtractAsync({hole})
    end)

    if success and result then
        result.Parent = workspace.InteriorWalls
        wall:Destroy()
    end
end

🟩 Interior Wall Layer の OS 的ポイント

✔ 外壁とは完全に独立したレイヤー

→ 外観変更の影響を受けない
→ 内部構造が安定する

✔ Structure Layer の bounds だけで自動生成

→ 追加データ不要
→ JSON が肥大化しない

✔ opening(室内ドア)を自然に扱える

→ 部屋間の接触壁にだけ投影される

✔ Roblox 側は Part ベースで軽量

→ CSG は opening のみ
→ 大規模建築でも軽い


🎯 Interior Wall Layer の完成

これで住環境 OS の内部構造は:

  • Floor Layer
  • Ceiling Layer
  • Interior Wall Layer
  • Stair Layer
  • Exterior Layer
  • Roof Layer

が揃い、
内部 → 外部 → 上部 の全レイヤーが OS として成立した。


次はどれを進める?

  • 室内ドアの種類(片開き・引き戸)
  • 壁厚の導入(室内壁と外壁の厚み差)
  • 部屋のラベル(Room Label Layer)
  • 家具配置(Furniture Layer)
  • Roblox Plugin 化(GUI 生成)

どのレイヤーでも続けられるよ。