@planara/core 1.3.1 → 1.4.1
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;IAM1B;;OAEG;IACH,OAAO,CAAC,eAAe,CAerB;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 p(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=p(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 v 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)})}handleMouseMove=e=>{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)}}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,l]=i.split("/"),m=n?parseInt(n,10):void 0,c=a?parseInt(a,10):void 0,u=l?parseInt(l,10):void 0;if(m!==void 0){const o=this.tmpPositions[m-1];o&&this.positions.push(...o)}if(c!==void 0){const o=this.tmpUVs[c-1];o&&this.uvs.push(...o)}if(u!==void 0){const o=this.tmpNormals[u-1];o&&this.normals.push(...o)}}}}exports.EditorRenderer=v;exports.ObjLoader=b;exports.PreviewRenderer=g;exports.Renderer=h;exports.createProgram=p;
|
package/dist/index.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Texture as
|
|
2
|
-
function
|
|
3
|
-
const
|
|
1
|
+
import { Texture as v, 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 c, 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 v(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 c(this.camera, { element: this.canvas }), this.raycast = new P(), this.mouse = new z(), this.initMouseListeners();
|
|
115
122
|
}
|
|
116
123
|
/**
|
|
117
124
|
* Обновление состояния рендерера.
|
|
@@ -119,18 +126,53 @@ 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);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Обработчик движения мыши
|
|
160
|
+
*/
|
|
161
|
+
handleMouseMove = (e) => {
|
|
162
|
+
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);
|
|
163
|
+
};
|
|
122
164
|
}
|
|
123
|
-
class
|
|
165
|
+
class U extends u {
|
|
124
166
|
/** Orbit-контроллер для управления камерой */
|
|
125
167
|
orbit;
|
|
126
168
|
/**
|
|
127
169
|
* Инициализация сцены предпросмотра.
|
|
128
170
|
* @param canvas - HTMLCanvasElement для рендеринга
|
|
129
171
|
*/
|
|
130
|
-
constructor(
|
|
131
|
-
super(
|
|
172
|
+
constructor(e) {
|
|
173
|
+
super(e), this.orbit = new c(this.camera, {
|
|
132
174
|
element: this.canvas,
|
|
133
|
-
target: new
|
|
175
|
+
target: new C(0, 0, 0),
|
|
134
176
|
minPolarAngle: Math.PI / 2,
|
|
135
177
|
maxPolarAngle: Math.PI / 2,
|
|
136
178
|
enableRotate: !0,
|
|
@@ -145,7 +187,7 @@ class F extends p {
|
|
|
145
187
|
this.orbit?.update();
|
|
146
188
|
}
|
|
147
189
|
}
|
|
148
|
-
class
|
|
190
|
+
class I {
|
|
149
191
|
/** Тип фигуры */
|
|
150
192
|
type;
|
|
151
193
|
/** Позиции вершин */
|
|
@@ -160,11 +202,11 @@ class C {
|
|
|
160
202
|
* Создаёт новую фигуру
|
|
161
203
|
* @param data - исходные данные фигуры
|
|
162
204
|
*/
|
|
163
|
-
constructor(
|
|
164
|
-
this.type =
|
|
205
|
+
constructor(e) {
|
|
206
|
+
this.type = e.type, this.position = e.position, this.normal = e.normal ?? [], this.uv = e.uv ?? [], this.material = e.material;
|
|
165
207
|
}
|
|
166
208
|
}
|
|
167
|
-
var
|
|
209
|
+
var p = /* @__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))(p || {});
|
|
168
210
|
class A {
|
|
169
211
|
/** Позиции вершин */
|
|
170
212
|
positions = [];
|
|
@@ -180,12 +222,12 @@ class A {
|
|
|
180
222
|
* Загружает OBJ-модель в Figure
|
|
181
223
|
* @param objContent Строка содержимого .obj файла
|
|
182
224
|
*/
|
|
183
|
-
load(
|
|
184
|
-
const
|
|
225
|
+
load(e) {
|
|
226
|
+
const t = e.split(`
|
|
185
227
|
`);
|
|
186
|
-
for (const
|
|
187
|
-
if (!
|
|
188
|
-
const r =
|
|
228
|
+
for (const o of t) {
|
|
229
|
+
if (!o.trim() || o.startsWith("#")) continue;
|
|
230
|
+
const r = o.trim().split(/\s+/);
|
|
189
231
|
switch (r[0]) {
|
|
190
232
|
case "v":
|
|
191
233
|
this.tmpPositions.push(r.slice(1).map(Number));
|
|
@@ -202,31 +244,31 @@ class A {
|
|
|
202
244
|
}
|
|
203
245
|
}
|
|
204
246
|
const i = {
|
|
205
|
-
type:
|
|
247
|
+
type: p.Custom,
|
|
206
248
|
position: this.positions,
|
|
207
249
|
...this.normals.length > 0 && { normal: this.normals },
|
|
208
250
|
...this.uvs.length > 0 && { uv: this.uvs }
|
|
209
251
|
};
|
|
210
|
-
return new
|
|
252
|
+
return new I(i);
|
|
211
253
|
}
|
|
212
254
|
/**
|
|
213
255
|
* Обрабатывает строку face (f) и разворачивает индексы в массивы для рендеринга
|
|
214
256
|
*/
|
|
215
|
-
processFaceLine(
|
|
216
|
-
for (let
|
|
217
|
-
const i = t
|
|
257
|
+
processFaceLine(e) {
|
|
258
|
+
for (let t = 1; t < e.length; t++) {
|
|
259
|
+
const i = e[t];
|
|
218
260
|
if (!i) continue;
|
|
219
|
-
const [
|
|
220
|
-
if (
|
|
221
|
-
const a = this.tmpPositions[
|
|
261
|
+
const [o, r, n] = i.split("/"), h = o ? parseInt(o, 10) : void 0, m = r ? parseInt(r, 10) : void 0, l = n ? parseInt(n, 10) : void 0;
|
|
262
|
+
if (h !== void 0) {
|
|
263
|
+
const a = this.tmpPositions[h - 1];
|
|
222
264
|
a && this.positions.push(...a);
|
|
223
265
|
}
|
|
224
266
|
if (m !== void 0) {
|
|
225
267
|
const a = this.tmpUVs[m - 1];
|
|
226
268
|
a && this.uvs.push(...a);
|
|
227
269
|
}
|
|
228
|
-
if (
|
|
229
|
-
const a = this.tmpNormals[
|
|
270
|
+
if (l !== void 0) {
|
|
271
|
+
const a = this.tmpNormals[l - 1];
|
|
230
272
|
a && this.normals.push(...a);
|
|
231
273
|
}
|
|
232
274
|
}
|
|
@@ -235,7 +277,7 @@ class A {
|
|
|
235
277
|
export {
|
|
236
278
|
N as EditorRenderer,
|
|
237
279
|
A as ObjLoader,
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
280
|
+
U as PreviewRenderer,
|
|
281
|
+
u as Renderer,
|
|
282
|
+
F as createProgram
|
|
241
283
|
};
|
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 c(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 m{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=c(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 g extends m{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)})}handleMouseMove=e=>{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)}}class f extends m{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,p=n?parseInt(n,10):void 0,v=u?parseInt(u,10):void 0;if(d!==void 0){const o=this.tmpPositions[d-1];o&&this.positions.push(...o)}if(p!==void 0){const o=this.tmpUVs[p-1];o&&this.uvs.push(...o)}if(v!==void 0){const o=this.tmpNormals[v-1];o&&this.normals.push(...o)}}}}a.EditorRenderer=g,a.ObjLoader=y,a.PreviewRenderer=f,a.Renderer=m,a.createProgram=c,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})}));
|