bplinejs 0.0.101-beta.10

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 (129) hide show
  1. package/README.md +215 -0
  2. package/docs/API.md +471 -0
  3. package/lib/Camera/index.d.ts +88 -0
  4. package/lib/Camera/index.js +178 -0
  5. package/lib/Camera/index.js.map +1 -0
  6. package/lib/Color/index.d.ts +99 -0
  7. package/lib/Color/index.js +178 -0
  8. package/lib/Color/index.js.map +1 -0
  9. package/lib/Geometry/Geo.d.ts +131 -0
  10. package/lib/Geometry/Geo.js +180 -0
  11. package/lib/Geometry/Geo.js.map +1 -0
  12. package/lib/Geometry/Poly2D.d.ts +53 -0
  13. package/lib/Geometry/Poly2D.js +133 -0
  14. package/lib/Geometry/Poly2D.js.map +1 -0
  15. package/lib/Geometry/Rect2d.d.ts +89 -0
  16. package/lib/Geometry/Rect2d.js +128 -0
  17. package/lib/Geometry/Rect2d.js.map +1 -0
  18. package/lib/Geometry/index.d.ts +6 -0
  19. package/lib/Geometry/index.js +4 -0
  20. package/lib/Group/index.d.ts +70 -0
  21. package/lib/Group/index.js +110 -0
  22. package/lib/Group/index.js.map +1 -0
  23. package/lib/ID.d.ts +6 -0
  24. package/lib/ID.js +15 -0
  25. package/lib/ID.js.map +1 -0
  26. package/lib/IMesh/index.d.ts +104 -0
  27. package/lib/IMesh/index.js +333 -0
  28. package/lib/IMesh/index.js.map +1 -0
  29. package/lib/Material/Material.d.ts +158 -0
  30. package/lib/Material/Material.js +229 -0
  31. package/lib/Material/Material.js.map +1 -0
  32. package/lib/Material/baseMaterial.d.ts +15 -0
  33. package/lib/Material/baseMaterial.js +24 -0
  34. package/lib/Material/baseMaterial.js.map +1 -0
  35. package/lib/Material/index.d.ts +4 -0
  36. package/lib/Material/index.js +3 -0
  37. package/lib/Material/shaders/base/poly/fragment.js +6 -0
  38. package/lib/Material/shaders/base/poly/fragment.js.map +1 -0
  39. package/lib/Material/shaders/base/poly/vertex.js +6 -0
  40. package/lib/Material/shaders/base/poly/vertex.js.map +1 -0
  41. package/lib/Material/shaders/base/rect/fragment.js +6 -0
  42. package/lib/Material/shaders/base/rect/fragment.js.map +1 -0
  43. package/lib/Material/shaders/base/rect/vertex.js +6 -0
  44. package/lib/Material/shaders/base/rect/vertex.js.map +1 -0
  45. package/lib/Material/shaders/line/fragment.js +6 -0
  46. package/lib/Material/shaders/line/fragment.js.map +1 -0
  47. package/lib/Material/shaders/line/vertex.js +6 -0
  48. package/lib/Material/shaders/line/vertex.js.map +1 -0
  49. package/lib/Mesh/index.d.ts +154 -0
  50. package/lib/Mesh/index.js +254 -0
  51. package/lib/Mesh/index.js.map +1 -0
  52. package/lib/Object/index.d.ts +95 -0
  53. package/lib/Object/index.js +212 -0
  54. package/lib/Object/index.js.map +1 -0
  55. package/lib/Raws/index.d.ts +87 -0
  56. package/lib/Raws/index.js +164 -0
  57. package/lib/Raws/index.js.map +1 -0
  58. package/lib/Render/BufferManager.d.ts +93 -0
  59. package/lib/Render/BufferManager.js +281 -0
  60. package/lib/Render/BufferManager.js.map +1 -0
  61. package/lib/Render/DepthManager.d.ts +22 -0
  62. package/lib/Render/DepthManager.js +95 -0
  63. package/lib/Render/DepthManager.js.map +1 -0
  64. package/lib/Render/DestroyManager.d.ts +74 -0
  65. package/lib/Render/DestroyManager.js +221 -0
  66. package/lib/Render/DestroyManager.js.map +1 -0
  67. package/lib/Render/DevelopmentValidator.d.ts +73 -0
  68. package/lib/Render/DevelopmentValidator.js +188 -0
  69. package/lib/Render/DevelopmentValidator.js.map +1 -0
  70. package/lib/Render/DrawCallManager.d.ts +58 -0
  71. package/lib/Render/DrawCallManager.js +267 -0
  72. package/lib/Render/DrawCallManager.js.map +1 -0
  73. package/lib/Render/PipelineManager.d.ts +46 -0
  74. package/lib/Render/PipelineManager.js +254 -0
  75. package/lib/Render/PipelineManager.js.map +1 -0
  76. package/lib/Render/SamplerManager.d.ts +26 -0
  77. package/lib/Render/SamplerManager.js +42 -0
  78. package/lib/Render/SamplerManager.js.map +1 -0
  79. package/lib/Render/SceneUpdate.d.ts +9 -0
  80. package/lib/Render/SceneUpdate.js +18 -0
  81. package/lib/Render/SceneUpdate.js.map +1 -0
  82. package/lib/Render/TextureManager.d.ts +33 -0
  83. package/lib/Render/TextureManager.js +152 -0
  84. package/lib/Render/TextureManager.js.map +1 -0
  85. package/lib/Render/index.d.ts +212 -0
  86. package/lib/Render/index.js +347 -0
  87. package/lib/Render/index.js.map +1 -0
  88. package/lib/Render/types.d.ts +191 -0
  89. package/lib/Scene/index.d.ts +124 -0
  90. package/lib/Scene/index.js +225 -0
  91. package/lib/Scene/index.js.map +1 -0
  92. package/lib/Style/EdgeStyle.d.ts +28 -0
  93. package/lib/Style/EdgeStyle.js +67 -0
  94. package/lib/Style/EdgeStyle.js.map +1 -0
  95. package/lib/Style/JoinStyle.d.ts +27 -0
  96. package/lib/Style/JoinStyle.js +53 -0
  97. package/lib/Style/JoinStyle.js.map +1 -0
  98. package/lib/Style/PartStyle.d.ts +50 -0
  99. package/lib/Style/PartStyle.js +92 -0
  100. package/lib/Style/PartStyle.js.map +1 -0
  101. package/lib/Style/PointsStyle.d.ts +43 -0
  102. package/lib/Style/PointsStyle.js +98 -0
  103. package/lib/Style/PointsStyle.js.map +1 -0
  104. package/lib/Style/SolidStyle.d.ts +37 -0
  105. package/lib/Style/SolidStyle.js +83 -0
  106. package/lib/Style/SolidStyle.js.map +1 -0
  107. package/lib/Style/TexturedStyle.d.ts +29 -0
  108. package/lib/Style/TexturedStyle.js +66 -0
  109. package/lib/Style/TexturedStyle.js.map +1 -0
  110. package/lib/Style/WireframeStyle.d.ts +7 -0
  111. package/lib/Style/WireframeStyle.js +13 -0
  112. package/lib/Style/WireframeStyle.js.map +1 -0
  113. package/lib/Style/WriteStyleData.d.ts +10 -0
  114. package/lib/Style/WriteStyleData.js +59 -0
  115. package/lib/Style/WriteStyleData.js.map +1 -0
  116. package/lib/Style/index.d.ts +50 -0
  117. package/lib/Style/index.js +92 -0
  118. package/lib/Style/index.js.map +1 -0
  119. package/lib/Style/types.d.ts +21 -0
  120. package/lib/Texture/Layers.d.ts +26 -0
  121. package/lib/Texture/Layers.js +42 -0
  122. package/lib/Texture/Layers.js.map +1 -0
  123. package/lib/Texture/index.d.ts +116 -0
  124. package/lib/Texture/index.js +198 -0
  125. package/lib/Texture/index.js.map +1 -0
  126. package/lib/global-types.d.ts +8 -0
  127. package/lib/index.d.ts +43 -0
  128. package/lib/index.js +34 -0
  129. package/package.json +130 -0
@@ -0,0 +1,70 @@
1
+ import { Mat3 } from "bpmatrixjs/Math/Mat3";
2
+ import type { AddObject } from "../global-types";
3
+ import ObjectNode from "../Object";
4
+ import type { ObjectNodeLike } from "../Object";
5
+ import type { SceneLike } from "../Scene";
6
+ interface GroupLike extends ObjectNodeLike {
7
+ children: AddObject[];
8
+ add(child: AddObject): void;
9
+ removeSelf(): boolean;
10
+ removeChild(child: AddObject): boolean;
11
+ removeAll(): void;
12
+ updateWorldMatrix(): Mat3;
13
+ }
14
+ /**
15
+ * 组对象
16
+ * 用于组织子节点和维护基础变换信息
17
+ * @class
18
+ */
19
+ declare class Group extends ObjectNode implements GroupLike {
20
+ /**
21
+ * 对象类型
22
+ */
23
+ readonly type: string;
24
+ /**
25
+ * 子节点列表
26
+ */
27
+ children: AddObject[];
28
+ /**
29
+ * 创建组对象
30
+ * @param x 初始位置 X
31
+ * @param y 初始位置 Y
32
+ */
33
+ constructor(x: number, y: number);
34
+ /**
35
+ * 添加子节点
36
+ * @param child 子节点对象
37
+ * @returns 无返回值
38
+ */
39
+ add(child: AddObject): void;
40
+ /**
41
+ * 从父组中删除当前节点。
42
+ * 当前节点没有父组时不进行处理。
43
+ * @returns 是否成功从父组中删除
44
+ */
45
+ removeSelf(): boolean;
46
+ /**
47
+ * 删除当前组中的一个直接子节点。
48
+ * @param child 需要删除的直接子节点
49
+ * @returns 是否找到并删除了该子节点
50
+ */
51
+ removeChild(child: AddObject): boolean;
52
+ /**
53
+ * 删除当前组中的全部直接子节点。
54
+ * @returns 无返回值
55
+ */
56
+ removeAll(): void;
57
+ /**
58
+ * 强制更新当前节点及子节点世界矩阵
59
+ * @returns Mat3
60
+ */
61
+ updateWorldMatrix(): Mat3;
62
+ /**
63
+ * 从当前节点沿父级查找所属场景。
64
+ * @param node 起始节点
65
+ * @returns 所属场景,未加入场景时返回 undefined
66
+ */
67
+ protected getScene(node: AddObject): SceneLike | undefined;
68
+ }
69
+ export default Group;
70
+ export type { GroupLike };
@@ -0,0 +1,110 @@
1
+ import ObjectNode from "../Object/index.js";
2
+ import "bpmatrixjs/Math/Mat3";
3
+ //#region src/scripts/Group/index.ts
4
+ /**
5
+ * 组对象
6
+ * 用于组织子节点和维护基础变换信息
7
+ * @class
8
+ */
9
+ var Group = class extends ObjectNode {
10
+ /**
11
+ * 对象类型
12
+ */
13
+ type = "Group";
14
+ /**
15
+ * 子节点列表
16
+ */
17
+ children = [];
18
+ /**
19
+ * 创建组对象
20
+ * @param x 初始位置 X
21
+ * @param y 初始位置 Y
22
+ */
23
+ constructor(x, y) {
24
+ super(x, y);
25
+ }
26
+ /**
27
+ * 添加子节点
28
+ * @param child 子节点对象
29
+ * @returns 无返回值
30
+ */
31
+ add(child) {
32
+ if (child === this) throw new Error("Cannot add a group to itself or one of its descendants.");
33
+ let current = this.parent;
34
+ while (current !== null) {
35
+ if (current === child) throw new Error("Cannot add a group to itself or one of its descendants.");
36
+ current = current.parent;
37
+ }
38
+ if (child.parent === this && this.children.includes(child)) return;
39
+ if (child.parent !== null && "removeChild" in child.parent) child.parent.removeChild(child);
40
+ child.parent = this;
41
+ this.children.push(child);
42
+ const scene = this.getScene(child);
43
+ if (scene !== void 0) {
44
+ scene.addToLists(child);
45
+ scene.updateVersion();
46
+ }
47
+ }
48
+ /**
49
+ * 从父组中删除当前节点。
50
+ * 当前节点没有父组时不进行处理。
51
+ * @returns 是否成功从父组中删除
52
+ */
53
+ removeSelf() {
54
+ const parent = this.parent;
55
+ if (parent === null || !("removeChild" in parent)) return false;
56
+ return parent.removeChild(this);
57
+ }
58
+ /**
59
+ * 删除当前组中的一个直接子节点。
60
+ * @param child 需要删除的直接子节点
61
+ * @returns 是否找到并删除了该子节点
62
+ */
63
+ removeChild(child) {
64
+ const childIndex = this.children.indexOf(child);
65
+ if (childIndex === -1) return false;
66
+ const scene = this.getScene(this);
67
+ this.children.splice(childIndex, 1);
68
+ child.parent = null;
69
+ if (scene !== void 0) scene.removeFromLists(child);
70
+ return true;
71
+ }
72
+ /**
73
+ * 删除当前组中的全部直接子节点。
74
+ * @returns 无返回值
75
+ */
76
+ removeAll() {
77
+ if (this.children.length === 0) return;
78
+ const scene = this.getScene(this);
79
+ for (const child of this.children) {
80
+ scene?.removeFromLists(child);
81
+ child.parent = null;
82
+ }
83
+ this.children.length = 0;
84
+ }
85
+ /**
86
+ * 强制更新当前节点及子节点世界矩阵
87
+ * @returns Mat3
88
+ */
89
+ updateWorldMatrix() {
90
+ super.updateWorldMatrix();
91
+ for (const child of this.children) child.updateWorldMatrix();
92
+ return this.worldMatrix;
93
+ }
94
+ /**
95
+ * 从当前节点沿父级查找所属场景。
96
+ * @param node 起始节点
97
+ * @returns 所属场景,未加入场景时返回 undefined
98
+ */
99
+ getScene(node) {
100
+ let current = node;
101
+ while (current !== null) {
102
+ if (current.type === "Scene") return current;
103
+ current = current.parent;
104
+ }
105
+ }
106
+ };
107
+ //#endregion
108
+ export { Group as default };
109
+
110
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/scripts/Group/index.ts"],"sourcesContent":["import { Mat3 } from \"bpmatrixjs/Math/Mat3\";\nimport type { AddObject } from \"../global-types\";\nimport ObjectNode from \"../Object\";\nimport type { ObjectNodeLike } from \"../Object\";\nimport type { SceneLike } from \"../Scene\";\n\ninterface GroupLike extends ObjectNodeLike {\n children: AddObject[];\n add(child: AddObject): void;\n removeSelf(): boolean;\n removeChild(child: AddObject): boolean;\n removeAll(): void;\n updateWorldMatrix(): Mat3;\n}\n\n/**\n * 组对象\n * 用于组织子节点和维护基础变换信息\n * @class\n */\nclass Group extends ObjectNode implements GroupLike {\n /**\n * 对象类型\n */\n public readonly type: string = \"Group\";\n\n /**\n * 子节点列表\n */\n public children: AddObject[] = [];\n\n /**\n * 创建组对象\n * @param x 初始位置 X\n * @param y 初始位置 Y\n */\n public constructor(x: number, y: number) {\n super(x, y);\n }\n\n /**\n * 添加子节点\n * @param child 子节点对象\n * @returns 无返回值\n */\n public add(child: AddObject): void {\n if (child === this) {\n throw new Error(\"Cannot add a group to itself or one of its descendants.\");\n }\n\n let current: AddObject | null = this.parent;\n\n // 禁止把自身或祖先作为子节点,否则 parent 链会形成死循环。\n while (current !== null) {\n if (current === child) {\n throw new Error(\"Cannot add a group to itself or one of its descendants.\");\n }\n\n current = current.parent;\n }\n\n if (child.parent === this && this.children.includes(child)) {\n return;\n }\n\n // 节点只能有一个父级,换父级前先从旧父级的 children 中移除。\n if (child.parent !== null && \"removeChild\" in child.parent) {\n (child.parent as GroupLike).removeChild(child);\n }\n\n child.parent = this;\n this.children.push(child);\n const scene: SceneLike | undefined = this.getScene(child);\n\n if (scene !== undefined) {\n scene.addToLists(child);\n scene.updateVersion();\n }\n }\n\n /**\n * 从父组中删除当前节点。\n * 当前节点没有父组时不进行处理。\n * @returns 是否成功从父组中删除\n */\n public removeSelf(): boolean {\n const parent: AddObject | null = this.parent;\n\n if (parent === null || !(\"removeChild\" in parent)) {\n return false;\n }\n\n const parentGroup: GroupLike = parent as GroupLike;\n return parentGroup.removeChild(this);\n }\n\n /**\n * 删除当前组中的一个直接子节点。\n * @param child 需要删除的直接子节点\n * @returns 是否找到并删除了该子节点\n */\n public removeChild(child: AddObject): boolean {\n const childIndex: number = this.children.indexOf(child);\n\n if (childIndex === -1) {\n return false;\n }\n\n const scene: SceneLike | undefined = this.getScene(this);\n\n this.children.splice(childIndex, 1);\n child.parent = null;\n\n if (scene !== undefined) {\n scene.removeFromLists(child);\n }\n\n return true;\n }\n\n /**\n * 删除当前组中的全部直接子节点。\n * @returns 无返回值\n */\n public removeAll(): void {\n if (this.children.length === 0) {\n return;\n }\n\n const scene: SceneLike | undefined = this.getScene(this);\n\n for (const child of this.children) {\n scene?.removeFromLists(child);\n child.parent = null;\n }\n\n this.children.length = 0;\n }\n\n /**\n * 强制更新当前节点及子节点世界矩阵\n * @returns Mat3\n */\n public updateWorldMatrix(): Mat3 {\n super.updateWorldMatrix();\n\n for (const child of this.children) {\n child.updateWorldMatrix();\n }\n return this.worldMatrix;\n }\n\n /**\n * 从当前节点沿父级查找所属场景。\n * @param node 起始节点\n * @returns 所属场景,未加入场景时返回 undefined\n */\n protected getScene(node: AddObject): SceneLike | undefined {\n let current: AddObject | null = node;\n\n while (current !== null) {\n if (current.type === \"Scene\") {\n return current as SceneLike;\n }\n\n current = current.parent;\n }\n\n return undefined;\n }\n}\n\nexport default Group;\nexport type { GroupLike };\n"],"mappings":";;;;;;;;AAoBA,IAAM,QAAN,cAAoB,WAAgC;;;;CAIhD,OAA+B;;;;CAK/B,WAA+B,CAAC;;;;;;CAOhC,YAAmB,GAAW,GAAW;EACrC,MAAM,GAAG,CAAC;CACd;;;;;;CAOA,IAAW,OAAwB;EAC/B,IAAI,UAAU,MACV,MAAM,IAAI,MAAM,yDAAyD;EAG7E,IAAI,UAA4B,KAAK;EAGrC,OAAO,YAAY,MAAM;GACrB,IAAI,YAAY,OACZ,MAAM,IAAI,MAAM,yDAAyD;GAG7E,UAAU,QAAQ;EACtB;EAEA,IAAI,MAAM,WAAW,QAAQ,KAAK,SAAS,SAAS,KAAK,GACrD;EAIJ,IAAI,MAAM,WAAW,QAAQ,iBAAiB,MAAM,QAChD,MAAO,OAAqB,YAAY,KAAK;EAGjD,MAAM,SAAS;EACf,KAAK,SAAS,KAAK,KAAK;EACxB,MAAM,QAA+B,KAAK,SAAS,KAAK;EAExD,IAAI,UAAU,KAAA,GAAW;GACrB,MAAM,WAAW,KAAK;GACtB,MAAM,cAAc;EACxB;CACJ;;;;;;CAOA,aAA6B;EACzB,MAAM,SAA2B,KAAK;EAEtC,IAAI,WAAW,QAAQ,EAAE,iBAAiB,SACtC,OAAO;EAIX,OAAO,OAAY,YAAY,IAAI;CACvC;;;;;;CAOA,YAAmB,OAA2B;EAC1C,MAAM,aAAqB,KAAK,SAAS,QAAQ,KAAK;EAEtD,IAAI,eAAe,IACf,OAAO;EAGX,MAAM,QAA+B,KAAK,SAAS,IAAI;EAEvD,KAAK,SAAS,OAAO,YAAY,CAAC;EAClC,MAAM,SAAS;EAEf,IAAI,UAAU,KAAA,GACV,MAAM,gBAAgB,KAAK;EAG/B,OAAO;CACX;;;;;CAMA,YAAyB;EACrB,IAAI,KAAK,SAAS,WAAW,GACzB;EAGJ,MAAM,QAA+B,KAAK,SAAS,IAAI;EAEvD,KAAK,MAAM,SAAS,KAAK,UAAU;GAC/B,OAAO,gBAAgB,KAAK;GAC5B,MAAM,SAAS;EACnB;EAEA,KAAK,SAAS,SAAS;CAC3B;;;;;CAMA,oBAAiC;EAC7B,MAAM,kBAAkB;EAExB,KAAK,MAAM,SAAS,KAAK,UACrB,MAAM,kBAAkB;EAE5B,OAAO,KAAK;CAChB;;;;;;CAOA,SAAmB,MAAwC;EACvD,IAAI,UAA4B;EAEhC,OAAO,YAAY,MAAM;GACrB,IAAI,QAAQ,SAAS,SACjB,OAAO;GAGX,UAAU,QAAQ;EACtB;CAGJ;AACJ"}
package/lib/ID.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 获取全局唯一的递增对象 ID。
3
+ * @returns 新对象的 ID
4
+ */
5
+ declare const GETID: () => number;
6
+ export { GETID };
package/lib/ID.js ADDED
@@ -0,0 +1,15 @@
1
+ //#region src/scripts/ID.ts
2
+ var currentId = 0;
3
+ /**
4
+ * 获取全局唯一的递增对象 ID。
5
+ * @returns 新对象的 ID
6
+ */
7
+ var GETID = () => {
8
+ const id = currentId;
9
+ currentId += 1;
10
+ return id;
11
+ };
12
+ //#endregion
13
+ export { GETID };
14
+
15
+ //# sourceMappingURL=ID.js.map
package/lib/ID.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ID.js","names":[],"sources":["../src/scripts/ID.ts"],"sourcesContent":["let currentId = 0;\n\n/**\n * 获取全局唯一的递增对象 ID。\n * @returns 新对象的 ID\n */\nconst GETID = (): number => {\n const id = currentId;\n currentId += 1;\n return id;\n};\n\nexport { GETID };\n"],"mappings":";AAAA,IAAI,YAAY;;;;;AAMhB,IAAM,cAAsB;CACxB,MAAM,KAAK;CACX,aAAa;CACb,OAAO;AACX"}
@@ -0,0 +1,104 @@
1
+ import type { VersionedMath } from "bpmatrixjs/Math";
2
+ import Mesh from "../Mesh";
3
+ import type { Geometry2d, Material2d } from "../global-types";
4
+ import Raws, { Raw } from "../Raws";
5
+ import type { RawChange, RawOptions, RawSubscriber } from "../Raws";
6
+ import TextureLayers from "../Texture/Layers";
7
+ /** 实例管理设置;raw 为构建时选择,避免丢失的原始值被误认为可以恢复。 */
8
+ export interface IMeshOptions {
9
+ /** 保留原始值和订阅,默认 true,构建后不可切换。 */
10
+ raw?: boolean;
11
+ /** 初始槽数,默认 2,必须是正整数。 */
12
+ capacity?: number;
13
+ /** 扩容倍率,默认 2,必须是不小于 2 的整数。 */
14
+ growthFactor?: number;
15
+ }
16
+ /** 共用 Geometry / Material 的实例网格,每个槽位独立储存世界矩阵和样式。 */
17
+ declare class IMesh extends Mesh implements RawSubscriber {
18
+ /** 对象类型;Scene 仍通过 Mesh 基类识别。 */
19
+ readonly type: string;
20
+ private readonly _raw;
21
+ private readonly _raws;
22
+ private _growthFactor;
23
+ private readonly _ids;
24
+ private readonly _pendingMatrices;
25
+ private readonly _pendingStyles;
26
+ private readonly _local;
27
+ private readonly _world;
28
+ private readonly _sources;
29
+ private readonly _textures;
30
+ private readonly _layerIndices;
31
+ private _layersPending;
32
+ /**
33
+ * @param data 共用几何模板,提前启用需要生成的分区
34
+ * @param material 共用管线和采样器设置,不接管其 Style
35
+ * @param options 默认管理原始值,容量 2,按 2 倍扩容
36
+ */
37
+ constructor(data: Geometry2d, material: Material2d, options?: IMeshOptions);
38
+ /** 是否保留并订阅原始值,只读。 */
39
+ get raw(): boolean;
40
+ /** 原始记录按稳定 ID 查询;raw=false 时 Map 为空。 */
41
+ get raws(): Raws;
42
+ /** 扩容倍率,默认 2;达到 100000 槽后每批追加 100000。 */
43
+ get growthFactor(): number;
44
+ /** @param value 不小于 2 的整数倍率,不改变已有记录 */
45
+ set growthFactor(value: number);
46
+ /** 已分配的槽数,不等于有效条数 count。 */
47
+ get capacity(): number;
48
+ /**
49
+ * 显式预留容量;不缩容、不丢弃记录。GPU 限制在 Render 上传前校验。
50
+ * @param value 不小于 count 的正整数
51
+ */
52
+ set capacity(value: number);
53
+ /** 三套独立图片层表;普通 Mesh 在相同绑定位置只使用一层。 */
54
+ get textures(): readonly TextureLayers[];
55
+ /**
56
+ * 按 push 顺序绘制,返回 ID 而非槽位。raw=false 冻结本次调用时的世界矩阵。
57
+ * @param options 原始值;省略 style 使用当前材质样式
58
+ * @returns 稳定 ID,通过 raws.map.get(id) 获取受管记录
59
+ */
60
+ push(options?: RawOptions): number;
61
+ /**
62
+ * 手动完整覆盖一个槽位,省略值使用默认值,不是局部 patch。
63
+ * raw=false 不建立订阅,按当前 IMesh 世界矩阵重新计算这个槽位。
64
+ * @param index 连续数组下标
65
+ * @param options 新的完整原始值
66
+ */
67
+ updateAt(index: number, options: RawOptions): void;
68
+ /**
69
+ * 变化只登记槽位;共享 Style 可以通知多个记录,不同步上传 GPU。
70
+ * @param record 来源记录
71
+ * @param change 变化区域
72
+ */
73
+ onRawChange(record: Raw, change: RawChange): void;
74
+ /**
75
+ * 只在受管模式下由父级世界矩阵变化安排全体矩阵重算。
76
+ * @param source 数学对象
77
+ * @param field 关联字段
78
+ */
79
+ onMathChange(source: VersionedMath, field: string): void;
80
+ /** 按待处理槽位打包,静止帧不重新分配数组;世界矩阵仅储存一份。 */
81
+ updateInstanceData(): void;
82
+ /** 清空记录并解绑,保留已分配 CPU 容量供后续 push 使用。 */
83
+ clear(): void;
84
+ /** 解除原始记录、贴图层表和资源订阅,不销毁共享几何、材质或图片。 */
85
+ dispose(): void;
86
+ /** @param count 即将使用的条数 */
87
+ private ensureCapacity;
88
+ /** @param options 完整输入 @returns 校验后的值,不保留临时默认对象 */
89
+ private resolve;
90
+ /** @param index 槽位 @param values 局部变换,输出只保存 world * local */
91
+ private writeMatrix;
92
+ /** @param index 槽位 @param style 样式 @param enabled 整条记录开关 */
93
+ private writeStyle;
94
+ /** @param index 槽位 @param style 只截取图片引用,不保留整个 Style */
95
+ private setSources;
96
+ /** 图片引用变化时才重建去重层表,避免反复换图后无限积累废弃层。 */
97
+ private updateTextureLayers;
98
+ /** @param index 将三套纹理层号写到样式最后一个 vec4 */
99
+ private writeLayers;
100
+ /** 拦截销毁后复用。 */
101
+ private assertActive;
102
+ }
103
+ export default IMesh;
104
+ export type { RawOptions } from "../Raws";
@@ -0,0 +1,333 @@
1
+ import { GETID } from "../ID.js";
2
+ import { WriteStyleData } from "../Style/WriteStyleData.js";
3
+ import Style from "../Style/index.js";
4
+ import Mesh from "../Mesh/index.js";
5
+ import Raws, { Raw } from "../Raws/index.js";
6
+ import TextureLayers from "../Texture/Layers.js";
7
+ import { Mat3, Vec2 } from "bpmatrixjs/Math";
8
+ //#region src/scripts/IMesh/index.ts
9
+ /** 共用 Geometry / Material 的实例网格,每个槽位独立储存世界矩阵和样式。 */
10
+ var IMesh = class extends Mesh {
11
+ /** 对象类型;Scene 仍通过 Mesh 基类识别。 */
12
+ type = "IMesh";
13
+ _raw;
14
+ _raws = new Raws();
15
+ _growthFactor = 2;
16
+ _ids = [];
17
+ _pendingMatrices = /* @__PURE__ */ new Set();
18
+ _pendingStyles = /* @__PURE__ */ new Set();
19
+ _local = new Mat3();
20
+ _world = new Mat3();
21
+ _sources = [];
22
+ _textures = [
23
+ new TextureLayers(),
24
+ new TextureLayers(),
25
+ new TextureLayers()
26
+ ];
27
+ _layerIndices = [
28
+ /* @__PURE__ */ new Map(),
29
+ /* @__PURE__ */ new Map(),
30
+ /* @__PURE__ */ new Map()
31
+ ];
32
+ _layersPending = false;
33
+ /**
34
+ * @param data 共用几何模板,提前启用需要生成的分区
35
+ * @param material 共用管线和采样器设置,不接管其 Style
36
+ * @param options 默认管理原始值,容量 2,按 2 倍扩容
37
+ */
38
+ constructor(data, material, options = {}) {
39
+ ValidateOptions(options);
40
+ super(data, material, false);
41
+ this._raw = options.raw ?? true;
42
+ this._count = 0;
43
+ this._capacity = 0;
44
+ this.growthFactor = options.growthFactor ?? 2;
45
+ try {
46
+ this.capacity = options.capacity ?? 2;
47
+ } catch (error) {
48
+ super.dispose();
49
+ throw error;
50
+ }
51
+ }
52
+ /** 是否保留并订阅原始值,只读。 */
53
+ get raw() {
54
+ return this._raw;
55
+ }
56
+ /** 原始记录按稳定 ID 查询;raw=false 时 Map 为空。 */
57
+ get raws() {
58
+ return this._raws;
59
+ }
60
+ /** 扩容倍率,默认 2;达到 100000 槽后每批追加 100000。 */
61
+ get growthFactor() {
62
+ return this._growthFactor;
63
+ }
64
+ /** @param value 不小于 2 的整数倍率,不改变已有记录 */
65
+ set growthFactor(value) {
66
+ if (!Number.isSafeInteger(value) || value < 2) throw new RangeError("growthFactor must be an integer >= 2.");
67
+ this._growthFactor = value;
68
+ }
69
+ /** 已分配的槽数,不等于有效条数 count。 */
70
+ get capacity() {
71
+ return this._capacity;
72
+ }
73
+ /**
74
+ * 显式预留容量;不缩容、不丢弃记录。GPU 限制在 Render 上传前校验。
75
+ * @param value 不小于 count 的正整数
76
+ */
77
+ set capacity(value) {
78
+ this.assertActive();
79
+ if (!Number.isSafeInteger(value) || value < 1 || value < this._count) throw new RangeError("Invalid capacity.");
80
+ if (value <= this._capacity) return;
81
+ if (value > Math.floor(4294967295 / 176)) throw new RangeError("CPU array capacity exceeds 4 GiB.");
82
+ const matrices = new Float32Array(value * 12);
83
+ const styles = new Float32Array(value * 44);
84
+ matrices.set(this._matrixData.subarray(0, this._count * 12));
85
+ styles.set(this._styleData.subarray(0, this._count * 44));
86
+ this._matrixData = matrices;
87
+ this._styleData = styles;
88
+ this._capacity = value;
89
+ this._matrixVersion++;
90
+ this._styleVersion++;
91
+ this.updateVersion();
92
+ }
93
+ /** 三套独立图片层表;普通 Mesh 在相同绑定位置只使用一层。 */
94
+ get textures() {
95
+ this.updateTextureLayers();
96
+ return this._textures;
97
+ }
98
+ /**
99
+ * 按 push 顺序绘制,返回 ID 而非槽位。raw=false 冻结本次调用时的世界矩阵。
100
+ * @param options 原始值;省略 style 使用当前材质样式
101
+ * @returns 稳定 ID,通过 raws.map.get(id) 获取受管记录
102
+ */
103
+ push(options = {}) {
104
+ this.assertActive();
105
+ const values = this.resolve(options);
106
+ this.ensureCapacity(this._count + 1);
107
+ this.ensureWorldMatrix();
108
+ const index = this._count;
109
+ const record = this._raw ? new Raw(index, values) : void 0;
110
+ const id = record?.id ?? GETID();
111
+ this._count++;
112
+ this._ids.push(id);
113
+ if (record !== void 0) {
114
+ this._raws.add(record);
115
+ record.add(this);
116
+ }
117
+ this.writeMatrix(index, values);
118
+ this.writeStyle(index, values.style, values.enabled);
119
+ this.setSources(index, values.style);
120
+ this._matrixVersion++;
121
+ this._styleVersion++;
122
+ this.updateVersion();
123
+ return id;
124
+ }
125
+ /**
126
+ * 手动完整覆盖一个槽位,省略值使用默认值,不是局部 patch。
127
+ * raw=false 不建立订阅,按当前 IMesh 世界矩阵重新计算这个槽位。
128
+ * @param index 连续数组下标
129
+ * @param options 新的完整原始值
130
+ */
131
+ updateAt(index, options) {
132
+ this.assertActive();
133
+ if (!Number.isSafeInteger(index) || index < 0 || index >= this._count) throw new RangeError("Invalid slot index.");
134
+ const values = this.resolve(options);
135
+ const record = this._raws.map.get(this._ids[index]);
136
+ if (record !== void 0) {
137
+ record.position = values.position;
138
+ record.rotation = values.rotation;
139
+ record.scale = values.scale;
140
+ record.style = values.style;
141
+ record.enabled = values.enabled;
142
+ }
143
+ this.ensureWorldMatrix();
144
+ this.writeMatrix(index, values);
145
+ this.writeStyle(index, values.style, values.enabled);
146
+ this.setSources(index, values.style);
147
+ this._pendingMatrices.delete(index);
148
+ this._pendingStyles.delete(index);
149
+ this._matrixVersion++;
150
+ this._styleVersion++;
151
+ this.updateVersion();
152
+ }
153
+ /**
154
+ * 变化只登记槽位;共享 Style 可以通知多个记录,不同步上传 GPU。
155
+ * @param record 来源记录
156
+ * @param change 变化区域
157
+ */
158
+ onRawChange(record, change) {
159
+ if (this._disposed || this._raws.map.get(record.id) !== record) return;
160
+ if (change === "matrix") this._pendingMatrices.add(record.index);
161
+ else if (change !== "textureData" && change !== "sampler") this._pendingStyles.add(record.index);
162
+ if (change === "texture") this.setSources(record.index, record.style);
163
+ this._materialPending = true;
164
+ }
165
+ /**
166
+ * 只在受管模式下由父级世界矩阵变化安排全体矩阵重算。
167
+ * @param source 数学对象
168
+ * @param field 关联字段
169
+ */
170
+ onMathChange(source, field) {
171
+ super.onMathChange(source, field);
172
+ if (!this._raw && field === "worldMatrix") this._matrixPending = false;
173
+ }
174
+ /** 按待处理槽位打包,静止帧不重新分配数组;世界矩阵仅储存一份。 */
175
+ updateInstanceData() {
176
+ this.assertActive();
177
+ this.ensureWorldMatrix();
178
+ if (this._geometryPending && this.data !== void 0) this.material?.addGeometryType(this.data.type);
179
+ let matricesChanged = false;
180
+ let stylesChanged = false;
181
+ if (this._raw && this._matrixPending) {
182
+ for (const record of this._raws.map.values()) this.writeMatrix(record.index, record);
183
+ matricesChanged = this._count > 0;
184
+ } else for (const index of this._pendingMatrices) {
185
+ const record = this._raws.map.get(this._ids[index]);
186
+ if (record !== void 0) {
187
+ this.writeMatrix(index, record);
188
+ matricesChanged = true;
189
+ }
190
+ }
191
+ this.updateTextureLayers();
192
+ for (const index of this._pendingStyles) {
193
+ const record = this._raws.map.get(this._ids[index]);
194
+ if (record !== void 0) {
195
+ this.writeStyle(index, record.style, record.enabled);
196
+ stylesChanged = true;
197
+ }
198
+ }
199
+ if (matricesChanged) this._matrixVersion++;
200
+ if (stylesChanged) this._styleVersion++;
201
+ this._pendingMatrices.clear();
202
+ this._pendingStyles.clear();
203
+ this._matrixPending = false;
204
+ this._stylePending = false;
205
+ this._geometryPending = false;
206
+ this._materialPending = false;
207
+ }
208
+ /** 清空记录并解绑,保留已分配 CPU 容量供后续 push 使用。 */
209
+ clear() {
210
+ this.assertActive();
211
+ this._raws.clear();
212
+ this._count = 0;
213
+ this._ids.length = 0;
214
+ this._sources.length = 0;
215
+ this._pendingMatrices.clear();
216
+ this._pendingStyles.clear();
217
+ for (const texture of this._textures) texture.set([]);
218
+ for (const indices of this._layerIndices) indices.clear();
219
+ this._layersPending = false;
220
+ this._matrixVersion++;
221
+ this._styleVersion++;
222
+ this.updateVersion();
223
+ this.getScene(this)?.updateVersion();
224
+ }
225
+ /** 解除原始记录、贴图层表和资源订阅,不销毁共享几何、材质或图片。 */
226
+ dispose() {
227
+ if (this._disposed) return;
228
+ this.clear();
229
+ for (const texture of this._textures) texture.dispose();
230
+ super.dispose();
231
+ }
232
+ /** @param count 即将使用的条数 */
233
+ ensureCapacity(count) {
234
+ let capacity = this._capacity;
235
+ while (capacity < count) capacity = capacity < 1e5 ? Math.min(capacity * this._growthFactor, 1e5) : Math.ceil(count / 1e5) * 1e5;
236
+ if (capacity !== this._capacity) this.capacity = capacity;
237
+ }
238
+ /** @param options 完整输入 @returns 校验后的值,不保留临时默认对象 */
239
+ resolve(options) {
240
+ const values = {
241
+ position: options.position ?? new Vec2(),
242
+ rotation: options.rotation ?? 0,
243
+ scale: options.scale ?? new Vec2(1, 1),
244
+ style: options.style ?? this.material?.style ?? new Style(),
245
+ enabled: options.enabled ?? true
246
+ };
247
+ if (![
248
+ values.position.x,
249
+ values.position.y,
250
+ values.scale.x,
251
+ values.scale.y,
252
+ values.rotation
253
+ ].every(Number.isFinite)) throw new RangeError("Transform components must be finite.");
254
+ return values;
255
+ }
256
+ /** @param index 槽位 @param values 局部变换,输出只保存 world * local */
257
+ writeMatrix(index, values) {
258
+ const c = Math.cos(values.rotation);
259
+ const s = Math.sin(values.rotation);
260
+ this._local.set([
261
+ c * values.scale.x,
262
+ s * values.scale.x,
263
+ 0,
264
+ -s * values.scale.y,
265
+ c * values.scale.y,
266
+ 0,
267
+ values.position.x,
268
+ values.position.y,
269
+ 1
270
+ ]);
271
+ this._world.mul(this.worldMatrix, this._local);
272
+ this._matrixData.set(this._world.GPUData, index * 12);
273
+ }
274
+ /** @param index 槽位 @param style 样式 @param enabled 整条记录开关 */
275
+ writeStyle(index, style, enabled) {
276
+ const offset = index * 44;
277
+ WriteStyleData(style, this._styleData, offset);
278
+ if (!enabled) this._styleData.fill(0, offset + 36, offset + 40);
279
+ this.writeLayers(index);
280
+ }
281
+ /** @param index 槽位 @param style 只截取图片引用,不保留整个 Style */
282
+ setSources(index, style) {
283
+ const previous = this._sources.at(index);
284
+ const next = [
285
+ style.solid.texture,
286
+ style.edge.texture,
287
+ style.points.texture
288
+ ];
289
+ if (previous !== void 0 && next.every((texture, part) => texture === previous[part])) return;
290
+ this._sources[index] = next;
291
+ this._layersPending = true;
292
+ this.getScene(this)?.updateVersion();
293
+ }
294
+ /** 图片引用变化时才重建去重层表,避免反复换图后无限积累废弃层。 */
295
+ updateTextureLayers() {
296
+ if (!this._layersPending) return;
297
+ for (let part = 0; part < 3; part++) {
298
+ const indices = this._layerIndices[part];
299
+ const layers = [];
300
+ indices.clear();
301
+ for (const sources of this._sources) {
302
+ const texture = sources[part];
303
+ if (!indices.has(texture)) {
304
+ indices.set(texture, layers.length);
305
+ layers.push(texture);
306
+ }
307
+ }
308
+ this._textures[part].set(layers);
309
+ }
310
+ for (let index = 0; index < this._count; index++) this.writeLayers(index);
311
+ this._styleVersion++;
312
+ this._layersPending = false;
313
+ }
314
+ /** @param index 将三套纹理层号写到样式最后一个 vec4 */
315
+ writeLayers(index) {
316
+ for (let part = 0; part < 3; part++) this._styleData[index * 44 + 40 + part] = this._layerIndices[part].get(this._sources[index]?.[part]) ?? 0;
317
+ }
318
+ /** 拦截销毁后复用。 */
319
+ assertActive() {
320
+ if (this._disposed) throw new Error("Disposed IMesh cannot be reused.");
321
+ }
322
+ };
323
+ /** @param options 构建选项;不创建任何订阅或分配大数组 */
324
+ var ValidateOptions = (options) => {
325
+ const capacity = options.capacity ?? 2;
326
+ const factor = options.growthFactor ?? 2;
327
+ if (!Number.isSafeInteger(capacity) || capacity < 1 || capacity > Math.floor(4294967295 / 176)) throw new RangeError("Invalid initial capacity.");
328
+ if (!Number.isSafeInteger(factor) || factor < 2) throw new RangeError("growthFactor must be an integer >= 2.");
329
+ };
330
+ //#endregion
331
+ export { IMesh as default };
332
+
333
+ //# sourceMappingURL=index.js.map