@planara/core 1.4.8 → 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 H(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 H(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
99
|
}), i = new b(this.gl.gl, {
|
|
100
|
-
geometry:
|
|
100
|
+
geometry: t,
|
|
101
101
|
program: this.program
|
|
102
102
|
});
|
|
103
103
|
return i.setParent(this.scene), this.meshes.push(i), i;
|
|
@@ -107,7 +107,19 @@ 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
|
|
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
|
+
}
|
|
122
|
+
class F extends u {
|
|
111
123
|
/** Orbit-контроллер для управления камерой */
|
|
112
124
|
orbit;
|
|
113
125
|
/** Raycast для подсветки моделей при наведении */
|
|
@@ -123,8 +135,8 @@ class z 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 z 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 || this.initMouseListeners(),
|
|
160
|
+
}), this.isEventListenersAdded || this.initMouseListeners(), t;
|
|
149
161
|
}
|
|
150
162
|
/**
|
|
151
163
|
* Обновление uniform uHit для конкретной 3D-модели
|
|
@@ -163,6 +175,7 @@ class z extends u {
|
|
|
163
175
|
* Обработчик движения мыши
|
|
164
176
|
*/
|
|
165
177
|
handleMouseMove = (e) => {
|
|
178
|
+
if (this.orbit.isInteracting) return;
|
|
166
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);
|
|
167
180
|
};
|
|
168
181
|
/** Деструктор */
|
|
@@ -170,7 +183,7 @@ class z extends u {
|
|
|
170
183
|
this.isEventListenersAdded && (window.removeEventListener("mousemove", this.handleMouseMove, !1), this.isEventListenersAdded = !1), this.orbit = null, this.raycast = null, this.mouse = null, super.destroy();
|
|
171
184
|
}
|
|
172
185
|
}
|
|
173
|
-
class
|
|
186
|
+
class z extends u {
|
|
174
187
|
/** Orbit-контроллер для управления камерой */
|
|
175
188
|
orbit;
|
|
176
189
|
/**
|
|
@@ -180,7 +193,7 @@ class C extends u {
|
|
|
180
193
|
constructor(e) {
|
|
181
194
|
super(e), this.orbit = new c(this.camera, {
|
|
182
195
|
element: this.canvas,
|
|
183
|
-
target: new
|
|
196
|
+
target: new E(0, 0, 0),
|
|
184
197
|
minPolarAngle: Math.PI / 2,
|
|
185
198
|
maxPolarAngle: Math.PI / 2,
|
|
186
199
|
enableRotate: !0,
|
|
@@ -195,7 +208,7 @@ class C extends u {
|
|
|
195
208
|
this.orbit?.update();
|
|
196
209
|
}
|
|
197
210
|
}
|
|
198
|
-
class
|
|
211
|
+
class A {
|
|
199
212
|
/** Тип фигуры */
|
|
200
213
|
type;
|
|
201
214
|
/** Позиции вершин */
|
|
@@ -214,8 +227,8 @@ class L {
|
|
|
214
227
|
this.type = e.type, this.position = e.position, this.normal = e.normal ?? [], this.uv = e.uv ?? [], this.material = e.material;
|
|
215
228
|
}
|
|
216
229
|
}
|
|
217
|
-
var d = /* @__PURE__ */ ((
|
|
218
|
-
class
|
|
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 || {});
|
|
231
|
+
class C {
|
|
219
232
|
/** Позиции вершин */
|
|
220
233
|
positions = [];
|
|
221
234
|
/** Нормали вершин */
|
|
@@ -231,9 +244,9 @@ class E {
|
|
|
231
244
|
* @param objContent Строка содержимого .obj файла
|
|
232
245
|
*/
|
|
233
246
|
load(e) {
|
|
234
|
-
const
|
|
247
|
+
const t = e.split(`
|
|
235
248
|
`);
|
|
236
|
-
for (const a of
|
|
249
|
+
for (const a of t) {
|
|
237
250
|
if (!a.trim() || a.startsWith("#")) continue;
|
|
238
251
|
const r = a.trim().split(/\s+/);
|
|
239
252
|
switch (r[0]) {
|
|
@@ -257,14 +270,14 @@ class E {
|
|
|
257
270
|
...this.normals.length > 0 && { normal: this.normals },
|
|
258
271
|
...this.uvs.length > 0 && { uv: this.uvs }
|
|
259
272
|
};
|
|
260
|
-
return new
|
|
273
|
+
return new A(i);
|
|
261
274
|
}
|
|
262
275
|
/**
|
|
263
276
|
* Обрабатывает строку face (f) и разворачивает индексы в массивы для рендеринга
|
|
264
277
|
*/
|
|
265
278
|
processFaceLine(e) {
|
|
266
|
-
for (let
|
|
267
|
-
const i = e[
|
|
279
|
+
for (let t = 1; t < e.length; t++) {
|
|
280
|
+
const i = e[t];
|
|
268
281
|
if (!i) continue;
|
|
269
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;
|
|
270
283
|
if (h !== void 0) {
|
|
@@ -283,9 +296,9 @@ class E {
|
|
|
283
296
|
}
|
|
284
297
|
}
|
|
285
298
|
export {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
299
|
+
F as EditorRenderer,
|
|
300
|
+
C as ObjLoader,
|
|
301
|
+
z as PreviewRenderer,
|
|
289
302
|
u as Renderer,
|
|
290
|
-
|
|
303
|
+
M as createProgram
|
|
291
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
|
|
|
@@ -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 i.Program(
|
|
30
|
-
`);for(const h of
|
|
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"})}));
|