hart-estate-widget 0.0.10 → 0.0.11
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/build/api/index.js +24 -0
- package/build/assets/img/bricks.jpeg +0 -0
- package/build/assets/img/door-texture.jpeg +0 -0
- package/build/assets/img/door.jpeg +0 -0
- package/build/assets/img/exterior-wall-texture.jpeg +0 -0
- package/build/assets/img/floor-bathroom.jpg +0 -0
- package/build/assets/img/floor-dark.png +0 -0
- package/build/assets/img/floor-white.png +0 -0
- package/build/assets/img/floor.jpg +0 -0
- package/build/assets/img/ground.svg +9 -0
- package/build/assets/img/wall-texture.jpg +0 -0
- package/build/assets/sass/animation.sass +5 -0
- package/build/assets/sass/components/panorama.sass +2 -35
- package/build/assets/sass/components/tabs.sass +66 -0
- package/build/components/ModelTab.js +90 -85
- package/build/components/PanoramaTab.js +2 -2
- package/build/index.css +1 -1
- package/build/index.css.map +1 -1
- package/build/store/houseStore.js +675 -0
- package/build/store/modelStore.js +196 -0
- package/build/utils/csg/csg-lib.js +387 -0
- package/build/utils/csg/csg-worker.js +94 -0
- package/build/utils/csg/three-csg.js +280 -0
- package/build/utils/modelHelpers.js +79 -35
- package/package.json +1 -1
@@ -0,0 +1,196 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.default = void 0;
|
7
|
+
|
8
|
+
require("core-js/modules/web.dom-collections.iterator.js");
|
9
|
+
|
10
|
+
var _react = _interopRequireDefault(require("react"));
|
11
|
+
|
12
|
+
var _mobx = require("mobx");
|
13
|
+
|
14
|
+
var THREE = _interopRequireWildcard(require("three"));
|
15
|
+
|
16
|
+
var _cameraControls = _interopRequireDefault(require("camera-controls"));
|
17
|
+
|
18
|
+
var _houseStore = _interopRequireDefault(require("./houseStore"));
|
19
|
+
|
20
|
+
var _grass = _interopRequireDefault(require("../assets/img/grass.png"));
|
21
|
+
|
22
|
+
var _modelHelpers = require("../utils/modelHelpers");
|
23
|
+
|
24
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
25
|
+
|
26
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
27
|
+
|
28
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
29
|
+
|
30
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
31
|
+
|
32
|
+
(0, _mobx.configure)({
|
33
|
+
useProxies: 'never'
|
34
|
+
});
|
35
|
+
|
36
|
+
class ModelStore {
|
37
|
+
constructor() {
|
38
|
+
_defineProperty(this, "json", null);
|
39
|
+
|
40
|
+
_defineProperty(this, "initialized", false);
|
41
|
+
|
42
|
+
_defineProperty(this, "textureLoader", new THREE.TextureLoader());
|
43
|
+
|
44
|
+
_defineProperty(this, "clock", new THREE.Clock());
|
45
|
+
|
46
|
+
_defineProperty(this, "scene", null);
|
47
|
+
|
48
|
+
_defineProperty(this, "renderer", null);
|
49
|
+
|
50
|
+
_defineProperty(this, "camera", null);
|
51
|
+
|
52
|
+
_defineProperty(this, "controls", null);
|
53
|
+
|
54
|
+
_defineProperty(this, "houseStore", null);
|
55
|
+
|
56
|
+
_defineProperty(this, "sceneScale", 0.025);
|
57
|
+
|
58
|
+
_defineProperty(this, "wallsHeight", 280 * this.sceneScale);
|
59
|
+
|
60
|
+
_defineProperty(this, "init", json => {
|
61
|
+
this.json = json;
|
62
|
+
this.initialized = true;
|
63
|
+
this.houseStore = new _houseStore.default(this);
|
64
|
+
this.scene.add(this.houseStore.houseGroup);
|
65
|
+
});
|
66
|
+
|
67
|
+
_defineProperty(this, "createScene", () => {
|
68
|
+
this.scene = new THREE.Scene();
|
69
|
+
const light = new THREE.AmbientLight(0xffffff);
|
70
|
+
this.scene.rotation.x = -Math.PI / 2;
|
71
|
+
this.scene.scale.y = -1;
|
72
|
+
this.scene.background = new THREE.Color('#FAFAFA');
|
73
|
+
this.scene.add(light); // const axesHelper = new THREE.AxesHelper( 50 );
|
74
|
+
// this.scene.add( axesHelper );
|
75
|
+
|
76
|
+
this.createGround();
|
77
|
+
return this;
|
78
|
+
});
|
79
|
+
|
80
|
+
_defineProperty(this, "createGround", () => {
|
81
|
+
this.textureLoader.load(_grass.default, texture => {
|
82
|
+
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
|
83
|
+
texture.repeat.set(70, 70);
|
84
|
+
let groundMaterial = new THREE.MeshBasicMaterial({
|
85
|
+
map: texture,
|
86
|
+
color: 'rgb(255,255,255)'
|
87
|
+
});
|
88
|
+
let groundMesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(300, 300), groundMaterial);
|
89
|
+
groundMesh.position.z = -0.01;
|
90
|
+
this.scene.add(groundMesh);
|
91
|
+
});
|
92
|
+
return this;
|
93
|
+
});
|
94
|
+
|
95
|
+
_defineProperty(this, "createRenderer", () => {
|
96
|
+
this.renderer = new THREE.WebGLRenderer();
|
97
|
+
this.renderer.setPixelRatio(window.devicePixelRatio);
|
98
|
+
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
99
|
+
this.renderer.localClippingEnabled = true;
|
100
|
+
return this;
|
101
|
+
});
|
102
|
+
|
103
|
+
_defineProperty(this, "createCamera", () => {
|
104
|
+
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
105
|
+
this.camera.position.set(0, 0, 0);
|
106
|
+
window.addEventListener('resize', () => {
|
107
|
+
this.camera.aspect = window.innerWidth / window.innerHeight;
|
108
|
+
this.camera.updateProjectionMatrix();
|
109
|
+
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
110
|
+
});
|
111
|
+
return this;
|
112
|
+
});
|
113
|
+
|
114
|
+
_defineProperty(this, "createControls", () => {
|
115
|
+
this.controls = new _cameraControls.default(this.camera, this.renderer.domElement);
|
116
|
+
this.controls.minDistance = 0.5;
|
117
|
+
this.controls.maxDistance = 50;
|
118
|
+
this.controls.maxPolarAngle = Math.PI / 2.1;
|
119
|
+
this.setDefaultControls(Math.PI / 4);
|
120
|
+
this.controls.verticalDragToForward = true;
|
121
|
+
this.controls.currentControlsType = 'orbit';
|
122
|
+
|
123
|
+
const animate = () => {
|
124
|
+
this.controls.update(this.clock.getDelta());
|
125
|
+
window.requestAnimationFrame(animate);
|
126
|
+
this.renderer.render(this.scene, this.camera);
|
127
|
+
};
|
128
|
+
|
129
|
+
animate();
|
130
|
+
return this;
|
131
|
+
});
|
132
|
+
|
133
|
+
_defineProperty(this, "setDefaultControls", angle => {
|
134
|
+
this.controls.dollyTo(20, true);
|
135
|
+
this.controls.moveTo(0, 0, 0, true);
|
136
|
+
this.controls.mouseButtons.wheel = _cameraControls.default.ACTION.DOLLY;
|
137
|
+
this.controls.touches.two = _cameraControls.default.ACTION.NONE;
|
138
|
+
this.controls.rotateTo(0, angle, true); // this.destroyNipple();
|
139
|
+
});
|
140
|
+
|
141
|
+
_defineProperty(this, "setCurrentControlsType", type => {
|
142
|
+
this.controls.currentControlsType = type;
|
143
|
+
const EPS = 1e-5;
|
144
|
+
|
145
|
+
if (type === 'orbit') {
|
146
|
+
this.controls.maxPolarAngle = Math.PI / 2.1;
|
147
|
+
this.setDefaultControls(Math.PI / 4);
|
148
|
+
return;
|
149
|
+
}
|
150
|
+
|
151
|
+
if (type === 'plan') {
|
152
|
+
this.setDefaultControls(0);
|
153
|
+
this.controls.maxPolarAngle = 0;
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
|
157
|
+
if (type === 'wasd') {
|
158
|
+
this.camera.position.set(0, 0, EPS);
|
159
|
+
this.controls.maxPolarAngle = Math.PI;
|
160
|
+
this.controls.dollyTo(0, true);
|
161
|
+
this.controls.moveTo(0, this.wallsHeight / 2, 0, true);
|
162
|
+
this.controls.rotateTo(0, Math.PI / 2, true);
|
163
|
+
this.controls.mouseButtons.wheel = _cameraControls.default.ACTION.NONE;
|
164
|
+
this.controls.touches.two = _cameraControls.default.ACTION.NONE;
|
165
|
+
}
|
166
|
+
});
|
167
|
+
|
168
|
+
_defineProperty(this, "addKeyEvents", () => {
|
169
|
+
const keyEvents = (0, _modelHelpers.getKeyEvents)(this.controls);
|
170
|
+
keyEvents.forEach(_ref => {
|
171
|
+
let {
|
172
|
+
keys,
|
173
|
+
callback
|
174
|
+
} = _ref;
|
175
|
+
keys.forEach(key => key.addEventListener('holding', () => {
|
176
|
+
if (this.controls.currentControlsType !== 'wasd') return;
|
177
|
+
callback();
|
178
|
+
}));
|
179
|
+
});
|
180
|
+
return this;
|
181
|
+
});
|
182
|
+
|
183
|
+
(0, _mobx.makeAutoObservable)(this);
|
184
|
+
|
185
|
+
_cameraControls.default.install({
|
186
|
+
THREE: THREE
|
187
|
+
});
|
188
|
+
|
189
|
+
this.createScene().createRenderer().createCamera().createControls().addKeyEvents();
|
190
|
+
}
|
191
|
+
|
192
|
+
}
|
193
|
+
|
194
|
+
var _default = new ModelStore();
|
195
|
+
|
196
|
+
exports.default = _default;
|
@@ -0,0 +1,387 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.Vertex = exports.Vector = exports.Polygon = exports.Plane = exports.CSG = void 0;
|
7
|
+
|
8
|
+
require("core-js/modules/es.array.reverse.js");
|
9
|
+
|
10
|
+
var _react = _interopRequireDefault(require("react"));
|
11
|
+
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
13
|
+
|
14
|
+
class CSG {
|
15
|
+
constructor() {
|
16
|
+
this.polygons = [];
|
17
|
+
}
|
18
|
+
|
19
|
+
clone() {
|
20
|
+
let csg = new CSG();
|
21
|
+
csg.polygons = this.polygons.map(p => p.clone());
|
22
|
+
return csg;
|
23
|
+
}
|
24
|
+
|
25
|
+
toPolygons() {
|
26
|
+
return this.polygons;
|
27
|
+
}
|
28
|
+
|
29
|
+
union(csg) {
|
30
|
+
let a = new Node(this.clone().polygons);
|
31
|
+
let b = new Node(csg.clone().polygons);
|
32
|
+
a.clipTo(b);
|
33
|
+
b.clipTo(a);
|
34
|
+
b.invert();
|
35
|
+
b.clipTo(a);
|
36
|
+
b.invert();
|
37
|
+
a.build(b.allPolygons());
|
38
|
+
return CSG.fromPolygons(a.allPolygons());
|
39
|
+
}
|
40
|
+
|
41
|
+
subtract(csg) {
|
42
|
+
let a = new Node(this.clone().polygons);
|
43
|
+
let b = new Node(csg.clone().polygons);
|
44
|
+
a.invert();
|
45
|
+
a.clipTo(b);
|
46
|
+
b.clipTo(a);
|
47
|
+
b.invert();
|
48
|
+
b.clipTo(a);
|
49
|
+
b.invert();
|
50
|
+
a.build(b.allPolygons());
|
51
|
+
a.invert();
|
52
|
+
return CSG.fromPolygons(a.allPolygons());
|
53
|
+
}
|
54
|
+
|
55
|
+
intersect(csg) {
|
56
|
+
let a = new Node(this.clone().polygons);
|
57
|
+
let b = new Node(csg.clone().polygons);
|
58
|
+
a.invert();
|
59
|
+
b.clipTo(a);
|
60
|
+
b.invert();
|
61
|
+
a.clipTo(b);
|
62
|
+
b.clipTo(a);
|
63
|
+
a.build(b.allPolygons());
|
64
|
+
a.invert();
|
65
|
+
return CSG.fromPolygons(a.allPolygons());
|
66
|
+
} // Return a new CSG solid with solid and empty space switched. This solid is
|
67
|
+
// not modified.
|
68
|
+
|
69
|
+
|
70
|
+
inverse() {
|
71
|
+
let csg = this.clone();
|
72
|
+
csg.polygons.forEach(p => p.flip());
|
73
|
+
return csg;
|
74
|
+
}
|
75
|
+
|
76
|
+
}
|
77
|
+
|
78
|
+
exports.CSG = CSG;
|
79
|
+
|
80
|
+
CSG.fromPolygons = function (polygons) {
|
81
|
+
let csg = new CSG();
|
82
|
+
csg.polygons = polygons;
|
83
|
+
return csg;
|
84
|
+
};
|
85
|
+
|
86
|
+
class Vector {
|
87
|
+
constructor() {
|
88
|
+
let x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
89
|
+
let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
90
|
+
let z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
91
|
+
this.x = x;
|
92
|
+
this.y = y;
|
93
|
+
this.z = z;
|
94
|
+
}
|
95
|
+
|
96
|
+
copy(v) {
|
97
|
+
this.x = v.x;
|
98
|
+
this.y = v.y;
|
99
|
+
this.z = v.z;
|
100
|
+
return this;
|
101
|
+
}
|
102
|
+
|
103
|
+
clone() {
|
104
|
+
return new Vector(this.x, this.y, this.z);
|
105
|
+
}
|
106
|
+
|
107
|
+
negate() {
|
108
|
+
this.x *= -1;
|
109
|
+
this.y *= -1;
|
110
|
+
this.z *= -1;
|
111
|
+
return this;
|
112
|
+
}
|
113
|
+
|
114
|
+
add(a) {
|
115
|
+
this.x += a.x;
|
116
|
+
this.y += a.y;
|
117
|
+
this.z += a.z;
|
118
|
+
return this;
|
119
|
+
}
|
120
|
+
|
121
|
+
sub(a) {
|
122
|
+
this.x -= a.x;
|
123
|
+
this.y -= a.y;
|
124
|
+
this.z -= a.z;
|
125
|
+
return this;
|
126
|
+
}
|
127
|
+
|
128
|
+
times(a) {
|
129
|
+
this.x *= a;
|
130
|
+
this.y *= a;
|
131
|
+
this.z *= a;
|
132
|
+
return this;
|
133
|
+
}
|
134
|
+
|
135
|
+
dividedBy(a) {
|
136
|
+
this.x /= a;
|
137
|
+
this.y /= a;
|
138
|
+
this.z /= a;
|
139
|
+
return this;
|
140
|
+
}
|
141
|
+
|
142
|
+
lerp(a, t) {
|
143
|
+
return this.add(tv0.copy(a).sub(this).times(t));
|
144
|
+
}
|
145
|
+
|
146
|
+
unit() {
|
147
|
+
return this.dividedBy(this.length());
|
148
|
+
}
|
149
|
+
|
150
|
+
length() {
|
151
|
+
return Math.sqrt(this.x ** 2 + this.y ** 2 + this.z ** 2);
|
152
|
+
}
|
153
|
+
|
154
|
+
normalize() {
|
155
|
+
return this.unit();
|
156
|
+
}
|
157
|
+
|
158
|
+
cross(b) {
|
159
|
+
let a = this;
|
160
|
+
const ax = a.x,
|
161
|
+
ay = a.y,
|
162
|
+
az = a.z;
|
163
|
+
const bx = b.x,
|
164
|
+
by = b.y,
|
165
|
+
bz = b.z;
|
166
|
+
this.x = ay * bz - az * by;
|
167
|
+
this.y = az * bx - ax * bz;
|
168
|
+
this.z = ax * by - ay * bx;
|
169
|
+
return this;
|
170
|
+
}
|
171
|
+
|
172
|
+
dot(b) {
|
173
|
+
return this.x * b.x + this.y * b.y + this.z * b.z;
|
174
|
+
}
|
175
|
+
|
176
|
+
}
|
177
|
+
|
178
|
+
exports.Vector = Vector;
|
179
|
+
let tv0 = new Vector();
|
180
|
+
let tv1 = new Vector();
|
181
|
+
|
182
|
+
class Vertex {
|
183
|
+
constructor(pos, normal, uv, color) {
|
184
|
+
this.pos = new Vector().copy(pos);
|
185
|
+
this.normal = new Vector().copy(normal);
|
186
|
+
uv && (this.uv = new Vector().copy(uv)) && (this.uv.z = 0);
|
187
|
+
color && (this.color = new Vector().copy(color));
|
188
|
+
}
|
189
|
+
|
190
|
+
clone() {
|
191
|
+
return new Vertex(this.pos, this.normal, this.uv, this.color);
|
192
|
+
}
|
193
|
+
|
194
|
+
flip() {
|
195
|
+
this.normal.negate();
|
196
|
+
}
|
197
|
+
|
198
|
+
interpolate(other, t) {
|
199
|
+
return new Vertex(this.pos.clone().lerp(other.pos, t), this.normal.clone().lerp(other.normal, t), this.uv && other.uv && this.uv.clone().lerp(other.uv, t), this.color && other.color && this.color.clone().lerp(other.color, t));
|
200
|
+
}
|
201
|
+
|
202
|
+
}
|
203
|
+
|
204
|
+
exports.Vertex = Vertex;
|
205
|
+
|
206
|
+
class Plane {
|
207
|
+
constructor(normal, w) {
|
208
|
+
this.normal = normal;
|
209
|
+
this.w = w;
|
210
|
+
}
|
211
|
+
|
212
|
+
clone() {
|
213
|
+
return new Plane(this.normal.clone(), this.w);
|
214
|
+
}
|
215
|
+
|
216
|
+
flip() {
|
217
|
+
this.normal.negate();
|
218
|
+
this.w = -this.w;
|
219
|
+
}
|
220
|
+
|
221
|
+
splitPolygon(polygon, coplanarFront, coplanarBack, front, back) {
|
222
|
+
const COPLANAR = 0;
|
223
|
+
const FRONT = 1;
|
224
|
+
const BACK = 2;
|
225
|
+
const SPANNING = 3;
|
226
|
+
let polygonType = 0;
|
227
|
+
let types = [];
|
228
|
+
|
229
|
+
for (let i = 0; i < polygon.vertices.length; i++) {
|
230
|
+
let t = this.normal.dot(polygon.vertices[i].pos) - this.w;
|
231
|
+
let type = t < -Plane.EPSILON ? BACK : t > Plane.EPSILON ? FRONT : COPLANAR;
|
232
|
+
polygonType |= type;
|
233
|
+
types.push(type);
|
234
|
+
}
|
235
|
+
|
236
|
+
switch (polygonType) {
|
237
|
+
case COPLANAR:
|
238
|
+
(this.normal.dot(polygon.plane.normal) > 0 ? coplanarFront : coplanarBack).push(polygon);
|
239
|
+
break;
|
240
|
+
|
241
|
+
case FRONT:
|
242
|
+
front.push(polygon);
|
243
|
+
break;
|
244
|
+
|
245
|
+
case BACK:
|
246
|
+
back.push(polygon);
|
247
|
+
break;
|
248
|
+
|
249
|
+
case SPANNING:
|
250
|
+
let f = [];
|
251
|
+
let b = [];
|
252
|
+
|
253
|
+
for (let i = 0; i < polygon.vertices.length; i++) {
|
254
|
+
let j = (i + 1) % polygon.vertices.length;
|
255
|
+
let ti = types[i],
|
256
|
+
tj = types[j];
|
257
|
+
let vi = polygon.vertices[i],
|
258
|
+
vj = polygon.vertices[j];
|
259
|
+
if (ti != BACK) f.push(vi);
|
260
|
+
if (ti != FRONT) b.push(ti != BACK ? vi.clone() : vi);
|
261
|
+
|
262
|
+
if ((ti | tj) == SPANNING) {
|
263
|
+
let t = (this.w - this.normal.dot(vi.pos)) / this.normal.dot(tv0.copy(vj.pos).sub(vi.pos));
|
264
|
+
let v = vi.interpolate(vj, t);
|
265
|
+
f.push(v);
|
266
|
+
b.push(v.clone());
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
if (f.length >= 3) front.push(new Polygon(f, polygon.shared));
|
271
|
+
if (b.length >= 3) back.push(new Polygon(b, polygon.shared));
|
272
|
+
break;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
|
276
|
+
}
|
277
|
+
|
278
|
+
exports.Plane = Plane;
|
279
|
+
Plane.EPSILON = 1e-5;
|
280
|
+
|
281
|
+
Plane.fromPoints = function (a, b, c) {
|
282
|
+
let n = tv0.copy(b).sub(a).cross(tv1.copy(c).sub(a)).normalize();
|
283
|
+
return new Plane(n.clone(), n.dot(a));
|
284
|
+
};
|
285
|
+
|
286
|
+
class Polygon {
|
287
|
+
constructor(vertices, shared) {
|
288
|
+
this.vertices = vertices;
|
289
|
+
this.shared = shared;
|
290
|
+
this.plane = Plane.fromPoints(vertices[0].pos, vertices[1].pos, vertices[2].pos);
|
291
|
+
}
|
292
|
+
|
293
|
+
clone() {
|
294
|
+
return new Polygon(this.vertices.map(v => v.clone()), this.shared);
|
295
|
+
}
|
296
|
+
|
297
|
+
flip() {
|
298
|
+
this.vertices.reverse().forEach(v => v.flip());
|
299
|
+
this.plane.flip();
|
300
|
+
}
|
301
|
+
|
302
|
+
}
|
303
|
+
|
304
|
+
exports.Polygon = Polygon;
|
305
|
+
|
306
|
+
class Node {
|
307
|
+
constructor(polygons) {
|
308
|
+
this.plane = null;
|
309
|
+
this.front = null;
|
310
|
+
this.back = null;
|
311
|
+
this.polygons = [];
|
312
|
+
if (polygons) this.build(polygons);
|
313
|
+
}
|
314
|
+
|
315
|
+
clone() {
|
316
|
+
let node = new Node();
|
317
|
+
node.plane = this.plane && this.plane.clone();
|
318
|
+
node.front = this.front && this.front.clone();
|
319
|
+
node.back = this.back && this.back.clone();
|
320
|
+
node.polygons = this.polygons.map(p => p.clone());
|
321
|
+
return node;
|
322
|
+
}
|
323
|
+
|
324
|
+
invert() {
|
325
|
+
for (let i = 0; i < this.polygons.length; i++) this.polygons[i].flip();
|
326
|
+
|
327
|
+
this.plane && this.plane.flip();
|
328
|
+
this.front && this.front.invert();
|
329
|
+
this.back && this.back.invert();
|
330
|
+
let temp = this.front;
|
331
|
+
this.front = this.back;
|
332
|
+
this.back = temp;
|
333
|
+
}
|
334
|
+
|
335
|
+
clipPolygons(polygons) {
|
336
|
+
if (!this.plane) return polygons.slice();
|
337
|
+
let front = [],
|
338
|
+
back = [];
|
339
|
+
|
340
|
+
for (let i = 0; i < polygons.length; i++) {
|
341
|
+
this.plane.splitPolygon(polygons[i], front, back, front, back);
|
342
|
+
}
|
343
|
+
|
344
|
+
if (this.front) front = this.front.clipPolygons(front);
|
345
|
+
if (this.back) back = this.back.clipPolygons(back);else back = [];
|
346
|
+
return front.concat(back);
|
347
|
+
}
|
348
|
+
|
349
|
+
clipTo(bsp) {
|
350
|
+
this.polygons = bsp.clipPolygons(this.polygons);
|
351
|
+
if (this.front) this.front.clipTo(bsp);
|
352
|
+
if (this.back) this.back.clipTo(bsp);
|
353
|
+
}
|
354
|
+
|
355
|
+
allPolygons() {
|
356
|
+
let polygons = this.polygons.slice();
|
357
|
+
if (this.front) polygons = polygons.concat(this.front.allPolygons());
|
358
|
+
if (this.back) polygons = polygons.concat(this.back.allPolygons());
|
359
|
+
return polygons;
|
360
|
+
}
|
361
|
+
|
362
|
+
build(polygons) {
|
363
|
+
if (!polygons.length) return;
|
364
|
+
if (!this.plane) this.plane = polygons[0].plane.clone();
|
365
|
+
let front = [],
|
366
|
+
back = [];
|
367
|
+
|
368
|
+
for (let i = 0; i < polygons.length; i++) {
|
369
|
+
this.plane.splitPolygon(polygons[i], this.polygons, this.polygons, front, back);
|
370
|
+
}
|
371
|
+
|
372
|
+
if (front.length) {
|
373
|
+
if (!this.front) this.front = new Node();
|
374
|
+
this.front.build(front);
|
375
|
+
}
|
376
|
+
|
377
|
+
if (back.length) {
|
378
|
+
if (!this.back) this.back = new Node();
|
379
|
+
this.back.build(back);
|
380
|
+
}
|
381
|
+
}
|
382
|
+
|
383
|
+
}
|
384
|
+
|
385
|
+
CSG.fromJSON = function (json) {
|
386
|
+
return CSG.fromPolygons(json.polygons.map(p => new Polygon(p.vertices.map(v => new Vertex(v.pos, v.normal, v.uv)), p.shared)));
|
387
|
+
};
|
@@ -0,0 +1,94 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
require("core-js/modules/es.promise.js");
|
4
|
+
|
5
|
+
require("core-js/modules/web.dom-collections.iterator.js");
|
6
|
+
|
7
|
+
require("core-js/modules/web.url.js");
|
8
|
+
|
9
|
+
require("core-js/modules/web.url-search-params.js");
|
10
|
+
|
11
|
+
require("core-js/modules/es.json.stringify.js");
|
12
|
+
|
13
|
+
var _react = _interopRequireDefault(require("react"));
|
14
|
+
|
15
|
+
var _csgLib = require("./csg-lib.js");
|
16
|
+
|
17
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
18
|
+
|
19
|
+
let gWorkersStarted = false;
|
20
|
+
let gWorker;
|
21
|
+
let gWorkerUrl;
|
22
|
+
let taskId = 0;
|
23
|
+
let tasks = {};
|
24
|
+
|
25
|
+
let spawnWorker = () => {
|
26
|
+
const worker = new Worker(gWorkerUrl);
|
27
|
+
|
28
|
+
worker.onmessage = function (e) {
|
29
|
+
let rslt = JSON.parse(e.data);
|
30
|
+
let task = tasks[rslt.taskId];
|
31
|
+
delete tasks[rslt.taskId];
|
32
|
+
task.resolve(_csgLib.CSG.fromJSON(rslt.result)); //console.log('Message received from worker');
|
33
|
+
|
34
|
+
gWorker.busy = false;
|
35
|
+
};
|
36
|
+
|
37
|
+
return gWorker = {
|
38
|
+
worker,
|
39
|
+
busy: false
|
40
|
+
};
|
41
|
+
};
|
42
|
+
|
43
|
+
let getWorker = () => {
|
44
|
+
if (!gWorkersStarted) {
|
45
|
+
gWorkersStarted = true;
|
46
|
+
return fetch('../csg-lib.js').then(function (response) {
|
47
|
+
return response.text().then(function (text) {
|
48
|
+
text = text.slice(0, text.lastIndexOf('export'));
|
49
|
+
const code = text + "\n self.onmessage=(message)=>{\n let task = JSON.parse(message.data)\n //console.log(\"Got task:\"+task.op+' '+task.taskId)\n postMessage(JSON.stringify({\n taskId:task.taskId,\n result : CSG.fromJSON(task.a)[task.op](CSG.fromJSON(task.b))\n }))\n }\n console.log('CSG worker started!')";
|
50
|
+
const blob = new Blob([code], {
|
51
|
+
type: 'application/javascript'
|
52
|
+
});
|
53
|
+
gWorkerUrl = URL.createObjectURL(blob);
|
54
|
+
}).then(() => {
|
55
|
+
return spawnWorker();
|
56
|
+
});
|
57
|
+
});
|
58
|
+
}
|
59
|
+
|
60
|
+
if (gWorker && !gWorker.busy) {
|
61
|
+
gWorker.busy = true;
|
62
|
+
return {
|
63
|
+
then: fn => {
|
64
|
+
return fn(gWorker);
|
65
|
+
}
|
66
|
+
};
|
67
|
+
}
|
68
|
+
|
69
|
+
return {
|
70
|
+
then: function then() {
|
71
|
+
return this;
|
72
|
+
}
|
73
|
+
};
|
74
|
+
};
|
75
|
+
|
76
|
+
_csgLib.CSG.doAsync = (a, op, b) => {
|
77
|
+
return getWorker().then(worker => {
|
78
|
+
let task = {
|
79
|
+
a,
|
80
|
+
op,
|
81
|
+
b,
|
82
|
+
taskId
|
83
|
+
};
|
84
|
+
tasks[taskId] = task;
|
85
|
+
taskId++;
|
86
|
+
task.result = new Promise((resolve, reject) => {
|
87
|
+
task.resolve = resolve; //console.log("posting to worker:")
|
88
|
+
|
89
|
+
worker.busy = true;
|
90
|
+
worker.worker.postMessage(JSON.stringify(task));
|
91
|
+
});
|
92
|
+
return task.result;
|
93
|
+
});
|
94
|
+
};
|