@glyphcss/react 0.0.5 → 0.0.7

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/index.cjs CHANGED
@@ -303,12 +303,14 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
303
303
  function GlyphMeshInner({
304
304
  id,
305
305
  polygons: polygonsProp,
306
+ src,
306
307
  geometry,
307
308
  size = 1,
308
309
  color,
309
310
  position,
310
311
  scale,
311
312
  rotation,
313
+ autoCenter = false,
312
314
  castShadow = false,
313
315
  receiveShadow = false,
314
316
  className,
@@ -318,11 +320,26 @@ function GlyphMeshInner({
318
320
  const { sceneRef } = useGlyphSceneContext();
319
321
  const meshRef = (0, import_react4.useRef)(null);
320
322
  const wrapperRef = (0, import_react4.useRef)(null);
323
+ const [loadedPolygons, setLoadedPolygons] = (0, import_react4.useState)(null);
324
+ (0, import_react4.useEffect)(() => {
325
+ if (!src) {
326
+ setLoadedPolygons(null);
327
+ return;
328
+ }
329
+ let cancelled = false;
330
+ (0, import_core.loadMesh)(src).then((result) => {
331
+ if (!cancelled) setLoadedPolygons(result.polygons);
332
+ }).catch(() => {
333
+ if (!cancelled) setLoadedPolygons([]);
334
+ });
335
+ return () => {
336
+ cancelled = true;
337
+ };
338
+ }, [src]);
321
339
  const polygons = (0, import_react4.useMemo)(() => {
322
- if (polygonsProp !== void 0) return polygonsProp;
323
- if (geometry !== void 0) return (0, import_core.resolveGeometry)(geometry, { size, color });
324
- return [];
325
- }, [polygonsProp, geometry, size, color]);
340
+ const base = polygonsProp !== void 0 ? polygonsProp : src !== void 0 ? loadedPolygons ?? [] : geometry !== void 0 ? (0, import_core.resolveGeometry)(geometry, { size, color }) : [];
341
+ return autoCenter ? (0, import_core.recenterPolygons)(base) : base;
342
+ }, [polygonsProp, src, loadedPolygons, geometry, size, color, autoCenter]);
326
343
  const transform = (0, import_react4.useMemo)(() => ({
327
344
  id,
328
345
  position,
@@ -683,28 +700,15 @@ function GlyphMapControls({
683
700
  // src/glyphcss/controls/GlyphFirstPersonControls.tsx
684
701
  var import_react13 = require("react");
685
702
  var import_glyphcss7 = require("glyphcss");
686
- function GlyphFirstPersonControls({
687
- drag = true,
688
- keyboard = true,
689
- moveSpeed = 0.05,
690
- lookSpeed = 4e-3,
691
- invert = false
692
- }) {
703
+ function GlyphFirstPersonControls(props) {
693
704
  const { sceneRef } = useGlyphSceneContext();
694
705
  const controlsRef = (0, import_react13.useRef)(null);
695
- const propsRef = (0, import_react13.useRef)({ drag, keyboard, moveSpeed, lookSpeed, invert });
696
- propsRef.current = { drag, keyboard, moveSpeed, lookSpeed, invert };
706
+ const propsRef = (0, import_react13.useRef)(props);
707
+ propsRef.current = props;
697
708
  (0, import_react13.useEffect)(() => {
698
709
  const scene = sceneRef.current;
699
710
  if (!scene) return;
700
- const opts = {
701
- drag: propsRef.current.drag,
702
- keyboard: propsRef.current.keyboard,
703
- moveSpeed: propsRef.current.moveSpeed,
704
- lookSpeed: propsRef.current.lookSpeed,
705
- invert: propsRef.current.invert
706
- };
707
- const controls = (0, import_glyphcss7.createGlyphFirstPersonControls)(scene, opts);
711
+ const controls = (0, import_glyphcss7.createGlyphFirstPersonControls)(scene, propsRef.current);
708
712
  controlsRef.current = controls;
709
713
  return () => {
710
714
  controls.destroy();
@@ -712,9 +716,7 @@ function GlyphFirstPersonControls({
712
716
  };
713
717
  }, [sceneRef]);
714
718
  (0, import_react13.useEffect)(() => {
715
- const controls = controlsRef.current;
716
- if (!controls) return;
717
- controls.update({ drag, keyboard, moveSpeed, lookSpeed, invert });
719
+ controlsRef.current?.update(props);
718
720
  });
719
721
  return null;
720
722
  }
package/dist/index.d.cts CHANGED
@@ -43,6 +43,8 @@ declare const GlyphScene: react.MemoExoticComponent<typeof GlyphSceneInner>;
43
43
  interface GlyphMeshProps {
44
44
  id?: string;
45
45
  polygons?: Polygon[];
46
+ /** URL of an OBJ / GLB / glTF / VOX / STL mesh, fetched + parsed via `loadMesh`. */
47
+ src?: string;
46
48
  /**
47
49
  * Built-in geometry name. Resolved via `resolveGeometry` when neither
48
50
  * `polygons` nor `src` is provided.
@@ -57,6 +59,11 @@ interface GlyphMeshProps {
57
59
  position?: Vec3;
58
60
  scale?: number | Vec3;
59
61
  rotation?: Vec3;
62
+ /**
63
+ * Recenter the mesh's bounding-box center to the origin so it pivots around
64
+ * its own center (center only, no scaling — matches voxcss). Default false.
65
+ */
66
+ autoCenter?: boolean;
60
67
  /**
61
68
  * This mesh casts shadows onto `receiveShadow` surfaces.
62
69
  * Default false — opt-in, matching PolyMesh behaviour.
@@ -79,7 +86,7 @@ interface GlyphMeshProps {
79
86
  onClick?: (event: GlyphMouseEvent) => void;
80
87
  onWheel?: (event: GlyphWheelEvent) => void;
81
88
  }
82
- declare function GlyphMeshInner({ id, polygons: polygonsProp, geometry, size, color, position, scale, rotation, castShadow, receiveShadow, className, style, children, }: GlyphMeshProps): react_jsx_runtime.JSX.Element;
89
+ declare function GlyphMeshInner({ id, polygons: polygonsProp, src, geometry, size, color, position, scale, rotation, autoCenter, castShadow, receiveShadow, className, style, children, }: GlyphMeshProps): react_jsx_runtime.JSX.Element;
83
90
  declare const GlyphMesh: react.MemoExoticComponent<typeof GlyphMeshInner>;
84
91
 
85
92
  interface GlyphGroundProps {
@@ -229,13 +236,23 @@ interface GlyphMapControlsProps {
229
236
  declare function GlyphMapControls({ drag, wheel, invert, animate, }: GlyphMapControlsProps): null;
230
237
 
231
238
  interface GlyphFirstPersonControlsProps {
232
- drag?: boolean;
233
- keyboard?: boolean;
239
+ enabled?: boolean;
240
+ lookEnabled?: boolean;
241
+ moveEnabled?: boolean;
242
+ jumpEnabled?: boolean;
243
+ crouchEnabled?: boolean;
244
+ lookSensitivity?: number;
245
+ invertY?: boolean;
234
246
  moveSpeed?: number;
235
- lookSpeed?: number;
236
- invert?: boolean | number;
247
+ jumpVelocity?: number;
248
+ gravity?: number;
249
+ eyeHeight?: number;
250
+ crouchHeight?: number;
251
+ groundZ?: number;
252
+ minPitch?: number;
253
+ maxPitch?: number;
237
254
  }
238
- declare function GlyphFirstPersonControls({ drag, keyboard, moveSpeed, lookSpeed, invert, }: GlyphFirstPersonControlsProps): null;
255
+ declare function GlyphFirstPersonControls(props: GlyphFirstPersonControlsProps): null;
239
256
 
240
257
  interface GlyphAxesHelperProps {
241
258
  /** Length of each axis bar in world units. Default 1. */
package/dist/index.d.ts CHANGED
@@ -43,6 +43,8 @@ declare const GlyphScene: react.MemoExoticComponent<typeof GlyphSceneInner>;
43
43
  interface GlyphMeshProps {
44
44
  id?: string;
45
45
  polygons?: Polygon[];
46
+ /** URL of an OBJ / GLB / glTF / VOX / STL mesh, fetched + parsed via `loadMesh`. */
47
+ src?: string;
46
48
  /**
47
49
  * Built-in geometry name. Resolved via `resolveGeometry` when neither
48
50
  * `polygons` nor `src` is provided.
@@ -57,6 +59,11 @@ interface GlyphMeshProps {
57
59
  position?: Vec3;
58
60
  scale?: number | Vec3;
59
61
  rotation?: Vec3;
62
+ /**
63
+ * Recenter the mesh's bounding-box center to the origin so it pivots around
64
+ * its own center (center only, no scaling — matches voxcss). Default false.
65
+ */
66
+ autoCenter?: boolean;
60
67
  /**
61
68
  * This mesh casts shadows onto `receiveShadow` surfaces.
62
69
  * Default false — opt-in, matching PolyMesh behaviour.
@@ -79,7 +86,7 @@ interface GlyphMeshProps {
79
86
  onClick?: (event: GlyphMouseEvent) => void;
80
87
  onWheel?: (event: GlyphWheelEvent) => void;
81
88
  }
82
- declare function GlyphMeshInner({ id, polygons: polygonsProp, geometry, size, color, position, scale, rotation, castShadow, receiveShadow, className, style, children, }: GlyphMeshProps): react_jsx_runtime.JSX.Element;
89
+ declare function GlyphMeshInner({ id, polygons: polygonsProp, src, geometry, size, color, position, scale, rotation, autoCenter, castShadow, receiveShadow, className, style, children, }: GlyphMeshProps): react_jsx_runtime.JSX.Element;
83
90
  declare const GlyphMesh: react.MemoExoticComponent<typeof GlyphMeshInner>;
84
91
 
85
92
  interface GlyphGroundProps {
@@ -229,13 +236,23 @@ interface GlyphMapControlsProps {
229
236
  declare function GlyphMapControls({ drag, wheel, invert, animate, }: GlyphMapControlsProps): null;
230
237
 
231
238
  interface GlyphFirstPersonControlsProps {
232
- drag?: boolean;
233
- keyboard?: boolean;
239
+ enabled?: boolean;
240
+ lookEnabled?: boolean;
241
+ moveEnabled?: boolean;
242
+ jumpEnabled?: boolean;
243
+ crouchEnabled?: boolean;
244
+ lookSensitivity?: number;
245
+ invertY?: boolean;
234
246
  moveSpeed?: number;
235
- lookSpeed?: number;
236
- invert?: boolean | number;
247
+ jumpVelocity?: number;
248
+ gravity?: number;
249
+ eyeHeight?: number;
250
+ crouchHeight?: number;
251
+ groundZ?: number;
252
+ minPitch?: number;
253
+ maxPitch?: number;
237
254
  }
238
- declare function GlyphFirstPersonControls({ drag, keyboard, moveSpeed, lookSpeed, invert, }: GlyphFirstPersonControlsProps): null;
255
+ declare function GlyphFirstPersonControls(props: GlyphFirstPersonControlsProps): null;
239
256
 
240
257
  interface GlyphAxesHelperProps {
241
258
  /** Length of each axis bar in world units. Default 1. */
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  parseGltf,
24
24
  bakeSolidTextureSamples,
25
25
  bakeSolidTextureSampledPolygons,
26
- loadMesh,
26
+ loadMesh as loadMesh2,
27
27
  createIsometricCamera,
28
28
  parseVox,
29
29
  polygonFaces,
@@ -213,8 +213,8 @@ function GlyphSceneInner({
213
213
  var GlyphScene = memo(GlyphSceneInner);
214
214
 
215
215
  // src/glyphcss/scene/GlyphMesh.tsx
216
- import { memo as memo2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2 } from "react";
217
- import { resolveGeometry } from "@glyphcss/core";
216
+ import { memo as memo2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState } from "react";
217
+ import { resolveGeometry, recenterPolygons, loadMesh } from "@glyphcss/core";
218
218
 
219
219
  // src/glyphcss/scene/events.ts
220
220
  var MESH_REGISTRY = /* @__PURE__ */ new WeakMap();
@@ -259,12 +259,14 @@ import { jsx as jsx2 } from "react/jsx-runtime";
259
259
  function GlyphMeshInner({
260
260
  id,
261
261
  polygons: polygonsProp,
262
+ src,
262
263
  geometry,
263
264
  size = 1,
264
265
  color,
265
266
  position,
266
267
  scale,
267
268
  rotation,
269
+ autoCenter = false,
268
270
  castShadow = false,
269
271
  receiveShadow = false,
270
272
  className,
@@ -274,11 +276,26 @@ function GlyphMeshInner({
274
276
  const { sceneRef } = useGlyphSceneContext();
275
277
  const meshRef = useRef2(null);
276
278
  const wrapperRef = useRef2(null);
279
+ const [loadedPolygons, setLoadedPolygons] = useState(null);
280
+ useEffect2(() => {
281
+ if (!src) {
282
+ setLoadedPolygons(null);
283
+ return;
284
+ }
285
+ let cancelled = false;
286
+ loadMesh(src).then((result) => {
287
+ if (!cancelled) setLoadedPolygons(result.polygons);
288
+ }).catch(() => {
289
+ if (!cancelled) setLoadedPolygons([]);
290
+ });
291
+ return () => {
292
+ cancelled = true;
293
+ };
294
+ }, [src]);
277
295
  const polygons = useMemo2(() => {
278
- if (polygonsProp !== void 0) return polygonsProp;
279
- if (geometry !== void 0) return resolveGeometry(geometry, { size, color });
280
- return [];
281
- }, [polygonsProp, geometry, size, color]);
296
+ const base = polygonsProp !== void 0 ? polygonsProp : src !== void 0 ? loadedPolygons ?? [] : geometry !== void 0 ? resolveGeometry(geometry, { size, color }) : [];
297
+ return autoCenter ? recenterPolygons(base) : base;
298
+ }, [polygonsProp, src, loadedPolygons, geometry, size, color, autoCenter]);
282
299
  const transform = useMemo2(() => ({
283
300
  id,
284
301
  position,
@@ -365,7 +382,7 @@ function GlyphGroundInner({
365
382
  var GlyphGround = memo3(GlyphGroundInner);
366
383
 
367
384
  // src/glyphcss/scene/GlyphHotspot.tsx
368
- import { memo as memo4, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState } from "react";
385
+ import { memo as memo4, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState2 } from "react";
369
386
  import { createPortal } from "react-dom";
370
387
  function GlyphHotspotInner({
371
388
  id,
@@ -379,7 +396,7 @@ function GlyphHotspotInner({
379
396
  const hotspotRef = useRef3(null);
380
397
  const onClickRef = useRef3(onClick);
381
398
  onClickRef.current = onClick;
382
- const [overlayEl, setOverlayEl] = useState(null);
399
+ const [overlayEl, setOverlayEl] = useState2(null);
383
400
  const atKey = useMemo4(() => at.join(","), [at]);
384
401
  const sizeKey = size ? size.join(",") : "";
385
402
  useEffect3(() => {
@@ -414,11 +431,11 @@ function GlyphHotspotInner({
414
431
  var GlyphHotspot = memo4(GlyphHotspotInner);
415
432
 
416
433
  // src/glyphcss/scene/useGlyphMesh.ts
417
- import { useEffect as useEffect4, useRef as useRef4, useState as useState2 } from "react";
434
+ import { useEffect as useEffect4, useRef as useRef4, useState as useState3 } from "react";
418
435
  function useGlyphMesh(polygons, options) {
419
436
  const { sceneRef } = useGlyphSceneContext();
420
437
  const meshRef = useRef4(null);
421
- const [loading] = useState2(false);
438
+ const [loading] = useState3(false);
422
439
  useEffect4(() => {
423
440
  const scene = sceneRef.current;
424
441
  if (!scene) return;
@@ -639,28 +656,15 @@ function GlyphMapControls({
639
656
  // src/glyphcss/controls/GlyphFirstPersonControls.tsx
640
657
  import { useEffect as useEffect9, useRef as useRef10 } from "react";
641
658
  import { createGlyphFirstPersonControls } from "glyphcss";
642
- function GlyphFirstPersonControls({
643
- drag = true,
644
- keyboard = true,
645
- moveSpeed = 0.05,
646
- lookSpeed = 4e-3,
647
- invert = false
648
- }) {
659
+ function GlyphFirstPersonControls(props) {
649
660
  const { sceneRef } = useGlyphSceneContext();
650
661
  const controlsRef = useRef10(null);
651
- const propsRef = useRef10({ drag, keyboard, moveSpeed, lookSpeed, invert });
652
- propsRef.current = { drag, keyboard, moveSpeed, lookSpeed, invert };
662
+ const propsRef = useRef10(props);
663
+ propsRef.current = props;
653
664
  useEffect9(() => {
654
665
  const scene = sceneRef.current;
655
666
  if (!scene) return;
656
- const opts = {
657
- drag: propsRef.current.drag,
658
- keyboard: propsRef.current.keyboard,
659
- moveSpeed: propsRef.current.moveSpeed,
660
- lookSpeed: propsRef.current.lookSpeed,
661
- invert: propsRef.current.invert
662
- };
663
- const controls = createGlyphFirstPersonControls(scene, opts);
667
+ const controls = createGlyphFirstPersonControls(scene, propsRef.current);
664
668
  controlsRef.current = controls;
665
669
  return () => {
666
670
  controls.destroy();
@@ -668,9 +672,7 @@ function GlyphFirstPersonControls({
668
672
  };
669
673
  }, [sceneRef]);
670
674
  useEffect9(() => {
671
- const controls = controlsRef.current;
672
- if (!controls) return;
673
- controls.update({ drag, keyboard, moveSpeed, lookSpeed, invert });
675
+ controlsRef.current?.update(props);
674
676
  });
675
677
  return null;
676
678
  }
@@ -903,7 +905,7 @@ export {
903
905
  inverseRotateVec3,
904
906
  isAxisAlignedSurfaceNormal,
905
907
  isVoxelCameraCullableNormalGroups,
906
- loadMesh,
908
+ loadMesh2 as loadMesh,
907
909
  mergePolygons,
908
910
  normalFacesCamera,
909
911
  normalizeInvertMultiplier,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glyphcss/react",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "React components for the glyphcss ASCII polygon mesh rendering engine",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -40,8 +40,8 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@glyphcss/core": "^0.0.5",
44
- "glyphcss": "^0.0.5"
43
+ "glyphcss": "^0.0.7",
44
+ "@glyphcss/core": "^0.0.7"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "react": "^18.0.0 || ^19.0.0",