@planara/core 1.4.7 → 1.4.9
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-renderer.d.ts","sourceRoot":"","sources":["../../src/core/editor-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,
|
|
1
|
+
{"version":3,"file":"editor-renderer.d.ts","sourceRoot":"","sources":["../../src/core/editor-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAgC,KAAK,IAAI,EAAW,MAAM,KAAK,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAG7C;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,8CAA8C;IAC9C,OAAO,CAAC,KAAK,CAAkB;IAE/B,kDAAkD;IAClD,OAAO,CAAC,OAAO,CAAW;IAE1B,0DAA0D;IAC1D,OAAO,CAAC,KAAK,CAAQ;IAErB,4DAA4D;IAC5D,OAAO,CAAC,qBAAqB,CAAW;IAExC;;;;OAIG;gBACgB,MAAM,EAAE,iBAAiB;IAyB5C;;OAEG;IACH,SAAS,CAAC,MAAM;IAKhB;;;;OAIG;IACa,SAAS,CAAC,MAAM,EAAE,MAAM;IA2BxC;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI;IAIrC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAK1B;;OAEG;IACH,OAAO,CAAC,eAAe,CAkBrB;IAEF,iBAAiB;IACV,OAAO;CAaf"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Orbit } from 'ogl';
|
|
2
|
+
/** Расширение для Orbit с отслеживанием управления камерой*/
|
|
3
|
+
export declare class OrbitWithState extends Orbit {
|
|
4
|
+
/** Используется ли Orbit-controls */
|
|
5
|
+
isInteracting: boolean;
|
|
6
|
+
private readonly element;
|
|
7
|
+
constructor(object: any, options?: any);
|
|
8
|
+
/** Очистка новых обработчиков событий */
|
|
9
|
+
destroy(): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=orbit-extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orbit-extension.d.ts","sourceRoot":"","sources":["../../src/extensions/orbit-extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC;AAE5B,6DAA6D;AAC7D,qBAAa,cAAe,SAAQ,KAAK;IACvC,qCAAqC;IAC9B,aAAa,EAAE,OAAO,CAAS;IAEtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAEb,MAAM,EAAE,GAAG,EAAE,OAAO,GAAE,GAAQ;IAY1C,yCAAyC;IAClC,OAAO;CAMf"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("ogl");function d(
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("ogl");function d(s){const e=`
|
|
2
2
|
attribute vec3 position;
|
|
3
3
|
attribute vec3 normal;
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
vNormal = normalize(normalMatrix * normal);
|
|
13
13
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
14
14
|
}
|
|
15
|
-
`,
|
|
15
|
+
`,t=`
|
|
16
16
|
precision highp float;
|
|
17
17
|
|
|
18
18
|
uniform float uHit;
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
gl_FragColor.rgb = color + lighting * 0.1;
|
|
27
27
|
gl_FragColor.a = 1.0;
|
|
28
28
|
}
|
|
29
|
-
`;return new r.Program(
|
|
30
|
-
`);for(const
|
|
29
|
+
`;return new r.Program(s,{vertex:e,fragment:t,cullFace:!1,uniforms:{uHit:{value:0}}})}class h{gl;scene;camera;canvas;program;meshes;constructor(e){this.canvas=e,this.gl=new r.Renderer({canvas:e,dpr:2}),this.gl.setSize(e.clientWidth,e.clientHeight),this.gl.gl.clearColor(.1,.1,.1,1),this.scene=new r.Transform,this.camera=new r.Camera(this.gl.gl,{fov:45}),this.camera.position.set(1,1,7),this.camera.lookAt([0,0,0]),this.program=d(this.gl.gl),this.meshes=[]}resize(){this.gl.setSize(this.canvas.width,this.canvas.height),this.camera.perspective({aspect:this.canvas.width/this.canvas.height})}render(){this.gl.render({scene:this.scene,camera:this.camera})}update(){}loop(){this.update(),this.render(),requestAnimationFrame(this.loop.bind(this))}addFigure(e){const t=new r.Geometry(this.gl.gl,{position:{size:3,data:new Float32Array(e.position)},normal:{size:3,data:new Float32Array(e.normal??[])},uv:{size:2,data:new Float32Array(e.uv??[])}}),i=new r.Mesh(this.gl.gl,{geometry:t,program:this.program});return i.setParent(this.scene),this.meshes.push(i),i}destroy(){this.meshes&&(this.meshes.length=0,this.meshes=[]),this.scene=null,this.camera=null,this.program=null,this.gl=null,this.canvas=null}}class p extends r.Orbit{isInteracting=!1;element;constructor(e,t={}){super(e,t),this.element=t.element||document,this.element.addEventListener("mousedown",()=>this.isInteracting=!0),this.element.addEventListener("mouseup",()=>this.isInteracting=!1),this.element.addEventListener("touchstart",()=>this.isInteracting=!0),this.element.addEventListener("touchend",()=>this.isInteracting=!1)}destroy(){this.element.removeEventListener("mousedown",()=>this.isInteracting=!0),this.element.removeEventListener("mouseup",()=>this.isInteracting=!1),this.element.removeEventListener("touchstart",()=>this.isInteracting=!0),this.element.removeEventListener("touchend",()=>this.isInteracting=!1)}}class g extends h{orbit;raycast;mouse;isEventListenersAdded;constructor(e){super(e);const t=new r.GridHelper(this.gl.gl,{size:10,divisions:10});t.position.y=-.001,t.setParent(this.scene),new r.AxesHelper(this.gl.gl,{size:6,symmetric:!0}).setParent(this.scene),this.orbit=new p(this.camera,{element:this.canvas}),this.raycast=new r.Raycast,this.mouse=new r.Vec2,this.isEventListenersAdded=!1}update(){this.orbit?.update()}addFigure(e){const t=super.addFigure(e);if(t.geometry){const i=t.geometry.constructor.name;t.geometry.raycast=i.includes("Sphere")?"sphere":"box"}return t.isHit=!1,t.onBeforeRender(({mesh:i})=>{this.updateHitUniform(i)}),this.isEventListenersAdded||this.initMouseListeners(),t}updateHitUniform(e){this.program.uniforms.uHit.value=e.isHit?1:0}initMouseListeners(){document.addEventListener("mousemove",this.handleMouseMove,!1),this.isEventListenersAdded=!0}handleMouseMove=e=>{if(this.orbit.isInteracting)return;this.mouse.set(2*(e.x/this.gl.width)-1,2*(1-e.y/this.gl.height)-1),this.raycast.castMouse(this.camera,this.mouse),this.meshes.forEach(i=>i.isHit=!1),this.raycast.intersectBounds(this.meshes).forEach(i=>i.isHit=!0)};destroy(){this.isEventListenersAdded&&(window.removeEventListener("mousemove",this.handleMouseMove,!1),this.isEventListenersAdded=!1),this.orbit=null,this.raycast=null,this.mouse=null,super.destroy()}}class f extends h{orbit;constructor(e){super(e),this.orbit=new r.Orbit(this.camera,{element:this.canvas,target:new r.Vec3(0,0,0),minPolarAngle:Math.PI/2,maxPolarAngle:Math.PI/2,enableRotate:!0,enableZoom:!1,enablePan:!1})}update(){this.orbit?.update()}}class b{type;position;normal;uv;material;constructor(e){this.type=e.type,this.position=e.position,this.normal=e.normal??[],this.uv=e.uv??[],this.material=e.material}}var v=(s=>(s[s.Cube=0]="Cube",s[s.Sphere=1]="Sphere",s[s.Plane=2]="Plane",s[s.Cylinder=3]="Cylinder",s[s.Custom=4]="Custom",s))(v||{});class y{positions=[];normals=[];uvs=[];tmpPositions=[];tmpNormals=[];tmpUVs=[];load(e){const t=e.split(`
|
|
30
|
+
`);for(const o of t){if(!o.trim()||o.startsWith("#"))continue;const n=o.trim().split(/\s+/);switch(n[0]){case"v":this.tmpPositions.push(n.slice(1).map(Number));break;case"vn":this.tmpNormals.push(n.slice(1).map(Number));break;case"vt":this.tmpUVs.push(n.slice(1).map(Number));break;case"f":this.processFaceLine(n);break}}const i={type:v.Custom,position:this.positions,...this.normals.length>0&&{normal:this.normals},...this.uvs.length>0&&{uv:this.uvs}};return new b(i)}processFaceLine(e){for(let t=1;t<e.length;t++){const i=e[t];if(!i)continue;const[o,n,l]=i.split("/"),m=o?parseInt(o,10):void 0,c=n?parseInt(n,10):void 0,u=l?parseInt(l,10):void 0;if(m!==void 0){const a=this.tmpPositions[m-1];a&&this.positions.push(...a)}if(c!==void 0){const a=this.tmpUVs[c-1];a&&this.uvs.push(...a)}if(u!==void 0){const a=this.tmpNormals[u-1];a&&this.normals.push(...a)}}}}exports.EditorRenderer=g;exports.ObjLoader=y;exports.PreviewRenderer=f;exports.Renderer=h;exports.createProgram=d;
|
package/dist/index.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Program as
|
|
2
|
-
function
|
|
1
|
+
import { Program as v, Renderer as p, Transform as g, Camera as f, Geometry as y, Mesh as b, Orbit as c, GridHelper as w, AxesHelper as x, Raycast as I, Vec2 as L, Vec3 as E } from "ogl";
|
|
2
|
+
function M(s) {
|
|
3
3
|
const e = (
|
|
4
4
|
/* glsl */
|
|
5
5
|
`
|
|
@@ -17,7 +17,7 @@ function L(t) {
|
|
|
17
17
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
18
18
|
}
|
|
19
19
|
`
|
|
20
|
-
),
|
|
20
|
+
), t = (
|
|
21
21
|
/* glsl */
|
|
22
22
|
`
|
|
23
23
|
precision highp float;
|
|
@@ -35,9 +35,9 @@ function L(t) {
|
|
|
35
35
|
}
|
|
36
36
|
`
|
|
37
37
|
);
|
|
38
|
-
return new
|
|
38
|
+
return new v(s, {
|
|
39
39
|
vertex: e,
|
|
40
|
-
fragment:
|
|
40
|
+
fragment: t,
|
|
41
41
|
cullFace: !1,
|
|
42
42
|
uniforms: {
|
|
43
43
|
uHit: { value: 0 }
|
|
@@ -62,7 +62,7 @@ class u {
|
|
|
62
62
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
63
63
|
*/
|
|
64
64
|
constructor(e) {
|
|
65
|
-
this.canvas = e, this.gl = new
|
|
65
|
+
this.canvas = e, this.gl = new p({ canvas: e, dpr: 2 }), this.gl.setSize(e.clientWidth, e.clientHeight), this.gl.gl.clearColor(0.1, 0.1, 0.1, 1), this.scene = new g(), this.camera = new f(this.gl.gl, { fov: 45 }), this.camera.position.set(1, 1, 7), this.camera.lookAt([0, 0, 0]), this.program = M(this.gl.gl), this.meshes = [];
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
68
68
|
* Обновляет размер рендерера и камеры при изменении размеров canvas.
|
|
@@ -92,12 +92,12 @@ class u {
|
|
|
92
92
|
* @param figure Данные фигуры: position, normal, uv
|
|
93
93
|
*/
|
|
94
94
|
addFigure(e) {
|
|
95
|
-
const
|
|
95
|
+
const t = new y(this.gl.gl, {
|
|
96
96
|
position: { size: 3, data: new Float32Array(e.position) },
|
|
97
97
|
normal: { size: 3, data: new Float32Array(e.normal ?? []) },
|
|
98
98
|
uv: { size: 2, data: new Float32Array(e.uv ?? []) }
|
|
99
|
-
}), i = new
|
|
100
|
-
geometry:
|
|
99
|
+
}), i = new b(this.gl.gl, {
|
|
100
|
+
geometry: t,
|
|
101
101
|
program: this.program
|
|
102
102
|
});
|
|
103
103
|
return i.setParent(this.scene), this.meshes.push(i), i;
|
|
@@ -107,6 +107,18 @@ class u {
|
|
|
107
107
|
this.meshes && (this.meshes.length = 0, this.meshes = []), this.scene = null, this.camera = null, this.program = null, this.gl = null, this.canvas = null;
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
+
class P extends c {
|
|
111
|
+
/** Используется ли Orbit-controls */
|
|
112
|
+
isInteracting = !1;
|
|
113
|
+
element;
|
|
114
|
+
constructor(e, t = {}) {
|
|
115
|
+
super(e, t), this.element = t.element || document, this.element.addEventListener("mousedown", () => this.isInteracting = !0), this.element.addEventListener("mouseup", () => this.isInteracting = !1), this.element.addEventListener("touchstart", () => this.isInteracting = !0), this.element.addEventListener("touchend", () => this.isInteracting = !1);
|
|
116
|
+
}
|
|
117
|
+
/** Очистка новых обработчиков событий */
|
|
118
|
+
destroy() {
|
|
119
|
+
this.element.removeEventListener("mousedown", () => this.isInteracting = !0), this.element.removeEventListener("mouseup", () => this.isInteracting = !1), this.element.removeEventListener("touchstart", () => this.isInteracting = !0), this.element.removeEventListener("touchend", () => this.isInteracting = !1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
110
122
|
class F extends u {
|
|
111
123
|
/** Orbit-контроллер для управления камерой */
|
|
112
124
|
orbit;
|
|
@@ -123,8 +135,8 @@ class F extends u {
|
|
|
123
135
|
*/
|
|
124
136
|
constructor(e) {
|
|
125
137
|
super(e);
|
|
126
|
-
const
|
|
127
|
-
|
|
138
|
+
const t = new w(this.gl.gl, { size: 10, divisions: 10 });
|
|
139
|
+
t.position.y = -1e-3, t.setParent(this.scene), new x(this.gl.gl, { size: 6, symmetric: !0 }).setParent(this.scene), this.orbit = new P(this.camera, { element: this.canvas }), this.raycast = new I(), this.mouse = new L(), this.isEventListenersAdded = !1;
|
|
128
140
|
}
|
|
129
141
|
/**
|
|
130
142
|
* Обновление состояния рендерера.
|
|
@@ -138,14 +150,14 @@ class F extends u {
|
|
|
138
150
|
* @param figure Данные фигуры: position, normal, uv
|
|
139
151
|
*/
|
|
140
152
|
addFigure(e) {
|
|
141
|
-
const
|
|
142
|
-
if (
|
|
143
|
-
const i =
|
|
144
|
-
|
|
153
|
+
const t = super.addFigure(e);
|
|
154
|
+
if (t.geometry) {
|
|
155
|
+
const i = t.geometry.constructor.name;
|
|
156
|
+
t.geometry.raycast = i.includes("Sphere") ? "sphere" : "box";
|
|
145
157
|
}
|
|
146
|
-
return
|
|
158
|
+
return t.isHit = !1, t.onBeforeRender(({ mesh: i }) => {
|
|
147
159
|
this.updateHitUniform(i);
|
|
148
|
-
}), this.isEventListenersAdded ||
|
|
160
|
+
}), this.isEventListenersAdded || this.initMouseListeners(), t;
|
|
149
161
|
}
|
|
150
162
|
/**
|
|
151
163
|
* Обновление uniform uHit для конкретной 3D-модели
|
|
@@ -157,14 +169,13 @@ class F extends u {
|
|
|
157
169
|
* Инициализация обработчиков мыши для raycast
|
|
158
170
|
*/
|
|
159
171
|
initMouseListeners() {
|
|
160
|
-
|
|
161
|
-
document.addEventListener("mousemove", this.handleMouseMove, !1);
|
|
162
|
-
});
|
|
172
|
+
document.addEventListener("mousemove", this.handleMouseMove, !1), this.isEventListenersAdded = !0;
|
|
163
173
|
}
|
|
164
174
|
/**
|
|
165
175
|
* Обработчик движения мыши
|
|
166
176
|
*/
|
|
167
177
|
handleMouseMove = (e) => {
|
|
178
|
+
if (this.orbit.isInteracting) return;
|
|
168
179
|
this.mouse.set(2 * (e.x / this.gl.width) - 1, 2 * (1 - e.y / this.gl.height) - 1), this.raycast.castMouse(this.camera, this.mouse), this.meshes.forEach((i) => i.isHit = !1), this.raycast.intersectBounds(this.meshes).forEach((i) => i.isHit = !0);
|
|
169
180
|
};
|
|
170
181
|
/** Деструктор */
|
|
@@ -182,7 +193,7 @@ class z extends u {
|
|
|
182
193
|
constructor(e) {
|
|
183
194
|
super(e), this.orbit = new c(this.camera, {
|
|
184
195
|
element: this.canvas,
|
|
185
|
-
target: new
|
|
196
|
+
target: new E(0, 0, 0),
|
|
186
197
|
minPolarAngle: Math.PI / 2,
|
|
187
198
|
maxPolarAngle: Math.PI / 2,
|
|
188
199
|
enableRotate: !0,
|
|
@@ -197,7 +208,7 @@ class z extends u {
|
|
|
197
208
|
this.orbit?.update();
|
|
198
209
|
}
|
|
199
210
|
}
|
|
200
|
-
class
|
|
211
|
+
class A {
|
|
201
212
|
/** Тип фигуры */
|
|
202
213
|
type;
|
|
203
214
|
/** Позиции вершин */
|
|
@@ -216,7 +227,7 @@ class H {
|
|
|
216
227
|
this.type = e.type, this.position = e.position, this.normal = e.normal ?? [], this.uv = e.uv ?? [], this.material = e.material;
|
|
217
228
|
}
|
|
218
229
|
}
|
|
219
|
-
var d = /* @__PURE__ */ ((
|
|
230
|
+
var d = /* @__PURE__ */ ((s) => (s[s.Cube = 0] = "Cube", s[s.Sphere = 1] = "Sphere", s[s.Plane = 2] = "Plane", s[s.Cylinder = 3] = "Cylinder", s[s.Custom = 4] = "Custom", s))(d || {});
|
|
220
231
|
class C {
|
|
221
232
|
/** Позиции вершин */
|
|
222
233
|
positions = [];
|
|
@@ -233,9 +244,9 @@ class C {
|
|
|
233
244
|
* @param objContent Строка содержимого .obj файла
|
|
234
245
|
*/
|
|
235
246
|
load(e) {
|
|
236
|
-
const
|
|
247
|
+
const t = e.split(`
|
|
237
248
|
`);
|
|
238
|
-
for (const a of
|
|
249
|
+
for (const a of t) {
|
|
239
250
|
if (!a.trim() || a.startsWith("#")) continue;
|
|
240
251
|
const r = a.trim().split(/\s+/);
|
|
241
252
|
switch (r[0]) {
|
|
@@ -259,14 +270,14 @@ class C {
|
|
|
259
270
|
...this.normals.length > 0 && { normal: this.normals },
|
|
260
271
|
...this.uvs.length > 0 && { uv: this.uvs }
|
|
261
272
|
};
|
|
262
|
-
return new
|
|
273
|
+
return new A(i);
|
|
263
274
|
}
|
|
264
275
|
/**
|
|
265
276
|
* Обрабатывает строку face (f) и разворачивает индексы в массивы для рендеринга
|
|
266
277
|
*/
|
|
267
278
|
processFaceLine(e) {
|
|
268
|
-
for (let
|
|
269
|
-
const i = e[
|
|
279
|
+
for (let t = 1; t < e.length; t++) {
|
|
280
|
+
const i = e[t];
|
|
270
281
|
if (!i) continue;
|
|
271
282
|
const [a, r, o] = i.split("/"), h = a ? parseInt(a, 10) : void 0, l = r ? parseInt(r, 10) : void 0, m = o ? parseInt(o, 10) : void 0;
|
|
272
283
|
if (h !== void 0) {
|
|
@@ -289,5 +300,5 @@ export {
|
|
|
289
300
|
C as ObjLoader,
|
|
290
301
|
z as PreviewRenderer,
|
|
291
302
|
u as Renderer,
|
|
292
|
-
|
|
303
|
+
M as createProgram
|
|
293
304
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(r,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("ogl")):typeof define=="function"&&define.amd?define(["exports","ogl"],i):(r=typeof globalThis<"u"?globalThis:r||self,i(r.PlanaraCore={},r.OGL))})(this,(function(r,i){"use strict";function m(s){const e=`
|
|
2
2
|
attribute vec3 position;
|
|
3
3
|
attribute vec3 normal;
|
|
4
4
|
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
gl_FragColor.rgb = color + lighting * 0.1;
|
|
27
27
|
gl_FragColor.a = 1.0;
|
|
28
28
|
}
|
|
29
|
-
`;return new i.Program(s,{vertex:e,fragment:t,cullFace:!1,uniforms:{uHit:{value:0}}})}class l{gl;scene;camera;canvas;program;meshes;constructor(e){this.canvas=e,this.gl=new i.Renderer({canvas:e,dpr:2}),this.gl.setSize(e.clientWidth,e.clientHeight),this.gl.gl.clearColor(1
|
|
30
|
-
`);for(const h of t){if(!h.trim()||h.startsWith("#"))continue;const a=h.trim().split(/\s+/);switch(a[0]){case"v":this.tmpPositions.push(a.slice(1).map(Number));break;case"vn":this.tmpNormals.push(a.slice(1).map(Number));break;case"vt":this.tmpUVs.push(a.slice(1).map(Number));break;case"f":this.processFaceLine(a);break}}const
|
|
29
|
+
`;return new i.Program(s,{vertex:e,fragment:t,cullFace:!1,uniforms:{uHit:{value:0}}})}class l{gl;scene;camera;canvas;program;meshes;constructor(e){this.canvas=e,this.gl=new i.Renderer({canvas:e,dpr:2}),this.gl.setSize(e.clientWidth,e.clientHeight),this.gl.gl.clearColor(.1,.1,.1,1),this.scene=new i.Transform,this.camera=new i.Camera(this.gl.gl,{fov:45}),this.camera.position.set(1,1,7),this.camera.lookAt([0,0,0]),this.program=m(this.gl.gl),this.meshes=[]}resize(){this.gl.setSize(this.canvas.width,this.canvas.height),this.camera.perspective({aspect:this.canvas.width/this.canvas.height})}render(){this.gl.render({scene:this.scene,camera:this.camera})}update(){}loop(){this.update(),this.render(),requestAnimationFrame(this.loop.bind(this))}addFigure(e){const t=new i.Geometry(this.gl.gl,{position:{size:3,data:new Float32Array(e.position)},normal:{size:3,data:new Float32Array(e.normal??[])},uv:{size:2,data:new Float32Array(e.uv??[])}}),n=new i.Mesh(this.gl.gl,{geometry:t,program:this.program});return n.setParent(this.scene),this.meshes.push(n),n}destroy(){this.meshes&&(this.meshes.length=0,this.meshes=[]),this.scene=null,this.camera=null,this.program=null,this.gl=null,this.canvas=null}}class g extends i.Orbit{isInteracting=!1;element;constructor(e,t={}){super(e,t),this.element=t.element||document,this.element.addEventListener("mousedown",()=>this.isInteracting=!0),this.element.addEventListener("mouseup",()=>this.isInteracting=!1),this.element.addEventListener("touchstart",()=>this.isInteracting=!0),this.element.addEventListener("touchend",()=>this.isInteracting=!1)}destroy(){this.element.removeEventListener("mousedown",()=>this.isInteracting=!0),this.element.removeEventListener("mouseup",()=>this.isInteracting=!1),this.element.removeEventListener("touchstart",()=>this.isInteracting=!0),this.element.removeEventListener("touchend",()=>this.isInteracting=!1)}}class f extends l{orbit;raycast;mouse;isEventListenersAdded;constructor(e){super(e);const t=new i.GridHelper(this.gl.gl,{size:10,divisions:10});t.position.y=-.001,t.setParent(this.scene),new i.AxesHelper(this.gl.gl,{size:6,symmetric:!0}).setParent(this.scene),this.orbit=new g(this.camera,{element:this.canvas}),this.raycast=new i.Raycast,this.mouse=new i.Vec2,this.isEventListenersAdded=!1}update(){this.orbit?.update()}addFigure(e){const t=super.addFigure(e);if(t.geometry){const n=t.geometry.constructor.name;t.geometry.raycast=n.includes("Sphere")?"sphere":"box"}return t.isHit=!1,t.onBeforeRender(({mesh:n})=>{this.updateHitUniform(n)}),this.isEventListenersAdded||this.initMouseListeners(),t}updateHitUniform(e){this.program.uniforms.uHit.value=e.isHit?1:0}initMouseListeners(){document.addEventListener("mousemove",this.handleMouseMove,!1),this.isEventListenersAdded=!0}handleMouseMove=e=>{if(this.orbit.isInteracting)return;this.mouse.set(2*(e.x/this.gl.width)-1,2*(1-e.y/this.gl.height)-1),this.raycast.castMouse(this.camera,this.mouse),this.meshes.forEach(n=>n.isHit=!1),this.raycast.intersectBounds(this.meshes).forEach(n=>n.isHit=!0)};destroy(){this.isEventListenersAdded&&(window.removeEventListener("mousemove",this.handleMouseMove,!1),this.isEventListenersAdded=!1),this.orbit=null,this.raycast=null,this.mouse=null,super.destroy()}}class y extends l{orbit;constructor(e){super(e),this.orbit=new i.Orbit(this.camera,{element:this.canvas,target:new i.Vec3(0,0,0),minPolarAngle:Math.PI/2,maxPolarAngle:Math.PI/2,enableRotate:!0,enableZoom:!1,enablePan:!1})}update(){this.orbit?.update()}}class b{type;position;normal;uv;material;constructor(e){this.type=e.type,this.position=e.position,this.normal=e.normal??[],this.uv=e.uv??[],this.material=e.material}}var c=(s=>(s[s.Cube=0]="Cube",s[s.Sphere=1]="Sphere",s[s.Plane=2]="Plane",s[s.Cylinder=3]="Cylinder",s[s.Custom=4]="Custom",s))(c||{});class w{positions=[];normals=[];uvs=[];tmpPositions=[];tmpNormals=[];tmpUVs=[];load(e){const t=e.split(`
|
|
30
|
+
`);for(const h of t){if(!h.trim()||h.startsWith("#"))continue;const a=h.trim().split(/\s+/);switch(a[0]){case"v":this.tmpPositions.push(a.slice(1).map(Number));break;case"vn":this.tmpNormals.push(a.slice(1).map(Number));break;case"vt":this.tmpUVs.push(a.slice(1).map(Number));break;case"f":this.processFaceLine(a);break}}const n={type:c.Custom,position:this.positions,...this.normals.length>0&&{normal:this.normals},...this.uvs.length>0&&{uv:this.uvs}};return new b(n)}processFaceLine(e){for(let t=1;t<e.length;t++){const n=e[t];if(!n)continue;const[h,a,u]=n.split("/"),d=h?parseInt(h,10):void 0,v=a?parseInt(a,10):void 0,p=u?parseInt(u,10):void 0;if(d!==void 0){const o=this.tmpPositions[d-1];o&&this.positions.push(...o)}if(v!==void 0){const o=this.tmpUVs[v-1];o&&this.uvs.push(...o)}if(p!==void 0){const o=this.tmpNormals[p-1];o&&this.normals.push(...o)}}}}r.EditorRenderer=f,r.ObjLoader=w,r.PreviewRenderer=y,r.Renderer=l,r.createProgram=m,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
|