kitchen-simulator
Version:
It is a kitchen simulator (self-contained micro-frontend).
1,122 lines (1,106 loc) • 121 kB
JavaScript
'use strict';
import _readOnlyError from "@babel/runtime/helpers/esm/readOnlyError";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/esm/inherits";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
import React from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import * as Three from 'three';
import { checkCabinetOverlap, createBacksplash, deleteSpecifiedMeshObjects, fVLine, getDistances, parseData, updateScene, visibleTransformBox } from "./scene-creator";
import { disposeObject, disposeScene } from "./three-memory-cleaner";
import diff from 'immutablediff';
import * as SharedStyle from "../../shared-style";
import { BASE_CABINET_LAYOUTPOS, MODE_3D_VIEW, MODE_DRAGGING_ITEM_3D, MODE_DRAWING_HOLE_3D, MODE_DRAWING_ITEM_3D, MODE_ELEVATION_VIEW, MODE_IDLE_3D, MODE_ROTATING_ITEM_3D, SECONDARY_PURPLE_COLOR, TALL_CABINET_LAYOUTPOS, UNIT_CENTIMETER, WALL_CABINET_LAYOUTPOS } from "../../constants";
import { isUndefined } from 'util';
import { verticesDistance } from "../../utils/geometry";
import { convert } from "../../utils/convert-units-lite";
import { GeometryUtils } from "../../utils/export";
import { handleCamRect, isElevationView, isEmpty } from "../../utils/helper";
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';
import CameraControls from 'camera-controls';
import { returnReplaceableDeepSearchType } from "../viewer2d/utils";
import { getAllMeshes, vectorIntersectWithMesh } from "../../utils/objects-utils";
CameraControls.install({
THREE: Three
});
var Scene3DViewer = /*#__PURE__*/function (_React$Component) {
function Scene3DViewer(props) {
var _this;
_classCallCheck(this, Scene3DViewer);
_this = _callSuper(this, Scene3DViewer, [props]);
_this.state = {
isLoading: false,
showflag: true,
isLoadingCabinet: props.state.scene.isLoadingCabinet,
toolObj: null,
angleObj: null,
waitForRender: 0,
lineLength: null // when view wall's elevation, that wall's length
};
_this.lastMousePosition = {};
_this.width = props.width;
_this.height = props.height;
_this.renderingID = 0;
var mode = props.state.mode;
if (!window.__elevationRendererDownload) {
window.__elevationRendererDownload = {};
}
switch (mode) {
case MODE_IDLE_3D:
_this.renderer = window.__threeRenderer || new Three.WebGLRenderer({
preserveDrawingBuffer: true,
alpha: true,
antialias: true
});
break;
case MODE_3D_VIEW:
_this.renderer = window.__threeRendererDownload || new Three.WebGLRenderer({
preserveDrawingBuffer: true,
alpha: true,
antialias: true
});
break;
default:
if (_this.props.downloadFlag) {
_this.renderer = window.__elevationRendererDownload[mode] || new Three.WebGLRenderer({
preserveDrawingBuffer: true,
alpha: true,
antialias: true
});
} else {
_this.renderer = window.__elevationRenderer || new Three.WebGLRenderer({
preserveDrawingBuffer: true,
alpha: true,
antialias: true
});
}
break;
}
_this.renderer.shadowMap.enabled = true;
_this.renderer.shadowMapSoft = true;
if (mode == 'MODE_IDLE_3D') {
window.__threeRenderer = _this.renderer;
} else if (mode == 'MODE_3D_VIEW') {
window.__threeRendererDownload = _this.renderer;
} else {
if (_this.props.downloadFlag) window.__elevationRendererDownload[mode] = _this.renderer;else window.__elevationRenderer = _this.renderer;
}
_this.renderer.domElement.style.display = 'none';
return _this;
}
_inherits(Scene3DViewer, _React$Component);
return _createClass(Scene3DViewer, [{
key: "componentDidMount",
value: function componentDidMount(nextProps) {
var _this2 = this;
var scene3D, camera, pivot, cameraControls, clock;
var spotLight1, spotLightTarget;
var actions = {
areaActions: this.context.areaActions,
holesActions: this.context.holesActions,
itemsActions: this.context.itemsActions,
sceneActions: this.context.sceneActions,
linesActions: this.context.linesActions,
projectActions: this.context.projectActions,
catalog: this.context.catalog
};
var self = this;
var state = this.props.state;
var mode = state.mode,
scene = state.scene;
function setupLight(scene, inbBox) {
if (isElevationView(mode)) {
var ambilight = new Three.AmbientLight('0xffffff', 3);
scene.add(ambilight);
} else {
var addDirLight = function addDirLight(inColor, inIntensity, inPosition) {
var dirLight = new Three.DirectionalLight(inColor, inIntensity);
dirLight.castShadow = true;
dirLight.shadow.mapSize.x = shadowMapSize;
dirLight.shadow.mapSize.y = shadowMapSize;
dirLight.shadow.camera.near = 0;
dirLight.shadow.camera.far = shadowCameraFar;
dirLight.shadow.camera.top = shadowCameraSize * 1.5;
dirLight.shadow.camera.bottom = -shadowCameraSize * 1.5;
dirLight.shadow.camera.left = -shadowCameraSize * 1.5;
dirLight.shadow.camera.right = shadowCameraSize * 1.5;
dirLight.position.copy(inPosition);
var targetObject = new Three.Object3D();
targetObject.position.copy(bboxCenter);
scene.add(targetObject);
dirLight.target = targetObject;
dirLight.target.updateMatrixWorld();
scene.add(dirLight);
};
var addSpotLight = function addSpotLight(inColor, inIntensity, inPosition, inTarget, inDistance) {
var spotLight = new Three.SpotLight();
spotLight.intensity = inIntensity;
spotLight.color.setHex(inColor);
spotLight.position.copy(inPosition);
spotLight.angle = 1.3;
spotLight.distance = inDistance;
spotLight.penumbra = 1.8;
spotLight.decay = 0.01;
spotLight.castShadow = true;
spotLight.shadow.intensity = 2;
spotLight.shadow.mapSize.width = 4096;
spotLight.shadow.mapSize.height = 4096;
var targetObject = new Three.Object3D();
targetObject.position.copy(new Three.Vector3(inTarget.x, 0, inTarget.z));
scene.add(targetObject);
spotLight.target = targetObject;
spotLight.target.updateMatrixWorld();
scene.add(spotLight);
};
var shadowMapSize = 2048;
var shadowCameraSize = Math.max(Math.abs(inbBox.min.x - inbBox.max.x), Math.abs(inbBox.min.y - inbBox.max.y), Math.abs(inbBox.min.z - inbBox.max.z)) / 2;
var shadowCameraFar = shadowCameraSize * 10;
var bboxCenter = new Three.Vector3((inbBox.min.x + inbBox.max.x) / 2, inbBox.min.y, (inbBox.min.z + inbBox.max.z) / 2);
var dirLightPos = new Three.Vector3(inbBox.max.x, inbBox.max.y + 1.8 * Math.abs(inbBox.max.y - inbBox.min.y), inbBox.min.z - 0.5 * Math.abs(inbBox.max.z - inbBox.min.z));
addDirLight('white', 1.5, dirLightPos);
var ceiling = scene3D.getObjectByName('ceil');
if (ceiling) {
var ceilBBox = new Three.Box3().setFromObject(ceiling);
var spot1 = new Three.Vector3(ceilBBox.min.x + Math.abs(ceilBBox.min.x - ceilBBox.max.x) / 4, ceilBBox.max.y - 0.5, ceilBBox.min.z + Math.abs(ceilBBox.min.z - inbBox.max.z) / 4);
var spot2 = new Three.Vector3(ceilBBox.min.x + Math.abs(ceilBBox.min.x - ceilBBox.max.x) / 4, ceilBBox.max.y - 0.5, ceilBBox.max.z - Math.abs(ceilBBox.min.z - ceilBBox.max.z) / 4);
var spot3 = new Three.Vector3(ceilBBox.max.x - Math.abs(ceilBBox.min.x - ceilBBox.max.x) / 4, ceilBBox.max.y - 0.5, ceilBBox.min.z + Math.abs(ceilBBox.min.z - ceilBBox.max.z) / 4);
var spot4 = new Three.Vector3(ceilBBox.max.x - Math.abs(ceilBBox.min.x - ceilBBox.max.x) / 4, ceilBBox.max.y - 0.5, ceilBBox.max.z - Math.abs(ceilBBox.min.z - ceilBBox.max.z) / 4);
var spotlightDis = 1.5 * Math.abs(inbBox.min.y - inbBox.max.y);
// check if spotlight is inside the room
vectorIntersectWithMesh(spot1, scene3D.getObjectByName('floor')) && addSpotLight('0xffffff', 0.8, spot1, spot1, spotlightDis);
vectorIntersectWithMesh(spot2, scene3D.getObjectByName('floor')) && addSpotLight('0xffffff', 0.8, spot2, spot2, spotlightDis);
vectorIntersectWithMesh(spot3, scene3D.getObjectByName('floor')) && addSpotLight('0xffffff', 0.8, spot3, spot3, spotlightDis);
vectorIntersectWithMesh(spot4, scene3D.getObjectByName('floor')) && addSpotLight('0xffffff', 0.8, spot4, spot4, spotlightDis);
}
}
}
// Load data
this.setState({
isLoading: true
});
if (self.props.downloadFlag) {
this.setState({
waitForRender: 0
});
// set loading bar
switch (self.props.state.mode) {
case MODE_ELEVATION_VIEW:
self.props.setIsLoadingElevation('front', true);
break;
case MODE_3D_VIEW:
self.props.setIsLoading3D(true);
break;
}
}
var _parseData = parseData(scene, actions, this.context.catalog, camera, this.renderer, state.mode),
promise = _parseData.promise,
planData = _parseData.planData;
promise.then(function () {
var objToRemove = [];
planData.plan.traverse(function (obj) {
if (obj.geometry === null) {
objToRemove.push(obj);
}
});
objToRemove.forEach(function (obj) {
obj.removeFromParent();
});
var bbox = new Three.Box3().setFromObject(planData.plan);
if (!isElevationView(state.mode)) {
cameraControls.fitToBox(bbox);
}
setupLight(scene3D, planData.boundingBox);
self.setState({
waitForRender: 1
});
setTimeout(function () {
self.setState({
isLoading: false
});
self.renderer.domElement.style.display = 'block';
}, 1500);
});
var area = scene.getIn(['layers', scene.selectedLayer, 'areas']);
var layer = scene.getIn(['layers', scene.selectedLayer]);
var areas = [],
lights = [];
var snapBox = null;
// Check for data
var msg = '';
scene.layers.forEach(function (layer) {
if (layer.id === scene.selectedLayer || layer.visible) {
layer.items.forEach(function (item) {
if (item.doorStyle === null) {
if (!msg.includes(item.name + "'s doorStyle is null.")) msg += item.name + "'s doorStyle is null.\n";
}
});
}
});
if (msg !== '') {
confirm(msg);
}
init();
render();
// area lightning(wall lightning)/////
area.forEach(function (data) {
areas.push(data);
});
var _loop = function _loop() {
var aVertices = [];
var lines = [];
var height = 100;
areas[i].vertices.forEach(function (data) {
aVertices.push(data);
});
layer.lines.forEach(function (data) {
lines.push(data);
});
var _loop3 = function _loop3() {
var data = lines[_i15];
var realVec = [];
data.vertices.forEach(function (vec) {
realVec.push(vec);
});
if (aVertices.includes(realVec[0]) && aVertices.includes(realVec[1])) {
height = convert(layer.ceilHeight).from(layer.unit).to(UNIT_CENTIMETER);
// height = data.properties.getIn(['height', 'length']);
return 1; // break
}
};
for (var _i15 = 0; _i15 < lines.length; _i15++) {
if (_loop3()) break;
}
var vertices = [];
areas[i].vertices.forEach(function (datas) {
var vertex = scene.getIn(['layers', scene.selectedLayer, 'vertices', datas]);
vertices.push(vertex);
});
vertices.push(vertices[0]);
var fLen = vertices.length - 1;
for (var _i16 = 0; _i16 < fLen; _i16++) {
var sX = vertices[_i16].x;
var sY = vertices[_i16].y;
var eX = vertices[_i16 + 1].x;
var eY = vertices[_i16 + 1].y;
var len = Math.sqrt((eX - sX) * (eX - sX) + (eY - sY) * (eY - sY));
for (var cLen = 200; cLen < len; cLen += 200) {
var cX = sX + (eX - sX) * cLen / len;
var cY = sY + (eY - sY) * cLen / len;
var endLen = Math.sqrt((eX - cX) * (eX - cX) + (eY - cY) * (eY - cY));
if (endLen <= 100) continue;
var vec2 = new Three.Vector2(cX - sX, cY - sY);
var angle = vec2.angle() + Math.PI / 2;
cX = Math.cos(angle) * 30 + cX;
cY = Math.sin(angle) * 30 + cY;
var spotLight = new Three.SpotLight(0xeeeeee, 1.7);
spotLight.angle = 0.76;
spotLight.castShadow = true;
spotLight.penumbra = 1;
spotLight.decay = 1.7;
spotLight.distance = height - 20;
var target = new Three.Object3D();
spotLight.target = target;
lights.push({
light: spotLight,
target: target,
x: cX,
y: cY,
height: height
});
}
}
};
for (var i = 0; i < areas.length; i++) {
_loop();
}
// //////////////////////////
// OBJECT PICKING
var toIntersect = [planData.plan];
var mouse = new Three.Vector2();
var gridPlane = planData.grid;
var raycaster = new Three.Raycaster();
var selectedObject = {};
var selectedFlag = false;
var currentObject = null;
var isSelected = false;
var bRotate = false;
var bMove = false;
var bMoveUP = false;
/** Transformation matrix of grid */
var gridMatrix = new Three.Matrix4();
var rayDirection = new Three.Vector3();
/** World position of grid plane */
var gridPlanOrigin = new Three.Vector3();
var Point = new Three.Vector2();
var sPoint = new Three.Vector2();
// SNAP FUNCTION VARIABLE
var snapFlag = false;
var snapAnimI = 0;
var snapDelta = 6;
var t_i = 0;
var targetPoint = new Three.Vector3();
var targetRot = 0;
var targetUVec = new Three.Vector3();
var targetCRotation = 0;
var targetObj = null;
var targetNumber = 0;
var wallSlide = false;
var pinFlag = false;
var sFlag = false; //for all object move
var endPoint = {};
var allItemRect;
var allItemSnap;
var allLines;
var allLineRects;
var allLineSnap;
var allRect;
var allArea;
// FLAG FOR initial phase of drawing an item
var isInitialPhase = true;
// end snap function variable///////////////////////
var backsplashVisible = false;
var holeItems = GeometryUtils.getHoleItems(layer);
var removeSnapBox = function removeSnapBox() {
if (snapBox != null) {
planData.plan.remove(snapBox);
disposeObject(snapBox);
snapBox = null;
targetObj = null;
snapFlag = false;
}
};
var camToGrid = new Three.Vector3();
var camPos = camera.position;
var mapCursorPosition = function mapCursorPosition(e, altitude) {
camToGrid.subVectors(gridPlanOrigin, camPos);
var camD = camToGrid.y + (altitude ? altitude : 0);
var rayD = rayDirection.y;
var intersectPt = rayDirection.multiplyScalar(camD / rayD).add(camPos);
intersectPt.y = gridPlanOrigin.y;
intersectPt.applyMatrix4(gridMatrix);
return {
x: intersectPt.x,
y: -intersectPt.z
};
};
/* for Snap Functions*/
var pointLineDistance = function pointLineDistance(point, line) {
// return distance from point to line and directional point of line
var pX = point.x;
var pY = point.y;
var l1x = line[0].x;
var l1y = line[0].y;
var l2x = line[1].x;
var l2y = line[1].y;
var pLine = new Three.Vector2(l1x - pX, l1y - pY);
var Line = new Three.Vector2(l1x - l2x, l1y - l2y);
var pAngle = pLine.angle();
var lAngle = Line.angle();
var pDistance = pLine.length();
var oDistance = Line.length();
var directDistance = Math.sin(pAngle - lAngle) * pDistance;
var lineDistance = Math.cos(pAngle - lAngle) * pDistance;
var dX = l1x + (l2x - l1x) * lineDistance / oDistance;
var dY = l1y + (l2y - l1y) * lineDistance / oDistance;
var dPoint = {
x: dX,
y: dY
};
return {
distance: directDistance,
point: dPoint
};
};
var getInterSect = function getInterSect(shape1, shape2) {
// return result of intersect of two shape
var count = 0;
for (var _i = 0; _i < shape1.length - 1; _i++) {
var sl1 = {
x: shape1[_i].x,
y: shape1[_i].y
};
var sl2 = {
x: shape1[_i + 1].x,
y: shape1[_i + 1].y
};
for (var j = 0; j < shape2.length - 1; j++) {
var el1 = {
x: shape2[j].x,
y: shape2[j].y
};
var el2 = {
x: shape2[j + 1].x,
y: shape2[j + 1].y
};
var flag = GeometryUtils.getLineInterSect(sl1.x, sl1.y, sl2.x, sl2.y, el1.x, el1.y, el2.x, el2.y);
if (flag) {
count++;
if (count > 1) return true;
}
}
}
return false;
};
this.getRectPoints = function (width, height, pos, rot) {
// return 4 points from it's position, width, height, and rotation info
var rX = width / 2;
var rY = height / 2;
var vertices = [];
var cRot = rot;
var pX = pos.x + Math.cos(cRot) * rX + Math.cos(cRot + Math.PI / 2) * rY;
var pY = pos.y + Math.sin(cRot) * rX + Math.sin(cRot + Math.PI / 2) * rY;
vertices.push({
x: Math.floor(pX + 0.5),
y: Math.floor(pY + 0.5)
});
rX = -rX;
pX = pos.x + Math.cos(cRot) * rX + Math.cos(cRot + Math.PI / 2) * rY;
pY = pos.y + Math.sin(cRot) * rX + Math.sin(cRot + Math.PI / 2) * rY;
vertices.push({
x: Math.floor(pX + 0.5),
y: Math.floor(pY + 0.5)
});
rY = -rY;
pX = pos.x + Math.cos(cRot) * rX + Math.cos(cRot + Math.PI / 2) * rY;
pY = pos.y + Math.sin(cRot) * rX + Math.sin(cRot + Math.PI / 2) * rY;
vertices.push({
x: Math.floor(pX + 0.5),
y: Math.floor(pY + 0.5)
});
rX = -rX;
pX = pos.x + Math.cos(cRot) * rX + Math.cos(cRot + Math.PI / 2) * rY;
pY = pos.y + Math.sin(cRot) * rX + Math.sin(cRot + Math.PI / 2) * rY;
vertices.push({
x: Math.floor(pX + 0.5),
y: Math.floor(pY + 0.5)
});
vertices.push(vertices[0]);
vertices.push(vertices[2]);
return vertices;
};
var prepareSnap = function prepareSnap(layer) {
allLines = GeometryUtils.getAllLines(layer);
allLineRects = GeometryUtils.buildRectFromLines(layer, allLines);
allItemRect = GeometryUtils.getAllItems(_this2.props.state.scene, actions.catalog, allLineRects);
allItemSnap = GeometryUtils.getAllItemSnap(allItemRect);
allLineSnap = GeometryUtils.getAllLineSnap(allLineRects, allItemRect.cur);
allRect = allItemRect.others.concat(allLineRects);
allItemSnap = GeometryUtils.validateSnaps(allItemSnap, allRect);
allLineSnap = GeometryUtils.validateSnaps(allLineSnap, allRect);
allArea = GeometryUtils.getAllArea(layer);
};
var prepareSnapSpec = function prepareSnapSpec(layer) {
allLines = GeometryUtils.getAllLines(layer);
allLineRects = GeometryUtils.buildRectFromLines(layer, allLines);
allItemRect = GeometryUtils.getAllItemSpecified(_this2.props.state.scene, actions.catalog, WALL_CABINET_LAYOUTPOS);
// allItemSnap = GeometryUtils.getAllItemSnap(allItemRect);
};
// prepareSnapSpec(layer);
var lineRect = function lineRect(layer) {
var areainfo = [];
layer.areas.forEach(function (area) {
var sz = area.vertices.size;
for (var i = 0; i < sz; i++) {
areainfo.push(area.vertices.get(i));
}
});
var rect = [];
areainfo.forEach(function (area) {
var vert = layer.vertices.get(area);
rect.push(vert.x, vert.y);
});
return rect;
};
this.collisionCheck = function (obj, pos, rot, tObj) {
var _this3 = this;
var item = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
var catalog = arguments.length > 5 ? arguments[5] : undefined;
//collision check from one object to every other object excpet target object
var layer = this.props.state.scene.getIn(['layers', obj.userData.layerId]);
var layoutpos = 'utype';
if (item !== null) {
var catid = item.type;
var cat = catalog.elements[catid];
layoutpos = cat.info.layoutpos;
}
var oPos = new Three.Vector2(pos.clone().x, pos.clone().y);
var sBounding = obj.children[0].userData;
var width = sBounding.max.x - sBounding.min.x;
var depth = sBounding.max.z - sBounding.min.z;
var oVertices = this.getRectPoints(width, depth, oPos.clone(), rot % 360 / 180 * Math.PI);
var datas = [];
layer.items.forEach(function (data) {
datas.push(data);
});
for (var _i2 = 0; _i2 < datas.length; _i2++) {
var data = datas[_i2];
if (data.id == obj.userData.itemId || data.id == tObj.userData.itemId) continue;
var target = planData.sceneGraph.layers[obj.userData.layerId].items[data.id];
if (target === undefined) {
console.log(data.id + ' does not exist in viewer3d/viewer3d.js collisionCheck function');
return false;
}
var _item = layer.items.getIn([data.id]);
var ocatid = _item.type;
var ocat = catalog.elements[ocatid];
var olayoutpos = ocat.info.layoutpos;
if (!(layoutpos === BASE_CABINET_LAYOUTPOS && olayoutpos === WALL_CABINET_LAYOUTPOS || layoutpos === WALL_CABINET_LAYOUTPOS && olayoutpos === BASE_CABINET_LAYOUTPOS)) {
var tRot = _item.rotation;
var tPos = new Three.Vector2(_item.x, _item.y);
var tBounding = target.children[0].userData;
var twidth = tBounding.max.x - tBounding.min.x;
var tdepth = tBounding.max.z - tBounding.min.z;
var tVertices = this.getRectPoints(twidth, tdepth, tPos.clone(), tRot % 360 / 180 * Math.PI);
if (getInterSect(oVertices, tVertices)) {
return false;
}
}
}
datas = [];
layer.lines.forEach(function (data) {
datas.push(data);
});
var _loop2 = function _loop2() {
var data = datas[_i3];
if (data.id == obj.userData.itemId || data.id == tObj.userData.itemId) return 0; // continue
var item = layer.lines.getIn([data.id]);
// let llayoutpos = catalog.elements[item.type].info.layoutpos;
var vertices = [];
item.vertices.forEach(function (data) {
var vertex = layer.vertices.get(data);
vertices.push({
x: vertex.x,
y: vertex.y
});
});
var vec = new Three.Vector2(vertices[1].x - vertices[0].x, vertices[1].y - vertices[0].y);
var tRot = vec.angle();
var tPos = new Three.Vector2((vertices[0].x + vertices[1].x) / 2, (vertices[0].y + vertices[1].y) / 2);
var tdepth = item.properties.getIn(['thickness', 'length']);
var twidth = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
var tVertices = _this3.getRectPoints(twidth, tdepth, tPos.clone(), tRot);
if (getInterSect(oVertices, tVertices)) {
return {
v: false
};
}
},
_ret;
for (var _i3 = 0; _i3 < datas.length; _i3++) {
_ret = _loop2();
if (_ret === 0) continue;
if (_ret) return _ret.v;
}
return true;
};
this.collisionHoleCheck = function (obj, pos, rot, tObj) {
var item = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
var catalog = arguments.length > 5 ? arguments[5] : undefined;
var layer = this.props.state.scene.getIn(['layers', obj.userData.layerId]);
var currentItem;
if (item !== null) {
var catid = item.type;
var cat = catalog.elements[catid];
currentItem = {
selectedItem: item,
cat: cat
};
}
var oPos = new Three.Vector2(pos.clone().x, pos.clone().y);
var sBounding = obj.children[0].userData;
var width = sBounding.max.x - sBounding.min.x;
var depth = sBounding.max.z - sBounding.min.z;
var oVertices = this.getRectPoints(width, depth, oPos.clone(), rot % 360 / 180 * Math.PI);
var datas = [];
layer.items.forEach(function (data) {
datas.push(data);
});
for (var _i4 = 0; _i4 < datas.length; _i4++) {
var data = datas[_i4];
if (data.id == obj.userData.itemId || data.id == tObj.userData.itemId) continue;
var target = planData.sceneGraph.layers[obj.userData.layerId].items[data.id];
if (target === undefined) {
console.log(data.id + ' does not exist in viewer3d/viewer3d.js collisionCheck function');
return false;
}
var _item2 = layer.items.getIn([data.id]);
var ocatid = _item2.type;
var ocat = catalog.elements[ocatid];
if (!ocat) ocat = catalog.elements[returnReplaceableDeepSearchType(ocatid)];
var otherItem = {
item: _item2,
cat: ocat
};
if (GeometryUtils.needSnap(currentItem, otherItem) && otherItem.cat.type != 'cabinet') {
var tRot = _item2.rotation;
var tPos = new Three.Vector2(_item2.x, _item2.y);
var tBounding = target.children[0].userData;
var twidth = tBounding.max.x - tBounding.min.x;
var tdepth = tBounding.max.z - tBounding.min.z;
var tVertices = this.getRectPoints(twidth, tdepth, tPos.clone(), tRot % 360 / 180 * Math.PI);
if (getInterSect(oVertices, tVertices)) {
return false;
}
}
}
var holes = [];
layer.lines.forEach(function (line) {
line.holes.forEach(function (holeID) {
var hole = layer.holes.get(holeID);
holes.push(hole);
});
});
var i = 0;
for (; i < holes.length; i++) {
var _tPos = new Three.Vector2(holes[i].x, holes[i].y);
var _twidth = holes[i].properties.getIn(['width', 'length']);
var theight = holes[i].properties.getIn(['thickness', 'length']);
var trot = holes[i].rotation;
var _tVertices = this.getRectPoints(_twidth, theight, _tPos.clone(), trot);
if (getInterSect(oVertices, _tVertices)) {
return false;
}
}
return true;
};
this.collisionSlide = function (item3D, originPos, layer, sVertices, tPos, item) {
var items = [];
var cur_category = '';
var catalog = actions.catalog;
if (layer.selected.items.size > 0) {
var selectedItem = layer.getIn(['items', layer.selected.items.get(0)]);
var catid = selectedItem.type;
var cat = catalog.elements[catid];
if (cat === undefined || cat === null) cat = catalog.getIn(['elements', catid]);
cur_category = cat.obj.category;
}
layer.items.forEach(function (data) {
if (data.id == selectedObject.itemID) {
return;
}
items.push(data.toJS());
});
var oPos = new Three.Vector2(originPos.x, -originPos.z);
// sort from distance
for (var _i5 = 0; _i5 < items.length - 1; _i5++) {
for (var j = _i5 + 1; j < items.length; j++) {
if (verticesDistance(oPos, new Three.Vector2(items[_i5].x, items[_i5].y)) > verticesDistance(oPos, new Three.Vector2(items[j].x, items[j].y))) {
var exchange = items[j];
items[j] = items[_i5];
items[_i5] = exchange;
}
}
}
var i = 0;
for (; i < items.length; i++) {
if (!items[i]) return;
var _target = planData.sceneGraph.layers[selectedObject.layerID].items[items[i].id];
if (_target === undefined) {
return false;
}
var _targetData = layer.items.getIn([items[i].id]);
var _tRot = _targetData.rotation;
var _tPos2 = new Three.Vector2(_targetData.x, _targetData.y);
var _tBounding = _target.children[0].userData;
var _twidth2 = _tBounding.max.x - _tBounding.min.x;
var _tdepth = _tBounding.max.z - _tBounding.min.z;
var _tVertices2 = this.getRectPoints(_twidth2, _tdepth, _tPos2.clone(), _tRot % 360 / 180 * Math.PI);
if (getInterSect(sVertices, _tVertices2)) {
break;
}
}
if (items.length == 0 || !items[i]) return;
var target = planData.sceneGraph.layers[selectedObject.layerID].items[items[i].id];
var targetData = layer.items.getIn([items[i].id]);
var targetPos = new Three.Vector2(targetData.x, targetData.y);
var tRot = targetData.rotation;
var tBounding = target.children[0].userData;
var twidth = tBounding.max.x - tBounding.min.x;
var tdepth = tBounding.max.z - tBounding.min.z;
var tVertices = this.getRectPoints(twidth, tdepth, targetPos.clone(), tRot % 360 / 180 * Math.PI);
// ////////////////////////
var vArray = [];
var dteArray = [];
var lineArray = [];
var vdistanceArray = [];
var cVecArray = [];
var inFlag = false;
for (var _i6 = 0; _i6 < 4; _i6++) {
var v1 = tVertices[_i6];
var v2 = tVertices[_i6 + 1];
var data = pointLineDistance({
x: tPos.x,
y: tPos.y
}, [{
x: v1.x,
y: v1.y
}, {
x: v2.x,
y: v2.y
}]);
dteArray.push(data.distance);
vArray.push(data.point);
lineArray.push([v1, v2]);
}
// if tPos in target object
var tPosDistance = Math.abs(pointLineDistance(tPos, lineArray[0]).distance) + Math.abs(pointLineDistance(tPos, lineArray[2]).distance);
var realDistance = new Three.Vector2(lineArray[1][0].x - lineArray[1][1].x, lineArray[1][0].y - lineArray[1][1].y).length();
var tPosDistance1 = Math.abs(pointLineDistance(tPos, lineArray[1]).distance) + Math.abs(pointLineDistance(tPos, lineArray[3]).distance);
var realDistance1 = new Three.Vector2(lineArray[0][0].x - lineArray[0][1].x, lineArray[0][0].y - lineArray[0][1].y).length();
if (Math.abs(Math.abs(tPosDistance) - Math.abs(realDistance)) < 0.01 && Math.abs(Math.abs(tPosDistance1) - Math.abs(realDistance1)) < 0.01) inFlag = true;
// ////////////////////
var key = 0;
// sort distance from origin point
for (var _j = 0; _j < dteArray.length - 1; _j++) {
for (var k = _j + 1; k < dteArray.length; k++) {
if (Math.abs(dteArray[_j]) > Math.abs(dteArray[k])) {
var temp = dteArray[k];
dteArray[_j] = dteArray[k];
dteArray[k] = temp;
var temp1 = vArray[k];
vArray[_j] = vArray[k];
vArray[k] = temp1;
var temp2 = lineArray[k];
lineArray[_j] = lineArray[k];
lineArray[k] = temp2;
}
}
}
// //////////////////////////////
for (var _i7 = 0; _i7 < 4; _i7++) {
var _data = pointLineDistance(sVertices[_i7], lineArray[key]);
vdistanceArray.push(_data.distance);
cVecArray.push({
x: _data.point.x - sVertices[_i7].x,
y: _data.point.y - sVertices[_i7].y
});
}
for (var _j2 = 0; _j2 < vdistanceArray.length; _j2++) {
var tX = tPos.x + cVecArray[_j2].x;
var tY = tPos.y + cVecArray[_j2].y;
if (this.collisionCheck(item3D, new Three.Vector2(tX, tY), item.rotation, {
userData: {
itemId: null
}
}, item, this.context.catalog)) {
item3D.position.set(tX, originPos.y, -tY);
sPoint.set(tX, tY);
break;
}
}
};
this.snap = function (obj, layer) {
// snap operation
var target = obj.userData.target;
for (; target.parent != null;) {
if (target.name == 'pivot') break;
target = target.parent;
}
var source = obj.parent.parent.parent;
if (target.userData.type == 'item') {
var sRot = layer.getIn(['items', source.userData.itemId]).rotation;
var tRot = layer.getIn(['items', target.userData.itemId]) ? layer.getIn(['items', target.userData.itemId]).rotation : 0;
var item = layer.getIn(['items', source.userData.itemId]);
var layoutType = item.layoutpos;
var altitudeLength = convert(item.properties.getIn(['altitude', '_length'])).from('in').to('cm');
var sBounding = source.children[0].userData;
var tBounding = target.children[0].userData;
var tPos = target.position.clone();
var width = sBounding.max.x - sBounding.min.x;
var height = sBounding.max.y - sBounding.min.y;
var depth = sBounding.max.z - sBounding.min.z;
var snapBoxGeom = new Three.BoxGeometry(width, height, depth);
var snapBoxObj = new Three.Mesh(snapBoxGeom, new Three.MeshBasicMaterial({
// color: 0x2cde6b,
// opacity: 0.7,
transparent: true,
blending: Three.MultiplyBlending
}));
var removeSnapBoxObj = function removeSnapBoxObj() {
if (snapBoxObj) {
planData.plan.remove(snapBoxObj);
disposeObject(snapBoxObj);
}
snapFlag = false;
};
var box = new Three.BoxHelper(snapBoxObj, 0xffffff);
box.material.linewidth = 2;
box.material.depthTest = false;
box.renderOrder = 200;
snapBoxObj.add(box);
snapBoxObj.position.set(source.position.x, layoutType === WALL_CABINET_LAYOUTPOS ? altitudeLength + source.position.y + height / 2 : source.position.y + height / 2, source.position.z);
snapBoxObj.rotation.set(source.rotation.x, source.rotation.y, source.rotation.z);
snapBoxObj.name = 'TransformBox';
planData.plan.add(snapBoxObj);
var deltaX = (tBounding.max.x - tBounding.min.x) / 2 + (sBounding.max.x - sBounding.min.x) / 2;
var deltaZ = (tBounding.max.z - tBounding.min.z) / 2 - (sBounding.max.z - sBounding.min.z) / 2;
var sPos = snapBoxObj.position.clone();
// avaliable snap place///////////////
var tPoses = [];
var pX = tPos.x + deltaX * Math.cos(tRot / 180 * Math.PI) + deltaZ * Math.sin(tRot / 180 * Math.PI);
var pZ = tPos.z - deltaX * Math.sin(tRot / 180 * Math.PI) + deltaZ * Math.cos(tRot / 180 * Math.PI);
tPoses.push(new Three.Vector3(pX, 0, pZ));
deltaX = -deltaX;
pX = tPos.x + deltaX * Math.cos(tRot / 180 * Math.PI) + deltaZ * Math.sin(tRot / 180 * Math.PI);
pZ = tPos.z - deltaX * Math.sin(tRot / 180 * Math.PI) + deltaZ * Math.cos(tRot / 180 * Math.PI);
tPoses.push(new Three.Vector3(pX, 0, pZ));
deltaX = (tBounding.max.x - tBounding.min.x) / 2 - (sBounding.max.x - sBounding.min.x) / 2;
deltaZ = -(tBounding.max.z - tBounding.min.z) / 2 - (sBounding.max.z - sBounding.min.z) / 2;
pX = tPos.x + deltaX * Math.cos(tRot / 180 * Math.PI) + deltaZ * Math.sin(tRot / 180 * Math.PI);
pZ = tPos.z - deltaX * Math.sin(tRot / 180 * Math.PI) + deltaZ * Math.cos(tRot / 180 * Math.PI);
tPoses.push(new Three.Vector3(pX, 0, pZ));
deltaX = -deltaX;
pX = tPos.x + deltaX * Math.cos(tRot / 180 * Math.PI) + deltaZ * Math.sin(tRot / 180 * Math.PI);
pZ = tPos.z - deltaX * Math.sin(tRot / 180 * Math.PI) + deltaZ * Math.cos(tRot / 180 * Math.PI);
tPoses.push(new Three.Vector3(pX, 0, pZ));
var distance = Math.sqrt((sPos.x - tPoses[0].x) * (sPos.x - tPoses[0].x) + (sPos.z - tPoses[0].z) * (sPos.z - tPoses[0].z));
var tNum = 1;
tPos = tPoses[0].clone();
for (var _i8 = 1; _i8 < tPoses.length; _i8++) {
var curDis = Math.sqrt((sPos.x - tPoses[_i8].x) * (sPos.x - tPoses[_i8].x) + (sPos.z - tPoses[_i8].z) * (sPos.z - tPoses[_i8].z));
if (curDis < distance) {
distance = curDis;
tNum = _i8 + 1;
tPos = tPoses[_i8].clone();
}
}
// //////////////////////////////////
if (targetObj != null && targetObj.userData.itemId == target.userData.itemId && tNum == targetNumber) {
removeSnapBoxObj();
return;
} else {
removeSnapBox();
}
// //////////////////////////////////
if (tNum >= 3) tRot += 180;
snapAnimI = 0;
t_i = 0;
targetObj = target;
targetNumber = tNum;
targetRot = tRot;
targetPoint = tPos;
snapBox = snapBoxObj;
var cx = sPos.x - tPos.x;
var cz = sPos.z - tPos.z;
targetUVec = new Three.Vector3(cx, 0, cz);
targetCRotation = (tRot - sRot) % 360 / 180 * Math.PI;
} else {
var _item3 = layer.getIn(['items', source.userData.itemId]);
if (holeItems.length && selectedObj) {
var _i9;
for (_i9 = 0; _i9 < holeItems.length; _i9++) {
var hole = holeItems[_i9];
if (Math.abs(Math.sin(selectedObj.rotRad)) === 1) {
if (_item3.y + selectedObj.size.width / 2 >= hole.y - hole.width / 2 && _item3.y - selectedObj.size.width / 2 <= hole.y + hole.width / 2 && (selectedObj.rotRad == 0 || selectedObj.rotRad == -Math.PI / 2 ? _item3.x <= hole.x && _item3.x + selectedObj.size.height >= hole.x : _item3.x >= hole.x && _item3.x - selectedObj.size.height <= hole.x)) break;
} else {
if (_item3.x + selectedObj.size.width / 2 >= hole.x - hole.width / 2 && _item3.x - selectedObj.size.width / 2 <= hole.x + hole.width / 2 && (selectedObj.rotRad == 0 || selectedObj.rotRad == -Math.PI / 2 ? _item3.y <= hole.y && _item3.y + selectedObj.size.height >= hole.y : _item3.y >= hole.y && _item3.y - selectedObj.size.height <= hole.y)) break;
}
}
if (_i9 != holeItems.length) return;
}
if (target.userData.type == 'hole') {
snapFlag = false;
return;
} else {
var _layoutType = _item3.layoutpos;
var _altitudeLength = convert(_item3.properties.getIn(['altitude', '_length'])).from('in').to('cm');
var _sBounding = source.children[0].userData;
var _width = _sBounding.max.x - _sBounding.min.x;
var _height = _sBounding.max.y - _sBounding.min.y;
var _depth = _sBounding.max.z - _sBounding.min.z;
var _snapBoxGeom = new Three.BoxGeometry(_width, _height, _depth);
var _snapBoxObj = new Three.Mesh(_snapBoxGeom, new Three.MeshBasicMaterial({
// color: 0x2cde6b,
// opacity: 0.7,
transparent: true,
blending: Three.MultiplyBlending
}));
var _removeSnapBoxObj = function _removeSnapBoxObj() {
if (_snapBoxObj) {
planData.plan.remove(_snapBoxObj);
disposeObject(_snapBoxObj);
}
snapFlag = false;
};
var _box = new Three.BoxHelper(_snapBoxObj, 0xffffff);
_box.material.linewidth = 2;
_box.material.depthTest = false;
_box.renderOrder = 100;
_snapBoxObj.add(_box);
_snapBoxObj.position.set(source.position.x, _layoutType === WALL_CABINET_LAYOUTPOS ? _altitudeLength + source.position.y + _height / 2 : source.position.y + _height / 2, source.position.z);
_snapBoxObj.rotation.set(source.rotation.x, source.rotation.y, source.rotation.z);
_snapBoxObj.name = 'TransformBox';
planData.plan.add(_snapBoxObj);
var snapLine = layer.getIn(['lines', target.userData.lineId]);
// let snapLineThickness = snapLine.properties.getIn([
// 'thickness',
// 'length'
// ]);
var snapLineThickness = 10.64;
var vertices = [];
if (snapLine === undefined) return;
snapLine.vertices.forEach(function (data) {
var vec = layer.getIn(['vertices', data]);
vertices.push(vec);
});
var iX = source.position.clone().x;
var iY = -source.position.clone().z;
var lineVec = new Three.Vector2(vertices[1].x - vertices[0].x, vertices[1].y - vertices[0].y);
var oLength = Math.sqrt(lineVec.x * lineVec.x + lineVec.y * lineVec.y);
lineVec.normalize();
var vec2 = new Three.Vector2(iX - vertices[0].x, iY - vertices[0].y);
var vec2Legnth = Math.sqrt(vec2.x * vec2.x + vec2.y * vec2.y);
var angle = Math.abs(lineVec.angle() - vec2.angle());
angle = angle > Math.PI ? 2 * Math.PI - angle : angle;
var lineLength = Math.cos(angle) * vec2Legnth;
var transLength = 0;
if (lineLength < 100) {
transLength = -lineLength + (snapLineThickness + _width) / 2;
}
if (lineLength > oLength - 100) {
transLength = -lineLength - (snapLineThickness + _width) / 2 + oLength;
}
var directPoint = new Three.Vector2(lineVec.x * lineLength + vertices[0].x, lineVec.y * lineLength + vertices[0].y);
var directLine = new Three.Vector2(directPoint.x - iX, directPoint.y - iY);
var dLength = Math.sqrt((iX - directPoint.x) * (iX - directPoint.x) + (iY - directPoint.y) * (iY - directPoint.y));
var reduceLen = (snapLineThickness + _depth) / 2;
var scale = (dLength - reduceLen) / dLength;
var _tPos3 = new Three.Vector2(iX + (directPoint.x - iX) * scale + lineVec.x * transLength, iY + (directPoint.y - iY) * scale + lineVec.y * transLength);
var realAngle = directLine.angle() - Math.PI / 2;
var _tRot2 = realAngle * 180 / Math.PI;
var _sPos = new Three.Vector2(iX, iY);
var _sRot = _item3.rotation;
var _tNum = 0;
// //////////////////////////////////////
// check part////
var result = this.collisionCheck(source, _tPos3, _tRot2, target, _item3, this.context.catalog);
// console.log('result', result);
if (result == false) {
_removeSnapBoxObj();
removeSnapBox();
return;
}
// ////////////////
if (targetObj === target && snapBox !== null) {
_removeSnapBoxObj();
snapAnimI = 20;
targetPoint = new Three.Vector3(_tPos3.x, 0, -_tPos3.y);
var _sourcePos = snapBox.position.clone();
var _cx = _sourcePos.x - targetPoint.x;
var _cz = _sourcePos.z - targetPoint.z;
targetUVec = new Three.Vector3(_cx, 0, _cz);
targetRot = _tRot2;
targetCRotation = (_tRot2 - _sRot) % 360 / 180 * Math.PI;
snapFlag = false;
return;
} else {
removeSnapBox();
}
// //////////////////////////////////////
snapAnimI = 0;
t_i = 0;
targetObj = target;
targetNumber = _tNum;
targetRot = _tRot2;
targetPoint = new Three.Vector3(_tPos3.x, 0, -_tPos3.y);
snapBox = _snapBoxObj;
var sourcePos = snapBox.position.clone();
var _cx2 = sourcePos.x - targetPoint.x;
var _cz2 = sourcePos.z - targetPoint.z;
targetUVec = new Three.Vector3(_cx2, 0, _cz2);
targetRot = _tRot2;
targetCRotation = (_tRot2 - _sRot) % 360 / 180 * Math.PI;
}
}
};
/*end of snap functions*/
var selectedObj = null;
var firstMove = false;
var prevX, prevY;
var selObj = null;
var createToolObject = function createToolObject() {
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 200;
canvas.style.width = 50 + 'px';
canvas.style.height = 100 + 'px';
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#FFFFFF';
ctx.strokeStyle = '#000000';
ctx.beginPath();
ctx.arc(50, 50, 40, 0, 4 * Math.PI);
ctx.fill();
ctx.stroke();
var img1 = new Image();
img1.crossOrigin = 'anonymous';
img1.src = '/assets/img/svg/3d_item_rotation.svg';
img1.onload = function () {
ctx.drawImage(img1, 16, 16, 68, 68);
};
ctx.beginPath();
ctx.arc(50, 150, 40, 0, 4 * Math.PI);
ctx.fill();
ctx.stroke();
var img2 = new Image();
img2.crossOrigin = 'anonymous';
img2.src = '/assets/img/svg/3d_item_move.svg';
img2.onload = function () {
ctx.drawImage(img2, 16, 116, 68, 68);
};
return canvas;
};
var clockWise = true;
var lastAngle = 0;
var createAngleObject = function createAngleObject(rotate) {
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 100;
canvas.style.width = 100 + 'px';
canvas.style.height = 100 + 'px';
var ctx = canvas.getContext('2d');
ctx.strokeStyle = '#FFFFFF';
ctx.lineWidth = 10;
ctx.beginPath();
ctx.arc(50, 50, 45, 0, 2 * Math.PI);
ctx.stroke();
ctx.strokeStyle = SECONDARY_PURPLE_COLOR;
ctx.lineWidth = 6;
ctx.beginPath();
if (lastAngle < 15 && lastAngle > -15) {
if (rotate >= 0) {
clockWise = false;
} else {
clockWise = true;
}
if (lastAngle === 0) {
if (rotate > -180) {
clockWise = true;
} else {
clockWise = false;
}
}
}
ctx.arc(50, 50, 45, 0, rotate / 180.0 * Math.PI, clockWise);
ctx.stroke();
lastAngle = rotate;
return canvas;
};
var toolTexture = new Three.Texture(createToolObject());
toolTexture.needsUpdate = true;
var toolObj = new Three.Sprite(new Three.SpriteMaterial({
map: toolTexture,
sizeAttenuation: true
}));
toolObj.material.transparent = true;
toolObj.material.depthTest = false;
toolObj.scale.set(20, 40, 20);
toolObj.renderOrder = 3;
tool