@pascal-app/viewer 0.1.9 → 0.1.11
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/dist/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +2 -1
- package/dist/components/renderers/scan/scan-renderer.js +2 -0
- package/dist/components/renderers/site/site-renderer.d.ts +5 -0
- package/dist/components/renderers/site/site-renderer.d.ts.map +1 -0
- package/dist/components/renderers/site/site-renderer.js +57 -0
- package/dist/hooks/use-node-events.d.ts +5 -1
- package/dist/hooks/use-node-events.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-renderer.d.ts","sourceRoot":"","sources":["../../../src/components/renderers/node-renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAY,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"node-renderer.d.ts","sourceRoot":"","sources":["../../../src/components/renderers/node-renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAY,MAAM,kBAAkB,CAAA;AAazD,eAAO,MAAM,YAAY,GAAI,YAAY;IAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,mDAoBjE,CAAA"}
|
|
@@ -8,6 +8,7 @@ import { ItemRenderer } from './item/item-renderer';
|
|
|
8
8
|
import { LevelRenderer } from './level/level-renderer';
|
|
9
9
|
import { RoofRenderer } from './roof/roof-renderer';
|
|
10
10
|
import { ScanRenderer } from './scan/scan-renderer';
|
|
11
|
+
import { SiteRenderer } from './site/site-renderer';
|
|
11
12
|
import { SlabRenderer } from './slab/slab-renderer';
|
|
12
13
|
import { WallRenderer } from './wall/wall-renderer';
|
|
13
14
|
import { ZoneRenderer } from './zone/zone-renderer';
|
|
@@ -15,5 +16,5 @@ export const NodeRenderer = ({ nodeId }) => {
|
|
|
15
16
|
const node = useScene((state) => state.nodes[nodeId]);
|
|
16
17
|
if (!node)
|
|
17
18
|
return null;
|
|
18
|
-
return (_jsxs(_Fragment, { children: [node.type === 'building' && _jsx(BuildingRenderer, { node: node }), node.type === 'ceiling' && _jsx(CeilingRenderer, { node: node }), node.type === 'level' && _jsx(LevelRenderer, { node: node }), node.type === 'item' && _jsx(ItemRenderer, { node: node }), node.type === 'slab' && _jsx(SlabRenderer, { node: node }), node.type === 'wall' && _jsx(WallRenderer, { node: node }), node.type === 'zone' && _jsx(ZoneRenderer, { node: node }), node.type === 'roof' && _jsx(RoofRenderer, { node: node }), node.type === 'scan' && _jsx(ScanRenderer, { node: node }), node.type === 'guide' && _jsx(GuideRenderer, { node: node })] }));
|
|
19
|
+
return (_jsxs(_Fragment, { children: [node.type === 'site' && _jsx(SiteRenderer, { node: node }), node.type === 'building' && _jsx(BuildingRenderer, { node: node }), node.type === 'ceiling' && _jsx(CeilingRenderer, { node: node }), node.type === 'level' && _jsx(LevelRenderer, { node: node }), node.type === 'item' && _jsx(ItemRenderer, { node: node }), node.type === 'slab' && _jsx(SlabRenderer, { node: node }), node.type === 'wall' && _jsx(WallRenderer, { node: node }), node.type === 'zone' && _jsx(ZoneRenderer, { node: node }), node.type === 'roof' && _jsx(RoofRenderer, { node: node }), node.type === 'scan' && _jsx(ScanRenderer, { node: node }), node.type === 'guide' && _jsx(GuideRenderer, { node: node })] }));
|
|
19
20
|
};
|
|
@@ -19,10 +19,12 @@ const ScanModel = ({ url, opacity }) => {
|
|
|
19
19
|
if (isTransparent) {
|
|
20
20
|
material.transparent = true;
|
|
21
21
|
material.opacity = normalizedOpacity;
|
|
22
|
+
material.depthWrite = false;
|
|
22
23
|
}
|
|
23
24
|
else {
|
|
24
25
|
material.transparent = false;
|
|
25
26
|
material.opacity = 1;
|
|
27
|
+
material.depthWrite = true;
|
|
26
28
|
}
|
|
27
29
|
material.needsUpdate = true;
|
|
28
30
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/site/site-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AAgC7D,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,mDAsExD,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRegistry } from '@pascal-app/core';
|
|
3
|
+
import { useMemo, useRef } from 'react';
|
|
4
|
+
import { BufferGeometry, DoubleSide, Float32BufferAttribute, Shape } from 'three';
|
|
5
|
+
import { useNodeEvents } from '../../../hooks/use-node-events';
|
|
6
|
+
import { NodeRenderer } from '../node-renderer';
|
|
7
|
+
const Y_OFFSET = 0.01;
|
|
8
|
+
const LINE_HEIGHT = 0.5;
|
|
9
|
+
/**
|
|
10
|
+
* Creates simple line geometry for site boundary
|
|
11
|
+
* Single horizontal line at ground level
|
|
12
|
+
*/
|
|
13
|
+
const createBoundaryLineGeometry = (points) => {
|
|
14
|
+
const geometry = new BufferGeometry();
|
|
15
|
+
if (points.length < 2)
|
|
16
|
+
return geometry;
|
|
17
|
+
const positions = [];
|
|
18
|
+
// Create a simple line loop at ground level
|
|
19
|
+
for (const [x, z] of points) {
|
|
20
|
+
positions.push(x, Y_OFFSET, z);
|
|
21
|
+
}
|
|
22
|
+
// Close the loop
|
|
23
|
+
positions.push(points[0][0], Y_OFFSET, points[0][1]);
|
|
24
|
+
geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
|
|
25
|
+
return geometry;
|
|
26
|
+
};
|
|
27
|
+
export const SiteRenderer = ({ node }) => {
|
|
28
|
+
const ref = useRef(null);
|
|
29
|
+
useRegistry(node.id, 'site', ref);
|
|
30
|
+
// Create floor shape from polygon points
|
|
31
|
+
const floorShape = useMemo(() => {
|
|
32
|
+
if (!node?.polygon?.points || node.polygon.points.length < 3)
|
|
33
|
+
return null;
|
|
34
|
+
const shape = new Shape();
|
|
35
|
+
const firstPt = node.polygon.points[0];
|
|
36
|
+
// Shape is in X-Y plane, we rotate it to X-Z plane
|
|
37
|
+
// Negate Y (which becomes Z) to get correct orientation
|
|
38
|
+
shape.moveTo(firstPt[0], -firstPt[1]);
|
|
39
|
+
for (let i = 1; i < node.polygon.points.length; i++) {
|
|
40
|
+
const pt = node.polygon.points[i];
|
|
41
|
+
shape.lineTo(pt[0], -pt[1]);
|
|
42
|
+
}
|
|
43
|
+
shape.closePath();
|
|
44
|
+
return shape;
|
|
45
|
+
}, [node?.polygon?.points]);
|
|
46
|
+
// Create boundary line geometry
|
|
47
|
+
const lineGeometry = useMemo(() => {
|
|
48
|
+
if (!node?.polygon?.points || node.polygon.points.length < 2)
|
|
49
|
+
return null;
|
|
50
|
+
return createBoundaryLineGeometry(node.polygon.points);
|
|
51
|
+
}, [node?.polygon?.points]);
|
|
52
|
+
const handlers = useNodeEvents(node, 'site');
|
|
53
|
+
if (!node || !floorShape || !lineGeometry) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return (_jsxs("group", { ref: ref, ...handlers, children: [node.children.map((child) => (_jsx(NodeRenderer, { nodeId: typeof child === 'string' ? child : child.id }, typeof child === 'string' ? child : child.id))), _jsxs("mesh", { position: [0, Y_OFFSET - 0.005, 0], rotation: [-Math.PI / 2, 0, 0], children: [_jsx("shapeGeometry", { args: [floorShape] }), _jsx("meshBasicMaterial", { color: "#f59e0b", transparent: true, opacity: 0.05, side: DoubleSide, depthWrite: false })] }), _jsx("line", { geometry: lineGeometry, frustumCulled: false, renderOrder: 9, children: _jsx("lineBasicMaterial", { color: "#f59e0b", linewidth: 2, transparent: true, opacity: 0.6 }) })] }));
|
|
57
|
+
};
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { type BuildingEvent, type BuildingNode, type CeilingEvent, type CeilingNode, type ItemEvent, type ItemNode, type LevelEvent, type LevelNode, type RoofEvent, type RoofNode, type SlabEvent, type SlabNode, type WallEvent, type WallNode, type ZoneEvent, type ZoneNode } from '@pascal-app/core';
|
|
1
|
+
import { type BuildingEvent, type BuildingNode, type CeilingEvent, type CeilingNode, type ItemEvent, type ItemNode, type LevelEvent, type LevelNode, type RoofEvent, type RoofNode, type SiteEvent, type SiteNode, type SlabEvent, type SlabNode, type WallEvent, type WallNode, type ZoneEvent, type ZoneNode } from '@pascal-app/core';
|
|
2
2
|
import type { ThreeEvent } from '@react-three/fiber';
|
|
3
3
|
type NodeConfig = {
|
|
4
|
+
site: {
|
|
5
|
+
node: SiteNode;
|
|
6
|
+
event: SiteEvent;
|
|
7
|
+
};
|
|
4
8
|
item: {
|
|
5
9
|
node: ItemNode;
|
|
6
10
|
event: ItemEvent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-node-events.d.ts","sourceRoot":"","sources":["../../src/hooks/use-node-events.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,WAAW,EAGhB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAC1C,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAC1C,QAAQ,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,aAAa,CAAA;KAAE,CAAA;IACtD,KAAK,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAA;IAC7C,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAC1C,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAC1C,OAAO,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAA;IACnD,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;CAC3C,CAAA;AAED,KAAK,QAAQ,GAAG,MAAM,UAAU,CAAA;AAEhC,wBAAgB,aAAa,CAAC,CAAC,SAAS,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC;uBAiB/D,UAAU,CAAC,YAAY,CAAC;qBAI1B,UAAU,CAAC,YAAY,CAAC;iBAI5B,UAAU,CAAC,YAAY,CAAC;wBAIjB,UAAU,CAAC,YAAY,CAAC;wBACxB,UAAU,CAAC,YAAY,CAAC;uBACzB,UAAU,CAAC,YAAY,CAAC;uBACxB,UAAU,CAAC,YAAY,CAAC;uBACxB,UAAU,CAAC,YAAY,CAAC;EAE9C"}
|
|
1
|
+
{"version":3,"file":"use-node-events.d.ts","sourceRoot":"","sources":["../../src/hooks/use-node-events.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,WAAW,EAGhB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAC1C,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAC1C,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAC1C,QAAQ,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,aAAa,CAAA;KAAE,CAAA;IACtD,KAAK,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAA;IAC7C,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAC1C,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAC1C,OAAO,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAA;IACnD,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;CAC3C,CAAA;AAED,KAAK,QAAQ,GAAG,MAAM,UAAU,CAAA;AAEhC,wBAAgB,aAAa,CAAC,CAAC,SAAS,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC;uBAiB/D,UAAU,CAAC,YAAY,CAAC;qBAI1B,UAAU,CAAC,YAAY,CAAC;iBAI5B,UAAU,CAAC,YAAY,CAAC;wBAIjB,UAAU,CAAC,YAAY,CAAC;wBACxB,UAAU,CAAC,YAAY,CAAC;uBACzB,UAAU,CAAC,YAAY,CAAC;uBACxB,UAAU,CAAC,YAAY,CAAC;uBACxB,UAAU,CAAC,YAAY,CAAC;EAE9C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pascal-app/viewer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "3D viewer component for Pascal building editor",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "tsc --
|
|
21
|
-
"dev": "tsc --
|
|
20
|
+
"build": "tsc --build",
|
|
21
|
+
"dev": "tsc --build --watch",
|
|
22
22
|
"prepublishOnly": "npm run build"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|