@holoscript/std 2.1.0 → 3.1.1

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.
Files changed (85) hide show
  1. package/README.md +197 -0
  2. package/dist/__tests__/EconomicPrimitives.test.d.ts.map +1 -0
  3. package/dist/__tests__/EconomicTraits.test.d.ts.map +1 -0
  4. package/dist/__tests__/SimulationLabPrimitives.test.d.ts.map +1 -0
  5. package/dist/__tests__/Sprint33.test.d.ts.map +1 -0
  6. package/dist/__tests__/Sprint56.test.d.ts.map +1 -0
  7. package/dist/__tests__/collections.test.d.ts.map +1 -0
  8. package/dist/__tests__/events.test.d.ts.map +1 -0
  9. package/dist/__tests__/materials.test.d.ts.map +1 -0
  10. package/dist/__tests__/math.test.d.ts.map +1 -0
  11. package/dist/__tests__/physics.test.d.ts.map +1 -0
  12. package/dist/__tests__/spatial.test.d.ts.map +1 -0
  13. package/dist/__tests__/string-decoupled.test.d.ts.map +1 -0
  14. package/dist/__tests__/string.test.d.ts.map +1 -0
  15. package/dist/__tests__/time.test.d.ts.map +1 -0
  16. package/dist/collections.d.ts.map +1 -1
  17. package/dist/events.d.ts.map +1 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +42 -9
  20. package/dist/materials.d.ts.map +1 -0
  21. package/dist/math.d.ts.map +1 -1
  22. package/dist/physics.d.ts.map +1 -0
  23. package/dist/spatial.d.ts.map +1 -0
  24. package/dist/string.d.ts.map +1 -1
  25. package/dist/time.d.ts.map +1 -1
  26. package/dist/traits/ARTraits.d.ts.map +1 -0
  27. package/dist/traits/EconomicPrimitives.d.ts.map +1 -0
  28. package/dist/traits/EconomicTraits.d.ts.map +1 -0
  29. package/dist/traits/IoTTraits.d.ts.map +1 -0
  30. package/dist/traits/SimulationLabPrimitives.d.ts.map +1 -0
  31. package/dist/traits/SimulationLabTraits.d.ts.map +1 -0
  32. package/dist/traits/VRRTraits.d.ts.map +1 -0
  33. package/dist/types.d.ts.map +1 -1
  34. package/package.json +17 -6
  35. package/src/__tests__/EconomicPrimitives.test.ts +690 -0
  36. package/src/__tests__/EconomicTraits.test.ts +425 -0
  37. package/src/__tests__/SimulationLabPrimitives.test.ts +415 -0
  38. package/src/__tests__/Sprint33.test.ts +1301 -0
  39. package/src/__tests__/Sprint56.test.ts +1070 -0
  40. package/src/__tests__/collections.test.ts +182 -0
  41. package/src/__tests__/events.test.ts +135 -0
  42. package/src/__tests__/materials.test.ts +84 -0
  43. package/src/__tests__/math.test.ts +246 -0
  44. package/src/__tests__/physics.test.ts +83 -0
  45. package/src/__tests__/spatial.test.ts +333 -0
  46. package/src/__tests__/string-decoupled.test.ts +16 -0
  47. package/src/__tests__/string.test.ts +164 -0
  48. package/src/__tests__/time.test.ts +110 -0
  49. package/src/collections.ts +8 -2
  50. package/src/events.ts +88 -0
  51. package/src/index.ts +161 -11
  52. package/src/materials.ts +109 -0
  53. package/src/math.ts +30 -14
  54. package/src/physics.ts +141 -0
  55. package/src/spatial.ts +320 -0
  56. package/src/string.basic.test.ts +14 -0
  57. package/src/string.test.ts +335 -0
  58. package/src/string.ts +19 -2
  59. package/src/time.ts +9 -10
  60. package/src/traits/ARTraits.ts +103 -0
  61. package/src/traits/EconomicPrimitives.ts +755 -0
  62. package/src/traits/EconomicTraits.ts +552 -0
  63. package/src/traits/IoTTraits.ts +102 -0
  64. package/src/traits/SimulationLabPrimitives.ts +650 -0
  65. package/src/traits/SimulationLabTraits.ts +191 -0
  66. package/src/traits/VRRTraits.ts +326 -0
  67. package/src/types.ts +47 -12
  68. package/vitest.config.ts +10 -0
  69. package/dist/collections.d.ts +0 -177
  70. package/dist/collections.js +0 -720
  71. package/dist/collections.js.map +0 -1
  72. package/dist/index.d.ts +0 -89
  73. package/dist/index.js.map +0 -1
  74. package/dist/math.d.ts +0 -162
  75. package/dist/math.js +0 -539
  76. package/dist/math.js.map +0 -1
  77. package/dist/string.d.ts +0 -208
  78. package/dist/string.js +0 -443
  79. package/dist/string.js.map +0 -1
  80. package/dist/time.d.ts +0 -215
  81. package/dist/time.js +0 -530
  82. package/dist/time.js.map +0 -1
  83. package/dist/types.d.ts +0 -193
  84. package/dist/types.js +0 -198
  85. package/dist/types.js.map +0 -1
@@ -825,10 +825,16 @@ export class PriorityQueue<T> {
825
825
  const rightChild = 2 * index + 2;
826
826
  let smallest = index;
827
827
 
828
- if (leftChild < this.heap.length && this.compareFn(this.heap[leftChild].priority, this.heap[smallest].priority) < 0) {
828
+ if (
829
+ leftChild < this.heap.length &&
830
+ this.compareFn(this.heap[leftChild].priority, this.heap[smallest].priority) < 0
831
+ ) {
829
832
  smallest = leftChild;
830
833
  }
831
- if (rightChild < this.heap.length && this.compareFn(this.heap[rightChild].priority, this.heap[smallest].priority) < 0) {
834
+ if (
835
+ rightChild < this.heap.length &&
836
+ this.compareFn(this.heap[rightChild].priority, this.heap[smallest].priority) < 0
837
+ ) {
832
838
  smallest = rightChild;
833
839
  }
834
840
 
package/src/events.ts ADDED
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @holoscript/std — Events Module
3
+ *
4
+ * Provides a typed event bus for HoloScript compositions.
5
+ * Supports emit, on, once, off, and wildcard listeners.
6
+ *
7
+ * @version 0.2.0
8
+ * @module @holoscript/std/events
9
+ */
10
+
11
+ export type EventHandler<T = any> = (data: T) => void;
12
+
13
+ interface Listener {
14
+ handler: EventHandler;
15
+ once: boolean;
16
+ }
17
+
18
+ export class EventBus {
19
+ private listeners: Map<string, Listener[]> = new Map();
20
+ private wildcardListeners: Listener[] = [];
21
+
22
+ /** Register an event listener. */
23
+ on<T = any>(event: string, handler: EventHandler<T>): () => void {
24
+ if (!this.listeners.has(event)) this.listeners.set(event, []);
25
+ const listener: Listener = { handler, once: false };
26
+ this.listeners.get(event)!.push(listener);
27
+ return () => this.off(event, handler);
28
+ }
29
+
30
+ /** Register a one-time event listener. */
31
+ once<T = any>(event: string, handler: EventHandler<T>): () => void {
32
+ if (!this.listeners.has(event)) this.listeners.set(event, []);
33
+ const listener: Listener = { handler, once: true };
34
+ this.listeners.get(event)!.push(listener);
35
+ return () => this.off(event, handler);
36
+ }
37
+
38
+ /** Remove an event listener. */
39
+ off(event: string, handler: EventHandler): void {
40
+ const list = this.listeners.get(event);
41
+ if (!list) return;
42
+ this.listeners.set(
43
+ event,
44
+ list.filter((l) => l.handler !== handler)
45
+ );
46
+ }
47
+
48
+ /** Emit an event to all registered listeners. */
49
+ emit<T = any>(event: string, data?: T): void {
50
+ // Fire specific listeners
51
+ const list = this.listeners.get(event);
52
+ if (list) {
53
+ const remaining: Listener[] = [];
54
+ for (const l of list) {
55
+ l.handler(data);
56
+ if (!l.once) remaining.push(l);
57
+ }
58
+ this.listeners.set(event, remaining);
59
+ }
60
+ // Fire wildcard listeners
61
+ for (const l of this.wildcardListeners) {
62
+ l.handler({ event, data });
63
+ }
64
+ }
65
+
66
+ /** Listen to all events. */
67
+ onAny(handler: EventHandler<{ event: string; data: any }>): () => void {
68
+ const listener: Listener = { handler, once: false };
69
+ this.wildcardListeners.push(listener);
70
+ return () => {
71
+ this.wildcardListeners = this.wildcardListeners.filter((l) => l !== listener);
72
+ };
73
+ }
74
+
75
+ /** Remove all listeners. */
76
+ clear(): void {
77
+ this.listeners.clear();
78
+ this.wildcardListeners = [];
79
+ }
80
+
81
+ /** Get count of listeners for an event (or all events). */
82
+ listenerCount(event?: string): number {
83
+ if (event) return (this.listeners.get(event) || []).length;
84
+ let total = this.wildcardListeners.length;
85
+ for (const [, list] of this.listeners) total += list.length;
86
+ return total;
87
+ }
88
+ }
package/src/index.ts CHANGED
@@ -2,25 +2,62 @@
2
2
  * @holoscript/std - Standard Library for HoloScript Plus
3
3
  *
4
4
  * Provides core types, math utilities, collections, string operations,
5
- * and time management for HoloScript Plus programs.
5
+ * time management, spatial math, physics primitives, materials, and events
6
+ * for HoloScript Plus programs.
6
7
  *
7
8
  * @example
8
9
  * ```hsplus
9
- * import { Vec3, List, sleep } from "@holoscript/std";
10
+ * import { Vec3, createPBRMaterial, EventBus } from "@holoscript/std";
10
11
  *
11
12
  * let position = Vec3(0, 1, 0);
12
- * let items = List.of(1, 2, 3).map(n => n * 2);
13
- *
14
- * async fn main() {
15
- * await sleep(1000);
16
- * print("Done!");
17
- * }
13
+ * let steel = createPBRMaterial("Steel", "metal");
14
+ * let bus = new EventBus();
18
15
  * ```
19
16
  */
20
17
 
21
18
  // Re-export everything from types.js
22
19
  export * from './types.js';
23
20
 
21
+ // Spatial math (v4.2)
22
+ export {
23
+ Vec3,
24
+ Quaternion,
25
+ Transform,
26
+ Ray,
27
+ AABB,
28
+ distance,
29
+ lerp as spatialLerp,
30
+ clamp as spatialClamp,
31
+ degToRad as spatialDegToRad,
32
+ radToDeg as spatialRadToDeg,
33
+ } from './spatial.js';
34
+
35
+ // Physics primitives (v4.2)
36
+ export {
37
+ createBoxCollider,
38
+ createSphereCollider,
39
+ createCapsuleCollider,
40
+ createRigidbody,
41
+ } from './physics.js';
42
+ export type {
43
+ ColliderConfig,
44
+ ColliderShapeType,
45
+ RigidbodyConfig,
46
+ ForceFieldConfig,
47
+ ForceFieldType,
48
+ JointConfig,
49
+ JointType,
50
+ RaycastHit,
51
+ } from './physics.js';
52
+
53
+ // Materials (v4.2)
54
+ export { MATERIAL_PRESETS, createPBRMaterial } from './materials.js';
55
+ export type { PBRMaterial, UnlitMaterial, TextureMapType, TextureConfig } from './materials.js';
56
+
57
+ // Events (v4.2)
58
+ export { EventBus } from './events.js';
59
+ export type { EventHandler } from './events.js';
60
+
24
61
  // Math utilities - export objects from math.ts
25
62
  export {
26
63
  // Constants
@@ -120,8 +157,114 @@ export {
120
157
  wordWrap,
121
158
  levenshtein,
122
159
  similarity,
160
+ extractTraits,
123
161
  } from './string.js';
124
162
 
163
+ // Economic primitives (v4.3)
164
+ export {
165
+ // Tradeable
166
+ generateTxHash,
167
+ executeTrade,
168
+ // Depreciation
169
+ calculateDepreciation,
170
+ depreciatedValue,
171
+ isDestroyed,
172
+ calculateRepairCost,
173
+ DEFAULT_DEPRECIATION,
174
+ // Bonding curves
175
+ bondingCurvePrice,
176
+ bondingCurveBuyCost,
177
+ bondingCurveSellRefund,
178
+ spatialPrice,
179
+ DEFAULT_BONDING_CURVE,
180
+ // Wealth taxation
181
+ calculateTaxRate,
182
+ calculateTaxAmount,
183
+ calculateRedistribution,
184
+ DEFAULT_WEALTH_TAX,
185
+ // PID control
186
+ createPIDState,
187
+ updatePID,
188
+ createDualLoopPIDState,
189
+ updateDualLoopPID,
190
+ DEFAULT_PID,
191
+ // Faucet-sink tracking
192
+ createFaucetSinkMetrics,
193
+ recordFaucet,
194
+ recordSink,
195
+ resetMetricsPeriod,
196
+ } from './traits/EconomicPrimitives.js';
197
+ export type {
198
+ Currency,
199
+ AgentID,
200
+ EconomicResult,
201
+ EconomicError,
202
+ EconomicPermission,
203
+ OwnershipRecord,
204
+ TransferRecord,
205
+ DepreciationConfig,
206
+ BondingCurveType,
207
+ BondingCurveConfig,
208
+ WealthTaxConfig,
209
+ PIDConfig,
210
+ PIDState,
211
+ DualLoopPIDConfig,
212
+ DualLoopPIDState,
213
+ FaucetSinkMetrics,
214
+ } from './traits/EconomicPrimitives.js';
215
+
216
+ // Economic traits (v4.3)
217
+ export {
218
+ EconomicTraits,
219
+ getEconomicTraitNames,
220
+ getEconomicTrait,
221
+ validateTraitComposition,
222
+ getRequiredPermissions,
223
+ } from './traits/EconomicTraits.js';
224
+ export type { EconomicTraitDefinition } from './traits/EconomicTraits.js';
225
+
226
+ // SimulationLab primitives (v4.3)
227
+ export {
228
+ // Statistics
229
+ mean,
230
+ variance,
231
+ standardDeviation,
232
+ standardError,
233
+ cohensD,
234
+ // Statistical tests
235
+ tTest,
236
+ oneSampleTTest,
237
+ mannWhitneyU,
238
+ chiSquaredTest,
239
+ // Parameter sweeps
240
+ expandSweep,
241
+ generateSweepCombinations,
242
+ isParameterRange,
243
+ // Metric aggregation
244
+ extractMetric,
245
+ groupByParameter,
246
+ summarizeMetrics,
247
+ } from './traits/SimulationLabPrimitives.js';
248
+ export type {
249
+ Hypothesis,
250
+ HypothesisDirection,
251
+ SimulationStatus,
252
+ ParameterRange,
253
+ ParameterSet,
254
+ ParameterSweep,
255
+ SimulationMetrics,
256
+ StatisticalResult,
257
+ ExperimentResult,
258
+ } from './traits/SimulationLabPrimitives.js';
259
+
260
+ // SimulationLab traits (v4.3)
261
+ export {
262
+ SimulationLabTraits,
263
+ getSimulationTraitNames,
264
+ getSimulationTrait,
265
+ } from './traits/SimulationLabTraits.js';
266
+ export type { SimulationTraitDefinition } from './traits/SimulationLabTraits.js';
267
+
125
268
  // Time utilities
126
269
  export {
127
270
  now,
@@ -178,7 +321,10 @@ export function assert(condition: boolean, message?: string): asserts condition
178
321
  /**
179
322
  * Assert a value is not null or undefined
180
323
  */
181
- export function assertDefined<T>(value: T | null | undefined, message?: string): asserts value is T {
324
+ export function assertDefined<T>(
325
+ value: T | null | undefined,
326
+ message?: string
327
+ ): asserts value is T {
182
328
  if (value === null || value === undefined) {
183
329
  throw new Error(message ?? 'Value is null or undefined');
184
330
  }
@@ -266,7 +412,7 @@ export function equals(a: unknown, b: unknown): boolean {
266
412
  return true;
267
413
  }
268
414
 
269
- const keysA = Object.keys(a as object);
415
+ const keysA = Object.keys(a);
270
416
  const keysB = Object.keys(b as object);
271
417
  if (keysA.length !== keysB.length) return false;
272
418
 
@@ -299,7 +445,11 @@ export function pipe(value: unknown, ...fns: ((x: unknown) => unknown)[]): unkno
299
445
  export function compose<A>(): (a: A) => A;
300
446
  export function compose<A, B>(fn1: (a: A) => B): (a: A) => B;
301
447
  export function compose<A, B, C>(fn2: (b: B) => C, fn1: (a: A) => B): (a: A) => C;
302
- export function compose<A, B, C, D>(fn3: (c: C) => D, fn2: (b: B) => C, fn1: (a: A) => B): (a: A) => D;
448
+ export function compose<A, B, C, D>(
449
+ fn3: (c: C) => D,
450
+ fn2: (b: B) => C,
451
+ fn1: (a: A) => B
452
+ ): (a: A) => D;
303
453
  export function compose(...fns: ((x: unknown) => unknown)[]): (x: unknown) => unknown {
304
454
  return (value: unknown) => fns.reduceRight((acc, fn) => fn(acc), value);
305
455
  }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @holoscript/std — Materials Module
3
+ *
4
+ * Provides PBR material types, texture map definitions, and material presets.
5
+ * Maps directly to HoloScript material_block grammar constructs.
6
+ *
7
+ * @version 0.2.0
8
+ * @module @holoscript/std/materials
9
+ */
10
+
11
+ // =============================================================================
12
+ // PBR Material
13
+ // =============================================================================
14
+
15
+ export interface PBRMaterial {
16
+ name: string;
17
+ baseColor: string; // hex color
18
+ roughness: number; // 0.0 - 1.0
19
+ metallic: number; // 0.0 - 1.0
20
+ emissiveColor?: string;
21
+ emissiveIntensity?: number;
22
+ opacity?: number; // 0.0 - 1.0
23
+ ior?: number; // Index of refraction (glass ~1.5, water ~1.33)
24
+ subsurface?: number;
25
+ clearcoat?: number;
26
+ clearcoatRoughness?: number;
27
+ // Texture maps
28
+ albedoMap?: string;
29
+ normalMap?: string;
30
+ roughnessMap?: string;
31
+ metallicMap?: string;
32
+ emissionMap?: string;
33
+ aoMap?: string;
34
+ heightMap?: string;
35
+ opacityMap?: string;
36
+ displacementMap?: string;
37
+ }
38
+
39
+ export interface UnlitMaterial {
40
+ name: string;
41
+ color: string;
42
+ emissiveColor?: string;
43
+ emissiveIntensity?: number;
44
+ opacity?: number;
45
+ texture?: string;
46
+ }
47
+
48
+ // =============================================================================
49
+ // Material Presets
50
+ // =============================================================================
51
+
52
+ export const MATERIAL_PRESETS: Record<string, Partial<PBRMaterial>> = {
53
+ metal: { roughness: 0.2, metallic: 1.0 },
54
+ wood: { roughness: 0.85, metallic: 0.0, baseColor: '#8B6914' },
55
+ glass: { roughness: 0.05, metallic: 0.0, opacity: 0.3, ior: 1.5 },
56
+ plastic: { roughness: 0.4, metallic: 0.0 },
57
+ concrete: { roughness: 0.95, metallic: 0.0, baseColor: '#808080' },
58
+ fabric: { roughness: 0.9, metallic: 0.0, subsurface: 0.2 },
59
+ water: { roughness: 0.05, metallic: 0.0, opacity: 0.7, ior: 1.33 },
60
+ rubber: { roughness: 0.95, metallic: 0.0, baseColor: '#222222' },
61
+ marble: { roughness: 0.3, metallic: 0.0, baseColor: '#f0f0f0' },
62
+ skin: { roughness: 0.6, metallic: 0.0, subsurface: 0.5 },
63
+ foliage: { roughness: 0.8, metallic: 0.0, baseColor: '#2d5a27', subsurface: 0.3 },
64
+ chrome: { roughness: 0.05, metallic: 1.0, baseColor: '#cccccc' },
65
+ gold: { roughness: 0.2, metallic: 1.0, baseColor: '#ffd700' },
66
+ copper: { roughness: 0.3, metallic: 1.0, baseColor: '#b87333' },
67
+ ice: { roughness: 0.1, metallic: 0.0, opacity: 0.8, ior: 1.31 },
68
+ };
69
+
70
+ export function createPBRMaterial(
71
+ name: string,
72
+ preset?: keyof typeof MATERIAL_PRESETS,
73
+ overrides?: Partial<PBRMaterial>
74
+ ): PBRMaterial {
75
+ const base = preset ? MATERIAL_PRESETS[preset] : {};
76
+ return {
77
+ name,
78
+ baseColor: '#ffffff',
79
+ roughness: 0.5,
80
+ metallic: 0.0,
81
+ ...base,
82
+ ...overrides,
83
+ };
84
+ }
85
+
86
+ // =============================================================================
87
+ // Texture Map Types
88
+ // =============================================================================
89
+
90
+ export type TextureMapType =
91
+ | 'albedo_map'
92
+ | 'normal_map'
93
+ | 'roughness_map'
94
+ | 'metallic_map'
95
+ | 'emission_map'
96
+ | 'ao_map'
97
+ | 'height_map'
98
+ | 'opacity_map'
99
+ | 'displacement_map'
100
+ | 'specular_map'
101
+ | 'clearcoat_map';
102
+
103
+ export interface TextureConfig {
104
+ source: string;
105
+ tiling?: [number, number];
106
+ offset?: [number, number];
107
+ filter?: 'linear' | 'nearest';
108
+ wrap?: 'repeat' | 'clamp' | 'mirror';
109
+ }
package/src/math.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Vector math, quaternion operations, interpolation, and noise functions.
5
5
  */
6
6
 
7
- import type { Vec2, Vec3, Vec4, Quat, EulerAngles, AABB, Ray, RaycastHit } from './types.js';
7
+ import type { Vec2, Vec3, Quat, EulerAngles, AABB } from './types.js';
8
8
  import { vec3, quat } from './types.js';
9
9
 
10
10
  // =============================================================================
@@ -34,7 +34,13 @@ export function inverseLerp(a: number, b: number, value: number): number {
34
34
  return (value - a) / (b - a);
35
35
  }
36
36
 
37
- export function remap(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number {
37
+ export function remap(
38
+ value: number,
39
+ inMin: number,
40
+ inMax: number,
41
+ outMin: number,
42
+ outMax: number
43
+ ): number {
38
44
  return lerp(outMin, outMax, inverseLerp(inMin, inMax, value));
39
45
  }
40
46
 
@@ -153,10 +159,7 @@ export const vec3Math = {
153
159
  const dot = clamp(vec3Math.dot(a, b), -1, 1);
154
160
  const theta = Math.acos(dot) * t;
155
161
  const relative = vec3Math.normalize(vec3Math.sub(b, vec3Math.mul(a, dot)));
156
- return vec3Math.add(
157
- vec3Math.mul(a, Math.cos(theta)),
158
- vec3Math.mul(relative, Math.sin(theta))
159
- );
162
+ return vec3Math.add(vec3Math.mul(a, Math.cos(theta)), vec3Math.mul(relative, Math.sin(theta)));
160
163
  },
161
164
 
162
165
  negate: (v: Vec3): Vec3 => ({ x: -v.x, y: -v.y, z: -v.z }),
@@ -406,17 +409,23 @@ export const quatMath = {
406
409
  export const aabbMath = {
407
410
  contains: (aabb: AABB, point: Vec3): boolean => {
408
411
  return (
409
- point.x >= aabb.min.x && point.x <= aabb.max.x &&
410
- point.y >= aabb.min.y && point.y <= aabb.max.y &&
411
- point.z >= aabb.min.z && point.z <= aabb.max.z
412
+ point.x >= aabb.min.x &&
413
+ point.x <= aabb.max.x &&
414
+ point.y >= aabb.min.y &&
415
+ point.y <= aabb.max.y &&
416
+ point.z >= aabb.min.z &&
417
+ point.z <= aabb.max.z
412
418
  );
413
419
  },
414
420
 
415
421
  intersects: (a: AABB, b: AABB): boolean => {
416
422
  return (
417
- a.min.x <= b.max.x && a.max.x >= b.min.x &&
418
- a.min.y <= b.max.y && a.max.y >= b.min.y &&
419
- a.min.z <= b.max.z && a.max.z >= b.min.z
423
+ a.min.x <= b.max.x &&
424
+ a.max.x >= b.min.x &&
425
+ a.min.y <= b.max.y &&
426
+ a.max.y >= b.min.y &&
427
+ a.min.z <= b.max.z &&
428
+ a.max.z >= b.min.z
420
429
  );
421
430
  },
422
431
 
@@ -508,7 +517,14 @@ export const noise = {
508
517
  /**
509
518
  * Fractal Brownian Motion (fBm)
510
519
  */
511
- fbm: (x: number, y: number, z: number, octaves: number = 6, lacunarity: number = 2, gain: number = 0.5): number => {
520
+ fbm: (
521
+ x: number,
522
+ y: number,
523
+ z: number,
524
+ octaves: number = 6,
525
+ lacunarity: number = 2,
526
+ gain: number = 0.5
527
+ ): number => {
512
528
  let value = 0;
513
529
  let amplitude = 1;
514
530
  let frequency = 1;
@@ -550,7 +566,7 @@ export const noise = {
550
566
 
551
567
  // Pseudo-random point in cell
552
568
  const hash = perm[(perm[(perm[cellX & 255] + cellY) & 255] + cellZ) & 255];
553
- const px = cellX + (hash / 255);
569
+ const px = cellX + hash / 255;
554
570
  const py = cellY + ((hash * 7) % 255) / 255;
555
571
  const pz = cellZ + ((hash * 13) % 255) / 255;
556
572
 
package/src/physics.ts ADDED
@@ -0,0 +1,141 @@
1
+ /**
2
+ * @holoscript/std — Physics Module
3
+ *
4
+ * Provides physics primitives: ColliderShape, RigidbodyConfig, ForceField, Joint.
5
+ * Runtime representations for HoloScript physics blocks.
6
+ *
7
+ * @version 0.2.0
8
+ * @module @holoscript/std/physics
9
+ */
10
+
11
+ import type { Vec3 } from './spatial.js';
12
+
13
+ // =============================================================================
14
+ // Collider Shapes
15
+ // =============================================================================
16
+
17
+ export type ColliderShapeType =
18
+ | 'box'
19
+ | 'sphere'
20
+ | 'capsule'
21
+ | 'mesh'
22
+ | 'convex'
23
+ | 'cylinder'
24
+ | 'heightfield';
25
+
26
+ export interface ColliderConfig {
27
+ shape: ColliderShapeType;
28
+ isTrigger: boolean;
29
+ friction: number;
30
+ restitution: number;
31
+ // Shape-specific
32
+ radius?: number;
33
+ halfExtents?: Vec3;
34
+ height?: number;
35
+ meshAsset?: string;
36
+ }
37
+
38
+ export function createBoxCollider(
39
+ halfExtents: Vec3,
40
+ options?: Partial<ColliderConfig>
41
+ ): ColliderConfig {
42
+ return {
43
+ shape: 'box',
44
+ isTrigger: false,
45
+ friction: 0.5,
46
+ restitution: 0.0,
47
+ halfExtents,
48
+ ...options,
49
+ };
50
+ }
51
+
52
+ export function createSphereCollider(
53
+ radius: number,
54
+ options?: Partial<ColliderConfig>
55
+ ): ColliderConfig {
56
+ return { shape: 'sphere', isTrigger: false, friction: 0.5, restitution: 0.0, radius, ...options };
57
+ }
58
+
59
+ export function createCapsuleCollider(
60
+ radius: number,
61
+ height: number,
62
+ options?: Partial<ColliderConfig>
63
+ ): ColliderConfig {
64
+ return {
65
+ shape: 'capsule',
66
+ isTrigger: false,
67
+ friction: 0.5,
68
+ restitution: 0.0,
69
+ radius,
70
+ height,
71
+ ...options,
72
+ };
73
+ }
74
+
75
+ // =============================================================================
76
+ // Rigidbody
77
+ // =============================================================================
78
+
79
+ export interface RigidbodyConfig {
80
+ mass: number;
81
+ useGravity: boolean;
82
+ linearDamping: number;
83
+ angularDamping: number;
84
+ freezePosition: [boolean, boolean, boolean];
85
+ freezeRotation: [boolean, boolean, boolean];
86
+ isKinematic: boolean;
87
+ }
88
+
89
+ export function createRigidbody(mass: number, options?: Partial<RigidbodyConfig>): RigidbodyConfig {
90
+ return {
91
+ mass,
92
+ useGravity: true,
93
+ linearDamping: 0.0,
94
+ angularDamping: 0.05,
95
+ freezePosition: [false, false, false],
96
+ freezeRotation: [false, false, false],
97
+ isKinematic: false,
98
+ ...options,
99
+ };
100
+ }
101
+
102
+ // =============================================================================
103
+ // Force Fields
104
+ // =============================================================================
105
+
106
+ export type ForceFieldType = 'directional' | 'radial' | 'vortex' | 'buoyancy';
107
+
108
+ export interface ForceFieldConfig {
109
+ type: ForceFieldType;
110
+ strength: number;
111
+ direction?: Vec3;
112
+ falloff: 'none' | 'linear' | 'quadratic';
113
+ turbulence: number;
114
+ }
115
+
116
+ // =============================================================================
117
+ // Joints
118
+ // =============================================================================
119
+
120
+ export type JointType = 'hinge' | 'slider' | 'ball_socket' | 'fixed' | 'd6' | 'spring';
121
+
122
+ export interface JointConfig {
123
+ type: JointType;
124
+ connectedBody?: string;
125
+ axis?: Vec3;
126
+ limits?: [number, number];
127
+ damping: number;
128
+ springForce?: number;
129
+ breakForce?: number;
130
+ }
131
+
132
+ // =============================================================================
133
+ // Raycast Utility
134
+ // =============================================================================
135
+
136
+ export interface RaycastHit {
137
+ point: Vec3;
138
+ normal: Vec3;
139
+ distance: number;
140
+ objectName: string;
141
+ }