@adatechnology/game-floorplan-three 0.0.0-stage → 0.1.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anderson Fernandes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/MIGRATION.md ADDED
@@ -0,0 +1,118 @@
1
+ # Migration: Casa3DSDK and AndaresSDK (Visor de casas 3D) to `@adatechnology/game-floorplan-three`
2
+
3
+ The port is literal: the geometry, the draws and the seeded random of `Casa3DSDK.construir` are the team's. Only names changed (English API, texts in `locales`), and
4
+ what the page injected through globals is now an option. The scene equals the page's, node by node, for six plans (`tests/golden-scene.test.ts`, which maps the new ids to the
5
+ legacy ones through `seedKey`), and the level of detail planner gives the same levels in 25 situations.
6
+
7
+ ## Entry point
8
+
9
+ | Visor de casas 3D | SDK |
10
+ |---|---|
11
+ | `Casa3DSDK.criar(THREE, cfg)` | `create(THREE, options)` (alias `createHouseRenderer`) |
12
+ | `sdk.construir(res, opts)` | `renderer.build(plan, options)` |
13
+ | `sdk.novoEstado()` | `renderer.newState()` |
14
+ | `sdk.tipos`, `sdk.mv` | `renderer.types` (type to `{ f, source }`), `renderer.mv` (the props module) |
15
+ | `sdk.aplicaParte(grupo, t)` | `renderer.applyPart(group, t)` |
16
+ | `sdk.materiais`, `sdk.mascaraLuz`, `sdk.iluminacao` | `renderer.materials`, `renderer.roomLightMask`, `renderer.lighting` |
17
+ | `sdk.definirNoite(n)` | `renderer.setNight(night)` |
18
+ | `sdk.carros.{modelo,grupo,info}` | `renderer.cars.{model,group,info}` (`info` returns `{ parts, tris, L, W, H }`) |
19
+ | `Casa3DSDK.planejaLOD(casas, foco, orcamento)` | `planLod(houses, focus, budget)` returns `{ total, levels, houses }` |
20
+
21
+ ## Options (`cfg` of `criar`)
22
+
23
+ | VC3 | SDK |
24
+ |---|---|
25
+ | `document` | `document` |
26
+ | `qualidade` `'alta'` / `'jogo'` | `quality` `'high'` / `'game'` |
27
+ | `Moveis3DSDK` | `props` (default: `@adatechnology/game-props3d`) |
28
+ | `Reflector` | `reflector` |
29
+ | `frota` | `fleet` |
30
+ | (fixed lists of car models per lot style) | `carKinds` (`budget`, `mid`, `high`; ids of `game-vehicles-fleet`) |
31
+ | `hp` | `hp` |
32
+ | `texturas`, `atlas`, `materiais` | `textures`, `atlas`, `materials` |
33
+ | `destruicao` (world) | `destruction` (world of `game-destruction`) |
34
+ | (the page's own fragment drawing) | `destructionRenderer` (`game-destruction-three`) draws fracture, fragments, spalls and the rebar cage |
35
+ | `interativos` | `interactives` |
36
+ | `vegetacao` | `vegetation` |
37
+ | `lod` `{ interior, ocultar }` | `lod` `{ interior, hide }`, or `false` |
38
+ | `orcamentoDrawCalls` | `drawCallBudget` |
39
+ | `onMudou`, `onColisor`, `onDano`, `onEstrago`, `onInteragir`, `onLuz`, `onMensagem` | `onChange`, `onCollider`, `onDamage`, `onWreck`, `onInteract`, `onLight`, `onMessage` |
40
+ | (ids of the page's plan feed the seeded random) | `seedKey(id)` |
41
+ | (texts in Portuguese in the code) | `locale` (`'en'`, `'pt-BR'` or a table) |
42
+
43
+ ## Build options (`opts` of `construir`)
44
+
45
+ | VC3 | SDK |
46
+ |---|---|
47
+ | `qualidade` | `quality` |
48
+ | `noite` | `night` |
49
+ | `corte` | `cut` |
50
+ | `estado` | `state` |
51
+ | `terreno: false` | `terrain: false` |
52
+ | `semPerimetro` | `noPerimeter` |
53
+ | `pecas: 'malhas'` | `pieces: 'meshes'` |
54
+ | `predio` `{ andares, andar, unidade, mostrarPredio }` | `building` `{ floors, floor, unit, showBuilding }` |
55
+ | `orcamentoDrawCalls` | `drawCallBudget` |
56
+
57
+ ## The house (result of `construir`)
58
+
59
+ | VC3 | SDK | VC3 | SDK |
60
+ |---|---|---|---|
61
+ | `versao` | `version` | `grupo` | `group` |
62
+ | `casa` | `house` | `grupos` | `groups` (`f0`, `f1`, `t1`, `roof`, `lot`...) |
63
+ | `andares` | `floors` | `forros` | `ceilings` |
64
+ | `telhado` | `roof` | `lote` | `lot` |
65
+ | `chao` | `ground` | `predio` | `building` |
66
+ | `caixaDagua` `{ parte, grupo, pos, planta }` | `waterTank` `{ part, group, pos, plant }` | `colisores` | `colliders` |
67
+ | `partes` | `parts` | `carros` | `cars` |
68
+ | `interagiveis` | `interactables` | `portas` | `doors` |
69
+ | `escadas` | `stairs` | `rotulos` | `labels` |
70
+ | `semModelo` | `noModel` | `luzes` `{ lista, porComodo }` | `lights` `{ list, byRoom }` |
71
+ | `limites` | `limits` | `apt` | `apartment` |
72
+ | `mostraPredio` | `showBuilding` | `predioCfg` `{ andares, andar, unidade }` | `buildingConfig` `{ floors, floor, unit }` |
73
+ | `unidadeRy` | `unitRy` | `noite`, `corte` | `night`, `cut` |
74
+ | `interativos` | `interactives` | `estado` | `state` |
75
+ | `vegetacao`, `solar`, `agua`, `eletrica`, `calhas` | `vegetation`, `solar`, `water`, `electrical`, `gutters` | `estrutura` | `structure` |
76
+ | `destruicao` | `destruction` | `interno` | `internal` |
77
+
78
+ Methods: `atualiza(dt, tempo, foco)` is `update(dt, time, focus)`; `mostra({ andar, corte, lote })` is `show({ floor, cut, lot })`; `alvo` is `target`; `interage` is `interact`;
79
+ `mensagem` is `message`; `alternaPorta` is `toggleDoor`; `luzLigada` is `lightOn`; `alternaLuz` is `toggleLight`; `colide` is `collide`; `comodoEm` is `roomAt`;
80
+ `escolheEspelho` is `chooseMirror`; `definirLOD` is `setLod`; `centro` is `center`; `distancia` is `distance`; `dano` is `damage`; `danoColisor` is `colliderDamage`;
81
+ `parteDe(obj)` is `partOf(object)`; `parteEm(p, tol)` is `partAt(point, tolerance)`; `descartar` is `dispose`.
82
+
83
+ A door of `house.doors`: `{ id, andar, tipo ('aco' or 'giro'), aberta, t, bloq, trancada, macNomes, hT, cx, cz, visH, grupos, col }` is `{ id, floor, type ('steel' or 'swing'), open, t, blockedFlag, locked, handleNames, hT, cx, cz, visH, groups, col }`.
84
+
85
+ ## Names of parts, groups and lights
86
+
87
+ | VC3 | SDK | VC3 | SDK |
88
+ |---|---|---|---|
89
+ | `porta:<id>` | `door:<id>` | `janela:<id>` | `window:<id>` |
90
+ | `espelho:<n>` | `mirror:<n>` | `carro:<n>:<zone>:<n>` | `car:<n>:<zone>:<n>` |
91
+ | `torn_<seed>_<n>` (tap) | `tap_<seed>_<n>` | `chuv_<seed>` (shower) | `shower_<seed>` |
92
+ | `correio_<seed>` | `mailbox_<seed>` | `roupas_<seed>` | `laundry_<seed>` |
93
+ | `botijao_<seed>` | `gas_cylinder_<seed>` | `caixa_<seed>` | `tank_<seed>` |
94
+ | `tabuas:<id>` | `boards:<id>` | `disjuntor_<n>` | `breaker_<n>` |
95
+ | light type `externa` | `outdoor` | `ix:`, `lamp_`, `lp_`, `sw_`, `lamp_ab_`, `lamp_ar_`, `lamp_ext_`, `lamp_pe_` | the same (they feed the seeded random) |
96
+ | mesh groups `chapisco`, `reboco`, `calcada`, `madeira`, `vidro`, `telha`, `liso`, `lote/...` | `roughcast`, `plaster`, `sidewalk`, `wood`, `glass`, `tile`, `plain`, `lot/...` | `fonte` of a type (`moveis3d`, `jogo`) | `source` (`props3d`, `game`) |
97
+
98
+ The salts of the seeded random (`'|varal'`, `'|luz'`, `'|temp'`, `'|veg'`...) are kept as the team wrote them: changing one changes the scene.
99
+
100
+ ## Messages
101
+
102
+ All the texts the house shows are in `locales` (`en`, `pt-BR`): `prompt.*` (E: abrir a porta...), `what.*`, `message.*`, `outbuilding.*`, `warn.interactablesIncomplete`.
103
+
104
+ ## AndaresSDK
105
+
106
+ | AndaresSDK | SDK |
107
+ |---|---|
108
+ | `AndaresSDK.criar()` | `createFloorNavigator()` |
109
+ | `registra({ id, andares: [{ y, h, solidos }], escadas, grupos, telhado, proprio })` | `register({ id, floors: [{ y, h, solids }], stairs, groups, roof, own })` |
110
+ | `casaEm`, `bloqueio(x, z, andar)`, `nivel`, `ponta`, `escadaPara`, `rumo`, `raio`, `tetoDe`, `oclui`, `cel` | `houseAt`, `blocked`, `level`, `landing`, `stairTo`, `heading`, `ray`, `ceilingOf`, `occlude`, `cell` |
111
+ | `aplica(casa, andar)` (internal) | `apply(house, floor)` |
112
+ | (new, T2.4d) | `openCells`, `closeCells`, `undoChanges`, `houseOf` |
113
+ | (new, T2.4d) | `navigationDefOf(house, options)`: the registration of a built house; `bindNavigator(navigator, id, house)`: follows the destruction |
114
+
115
+ ## What is not here
116
+
117
+ - `AdaptadorInterativos` (plan to objects of the interactables kit) is game code by its own header. The `interactives` option takes the adapter from the game.
118
+ - The globals of the page (`Moveis3DSDK`, `FrotaLeve`, `Reflector`...) are options now.
package/README.md CHANGED
@@ -1,3 +1,102 @@
1
- # Temporary Holding Version
1
+ # @adatechnology/game-floorplan-three
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The three.js renderer of `@adatechnology/game-floorplan`: it draws a generated plan as a house (walls, doors, windows, floors, slabs, stairs, roofs, gutters, lot,
4
+ furniture, lights, mirrors, cars, utilities) and binds it to the destruction of its structure. It is the port of the team's `Casa3DSDK` (Visor de casas 3D) and
5
+ `AndaresSDK` (floor navigator), literally: same geometry, same draws, same seeded random, so a plan looks the same as on the team's page
6
+ (`tests/golden-scene.test.ts` compares the scene node by node with the page's, for six plans).
7
+
8
+ ```ts
9
+ import * as THREE from 'three'
10
+ import { engine } from '@adatechnology/game-floorplan'
11
+ import { register as residential } from '@adatechnology/game-floorplan-residential'
12
+ import { register as structure } from '@adatechnology/game-floorplan-structure'
13
+ import { createDestruction } from '@adatechnology/game-destruction'
14
+ import { createDestructionRenderer } from '@adatechnology/game-destruction-three'
15
+ import { create } from '@adatechnology/game-floorplan-three'
16
+
17
+ residential(engine, { region: 'br' })
18
+ structure(engine)
19
+ const plan = engine.generate('townhouse', { seed: 7, state: 'normal' })
20
+
21
+ const world = createDestruction({ seed: 1 })
22
+ const scene = new THREE.Scene()
23
+ const renderer = create(THREE, {
24
+ destruction: world,
25
+ destructionRenderer: createDestructionRenderer(THREE, { scene, world }),
26
+ fleet, // optional: { build(kind, { quality, seed }) } of game-vehicles-fleet
27
+ locale: 'en', // or 'pt-BR', or a table of messages
28
+ })
29
+ const house = renderer.build(plan, { quality: 'high', night: false })
30
+ scene.add(house.group)
31
+
32
+ // every frame
33
+ house.update(dt, performance.now(), camera.position) // doors, laundry, wind, distance LOD
34
+ ```
35
+
36
+ ## What it draws
37
+
38
+ | Part | Where |
39
+ |---|---|
40
+ | walls, doors, windows, floors, slabs, stairs, baseboards, outbuildings, building shell | `house.floors[i]` (one group per floor), `house.doors`, `house.stairs` |
41
+ | lot: ground, street, sidewalk, lot wall, gates, zones, fence | `house.lot` |
42
+ | roof, tiles, gutters | `house.roof`, `house.gutters` |
43
+ | furniture (`game-props3d` plus the house's own builders) | in the floor groups, merged by material; `renderer.types` is the map |
44
+ | lamps, switches, room lights | `house.lights`, `house.toggleLight(room)` |
45
+ | mirrors (the nearest one reflects when the camera is in its room) | `house.chooseMirror(camera)` |
46
+ | cars (needs a `fleet`) | `house.cars`, `renderer.cars` |
47
+ | solar panels, water, electrical, pipes | `house.solar`, `house.water`, `house.electrical` |
48
+
49
+ `house.group` is the root. Everything is merged to one mesh per group and material (a draw call each); only what moves stays apart.
50
+
51
+ ## Bound to the destruction
52
+
53
+ With `destruction` (a world of `game-destruction`) and `destructionRenderer` (`game-destruction-three`), the house registers itself in the world on first need
54
+ (`house.destruction.activate()`, or the first hit through `house.damage`):
55
+
56
+ - **One part per wall**, with the assembly of its masonry (units, breach, layers) and **the rebar of reinforced concrete on slabs, beams, pillars and stairs**.
57
+ - **A vertex range per piece.** Every wall, slab, window, door... knows its range in the merged mesh (`house.structure.meshesOf(id)`); the renderer's `bind` gets them,
58
+ so fracture and collapse hide the range and the renderer lets the fragments fall. `house.destruction.reset()` puts everything back.
59
+ - **Brick courses at LOD 0.** A masonry wall that reaches stage 2 stops being a box: its range collapses and it is drawn again as instanced units (running bond,
60
+ one instance per unit) without the ones inside the opening; the units around the edge show the bare brick. At LOD 1 and 2 the box comes back.
61
+ - **Spall decal and rebar cage** come from the destruction renderer (decals on hits, instanced bars when the concrete is exposed).
62
+ - `house.damage(id, point, type, amount)` keeps the legacy behaviour (hp of the part, `onDamage`) and becomes a hit in the world.
63
+
64
+ ## Floor navigator
65
+
66
+ `createFloorNavigator()` is the team's AndaresSDK: a 10 cm grid per floor, stairs with banisters and U-turns, path fields, occlusion of the floors above.
67
+
68
+ ```ts
69
+ import { createFloorNavigator, navigationDefOf, bindNavigator } from '@adatechnology/game-floorplan-three'
70
+
71
+ const navigator = createFloorNavigator()
72
+ navigator.register(navigationDefOf(house, { id: 'home', own: true })) // heights, wall colliders, flights, floor groups
73
+ const binding = bindNavigator(navigator, 'home', house) // wall stage 2 opens cells; a wall or slab that falls changes the grid
74
+ navigator.blocked(x, z, floor) // 1 blocked, 0 free, -1 use the ground grid
75
+ ```
76
+
77
+ ## Injected, never read from globals
78
+
79
+ | Option | What |
80
+ |---|---|
81
+ | `fleet` | cars (`game-vehicles-fleet`) |
82
+ | `reflector` | `THREE.Reflector` for the mirrors |
83
+ | `props` | `game-props3d` (default: the package's dependency) |
84
+ | `interactives` | `{ GameInteractables, GameInteractablesHousehold, GameInteractablesThree, adapter }`: the interactable kit in place of the static furniture. The adapter (plan to kit objects) is game code, not part of this package. |
85
+ | `vegetation` | `{ GameVegetation: { ...core, ...three }, GameVegetationSpecies }` |
86
+ | `textures`, `atlas`, `materials` | the app's replacements |
87
+ | `seedKey` | maps an id of the plan to the key its seeded draws use (to reproduce a scene drawn with other ids) |
88
+
89
+ Everything the house says to the player (prompts, messages) is in `locales` (`en`, `pt-BR`).
90
+
91
+ ## Build
92
+
93
+ `dist/index.js` (ESM, three.js and the other packages external), `dist/index.d.ts`, and `dist/index.global.js` exposing `GameFloorplanThree` (three.js is the page's own `THREE`).
94
+
95
+ See `.claude/skills/game-floorplan-three/SKILL.md` for the API and `MIGRATION.md` for the Portuguese names the Visor de casas 3D used.
96
+
97
+ ## Em português
98
+
99
+ Desenho em three.js das plantas do `game-floorplan`: porte literal do `Casa3DSDK` (Visor de casas 3D) e do `AndaresSDK` (navegação por andares). Paredes, portas, janelas,
100
+ pisos, lajes, escadas, telhado, calhas, lote, móveis, luzes, espelhos e carros; cada peça sabe a faixa de vértices que ocupa na malha fundida para a destruição
101
+ (fratura, colapso, fileiras de tijolo no LOD 0, decalque de lascamento e armadura aparente). Os pacotes (frota, interativos, vegetação, espelho) são injetados. Os
102
+ textos vêm de `locales` (`en`, `pt-BR`).