@planara/core 1.3.1 → 1.4.0
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,4 +1,6 @@
|
|
|
1
1
|
import { Renderer } from './renderer';
|
|
2
|
+
import { Mesh } from 'ogl';
|
|
3
|
+
import { Figure } from '@planara/types';
|
|
2
4
|
/**
|
|
3
5
|
* Рендерер для редактора.
|
|
4
6
|
* Добавляет сетку, оси координат и поддержку Orbit для управления камерой.
|
|
@@ -7,6 +9,10 @@ import { Renderer } from './renderer';
|
|
|
7
9
|
export declare class EditorRenderer extends Renderer {
|
|
8
10
|
/** Orbit-контроллер для управления камерой */
|
|
9
11
|
private orbit;
|
|
12
|
+
/** Raycast для подсветки моделей при наведении */
|
|
13
|
+
private raycast;
|
|
14
|
+
/** Курсор мыши для остлеживания наведения на 3D-модель */
|
|
15
|
+
private readonly mouse;
|
|
10
16
|
/**
|
|
11
17
|
* Инициализация сцены редактора.
|
|
12
18
|
* Создает сетку, оси координат и orbit-контроллер.
|
|
@@ -17,5 +23,23 @@ export declare class EditorRenderer extends Renderer {
|
|
|
17
23
|
* Обновление состояния рендерера.
|
|
18
24
|
*/
|
|
19
25
|
protected update(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Метод для добавления фигуры.
|
|
28
|
+
* Настройка raycast.
|
|
29
|
+
* @param figure Данные фигуры: position, normal, uv
|
|
30
|
+
*/
|
|
31
|
+
addFigure(figure: Figure): Mesh<import('ogl').Geometry, import('ogl').Program>;
|
|
32
|
+
/**
|
|
33
|
+
* Обновление uniform uHit для конкретной 3D-модели
|
|
34
|
+
*/
|
|
35
|
+
protected updateHitUniform(mesh: Mesh): void;
|
|
36
|
+
/**
|
|
37
|
+
* Инициализация обработчиков мыши для raycast
|
|
38
|
+
*/
|
|
39
|
+
private initMouseListeners;
|
|
40
|
+
/**
|
|
41
|
+
* Обработчик движения мыши
|
|
42
|
+
*/
|
|
43
|
+
private handleMouseMove;
|
|
20
44
|
}
|
|
21
45
|
//# sourceMappingURL=editor-renderer.d.ts.map
|
|
@@ -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;
|
|
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,EAAgD,KAAK,IAAI,EAAE,MAAM,KAAK,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,8CAA8C;IAC9C,OAAO,CAAC,KAAK,CAAS;IAEtB,kDAAkD;IAClD,OAAO,CAAC,OAAO,CAAW;IAE1B,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B;;;;OAIG;gBACgB,MAAM,EAAE,iBAAiB;IAyB5C;;OAEG;IACH,SAAS,CAAC,MAAM;IAKhB;;;;OAIG;IACa,SAAS,CAAC,MAAM,EAAE,MAAM;IAsBxC;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI;IAIrC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,eAAe,CA2BrB;CACH"}
|
package/dist/core/renderer.d.ts
CHANGED
|
@@ -13,7 +13,10 @@ export declare abstract class Renderer {
|
|
|
13
13
|
protected camera: Camera;
|
|
14
14
|
/** HTML-элемент canvas, на котором рендерится сцена */
|
|
15
15
|
protected canvas: HTMLCanvasElement;
|
|
16
|
+
/** Program для настройки рендеринга моделей */
|
|
16
17
|
protected program: Program;
|
|
18
|
+
/** Массив моделей на сцене */
|
|
19
|
+
protected meshes: Mesh[];
|
|
17
20
|
/**
|
|
18
21
|
* Конструктор рендерера
|
|
19
22
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/core/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,KAAK,CAAC;AAE/F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;;GAGG;AACH,8BAAsB,QAAQ;IAC5B,8BAA8B;IAC9B,SAAS,CAAC,EAAE,EAAE,WAAW,CAAC;IAE1B,4BAA4B;IAC5B,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC;IAE3B,uBAAuB;IACvB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IAEzB,uDAAuD;IACvD,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAEpC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,SAAS,aAAa,MAAM,EAAE,iBAAiB;IAyB/C;;OAEG;IACI,MAAM;IAMb;;OAEG;IACH,SAAS,CAAC,MAAM;IAIhB;;OAEG;IACH,SAAS,CAAC,MAAM,IAAI,IAAI;IAExB;;OAEG;IACI,IAAI;IAMX;;;OAGG;IACI,SAAS,CAAC,MAAM,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/core/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,KAAK,CAAC;AAE/F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;;GAGG;AACH,8BAAsB,QAAQ;IAC5B,8BAA8B;IAC9B,SAAS,CAAC,EAAE,EAAE,WAAW,CAAC;IAE1B,4BAA4B;IAC5B,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC;IAE3B,uBAAuB;IACvB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IAEzB,uDAAuD;IACvD,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAEpC,+CAA+C;IAC/C,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAE3B,8BAA8B;IAC9B,SAAS,CAAC,MAAM,EAAG,IAAI,EAAE,CAAC;IAE1B;;;OAGG;IACH,SAAS,aAAa,MAAM,EAAE,iBAAiB;IAyB/C;;OAEG;IACI,MAAM;IAMb;;OAEG;IACH,SAAS,CAAC,MAAM;IAIhB;;OAEG;IACH,SAAS,CAAC,MAAM,IAAI,IAAI;IAExB;;OAEG;IACI,IAAI;IAMX;;;OAGG;IACI,SAAS,CAAC,MAAM,EAAE,MAAM;CAqBhC"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("ogl");function v(s){const e=`
|
|
2
2
|
attribute vec3 position;
|
|
3
3
|
attribute vec3 normal;
|
|
4
4
|
attribute vec2 uv;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
vNormal = normalize(normalMatrix * normal);
|
|
16
16
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
17
17
|
}
|
|
18
|
-
`,
|
|
18
|
+
`,t=`
|
|
19
19
|
precision highp float;
|
|
20
20
|
|
|
21
21
|
uniform sampler2D tMap;
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
gl_FragColor.rgb = tex + shading;
|
|
30
30
|
gl_FragColor.a = 1.0;
|
|
31
31
|
}
|
|
32
|
-
`,
|
|
33
|
-
`);for(const
|
|
32
|
+
`,i=new r.Texture(s);return new r.Program(s,{vertex:e,fragment:t,uniforms:{tMap:{value:i}}})}class h{gl;scene;camera;canvas;program;meshes;constructor(e){this.canvas=e,this.gl=new r.Renderer({canvas:e}),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=v(this.gl.gl)}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}}class p extends h{orbit;raycast;mouse;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 r.Orbit(this.camera,{element:this.canvas}),this.raycast=new r.Raycast,this.mouse=new r.Vec2,this.initMouseListeners()}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)}),t}updateHitUniform(e){this.program.uniforms.uHit.value=e.isHit?1:0}initMouseListeners(){window.addEventListener("load",()=>{document.addEventListener("mousemove",this.handleMouseMove,!1),document.addEventListener("touchmove",this.handleMouseMove,!1)})}handleMouseMove=e=>{let t,i;if(e instanceof MouseEvent)t=e.clientX,i=e.clientY;else{if(e.touches[0]===void 0)return;t=e.touches[0].clientX,i=e.touches[0].clientY}this.mouse.set(2*(t/this.canvas.width)-1,2*(1-i/this.canvas.height)-1),this.raycast.castMouse(this.camera,this.mouse),this.meshes.forEach(a=>a.isHit=!1),this.raycast.intersectBounds(this.meshes).forEach(a=>a.isHit=!0)}}class g 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 f{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 d=(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||{});class b{positions=[];normals=[];uvs=[];tmpPositions=[];tmpNormals=[];tmpUVs=[];load(e){const t=e.split(`
|
|
33
|
+
`);for(const n of t){if(!n.trim()||n.startsWith("#"))continue;const a=n.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 i={type:d.Custom,position:this.positions,...this.normals.length>0&&{normal:this.normals},...this.uvs.length>0&&{uv:this.uvs}};return new f(i)}processFaceLine(e){for(let t=1;t<e.length;t++){const i=e[t];if(!i)continue;const[n,a,c]=i.split("/"),l=n?parseInt(n,10):void 0,m=a?parseInt(a,10):void 0,u=c?parseInt(c,10):void 0;if(l!==void 0){const o=this.tmpPositions[l-1];o&&this.positions.push(...o)}if(m!==void 0){const o=this.tmpUVs[m-1];o&&this.uvs.push(...o)}if(u!==void 0){const o=this.tmpNormals[u-1];o&&this.normals.push(...o)}}}}exports.EditorRenderer=p;exports.ObjLoader=b;exports.PreviewRenderer=g;exports.Renderer=h;exports.createProgram=v;
|
package/dist/index.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Texture as
|
|
2
|
-
function
|
|
3
|
-
const
|
|
1
|
+
import { Texture as p, Program as d, Renderer as g, Transform as f, Camera as b, Geometry as w, Mesh as x, GridHelper as y, AxesHelper as M, Orbit as m, Raycast as P, Vec2 as z, Vec3 as C } from "ogl";
|
|
2
|
+
function F(s) {
|
|
3
|
+
const e = (
|
|
4
4
|
/* glsl */
|
|
5
5
|
`
|
|
6
6
|
attribute vec3 position;
|
|
@@ -20,7 +20,7 @@ function z(e) {
|
|
|
20
20
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
21
21
|
}
|
|
22
22
|
`
|
|
23
|
-
),
|
|
23
|
+
), t = (
|
|
24
24
|
/* glsl */
|
|
25
25
|
`
|
|
26
26
|
precision highp float;
|
|
@@ -37,14 +37,14 @@ function z(e) {
|
|
|
37
37
|
gl_FragColor.a = 1.0;
|
|
38
38
|
}
|
|
39
39
|
`
|
|
40
|
-
), i = new
|
|
41
|
-
return new d(
|
|
42
|
-
vertex:
|
|
43
|
-
fragment:
|
|
40
|
+
), i = new p(s);
|
|
41
|
+
return new d(s, {
|
|
42
|
+
vertex: e,
|
|
43
|
+
fragment: t,
|
|
44
44
|
uniforms: { tMap: { value: i } }
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
-
class
|
|
47
|
+
class u {
|
|
48
48
|
/** Экземпляр рендерера OGL */
|
|
49
49
|
gl;
|
|
50
50
|
/** Корневой объект сцены */
|
|
@@ -53,13 +53,16 @@ class p {
|
|
|
53
53
|
camera;
|
|
54
54
|
/** HTML-элемент canvas, на котором рендерится сцена */
|
|
55
55
|
canvas;
|
|
56
|
+
/** Program для настройки рендеринга моделей */
|
|
56
57
|
program;
|
|
58
|
+
/** Массив моделей на сцене */
|
|
59
|
+
meshes;
|
|
57
60
|
/**
|
|
58
61
|
* Конструктор рендерера
|
|
59
62
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
60
63
|
*/
|
|
61
|
-
constructor(
|
|
62
|
-
this.canvas =
|
|
64
|
+
constructor(e) {
|
|
65
|
+
this.canvas = e, this.gl = new g({ canvas: e }), this.gl.setSize(e.clientWidth, e.clientHeight), this.gl.gl.clearColor(1, 1, 1, 1), this.scene = new f(), this.camera = new b(this.gl.gl, { fov: 45 }), this.camera.position.set(1, 1, 7), this.camera.lookAt([0, 0, 0]), this.program = F(this.gl.gl);
|
|
63
66
|
}
|
|
64
67
|
/**
|
|
65
68
|
* Обновляет размер рендерера и камеры при изменении размеров canvas.
|
|
@@ -88,30 +91,34 @@ class p {
|
|
|
88
91
|
* Публичный метод для добавления фигуры.
|
|
89
92
|
* @param figure Данные фигуры: position, normal, uv
|
|
90
93
|
*/
|
|
91
|
-
addFigure(
|
|
92
|
-
const
|
|
93
|
-
position: { size: 3, data: new Float32Array(
|
|
94
|
-
normal: { size: 3, data: new Float32Array(
|
|
95
|
-
uv: { size: 2, data: new Float32Array(
|
|
96
|
-
}), i = new
|
|
97
|
-
geometry:
|
|
94
|
+
addFigure(e) {
|
|
95
|
+
const t = new w(this.gl.gl, {
|
|
96
|
+
position: { size: 3, data: new Float32Array(e.position) },
|
|
97
|
+
normal: { size: 3, data: new Float32Array(e.normal ?? []) },
|
|
98
|
+
uv: { size: 2, data: new Float32Array(e.uv ?? []) }
|
|
99
|
+
}), i = new x(this.gl.gl, {
|
|
100
|
+
geometry: t,
|
|
98
101
|
program: this.program
|
|
99
102
|
});
|
|
100
|
-
return i.setParent(this.scene), i;
|
|
103
|
+
return i.setParent(this.scene), this.meshes.push(i), i;
|
|
101
104
|
}
|
|
102
105
|
}
|
|
103
|
-
class N extends
|
|
106
|
+
class N extends u {
|
|
104
107
|
/** Orbit-контроллер для управления камерой */
|
|
105
108
|
orbit;
|
|
109
|
+
/** Raycast для подсветки моделей при наведении */
|
|
110
|
+
raycast;
|
|
111
|
+
/** Курсор мыши для остлеживания наведения на 3D-модель */
|
|
112
|
+
mouse;
|
|
106
113
|
/**
|
|
107
114
|
* Инициализация сцены редактора.
|
|
108
115
|
* Создает сетку, оси координат и orbit-контроллер.
|
|
109
116
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
110
117
|
*/
|
|
111
|
-
constructor(
|
|
112
|
-
super(
|
|
113
|
-
const
|
|
114
|
-
|
|
118
|
+
constructor(e) {
|
|
119
|
+
super(e);
|
|
120
|
+
const t = new y(this.gl.gl, { size: 10, divisions: 10 });
|
|
121
|
+
t.position.y = -1e-3, t.setParent(this.scene), new M(this.gl.gl, { size: 6, symmetric: !0 }).setParent(this.scene), this.orbit = new m(this.camera, { element: this.canvas }), this.raycast = new P(), this.mouse = new z(), this.initMouseListeners();
|
|
115
122
|
}
|
|
116
123
|
/**
|
|
117
124
|
* Обновление состояния рендерера.
|
|
@@ -119,18 +126,60 @@ class N extends p {
|
|
|
119
126
|
update() {
|
|
120
127
|
this.orbit?.update();
|
|
121
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Метод для добавления фигуры.
|
|
131
|
+
* Настройка raycast.
|
|
132
|
+
* @param figure Данные фигуры: position, normal, uv
|
|
133
|
+
*/
|
|
134
|
+
addFigure(e) {
|
|
135
|
+
const t = super.addFigure(e);
|
|
136
|
+
if (t.geometry) {
|
|
137
|
+
const i = t.geometry.constructor.name;
|
|
138
|
+
t.geometry.raycast = i.includes("Sphere") ? "sphere" : "box";
|
|
139
|
+
}
|
|
140
|
+
return t.isHit = !1, t.onBeforeRender(({ mesh: i }) => {
|
|
141
|
+
this.updateHitUniform(i);
|
|
142
|
+
}), t;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Обновление uniform uHit для конкретной 3D-модели
|
|
146
|
+
*/
|
|
147
|
+
updateHitUniform(e) {
|
|
148
|
+
this.program.uniforms.uHit.value = e.isHit ? 1 : 0;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Инициализация обработчиков мыши для raycast
|
|
152
|
+
*/
|
|
153
|
+
initMouseListeners() {
|
|
154
|
+
window.addEventListener("load", () => {
|
|
155
|
+
document.addEventListener("mousemove", this.handleMouseMove, !1), document.addEventListener("touchmove", this.handleMouseMove, !1);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Обработчик движения мыши
|
|
160
|
+
*/
|
|
161
|
+
handleMouseMove = (e) => {
|
|
162
|
+
let t, i;
|
|
163
|
+
if (e instanceof MouseEvent)
|
|
164
|
+
t = e.clientX, i = e.clientY;
|
|
165
|
+
else {
|
|
166
|
+
if (e.touches[0] === void 0) return;
|
|
167
|
+
t = e.touches[0].clientX, i = e.touches[0].clientY;
|
|
168
|
+
}
|
|
169
|
+
this.mouse.set(2 * (t / this.canvas.width) - 1, 2 * (1 - i / this.canvas.height) - 1), this.raycast.castMouse(this.camera, this.mouse), this.meshes.forEach((r) => r.isHit = !1), this.raycast.intersectBounds(this.meshes).forEach((r) => r.isHit = !0);
|
|
170
|
+
};
|
|
122
171
|
}
|
|
123
|
-
class
|
|
172
|
+
class U extends u {
|
|
124
173
|
/** Orbit-контроллер для управления камерой */
|
|
125
174
|
orbit;
|
|
126
175
|
/**
|
|
127
176
|
* Инициализация сцены предпросмотра.
|
|
128
177
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
129
178
|
*/
|
|
130
|
-
constructor(
|
|
131
|
-
super(
|
|
179
|
+
constructor(e) {
|
|
180
|
+
super(e), this.orbit = new m(this.camera, {
|
|
132
181
|
element: this.canvas,
|
|
133
|
-
target: new
|
|
182
|
+
target: new C(0, 0, 0),
|
|
134
183
|
minPolarAngle: Math.PI / 2,
|
|
135
184
|
maxPolarAngle: Math.PI / 2,
|
|
136
185
|
enableRotate: !0,
|
|
@@ -145,7 +194,7 @@ class F extends p {
|
|
|
145
194
|
this.orbit?.update();
|
|
146
195
|
}
|
|
147
196
|
}
|
|
148
|
-
class
|
|
197
|
+
class I {
|
|
149
198
|
/** Тип фигуры */
|
|
150
199
|
type;
|
|
151
200
|
/** Позиции вершин */
|
|
@@ -160,11 +209,11 @@ class C {
|
|
|
160
209
|
* Создаёт новую фигуру
|
|
161
210
|
* @param data - исходные данные фигуры
|
|
162
211
|
*/
|
|
163
|
-
constructor(
|
|
164
|
-
this.type =
|
|
212
|
+
constructor(e) {
|
|
213
|
+
this.type = e.type, this.position = e.position, this.normal = e.normal ?? [], this.uv = e.uv ?? [], this.material = e.material;
|
|
165
214
|
}
|
|
166
215
|
}
|
|
167
|
-
var v = /* @__PURE__ */ ((
|
|
216
|
+
var v = /* @__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))(v || {});
|
|
168
217
|
class A {
|
|
169
218
|
/** Позиции вершин */
|
|
170
219
|
positions = [];
|
|
@@ -180,12 +229,12 @@ class A {
|
|
|
180
229
|
* Загружает OBJ-модель в Figure
|
|
181
230
|
* @param objContent Строка содержимого .obj файла
|
|
182
231
|
*/
|
|
183
|
-
load(
|
|
184
|
-
const
|
|
232
|
+
load(e) {
|
|
233
|
+
const t = e.split(`
|
|
185
234
|
`);
|
|
186
|
-
for (const
|
|
187
|
-
if (!
|
|
188
|
-
const r =
|
|
235
|
+
for (const o of t) {
|
|
236
|
+
if (!o.trim() || o.startsWith("#")) continue;
|
|
237
|
+
const r = o.trim().split(/\s+/);
|
|
189
238
|
switch (r[0]) {
|
|
190
239
|
case "v":
|
|
191
240
|
this.tmpPositions.push(r.slice(1).map(Number));
|
|
@@ -207,26 +256,26 @@ class A {
|
|
|
207
256
|
...this.normals.length > 0 && { normal: this.normals },
|
|
208
257
|
...this.uvs.length > 0 && { uv: this.uvs }
|
|
209
258
|
};
|
|
210
|
-
return new
|
|
259
|
+
return new I(i);
|
|
211
260
|
}
|
|
212
261
|
/**
|
|
213
262
|
* Обрабатывает строку face (f) и разворачивает индексы в массивы для рендеринга
|
|
214
263
|
*/
|
|
215
|
-
processFaceLine(
|
|
216
|
-
for (let
|
|
217
|
-
const i = t
|
|
264
|
+
processFaceLine(e) {
|
|
265
|
+
for (let t = 1; t < e.length; t++) {
|
|
266
|
+
const i = e[t];
|
|
218
267
|
if (!i) continue;
|
|
219
|
-
const [
|
|
220
|
-
if (
|
|
221
|
-
const a = this.tmpPositions[
|
|
268
|
+
const [o, r, n] = i.split("/"), h = o ? parseInt(o, 10) : void 0, c = r ? parseInt(r, 10) : void 0, l = n ? parseInt(n, 10) : void 0;
|
|
269
|
+
if (h !== void 0) {
|
|
270
|
+
const a = this.tmpPositions[h - 1];
|
|
222
271
|
a && this.positions.push(...a);
|
|
223
272
|
}
|
|
224
|
-
if (
|
|
225
|
-
const a = this.tmpUVs[
|
|
273
|
+
if (c !== void 0) {
|
|
274
|
+
const a = this.tmpUVs[c - 1];
|
|
226
275
|
a && this.uvs.push(...a);
|
|
227
276
|
}
|
|
228
|
-
if (
|
|
229
|
-
const a = this.tmpNormals[
|
|
277
|
+
if (l !== void 0) {
|
|
278
|
+
const a = this.tmpNormals[l - 1];
|
|
230
279
|
a && this.normals.push(...a);
|
|
231
280
|
}
|
|
232
281
|
}
|
|
@@ -235,7 +284,7 @@ class A {
|
|
|
235
284
|
export {
|
|
236
285
|
N as EditorRenderer,
|
|
237
286
|
A as ObjLoader,
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
287
|
+
U as PreviewRenderer,
|
|
288
|
+
u as Renderer,
|
|
289
|
+
F as createProgram
|
|
241
290
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(r
|
|
1
|
+
(function(a,r){typeof exports=="object"&&typeof module<"u"?r(exports,require("ogl")):typeof define=="function"&&define.amd?define(["exports","ogl"],r):(a=typeof globalThis<"u"?globalThis:a||self,r(a.PlanaraCore={},a.OGL))})(this,(function(a,r){"use strict";function m(s){const e=`
|
|
2
2
|
attribute vec3 position;
|
|
3
3
|
attribute vec3 normal;
|
|
4
4
|
attribute vec2 uv;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
vNormal = normalize(normalMatrix * normal);
|
|
16
16
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
17
17
|
}
|
|
18
|
-
`,
|
|
18
|
+
`,t=`
|
|
19
19
|
precision highp float;
|
|
20
20
|
|
|
21
21
|
uniform sampler2D tMap;
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
gl_FragColor.rgb = tex + shading;
|
|
30
30
|
gl_FragColor.a = 1.0;
|
|
31
31
|
}
|
|
32
|
-
`,
|
|
33
|
-
`);for(const
|
|
32
|
+
`,i=new r.Texture(s);return new r.Program(s,{vertex:e,fragment:t,uniforms:{tMap:{value:i}}})}class c{gl;scene;camera;canvas;program;meshes;constructor(e){this.canvas=e,this.gl=new r.Renderer({canvas:e}),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=m(this.gl.gl)}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}}class f extends c{orbit;raycast;mouse;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 r.Orbit(this.camera,{element:this.canvas}),this.raycast=new r.Raycast,this.mouse=new r.Vec2,this.initMouseListeners()}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)}),t}updateHitUniform(e){this.program.uniforms.uHit.value=e.isHit?1:0}initMouseListeners(){window.addEventListener("load",()=>{document.addEventListener("mousemove",this.handleMouseMove,!1),document.addEventListener("touchmove",this.handleMouseMove,!1)})}handleMouseMove=e=>{let t,i;if(e instanceof MouseEvent)t=e.clientX,i=e.clientY;else{if(e.touches[0]===void 0)return;t=e.touches[0].clientX,i=e.touches[0].clientY}this.mouse.set(2*(t/this.canvas.width)-1,2*(1-i/this.canvas.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)}}class g extends c{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 l=(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))(l||{});class y{positions=[];normals=[];uvs=[];tmpPositions=[];tmpNormals=[];tmpUVs=[];load(e){const t=e.split(`
|
|
33
|
+
`);for(const h of t){if(!h.trim()||h.startsWith("#"))continue;const n=h.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:l.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[h,n,u]=i.split("/"),d=h?parseInt(h,10):void 0,v=n?parseInt(n,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)}}}}a.EditorRenderer=f,a.ObjLoader=y,a.PreviewRenderer=g,a.Renderer=c,a.createProgram=m,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})}));
|