@planara/core 1.2.4 → 1.3.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.
- package/README.md +2 -1
- package/dist/core/editor-renderer.d.ts.map +1 -1
- package/dist/core/preview-renderer.d.ts.map +1 -1
- package/dist/core/renderer.d.ts +15 -8
- package/dist/core/renderer.d.ts.map +1 -1
- package/dist/index.cjs.js +33 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.js +117 -50
- package/dist/index.umd.js +33 -2
- package/dist/loaders/obj-loader.d.ts +4 -1
- package/dist/loaders/obj-loader.d.ts.map +1 -1
- package/dist/utils/program-settings.d.ts +12 -0
- package/dist/utils/program-settings.d.ts.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|

|
|
2
|
+

|
|
2
3
|
|
|
3
4
|
## Planara Core
|
|
4
5
|
|
|
@@ -20,4 +21,4 @@
|
|
|
20
21
|
|
|
21
22
|
- Покраска объектов (через материалы или vertex colors).
|
|
22
23
|
|
|
23
|
-
- Отображение сетки и осей (Grid и Axes Helper).
|
|
24
|
+
- Отображение сетки и осей (Grid и Axes Helper).
|
|
@@ -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;AAGtC;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,8CAA8C;IAC9C,OAAO,CAAC,KAAK,CAAS;IAEtB;;;;OAIG;
|
|
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;AAGtC;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,8CAA8C;IAC9C,OAAO,CAAC,KAAK,CAAS;IAEtB;;;;OAIG;gBACgB,MAAM,EAAE,iBAAiB;IAgB5C;;OAEG;IACH,SAAS,CAAC,MAAM;CAIjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-renderer.d.ts","sourceRoot":"","sources":["../../src/core/preview-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;IAC3C,8CAA8C;IAC9C,OAAO,CAAC,KAAK,CAAS;IAEtB;;;OAGG;gBACS,MAAM,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"preview-renderer.d.ts","sourceRoot":"","sources":["../../src/core/preview-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;IAC3C,8CAA8C;IAC9C,OAAO,CAAC,KAAK,CAAS;IAEtB;;;OAGG;gBACS,MAAM,EAAE,iBAAiB;IAerC;;OAEG;IACH,SAAS,CAAC,MAAM;CAIjB"}
|
package/dist/core/renderer.d.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { Renderer as OGLRenderer, Camera, Transform } from 'ogl';
|
|
1
|
+
import { Renderer as OGLRenderer, Camera, Transform, Mesh, Geometry, Program } from 'ogl';
|
|
2
|
+
import { Figure } from '@planara/types';
|
|
2
3
|
/**
|
|
3
4
|
* Абстрактный базовый класс рендерера для работы с WebGL через OGL.
|
|
4
5
|
* Отвечает за инициализацию сцены, камеры и цикла рендеринга.
|
|
5
6
|
*/
|
|
6
7
|
export declare abstract class Renderer {
|
|
7
8
|
/** Экземпляр рендерера OGL */
|
|
8
|
-
gl: OGLRenderer;
|
|
9
|
+
protected gl: OGLRenderer;
|
|
9
10
|
/** Корневой объект сцены */
|
|
10
|
-
scene: Transform;
|
|
11
|
+
protected scene: Transform;
|
|
11
12
|
/** Камера для сцены */
|
|
12
|
-
camera: Camera;
|
|
13
|
+
protected camera: Camera;
|
|
13
14
|
/** HTML-элемент canvas, на котором рендерится сцена */
|
|
14
15
|
protected canvas: HTMLCanvasElement;
|
|
16
|
+
protected program: Program;
|
|
15
17
|
/**
|
|
16
18
|
* Конструктор рендерера
|
|
17
19
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
18
20
|
*/
|
|
19
|
-
constructor(canvas: HTMLCanvasElement);
|
|
21
|
+
protected constructor(canvas: HTMLCanvasElement);
|
|
20
22
|
/**
|
|
21
23
|
* Обновляет размер рендерера и камеры при изменении размеров canvas.
|
|
22
24
|
*/
|
|
@@ -24,14 +26,19 @@ export declare abstract class Renderer {
|
|
|
24
26
|
/**
|
|
25
27
|
* Выполняет рендеринг сцены с текущей камерой.
|
|
26
28
|
*/
|
|
27
|
-
render(): void;
|
|
29
|
+
protected render(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Метод для обновления логики рендерера.
|
|
32
|
+
*/
|
|
33
|
+
protected update(): void;
|
|
28
34
|
/**
|
|
29
35
|
* Запускает основной цикл рендеринга.
|
|
30
36
|
*/
|
|
31
37
|
loop(): void;
|
|
32
38
|
/**
|
|
33
|
-
*
|
|
39
|
+
* Публичный метод для добавления фигуры.
|
|
40
|
+
* @param figure Данные фигуры: position, normal, uv
|
|
34
41
|
*/
|
|
35
|
-
|
|
42
|
+
addFigure(figure: Figure): Mesh<Geometry, Program>;
|
|
36
43
|
}
|
|
37
44
|
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -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,MAAM,KAAK,CAAC;
|
|
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;IAUb;;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;CAkBhC"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,2 +1,33 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
2
|
-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("ogl");function p(t){const e=`
|
|
2
|
+
attribute vec3 position;
|
|
3
|
+
attribute vec3 normal;
|
|
4
|
+
attribute vec2 uv;
|
|
5
|
+
|
|
6
|
+
uniform mat4 modelViewMatrix;
|
|
7
|
+
uniform mat4 projectionMatrix;
|
|
8
|
+
uniform mat3 normalMatrix;
|
|
9
|
+
|
|
10
|
+
varying vec3 vNormal;
|
|
11
|
+
varying vec2 vUv;
|
|
12
|
+
|
|
13
|
+
void main() {
|
|
14
|
+
vUv = uv;
|
|
15
|
+
vNormal = normalize(normalMatrix * normal);
|
|
16
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
17
|
+
}
|
|
18
|
+
`,i=`
|
|
19
|
+
precision highp float;
|
|
20
|
+
|
|
21
|
+
uniform sampler2D tMap;
|
|
22
|
+
varying vec3 vNormal;
|
|
23
|
+
varying vec2 vUv;
|
|
24
|
+
|
|
25
|
+
void main() {
|
|
26
|
+
vec3 tex = texture2D(tMap, vUv).rgb;
|
|
27
|
+
vec3 light = normalize(vec3(0.5, 1.0, -0.3));
|
|
28
|
+
float shading = dot(normalize(vNormal), light) * 0.15;
|
|
29
|
+
gl_FragColor.rgb = tex + shading;
|
|
30
|
+
gl_FragColor.a = 1.0;
|
|
31
|
+
}
|
|
32
|
+
`,r=new s.Texture(t);return new s.Program(t,{vertex:e,fragment:i,uniforms:{tMap:{value:r}}})}class l{gl;scene;camera;canvas;program;constructor(e){this.canvas=e,this.gl=new s.Renderer({canvas:e}),this.gl.setSize(e.clientWidth,e.clientHeight),this.gl.gl.clearColor(1,1,1,1),this.scene=new s.Transform,this.camera=new s.Camera(this.gl.gl,{fov:45}),this.camera.position.set(1,1,7),this.camera.lookAt([0,0,0]),this.program=p(this.gl.gl)}resize(){this.canvas.width=this.canvas.clientWidth,this.canvas.height=this.canvas.clientHeight,this.gl.setSize(this.canvas.clientWidth,this.canvas.clientHeight),this.camera.perspective({aspect:this.canvas.clientWidth/this.canvas.clientHeight})}render(){this.gl.render({scene:this.scene,camera:this.camera})}update(){}loop(){this.update(),this.render(),requestAnimationFrame(this.loop.bind(this))}addFigure(e){const i=new s.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??[])}}),r=new s.Mesh(this.gl.gl,{geometry:i,program:this.program});return r.setParent(this.scene),r}}class d extends l{orbit;constructor(e){super(e);const i=new s.GridHelper(this.gl.gl,{size:10,divisions:10});i.position.y=-.001,i.setParent(this.scene),new s.AxesHelper(this.gl.gl,{size:6,symmetric:!0}).setParent(this.scene),this.orbit=new s.Orbit(this.camera,{element:this.canvas})}update(){this.orbit?.update()}}class g extends l{orbit;constructor(e){super(e),this.orbit=new s.Orbit(this.camera,{element:this.canvas,target:new s.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 u=(t=>(t[t.Cube=0]="Cube",t[t.Sphere=1]="Sphere",t[t.Plane=2]="Plane",t[t.Cylinder=3]="Cylinder",t[t.Custom=4]="Custom",t))(u||{});class f{positions=[];normals=[];uvs=[];tmpPositions=[];tmpNormals=[];tmpUVs=[];load(e){const i=e.split(`
|
|
33
|
+
`);for(const o of i){if(!o.trim()||o.startsWith("#"))continue;const a=o.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 r={type:u.Custom,position:this.positions,...this.normals.length>0&&{normal:this.normals},...this.uvs.length>0&&{uv:this.uvs}};return new b(r)}processFaceLine(e){for(let i=1;i<e.length;i++){const r=e[i];if(!r)continue;const[o,a,c]=r.split("/"),h=o?parseInt(o,10):void 0,m=a?parseInt(a,10):void 0,v=c?parseInt(c,10):void 0;if(h!==void 0){const n=this.tmpPositions[h-1];n&&this.positions.push(...n)}if(m!==void 0){const n=this.tmpUVs[m-1];n&&this.uvs.push(...n)}if(v!==void 0){const n=this.tmpNormals[v-1];n&&this.normals.push(...n)}}}}exports.EditorRenderer=d;exports.ObjLoader=f;exports.PreviewRenderer=g;exports.Renderer=l;exports.createProgram=p;
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC"}
|
package/dist/index.es.js
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { Texture as u, Program as d, Renderer as g, Transform as b, Camera as f, Geometry as x, Mesh as w, GridHelper as y, AxesHelper as P, Orbit as m, Vec3 as M } from "ogl";
|
|
2
|
+
function z(e) {
|
|
3
|
+
const t = (
|
|
4
|
+
/* glsl */
|
|
5
|
+
`
|
|
6
|
+
attribute vec3 position;
|
|
7
|
+
attribute vec3 normal;
|
|
8
|
+
attribute vec2 uv;
|
|
9
|
+
|
|
10
|
+
uniform mat4 modelViewMatrix;
|
|
11
|
+
uniform mat4 projectionMatrix;
|
|
12
|
+
uniform mat3 normalMatrix;
|
|
13
|
+
|
|
14
|
+
varying vec3 vNormal;
|
|
15
|
+
varying vec2 vUv;
|
|
16
|
+
|
|
17
|
+
void main() {
|
|
18
|
+
vUv = uv;
|
|
19
|
+
vNormal = normalize(normalMatrix * normal);
|
|
20
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
21
|
+
}
|
|
22
|
+
`
|
|
23
|
+
), i = (
|
|
24
|
+
/* glsl */
|
|
25
|
+
`
|
|
26
|
+
precision highp float;
|
|
27
|
+
|
|
28
|
+
uniform sampler2D tMap;
|
|
29
|
+
varying vec3 vNormal;
|
|
30
|
+
varying vec2 vUv;
|
|
31
|
+
|
|
32
|
+
void main() {
|
|
33
|
+
vec3 tex = texture2D(tMap, vUv).rgb;
|
|
34
|
+
vec3 light = normalize(vec3(0.5, 1.0, -0.3));
|
|
35
|
+
float shading = dot(normalize(vNormal), light) * 0.15;
|
|
36
|
+
gl_FragColor.rgb = tex + shading;
|
|
37
|
+
gl_FragColor.a = 1.0;
|
|
38
|
+
}
|
|
39
|
+
`
|
|
40
|
+
), s = new u(e);
|
|
41
|
+
return new d(e, {
|
|
42
|
+
vertex: t,
|
|
43
|
+
fragment: i,
|
|
44
|
+
uniforms: { tMap: { value: s } }
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
class p {
|
|
3
48
|
/** Экземпляр рендерера OGL */
|
|
4
49
|
gl;
|
|
5
50
|
/** Корневой объект сцены */
|
|
@@ -8,18 +53,19 @@ class m {
|
|
|
8
53
|
camera;
|
|
9
54
|
/** HTML-элемент canvas, на котором рендерится сцена */
|
|
10
55
|
canvas;
|
|
56
|
+
program;
|
|
11
57
|
/**
|
|
12
58
|
* Конструктор рендерера
|
|
13
59
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
14
60
|
*/
|
|
15
|
-
constructor(
|
|
16
|
-
this.canvas =
|
|
61
|
+
constructor(t) {
|
|
62
|
+
this.canvas = t, this.gl = new g({ canvas: t }), this.gl.setSize(t.clientWidth, t.clientHeight), this.gl.gl.clearColor(1, 1, 1, 1), this.scene = new b(), this.camera = new f(this.gl.gl, { fov: 45 }), this.camera.position.set(1, 1, 7), this.camera.lookAt([0, 0, 0]), this.program = z(this.gl.gl);
|
|
17
63
|
}
|
|
18
64
|
/**
|
|
19
65
|
* Обновляет размер рендерера и камеры при изменении размеров canvas.
|
|
20
66
|
*/
|
|
21
67
|
resize() {
|
|
22
|
-
this.gl.setSize(this.canvas.clientWidth, this.canvas.clientHeight), this.camera.perspective({ aspect: this.canvas.
|
|
68
|
+
this.canvas.width = this.canvas.clientWidth, this.canvas.height = this.canvas.clientHeight, this.gl.setSize(this.canvas.clientWidth, this.canvas.clientHeight), this.camera.perspective({ aspect: this.canvas.clientWidth / this.canvas.clientHeight });
|
|
23
69
|
}
|
|
24
70
|
/**
|
|
25
71
|
* Выполняет рендеринг сцены с текущей камерой.
|
|
@@ -27,6 +73,11 @@ class m {
|
|
|
27
73
|
render() {
|
|
28
74
|
this.gl.render({ scene: this.scene, camera: this.camera });
|
|
29
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Метод для обновления логики рендерера.
|
|
78
|
+
*/
|
|
79
|
+
update() {
|
|
80
|
+
}
|
|
30
81
|
/**
|
|
31
82
|
* Запускает основной цикл рендеринга.
|
|
32
83
|
*/
|
|
@@ -34,12 +85,22 @@ class m {
|
|
|
34
85
|
this.update(), this.render(), requestAnimationFrame(this.loop.bind(this));
|
|
35
86
|
}
|
|
36
87
|
/**
|
|
37
|
-
*
|
|
88
|
+
* Публичный метод для добавления фигуры.
|
|
89
|
+
* @param figure Данные фигуры: position, normal, uv
|
|
38
90
|
*/
|
|
39
|
-
|
|
91
|
+
addFigure(t) {
|
|
92
|
+
const i = new x(this.gl.gl, {
|
|
93
|
+
position: { size: 3, data: new Float32Array(t.position) },
|
|
94
|
+
normal: { size: 3, data: new Float32Array(t.normal ?? []) },
|
|
95
|
+
uv: { size: 2, data: new Float32Array(t.uv ?? []) }
|
|
96
|
+
}), s = new w(this.gl.gl, {
|
|
97
|
+
geometry: i,
|
|
98
|
+
program: this.program
|
|
99
|
+
});
|
|
100
|
+
return s.setParent(this.scene), s;
|
|
40
101
|
}
|
|
41
102
|
}
|
|
42
|
-
class
|
|
103
|
+
class N extends p {
|
|
43
104
|
/** Orbit-контроллер для управления камерой */
|
|
44
105
|
orbit;
|
|
45
106
|
/**
|
|
@@ -47,10 +108,10 @@ class I extends m {
|
|
|
47
108
|
* Создает сетку, оси координат и orbit-контроллер.
|
|
48
109
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
49
110
|
*/
|
|
50
|
-
constructor(
|
|
51
|
-
super(
|
|
52
|
-
const
|
|
53
|
-
|
|
111
|
+
constructor(t) {
|
|
112
|
+
super(t);
|
|
113
|
+
const i = new y(this.gl.gl, { size: 10, divisions: 10 });
|
|
114
|
+
i.position.y = -1e-3, i.setParent(this.scene), new P(this.gl.gl, { size: 6, symmetric: !0 }).setParent(this.scene), this.orbit = new m(this.camera, { element: this.canvas });
|
|
54
115
|
}
|
|
55
116
|
/**
|
|
56
117
|
* Обновление состояния рендерера.
|
|
@@ -59,16 +120,17 @@ class I extends m {
|
|
|
59
120
|
this.orbit?.update();
|
|
60
121
|
}
|
|
61
122
|
}
|
|
62
|
-
class
|
|
123
|
+
class F extends p {
|
|
63
124
|
/** Orbit-контроллер для управления камерой */
|
|
64
125
|
orbit;
|
|
65
126
|
/**
|
|
66
127
|
* Инициализация сцены предпросмотра.
|
|
67
128
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
68
129
|
*/
|
|
69
|
-
constructor(
|
|
70
|
-
super(
|
|
71
|
-
|
|
130
|
+
constructor(t) {
|
|
131
|
+
super(t), this.orbit = new m(this.camera, {
|
|
132
|
+
element: this.canvas,
|
|
133
|
+
target: new M(0, 0, 0),
|
|
72
134
|
minPolarAngle: Math.PI / 2,
|
|
73
135
|
maxPolarAngle: Math.PI / 2,
|
|
74
136
|
enableRotate: !0,
|
|
@@ -83,7 +145,7 @@ class C extends m {
|
|
|
83
145
|
this.orbit?.update();
|
|
84
146
|
}
|
|
85
147
|
}
|
|
86
|
-
class
|
|
148
|
+
class C {
|
|
87
149
|
/** Тип фигуры */
|
|
88
150
|
type;
|
|
89
151
|
/** Позиции вершин */
|
|
@@ -98,15 +160,19 @@ class P {
|
|
|
98
160
|
* Создаёт новую фигуру
|
|
99
161
|
* @param data - исходные данные фигуры
|
|
100
162
|
*/
|
|
101
|
-
constructor(
|
|
102
|
-
this.type =
|
|
163
|
+
constructor(t) {
|
|
164
|
+
this.type = t.type, this.position = t.position, this.normal = t.normal ?? [], this.uv = t.uv ?? [], this.material = t.material;
|
|
103
165
|
}
|
|
104
166
|
}
|
|
105
|
-
var
|
|
106
|
-
class
|
|
167
|
+
var v = /* @__PURE__ */ ((e) => (e[e.Cube = 0] = "Cube", e[e.Sphere = 1] = "Sphere", e[e.Plane = 2] = "Plane", e[e.Cylinder = 3] = "Cylinder", e[e.Custom = 4] = "Custom", e))(v || {});
|
|
168
|
+
class A {
|
|
169
|
+
/** Позиции вершин */
|
|
107
170
|
positions = [];
|
|
171
|
+
/** Нормали вершин */
|
|
108
172
|
normals = [];
|
|
173
|
+
/** UV-координаты (опционально) */
|
|
109
174
|
uvs = [];
|
|
175
|
+
// Временные поля для парсинга файла
|
|
110
176
|
tmpPositions = [];
|
|
111
177
|
tmpNormals = [];
|
|
112
178
|
tmpUVs = [];
|
|
@@ -114,61 +180,62 @@ class y {
|
|
|
114
180
|
* Загружает OBJ-модель в Figure
|
|
115
181
|
* @param objContent Строка содержимого .obj файла
|
|
116
182
|
*/
|
|
117
|
-
|
|
118
|
-
const
|
|
183
|
+
load(t) {
|
|
184
|
+
const i = t.split(`
|
|
119
185
|
`);
|
|
120
|
-
for (const n of
|
|
186
|
+
for (const n of i) {
|
|
121
187
|
if (!n.trim() || n.startsWith("#")) continue;
|
|
122
|
-
const
|
|
123
|
-
switch (
|
|
188
|
+
const r = n.trim().split(/\s+/);
|
|
189
|
+
switch (r[0]) {
|
|
124
190
|
case "v":
|
|
125
|
-
this.tmpPositions.push(
|
|
191
|
+
this.tmpPositions.push(r.slice(1).map(Number));
|
|
126
192
|
break;
|
|
127
193
|
case "vn":
|
|
128
|
-
this.tmpNormals.push(
|
|
194
|
+
this.tmpNormals.push(r.slice(1).map(Number));
|
|
129
195
|
break;
|
|
130
196
|
case "vt":
|
|
131
|
-
this.tmpUVs.push(
|
|
197
|
+
this.tmpUVs.push(r.slice(1).map(Number));
|
|
132
198
|
break;
|
|
133
199
|
case "f":
|
|
134
|
-
this.processFaceLine(
|
|
200
|
+
this.processFaceLine(r);
|
|
135
201
|
break;
|
|
136
202
|
}
|
|
137
203
|
}
|
|
138
|
-
const
|
|
139
|
-
type:
|
|
204
|
+
const s = {
|
|
205
|
+
type: v.Custom,
|
|
140
206
|
position: this.positions,
|
|
141
207
|
...this.normals.length > 0 && { normal: this.normals },
|
|
142
208
|
...this.uvs.length > 0 && { uv: this.uvs }
|
|
143
209
|
};
|
|
144
|
-
return new
|
|
210
|
+
return new C(s);
|
|
145
211
|
}
|
|
146
212
|
/**
|
|
147
213
|
* Обрабатывает строку face (f) и разворачивает индексы в массивы для рендеринга
|
|
148
214
|
*/
|
|
149
|
-
processFaceLine(
|
|
150
|
-
for (let
|
|
151
|
-
const
|
|
152
|
-
if (!
|
|
153
|
-
const [n,
|
|
154
|
-
if (
|
|
155
|
-
const
|
|
156
|
-
|
|
215
|
+
processFaceLine(t) {
|
|
216
|
+
for (let i = 1; i < t.length; i++) {
|
|
217
|
+
const s = t[i];
|
|
218
|
+
if (!s) continue;
|
|
219
|
+
const [n, r, o] = s.split("/"), l = n ? parseInt(n, 10) : void 0, c = r ? parseInt(r, 10) : void 0, h = o ? parseInt(o, 10) : void 0;
|
|
220
|
+
if (l !== void 0) {
|
|
221
|
+
const a = this.tmpPositions[l - 1];
|
|
222
|
+
a && this.positions.push(...a);
|
|
157
223
|
}
|
|
158
224
|
if (c !== void 0) {
|
|
159
|
-
const
|
|
160
|
-
|
|
225
|
+
const a = this.tmpUVs[c - 1];
|
|
226
|
+
a && this.uvs.push(...a);
|
|
161
227
|
}
|
|
162
|
-
if (
|
|
163
|
-
const
|
|
164
|
-
|
|
228
|
+
if (h !== void 0) {
|
|
229
|
+
const a = this.tmpNormals[h - 1];
|
|
230
|
+
a && this.normals.push(...a);
|
|
165
231
|
}
|
|
166
232
|
}
|
|
167
233
|
}
|
|
168
234
|
}
|
|
169
235
|
export {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
236
|
+
N as EditorRenderer,
|
|
237
|
+
A as ObjLoader,
|
|
238
|
+
F as PreviewRenderer,
|
|
239
|
+
p as Renderer,
|
|
240
|
+
z as createProgram
|
|
174
241
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,2 +1,33 @@
|
|
|
1
|
-
(function(i
|
|
2
|
-
|
|
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 h(t){const e=`
|
|
2
|
+
attribute vec3 position;
|
|
3
|
+
attribute vec3 normal;
|
|
4
|
+
attribute vec2 uv;
|
|
5
|
+
|
|
6
|
+
uniform mat4 modelViewMatrix;
|
|
7
|
+
uniform mat4 projectionMatrix;
|
|
8
|
+
uniform mat3 normalMatrix;
|
|
9
|
+
|
|
10
|
+
varying vec3 vNormal;
|
|
11
|
+
varying vec2 vUv;
|
|
12
|
+
|
|
13
|
+
void main() {
|
|
14
|
+
vUv = uv;
|
|
15
|
+
vNormal = normalize(normalMatrix * normal);
|
|
16
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
17
|
+
}
|
|
18
|
+
`,s=`
|
|
19
|
+
precision highp float;
|
|
20
|
+
|
|
21
|
+
uniform sampler2D tMap;
|
|
22
|
+
varying vec3 vNormal;
|
|
23
|
+
varying vec2 vUv;
|
|
24
|
+
|
|
25
|
+
void main() {
|
|
26
|
+
vec3 tex = texture2D(tMap, vUv).rgb;
|
|
27
|
+
vec3 light = normalize(vec3(0.5, 1.0, -0.3));
|
|
28
|
+
float shading = dot(normalize(vNormal), light) * 0.15;
|
|
29
|
+
gl_FragColor.rgb = tex + shading;
|
|
30
|
+
gl_FragColor.a = 1.0;
|
|
31
|
+
}
|
|
32
|
+
`,n=new i.Texture(t);return new i.Program(t,{vertex:e,fragment:s,uniforms:{tMap:{value:n}}})}class l{gl;scene;camera;canvas;program;constructor(e){this.canvas=e,this.gl=new i.Renderer({canvas:e}),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=h(this.gl.gl)}resize(){this.canvas.width=this.canvas.clientWidth,this.canvas.height=this.canvas.clientHeight,this.gl.setSize(this.canvas.clientWidth,this.canvas.clientHeight),this.camera.perspective({aspect:this.canvas.clientWidth/this.canvas.clientHeight})}render(){this.gl.render({scene:this.scene,camera:this.camera})}update(){}loop(){this.update(),this.render(),requestAnimationFrame(this.loop.bind(this))}addFigure(e){const s=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:s,program:this.program});return n.setParent(this.scene),n}}class g extends l{orbit;constructor(e){super(e);const s=new i.GridHelper(this.gl.gl,{size:10,divisions:10});s.position.y=-.001,s.setParent(this.scene),new i.AxesHelper(this.gl.gl,{size:6,symmetric:!0}).setParent(this.scene),this.orbit=new i.Orbit(this.camera,{element:this.canvas})}update(){this.orbit?.update()}}class f 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 m=(t=>(t[t.Cube=0]="Cube",t[t.Sphere=1]="Sphere",t[t.Plane=2]="Plane",t[t.Cylinder=3]="Cylinder",t[t.Custom=4]="Custom",t))(m||{});class w{positions=[];normals=[];uvs=[];tmpPositions=[];tmpNormals=[];tmpUVs=[];load(e){const s=e.split(`
|
|
33
|
+
`);for(const c of s){if(!c.trim()||c.startsWith("#"))continue;const a=c.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:m.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 s=1;s<e.length;s++){const n=e[s];if(!n)continue;const[c,a,p]=n.split("/"),v=c?parseInt(c,10):void 0,u=a?parseInt(a,10):void 0,d=p?parseInt(p,10):void 0;if(v!==void 0){const o=this.tmpPositions[v-1];o&&this.positions.push(...o)}if(u!==void 0){const o=this.tmpUVs[u-1];o&&this.uvs.push(...o)}if(d!==void 0){const o=this.tmpNormals[d-1];o&&this.normals.push(...o)}}}}r.EditorRenderer=g,r.ObjLoader=w,r.PreviewRenderer=f,r.Renderer=l,r.createProgram=h,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Figure } from '@planara/types';
|
|
2
2
|
export declare class ObjLoader {
|
|
3
|
+
/** Позиции вершин */
|
|
3
4
|
private positions;
|
|
5
|
+
/** Нормали вершин */
|
|
4
6
|
private normals;
|
|
7
|
+
/** UV-координаты (опционально) */
|
|
5
8
|
private uvs;
|
|
6
9
|
private tmpPositions;
|
|
7
10
|
private tmpNormals;
|
|
@@ -10,7 +13,7 @@ export declare class ObjLoader {
|
|
|
10
13
|
* Загружает OBJ-модель в Figure
|
|
11
14
|
* @param objContent Строка содержимого .obj файла
|
|
12
15
|
*/
|
|
13
|
-
|
|
16
|
+
load(objContent: string): Figure;
|
|
14
17
|
/**
|
|
15
18
|
* Обрабатывает строку face (f) и разворачивает индексы в массивы для рендеринга
|
|
16
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obj-loader.d.ts","sourceRoot":"","sources":["../../src/loaders/obj-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA+B,MAAM,gBAAgB,CAAC;AAErE,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAgB;
|
|
1
|
+
{"version":3,"file":"obj-loader.d.ts","sourceRoot":"","sources":["../../src/loaders/obj-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA+B,MAAM,gBAAgB,CAAC;AAErE,qBAAa,SAAS;IACpB,qBAAqB;IACrB,OAAO,CAAC,SAAS,CAAgB;IAEjC,qBAAqB;IACrB,OAAO,CAAC,OAAO,CAAgB;IAE/B,kCAAkC;IAClC,OAAO,CAAC,GAAG,CAAgB;IAG3B,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,MAAM,CAAkB;IAEhC;;;OAGG;IACI,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAmCvC;;OAEG;IACH,OAAO,CAAC,eAAe;CA2BxB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { OGLRenderingContext, Program } from 'ogl';
|
|
2
|
+
/**
|
|
3
|
+
* Создает универсальный Program для рендерера.
|
|
4
|
+
*
|
|
5
|
+
* Включает базовый vertex и fragment шейдеры, добавляет uniform `tMap` с дефолтной текстурой.
|
|
6
|
+
* Этот Program можно использовать для всех фигур в сцене, а также для сетки и осей.
|
|
7
|
+
*
|
|
8
|
+
* @param {OGLRenderingContext} gl - WebGL контекст.
|
|
9
|
+
* @returns {Program} Экземпляр Program с базовыми шейдерами и uniform.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createProgram(gl: OGLRenderingContext): Program;
|
|
12
|
+
//# sourceMappingURL=program-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program-settings.d.ts","sourceRoot":"","sources":["../../src/utils/program-settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,OAAO,EAAW,MAAM,KAAK,CAAC;AAEjE;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,mBAAmB,GAAG,OAAO,CA2C9D"}
|